[
  {
    "path": ".github/ISSUE_TEMPLATE.md",
    "content": "# 规则：\n* 请不要只写标题，不写内容，请先清空或另起新行，不遵守规则的提问会被自动关闭。\n\n* 登陆问题、602问题， 请发邮件到  xxnet.dev@gmail.com ，附上帐号，请参考： \n  https://github.com/XX-net/XX-Net/wiki/%E5%A6%82%E4%BD%95%E6%8A%A5%E5%91%8A%E9%97%AE%E9%A2%98\n\n* 是否查看过 [Wiki](https://github.com/XX-net/XX-Net/wiki )？\n\n* 是否以相关关键词搜索过类似 issues？\n\n* 如果问题得到解决，请务必回复相关情况，谢谢。\n\n* 即使最终无法解决你遇到的问题，这也是正常的，因为系统和网络环境千差万别。最终结果也能帮助到后来者，请保持正常交流，再寻它法。\n\n* 请不要只写标题，不写内容，请先清空或另起新行，不遵守规则的提问会被自动关闭。\n\n\n# 提问模版：\n- 操作系统：  \n- 客户端版本号：  \n- 问题现象：  \n- 日志文件：  \n\n# 日志文件获取方法：\n访问 http://localhost:8085/?module=launcher&menu=about 或进入 [系统] -> [关于]\n点 收集调试信息 后面的 [下载] 按钮。"
  },
  {
    "path": ".github/SECURITY.md",
    "content": "# Security Policy\n\n## Supported Versions\n\n\n| Version | Supported          |\n| ------- | ------------------ |\n| current stable/testing version   | :white_check_mark: |\n| older version | :x:                |\n\n## Reporting a Vulnerability\n\nPlease email xxnet.dev@gmail.com to report security issue.  \nNormally we will response to you in one week.  \nThank you for your contribution.  \n"
  },
  {
    "path": ".github/workflows/lint_python.yml",
    "content": "name: lint_python\non:\n  pull_request:\n  push:\n    branches: [test]\njobs:\n  testing_linux:\n    runs-on: ubuntu-latest\n    strategy:\n       matrix:\n         python-version: [ '3.10' ]  # 3.8, 3.9,\n    steps:\n      - uses: actions/checkout@v2\n      - uses: actions/setup-python@v2\n        with:\n          python-version: ${{ matrix.python-version }}\n      - run: pip install pytest\n\n      # - run: pip install  reorder-python-imports codespell flake8 isort\n      # - if: matrix.python-version >= 3.6\n      #  run: |\n      #    pip install black\n      #    black --check . || true\n      # - run: black --diff . || true\n\n#      - run: codespell --quiet-level=2 || true  # --ignore-words-list=\"\" --skip=\"\"\n#      - run: flake8 code --count --select=E9,F63,F7,F82 --show-source --statistics --exclude=code/default/gae_proxy/server,code/default/lib/noarch/six.py\n      # isort and reorder-python-imports are two ways of doing the same thing\n#      - run: isort --recursive . || true\n#      - run: reorder-python-imports . || true\n\n      - run: pip install -r requirements.txt || true\n      - shell: bash\n        env:\n          XTUNNEL_USER: ${{ secrets.XTUNNEL_USER }}\n          XTUNNEL_PASS: ${{ secrets.XTUNNEL_PASS }}\n          PYTHONPATH: ./code/default:./code/default/lib/noarch\n        run: |\n          pytest -v code/default || true\n\n      - name: Integrate testing\n        shell: bash\n        env:\n          XTUNNEL_USER: ${{ secrets.XTUNNEL_USER }}\n          XTUNNEL_PASS: ${{ secrets.XTUNNEL_PASS }}\n          PYTHONPATH: ./code/default:./code/default/lib/noarch\n        run: |\n          python code/default/launcher/tests/integrate_testing.py\n\n  testing_windows:\n    runs-on: windows-latest\n    strategy:\n       matrix:\n         python-version: [3.8, '3.10']\n    steps:\n      - uses: actions/checkout@master\n      - uses: actions/setup-python@v2\n        with:\n          python-version: ${{ matrix.python-version }}\n      - run: pip install pytest\n      - run: pip install -r requirements.txt || true\n      - shell: bash\n        env:\n          XTUNNEL_USER: ${{ secrets.XTUNNEL_USER }}\n          XTUNNEL_PASS: ${{ secrets.XTUNNEL_PASS }}\n          PYTHONPATH: ./code/default:./code/default/lib/noarch\n        run: |\n          pytest -v code/default || true\n\n      - name: Integrate testing\n        shell: bash\n        env:\n          XTUNNEL_USER: ${{ secrets.XTUNNEL_USER }}\n          XTUNNEL_PASS: ${{ secrets.XTUNNEL_PASS }}\n          PYTHONPATH: ./code/default:./code/default/lib/noarch\n        run: |\n          python code/default/launcher/tests/integrate_testing.py\n\n  testing_mac:\n    runs-on: macos-latest\n    strategy:\n       matrix:\n         python-version: ['3.10']\n    steps:\n      - uses: actions/checkout@master\n      - uses: actions/setup-python@v2\n        with:\n          python-version: ${{ matrix.python-version }}\n      - run: pip install pytest\n\n      - run: pip install -r requirements.txt || true\n      - shell: bash\n        env:\n          XTUNNEL_USER: ${{ secrets.XTUNNEL_USER }}\n          XTUNNEL_PASS: ${{ secrets.XTUNNEL_PASS }}\n          PYTHONPATH: ./code/default:./code/default/lib/noarch\n        run: |\n          pytest -v code/default || true\n\n      - name: Integrate testing\n        shell: bash\n        env:\n          XTUNNEL_USER: ${{ secrets.XTUNNEL_USER }}\n          XTUNNEL_PASS: ${{ secrets.XTUNNEL_PASS }}\n          PYTHONPATH: ./code/default:./code/default/lib/noarch\n        run: |\n          python code/default/launcher/tests/integrate_testing.py\n"
  },
  {
    "path": ".github/workflows/notify_aur_upgrade.yml",
    "content": "name: notify_aur_upgrade\non:\n  push:\n\njobs:\n  Notify:\n    name: Notify\n    if: startsWith(github.ref, 'refs/tags')\n    runs-on: ubuntu-latest\n    steps:\n      - run: |\n          curl -L \\\n            -X POST \\\n            -H \"Accept: application/vnd.github+json\" \\\n            -H \"Authorization: Bearer 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\"\\\n            -H \"X-GitHub-Api-Version: 2022-11-28\" \\\n            https://api.github.com/repos/lisuke/PKGBUILD/actions/workflows/xx-net.yml/dispatches \\\n            -d '{\"ref\":\"xx-net\"}'\n"
  },
  {
    "path": ".gitignore",
    "content": ".idea\n/data*\n*~\n*.pyc\n*.swp\n*.pot\n*.mo\n*.xpi\n*pybabel_update.sh\ncore\n.DS_Store\ndesktop.ini\n/SwitchyOmega/AutoProxy.xpi\n/SwitchyOmega/SwitchyOmega.crx\n/code/default/gae_proxy/server/lib/\n/code/default/gae_proxy/local/ipv6_tunnel/enable_ipv6_temp.bat\n/code/default/gae_proxy/local/ipv6_tunnel/set_best_server_temp.bat\n.pytest_cache\n*.log\ncode/version.txt\n\n\n# Babel files\nmessages.po-e\nmessages.pot\ntranslated.po"
  },
  {
    "path": "README.md",
    "content": ":rocket: XX-Net (翻墙VPN)\n=========\n这是一个稳健可靠的翻墙系统，已经连续运行 9 年！  \n我们不去研究墙有什么缺陷，因为所有的缺陷都会被慢慢的补上。  \n我们的策略是化身为普通流量，完全无法区分，最终隐身在茫茫的网络连接中。。。\n\n:electric_plug: 功能特性\n=========\n* 支持多平台： Android/iOS/Windows/Mac/Linux   \n* 采用独特的混淆算法，让您的流量在网络中无法被识别  \n* 开源绿色软件，无需安装，可以支持多台设备同时连接\n* 模拟Chrome浏览器行为，完全无法识别，稳定翻墙\n* 内置 ChatGPT，每个套餐赠送 ChatGPT-3.5 一百万token \n\n\n<br>\n\n### 官网下载: [https://xx-net.com](https://xx-net.com)\n### Telegram: [https://t.me/xxnetshare](https://t.me/xxnetshare)\n### Twitter: [https://twitter.com/XXNetDev](https://twitter.com/XXNetDev)\n###\n###### [中文帮助文档](https://github.com/XX-net/XX-Net/wiki/%E4%B8%AD%E6%96%87%E6%96%87%E6%A1%A3) &nbsp; &nbsp; &nbsp;[English Document](https://github.com/XX-net/XX-Net/wiki/English-Home-Page) &nbsp; &nbsp; &nbsp;[فارسی صفحه اصلی](https://github.com/XX-net/XX-Net/wiki/Persian-home-page) \n\n<br>\n\n\n### 最新公告：\n 2024-03-06\n* 最新版5.9.10, 更新黑名单列表。\n* 5.9.0 升级GAE服务端到python3\n* 5.8.8 改进iOS下连接性能\n* 5.7.0 为X-Tunnel增加新通道\n* 5.6.0 重构代码，减少系统资源消耗\n* 5.1.0，内置ChatGPT\n* 原来是4.x.x 老版本的，需要重新下载新版安装，不能应用内升级。\n\n  \n<br>\n\n#### 提示：  \n* 有问题请先看[Wiki文档](https://github.com/XX-net/XX-Net/wiki/%E4%B8%AD%E6%96%87%E6%96%87%E6%A1%A3)\n* [提问](https://github.com/XX-net/XX-Net/issues) 前，请先看[最近讨论主题](https://github.com/XX-net/XX-Net/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc) ，避免重复发问。  \n"
  },
  {
    "path": "SwitchyOmega/OmegaOptions.bak",
    "content": "{\n\"+Smart-Router\": {\"name\": \"Smart-Router\", \"color\": \"#096dba\", \"fallbackProxy\": {\"host\": \"127.0.0.1\", \"scheme\": \"socks5\", \"port\": 8086}, \"bypassList\": [{\"pattern\": \"<local>\", \"conditionType\": \"BypassCondition\"}], \"profileType\": \"FixedProfile\", \"revision\": \"1538358c83c\"}, \n\"+GAE-Proxy\": {\"name\": \"GAE-Proxy\", \"color\": \"#d42d09\", \"fallbackProxy\": {\"host\": \"127.0.0.1\", \"scheme\": \"http\", \"port\": 8087}, \"bypassList\": [{\"pattern\": \"<local>\", \"conditionType\": \"BypassCondition\"}], \"profileType\": \"FixedProfile\", \"revision\": \"15383570633\"}, \n\"+X-Tunnel\": {\"name\": \"X-Tunnel\", \"color\": \"#092dba\", \"fallbackProxy\": {\"host\": \"127.0.0.1\", \"scheme\": \"socks5\", \"port\": 1080}, \"bypassList\": [{\"pattern\": \"<local>\", \"conditionType\": \"BypassCondition\"}], \"profileType\": \"FixedProfile\", \"revision\": \"1538358c83c\"}, \n\"+GAE-Proxy\\u81ea\\u52a8\\u5207\\u6362\": {\"name\": \"GAE-Proxy\\u81ea\\u52a8\\u5207\\u6362\", \"color\": \"#55bb55\", \"rules\": [\n{\"profileName\": \"GAE-Proxy\", \"condition\": {\"pattern\": \"*.google.com.*\", \"conditionType\": \"HostWildcardCondition\"}}, \n{\"profileName\": \"GAE-Proxy\", \"condition\": {\"pattern\": \"*.google*.com\", \"conditionType\": \"HostWildcardCondition\"}}\n], \"profileType\": \"SwitchProfile\", \"defaultProfileName\": \"__ruleListOf_GAE-Proxy\\u81ea\\u52a8\\u5207\\u6362\", \"revision\": \"15383578bce\"}, \n\"+__ruleListOf_GAE-Proxy\\u81ea\\u52a8\\u5207\\u6362\": {\"sourceUrl\": \"https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt\", \"name\": \"__ruleListOf_GAE-Proxy\\u81ea\\u52a8\\u5207\\u6362\", \"format\": \"AutoProxy\", \"color\": \"#dd6633\", \"matchProfileName\": \"GAE-Proxy\", \"profileType\": \"RuleListProfile\", \"defaultProfileName\": \"direct\", \"ruleList\": \"\", \"revision\": \"1538357da4c\"}, \n\"+X-Tunnel\\u81ea\\u52a8\\u5207\\u6362\": {\"name\": \"X-Tunnel\\u81ea\\u52a8\\u5207\\u6362\", \"rules\": [\n{\"profileName\": \"X-Tunnel\", \"condition\": {\"pattern\": \"*.google.com.*\", \"conditionType\": \"HostWildcardCondition\"}}, \n{\"profileName\": \"X-Tunnel\", \"condition\": {\"pattern\": \"*.google*.com\", \"conditionType\": \"HostWildcardCondition\"}}\n], \"color\": \"#7c05ae\", \"profileType\": \"SwitchProfile\", \"defaultProfileName\": \"__ruleListOf_X-Tunnel\\u81ea\\u52a8\\u5207\\u6362\", \"revision\": \"153835abfe0\"}, \n\"+__ruleListOf_X-Tunnel\\u81ea\\u52a8\\u5207\\u6362\": {\"sourceUrl\": \"https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt\", \"name\": \"__ruleListOf_X-Tunnel\\u81ea\\u52a8\\u5207\\u6362\", \"format\": \"AutoProxy\", \"color\": \"#7c05ae\", \"matchProfileName\": \"X-Tunnel\", \"profileType\": \"RuleListProfile\", \"defaultProfileName\": \"direct\", \"ruleList\": \"\", \"revision\": \"153835b3117\"}, \n\"-monitorWebRequests\": true, \"-startupProfileName\": \"Smart-Router\", \"-showInspectMenu\": true, \"-confirmDeletion\": true, \"-revertProxyChanges\": false, \"-refreshOnProfileChange\": true, \"-quickSwitchProfiles\": [\"direct\"], \"schemaVersion\": 2, \"-enableQuickSwitch\": false, \"-downloadInterval\": 180\n}"
  },
  {
    "path": "SwitchyOmega/download SwitchyOmega for Chromium & Firefox.url",
    "content": "[InternetShortcut]\nURL=https://github.com/FelisCatus/SwitchyOmega/releases\n"
  },
  {
    "path": "code/app_info.json",
    "content": "{\n  \"app_name\": \"XX-Net\"\n}"
  },
  {
    "path": "code/default/LICENSE.txt",
    "content": "Copyright (c) [2022], [XX-Net]\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n  list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n  this list of conditions and the following disclaimer in the documentation\n  and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "code/default/babel_update.py",
    "content": "#!/usr/env/bin python\n\nimport os\n\n\n# pip install googletrans==4.0.0-rc1\nfrom googletrans import Translator\nimport polib\n\n\ntranslator = Translator(service_urls=[\n      'translate.google.com',\n    ])\n\nfor lang in [\"ru_RU\"]:  # \"fa_IR\",\n    for module in [\"launcher\", \"smart_router\", \"x_tunnel\"]:  #\n        source_po = polib.pofile(f'{module}/lang/zh_CN/LC_MESSAGES/messages.po')\n        lang_path = f'{module}/lang/{lang}/LC_MESSAGES'\n        if not os.path.isdir(lang_path):\n            os.makedirs(lang_path, exist_ok=True)\n\n        new_fp = f'{lang_path}/translated.po'\n        with open(new_fp, \"w\") as fd:\n            fd.write(\"\")\n\n        new_po = polib.pofile(new_fp)\n\n        for entry in source_po:\n            try:\n                result = translator.translate(entry.msgid, dest=lang[0:2])\n                res_text = result.text\n            except Exception as e:\n                print(f\"translate {entry.msgid} failed, e:{e}\")\n                res_text = \"\"\n\n            new_entry = polib.POEntry(\n                msgid=entry.msgid,\n                msgstr=res_text,\n                occurrences=entry.occurrences )\n\n            new_po.append(new_entry)\n\n        new_po.save(new_fp)\n        print(f\"module {module} translated to {lang}.\")\n"
  },
  {
    "path": "code/default/download.md",
    "content": "\n## 下载(Download)：\n稳定版(Stable version 4.12.5)：   \n[Win10 版下载](https://github.com/XX-net/XX-Net/releases/download/4.12.5/XX-Net-win10-4.12.5.7z)   \n[Win7 版下载](https://github.com/XX-net/XX-Net/releases/download/4.12.5/XX-Net-win7-4.12.5.7z)   \n[Mac 版下载](https://github.com/XX-net/XX-Net/releases/download/4.12.5/XX-Net-mac-4.12.5.7z)  \n[Linux 版下载](https://github.com/XX-net/XX-Net/archive/4.12.5.zip)  \n[Android版下载](https://github.com/XX-net/XX-Net/releases/download/4.12.5/XX-Net-4.12.5.apk)  \n\n\n\n\n测试版(Test version 4.13.7)：  \n[Win10 版下载](https://github.com/XX-net/XX-Net/releases/download/4.12.6/XX-Net-win10-4.12.6.7z)   \n[Win7 版下载](https://github.com/XX-net/XX-Net/releases/download/4.12.6/XX-Net-win7-4.12.6.7z)   \n[Mac 版下载](https://github.com/XX-net/XX-Net/releases/download/4.12.6/XX-Net-mac-4.12.6.7z)  \n[Linux 版下载](https://github.com/XX-net/XX-Net/archive/4.12.6.zip)  \n[Android版下载](https://github.com/XX-net/XX-Net/releases/download/4.12.6/XX-Net-4.12.6.apk)  \n"
  },
  {
    "path": "code/default/gae_proxy/__init__.py",
    "content": "__all__ = [\"local\", \"start\"]"
  },
  {
    "path": "code/default/gae_proxy/babel.config",
    "content": "# Extraction from Python source files\n#[python: **.py]\n\n# Extraction from HTML and YAML templates\n[jinja2: **/web_ui/**.html]\n[jinja2: **/web_ui/**.yaml]\n\nencoding = utf-8\n"
  },
  {
    "path": "code/default/gae_proxy/lang/de_DE/LC_MESSAGES/messages.po",
    "content": "# German (Germany) translations for PROJECT.\n# Copyright (C) 2015 ORGANIZATION\n# This file is distributed under the same license as the PROJECT project.\n# FIRST AUTHOR <EMAIL@ADDRESS>, 2015.\n#\n#, fuzzy\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: PROJECT VERSION\\n\"\n\"Report-Msgid-Bugs-To: EMAIL@ADDRESS\\n\"\n\"POT-Creation-Date: 2015-12-14 07:04+0800\\n\"\n\"PO-Revision-Date: 2015-12-06 09:15+0800\\n\"\n\"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n\"\n\"Language-Team: de_DE <LL@li.org>\\n\"\n\"Plural-Forms: nplurals=2; plural=(n != 1)\\n\"\n\"MIME-Version: 1.0\\n\"\n\"Content-Type: text/plain; charset=utf-8\\n\"\n\"Content-Transfer-Encoding: 8bit\\n\"\n\"Generated-By: Babel 1.3\\n\"\n\n#: web_ui/config.html:7\nmsgid \"Public appids used by default\"\nmsgstr \"\"\n\n#: web_ui/config.html:10\nmsgid \"The public appids are disabled to access videos or download files.\"\nmsgstr \"\"\n\n#: web_ui/config.html:11 web_ui/deploy.html:14\nmsgid \"How to apply\"\nmsgstr \"\"\n\n#: web_ui/config.html:16\nmsgid \"Attention: inaccessable before appids are deployed.\"\nmsgstr \"\"\n\n#: web_ui/config.html:23 web_ui/deploy.html:43\nmsgid \"Advanced options\"\nmsgstr \"\"\n\n#: web_ui/config.html:29 web_ui/config.html:45 web_ui/deploy.html:49\n#: web_ui/scan_ip.html:10 web_ui/status.html:25 web_ui/status.html:33\nmsgid \"Help\"\nmsgstr \"\"\n\n#: web_ui/config.html:32\nmsgid \"Needless to configure generally\"\nmsgstr \"\"\n\n#: web_ui/config.html:37\nmsgid \"Enable IPv6(If it's available)\"\nmsgstr \"\"\n\n#: web_ui/config.html:45\nmsgid \"LAN proxy(Generally not needed)\"\nmsgstr \"\"\n\n#: web_ui/config.html:54\nmsgid \"Proxy type\"\nmsgstr \"\"\n\n#: web_ui/config.html:66\nmsgid \"Proxy IP address or domain name\"\nmsgstr \"\"\n\n#: web_ui/config.html:74\nmsgid \"Port\"\nmsgstr \"\"\n\n#: web_ui/config.html:82\nmsgid \"User name\"\nmsgstr \"\"\n\n#: web_ui/config.html:90\nmsgid \"Password\"\nmsgstr \"\"\n\n#: web_ui/config.html:100\nmsgid \"Save\"\nmsgstr \"\"\n\n#: web_ui/config.html:107\nmsgid \"Advanced tricks:\"\nmsgstr \"\"\n\n#: web_ui/config.html:107\nmsgid \"By the configuration file\"\nmsgstr \"\"\n\n#: web_ui/config.html:112\nmsgid \"Configure GAEProxy\"\nmsgstr \"\"\n\n#: web_ui/config.html:194\nmsgid \"Failed reading the seeting.\"\nmsgstr \"\"\n\n#: web_ui/config.html:239 web_ui/scan_ip.html:77 web_ui/scan_ip.html:148\n#: web_ui/scan_ip.html:170\nmsgid \"Settings saved successfully\"\nmsgstr \"\"\n\n#: web_ui/config.html:241\nmsgid \"Unkown error occurred.\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:1\nmsgid \"Deploy XX-Net onto GAE\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:3\nmsgid \"Current status: idle\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:6\nmsgid \"Authorization\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:7 web_ui/menu.yaml:25 web_ui/scan_ip.html:3\nmsgid \"Log\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:17\nmsgid \"Delimit multiple appids with |\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:35\nmsgid \"If the 2-step verification is in-use, please use your exclusive password.\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:35 web_ui/deploy.html:36\nmsgid \"Configure now\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:36\nmsgid \"\"\n\"If the 2-step verification is NOT in-use, please enable the less secure \"\n\"apps.\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:37\nmsgid \"Details\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:52\nmsgid \"Needless to fill generally\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:54\nmsgid \"\"\n\"If RC4 password is used, please configure it in the advanced settings \"\n\"while configuring GAE Proxy\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:61\nmsgid \"Start to deploy\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:65\nmsgid \"Redploy the server if XX-Net version is prior to 1.13.6.\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:170 web_ui/deploy.html:178 web_ui/deploy.html:184\n#: web_ui/deploy.html:190 web_ui/deploy.html:193 web_ui/deploy.html:200\n#: web_ui/deploy.html:205 web_ui/deploy.html:269 web_ui/deploy.html:272\nmsgid \"Current status: \"\nmsgstr \"\"\n\n#: web_ui/deploy.html:170\nmsgid \"XX-Net was reset.\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:178 web_ui/deploy.html:200\nmsgid \"Deployment completed. \"\nmsgstr \"\"\n\n#: web_ui/deploy.html:178\nmsgid \"Please go to \"\nmsgstr \"\"\n\n#: web_ui/deploy.html:178\nmsgid \"the configuration page \"\nmsgstr \"\"\n\n#: web_ui/deploy.html:178\nmsgid \"to set AppID to enable them.\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:184 web_ui/deploy.html:205 web_ui/deploy.html:272\nmsgid \"An exception occurred. \"\nmsgstr \"\"\n\n#: web_ui/deploy.html:184 web_ui/deploy.html:205 web_ui/deploy.html:272\nmsgid \"The exception info: \"\nmsgstr \"\"\n\n#: web_ui/deploy.html:190\nmsgid \"idle\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:193\nmsgid \"deploying ...\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:221 web_ui/deploy.html:231\nmsgid \"Start deploying\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:225 web_ui/deploy.html:233\nmsgid \"Terminate deploying\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:269\nmsgid \"Deployment cancelled.\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:282\nmsgid \"Either AppID is empty or invalid.\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:285\nmsgid \"Either your Email address is empty or invalid.\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:288\nmsgid \"Please fill in your account & its password.\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:4\nmsgid \"Task type\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:10\nmsgid \"Import\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:14\nmsgid \"Export\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:21\nmsgid \"Import/Export format\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:25\nmsgid \" format\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:26\nmsgid \"New line delimiter\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:27\nmsgid \"Intelligent regular matching\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:33\nmsgid \"IP address list\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:41\nmsgid \"Run\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:48\nmsgid \"IP Import/Export\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:90\nmsgid \"Trying to import \"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:90 web_ui/ipconfig.html:102 web_ui/ipconfig.html:119\nmsgid \" IP addresses.\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:102\nmsgid \"Succeeded importing \"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:105\nmsgid \"Failed importing IP addresses.\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:119\nmsgid \"Succeeded exporting \"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:125\nmsgid \"Failed exporting the IP addresses.\"\nmsgstr \"\"\n\n#: web_ui/logging.html:15\nmsgid \"GAEProxy Log\"\nmsgstr \"\"\n\n#: web_ui/menu.yaml:5 web_ui/status.html:7\nmsgid \"Status\"\nmsgstr \"\"\n\n#: web_ui/menu.yaml:9 web_ui/status.html:39\nmsgid \"Configuration\"\nmsgstr \"\"\n\n#: web_ui/menu.yaml:13\nmsgid \"Deploy Server\"\nmsgstr \"\"\n\n#: web_ui/menu.yaml:17\nmsgid \"Scan IP Addresses\"\nmsgstr \"\"\n\n#: web_ui/menu.yaml:21\nmsgid \"Import/Export IP Addresses\"\nmsgstr \"\"\n\n#: web_ui/scan_ip.html:2\nmsgid \"Settings\"\nmsgstr \"\"\n\n#: web_ui/scan_ip.html:10\nmsgid \"Auto-adjust scan thread count\"\nmsgstr \"\"\n\n#: web_ui/scan_ip.html:18\nmsgid \"Max scan thread count\"\nmsgstr \"\"\n\n#: web_ui/scan_ip.html:24\nmsgid \"Update\"\nmsgstr \"\"\n\n#: web_ui/scan_ip.html:29\nmsgid \"IP range list\"\nmsgstr \"\"\n\n#: web_ui/scan_ip.html:29\nmsgid \"Supporting formats\"\nmsgstr \"\"\n\n#: web_ui/scan_ip.html:37\nmsgid \"Submit\"\nmsgstr \"\"\n\n#: web_ui/scan_ip.html:46\nmsgid \"Refresh\"\nmsgstr \"\"\n\n#: web_ui/scan_ip.html:52\nmsgid \"IP scan settings(Needless to modify generally)\"\nmsgstr \"\"\n\n#: web_ui/scan_ip.html:99\nmsgid \"Failed reading the log\"\nmsgstr \"\"\n\n#: web_ui/scan_ip.html:120\nmsgid \"Failed reading the settings\"\nmsgstr \"\"\n\n#: web_ui/scan_ip.html:150 web_ui/scan_ip.html:172\nmsgid \"Unkown error occurred\"\nmsgstr \"\"\n\n#: web_ui/status.html:3\nmsgid \"Your browser is obsolete. Partial functionality will not be available.\"\nmsgstr \"\"\n\n#: web_ui/status.html:4\nmsgid \"The latest Chrome browser is recommended.\"\nmsgstr \"\"\n\n#: web_ui/status.html:91\nmsgid \"System Version\"\nmsgstr \"\"\n\n#: web_ui/status.html:142\nmsgid \"Feedback\"\nmsgstr \"\"\n\n#: web_ui/status.html:147\nmsgid \"Diagnostic Info\"\nmsgstr \"\"\n\n#: web_ui/status.html:150\nmsgid \"The one-key feedback needs to sign in your Github account\"\nmsgstr \"\"\n\n#: web_ui/status.html:154\nmsgid \"To Google Groups\"\nmsgstr \"\"\n\n#: web_ui/status.html:155\nmsgid \"One-key feedback\"\nmsgstr \"\"\n\n#: web_ui/status.html:161\nmsgid \"GAE Proxy Status Info\"\nmsgstr \"\"\n\n#: web_ui/status.html:274\nmsgid \"\"\n\"The status page is empty. Highly likely that GAEProxy failed getting \"\n\"started. Please follow \"\nmsgstr \"\"\n\n#: web_ui/status.html:274\nmsgid \"guide \"\nmsgstr \"\"\n\n#: web_ui/status.html:274\nmsgid \"to troubleshoot.\"\nmsgstr \"\"\n\n#: web_ui/status.html:276\nmsgid \"No response from GAEProxy process. It might have already exited.\"\nmsgstr \"\"\n\n"
  },
  {
    "path": "code/default/gae_proxy/lang/es_VE/LC_MESSAGES/messages.po",
    "content": "# Spanish (Venezuela) translations for PROJECT.\n# Copyright (C) 2015 ORGANIZATION\n# This file is distributed under the same license as the PROJECT project.\n# FIRST AUTHOR <EMAIL@ADDRESS>, 2015.\n#\n#, fuzzy\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: PROJECT VERSION\\n\"\n\"Report-Msgid-Bugs-To: EMAIL@ADDRESS\\n\"\n\"POT-Creation-Date: 2015-12-14 07:04+0800\\n\"\n\"PO-Revision-Date: 2015-12-06 09:27+0800\\n\"\n\"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n\"\n\"Language-Team: es_VE <LL@li.org>\\n\"\n\"Plural-Forms: nplurals=2; plural=(n != 1)\\n\"\n\"MIME-Version: 1.0\\n\"\n\"Content-Type: text/plain; charset=utf-8\\n\"\n\"Content-Transfer-Encoding: 8bit\\n\"\n\"Generated-By: Babel 1.3\\n\"\n\n#: web_ui/config.html:7\nmsgid \"Public appids used by default\"\nmsgstr \"\"\n\n#: web_ui/config.html:10\nmsgid \"The public appids are disabled to access videos or download files.\"\nmsgstr \"\"\n\n#: web_ui/config.html:11 web_ui/deploy.html:14\nmsgid \"How to apply\"\nmsgstr \"\"\n\n#: web_ui/config.html:16\nmsgid \"Attention: inaccessable before appids are deployed.\"\nmsgstr \"\"\n\n#: web_ui/config.html:23 web_ui/deploy.html:43\nmsgid \"Advanced options\"\nmsgstr \"\"\n\n#: web_ui/config.html:29 web_ui/config.html:45 web_ui/deploy.html:49\n#: web_ui/scan_ip.html:10 web_ui/status.html:25 web_ui/status.html:33\nmsgid \"Help\"\nmsgstr \"\"\n\n#: web_ui/config.html:32\nmsgid \"Needless to configure generally\"\nmsgstr \"\"\n\n#: web_ui/config.html:37\nmsgid \"Enable IPv6(If it's available)\"\nmsgstr \"\"\n\n#: web_ui/config.html:45\nmsgid \"LAN proxy(Generally not needed)\"\nmsgstr \"\"\n\n#: web_ui/config.html:54\nmsgid \"Proxy type\"\nmsgstr \"\"\n\n#: web_ui/config.html:66\nmsgid \"Proxy IP address or domain name\"\nmsgstr \"\"\n\n#: web_ui/config.html:74\nmsgid \"Port\"\nmsgstr \"\"\n\n#: web_ui/config.html:82\nmsgid \"User name\"\nmsgstr \"\"\n\n#: web_ui/config.html:90\nmsgid \"Password\"\nmsgstr \"\"\n\n#: web_ui/config.html:100\nmsgid \"Save\"\nmsgstr \"\"\n\n#: web_ui/config.html:107\nmsgid \"Advanced tricks:\"\nmsgstr \"\"\n\n#: web_ui/config.html:107\nmsgid \"By the configuration file\"\nmsgstr \"\"\n\n#: web_ui/config.html:112\nmsgid \"Configure GAEProxy\"\nmsgstr \"\"\n\n#: web_ui/config.html:194\nmsgid \"Failed reading the seeting.\"\nmsgstr \"\"\n\n#: web_ui/config.html:239 web_ui/scan_ip.html:77 web_ui/scan_ip.html:148\n#: web_ui/scan_ip.html:170\nmsgid \"Settings saved successfully\"\nmsgstr \"\"\n\n#: web_ui/config.html:241\nmsgid \"Unkown error occurred.\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:1\nmsgid \"Deploy XX-Net onto GAE\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:3\nmsgid \"Current status: idle\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:6\nmsgid \"Authorization\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:7 web_ui/menu.yaml:25 web_ui/scan_ip.html:3\nmsgid \"Log\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:17\nmsgid \"Delimit multiple appids with |\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:35\nmsgid \"If the 2-step verification is in-use, please use your exclusive password.\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:35 web_ui/deploy.html:36\nmsgid \"Configure now\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:36\nmsgid \"\"\n\"If the 2-step verification is NOT in-use, please enable the less secure \"\n\"apps.\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:37\nmsgid \"Details\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:52\nmsgid \"Needless to fill generally\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:54\nmsgid \"\"\n\"If RC4 password is used, please configure it in the advanced settings \"\n\"while configuring GAE Proxy\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:61\nmsgid \"Start to deploy\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:65\nmsgid \"Redploy the server if XX-Net version is prior to 1.13.6.\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:170 web_ui/deploy.html:178 web_ui/deploy.html:184\n#: web_ui/deploy.html:190 web_ui/deploy.html:193 web_ui/deploy.html:200\n#: web_ui/deploy.html:205 web_ui/deploy.html:269 web_ui/deploy.html:272\nmsgid \"Current status: \"\nmsgstr \"\"\n\n#: web_ui/deploy.html:170\nmsgid \"XX-Net was reset.\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:178 web_ui/deploy.html:200\nmsgid \"Deployment completed. \"\nmsgstr \"\"\n\n#: web_ui/deploy.html:178\nmsgid \"Please go to \"\nmsgstr \"\"\n\n#: web_ui/deploy.html:178\nmsgid \"the configuration page \"\nmsgstr \"\"\n\n#: web_ui/deploy.html:178\nmsgid \"to set AppID to enable them.\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:184 web_ui/deploy.html:205 web_ui/deploy.html:272\nmsgid \"An exception occurred. \"\nmsgstr \"\"\n\n#: web_ui/deploy.html:184 web_ui/deploy.html:205 web_ui/deploy.html:272\nmsgid \"The exception info: \"\nmsgstr \"\"\n\n#: web_ui/deploy.html:190\nmsgid \"idle\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:193\nmsgid \"deploying ...\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:221 web_ui/deploy.html:231\nmsgid \"Start deploying\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:225 web_ui/deploy.html:233\nmsgid \"Terminate deploying\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:269\nmsgid \"Deployment cancelled.\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:282\nmsgid \"Either AppID is empty or invalid.\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:285\nmsgid \"Either your Email address is empty or invalid.\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:288\nmsgid \"Please fill in your account & its password.\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:4\nmsgid \"Task type\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:10\nmsgid \"Import\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:14\nmsgid \"Export\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:21\nmsgid \"Import/Export format\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:25\nmsgid \" format\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:26\nmsgid \"New line delimiter\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:27\nmsgid \"Intelligent regular matching\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:33\nmsgid \"IP address list\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:41\nmsgid \"Run\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:48\nmsgid \"IP Import/Export\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:90\nmsgid \"Trying to import \"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:90 web_ui/ipconfig.html:102 web_ui/ipconfig.html:119\nmsgid \" IP addresses.\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:102\nmsgid \"Succeeded importing \"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:105\nmsgid \"Failed importing IP addresses.\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:119\nmsgid \"Succeeded exporting \"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:125\nmsgid \"Failed exporting the IP addresses.\"\nmsgstr \"\"\n\n#: web_ui/logging.html:15\nmsgid \"GAEProxy Log\"\nmsgstr \"\"\n\n#: web_ui/menu.yaml:5 web_ui/status.html:7\nmsgid \"Status\"\nmsgstr \"\"\n\n#: web_ui/menu.yaml:9 web_ui/status.html:39\nmsgid \"Configuration\"\nmsgstr \"\"\n\n#: web_ui/menu.yaml:13\nmsgid \"Deploy Server\"\nmsgstr \"\"\n\n#: web_ui/menu.yaml:17\nmsgid \"Scan IP Addresses\"\nmsgstr \"\"\n\n#: web_ui/menu.yaml:21\nmsgid \"Import/Export IP Addresses\"\nmsgstr \"\"\n\n#: web_ui/scan_ip.html:2\nmsgid \"Settings\"\nmsgstr \"\"\n\n#: web_ui/scan_ip.html:10\nmsgid \"Auto-adjust scan thread count\"\nmsgstr \"\"\n\n#: web_ui/scan_ip.html:18\nmsgid \"Max scan thread count\"\nmsgstr \"\"\n\n#: web_ui/scan_ip.html:24\nmsgid \"Update\"\nmsgstr \"\"\n\n#: web_ui/scan_ip.html:29\nmsgid \"IP range list\"\nmsgstr \"\"\n\n#: web_ui/scan_ip.html:29\nmsgid \"Supporting formats\"\nmsgstr \"\"\n\n#: web_ui/scan_ip.html:37\nmsgid \"Submit\"\nmsgstr \"\"\n\n#: web_ui/scan_ip.html:46\nmsgid \"Refresh\"\nmsgstr \"\"\n\n#: web_ui/scan_ip.html:52\nmsgid \"IP scan settings(Needless to modify generally)\"\nmsgstr \"\"\n\n#: web_ui/scan_ip.html:99\nmsgid \"Failed reading the log\"\nmsgstr \"\"\n\n#: web_ui/scan_ip.html:120\nmsgid \"Failed reading the settings\"\nmsgstr \"\"\n\n#: web_ui/scan_ip.html:150 web_ui/scan_ip.html:172\nmsgid \"Unkown error occurred\"\nmsgstr \"\"\n\n#: web_ui/status.html:3\nmsgid \"Your browser is obsolete. Partial functionality will not be available.\"\nmsgstr \"\"\n\n#: web_ui/status.html:4\nmsgid \"The latest Chrome browser is recommended.\"\nmsgstr \"\"\n\n#: web_ui/status.html:91\nmsgid \"System Version\"\nmsgstr \"\"\n\n#: web_ui/status.html:142\nmsgid \"Feedback\"\nmsgstr \"\"\n\n#: web_ui/status.html:147\nmsgid \"Diagnostic Info\"\nmsgstr \"\"\n\n#: web_ui/status.html:150\nmsgid \"The one-key feedback needs to sign in your Github account\"\nmsgstr \"\"\n\n#: web_ui/status.html:154\nmsgid \"To Google Groups\"\nmsgstr \"\"\n\n#: web_ui/status.html:155\nmsgid \"One-key feedback\"\nmsgstr \"\"\n\n#: web_ui/status.html:161\nmsgid \"GAE Proxy Status Info\"\nmsgstr \"\"\n\n#: web_ui/status.html:274\nmsgid \"\"\n\"The status page is empty. Highly likely that GAEProxy failed getting \"\n\"started. Please follow \"\nmsgstr \"\"\n\n#: web_ui/status.html:274\nmsgid \"guide \"\nmsgstr \"\"\n\n#: web_ui/status.html:274\nmsgid \"to troubleshoot.\"\nmsgstr \"\"\n\n#: web_ui/status.html:276\nmsgid \"No response from GAEProxy process. It might have already exited.\"\nmsgstr \"\"\n\n#~ msgid \"GAEProxy Status Info\"\n#~ msgstr \"\"\n\n"
  },
  {
    "path": "code/default/gae_proxy/lang/fa_IR/LC_MESSAGES/messages.po",
    "content": "\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: PROJECT VERSION\\n\"\n\"Report-Msgid-Bugs-To: EMAIL@ADDRESS\\n\"\n\"POT-Creation-Date: 2017-11-15 08:26+0800\\n\"\n\"PO-Revision-Date: 2015-12-06 09:14+0800\\n\"\n\"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n\"\n\"Language: fa_IR\\n\"\n\"Language-Team: fa_IR <LL@li.org>\\n\"\n\"Plural-Forms: nplurals=1; plural=0\\n\"\n\"MIME-Version: 1.0\\n\"\n\"Content-Type: text/plain; charset=utf-8\\n\"\n\"Content-Transfer-Encoding: 8bit\\n\"\n\"Generated-By: Babel 2.3.4\\n\"\n\nmsgid \"Scan Settings\"\nmsgstr \"تنظیمات اسکن\"\n\nmsgid \"Scan Log\"\nmsgstr \"اسکن ورود\"\n\nmsgid \"Import IP\"\nmsgstr \"واردات IP\"\n\nmsgid \"Export IP\"\nmsgstr \"صادرات IP\"\n\nmsgid \"Check IP\"\nmsgstr \"بررسی IP\"\n\nmsgid \"IPv6 Tunnel\"\nmsgstr \"\"\n\nmsgid \"Advanced\"\nmsgstr \"پیشرفته\"\n\nmsgid \"Your browser is obsolete. Partial functionality will not be available.\"\nmsgstr \"مرورگر شما قدیمی است. قابلیت جزئی در دسترس نخواهد بود.\"\n\nmsgid \"The latest Chrome browser is recommended.\"\nmsgstr \"آخرین مرورگر کروم توصیه می شود.\"\n\nmsgid \"Status\"\nmsgstr \"وضعیت\"\n\nmsgid \"Property\"\nmsgstr \"ویژگی\"\n\nmsgid \"Value\"\nmsgstr \"ارزش\"\n\nmsgid \"All IP Number\"\nmsgstr \"همه شماره IP\"\n\nmsgid \"Left Number\"\nmsgstr \"عدد سمت چپ\"\n\nmsgid \"Good IP Number\"\nmsgstr \"خوب شماره IP\"\n\nmsgid \"Run\"\nmsgstr \"اجرا\"\n\nmsgid \"No response from GAEProxy process. It might have already exited.\"\nmsgstr \"هیچ پاسخی از روند GAEProxy. این ممکن است در حال حاضر خارج می شود.\"\n\nmsgid \"Stop\"\nmsgstr \"متوقف کردن\"\n\nmsgid \"Public appids used by default\"\nmsgstr \"appids عمومی استفاده می شود به طور پیش فرض\"\n\nmsgid \"The public appids are disabled to access videos or download files.\"\nmsgstr \"\"\n\"appids عمومی را غیرفعال برای دسترسی به فیلم ها و یا فایل های دانلود می \"\n\"باشد.\"\n\nmsgid \"How to apply\"\nmsgstr \"چگونه به درخواست\"\n\nmsgid \"Attention: inaccessable before appids are deployed.\"\nmsgstr \"توجه: غیر قابل دسترس قبل از appids مستقر هستند.\"\n\nmsgid \"Advanced options\"\nmsgstr \"گزینه های پیشرفته\"\n\nmsgid \"LAN proxy(Generally not needed)\"\nmsgstr \"پروکسی LAN (به طور کلی مورد نیاز نیست)\"\n\nmsgid \"Help\"\nmsgstr \"کمک\"\n\nmsgid \"Proxy type\"\nmsgstr \"نوع پروکسی\"\n\nmsgid \"Proxy IP address or domain name\"\nmsgstr \"آدرس IP پروکسی و یا نام دامنه\"\n\nmsgid \"Port\"\nmsgstr \"درگاه\"\n\nmsgid \"User name\"\nmsgstr \"نام کاربری\"\n\nmsgid \"Password\"\nmsgstr \"رمز عبور\"\n\nmsgid \"Save\"\nmsgstr \"ذخیره\"\n\nmsgid \"Advanced tricks:\"\nmsgstr \"ترفندهای پیشرفته:\"\n\nmsgid \"By the configuration file\"\nmsgstr \"توسط فایل پیکربندی\"\n\nmsgid \"Configure GAEProxy\"\nmsgstr \"پیکربندی GAEProxy\"\n\nmsgid \"Failed reading the settings.\"\nmsgstr \"خواندن تنظیمات انجام نشد.\"\n\nmsgid \"Wait for checking setting...\"\nmsgstr \"صبر کنید برای چک کردن تنظیمات ...\"\n\nmsgid \"Settings saved successfully\"\nmsgstr \"تنظیمات با موفقیت ذخیره\"\n\nmsgid \"AppID invalid:\"\nmsgstr \"_AppID_ نامعتبر است:\"\n\nmsgid \", deploy appid before using.\"\nmsgstr \"، استقرار APPID قبل از استفاده.\"\n\nmsgid \"Failed saving settings\"\nmsgstr \"خواندن تنظیمات انجام نشد.\"\n\nmsgid \"Deploy XX-Net onto GAE\"\nmsgstr \"استقرار _XX-Net_ بر روی GAE\"\n\nmsgid \"Current status: \"\nmsgstr \"وضعیت فعلی:\"\n\nmsgid \"idle\"\nmsgstr \"آماده به کار\"\n\nmsgid \"Authorization\"\nmsgstr \"اجازه\"\n\nmsgid \"Log\"\nmsgstr \"ورود\"\n\nmsgid \"Delimit multiple appids with |\"\nmsgstr \"محدود appids های متعدد را با |\"\n\nmsgid \"Show Debug Log\"\nmsgstr \"\"\n\nmsgid \"Start to deploy\"\nmsgstr \"شروع به استقرار\"\n\nmsgid \"Auth window will popup, make sure don't block popup in browser.\"\nmsgstr \"\"\n\nmsgid \"XX-Net was reset.\"\nmsgstr \"_XX-Net_ بازنشانی شد.\"\n\nmsgid \"Deployment completed. \"\nmsgstr \"استقرار تکمیل شده است. \"\n\nmsgid \"Please go to \"\nmsgstr \"لطفا رفتن به \"\n\nmsgid \"the configuration page \"\nmsgstr \"صفحه تنظیمات \"\n\nmsgid \"to set AppID to enable them.\"\nmsgstr \"به مجموعه ای از _AppID_ به آنها را فعال کنید.\"\n\nmsgid \"An exception occurred. \"\nmsgstr \"یک استثنا رخ داده است. \"\n\nmsgid \"The exception info: \"\nmsgstr \"اطلاعات استثنا:\"\n\nmsgid \"deploying ...\"\nmsgstr \"استقرار ...\"\n\nmsgid \"Terminate deploying\"\nmsgstr \"خاتمه استقرار\"\n\nmsgid \"Deployment cancelled.\"\nmsgstr \"استقرار لغو شده است.\"\n\nmsgid \"Your AppID is either empty or invalid.\"\nmsgstr \"_AppID_ خود را به صورت خالی و یا نامعتبر است.\"\n\nmsgid \"Export format\"\nmsgstr \"فرمت صادرات\"\n\nmsgid \" format\"\nmsgstr \"قالب \"\n\nmsgid \"New line delimiter\"\nmsgstr \"ذخیره خط جدید\"\n\nmsgid \"IP address list\"\nmsgstr \"لیست آدرس IP\"\n\nmsgid \"Succeeded exporting \"\nmsgstr \"موفق صادرات \"\n\nmsgid \" IP addresses.\"\nmsgstr \" آدرس IP است.\"\n\nmsgid \"Failed exporting the IP addresses.\"\nmsgstr \"صادرات آدرس IP شکست خورده است.\"\n\nmsgid \"IP list\"\nmsgstr \"لیست IP\"\n\nmsgid \"Enable\"\nmsgstr \"\"\n\nmsgid \"Disable\"\nmsgstr \"\"\n\nmsgid \"Running ...\"\nmsgstr \"\"\n\nmsgid \"GAEProxy Log\"\nmsgstr \"GAEProxy ورود\"\n\nmsgid \"Configuration\"\nmsgstr \"پیکربندی\"\n\nmsgid \"Deploy Server\"\nmsgstr \"استقرار سرور\"\n\nmsgid \"Refresh\"\nmsgstr \"تازه کردن\"\n\nmsgid \"Failed reading the log\"\nmsgstr \"خواندن ورود به سیستم شکست خورده\"\n\nmsgid \"Auto-adjust scan thread count\"\nmsgstr \"خودکار تنظیم تعداد موضوع اسکن\"\n\nmsgid \"Max scan thread count\"\nmsgstr \"حداکثر تعداد موضوع اسکن\"\n\nmsgid \"Enable IPv6(If it's available)\"\nmsgstr \"فعال کردن IPv6 را (سرنت تنها)\"\n\nmsgid \"AUTO\"\nmsgstr \"\"\n\nmsgid \"Force IPv4\"\nmsgstr \"\"\n\nmsgid \"Force IPv6\"\nmsgstr \"\"\n\nmsgid \"IP range list\"\nmsgstr \"لیست محدوده IP\"\n\nmsgid \"Supporting formats\"\nmsgstr \"حمایت از فرمت های\"\n\nmsgid \"Submit\"\nmsgstr \"ارسال\"\n\nmsgid \"Failed reading the settings\"\nmsgstr \"خواندن تنظیمات انجام نشد\"\n\nmsgid \"Unkown error occurred\"\nmsgstr \"خطای ناشناخته رخ داده\"\n\nmsgid \"IPv4 Status\"\nmsgstr \"\"\n\nmsgid \"IPv6 Status\"\nmsgstr \"\"\n\nmsgid \"IPv4 Number\"\nmsgstr \"\"\n\nmsgid \"IPv6 Number\"\nmsgstr \"\"\n\nmsgid \"Is Idle\"\nmsgstr \"آماده به کار\"\n\nmsgid \"IP Quality\"\nmsgstr \"IP کیفیت\"\n\nmsgid \"Connection Pool\"\nmsgstr \"وضعیت اتصال\"\n\nmsgid \"Browser Proxy Setting\"\nmsgstr \"مرورگر تنظیم پروکسی\"\n\nmsgid \"CA status\"\nmsgstr \"وضعیت CA\"\n\nmsgid \"Download\"\nmsgstr \"دانلود\"\n\nmsgid \"Number of IP-Scanning Threads\"\nmsgstr \"تعداد IP-اسکن موضوعات\"\n\nmsgid \"Settings\"\nmsgstr \"تنظیمات\"\n\nmsgid \"Block Status\"\nmsgstr \"وضعیت بلوک\"\n\nmsgid \"XX-Net Version\"\nmsgstr \"_XX-Net_ نسخه\"\n\nmsgid \"System Proxy Status\"\nmsgstr \"_XX-Net_ نسخه\"\n\nmsgid \"Listening Proxy\"\nmsgstr \"گوش دادن پروکسی\"\n\nmsgid \"PAC URL\"\nmsgstr \"\"\n\nmsgid \"USE IPv6\"\nmsgstr \"\"\n\nmsgid \"Working AppIDs\"\nmsgstr \"بدون APPID کارگر. لطفا بررسی کنید. \"\n\nmsgid \"Out-of-quota AppIDs\"\nmsgstr \"خارج از سهمیه AppIDs\"\n\nmsgid \"Nonexistent AppIDs\"\nmsgstr \"AppIDs وجود ندارد\"\n\nmsgid \"System Version\"\nmsgstr \"نسخه سیستم\"\n\nmsgid \"Diagnostic Info\"\nmsgstr \"اطلاعات تشخیصی\"\n\nmsgid \"Check Github issues\"\nmsgstr \"بررسی مسائل _Github_\"\n\nmsgid \" or \"\nmsgstr \" یا \"\n\nmsgid \" Discussions\"\nmsgstr \"بحث\"\n\nmsgid \"Show Details\"\nmsgstr \"نمایش جزئیات\"\n\nmsgid \"Post to Github issue needs to sign in your Github account\"\nmsgstr \"بازخورد یک کلید نیاز به ثبت نام در حساب github خود را\"\n\nmsgid \"GAE Proxy Status Info\"\nmsgstr \"GAE پروکسی وضعیت\"\n\nmsgid \"\"\n\"-----------%0AProblem Description:%0APlease describe your problem, \"\n\"running logs may be needed.%0A%0A-----------%0ADiagnostic information:%0A\"\nmsgstr \"\"\n\nmsgid \"\"\n\"The status page is empty. Highly likely that GAEProxy failed getting \"\n\"started. Please follow \"\nmsgstr \"\"\n\"صفحه وضعیت خالی است. بسیار محتمل است که GAEProxy شروع کار شکست خورده است.\"\n\" لطفا دنبال کنید\"\n\nmsgid \"guide \"\nmsgstr \"راهنما\"\n\nmsgid \"to troubleshoot.\"\nmsgstr \"به عیب یابی.\"\n\nmsgid \"Your local network failed. Please check your network and firewall. \"\nmsgstr \"شبکه محلی شما را شکست خورده است. لطفا شبکه و فایروال خود را چک کنید.\"\n\nmsgid \"You may want to $1turn on IP scaner$2.\"\nmsgstr \"\"\n\nmsgid \"\"\n\"You can try <a href=\\\"https://github.com/XX-net/XX-Net/wiki/How-to-turn-\"\n\"on-IPv6\\\">turn on IPv6</a> or <a href=\\\"https://github.com/XX-net/XX-\"\n\"Net/wiki/How-to-use-XTunnel\\\">use X-Tunnel</a>\"\nmsgstr \"\"\n\nmsgid \"XX-Net is scanning IP. Please wait about half an hour.\"\nmsgstr \"_XX-Net_ اسکن است. لطفا صبر کنید.\"\n\nmsgid \"\"\n\"Public appid out of quota, Please <a href=\\\"https://github.com/XX-net/XX-\"\n\"Net/wiki/Register-Google-appid\\\" target=\\\"_blank\\\">deploy your own \"\n\"APPID</a>\"\nmsgstr \"\"\n\nmsgid \"\"\n\"Your appid out of quota, Please <a href=\\\"https://github.com/XX-net/XX-\"\n\"Net/wiki/Register-Google-appid\\\" target=\\\"_blank\\\">deploy more APPID</a>\"\nmsgstr \"\"\n\nmsgid \"No working appid. Please check. \"\nmsgstr \"بدون APPID کارگر. لطفا بررسی کنید. \"\n\nmsgid \"System is Idle. \"\nmsgstr \"\"\n\nmsgid \"Connection not established yet. \"\nmsgstr \"اتصال برقرار نشده است\"\n\nmsgid \"Please check your browser proxy setting.\"\nmsgstr \"لطفا تنظیمات پروکسی مرورگر خود را بررسی کنید.\"\n\nmsgid \"Detecting...\"\nmsgstr \"استقرار ...\"\n\nmsgid \"Please import certificates to your browser.\"\nmsgstr \"لطفا مرورگر خود را به گواهی وارد کنید.\"\n\nmsgid \"\"\n\"You are using public APPID. You are recommended to <a \"\n\"href=\\\"https://github.com/XX-net/XX-Net/wiki/Register-Google-appid\\\" \"\n\"target=\\\"_blank\\\">deploy your own APPID</a>\"\nmsgstr \"\"\n\nmsgid \", Everything is OK. Welcome to the FREE Internet. \"\nmsgstr \"، همه چی خوبه. به اینترنت خوش آمدید. \"\n\nmsgid \"\"\n\"The status page is empty. Highly likely that XX-Net failed getting \"\n\"started. Please follow \"\nmsgstr \"\"\n\"صفحه وضعیت خالی است. بسیار محتمل است که GAEProxy شروع کار شکست خورده است.\"\n\" لطفا دنبال کنید\"\n\nmsgid \"No response from process. It might have already exited.\"\nmsgstr \"هیچ پاسخی از روند GAEProxy. این ممکن است در حال حاضر خارج می شود.\"\n\nmsgid \"You are using the public Appid.\"\nmsgstr \"شما با استفاده از شناسه های عمومی است.\"\n\nmsgid \"new:\"\nmsgstr \"\"\n\nmsgid \" h1:\"\nmsgstr \"\"\n\nmsgid \" h2:\"\nmsgstr \"\"\n\nmsgid \"Auto proxy enabled at \"\nmsgstr \"پروکسی خودکار را فعال کنید در\"\n\nmsgid \"Proxy enabled at \"\nmsgstr \"پروکسی را فعال کنید در \"\n\nmsgid \"Proxy disabled\"\nmsgstr \"پروکسی غیرفعال\"\n\n\n\n\n\n\n"
  },
  {
    "path": "code/default/gae_proxy/lang/ja_JP/LC_MESSAGES/messages.po",
    "content": "# Japanese (Japan) translations for PROJECT.\n# Copyright (C) 2015 ORGANIZATION\n# This file is distributed under the same license as the PROJECT project.\n# FIRST AUTHOR <EMAIL@ADDRESS>, 2015.\n#\n#, fuzzy\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: PROJECT VERSION\\n\"\n\"Report-Msgid-Bugs-To: EMAIL@ADDRESS\\n\"\n\"POT-Creation-Date: 2015-12-14 07:04+0800\\n\"\n\"PO-Revision-Date: 2015-12-06 09:22+0800\\n\"\n\"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n\"\n\"Language-Team: ja_JP <LL@li.org>\\n\"\n\"Plural-Forms: nplurals=1; plural=0\\n\"\n\"MIME-Version: 1.0\\n\"\n\"Content-Type: text/plain; charset=utf-8\\n\"\n\"Content-Transfer-Encoding: 8bit\\n\"\n\"Generated-By: Babel 1.3\\n\"\n\n#: web_ui/config.html:7\nmsgid \"Public appids used by default\"\nmsgstr \"\"\n\n#: web_ui/config.html:10\nmsgid \"The public appids are disabled to access videos or download files.\"\nmsgstr \"\"\n\n#: web_ui/config.html:11 web_ui/deploy.html:14\nmsgid \"How to apply\"\nmsgstr \"\"\n\n#: web_ui/config.html:16\nmsgid \"Attention: inaccessable before appids are deployed.\"\nmsgstr \"\"\n\n#: web_ui/config.html:23 web_ui/deploy.html:43\nmsgid \"Advanced options\"\nmsgstr \"\"\n\n#: web_ui/config.html:29 web_ui/config.html:45 web_ui/deploy.html:49\n#: web_ui/scan_ip.html:10 web_ui/status.html:25 web_ui/status.html:33\nmsgid \"Help\"\nmsgstr \"\"\n\n#: web_ui/config.html:32\nmsgid \"Needless to configure generally\"\nmsgstr \"\"\n\n#: web_ui/config.html:37\nmsgid \"Enable IPv6(If it's available)\"\nmsgstr \"\"\n\n#: web_ui/config.html:45\nmsgid \"LAN proxy(Generally not needed)\"\nmsgstr \"\"\n\n#: web_ui/config.html:54\nmsgid \"Proxy type\"\nmsgstr \"\"\n\n#: web_ui/config.html:66\nmsgid \"Proxy IP address or domain name\"\nmsgstr \"\"\n\n#: web_ui/config.html:74\nmsgid \"Port\"\nmsgstr \"\"\n\n#: web_ui/config.html:82\nmsgid \"User name\"\nmsgstr \"\"\n\n#: web_ui/config.html:90\nmsgid \"Password\"\nmsgstr \"\"\n\n#: web_ui/config.html:100\nmsgid \"Save\"\nmsgstr \"\"\n\n#: web_ui/config.html:107\nmsgid \"Advanced tricks:\"\nmsgstr \"\"\n\n#: web_ui/config.html:107\nmsgid \"By the configuration file\"\nmsgstr \"\"\n\n#: web_ui/config.html:112\nmsgid \"Configure GAEProxy\"\nmsgstr \"\"\n\n#: web_ui/config.html:194\nmsgid \"Failed reading the seeting.\"\nmsgstr \"\"\n\n#: web_ui/config.html:239 web_ui/scan_ip.html:77 web_ui/scan_ip.html:148\n#: web_ui/scan_ip.html:170\nmsgid \"Settings saved successfully\"\nmsgstr \"\"\n\n#: web_ui/config.html:241\nmsgid \"Unkown error occurred.\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:1\nmsgid \"Deploy XX-Net onto GAE\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:3\nmsgid \"Current status: idle\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:6\nmsgid \"Authorization\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:7 web_ui/menu.yaml:25 web_ui/scan_ip.html:3\nmsgid \"Log\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:17\nmsgid \"Delimit multiple appids with |\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:35\nmsgid \"If the 2-step verification is in-use, please use your exclusive password.\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:35 web_ui/deploy.html:36\nmsgid \"Configure now\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:36\nmsgid \"\"\n\"If the 2-step verification is NOT in-use, please enable the less secure \"\n\"apps.\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:37\nmsgid \"Details\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:52\nmsgid \"Needless to fill generally\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:54\nmsgid \"\"\n\"If RC4 password is used, please configure it in the advanced settings \"\n\"while configuring GAE Proxy\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:61\nmsgid \"Start to deploy\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:65\nmsgid \"Redploy the server if XX-Net version is prior to 1.13.6.\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:170 web_ui/deploy.html:178 web_ui/deploy.html:184\n#: web_ui/deploy.html:190 web_ui/deploy.html:193 web_ui/deploy.html:200\n#: web_ui/deploy.html:205 web_ui/deploy.html:269 web_ui/deploy.html:272\nmsgid \"Current status: \"\nmsgstr \"\"\n\n#: web_ui/deploy.html:170\nmsgid \"XX-Net was reset.\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:178 web_ui/deploy.html:200\nmsgid \"Deployment completed. \"\nmsgstr \"\"\n\n#: web_ui/deploy.html:178\nmsgid \"Please go to \"\nmsgstr \"\"\n\n#: web_ui/deploy.html:178\nmsgid \"the configuration page \"\nmsgstr \"\"\n\n#: web_ui/deploy.html:178\nmsgid \"to set AppID to enable them.\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:184 web_ui/deploy.html:205 web_ui/deploy.html:272\nmsgid \"An exception occurred. \"\nmsgstr \"\"\n\n#: web_ui/deploy.html:184 web_ui/deploy.html:205 web_ui/deploy.html:272\nmsgid \"The exception info: \"\nmsgstr \"\"\n\n#: web_ui/deploy.html:190\nmsgid \"idle\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:193\nmsgid \"deploying ...\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:221 web_ui/deploy.html:231\nmsgid \"Start deploying\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:225 web_ui/deploy.html:233\nmsgid \"Terminate deploying\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:269\nmsgid \"Deployment cancelled.\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:282\nmsgid \"Either AppID is empty or invalid.\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:285\nmsgid \"Either your Email address is empty or invalid.\"\nmsgstr \"\"\n\n#: web_ui/deploy.html:288\nmsgid \"Please fill in your account & its password.\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:4\nmsgid \"Task type\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:10\nmsgid \"Import\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:14\nmsgid \"Export\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:21\nmsgid \"Import/Export format\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:25\nmsgid \" format\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:26\nmsgid \"New line delimiter\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:27\nmsgid \"Intelligent regular matching\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:33\nmsgid \"IP address list\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:41\nmsgid \"Run\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:48\nmsgid \"IP Import/Export\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:90\nmsgid \"Trying to import \"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:90 web_ui/ipconfig.html:102 web_ui/ipconfig.html:119\nmsgid \" IP addresses.\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:102\nmsgid \"Succeeded importing \"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:105\nmsgid \"Failed importing IP addresses.\"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:119\nmsgid \"Succeeded exporting \"\nmsgstr \"\"\n\n#: web_ui/ipconfig.html:125\nmsgid \"Failed exporting the IP addresses.\"\nmsgstr \"\"\n\n#: web_ui/logging.html:15\nmsgid \"GAEProxy Log\"\nmsgstr \"\"\n\n#: web_ui/menu.yaml:5 web_ui/status.html:7\nmsgid \"Status\"\nmsgstr \"\"\n\n#: web_ui/menu.yaml:9 web_ui/status.html:39\nmsgid \"Configuration\"\nmsgstr \"\"\n\n#: web_ui/menu.yaml:13\nmsgid \"Deploy Server\"\nmsgstr \"\"\n\n#: web_ui/menu.yaml:17\nmsgid \"Scan IP Addresses\"\nmsgstr \"\"\n\n#: web_ui/menu.yaml:21\nmsgid \"Import/Export IP Addresses\"\nmsgstr \"\"\n\n#: web_ui/scan_ip.html:2\nmsgid \"Settings\"\nmsgstr \"\"\n\n#: web_ui/scan_ip.html:10\nmsgid \"Auto-adjust scan thread count\"\nmsgstr \"\"\n\n#: web_ui/scan_ip.html:18\nmsgid \"Max scan thread count\"\nmsgstr \"\"\n\n#: web_ui/scan_ip.html:24\nmsgid \"Update\"\nmsgstr \"\"\n\n#: web_ui/scan_ip.html:29\nmsgid \"IP range list\"\nmsgstr \"\"\n\n#: web_ui/scan_ip.html:29\nmsgid \"Supporting formats\"\nmsgstr \"\"\n\n#: web_ui/scan_ip.html:37\nmsgid \"Submit\"\nmsgstr \"\"\n\n#: web_ui/scan_ip.html:46\nmsgid \"Refresh\"\nmsgstr \"\"\n\n#: web_ui/scan_ip.html:52\nmsgid \"IP scan settings(Needless to modify generally)\"\nmsgstr \"\"\n\n#: web_ui/scan_ip.html:99\nmsgid \"Failed reading the log\"\nmsgstr \"\"\n\n#: web_ui/scan_ip.html:120\nmsgid \"Failed reading the settings\"\nmsgstr \"\"\n\n#: web_ui/scan_ip.html:150 web_ui/scan_ip.html:172\nmsgid \"Unkown error occurred\"\nmsgstr \"\"\n\n#: web_ui/status.html:3\nmsgid \"Your browser is obsolete. Partial functionality will not be available.\"\nmsgstr \"\"\n\n#: web_ui/status.html:4\nmsgid \"The latest Chrome browser is recommended.\"\nmsgstr \"\"\n\n#: web_ui/status.html:91\nmsgid \"System Version\"\nmsgstr \"\"\n\n#: web_ui/status.html:142\nmsgid \"Feedback\"\nmsgstr \"\"\n\n#: web_ui/status.html:147\nmsgid \"Diagnostic Info\"\nmsgstr \"\"\n\n#: web_ui/status.html:150\nmsgid \"The one-key feedback needs to sign in your Github account\"\nmsgstr \"\"\n\n#: web_ui/status.html:154\nmsgid \"To Google Groups\"\nmsgstr \"\"\n\n#: web_ui/status.html:155\nmsgid \"One-key feedback\"\nmsgstr \"\"\n\n#: web_ui/status.html:161\nmsgid \"GAE Proxy Status Info\"\nmsgstr \"\"\n\n#: web_ui/status.html:274\nmsgid \"\"\n\"The status page is empty. Highly likely that GAEProxy failed getting \"\n\"started. Please follow \"\nmsgstr \"\"\n\n#: web_ui/status.html:274\nmsgid \"guide \"\nmsgstr \"\"\n\n#: web_ui/status.html:274\nmsgid \"to troubleshoot.\"\nmsgstr \"\"\n\n#: web_ui/status.html:276\nmsgid \"No response from GAEProxy process. It might have already exited.\"\nmsgstr \"\"\n\n"
  },
  {
    "path": "code/default/gae_proxy/lang/zh_CN/LC_MESSAGES/messages.po",
    "content": "\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: PROJECT VERSION\\n\"\n\"Report-Msgid-Bugs-To: xxnet.dev@gmail.com\\n\"\n\"POT-Creation-Date: 2017-12-24 12:00+0800\\n\"\n\"PO-Revision-Date: 2017-12-29 12:00+0800\\n\"\n\"Last-Translator: Emphasia@github\\n\"\n\"Language: zh_Hans_CN\\n\"\n\"Language-Team: zh_Hans_CN <LL@li.org>\\n\"\n\"Plural-Forms: nplurals=2; plural=(n != 1)\\n\"\n\"MIME-Version: 1.0\\n\"\n\"Content-Type: text/plain; charset=utf-8\\n\"\n\"Content-Transfer-Encoding: 8bit\\n\"\n\"Generated-By: Babel 2.3.4\\n\"\n\nmsgid \"Global Settings\"\nmsgstr \"全局设置\"\n\nmsgid \"Switch ON to submit setting level\"\nmsgstr \"切换到 ON 才能提交设置级别\"\n\nmsgid \"Passive mode consumes less system resources\"\nmsgstr \"被动模式消耗更少的系统资源\"\n\nmsgid \"Customized an adequate value for your network connection. large values will provide a larger bandwidth limit, but may result in tunnel connection unstable.\"\nmsgstr \"为你的网络连接自定义适当的数值。大的数值会提供较大的带宽上限，但是可能导致隧道连接不稳定。\"\n\nmsgid \"Submit setting level\"\nmsgstr \"提交设置级别\"\n\nmsgid \"Setting level\"\nmsgstr \"设置级别\"\n\nmsgid \"Passive\"\nmsgstr \"被动\"\n\nmsgid \"Conservative\"\nmsgstr \"保守\"\n\nmsgid \"Normal\"\nmsgstr \"正常\"\n\nmsgid \"Radical\"\nmsgstr \"积极\"\n\nmsgid \"Extreme\"\nmsgstr \"极端\"\n\nmsgid \"Connect receive buffer size\"\nmsgstr \"连接接收缓冲大小\"\n\nmsgid \"Scan Settings\"\nmsgstr \"扫描设置\"\n\nmsgid \"Scan Log\"\nmsgstr \"扫描日志\"\n\nmsgid \"Import IP\"\nmsgstr \"导入 IP\"\n\nmsgid \"Export IP\"\nmsgstr \"导出 IP\"\n\nmsgid \"Check IP\"\nmsgstr \"检查 IP\"\n\nmsgid \"IPv6 Tunnel\"\nmsgstr \"IPv6 隧道\"\n\nmsgid \"Teredo Tunnel\"\nmsgstr \"Teredo 隧道\"\n\nmsgid \"GAEProxy Advanced Configuration\"\nmsgstr \"GAEProxy 高级配置\"\n\nmsgid \"Your browser is obsolete. Partial functionality will not be available.\"\nmsgstr \"您的浏览器版本过低, 部分功能将无法使用。\"\n\nmsgid \"The latest Chrome browser is recommended.\"\nmsgstr \"建议您使用最新版本的 Chrome 浏览器。\"\n\nmsgid \"Status\"\nmsgstr \"状态\"\n\nmsgid \"Property\"\nmsgstr \"属性\"\n\nmsgid \"Value\"\nmsgstr \"值\"\n\nmsgid \"All IP Number\"\nmsgstr \"总 IP 数\"\n\nmsgid \"Left Number\"\nmsgstr \"待测 IP 数\"\n\nmsgid \"Good IP Number\"\nmsgstr \"有效 IP 数\"\n\nmsgid \"Run\"\nmsgstr \"开始\"\n\nmsgid \"No response from process: \"\nmsgstr \"进程：\"\n\n# msgid \"GAEProxy\"\n# msgstr \"\"\n\n# msgid \"XX-Net\"\n# msgstr \"\"\n\nmsgid \". It might have already exited.\"\nmsgstr \" 无响应, 可能已退出。\"\n\nmsgid \"Stop\"\nmsgstr \"停止\"\n\nmsgid \"Public AppIDs used by default\"\nmsgstr \"默认使用公共 AppID，保存多个 AppID 请用 | 分割\"\n\nmsgid \"The public AppIDs are disabled to access videos or download files.\"\nmsgstr \"公共 AppID 不能看视频、下载文件。\"\n\nmsgid \"How to apply\"\nmsgstr \"如何申请\"\n\nmsgid \"Attention: inaccessable before AppIDs are deployed.\"\nmsgstr \"注意：AppID 部署之前无法使用。\"\n\nmsgid \"Save\"\nmsgstr \"保存\"\n\nmsgid \"Advanced tricks:\"\nmsgstr \"高级技巧：\"\n\nmsgid \"By the configuration file\"\nmsgstr \"通过文件配置\"\n\nmsgid \"GAEProxy Configuration\"\nmsgstr \"GAEProxy 配置\"\n\nmsgid \"Failed reading the settings.\"\nmsgstr \"读取设置失败。\"\n\nmsgid \"Failed reading the prefix policies.\"\nmsgstr \"读取前缀策略失败。\"\n\nmsgid \"No teredo prefix policiy is found.\"\nmsgstr \"未发现 Teredo 前缀策略。\"\n\nmsgid \"Checking settings ...\"\nmsgstr \"请等待检查设置有效性...\"\n\nmsgid \"Settings saved successfully.\"\nmsgstr \"设置保存成功。\"\n\nmsgid \"AppID invalid:\"\nmsgstr \"无效的AppID：\"\n\nmsgid \", deploy AppID before using.\"\nmsgstr \"，使用前请先部署。\"\n\nmsgid \"Failed saving settings: \"\nmsgstr \"保存设置失败：\"\n\nmsgid \"Failed saving settings.\"\nmsgstr \"保存设置失败。\"\n\nmsgid \"Deploy XX-Net onto GAE\"\nmsgstr \"部署 XX-Net 至 GAE\"\n\nmsgid \"Current status: \"\nmsgstr \"当前状态：\"\n\nmsgid \"idle\"\nmsgstr \"空闲\"\n\nmsgid \"unknown\"\nmsgstr \"未知\"\n\nmsgid \"offline\"\nmsgstr \"离线（无法连接）\"\n\nmsgid \"probe\"\nmsgstr \"正在检查网络\"\n\nmsgid \"qualified\"\nmsgstr \"合格（已连接）\"\n\nmsgid \"dormant\"\nmsgstr \"休眠（未连接）\"\n\nmsgid \"enabled\"\nmsgstr \"已启用\"\n\nmsgid \"disabled\"\nmsgstr \"已禁用\"\n\nmsgid \"Still not connected? Wait for a while, or\"\nmsgstr \"仍然连接不上？等一会儿，或者\"\n\nmsgid \"try to reduce the connection buffer size\"\nmsgstr \"尝试降低连接缓冲数值\"\n\nmsgid \"Script is running, please retry later.\"\nmsgstr \"脚本正在运行，请稍后再试。\"\n\nmsgid \", are you sure to continue?\"\nmsgstr \"，你确定要继续吗？\"\n\nmsgid \"working\"\nmsgstr \"工作\"\n\nmsgid \"Authorization\"\nmsgstr \"授权\"\n\nmsgid \"Log\"\nmsgstr \"日志\"\n\nmsgid \"Delimit multiple AppIDs with |\"\nmsgstr \"批量部署多个 AppID 请用 | 分割；部署时不要占用 8080 端口\"\n\nmsgid \"Show Debug Log\"\nmsgstr \"显示日志\"\n\nmsgid \"Start to deploy\"\nmsgstr \"开始部署\"\n\nmsgid \"Auth window will popup, make sure don't block popup in browser.\"\nmsgstr \"认证会弹出窗口，请确认浏览器不会阻止弹窗。\"\n\nmsgid \"XX-Net was reset.\"\nmsgstr \"XX-Net已被重置。\"\n\nmsgid \"Deployment completed.\"\nmsgstr \"部署完成。\"\n\nmsgid \"Please go to \"\nmsgstr \"请在\"\n\nmsgid \"the configuration page \"\nmsgstr \"配置页面\"\n\nmsgid \"to set AppID to enable them.\"\nmsgstr \"中设置 AppID, 方会生效。\"\n\nmsgid \"An exception occurred.\"\nmsgstr \"发生异常。\"\n\nmsgid \"The exception info: \"\nmsgstr \"异常信息：\"\n\nmsgid \"deploying ...\"\nmsgstr \"正在部署...\"\n\nmsgid \"Terminate deploying\"\nmsgstr \"终止部署\"\n\nmsgid \"Deployment cancelled.\"\nmsgstr \"部署已被取消。\"\n\nmsgid \"Your AppID is either empty or invalid.\"\nmsgstr \"您的 AppID 为空或无效。\"\n\nmsgid \"Export format\"\nmsgstr \"导出格式\"\n\nmsgid \"IP|IP|IP (GoGo Tester/GoAgent format)\"\nmsgstr \"IP|IP|IP (GoGo Tester/GoAgent 格式)\"\n\nmsgid \"New line delimiter\"\nmsgstr \"以换行分隔\"\n\nmsgid \"IP address list\"\nmsgstr \"IP 地址列表\"\n\nmsgid \"Succeeded exporting \"\nmsgstr \"成功导出\"\n\nmsgid \" IP addresses.\"\nmsgstr \"个 IP。\"\n\nmsgid \"Failed exporting the IP addresses.\"\nmsgstr \"导出 IP 失败。\"\n\nmsgid \"IP list\"\nmsgstr \"IP 列表\"\n\nmsgid \"Success import \"\nmsgstr \"成功导入 \"\n\nmsgid \" IP.\"\nmsgstr \"个 IP。\"\n\nmsgid \"Failed importing IP.\"\nmsgstr \"导入 IP 失败。\"\n\nmsgid \"Tips\"\nmsgstr \"提示\"\n\nmsgid \"Enable operations usually only needs to be performed once at each device.\"\nmsgstr \"启用操作通常只需要在每台设备上执行一次。\"\n\nmsgid \"After changing the server, it takes 10-90 seconds to successfully establish a new teredo tunnel.\"\nmsgstr \"更换服务器后，需要等待 10-90 秒钟才会成功建立新的 teredo 隧道。\"\n\nmsgid \"To use teredo tunnel, win user must keep firewall enabled, and allow outbound.\"\nmsgstr \"Win 用户使用 teredo 必须保持防火墙开启，出站放行即可。\"\n\nmsgid \"Non-win users can also use the test button to get the fastest server for change manually.\"\nmsgstr \"非 win 用户也可以使用测试按钮来获取响应最快的服务器，以便手动更换。\"\n\nmsgid \"Enable\"\nmsgstr \"启用\"\n\nmsgid \"Disable\"\nmsgstr \"禁用\"\n\nmsgid \"Test teredo\"\nmsgstr \"测试 teredo\"\n\nmsgid \"Test teredo usability only\"\nmsgstr \"仅测试 teredo 可用性\"\n\nmsgid \"Test teredo server only\"\nmsgstr \"仅测试 teredo 服务器\"\n\nmsgid \"Change teredo server\"\nmsgstr \"更换 teredo 服务器\"\n\nmsgid \"Switch teredo first\"\nmsgstr \"切换到 teredo 隧道优先\"\n\nmsgid \"Switch origin first\"\nmsgstr \"切换到原生 IPv6 优先\"\n\nmsgid \"Running ...\"\nmsgstr \"正在执行...\"\n\nmsgid \"GAEProxy Log\"\nmsgstr \"GAEProxy 日志\"\n\nmsgid \"Configuration\"\nmsgstr \"配置\"\n\nmsgid \"Deploy Server\"\nmsgstr \"部署服务端\"\n\nmsgid \"Advanced\"\nmsgstr \"高级\"\n\nmsgid \"Refresh\"\nmsgstr \"刷新\"\n\nmsgid \"Failed reading the log.\"\nmsgstr \"读取日志失败。\"\n\nmsgid \"Auto-adjust scan thread count\"\nmsgstr \"自动调整扫描线程数\"\n\nmsgid \"How enable\"\nmsgstr \"如何开启\"\n\nmsgid \"Help\"\nmsgstr \"帮助\"\n\nmsgid \"Max scan thread count\"\nmsgstr \"最大扫描线程数\"\n\nmsgid \"AUTO\"\nmsgstr \"自动\"\n\nmsgid \"Force-IPv4\"\nmsgstr \"仅 IPv4\"\n\nmsgid \"Force-IPv6\"\nmsgstr \"仅 IPv6\"\n\nmsgid \"IP range list\"\nmsgstr \"IP 段列表\"\n\nmsgid \"Supporting formats\"\nmsgstr \"支持格式\"\n\nmsgid \"Submit\"\nmsgstr \"提交\"\n\nmsgid \"Scan IP thread is larger than the max number.\"\nmsgstr \"扫描线程数超过最大值。\"\n\nmsgid \"Unkown error occurred.\"\nmsgstr \"发生未知错误。\"\n\nmsgid \"IPv4 Status\"\nmsgstr \"IPv4 状态\"\n\nmsgid \"IPv6 Status\"\nmsgstr \"IPv6 状态\"\n\nmsgid \"try repair\"\nmsgstr \"尝试修复\"\n\nmsgid \"Good IPv4 Number\"\nmsgstr \"有效 IPv4 IP 数\"\n\nmsgid \"Good IPv6 Number\"\nmsgstr \"有效 IPv6 IP 数\"\n\nmsgid \"XX-Net Status\"\nmsgstr \"XX-Net 状态\"\n\nmsgid \"IP Quality\"\nmsgstr \"IP 延迟\"\n\nmsgid \"Connection Pool\"\nmsgstr \"连接池\"\n\nmsgid \"Browser Proxy Setting\"\nmsgstr \"浏览器代理设置\"\n\nmsgid \"CA status\"\nmsgstr \"CA 证书状态\"\n\nmsgid \"Download\"\nmsgstr \"下载\"\n\nmsgid \"Number of IP-Scanning Threads\"\nmsgstr \"IP 扫描线程数\"\n\nmsgid \"Settings\"\nmsgstr \"设置\"\n\nmsgid \"Block Status\"\nmsgstr \"屏蔽状态\"\n\nmsgid \"XX-Net Version\"\nmsgstr \"XX-Net 版本\"\n\nmsgid \"System Proxy Status\"\nmsgstr \"系统代理状态\"\n\nmsgid \"Listening At\"\nmsgstr \"代理监听\"\n\n# msgid \"PAC URL\"\n# msgstr \"PAC 自动代理地址\"\n\nmsgid \"IP mode\"\nmsgstr \"IP 模式\"\n\nmsgid \"LAN proxy\"\nmsgstr \"前置代理\"\n\nmsgid \"working AppIDs\"\nmsgstr \"工作 AppID\"\n\nmsgid \"out-of-quota AppIDs\"\nmsgstr \"超额 AppID\"\n\nmsgid \"not-exist AppIDs\"\nmsgstr \"无效 AppID\"\n\nmsgid \"System Info\"\nmsgstr \"系统信息\"\n\nmsgid \"Diagnostic Info\"\nmsgstr \"诊断信息\"\n\nmsgid \"Check\"\nmsgstr \"查看\"\n\nmsgid \"GitHub issues\"\nmsgstr \"GitHub 问题讨论区\"\n\nmsgid \"or\"\nmsgstr \"或\"\n\nmsgid \"Google Group Discussions\"\nmsgstr \"Google Group 讨论组\"\n\nmsgid \"Show Details\"\nmsgstr \"显示详细信息\"\n\nmsgid \"Post to Github issue needs to sign in your Github account\"\nmsgstr \"贴到 GitHub 问题区需要登录 GitHub 账号\"\n\nmsgid \"GAE Proxy Status Info\"\nmsgstr \"GAEProxy 状态信息\"\n\nmsgid \"\"\n\"-----------%0AProblem Description:%0APlease describe your problem, \"\n\"running logs may be needed.%0A%0A-----------%0ADiagnostic information:%0A\"\nmsgstr \"-----------%0A问题描述：%0A请在此描述你遇到的问题，必要时贴出相关的日志信息。%0A%0A-----------%0A诊断信息：%0A\"\n\nmsgid \"The status page is empty. Highly likely that \"\nmsgstr \"状态页显示空白, 很可能 \"\n\nmsgid \" failed getting started. Please follow \"\nmsgstr \" 启动失败, 请按 \"\n\nmsgid \"guide\"\nmsgstr \"指导\"\n\nmsgid \" to troubleshoot.\"\nmsgstr \"去解决。\"\n\nmsgid \"Your local network failed, please check your network and firewall.\"\nmsgstr \"网络无法连接，请检查网络和防火墙设置。\"\n\nmsgid \" not available, Please check.\"\nmsgstr \" 不可用，请检查。\"\n\nmsgid \"You may want to $1turn on IP scaner$2.\"\nmsgstr \"您应该考虑$1开启IP扫描器$2。\"\n\nmsgid \"\"\n\"You can try <a href=\\\"https://github.com/XX-net/XX-Net/wiki/How-to-turn-\"\n\"on-IPv6\\\">turn on IPv6</a> or <a href=\\\"https://github.com/XX-net/XX-\"\n\"Net/wiki/How-to-use-XTunnel\\\">use X-Tunnel</a>.\"\nmsgstr \"你可以尝试 <a href=\\\"https://github.com/XX-net/XX-Net/wiki/%E5%A6%82%E4%BD%95%E5%BC%80%E5%90%AFIPv6\\\">开启IPv6</a> 或 <a href=\\\"https://github.com/XX-net/XX-Net/wiki/x-tunnel%E4%BD%BF%E7%94%A8%E6%95%99%E7%A8%8B\\\">使用X-Tunnel</a>。\"\n\nmsgid \"XX-Net is scanning IP. Please wait about half an hour.\"\nmsgstr \"等待扫描 IP，建议开启 IPv6。\"\n\nmsgid \"\"\n\"Public AppID out of quota, Please <a href=\\\"https://github.com/XX-net/XX-\"\n\"Net/wiki/how-to-create-my-appids\\\" target=\\\"_blank\\\">deploy your own AppID</a>.\"\nmsgstr \"公共 AppID 配额已用完，请<a href=\\\"https://github.com/XX-net/XX-Net/wiki/how-to-create-my-appids\\\" target=\\\"_blank\\\">部署私有 AppID</a>。\"\n\nmsgid \"\"\n\"Your AppID out of quota, Please <a href=\\\"https://github.com/XX-net/XX-\"\n\"Net/wiki/how-to-create-my-appids\\\" target=\\\"_blank\\\">deploy more AppID</a>.\"\nmsgstr \"您的 AppID 流量已用完，请<a href=\\\"https://github.com/XX-net/XX-Net/wiki/how-to-create-my-appids\\\" target=\\\"_blank\\\">部署更多 AppID</a>。\"\n\nmsgid \"No working AppID. Please check.\"\nmsgstr \"没有可用 AppID，请检查。\"\n\nmsgid \"System is Idle.\"\nmsgstr \"系统空闲。\"\n\nmsgid \"Connection not established yet.\"\nmsgstr \"连接尚未建立。\"\n\nmsgid \"Please check your browser proxy setting.\"\nmsgstr \"请检查浏览器代理设置。\"\n\nmsgid \"Detecting ...\"\nmsgstr \"正在自检...\"\n\nmsgid \"Please import certificates to your browser.\"\nmsgstr \"请导入浏览器 CA 证书。\"\n\nmsgid \"\"\n\"You are using public AppIDs. You are recommended to <a \"\n\"href=\\\"https://github.com/XX-net/XX-Net/wiki/how-to-create-my-appids\\\" \"\n\"target=\\\"_blank\\\">deploy your own AppID</a>.\"\nmsgstr \"您正在使用公共 AppID，因为资源有限，使用上存在限制，建议<a href=\\\"https://github.com/XX-net/XX-Net/wiki/how-to-create-my-appids\\\" target=\\\"_blank\\\">部署私有 AppID</a>。\"\n\nmsgid \", Everything is OK. Welcome to the FREE Internet.\"\nmsgstr \"，一切正常，你可以访问真正的互联网了。\"\n\nmsgid \"You are using public AppIDs.\"\nmsgstr \"你正使用公共 AppID。\"\n\nmsgid \"new:\"\nmsgstr \"新:\"\n\nmsgid \"h1:\"\nmsgstr \"\"\n\nmsgid \"h2:\"\nmsgstr \"\"\n\nmsgid \"Auto proxy enabled at \"\nmsgstr \"智能代理已启用：\"\n\nmsgid \"Proxy enabled at \"\nmsgstr \"全局代理已启用：\"\n\nmsgid \"Proxy disabled\"\nmsgstr \"全局代理已禁用\"\n\n"
  },
  {
    "path": "code/default/gae_proxy/local/__init__.py",
    "content": "\nfrom . import apis\nfrom . import web_control\nfrom . import proxy\n\n\ndef is_ready():\n    return proxy.ready\n\n\ndef start(args):\n    proxy.main(args)\n\n\ndef stop():\n    proxy.terminate()\n"
  },
  {
    "path": "code/default/gae_proxy/local/apis.py",
    "content": "\nfrom .front import front, direct_front\nfrom xlog import getLogger\nxlog = getLogger(\"gae_proxy\")\n\n\ndef set_proxy(args):\n    front.set_proxy(args)\n    direct_front.set_proxy(args)\n\n\ndef _count_conn_num():\n    return len(front.connect_manager.new_conn_pool.pool) +\\\n           front.http_dispatcher.h1_num + \\\n           front.http_dispatcher.h2_num\n\n\ndef is_workable():\n    #if front.http_dispatcher.is_idle():\n    #    return True\n\n    if _count_conn_num() > 0:\n        return True\n    else:\n        front.http_dispatcher.get_worker()\n        return _count_conn_num() > 0\n\n\ndef set_bind_ip(args):\n    xlog.info(\"set_bind_ip:%s\", args)\n\n    front.config.listen_ip = args[\"ip\"]\n    front.config.save()\n"
  },
  {
    "path": "code/default/gae_proxy/local/appid_manager.py",
    "content": "#!/usr/bin/env python\n# coding:utf-8\n\nimport random\nimport threading\nimport time\nimport os\nfrom front_base.random_get_slice import RandomGetSlice\n\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\n\n\nclass AppidManager(object):\n    lock = threading.Lock()\n\n    def __init__(self, config, logger):\n        self.config = config\n        self.logger = logger\n        self.check_api = None\n        self.ip_manager = None\n\n        fn = os.path.join(current_path, \"appids.txt\")\n        self.public_appid = RandomGetSlice(fn, 60)\n\n        self.reset_appid()\n\n    def reset_appid(self):\n        # called by web_control\n        with self.lock:\n            self.working_appid_list = list()\n            for appid in self.config.GAE_APPIDS:\n                if not appid:\n                    self.config.GAE_APPIDS.remove(appid)\n                    continue\n                self.working_appid_list.append(appid)\n            self.not_exist_appids = []\n            self.out_of_quota_appids = []\n        self.last_reset_time = time.time()\n\n    def get(self):\n        if len(self.config.GAE_APPIDS):\n            if len(self.working_appid_list) == 0:\n                time_to_reset = 600 - (time.time() - self.last_reset_time)\n                if time_to_reset > 0:\n                    self.logger.warn(\"all appid out of quota, wait %d seconds to reset\", time_to_reset)\n                    sleep_end = time.time() + time_to_reset\n                    while len(self.working_appid_list) == 0 and time.time() < sleep_end:\n                        time.sleep(1)\n                    return None\n                else:\n                    self.logger.warn(\"reset appid\")\n                    self.reset_appid()\n\n            appid = random.choice(self.working_appid_list)\n            return str(appid)\n        else:\n            for _ in range(0, 10):\n                appid = self.public_appid.get()\n                if appid in self.out_of_quota_appids or appid in self.not_exist_appids:\n                    continue\n                else:\n                    return appid\n            return None\n\n    def report_out_of_quota(self, appid):\n        self.logger.warn(\"report_out_of_quota:%s\", appid)\n        with self.lock:\n            if appid not in self.out_of_quota_appids:\n                self.out_of_quota_appids.append(appid)\n            try:\n                self.working_appid_list.remove(appid)\n            except:\n                pass\n\n    def report_not_exist(self, appid, ip):\n        self.logger.debug(\"report_not_exist:%s %s\", appid, ip)\n        th = threading.Thread(target=self.process_appid_not_exist, args=(appid, ip), name=\"process_appid_not_exist\")\n        th.start()\n\n    def process_appid_not_exist(self, appid, ip):\n        ret = self.check_api(ip, \"xxnet-1\")\n        if ret and ret.ok:\n            self.set_appid_not_exist(appid)\n        else:\n            self.logger.warn(\"process_appid_not_exist, remove ip:%s\", ip)\n\n            self.ip_manager.report_connect_fail(ip, force_remove=True)\n\n    def set_appid_not_exist(self, appid):\n        self.logger.warn(\"APPID_manager, set_appid_not_exist %s\", appid)\n        with self.lock:\n            if appid not in self.not_exist_appids:\n                self.not_exist_appids.append(appid)\n            try:\n                self.config.GAE_APPIDS.remove(appid)\n            except:\n                pass\n\n            try:\n                self.working_appid_list.remove(appid)\n            except:\n                pass\n\n    def appid_exist(self, appids):\n        for appid in appids.split('|'):\n            if appid == \"\":\n                continue\n            if appid in self.config.GAE_APPIDS:\n                return True\n        return False\n\n"
  },
  {
    "path": "code/default/gae_proxy/local/appids.txt",
    "content": "1-dot-api-project-959547526753\r\n1-dot-fishding-001\r\n1-dot-fishding-002\r\n1-dot-fishding-003\r\n1-dot-fishding-004\r\n1-dot-fishding-005\r\n1-dot-fishding-006\r\n1-dot-fishding-007\r\n1-dot-fishding-008\r\n1-dot-fishding-009\r\n1-dot-fishding-010\r\n1-dot-fishding-011\r\n1-dot-fishding-012\r\n1-dot-fzongkkkk-1114\r\n1-dot-myzoo-185116\r\n1-dot-nangua0002\r\n1-dot-ningerte004\r\n1-dot-one1-178105\r\n1-dot-one10-178105\r\n1-dot-one11-178105\r\n1-dot-one12-178105\r\n1-dot-one2-178105\r\n1-dot-one3-178105\r\n1-dot-one4-178105\r\n1-dot-one5-178105\r\n1-dot-one6-178105\r\n1-dot-one7-178105\r\n1-dot-one8-178105\r\n1-dot-one9-178105\r\n1-dot-openvpn-helloworld\r\n1-dot-wangwei2017-168512\r\n1-dot-xx-net-01-216008\r\n1-dot-xx-net-155804\r\n1-dot-xx-net-202106\r\n1-dot-xx-net-215409\r\n1-dot-xx-net-8-233015\r\n1-dot-xx-net1-189816\r\n1-dot-xx-net1-paper\r\n1-dot-xx-net2-paper\r\n1-dot-xxnet-01-212704\r\n1-dot-xxnet-20171001\r\n1-dot-xxnet-20180218\r\n1-dot-xxnet-209400\r\n1-dot-xxnet-xhyproject\r\n1-dot-xxnet4ae01\r\n1-dot-xxnet4paper\r\n1-dot-xyyaoxin\r\n1-dot-zippy-rarity-179110\r\n109744884a\r\n13664191203zl\r\n1rrgfre\r\n34e-6y\r\n8487753\r\n8ziw2rt7\r\na-6332450\r\na0411641\r\na0411642\r\na0411643\r\na0411644\r\na0411645\r\na0411646\r\na04116471\r\na04116481\r\na0411649\r\na0411650\r\na0411684\r\na0411685\r\na0411686\r\na0411687\r\na0411688\r\na0411689\r\na0411690\r\na0411691\r\na0411692\r\na41200421\r\na514987111\r\na790412405\r\na82943658\r\na837036615\r\naa514987111\r\naaa514987111\r\naaaa514987111\r\naaaaa514987111\r\naaaaaa-159813\r\naaaaaaaaa-159813\r\nabc555-214808\r\nabcdff-1\r\nabcdff-2\r\nabcdff-3\r\nabcdff-4\r\nabcdff-5\r\nabiding-cycle-243802\r\nabiding-sunset-201306\r\nable-groove-187110\r\nable-involution-123514\r\nabneimenggu\r\nabstract-tract-187808\r\nacademic-atlas-149814\r\nacademic-atlas-235917\r\nacademic-notch-233214\r\nacoustic-bridge-859\r\nacoustic-welder-191202\r\nacquired-backup-212108\r\nactivationitrogen\r\nactivationitrogen2\r\nactivationitrogen9\r\nactive-campus-216915\r\nadept-crossing-215102\r\nadept-depth-189010\r\nadept-elevator-183105\r\nadept-primacy-191106\r\nadfrog1-152805\r\nadfrog2\r\nadfrog3-152805\r\nadfrog4\r\nadfrog5-152805\r\nadroit-solstice-218302\r\nadvance-casing-181213\r\nadvance-stratum-226713\r\naerial-anagram-180703\r\naerobic-library-225500\r\naffable-audio-859\r\naffable-beaker-189008\r\nagile-skyline-247301\r\nagile-sprite-152707\r\nai-sentoisuzu\r\nairy-ceremony-184318\r\nairy-machine-123514\r\nairy-torus-232908\r\nakakljf115-12\r\nakecheta\r\nalert-basis-184913\r\nalgebraic-creek-201306\r\nalgebraic-depot-170705\r\nalibaba-wangchong-147606\r\nalibaba-wangchong6\r\nalibaba-wangchong8\r\nalibaba-wangchong9\r\nalien-array-241811\r\nalien-paratext-155412\r\nallah-001a\r\nallah-001b\r\nalpine-air-123504\r\namiable-flames-189700\r\nanalog-crossing-228003\r\nanalog-subset-243305\r\nandroidproxyforcui\r\nandyddy126\r\naneimenggu\r\nangelic-artwork-205801\r\nangyrgoagent9\r\nanimated-scope-189703\r\nanimated-zenith-859\r\nankangsex\r\nanlahao-159813\r\nannihilation21\r\nanti-wand1\r\nanti-wand2\r\nanti-wand21\r\nanti-wand22\r\nanti-wand23\r\nanti-wand24\r\nanti-wand25\r\nanti-wand26\r\nanti-wand27\r\nanti-wand28\r\nanti-wand29\r\nanti-wand3\r\nanti-wand30\r\nanti-wand31\r\nanti-wand32\r\nanti-wand4\r\nanti-wand5\r\nanti-wand6\r\nanti-wand7\r\nanti-wand8\r\nanti-wand9\r\nanti-wandiix\r\nanti-wandx\r\nanti-wandxi\r\naotuman-51396\r\naotuman-513961\r\naotuman-513962\r\napi-project-256541348713\r\napi-project-338155433549\r\napi-project-855063073479\r\napi-project-8691297067\r\napp12345-149811\r\napp123456-149811\r\napp1234567-149811\r\napp19820220\r\napp19820221\r\napp19820222\r\napp19820223\r\nappid-01-189210\r\nappid-02-161702\r\nappid-03-161702\r\nappid-04-161702\r\nappid-05-161907\r\nappid-06-161907\r\nappid-07-161907\r\nappid-08-161907\r\nappid-09-161907\r\nappid-1-192801\r\nappid-10-161912\r\nappid-11-161912\r\nappid-12-161912\r\nappid-2-192801\r\nappid-3-192801\r\nappid-4-192801\r\nappid-5-192801\r\nappid-6-192801\r\nappid0-174506\r\nappid0-174905\r\nappid1-174506\r\nappid1-174905\r\nappid10-174506\r\nappid10-174905\r\nappid11-174506\r\nappid11-174905\r\nappid2-174506\r\nappid2-174905\r\nappid3-174506\r\nappid3-174905\r\nappid4-174506\r\nappid4-174905\r\nappid5-174506\r\nappid5-174905\r\nappid6-174506\r\nappid6-174905\r\nappid7-174506\r\nappid7-174905\r\nappid8-174506\r\nappid8-174905\r\nappid9-174506\r\nappid9-174905\r\nappjian08225\r\nappjianguo0822\r\napplied-pipe-192704\r\napplied-pursuit-218209\r\nappliss-146309\r\napt-decorator-163211\r\napt-subset-113123\r\narctic-analyzer-236503\r\narctic-math-146309\r\narctic-maxim-142514\r\nardent-curve-190608\r\nargon-ace-180703\r\nargon-gear-119613\r\nartful-logic-203109\r\nartful-reactor-233108\r\narvin13408100205\r\nascendant-bloom-171907\r\nassgfwhole\r\nassgfwhole2\r\nassgfwhole3\r\nassgfwhole4\r\nassgfwholenew\r\nassgfwholenew1\r\nassgfwholenew2\r\nastral-digit-151605\r\nastral-sorter-217505\r\nastute-baton-184209\r\nastute-diode-189007\r\nastute-diode-233015\r\nastute-task-135723\r\nastute-veld-164609\r\nastute-winter-186909\r\nasxx-1\r\nasxx-10\r\nasxx-11\r\nasxx-12\r\nasxx-2\r\nasxx-3\r\nasxx-4\r\nasxx-5\r\nasxx-6\r\nasxx-7\r\nasxx-8\r\nasxx-9\r\natlantean-depth-248804\r\natomic-horizon-232307\r\natomic-matrix-188715\r\naugust-tract-169300\r\nautoman-513963\r\nautoman-513964\r\nautoman-513965\r\nautoman-513966\r\nautomated-rune-187715\r\nautomatic-rite-238714\r\nawesome-flash-148607\r\naxial-history-105113\r\naxial-sunup-191202\r\nbaba-208615\r\nbalmy-cab-232002\r\nbalmy-coral-211906\r\nbalmy-renderer-153407\r\nbalmy-renderer-191106\r\nbanded-nimbus-138308\r\nbang-166903\r\nbaobao-189715\r\nbasic-perigee-193312\r\nbbneimenggu\r\nbbszzf\r\nbbtvjs2013\r\nbccccccc09\r\nbccccccc10-185400\r\nbcmtester0\r\nbcmtester1\r\nbcmtester2\r\nbcmtester3\r\nbe02wz\r\nbear940214\r\nbear9402140\r\nbear9402141\r\nbear9402142\r\nbear9402143\r\nbear9402144\r\nbear9402145\r\nbear9402146\r\nbear9402147\r\nbear9402148\r\nbear9402149\r\nbear940325\r\nbeckzf9\r\nbeijihu129\r\nbeyond6679\r\nbig-coil-859\r\nbig-depth-186703\r\nbinjing101010\r\nbinjing333\r\nbinjing444\r\nbinjing555\r\nbinjing666\r\nbinjing777\r\nbinjing888\r\nbinjing999\r\nbinjoo-xxnet-1-01\r\nbinjoo-xxnet-1-02\r\nbinjoo-xxnet-1-03\r\nbinjoo-xxnet-1-04\r\nbinjoo-xxnet-1-05\r\nbinjoo-xxnet-1-06\r\nbinjoo-xxnet-1-07\r\nbinjoo-xxnet-1-08\r\nbinjoo-xxnet-1-09\r\nbinjoo-xxnet-1-10\r\nbinjoo-xxnet-1-11\r\nbinjoo-xxnet-1-12\r\nbiomeitroic16\r\nbionic-comfort-158112\r\nbionic-genre-214609\r\nbivozeou\r\nblack-abode-126006\r\nblack-abode-187110\r\nblissful-mantis-242711\r\nblissful-sun-152204\r\nbluesailcn06\r\nbluesailcn07\r\nbluesailcn08\r\nbluesailcn09\r\nbluesailcn10\r\nbluesailcn11\r\nbmqe-143715\r\nbmqe-143716\r\nbmqe-143717\r\nbmqe-143718\r\nbmqe-143719\r\nbmqe-143720\r\nbneimenggu\r\nbnujazz\r\nbold-camera-192906\r\nbold-physics-859\r\nbonew80\r\nbonnyshenvpn\r\nbonnyshenvpn-001\r\nbonnyshenvpn-002\r\nbonnyshenvpn-003\r\nbonnyshenvpn-004\r\nbonnyshenvpn-005\r\nbonnyshenvpn-006\r\nbonnyshenvpn-007\r\nbonnyshenvpn-008\r\nbonnyshenvpn-009\r\nbooming-alchemy-123514\r\nbooming-coast-150311\r\nboulder-158315\r\nboxwood-axon-133123\r\nboxwood-office-208211\r\nboxwood-valve-208507\r\nboy1039459398\r\nbrachio112\r\nbrachio113\r\nbrachio114\r\nbrachio115\r\nbrachio116\r\nbrachio118\r\nbrachio119\r\nbraided-rush-212512\r\nbrave-aileron-193713\r\nbrave-embassy-194208\r\nbreakqiang751\r\nbright-karma-188116\r\nbright-practice-187913\r\nbronzemonster1\r\nbronzemonster2\r\nbronzemonster3\r\nbslzr003-174918\r\nbujizhicai\r\nbujizhicai1\r\nbujizhicai10\r\nbujizhicai11\r\nbujizhicai2\r\nbujizhicai3\r\nbujizhicai4\r\nbujizhicai5\r\nbujizhicai6\r\nbujizhicai7\r\nbujizhicai8\r\nbujizhicai9\r\nbuoyant-braid-186612\r\nbuoyant-braid-193713\r\nbuoyant-operand-199608\r\nburnished-web-191106\r\nbwg1991\r\nbypassgfw-1374\r\nbypassgfw2-1374\r\nbypassgfw3-1374\r\nbypassgfw4-1374\r\nc123123eeeee\r\nc123123fffff\r\nc123123ggggg\r\ncalcium-adapter-125209\r\ncalcium-adapter-192106\r\ncalcium-backup-257701\r\ncalixcms1\r\ncalixcms2\r\ncalm-drive-186612\r\ncalm-edge-859\r\ncalm-history-153512\r\ncaocao595\r\ncaocaocao485\r\ncaocaocao595\r\ncaocaocaocao485\r\ncaocaocaocao595\r\ncaocaocaocaocao485\r\ncaocaocaocaocao595\r\ncaocaocaocaocaocao595\r\ncaojinsheng123\r\ncaojinsheng123456\r\ncaojinsheng1234567\r\ncaojinsheng12345678\r\ncaojinsheng123456789\r\ncaojinsheng1234567890\r\ncaojinsheng12345678901\r\ncar-10-229009\r\ncar-11\r\ncar-12-229009\r\ncar-4-229009\r\ncar-9-229009\r\ncar-d-229009\r\ncar3-229009\r\ncar5-229009\r\ncar6-229009\r\ncar7-229009\r\ncar8-229009\r\ncaramel-core-249206\r\ncaramel-limiter-138023\r\ncaramel-pager-197708\r\ncaramel-theory-123504\r\ncarbide-bonsai-115805\r\ncarbon-feat-124818\r\ncareful-compass-178405\r\ncareful-flow-214609\r\ncatpapa0507\r\ncatpapa0508\r\ncatpapa0509\r\ncatpapa0510\r\ncatpapa0511\r\ncatpapa0513\r\ncausal-benefit-242612\r\ncausal-temple-212406\r\ncbneimenggu\r\nccdream6501\r\nccdream6502\r\nccdream6503\r\nccdream6504\r\nccdream6505\r\nccdream6506\r\nccdream6507\r\nccdream6508\r\nccdream6509\r\nccdream6510\r\nccdream6511\r\nccdream6512\r\nccdream6513\r\ncedar-abacus-187913\r\ncedar-helper-192506\r\ncedar-shape-188411\r\ncelestial-gist-171813\r\ncelestial-now-242006\r\ncellular-block-133123\r\ncellular-codex-187205\r\ncellular-gift-184212\r\nceltic-bazaar-122813\r\ncen000001\r\ncentral-cinema-208808\r\ncentral-diagram-209014\r\ncentral-node-151605\r\ncgw19920930\r\ncgwfifa\r\nchangzhou-194902\r\nchangzhou-194903\r\nchangzhou-194904\r\nchangzhou-194905\r\nchangzhou-194906\r\nchaoji000011\r\nchaoji000012\r\ncharged-audio-187002\r\ncharged-hub-214609\r\ncharged-kiln-105204\r\ncharles001\r\ncharles002\r\ncharles003\r\ncharles004\r\ncharles005\r\ncharles006\r\ncharles008\r\ncharles009\r\ncharles010\r\ncharles011\r\ncharlie-xxnet01\r\ncheathao\r\ncheathaob\r\ncheathaof\r\ncheathaog\r\ncheathaoh\r\ncheathaoi\r\ncheletong-151301\r\nchengchongfan\r\nchengchongfan10\r\nchengchongfan2\r\nchengchongfan3\r\nchengchongfan4\r\nchengchongfan5\r\nchengchongfan6\r\nchengchongfan7\r\nchengchongfan8\r\nchengchongfan9\r\nchengjm7619\r\nchenjiaan230\r\nchenjiaan240\r\nchenjiaan250\r\nchenjiaan333\r\nchenjiaan456\r\nchenjiaan555\r\nchenjiaan666\r\nchenjiaan777\r\nchenjiaan888\r\nchenjiaan999\r\nchenqun0411\r\nchenqun0412\r\nchenqun0413\r\nchenqun0414\r\nchenqun0415\r\nchenqun0416\r\nchenqun0417\r\nchenqun0418\r\nchenqun0419\r\nchenqun0420\r\nchenqun0421\r\nchenqun0423\r\nchenqun0424\r\nchenqun0425\r\nchenqun0426\r\nchenqun0427\r\nchenxiyuan1988\r\nchinazhou110\r\nchinazhou112\r\nchinazhou113\r\nchinazhou114\r\nchinazhou115\r\nchinazzlfz\r\nchiuhum-appid-10\r\nchiuhum-appid-11\r\nchiuhum-appid-12\r\nchiuhum-appid-7\r\nchiuhum-appid-8\r\nchiuhum-appid-9\r\nchnmc-2132312\r\nchnmc-213503\r\nchnmc-213504\r\nchnmc-6165d\r\nchnmc-651652\r\nchome-218209\r\nchrome---1231\r\nchrome---1234\r\nchrome--1231\r\nchrome--1234\r\nchrome-06\r\nchrome-07\r\nchrome-08\r\nchrome-09\r\nchrome-10\r\nchrome-11\r\nchrome-12\r\nchrome-1231\r\nchrome-1231-1231\r\nchrome-1234\r\nchrome-courage-223709\r\nchrome-epigram-125209\r\nchrome-sphere-213503\r\nchrome-unity-146010\r\nchrome0-1234\r\nchrome0-1239\r\nchrome1-1209\r\nchrome1-1234\r\nchrome10-1209\r\nchrome10-1239\r\nchrome11-1209\r\nchrome11-1239\r\nchrome12-1209\r\nchrome2-1209\r\nchrome2-1234\r\nchrome2-1239\r\nchrome26-1100\r\nchrome27-1100\r\nchrome28-1100\r\nchrome29-1100\r\nchrome3-1209\r\nchrome3-1234\r\nchrome3-1239\r\nchrome30-1100\r\nchrome4-1209\r\nchrome4-1234\r\nchrome4-1239\r\nchrome5-1234\r\nchrome5-1239\r\nchrome6-1209\r\nchrome6-1234\r\nchrome6-1239\r\nchrome7-1234\r\nchrome7-1239\r\nchrome8-1234\r\nchrome8-1239\r\nchrome9-1239\r\nchunlong-148607\r\ncindy-01\r\ncindy-02\r\ncindy-03\r\ncivic-origin-221514\r\ncivil-sprite-211501\r\ncivil-victory-186402\r\ncjnjesus01\r\ncjnjesus02\r\ncjnjesus03\r\ncjnjesus04\r\ncjnjesus05\r\ncjnjesus06\r\ncjnjesus07\r\ncjnjesus08\r\ncjnjesus09\r\ncjnjesus10\r\ncjnjesus11\r\ncjnjesus12\r\nclean-yew-123504\r\nclean-yew-167204\r\nclear-column-187715\r\nclear-practice-213002\r\nclever-bee-146713\r\nclever-cortex-149703\r\nclever-cortex-187715\r\nclj156024\r\nclj156025\r\nclj156026\r\nclj156027\r\nclj156028\r\ncloudfra-fjl10\r\ncloudpower-7\r\ncmccc-180801\r\ncneimenggu\r\ncnonegae\r\ncoastal-mercury-177513\r\ncobalt-sector-123504\r\ncodetimes-2\r\ncodetimes-2017\r\ncodetimes-9\r\ncodingtiming\r\ncogent-quarter-208808\r\ncogent-silicon-133123\r\ncoherent-acre-227309\r\ncoherent-window-196502\r\ncohesive-idiom-183908\r\ncohesive-keel-214609\r\ncohesive-link-234103\r\ncommanding-mix-240201\r\ncompact-life-123504\r\ncomposed-maxim-187205\r\ncomposite-haiku-132302\r\ncomposite-rhino-213503\r\ncomposite-sun-160715\r\nconcise-beanbag-120316\r\nconcise-cinema-213002\r\nconcise-crane-146713\r\nconcise-slate-208609\r\nconcise-upgrade-217406\r\nconfident-key-170508\r\nconfident-sweep-187715\r\ncool-continuity-122814\r\ncopper-sunspot-254717\r\ncopper-tempo-189502\r\ncoral-mariner-221514\r\ncoral-muse-122814\r\ncorded-academy-189703\r\ncorded-cortex-242711\r\ncorded-smithy-192108\r\ncorded-sunlight-166909\r\ncore-incentive-241905\r\ncosmic-descent-107908\r\ncosmic-descent-204510\r\ncosmic-gizmo-243106\r\ncowardsage-1470373969510\r\ncozy001250\r\ncpcp6100\r\ncpproxy06\r\ncpproxy07\r\ncpproxy08\r\ncqmh-2016-0610\r\ncqmh-2016-0610-2309\r\ncquptyc\r\ncrack-muse-151706\r\ncrack-photon-232002\r\ncrafty-automata-189502\r\ncrafty-shield-183514\r\ncrazyliting10\r\ncrazyliting11\r\ncredible-cosine-127307\r\ncredible-list-201914\r\ncredible-torus-210602\r\ncrested-climber-192112\r\ncrested-polygon-187205\r\ncryptic-lattice-123514\r\ncrypto-galaxy-257701\r\ncugwxt\r\ncugwxt2018\r\ncugzb-xx-net\r\ncuiduke1\r\ncuiduke10\r\ncuiduke11\r\ncuiduke12\r\ncuiduke2\r\ncuiduke3\r\ncuiduke4\r\ncuiduke6\r\ncuiduke7\r\ncuiduke8\r\ncuiduke9\r\ncurious-framing-184318\r\ncurious-memory-122814\r\ncurious-nucleus-191106\r\ncustom-rampart-186612\r\ncustom-tine-189010\r\ncwj5814\r\ncwj6714\r\ncwj7714\r\ncwj9714\r\ncxinjia100\r\ncxinjia110\r\ncxinjia120\r\ncxinjia130\r\ncxinjia140\r\ncxinjia150\r\ncxinjia160\r\ncxinjia170\r\ncxinjia180\r\ncxinjia190\r\ncxinjia200\r\ncxinjia210\r\ncxinjia220\r\ncxinjia230\r\ncxinjia240\r\ncxinjia250\r\ncxinjia260\r\nczechrepublic-182402\r\nczyuan93\r\nd-xx-net-1\r\nd-xx-net-2\r\nda-feiji\r\nda27149-1\r\ndaaikuaiji\r\ndadsdasdw\r\ndageini\r\ndakadklf\r\ndark-safeguard-151605\r\ndarkzgoagent101\r\ndarkzgoagent102\r\ndarkzgoagent103\r\ndarkzgoagent104\r\ndarkzgoagent105\r\ndarkzgoagent106\r\ndarkzgoagent107\r\ndarkzgoagent108\r\ndarkzgoagent109\r\ndarkzgoagent110\r\ndarkzgoagent111\r\ndarkzgoagent112\r\ndata-media-170706\r\ndata-totality-226108\r\ndavie1256\r\ndaviebear55\r\ndawnlcx-168802\r\ndazzling-ocean-208808\r\ndbneimenggu\r\ndcshengz\r\ndcshenjx\r\nddd-gae10\r\nddnnff\r\nddyxhj\r\ndecent-terra-217505\r\ndecoded-doodad-184318\r\ndecoded-pilot-223802\r\ndeeevilyu-8801\r\ndeeevilyu-8802\r\ndeep-mile-227309\r\ndeft-falcon-186402\r\ndeft-falcon-244606\r\ndeft-ocean-232002\r\ndeft-smile-213002\r\ndeft-waters-192112\r\ndelta-surface-107908\r\ndelta-wonder-227614\r\ndepplyloveu22\r\ndesire-legend\r\ndesire-legend2\r\ndesire-legend3\r\ndesire-legend4\r\ndesire-legend5\r\ndesire-legend6\r\ndesire-legend7\r\ndesire-legend8\r\ndesire-legend9\r\ndesirelegend02\r\ndesirelegend03\r\ndesirelegend04\r\ndesirelegend05\r\ndesirelegend06\r\ndesirelegend07\r\ndesirelegend08\r\ndesirelegend09\r\ndesirelegend1\r\ndesirelegend10\r\ndeyidong\r\ndiafe-181623\r\ndiao82017\r\ndiaobaz\r\ndiary-1470053225438\r\ndidididw\r\ndiesel-acolyte-218802\r\ndirect-terminal-205201\r\ndisablegfw\r\ndisco-skyline-208808\r\ndivine-descent-242711\r\ndmiflyvpn11\r\ndneimenggu\r\ndocker-187703\r\ndogwood-goods-242711\r\ndoit1-142709\r\ndoit2-142709\r\ndoit3-142709\r\ndoit4-142709\r\ndoit5-142709\r\ndominica-189005\r\ndona1-185012\r\ndonate-153512\r\ndonate-5438\r\ndonate-for-xx-net\r\ndonate-xxnet\r\ndonate1-191205\r\ndonate10-191205\r\ndonate11-191205\r\ndonate12-191205\r\ndonate13-191205\r\ndonate14-191205\r\ndonate15-191205\r\ndonate16-191205\r\ndonate17-191205\r\ndonate18-191205\r\ndonate19-191205\r\ndonate2-1265\r\ndonate2-191205\r\ndonate20-191205\r\ndonate2017042401\r\ndonate2017042402\r\ndonate2017042403\r\ndonate2017042404\r\ndonate2017042405\r\ndonate21-191205\r\ndonate22-191205\r\ndonate23-191205\r\ndonate24-191205\r\ndonate25-191205\r\ndonate26-191205\r\ndonate27-191205\r\ndonate28-191205\r\ndonate29-191205\r\ndonate3-1265\r\ndonate3-191205\r\ndonate30-191205\r\ndonate4-1265\r\ndonate4-191205\r\ndonate5-1265\r\ndonate5-191205\r\ndonate6-191205\r\ndonate7-191205\r\ndonate8-191205\r\ndonate9-191205\r\ndonatetoxxnet\r\ndonatexxnet1\r\ndonation01-196903\r\ndonation02-196903\r\ndonation03-196903\r\ndonation04-196903\r\ndonation05-196903\r\ndonation06-196903\r\ndonation07-196903\r\ndonation08-196903\r\ndonation09-196904\r\ndonation1\r\ndonation10-196904\r\ndonor-153401\r\ndonor1-153401\r\ndonor2-153401\r\ndopsy50\r\ndospytang11\r\ndospytang12\r\ndospytang13\r\ndotted-banner-210602\r\ndotted-task-213002\r\ndouble-venture-133123\r\ndreain-goagent\r\ndreain-goagent2\r\ndreain-gogent3\r\ndriven-seer-189703\r\ndrwangyd8\r\ndrwangyd9\r\ndrxxnet1\r\ndrxxnet2\r\ndrxxnet3\r\ndrxxnet4\r\ndrxxnet5\r\ndrxxnet6\r\ndsetng10\r\ndsetng6\r\ndsetng7\r\ndsetng8\r\ndsetng9\r\nduanyu20061994\r\ndujingxiu-147503\r\ndulcet-bastion-106015\r\ndulcet-bucksaw-123514\r\ndurable-bond-181103\r\ndurable-syntax-194202\r\ndv23d-142511\r\ndxxnet-1\r\ndynamic-cooler-187503\r\ndynamic-cove-239106\r\ndynamic-hybrid-242612\r\ne-lexicon-123514\r\ne-night-125209\r\ne1574559475\r\nearnest-pact-227309\r\neastern-amp-226408\r\neastern-stock-168012\r\nebneimenggu\r\necg-test\r\neco-layout-195404\r\necstatic-fiber-213002\r\neddy-chiang\r\neffective-light-243106\r\neighth-epsilon-184613\r\neighth-pen-200303\r\nelated-gizmo-197708\r\nelated-guild-213002\r\nelated-practice-123515\r\nelfive-donateproject-01\r\nelfive-donateproject-02\r\nelfive-donateproject-03\r\nelfive-donateproject-04\r\nelfive-donateproject-05\r\nelfive-donateproject-06\r\nelfive-donateproject-07\r\nelfive-donateproject-08\r\nelfive-donateproject-09\r\nelfive-donateproject-10\r\nelfive-donateproject-11\r\nelfive-donateproject-12\r\nelite-ceremony-167205\r\nelite-name-184603\r\nelliptical-flow-195404\r\nelvis-agl\r\nelvis-br\r\nem2qhc\r\nemerald-ellipse-194808\r\nemy3qg\r\nencoded-region-138323\r\nendless-lamp-106710\r\nenduring-button-223912\r\nenduring-coil-186715\r\nenduring-lane-232002\r\neneimenggu\r\nenhanced-gizmo-184213\r\nerdrfn\r\nerdrfn1\r\nerdrfn11\r\nerdrfn111\r\nerdrfn1111\r\nerdrfn11111\r\nersae-181623\r\nersxs-181623\r\nesoteric-accord-201111\r\nesoteric-life-191107\r\nessential-graph-186112\r\nessential-storm-204406\r\nessential-text-146309\r\nessential-truth-189502\r\nessential-wares-239207\r\neternal-coral-228003\r\neternal-empire-188701\r\neternal-impulse-201306\r\neternal-outlook-123504\r\neven-scheduler-192108\r\nevic-197614\r\nevident-etching-208503\r\nevident-theory-186402\r\nexalted-ability-170706\r\nexalted-splicer-221514\r\nexcellent-tide-213002\r\nexemplary-torch-257701\r\nexpanded-genius-243611\r\nf1574559475\r\nf4cj9q\r\nfabled-progress-233214\r\nfackgfw1028\r\nfair-hallway-187002\r\nfaker-166903\r\nfakexijinping\r\nfakezhouyongkang\r\nfamous-charge-123515\r\nfamous-gearing-187002\r\nfan1-143906\r\nfan2-143907\r\nfanfanqiangming\r\nfangqiang-207615\r\nfaniver98\r\nfaniver99\r\nfanqiang161\r\nfashionnew2083st003xt\r\nfavorable-bolt-200303\r\nfavorable-iris-162705\r\nfb0087-1274\r\nfb12011024\r\nfb120110241\r\nfb120110242\r\nfb120110243\r\nfb120110244\r\nfb120110245\r\nfbneimenggu\r\nfeel-1370\r\nfeel-1371\r\nfeisty-current-122813\r\nfeisty-current-170308\r\nfeisty-reporter-207606\r\nferrous-depth-215910\r\nfestive-radar-210100\r\nfestive-tiger-237602\r\nfffffffff-142308\r\nfgdhsjak12345\r\nfgdhsjak132\r\nfgrtd-1\r\nfiery-iridium-187212\r\nfifth-being-127312\r\nfire201401\r\nfirecola1\r\nfirm-vertex-228514\r\nfirst-10001\r\nfirst-73017\r\nfirst-hearth-192112\r\nfirst-planet-243106\r\nfirst-tine-148607\r\nfirst-tracer-242006\r\nfit-asset-215910\r\nfit-authority-231609\r\nfive-10005\r\nfixyou-158112\r\nfk-xxnet-01\r\nfk-xxnet-02\r\nfk-xxnet-03\r\nfk-xxnet-04\r\nflash-cache-186402\r\nflash-moonlight-123504\r\nflash-moonlight-123803\r\nflash-sol-225607\r\nfleet-acumen-214609\r\nfleet-muse-143000\r\nfluent-ego-212910\r\nfluid-brook-212406\r\nfluid-fiber-170209\r\nfluted-ranger-188715\r\nflygaes1\r\nfms-test-171708\r\nfneimenggu\r\nfnshiwu21\r\nfnshiwu22\r\nfnshiwu23\r\nfnshiwu24\r\nfocal-charge-127023\r\nfocused-outlook-198215\r\nfolkloric-stone-123514\r\nfor-friends\r\nfor-yaya\r\nformal-branch-258214\r\nformal-landing-171813\r\nformidable-gate-214906\r\nformidable-pact-221514\r\nforusa2021\r\nforward-pad-123803\r\nforward-scion-152204\r\nforward-server-109414\r\nforxxnet-156508\r\nforxxnet-156508a\r\nforxxnet-156508b\r\nforxxnet-156508c\r\nforxxnet-156508d\r\nforxxnet-156508e\r\nforxxnet-156508f\r\nforxxnet-156508g\r\nforxxnet-156508h\r\nforxxnet-156508i\r\nforxxnet-156508j\r\nforxxnet-156508k\r\nfour-10004\r\nfourth-caster-186402\r\nfourth-library-188412\r\nfourth-walker-123515\r\nfoxpro-001\r\nfoxpro-002\r\nfoxpro-003\r\nfoxpro-004\r\nfoxpro-005\r\nfoxpro-006\r\nfoxpro-007\r\nfoxpro-008\r\nfoxpro-009\r\nfoxpro-259503\r\nfqlbshen\r\nfqlbshenv2\r\nfqlbshenv3\r\nfqrote1\r\nfqrote2\r\nfqrote3\r\nfqrote4\r\nfree-227202\r\nfree1-227202\r\nfree198228\r\nfreedom-00005\r\nfreeyangzhihui10\r\nfreeyangzhihui11\r\nfreeyangzhihui12\r\nfreeyangzhihui6\r\nfreeyangzhihui7\r\nfreeyangzhihui8\r\nfreeyangzhihui9\r\nfresh-arcade-208808\r\nfresh-forest-243513\r\nfresh-media-186103\r\nfresh-oath-164207\r\nfresh-ward-162011\r\nfriendly-magnet-168105\r\nfrog-pig\r\nfuba088-1274\r\nfucjeektd\r\nfupengnet1\r\nfupengnet2\r\nfupnet3\r\nfupnet4\r\nfupnet5\r\nfupnet6\r\nfupnet7\r\nfupnet8\r\nfuture-area-163914\r\nfuture-synapse-123514\r\nfuyexifei9\r\nfzong-1108\r\nfzong-1114\r\nfzongaaa\r\nfzongbbb\r\nfzongccc\r\nfzongfff\r\nfzongggg\r\nfzonghhh\r\nfzongjjj\r\nfzongkkkk-1114\r\nfzongmmm\r\nfzongnnn\r\nfzongsss\r\nfzongxcf\r\nfzongxxx\r\nfzy930\r\ng-1222\r\ngaedonate001\r\ngaedonate002\r\ngaedonate003\r\ngaedonate01\r\ngaedonate02\r\ngaedonate03\r\ngaedonate04\r\ngaedonate05\r\ngaeproxy-1336\r\ngaewb14\r\ngaewb141\r\ngaewb142\r\ngaewb143\r\ngaewb144\r\ngaewb145\r\ngaewb146\r\ngaewb147\r\ngaewb148\r\ngaewb149\r\ngalvanized-case-123515\r\ngalvanized-case-170706\r\ngap7b01\r\ngap7b02\r\ngap7b03\r\ngap7b04\r\ngap7b05\r\ngap7b06\r\ngap7b07\r\ngap7b08\r\ngap7b09\r\ngap7b10\r\ngap7b11\r\ngap7b12\r\ngap7b13\r\ngap7b14\r\ngap7b15\r\ngap7b16\r\ngap7b17\r\ngap7b18\r\ngap7b19\r\ngap7b20\r\ngate-188212\r\ngbneimenggu\r\ngcdsb3\r\ngcdsb4\r\ngcdsb6\r\ngcdsb7\r\ngcdsb8\r\ngdl-go1\r\ngdl-go2\r\ngdl-go3\r\ngdl-go4\r\ngdl-go5\r\ngdl-go6\r\ngdq207590122\r\ngdswcom1\r\ngdswcom2\r\ngdswcom3\r\ngenial-cycling-192108\r\ngenial-reporter-184705\r\ngenial-stage-217017\r\ngenuine-essence-174401\r\ngeometric-hull-142604\r\ngeometric-shine-181213\r\ngeometric-vim-232002\r\ngetout-share\r\ngfw-yes01\r\ngfw10-175208\r\ngfw10-179913\r\ngfw11-179913\r\ngfw6-179913\r\ngfw7-179913\r\ngfw8-179913\r\ngfw9-179913\r\ngfwed-1\r\ngfwed-10\r\ngfwed-11\r\ngfwed-12\r\ngfwed-152305\r\ngfwed-169300\r\ngfwed-2\r\ngfwed-3\r\ngfwed-4\r\ngfwed-5\r\ngfwed-6\r\ngfwed-7\r\ngfwed-8\r\ngfwed-9\r\ngfwfighter001\r\ngfwfighter002\r\ngfwfighter003\r\ngfwfighter004\r\ngfwfighter005\r\ngfwfighter006\r\ngfwfighter007\r\ngggggggggg-142308\r\nggttd2-1158\r\ngh778-189715\r\nghq214101\r\nghq214201\r\nghq214301\r\nghq214401\r\nghq214501\r\nghq214601\r\nghq214701\r\nghq214801\r\nghq214901\r\nghr-65\r\ngifted-veld-214609\r\nglass-scanner-167416\r\nglass-stratum-162012\r\nglassy-keyword-859\r\nglassy-vial-122813\r\nglossy-monitor-188715\r\nglowing-baton-258917\r\ngneimenggu\r\ngoagent-157515\r\ngoagent-freeweb\r\ngoagent1-996\r\ngoagent10-157607\r\ngoagent11-157607\r\ngoagent2-157607\r\ngoagent2109\r\ngoagent3-157607\r\ngoagent4-157607\r\ngoagent5-157607\r\ngoagent6-157607\r\ngoagent7-157607\r\ngoagent9955\r\ngoagentunderwood\r\ngoagentv320g\r\ngoagentv320h\r\ngoagentv320i\r\ngoagentv320j\r\ngoagentxx1\r\ngodlikejjyy\r\ngodlovevpn\r\ngodlovevpn2\r\ngodlovevpn2-169003\r\ngodlovevpn3\r\ngodlovevpn3-169003\r\ngodness-149611\r\ngogo-1292\r\ngold-chess-208703\r\ngold-gearbox-209903\r\ngold-mode-142708\r\ngolden-imprint-188912\r\ngoogae005\r\ngoproj-177307\r\ngoproxy-a\r\ngoproxy-b\r\ngoproxy-c\r\ngplin1991-188809\r\ngr45-8\r\ngraceful-castle-206711\r\ngraceful-ratio-242006\r\ngrand-bridge-215910\r\ngraphic-theory-125209\r\ngraphical-bus-221514\r\ngraphical-bus-232304\r\ngreatgfw4\r\ngree-20125\r\ngree-20126\r\ngree-20127\r\ngree-20128\r\ngree-20129\r\ngreen-154700\r\ngroovy-design-187913\r\ngroovy-patrol-122814\r\ngroovy-reserve-256906\r\ngrwaitting-244303\r\ngrwaitting10\r\ngrwaitting11\r\ngrwaitting3\r\ngrwaitting5\r\ngrwaitting6\r\ngrwaitting7\r\ngrwaitting8\r\ngrwaitting9\r\ngrwatting2\r\nguogoagent06\r\nguojian0822\r\nguoyangdominating\r\nguweishi2b\r\nguxizhao1\r\nguxizhao10\r\nguxizhao11\r\nguxizhao12\r\nguxizhao13\r\nguxizhao14\r\nguxizhao2\r\nguxizhao4\r\nguxizhao5\r\nguxizhao6\r\nguxizhao7\r\nguxizhao8\r\ngxfagent3\r\nhaha-1007\r\nhahaneimenggu\r\nhahazhej\r\nhalfpaid\r\nhalfpaid-167105\r\nhalogen-goods-243016\r\nhalogen-premise-167105\r\nhandatouftvpn\r\nhanxiao-148607\r\nhaodee-146208\r\nhaolen-1805\r\nhaolen-1806\r\nhaolen-1807\r\nhaolen-1808\r\nhaolen-1809\r\nhardy-thinker-213501\r\nhasaki-187702\r\nhawyrihby\r\nhazel-quanta-186402\r\nhbkechen001\r\nhbkechen002\r\nhbkechen003\r\nhbkechen004\r\nhbkechen005\r\nhbkechen006\r\nhbkechen007\r\nhbkechen008\r\nhbkechen009\r\nhbkechen010\r\nhbkechen011\r\nhbkechen012\r\nhbneimenggu\r\nhealthy-bonsai-240209\r\nhealthy-highway-125209\r\nhealthy-life-180703\r\nhealthy-wares-202206\r\nhealthy-zone-237305\r\nheihei-1183\r\nhelical-beaker-187715\r\nhelical-indexer-187508\r\nhelical-land-133123\r\nhelical-study-257701\r\nhello-b9a3c\r\nhelloworld-140114\r\nhelloworld-165114\r\nhelloworld-187709\r\nhelloworld1-187615\r\nhelloworld10-188607\r\nhelloworld11-188607\r\nhelloworld4-187615\r\nhelloworld6-187615\r\nhelloworld7-187615\r\nhelloworld8-187615\r\nhelloworld9-188607\r\nhelpful-ally-123514\r\nhelpful-ally-133123\r\nhelpful-quanta-170209\r\nhelpful-reactor-205203\r\nhendry001-154114\r\nhengye-1270\r\nhepeng5970\r\nhepeng59700\r\nhfldnt00\r\nhfldnt01\r\nhfldnt02\r\nhfldnt03\r\nhfldnt04\r\nhfldnt05\r\nhfldnt06\r\nhfldnt07\r\nhfldnt08\r\nhfldnt09\r\nhfldnt10\r\nhfldnt11\r\nhhhhh-144412\r\nhhhhh19910926\r\nhhhhhh-144412\r\nhhhhhhhh-142308\r\nhidden-solstice-229902\r\nhimon-20172\r\nhimon-20173\r\nhimon-20174\r\nhip-fusion-224007\r\nhip-spanner-235306\r\nhixcjj\r\nhl150423175\r\nhmsfeng20\r\nhome-149008\r\nhome1-175814\r\nhonkerjha003\r\nhonkerjha004\r\nhonkerjha005\r\nhonkerjha006\r\nhorizontal-ring-133123\r\nhouhou-1183\r\nhouweixiao9\r\nhuangzhengjun4\r\nhuangzhengjun6\r\nhuangzhengjun7\r\nhuangzhengjun8\r\nhuangzhengjun9\r\nhuyubo1\r\nhuyubo11\r\nhuyubo12\r\nhuyubo13\r\nhuyubo2-150311\r\nhuyubo3\r\nhuyubo4\r\nhuyubo6\r\nhuyubo7\r\nhuyubo8\r\nhxd-project02\r\nhybrid-text-170706\r\nhypdreamandlove\r\nhypdreamandlove1\r\nhypdreamandlove2\r\nhypdreamandlove3\r\nhypdreamandlove4\r\nhypdreamandlove5\r\nhypdreamandlove6\r\nhypdreamandlove7\r\nhypdreamandlove8\r\nhypdreamandlove9\r\nhypnotic-guard-177622\r\nhzc-net10\r\nhzc-net9\r\nhzjxxnet01d\r\nhzjxxnet01e\r\nhzjxxnet01f\r\nhzjxxnet01g\r\nhzjxxnet01h\r\nhzjxxnet01i\r\nhzjxxnet01j\r\nhzjxxnet01k\r\nhzjxxnet01l-1273\r\ni-beaker-189715\r\ni-condition-232603\r\ni-freedom-205914\r\niaeegdj10\r\nibneimenggu\r\nicean1025\r\nidyllic-aspect-231106\r\nigneous-primacy-192906\r\nigneous-study-197708\r\nilinxi-0001\r\nilinxi-0002\r\nilinxi-0003\r\nilinxi-0004\r\nilinxi-0005\r\nimacatt-1470053327056\r\nimadog-1470053319075\r\nimperial-glyph-123514\r\nimperial-signer-226806\r\nimport-187703\r\nimposing-cinema-215910\r\ninbound-fulcrum-207606\r\ninbound-lattice-213503\r\ninbound-pattern-227309\r\nindigo-plate-215910\r\ninfra-ratio-127310\r\ninfra-sublime-233214\r\ninfra-window-190710\r\ninnate-octagon-120813\r\ninnate-summit-123514\r\ninner-autonomy-183914\r\ninner-legacy-186402\r\nintegral-glass-257701\r\nintegral-surfer-249613\r\nintense-nexus-189703\r\nintense-pointer-236313\r\ninvoluted-reach-107908\r\niron-area-123514\r\niron-potion-142510\r\nironic-objectivist-233214\r\nisaac-12\r\nisentropic-road-146309\r\nivan-shu\r\nivanshuchen\r\niview-65949\r\nivory-partition-137323\r\nivory-volt-242306\r\niwantto-184200\r\niyft-hws150\r\njackcp9-19930218-10\r\njackcp9-19930218-11\r\njackcp9-19930218-7\r\njackcp9-19930218-8\r\njackcp9-19930218-9\r\njackey001-1181\r\njackieqqh\r\njackieqqh01\r\njackieqqh02\r\njackieqqh03\r\njackieqqh04\r\njackieqqh05\r\njackieqqh06\r\njackieqqh07\r\njackieqqh08\r\njackshao101\r\njackshao102\r\njames-goagent21\r\njames-goagent22\r\njames-goagent23\r\njames-goagent24\r\njames-goagent25\r\njameswang-196304\r\njazuwisa27\r\njeffluo35\r\njemmibo2\r\njemmibo3\r\njhgkf-232603\r\njia4-166810\r\njiangyue111222\r\njiangzemindashab2\r\njingtao-001\r\njiuaiping\r\njiustsos\r\njoehello-218304\r\njoeljoel-174906\r\njoeljoel-183810\r\njohnnnn-1470053192524\r\njohntongoagentpublic2\r\njonewangzai\r\njoson-167406\r\njosonchan-167220\r\njuanxian-0001\r\njuanxian-0002\r\njuanxian-0003\r\njuanxian-0004\r\njuanxian-0005\r\njuanxian-0006\r\njuanxian-0007\r\njuanxian-0008\r\njuanzeng-1\r\njuanzeng-10\r\njuanzeng-11\r\njuanzeng-12\r\njuanzeng-13\r\njuanzeng-14\r\njuanzeng-15\r\njuanzeng-2\r\njuanzeng-3\r\njuanzeng-4\r\njuanzeng-5\r\njuanzeng-6\r\njuanzeng-7\r\njuanzeng-8\r\njuanzeng-9\r\njuly1-1383\r\njuqn-67440\r\njust-duality-226602\r\njustatest-1470053639545\r\njw-xxnet002\r\njxsj-123654\r\njygxxnet0145\r\njz1-1234567\r\njz3-1234567\r\njz4-1234567\r\njz5-1234567\r\njzid-191123\r\njzxm01-142511\r\njzxm02\r\nkeecolite\r\nkeecolite1\r\nkeecolite2\r\nkeecolite3\r\nkeecolite4\r\nkeecolite5\r\nkeecolite6\r\nkeecolite7\r\nkeecolite8\r\nkeecolite9\r\nkeen-device-151402\r\nkevin1990-191616\r\nkevinyang-191616\r\nkexueshangwang12-158014\r\nkey-affinity-859\r\nkey-chalice-192704\r\nkey-prism-207507\r\nkfeimaro6\r\nkhan-1134\r\nkillgfw-004\r\nkillgfw-005\r\nkillgfw-006\r\nkillgfw-007\r\nkillgfw-008\r\nkillgfw-009\r\nkillgfw-010\r\nkillgfw-011\r\nkillgfw-012\r\nkimpaygoa\r\nkinetic-center-197409\r\nkinetic-cosmos-159409\r\nkingdog807\r\nkingdog808\r\nkingdog818\r\nkingdog828\r\nkingdog838\r\nkingdog858\r\nkingdog868\r\nkingdog878\r\nkingdog898\r\nkingdog899\r\nkingdog910\r\nkingdog912\r\nkingdog913\r\nkingdog914\r\nkingdog915\r\nkingdog916\r\nkingdog918\r\nkingdog919\r\nkingmax-1245\r\nkinopakuyumen\r\nkiss4-201914\r\nkk92fortune001\r\nkk92fortune002\r\nkk92fortune003\r\nkk92fortune004\r\nkk92fortune005\r\nkk92fortune006\r\nkk92fortune007\r\nkk92fortune008\r\nkk92fortune009\r\nkk92fortune010\r\nkouyt-232603\r\nksdcjf\r\nksmksm7900-01\r\nkt-1001\r\nkuailezhaoze\r\nkuailezhaoze01\r\nkuailezhaoze101\r\nkuailezhaoze102\r\nkuailezhaoze103\r\nkuailezhaoze104\r\nkuailezhaoze105\r\nkurisu-190106\r\nkwanlily-146010\r\nkwchen-208615\r\nkxsw-88888801\r\nkxsw-88888802\r\nkxsw-88888803\r\nkxsw-88888804\r\nkxsw-88888805\r\nkxsw-88888806\r\nkxsw-88888807\r\nkxsw-88888808\r\nkxsw-88888809\r\nkxsw-88888810\r\nkyo9950\r\nkzsj-xx-net-06\r\nkzsj-xx-net-07\r\nkzsj-xx-net-08\r\nkzsj-xx-net-09\r\nkzsj-xx-net-10\r\nlady-160402-1\r\nlady-160402-10\r\nlady-160402-12\r\nlala-1183\r\nlateral-booster-232002\r\nlateral-concord-187913\r\nlateral-faculty-205006\r\nleafy-environs-142014\r\nleafy-ripsaw-151605\r\nlearned-cosine-208808\r\nlearned-house-143412\r\nlearned-iris-188715\r\nleejaewan-166903\r\nleidilldd1\r\nleidilldd10\r\nleidilldd11\r\nleidilldd12\r\nleidilldd13\r\nleidilldd14\r\nleidilldd15\r\nleidilldd16\r\nleidilldd17\r\nleidilldd18\r\nleidilldd19\r\nleidilldd2\r\nleidilldd20\r\nleidilldd21\r\nleidilldd22\r\nleidilldd23\r\nleidilldd24\r\nleidilldd25\r\nleidilldd3\r\nleidilldd4\r\nleidilldd5\r\nleidilldd6\r\nleidilldd7\r\nleidilldd8\r\nleidilldd9\r\nleonproject10\r\nleonproject11\r\nleospublicid13\r\nleospublicid14\r\nleospublicid15\r\nleospublicid16\r\nleospublicid17\r\nleospublicid18\r\nleowlong1989s8\r\nlexical-botany-192906\r\nlgnativs07\r\nlgnativs08\r\nlgnativs09\r\nliangaa2net\r\nliangaa2net-187503\r\nliangaanet-187502\r\nlichangmao08\r\nlidegang11231\r\nlidegang11232\r\nlight-ether-147016\r\nlihuacai6\r\nlihuacai7\r\nlihuacai9\r\nlihuacaiabc\r\nlijiesherlcok\r\nlilhoe10\r\nlilhoe11\r\nlilhoe1111\r\nlilhoe22\r\nlilhoe222\r\nlilhoe33\r\nlilhoe66\r\nlilhoe77\r\nlilhoe88\r\nlilhoe99-1229\r\nlilhoea1\r\nlinear-axle-186502\r\nlinear-ether-244611\r\nlinear-facet-168013\r\nlinear-reporter-191716\r\nlinfenpark-1111\r\nlinfenpark-1112\r\nlinfenpark-1114\r\nlinfenpark-1115\r\nlinfenpark-1116\r\nlinfenpark-1117\r\nlinfenpark-1118\r\nlinfenpark-1252\r\nlingdaode\r\nlinux1-166406\r\nlinworld671\r\nlinworld672\r\nlinworld673\r\nlinworld674\r\nlinworld675\r\nlinworld676\r\nlinworld677\r\nlinworld678\r\nlinworld679\r\nlinworld680\r\nlionchinala\r\nlionchinaxxx\r\nlionkobeseeme\r\nlionseekobe\r\nliqinna0\r\nliqinna1\r\nliqinna2\r\nliqinna3\r\nliqinna4\r\nliqinna5\r\nliqinna6\r\nliqinna7\r\nliqinna8\r\nliqinna9\r\nliquid-journal-227309\r\nlithe-camp-177104\r\nlithe-saga-214609\r\nlithe-style-242711\r\nliuchenfang1\r\nliuchenfang2\r\nliujianmao-1\r\nliujianmao-2\r\nliuli0-140401\r\nliumangtu147853447\r\nliushappy\r\nliushope\r\nliuxiaobo-1104\r\nliuxiaobo1-1384\r\nliuxiaobo2-1384\r\nliuxiaobo3\r\nliuxiaobo4-1384\r\nliuxiaobo5-1384\r\nliuxiaobo6-1384\r\nliuxiaobo7-1384\r\nliuxiaobo8-1384\r\nliuxiaobo9-1384\r\nlively-armor-181018\r\nliy-pay-153300\r\nliy-soft-153301\r\nliy-zone-153208\r\nliyafang-project2\r\nliyisn020\r\nliyuankai82\r\nliyuankai83\r\nliyuankai85\r\nliyuankai86\r\nliyuankai87\r\nliyuankai88\r\nliyuankai89\r\nliyuankai90\r\nliyuankai91\r\nlizhaodong199026\r\nlizhaodong199126\r\nljf01-233906\r\nljy-xx-net\r\nlocal-chalice-192906\r\nlofty-bolt-859\r\nlofty-dynamics-189703\r\nlokkingg-1470053234347\r\nlonely-bbs\r\nlonely-sex\r\nlonelyzf\r\nlonghaofeixia\r\nlookeecbb\r\nloopback-001\r\nloyal-manifest-187602\r\nlszy-157702\r\nluchia011-1218\r\nluchia012-1218\r\nlucid-course-191201\r\nlucid-sweep-123514\r\nlucid-sweep-192515\r\nlucky-apparatus-213002\r\nluisfly-1\r\nluisfly-2\r\nluluxi-182315\r\nlumia1-163910\r\nlumia10-163910\r\nlumia2-163910\r\nlumia3-163910\r\nlumia4-163910\r\nlumia5-163910\r\nlumia6-163910\r\nlumia7-163910\r\nlumia8-163910\r\nlumia9-163910\r\nluoke90hou\r\nluoke91hou\r\nluoke92hou\r\nluoke93hou\r\nlxdfanqiang10\r\nlxdfanqiang11\r\nlxdfanqiang12\r\nlypproxy\r\nlzlofjo10\r\nlzlofjo11\r\nlzr001\r\nlzr002\r\nlzr003\r\nlzr004\r\nlzr005\r\nlzr006\r\nlzr007\r\nlzr008\r\nlzr009\r\nlzxx0112\r\nlzxx0113\r\nlzxx20150109\r\nmacro-resolver-187502\r\nmadalice0226a124bd\r\nmadalice0226a2c85b\r\nmadalice0226b2d5df\r\nmadalice0226b7699d\r\nmagnetic-gadget-215410\r\nmagnetic-hawk-233509\r\nmagnificent-pen-221514\r\nmain-byte-185802\r\nmain-duality-159813\r\nmajestic-fuze-196917\r\nmakegame\r\nmakelshadow3103d46\r\nmakelshadow32e70fd\r\nmakelshadow3334424\r\nmakelshadow337ade8\r\nmakelshadow33eed47\r\nmakelshadow35cbb2d\r\nmakelshadow37ca0bb\r\nmakelshadow38beb87\r\nmakelshadow38c57ae\r\nmakelshadow3cfde6a\r\nmakrse-1470053659892\r\nmama-208615\r\nmanatsu3115a\r\nmanatsu3115b\r\nmanatsu3115d\r\nmanifest-altar-123515\r\nmanifest-quasar-214609\r\nmarine-defender-182008\r\nmarkwang11111\r\nmarkwang11112\r\nmarkwang11116\r\nmarkwang1112\r\nmarkwang112\r\nmarxist-2017\r\nmasko1-977\r\nmasko2-977\r\nmasko3-977\r\nmasko4-977\r\nmassive-hexagon-164205\r\nmassive-tensor-107908\r\nmaster-bulwark-159814\r\nmaster-charmer-138323\r\nmaster-tuner-191112\r\nmathsunhonglin-001\r\nmathsunhonglin-002\r\nmathsunhonglin-003\r\nmathsunhonglin-004\r\nmathsunhonglin-005\r\nmathsunhonglin-006\r\nmathsunhonglin-1283\r\nmaximal-ascent-184212\r\nmaximal-furnace-189008\r\nmaximal-window-209014\r\nmayx160407\r\nmayx160408\r\nmayx160409\r\nmayx160410\r\nmayx160411\r\nmayx160412\r\nmeaveric\r\nmechbug-1\r\nmechbug-2\r\nmechbug-3\r\nmechbug-4\r\nmei66-165709\r\nmei67-165709\r\nmei68-165709\r\nmei69-165709\r\nmeilidewo-142514\r\nmengxian-186203\r\nmercurial-idiom-197708\r\nmeta-altar-181522\r\nmetal-seeker-211015\r\nmetleau\r\nmetleau01\r\nmetleau02\r\nmetleau04\r\nmetorm-anti-gfw\r\nmexzn01\r\nmexzn02\r\nmexzn03\r\nmexzn04\r\nmexzn05\r\nmexzn06\r\nmexzn07\r\nmexzn08\r\nmexzn09\r\nmfk55555\r\nmfk555555\r\nmfsz-001\r\nmianyang621005\r\nmianyang621006\r\nmichael-160410\r\nmickweb-1\r\nmickweb-2\r\nmickweb-3\r\nmicro-cacao-140616\r\nmicro-cacao-215910\r\nmidyear-choir-227609\r\nmidyear-cursor-184318\r\nmidyear-machine-148607\r\nmig2999djproxy4\r\nmig2999djproxy5\r\nmig2999djproxy6\r\nmindful-ship-188705\r\nmindfulness-174001\r\nmltx-00010101\r\nmm0909-1247\r\nmodel-arcadia-177513\r\nmodel-cirrus-859\r\nmodern-alpha-177622\r\nmodular-tube-244203\r\nmolten-position-257701\r\nmolten-sandbox-170211\r\nmolten-topic-208615\r\nmona1-190308\r\nmona2-190308\r\nmona3-190308\r\nmona4-190308\r\nmona5-190308\r\nmoonlit-byway-205004\r\nmoonlit-creek-151605\r\nmoonlit-rock-174804\r\nmosexegae12\r\nmoshengrenw2\r\nmp-wlw101\r\nmp-wlw102\r\nmp-wlw103\r\nmp-wlw104\r\nmp-wlw105\r\nmp0009-1275\r\nmphuang2008\r\nmphuang2009\r\nmxx711-1274\r\nmxxnettestid1\r\nmxxnettestid2\r\nmxxnettestid3\r\nmxxnettestid4\r\nmxxnettestid5\r\nmy-appid-10-227013\r\nmy-appid-111-227013\r\nmy-appid-12-227013\r\nmy-appid-7-227013\r\nmy-appid-8-227013\r\nmy-appid-9-227013\r\nmy-appid-name\r\nmy-application-01-01\r\nmy-application-02-02\r\nmy-application-03-03\r\nmy-application-04-04\r\nmy-application-05-05\r\nmy-application-06-06\r\nmy-application-07-07\r\nmy-application-08-08\r\nmy-application-09-09\r\nmy-application-10-10\r\nmy-application-11-11\r\nmy-application-12-12\r\nmy-mcc5\r\nmy-phpliang537617\r\nmy-project-002-1262\r\nmy-project-002-148912\r\nmy-project-005-1262\r\nmy-project-011-1332\r\nmy-project-012-1332\r\nmy-project-013-1332\r\nmy-project-014-1332\r\nmy-project-016-1332\r\nmy-project-017-1332\r\nmy-project-018\r\nmy-project-019-1332\r\nmy-project-020-1332\r\nmy-project-021\r\nmy-project-022\r\nmy-project-023\r\nmy-project-024\r\nmy-project-025\r\nmy-project-026\r\nmy-project-027\r\nmy-project-028\r\nmy-project-029\r\nmy-project-1-151403\r\nmy-project-10-1470318399543\r\nmy-project-10-151606\r\nmy-project-10-157123\r\nmy-project-10-177514\r\nmy-project-11-1331\r\nmy-project-11-156439\r\nmy-project-11-157123\r\nmy-project-11-173001\r\nmy-project-11-177514\r\nmy-project-12-172010\r\nmy-project-12-177514\r\nmy-project-14-1332\r\nmy-project-15-1332\r\nmy-project-1539253515081\r\nmy-project-16-1332\r\nmy-project-16-1469791357104\r\nmy-project-17-1332\r\nmy-project-17-1469791366911\r\nmy-project-18-1469791544968\r\nmy-project-19556\r\nmy-project-2-147016\r\nmy-project-2-155001\r\nmy-project-2-157122\r\nmy-project-20161007-1\r\nmy-project-2017-12-22-1\r\nmy-project-2017-12-22-2\r\nmy-project-2017-12-22-3\r\nmy-project-2017-12-22-4\r\nmy-project-2017-12-22-5\r\nmy-project-2017-12-22-6\r\nmy-project-2017-12-22-7\r\nmy-project-2017-12-22-7-189808\r\nmy-project-2017-12-22-8\r\nmy-project-3-1469883794714\r\nmy-project-3-157122\r\nmy-project-3-168017\r\nmy-project-3-243106\r\nmy-project-30-1332\r\nmy-project-4-157122\r\nmy-project-4-164609\r\nmy-project-4-168017\r\nmy-project-4-170210\r\nmy-project-4-243106\r\nmy-project-4172-249613\r\nmy-project-5-157122\r\nmy-project-5-170706\r\nmy-project-524-185314\r\nmy-project-57690-juan-xian\r\nmy-project-597520\r\nmy-project-597521\r\nmy-project-597522\r\nmy-project-597523\r\nmy-project-597524\r\nmy-project-597525\r\nmy-project-597526\r\nmy-project-597527\r\nmy-project-597528\r\nmy-project-597529\r\nmy-project-6-1470318197921\r\nmy-project-6-157122\r\nmy-project-6-170706\r\nmy-project-6-243106\r\nmy-project-7-1470318242557\r\nmy-project-7-157122\r\nmy-project-7-170706\r\nmy-project-7-243106\r\nmy-project-8-1470318289690\r\nmy-project-8-157122\r\nmy-project-8-170706\r\nmy-project-9-1470318330078\r\nmy-project-9-157123\r\nmy-project-9-194714\r\nmy-project-946-189702\r\nmy-project-for-first\r\nmy-project-hzjxxnet01\r\nmy-project-hzjxxnet01b\r\nmy-project-hzjxxnet01c\r\nmy-project-liu1\r\nmy-project-liu10\r\nmy-project-lxh\r\nmy-project-of-ladder-10\r\nmy-project-xx-net-186203\r\nmy-project-xx-net2-183913\r\nmy-project-xxnet1-183914\r\nmy-project-xxnet3-183914\r\nmy-project-xxnet4-183914\r\nmy-project10-1337\r\nmy-project10-223908\r\nmy-project10503\r\nmy-project11-1337\r\nmy-project111222-153713\r\nmy-project12-1337\r\nmy-project13-1332\r\nmy-project13-1337\r\nmy-project14-1332\r\nmy-project14-1337\r\nmy-project190307\r\nmy-project1996-145807\r\nmy-project2-223908\r\nmy-project3-223908\r\nmy-project3-237503\r\nmy-project4-223908\r\nmy-project5-223908\r\nmy-project6-223908\r\nmy-project7-1273\r\nmy-project7-223908\r\nmy-project8-1273\r\nmy-project8-223908\r\nmy-project9-1273\r\nmy-project9-1337\r\nmy-project9-223908\r\nmy-time-123\r\nmy-vpn-188308\r\nmy-vpn-2-188409\r\nmy-vpn-3-188409\r\nmy-vpn-4-xx-net\r\nmy-wall-154700\r\nmy-xx-net-226203\r\nmy-xxnet-21076\r\nmy-xxnet-21077\r\nmy-xxnet-21078\r\nmy-xxnet-21079\r\nmy-xxnet-21080\r\nmy-xxnet-21081\r\nmy-xxnet-21082\r\nmy-xxnet-21083\r\nmy-xxnet-21084\r\nmy-xxnet-21085\r\nmy-xxnet-21086\r\nmy-xxnet001-171613\r\nmy-xxnet002-171614\r\nmy2017project04\r\nmy2017project05\r\nmy20180501\r\nmy20180502\r\nmy20180503\r\nmy20180504\r\nmy20180505-203901\r\nmyappid-20124443\r\nmyappid-ikuta1997\r\nmyappid-ikutaerika\r\nmyappid-lee20124443\r\nmyappid-xxnet-226713\r\nmyappid1-142508\r\nmycloud201706242\r\nmydonate1\r\nmydonate2\r\nmydonate3\r\nmydonate4\r\nmyfanqianone\r\nmygoagent1-1226\r\nmygoagent2-1226\r\nmygoagent3-1364\r\nmykeai-189715\r\nmymap-225908\r\nmynet5-165000\r\nmynet6-165000\r\nmyproject-223911\r\nmyproject-5101162\r\nmyproject-europe-west\r\nmyproject-liu01\r\nmyproject-liu02\r\nmyproject-liu03\r\nmyproject-liu04\r\nmyproject-liu05\r\nmyproject-liu06\r\nmyproject04-247802\r\nmyproject1-223908\r\nmyproject12-244314\r\nmyproject13-244401\r\nmyproject14-244401\r\nmyproject15\r\nmyproject16\r\nmyproject17-244401\r\nmyproject18\r\nmyproject19-244401\r\nmyproject20\r\nmyproject21-244401\r\nmyproject22-244401\r\nmyproject23-244401\r\nmyproject24\r\nmyproject25\r\nmyproject26-244406\r\nmyproject27\r\nmyproject28\r\nmyproject9511114\r\nmystic-creek-107908\r\nmythical-height-225406\r\nmyxxnet-1264\r\nmyxxnet1-1285\r\nmyxxnet1-197814\r\nmyxxnet2-1285\r\nmyxxnet2-197814\r\nmyxxnet3-1285\r\nmyxxnet4-1285\r\nmyxxnetprojectfordonate-1\r\nmyxxnetprojectfordonate-2\r\nname1-156514\r\nname2-156514\r\nname3-156514\r\nname4-156514\r\nname5-156514\r\nname6-156514\r\nname7-156514\r\nnamed-dialect-208808\r\nnamed-inn-197708\r\nnanj987-1274\r\nnanxijw-xxnet01\r\nnarutobm123\r\nnarutobm1234\r\nnarutonbm123\r\nnarutonbm1234\r\nnasxxnet\r\nnasxxnet1\r\nnbjncknla\r\nneat-bliss-123313\r\nneat-bricolage-218008\r\nneat-vent-149203\r\nneon-circle-226806\r\nneon-feat-211015\r\nneon-trilogy-188809\r\nnet-1111\r\nnet-246615\r\nnet-3-162407\r\nnet-ex\r\nnet-lovely\r\nnet04-185713\r\nnet05-187603\r\nnet123-226713\r\nnet2-226804\r\nnet3-226804\r\nnetproject1-196801\r\nnetproject2-196802\r\nnetproject3-196802\r\nnetproject4-196802\r\nnetproject5-196802\r\nnetproject6-196802\r\nnetview-141308\r\nnetweb-agent2\r\nnetx-231408\r\nnetx1-231408\r\nnetx2-231408\r\nnetx4-231408\r\nnetx5-231408\r\nnetx6-231408\r\nnetx7-231408\r\nnetx8-231408\r\nnetx9-231408\r\nnetxa-231408\r\nnetxb-231408\r\nnetxc-231408\r\nnetxx-199505\r\nnetxx-2-199505\r\nnetxx-3-199505\r\nnetxx-5691aa\r\nnetz-243307\r\nneural-hour-189703\r\nneural-ripple-146309\r\nneural-tome-123515\r\nnewland-170315\r\nnewlife-170315\r\nnewlove-170315\r\nnewproxy-185211\r\nnewweb-159812\r\nniangniub\r\nnianguib\r\nnianguuib\r\nnice-azimuth-123514\r\nnico-166707\r\nnifty-altar-184200\r\nnifty-artwork-170209\r\nnightfuryfordou6\r\nnightfuryfordou7\r\nnightfuryfordou8\r\nnikitamas66\r\nnikitamas77\r\nnikitamas99\r\nnikitmas88\r\nnimble-host-191708\r\nning123-161106\r\nningerte001\r\nningerte002\r\nningerte003\r\nningerte01\r\nningerte01-221312\r\nningerte02\r\nningerte04\r\nningerte05\r\nninoleee2\r\nninoleee3\r\nninth-iris-232002\r\nnjbh-88\r\nnjh19900608\r\nnjh19901120\r\nnjh19901121\r\nnjh19901122\r\nnjh19901123\r\nnjh19901124\r\nnjh19901125\r\nnjh19901126\r\nnjh19901127\r\nnjh19901128\r\nnjh19901129\r\nnjh420974489\r\nnjh869084221\r\nnkatfree20\r\nnmb48keila\r\nnoble-trees-206114\r\nnodal-deck-178706\r\nnodal-element-217505\r\nnodal-operand-200408\r\nnomadic-archway-234904\r\nnorse-wavelet-233015\r\nnoted-tide-217505\r\nnth-theater-225607\r\nnudt-toronto10\r\nnumeric-button-249613\r\nnvbmj-189715\r\nnxiaobin-2015\r\nnxiaobin-2016\r\nnxiaobin-2017\r\nnxiaobin-2018\r\nnxiaobin-2019\r\nobserver20120904\r\nobserver20121031\r\noctodile-pus01\r\noctodile-pus02\r\noctodile-pus03\r\noctodile-pus04\r\noctodile-pus05\r\noctodile-pus07\r\noctodile-pus08\r\noctodile-pus09\r\noctodile-pus10\r\noctodile-pus11\r\noctodile-pus12\r\noctodile-pus13\r\noilrecord-163619\r\nomega-iterator-228003\r\nomega-terrain-123504\r\nomjust\r\nonyx-stack-193604\r\noo349294222\r\nopenx-200508\r\nopenx-200509\r\nopenx-200510\r\noppffg-189715\r\noppj-1\r\noppj-10\r\noppj-11\r\noppj-12\r\noppj-13\r\noppj-14\r\noppj-15\r\noppj-16\r\noppj-17\r\noppj-18\r\noppj-19\r\noppj-2\r\noppj-20\r\noppj-3\r\noppj-4\r\noppj-5\r\noppj-6\r\noppj-7\r\noppj-8\r\noppj-9\r\nopportune-scope-192906\r\noptical-psyche-226312\r\noptical-scarab-151605\r\noptimal-relic-186707\r\noptimal-timer-205006\r\noptimistic-keel-161020\r\norganic-berm-125203\r\norganic-isotope-153512\r\norganic-isotope-189414\r\norganic-spirit-184408\r\nornate-serenity-232002\r\nour-highway-159814\r\nour-lamp-214609\r\nour-pursuit-250817\r\nour-sign-107908\r\noutstanding-yew-226806\r\noval-campaign-227309\r\noval-day-180703\r\npacific-apex-192906\r\npacific-destiny-192908\r\npacific-element-184318\r\npangzi-1\r\npangzi-10\r\npangzi-11\r\npangzi-12\r\npangzi-2\r\npangzi-3\r\npangzi-4\r\npangzi-5\r\npangzi-6\r\npangzi-7\r\npangzi-8\r\npangzi-9\r\npanhut-1233\r\npapastarpapa\r\nparabolic-clock-242414\r\npasswall-3\r\npeerless-garage-243002\r\npeerless-kit-133123\r\npeerless-summit-180703\r\npeerless-trees-128708\r\npelagic-sorter-151605\r\npenghuaifa15\r\npenghuaifa16\r\npenghuaifa17\r\npenghuaifa18\r\npenghuaifa19\r\npenghuaifa20\r\npenghuaifa21\r\npenghuaifa22\r\npenghuaifa23\r\npenghuaifa24\r\npenghuaifa25\r\npengzhaopan-1272\r\npengzhaopan11\r\npeoplevsgfw1\r\npeoplevsgfw10\r\npeoplevsgfw11\r\npeoplevsgfw12\r\npeoplevsgfw2\r\npeoplevsgfw3\r\npeoplevsgfw4\r\npeoplevsgfw5\r\npeoplevsgfw6\r\npeoplevsgfw7\r\npeoplevsgfw8\r\npeoplevsgfw9\r\nperfect-aura-177307\r\nperfer-147105\r\nperfer2-147105\r\nperfer3-147105\r\nperfer4-147105\r\nperfer5-147105\r\npharos-215409\r\nphrasal-bonus-214609\r\nphrasal-chiller-172906\r\nphrasal-edition-193607\r\npi-project-152413\r\npichunhan7\r\npioneering-flow-233206\r\npivotal-base-221514\r\npivotal-purpose-170211\r\nplanar-name-127301\r\nplanar-name-127302\r\nplanar-name-127305\r\nplanar-name-127306\r\nplanar-name-127307\r\nplanar-name-127308\r\nplanar-name-127309\r\nplanar-name-127310\r\nplanar-name-127311\r\nplanar-name-127312\r\nplanar-name-127313\r\nplanar-name-127314\r\nplanar-osprey-211501\r\nplasma-circle-191107\r\nplasma-elf-189703\r\nplatinum-hour-123803\r\nplucky-balm-190215\r\nplucky-order-157607\r\npnj2014163\r\npnj201416301\r\npnj2014163010\r\npnj201416302\r\npnj201416303\r\npnj201416304\r\npnj201416305\r\npnj201416306\r\npnj201416307\r\npnj201416308\r\npnj201416309\r\npnj201416310\r\npnj201416311\r\npnj201416312\r\npnj201416313\r\npnj201416314\r\npnj201416315\r\npnj201416316\r\npnj201416317\r\npnj201416318\r\npnj201416319\r\npnj201416320\r\npoetic-archway-221514\r\npoetic-chariot-186703\r\npoised-artwork-190710\r\npoised-defender-162012\r\npoised-rock-133123\r\npolished-will-236503\r\npolonium432\r\npolonium543\r\npolymer1-191714\r\npositive-cocoa-213503\r\npossible-jetty-182501\r\npotent-trail-174402\r\npotent-well-237014\r\npotent-zodiac-173517\r\npractical-album-122814\r\npragmatic-ruler-185005\r\nprecise-bank-778\r\nprecise-data-180703\r\nprecise-formula-184910\r\npredictive-net-187715\r\nprefab-glazing-171713\r\nprefab-pursuit-221514\r\nprefab-segment-125209\r\npremium-oven-184200\r\npremium-weft-123504\r\nprimal-buttress-183205\r\nprimal-pod-214609\r\nprimeval-proton-214605\r\nprimeval-stack-209903\r\nprimordial-ship-203109\r\nprofect-for-xx-net-1\r\nproject-161216\r\nproject-for-xx-net-167007\r\nproject-for-xx-net-2\r\nproject202001\r\nproject202002\r\nproject202003\r\nproject202004\r\nproject202005\r\nproject202006\r\nproject202007\r\nproject202008\r\nproject202009\r\nproject4xxnet-206722\r\nproject4xxnet1\r\nproject4xxnet2-206722\r\nproject4xxnet3\r\nproject4xxnet4\r\nproject4xxnet5\r\nprojecteast-5101162\r\nprojects1-232002\r\npropane-primacy-214609\r\nprotean-mind-207504\r\nprotel-pacific10\r\nprotel-pacific8\r\nprotel-pacific9\r\nproud-storm-122813\r\nproven-wavelet-192906\r\nproxy-181212\r\nproxy-181213\r\nproxy-go-214805\r\nproxy1-185211\r\nproxy2-185211\r\nproxy3-185211\r\nproxypeak21\r\npsychic-etching-190215\r\npsychic-glider-184209\r\npublic-1025\r\npublic1-190407\r\npublicht2017\r\npure-chariot-228414\r\npure-media-187002\r\npure-mission-183900\r\npython-227202\r\npz123-190010\r\npzrproject\r\nq74110-208509\r\nq7411074\r\nqawxer4\r\nqiangfei-19880318\r\nqiu15-1105\r\nqiupeng1993\r\nqiupeng1994-1182\r\nqiupeng1995-1182\r\nqiupeng1996-1182\r\nqiupeng1997-1182\r\nqiupeng1998\r\nqiupeng1999-1182\r\nqiupeng2000-1182\r\nqiupeng2001\r\nqiupeng2011-1169\r\nqqnet1\r\nqqqq-208615\r\nqsj901222\r\nqualified-city-189703\r\nquantum-spring-190215\r\nquick-art-257701\r\nquick-function-242612\r\nquick-sonar-189715\r\nquicksci-0011\r\nquicksci-0012\r\nquiet-axon-201702\r\nquiet-branch-146309\r\nquixotic-folio-174804\r\nqujinfeng006\r\nqujinfeng008\r\nqujinfeng390\r\nqunchen0411\r\nqunchen0412\r\nqunchen0416\r\nqwe-qwe1\r\nqwe-qwe2\r\nqwe-qwe3\r\nqwe-qwe4\r\nqwe-qwe5\r\nqwe-qwe6\r\nqwe-qwe7\r\nqwe-qwe8\r\nqwertwert-181109\r\nqybust0\r\nqybust1\r\nqybust2\r\nqybust3\r\nqybust4\r\nqybust5\r\nqybust6\r\nqybust7\r\nqybust8\r\nqybust9\r\nqzhunb\r\nqzhunb10\r\nqzhunb11\r\nqzhunb12\r\nqzhunb13\r\nqzhunb14\r\nqzhunb15\r\nqzhunb16\r\nqzhunb17\r\nqzhunb18\r\nqzhunb19\r\nqzhunb2\r\nqzhunb20\r\nqzhunb21\r\nqzhunb22\r\nqzhunb23\r\nqzhunb24\r\nqzhunb3\r\nqzhunb4\r\nqzhunb5\r\nqzhunb6\r\nqzhunb7\r\nqzhunb8\r\nqzhunb9\r\nrabbit-000001\r\nrabbit-000002\r\nrabbit-000003\r\nrabbit-000004\r\nrabbit-000005\r\nrabbit-000006\r\nrabbit-000007\r\nrabbit-000008\r\nrabbit-000009\r\nrabbit-000010\r\nrabbit-000011\r\nrabbit-000012\r\nrailgun-11\r\nrailgun01-163611\r\nrain1213\r\nrare-attic-170706\r\nrare-chiller-160309\r\nred-agility-192503\r\nred-agility-239914\r\nrefined-grammar-125209\r\nrefined-helix-143904\r\nrefined-rookery-249613\r\nreflecting-card-216108\r\nreliable-return-159813\r\nreliable-vector-146301\r\nren-zhi-chu21\r\nren-zhi-chu22\r\nren-zhi-chu23\r\nren-zhi-chu24\r\nren-zhi-chu25\r\nresolute-cat-248804\r\nresponsible-map-184603\r\nresponsive-sun-183406\r\nrh4xtunnel\r\nrich-operand-126901\r\nrich-suprstate-133209\r\nrichy20k12\r\nringed-spot-132123\r\nringed-tractor-189912\r\nrising-analogy-106015\r\nriver-karma-123514\r\nriver-psyche-149813\r\nrj226-1\r\nrj226-10\r\nrj226-11\r\nrj226-12\r\nrj226-2\r\nrj226-3\r\nrj226-4\r\nrj226-5\r\nrj226-6\r\nrj226-7\r\nrj226-8\r\nrj226-9\r\nrobotic-tide-187615\r\nrobotic-tiger-237305\r\nrock-loop-206909\r\nrockneimenggu\r\nrongshaofeng-174118\r\nroot-1233\r\nroot-habitat-232002\r\nroot-matrix-142508\r\nroot-micron-231600\r\nroot-patrol-107908\r\nroot-patrol-192908\r\nrosy-dialect-124115\r\nrosy-hangout-210602\r\nround-plating-159814\r\nround-sunset-208402\r\nrtemis0004\r\nrugged-alcove-186315\r\nrugged-layout-189005\r\nrugged-nucleus-221514\r\nrunbird20\r\nrunck14\r\nsaaas-1235\r\nsacred-attic-187913\r\nsacred-catfish-107908\r\nsagitonychen9\r\nsampirga1\r\nsandro-xx-net-2\r\nsanshai-1240\r\nsanshai-1241\r\nsanshai-1242\r\nsanshai-1243\r\nsanshai-1244\r\nsanshai-1255\r\nsantali1985\r\nsapient-mote-184209\r\nsappmd-146309\r\nsavexx-net1\r\nsavexx-net2\r\nsavexx-net3\r\nsavexx-net4\r\nsaviorsyang11\r\nsaviorsyang12\r\nsavvy-hybrid-188705\r\nsciencesurfininternet-210416\r\nscientific-glow-192905\r\nsclproject-150315\r\nscto2101\r\nscto2102\r\nscto2103\r\nscto2104\r\nscuyanghao01\r\nscuyanghao02\r\nscuyanghao03\r\nsdjproject-214607\r\nsdwanghf5\r\nsdwanghf6\r\nsdwanghf7\r\nsdwanghf8\r\nsdwanghf9\r\nseasprseaspr10\r\nseasprseaspr11\r\nseasprseaspr6\r\nseasprseaspr7\r\nseasprseaspr8\r\nseasprseaspr9\r\nsecgao\r\nsecgao2\r\nsecgao3\r\nsecgao4\r\nsecgao5\r\nsecond-10002\r\nsecond-pier-169804\r\nseebug11\r\nseeker958115\r\nseeker958116\r\nseeker958117\r\nseeker958118\r\nseekobelion\r\nseelionkobe\r\nseeme-lion\r\nseemechina\r\nseemelion\r\nseemelionxxx\r\nseismic-operand-177707\r\nself-vpn-209714\r\nsemiotic-karma-188809\r\nseraphic-being-151605\r\nserious-mariner-221309\r\nseven-10007\r\nseventh-history-123514\r\nseventh-palace-153014\r\nsfbj9991vpn3\r\nsfbj9991vpn4\r\nsfowqd\r\nsfowqd01\r\nsfowqd02\r\nsfowqd03\r\nsfowqd04\r\nsfowqd05\r\nsfowqd06\r\nsfowqd07\r\nsfowqd08\r\nsfowqd09\r\nsfowqd10\r\nsfowqd11\r\nsfowqd12\r\nsfowqd13\r\nsfowqd14\r\nsfowqd15\r\nsfowqd16\r\nsfowqd17\r\nsfowqd18\r\nsfowqd19\r\nsfowqd20\r\nsfowqd21\r\nsfowqd22\r\nsfowqd23\r\nsfowqd24\r\nsfowqd25\r\nsfowqd26\r\nsfowqd27\r\nsfowqd28\r\nsfowqd29\r\nsfowqd30\r\nsfowqd31\r\nsfowqd32\r\nsfowqd33\r\nsfowqd34\r\nsfowqd35\r\nsfowqd36\r\nsfowqd37\r\nsfowqd38\r\nsfowqd39\r\nsfowqd40\r\nsfowqd41\r\nsfowqd42\r\nsfowqd43\r\nsfowqd44\r\nsfowqd45\r\nsfowqd46\r\nsfowqd47\r\nsfowqd48\r\nsfowqd49\r\nsfzo0001-1095\r\nsfzo0002-1095\r\nshangwang1111\r\nshangwang1234\r\nshangwang12345\r\nshangwang123456\r\nshangwang1234567\r\nshangwang12345678\r\nshangwang123456789\r\nshangwang2222\r\nshangwang3333\r\nshangwang5555\r\nshanlonglong-184110\r\nshaofeng-167407\r\nshaofeng-174120\r\nshaofeng2-168206\r\nshaped-density-208808\r\nshare-664123\r\nshare-xxnet01\r\nshare-xxnet02\r\nsharp-airway-192503\r\nsharp-quest-123515\r\nshejiwanga\r\nshejiwangb\r\nshejiwangc\r\nshejiwangd\r\nshejiwange\r\nshejiwangf\r\nshejiwangg\r\nshejiwangh\r\nshejiwangk\r\nshendcsa\r\nshewnei2288\r\nshinever-9\r\nshinever-catcher-95809\r\nshining-env-216915\r\nshounan0515\r\nshounan1984\r\nshuaiyer2013\r\nshuaiyer2015\r\nshumaye-20180401\r\nshumaye-20180402\r\nshumaye-20180403\r\nshumaye-20180404\r\nshumaye-20180405\r\nsigma-celerity-248804\r\nsigma-sector-192515\r\nsilent-octagon-198615\r\nsilicon-coder-191107\r\nsilken-inverter-191106\r\nsilver-fiber-187715\r\nsilver-nova-133623\r\nsimon-1283\r\nsincere-quasar-248110\r\nsing-a-song-1991\r\nsingingfor-1245\r\nsingle-beaker-186909\r\nsingle-bulwark-188715\r\nsingular-hash-233108\r\nsinoadongdong\r\nsisix-182315\r\nsixth-clone-06\r\nsixth-well-232002\r\nsixx-10006\r\nsj-34474\r\nskilful-display-187515\r\nskilful-scarab-221603\r\nskilled-duality-237523\r\nskyxsky10\r\nsmart-oa\r\nsmart-oasis-184115\r\nsmart-seer-188705\r\nsmiling-diode-162011\r\nsnappy-rainfall-155411\r\nsnappy-thought-220505\r\nsodium-hangar-151605\r\nsolar-vortex-217018\r\nsolid-coder-167907\r\nsolid-depot-246308\r\nsolid-dominion-107908\r\nsomshame\r\nsomshame1\r\nsomshame2\r\nsongxu921\r\nsongyajun00001\r\nsongyuxuan211\r\nsongyuxuan212-185304\r\nsonic-column-162405\r\nsound-invention-122813\r\nsound-velocity-184603\r\nsouthamerica-east-182\r\nsparereal33\r\nspartan-buckeye-242711\r\nspeedy-hold-228003\r\nspheric-brand-213002\r\nspiritual-aloe-177622\r\nspring-forest-187715\r\nspry-equator-123515\r\nspry-guru-180703\r\nspry-pipe-249808\r\nspuerjimm\r\nssongyajun\r\nstable-balancer-235613\r\nstablemars\r\nstarlit-cocoa-122814\r\nstarlit-primacy-227309\r\nstarlit-ship-123504\r\nstarlit-verve-194808\r\nstarlit-vim-231010\r\nstarry-embassy-107908\r\nstately-gist-807\r\nstately-math-123514\r\nstatic-bond-180703\r\nstatic-cirrus-184606\r\nstatic-pottery-207606\r\nstatic-resource-106711\r\nsteam-ego-191802\r\nsteam-style-184318\r\nsteam-thinker-241905\r\nsteam-way-149711\r\nsteel-citizen-123515\r\nsteel-minutia-167204\r\nsteel-sequencer-215206\r\nsteel-sonar-146810\r\nstephen-1\r\nstephen-2-1265\r\nstill-protocol-210206\r\nstill-tensor-216915\r\nstlivoe1-1470704581040\r\nstmapp1\r\nstock-store\r\nstoked-dominion-123514\r\nstone-botany-255102\r\nstone-column-213103\r\nstone-dispatch-146309\r\nstoried-channel-186702\r\nstoried-myth-123514\r\nstoried-storm-135623\r\nstorystorynight-1108\r\nstrategic-cargo-232304\r\nstrav311\r\nstrav317\r\nstrav318\r\nstriking-goal-249409\r\nstriped-bonfire-125209\r\nstriped-device-203807\r\nstriped-device-231003\r\nstriped-history-249804\r\nstrong-minutia-135702\r\nstrv301\r\nstudious-lore-131616\r\nstudious-union-194808\r\nsturdy-plateau-226904\r\nsublime-elixir-118315\r\nsublime-lens-215807\r\nsubtle-striker-164609\r\nsubtle-sublime-123515\r\nsummer-surface-247106\r\nsundayinvip\r\nsunlit-fuze-183714\r\nsunlit-segment-224104\r\nsunny-emissary-243002\r\nsunny-footing-184600\r\nsunny-lore-180703\r\nsunxingstargoagent1\r\nsuper-stingx17\r\nsuper-stingx18\r\nsuper-stingx19\r\nsuperb-cubist-189703\r\nsuperb-infusion-213503\r\nsupermanxia1\r\nsupermanxia2\r\nsupple-fold-191106\r\nsurezheng198822\r\nsurezheng198823\r\nsurezheng198824\r\nsurfree31\r\nsurfree32\r\nsurfree33\r\nsurfree34\r\nsurfree35\r\nsurfree36\r\nsurfree37\r\nsurfree38\r\nsurfree39\r\nsurfree40\r\nsutungpo-09\r\nsutungpo-10\r\nswdada89\r\nswift-hangar-192906\r\nswkoko1989\r\nsxt901222\r\nsxxnet-1222\r\nsylvan-fusion-125209\r\nsylvan-server-233015\r\nsylvan-solstice-241811\r\nsymbolic-eye-159814\r\nsymmetric-flag-248211\r\nsymmetric-lotus-180703\r\nsymmetric-ray-116004\r\ntactical-codex-190606\r\ntactical-gate-146713\r\ntactile-acolyte-217410\r\ntakonyan-project\r\ntakonyan-project2\r\ntakonyan-project3\r\ntakonyan-project4\r\ntakonyan-project5\r\ntangtdjia\r\ntangyidikej\r\ntanjianwen-demo\r\ntaopanpan\r\ntassader006\r\ntassader007\r\ntassader008\r\ntassader009\r\ntassader010\r\ntassader011\r\ntassader012\r\ntassader013\r\ntassader014\r\ntassader015\r\ntassader016\r\ntassader017\r\ntassader018\r\ntassader019\r\ntassader020\r\ntdztw105\r\nteak-banner-242003\r\nteak-instrument-184212\r\ntegry2014\r\ntemporal-bebop-226408\r\ntemporal-potion-170704\r\ntemporal-potion-257701\r\ntenacious-ring-196408\r\ntengjifive\r\ntengjione\r\ntengjisix\r\ntengjithree\r\ntengjitwo\r\ntensile-analyst-146309\r\ntensile-analyst-229009\r\ntensile-splice-248804\r\ntenymisswork1\r\ntenymisswork2\r\ntenymisswork3\r\ntenymisswork4\r\ntenymisswork5\r\ntest-1909\r\ntest-207587\r\ntest-208448\r\ntest-208771\r\ntest-208808\r\ntest-net-210207\r\ntest01-186302\r\ntest02-186302\r\ntest03-186304\r\ntest20190114\r\ntest4app7374\r\ntest805gz06\r\ntest805gz07\r\ntest805gz08\r\ntestine1001\r\ntestxxnetsteven\r\ntext1-1376\r\nthaishare-195102\r\nthaishare-27502\r\nthankyou-189715\r\nthe-flame-208808\r\nthe-racer-205005\r\nthematic-cider-249009\r\nthermal-rock-184203\r\ntheta-camera-146810\r\ntheyirun\r\nthinking-text-189910\r\nthird-circle-122813\r\nthird-wharf-210104\r\nthree-10003\r\ntianguomyu003\r\ntianjianxinyue\r\ntianjianxinyue1\r\ntianjianxinyue2\r\ntianjianxinyue3\r\ntianjianxinyue4\r\ntianjianxinyue5\r\ntianjianxinyue6\r\ntianjianxinyue7\r\ntianjianxinyue8\r\ntianjianxinyue9\r\ntianxin00888310\r\ntianxin0088837\r\ntianxin0088838\r\ntianxin0088839\r\ntidal-anvil-207507\r\ntidal-discovery-187715\r\ntidal-orbit-186402\r\ntidy-crane-204208\r\ntingxiao4\r\ntingxiao5-1211\r\ntingzhuzhefeng-211214\r\ntinycai001\r\ntinycai002\r\ntinycai003\r\ntinycai004\r\ntinycai005\r\ntinylens-168602\r\ntinylens-168603\r\ntinylens-168604\r\ntizi-164807\r\ntizi-165409\r\ntjdxncu5\r\ntjdxncu6\r\ntjdxncu7\r\ntjdxncu8\r\ntjdxncu9\r\ntoadprince2010\r\ntoadprince2011\r\ntokyo-mark-185802\r\ntonal-griffin-125209\r\ntony0401175803\r\ntony0405040826\r\ntony0412430025\r\ntony0415978520\r\ntony0423203189\r\ntony0426684326\r\ntony0466478249\r\ntony0469059164\r\ntony198911\r\ntony535134\r\ntony68764354\r\ntony714189010\r\ntop-alliance-187715\r\ntornado-190303\r\ntotal-stratum-178304\r\ntough-hull-192905\r\ntough-ivy-188715\r\ntrans-campus-152114\r\ntrans-campus-187715\r\ntrans-gate-123514\r\ntranwand-hrd\r\ntranwandwand\r\ntribal-saga-190710\r\ntribal-terra-137723\r\ntrim-attic-133123\r\ntrim-diode-192219\r\ntrim-mote-125209\r\ntriple-mountain-127310\r\ntriple-virtue-151606\r\ntrue-velocity-237602\r\ntrusty-anchor-214906\r\ntrusty-banner-192017\r\ntrusty-relic-233617\r\ntset-142510\r\ntunnel-share-001\r\nturing-clover-146309\r\nturnkey-charter-180904\r\nturnkey-diode-186201\r\nturnkey-rookery-125209\r\nui34-189715\r\nultra-aloe-261016\r\nultra-aquifer-182402\r\nultra-optics-189315\r\nunderwoods01\r\nunderwoods02\r\nunderwoods03\r\nunderwoods04\r\nunderwoods05\r\nunderwoods06\r\nunderwoods07\r\nunderwoods08\r\nunderwoods09\r\nunderwoods10\r\nunderwoods11\r\nunderwoods12\r\nunich881\r\nunified-adviser-186402\r\nunified-chess-166906\r\nunink88\r\nunink880\r\nunink884\r\nunique-antonym-123515\r\nunique-ellipse-123514\r\nunique-source-253502\r\nuniversal-rider-216108\r\nuniversal-stone-123514\r\nupbeat-cargo-131607\r\nupbeat-flame-207503\r\nupbeat-voice-123514\r\nupheld-dragon-137308\r\nuplifted-nuance-238209\r\nuplifted-record-242612\r\nustc641app1\r\nustc641app2\r\nustc641app3\r\nutopian-precept-170209\r\nuu7890-1247\r\nvaliant-airlock-188715\r\nvaliant-index-166213\r\nvaliant-metric-143110\r\nvalid-chess-233015\r\nvalid-moment-221514\r\nvalid-octagon-137823\r\nvaulted-codex-237305\r\nvd34-p\r\nvelvety-folder-181606\r\nvelvety-transit-220019\r\nverdant-legacy-186402\r\nverdant-medium-187107\r\nversatile-vine-180703\r\nvertical-karma-261123\r\nvertical-planet-189010\r\nvfr45q\r\nviekin880121\r\nvigilant-shell-161715\r\nvincentwangzai\r\nvirtual-airport-185802\r\nvirtual-dynamo-242711\r\nvivid-now-167105\r\nvivid-science-166810\r\nvivid-vent-138023\r\nvmms-163619\r\nvocal-affinity-173517\r\nvocal-ceiling-208808\r\nvocal-sunlight-190710\r\nvocal-terminal-261123\r\nvodomine1\r\nvoltaic-racer-185501\r\nvoltaic-range-220607\r\nvpn-1001\r\nvpn-1002\r\nvpn-project-1-171712\r\nvpn-project-793427156\r\nvpn5-1383\r\nvpn6-1383\r\nvpnb-179503\r\nvpnbittt-181300\r\nw183110795\r\nw183110796\r\nw183110797\r\nw183110798\r\nw183110799\r\nw3qeqd3\r\nw511655778\r\nw708846696-182101\r\nwalker-13-1193\r\nwalker313-1319\r\nwall-1336\r\nwamssj11\r\nwang-yu-zhe\r\nwang-yu-zhe-9011\r\nwangdatou-001\r\nwangdatou-002\r\nwangfengyoyo1\r\nwangfengyoyo2\r\nwangwei-168512\r\nwangwenbin1\r\nwangwenbin2\r\nwangyan-10\r\nwangyan-11\r\nwangyan-12\r\nwangyan-123\r\nwangyan-8\r\nwangyan-9\r\nwangyansong1010\r\nwanxmo02\r\nwanxmo03\r\nwanxmo04\r\nwanxmo05\r\nwanxmo06\r\nwanxmo07\r\nwanxmo08\r\nwanxmo09\r\nwarm-composite-217812\r\nwatchful-gear-192108\r\nwatchful-scope-208808\r\nwdcagent\r\nwdcagent1\r\nwdcagent2\r\nwdcagent3\r\nweberdyx21\r\nweberdyx22\r\nweberdyx23\r\nweberdyx24\r\nwedcf110-3\r\nweienjoy5\r\nweienjoy6\r\nweienjoy7\r\nweienjoy8\r\nweienjoy9\r\nweighty-flag-221514\r\nweighty-works-192112\r\nweimingyangvip10\r\nweimingyangvip2\r\nweimingyangvip3\r\nweimingyangvip4\r\nweimingyangvip5\r\nweimingyangvip6\r\nweimingyangvip7\r\nweimingyangvip8\r\nweimingyangvip9\r\nweipo1989\r\nweipo1991\r\nweipo1994\r\nweipo1995\r\nweipo1996\r\nweipo1997\r\nweipo1998\r\nweipo1999\r\nweipo2000\r\nweipo2001\r\nweishiyong1\r\nwelikeclimb\r\nwen-412702190\r\nwen-412702196\r\nwen-412702197\r\nwen-412702198\r\nwen-412702199\r\nwestern-net-192906\r\nwestern-will-807\r\nwestmylove121\r\nwestmylove122\r\nwhenican2\r\nwhenican3\r\nwhenican4\r\nwhite-airship-213502\r\nwhite-cider-162012\r\nwhitescinewoo4xx\r\nwide-bivouac-180703\r\nwide-exchanger-189008\r\nwindbell-1193\r\nwindbell1-1193\r\nwindbell12-1193\r\nwindbell123-1193\r\nwindbell1234-1193\r\nwindbell12345-1193\r\nwinter-gear-172906\r\nwinter-wonder-249804\r\nwise-resolver-163408\r\nwise-trainer-151605\r\nwizga-140504\r\nwoaixjj-209617\r\nwojiagougou0000\r\nwooden1-179902\r\nwooden2-179903\r\nwooden3-179903\r\nwooden4-179903\r\nwooden5-179903\r\nworks-1470053169939\r\nwoshicyx-162308\r\nwoven-amulet-127312\r\nwoven-rush-164914\r\nwoven-victor-170706\r\nwtchina13\r\nwtz-project-1\r\nwu4258528xxnet1\r\nwuguanlinfight8\r\nwuguanlinfight9\r\nwuju0012\r\nwuju0013\r\nwuju009001\r\nwuju009002\r\nwumingkun5-1099\r\nwumingkun6-1099\r\nwumingkun7-1099\r\nwumingkun8-1099\r\nwumingkun9-1099\r\nwushibin01\r\nwushibin02\r\nwushibin03-184301\r\nwushibin14\r\nwushibin15\r\nwushibin16\r\nwushibin17\r\nwushibin18\r\nwushibin19\r\nwuwalkerman\r\nwuyaoliuo\r\nwuyaoliuoo\r\nwuyaoliuoo1\r\nwuyaoliuooo\r\nwwszy01\r\nwwszy02\r\nwwwccatv10\r\nwwwccatv11\r\nwwwccatv12\r\nwwwccatv13\r\nwwwccatv14\r\nwwwtt0412\r\nwx362com\r\nwxiang01-194109\r\nwxxnet-1\r\nwxxnet-209812\r\nwxy11064\r\nwxy11065\r\nwxy11067\r\nwxy11068\r\nwxy11069\r\nwyb0531-646359954\r\nwys-proxy-1\r\nwys-proxy-10\r\nwys-proxy-2\r\nwys-proxy-3\r\nwys-proxy-4\r\nwys-proxy-5\r\nwys-proxy-6\r\nwys-proxy-7\r\nwys-proxy-8\r\nwys-proxy-9\r\nwyslmt11\r\nwyslmt12\r\nx-alcove-237412\r\nx-micron-123504\r\nx-net-1214\r\nx-net1-185412\r\nx-net2-185412\r\nx-net5-186107\r\nx-router-218209\r\nx-sorter-168017\r\nx-tunnel-communal\r\nx-tunnel-lql0\r\nx-tunnel-lql1\r\nx-tunnel-lql10\r\nx-tunnel-lql11\r\nx-tunnel-lql2\r\nx-tunnel-lql3\r\nx-tunnel-lql4\r\nx-tunnel-lql5\r\nx-tunnel-lql6\r\nx-tunnel-lql7\r\nx-tunnel-lql8\r\nx-tunnel-lql9\r\nx-tunnel-tinycai-001\r\nx-tunnel-tinycai-002\r\nx-tunnel-tinycai-003\r\nx-tunnel1\r\nx-tunnel3\r\nx-tunnel4\r\nx-tunnela\r\nx-tunnelb\r\nx-tunnelc\r\nx-tunneld\r\nx-tunnele\r\nx-tunnelf\r\nx-tunnelg\r\nx-tunnelh\r\nx-tunnelh-221308\r\nx-tunnelk\r\nx-tunnelz\r\nx-victor-249206\r\nx222-1233\r\nx2netforall01\r\nx333-1233\r\nx444-1233\r\nx555-1233\r\nx666-1233\r\nx777-1234\r\nx888-1234\r\nx888-2345\r\nxaegxy6\r\nxaegxy7\r\nxaegxy8\r\nxdffish15\r\nxdffish16\r\nxdffish17\r\nxdffish18\r\nxdffish19\r\nxdffish20\r\nxenon-momentum-233515\r\nxiang-mu-7\r\nxiang-mu-8\r\nxiaocaiya\r\nxiaole5775\r\nxiaole5776\r\nxiaoleiapple\r\nxiaolong6-20180829\r\nxiaolong7-20180829\r\nxiaolong7-20180830\r\nxiaolong8-20180909\r\nxiaolongthree-20180826\r\nxiaoxhcrtvu2016001\r\nxiaoyehao-207704\r\nxiejiajia400\r\nxieluo333\r\nxieluo444\r\nxieluo555\r\nxieluo666\r\nxieluo777\r\nxieluo888\r\nxieluo999\r\nxieyihong12\r\nxihaneimenggu\r\nxijsidjwn\r\nxindewagnsutest\r\nxinxijishuwyq\r\nxinxijishuwyq1\r\nxinxijishuwyq10\r\nxinxijishuwyq11\r\nxinxijishuwyq12\r\nxinxijishuwyq13\r\nxinxijishuwyq14\r\nxinxijishuwyq15\r\nxinxijishuwyq2\r\nxinxijishuwyq3\r\nxinxijishuwyq4\r\nxinxijishuwyq5\r\nxinxijishuwyq6\r\nxinxijishuwyq7\r\nxinxijishuwyq8\r\nxinxijishuwyq9\r\nxinyang0111\r\nxinyang0211\r\nxinyang0411\r\nxinyi1237\r\nxj00001-1269\r\nxjtusoc1\r\nxjtusoc3\r\nxjtusoc4\r\nxjtusoc5\r\nxnet27154\r\nxnetynmfl2\r\nxnroid1\r\nxnroid2\r\nxqnet-207202\r\nxqqflyer\r\nxthetom10\r\nxtunnel002\r\nxtunnelrh1\r\nxtwfyjdh\r\nxuanlong-huimiezhe\r\nxx-lot-185509\r\nxx-nat-197813\r\nxx-net\r\nxx-net-0-191100\r\nxx-net-002-250718\r\nxx-net-003-191104\r\nxx-net-004-191104\r\nxx-net-005-191104\r\nxx-net-006-191104\r\nxx-net-007-191104\r\nxx-net-007001\r\nxx-net-008-191104\r\nxx-net-009-191104\r\nxx-net-010-191104\r\nxx-net-012-12\r\nxx-net-02-188610\r\nxx-net-02-200408\r\nxx-net-0818\r\nxx-net-1-181313\r\nxx-net-1-191100\r\nxx-net-1-194206\r\nxx-net-1-199912\r\nxx-net-10-193808\r\nxx-net-1022-244313\r\nxx-net-11094\r\nxx-net-11110\r\nxx-net-111178\r\nxx-net-1214\r\nxx-net-123459\r\nxx-net-1427690\r\nxx-net-1470434775337\r\nxx-net-149202\r\nxx-net-1500\r\nxx-net-1501\r\nxx-net-15687\r\nxx-net-15688\r\nxx-net-159305\r\nxx-net-162407\r\nxx-net-166900\r\nxx-net-166923\r\nxx-net-16992\r\nxx-net-16997\r\nxx-net-170302\r\nxx-net-170309\r\nxx-net-175407\r\nxx-net-177622\r\nxx-net-177906\r\nxx-net-182702\r\nxx-net-184012\r\nxx-net-184318\r\nxx-net-184501\r\nxx-net-184505\r\nxx-net-185304\r\nxx-net-185612\r\nxx-net-185716\r\nxx-net-185717\r\nxx-net-186704\r\nxx-net-187006-187006\r\nxx-net-187110\r\nxx-net-187310\r\nxx-net-187312\r\nxx-net-187715\r\nxx-net-187812\r\nxx-net-187917\r\nxx-net-18800\r\nxx-net-18801\r\nxx-net-188116\r\nxx-net-188315\r\nxx-net-188610\r\nxx-net-188801\r\nxx-net-188804\r\nxx-net-189012\r\nxx-net-190403\r\nxx-net-190404\r\nxx-net-190507\r\nxx-net-190606\r\nxx-net-191100\r\nxx-net-192116\r\nxx-net-192516\r\nxx-net-192705\r\nxx-net-192706\r\nxx-net-192707\r\nxx-net-192708\r\nxx-net-194206\r\nxx-net-195313\r\nxx-net-197315\r\nxx-net-197409\r\nxx-net-198606\r\nxx-net-198615\r\nxx-net-19970214\r\nxx-net-2-149311\r\nxx-net-2-181313\r\nxx-net-2-191100\r\nxx-net-2-194206\r\nxx-net-2-210704\r\nxx-net-2-215106\r\nxx-net-200615\r\nxx-net-20170830\r\nxx-net-2018-191615\r\nxx-net-20180709-209714\r\nxx-net-20180801901\r\nxx-net-20180801902\r\nxx-net-20180801903\r\nxx-net-20180801904\r\nxx-net-20180801905\r\nxx-net-20180801906\r\nxx-net-20180801907\r\nxx-net-20180801908\r\nxx-net-20180801909\r\nxx-net-20180801910\r\nxx-net-20180801911\r\nxx-net-20180801912\r\nxx-net-20180801913\r\nxx-net-20180801914\r\nxx-net-20180801915\r\nxx-net-20180801916\r\nxx-net-20180801917\r\nxx-net-20180801918\r\nxx-net-20180801919\r\nxx-net-20180801920\r\nxx-net-201811081559\r\nxx-net-201811081601\r\nxx-net-201811081603\r\nxx-net-2018121503\r\nxx-net-20181224\r\nxx-net-20190108\r\nxx-net-202201\r\nxx-net-20564\r\nxx-net-207314\r\nxx-net-208010\r\nxx-net-208614\r\nxx-net-208808\r\nxx-net-209413\r\nxx-net-209502\r\nxx-net-209503\r\nxx-net-209702\r\nxx-net-210503\r\nxx-net-211302\r\nxx-net-211616\r\nxx-net-212100\r\nxx-net-212101\r\nxx-net-213803\r\nxx-net-214308\r\nxx-net-214400\r\nxx-net-214500\r\nxx-net-215011\r\nxx-net-215313\r\nxx-net-215318\r\nxx-net-215456\r\nxx-net-216210\r\nxx-net-216708\r\nxx-net-2170120\r\nxx-net-2170121\r\nxx-net-2170122\r\nxx-net-2170123\r\nxx-net-2170124\r\nxx-net-2170125\r\nxx-net-2170126\r\nxx-net-217015\r\nxx-net-217016\r\nxx-net-217019\r\nxx-net-217203\r\nxx-net-217414\r\nxx-net-218104\r\nxx-net-218703\r\nxx-net-218802\r\nxx-net-218912\r\nxx-net-219205\r\nxx-net-219209\r\nxx-net-219711\r\nxx-net-221217\r\nxx-net-221305\r\nxx-net-2213051\r\nxx-net-221908\r\nxx-net-222211\r\nxx-net-223008\r\nxx-net-223009\r\nxx-net-223710\r\nxx-net-226314\r\nxx-net-226806\r\nxx-net-229906\r\nxx-net-231802\r\nxx-net-232823\r\nxx-net-232901\r\nxx-net-23333\r\nxx-net-233602\r\nxx-net-234909\r\nxx-net-238514\r\nxx-net-241802\r\nxx-net-242206\r\nxx-net-243002\r\nxx-net-243212\r\nxx-net-243316\r\nxx-net-243414\r\nxx-net-243609\r\nxx-net-243611\r\nxx-net-244109\r\nxx-net-244210\r\nxx-net-244306\r\nxx-net-244307\r\nxx-net-244308\r\nxx-net-244309\r\nxx-net-244310\r\nxx-net-244311\r\nxx-net-244312\r\nxx-net-244313\r\nxx-net-244314\r\nxx-net-245300\r\nxx-net-245306\r\nxx-net-2458\r\nxx-net-247012\r\nxx-net-248010\r\nxx-net-248014\r\nxx-net-248804\r\nxx-net-248908\r\nxx-net-249305\r\nxx-net-249613\r\nxx-net-249813\r\nxx-net-249814\r\nxx-net-249815\r\nxx-net-250612\r\nxx-net-250705\r\nxx-net-250713\r\nxx-net-251013\r\nxx-net-251100\r\nxx-net-251101\r\nxx-net-251306\r\nxx-net-251801\r\nxx-net-257302\r\nxx-net-26255\r\nxx-net-264141\r\nxx-net-3-149203\r\nxx-net-3-194206\r\nxx-net-3-215106\r\nxx-net-316356\r\nxx-net-33925\r\nxx-net-35942\r\nxx-net-38195\r\nxx-net-384587\r\nxx-net-4-183714\r\nxx-net-436855\r\nxx-net-443263\r\nxx-net-45284\r\nxx-net-463246\r\nxx-net-473096\r\nxx-net-498415\r\nxx-net-5-182618\r\nxx-net-50640\r\nxx-net-518404\r\nxx-net-6-183714\r\nxx-net-6-226806\r\nxx-net-6-233015\r\nxx-net-614307\r\nxx-net-6178984\r\nxx-net-6883\r\nxx-net-7-183714\r\nxx-net-8-183714\r\nxx-net-8362\r\nxx-net-85869\r\nxx-net-9-226108\r\nxx-net-9038\r\nxx-net-905141\r\nxx-net-91102\r\nxx-net-987512\r\nxx-net-994447\r\nxx-net-agent\r\nxx-net-archway-233305\r\nxx-net-basic-fact-191302\r\nxx-net-boom1\r\nxx-net-boom10\r\nxx-net-boom11\r\nxx-net-boom12\r\nxx-net-boom2\r\nxx-net-boom3\r\nxx-net-boom4\r\nxx-net-boom5\r\nxx-net-boom6\r\nxx-net-boom7\r\nxx-net-boom8\r\nxx-net-boom9\r\nxx-net-box-233305\r\nxx-net-card-233305\r\nxx-net-comfort-233305\r\nxx-net-common1122\r\nxx-net-copilot-233305\r\nxx-net-dev\r\nxx-net-do-235306\r\nxx-net-do01\r\nxx-net-donate-249109\r\nxx-net-donateaid\r\nxx-net-donation01\r\nxx-net-donation02\r\nxx-net-donation03\r\nxx-net-donation04\r\nxx-net-donation05\r\nxx-net-donation06\r\nxx-net-donation07\r\nxx-net-donation08\r\nxx-net-donnate\r\nxx-net-dy-01\r\nxx-net-elevator-209413\r\nxx-net-fk-01\r\nxx-net-frame-233305\r\nxx-net-gengchen\r\nxx-net-glass-233305\r\nxx-net-hazel-mote-191302\r\nxx-net-hexu16413\r\nxx-net-home\r\nxx-net-hrhqm\r\nxx-net-jia-001\r\nxx-net-jia-002\r\nxx-net-jia-003\r\nxx-net-jiuyishan-01\r\nxx-net-kxw1\r\nxx-net-kxw2\r\nxx-net-lwy\r\nxx-net-mori01\r\nxx-net-mori02\r\nxx-net-movie01\r\nxx-net-movie02\r\nxx-net-movie03\r\nxx-net-nm1\r\nxx-net-project-01-260905\r\nxx-net-project-for-test\r\nxx-net-proxy-157013\r\nxx-net-public\r\nxx-net-public-000\r\nxx-net-public-001\r\nxx-net-public-002\r\nxx-net-public-003\r\nxx-net-public-004\r\nxx-net-public-005\r\nxx-net-public-006\r\nxx-net-public-007\r\nxx-net-public-009\r\nxx-net-public-01\r\nxx-net-ray-233305\r\nxx-net-self\r\nxx-net-si01\r\nxx-net-si010\r\nxx-net-si02\r\nxx-net-si03\r\nxx-net-si04\r\nxx-net-si05\r\nxx-net-si06\r\nxx-net-si07\r\nxx-net-si08\r\nxx-net-si09\r\nxx-net-si10-184013\r\nxx-net-ssssss233305\r\nxx-net-tensor-233305\r\nxx-net-test-1248\r\nxx-net-tk-000\r\nxx-net-tk-001\r\nxx-net-trilogy-233305\r\nxx-net-tt1-194602\r\nxx-net-tt10\r\nxx-net-tt11\r\nxx-net-tt12\r\nxx-net-tt7\r\nxx-net-tt8\r\nxx-net-tunnel-1\r\nxx-net-tunnel-2\r\nxx-net-tunnel-3\r\nxx-net-tunnel-4\r\nxx-net-welder-233305\r\nxx-net-wori\r\nxx-net-z-209708\r\nxx-net00-201218\r\nxx-net0001-237309\r\nxx-net0002-190209\r\nxx-net001-140309\r\nxx-net0011\r\nxx-net0012\r\nxx-net01-212303\r\nxx-net01-236212\r\nxx-net01-243000\r\nxx-net02-212303\r\nxx-net02-233711\r\nxx-net02-243000\r\nxx-net03-212303\r\nxx-net04-212303\r\nxx-net05-212303\r\nxx-net06-212303\r\nxx-net07-212303\r\nxx-net0754\r\nxx-net08-212303\r\nxx-net09-212303\r\nxx-net1-169203\r\nxx-net1-179210\r\nxx-net1-184212\r\nxx-net1-193807\r\nxx-net1-211802\r\nxx-net1-213502\r\nxx-net1-217510\r\nxx-net1-218322\r\nxx-net1-225501\r\nxx-net1-226706\r\nxx-net1-248602\r\nxx-net10-184212\r\nxx-net10-186704\r\nxx-net10-187809\r\nxx-net10-188509\r\nxx-net10-192909\r\nxx-net11-1329\r\nxx-net11-184212\r\nxx-net11-186704\r\nxx-net11-187809\r\nxx-net11-188509\r\nxx-net11-192909\r\nxx-net12-1329\r\nxx-net12-184212\r\nxx-net12-187809\r\nxx-net12-189809\r\nxx-net12-192909\r\nxx-net1582\r\nxx-net159\r\nxx-net160\r\nxx-net161\r\nxx-net162\r\nxx-net163\r\nxx-net164\r\nxx-net165\r\nxx-net166\r\nxx-net167\r\nxx-net168\r\nxx-net169\r\nxx-net170\r\nxx-net17341\r\nxx-net188804\r\nxx-net1995\r\nxx-net2-1260\r\nxx-net2-156401\r\nxx-net2-164802\r\nxx-net2-169203\r\nxx-net2-175407\r\nxx-net2-184212\r\nxx-net2-187809\r\nxx-net2-189914\r\nxx-net2-207703\r\nxx-net2-213509\r\nxx-net2-225415\r\nxx-net2-226706\r\nxx-net2-248804\r\nxx-net2008\r\nxx-net20180722\r\nxx-net3-156401\r\nxx-net3-164802\r\nxx-net3-175407\r\nxx-net3-179210\r\nxx-net3-184212\r\nxx-net3-187809\r\nxx-net3-190013\r\nxx-net3-192908\r\nxx-net37048279901\r\nxx-net37048279902\r\nxx-net4-156401\r\nxx-net4-175407\r\nxx-net4-179210\r\nxx-net4-184212\r\nxx-net4-187809\r\nxx-net4-190604\r\nxx-net4-192908\r\nxx-net4-193808\r\nxx-net4-225500\r\nxx-net4444\r\nxx-net4donate\r\nxx-net4donate1\r\nxx-net4wiki01\r\nxx-net5-156401\r\nxx-net5-175407\r\nxx-net5-184212\r\nxx-net5-187809\r\nxx-net5-190604\r\nxx-net5-225500\r\nxx-net6-156401\r\nxx-net6-184212\r\nxx-net6-187809\r\nxx-net6-192909\r\nxx-net6-194401\r\nxx-net6-198409\r\nxx-net6-248804\r\nxx-net61674\r\nxx-net7-184212\r\nxx-net7-184901\r\nxx-net7-187809\r\nxx-net7-192909\r\nxx-net7-248804\r\nxx-net72085\r\nxx-net76895\r\nxx-net8-184212\r\nxx-net8-184901\r\nxx-net8-186704\r\nxx-net8-187809\r\nxx-net8-192909\r\nxx-net88356\r\nxx-net9-184212\r\nxx-net9-186704\r\nxx-net9-187809\r\nxx-net9-192909\r\nxx-net9-198410\r\nxx-net91\r\nxx-net92\r\nxx-net93\r\nxx-net94\r\nxx-net971119\r\nxx-neta-208009\r\nxx-neta-208010\r\nxx-neta1\r\nxx-neta2\r\nxx-netcht1\r\nxx-netcht2\r\nxx-netchts21\r\nxx-netdonate1\r\nxx-netdonate2\r\nxx-netjuanxian2\r\nxx-netjy05\r\nxx-netstandley\r\nxx-netwdx520\r\nxx-obj-1\r\nxx-obj-10\r\nxx-obj-11\r\nxx-obj-12\r\nxx-obj-2\r\nxx-obj-3\r\nxx-obj-4\r\nxx-obj-5\r\nxx-obj-6\r\nxx-obj-7\r\nxx-obj-8\r\nxx-obj-9\r\nxx-vpn-1\r\nxx-vpn-2\r\nxx-vpn-3\r\nxx-xx0001\r\nxx-xx0002\r\nxx-xx0003\r\nxx-xx0004\r\nxx-xx0005\r\nxx-xx0006\r\nxx-xx0007\r\nxx-xx0008\r\nxx-xx0009\r\nxx-xx0010\r\nxx-xx0011\r\nxx-xx0012\r\nxx-xx0013\r\nxx-xx0014\r\nxx-xx0015\r\nxx-xx0016\r\nxx-zlg01\r\nxx184701\r\nxx7837rhim\r\nxxbet-creek-186016\r\nxxcrossfire1144\r\nxxfreevpn\r\nxxfreevpn-01\r\nxxfreevpn-02\r\nxxfreevpn-03\r\nxxfreevpn-05\r\nxxfreevpn-06\r\nxxfreevpn-07\r\nxxfreevpn-08\r\nxxfreevpn-10\r\nxxfreevpn-11\r\nxxfreevpn-12\r\nxxfreevpn-4\r\nxxn-833000\r\nxxn-883001\r\nxxna-227105\r\nxxnat2\r\nxxnb-227105\r\nxxne-1273\r\nxxne-184408\r\nxxnet--01\r\nxxnet--02\r\nxxnet--03\r\nxxnet--04\r\nxxnet--05\r\nxxnet--1229\r\nxxnet--1248\r\nxxnet--124811\r\nxxnet--1252\r\nxxnet--1265\r\nxxnet--1267\r\nxxnet--1268\r\nxxnet--1269\r\nxxnet--1273\r\nxxnet--1274\r\nxxnet--1289\r\nxxnet--1290\r\nxxnet--1308\r\nxxnet--1313\r\nxxnet--1357\r\nxxnet--1375\r\nxxnet--142420\r\nxxnet--180307\r\nxxnet--180395\r\nxxnet--205704\r\nxxnet--211902\r\nxxnet--voyage-145601\r\nxxnet--xtunnel\r\nxxnet-00-147002\r\nxxnet-001-186502\r\nxxnet-001-186707\r\nxxnet-001-189310\r\nxxnet-001-225608\r\nxxnet-001-229607\r\nxxnet-001-234808\r\nxxnet-001-244402\r\nxxnet-0010-196609\r\nxxnet-001001\r\nxxnet-001002\r\nxxnet-001003\r\nxxnet-001004\r\nxxnet-001005\r\nxxnet-001006\r\nxxnet-001007\r\nxxnet-001008\r\nxxnet-002-186502\r\nxxnet-002-186707\r\nxxnet-002-225608\r\nxxnet-003-186502\r\nxxnet-003-186707\r\nxxnet-003-225608\r\nxxnet-004-186502\r\nxxnet-004-225608\r\nxxnet-004869\r\nxxnet-005-186502\r\nxxnet-005-225608\r\nxxnet-006-186502\r\nxxnet-006-225608\r\nxxnet-007-186502\r\nxxnet-008-186502\r\nxxnet-009-186502\r\nxxnet-01-1\r\nxxnet-01-1300\r\nxxnet-01-1303\r\nxxnet-01-147002\r\nxxnet-01-178218\r\nxxnet-01-185203\r\nxxnet-01-195803\r\nxxnet-01-204407\r\nxxnet-01-215207\r\nxxnet-01-222815\r\nxxnet-010-186502\r\nxxnet-012\r\nxxnet-02-1300\r\nxxnet-02-1303\r\nxxnet-02-147002\r\nxxnet-02-178218\r\nxxnet-02-189012\r\nxxnet-02-192506\r\nxxnet-02-212704\r\nxxnet-02-235917\r\nxxnet-03-1303\r\nxxnet-03-147002\r\nxxnet-03-178218\r\nxxnet-03-189012\r\nxxnet-03-235917\r\nxxnet-0301\r\nxxnet-03045555\r\nxxnet-04-1303\r\nxxnet-04-147002\r\nxxnet-04-178218\r\nxxnet-05-1303\r\nxxnet-05-147002\r\nxxnet-05-178218\r\nxxnet-05-205003\r\nxxnet-050\r\nxxnet-06-1303\r\nxxnet-06-147002\r\nxxnet-06-178218\r\nxxnet-07-1303\r\nxxnet-07-147002\r\nxxnet-0709-1\r\nxxnet-0720-230112\r\nxxnet-0721-230112\r\nxxnet-08-1303\r\nxxnet-08-147002\r\nxxnet-0817\r\nxxnet-0825-233502\r\nxxnet-0828\r\nxxnet-089\r\nxxnet-09-1303\r\nxxnet-09-147002\r\nxxnet-090\r\nxxnet-091\r\nxxnet-092\r\nxxnet-09291\r\nxxnet-092910\r\nxxnet-092911\r\nxxnet-092912\r\nxxnet-09292\r\nxxnet-09293\r\nxxnet-09294\r\nxxnet-09295\r\nxxnet-09296\r\nxxnet-09297\r\nxxnet-09298\r\nxxnet-09299\r\nxxnet-093\r\nxxnet-094\r\nxxnet-095\r\nxxnet-096\r\nxxnet-097\r\nxxnet-097575621\r\nxxnet-1\r\nxxnet-1--1273\r\nxxnet-1-1265\r\nxxnet-1-1294\r\nxxnet-1-1470489237406\r\nxxnet-1-161301\r\nxxnet-1-179915\r\nxxnet-1-181703\r\nxxnet-1-182011\r\nxxnet-1-184213\r\nxxnet-1-184705\r\nxxnet-1-186703\r\nxxnet-1-187504\r\nxxnet-1-190711\r\nxxnet-1-193607\r\nxxnet-1-197113\r\nxxnet-1-199505\r\nxxnet-1-199912\r\nxxnet-1-2008\r\nxxnet-1-2009\r\nxxnet-1-2010\r\nxxnet-1-2011\r\nxxnet-1-2012\r\nxxnet-1-205004\r\nxxnet-1-206406\r\nxxnet-1-207305\r\nxxnet-1-207807\r\nxxnet-1-209000\r\nxxnet-1-211015\r\nxxnet-1-211500\r\nxxnet-1-211501\r\nxxnet-1-218515\r\nxxnet-1-224107\r\nxxnet-1-227015\r\nxxnet-1-232206\r\nxxnet-1-233308\r\nxxnet-1-256910\r\nxxnet-10\r\nxxnet-10-1252\r\nxxnet-10-1264\r\nxxnet-10-1265\r\nxxnet-10-1303\r\nxxnet-10-147002\r\nxxnet-10-184213\r\nxxnet-10-184606\r\nxxnet-10-184705\r\nxxnet-10-187504\r\nxxnet-10-208703\r\nxxnet-10-211015\r\nxxnet-10-214016\r\nxxnet-100\r\nxxnet-100001\r\nxxnet-1001-200215\r\nxxnet-1001-218313\r\nxxnet-1001-226315\r\nxxnet-10011\r\nxxnet-10012\r\nxxnet-1002-218313\r\nxxnet-100201\r\nxxnet-100202\r\nxxnet-100203\r\nxxnet-100204\r\nxxnet-100205\r\nxxnet-1003-218313\r\nxxnet-1005-218313\r\nxxnet-1006-218313\r\nxxnet-10086-188007\r\nxxnet-100a\r\nxxnet-101\r\nxxnet-101-x\r\nxxnet-1017\r\nxxnet-1017-183905\r\nxxnet-1018\r\nxxnet-1018-183905\r\nxxnet-1019\r\nxxnet-1019-183905\r\nxxnet-102\r\nxxnet-102-x\r\nxxnet-1020-183905\r\nxxnet-10200\r\nxxnet-1021\r\nxxnet-1022\r\nxxnet-1023\r\nxxnet-1024\r\nxxnet-1025\r\nxxnet-1025-184012\r\nxxnet-1026\r\nxxnet-1026-184012\r\nxxnet-1026171143\r\nxxnet-1026171144\r\nxxnet-1026171145\r\nxxnet-1026171348\r\nxxnet-1026171349\r\nxxnet-1027\r\nxxnet-1028\r\nxxnet-1029\r\nxxnet-103\r\nxxnet-103-1188\r\nxxnet-103-x\r\nxxnet-1030\r\nxxnet-1031\r\nxxnet-1032-1188\r\nxxnet-1033\r\nxxnet-1034\r\nxxnet-1035\r\nxxnet-1037\r\nxxnet-104\r\nxxnet-104-x\r\nxxnet-105\r\nxxnet-105-x\r\nxxnet-1053\r\nxxnet-1054\r\nxxnet-106\r\nxxnet-107\r\nxxnet-108\r\nxxnet-1088-211906\r\nxxnet-109\r\nxxnet-11\r\nxxnet-11-1264\r\nxxnet-11-1265\r\nxxnet-11-1273\r\nxxnet-11-147002\r\nxxnet-11-184606\r\nxxnet-11-187504\r\nxxnet-11-202110\r\nxxnet-11-211015\r\nxxnet-11-214016\r\nxxnet-11-233209\r\nxxnet-110\r\nxxnet-1101-211906\r\nxxnet-11028\r\nxxnet-11029\r\nxxnet-111\r\nxxnet-111-182502\r\nxxnet-111-186201\r\nxxnet-1111111\r\nxxnet-111112\r\nxxnet-111113\r\nxxnet-111114\r\nxxnet-111115\r\nxxnet-111116\r\nxxnet-111117\r\nxxnet-111118\r\nxxnet-111119\r\nxxnet-112\r\nxxnet-1122-211906\r\nxxnet-11223344\r\nxxnet-1123-186902\r\nxxnet-1123581321\r\nxxnet-1128-187402\r\nxxnet-113\r\nxxnet-113243\r\nxxnet-11398\r\nxxnet-114\r\nxxnet-115\r\nxxnet-11588\r\nxxnet-11589\r\nxxnet-116\r\nxxnet-116110\r\nxxnet-117\r\nxxnet-118\r\nxxnet-119\r\nxxnet-12\r\nxxnet-12-1264\r\nxxnet-12-1265\r\nxxnet-12-184606\r\nxxnet-12-187504\r\nxxnet-12-214016\r\nxxnet-12-233209\r\nxxnet-120\r\nxxnet-120-187109\r\nxxnet-1206-1\r\nxxnet-12099\r\nxxnet-121\r\nxxnet-12123131\r\nxxnet-122\r\nxxnet-123\r\nxxnet-123-186201\r\nxxnet-123-224209\r\nxxnet-12306-194202\r\nxxnet-12307\r\nxxnet-12308\r\nxxnet-12309\r\nxxnet-12309-194202\r\nxxnet-123150\r\nxxnet-1233-211906\r\nxxnet-1234-1273\r\nxxnet-1234-211906\r\nxxnet-1234321-225212\r\nxxnet-123445323\r\nxxnet-12345-214204\r\nxxnet-12345543\r\nxxnet-123456\r\nxxnet-123456-214204\r\nxxnet-123456-239202\r\nxxnet-123457\r\nxxnet-123458\r\nxxnet-123460\r\nxxnet-123461\r\nxxnet-123462\r\nxxnet-123463\r\nxxnet-1235-211906\r\nxxnet-123567321\r\nxxnet-123678\r\nxxnet-124\r\nxxnet-1248903\r\nxxnet-1248904\r\nxxnet-1248905\r\nxxnet-1248906\r\nxxnet-1248907\r\nxxnet-125\r\nxxnet-1252\r\nxxnet-1255\r\nxxnet-1256\r\nxxnet-126\r\nxxnet-12641\r\nxxnet-1268\r\nxxnet-1268841\r\nxxnet-1268842\r\nxxnet-1269\r\nxxnet-127\r\nxxnet-1270\r\nxxnet-1271\r\nxxnet-1272\r\nxxnet-1273\r\nxxnet-1274\r\nxxnet-1275\r\nxxnet-1276\r\nxxnet-1277\r\nxxnet-1278\r\nxxnet-128\r\nxxnet-129\r\nxxnet-1291\r\nxxnet-1292\r\nxxnet-1293\r\nxxnet-1294\r\nxxnet-1295\r\nxxnet-1296\r\nxxnet-1297\r\nxxnet-1298\r\nxxnet-1299\r\nxxnet-13\r\nxxnet-130\r\nxxnet-1300\r\nxxnet-1301\r\nxxnet-1302\r\nxxnet-13081\r\nxxnet-13082\r\nxxnet-131\r\nxxnet-131309\r\nxxnet-131310\r\nxxnet-131311\r\nxxnet-131312\r\nxxnet-131313\r\nxxnet-131314\r\nxxnet-131315\r\nxxnet-131316\r\nxxnet-131317\r\nxxnet-131318\r\nxxnet-131319\r\nxxnet-131320\r\nxxnet-131321\r\nxxnet-131323\r\nxxnet-132\r\nxxnet-1321\r\nxxnet-1327\r\nxxnet-1328\r\nxxnet-133\r\nxxnet-134\r\nxxnet-135\r\nxxnet-13531\r\nxxnet-135725\r\nxxnet-136\r\nxxnet-136847\r\nxxnet-136901\r\nxxnet-136923\r\nxxnet-136924\r\nxxnet-136925\r\nxxnet-137\r\nxxnet-1370-1370\r\nxxnet-1376\r\nxxnet-1377\r\nxxnet-1378\r\nxxnet-1379\r\nxxnet-138\r\nxxnet-1380\r\nxxnet-1381\r\nxxnet-1382\r\nxxnet-1383\r\nxxnet-1384\r\nxxnet-139\r\nxxnet-1396\r\nxxnet-1397\r\nxxnet-139904\r\nxxnet-139905\r\nxxnet-14\r\nxxnet-14-214016\r\nxxnet-140\r\nxxnet-140705\r\nxxnet-141\r\nxxnet-1414114\r\nxxnet-142\r\nxxnet-142603\r\nxxnet-142604\r\nxxnet-142605\r\nxxnet-142606\r\nxxnet-142607\r\nxxnet-142608\r\nxxnet-142609\r\nxxnet-143\r\nxxnet-143404\r\nxxnet-143602\r\nxxnet-143603\r\nxxnet-143604\r\nxxnet-143606\r\nxxnet-143607\r\nxxnet-143608\r\nxxnet-143609\r\nxxnet-143610\r\nxxnet-143611\r\nxxnet-143612\r\nxxnet-143613\r\nxxnet-144\r\nxxnet-1440\r\nxxnet-1441\r\nxxnet-14433\r\nxxnet-14435\r\nxxnet-145\r\nxxnet-1451159047\r\nxxnet-146\r\nxxnet-14641\r\nxxnet-147\r\nxxnet-1470\r\nxxnet-1470434997049\r\nxxnet-1470566028726\r\nxxnet-1470566228993\r\nxxnet-147331\r\nxxnet-147916\r\nxxnet-147917\r\nxxnet-14799\r\nxxnet-148\r\nxxnet-148412\r\nxxnet-149\r\nxxnet-150\r\nxxnet-151\r\nxxnet-151606\r\nxxnet-151715\r\nxxnet-152\r\nxxnet-153\r\nxxnet-154\r\nxxnet-155\r\nxxnet-156\r\nxxnet-1564846\r\nxxnet-15659\r\nxxnet-15678\r\nxxnet-157\r\nxxnet-158\r\nxxnet-1588\r\nxxnet-159\r\nxxnet-15927\r\nxxnet-15927-227708\r\nxxnet-15928\r\nxxnet-15929\r\nxxnet-15930\r\nxxnet-15931\r\nxxnet-15932\r\nxxnet-15933\r\nxxnet-15934\r\nxxnet-15935\r\nxxnet-15936\r\nxxnet-15937\r\nxxnet-15938\r\nxxnet-16\r\nxxnet-16091601\r\nxxnet-16091602\r\nxxnet-16091701\r\nxxnet-16091702\r\nxxnet-16091703\r\nxxnet-161301\r\nxxnet-162408\r\nxxnet-162409\r\nxxnet-163408\r\nxxnet-16439\r\nxxnet-1649911\r\nxxnet-1649912\r\nxxnet-1649913\r\nxxnet-1649915\r\nxxnet-1649916\r\nxxnet-1649917\r\nxxnet-165817\r\nxxnet-165818\r\nxxnet-165820\r\nxxnet-1670\r\nxxnet-1671\r\nxxnet-1672\r\nxxnet-1673\r\nxxnet-1674\r\nxxnet-1675\r\nxxnet-1676\r\nxxnet-1677\r\nxxnet-1678\r\nxxnet-1679\r\nxxnet-1680\r\nxxnet-1681\r\nxxnet-1682\r\nxxnet-1683\r\nxxnet-1684\r\nxxnet-1685\r\nxxnet-1686\r\nxxnet-168602\r\nxxnet-1687\r\nxxnet-169707-169707\r\nxxnet-17\r\nxxnet-17-233\r\nxxnet-17-234\r\nxxnet-17-235\r\nxxnet-17-236\r\nxxnet-17-237\r\nxxnet-1707n1\r\nxxnet-1707n10\r\nxxnet-1707n11\r\nxxnet-1707n12\r\nxxnet-1707n2\r\nxxnet-1707n4\r\nxxnet-1707n5\r\nxxnet-1707n6\r\nxxnet-1707n7\r\nxxnet-1707n8\r\nxxnet-1707n9\r\nxxnet-17101401\r\nxxnet-17101402\r\nxxnet-17101403\r\nxxnet-171127\r\nxxnet-17166\r\nxxnet-1717-1\r\nxxnet-1717-2\r\nxxnet-1717-3\r\nxxnet-1717-4\r\nxxnet-171903-171903\r\nxxnet-171910\r\nxxnet-173011\r\nxxnet-173012\r\nxxnet-173013\r\nxxnet-173014\r\nxxnet-173015\r\nxxnet-173016\r\nxxnet-1730667\r\nxxnet-1730668\r\nxxnet-174008\r\nxxnet-174009\r\nxxnet-174010\r\nxxnet-174011\r\nxxnet-174012\r\nxxnet-174013\r\nxxnet-174014\r\nxxnet-174315\r\nxxnet-17452\r\nxxnet-17474\r\nxxnet-175305\r\nxxnet-175814\r\nxxnet-175916\r\nxxnet-177622\r\nxxnet-177914\r\nxxnet-18\r\nxxnet-18-181111\r\nxxnet-18010601\r\nxxnet-180308\r\nxxnet-180309\r\nxxnet-180310\r\nxxnet-180311\r\nxxnet-180312\r\nxxnet-180313\r\nxxnet-180314\r\nxxnet-180315\r\nxxnet-180316\r\nxxnet-180317\r\nxxnet-180318\r\nxxnet-180319\r\nxxnet-180320\r\nxxnet-180321\r\nxxnet-180322\r\nxxnet-180323\r\nxxnet-180801\r\nxxnet-180808\r\nxxnet-181\r\nxxnet-181013\r\nxxnet-1813\r\nxxnet-1814\r\nxxnet-1818-191511\r\nxxnet-182\r\nxxnet-182006\r\nxxnet-182008\r\nxxnet-182009\r\nxxnet-182010\r\nxxnet-182011\r\nxxnet-182012\r\nxxnet-182013\r\nxxnet-182014\r\nxxnet-182015\r\nxxnet-182104\r\nxxnet-182303\r\nxxnet-182304\r\nxxnet-182305\r\nxxnet-183\r\nxxnet-183009\r\nxxnet-183141\r\nxxnet-183406\r\nxxnet-183407\r\nxxnet-183409\r\nxxnet-183427\r\nxxnet-183457\r\nxxnet-183470\r\nxxnet-183513\r\nxxnet-183607\r\nxxnet-183905\r\nxxnet-183906\r\nxxnet-184\r\nxxnet-184506\r\nxxnet-184507\r\nxxnet-184508\r\nxxnet-184605\r\nxxnet-184705\r\nxxnet-184812\r\nxxnet-185\r\nxxnet-185001\r\nxxnet-185106\r\nxxnet-185304\r\nxxnet-185403\r\nxxnet-185404\r\nxxnet-185406\r\nxxnet-185415\r\nxxnet-185502\r\nxxnet-185505\r\nxxnet-185613\r\nxxnet-185614\r\nxxnet-185705-185705\r\nxxnet-185718\r\nxxnet-185719\r\nxxnet-185720\r\nxxnet-185721\r\nxxnet-185722\r\nxxnet-185723\r\nxxnet-185814\r\nxxnet-185815\r\nxxnet-185816\r\nxxnet-185817\r\nxxnet-185818\r\nxxnet-185906\r\nxxnet-185907\r\nxxnet-185908\r\nxxnet-185909\r\nxxnet-185910\r\nxxnet-186\r\nxxnet-186016\r\nxxnet-186186\r\nxxnet-186201\r\nxxnet-186222\r\nxxnet-186223\r\nxxnet-186301\r\nxxnet-186419\r\nxxnet-186420\r\nxxnet-186421\r\nxxnet-186422\r\nxxnet-186424\r\nxxnet-186425\r\nxxnet-186426\r\nxxnet-186427\r\nxxnet-186428\r\nxxnet-186429\r\nxxnet-186502\r\nxxnet-186602\r\nxxnet-1866190\r\nxxnet-186701\r\nxxnet-186702\r\nxxnet-186703\r\nxxnet-186704\r\nxxnet-186705\r\nxxnet-186706\r\nxxnet-186715\r\nxxnet-186913\r\nxxnet-187\r\nxxnet-187002\r\nxxnet-187204\r\nxxnet-187206\r\nxxnet-187207\r\nxxnet-187208\r\nxxnet-187209\r\nxxnet-187212\r\nxxnet-187303\r\nxxnet-187407\r\nxxnet-187514\r\nxxnet-187515\r\nxxnet-187516\r\nxxnet-187813\r\nxxnet-187913\r\nxxnet-188\r\nxxnet-188004\r\nxxnet-188005\r\nxxnet-188007\r\nxxnet-188008\r\nxxnet-188009\r\nxxnet-188010\r\nxxnet-188111\r\nxxnet-188412-188412\r\nxxnet-188506\r\nxxnet-188608\r\nxxnet-188707\r\nxxnet-188708\r\nxxnet-188709\r\nxxnet-188710\r\nxxnet-188711\r\nxxnet-188715\r\nxxnet-188903\r\nxxnet-188904\r\nxxnet-188905\r\nxxnet-188906\r\nxxnet-188907\r\nxxnet-189012\r\nxxnet-189415\r\nxxnet-189703\r\nxxnet-189816\r\nxxnet-189902\r\nxxnet-19\r\nxxnet-1900\r\nxxnet-190114\r\nxxnet-190123\r\nxxnet-190210\r\nxxnet-190316\r\nxxnet-190405\r\nxxnet-190612\r\nxxnet-190613\r\nxxnet-190812\r\nxxnet-190824\r\nxxnet-190920\r\nxxnet-191201\r\nxxnet-191212\r\nxxnet-191213\r\nxxnet-191410\r\nxxnet-191706\r\nxxnet-1919-191511\r\nxxnet-191919191\r\nxxnet-192017\r\nxxnet-192116\r\nxxnet-192219\r\nxxnet-192906\r\nxxnet-19305\r\nxxnet-193101\r\nxxnet-193103\r\nxxnet-193106\r\nxxnet-193414\r\nxxnet-193512\r\nxxnet-193614\r\nxxnet-19376\r\nxxnet-193817\r\nxxnet-194016\r\nxxnet-194107\r\nxxnet-194110\r\nxxnet-194111\r\nxxnet-194112\r\nxxnet-194113\r\nxxnet-194114\r\nxxnet-194115\r\nxxnet-194116\r\nxxnet-194117\r\nxxnet-194118\r\nxxnet-194207\r\nxxnet-194207-194207\r\nxxnet-194208\r\nxxnet-194209\r\nxxnet-194210\r\nxxnet-194307\r\nxxnet-194418\r\nxxnet-194808\r\nxxnet-19551\r\nxxnet-196106\r\nxxnet-196107\r\nxxnet-196108\r\nxxnet-196109\r\nxxnet-196110\r\nxxnet-196302\r\nxxnet-19640\r\nxxnet-196405\r\nxxnet-196408\r\nxxnet-1964081\r\nxxnet-1964082\r\nxxnet-196412\r\nxxnet-196413\r\nxxnet-196414\r\nxxnet-196415\r\nxxnet-196416\r\nxxnet-196417\r\nxxnet-196501\r\nxxnet-196510\r\nxxnet-197604\r\nxxnet-197620\r\nxxnet-197621\r\nxxnet-197622\r\nxxnet-197623\r\nxxnet-197624\r\nxxnet-197625\r\nxxnet-197626\r\nxxnet-197627\r\nxxnet-197628\r\nxxnet-197629\r\nxxnet-197630\r\nxxnet-197631\r\nxxnet-197701\r\nxxnet-197816\r\nxxnet-1985010101\r\nxxnet-1986-193817\r\nxxnet-198606\r\nxxnet-198615\r\nxxnet-198703\r\nxxnet-19870702\r\nxxnet-1991111\r\nxxnet-1991112\r\nxxnet-1992-186103\r\nxxnet-199207\r\nxxnet-1995-186103\r\nxxnet-199512\r\nxxnet-199513\r\nxxnet-1997-186103\r\nxxnet-1999-186105\r\nxxnet-1ee1\r\nxxnet-1ee2\r\nxxnet-1ee3\r\nxxnet-1ee4\r\nxxnet-1ee5\r\nxxnet-1ee6\r\nxxnet-2\r\nxxnet-2-1252\r\nxxnet-2-1264\r\nxxnet-2-1265\r\nxxnet-2-1294\r\nxxnet-2-142420\r\nxxnet-2-1470489256157\r\nxxnet-2-171901\r\nxxnet-2-179915\r\nxxnet-2-181013\r\nxxnet-2-181703\r\nxxnet-2-182006\r\nxxnet-2-182011\r\nxxnet-2-182815\r\nxxnet-2-184213\r\nxxnet-2-184606\r\nxxnet-2-184705\r\nxxnet-2-185501\r\nxxnet-2-187212\r\nxxnet-2-187504\r\nxxnet-2-188111\r\nxxnet-2-193607\r\nxxnet-2-196917\r\nxxnet-2-197816\r\nxxnet-2-205004\r\nxxnet-2-207305\r\nxxnet-2-209000\r\nxxnet-2-211015\r\nxxnet-2-211501\r\nxxnet-2-216201\r\nxxnet-2-227015\r\nxxnet-2-233308\r\nxxnet-2-233811\r\nxxnet-2-235202\r\nxxnet-2-249806\r\nxxnet-20\r\nxxnet-200-1199\r\nxxnet-2000-211906\r\nxxnet-2000000\r\nxxnet-200001\r\nxxnet-200002\r\nxxnet-200003\r\nxxnet-200004\r\nxxnet-200005\r\nxxnet-200006\r\nxxnet-200007\r\nxxnet-20024\r\nxxnet-200713\r\nxxnet-200714\r\nxxnet-201-1199\r\nxxnet-201104\r\nxxnet-201105\r\nxxnet-2011056\r\nxxnet-2011076\r\nxxnet-201108\r\nxxnet-2011086\r\nxxnet-2011087\r\nxxnet-2011096\r\nxxnet-201113\r\nxxnet-201114\r\nxxnet-201306\r\nxxnet-201614\r\nxxnet-2016ka\r\nxxnet-2016kb\r\nxxnet-2016kc\r\nxxnet-2016kd\r\nxxnet-2016ke\r\nxxnet-2016kf\r\nxxnet-2016kg\r\nxxnet-2016kh\r\nxxnet-2016ki\r\nxxnet-2016kj\r\nxxnet-2016kk\r\nxxnet-2016km\r\nxxnet-2017-182809\r\nxxnet-2017-182830\r\nxxnet-2017-186105\r\nxxnet-2017001a000\r\nxxnet-2017001a001\r\nxxnet-2017001a002\r\nxxnet-2017001a003\r\nxxnet-2017001a004\r\nxxnet-2017001a005\r\nxxnet-2017001a006\r\nxxnet-2017001a007\r\nxxnet-2017001a008\r\nxxnet-2017001a009\r\nxxnet-2017002a000\r\nxxnet-2017002a001\r\nxxnet-2017002a002\r\nxxnet-2017002a003\r\nxxnet-2017002a004\r\nxxnet-2017002a005\r\nxxnet-2017002a006\r\nxxnet-2017002a007\r\nxxnet-2017002a008\r\nxxnet-2017002a009\r\nxxnet-2017003a000\r\nxxnet-2017003a001\r\nxxnet-2017003a002\r\nxxnet-2017003a003\r\nxxnet-2017003a004\r\nxxnet-2017003a005\r\nxxnet-2017003a006\r\nxxnet-2017003a007\r\nxxnet-2017003a008\r\nxxnet-2017003a009\r\nxxnet-2017004a000\r\nxxnet-2017004a001\r\nxxnet-2017004a002\r\nxxnet-2017004a003\r\nxxnet-2017004a004\r\nxxnet-2017004a005\r\nxxnet-2017004a006\r\nxxnet-2017004a007\r\nxxnet-2017004a008\r\nxxnet-2017004a009\r\nxxnet-2017005a000\r\nxxnet-2017005a001\r\nxxnet-2017005a002\r\nxxnet-2017005a003\r\nxxnet-2017005a004\r\nxxnet-2017005a005\r\nxxnet-2017005a006\r\nxxnet-2017005a007\r\nxxnet-2017005a008\r\nxxnet-2017005a009\r\nxxnet-2017006a000\r\nxxnet-2017006a001\r\nxxnet-2017006a002\r\nxxnet-2017006a003\r\nxxnet-2017006a004\r\nxxnet-2017006a005\r\nxxnet-2017006a006\r\nxxnet-2017006a007\r\nxxnet-2017006a008\r\nxxnet-2017006a009\r\nxxnet-2017007a000\r\nxxnet-2017007a001\r\nxxnet-2017007a002\r\nxxnet-2017007a003\r\nxxnet-2017007a004\r\nxxnet-2017007a005\r\nxxnet-2017007a006\r\nxxnet-2017007a007\r\nxxnet-2017007a008\r\nxxnet-2017007a009\r\nxxnet-2017008a000\r\nxxnet-2017008a001\r\nxxnet-2017008a002\r\nxxnet-2017008a003\r\nxxnet-2017008a004\r\nxxnet-2017008a005\r\nxxnet-2017008a006\r\nxxnet-2017008a007\r\nxxnet-2017008a008\r\nxxnet-2017008a009\r\nxxnet-2017009a000\r\nxxnet-2017009a001\r\nxxnet-2017009a002\r\nxxnet-2017009a003\r\nxxnet-2017009a004\r\nxxnet-2017009a005\r\nxxnet-2017009a006\r\nxxnet-2017009a007\r\nxxnet-2017009a008\r\nxxnet-2017009a009\r\nxxnet-2017010a000\r\nxxnet-2017010a001\r\nxxnet-2017010a002\r\nxxnet-2017010a003\r\nxxnet-2017010a004\r\nxxnet-2017010a005\r\nxxnet-2017010a006\r\nxxnet-2017010a007\r\nxxnet-2017010a008\r\nxxnet-2017010a009\r\nxxnet-2017011a000\r\nxxnet-2017011a001\r\nxxnet-2017011a002\r\nxxnet-2017011a003\r\nxxnet-2017011a004\r\nxxnet-2017011a005\r\nxxnet-2017011a006\r\nxxnet-2017011a007\r\nxxnet-2017011a008\r\nxxnet-2017011a009\r\nxxnet-2017012a000\r\nxxnet-2017012a001\r\nxxnet-2017012a002\r\nxxnet-2017012a003\r\nxxnet-2017012a004\r\nxxnet-2017012a005\r\nxxnet-2017012a006\r\nxxnet-2017012a007\r\nxxnet-2017012a008\r\nxxnet-2017012a009\r\nxxnet-2017013a000\r\nxxnet-2017013a001\r\nxxnet-2017013a002\r\nxxnet-2017013a003\r\nxxnet-2017013a004\r\nxxnet-2017013a005\r\nxxnet-2017013a006\r\nxxnet-2017013a007\r\nxxnet-2017013a008\r\nxxnet-2017013a009\r\nxxnet-2017014a000\r\nxxnet-2017014a001\r\nxxnet-2017014a002\r\nxxnet-2017014a003\r\nxxnet-2017014a004\r\nxxnet-2017014a005\r\nxxnet-2017014a006\r\nxxnet-2017014a007\r\nxxnet-2017014a008\r\nxxnet-2017014a009\r\nxxnet-2017015a000\r\nxxnet-2017015a001\r\nxxnet-2017015a002\r\nxxnet-2017015a003\r\nxxnet-2017015a004\r\nxxnet-2017015a005\r\nxxnet-2017015a006\r\nxxnet-2017015a007\r\nxxnet-2017015a008\r\nxxnet-2017015a009\r\nxxnet-2017016a000\r\nxxnet-2017016a001\r\nxxnet-2017016a002\r\nxxnet-2017016a003\r\nxxnet-2017016a004\r\nxxnet-2017016a005\r\nxxnet-2017016a006\r\nxxnet-2017016a007\r\nxxnet-2017016a008\r\nxxnet-2017016a009\r\nxxnet-2017017a000\r\nxxnet-2017017a001\r\nxxnet-2017017a002\r\nxxnet-2017017a003\r\nxxnet-2017017a004\r\nxxnet-2017017a005\r\nxxnet-2017017a006\r\nxxnet-2017017a007\r\nxxnet-2017017a008\r\nxxnet-2017017a009\r\nxxnet-2017018a000\r\nxxnet-2017018a001\r\nxxnet-2017018a002\r\nxxnet-2017018a003\r\nxxnet-2017018a004\r\nxxnet-2017018a005\r\nxxnet-2017018a006\r\nxxnet-2017018a007\r\nxxnet-2017018a008\r\nxxnet-2017018a009\r\nxxnet-2017019a000\r\nxxnet-2017019a001\r\nxxnet-2017019a002\r\nxxnet-2017019a003\r\nxxnet-2017019a004\r\nxxnet-2017019a005\r\nxxnet-2017019a006\r\nxxnet-2017019a007\r\nxxnet-2017019a008\r\nxxnet-2017019a009\r\nxxnet-2017020a000\r\nxxnet-2017020a001\r\nxxnet-2017020a002\r\nxxnet-2017020a003\r\nxxnet-2017020a004\r\nxxnet-2017020a005\r\nxxnet-2017020a006\r\nxxnet-2017020a007\r\nxxnet-2017020a008\r\nxxnet-2017020a009\r\nxxnet-20170601\r\nxxnet-20170602\r\nxxnet-2017100902\r\nxxnet-2017100903\r\nxxnet-2017100904\r\nxxnet-2017100905\r\nxxnet-20171013\r\nxxnet-20171126\r\nxxnet-201712041\r\nxxnet-20171225\r\nxxnet-201716\r\nxxnet-20171610\r\nxxnet-20171611\r\nxxnet-2017162\r\nxxnet-2017163\r\nxxnet-2017164\r\nxxnet-2017165\r\nxxnet-2017166\r\nxxnet-2017167\r\nxxnet-2017168-154812\r\nxxnet-2017169\r\nxxnet-2018-190707\r\nxxnet-2018-226106\r\nxxnet-201801051632\r\nxxnet-20180114-192101\r\nxxnet-20180121\r\nxxnet-20180122\r\nxxnet-201803\r\nxxnet-20180311\r\nxxnet-20180312\r\nxxnet-20180313\r\nxxnet-20180410\r\nxxnet-20180709\r\nxxnet-201807094-209714\r\nxxnet-20180816\r\nxxnet-20180816-213514\r\nxxnet-2018081600\r\nxxnet-2018081601\r\nxxnet-2018081602\r\nxxnet-2018081603\r\nxxnet-2018081604\r\nxxnet-2018081605\r\nxxnet-2018081606\r\nxxnet-2018081607\r\nxxnet-2018081608\r\nxxnet-2018081609\r\nxxnet-20180820\r\nxxnet-2018082602\r\nxxnet-2018082603\r\nxxnet-2018082604\r\nxxnet-20180900\r\nxxnet-20180901\r\nxxnet-20180902\r\nxxnet-20180903\r\nxxnet-20180904\r\nxxnet-20180905\r\nxxnet-20180906\r\nxxnet-20180907\r\nxxnet-20180908\r\nxxnet-20180909\r\nxxnet-20180910\r\nxxnet-201811\r\nxxnet-20181201\r\nxxnet-20181202\r\nxxnet-20181203\r\nxxnet-20181204\r\nxxnet-20181204-224602\r\nxxnet-20181205\r\nxxnet-20181205-224602\r\nxxnet-20181206\r\nxxnet-20181207\r\nxxnet-20181208\r\nxxnet-20181209\r\nxxnet-20181210\r\nxxnet-20181211\r\nxxnet-20190123\r\nxxnet-20190128\r\nxxnet-20190131\r\nxxnet-20190131a\r\nxxnet-20190131b\r\nxxnet-20190131c\r\nxxnet-20190131d\r\nxxnet-201902190908\r\nxxnet-2019021909081128\r\nxxnet-20190225\r\nxxnet-20190226\r\nxxnet-20190227\r\nxxnet-20190228\r\nxxnet-20190228-232811\r\nxxnet-20190301\r\nxxnet-20190302\r\nxxnet-20190303\r\nxxnet-2019030301\r\nxxnet-2019030302\r\nxxnet-20190304\r\nxxnet-20190305\r\nxxnet-20190306\r\nxxnet-20190307\r\nxxnet-201904211824\r\nxxnet-201904211828\r\nxxnet-201908\r\nxxnet-20190823a\r\nxxnet-20190823b\r\nxxnet-20190925\r\nxxnet-202-1199\r\nxxnet-202205\r\nxxnet-202414\r\nxxnet-203-1199\r\nxxnet-203108\r\nxxnet-203500\r\nxxnet-203802\r\nxxnet-203852938\r\nxxnet-204-1199\r\nxxnet-20401\r\nxxnet-20402\r\nxxnet-20403\r\nxxnet-204406\r\nxxnet-204711\r\nxxnet-2047113\r\nxxnet-204719\r\nxxnet-205-1199\r\nxxnet-205202\r\nxxnet-205702\r\nxxnet-205703\r\nxxnet-205705\r\nxxnet-205706\r\nxxnet-205707\r\nxxnet-205708\r\nxxnet-205709\r\nxxnet-205710\r\nxxnet-205711\r\nxxnet-205712\r\nxxnet-205713\r\nxxnet-206-1199\r\nxxnet-206203\r\nxxnet-206752\r\nxxnet-206903\r\nxxnet-207-1199\r\nxxnet-207003\r\nxxnet-207011\r\nxxnet-20712\r\nxxnet-207312\r\nxxnet-207315\r\nxxnet-207609\r\nxxnet-208106\r\nxxnet-208507\r\nxxnet-2090\r\nxxnet-2091\r\nxxnet-2092\r\nxxnet-2093\r\nxxnet-2094\r\nxxnet-2095\r\nxxnet-2096\r\nxxnet-209616\r\nxxnet-2097\r\nxxnet-2098\r\nxxnet-2099\r\nxxnet-209902\r\nxxnet-209903\r\nxxnet-21\r\nxxnet-210002\r\nxxnet-210206\r\nxxnet-210602\r\nxxnet-211015\r\nxxnet-21111-211906\r\nxxnet-211802\r\nxxnet-212302\r\nxxnet-21232123\r\nxxnet-212405\r\nxxnet-212702\r\nxxnet-2137\r\nxxnet-214016\r\nxxnet-214114\r\nxxnet-214115\r\nxxnet-214214\r\nxxnet-214503\r\nxxnet-215102\r\nxxnet-215103\r\nxxnet-215111\r\nxxnet-215413\r\nxxnet-215902\r\nxxnet-215904\r\nxxnet-215910\r\nxxnet-215911\r\nxxnet-2159118\r\nxxnet-2159119\r\nxxnet-215913\r\nxxnet-215916\r\nxxnet-215917\r\nxxnet-215921\r\nxxnet-215922\r\nxxnet-216012\r\nxxnet-216109\r\nxxnet-216915\r\nxxnet-217301\r\nxxnet-217403\r\nxxnet-217607\r\nxxnet-218302\r\nxxnet-218313\r\nxxnet-218323\r\nxxnet-218403\r\nxxnet-218404\r\nxxnet-218705\r\nxxnet-219901\r\nxxnet-22\r\nxxnet-22-1273\r\nxxnet-22-225902\r\nxxnet-220306\r\nxxnet-2203061\r\nxxnet-2204306\r\nxxnet-220609\r\nxxnet-221713\r\nxxnet-2220306\r\nxxnet-222211\r\nxxnet-22233\r\nxxnet-222502\r\nxxnet-223701\r\nxxnet-223708\r\nxxnet-223709\r\nxxnet-224104\r\nxxnet-224208\r\nxxnet-224602\r\nxxnet-225402\r\nxxnet-225902\r\nxxnet-225906\r\nxxnet-226201\r\nxxnet-226202\r\nxxnet-226301\r\nxxnet-226317\r\nxxnet-226318\r\nxxnet-226601\r\nxxnet-226908\r\nxxnet-227710\r\nxxnet-227806\r\nxxnet-228003\r\nxxnet-22832\r\nxxnet-228613\r\nxxnet-229003\r\nxxnet-229101\r\nxxnet-229207\r\nxxnet-229405\r\nxxnet-229515\r\nxxnet-229801\r\nxxnet-23\r\nxxnet-230105\r\nxxnet-230306\r\nxxnet-230617\r\nxxnet-230711\r\nxxnet-230915\r\nxxnet-231\r\nxxnet-231104\r\nxxnet-231501\r\nxxnet-2315017\r\nxxnet-2315037\r\nxxnet-2315047\r\nxxnet-2315057\r\nxxnet-2315067\r\nxxnet-231507\r\nxxnet-2315071\r\nxxnet-2315077\r\nxxnet-2315087\r\nxxnet-2315807\r\nxxnet-2315907\r\nxxnet-232\r\nxxnet-232105\r\nxxnet-232106\r\nxxnet-2322\r\nxxnet-2323\r\nxxnet-232304\r\nxxnet-23230423\r\nxxnet-23245\r\nxxnet-233\r\nxxnet-233001\r\nxxnet-233107\r\nxxnet-233108\r\nxxnet-233109\r\nxxnet-233110\r\nxxnet-233333-185712\r\nxxnet-2336\r\nxxnet-233806\r\nxxnet-233807\r\nxxnet-234\r\nxxnet-234-1q\r\nxxnet-234004\r\nxxnet-2341\r\nxxnet-234103\r\nxxnet-2343\r\nxxnet-2347\r\nxxnet-2348\r\nxxnet-2349\r\nxxnet-23491\r\nxxnet-234ghgs\r\nxxnet-235\r\nxxnet-235115\r\nxxnet-235404\r\nxxnet-23555\r\nxxnet-23556\r\nxxnet-23557\r\nxxnet-2356\r\nxxnet-235903\r\nxxnet-235917\r\nxxnet-236\r\nxxnet-237\r\nxxnet-237003\r\nxxnet-237010\r\nxxnet-237410\r\nxxnet-237411\r\nxxnet-237502\r\nxxnet-237807\r\nxxnet-238\r\nxxnet-23848\r\nxxnet-239\r\nxxnet-239712\r\nxxnet-239911\r\nxxnet-24\r\nxxnet-240\r\nxxnet-240009\r\nxxnet-240709\r\nxxnet-241\r\nxxnet-242\r\nxxnet-242004\r\nxxnet-242712\r\nxxnet-243802\r\nxxnet-244504\r\nxxnet-244611\r\nxxnet-2456\r\nxxnet-24626\r\nxxnet-246818\r\nxxnet-246914\r\nxxnet-249102\r\nxxnet-249604\r\nxxnet-249803\r\nxxnet-249806\r\nxxnet-25\r\nxxnet-250116\r\nxxnet-250123\r\nxxnet-250160\r\nxxnet-250217\r\nxxnet-251106\r\nxxnet-251301\r\nxxnet-251900\r\nxxnet-251901\r\nxxnet-25305\r\nxxnet-253309\r\nxxnet-253310\r\nxxnet-253311\r\nxxnet-253311-253309\r\nxxnet-255\r\nxxnet-256002\r\nxxnet-256105\r\nxxnet-256602\r\nxxnet-256608\r\nxxnet-257302\r\nxxnet-257304\r\nxxnet-257701\r\nxxnet-2580\r\nxxnet-2581\r\nxxnet-2582\r\nxxnet-2583\r\nxxnet-2584\r\nxxnet-2585\r\nxxnet-2586\r\nxxnet-2587\r\nxxnet-2588\r\nxxnet-2588-209014\r\nxxnet-2589\r\nxxnet-2590\r\nxxnet-26\r\nxxnet-26199\r\nxxnet-26389\r\nxxnet-26868\r\nxxnet-27\r\nxxnet-27044\r\nxxnet-27636\r\nxxnet-276893\r\nxxnet-27887\r\nxxnet-27980\r\nxxnet-28\r\nxxnet-28198\r\nxxnet-28401\r\nxxnet-28764\r\nxxnet-29\r\nxxnet-29250\r\nxxnet-294\r\nxxnet-295\r\nxxnet-3\r\nxxnet-3-1252\r\nxxnet-3-1264\r\nxxnet-3-1265\r\nxxnet-3-1294\r\nxxnet-3-1470489266796\r\nxxnet-3-181013\r\nxxnet-3-181703\r\nxxnet-3-182006\r\nxxnet-3-182011\r\nxxnet-3-182815\r\nxxnet-3-184213\r\nxxnet-3-184606\r\nxxnet-3-184705\r\nxxnet-3-187504\r\nxxnet-3-193607\r\nxxnet-3-196917\r\nxxnet-3-197816\r\nxxnet-3-205004\r\nxxnet-3-209000\r\nxxnet-3-211015\r\nxxnet-3-211501\r\nxxnet-3-214016\r\nxxnet-3-227015\r\nxxnet-3-233308\r\nxxnet-3-233811\r\nxxnet-30\r\nxxnet-300001\r\nxxnet-300002\r\nxxnet-300003\r\nxxnet-300004\r\nxxnet-300005\r\nxxnet-300006\r\nxxnet-300007\r\nxxnet-300008\r\nxxnet-300009\r\nxxnet-300009-228901\r\nxxnet-300010\r\nxxnet-300011\r\nxxnet-300110\r\nxxnet-300111\r\nxxnet-3021\r\nxxnet-30982\r\nxxnet-31\r\nxxnet-311\r\nxxnet-31169-238008\r\nxxnet-3123456\r\nxxnet-3123457\r\nxxnet-31415\r\nxxnet-3141501\r\nxxnet-3141502\r\nxxnet-3141503\r\nxxnet-3141504\r\nxxnet-3141505\r\nxxnet-3141506\r\nxxnet-3141507\r\nxxnet-3141508\r\nxxnet-3141509\r\nxxnet-3141511\r\nxxnet-3141512\r\nxxnet-3141513\r\nxxnet-3141514\r\nxxnet-3141515\r\nxxnet-3141516\r\nxxnet-3141517\r\nxxnet-3141518\r\nxxnet-3141519\r\nxxnet-3141520\r\nxxnet-31605\r\nxxnet-31718\r\nxxnet-32\r\nxxnet-32-1273\r\nxxnet-321\r\nxxnet-322\r\nxxnet-323\r\nxxnet-324\r\nxxnet-3245325\r\nxxnet-326\r\nxxnet-327\r\nxxnet-329\r\nxxnet-33\r\nxxnet-33-1273\r\nxxnet-330\r\nxxnet-331\r\nxxnet-332\r\nxxnet-3326\r\nxxnet-3338\r\nxxnet-33443\r\nxxnet-3345\r\nxxnet-3346\r\nxxnet-3347\r\nxxnet-3348\r\nxxnet-3349\r\nxxnet-34\r\nxxnet-34708\r\nxxnet-347952\r\nxxnet-35\r\nxxnet-351\r\nxxnet-35400\r\nxxnet-35400-208609\r\nxxnet-35422\r\nxxnet-35488\r\nxxnet-35789-171400\r\nxxnet-35789-214215\r\nxxnet-36\r\nxxnet-36922\r\nxxnet-36969\r\nxxnet-37\r\nxxnet-371400\r\nxxnet-371401\r\nxxnet-371402\r\nxxnet-371403\r\nxxnet-371404\r\nxxnet-371405\r\nxxnet-371406\r\nxxnet-371407\r\nxxnet-371408\r\nxxnet-371409\r\nxxnet-371410\r\nxxnet-371411\r\nxxnet-3720\r\nxxnet-37245\r\nxxnet-38\r\nxxnet-38584\r\nxxnet-39\r\nxxnet-39474\r\nxxnet-39475\r\nxxnet-39476\r\nxxnet-39477\r\nxxnet-3952\r\nxxnet-4\r\nxxnet-4-1252\r\nxxnet-4-1264\r\nxxnet-4-1265\r\nxxnet-4-1294\r\nxxnet-4-1470489307188\r\nxxnet-4-181703\r\nxxnet-4-182006\r\nxxnet-4-182011\r\nxxnet-4-182815\r\nxxnet-4-184213\r\nxxnet-4-184606\r\nxxnet-4-184705\r\nxxnet-4-187504\r\nxxnet-4-196917\r\nxxnet-4-197816\r\nxxnet-4-199505\r\nxxnet-4-205004\r\nxxnet-4-211015\r\nxxnet-4-214016\r\nxxnet-4-216002\r\nxxnet-4-227015\r\nxxnet-4-233308\r\nxxnet-4-233811\r\nxxnet-40\r\nxxnet-4011\r\nxxnet-4011-192902\r\nxxnet-4011-193007\r\nxxnet-4012\r\nxxnet-4012-192902\r\nxxnet-4012-193007\r\nxxnet-4013\r\nxxnet-4013-193007\r\nxxnet-4014\r\nxxnet-4014-193007\r\nxxnet-4015\r\nxxnet-4015-193007\r\nxxnet-4016\r\nxxnet-4016-193007\r\nxxnet-4017\r\nxxnet-4017-193007\r\nxxnet-4018\r\nxxnet-4018-193007\r\nxxnet-4019\r\nxxnet-4019-193007\r\nxxnet-4020\r\nxxnet-4020-193007\r\nxxnet-4021\r\nxxnet-4021-193007\r\nxxnet-4022\r\nxxnet-4022-193007\r\nxxnet-40944\r\nxxnet-41\r\nxxnet-42\r\nxxnet-4201\r\nxxnet-42033\r\nxxnet-42630\r\nxxnet-42744\r\nxxnet-43\r\nxxnet-44\r\nxxnet-44144\r\nxxnet-44156\r\nxxnet-44279\r\nxxnet-44566\r\nxxnet-4494\r\nxxnet-45\r\nxxnet-45269\r\nxxnet-4562103\r\nxxnet-456290\r\nxxnet-46\r\nxxnet-46008\r\nxxnet-46079\r\nxxnet-4620\r\nxxnet-46261\r\nxxnet-46565\r\nxxnet-466008\r\nxxnet-46745\r\nxxnet-46768\r\nxxnet-468935\r\nxxnet-47\r\nxxnet-47437\r\nxxnet-47614\r\nxxnet-48\r\nxxnet-48511\r\nxxnet-4869\r\nxxnet-48965\r\nxxnet-49\r\nxxnet-49022\r\nxxnet-49280\r\nxxnet-4980\r\nxxnet-4s5-1\r\nxxnet-5\r\nxxnet-5-1252\r\nxxnet-5-1264\r\nxxnet-5-1265\r\nxxnet-5-1294\r\nxxnet-5-1470489318289\r\nxxnet-5-181703\r\nxxnet-5-182007\r\nxxnet-5-182011\r\nxxnet-5-182815\r\nxxnet-5-184213\r\nxxnet-5-184606\r\nxxnet-5-184705\r\nxxnet-5-187504\r\nxxnet-5-196917\r\nxxnet-5-197816\r\nxxnet-5-199505\r\nxxnet-5-205004\r\nxxnet-5-211015\r\nxxnet-5-214016\r\nxxnet-5-220306\r\nxxnet-5-227308\r\nxxnet-5-233308\r\nxxnet-5-233811\r\nxxnet-50\r\nxxnet-500\r\nxxnet-5000-205202\r\nxxnet-5001\r\nxxnet-5001-205202\r\nxxnet-5002\r\nxxnet-501\r\nxxnet-502\r\nxxnet-503\r\nxxnet-50306\r\nxxnet-504\r\nxxnet-505\r\nxxnet-506\r\nxxnet-50619\r\nxxnet-507\r\nxxnet-508\r\nxxnet-509\r\nxxnet-51\r\nxxnet-510\r\nxxnet-511\r\nxxnet-514987111\r\nxxnet-514987444\r\nxxnet-5168\r\nxxnet-5169\r\nxxnet-51838\r\nxxnet-51990\r\nxxnet-52\r\nxxnet-520001\r\nxxnet-520002\r\nxxnet-520003\r\nxxnet-520004\r\nxxnet-520005\r\nxxnet-520006\r\nxxnet-520007\r\nxxnet-520008\r\nxxnet-520009\r\nxxnet-520010\r\nxxnet-520011\r\nxxnet-520012\r\nxxnet-53\r\nxxnet-5331\r\nxxnet-54\r\nxxnet-5438\r\nxxnet-5443\r\nxxnet-5465\r\nxxnet-55\r\nxxnet-5545\r\nxxnet-55502\r\nxxnet-556\r\nxxnet-56\r\nxxnet-5692aa\r\nxxnet-5693aa\r\nxxnet-57\r\nxxnet-57420\r\nxxnet-576190\r\nxxnet-58\r\nxxnet-59\r\nxxnet-594463981\r\nxxnet-59808\r\nxxnet-6\r\nxxnet-6-1252\r\nxxnet-6-1264\r\nxxnet-6-1265\r\nxxnet-6-1294\r\nxxnet-6-182007\r\nxxnet-6-184202\r\nxxnet-6-184213\r\nxxnet-6-184606\r\nxxnet-6-184705\r\nxxnet-6-187504\r\nxxnet-6-197816\r\nxxnet-6-205004\r\nxxnet-6-208703\r\nxxnet-6-214016\r\nxxnet-6-227308\r\nxxnet-60\r\nxxnet-601\r\nxxnet-602\r\nxxnet-603\r\nxxnet-604\r\nxxnet-605\r\nxxnet-606\r\nxxnet-607\r\nxxnet-608\r\nxxnet-609\r\nxxnet-61\r\nxxnet-610\r\nxxnet-611\r\nxxnet-612\r\nxxnet-613\r\nxxnet-614\r\nxxnet-615\r\nxxnet-616\r\nxxnet-617\r\nxxnet-618\r\nxxnet-619\r\nxxnet-62\r\nxxnet-620\r\nxxnet-621\r\nxxnet-62576\r\nxxnet-62912\r\nxxnet-62963\r\nxxnet-63\r\nxxnet-63723\r\nxxnet-63997\r\nxxnet-64\r\nxxnet-64187\r\nxxnet-64270\r\nxxnet-64453\r\nxxnet-65\r\nxxnet-6553601\r\nxxnet-6553607\r\nxxnet-66\r\nxxnet-66-184202\r\nxxnet-6623\r\nxxnet-66615\r\nxxnet-66616\r\nxxnet-66617\r\nxxnet-66661\r\nxxnet-667-183908\r\nxxnet-67\r\nxxnet-67168\r\nxxnet-67363\r\nxxnet-68\r\nxxnet-6814\r\nxxnet-6825\r\nxxnet-6853\r\nxxnet-6854\r\nxxnet-6855\r\nxxnet-68558\r\nxxnet-6856\r\nxxnet-6856-1251\r\nxxnet-6857\r\nxxnet-6858\r\nxxnet-6859\r\nxxnet-6870\r\nxxnet-6871\r\nxxnet-6872\r\nxxnet-69\r\nxxnet-6x6666\r\nxxnet-7\r\nxxnet-7-1252\r\nxxnet-7-1264\r\nxxnet-7-1265\r\nxxnet-7-1294\r\nxxnet-7-182007\r\nxxnet-7-184213\r\nxxnet-7-184606\r\nxxnet-7-184705\r\nxxnet-7-185209\r\nxxnet-7-197816\r\nxxnet-7-205004\r\nxxnet-7-208703\r\nxxnet-7-211015\r\nxxnet-7-214016\r\nxxnet-70\r\nxxnet-7096\r\nxxnet-70983\r\nxxnet-71\r\nxxnet-71495\r\nxxnet-72\r\nxxnet-731220\r\nxxnet-74\r\nxxnet-7418-201902191041\r\nxxnet-74523\r\nxxnet-75\r\nxxnet-76\r\nxxnet-77\r\nxxnet-77121649\r\nxxnet-77504\r\nxxnet-77541\r\nxxnet-7777-233503\r\nxxnet-78\r\nxxnet-786446581-1\r\nxxnet-786446581-2\r\nxxnet-786446581-3\r\nxxnet-786446581-4\r\nxxnet-786446581-5\r\nxxnet-786446581-6\r\nxxnet-786446581-7\r\nxxnet-79\r\nxxnet-79412\r\nxxnet-7963\r\nxxnet-7964\r\nxxnet-7965\r\nxxnet-7966\r\nxxnet-7967\r\nxxnet-7968\r\nxxnet-8\r\nxxnet-8-1252\r\nxxnet-8-1264\r\nxxnet-8-1265\r\nxxnet-8-1294\r\nxxnet-8-182007\r\nxxnet-8-184213\r\nxxnet-8-184606\r\nxxnet-8-184705\r\nxxnet-8-185209\r\nxxnet-8-187504\r\nxxnet-8-197816\r\nxxnet-8-205004\r\nxxnet-8-208703\r\nxxnet-8-214016\r\nxxnet-80\r\nxxnet-80221\r\nxxnet-80374\r\nxxnet-81\r\nxxnet-81230\r\nxxnet-81322\r\nxxnet-81706\r\nxxnet-81733\r\nxxnet-82\r\nxxnet-8222\r\nxxnet-83\r\nxxnet-84\r\nxxnet-84114a\r\nxxnet-84114c\r\nxxnet-84114d\r\nxxnet-84114e\r\nxxnet-84114f\r\nxxnet-84114g\r\nxxnet-84114h\r\nxxnet-84114j\r\nxxnet-84114k\r\nxxnet-84114m\r\nxxnet-84114n\r\nxxnet-84585\r\nxxnet-84832\r\nxxnet-84868\r\nxxnet-85\r\nxxnet-86\r\nxxnet-86212\r\nxxnet-865180983-01\r\nxxnet-865180983-02\r\nxxnet-865180983-03\r\nxxnet-87\r\nxxnet-874184\r\nxxnet-87658\r\nxxnet-87677\r\nxxnet-87742\r\nxxnet-88\r\nxxnet-8881\r\nxxnet-8882\r\nxxnet-89\r\nxxnet-89039003\r\nxxnet-89275\r\nxxnet-896thy\r\nxxnet-9\r\nxxnet-9-1252\r\nxxnet-9-1264\r\nxxnet-9-1265\r\nxxnet-9-1294\r\nxxnet-9-184213\r\nxxnet-9-184705\r\nxxnet-9-185209\r\nxxnet-9-187504\r\nxxnet-9-208703\r\nxxnet-9-211015\r\nxxnet-9-214016\r\nxxnet-90\r\nxxnet-900001\r\nxxnet-9011\r\nxxnet-9012\r\nxxnet-905\r\nxxnet-906\r\nxxnet-907\r\nxxnet-908\r\nxxnet-9089\r\nxxnet-909\r\nxxnet-9091\r\nxxnet-9092\r\nxxnet-91\r\nxxnet-910\r\nxxnet-911\r\nxxnet-91170\r\nxxnet-91310\r\nxxnet-9164\r\nxxnet-92\r\nxxnet-92280\r\nxxnet-92676\r\nxxnet-92676-213116\r\nxxnet-93\r\nxxnet-93050\r\nxxnet-93069\r\nxxnet-93279\r\nxxnet-93967\r\nxxnet-94\r\nxxnet-942640\r\nxxnet-94575\r\nxxnet-9489\r\nxxnet-95\r\nxxnet-95111\r\nxxnet-954\r\nxxnet-95413\r\nxxnet-956197212\r\nxxnet-96\r\nxxnet-9616811\r\nxxnet-96170\r\nxxnet-96173\r\nxxnet-96804\r\nxxnet-96928\r\nxxnet-96928-57857\r\nxxnet-97\r\nxxnet-98\r\nxxnet-980311\r\nxxnet-986\r\nxxnet-9875\r\nxxnet-9876-203514\r\nxxnet-98947\r\nxxnet-99\r\nxxnet-99164-240411\r\nxxnet-9955\r\nxxnet-996\r\nxxnet-99668\r\nxxnet-99764\r\nxxnet-999\r\nxxnet-99901\r\nxxnet-99902\r\nxxnet-99903\r\nxxnet-99904\r\nxxnet-99905\r\nxxnet-99906\r\nxxnet-99907\r\nxxnet-99908\r\nxxnet-99909\r\nxxnet-99910\r\nxxnet-99911\r\nxxnet-99912\r\nxxnet-a-191001\r\nxxnet-a-226318\r\nxxnet-a-226609\r\nxxnet-a2\r\nxxnet-a3\r\nxxnet-a372872\r\nxxnet-a372872-184509\r\nxxnet-aa-187503\r\nxxnet-aaa\r\nxxnet-abc-188015\r\nxxnet-abiding-lead-162410\r\nxxnet-abroad\r\nxxnet-abroad-2\r\nxxnet-adol1\r\nxxnet-adv01\r\nxxnet-adv02\r\nxxnet-adv03\r\nxxnet-adv04\r\nxxnet-adv05\r\nxxnet-adv06\r\nxxnet-adv07\r\nxxnet-adv08\r\nxxnet-adv09\r\nxxnet-adv10\r\nxxnet-adv11\r\nxxnet-adv12\r\nxxnet-akbxx101\r\nxxnet-akbxx102\r\nxxnet-akbxx103\r\nxxnet-akbxx104\r\nxxnet-akbxx105\r\nxxnet-akbxx106\r\nxxnet-akbxx107\r\nxxnet-akbxx108\r\nxxnet-akbxx109\r\nxxnet-akbxx111\r\nxxnet-al1\r\nxxnet-al26313\r\nxxnet-alex3016-1\r\nxxnet-alex3016-2\r\nxxnet-alex3016-3\r\nxxnet-alex3016-4\r\nxxnet-alex3016-5\r\nxxnet-alex3016-6\r\nxxnet-algebraic-depot-187413\r\nxxnet-alien-sol-226702\r\nxxnet-alphago\r\nxxnet-alphago-176603\r\nxxnet-andsoareyou\r\nxxnet-any008\r\nxxnet-any009\r\nxxnet-any010\r\nxxnet-aono001\r\nxxnet-aono002\r\nxxnet-aow1\r\nxxnet-aow2\r\nxxnet-aow3\r\nxxnet-aow4\r\nxxnet-app30\r\nxxnet-app31\r\nxxnet-appid-001\r\nxxnet-appid-228515\r\nxxnet-appid-230211\r\nxxnet-appid01\r\nxxnet-application-1033\r\nxxnet-apro-01\r\nxxnet-apro-02\r\nxxnet-apro-03\r\nxxnet-asxvccb\r\nxxnet-attention-2215\r\nxxnet-aw-01\r\nxxnet-aw-02\r\nxxnet-aw-03\r\nxxnet-aw-04\r\nxxnet-aw-05\r\nxxnet-aw-06\r\nxxnet-aw-07\r\nxxnet-aw-08\r\nxxnet-aw-09\r\nxxnet-aw-10\r\nxxnet-aw-11\r\nxxnet-aw-12\r\nxxnet-b-191001\r\nxxnet-b-226318\r\nxxnet-bb-187503\r\nxxnet-betykang01\r\nxxnet-betykang02\r\nxxnet-bin-1\r\nxxnet-bled01\r\nxxnet-bled02\r\nxxnet-bled03\r\nxxnet-bled04\r\nxxnet-bob1\r\nxxnet-bob2\r\nxxnet-bona-1\r\nxxnet-bona-2\r\nxxnet-bona-3\r\nxxnet-bona-4\r\nxxnet-bona-5\r\nxxnet-bsl001\r\nxxnet-bsl002\r\nxxnet-bsl003\r\nxxnet-burner-248708\r\nxxnet-c-191001\r\nxxnet-c-226318\r\nxxnet-c-226609\r\nxxnet-calvne\r\nxxnet-calvneice\r\nxxnet-cc-187503\r\nxxnet-cheathao1\r\nxxnet-cheathao2\r\nxxnet-chegan1\r\nxxnet-chegan2\r\nxxnet-chenzn1\r\nxxnet-chenzn2\r\nxxnet-chenzn3\r\nxxnet-chenzn4\r\nxxnet-chenzn5\r\nxxnet-chncnlp\r\nxxnet-chncnlp2\r\nxxnet-chris-cn-0\r\nxxnet-chris-cn-1\r\nxxnet-chris-cn-2\r\nxxnet-chris-cn-3\r\nxxnet-chris-cn-4\r\nxxnet-chris-cn-5\r\nxxnet-chris-cn-6\r\nxxnet-chris-cn-7\r\nxxnet-chris-cn-8\r\nxxnet-chris-cn-9\r\nxxnet-cjzs1\r\nxxnet-cjzs10\r\nxxnet-cjzs11\r\nxxnet-cjzs2\r\nxxnet-cjzs3\r\nxxnet-cjzs4\r\nxxnet-cjzs5\r\nxxnet-cjzs6\r\nxxnet-cjzs7\r\nxxnet-cjzs8\r\nxxnet-cjzs9\r\nxxnet-clgg-1010\r\nxxnet-clgg-1011\r\nxxnet-clgg-1012\r\nxxnet-cng1\r\nxxnet-cng10\r\nxxnet-cng11\r\nxxnet-cng12\r\nxxnet-cng2\r\nxxnet-cng3\r\nxxnet-cng4\r\nxxnet-cng5\r\nxxnet-cng6\r\nxxnet-cng7\r\nxxnet-cng8\r\nxxnet-cng9\r\nxxnet-cntchen\r\nxxnet-code\r\nxxnet-coffe-1\r\nxxnet-coffe-10\r\nxxnet-coffe-11\r\nxxnet-coffe-12\r\nxxnet-coffe-2\r\nxxnet-coffe-3\r\nxxnet-coffe-4\r\nxxnet-coffe-5\r\nxxnet-coffe-6\r\nxxnet-coffe-7\r\nxxnet-coffe-8\r\nxxnet-coffe-9\r\nxxnet-con01\r\nxxnet-con02\r\nxxnet-con03\r\nxxnet-con04\r\nxxnet-con05\r\nxxnet-con06\r\nxxnet-con07\r\nxxnet-con08\r\nxxnet-con09\r\nxxnet-con10\r\nxxnet-con11\r\nxxnet-con12\r\nxxnet-cove-184808\r\nxxnet-csjzc\r\nxxnet-csjzc1\r\nxxnet-custardcup\r\nxxnet-custardpie\r\nxxnet-custardpowder\r\nxxnet-custards\r\nxxnet-custerite\r\nxxnet-custode\r\nxxnet-cx-1\r\nxxnet-cx-2\r\nxxnet-cx-3\r\nxxnet-cx-4\r\nxxnet-cx-5\r\nxxnet-d-191001\r\nxxnet-d-226318\r\nxxnet-d-226609\r\nxxnet-d01\r\nxxnet-d01-185014\r\nxxnet-d02\r\nxxnet-d02-185014\r\nxxnet-d03\r\nxxnet-d04\r\nxxnet-d05\r\nxxnet-d06\r\nxxnet-d2131\r\nxxnet-d701\r\nxxnet-d702\r\nxxnet-d703\r\nxxnet-d704\r\nxxnet-da-01\r\nxxnet-da-02\r\nxxnet-da01\r\nxxnet-da02\r\nxxnet-da03\r\nxxnet-da04\r\nxxnet-da05\r\nxxnet-dbd01\r\nxxnet-dbd02\r\nxxnet-dbd04\r\nxxnet-dbd05\r\nxxnet-dbd06\r\nxxnet-dbd07\r\nxxnet-dbd08\r\nxxnet-destiny-184808\r\nxxnet-devn1101\r\nxxnet-dfaggf\r\nxxnet-diyag-01\r\nxxnet-djs1\r\nxxnet-djs2\r\nxxnet-djs3\r\nxxnet-djs4\r\nxxnet-djs5\r\nxxnet-djs6\r\nxxnet-djs7\r\nxxnet-dmw02\r\nxxnet-dn001\r\nxxnet-dn002\r\nxxnet-dn003\r\nxxnet-dn004\r\nxxnet-dn005\r\nxxnet-dn006\r\nxxnet-dntbylu1\r\nxxnet-do\r\nxxnet-donate\r\nxxnet-donate-001-187502\r\nxxnet-donate-0010-40469\r\nxxnet-donate-0011-59245\r\nxxnet-donate-0012-21393\r\nxxnet-donate-003-80571\r\nxxnet-donate-004-20785\r\nxxnet-donate-005-1825\r\nxxnet-donate-006-39642\r\nxxnet-donate-007-69769\r\nxxnet-donate-008-500\r\nxxnet-donate-009-63904\r\nxxnet-donate-01\r\nxxnet-donate-01-220912\r\nxxnet-donate-1\r\nxxnet-donate-1-184903\r\nxxnet-donate-193608\r\nxxnet-donate-2\r\nxxnet-donate-245802\r\nxxnet-donate-3\r\nxxnet-donate-id\r\nxxnet-donate-junting1\r\nxxnet-donate001\r\nxxnet-donate002\r\nxxnet-donate1-186509\r\nxxnet-donate1-187508\r\nxxnet-donate1-196407\r\nxxnet-donate1-236708\r\nxxnet-donate2-186509\r\nxxnet-donate2-187508\r\nxxnet-donate2-196407\r\nxxnet-donate2-236708\r\nxxnet-donate3-236708\r\nxxnet-donate4-236708\r\nxxnet-donate5-236708\r\nxxnet-donatelxd1\r\nxxnet-donatelxd1-220102\r\nxxnet-donatelxd2\r\nxxnet-donatelxd3\r\nxxnet-dongdongdonate\r\nxxnet-dtdtrr1\r\nxxnet-e-191001\r\nxxnet-e-226609\r\nxxnet-ee\r\nxxnet-eighth-veld-162410\r\nxxnet-ellipsia\r\nxxnet-ellipsia-189114\r\nxxnet-ellipsia-2\r\nxxnet-ellipsia-3\r\nxxnet-en-130\r\nxxnet-en-131\r\nxxnet-en-132\r\nxxnet-enaihei-a\r\nxxnet-enaihei-b\r\nxxnet-enaihei-c\r\nxxnet-enaihei-d\r\nxxnet-enaihei-e\r\nxxnet-enaihei-f\r\nxxnet-enaihei-g\r\nxxnet-environs-124806\r\nxxnet-etc\r\nxxnet-etc02\r\nxxnet-etc03\r\nxxnet-etc04\r\nxxnet-etc05\r\nxxnet-etc06\r\nxxnet-ethanzhu1109\r\nxxnet-ethanzhu110902\r\nxxnet-ethanzhu110903\r\nxxnet-evachen\r\nxxnet-exh01\r\nxxnet-exh02\r\nxxnet-exh03\r\nxxnet-exh04\r\nxxnet-exh05\r\nxxnet-exh06\r\nxxnet-exh07\r\nxxnet-exh08\r\nxxnet-exh09\r\nxxnet-exh10\r\nxxnet-exh11\r\nxxnet-exh12\r\nxxnet-f-191001\r\nxxnet-f0rrest-cn10\r\nxxnet-f0rrest-cn11\r\nxxnet-f21\r\nxxnet-f22\r\nxxnet-f23\r\nxxnet-f24\r\nxxnet-f25\r\nxxnet-f26\r\nxxnet-fafa\r\nxxnet-fangxw-do-01\r\nxxnet-fangxw-do-02\r\nxxnet-fcxnydew\r\nxxnet-fek\r\nxxnet-fengye\r\nxxnet-fengye-237300\r\nxxnet-fengye01\r\nxxnet-fengye02\r\nxxnet-fengye05\r\nxxnet-fengye06\r\nxxnet-fengye07\r\nxxnet-fengye08\r\nxxnet-fengye09\r\nxxnet-fengye10\r\nxxnet-fengye11\r\nxxnet-ff1\r\nxxnet-ff2\r\nxxnet-ff3\r\nxxnet-ff4\r\nxxnet-ff5\r\nxxnet-fgfw\r\nxxnet-fgfw-1\r\nxxnet-fgfw-2\r\nxxnet-fin01\r\nxxnet-fin02\r\nxxnet-fin03\r\nxxnet-fin04\r\nxxnet-fin05\r\nxxnet-fin06\r\nxxnet-fin07\r\nxxnet-fin09\r\nxxnet-fin10\r\nxxnet-fin11\r\nxxnet-fin12\r\nxxnet-first-221705\r\nxxnet-fjcyyjcf5\r\nxxnet-fk01\r\nxxnet-fk02\r\nxxnet-fk03\r\nxxnet-flux-184808\r\nxxnet-flykarry1\r\nxxnet-flykarry10\r\nxxnet-flykarry11\r\nxxnet-flykarry2\r\nxxnet-flykarry5\r\nxxnet-flykarry6\r\nxxnet-flykarry7\r\nxxnet-flykarry8\r\nxxnet-flykarry9-218303\r\nxxnet-for-xtunnel\r\nxxnet-forpublic\r\nxxnet-forxchannel1\r\nxxnet-forxchannel2\r\nxxnet-forzcy4\r\nxxnet-forzcy5\r\nxxnet-forzcy6\r\nxxnet-forzcy7\r\nxxnet-foshan2\r\nxxnet-foshan3\r\nxxnet-foshan4\r\nxxnet-foshan5\r\nxxnet-foshan6\r\nxxnet-foshan7\r\nxxnet-fran\r\nxxnet-frank1\r\nxxnet-frank2\r\nxxnet-free01-245209\r\nxxnet-free20180822\r\nxxnet-fu001-00\r\nxxnet-fu001-01\r\nxxnet-fu001-02\r\nxxnet-fu001-03\r\nxxnet-fu001-04\r\nxxnet-fw021\r\nxxnet-fw022\r\nxxnet-fw023\r\nxxnet-fw024\r\nxxnet-fw025\r\nxxnet-fw026\r\nxxnet-fw9020\r\nxxnet-fy1-196501\r\nxxnet-g-189807\r\nxxnet-gagahaha\r\nxxnet-game\r\nxxnet-gate-184808\r\nxxnet-gate-199205\r\nxxnet-gd01\r\nxxnet-gd02\r\nxxnet-gd03\r\nxxnet-gdei01-188912\r\nxxnet-gdonat0\r\nxxnet-gdonate1\r\nxxnet-gfwed-1\r\nxxnet-gfwed-1-237006\r\nxxnet-gfwed-2\r\nxxnet-gfwed-3\r\nxxnet-gfwed-4\r\nxxnet-gfwed-5\r\nxxnet-gfwed-7\r\nxxnet-gfwed-9\r\nxxnet-gg\r\nxxnet-gggion-196917\r\nxxnet-gift\r\nxxnet-gift999\r\nxxnet-give1\r\nxxnet-give2\r\nxxnet-give3\r\nxxnet-gkkill1\r\nxxnet-gkkill2\r\nxxnet-gkz001\r\nxxnet-glow-200714\r\nxxnet-gmxshare001\r\nxxnet-go-188707\r\nxxnet-goole-186801\r\nxxnet-guguibin1\r\nxxnet-guguibin2\r\nxxnet-h-191001\r\nxxnet-h-226412\r\nxxnet-h1\r\nxxnet-h2\r\nxxnet-h3\r\nxxnet-haha-205003\r\nxxnet-hahaga\r\nxxnet-hahge\r\nxxnet-haixuling1\r\nxxnet-haixuling2\r\nxxnet-hbq\r\nxxnet-he-210711\r\nxxnet-hello\r\nxxnet-hello-123\r\nxxnet-hello-185106\r\nxxnet-hello-204613\r\nxxnet-hello-244611\r\nxxnet-hello0\r\nxxnet-help-go1\r\nxxnet-help-go2\r\nxxnet-helper\r\nxxnet-henu-001\r\nxxnet-herry\r\nxxnet-hf001\r\nxxnet-hf002\r\nxxnet-hf003\r\nxxnet-hf004\r\nxxnet-hh-187504\r\nxxnet-hifes\r\nxxnet-hihibin\r\nxxnet-hirro029-01\r\nxxnet-hj-01\r\nxxnet-hj-02\r\nxxnet-hj-03\r\nxxnet-hj-04\r\nxxnet-hj-05\r\nxxnet-hj-06\r\nxxnet-hj-07\r\nxxnet-hj-08\r\nxxnet-hj-09\r\nxxnet-hj-10\r\nxxnet-hj-11\r\nxxnet-hj-12\r\nxxnet-hjwhuhu1\r\nxxnet-hjwhuhu2\r\nxxnet-hjwhuhu3\r\nxxnet-hk-1001\r\nxxnet-hk-1002\r\nxxnet-hk-1003\r\nxxnet-hk-1004\r\nxxnet-hk-1005\r\nxxnet-holle10-donate\r\nxxnet-holle11-donate\r\nxxnet-holle12-donate\r\nxxnet-honkerjha007\r\nxxnet-honlessy\r\nxxnet-honlessy02\r\nxxnet-hr01\r\nxxnet-hr02\r\nxxnet-hr03\r\nxxnet-hr04\r\nxxnet-hr05\r\nxxnet-hr06\r\nxxnet-hr07\r\nxxnet-hr08\r\nxxnet-hr09\r\nxxnet-hr10\r\nxxnet-hr11\r\nxxnet-hr12\r\nxxnet-hua01\r\nxxnet-hua03\r\nxxnet-huang1\r\nxxnet-huanggusheng\r\nxxnet-huju122547\r\nxxnet-hyh01\r\nxxnet-hyh2-09\r\nxxnet-hyh2-10\r\nxxnet-hyh2-11\r\nxxnet-hyh2-12\r\nxxnet-hyh203\r\nxxnet-hzb-1\r\nxxnet-hzb-2\r\nxxnet-hzb-3\r\nxxnet-i-191001\r\nxxnet-iammkc\r\nxxnet-ian01\r\nxxnet-ian02\r\nxxnet-ian03\r\nxxnet-ian04\r\nxxnet-ian05\r\nxxnet-ian06\r\nxxnet-ian07\r\nxxnet-ian08\r\nxxnet-ian09\r\nxxnet-ian1\r\nxxnet-ian10\r\nxxnet-ian11\r\nxxnet-ian12\r\nxxnet-ian13\r\nxxnet-ian14\r\nxxnet-ian15\r\nxxnet-ian16\r\nxxnet-ian17\r\nxxnet-ian18\r\nxxnet-ian19\r\nxxnet-ian20\r\nxxnet-ian21\r\nxxnet-ian22\r\nxxnet-ian23\r\nxxnet-ian24\r\nxxnet-ian25\r\nxxnet-ian26\r\nxxnet-ian27\r\nxxnet-ian28\r\nxxnet-ian29\r\nxxnet-ian30\r\nxxnet-ian31\r\nxxnet-ian32\r\nxxnet-ian33\r\nxxnet-ian34\r\nxxnet-ian35\r\nxxnet-ian36\r\nxxnet-ian37\r\nxxnet-ian38\r\nxxnet-ian39\r\nxxnet-ice01\r\nxxnet-ice02\r\nxxnet-ice03\r\nxxnet-iceliquid\r\nxxnet-iceliquid1\r\nxxnet-iceliquid10\r\nxxnet-iceliquid11\r\nxxnet-iceliquid12\r\nxxnet-iceliquid13\r\nxxnet-iceliquid14\r\nxxnet-iceliquid15\r\nxxnet-iceliquid16\r\nxxnet-iceliquid17\r\nxxnet-iceliquid18\r\nxxnet-iceliquid19\r\nxxnet-iceliquid2\r\nxxnet-iceliquid20\r\nxxnet-iceliquid21\r\nxxnet-iceliquid22\r\nxxnet-iceliquid23\r\nxxnet-iceliquid24\r\nxxnet-iceliquid25\r\nxxnet-iceliquid26\r\nxxnet-iceliquid27\r\nxxnet-iceliquid28\r\nxxnet-iceliquid29\r\nxxnet-iceliquid3\r\nxxnet-iceliquid30\r\nxxnet-iceliquid31\r\nxxnet-iceliquid32\r\nxxnet-iceliquid33\r\nxxnet-iceliquid34\r\nxxnet-iceliquid35\r\nxxnet-iceliquid4\r\nxxnet-iceliquid5\r\nxxnet-iceliquid6\r\nxxnet-iceliquid7\r\nxxnet-iceliquid8\r\nxxnet-iceliquid9\r\nxxnet-icloud1024\r\nxxnet-idforxxnet-1\r\nxxnet-idforxxnet-10\r\nxxnet-idforxxnet-11\r\nxxnet-idforxxnet-12\r\nxxnet-idforxxnet-2\r\nxxnet-idforxxnet-3\r\nxxnet-idforxxnet-4\r\nxxnet-idforxxnet-5\r\nxxnet-idforxxnet-6\r\nxxnet-idforxxnet-7\r\nxxnet-idforxxnet-8\r\nxxnet-idforxxnet-9\r\nxxnet-irr1\r\nxxnet-irr10\r\nxxnet-irr11\r\nxxnet-irr2\r\nxxnet-irr3\r\nxxnet-irr4\r\nxxnet-irr5\r\nxxnet-irr6\r\nxxnet-irr7\r\nxxnet-irr8\r\nxxnet-irr9\r\nxxnet-izual1\r\nxxnet-izual2\r\nxxnet-izual3\r\nxxnet-izual4\r\nxxnet-izual5\r\nxxnet-j-191001\r\nxxnet-j0001\r\nxxnet-j0002\r\nxxnet-jaga211\r\nxxnet-jaga863\r\nxxnet-jaga985\r\nxxnet-jaine-donate\r\nxxnet-jamayy01\r\nxxnet-jamayy02\r\nxxnet-jamayy03\r\nxxnet-jamayy04\r\nxxnet-jamayy05\r\nxxnet-jamayy06\r\nxxnet-jamayy07\r\nxxnet-jamayy08\r\nxxnet-jamayy09\r\nxxnet-jayxa\r\nxxnet-jayxc\r\nxxnet-jayxd\r\nxxnet-jayxe\r\nxxnet-jayxf\r\nxxnet-jayxg\r\nxxnet-jayxh\r\nxxnet-jayxj\r\nxxnet-jayxk\r\nxxnet-jer\r\nxxnet-jer2\r\nxxnet-jiang-527329\r\nxxnet-jianzhi1\r\nxxnet-jianzhi2\r\nxxnet-jianzhi3\r\nxxnet-jianzhi4\r\nxxnet-jianzhi5\r\nxxnet-jiunin01\r\nxxnet-jiunin02\r\nxxnet-jiunin03\r\nxxnet-jiunin04\r\nxxnet-jiunin05\r\nxxnet-jiunin06\r\nxxnet-jiunin07\r\nxxnet-jiunin08\r\nxxnet-jiunin09\r\nxxnet-jiunin10\r\nxxnet-jiunin11\r\nxxnet-jiunin12\r\nxxnet-jj01\r\nxxnet-jj02\r\nxxnet-jj03\r\nxxnet-jksoiyrhkh\r\nxxnet-joren\r\nxxnet-jsdfgf\r\nxxnet-juan-xian-1\r\nxxnet-juan-xian-5\r\nxxnet-juanxian-1\r\nxxnet-juanxian-2\r\nxxnet-juanxian-3\r\nxxnet-juanxian-4\r\nxxnet-juanxian-5\r\nxxnet-juanzheng2\r\nxxnet-jz\r\nxxnet-jz001\r\nxxnet-jz002\r\nxxnet-jz01\r\nxxnet-k-191001\r\nxxnet-k1\r\nxxnet-k2\r\nxxnet-keepfighting\r\nxxnet-ken001\r\nxxnet-kevin1\r\nxxnet-kevin10\r\nxxnet-kevin11\r\nxxnet-kevin12\r\nxxnet-kevin2\r\nxxnet-kevin3\r\nxxnet-kevin4\r\nxxnet-kevin5\r\nxxnet-kevin6\r\nxxnet-kevin7\r\nxxnet-kevin8\r\nxxnet-kevin9\r\nxxnet-kevinyg1976\r\nxxnet-kg1\r\nxxnet-kg2\r\nxxnet-kimdonate1\r\nxxnet-kimdonate2\r\nxxnet-kimdonate3\r\nxxnet-kimdonate5\r\nxxnet-kimdonate6\r\nxxnet-kimdonate7\r\nxxnet-kittycheny1\r\nxxnet-kittycheny2\r\nxxnet-kittycheny3\r\nxxnet-kittycheny4\r\nxxnet-kittycheny5\r\nxxnet-kittycheny6\r\nxxnet-kokoooro1\r\nxxnet-kokoooro2\r\nxxnet-ksryy1\r\nxxnet-kudo\r\nxxnet-kugui\r\nxxnet-lead-184808\r\nxxnet-lee01\r\nxxnet-lennon\r\nxxnet-leo20171201\r\nxxnet-leo20171202\r\nxxnet-leobert-1\r\nxxnet-lhzbxx-001\r\nxxnet-lhzbxx-002\r\nxxnet-lhzbxx-003\r\nxxnet-li100\r\nxxnet-li102-187505\r\nxxnet-li103-187505\r\nxxnet-li104\r\nxxnet-li105\r\nxxnet-li106\r\nxxnet-liang\r\nxxnet-liangzheng\r\nxxnet-liaofanqiang107\r\nxxnet-lidegang1\r\nxxnet-lidegang10\r\nxxnet-lidegang11\r\nxxnet-lidegang12\r\nxxnet-lidegang13\r\nxxnet-lidegang14\r\nxxnet-lidegang2\r\nxxnet-lidegang3\r\nxxnet-lidegang4\r\nxxnet-lidegang5\r\nxxnet-lidegang6\r\nxxnet-lidegang7\r\nxxnet-lidegang8\r\nxxnet-lidegang9\r\nxxnet-lifeator\r\nxxnet-lifeguard\r\nxxnet-lifehistory\r\nxxnet-lifeinstinct\r\nxxnet-lifejacket\r\nxxnet-lifenet\r\nxxnet-linch-1\r\nxxnet-linch-2\r\nxxnet-linch-3\r\nxxnet-linch-5\r\nxxnet-lingdu001\r\nxxnet-lingdu002\r\nxxnet-lingdu003\r\nxxnet-lingdu004\r\nxxnet-lingdu005\r\nxxnet-lingdu006\r\nxxnet-lingdu007\r\nxxnet-lingdu008\r\nxxnet-lingdu010\r\nxxnet-lingdu012\r\nxxnet-liu-176602\r\nxxnet-liudanpao\r\nxxnet-liufi01\r\nxxnet-liufi03\r\nxxnet-liufi04\r\nxxnet-liushuai-00\r\nxxnet-liushuai-01\r\nxxnet-liushuai-03\r\nxxnet-liushuai-04\r\nxxnet-liushuai-05\r\nxxnet-liushuai-06\r\nxxnet-liushuai-07\r\nxxnet-liushuai-08\r\nxxnet-liushuai-09\r\nxxnet-ll824\r\nxxnet-loc001\r\nxxnet-loc002\r\nxxnet-lolikong1\r\nxxnet-lolikong10\r\nxxnet-lolikong11\r\nxxnet-lolikong12\r\nxxnet-lolikong13\r\nxxnet-lolikong2\r\nxxnet-lolikong4\r\nxxnet-lolikong5\r\nxxnet-lolikong6\r\nxxnet-lolikong7\r\nxxnet-lolikong8\r\nxxnet-lolikong9\r\nxxnet-longer\r\nxxnet-longfengweb-2018\r\nxxnet-lq-1910231\r\nxxnet-lss644\r\nxxnet-lx0612\r\nxxnet-lxb1\r\nxxnet-lxb2\r\nxxnet-lxb3\r\nxxnet-lxb4\r\nxxnet-lxb5\r\nxxnet-lxx01\r\nxxnet-lxx02\r\nxxnet-lxx03\r\nxxnet-lxx04\r\nxxnet-lxx05\r\nxxnet-lxx06\r\nxxnet-lxx07\r\nxxnet-lxx08\r\nxxnet-lxx09\r\nxxnet-lxx10\r\nxxnet-ly-185\r\nxxnet-ly-185905\r\nxxnet-ly-186\r\nxxnet-ly-187\r\nxxnet-ly-188\r\nxxnet-ly001\r\nxxnet-ly002\r\nxxnet-ly003\r\nxxnet-ly004\r\nxxnet-ly005\r\nxxnet-lyn0716\r\nxxnet-lyrical-bolt-205705\r\nxxnet-lzskyline-1\r\nxxnet-m-191001\r\nxxnet-m0003\r\nxxnet-m0004\r\nxxnet-m0005\r\nxxnet-mailchenbo0\r\nxxnet-mars-apple\r\nxxnet-math\r\nxxnet-maxuyang1\r\nxxnet-maxuyang12\r\nxxnet-maxuyang2\r\nxxnet-maxuyang3\r\nxxnet-maxuyang4\r\nxxnet-maxuyang5\r\nxxnet-maxuyang6\r\nxxnet-maxuyang7\r\nxxnet-maxuyang8\r\nxxnet-maxuyang9\r\nxxnet-mceesnail1\r\nxxnet-mceesnail2\r\nxxnet-mceesnail3\r\nxxnet-mceesnail4\r\nxxnet-mceesnail5\r\nxxnet-mceesnail6\r\nxxnet-meijie-pro1\r\nxxnet-mg1838\r\nxxnet-mhui1\r\nxxnet-mhui10\r\nxxnet-mhui11\r\nxxnet-mhui12\r\nxxnet-mhui2\r\nxxnet-mhui3\r\nxxnet-mhui4\r\nxxnet-mhui5\r\nxxnet-mhui6\r\nxxnet-mhui7\r\nxxnet-mhui8\r\nxxnet-mhui9\r\nxxnet-mig2999djproxy\r\nxxnet-min-01\r\nxxnet-min-02\r\nxxnet-mingj2018\r\nxxnet-mingj201801\r\nxxnet-mnbv-0987\r\nxxnet-mo1\r\nxxnet-mo2\r\nxxnet-mokio-001\r\nxxnet-mokio-002\r\nxxnet-moon\r\nxxnet-mouka-1\r\nxxnet-mouka-12\r\nxxnet-mouka-2\r\nxxnet-mouka-3\r\nxxnet-moustache\r\nxxnet-mrhgewnv-1\r\nxxnet-mrhgewnv-2\r\nxxnet-mrhgewnv-3\r\nxxnet-mrhgewnv-4\r\nxxnet-mrsheng-1\r\nxxnet-mrsheng-3\r\nxxnet-msjylll\r\nxxnet-msjylls\r\nxxnet-mulisai001\r\nxxnet-my-project-10205\r\nxxnet-my-project-11101\r\nxxnet-my-project-13778\r\nxxnet-my-project-16875\r\nxxnet-my-project-20548\r\nxxnet-my-project-39629\r\nxxnet-my-project-41238\r\nxxnet-my-project-54333\r\nxxnet-my-project-58828\r\nxxnet-my-project-73849\r\nxxnet-my-project-90468\r\nxxnet-my1\r\nxxnet-my10\r\nxxnet-my11\r\nxxnet-my12\r\nxxnet-my2\r\nxxnet-my3\r\nxxnet-my4\r\nxxnet-my5\r\nxxnet-my6\r\nxxnet-my7\r\nxxnet-my8\r\nxxnet-my9\r\nxxnet-myapp\r\nxxnet-mylove1\r\nxxnet-mylove2\r\nxxnet-mysql\r\nxxnet-mzy\r\nxxnet-mzy5\r\nxxnet-mzy56\r\nxxnet-mzy6\r\nxxnet-na\r\nxxnet-new-244504\r\nxxnet-ninth\r\nxxnet-no1-242306\r\nxxnet-nodejs\r\nxxnet-nome1\r\nxxnet-np1\r\nxxnet-one-228915\r\nxxnet-one-233315\r\nxxnet-open1-188802\r\nxxnet-ourui668\r\nxxnet-papastar\r\nxxnet-paynev-donate-1\r\nxxnet-pbpomgjl\r\nxxnet-pc-184914\r\nxxnet-pj01\r\nxxnet-pltznpgu\r\nxxnet-pnjdonate1\r\nxxnet-pnjdonate2\r\nxxnet-pnjdonate3\r\nxxnet-pohsin1\r\nxxnet-pohsin2\r\nxxnet-pojo\r\nxxnet-pp1\r\nxxnet-pp2\r\nxxnet-pp3\r\nxxnet-ppb01\r\nxxnet-practise\r\nxxnet-premise-184808\r\nxxnet-prism-180909\r\nxxnet-project-10\r\nxxnet-project-11\r\nxxnet-project-13206\r\nxxnet-project-2\r\nxxnet-project-20171120\r\nxxnet-project-20171121\r\nxxnet-project-20736\r\nxxnet-project-209711\r\nxxnet-project-21900\r\nxxnet-project-25654\r\nxxnet-project-2730\r\nxxnet-project-3\r\nxxnet-project-37050\r\nxxnet-project-37571\r\nxxnet-project-3987\r\nxxnet-project-4\r\nxxnet-project-433\r\nxxnet-project-47855\r\nxxnet-project-5\r\nxxnet-project-51161\r\nxxnet-project-6\r\nxxnet-project-63452\r\nxxnet-project-63772\r\nxxnet-project-7\r\nxxnet-project-8\r\nxxnet-project-83242\r\nxxnet-project-9\r\nxxnet-project-90354\r\nxxnet-project-yangkai18\r\nxxnet-project02-233001\r\nxxnet-proxynet1\r\nxxnet-proxynet2\r\nxxnet-public--1293\r\nxxnet-public-205803\r\nxxnet-public-205806\r\nxxnet-public-boomkeeper-01\r\nxxnet-public-project-78230\r\nxxnet-public-project-78231\r\nxxnet-publicooa\r\nxxnet-python\r\nxxnet-q002\r\nxxnet-q003\r\nxxnet-q004\r\nxxnet-q005\r\nxxnet-q006\r\nxxnet-q007\r\nxxnet-q008\r\nxxnet-q009\r\nxxnet-q010\r\nxxnet-q011\r\nxxnet-q012\r\nxxnet-qerb\r\nxxnet-qing01\r\nxxnet-qing01-187403\r\nxxnet-qishi\r\nxxnet-qsxmq1\r\nxxnet-quantye-test1\r\nxxnet-quantye-test10\r\nxxnet-quantye-test11\r\nxxnet-quantye-test11-208414\r\nxxnet-quantye-test2\r\nxxnet-quantye-test3\r\nxxnet-quantye-test4\r\nxxnet-quantye-test5\r\nxxnet-quantye-test6\r\nxxnet-quantye-test7\r\nxxnet-quantye-test8\r\nxxnet-r1\r\nxxnet-racer-184808\r\nxxnet-random\r\nxxnet-rcleart\r\nxxnet-release\r\nxxnet-rem-0\r\nxxnet-repeater-184808\r\nxxnet-rilnwnqu5\r\nxxnet-rilnwnqu6\r\nxxnet-rilnwnqu7\r\nxxnet-ringno001\r\nxxnet-ringno002\r\nxxnet-rnd01\r\nxxnet-rnd02\r\nxxnet-rnd03\r\nxxnet-rnd04\r\nxxnet-rnd05\r\nxxnet-rnd06\r\nxxnet-rnd07\r\nxxnet-rnd08\r\nxxnet-rnd09\r\nxxnet-rnd10\r\nxxnet-rnd11\r\nxxnet-rnd12\r\nxxnet-rosesarered\r\nxxnet-rs4donate0\r\nxxnet-rylkyo\r\nxxnet-rylkyo-229615\r\nxxnet-rylkyo1\r\nxxnet-sakura\r\nxxnet-sale01\r\nxxnet-sale02\r\nxxnet-sale03\r\nxxnet-sale04\r\nxxnet-sale05\r\nxxnet-sale06\r\nxxnet-sale07\r\nxxnet-sale08\r\nxxnet-sale09\r\nxxnet-sale10\r\nxxnet-sale11\r\nxxnet-sale12\r\nxxnet-samr\r\nxxnet-sandbox-235202\r\nxxnet-sayno\r\nxxnet-scats01\r\nxxnet-scats02\r\nxxnet-scats03\r\nxxnet-scats04\r\nxxnet-scats05\r\nxxnet-scats06\r\nxxnet-scats07\r\nxxnet-scats08\r\nxxnet-scats09\r\nxxnet-scats10\r\nxxnet-scats11\r\nxxnet-scats12\r\nxxnet-scats13\r\nxxnet-scats14\r\nxxnet-scrisqiu-5\r\nxxnet-scrisqiu-6\r\nxxnet-sdcf1\r\nxxnet-sdcf10\r\nxxnet-sdcf3\r\nxxnet-sdcf4\r\nxxnet-sdcf5\r\nxxnet-sdcf6\r\nxxnet-sdcf7\r\nxxnet-sdcf8\r\nxxnet-sdcf8-1241\r\nxxnet-sdcf9\r\nxxnet-sdcff1\r\nxxnet-sdcff10\r\nxxnet-sdcff11\r\nxxnet-sdcff12\r\nxxnet-sdcff2\r\nxxnet-sdcff3\r\nxxnet-sdcff4\r\nxxnet-sdcff5\r\nxxnet-sdcff6\r\nxxnet-sdcff7\r\nxxnet-sdcff8\r\nxxnet-sdcff9\r\nxxnet-service-lhw\r\nxxnet-service01\r\nxxnet-service02\r\nxxnet-service03\r\nxxnet-service04\r\nxxnet-service05\r\nxxnet-sfgsuurxpd3\r\nxxnet-sgg\r\nxxnet-sh-1\r\nxxnet-sh-2\r\nxxnet-shadow-111\r\nxxnet-shadow-222\r\nxxnet-shadow-333\r\nxxnet-shadow-444\r\nxxnet-shadow-555\r\nxxnet-shadow-666\r\nxxnet-shadow-777\r\nxxnet-shang\r\nxxnet-shangda030900\r\nxxnet-share-1\r\nxxnet-share-193512\r\nxxnet-share-2\r\nxxnet-share-257205\r\nxxnet-share-donate-01\r\nxxnet-share-donate-02\r\nxxnet-share-donate-03\r\nxxnet-share-donate-04\r\nxxnet-share-donate-05\r\nxxnet-share-donate-07\r\nxxnet-share-donate-08\r\nxxnet-share-donate-09\r\nxxnet-share-donate-10\r\nxxnet-share-donate-11\r\nxxnet-ship\r\nxxnet-silenq-1\r\nxxnet-silenq-2\r\nxxnet-singlev-001\r\nxxnet-singlev-002\r\nxxnet-singlev-004\r\nxxnet-singlev-006\r\nxxnet-singlev-007\r\nxxnet-sinkzephyr2017\r\nxxnet-skyhifi1\r\nxxnet-skyhifi10\r\nxxnet-skyhifi2-1266\r\nxxnet-skyhifi4\r\nxxnet-skyhifi5\r\nxxnet-skyhifi6\r\nxxnet-skyhifi7\r\nxxnet-skyhifi8\r\nxxnet-skyhifi9\r\nxxnet-smm\r\nxxnet-sofia01\r\nxxnet-sofia02\r\nxxnet-sofia03\r\nxxnet-sofia04\r\nxxnet-sofia06\r\nxxnet-sol-1\r\nxxnet-sol-2\r\nxxnet-sol-3\r\nxxnet-sol-4\r\nxxnet-sol-5\r\nxxnet-sol-6\r\nxxnet-sol-7\r\nxxnet-sol-8\r\nxxnet-solid-linker-162409\r\nxxnet-sorter\r\nxxnet-sp001\r\nxxnet-spark\r\nxxnet-sparkle\r\nxxnet-spox-1\r\nxxnet-sqs\r\nxxnet-sss\r\nxxnet-sss1\r\nxxnet-sss10\r\nxxnet-sss11\r\nxxnet-sss2\r\nxxnet-sss3\r\nxxnet-sss4\r\nxxnet-sss5\r\nxxnet-sss6\r\nxxnet-sss7\r\nxxnet-sss8\r\nxxnet-sss9\r\nxxnet-stan1\r\nxxnet-stan10\r\nxxnet-stan11\r\nxxnet-stan12\r\nxxnet-stan13\r\nxxnet-stan14\r\nxxnet-stan15\r\nxxnet-stan16\r\nxxnet-stan17\r\nxxnet-stan2\r\nxxnet-stan4\r\nxxnet-stan5\r\nxxnet-stan6\r\nxxnet-stan7\r\nxxnet-stan8\r\nxxnet-stan9\r\nxxnet-starwang01\r\nxxnet-sugarissweet\r\nxxnet-sun\r\nxxnet-sunny01\r\nxxnet-sunqiang00\r\nxxnet-sunqiang01\r\nxxnet-sunqiang02\r\nxxnet-sunqiang03\r\nxxnet-sunqiang04\r\nxxnet-sunqiang05\r\nxxnet-sunqiang06\r\nxxnet-sunqiang07\r\nxxnet-sunqiang09\r\nxxnet-swear\r\nxxnet-swear291\r\nxxnet-sxs01\r\nxxnet-sxs02\r\nxxnet-sycamore\r\nxxnet-sycamore1\r\nxxnet-t-184503\r\nxxnet-t1-235404\r\nxxnet-t2-235404\r\nxxnet-takeaidebaba1\r\nxxnet-takeaidebaba2\r\nxxnet-takeaidebaba3\r\nxxnet-takonyan1\r\nxxnet-takonyan2\r\nxxnet-takonyan3\r\nxxnet-takonyan3-184808\r\nxxnet-takonyan5\r\nxxnet-talon-184808\r\nxxnet-te\r\nxxnet-tech01\r\nxxnet-tech02\r\nxxnet-tech03\r\nxxnet-tech04\r\nxxnet-tech05\r\nxxnet-tech06\r\nxxnet-tech07\r\nxxnet-tech08\r\nxxnet-tech10\r\nxxnet-tech11\r\nxxnet-tech12\r\nxxnet-test-240204\r\nxxnet-test-for-xx\r\nxxnet-thanks\r\nxxnet-thanks-244611\r\nxxnet-thertno-20180117\r\nxxnet-thertno-20180118\r\nxxnet-thertno-20180119\r\nxxnet-thertno-20180120\r\nxxnet-think-t3\r\nxxnet-tiandidatong\r\nxxnet-tiny001\r\nxxnet-tiny002\r\nxxnet-tj\r\nxxnet-tlzx0\r\nxxnet-tlzx1\r\nxxnet-tlzx2\r\nxxnet-tlzx3\r\nxxnet-tlzx4\r\nxxnet-tlzx5\r\nxxnet-tlzx6\r\nxxnet-tlzx7\r\nxxnet-tlzx8\r\nxxnet-tlzx9\r\nxxnet-tms1\r\nxxnet-tn01\r\nxxnet-tn02\r\nxxnet-tn03\r\nxxnet-tn04\r\nxxnet-tn05\r\nxxnet-to-gae-10000\r\nxxnet-to-gae-10001\r\nxxnet-to-gae-10002\r\nxxnet-to-gae-10003\r\nxxnet-to-gae-10004\r\nxxnet-to-gae-10005\r\nxxnet-to-gae-10006\r\nxxnet-to-gae-10007\r\nxxnet-to-gae-10008\r\nxxnet-to-gae-10009\r\nxxnet-tom\r\nxxnet-totunnel\r\nxxnet-trip1\r\nxxnet-trip2\r\nxxnet-trsum-001\r\nxxnet-trsum-003\r\nxxnet-trsum-004\r\nxxnet-trsum-006\r\nxxnet-trsum-007\r\nxxnet-trsum-008\r\nxxnet-trsum-009\r\nxxnet-trsum-010\r\nxxnet-tunnel\r\nxxnet-tunnel-2\r\nxxnet-tunnel-251202\r\nxxnet-tunnel-3\r\nxxnet-twogen\r\nxxnet-twogen2\r\nxxnet-twogen3\r\nxxnet-tycomputer\r\nxxnet-tyreal\r\nxxnet-u639\r\nxxnet-ut001\r\nxxnet-uwgwo\r\nxxnet-v001\r\nxxnet-v002\r\nxxnet-v003\r\nxxnet-v004\r\nxxnet-v005\r\nxxnet-v006\r\nxxnet-vaip\r\nxxnet-vanore-1\r\nxxnet-vanore-2\r\nxxnet-vanore-3\r\nxxnet-vanore-4\r\nxxnet-vanore-5\r\nxxnet-violetsareblue\r\nxxnet-vision01\r\nxxnet-vpn-1996\r\nxxnet-vpn-211902\r\nxxnet-vpn002\r\nxxnet-vpn003\r\nxxnet-vssohu1\r\nxxnet-vssohu2\r\nxxnet-vssohu3\r\nxxnet-w-188508\r\nxxnet-w2\r\nxxnet-wallbreaker\r\nxxnet-wallbreaker1\r\nxxnet-wallbreaker10\r\nxxnet-wallbreaker2\r\nxxnet-wallbreaker3\r\nxxnet-wallbreaker4\r\nxxnet-wallbreaker5\r\nxxnet-wallbreaker6\r\nxxnet-wallbreaker7\r\nxxnet-wallbreaker8\r\nxxnet-wallbreaker9\r\nxxnet-walterclozet1\r\nxxnet-walterclozet2\r\nxxnet-wantsrain\r\nxxnet-wantsrain1\r\nxxnet-wantsrain10\r\nxxnet-wantsrain11\r\nxxnet-wantsrain12\r\nxxnet-wantsrain2\r\nxxnet-wantsrain3\r\nxxnet-wantsrain4\r\nxxnet-wantsrain6\r\nxxnet-wantsrain7\r\nxxnet-wantsrain8\r\nxxnet-wantsrain9\r\nxxnet-water001\r\nxxnet-water002\r\nxxnet-water004\r\nxxnet-water005\r\nxxnet-water007\r\nxxnet-water008\r\nxxnet-wb1\r\nxxnet-wei\r\nxxnet-wgqid3\r\nxxnet-wich01\r\nxxnet-wich02\r\nxxnet-wich03\r\nxxnet-wich04\r\nxxnet-wich05\r\nxxnet-wich06\r\nxxnet-wich06-1263\r\nxxnet-wich1\r\nxxnet-wiki4j\r\nxxnet-wilsonwu1\r\nxxnet-wilsonwu2\r\nxxnet-wind01\r\nxxnet-wind02\r\nxxnet-wind03\r\nxxnet-wind04\r\nxxnet-wind05\r\nxxnet-wind06\r\nxxnet-wind07\r\nxxnet-wind08\r\nxxnet-wind09\r\nxxnet-wind10\r\nxxnet-wind11\r\nxxnet-wind12\r\nxxnet-wingxu-001\r\nxxnet-wingxu-002\r\nxxnet-wingxu-003\r\nxxnet-wish\r\nxxnet-wizard1\r\nxxnet-wizard2\r\nxxnet-wizard3\r\nxxnet-wizard4\r\nxxnet-wkq\r\nxxnet-wkq1-212805\r\nxxnet-wmyhnl\r\nxxnet-work-219405\r\nxxnet-wuqq-1\r\nxxnet-wuqq-2\r\nxxnet-wwwhl1111\r\nxxnet-wwwhl2\r\nxxnet-wwwhl3\r\nxxnet-wwwhl4\r\nxxnet-wy11\r\nxxnet-wy12\r\nxxnet-wzbbj-01\r\nxxnet-wzz1270\r\nxxnet-wzz1271\r\nxxnet-wzz12710\r\nxxnet-wzz12711\r\nxxnet-wzz1272\r\nxxnet-wzz1273\r\nxxnet-wzz1274\r\nxxnet-wzz1275\r\nxxnet-wzz1276\r\nxxnet-wzz1277\r\nxxnet-wzz1278\r\nxxnet-wzz1279\r\nxxnet-x-200204\r\nxxnet-x-tunnel-donate-1\r\nxxnet-x-tunnel-donate-2\r\nxxnet-x-tunnel-donate-3\r\nxxnet-x-tunnel-donate-4\r\nxxnet-x-tunnel-donate-5\r\nxxnet-x-tunnel-donate-6\r\nxxnet-xhox\r\nxxnet-xiaomao\r\nxxnet-xiaoxiong6\r\nxxnet-xiaoxiong7\r\nxxnet-xiaoxiong8\r\nxxnet-xiaoxiong9\r\nxxnet-xingxing01\r\nxxnet-xingxing02\r\nxxnet-xique112301\r\nxxnet-xique112302\r\nxxnet-xique112303\r\nxxnet-xique112304\r\nxxnet-xique112305\r\nxxnet-xique112306\r\nxxnet-xique112307\r\nxxnet-xique112308\r\nxxnet-xique112309\r\nxxnet-xique112310\r\nxxnet-xlx01\r\nxxnet-xlx02\r\nxxnet-xlx03\r\nxxnet-xlx04\r\nxxnet-xlx05\r\nxxnet-xlx06\r\nxxnet-xlx07\r\nxxnet-xlx08\r\nxxnet-xlx09\r\nxxnet-xlx10\r\nxxnet-xlx11\r\nxxnet-xlx12\r\nxxnet-xpz10\r\nxxnet-xpz11\r\nxxnet-xpz8-185109\r\nxxnet-xpz9\r\nxxnet-xt-226202\r\nxxnet-xt1\r\nxxnet-xt10\r\nxxnet-xt2\r\nxxnet-xt3\r\nxxnet-xt4\r\nxxnet-xt6\r\nxxnet-xt7\r\nxxnet-xt8\r\nxxnet-xt9\r\nxxnet-xtkong\r\nxxnet-xtkong1\r\nxxnet-xtkong2\r\nxxnet-xtkong3\r\nxxnet-xtkong4\r\nxxnet-xtkong5\r\nxxnet-xtkong6\r\nxxnet-xtkong7\r\nxxnet-xtunnel\r\nxxnet-xu\r\nxxnet-xue1\r\nxxnet-xuehao\r\nxxnet-xujj-110301\r\nxxnet-xujj-110302\r\nxxnet-xx06\r\nxxnet-xx18\r\nxxnet-xx19\r\nxxnet-xx2\r\nxxnet-xx20\r\nxxnet-xx21\r\nxxnet-xx22\r\nxxnet-xx23\r\nxxnet-xx24\r\nxxnet-xx25\r\nxxnet-xxnet-1\r\nxxnet-xxnetdonate1\r\nxxnet-xxnetdonate2\r\nxxnet-xxnetdonate3\r\nxxnet-xxnetdonate4\r\nxxnet-xxnetdonate5\r\nxxnet-xxnetdonate6\r\nxxnet-xxnetdonate7\r\nxxnet-xxnetdonate8\r\nxxnet-xy\r\nxxnet-xy-1\r\nxxnet-xy-2\r\nxxnet-xy-3\r\nxxnet-xy-4\r\nxxnet-xy-5\r\nxxnet-xzl000\r\nxxnet-xzl001\r\nxxnet-xzl002\r\nxxnet-xzl004\r\nxxnet-xzl004-234103\r\nxxnet-xzl006\r\nxxnet-xzl007\r\nxxnet-yagnitdn\r\nxxnet-yang-6-11\r\nxxnet-yang01\r\nxxnet-yang02\r\nxxnet-yang03\r\nxxnet-yang03-235704\r\nxxnet-yanggkka\r\nxxnet-yaolong1\r\nxxnet-yaolong2\r\nxxnet-yaolong3\r\nxxnet-ygl\r\nxxnet-ykq1\r\nxxnet-ym000\r\nxxnet-ym001\r\nxxnet-ym002\r\nxxnet-yol\r\nxxnet-ysk1\r\nxxnet-ysk2\r\nxxnet-yt001\r\nxxnet-yt002\r\nxxnet-yuanchouyc001\r\nxxnet-yuanchouyc002\r\nxxnet-yujie020\r\nxxnet-yujie0201\r\nxxnet-yyl1990\r\nxxnet-yyt02-01\r\nxxnet-yyt02-02\r\nxxnet-yyt02-03\r\nxxnet-yyt02-04\r\nxxnet-yyt02-05\r\nxxnet-yyt02-06\r\nxxnet-yyt02-07\r\nxxnet-yyt02-08\r\nxxnet-yyt02-09\r\nxxnet-yyt02-10\r\nxxnet-yyt02-11\r\nxxnet-yyt02-12\r\nxxnet-zar01\r\nxxnet-zelinlee1\r\nxxnet-zhang1111\r\nxxnet-zhang2222\r\nxxnet-zhang3333\r\nxxnet-zhang4444\r\nxxnet-zhang5555\r\nxxnet-zhangyang7761-1\r\nxxnet-zhanzhan-1\r\nxxnet-zhanzhan-2\r\nxxnet-zhanzhan-3\r\nxxnet-zhanzhan-4\r\nxxnet-zhanzhan-5\r\nxxnet-zhanzhan-6\r\nxxnet-zhaozihao\r\nxxnet-zhengqi6\r\nxxnet-zhengqi7\r\nxxnet-zhengqi8\r\nxxnet-zhengqi9\r\nxxnet-zhj1\r\nxxnet-zhj2\r\nxxnet-zhou1\r\nxxnet-zhou2\r\nxxnet-zhoufxw1\r\nxxnet-zhoufxw2\r\nxxnet-zhoufxw3\r\nxxnet-zhoufxw4\r\nxxnet-zhoufxw5\r\nxxnet-zj01\r\nxxnet-zj02\r\nxxnet-zj03\r\nxxnet-zj04\r\nxxnet-zj05\r\nxxnet-zj06\r\nxxnet-zjn-1\r\nxxnet-zld1\r\nxxnet-zld2\r\nxxnet-zlg02\r\nxxnet-zlg03\r\nxxnet-zlg04\r\nxxnet-zt48\r\nxxnet-zx44711\r\nxxnet-zxz\r\nxxnet-zz-001\r\nxxnet-zz-002\r\nxxnet-zz-02\r\nxxnet-zz001\r\nxxnet-zzcqkk\r\nxxnet0-198703\r\nxxnet0-257701\r\nxxnet001-185802\r\nxxnet001-229801\r\nxxnet002-211112\r\nxxnet003-185588\r\nxxnet004-185588\r\nxxnet005\r\nxxnet005-665555\r\nxxnet0051\r\nxxnet006-226605\r\nxxnet006-444250\r\nxxnet007-665588\r\nxxnet01-188610\r\nxxnet01-197014\r\nxxnet01-213201\r\nxxnet010220\r\nxxnet010221\r\nxxnet010222\r\nxxnet010223\r\nxxnet010224\r\nxxnet010225\r\nxxnet010226\r\nxxnet010227\r\nxxnet010228\r\nxxnet02-197014\r\nxxnet02-199207\r\nxxnet02-207003\r\nxxnet0727\r\nxxnet1-111111111\r\nxxnet1-1345\r\nxxnet1-151005\r\nxxnet1-152111\r\nxxnet1-16974\r\nxxnet1-171111\r\nxxnet1-173906\r\nxxnet1-179710\r\nxxnet1-182212\r\nxxnet1-182815\r\nxxnet1-184408\r\nxxnet1-184506\r\nxxnet1-184602\r\nxxnet1-190512\r\nxxnet1-192017\r\nxxnet1-192215\r\nxxnet1-194702\r\nxxnet1-195604\r\nxxnet1-198703\r\nxxnet1-198900\r\nxxnet1-213107\r\nxxnet1-214011\r\nxxnet1-225311\r\nxxnet1-227710\r\nxxnet1-240509\r\nxxnet1-246818\r\nxxnet10-1208\r\nxxnet10-1345\r\nxxnet10-152204\r\nxxnet10-171112\r\nxxnet10-191411\r\nxxnet10-195605\r\nxxnet10-197815\r\nxxnet10-198703\r\nxxnet10-208507\r\nxxnet10-257701\r\nxxnet1018-234904\r\nxxnet11-1208\r\nxxnet11-152204\r\nxxnet11-191411\r\nxxnet11-197815\r\nxxnet11-208507\r\nxxnet12-141909\r\nxxnet12-152204\r\nxxnet12-197815\r\nxxnet1201\r\nxxnet12111\r\nxxnet12112\r\nxxnet12113\r\nxxnet12114\r\nxxnet12115\r\nxxnet123456-233214\r\nxxnet1258\r\nxxnet135-227515\r\nxxnet1489-186613\r\nxxnet16388\r\nxxnet18010602\r\nxxnet18010603\r\nxxnet18010604\r\nxxnet18010605\r\nxxnet186700\r\nxxnet186701\r\nxxnet186702\r\nxxnet186703\r\nxxnet186704\r\nxxnet186705\r\nxxnet186706\r\nxxnet186707\r\nxxnet186708\r\nxxnet186709\r\nxxnet186710\r\nxxnet190115\r\nxxnet193\r\nxxnet1949\r\nxxnet19601\r\nxxnet19602\r\nxxnet1id\r\nxxnet2-1345\r\nxxnet2-151716\r\nxxnet2-152204\r\nxxnet2-170603\r\nxxnet2-171111\r\nxxnet2-179711\r\nxxnet2-182212\r\nxxnet2-184506\r\nxxnet2-184604\r\nxxnet2-187112\r\nxxnet2-187405\r\nxxnet2-190512\r\nxxnet2-192017\r\nxxnet2-192215\r\nxxnet2-194702\r\nxxnet2-195604\r\nxxnet2-198703\r\nxxnet2-2010\r\nxxnet2-202119\r\nxxnet2-203803\r\nxxnet2-208507\r\nxxnet2-213205\r\nxxnet2-214012\r\nxxnet2-225311\r\nxxnet2-225906\r\nxxnet2-227710\r\nxxnet2-228621\r\nxxnet2-240509\r\nxxnet2-246818\r\nxxnet2-262713\r\nxxnet201-156516\r\nxxnet201701-186213\r\nxxnet201702-186213\r\nxxnet2017021406\r\nxxnet201703-186213\r\nxxnet201704-186213\r\nxxnet20170419\r\nxxnet20170420\r\nxxnet20170421\r\nxxnet201705-186213\r\nxxnet201706-186213\r\nxxnet20190227-233009\r\nxxnet20190731\r\nxxnet2019073101\r\nxxnet2019073102\r\nxxnet20191\r\nxxnet20192\r\nxxnet20193\r\nxxnet20194\r\nxxnet233-171123\r\nxxnet23456\r\nxxnet239201\r\nxxnet251306\r\nxxnet2945\r\nxxnet3-1208\r\nxxnet3-1345\r\nxxnet3-171112\r\nxxnet3-179711\r\nxxnet3-182212\r\nxxnet3-184506\r\nxxnet3-185505\r\nxxnet3-187212\r\nxxnet3-190513\r\nxxnet3-192017\r\nxxnet3-192215\r\nxxnet3-194702\r\nxxnet3-195604\r\nxxnet3-197815\r\nxxnet3-198703\r\nxxnet3-2011\r\nxxnet3-203803\r\nxxnet3-208507\r\nxxnet3-214105\r\nxxnet3-225311\r\nxxnet3-225607\r\nxxnet3-227710\r\nxxnet3-228621\r\nxxnet3-240509\r\nxxnet3-246818\r\nxxnet4-1208\r\nxxnet4-1321\r\nxxnet4-1345\r\nxxnet4-152204\r\nxxnet4-168608\r\nxxnet4-184506\r\nxxnet4-190611\r\nxxnet4-192017\r\nxxnet4-192215\r\nxxnet4-195604\r\nxxnet4-197815\r\nxxnet4-198703\r\nxxnet4-208507\r\nxxnet4-225607\r\nxxnet4-227710\r\nxxnet4-240513\r\nxxnet4-262713\r\nxxnet43383fq\r\nxxnet445\r\nxxnet456-233214\r\nxxnet45686\r\nxxnet45687\r\nxxnet45688\r\nxxnet45689\r\nxxnet48749\r\nxxnet4ae02\r\nxxnet4ae03\r\nxxnet4good\r\nxxnet5-1208\r\nxxnet5-1321\r\nxxnet5-1345\r\nxxnet5-152204\r\nxxnet5-168608\r\nxxnet5-195605\r\nxxnet5-197815\r\nxxnet5-198703\r\nxxnet5-208507\r\nxxnet5-227710\r\nxxnet5-246818\r\nxxnet5-262713\r\nxxnet54857\r\nxxnet6-1208\r\nxxnet6-1345\r\nxxnet6-152204\r\nxxnet6-191411\r\nxxnet6-195605\r\nxxnet6-197815\r\nxxnet6-198703\r\nxxnet6-227710\r\nxxnet7-1208\r\nxxnet7-1345\r\nxxnet7-152204\r\nxxnet7-191411\r\nxxnet7-195605\r\nxxnet7-197815\r\nxxnet7-208507\r\nxxnet7-210802\r\nxxnet74589\r\nxxnet7779-01\r\nxxnet7779-02\r\nxxnet7779-03\r\nxxnet7779-04\r\nxxnet7779-05\r\nxxnet7779-06\r\nxxnet7779-07\r\nxxnet7779-08\r\nxxnet7779-09\r\nxxnet7779-10\r\nxxnet7779-11\r\nxxnet7779-12\r\nxxnet789-233214\r\nxxnet8-1208\r\nxxnet8-1345\r\nxxnet8-152204\r\nxxnet8-178304\r\nxxnet8-191411\r\nxxnet8-195605\r\nxxnet8-197815\r\nxxnet8-198703\r\nxxnet8-208507\r\nxxnet8-257701\r\nxxnet89959\r\nxxnet9-1208\r\nxxnet9-1345\r\nxxnet9-191411\r\nxxnet9-195605\r\nxxnet9-197815\r\nxxnet9-198703\r\nxxnet9-208507\r\nxxnet9255-216802\r\nxxnet9901\r\nxxnet9970\r\nxxnet99901\r\nxxnet99904\r\nxxnet99906\r\nxxnet99907\r\nxxnet99908\r\nxxnet99909\r\nxxnet99910\r\nxxneta\r\nxxnetappid-161812\r\nxxnetappid-191416\r\nxxnetappid02\r\nxxnetc1wiki\r\nxxnetclair01\r\nxxnetclair02\r\nxxnetclair03\r\nxxnetclair04\r\nxxnetclair05\r\nxxnetclair06\r\nxxnetclair07\r\nxxnetclair08\r\nxxnetclair09\r\nxxnetclair10\r\nxxnetclair11\r\nxxnetclair12\r\nxxnetcogent-repeater-227609\r\nxxnetcrossgfw02\r\nxxnetcrossgfw04\r\nxxnetcrossgfw06\r\nxxnetdisco-math-187208\r\nxxnetdsb\r\nxxnetforlaptop\r\nxxnetfynmfl5\r\nxxnetid-194208\r\nxxnetid101\r\nxxnetid103\r\nxxnetid104\r\nxxnetid105\r\nxxnetid106\r\nxxnetid107\r\nxxnetid108\r\nxxnetid109\r\nxxnetid110\r\nxxnetid111\r\nxxnetid112\r\nxxnetid113\r\nxxnetid114\r\nxxnetid115\r\nxxnetid116\r\nxxnetid118\r\nxxnetid119\r\nxxnetid120\r\nxxnetid121\r\nxxnetid122\r\nxxnetid123\r\nxxnetid124\r\nxxnetid125\r\nxxnetid126\r\nxxnetid127\r\nxxnetid128\r\nxxnetid129\r\nxxnetid130\r\nxxnetid131\r\nxxnetid132\r\nxxnetid133\r\nxxnetid136\r\nxxnetid137\r\nxxnetid138\r\nxxnetid139\r\nxxnetid21\r\nxxnetidfjy\r\nxxnetiimax1\r\nxxnetiimax10\r\nxxnetiimax2\r\nxxnetiimax3\r\nxxnetiimax4\r\nxxnetiimax5\r\nxxnetiimax6\r\nxxnetiimax7\r\nxxnetiimax8\r\nxxnetiimax9\r\nxxnetjuan\r\nxxnetjuan2\r\nxxnetlhuang01\r\nxxnetlhuang02\r\nxxnetlhuang03\r\nxxnetlhuang04\r\nxxnetlhuang05\r\nxxnetlhuang06\r\nxxnetlhuang07\r\nxxnetlhuang08\r\nxxnetlhuang09\r\nxxnetlhuang10\r\nxxnetlhuang11\r\nxxnetlhuang12\r\nxxnetli1\r\nxxnetli2\r\nxxnetlinufo\r\nxxnetox11\r\nxxnetox12\r\nxxnetp1\r\nxxnetp2\r\nxxnetp4\r\nxxnetp5\r\nxxnetp7\r\nxxnetp8\r\nxxnetp9\r\nxxnetproject-31640\r\nxxnetproject-40187\r\nxxnetshout\r\nxxnetsz001\r\nxxnetsz002\r\nxxnetsz003\r\nxxnettest-160605\r\nxxnettest10\r\nxxnettest11\r\nxxnettest12\r\nxxnettest2-160605\r\nxxnettest3-160605\r\nxxnettest4-182813\r\nxxnettest5-182813\r\nxxnettest6-182813\r\nxxnettest7-182813\r\nxxnettest8-182813\r\nxxnettest9-182813\r\nxxnetwang-255506\r\nxxnetwiki-198508\r\nxxnetxe\r\nxxnetxx-145814\r\nxxnetydy8-188302\r\nxxnetynmfl1\r\nxxnetynmfl2\r\nxxnetynmfl3\r\nxxnetynmfl4\r\nxxnetyoucai\r\nxxnetzhaozhao\r\nxxoo650-1274\r\nxxs123456\r\nxxt-donate\r\nxxtet-chinese\r\nxxtunnel-180904\r\nxxtunnel-180906\r\nxxx-1-111\r\nxxx-net-1209\r\nxxx-net-225913\r\nxxxfhy-102030\r\nxxxnet-1\r\nxxxnet-10\r\nxxxnet-11\r\nxxxnet-12\r\nxxxnet-2-1244\r\nxxxnet-4\r\nxxxnet-5\r\nxxxnet-6\r\nxxxnet-7\r\nxxxnet-8\r\nxxxnet-9\r\nxynet-beichi-send1\r\nyagam9951\r\nyagam9952\r\nyagam9953\r\nyagam9954\r\nyagam9955\r\nyagam9956\r\nyangkevin\r\nyangshouyi31\r\nyangyangnetwork\r\nyangyuenanxx-net\r\nyangyuenanxx-net1\r\nyankop-1661\r\nyankop-1662\r\nyankop-1663\r\nyankop-1664\r\nyankop-1665\r\nyankop-1666\r\nyankop-1667\r\nyankop-1668\r\nyankop-1669\r\nyaowang59722669\r\nybr1-143110\r\nybr2-143110\r\nybr3-143110\r\nybr4-143110\r\nybr5-143110\r\nybr6-143110\r\nybr7-143110\r\nybr8-143110\r\nybr9-143110\r\nycg18-8-15\r\nyellowcoolcool1\r\nyellowcoolcool10\r\nyellowcoolcool2\r\nyellowcoolcool3\r\nyellowcoolcool4\r\nyellowcoolcool5\r\nyellowcoolcool6\r\nyellowcoolcool7\r\nyellowcoolcool8\r\nyellowcoolcool9\r\nyesxcj\r\nyfkm010\r\nyfkm011\r\nyfkm012\r\nyfkm013\r\nyfkm014\r\nyfkm015\r\nyfkm016\r\nyfkm017\r\nyfkm018\r\nyfkm019\r\nyfkm020\r\nyhwc9-235117\r\nyicheng750\r\nyicheng751\r\nyilian123110\r\nyilian123111\r\nying-9000\r\nyingerson012\r\nyiyi-227007\r\nyj3259669110\r\nyj3259669111\r\nyj3259669112\r\nyj3259669113\r\nyj3259669114\r\nyjy-project\r\nyjy-project2\r\nyjy-project4\r\nyjy-project5\r\nykyworld8\r\nynning\r\nyntdfsrw\r\nyntdfsrw10\r\nyntdfsrw2\r\nyntdfsrw3\r\nyntdfsrw4\r\nyntdfsrw5\r\nyntdfsrw6\r\nyntdfsrw7\r\nyntdfsrw8\r\nyntdfsrw9\r\nyochi03104450\r\nyongda-1\r\nyongda-10\r\nyongda-11\r\nyongda-2\r\nyongda-3\r\nyongda-4\r\nyongda-5\r\nyongda-6\r\nyongda-7\r\nyongda-8\r\nyongda-9\r\nyoungcookie-147607\r\nyourewb\r\nyoutube-watcher-186408\r\nyrtsai001\r\nyuan-jang11\r\nyuchen941110\r\nyuemeng440711\r\nyueyilin-163309\r\nyugmail\r\nyuku871-1274\r\nyulian0828\r\nyun-id10\r\nyun-id7\r\nyun-id8\r\nyun-id9\r\nyxd0010\r\nyyp111-211404\r\nyytcug\r\nyytv587\r\nyytwxt\r\nyyx-gtr-1111\r\nyyx-gtr-1112\r\nyyx-gtr-1113\r\nyyx-gtr-1114\r\nyyx-gtr-1115\r\nyyx-gtr-1116\r\nyyx-gtr-1117\r\nyyx-gtr-1118\r\nyyx-gtr-1119\r\nyyx-gtr-1120\r\nz403529262-21\r\nz403529262-22\r\nz403529262-23\r\nz403529262-24\r\nzapoo0709\r\nzebchou-160302\r\nzeta-crossbar-215712\r\nzexitouzi\r\nzeziyu31\r\nzeziyu32\r\nzeziyu33\r\nzeziyu34\r\nzeziyu35\r\nzeziyu36\r\nzeziyu37\r\nzeziyu38\r\nzeziyu39\r\nzeziyu40\r\nzeziyu9\r\nzhang-163706\r\nzhanghua-207701\r\nzhanghua1-207705\r\nzhangtina000\r\nzhangtina0000\r\nzhangwantong1\r\nzhangwantong2\r\nzhangwantong3\r\nzhaochengya2654\r\nzhaorain-1186\r\nzhaorain1\r\nzhaorain10\r\nzhaorain11\r\nzheng234-1331\r\nzheng345-1331\r\nzhenhong0001\r\nzhenhong0002\r\nzhenhong0003\r\nzhenhongbeiyong\r\nzhijiangdaqu3\r\nzhijiangdaqu4\r\nzhiying-163309\r\nzhongjiamingshitiancai2-168105\r\nzhongshangwu22\r\nzhongshangwu23\r\nzhongshangwu25\r\nzhongshangwu26\r\nzhongshangwu27\r\nzhongshangwu28\r\nzhongshangwu29\r\nzhongshangwu30\r\nzhoubiao-160302\r\nzhoumeng10080\r\nzhoumeng10081\r\nzhoumeng10082\r\nzhoumeng10083\r\nzhoumeng10084\r\nzhoumeng10085\r\nzhoumeng10086\r\nzhoumeng10087\r\nzhoumeng10088\r\nzhoumeng10089\r\nzhoumeng1081\r\nzhousuiyuan4\r\nzhousuiyuan5\r\nzhouwucheng1\r\nzhouwucheng11\r\nzhouxingyucn1\r\nzhouxingyucn10\r\nzhouxingyucn11\r\nzhouxingyucn12\r\nzhouxingyucn13\r\nzhouxingyucn14\r\nzhouxingyucn15\r\nzhouxingyucn16\r\nzhouxingyucn17\r\nzhouxingyucn18\r\nzhouxingyucn19\r\nzhouxingyucn2\r\nzhouxingyucn20\r\nzhouxingyucn21\r\nzhouxingyucn22\r\nzhouxingyucn23\r\nzhouxingyucn24\r\nzhouxingyucn25\r\nzhouxingyucn3\r\nzhouxingyucn4\r\nzhouxingyucn5\r\nzhouxingyucn6\r\nzhouxingyucn7\r\nzhouxingyucn8\r\nzhouxingyucn9\r\nzhuccct\r\nzhuccct01\r\nzhuccct02\r\nzhuccct03\r\nzhuccct04\r\nzhuccct05\r\nzhuccct06\r\nzhuccct07\r\nzhuccct08\r\nzhuccct09\r\nzhuccct10\r\nzhujixihu\r\nzhyqlp-01\r\nzhyqlp-02\r\nzhyqlp-03\r\nzhyqlp-04\r\nzhyqlp-05\r\nzhyqlp-06\r\nzhyqlp-07\r\nzhyqlp-08\r\nzhzhi4186\r\nzhzhi4187\r\nzhzhi4188\r\nzhzhi4189\r\nzhzytb1\r\nzhzytb2\r\nzhzytb3\r\nzhzytb4\r\nzinc-silicon-206709\r\nzinc-style-240007\r\nzipple0000\r\nzipple00000\r\nzipple000000\r\nzipple0000000\r\nzipple000000000\r\nzipple0000000000\r\nzipple00000000000\r\nzipple000000000000\r\nzipple0000000000000\r\nzipple00000000000000\r\nzippy-world-192108\r\nzoumeng10080\r\nzuooo-12\r\nzuotq121\r\nzuotq122\r\nzuotq123\r\nzuotq124\r\nzuotq125\r\nzuotq126\r\nzuotq127\r\nzuotq128\r\nzuotq129\r\nzuotq130\r\nzwx1232zwx\r\nzwx1233zwx\r\nzwx1234zwx\r\nzx-antigfw1\r\nzx-antigfw2\r\nzx-antigfw3\r\nzx-antigfw4\r\nzx-antigfw5\r\nzx-antigfw6\r\nzyyipai6\r\nzyyipai7\r\nzyyzpubready\r\nzzahun\r\nzzfa27\r\nzzfa28\r\nzzfa29\r\nzzfa30\r\nzzfa31\r\nzzfa32\r\nzzfa34\r\nzzfa35\r\nzzfahun\r\n"
  },
  {
    "path": "code/default/gae_proxy/local/cacert.pem",
    "content": "## Google Context Issuer Trust Root CA\n\n# Operating CA: GlobalSign\n# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2\n# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2\n# Label: \"GlobalSign Root CA - R2\"\n# Serial: 02:03:e4:f4:61:ec:99:d9:d5:79:66:ca:7a\n# MD5 Fingerprint: f1:5f:67:ab:01:e8:b1:0e:32:ff:37:07:26:06:ff:c4\n# SHA1 Fingerprint: 02:9d:4b:7e:33:d2:83:8c:66:8c:1d:2c:56:9e:f9:2a:54:0a:7b:96\n# SHA256 Fingerprint: 69:e2:d0:6c:30:f3:66:16:61:65:e9:1d:68:d1:ce:e5:cc:47:58:4a:80:22:7e:76:66:60:86:c0:10:72:41:eb\n-----BEGIN CERTIFICATE-----\nMIIDvDCCAqSgAwIBAgINAgPk9GHsmdnVeWbKejANBgkqhkiG9w0BAQUFADBMMSAw\nHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFs\nU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjAeFw0wNjEyMTUwODAwMDBaFw0yMTEy\nMTUwODAwMDBaMEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFIyMRMw\nEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMIIBIjANBgkq\nhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAps8kDr4ubyiZRULEqz4hVJsL03+EcPoS\ns8u/h1/Gf4bTsjBc1v2t8Xvc5fhglgmSEPXQU977e35ziKxSiHtKpspJpl6op4xa\nEbx6guu+jOmzrJYlB5dKmSoHL7Qed7+KD7UCfBuWuMW5Oiy81hK561l94tAGhl9e\nSWq1OV6INOy8eAwImIRsqM1LtKB9DHlN8LgtyyHK1WxbfeGgKYSh+dOUScskYpEg\nvN0L1dnM+eonCitzkcadG6zIy+jgoPQvkItN+7A2G/YZeoXgbfJhE4hcn+CTClGX\nilrOr6vV96oJqmC93Nlf33KpYBNeAAHJSvo/pOoHAyECjoLKA8KbjwIDAQABo4Gc\nMIGZMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSb\n4gdXZxwewGoG3lm0mi3f3BmGLjAfBgNVHSMEGDAWgBSb4gdXZxwewGoG3lm0mi3f\n3BmGLjA2BgNVHR8ELzAtMCugKaAnhiVodHRwOi8vY3JsLmdsb2JhbHNpZ24ubmV0\nL3Jvb3QtcjIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQANeX81Z1YqDIs4EaLjG0qP\nOxIzaJI/y4kiRj3a+y3KOx74clIkLuMgi/9/5iv/n+1LyhGU9g7174slbzJOPbSp\np1eT19ST2mYbdgTLx/hm3tTLoHIY/w4ZbnQYwfnPwAG4RefnEFYPQJmpD+Wh8BJw\nBgtm2drTale/T6NBwmwnEFunfaMfMX3g6IBrx7VKnxIkJh/3p190WveLKgl9n7i5\nSWce/4woPimEn9WfEQWRvp6wKhaCKFjuCMuulEZusoOUJ4LfJnXxcuQTgIrSnwI7\nKfSSjsd42w3lX1fbgJp7vPmLM6OBRvAXuYRKTFqMAWbb7OaGIEE+cbxY6PDepnva\n-----END CERTIFICATE-----\n\n# Operating CA: GlobalSign\n# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4\n# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4\n# Label: \"GlobalSign ECC Root CA - R4\"\n# Serial: 02:03:e5:7e:f5:3f:93:fd:a5:09:21:b2:a6\n# MD5 Fingerprint: 26:29:f8:6d:e1:88:bf:a2:65:7f:aa:c4:cd:0f:7f:fc\n# SHA1 Fingerprint: 6b:a0:b0:98:e1:71:ef:5a:ad:fe:48:15:80:77:10:f4:bd:6f:0b:28\n# SHA256 Fingerprint: b0:85:d7:0b:96:4f:19:1a:73:e4:af:0d:54:ae:7a:0e:07:aa:fd:af:9b:71:dd:08:62:13:8a:b7:32:5a:24:a2\n-----BEGIN CERTIFICATE-----\nMIIB3DCCAYOgAwIBAgINAgPlfvU/k/2lCSGypjAKBggqhkjOPQQDAjBQMSQwIgYD\nVQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0gUjQxEzARBgNVBAoTCkdsb2Jh\nbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTIxMTEzMDAwMDAwWhcNMzgw\nMTE5MDMxNDA3WjBQMSQwIgYDVQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0g\nUjQxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wWTAT\nBgcqhkjOPQIBBggqhkjOPQMBBwNCAAS4xnnTj2wlDp8uORkcA6SumuU5BwkWymOx\nuYb4ilfBV85C+nOh92VC/x7BALJucw7/xyHlGKSq2XE/qNS5zowdo0IwQDAOBgNV\nHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVLB7rUW44kB/\n+wpu+74zyTyjhNUwCgYIKoZIzj0EAwIDRwAwRAIgIk90crlgr/HmnKAWBVBfw147\nbmF0774BxL4YSFlhgjICICadVGNA3jdgUM/I2O2dgq43mLyjj0xMqTQrbO/7lZsm\n-----END CERTIFICATE-----\n\n# Operating CA: Google Trust Services LLC\n# Issuer: CN=GTS Root R1 O=Google Trust Services LLC\n# Subject: CN=GTS Root R1 O=Google Trust Services LLC\n# Label: \"GTS Root R1\"\n# Serial: 02:03:e5:93:6f:31:b0:13:49:88:6b:a2:17\n# MD5 Fingerprint: 05:fe:d0:bf:71:a8:a3:76:63:da:01:e0:d8:52:dc:40\n# SHA1 Fingerprint: e5:8c:1c:c4:91:3b:38:63:4b:e9:10:6e:e3:ad:8e:6b:9d:d9:81:4a\n# SHA256 Fingerprint: d9:47:43:2a:bd:e7:b7:fa:90:fc:2e:6b:59:10:1b:12:80:e0:e1:c7:e4:e4:0f:a3:c6:88:7f:ff:57:a7:f4:cf\n-----BEGIN CERTIFICATE-----\nMIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw\nCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU\nMBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw\nMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp\nY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA\nA4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo\n27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w\nCl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw\nTcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl\nqAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH\nszVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8\nY/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk\nMiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92\nwO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p\naDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN\nVjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID\nAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E\nFgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb\nC5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe\nQkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy\nh6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4\n7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J\nZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef\nMgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/\nZ6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT\n6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ\n0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm\n2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb\nbP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c\n-----END CERTIFICATE-----\n\n# Operating CA: Google Trust Services LLC\n# Issuer: CN=GTS Root R2 O=Google Trust Services LLC\n# Subject: CN=GTS Root R2 O=Google Trust Services LLC\n# Label: \"GTS Root R2\"\n# Serial: 02:03:e5:ae:c5:8d:04:25:1a:ab:11:25:aa\n# MD5 Fingerprint: 1e:39:c0:53:e6:1e:29:82:0b:ca:52:55:36:5d:57:dc\n# SHA1 Fingerprint: 9a:44:49:76:32:db:de:fa:d0:bc:fb:5a:7b:17:bd:9e:56:09:24:94\n# SHA256 Fingerprint: 8d:25:cd:97:22:9d:bf:70:35:6b:da:4e:b3:cc:73:40:31:e2:4c:f0:0f:af:cf:d3:2d:c7:6e:b5:84:1c:7e:a8\n-----BEGIN CERTIFICATE-----\nMIIFVzCCAz+gAwIBAgINAgPlrsWNBCUaqxElqjANBgkqhkiG9w0BAQwFADBHMQsw\nCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU\nMBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw\nMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp\nY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEBAQUA\nA4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3LvCvpt\nnfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3KgGjSY\n6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9BuXvAu\nMC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOdre7k\nRXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXuPuWg\nf9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1mKPV\n+3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K8Yzo\ndDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqjx5RW\nIr9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsRnTKa\nG73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0kzCq\ngc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9OktwID\nAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E\nFgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBAB/Kzt3H\nvqGf2SdMC9wXmBFqiN495nFWcrKeGk6c1SuYJF2ba3uwM4IJvd8lRuqYnrYb/oM8\n0mJhwQTtzuDFycgTE1XnqGOtjHsB/ncw4c5omwX4Eu55MaBBRTUoCnGkJE+M3DyC\nB19m3H0Q/gxhswWV7uGugQ+o+MePTagjAiZrHYNSVc61LwDKgEDg4XSsYPWHgJ2u\nNmSRXbBoGOqKYcl3qJfEycel/FVL8/B/uWU9J2jQzGv6U53hkRrJXRqWbTKH7QMg\nyALOWr7Z6v2yTcQvG99fevX4i8buMTolUVVnjWQye+mew4K6Ki3pHrTgSAai/Gev\nHyICc/sgCq+dVEuhzf9gR7A/Xe8bVr2XIZYtCtFenTgCR2y59PYjJbigapordwj6\nxLEokCZYCDzifqrXPW+6MYgKBesntaFJ7qBFVHvmJ2WZICGoo7z7GJa7Um8M7YNR\nTOlZ4iBgxcJlkoKM8xAfDoqXvneCbT+PHV28SSe9zE8P4c52hgQjxcCMElv924Sg\nJPFI/2R80L5cFtHvma3AH/vLrrw4IgYmZNralw4/KBVEqE8AyvCazM90arQ+POuV\n7LXTWtiBmelDGDfrs7vRWGJB82bSj6p4lVQgw1oudCvV0b4YacCs1aTPObpRhANl\n6WLAYv7YTVWW4tAR+kg0Eeye7QUd5MjWHYbL\n-----END CERTIFICATE-----\n\n# Operating CA: Google Trust Services LLC\n# Issuer: CN=GTS Root R3 O=Google Trust Services LLC\n# Subject: CN=GTS Root R3 O=Google Trust Services LLC\n# Label: \"GTS Root R3\"\n# Serial: 02:03:e5:b8:82:eb:20:f8:25:27:6d:3d:66\n# MD5 Fingerprint: 3e:e7:9d:58:02:94:46:51:94:e5:e0:22:4a:8b:e7:73\n# SHA1 Fingerprint: ed:e5:71:80:2b:c8:92:b9:5b:83:3c:d2:32:68:3f:09:cd:a0:1e:46\n# SHA256 Fingerprint: 34:d8:a7:3e:e2:08:d9:bc:db:0d:95:65:20:93:4b:4e:40:e6:94:82:59:6e:8b:6f:73:c8:42:6b:01:0a:6f:48\n-----BEGIN CERTIFICATE-----\nMIICCTCCAY6gAwIBAgINAgPluILrIPglJ209ZjAKBggqhkjOPQQDAzBHMQswCQYD\nVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG\nA1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw\nWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz\nIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQAIgNi\nAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout736G\njOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2ADDL2\n4CejQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW\nBBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEA9uEglRR7\nVKOQFhG/hMjqb2sXnh5GmCCbn9MN2azTL818+FsuVbu/3ZL3pAzcMeGiAjEA/Jdm\nZuVDFhOD3cffL74UOO0BzrEXGhF16b0DjyZ+hOXJYKaV11RZt+cRLInUue4X\n-----END CERTIFICATE-----\n\n# Operating CA: Google Trust Services LLC\n# Issuer: CN=GTS Root R4 O=Google Trust Services LLC\n# Subject: CN=GTS Root R4 O=Google Trust Services LLC\n# Label: \"GTS Root R4\"\n# Serial: 02:03:e5:c0:68:ef:63:1a:9c:72:90:50:52\n# MD5 Fingerprint: 43:96:83:77:19:4d:76:b3:9d:65:52:e4:1d:22:a5:e8\n# SHA1 Fingerprint: 77:d3:03:67:b5:e0:0c:15:f6:0c:38:61:df:7c:e1:3b:92:46:4d:47\n# SHA256 Fingerprint: 34:9d:fa:40:58:c5:e2:63:12:3b:39:8a:e7:95:57:3c:4e:13:13:c8:3f:e6:8f:93:55:6c:d5:e8:03:1b:3c:7d\n-----BEGIN CERTIFICATE-----\nMIICCTCCAY6gAwIBAgINAgPlwGjvYxqccpBQUjAKBggqhkjOPQQDAzBHMQswCQYD\nVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG\nA1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw\nWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz\nIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQAIgNi\nAATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzuhXyi\nQHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/lxKvR\nHYqjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW\nBBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNpADBmAjEA6ED/g94D\n9J+uHXqnLrmvT/aDHQ4thQEd0dlq7A/Cr8deVl5c1RxYIigL9zC2L7F8AjEA8GE8\np/SgguMh1YQdc4acLa/KNJvxn7kjNuK8YAOdgLOaVsjh4rsUecrNIdSUtUlD\n-----END CERTIFICATE-----\n\n# Operating CA: DigiCert Inc\n# Issuer: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com\n# Subject: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com\n# Label: \"www.digicert.com\"\n# Serial: 0c:e7:e0:e5:17:d8:46:fe:8f:e5:60:fc:1b:f0:30:39\n# MD5 Fingerprint: 87:ce:0b:7b:2a:0e:49:00:e1:58:71:9b:37:a8:93:72\n# SHA1 Fingerprint: 05:63:b8:63:0d:62:d7:5a:bb:c8:ab:1e:4b:df:b5:a8:99:b2:4d:43\n# SHA256 Fingerprint: 3e:90:99:b5:01:5e:8f:48:6c:00:bc:ea:9d:11:1e:e7:21:fa:ba:35:5a:89:bc:f1:df:69:56:1e:3d:c6:32:5c\n-----BEGIN CERTIFICATE-----\nMIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl\nMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\nd3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv\nb3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG\nEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl\ncnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi\nMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c\nJpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP\nmDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+\nwRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4\nVYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/\nAUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB\nAAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW\nBBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun\npyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC\ndWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf\nfwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm\nNW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx\nH2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe\n+o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==\n-----END CERTIFICATE-----\n\n# Operating CA: Equifax\n# Issuer: O=Equifax OU=Equifax Secure Certificate Authority\n# Subject: O=Equifax OU=Equifax Secure Certificate Authority\n# Label: \"Equifax Secure Certificate Authority\"\n# Serial: 35:de:f4:cf\n# MD5 Fingerprint: 67:cb:9d:c0:13:24:8a:82:9b:b2:17:1e:d1:1b:ec:d4\n# SHA1 Fingerprint: d2:32:09:ad:23:d3:14:23:21:74:e4:0d:7f:9d:62:13:97:86:63:3a\n# SHA256 Fingerprint: 08:29:7a:40:47:db:a2:36:80:c7:31:db:6e:31:76:53:ca:78:48:e1:be:bd:3a:0b:01:79:a7:07:f9:2c:f1:78\n-----BEGIN CERTIFICATE-----\nMIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV\nUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy\ndGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1\nMVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx\ndWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B\nAQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f\nBeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A\ncJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC\nAwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ\nMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm\naWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw\nODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj\nIBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF\nMAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA\nA4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y\n7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh\n1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4\n-----END CERTIFICATE-----\n\n\n# Old CAs\n\n# Operating CA: GlobalSign\n# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2\n# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2\n# Label: \"GlobalSign Root CA - R2\" DEPRECATED\n# Serial: 04:00:00:00:00:01:0f:86:26:e6:0d\n# MD5 Fingerprint: 94:14:77:7e:3e:5e:fd:8f:30:bd:41:b0:cf:e7:d0:30\n# SHA1 Fingerprint: 75:e0:ab:b6:13:85:12:27:1c:04:f8:5f:dd:de:38:e4:b7:24:2e:fe\n# SHA256 Fingerprint: ca:42:dd:41:74:5f:d0:b8:1e:b9:02:36:2c:f9:d8:bf:71:9d:a1:bd:1b:1e:fc:94:6f:5b:4c:99:f4:2c:1b:9e\n-----BEGIN CERTIFICATE-----\nMIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G\nA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp\nZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1\nMDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG\nA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI\nhvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL\nv4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8\neoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq\ntTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd\nC9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa\nzq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB\nmTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH\nV2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n\nbG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG\n3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs\nJ0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO\n291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS\not+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd\nAfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7\nTBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==\n-----END CERTIFICATE-----\n\n# Operating CA: GlobalSign\n# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4\n# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4\n# Label: \"GlobalSign ECC Root CA - R4\"\n# Serial: 2a:38:a4:1c:96:0a:04:de:42:b2:28:a5:0b:e8:34:98:02\n# MD5 Fingerprint: 20:f0:27:68:d1:7e:a0:9d:0e:e6:2a:ca:df:5c:89:8e\n# SHA1 Fingerprint: 69:69:56:2e:40:80:f4:24:a1:e7:19:9f:14:ba:f3:ee:58:ab:6a:bb\n# SHA256 Fingerprint: be:c9:49:11:c2:95:56:76:db:6c:0a:55:09:86:d7:6e:3b:a0:05:66:7c:44:2c:97:62:b4:fb:b7:73:de:22:8c\n-----BEGIN CERTIFICATE-----\nMIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk\nMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH\nbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX\nDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD\nQSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ\nFspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw\nDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F\nuOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX\nkPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs\newv4n4Q=\n-----END CERTIFICATE-----\n\n# Operating CA: Google Trust Services LLC\n# Issuer: CN=GTS Root R1 O=Google Trust Services LLC\n# Subject: CN=GTS Root R1 O=Google Trust Services LLC\n# Label: \"GTS Root R1\"\n# Serial: 6e:47:a9:c5:4b:47:0c:0d:ec:33:d0:89:b9:1c:f4:e1\n# MD5 Fingerprint: 82:1a:ef:d4:d2:4a:f2:9f:e2:3d:97:06:14:70:72:85\n# SHA1 Fingerprint: e1:c9:50:e6:ef:22:f8:4c:56:45:72:8b:92:20:60:d7:d5:a7:a3:e8\n# SHA256 Fingerprint: 2a:57:54:71:e3:13:40:bc:21:58:1c:bd:2c:f1:3e:15:84:63:20:3e:ce:94:bc:f9:d3:cc:19:6b:f0:9a:54:72\n-----BEGIN CERTIFICATE-----\nMIIFWjCCA0KgAwIBAgIQbkepxUtHDA3sM9CJuRz04TANBgkqhkiG9w0BAQwFADBH\nMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM\nQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy\nMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl\ncnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEB\nAQUAA4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaM\nf/vo27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vX\nmX7wCl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7\nzUjwTcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0P\nfyblqAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtc\nvfaHszVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4\nZor8Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUsp\nzBmkMiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOO\nRc92wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYW\nk70paDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+\nDVrNVjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgF\nlQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV\nHQ4EFgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBADiW\nCu49tJYeX++dnAsznyvgyv3SjgofQXSlfKqE1OXyHuY3UjKcC9FhHb8owbZEKTV1\nd5iyfNm9dKyKaOOpMQkpAWBz40d8U6iQSifvS9efk+eCNs6aaAyC58/UEBZvXw6Z\nXPYfcX3v73svfuo21pdwCxXu11xWajOl40k4DLh9+42FpLFZXvRq4d2h9mREruZR\ngyFmxhE+885H7pwoHyXa/6xmld01D1zvICxi/ZG6qcz8WpyTgYMpl0p8WnK0OdC3\nd8t5/Wk6kjftbjhlRn7pYL15iJdfOBL07q9bgsiG1eGZbYwE8na6SfZu6W0eX6Dv\nJ4J2QPim01hcDyxC2kLGe4g0x8HYRZvBPsVhHdljUEn2NIVq4BjFbkerQUIpm/Zg\nDdIx02OYI5NaAIFItO/Nis3Jz5nu2Z6qNuFoS3FJFDYoOj0dzpqPJeaAcWErtXvM\n+SUWgeExX6GjfhaknBZqlxi9dnKlC54dNuYvoS++cJEPqOba+MSSQGwlfnuzCdyy\nF62ARPBopY+Udf90WuioAnwMCeKpSwughQtiue+hMZL77/ZRBIls6Kl0obsXs7X9\nSQ98POyDGCBDTtWTurQ0sR8WNh8M5mQ5Fkzc4P4dyKliPUDqysU0ArSuiYgzNdws\nE3PYJ/HQcu51OyLemGhmW/HGY0dVHLqlCFF1pkgl\n-----END CERTIFICATE-----\n\n# Operating CA: Google Trust Services LLC\n# Issuer: CN=GTS Root R2 O=Google Trust Services LLC\n# Subject: CN=GTS Root R2 O=Google Trust Services LLC\n# Label: \"GTS Root R2\"\n# Serial: 6e:47:a9:c6:5a:b3:e7:20:c5:30:9a:3f:68:52:f2:6f\n# MD5 Fingerprint: 44:ed:9a:0e:a4:09:3b:00:f2:ae:4c:a3:c6:61:b0:8b\n# SHA1 Fingerprint: d2:73:96:2a:2a:5e:39:9f:73:3f:e1:c7:1e:64:3f:03:38:34:fc:4d\n# SHA256 Fingerprint: c4:5d:7b:b0:8e:6d:67:e6:2e:42:35:11:0b:56:4e:5f:78:fd:92:ef:05:8c:84:0a:ea:4e:64:55:d7:58:5c:60\n-----BEGIN CERTIFICATE-----\nMIIFWjCCA0KgAwIBAgIQbkepxlqz5yDFMJo/aFLybzANBgkqhkiG9w0BAQwFADBH\nMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM\nQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy\nMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl\ncnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEB\nAQUAA4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3Lv\nCvptnfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3Kg\nGjSY6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9Bu\nXvAuMC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOd\nre7kRXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXu\nPuWgf9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1\nmKPV+3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K\n8YzodDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqj\nx5RWIr9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsR\nnTKaG73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0\nkzCqgc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9Ok\ntwIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV\nHQ4EFgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBALZp\n8KZ3/p7uC4Gt4cCpx/k1HUCCq+YEtN/L9x0Pg/B+E02NjO7jMyLDOfxA325BS0JT\nvhaI8dI4XsRomRyYUpOM52jtG2pzegVATX9lO9ZY8c6DR2Dj/5epnGB3GFW1fgiT\nz9D2PGcDFWEJ+YF59exTpJ/JjwGLc8R3dtyDovUMSRqodt6Sm2T4syzFJ9MHwAiA\npJiS4wGWAqoC7o87xdFtCjMwc3i5T1QWvwsHoaRc5svJXISPD+AVdyx+Jn7axEvb\npxZ3B7DNdehyQtaVhJ2Gg/LkkM0JR9SLA3DaWsYDQvTtN6LwG1BUSw7YhN4ZKJmB\nR64JGz9I0cNv4rBgF/XuIwKl2gBbbZCr7qLpGzvpx0QnRY5rn/WkhLx3+WuXrD5R\nRaIRpsyF7gpo8j5QOHokYh4XIDdtak23CZvJ/KRY9bb7nE4Yu5UC56GtmwfuNmsk\n0jmGwZODUNKBRqhfYlcsu2xkiAhu7xNUX90txGdj08+JN7+dIPT7eoOboB6BAFDC\n5AwiWVIQ7UNWhwD4FFKnHYuTjKJNRn8nxnGbJN7k2oaLDX5rIMHAnuFl2GqjpuiF\nizoHCBy69Y9Vmhh1fuXsgWbRIXOhNUQLgD1bnF5vKheW0YMjiGZt5obicDIvUiLn\nyOd/xCxgXS/Dr55FBcOEArf9LAhST4Ldo/DUhgkC\n-----END CERTIFICATE-----\n\n# Operating CA: Google Trust Services LLC\n# Issuer: CN=GTS Root R3 O=Google Trust Services LLC\n# Subject: CN=GTS Root R3 O=Google Trust Services LLC\n# Label: \"GTS Root R3\"\n# Serial: 6e:47:a9:c7:6c:a9:73:24:40:89:0f:03:55:dd:8d:1d\n# MD5 Fingerprint: 1a:79:5b:6b:04:52:9c:5d:c7:74:33:1b:25:9a:f9:25\n# SHA1 Fingerprint: 30:d4:24:6f:07:ff:db:91:89:8a:0b:e9:49:66:11:eb:8c:5e:46:e5\n# SHA256 Fingerprint: 15:d5:b8:77:46:19:ea:7d:54:ce:1c:a6:d0:b0:c4:03:e0:37:a9:17:f1:31:e8:a0:4e:1e:6b:7a:71:ba:bc:e5\n-----BEGIN CERTIFICATE-----\nMIICDDCCAZGgAwIBAgIQbkepx2ypcyRAiQ8DVd2NHTAKBggqhkjOPQQDAzBHMQsw\nCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU\nMBIGA1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw\nMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp\nY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQA\nIgNiAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout\n736GjOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2A\nDDL24CejQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud\nDgQWBBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEAgFuk\nfCPAlaUs3L6JbyO5o91lAFJekazInXJ0glMLfalAvWhgxeG4VDvBNhcl2MG9AjEA\nnjWSdIUlUfUk7GRSJFClH9voy8l27OyCbvWFGFPouOOaKaqW04MjyaR7YbPMAuhd\n-----END CERTIFICATE-----\n\n# Operating CA: Google Trust Services LLC\n# Issuer: CN=GTS Root R4 O=Google Trust Services LLC\n# Subject: CN=GTS Root R4 O=Google Trust Services LLC\n# Label: \"GTS Root R4\"\n# Serial: 6e:47:a9:c8:8b:94:b6:e8:bb:3b:2a:d8:a2:b2:c1:99\n# MD5 Fingerprint: 5d:b6:6a:c4:60:17:24:6a:1a:99:a8:4b:ee:5e:b4:26\n# SHA1 Fingerprint: 2a:1d:60:27:d9:4a:b1:0a:1c:4d:91:5c:cd:33:a0:cb:3e:2d:54:cb\n# SHA256 Fingerprint: 71:cc:a5:39:1f:9e:79:4b:04:80:25:30:b3:63:e1:21:da:8a:30:43:bb:26:66:2f:ea:4d:ca:7f:c9:51:a4:bd\n-----BEGIN CERTIFICATE-----\nMIICCjCCAZGgAwIBAgIQbkepyIuUtui7OyrYorLBmTAKBggqhkjOPQQDAzBHMQsw\nCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU\nMBIGA1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw\nMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp\nY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQA\nIgNiAATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzu\nhXyiQHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/l\nxKvRHYqjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud\nDgQWBBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNnADBkAjBqUFJ0\nCMRw3J5QdCHojXohw0+WbhXRIjVhLfoIN+4Zba3bssx9BzT1YBkstTTZbyACMANx\nsbqjYAuG7ZoIapVon+Kz4ZNkfF6Tpt95LY2F45TPI11xzPKwTdb+mciUqXWi4w==\n-----END CERTIFICATE-----\n\n# Operating CA: GeoTrust Inc.\n# Issuer: CN=GeoTrust Global CA O=GeoTrust Inc.\n# Subject: CN=GeoTrust Global CA O=GeoTrust Inc.\n# Label: \"GeoTrust Global CA\"\n# Serial: 02:34:56\n# MD5 Fingerprint: f7:75:ab:29:fb:51:4e:b7:77:5e:ff:05:3c:99:8e:f5\n# SHA1 Fingerprint: de:28:f4:a4:ff:e5:b9:2f:a3:c5:03:d1:a3:49:a7:f9:96:2a:82:12\n# SHA256 Fingerprint: ff:85:6a:2d:25:1d:cd:88:d3:66:56:f4:50:12:67:98:cf:ab:aa:de:40:79:9c:72:2d:e4:d2:b5:db:36:a7:3a\n-----BEGIN CERTIFICATE-----\nMIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT\nMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i\nYWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG\nEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg\nR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9\n9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq\nfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv\niS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU\n1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+\nbw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW\nMPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA\nephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l\nuMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn\nZ57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS\ntQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF\nPseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un\nhw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV\n5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==\n-----END CERTIFICATE-----\n"
  },
  {
    "path": "code/default/gae_proxy/local/cert_util.py",
    "content": "#!/usr/bin/env python\n# coding:utf-8\n\nimport os\nimport sys\nimport glob\nimport time\nimport random\nimport base64\nimport threading\nimport subprocess\nimport datetime\n\ntry:\n    import OpenSSL\nexcept:\n    pass\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\npython_path = os.path.abspath( os.path.join(current_path, os.pardir, os.pardir))\nroot_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))\n\nif __name__ == \"__main__\":\n    noarch_lib = os.path.abspath( os.path.join(python_path, 'lib', 'noarch'))\n    sys.path.append(noarch_lib)\n\n    if sys.platform == \"win32\":\n        win32_lib = os.path.abspath( os.path.join(python_path, 'lib', 'win32'))\n        sys.path.append(win32_lib)\n    elif sys.platform == \"linux\" or sys.platform == \"linux2\":\n        linux_lib = os.path.abspath( os.path.join(python_path, 'lib', 'linux'))\n        sys.path.append(linux_lib)\n    elif sys.platform == \"darwin\":\n        darwin_lib = os.path.abspath( os.path.join(python_path, 'lib', 'darwin'))\n        sys.path.append(darwin_lib)\n\nimport env_info\ndata_path = os.path.abspath(os.path.join(env_info.data_path, \"gae_proxy\"))\nif not os.path.isdir(data_path):\n    data_path = current_path\n\nimport utils\nfrom xlog import getLogger\nxlog = getLogger(\"gae_proxy\")\n\nfrom utils import check_ip_valid\n\n\ndef get_cmd_out(cmd):\n    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n    out = proc.stdout\n    lines = out.readlines()\n    return lines\n\n\nclass CertUtil(object):\n    \"\"\"CertUtil module, based on mitmproxy\"\"\"\n\n    ca_vendor = 'GoAgent' #TODO: here should be XX-Net\n    ca_certfile = os.path.join(data_path, 'CA.crt')\n    ca_keyfile = os.path.join(data_path, 'CAkey.pem')\n    ca_thumbprint = b''\n    ca_privatekey = None\n    ca_subject = None\n    ca_certdir = os.path.join(data_path, 'certs')\n    ca_digest = 'sha256'\n    ca_lock = threading.Lock()\n    ca_validity_years = 10\n    ca_validity = 24 * 60 * 60 * 365 * ca_validity_years\n    cert_validity_years = 2\n    cert_validity = 24 * 60 * 60 * 365 * cert_validity_years\n    cert_publickey = None\n    cert_keyfile = os.path.join(data_path, 'Certkey.pem')\n    serial_reduce =  3600 * 24 * 365 * 46\n\n    @staticmethod\n    def create_ca():\n        key = OpenSSL.crypto.PKey()\n        key.generate_key(OpenSSL.crypto.TYPE_RSA, 2048)\n        ca = OpenSSL.crypto.X509()\n        ca.set_version(2)\n        ca.set_serial_number(0)\n        subj = ca.get_subject()\n        subj.countryName = 'CN'\n        subj.stateOrProvinceName = 'Internet'\n        subj.localityName = 'Cernet'\n        subj.organizationName = CertUtil.ca_vendor\n        # Log generated time.\n        subj.organizationalUnitName = '%s Root - %d' % (CertUtil.ca_vendor, int(time.time()))\n        subj.commonName = '%s XX-Net' % CertUtil.ca_vendor\n        ca.gmtime_adj_notBefore(- 3600 * 24)\n        ca.gmtime_adj_notAfter(CertUtil.ca_validity - 3600 * 24)\n        ca.set_issuer(subj)\n        ca.set_subject(subj)\n        ca.set_pubkey(key)\n        ca.add_extensions([\n            OpenSSL.crypto.X509Extension(\n                b'basicConstraints', False, b'CA:TRUE', subject=ca, issuer=ca)\n            ])\n        ca.sign(key, CertUtil.ca_digest)\n        #xlog.debug(\"CA key:%s\", key)\n        xlog.info(\"create CA\")\n        return key, ca\n\n    @staticmethod\n    def generate_ca_file():\n        xlog.info(\"generate CA file:%s\", CertUtil.ca_keyfile)\n        key, ca = CertUtil.create_ca()\n        with open(CertUtil.ca_certfile, 'wb') as fp:\n            fp.write(OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, ca))\n        with open(CertUtil.ca_keyfile, 'wb') as fp:\n            fp.write(OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, ca))\n            fp.write(OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, key))\n\n    @staticmethod\n    def generate_cert_keyfile():\n        xlog.info(\"generate certs's key file:%s\", CertUtil.cert_keyfile)\n        pkey = OpenSSL.crypto.PKey()\n        pkey.generate_key(OpenSSL.crypto.TYPE_RSA, 2048)\n        with open(CertUtil.cert_keyfile, 'wb') as fp:\n            fp.write(OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, pkey))\n            fp.write(OpenSSL.crypto.dump_publickey(OpenSSL.crypto.FILETYPE_PEM, pkey))\n        CertUtil.cert_publickey = pkey\n\n    @staticmethod\n    def _get_cert(commonname, isip=False, sans=None):\n        cert = OpenSSL.crypto.X509()\n        cert.set_version(2)\n        # setting the only serial number, the browser will refused fixed serial number when cert updated.\n        serial_number = int((int(time.time() - CertUtil.serial_reduce) + random.random()) * 100)\n        while 1:\n            try:\n                cert.set_serial_number(serial_number)\n            except OpenSSL.SSL.Error:\n                serial_number += 1\n            else:\n                break\n        subj = cert.get_subject()\n        subj.countryName = 'CN'\n        subj.stateOrProvinceName = 'Internet'\n        subj.localityName = 'Cernet'\n        subj.organizationalUnitName = '%s Branch' % CertUtil.ca_vendor\n        subj.commonName = commonname\n        subj.organizationName = commonname\n        cert.gmtime_adj_notBefore(-600) #avoid crt time error warning\n        cert.gmtime_adj_notAfter(CertUtil.cert_validity)\n        cert.set_issuer(CertUtil.ca_subject)\n        if CertUtil.cert_publickey:\n            pkey = CertUtil.cert_publickey\n        else:\n            pkey = OpenSSL.crypto.PKey()\n            pkey.generate_key(OpenSSL.crypto.TYPE_RSA, 2048)\n        cert.set_pubkey(pkey)\n\n        sans = set(sans) if sans else set()\n        sans.add(commonname)\n        if isip:\n            sans = b'IP: ' + commonname\n        else:\n            sans = b'DNS: %s, DNS: *.%s' % (commonname,  commonname)\n        cert.add_extensions([OpenSSL.crypto.X509Extension(b'subjectAltName', True, sans)])\n\n        cert.sign(CertUtil.ca_privatekey, CertUtil.ca_digest)\n\n        certfile = os.path.join(CertUtil.ca_certdir, utils.to_str(commonname) + '.crt')\n        with open(certfile, 'wb') as fp:\n            fp.write(OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, cert))\n            if CertUtil.cert_publickey is None:\n                fp.write(OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, pkey))\n        return certfile\n\n    @staticmethod\n    def _get_old_cert(commonname):\n        certfile = os.path.join(CertUtil.ca_certdir, utils.to_str(commonname) + '.crt')\n        if os.path.exists(certfile):\n            with open(certfile, 'rb') as fp:\n                cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, fp.read())\n            if datetime.datetime.strptime(utils.to_str(cert.get_notAfter()), '%Y%m%d%H%M%SZ') < datetime.datetime.utcnow() + datetime.timedelta(days=30):\n                try:\n                    os.remove(certfile)\n                except OSError as e:\n                    xlog.warning('CertUtil._get_old_cert failed: unable to remove outdated cert, %r', e)\n                else:\n                    return\n                # well, have to use the old one\n            return certfile\n\n    @staticmethod\n    def get_cert(commonname, sans=None, full_name=False):\n        commonname = utils.to_bytes(commonname)\n        isip =  check_ip_valid(commonname)\n        with CertUtil.ca_lock:\n            certfile = CertUtil._get_old_cert(commonname)\n            if certfile:\n                return certfile\n\n            # some site need full name cert\n            # like https://about.twitter.com in Google Chrome\n            if not isip and not full_name and commonname.count(b'.') >= 2 and [len(x) for x in reversed(commonname.split(b'.'))] > [2, 4]:\n                commonname = commonname.partition(b'.')[-1]\n                certfile = CertUtil._get_old_cert(commonname)\n                if certfile:\n                    return certfile\n\n            return CertUtil._get_cert(commonname, isip, sans)\n\n    @staticmethod\n    def win32_notify( msg=\"msg\", title=\"Title\"):\n        import ctypes\n        res = ctypes.windll.user32.MessageBoxW(None, msg, title, 1)\n        # Yes:1 No:2\n        return res\n\n    @staticmethod\n    def import_windows_ca(certfile):\n        xlog.debug(\"Begin to import Windows CA\")\n        with open(certfile, 'rb') as fp:\n            certdata = fp.read()\n            if certdata.startswith(b'-----'):\n                begin = b'-----BEGIN CERTIFICATE-----'\n                end = b'-----END CERTIFICATE-----'\n                certdata = base64.b64decode(b''.join(certdata[certdata.find(begin)+len(begin):certdata.find(end)].strip().splitlines()))\n        try:\n            common_name = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_ASN1, certdata).get_subject().CN\n        except Exception as e:\n            #logging.error('load_certificate(certfile=%r) 失败：%s', certfile, e)\n            return -1\n\n        assert certdata, 'cert file %r is broken' % certfile\n        import ctypes.wintypes\n        class CERT_CONTEXT(ctypes.Structure):\n            _fields_ = [\n                ('dwCertEncodingType', ctypes.wintypes.DWORD),\n                ('pbCertEncoded', ctypes.POINTER(ctypes.wintypes.BYTE)),\n                ('cbCertEncoded', ctypes.wintypes.DWORD),\n                ('pCertInfo', ctypes.c_void_p),\n                ('hCertStore', ctypes.c_void_p),]\n        X509_ASN_ENCODING = 0x1\n        CERT_STORE_ADD_ALWAYS = 4\n        CERT_STORE_PROV_SYSTEM = 10\n        CERT_STORE_OPEN_EXISTING_FLAG = 0x4000\n        CERT_SYSTEM_STORE_CURRENT_USER = 1 << 16\n        CERT_SYSTEM_STORE_LOCAL_MACHINE = 2 << 16\n        CERT_FIND_SUBJECT_STR = 8 << 16 | 7\n        crypt32 = ctypes.windll.crypt32\n        ca_exists = False\n        store_handle = None\n        pCertCtx = None\n        ret = 0\n        for store in (CERT_SYSTEM_STORE_LOCAL_MACHINE, CERT_SYSTEM_STORE_CURRENT_USER):\n            try:\n                store_handle = crypt32.CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, None, CERT_STORE_OPEN_EXISTING_FLAG | store, 'root')\n                if not store_handle:\n                    if store == CERT_SYSTEM_STORE_CURRENT_USER and not ca_exists:\n                        xlog.warning('CertUtil.import_windows_ca failed: could not open system cert store')\n                        return False\n                    else:\n                        continue\n\n                pCertCtx = crypt32.CertFindCertificateInStore(store_handle, X509_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR, common_name, None)\n                while pCertCtx:\n                    certCtx = CERT_CONTEXT.from_address(pCertCtx)\n                    _certdata = ctypes.string_at(certCtx.pbCertEncoded, certCtx.cbCertEncoded)\n                    if _certdata == certdata:\n                        ca_exists = True\n                        xlog.debug(\"XX-Net CA already exists\")\n                    else:\n                        cert =  OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_ASN1, _certdata)\n                        if hasattr(cert, 'get_subject'):\n                             cert = cert.get_subject()\n                        cert_name = next((v for k, v in cert.get_components() if k == 'CN'), '')\n                        if cert_name == common_name:\n                            ret = crypt32.CertDeleteCertificateFromStore(crypt32.CertDuplicateCertificateContext(pCertCtx))\n                            if ret == 1:\n                                xlog.debug(\"Invalid Windows CA %r has been removed\", common_name)\n                            elif ret == 0 and store == CERT_SYSTEM_STORE_LOCAL_MACHINE:\n                                # to elevate\n                                break\n                    pCertCtx = crypt32.CertFindCertificateInStore(store_handle, X509_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR, common_name, pCertCtx)\n\n                # Only add to current user\n                if store == CERT_SYSTEM_STORE_CURRENT_USER and not ca_exists:\n                    ret = crypt32.CertAddEncodedCertificateToStore(store_handle, X509_ASN_ENCODING, certdata, len(certdata), CERT_STORE_ADD_ALWAYS, None)\n            except Exception as e:\n                xlog.warning('CertUtil.import_windows_ca failed: %r', e)\n                if isinstance(e, OSError):\n                    store_handle = None\n                    continue\n                return False\n            finally:\n                if pCertCtx:\n                    crypt32.CertFreeCertificateContext(pCertCtx)\n                    pCertCtx = None\n                if store_handle:\n                    crypt32.CertCloseStore(store_handle, 0)\n                    store_handle = None\n\n        if ca_exists:\n            return True\n\n        if ret == 0 and __name__ != \"__main__\":\n            #res = CertUtil.win32_notify(msg=u'Import GoAgent Ca?', title=u'Authority need')\n            #if res == 2:\n            #    return -1\n\n            import win32elevate\n            try:\n                win32elevate.elevateAdminRun(os.path.abspath(__file__))\n            except Exception as e:\n                xlog.warning('CertUtil.import_windows_ca failed: %r', e)\n            return True\n        elif ret == 1:\n            CertUtil.win32_notify(msg='已经导入GoAgent证书，请重启浏览器.', title='Restart browser need.')\n\n        return ret == 1\n\n    @staticmethod\n    def get_linux_firefox_path():\n        home_path = os.path.expanduser(\"~\")\n        firefox_path = os.path.join(home_path, \".mozilla/firefox\")\n        if not os.path.isdir(firefox_path):\n            return\n\n        for filename in os.listdir(firefox_path):\n            if filename.endswith(\".default\") and os.path.isdir(os.path.join(firefox_path, filename)):\n                config_path = os.path.join(firefox_path, filename)\n                #xlog.debug(\"Got Firefox path: %s\", config_path)\n                return config_path\n\n    @staticmethod\n    def import_linux_firefox_ca(common_name, ca_file):\n        xlog.debug(\"Begin importing CA to Firefox\")\n        firefox_config_path = CertUtil.get_linux_firefox_path()\n        if not firefox_config_path:\n            #xlog.debug(\"Not found Firefox path\")\n            return False\n\n        if not any(os.path.isfile('%s/certutil' % x) for x in os.environ['PATH'].split(os.pathsep)):\n            xlog.warn('please install *libnss3-tools* package to import GoAgent root ca')\n            return False\n\n        xlog.info(\"Removing old cert to Firefox in %s\", firefox_config_path)\n        cmd_line = 'certutil -L -d %s |grep \"GoAgent\" &&certutil -d %s -D -n \"%s\" ' % (firefox_config_path, firefox_config_path, common_name)\n        os.system(cmd_line) # remove old cert first\n\n        xlog.info(\"Add new cert to Firefox in %s\", firefox_config_path)\n        cmd_line = 'certutil -d %s -A -t \"C,,\" -n \"%s\" -i \"%s\"' % (firefox_config_path, common_name, ca_file)\n        os.system(cmd_line) # install new cert\n        return True\n\n    @staticmethod\n    def import_linux_ca(common_name, ca_file):\n\n        def get_linux_ca_sha1(nss_path):\n            commonname = \"GoAgent XX-Net - GoAgent\" #TODO: here should be GoAgent - XX-Net\n\n            cmd = ['certutil', '-L','-d', 'sql:%s' % nss_path, '-n', commonname]\n            lines = get_cmd_out(cmd)\n\n            get_sha1_title = False\n            sha1 = b\"\"\n            for line in lines:\n                if line.endswith(b\"Fingerprint (SHA1):\\n\"):\n                    get_sha1_title = True\n                    continue\n                if get_sha1_title:\n                    sha1 = line\n                    break\n\n            sha1 = sha1.replace(b' ', b'').replace(b':', b'').replace(b'\\n', b'')\n            if len(sha1) != 40:\n                return False\n            else:\n                return sha1\n\n        home_path = os.path.expanduser(\"~\")\n        nss_path = os.path.join(home_path, \".pki/nssdb\")\n        if not os.path.isdir(nss_path):\n            return False\n\n        if not any(os.path.isfile('%s/certutil' % x) for x in os.environ['PATH'].split(os.pathsep)):\n            xlog.info('please install *libnss3-tools* package to import GoAgent root ca')\n            return False\n\n        sha1 = get_linux_ca_sha1(nss_path)\n        ca_hash = CertUtil.ca_thumbprint.replace(b':', b'')\n        if sha1 == ca_hash:\n            xlog.info(\"Database $HOME/.pki/nssdb cert exist\")\n            return\n\n        # shell command to list all cert\n        # certutil -L -d sql:$HOME/.pki/nssdb\n\n        # remove old cert first\n        xlog.info(\"Removing old cert in database $HOME/.pki/nssdb\")\n        cmd_line = 'certutil -L -d sql:$HOME/.pki/nssdb |grep \"GoAgent\" && certutil -d sql:$HOME/.pki/nssdb -D -n \"%s\" ' % ( common_name)\n        os.system(cmd_line)\n\n        # install new cert\n        xlog.info(\"Add cert to database $HOME/.pki/nssdb\")\n        cmd_line = 'certutil -d sql:$HOME/.pki/nssdb -A -t \"C,,\" -n \"%s\" -i \"%s\"' % (common_name, ca_file)\n        os.system(cmd_line)\n        return True\n\n    @staticmethod\n    def import_ubuntu_system_ca(common_name, certfile):\n        import platform\n        platform_distname = platform.dist()[0]\n        if platform_distname != 'Ubuntu':\n            return\n\n        pemfile = \"/etc/ssl/certs/CA.pem\"\n        new_certfile = \"/usr/local/share/ca-certificates/CA.crt\"\n        if not os.path.exists(pemfile) or not CertUtil.file_is_same(certfile, new_certfile):\n            if os.system('cp \"%s\" \"%s\" && update-ca-certificates' % (certfile, new_certfile)) != 0:\n                xlog.warning('install root certificate failed, Please run as administrator/root/sudo')\n\n    @staticmethod\n    def file_is_same(file1, file2):\n        BLOCKSIZE = 65536\n\n        try:\n            with open(file1, 'rb') as f1:\n                buf1 = f1.read(BLOCKSIZE)\n        except:\n            return False\n\n        try:\n            with open(file2, 'rb') as f2:\n                buf2 = f2.read(BLOCKSIZE)\n        except:\n            return False\n\n        if buf1 != buf2:\n            return False\n        else:\n            return True\n\n    @staticmethod\n    def import_mac_ca(common_name, certfile):\n        commonname = \"GoAgent XX-Net\" #TODO: need check again\n        ca_hash = CertUtil.ca_thumbprint.replace(b':', b'')\n\n        def get_exist_ca_sha1():\n            args = ['security', 'find-certificate', '-Z', '-a', '-c', commonname]\n            output = subprocess.check_output(args)\n            for line in output.splitlines(True):\n                if len(line) == 53 and line.startswith(b\"SHA-1 hash:\"):\n                    sha1_hash = line[12:52]\n                    return sha1_hash\n\n        exist_ca_sha1 = get_exist_ca_sha1()\n        if exist_ca_sha1 == ca_hash:\n            xlog.info(\"GoAgent CA exist\")\n            return\n\n        import_command = 'security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ../../../../data/gae_proxy/CA.crt'# % certfile.decode('utf-8')\n        if exist_ca_sha1:\n            delete_ca_command = 'security delete-certificate -Z %s' % exist_ca_sha1\n            exec_command = \"%s;%s\" % (delete_ca_command, import_command)\n        else:\n            exec_command = import_command\n\n        admin_command = \"\"\"osascript -e 'do shell script \"%s\" with administrator privileges' \"\"\" % exec_command\n        cmd = admin_command.encode('utf-8')\n        xlog.info(\"try auto import CA command:%s\", cmd)\n        os.system(cmd)\n\n    @staticmethod\n    def import_ca(certfile):\n        xlog.debug(\"Importing CA\")\n        commonname = \"GoAgent XX-Net - GoAgent\" #TODO: here should be GoAgent - XX-Net\n        if sys.platform.startswith('win'):\n            CertUtil.import_windows_ca(certfile)\n        elif sys.platform == 'darwin':\n            CertUtil.import_mac_ca(commonname, certfile)\n        elif sys.platform.startswith('linux'):\n            CertUtil.import_linux_ca(commonname, certfile)\n            CertUtil.import_linux_firefox_ca(commonname, certfile)\n            #CertUtil.import_ubuntu_system_ca(commonname, certfile) # we don't need install CA to system root, special user is enough\n\n    @staticmethod\n    def verify_certificate(ca, cert):\n        if hasattr(OpenSSL.crypto, \"X509StoreContext\"):\n            store = OpenSSL.crypto.X509Store()\n            store.add_cert(ca)\n            try:\n                OpenSSL.crypto.X509StoreContext(store, cert).verify_certificate()\n            except:\n                return False\n            else:\n                return True\n        else:\n            # A fake verify, just check generated time.\n            return ca.get_subject().OU == cert.get_issuer().OU\n\n\n    @staticmethod\n    def init_ca(no_mess_system=0):\n        import OpenSSL\n        #xlog.debug(\"Initializing CA\")\n\n        #Check Certs Dir\n        if not os.path.exists(CertUtil.ca_certdir):\n            os.makedirs(CertUtil.ca_certdir)\n\n        # Confirmed GoAgent CA exist\n        if not os.path.exists(CertUtil.ca_keyfile):\n            if os.path.exists(CertUtil.ca_certfile):\n                # update old unsafe CA file\n                xlog.info(\"update CA file storage format\")\n                if hasattr(OpenSSL.crypto, \"X509StoreContext\"):\n                    os.rename(CertUtil.ca_certfile, CertUtil.ca_keyfile)\n                else:\n                    xlog.warning(\"users may need to re-import CA file\")\n                    CertUtil.generate_ca_file()\n            else:\n                xlog.info(\"no GAE CA file exist in XX-Net data dir\")\n\n                xlog.info(\"clean old site certs in XX-Net cert dir\")\n                any(os.remove(x) for x in glob.glob(os.path.join(CertUtil.ca_certdir, '*.crt')) + glob.glob(os.path.join(CertUtil.ca_certdir, '.*.crt')))\n\n                CertUtil.generate_ca_file()\n\n        # Load GoAgent CA\n        with open(CertUtil.ca_keyfile, 'rb') as fp:\n            content = fp.read()\n        ca = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, content)\n        CertUtil.ca_privatekey = OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM, content)\n        CertUtil.ca_thumbprint = ca.digest('sha1')\n        CertUtil.ca_subject = ca.get_subject()\n        ca_cert_error = True\n        if os.path.exists(CertUtil.ca_certfile):\n            with open(CertUtil.ca_certfile, 'rb') as fp:\n                ca_cert_error = fp.read() not in content\n        if ca_cert_error:\n            with open(CertUtil.ca_certfile, 'wb') as fp:\n                fp.write(OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, ca))\n\n        # Check cert keyfile exists\n        if hasattr(OpenSSL.crypto, \"load_publickey\"):\n            if os.path.exists(CertUtil.cert_keyfile):\n                with open(CertUtil.cert_keyfile, 'rb') as fp:\n                    CertUtil.cert_publickey = OpenSSL.crypto.load_publickey(OpenSSL.crypto.FILETYPE_PEM, fp.read())\n            else:\n                CertUtil.generate_cert_keyfile()\n        else:\n            CertUtil.cert_keyfile = None\n\n        # Check exist site cert buffer with CA\n        certfiles = glob.glob(os.path.join(CertUtil.ca_certdir, '*.crt')) + glob.glob(os.path.join(CertUtil.ca_certdir, '.*.crt'))\n        if certfiles:\n            filename = random.choice(certfiles)\n            with open(filename, 'rb') as fp:\n                cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, fp.read())\n            remove_certs = False\n            if not CertUtil.verify_certificate(ca, cert):\n                remove_certs = True\n            if not remove_certs and CertUtil.cert_publickey:\n                context = OpenSSL.SSL.Context(OpenSSL.SSL.TLSv1_METHOD)\n                try:\n                    context.use_certificate(cert)\n                    context.use_privatekey_file(CertUtil.cert_keyfile)\n                except OpenSSL.SSL.Error:\n                    remove_certs = True\n            if remove_certs:\n                xlog.info(\"clean old site certs in XX-Net cert dir\")\n                any(os.remove(x) for x in certfiles)\n\n        if not no_mess_system:\n            CertUtil.import_ca(CertUtil.ca_keyfile)\n\n        # change the status,\n        # web_control /cert_import_status will return True, else return False\n        # launcher will wait ready to open browser and check update\n        # config.cert_import_ready = True\n\n\nif __name__ == '__main__':\n    CertUtil.init_ca()\n\n\n#TODO:\n# CA commaon should be GoAgent, vander should be XX-Net\n# need change and test on all support platform: Windows/Mac/Ubuntu/Debian\n"
  },
  {
    "path": "code/default/gae_proxy/local/check_ip.py",
    "content": "#!/usr/bin/env python2\n# coding:utf-8\n\nimport sys\nimport os\nimport threading\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\ndefault_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))\n\nif __name__ == \"__main__\":\n    sys.path.append(default_path)\n\n    noarch_lib = os.path.abspath(os.path.join(default_path, 'lib', 'noarch'))\n    sys.path.append(noarch_lib)\n\n    if sys.platform == \"win32\":\n        win32_lib = os.path.abspath(os.path.join(default_path, 'lib', 'win32'))\n        sys.path.append(win32_lib)\n    elif sys.platform.startswith(\"linux\"):\n        linux_lib = os.path.abspath(os.path.join(default_path, 'lib', 'linux'))\n        sys.path.append(linux_lib)\n    elif sys.platform == \"darwin\":\n        darwin_lib = os.path.abspath(os.path.join(default_path, 'lib', 'darwin'))\n        sys.path.append(darwin_lib)\n        extra_lib = \"/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python\"\n        sys.path.append(extra_lib)\n\n\nimport env_info\n\nmodule_data_path = os.path.join(env_info.data_path, 'gae_proxy')\nimport xlog\nlogger = xlog.getLogger(\"gae_proxy\")\n\nfrom xx_six import ConnectionError, ConnectionResetError, BrokenPipeError\n\nfrom front_base.openssl_wrap import SSLContext\nfrom front_base.connect_creator import ConnectCreator\nimport front_base.check_ip\n\nfrom gae_proxy.local.config import config\nfrom gae_proxy.local.host_manager import HostManager\n\n\nclass CheckIp(front_base.check_ip.CheckIp):\n    def check_response(self, response):\n        server_type = response.headers.get(b'Server', b\"\")\n        if isinstance(server_type, list):\n            server_type = server_type[0]\n        self.logger.debug(\"status:%d\", response.status)\n        self.logger.debug(\"Server type:%s\", server_type)\n\n        if response.status not in self.config.check_ip_accept_status:\n            return False\n\n        if response.status in [503, 500]:\n            # out of quota\n            if b\"gws\" not in server_type and b\"Google Frontend\" not in server_type and b\"GFE\" not in server_type:\n                xlog.warn(\"%d but server type:%s\", response.status, server_type)\n                return False\n            else:\n                return True\n\n        try:\n            content = response.read()\n        except Exception as e:\n            if sys.version_info[0] == 3 and (\n                    isinstance(e, ConnectionError) or\n                    isinstance(e, ConnectionResetError) or\n                    isinstance(e, BrokenPipeError)\n            ):\n                return False\n\n            self.logger.warn(\"app check except:%r\", e)\n            return False\n\n        if self.config.check_ip_content not in content:\n            self.logger.warn(\"app check content:%s\", content)\n            return False\n\n        return True\n\n\nclass CheckAllIp(object):\n\n    def __init__(self):\n        ca_certs = os.path.join(current_path, \"cacert.pem\")\n        openssl_context = SSLContext(\n            logger, ca_certs=ca_certs,\n            cipher_suites=[b'ALL', b\"!RC4-SHA\", b\"!ECDHE-RSA-RC4-SHA\", b\"!ECDHE-RSA-AES128-GCM-SHA256\",\n                           b\"!AES128-GCM-SHA256\", b\"!ECDHE-RSA-AES128-SHA\", b\"!AES128-SHA\"]\n        )\n        host_manager = HostManager()\n        connect_creator = ConnectCreator(logger, config, openssl_context, host_manager,\n                                         debug=True)\n        self.check_ip = CheckIp(logger, config, connect_creator)\n\n        self.lock = threading.Lock()\n\n        self.in_fd = open(\"ipv6_list.txt\", \"r\")\n        self.out_fd = open(\n            os.path.join(module_data_path, \"ipv6_list.txt\"),\n            \"w\"\n        )\n\n    def get_ip(self):\n        with self.lock:\n            while True:\n                line = self.in_fd.readline()\n                if not line:\n                    raise Exception()\n\n                try:\n                    ip = line.split()[0]\n                    return ip\n                except:\n                    continue\n\n    def write_ip(self, ip, host, handshake):\n        with self.lock:\n            self.out_fd.write(\"%s %s gws %d 0 0\\n\" % (ip, host, handshake))\n            self.out_fd.flush()\n\n    def checker(self):\n        while True:\n            try:\n                ip = self.get_ip()\n            except Exception as e:\n                xlog.info(\"no ip left\")\n                return\n\n            try:\n                res = self.check_ip.check_ip(ip)\n            except Exception as e:\n                xlog.warn(\"check except:%r\", e)\n                continue\n\n            if not res or not res.ok:\n                xlog.debug(\"ip:%s fail\", ip)\n                continue\n\n            if res.h2:\n                self.write_ip(ip, res.domain, res.handshake_time)\n\n    def run(self):\n        for i in range(0, 100):\n            threading.Thread(target=self.checker, name=\"gae_ip_checker\").start()\n\n\ndef check_all():\n    check = CheckAllIp()\n    check.run()\n    exit(0)\n\n\nif __name__ == \"__main__\":\n    # check_all()\n\n    # case 1: only ip\n    # case 2: ip + domain\n    #    connect use domain\n\n    if len(sys.argv) > 1:\n        ip = sys.argv[1]\n    else:\n        ip = \"142.250.66.180\"\n\n    xlog.info((\"test ip:%s\" % ip))\n\n    if len(sys.argv) > 2:\n        top_domain = sys.argv[2]\n    else:\n        top_domain = None\n\n    if len(sys.argv) > 3:\n        wait_time = int(sys.argv[3])\n    else:\n        wait_time = 0\n\n    ca_certs = os.path.join(current_path, \"cacert.pem\")\n    openssl_context = SSLContext(\n        logger, ca_certs=ca_certs,\n        protocol=\"TLSv1_2\"\n        # cipher_suites=[b'ALL', b\"!RC4-SHA\", b\"!ECDHE-RSA-RC4-SHA\", b\"!ECDHE-RSA-AES128-GCM-SHA256\",\n        #               b\"!AES128-GCM-SHA256\", b\"!ECDHE-RSA-AES128-SHA\", b\"!AES128-SHA\"]\n    )\n    host_manager = HostManager(config, logger)\n    connect_creator = ConnectCreator(logger, config, openssl_context, host_manager,\n                                     debug=True)\n    check_ip = CheckIp(logger, config, connect_creator)\n\n    res = check_ip.check_ip(ip, host=top_domain, wait_time=wait_time)\n    if not res:\n        xlog.info(\"connect fail\")\n    elif res.ok:\n        xlog.info((\"success, domain:%s handshake:%d\" % (res.host, res.handshake_time)))\n    else:\n        xlog.info(\"not support\")\n"
  },
  {
    "path": "code/default/gae_proxy/local/check_local_network.py",
    "content": "import sys\nimport os\n\nimport time\nimport threading\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\n\nif __name__ == \"__main__\":\n    python_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))\n    root_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))\n\n    noarch_lib = os.path.abspath(os.path.join(python_path, 'lib', 'noarch'))\n    sys.path.append(noarch_lib)\n    sys.path.append(root_path)\n\n    if sys.platform == \"win32\":\n        win32_lib = os.path.abspath(os.path.join(python_path, 'lib', 'win32'))\n        sys.path.append(win32_lib)\n    elif sys.platform.startswith(\"linux\"):\n        linux_lib = os.path.abspath(os.path.join(python_path, 'lib', 'linux'))\n        sys.path.append(linux_lib)\n\nfrom gae_proxy.local.config import config\n\nimport utils\nimport simple_http_client\nfrom xlog import getLogger\n\nxlog = getLogger(\"gae_proxy\")\n\nmax_timeout = 5\n\n\nclass CheckNetwork(object):\n    check_valid = 30\n    timeout = 5\n\n    def __init__(self, type=\"IPv4\"):\n        self.type = type\n        self.urls = []\n        self._checking_lock = threading.Lock()\n        self._checking_num = 0\n        self.network_stat = \"unknown\"\n        self.last_check_time = 0\n        self.continue_fail_count = 0\n\n        if config.PROXY_ENABLE:\n            if config.PROXY_USER:\n                self.proxy = \"%s://%s:%s@%s:%d\" % \\\n                             (config.PROXY_TYPE, config.PROXY_USER, config.PROXY_PASSWD, config.PROXY_HOST,\n                              config.PROXY_PORT)\n            else:\n                self.proxy = \"%s://%s:%d\" % \\\n                             (config.PROXY_TYPE, config.PROXY_HOST, config.PROXY_PORT)\n        else:\n            self.proxy = None\n\n        self.http_client = simple_http_client.Client(self.proxy, timeout=self.timeout)\n\n    def report_ok(self):\n        self.network_stat = \"OK\"\n        self.last_check_time = time.time()\n        self.continue_fail_count = 0\n\n    def report_fail(self):\n        self.continue_fail_count += 1\n        # don't record last_check_time here, it's not a real check\n        # last_check_time = time.time()\n\n        if self.continue_fail_count > 1:\n            # don't set network_stat to \"unknown\", wait for check\n            # network_stat = \"unknown\"\n            xlog.debug(\"report_connect_fail %s continue_fail_count:%d\",\n                       self.type, self.continue_fail_count)\n\n            if time.time() - self.last_check_time > self.check_valid:\n                self.triger_check_network(True)\n\n    def get_stat(self):\n        if config.check_local_network_rules == \"force_fail\":\n            return \"Fail\"\n        elif config.check_local_network_rules == \"force_ok\":\n            return \"OK\"\n        else:\n            return self.network_stat\n\n    def is_ok(self):\n        if self.network_stat == \"unknown\" or time.time() - self.last_check_time > self.check_valid:\n            self.triger_check_network(True)\n\n        if config.check_local_network_rules == \"normal\":\n            if self.network_stat == \"OK\" and time.time() - self.last_check_time < self.check_valid + self.timeout:\n                return True\n            else:\n                return False\n        elif config.check_local_network_rules == \"force_fail\":\n            return False\n        elif config.check_local_network_rules == \"force_ok\":\n            return True\n        else:\n            return self.network_stat == \"OK\"\n\n    def _test_host(self, url):\n        try:\n            header = {\n                \"user-agent\": \"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36\",\n                \"accept\": \"application/json, text/javascript, */*; q=0.01\",\n                \"accept-encoding\": \"gzip, deflate, sdch\",\n                \"accept-language\": 'en-US,en;q=0.8,ja;q=0.6,zh-CN;q=0.4,zh;q=0.2',\n                \"connection\": \"keep-alive\"\n            }\n            response = self.http_client.request(\"HEAD\", url, header, \"\", read_payload=False)\n            if response:\n                return True\n        except Exception as e:\n            if __name__ == \"__main__\":\n                xlog.exception(\"test %s e:%r\", url, e)\n\n        return False\n\n    def _simple_check_worker(self):\n        time_now = time.time()\n\n        self._checking_lock.acquire()\n        self._checking_num += 1\n        self._checking_lock.release()\n\n        network_ok = False\n        for url in self.urls:\n            if self._test_host(url):\n                network_ok = True\n                break\n            else:\n                if __name__ == \"__main__\":\n                    xlog.warn(\"test %s fail\", url)\n                time.sleep(1)\n\n        if network_ok:\n            self.last_check_time = time.time()\n            self.report_ok()\n            xlog.debug(\"network %s is ok, cost:%d ms\", self.type, 1000 * (time.time() - time_now))\n        else:\n            xlog.warn(\"network %s fail\", self.type)\n            self.network_stat = \"Fail\"\n            self.last_check_time = time.time()\n\n        self._checking_lock.acquire()\n        self._checking_num -= 1\n        self._checking_lock.release()\n\n    def triger_check_network(self, fail=False, force=False):\n        time_now = time.time()\n        if not force:\n            if self._checking_num > 0:\n                return\n\n            if fail or self.network_stat != \"OK\":\n                # Fail or unknown\n                if time_now - self.last_check_time < 3:\n                    return\n            else:\n                if time_now - self.last_check_time < 10:\n                    return\n\n        self.last_check_time = time_now\n        threading.Thread(target=self._simple_check_worker, name=\"network_checker\").start()\n\n\nIPv4 = CheckNetwork(\"IPv4\")\nIPv4.urls = [\n    \"https://www.bing.com\",\n    \"https://code.jquery.com\",\n    \"https://cdn.bootcss.com\",\n    \"https://upcdn.b0.upaiyun.com\",\n    \"https://cdn.bootcdn.net\",\n    \"https://cdn.staticfile.org\",\n]\n# IPv4.triger_check_network()\n\nIPv6 = CheckNetwork(\"IPv6\")\nIPv6.urls = [\n    \"https://ipv6.vm3.test-ipv6.com\",\n    \"https://ipv6.lookup.test-ipv6.com\",\n    \"https://v6.myip.la\",\n    \"https://speed.neu6.edu.cn/\"\n]\n# IPv6.triger_check_network()\n\n\ndef report_ok(ip):\n    if \".\" in ip:\n        IPv4.report_ok()\n    else:\n        IPv6.report_ok()\n\n\ndef report_fail(ip):\n    if \".\" in ip:\n        IPv4.report_fail()\n    else:\n        IPv6.report_fail()\n\n\ndef is_ok(ip=None):\n    ip = utils.to_str(ip)\n    if not ip:\n        return IPv4.is_ok() or IPv6.is_ok()\n    elif \".\" in ip:\n        return IPv4.is_ok()\n    else:\n        return IPv6.is_ok()\n\n\nif __name__ == \"__main__\":\n    # print(IPv6._test_host(\"http://[2804:10:4068::202:82]\"))\n    IPv4._test_host(\"https://www.baidu.com\")\n"
  },
  {
    "path": "code/default/gae_proxy/local/config.py",
    "content": "import os\n\nfrom front_base.config import ConfigBase\n\nimport utils\nimport env_info\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nroot_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))\n\nmodule_data_path = os.path.join(env_info.data_path, 'gae_proxy')\n\n\nheaders = {\"connection\": \"close\"}\n\n\nclass Config(ConfigBase):\n    def __init__(self, fn):\n        super(Config, self).__init__(fn)\n\n        # globa setting level\n        # passive < conservative < normal < radical < extreme\n        self.set_var(\"setting_level\", \"normal\")\n\n        # proxy\n        self.set_var(\"listen_ip\", \"127.0.0.1\")\n        self.set_var(\"listen_port\", 8087)\n\n        # auto range\n        self.set_var(\"AUTORANGE_THREADS\", 10)\n        self.set_var(\"AUTORANGE_MAXSIZE\", 512 * 1024)\n        # if mobile:\n        #     self.set_var(\"AUTORANGE_MAXBUFFERSIZE\", 10 * 1024 * 1024 / 8)\n        # else:\n        self.set_var(\"AUTORANGE_MAXBUFFERSIZE\", 20 * 1024 * 1024)\n        self.set_var(\"JS_MAXSIZE\", 0)\n\n        # gae\n        self.set_var(\"GAE_PASSWORD\", \"\")\n        self.set_var(\"GAE_VALIDATE\", 1)\n\n        # host rules\n        self.set_var(\"hosts_direct\", [\n            #b\"docs.google.com\",\n            #\"play.google.com\",\n            #b\"scholar.google.com\",\n            #\"scholar.google.com.hk\",\n            #b\"appengine.google.com\"\n        ])\n        self.set_var(\"hosts_direct_endswith\", [\n            #b\".gvt1.com\",\n            b\".appspot.com\"\n        ])\n\n        self.set_var(\"hosts_gae\", [\n            b\"accounts.google.com\",\n            b\"mail.google.com\"\n        ])\n\n        self.set_var(\"hosts_gae_endswith\", [\n            b\".googleapis.com\"\n        ])\n\n        # sites using br\n        self.set_var(\"BR_SITES\", [\n            b\"webcache.googleusercontent.com\",\n            b\"www.google.com\",\n            b\"www.google.com.hk\",\n            b\"www.google.com.cn\",\n            b\"fonts.googleapis.com\"\n        ])\n\n        self.set_var(\"BR_SITES_ENDSWITH\", [\n            b\".youtube.com\",\n            b\".facebook.com\",\n            b\".googlevideo.com\"\n        ])\n\n        # some unsupport request like url length > 2048, will go Direct\n        self.set_var(\"google_endswith\", [\n            b\".youtube.com\",\n            b\".googleapis.com\",\n            b\".google.com\",\n            b\".googleusercontent.com\",\n            b\".ytimg.com\",\n            b\".doubleclick.net\",\n            b\".google-analytics.com\",\n            b\".googlegroups.com\",\n            b\".googlesource.com\",\n            b\".gstatic.com\",\n            b\".appspot.com\",\n            b\".gvt1.com\",\n            b\".android.com\",\n            b\".ggpht.com\",\n            b\".googleadservices.com\",\n            b\".googlesyndication.com\",\n            b\".2mdn.net\"\n        ])\n\n        # front\n        self.set_var(\"front_continue_fail_num\", 10)\n        self.set_var(\"front_continue_fail_block\", 0)\n\n        # http_dispatcher\n        self.set_var(\"dispather_min_idle_workers\", 3)\n        self.set_var(\"dispather_work_min_idle_time\", 0)\n        self.set_var(\"dispather_work_max_score\", 1000)\n        self.set_var(\"dispather_min_workers\", 20)\n        self.set_var(\"dispather_max_workers\", 50)\n        self.set_var(\"dispather_max_idle_workers\", 15)\n\n        self.set_var(\"max_task_num\", 80)\n\n        # http 1 worker\n        self.set_var(\"http1_first_ping_wait\", 5)\n        self.set_var(\"http1_idle_time\", 200)\n        self.set_var(\"http1_ping_interval\", 0)\n\n        # http 2 worker\n        self.set_var(\"http2_max_concurrent\", 20)\n        self.set_var(\"http2_target_concurrent\", 1)\n        self.set_var(\"http2_max_timeout_tasks\", 1)\n        self.set_var(\"http2_timeout_active\", 0)\n        self.set_var(\"http2_ping_min_interval\", 0)\n\n        # connect_manager\n        self.set_var(\"https_max_connect_thread\", 10)\n        self.set_var(\"ssl_first_use_timeout\", 5)\n        self.set_var(\"connection_pool_min\", 1)\n        self.set_var(\"https_connection_pool_min\", 0)\n        self.set_var(\"https_connection_pool_max\", 10)\n        self.set_var(\"https_new_connect_num\", 3)\n        self.set_var(\"https_keep_alive\", 10)\n\n        # check_ip\n        self.set_var(\"check_ip_host\", \"xxnet-1.appspot.com\")\n        self.set_var(\"check_ip_accept_status\", [200, 500, 503])\n        self.set_var(\"check_ip_content\", b\"GoAgent\")\n\n        # host_manager\n        self.set_var(\"GAE_APPIDS\", [])\n\n        # connect_creator\n        self.set_var(\"check_pkp\", [\n# Expired CAs\n# GIAG2\n# GIAG3\n# GTSGIAG3\n# GIAG3ECC\n\n# GIAG4\n# https://pki.goog/repo/certs/giag4.pem\n# GIAG4x\n# https://pki.goog/repo/certs/giag4x.pem\nb'''\\\n-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvSw7AnhsoyYa5z/crKtt\nB52X+R0ld3UdQBU4Yc/4wmF66cpHeEOMSmhdaY5RzYrowZ6kG1xXLrSoVUuudUPR\nfg/zjRqv/AAVDJFqc8OnhghzaWZU9zlhtRgY4lx4Z6pDosTuR5imCcKvwqiDztOJ\nr4YKHuk23p3cxu1zDnUsuN+cm4TkVtI1SsuSc9t1uErBvFIcW6v3dLcjrPkmwE61\nudZQlBDHJzCFwrhXLtXLlmuSA5/9pOuWJ+U3rSgS7ICSfa83vkBe00ymjIZT6ogD\nXWuFsu4edue27nG8g9gO1YozIUCV7+zExG0G5kxTovis+FJpy9hIIxSFrRIKM4DX\naQIDAQAB\n-----END PUBLIC KEY-----\n''',\n# GIAG4 ECC\n# https://pki.goog/repo/certs/giag4ecc.pem\nb'''\\\n-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEWgDxDsTP7Od9rB8TPUltMacYCHYI\nNthcDjlPu3wP0Csmy6Drit3ghqaTqFecqcgks5RwcKQkT9rbY3e8lHuuAw==\n-----END PUBLIC KEY-----\n''',\n# GTS CA 1C3\n# https://pki.goog/repo/certs/gts1c3.pem\nb'''\\\n-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA9Yjf52KMHjf4N0KQf2yH\n0PtlgiX96MtrpP9t6Voj4pn2HOmSA5kTfAkKivpC1l5WJKp6M4Qf0elpu7l07FdM\nZmiTdzdVU/45EE23NLtfJXc3OxeU6jzlndW8w7RD6y6nR++wRBFj2LRBhd1BMEiT\nG7+39uBFAiHglkIXz9krZVY0ByYEDaj9fcou7+pIfDdNPwCfg9/vdYQueVdc/Fdu\nGpb//Iyappm+Jdl/liwG9xEqAoCA62MYPFBJh+WKyl8ZK1mWgQCg+1HbyncLC8mW\nT+9wScdcbSD9mbS04soud/0t3Au2axMMjBkrF5aYufCL9qAnu7bjjVGPva7Hm7GJ\nnQIDAQAB\n-----END PUBLIC KEY-----\n''',\n# GTS CA 1D2\n# https://pki.goog/repo/certs/gts1d2.pem\nb'''\\\n-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAstl74eHXPxyRcv/5EM2H\nFXl0tz5Hi7JhVf0MNsZ+d0I6svpSWwtxgdZN1ekrJE0jXosrcl8hVbUp70TL64JS\nqz4npJJJQUreqN0x4DzfbXpNLdZtCbAO42Hysv6QbFp7EGRJtAs8CPLqeQxsphqJ\nalYyoCmiMIKPgVEM86K52XW5Ip4nFLpKLyxjWIfxXRDmX5G7uVvMR+IedbaMj8x1\nXVcF54LGhA50cirLO1X1bnDrZmnDJLs4kzWbaGEvm9aupndyfHFIWDMQr+mAgh21\nB0Ab9j3soq1HnbSUKTSzjC/NJQNYNcAlpFVf4bMHVj3I0GO4IPuMHUMs+Pmp1exv\nlwIDAQAB\n-----END PUBLIC KEY-----\n''',\n# GTS CA 1D4\n# https://pki.goog/repo/certs/gts1d4.pem\nb'''\\\n-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq8Cqo8ITbuXTD3MLx1M8\ngTz1sD7FOYNobvLtV9Dhz6Y5aGVR5tRCkrTK/avrvxEkTErQdYON6r6csgc3USbm\nPqsBFmLGbJFKOEhHQo5A8YExSV2xrO0ggns7SD/zaqP+8YOX//e3i1OrGJGEtCdM\ntcl14H7YOGR1TogiDHrA3sTk1xQfdFyx6NyqPynlKPX28GbqLUWGosbKaEwWuhZV\nQY7fG0gf3V2yDLh4Upx8pUtYrejbX3RDQub9KIqYttEnkC7jLV64UmbYkz14HzgW\nSpreK+tdZR5W3J7QJB0q+xjYWRrO/G3G+6wsnMtZgeTnnNxEBpwMDZJ4S0FtB8PW\nqwIDAQAB\n-----END PUBLIC KEY-----\n''',\n# GTS CA 1O1\n# https://pki.goog/repo/certs/gts1o1.pem\nb'''\\\n-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0BjPRdSLzdOc5EDvfrTd\naSEbyc88jkx1uQ8xGYQ9njwp71ANEJNvBYCAnyqgvRJLAuE9n1gWJP4wnwt0d1WT\nHUv3TeGSghD2UawMw7IilA80a5gQSecLnYM53SDGHC3v0RhhZecjgyCoIxL/0iR/\n1C/nRGpbTddQZrCvnkJjBfvgHMRjYa+fajP/Ype9SNnTfBRn3HXcLmno+G14adC3\nEAW48THCOyT9GjN0+CPg7GsZihbG482kzQvbs6RZYDiIO60ducaMp1Mb/LzZpKu8\n3Txh15MVmO6BvY/iZEcgQAZO16yX6LnAWRKhSSUj5O1wNCyltGN8+aM9g9HNbSSs\nBwIDAQAB\n-----END PUBLIC KEY-----\n''',\n# GTS CA 1P5\n# https://pki.goog/repo/certs/gts1p5.pem\nb'''\\\n-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs4LwJIy/LYevstmnrvrK\nukTWWz7+sveyZRbc3hDoTy0QWFoohoeh7mqzoNl1T3+hUgGLVahKWwZIyDYSJauJ\n+fIjX51gZflc2r466FxtfZzQhBiFMM1Om+w82LPhltTzxQtl24+wdMv2HvN48ayV\nxd1zwzGIga90qm/9DOMFlfDFEE9lY/qgr8YYPcWh35d51wWJszCwdK49khBrjBV3\n3QsEV/uBA93qIjTV5Vay8MSNQbHDAtti7IDQ/3bUhuQEGra2DCticX3Zr9nxXvrA\nHsqgGVxV8IDRKgwHhpCfNeMoK1vvI8ijHaSjOu7+g9yCTCWwTcVRrZ6b01uEwhpa\n6QIDAQAB\n-----END PUBLIC KEY-----\n''',\n# GTS CA 2A1\n# https://pki.goog/repo/certs/gts2a1.pem\nb'''\\\n-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEAN+bsxmjxoOPZBA3MIh/CdD/J31/\n5vRh3MdletXO0zD+TrcD4wZPMrVdMsX4tiPtyzI/rYEiaaJFIBfAXqKIiA==\n-----END PUBLIC KEY-----\n''',\n# GTS Root R1 Cross\n# https://pki.goog/repo/certs/gtsr1x.pem\nb'''\\\n-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAthECix7joXebO9y/lD63\nladAPKH9gvl9MgaCcfb2jH/76Nu8ai6Xl6OMS/kr9rH5zoQdsfnFl97vufKj6bwS\niV6nqlKr+CMny6SxnGPb15l+8Ape62im9MZaRw1NEDPjTrETo8gYbEvs/AmQ351k\nKSUjB6G00j0uYODP0gmHu81I8E3CwnqIiru6z1kZ1q+PsAewnjHxgsHA3y6mbWwZ\nDrXYfiYaRQM9sHmklCitD38m5agI/pboPGiUU+6DOogrFZYJsuB6jC511pzrp1Zk\nj5ZPaK49l8KEj8C8QMALXL32h7M1bKwYUH+E4EzNktMg6TO8UpmvMrUpsyUqtEj5\ncuHKZPfmghCN6J3Cioj6OGaK/GP5Afl4/Xtcd/p2h/rs37EOeZVXtL0m79YB0esW\nCruOC7XFxYpVq9Os6pFLKcwZpDIlTirxZUTQAs6qzkm06p98g7BAe+dDq6dso499\niYH6TKX/1Y7DzkvgtdizjkXPdsDtQCv9Uw+wp9U7DbGKogPeMa3Md+pvez7W35Ei\nEua++tgy/BBjFFFy3l3WFpO9KWgz7zpm7AeKJt8T11dleCfeXkkUAKIAf5qoIbap\nsZWwpbkNFhHax2xIPEDgfg1azVY80ZcFuctL7TlLnMQ/0lUTbiSw1nH69MG6zO0b\n9f6BQdgAmD06yK56mDcYBZUCAwEAAQ==\n-----END PUBLIC KEY-----\n''',\n# GTS Y1\n# https://pki.goog/repo/certs/gtsy1.pem\nb'''\\\n-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv72WKaCDZTTnN6KC5yhi\naDZLawHdgu2zIhpeHogZBdpibue99PU8V26a17//FpbCHzCLBxq8IDnAcIGBtOkG\nJ+QfHcUow/iFccLDQrhN4YlHl4hhEAaejqXKBy3U+NN2De/rfdDB/QX+38MZnfrx\ncLudTgS8ItVbmA9kC/8wnGGrMbLvC7KhJk6aPspN8hXzmjfEHnz3Y9O64eu9QBou\n47trCZspr6bXqW/XZV/b/KiOlsprLR4pobkd4gOkrLSNMTsRcrTHh/4SCPYLR6QV\noIZ1K2cmLhJHuxYTOy7ziG0sQmvku/Sh+GeU2Pakm3wSPubxQFDofYs8AQ2dZYfw\nYQIDAQAB\n-----END PUBLIC KEY-----\n''',\n# GTS Y2\n# https://pki.goog/repo/certs/gtsy2.pem\nb'''\\\n-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqB9XbHMq4soQmRpOVF9C\nsnIPC2uZ3ITR0QRReBLhOY3sWwjeBctqqMcocN0zg+30c4+UVAcOdAxHjEpVakbr\ntcqfF71wrhau8o6sn+y8MrdYAtrGrYzns26KETX8NIzxJy/v31wJOQnW/WZEizes\n4JfO/1Mo3qWAiaoctsiHmL5PG8xQkdOhPNdHu6KcgO0IsJ9BCCufd9TpJMb0EnO1\nWK3WZLQdgmVny5FkEqp0Fz5TgQKekHyajnbujf1T09AGzTQgO0Btz15WL9pkMADM\nWKwYtbEurJaHrAgejMHWC7KjaqH3XlVmFMJs3rDDIQxyTRLBPqRLaiUkzxvBBnmr\nlwIDAQAB\n-----END PUBLIC KEY-----\n''',\n# GTS Y3\n# https://pki.goog/repo/certs/gtsy3.pem\nb'''\\\n-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8rfkbjTwx1dixmkxk3b8dhsNCYRC\nnpKv6jT9gnu5BtJlK3kG/l57HRM9E1/GwErnpBxDBnkLeee+Qb3VxGWHsw==\n-----END PUBLIC KEY-----\n''',\n# GTS Y4\n# https://pki.goog/repo/certs/gtsy4.pem\nb'''\\\n-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEqPJbOoggUvyliF5Us9hq047KDrKP\n9uViYwR13jjZCM4rgkOdciVuN0w8zuxzFnQWaY0r085HwQKAr8rGsbJYdg==\n-----END PUBLIC KEY-----\n''',\n# Google CA1\n# https://pki.goog/repo/certs/tp_googleca1.pem\nb'''\\\n-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAupYx7NU9sbeWxSISCARB\nGUNj/YKmUpoFxnM+cFwU98Qm3TWk+QkkbgWN7ScBqBHKHqwHt6OZvkhCEbV3D7C2\niDknM8riJdR45f9mDzHUiO12AHyxqao54PrSGvIukBCxU0BO8UV8zg/ZDFUoRPL6\n4Pk9xWld9Thzlwts6Bi6CkjZ6HM5EiFiiIcOSvx8tGIHc0/ncBBjsop/ceRK6415\nReXKpyFHEEqH42P64XrGdDYSVli0jZhUDQoHCCjZxIpAagLYM5pryVvdWBGTvH4n\n0j0uzPIM8riC+XYyHKnpW/JgargXADBQvIRwRNwEuvfvTVa4JIlPhCYwMo4qLzhx\nvQIDAQAB\n-----END PUBLIC KEY-----\n''',\n# GTS CA 1D3\n# https://pki.goog/repo/certs/tp_gtsca1d3.pem\nb'''\\\n-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsUX4++gDvlpQYGaFi9Jm\nomOPfqAsDVJBCLMQa8Ox2vBPsdd7ZqzqiVJquTRnSWNnOJBSuzf+RDZuEZz9eS5k\nZ19DcwrRU/aIKEhPBcnui7Z//JZpHBF6ai89CXpChanZXbX6I9ylVomPI9+uuTb6\n3RUAy6++1I/FdU/G/YTVNbJHsHXyBSHm7C537EPXowAH5zQZ8t18IoLuPVBrQpDV\nKvBVMdT9Wc21fvPvrkEY+Il/6Z8NXL/kUmAMxsSsulpUBwEUKe+1haRtGMsM6DZh\nN3Tphr+AwTioLnSvaNDyqo+zfpJeXsoiwFLH+Y6YsP6R5IjVBzUoimFgeWeTSbYP\nYQIDAQAB\n-----END PUBLIC KEY-----\n'''\n        ])\n        #self.set_var(\"check_commonname\", \"Google\")\n        self.set_var(\"min_intermediate_CA\", 2)\n        self.set_var(\"support_http2\", 1)\n\n        # ip_manager\n        self.set_var(\"max_scan_ip_thread_num\", 10)\n        self.set_var(\"max_good_ip_num\", 100)\n        self.set_var(\"target_handshake_time\", 600)\n\n        # ip source\n        self.set_var(\"use_ipv6\", \"auto\") #force_ipv4/force_ipv6/auto\n        self.set_var(\"ipv6_scan_ratio\", 90) # 0 - 100\n\n        # Check local network\n        self.set_var(\"check_local_network_rules\", \"normal\")  # normal, force_ok, force_fail\n\n        self.load()\n\n    def load(self):\n        super(Config, self).load()\n\n        need_save = 0\n        if not os.path.isfile(self.config_path):\n            for fn in [\n                os.path.join(module_data_path, \"config.ini\"),\n                os.path.join(module_data_path, \"manual.ini\")\n            ]:\n                need_save += self.load_old_config(fn)\n\n        self.HOSTS_GAE = tuple(utils.to_bytes(self.hosts_gae))\n        self.HOSTS_DIRECT = tuple(utils.to_bytes(self.hosts_direct))\n        self.HOSTS_GAE_ENDSWITH = tuple(utils.to_bytes(self.hosts_gae_endswith))\n        self.HOSTS_DIRECT_ENDSWITH = tuple(utils.to_bytes(self.hosts_direct_endswith))\n        self.GOOGLE_ENDSWITH = tuple(utils.to_bytes(self.google_endswith))\n\n        self.br_sites = tuple(utils.to_bytes(self.BR_SITES))\n        self.br_endswith = tuple(utils.to_bytes(self.BR_SITES_ENDSWITH))\n\n        # there are only hundreds of GAE IPs, we don't need a large threads num\n        self.max_scan_ip_thread_num = min(self.max_scan_ip_thread_num, 200)\n\n        if need_save:\n            self.save()\n\n    def load_old_config(self, fn):\n        if not os.path.isfile(fn):\n            return 0\n\n        need_save = 0\n        with open(fn, \"r\") as fd:\n            for line in fd.readlines():\n                if line.startswith(\"appid\"):\n                    try:\n                        appid_str = line.split(\"=\")[1]\n                        appids = []\n                        for appid in appid_str.split(\"|\"):\n                            appid = appid.strip()\n                            appids.append(appid)\n                        self.GAE_APPIDS = appids\n                        need_save += 1\n                    except Exception as e:\n                        pass\n                elif line.startswith(\"password\"):\n                    password = line.split(\"=\")[1].strip()\n                    self.GAE_PASSWORD = password\n                    need_save += 1\n\n        return need_save\n\n    def set_level(self, level=None):\n        if level is None:\n            level = self.setting_level\n        elif level in [\"passive\", \"conservative\", \"normal\", \"radical\", \"extreme\"]:\n            self.setting_level = level\n\n            if level == \"passive\":\n                self.dispather_min_idle_workers = 0\n                self.dispather_work_min_idle_time = 0\n                self.dispather_work_max_score = 1000\n                self.dispather_min_workers = 5\n                self.dispather_max_workers = 30\n                self.dispather_max_idle_workers = 5\n                self.max_task_num = 50\n                self.https_max_connect_thread = 10\n                self.https_keep_alive = 5\n                self.https_connection_pool_min = 0\n                self.https_connection_pool_max = 10\n                self.max_scan_ip_thread_num = 10\n                self.max_good_ip_num = 60\n                self.target_handshake_time = 600\n            elif level == \"conservative\":\n                self.dispather_min_idle_workers = 1\n                self.dispather_work_min_idle_time = 0\n                self.dispather_work_max_score = 1000\n                self.dispather_min_workers = 10\n                self.dispather_max_workers = 30\n                self.dispather_max_idle_workers = 10\n                self.max_task_num = 50\n                self.https_max_connect_thread = 10\n                self.https_keep_alive = 15\n                self.https_connection_pool_min = 0\n                self.https_connection_pool_max = 10\n                self.max_scan_ip_thread_num = 10\n                self.max_good_ip_num = 100\n                self.target_handshake_time = 600\n            elif level == \"normal\":\n                self.dispather_min_idle_workers = 3\n                self.dispather_work_min_idle_time = 0\n                self.dispather_work_max_score = 1000\n                self.dispather_min_workers = 20\n                self.dispather_max_workers = 50\n                self.dispather_max_idle_workers = 15\n                self.max_task_num = 80\n                self.https_max_connect_thread = 10\n                self.https_keep_alive = 15\n                self.https_connection_pool_min = 0\n                self.https_connection_pool_max = 10\n                self.max_scan_ip_thread_num = 10\n                self.max_good_ip_num = 100\n                self.target_handshake_time = 600\n            elif level == \"radical\":\n                self.dispather_min_idle_workers = 3\n                self.dispather_work_min_idle_time = 1\n                self.dispather_work_max_score = 1000\n                self.dispather_min_workers = 30\n                self.dispather_max_workers = 70\n                self.dispather_max_idle_workers = 25\n                self.max_task_num = 100\n                self.https_max_connect_thread = 15\n                self.https_keep_alive = 15\n                self.https_connection_pool_min = 1\n                self.https_connection_pool_max = 15\n                self.max_scan_ip_thread_num = 20\n                self.max_good_ip_num = 100\n                self.target_handshake_time = 1200\n            elif level == \"extreme\":\n                self.dispather_min_idle_workers = 5\n                self.dispather_work_min_idle_time = 5\n                self.dispather_work_max_score = 1000\n                self.dispather_min_workers = 45\n                self.dispather_max_workers = 100\n                self.dispather_max_idle_workers = 40\n                self.max_task_num = 130\n                self.https_max_connect_thread = 20\n                self.https_keep_alive = 15\n                self.https_connection_pool_min = 2\n                self.https_connection_pool_max = 20\n                self.max_scan_ip_thread_num = 30\n                self.max_good_ip_num = 200\n                self.target_handshake_time = 1500\n\n            self.save()\n            self.load()\n\n\nclass DirectConfig(object):\n    def __init__(self, config):\n        self._config = config\n        self.set_default()\n\n    def __getattr__(self, attr):\n        return getattr(self._config, attr)\n\n    def dummy(*args, **kwargs):\n        pass\n\n    set_var = save = load = dummy\n\n    def set_level(self, level=None):\n        if level is None:\n            level = self.setting_level\n\n        if level == \"passive\":\n            self.dispather_min_idle_workers = 0\n            self.dispather_work_min_idle_time = 0\n            self.dispather_work_max_score = 1000\n            self.dispather_min_workers = 0\n            self.dispather_max_workers = 8\n            self.dispather_max_idle_workers = 0\n            self.max_task_num = 16\n            self.https_max_connect_thread = 4\n            self.https_connection_pool_min = 0\n            self.https_connection_pool_max = 6\n        elif level == \"conservative\":\n            self.dispather_min_idle_workers = 1\n            self.dispather_work_min_idle_time = 0\n            self.dispather_work_max_score = 1000\n            self.dispather_min_workers = 1\n            self.dispather_max_workers = 8\n            self.dispather_max_idle_workers = 2\n            self.max_task_num = 16\n            self.https_max_connect_thread = 5\n            self.https_connection_pool_min = 0\n            self.https_connection_pool_max = 8\n        elif level == \"normal\":\n            self.dispather_min_idle_workers = 2\n            self.dispather_work_min_idle_time = 0\n            self.dispather_work_max_score = 1000\n            self.dispather_min_workers = 3\n            self.dispather_max_workers = 8\n            self.dispather_max_idle_workers = 3\n            self.max_task_num = 16\n            self.https_max_connect_thread = 6\n            self.https_connection_pool_min = 0\n            self.https_connection_pool_max = 10\n        elif level == \"radical\":\n            self.dispather_min_idle_workers = 3\n            self.dispather_work_min_idle_time = 1\n            self.dispather_work_max_score = 1000\n            self.dispather_min_workers = 5\n            self.dispather_max_workers = 10\n            self.dispather_max_idle_workers = 5\n            self.max_task_num = 20\n            self.https_max_connect_thread = 6\n            self.https_connection_pool_min = 1\n            self.https_connection_pool_max = 10\n        elif level == \"extreme\":\n            self.dispather_min_idle_workers = 5\n            self.dispather_work_min_idle_time = 5\n            self.dispather_work_max_score = 1000\n            self.dispather_min_workers = 5\n            self.dispather_max_workers = 15\n            self.dispather_max_idle_workers = 5\n            self.max_task_num = 30\n            self.https_max_connect_thread = 10\n            self.https_connection_pool_min = 1\n            self.https_connection_pool_max = 10\n\n    set_default = set_level\n\n\nconfig_path = os.path.join(module_data_path, \"config.json\")\nconfig = Config(config_path)\ndirect_config = DirectConfig(config)\n\n"
  },
  {
    "path": "code/default/gae_proxy/local/direct_handler.py",
    "content": "#!/usr/bin/env python\n# coding:utf-8\n\n\nimport time\nimport re\nimport socket\nimport ssl\nimport errno\n\ntry:\n    import OpenSSL\n    NetWorkIOError = (socket.error, ssl.SSLError, OpenSSL.SSL.Error, OSError)\nexcept:\n    NetWorkIOError = (socket.error, ssl.SSLError, OSError)\n\n\nfrom .gae_handler import send_header, return_fail_message\n\nfrom .front import direct_front\nfrom xlog import getLogger\nxlog = getLogger(\"gae_proxy\")\n\ngoogle_server_types = [b\"ClientMapServer\"]\n\n\ndef handler(method, host, path, headers, body, wfile, timeout=60):\n    time_request = time.time()\n\n    if b\"Connection\" in headers and headers[b\"Connection\"] == b\"close\":\n        del headers[b\"Connection\"]\n\n    errors = []\n    while True:\n        time_left = time_request + timeout - time.time()\n        if time_left <= 0:\n            return_fail_message(wfile)\n            return \"ok\"\n\n        try:\n            response = direct_front.request(method, host, path, headers, body, timeout=time_left)\n            if response:\n                if response.status > 600:\n                    xlog.warn(\"direct %s %s % status:%d\", method, host, path, response.status)\n                    continue\n                elif response.status > 400:\n                    server_type = response.headers.get(b'Server', b\"\")\n\n                    if b\"G\" not in server_type and b\"g\" not in server_type and server_type not in google_server_types:\n\n                        xlog.debug(\"IP:%s host:%s not support GAE, server type:%s status:%d\",\n                                  response.ssl_sock.ip_str, host, server_type, response.status)\n                        #direct_front.ip_manager.report_connect_fail(response.ssl_sock.ip_str, force_remove=True)\n                        response.worker.close()\n                        continue\n                break\n        except OpenSSL.SSL.SysCallError as e:\n            errors.append(e)\n            xlog.warn(\"direct_handler.handler err:%r %s/%s\", e, host, path)\n        except Exception as e:\n            errors.append(e)\n            xlog.exception('direct_handler.handler %r %s %s , retry...', e, host, path)\n\n    response_headers = {}\n    for key, value in list(response.headers.items()):\n        key = key.title()\n        response_headers[key] = value\n\n    response_headers[b\"Persist\"] = b\"\"\n    response_headers[b\"Connection\"] = b\"Persist\"\n\n    try:\n        wfile.write(b\"HTTP/1.1 %d %s\\r\\n\" % (response.status, response.reason))\n        for key, value in list(response_headers.items()):\n            send_header(wfile, key, value)\n        wfile.write(b\"\\r\\n\")\n\n        length = 0\n        while True:\n            data = response.task.read()\n            data_len = len(data)\n            length += data_len\n            if b'Transfer-Encoding' in response_headers:\n                if not data_len:\n                    wfile.write(b'0\\r\\n\\r\\n')\n                    break\n                wfile.write(b'%x\\r\\n' % data_len)\n                wfile.write(data)\n                wfile.write(b'\\r\\n')\n            else:\n                if not data_len:\n                    break\n                wfile.write(data)\n\n        xlog.info(\"DIRECT t:%d s:%d %d %s %s\",\n                  (time.time()-time_request)*1000, length, response.status, host, path)\n        if b'Content-Length' in response_headers or b'Transfer-Encoding' in response_headers:\n            return \"ok\"\n    except NetWorkIOError as e:\n        xlog.warn('DIRECT %s %s%s except:%r', method, host, path, e)\n        if e.args[0] not in (errno.ECONNABORTED, errno.ETIMEDOUT, errno.EPIPE):\n            raise\n    except Exception as e:\n        xlog.exception(\"DIRECT %s %d %s%s, t:%d send to client except:%r\",\n                 method, response.status, host, path, (time.time()-time_request)*1000, e)"
  },
  {
    "path": "code/default/gae_proxy/local/download_gae_lib.py",
    "content": "import os\nimport time\nimport zipfile\nimport shutil\n\n\nimport simple_http_client\nimport env_info\nfrom xlog import getLogger\nxlog = getLogger(\"gae_proxy\")\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nroot_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))\ntop_path = os.path.abspath(os.path.join(root_path, os.pardir, os.pardir))\ndata_path = os.path.abspath( os.path.join(env_info.data_path, 'gae_proxy'))\n\n\ndef request(url, retry=0, timeout=30):\n    cert = os.path.join(data_path, \"CA.crt\")\n    client = simple_http_client.Client(proxy={\n        \"type\": \"http\",\n        \"host\": \"127.0.0.1\",\n        \"port\": 8087,\n        \"user\": None,\n        \"pass\": None\n    }, timeout=timeout, cert=cert)\n\n    res = client.request(\"GET\", url, read_payload=False)\n    return res\n\n\ndef download_file(url, filename):\n    org_url = url\n    if os.path.isfile(filename):\n        return True\n\n    for i in range(0, 4):\n        try:\n            xlog.info(\"download %s to %s, retry:%d\", url, filename, i)\n            req = request(url, i, timeout=120)\n            if not req:\n                time.sleep(3)\n                continue\n\n            if req.status == 302:\n                url = req.headers[\"Location\"]\n                continue\n\n            start_time = time.time()\n            timeout = 300\n\n            if req.chunked:\n\n                downloaded = 0\n                with open(filename, 'wb') as fp:\n                    while True:\n                        time_left = timeout - (time.time() - start_time)\n                        if time_left < 0:\n                            raise Exception(\"time out\")\n\n                        dat = req.read(timeout=time_left)\n                        if not dat:\n                            break\n\n                        fp.write(dat)\n                        downloaded += len(dat)\n\n                return True\n            else:\n                file_size = int(req.getheader('Content-Length', 0))\n\n                left = file_size\n                downloaded = 0\n                with open(filename, 'wb') as fp:\n                    while True:\n                        chunk_len = min(65536, left)\n                        if not chunk_len:\n                            break\n\n                        chunk = req.read(chunk_len)\n                        if not chunk:\n                            break\n                        fp.write(chunk)\n                        downloaded += len(chunk)\n                        left -= len(chunk)\n\n            if downloaded != file_size:\n                xlog.warn(\"download size:%d, need size:%d, download fail.\", downloaded, file_size)\n                os.remove(filename)\n                continue\n            else:\n                xlog.info(\"download %s to %s success.\", org_url, filename)\n                return True\n        except Exception as e:\n            xlog.warn(\"download %s to %s fail:%r\", org_url, filename, e)\n            continue\n    xlog.warn(\"download %s fail\", org_url)\n\n\ndef download_unzip(url, extract_path):\n    if os.path.isdir(extract_path):\n        return True\n\n    data_root = os.path.join(top_path, 'data')\n    download_path = os.path.join(data_root, 'downloads')\n    if not os.path.isdir(download_path):\n        os.mkdir(download_path)\n\n    fn = url.split(\"/\")[-1]\n    dfn = os.path.join(download_path, fn)\n\n    if not download_file(url, dfn):\n        xlog.warn(\"download file %s fail.\", url)\n        return\n\n    try:\n        os.mkdir(extract_path)\n        with zipfile.ZipFile(dfn, \"r\") as dz:\n            dz.extractall(extract_path)\n            dz.close()\n        xlog.info(\"Extract %s to %s success.\", fn, extract_path)\n    except Exception as e:\n        xlog.warn(\"unzip %s fail:%r\", dfn, e)\n        shutil.rmtree(extract_path)\n        raise e\n    os.remove(dfn)\n\n\ndef check_lib_or_download():\n    lib_path = os.path.abspath(os.path.join(current_path, os.pardir, \"server\", \"lib\"))\n\n    if os.path.isdir(lib_path):\n        return True\n\n    download_unzip(\"https://github.com/XX-net/XX-Net/releases/download/3.15.0/lib.zip\", lib_path)"
  },
  {
    "path": "code/default/gae_proxy/local/front.py",
    "content": "import os\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nroot_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))\n\nimport env_info\ndata_path = env_info.data_path\nmodule_data_path = os.path.join(data_path, 'gae_proxy')\n\nimport xlog\nlogger = xlog.getLogger(\"gae_proxy\", log_path=module_data_path, save_start_log=500, save_warning_log=True)\nlogger.set_buffer(500)\n\nfrom . import check_local_network\n\nfrom .config import config, direct_config\nfrom . import host_manager\nfrom front_base.openssl_wrap import SSLContext\nfrom front_base.connect_creator import ConnectCreator\nfrom front_base.ip_manager import IpManager\nfrom front_base.ip_source import Ipv4RangeSource, Ipv6PoolSource, IpCombineSource\nfrom front_base.http_dispatcher import HttpsDispatcher\nfrom front_base.connect_manager import ConnectManager\nfrom .check_ip import CheckIp\n\nfrom .appid_manager import AppidManager\n\n\nclass Front(object):\n    name = \"gae_front\"\n\n    def __init__(self):\n        self.logger = logger\n        self.config = config\n\n    def start(self):\n        self.running = True\n\n        ca_certs = os.path.join(current_path, \"cacert.pem\")\n        self.openssl_context = SSLContext(\n            logger, ca_certs=ca_certs, support_http2=config.support_http2,\n            protocol=\"TLSv1_2\"\n            #cipher_suites=[b'ALL', b\"!RC4-SHA\", b\"!ECDHE-RSA-RC4-SHA\", b\"!ECDHE-RSA-AES128-GCM-SHA256\",\n            #               b\"!AES128-GCM-SHA256\", b\"!ECDHE-RSA-AES128-SHA\", b\"!AES128-SHA\"]\n        )\n\n        self.appid_manager = AppidManager(self.config, logger)\n\n        self.host_manager = host_manager.HostManager(self.config, logger)\n        self.host_manager.appid_manager = self.appid_manager\n\n        self.connect_creator = ConnectCreator(\n            logger, self.config, self.openssl_context, self.host_manager)\n\n        self.ip_checker = CheckIp(xlog.null, self.config, self.connect_creator)\n\n        self.ipv4_source = Ipv4RangeSource(\n            logger, self.config,\n            os.path.join(current_path, \"ip_range.txt\"),\n            os.path.join(module_data_path, \"ip_range.txt\")\n        )\n        self.ipv6_source = Ipv6PoolSource(\n            logger, self.config,\n            os.path.join(current_path, \"ipv6_list.txt\")\n        )\n        self.ip_source = IpCombineSource(\n            logger, self.config,\n            self.ipv4_source, self.ipv6_source\n        )\n        self.ip_manager = IpManager(\n            logger, self.config, self.ip_source, self.host_manager, check_local_network,\n            self.check_ip,\n            None,\n            os.path.join(module_data_path, \"good_ip.txt\"),\n            scan_ip_log=None)\n\n        self.appid_manager.check_api = self.ip_checker.check_ip\n        self.appid_manager.ip_manager = self.ip_manager\n\n        self.connect_manager = ConnectManager(\n            logger, self.config, self.connect_creator, self.ip_manager, check_local_network)\n\n        self.http_dispatcher = HttpsDispatcher(\n            logger, self.config, self.ip_manager, self.connect_manager\n        )\n\n    def check_ip(self, ip):\n        sni = self.host_manager.sni_manager.get()\n        host = self.config.check_ip_host\n        return self.ip_checker.check_ip(ip, sni=sni, host=host)\n\n    def get_dispatcher(self):\n        return self.http_dispatcher\n\n    def request(self, method, host, path=b\"/\", headers={}, data=\"\", timeout=120):\n        response = self.http_dispatcher.request(method, host, path, dict(headers), data, timeout=timeout)\n\n        return response\n\n    def stop(self):\n        logger.info(\"terminate\")\n        self.connect_manager.set_ssl_created_cb(None)\n        self.http_dispatcher.stop()\n        self.connect_manager.stop()\n        self.ip_manager.stop()\n\n        self.running = False\n\n    def set_proxy(self, args):\n        logger.info(\"set_proxy:%s\", args)\n\n        self.config.PROXY_ENABLE = args[\"enable\"]\n        self.config.PROXY_TYPE = args[\"type\"]\n        self.config.PROXY_HOST = args[\"host\"]\n        self.config.PROXY_PORT = args[\"port\"]\n        self.config.PROXY_USER = args[\"user\"]\n        self.config.PROXY_PASSWD = args[\"passwd\"]\n\n        self.config.save()\n\n        self.connect_creator.update_config()\n\n\nfront = Front()\n\n\nclass DirectFront(object):\n    name = \"direct_front\"\n\n    def __init__(self):\n        pass\n\n    def start(self):\n        self.running = True\n\n        self.host_manager = host_manager.HostManager(front.config, logger)\n\n        ca_certs = os.path.join(current_path, \"cacert.pem\")\n        self.openssl_context = SSLContext(\n            logger, ca_certs=ca_certs, support_http2=False, protocol=\"TLSv1_2\"\n            #cipher_suites=[b'ALL', b\"!RC4-SHA\", b\"!ECDHE-RSA-RC4-SHA\", b\"!ECDHE-RSA-AES128-GCM-SHA256\",\n            #               b\"!AES128-GCM-SHA256\", b\"!ECDHE-RSA-AES128-SHA\", b\"!AES128-SHA\"]\n        )\n\n        self.connect_creator = ConnectCreator(\n            logger, front.config, self.openssl_context, self.host_manager)\n\n        self.ip_manager = front.ip_manager\n        self.connect_manager = ConnectManager(\n            logger, front.config, self.connect_creator, self.ip_manager, check_local_network)\n\n        self.dispatchs = {}\n\n    def get_dispatcher(self, host):\n        if host not in self.dispatchs:\n            http_dispatcher = HttpsDispatcher(\n                logger, direct_config, front.ip_manager, self.connect_manager)\n            self.dispatchs[host] = http_dispatcher\n\n        return self.dispatchs[host]\n\n    def request(self, method, host, path=\"/\", headers={}, data=\"\", timeout=60):\n        dispatcher = self.get_dispatcher(host)\n\n        response = dispatcher.request(method, host, path, dict(headers), data, timeout=timeout)\n\n        return response\n\n    def stop(self):\n        logger.info(\"terminate\")\n        self.connect_manager.set_ssl_created_cb(None)\n        for host in self.dispatchs:\n            dispatcher = self.dispatchs[host]\n            dispatcher.stop()\n        self.connect_manager.stop()\n\n        self.running = False\n\n    def set_proxy(self, args):\n        self.connect_creator.update_config()\n\n\ndirect_front = DirectFront()\n"
  },
  {
    "path": "code/default/gae_proxy/local/gae_handler.py",
    "content": "#!/usr/bin/env python\n# coding:utf-8\n\n\n\"\"\"\nGoAgent local-server protocol 3.2\n\nrequest:\n  POST /_gh/ HTTP/1.1\n  HOST: appid.appspot.com\n  content-length: xxx\n\n  http content:\n  此为ｂｏｄｙ\n  {\n    pack_req_head_len: 2 bytes,＃ＰＯＳＴ　时使用\n    \n    pack_req_head : deflate{\n    此为负载\n      original request line,\n      original request headers,\n      X-URLFETCH-kwargs HEADS, {\n        password,\n        maxsize, defined in config AUTO RANGE MAX SIZE\n        timeout, request timeout for GAE urlfetch.\n      }\n    }\n    body\n  }\n\nresponse:\n  200 OK\n  http-Heads:\n    Content-type: image/gif\n\n\n    headers from real_server\n    # real_server 为ｇａｅ让客户端以为的服务器\n    #可能被gae改变，但对客户端不可见\n    #未分片ｂｏｄｙ也直接发给客户端\n\n    # body 分为下面两部分\n  http-content:{\n      response_head{\n        data_len: 2 bytes,\n        data: deflate{\n         HTTP/1.1 status, status_code\n         headers\n         content = error_message, if GAE server fail\n        }\n      }\n\n      body\n  }\n\"\"\"\n\nimport errno\nimport sys\nimport time\nimport xstruct as struct\nimport re\nimport string\nimport ssl\nimport threading\nimport zlib\nimport traceback\nfrom mimetypes import guess_type\n\ntry:\n    from urllib.parse import urlparse, urljoin, urljoin\nexcept ImportError:\n    from urlparse import urlparse, urljoin, urljoin\n\nfrom xx_six import ConnectionError, ConnectionResetError, BrokenPipeError, ConnectionAbortedError\n\nfrom . import check_local_network\nfrom .front import front\nimport utils\nfrom xlog import getLogger\nxlog = getLogger(\"gae_proxy\")\n\n\ndef inflate(data):\n    return zlib.decompress(data, -zlib.MAX_WBITS)\n\n\ndef deflate(data):\n    return zlib.compress(data)[2:-4]\n\n\nclass GAE_Exception(Exception):\n    def __init__(self, error_code, message):\n        xlog.debug(\"GAE_Exception %r %r\", error_code, message)\n        self.error_code = error_code\n        self.message = \"%r:%s\" % (error_code, message)\n\n    def __str__(self):\n        # for %s\n        return repr(self.message)\n\n    def __repr__(self):\n        # for %r\n        return repr(self.message)\n\n\ndef generate_message_html(title, banner, detail=''):\n    MESSAGE_TEMPLATE = '''\n    <html><head>\n    <meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\">\n    <title>$title</title>\n    <style><!--\n    body {font-family: arial,sans-serif}\n    div.nav {margin-top: 1ex}\n    div.nav A {font-size: 10pt; font-family: arial,sans-serif}\n    span.nav {font-size: 10pt; font-family: arial,sans-serif; font-weight: bold}\n    div.nav A,span.big {font-size: 12pt; color: #0000cc}\n    div.nav A {font-size: 10pt; color: black}\n    A.l:link {color: #6f6f6f}\n    A.u:link {color: green}\n    //--></style>\n    </head>\n    <body text=#000000 bgcolor=#ffffff>\n    <table border=0 cellpadding=2 cellspacing=0 width=100%>\n    <tr><td bgcolor=#3366cc><font face=arial,sans-serif color=#ffffff><b>Message</b></td></tr>\n    <tr><td> </td></tr></table>\n    <blockquote>\n    <H1>$banner</H1>\n    $detail\n    <p>\n    </blockquote>\n    <table width=100% cellpadding=0 cellspacing=0><tr><td bgcolor=#3366cc><img alt=\"\" width=1 height=4></td></tr></table>\n    </body></html>\n    '''\n    return string.Template(MESSAGE_TEMPLATE).substitute(\n        title=title, banner=banner, detail=detail)\n\n\ndef spawn_later(seconds, target, *args, **kwargs):\n    def wrap(*args, **kwargs):\n        __import__('time').sleep(seconds)\n        try:\n            result = target(*args, **kwargs)\n        except BaseException:\n            result = None\n        return result\n    return __import__('thread').start_new_thread(wrap, args, kwargs)\n\n\nskip_request_headers = frozenset([\n                          b'Vary',\n                          b'Via',\n                          b'Proxy-Authorization',\n                          b'Proxy-Connection',\n                          b'Upgrade',\n                          b'X-Google-Cache-Control',\n                          b'X-Forwarded-For',\n                          b'X-Chrome-Variations',\n                          ])\nskip_response_headers = frozenset([\n                          # http://en.wikipedia.org/wiki/Chunked_transfer_encoding\n                          b'Connection',\n                          b'Upgrade',\n                          b'Alt-Svc',\n                          b'Alternate-Protocol',\n                          b'X-Head-Content-Length',\n                          b'X-Google-Cache-Control',\n                          b'X-Chrome-Variations',\n                          ])\n\n\ndef send_header(wfile, keyword, value):\n    keyword = keyword.title()\n    if keyword == b'Set-Cookie':\n        # https://cloud.google.com/appengine/docs/python/urlfetch/responseobjects\n        for cookie in re.split(br', (?=[^ =]+(?:=|$))', value):\n            wfile.write(b\"%s: %s\\r\\n\" % (keyword, cookie))\n            #xlog.debug(\"Head1 %s: %s\", keyword, cookie)\n    elif keyword == b'Content-Disposition' and b'\"' not in value:\n        value = re.sub(br'filename=([^\"\\']+)', b'filename=\"\\\\1\"', value)\n        wfile.write(b\"%s: %s\\r\\n\" % (keyword, value))\n        #xlog.debug(\"Head1 %s: %s\", keyword, value)\n    elif keyword in skip_response_headers:\n        return\n    else:\n        if isinstance(value, int):\n            wfile.write(b\"%s: %d\\r\\n\" % (keyword, value))\n        else:\n            wfile.write(b\"%s: %s\\r\\n\" % (keyword, value))\n        #xlog.debug(\"Head1 %s: %s\", keyword, value)\n\n\ndef send_response(wfile, status=404, headers={}, body=b''):\n    body = utils.to_bytes(body)\n    headers = dict((k.title(), v) for k, v in list(headers.items()))\n    if b'Transfer-Encoding' in headers:\n        del headers[b'Transfer-Encoding']\n    if b'Content-Length' not in headers:\n        headers[b'Content-Length'] = len(body)\n    if b'Connection' not in headers:\n        headers[b'Connection'] = b'close'\n\n    try:\n        wfile.write(b\"HTTP/1.1 %d\\r\\n\" % status)\n        for key, value in list(headers.items()):\n            send_header(wfile, key, value)\n        wfile.write(b\"\\r\\n\")\n        wfile.write(body)\n    except ssl.SSLError as e:\n        xlog.warn(\"gae send response fail. %r\", e)\n        return\n    except Exception as e:\n        if sys.version_info[0] == 3 and (\n                isinstance(e, ConnectionError) or\n                isinstance(e, ConnectionResetError) or\n                isinstance(e, BrokenPipeError)\n        ):\n            xlog.warn(\"gae send response fail. %r\", e)\n        else:\n            xlog.exception(\"send response fail %r\", e)\n\n\ndef return_fail_message(wfile):\n    html = generate_message_html(\n        '504 GAEProxy Proxy Time out', '连接超时，先休息一会再来！')\n    send_response(wfile, 504, body=utils.to_bytes(html))\n    return\n\n\ndef pack_request(method, url, headers, body, timeout):\n    headers = dict(headers)\n    if isinstance(body, bytes) and body:\n        if len(body) < 10 * 1024 * 1024 and b'Content-Encoding' not in headers:\n            # 可以压缩\n            zbody = deflate(body)\n            if len(zbody) < len(body):\n                body = zbody\n                headers[b'Content-Encoding'] = b'deflate'\n        if len(body) > 10 * 1024 * 1024:\n            xlog.warn(\"body len:%d %s %s\", len(body), method, url)\n        headers[b'Content-Length'] = utils.to_bytes(str(len(body)))\n\n    # GAE don't allow set `Host` header\n    if b'Host' in headers:\n        del headers[b'Host']\n\n    kwargs = {}\n    # gae 用的参数\n    if front.config.GAE_PASSWORD:\n        kwargs[b'password'] = front.config.GAE_PASSWORD\n\n    # kwargs['options'] =\n    kwargs[b'validate'] = front.config.GAE_VALIDATE\n    if url.endswith(b\".js\"):\n        kwargs[b'maxsize'] = front.config.JS_MAXSIZE\n    else:\n        kwargs[b'maxsize'] = front.config.AUTORANGE_MAXSIZE\n    kwargs[b'timeout'] = str(timeout)\n    # gae 用的参数　ｅｎｄ\n\n    payload = b'%s %s HTTP/1.1\\r\\n' % (method, url)\n    payload += b''.join(b'%s: %s\\r\\n' % (k, v)\n                       for k, v in list(headers.items()) if k not in skip_request_headers)\n    # for k, v in headers.items():\n    #    xlog.debug(\"Send %s: %s\", k, v)\n    for k, v in kwargs.items():\n        if isinstance(v, int):\n            payload += b'X-URLFETCH-%s: %d\\r\\n' % (k, v)\n        else:\n            payload += b'X-URLFETCH-%s: %s\\r\\n' % (k, utils.to_bytes(v))\n\n    payload = deflate(payload)\n\n    body = b'%s%s%s' % (struct.pack('!h', len(payload)), payload, body)\n    request_headers = {}\n    request_headers[b'Content-Length'] = str(len(body))\n    # request_headers 只有上面一项\n\n    return request_headers, body\n\n\ndef unpack_response(response):\n    try:\n        data = response.task.read(size=2)\n        if not data:\n            raise GAE_Exception(600, \"get protocol head fail\")\n\n        if len(data) !=2:\n            raise GAE_Exception(600, \"get protocol head fail, data:%s, len:%d\" % (data, len(data)))\n\n        headers_length, = struct.unpack('!h', data)\n        data = response.task.read(size=headers_length)\n        if not data:\n            raise GAE_Exception(600,\n                \"get protocol head fail, len:%d\" % headers_length)\n\n        raw_response_line, headers_data = inflate(data).split(b'\\r\\n', 1)\n        rl = raw_response_line.split()\n        response.app_status = int(rl[1])\n        if len(rl) >=3:\n            response.app_reason = rl[2].strip()\n\n        headers_block, app_msg = headers_data.split(b'\\r\\n\\r\\n')\n        headers_pairs = headers_block.split(b'\\r\\n')\n        response.headers = {}\n        for pair in headers_pairs:\n            if not pair:\n                break\n            k, v = pair.split(b': ', 1)\n            response.headers[k] = v\n\n        response.app_msg = app_msg\n\n        return response\n    except Exception as e:\n        response.worker.close(\"unpack protocol error\")\n        raise GAE_Exception(600, \"unpack protocol:%r at:%s\" % (e, traceback.format_exc()))\n\n\ndef request_gae_server(headers, body, url, timeout):\n    # process on http protocol\n    # process status code return by http server\n    # raise error, let up layer retry.\n\n    try:\n        response = front.request(b\"POST\", b\"\", b\"/_gh/\", headers, body, timeout)\n        if not response:\n            raise GAE_Exception(600, \"fetch gae fail\")\n\n        if response.status >= 600:\n            raise GAE_Exception(\n                response.status, \"fetch gae fail:%d\" % response.status)\n\n        appid = response.ssl_sock.host.split(\".\")[0]\n        if response.status == 404:\n            # xlog.warning('APPID %r not exists, remove it.', response.ssl_sock.appid)\n            front.appid_manager.report_not_exist(\n                appid, response.ssl_sock.ip_str)\n            # google_ip.report_connect_closed(response.ssl_sock.ip_str, \"appid not exist\")\n            response.worker.close(\"appid not exist:%s\" % appid)\n            raise GAE_Exception(603, \"appid not exist %s\" % appid)\n\n        if response.status == 503:\n            xlog.warning('APPID %r out of Quota, remove it. %s',\n                         appid, response.ssl_sock.ip_str)\n            front.appid_manager.report_out_of_quota(appid)\n            # google_ip.report_connect_closed(response.ssl_sock.ip_str, \"out of quota\")\n            response.worker.close(\"appid out of quota:%s\" % appid)\n            raise GAE_Exception(604, \"appid out of quota:%s\" % appid)\n\n        server_type = response.getheader(b\"Server\", b\"\")\n        if (b\"gws\" not in server_type and b\"Google Frontend\" not in server_type and b\"GFE\" not in server_type) or \\\n                response.status == 403 or response.status == 405:\n\n            # some ip can connect, and server type can be gws\n            # but can't use as GAE server\n            # so we need remove it immediately\n\n            xlog.warn(\"IP:%s not support GAE, headers:%s status:%d\", response.ssl_sock.ip_str, response.headers,\n                      response.status)\n            response.worker.close(\"ip not support GAE\")\n            raise GAE_Exception(602, \"ip not support GAE\")\n\n        response.gps = response.getheader(b\"x-server\", b\"\")\n\n        if response.status > 300:\n            raise GAE_Exception(605, \"status:%d\" % response.status)\n\n        if response.status != 200:\n            xlog.warn(\"GAE %s appid:%s status:%d\", response.ssl_sock.ip_str,\n                      appid, response.status)\n\n        return response\n    except GAE_Exception as e:\n        if e.error_code not in (600, 603, 604) and hasattr(response, \"ssl_sock\"):\n            front.ip_manager.recheck_ip(response.ssl_sock.ip_str, first_report=False)\n        raise e\n\n\ndef request_gae_proxy(method, url, headers, body, timeout=None):\n    headers = dict(headers)\n    # make retry and time out\n    time_request = time.time()\n\n    # GAE urlfetch will not decode br if Accept-Encoding include gzip\n    accept_encoding = headers.get(b\"Accept-Encoding\", b\"\")\n    if b\"br\" in accept_encoding:\n        accept_br_encoding = True\n        # xlog.debug(\"accept_br_encoding for %s\", url)\n    else:\n        accept_br_encoding = False\n\n    host = headers.get(b\"Host\", b\"\")\n    if not host:\n        parsed_url = urlparse(url)\n        host = parsed_url.hostname\n\n    accept_codes = accept_encoding.replace(b\" \", b\"\").split(b\",\")\n    try:\n        accept_codes.remove(b\"\")\n    except:\n        pass\n\n    if not accept_br_encoding:\n        if b\"gzip\" in accept_encoding:\n            if host in front.config.br_sites or host.endswith(front.config.br_endswith):\n                accept_codes.remove(b\"gzip\")\n\n    if b\"br\" not in accept_codes:\n        accept_codes.append(b\"br\")\n\n    accept_code_str = b\",\".join(accept_codes)\n    if accept_code_str:\n        headers[b\"Accept-Encoding\"] = accept_code_str\n    else:\n        del headers[b\"Accept-Encoding\"]\n\n    error_msg = []\n\n    if not timeout:\n        timeouts = [15, 20, 30]\n    else:\n        timeouts = [timeout]\n\n    if body:\n        timeouts = [timeout + 10 for timeout in timeouts]\n\n    for timeout in timeouts:\n        request_headers, request_body = pack_request(method, url, headers, body, timeout)\n        try:\n            response = request_gae_server(request_headers, request_body, url, timeout)\n\n            response = unpack_response(response)\n\n            # xlog.debug(\"accept:%s content-encoding:%s url:%s\", accept_encoding,\n            #           response.headers.get(\"Content-Encoding\", \"\"), url)\n            if not accept_br_encoding:\n                # if gzip in Accept-Encoding, br will not decode in urlfetch\n                # else, urlfetch in GAE will auto decode br, but return br in Content-Encoding\n                if response.headers.get(b\"Content-Encoding\", b\"\") == b\"br\":\n                    # GAE urlfetch always return br in content-encoding even have decoded it.\n                    del response.headers[b\"Content-Encoding\"]\n                    # xlog.debug(\"remove br from Content-Encoding, %s\", url)\n                    if host not in front.config.br_sites:\n                        front.config.BR_SITES.append(host)\n                        front.config.save()\n                        front.config.load()\n                        xlog.warn(\"Add %s to br_sites\", host)\n\n            if response.app_msg:\n                xlog.warn(\"server app return fail, status:%d\",\n                          response.app_status)\n                # if len(response.app_msg) < 2048:\n                # xlog.warn('app_msg:%s', cgi.escape(response.app_msg))\n\n                if response.app_status == 510:\n                    # reach 80% of traffic today\n                    # disable for get big file.\n                    appid = response.ssl_sock.host.split(\".\")[0]\n                    front.appid_manager.report_out_of_quota(appid)\n                    response.worker.close(\n                        \"appid out of quota:%s\" % appid)\n                    continue\n\n            return response\n        except GAE_Exception as e:\n            err_msg = \"gae_exception:%r %s\" % (e, url)\n            error_msg.append(err_msg)\n            xlog.warn(\"gae_exception:%r %s\", e, url)\n            if e.message == '605:status:500':\n                raise e\n        except Exception as e:\n            err_msg = 'gae_handler.handler %r %s , retry...' % (e, url)\n            error_msg.append(err_msg)\n            xlog.exception('gae_handler.handler %r %s , retry...', e, url)\n\n    raise GAE_Exception(600, \"\".join(error_msg))\n\n\ndef handler(method, host, url, headers, body, wfile, fallback=None):\n    if not url.startswith(b\"http\") and not url.startswith(b\"HTTP\"):\n        xlog.error(\"gae:%s\", url)\n        return\n\n    request_time = time.time()\n\n    org_headers = dict(headers)\n    remove_list = []\n    req_range_begin = b\"\"\n    req_range_end = b\"\"\n    req_range = b\"\"\n    for k, v in list(headers.items()):\n        if v == \"\":\n            remove_list.append(k)\n            continue\n        if k.lower() == b\"range\":\n            req_range = v\n            req_range_begin, req_range_end = tuple(\n                x for x in re.search(br'bytes=(\\d*)-(\\d*)', v).group(1, 2))\n\n    # fix bug for android market app: Mobogenie\n    # GAE url_fetch refuse empty value in header.\n    for key in remove_list:\n        del headers[key]\n\n    # force to get content range\n    # reduce wait time\n    if method == b\"GET\":\n        if req_range_begin and not req_range_end:\n            # don't known how many bytes to get, but get from begin position\n            req_range_begin = int(req_range_begin)\n            headers[b\"Range\"] = b\"bytes=%d-%d\" % (\n                req_range_begin, req_range_begin + front.config.AUTORANGE_MAXSIZE - 1)\n            xlog.debug(\"change Range %s => %s %s\",\n                       req_range, headers[b\"Range\"], url)\n        elif req_range_begin and req_range_end:\n            req_range_begin = int(req_range_begin)\n            req_range_end = int(req_range_end)\n            if req_range_end - req_range_begin + 1 > front.config.AUTORANGE_MAXSIZE:\n                headers[b\"Range\"] = b\"bytes=%d-%d\" % (\n                    req_range_begin, req_range_begin + front.config.AUTORANGE_MAXSIZE - 1)\n                # remove wait time for GAE server to get knowledge that content\n                # size exceed the max size per fetch\n                xlog.debug(\"change Range %s => %s %s\",\n                           req_range, headers[b\"Range\"], url)\n        elif not req_range_begin and req_range_end:\n            # get the last n bytes of content\n            pass\n        else:\n            # no begin and no end\n            # don't add range, some host like github don't support Range.\n            # headers[\"Range\"] = \"bytes=0-%d\" % config.AUTORANGE_MAXSIZE\n            pass\n\n    try:\n        response = request_gae_proxy(method, url, headers, body)\n        # http://en.wikipedia.org/wiki/Chunked_transfer_encoding\n        response.headers.pop(b\"Transfer-Encoding\", None)\n        # gae代理请求\n    except GAE_Exception as e:\n        xlog.warn(\"GAE %s %s request fail:%r\", method, url, e)\n\n        if fallback and host.endswith(front.config.GOOGLE_ENDSWITH):\n            return fallback()\n\n        send_response(wfile, e.error_code, body=e.message)\n        return_fail_message(wfile)\n        return \"ok\"\n    except Exception as e:\n        xlog.exception(\"request_gae except:%r\", e)\n        send_response(wfile, 502, body=e.args[1]) # 502 means Gateway error.\n        return_fail_message(wfile)\n        return \"ok\"\n\n    if response.app_msg:\n        # XX-net 自己数据包\n        send_response(wfile, response.app_status, body=response.app_msg)\n        return \"ok\"\n    else:\n        response.status = response.app_status\n\n    if response.status == 206:\n        # use org_headers\n        # RangeFetch need to known the real range end\n        # 需要分片\n        return RangeFetch2(method, url, org_headers,\n                           body, response, wfile).run()\n\n    response_headers = {}\n    #　初始化给客户端的headers\n    for key, value in list(response.headers.items()):\n        key = key.title()\n        if key in skip_response_headers:\n            continue\n        response_headers[key] = value\n\n    response_headers[b\"Persist\"] = b\"\"\n    response_headers[b\"Connection\"] = b\"Persist\"\n\n    if b'X-Head-Content-Length' in response_headers:\n        if method == b\"HEAD\":\n            response_headers[b'Content-Length'] = response_headers[b'X-Head-Content-Length']\n        del response_headers[b'X-Head-Content-Length']\n        # 只是获取头\n\n    content_length = int(response.headers.get(b'Content-Length', 0))\n    content_range = response.headers.get(b'Content-Range', '')\n    # content_range 分片时合并用到\n    if content_range and b'bytes */' not in content_range:\n        start, end, length = tuple(int(x) for x in re.search(\n            br'bytes (\\d+)-(\\d+)/(\\d+)', content_range).group(1, 2, 3))\n    else:\n        start, end, length = 0, content_length - 1, content_length\n        # 未分片\n\n    if method == b\"HEAD\":\n        body_length = 0\n    else:\n        body_length = end - start + 1\n\n    def send_response_headers():\n        wfile.write(b\"HTTP/1.1 %d %s\\r\\n\" % (response.status, utils.to_bytes(response.reason)))\n        for key, value in list(response_headers.items()):\n            send_header(wfile, key, value)\n            # xlog.debug(\"Head- %s: %s\", key, value)\n        wfile.write(b\"\\r\\n\")\n        # 写入除body外内容\n\n    def is_text_content_type(content_type):\n        content_type = utils.to_bytes(content_type)\n        mct, _, sct = content_type.partition(b'/')\n        if mct == b'text':\n            return True\n        if mct == b'application':\n            sct = sct.split(b';', 1)[0]\n            if (sct in (b'json', b'javascript', b'x-www-form-urlencoded') or\n                    sct.endswith((b'xml', b'script')) or\n                    sct.startswith((b'xml', b'rss', b'atom'))):\n                return True\n        return False\n\n    data0 = b\"\"\n    content_type = response_headers.get(b\"Content-Type\", b\"\")\n    content_encoding = response_headers.get(b\"Content-Encoding\", b\"\")\n    if body_length and \\\n            content_encoding == b\"gzip\" and \\\n            response.gps < b\"GPS 3.3.2\" and \\\n            is_text_content_type(content_type):\n        url_guess_type = guess_type(utils.to_str(url))[0]\n        if url_guess_type is None or is_text_content_type(url_guess_type):\n            # try decode and detect type\n\n            min_block = min(1024, body_length)\n            data0 = response.task.read(min_block)\n            if not data0 or len(data0) == 0:\n                xlog.warn(\"recv body fail:%s\", url)\n                return\n\n            gzip_decompressor = zlib.decompressobj(16 + zlib.MAX_WBITS)\n            decoded_data0 = gzip_decompressor.decompress(data0)\n\n            deflate_decompressor = zlib.decompressobj(-zlib.MAX_WBITS)\n            decoded_data1 = None\n\n            if len(decoded_data0) > 1:\n                CMF, FLG = bytearray(decoded_data0[:2])\n                if CMF & 0x0F == 8 and CMF & 0x80 == 0 and ((CMF << 8) + FLG) % 31 == 0:\n                    decoded_data1 = deflate_decompressor.decompress(decoded_data0[2:])\n\n            if decoded_data1 is None and len(decoded_data0) > 0:\n                try:\n                    decoded_data1 = deflate_decompressor.decompress(decoded_data0)\n                    if deflate_decompressor.unused_data != '':\n                        decoded_data1 = None\n                except:\n                    pass\n\n            if decoded_data1:\n                try:\n                    response_headers.pop(b\"Content-Length\", None)\n\n                    if b\"deflate\" in headers.get(b\"Accept-Encoding\", b\"\"):\n                        # return deflate data if accept deflate\n                        response_headers[b\"Content-Encoding\"] = b\"deflate\"\n\n                        send_response_headers()\n                        while True:\n                            wfile.write(decoded_data0)\n                            if response.task.body_readed >= body_length:\n                                break\n                            data = response.task.read()\n                            decoded_data0 = gzip_decompressor.decompress(data)\n                        xlog.info(\"GAE send ungziped deflate data to browser t:%d s:%d %s %s %s\", (time.time() - request_time) * 1000, content_length, method,\n                                  url, response.task.get_trace())\n\n                    else:\n                        # inflate data and send\n                        del response_headers[b\"Content-Encoding\"]\n\n                        send_response_headers()\n                        while True:\n                            wfile.write(decoded_data1)\n                            if response.task.body_readed >= body_length:\n                                break\n                            data = response.task.read()\n                            decoded_data0 = gzip_decompressor.decompress(data)\n                            decoded_data1 = deflate_decompressor.decompress(decoded_data0)\n                        xlog.info(\"GAE send ungziped data to browser t:%d s:%d %s %s %s\", (time.time() - request_time) * 1000, content_length, method,\n                                  url, response.task.get_trace())\n\n                    return\n                except Exception as e:\n                    xlog.exception(\"gae_handler.handler try decode and send response fail. e:%r %s\", e, url)\n                    return\n\n    try:\n        send_response_headers()\n\n        if data0:\n            wfile.write(data0)\n            body_sended = len(data0)\n        else:\n            body_sended = 0\n    except Exception as e:\n        if sys.version_info[0] == 3 and \\\n                (isinstance(e, BrokenPipeError) or\n                 isinstance(e, ConnectionAbortedError) or\n                 isinstance(e, ssl.SSLEOFError)):\n            return\n\n        xlog.exception(\"gae_handler.handler send response fail. e:%r %s\", e, url)\n        return\n\n    while True:\n        # 可能分片发给客户端\n        if body_sended >= body_length:\n            break\n\n        data = response.task.read()\n        if not data:\n            xlog.warn(\"get body fail, until:%d %s\",\n                      body_length - body_sended, url)\n            break\n\n        body_sended += len(data)\n        try:\n            # https 包装\n            ret = wfile.write(data)\n            if ret == ssl.SSL_ERROR_WANT_WRITE or ret == ssl.SSL_ERROR_WANT_READ:\n                #xlog.debug(\"send to browser wfile.write ret:%d\", ret)\n                #ret = wfile.write(data)\n                wfile.write(data)\n        except Exception as e_b:\n            if sys.version_info[0] == 3 and \\\n                    (isinstance(e_b, BrokenPipeError) or isinstance(e_b, ConnectionAbortedError)):\n                return\n\n            if e_b.args[0] in (errno.ECONNABORTED, errno.EPIPE,\n                          errno.ECONNRESET) or 'bad write retry' in repr(e_b):\n                xlog.info('gae_handler send to browser return %r %r, len:%d, sended:%d', e_b, url, body_length, body_sended)\n            else:\n                xlog.info('gae_handler send to browser return %r %r', e_b, url)\n            return\n\n    # 完整一次https请求\n    appid = response.ssl_sock.host.split(\".\")[0]\n    xlog.info(\"GAE t:%d s:%d %s %s %s appid:%s\", (time.time() - request_time) * 1000, content_length, method, url,\n              response.task.get_trace(), appid)\n    return \"ok\"\n\n\nclass RangeFetch2(object):\n\n    all_data_size = {}\n\n    def __init__(self, method, url, headers, body, response, wfile):\n        self.method = method\n        self.wfile = wfile\n        self.url = url\n        self.headers = headers\n        self.body = body\n        self.response = response\n\n        self.keep_running = True\n        self.blocked = False\n\n        self.lock = threading.Lock()\n        self.waiter = threading.Condition(self.lock)\n\n        self.data_list = {}\n        # begin => payload\n        self.data_size = 0\n\n        self.req_begin = 0\n        self.req_end = 0\n        self.wait_begin = 0\n\n    def get_all_buffer_size(self):\n        return sum(v for k, v in list(self.all_data_size.items()))\n\n    def put_data(self, range_begin, payload):\n        with self.lock:\n            if range_begin < self.wait_begin:\n                raise Exception(\"range_begin:%d expect:%d\" %\n                                (range_begin, self.wait_begin))\n\n            self.data_list[range_begin] = payload\n            self.data_size += len(payload)\n            self.all_data_size[self] = self.data_size\n\n            if self.wait_begin in self.data_list:\n                self.waiter.notify()\n\n    def run(self):\n        req_range_begin = None\n        req_range_end = None\n        for k, v in list(self.headers.items()):\n            # xlog.debug(\"range req head:%s => %s\", k, v)\n            if k.lower() == b\"range\":\n                req_range_begin, req_range_end = tuple(\n                    x for x in re.search(br'bytes=(\\d*)-(\\d*)', v).group(1, 2))\n                # break\n\n        response_headers = dict((k.title(), v)\n                                for k, v in list(self.response.headers.items()))\n        content_range = response_headers[b'Content-Range']\n        res_begin, res_end, res_length = tuple(int(x) for x in re.search(\n            br'bytes (\\d+)-(\\d+)/(\\d+)', content_range).group(1, 2, 3))\n\n        self.req_begin = res_end + 1\n        if req_range_begin and req_range_end:\n            self.req_end = int(req_range_end)\n        else:\n            self.req_end = res_length - 1\n        self.wait_begin = res_begin\n\n        if self.wait_begin == 0 and self.req_end == res_length - 1:\n            response_headers[b'Content-Length'] = bytes(str(res_length), encoding='ascii')\n            del response_headers[b'Content-Range']\n            state_code = 200\n        else:\n            response_headers[b'Content-Range'] = b'bytes %d-%d/%d' % (\n                res_begin, self.req_end, res_length)\n            response_headers[b'Content-Length'] = bytes(str(\n                self.req_end - res_begin + 1), encoding='ascii')\n            state_code = 206\n\n        response_headers[b\"Persist\"] = b\"\"\n        response_headers[b\"Connection\"] = b\"Persist\"\n\n        xlog.info('RangeFetch %d-%d started(%r) ',\n                  res_begin, self.req_end, self.url)\n\n        try:\n            self.wfile.write(b\"HTTP/1.1 %d OK\\r\\n\" % state_code)\n            for key in response_headers:\n                if key in skip_response_headers:\n                    continue\n                value = response_headers[key]\n                #xlog.debug(\"Head %s: %s\", key.title(), value)\n                send_header(self.wfile, key, value)\n            self.wfile.write(b\"\\r\\n\")\n        except Exception as e:\n            self.keep_running = False\n            if sys.version_info[0] == 3 and \\\n                    (isinstance(e, BrokenPipeError) or\n                     isinstance(e, ConnectionAbortedError) or\n                     isinstance(e, ssl.SSLEOFError)\n                    ):\n                xlog.warn(\"RangeFetch send response fail:%r %s\", e, self.url)\n                return\n            else:\n                xlog.exception(\"RangeFetch send response fail:%r %s\", e, self.url)\n                return\n\n        data_left_to_fetch = self.req_end - self.req_begin + 1\n        fetch_times = int(\n            (data_left_to_fetch + front.config.AUTORANGE_MAXSIZE - 1) / front.config.AUTORANGE_MAXSIZE)\n        thread_num = min(front.config.AUTORANGE_THREADS, fetch_times)\n        for i in range(0, thread_num):\n            threading.Thread(target=self.fetch_worker, name=\"gae_fetch_work\").start()\n\n        threading.Thread(target=self.fetch, args=(\n            res_begin, res_end, self.response), name=\"gae_fetch\").start()\n\n        ok = \"ok\"\n        while self.keep_running and \\\n                (front.config.use_ipv6 == \"force_ipv6\" and\n                check_local_network.IPv6.is_ok() or\n                front.config.use_ipv6 != \"force_ipv6\" and\n                check_local_network.is_ok()) and \\\n                self.wait_begin < self.req_end + 1:\n            with self.lock:\n                if self.wait_begin not in self.data_list:\n                    self.waiter.wait()\n\n                if self.wait_begin not in self.data_list:\n                    xlog.error(\"get notify but no data\")\n                    continue\n                else:\n                    data = self.data_list[self.wait_begin]\n                    del self.data_list[self.wait_begin]\n                    self.wait_begin += len(data)\n                    self.data_size -= len(data)\n                    self.all_data_size[self] = self.data_size\n\n            try:\n                ret = self.wfile.write(data)\n                if ret == ssl.SSL_ERROR_WANT_WRITE or ret == ssl.SSL_ERROR_WANT_READ:\n                    xlog.debug(\n                        \"send to browser wfile.write ret:%d, retry\", ret)\n                    ret = self.wfile.write(data)\n                    xlog.debug(\"send to browser wfile.write ret:%d\", ret)\n                del data\n            except Exception as e:\n                xlog.info('RangeFetch client closed(%s). %s', e, self.url)\n                ok = None\n                break\n        self.keep_running = False\n        self.all_data_size.pop(self, None)\n        return ok\n\n    def fetch_worker(self):\n        blocked = False\n        while self.keep_running:\n            if blocked:\n                time.sleep(0.5)\n\n            with self.lock:\n                # at least 2 wait workers keep running\n                if self.req_begin > self.wait_begin + front.config.AUTORANGE_MAXSIZE:\n                    if self.get_all_buffer_size() > front.config.AUTORANGE_MAXBUFFERSIZE * (0.8 + len(self.all_data_size) * 0.2):\n                        if not self.blocked:\n                            xlog.debug(\"fetch_worker blocked, buffer:%d %s\",\n                                       self.data_size, self.url)\n                        self.blocked = blocked = True\n                        continue\n                    self.blocked = blocked = False\n\n                if self.req_begin >= self.req_end + 1:\n                    break\n\n                begin = self.req_begin\n                end = min(begin + front.config.AUTORANGE_MAXSIZE - 1, self.req_end)\n                self.req_begin = end + 1\n\n            self.fetch(begin, end, None)\n\n    def fetch(self, begin, end, first_response):\n        headers = dict((k.title(), v) for k, v in list(self.headers.items()))\n        retry_num = 0\n        while self.keep_running:\n            retry_num += 1\n            if retry_num > 20:\n                xlog.warn(\"RangeFetch try max times, exit. %s\", self.url)\n                self.close()\n                break\n\n            expect_len = end - begin + 1\n            headers[b'Range'] = b'bytes=%d-%d' % (begin, end)\n\n            if first_response:\n                response = first_response\n            else:\n                try:\n                    response = request_gae_proxy(\n                        self.method, self.url, headers, self.body)\n                except GAE_Exception as e:\n                    xlog.warning('RangeFetch %s request fail:%r',\n                                 headers[b'Range'], e)\n                    continue\n\n            if response.app_msg:\n                response.worker.close(\n                    \"range get gae status:%d\" % response.app_status)\n                continue\n\n            response.status = response.app_status\n            if response.headers.get(b'Location', None):\n                self.url = urljoin(\n                    self.url, response.headers.get(b'Location'))\n                xlog.warn('RangeFetch Redirect(%r) status:%s',\n                          self.url, response.status)\n                continue\n\n            if response.status >= 300:\n                #xlog.error('RangeFetch %r return %s :%s', self.url, response.status, cgi.escape(response.body))\n                response.worker.close(\"range status:%s\" % response.status)\n                continue\n\n            content_range = response.headers.get(b'Content-Range', b\"\")\n            if not content_range:\n                xlog.warning('RangeFetch \"%s %s\" return headers=%r, retry %s-%s',\n                             self.method, self.url, response.headers, begin, end)\n                # if len(response.body) < 2048:\n                #xlog.warn('body:%s', cgi.escape(response.body))\n                # response.worker.close(\"no range\")\n                continue\n\n            content_length = int(response.headers.get(b'Content-Length', 0))\n\n            data_readed = 0\n            while True:\n                if data_readed >= content_length:\n                    percent = begin * 100 / self.req_end\n\n                    xlog.debug('RangeFetch [%s] %d%% length:%s range:%s %s %s',\n                               response.ssl_sock.ip_str, percent,\n                               content_length, content_range, self.url, response.task.get_trace())\n                    break\n\n                data = response.task.read()\n                if not data:\n                    xlog.warn(\"RangeFetch [%s] get body fail, begin:%d %s\",\n                              response.ssl_sock.ip_str, begin, self.url)\n                    break\n\n                data_len = len(data)\n                data_readed += data_len\n                if data_len > expect_len:\n                    xlog.warn(\"RangeFetch expect:%d, get:%d\",\n                              expect_len, data_len)\n                    data = data[:expect_len]\n                    data_len = expect_len\n\n                self.put_data(begin, data)\n\n                expect_len -= data_len\n                begin += data_len\n\n            if begin >= end + 1:\n                break\n\n            xlog.warn(\"RangeFetch get left, begin:%d end:%d\", begin, end)\n\n    def close(self):\n        self.keep_running = False\n        with self.lock:\n            self.waiter.notify()\n"
  },
  {
    "path": "code/default/gae_proxy/local/host_manager.py",
    "content": "import time\n\nfrom front_base.connect_manager import NoRescourceException\nfrom front_base.host_manager import HostManagerBase\nfrom . sni_manager import SniManager\n\n\nclass HostManager(HostManagerBase):\n    def __init__(self, config, logger):\n        self.config = config\n        self.logger = logger\n        self.appid_manager = None\n\n        self.sni_manager = SniManager(logger)\n\n    def get_host(self):\n        if not self.appid_manager:\n            return \"\"\n\n        appid = self.appid_manager.get()\n        if not appid:\n            self.logger.warn(\"no appid\")\n            time.sleep(10)\n            raise NoRescourceException(\"no appid\")\n\n        return appid + \".appspot.com\"\n\n    def get_sni_host(self, ip):\n        sni = self.sni_manager.get()\n        host = self.get_host()\n\n        return sni, host\n\n"
  },
  {
    "path": "code/default/gae_proxy/local/http2_connection.py",
    "content": "\nfrom front_base.http2_connection import Http2Worker\n\n\nclass GaeHttp2Worker(Http2Worker):\n    def __init__(self, logger, ip_manager, config, ssl_sock, close_cb, retry_task_cb, idle_cb, log_debug_data,\n                 stream_class=None):\n        super(GaeHttp2Worker, self).__init__(logger, ip_manager, config, ssl_sock, close_cb, retry_task_cb, idle_cb,\n                                             log_debug_data)\n\n    def get_host(self, task_host):\n        return self.ssl_sock.host"
  },
  {
    "path": "code/default/gae_proxy/local/ip_list.txt",
    "content": ""
  },
  {
    "path": "code/default/gae_proxy/local/ip_range.old",
    "content": "1.9.22.0-1.9.22.255\n1.9.24.0-1.9.24.255\n1.9.57.0-1.9.57.255\n1.9.91.0-1.9.91.255\n1.9.131.0-1.9.131.255\n1.54.236.0-1.54.236.255\n1.255.22.0-1.255.22.255\n1.255.33.0-1.255.33.255\n2.78.40.0-2.78.41.255\n2.78.44.0-2.78.45.255\n2.78.47.0-2.78.47.255\n2.127.237.0-2.127.237.255\n2.127.251.0-2.127.251.255\n4.31.38.0-4.31.38.255\n4.31.115.0-4.31.115.255\n4.31.144.0-4.31.144.255\n4.34.16.0-4.34.16.255\n4.35.2.0-4.35.2.255\n4.35.21.0-4.35.21.255\n4.35.108.0-4.35.108.255\n4.35.153.0-4.35.153.255\n4.53.36.0-4.53.36.255\n4.53.56.0-4.53.56.255\n4.53.79.0-4.53.79.255\n4.53.166.0-4.53.166.255\n4.53.202.0-4.53.202.255\n4.59.40.0-4.59.40.255\n4.59.67.0-4.59.67.255\n4.59.90.0-4.59.90.255\n4.59.126.0-4.59.126.255\n5.10.226.0-5.10.226.255\n5.17.192.0-5.17.192.255\n5.20.5.0-5.20.5.255\n5.21.229.0-5.21.230.255\n5.22.190.0-5.22.190.255\n5.44.5.0-5.44.5.255\n5.44.32.0-5.44.32.255\n5.44.36.0-5.44.36.255\n5.62.128.0-5.62.129.255\n5.63.167.0-5.63.167.255\n5.102.167.0-5.102.167.255\n5.102.252.0-5.102.252.255\n5.149.101.0-5.149.103.255\n5.157.98.0-5.157.98.255\n5.158.127.0-5.158.127.255\n5.191.12.0-5.191.12.255\n5.226.127.0-5.226.127.255\n8.8.4.0-8.8.4.255\n8.8.8.0-8.8.8.255\n8.35.80.0-8.35.80.255\n14.1.102.0-14.1.102.255\n14.102.170.0-14.102.170.255\n14.192.150.0-14.192.150.255\n23.28.251.0-23.28.251.255\n23.228.129.0-23.228.130.255\n23.235.0.0-23.235.0.255\n23.236.5.0-23.236.5.255\n23.255.240.0-23.255.242.255\n23.255.245.0-23.255.245.255\n24.35.3.0-24.35.3.255\n24.35.137.0-24.35.137.255\n24.41.214.0-24.41.214.255\n24.51.113.0-24.51.113.255\n24.53.238.0-24.53.238.255\n24.56.144.0-24.56.144.255\n24.96.139.0-24.96.139.255\n24.100.187.0-24.100.187.255\n24.116.134.0-24.116.134.255\n24.124.1.0-24.124.1.255\n24.137.105.0-24.137.105.255\n24.140.3.0-24.140.3.255\n24.149.5.0-24.149.5.255\n24.154.57.0-24.154.57.255\n24.155.92.0-24.155.92.255\n24.156.131.0-24.156.131.255\n24.207.9.0-24.207.9.255\n24.214.95.0-24.214.95.255\n24.220.112.0-24.220.112.255\n24.225.16.0-24.225.16.255\n24.226.15.0-24.226.16.255\n24.244.4.0-24.244.4.255\n24.244.14.0-24.244.14.255\n24.244.19.0-24.244.19.255\n24.244.39.0-24.244.39.255\n24.246.130.0-24.246.130.255\n27.2.194.0-27.2.194.255\n27.2.226.0-27.2.226.255\n27.80.250.0-27.80.250.255\n27.85.180.0-27.85.181.255\n27.90.140.0-27.90.143.255\n27.90.189.0-27.90.189.255\n27.100.64.0-27.100.64.255\n27.106.94.0-27.106.94.255\n27.116.252.0-27.116.252.255\n27.121.46.0-27.121.46.255\n27.121.51.0-27.121.51.255\n27.121.54.0-27.121.54.255\n27.123.17.0-27.123.17.255\n27.123.130.0-27.123.130.255\n27.131.16.0-27.131.16.255\n31.7.161.0-31.7.161.255\n31.24.56.0-31.24.56.255\n31.25.141.0-31.25.141.255\n31.31.48.0-31.31.48.255\n31.46.22.0-31.46.22.255\n31.47.193.0-31.47.193.255\n31.55.162.0-31.55.163.255\n31.55.166.0-31.55.167.255\n31.129.192.0-31.129.192.255\n31.132.191.0-31.132.191.255\n31.132.224.0-31.132.224.255\n31.172.32.0-31.172.32.255\n31.173.129.0-31.173.129.255\n31.173.164.0-31.173.164.255\n31.173.166.0-31.173.166.255\n31.173.227.0-31.173.227.255\n31.186.176.0-31.186.176.255\n31.209.137.0-31.209.137.255\n31.210.208.0-31.210.208.255\n31.211.30.0-31.211.30.255\n31.211.248.0-31.211.248.255\n36.37.218.0-36.37.218.255\n37.8.144.0-37.8.144.255\n37.18.13.0-37.18.13.255\n37.18.153.0-37.18.153.255\n37.26.145.0-37.26.145.255\n37.29.1.0-37.29.1.255\n37.29.18.0-37.29.18.255\n37.44.42.0-37.44.42.255\n37.58.167.0-37.58.167.255\n37.60.16.0-37.60.17.255\n37.75.192.0-37.75.192.255\n37.77.53.0-37.77.53.255\n37.98.229.0-37.98.229.255\n37.98.242.0-37.98.242.255\n37.99.5.0-37.99.5.255\n37.99.77.0-37.99.77.255\n37.139.254.0-37.139.254.255\n37.151.45.0-37.151.45.255\n37.152.2.0-37.152.2.255\n37.236.115.0-37.236.115.255\n37.236.167.0-37.236.167.255\n37.236.223.0-37.236.223.255\n37.237.119.0-37.237.119.255\n37.238.127.0-37.238.127.255\n37.238.239.0-37.238.239.255\n37.238.247.0-37.238.247.255\n37.238.252.0-37.238.252.255\n37.239.119.0-37.239.119.255\n37.239.240.0-37.239.246.255\n37.239.252.0-37.239.254.255\n40.129.40.0-40.129.40.255\n40.130.0.0-40.130.0.255\n40.133.6.0-40.133.6.255\n40.135.136.0-40.135.136.255\n40.136.3.0-40.136.3.255\n40.136.10.0-40.136.10.255\n40.136.59.0-40.136.59.255\n40.137.34.0-40.137.34.255\n40.137.237.0-40.137.237.255\n40.138.0.0-40.138.0.255\n41.21.236.0-41.21.236.255\n41.74.24.0-41.74.24.255\n41.77.223.0-41.77.223.255\n41.84.195.0-41.84.195.255\n41.91.252.0-41.91.254.255\n41.128.200.0-41.128.200.255\n41.128.203.0-41.128.203.255\n41.160.35.0-41.160.35.255\n41.184.60.0-41.184.60.255\n41.187.111.0-41.187.111.255\n41.189.63.0-41.189.63.255\n41.189.230.0-41.189.230.255\n41.191.219.0-41.191.219.255\n41.201.128.0-41.201.129.255\n41.201.164.0-41.201.164.255\n41.205.32.0-41.205.32.255\n41.206.47.0-41.206.47.255\n41.206.96.0-41.206.96.255\n41.216.127.0-41.216.127.255\n41.219.127.0-41.219.127.255\n41.220.75.0-41.220.75.255\n41.221.166.0-41.221.166.255\n41.221.196.0-41.221.196.255\n41.223.219.0-41.223.219.255\n42.104.120.0-42.104.120.255\n42.106.160.0-42.106.160.255\n42.112.8.0-42.112.11.255\n42.116.237.0-42.116.237.255\n42.117.10.0-42.117.10.255\n42.119.208.0-42.119.211.255\n42.119.253.0-42.119.253.255\n42.125.225.0-42.125.225.255\n42.153.4.0-42.153.4.255\n42.153.8.0-42.153.8.255\n43.228.209.0-43.228.209.255\n43.230.130.0-43.230.130.255\n43.240.231.0-43.240.231.255\n43.243.38.0-43.243.38.255\n43.243.212.0-43.243.212.255\n43.245.104.0-43.245.104.255\n43.245.142.0-43.245.142.255\n43.245.144.0-43.245.145.255\n43.245.193.0-43.245.193.255\n43.245.195.0-43.245.195.255\n43.245.200.0-43.245.201.255\n43.245.232.0-43.245.232.255\n43.247.158.0-43.247.158.255\n43.250.82.0-43.250.82.255\n43.250.167.0-43.250.167.255\n43.252.16.0-43.252.16.255\n43.255.113.0-43.255.113.255\n45.64.20.0-45.64.20.255\n45.64.28.0-45.64.31.255\n45.64.34.0-45.64.35.255\n45.64.76.0-45.64.76.255\n45.64.138.0-45.64.138.255\n45.64.253.0-45.64.253.255\n45.112.179.0-45.112.179.255\n45.115.55.0-45.115.55.255\n45.115.98.0-45.115.98.255\n45.115.252.0-45.115.252.255\n45.116.219.0-45.116.219.255\n45.116.232.0-45.116.233.255\n45.117.75.0-45.117.75.255\n45.118.245.0-45.118.245.255\n45.120.84.0-45.120.85.255\n45.121.219.0-45.121.219.255\n45.122.234.0-45.122.234.255\n45.123.27.0-45.123.27.255\n45.125.68.0-45.125.68.255\n45.127.244.0-45.127.244.255\n45.251.32.0-45.251.32.255\n45.251.78.0-45.251.78.255\n46.8.148.0-46.8.148.255\n46.21.52.0-46.21.52.255\n46.29.169.0-46.29.169.255\n46.32.101.0-46.32.101.255\n46.32.222.0-46.32.222.255\n46.36.26.0-46.36.26.255\n46.39.3.0-46.39.3.255\n46.42.1.0-46.42.1.255\n46.42.80.0-46.42.80.255\n46.42.84.0-46.42.84.255\n46.47.1.0-46.47.1.255\n46.48.32.0-46.48.32.255\n46.61.155.0-46.61.155.255\n46.61.244.0-46.61.244.255\n46.97.101.0-46.97.101.255\n46.134.193.0-46.134.193.255\n46.134.208.0-46.134.208.255\n46.149.88.0-46.149.88.255\n46.151.240.0-46.151.240.255\n46.162.192.0-46.162.192.255\n46.165.2.0-46.165.2.255\n46.191.224.0-46.191.224.255\n46.227.113.0-46.227.113.255\n46.229.224.0-46.229.224.255\n46.236.127.0-46.236.127.255\n46.249.239.0-46.249.239.255\n46.252.111.0-46.252.111.255\n46.252.175.0-46.252.175.255\n49.44.49.0-49.44.49.255\n49.44.67.0-49.44.67.255\n49.44.76.0-49.44.76.255\n49.44.78.0-49.44.78.255\n49.44.80.0-49.44.87.255\n49.98.24.0-49.98.25.255\n49.98.35.0-49.98.35.255\n49.106.234.0-49.106.234.255\n49.231.55.0-49.231.56.255\n49.231.58.0-49.231.58.255\n49.231.60.0-49.231.60.255\n49.231.113.0-49.231.113.255\n49.243.141.0-49.243.141.255\n50.0.2.0-50.0.2.255\n50.27.150.0-50.27.150.255\n50.27.154.0-50.27.154.255\n50.38.0.0-50.38.0.255\n50.86.10.0-50.86.10.255\n58.26.8.0-58.26.8.255\n58.27.27.0-58.27.27.255\n58.27.108.0-58.27.109.255\n58.28.64.0-58.28.64.255\n58.97.143.0-58.97.143.255\n58.123.102.0-58.123.102.255\n58.123.220.0-58.123.220.255\n58.162.62.0-58.162.62.255\n58.176.217.0-58.176.217.255\n58.229.92.0-58.229.92.255\n59.18.34.0-59.18.35.255\n59.18.44.0-59.18.46.255\n59.18.49.0-59.18.49.255\n59.20.132.0-59.20.132.255\n59.152.110.0-59.152.110.255\n59.153.102.0-59.153.102.255\n59.190.145.0-59.190.145.255\n60.199.175.0-60.199.175.255\n61.4.66.0-61.4.67.255\n61.5.222.0-61.5.222.255\n61.7.18.0-61.7.18.255\n61.19.1.0-61.19.2.255\n61.33.130.0-61.33.130.255\n61.37.150.0-61.37.150.255\n61.58.64.0-61.58.64.255\n61.62.98.0-61.62.98.255\n61.86.203.0-61.86.203.255\n61.89.217.0-61.89.217.255\n61.90.179.0-61.90.179.255\n61.90.189.0-61.90.189.255\n61.91.8.0-61.91.9.255\n61.91.16.0-61.91.19.255\n61.91.160.0-61.91.161.255\n61.114.99.0-61.114.99.255\n61.122.213.0-61.122.213.255\n61.205.118.0-61.205.118.255\n61.205.127.0-61.205.127.255\n61.219.131.0-61.219.131.255\n61.219.146.0-61.219.146.255\n61.238.203.0-61.238.203.255\n61.238.239.0-61.238.239.255\n62.0.80.0-62.0.80.255\n62.1.38.0-62.1.38.255\n62.4.253.0-62.4.253.255\n62.8.95.0-62.8.95.255\n62.24.158.0-62.24.158.255\n62.38.6.0-62.38.6.255\n62.68.246.0-62.68.246.255\n62.75.10.0-62.75.10.255\n62.75.23.0-62.75.23.255\n62.78.83.0-62.78.83.255\n62.78.98.0-62.78.98.255\n62.84.6.0-62.84.6.255\n62.84.32.0-62.84.32.255\n62.84.90.0-62.84.90.255\n62.94.9.0-62.94.9.255\n62.101.158.0-62.101.158.255\n62.117.4.0-62.117.4.255\n62.133.128.0-62.133.128.255\n62.140.228.0-62.140.228.255\n62.149.79.0-62.149.79.255\n62.164.169.0-62.164.169.255\n62.168.125.0-62.168.125.255\n62.176.13.0-62.176.13.255\n62.197.198.0-62.197.198.255\n62.201.204.0-62.201.204.255\n62.201.216.0-62.201.216.255\n62.201.225.0-62.201.225.255\n62.209.24.0-62.209.24.255\n62.209.30.0-62.209.30.255\n62.212.33.0-62.212.33.255\n62.212.252.0-62.212.252.255\n62.214.62.0-62.214.62.255\n62.231.75.0-62.231.75.255\n62.231.91.0-62.231.91.255\n62.240.120.0-62.240.120.255\n62.243.26.0-62.243.26.255\n62.252.60.0-62.252.60.255\n62.252.169.0-62.252.170.255\n62.252.173.0-62.252.173.255\n62.252.191.0-62.252.191.255\n62.252.232.0-62.252.232.255\n62.253.3.0-62.253.3.255\n62.253.72.0-62.253.72.255\n63.84.3.0-63.84.3.255\n63.88.73.0-63.88.73.255\n63.117.14.0-63.117.14.255\n63.117.68.0-63.117.68.255\n63.117.215.0-63.117.215.255\n63.135.48.0-63.135.48.255\n63.143.72.0-63.143.72.255\n64.4.226.0-64.4.226.255\n64.9.227.0-64.9.229.255\n64.9.240.0-64.9.243.255\n64.15.112.0-64.15.121.255\n64.15.124.0-64.15.127.255\n64.20.30.0-64.20.30.255\n64.39.140.0-64.39.140.255\n64.53.1.0-64.53.1.255\n64.53.59.0-64.53.59.255\n64.53.242.0-64.53.242.255\n64.53.251.0-64.53.251.255\n64.71.249.0-64.71.249.255\n64.90.64.0-64.90.64.255\n64.118.108.0-64.118.108.255\n64.119.206.0-64.119.206.255\n64.126.1.0-64.126.1.255\n64.147.91.0-64.147.91.255\n64.178.237.0-64.178.237.255\n64.184.109.0-64.184.109.255\n64.203.194.0-64.203.194.255\n64.233.160.0-64.233.171.255\n64.233.176.0-64.233.191.255\n64.246.133.0-64.246.133.255\n64.251.160.0-64.251.160.255\n64.253.221.0-64.253.221.255\n65.19.82.0-65.19.82.255\n65.39.199.0-65.39.199.255\n65.48.146.0-65.48.146.255\n65.49.173.0-65.49.173.255\n65.60.171.0-65.60.171.255\n65.79.192.0-65.79.192.255\n65.87.229.0-65.87.229.255\n65.116.15.0-65.116.15.255\n65.183.12.0-65.183.12.255\n65.199.32.0-65.199.32.255\n65.199.248.0-65.199.248.255\n66.37.74.0-66.37.74.255\n66.38.63.0-66.38.63.255\n66.44.205.0-66.44.205.255\n66.54.121.0-66.54.121.255\n66.58.255.0-66.58.255.255\n66.76.28.0-66.76.28.255\n66.76.34.0-66.76.34.255\n66.76.194.0-66.76.194.255\n66.96.224.0-66.96.224.255\n66.96.226.0-66.96.226.255\n66.97.30.0-66.97.30.255\n66.102.1.0-66.102.1.255\n66.102.12.0-66.102.12.255\n66.112.178.0-66.112.178.255\n66.130.90.0-66.130.90.255\n66.152.103.0-66.152.103.255\n66.153.250.0-66.153.250.255\n66.159.33.0-66.159.33.255\n66.171.0.0-66.171.0.255\n66.171.92.0-66.171.92.255\n66.185.84.0-66.185.84.255\n66.186.226.0-66.186.226.255\n66.187.114.0-66.187.114.255\n66.199.151.0-66.199.151.255\n66.201.170.0-66.201.170.255\n66.203.176.0-66.203.176.255\n66.226.125.0-66.226.125.255\n66.244.74.0-66.244.74.255\n66.248.191.0-66.248.191.255\n66.253.131.0-66.253.131.255\n66.253.203.0-66.253.203.255\n67.21.145.0-67.21.145.255\n67.50.19.0-67.50.19.255\n67.89.227.0-67.89.227.255\n67.149.209.0-67.149.209.255\n67.204.184.0-67.204.184.255\n67.212.255.0-67.212.255.255\n67.215.19.0-67.215.19.255\n67.218.56.0-67.218.56.255\n67.218.93.0-67.218.93.255\n67.219.192.0-67.219.192.255\n67.219.201.0-67.219.201.255\n67.221.143.0-67.221.143.255\n67.221.221.0-67.221.221.255\n67.224.250.0-67.224.250.255\n68.65.124.0-68.65.124.255\n69.8.160.0-69.8.160.255\n69.9.127.0-69.9.127.255\n69.46.66.0-69.46.66.255\n69.51.73.0-69.51.73.255\n69.59.197.0-69.59.197.255\n69.63.167.0-69.63.167.255\n69.65.64.0-69.65.64.255\n69.77.145.0-69.77.145.255\n69.79.200.0-69.79.200.255\n69.85.196.0-69.85.196.255\n69.147.192.0-69.147.192.255\n69.160.212.0-69.160.212.255\n69.176.0.0-69.176.1.255\n69.195.30.0-69.195.30.255\n70.34.140.0-70.34.140.255\n70.40.189.0-70.40.189.255\n70.186.10.0-70.186.10.255\n70.186.24.0-70.186.24.255\n70.186.26.0-70.186.26.255\n70.186.28.0-70.186.28.255\n70.186.30.0-70.186.30.255\n71.19.173.0-71.19.173.255\n71.19.176.0-71.19.176.255\n72.22.27.0-72.22.27.255\n72.36.125.0-72.36.125.255\n72.46.62.0-72.46.62.255\n72.47.61.0-72.47.61.255\n72.50.12.0-72.50.12.255\n72.50.240.0-72.50.240.255\n72.195.166.0-72.195.166.255\n72.234.39.0-72.234.39.255\n72.240.108.0-72.240.108.255\n74.50.44.0-74.50.44.255\n74.51.15.0-74.51.15.255\n74.51.119.0-74.51.119.255\n74.51.221.0-74.51.221.255\n74.81.99.0-74.81.99.255\n74.124.63.0-74.124.63.255\n74.125.0.0-74.125.1.255\n74.125.3.0-74.125.15.255\n74.125.21.0-74.125.24.255\n74.125.26.0-74.125.26.255\n74.125.28.0-74.125.31.255\n74.125.68.0-74.125.71.255\n74.125.96.0-74.125.97.255\n74.125.100.0-74.125.100.255\n74.125.102.0-74.125.108.255\n74.125.110.0-74.125.111.255\n74.125.124.0-74.125.124.255\n74.125.126.0-74.125.136.255\n74.125.138.0-74.125.141.255\n74.125.143.0-74.125.143.255\n74.125.152.0-74.125.174.255\n74.125.192.0-74.125.193.255\n74.125.196.0-74.125.206.255\n74.125.230.0-74.125.230.255\n74.125.232.0-74.125.232.255\n74.125.238.0-74.125.238.255\n74.205.129.0-74.205.129.255\n74.213.193.0-74.213.193.255\n74.216.233.0-74.216.233.255\n75.76.44.0-75.76.44.255\n76.73.145.0-76.73.145.255\n76.73.150.0-76.73.150.255\n76.75.38.0-76.75.38.255\n76.165.14.0-76.165.14.255\n77.37.252.0-77.37.252.255\n77.42.249.0-77.42.249.255\n77.42.253.0-77.42.253.255\n77.50.2.0-77.50.2.255\n77.53.0.0-77.53.0.255\n77.66.9.0-77.66.9.255\n77.67.49.0-77.67.49.255\n77.68.246.0-77.68.246.255\n77.68.251.0-77.68.251.255\n77.77.7.0-77.77.7.255\n77.77.195.0-77.77.195.255\n77.82.149.0-77.82.149.255\n77.87.99.0-77.87.99.255\n77.88.221.0-77.88.221.255\n77.94.162.0-77.94.162.255\n77.95.65.0-77.95.65.255\n77.153.128.0-77.153.130.255\n77.154.206.0-77.154.206.255\n77.154.221.0-77.154.221.255\n77.154.227.0-77.154.228.255\n77.214.52.0-77.214.53.255\n77.232.162.0-77.232.162.255\n77.234.90.0-77.234.91.255\n77.235.7.0-77.235.7.255\n77.235.22.0-77.235.22.255\n77.237.27.0-77.237.27.255\n77.239.64.0-77.239.64.255\n77.244.17.0-77.244.17.255\n77.252.2.0-77.252.2.255\n78.11.253.0-78.11.253.255\n78.37.65.0-78.37.65.255\n78.37.100.0-78.37.100.255\n78.37.112.0-78.37.112.255\n78.40.178.0-78.40.178.255\n78.111.248.0-78.111.248.255\n78.111.255.0-78.111.255.255\n78.136.92.0-78.136.92.255\n78.159.164.0-78.159.164.255\n79.98.8.0-79.98.8.255\n79.101.110.0-79.101.111.255\n79.106.107.0-79.106.107.255\n79.121.0.0-79.121.0.255\n79.134.0.0-79.134.1.255\n79.134.129.0-79.134.129.255\n79.136.239.0-79.136.239.255\n79.171.121.0-79.171.121.255\n79.171.163.0-79.171.163.255\n79.173.80.0-79.173.80.255\n79.173.126.0-79.173.126.255\n80.64.175.0-80.64.175.255\n80.67.208.0-80.67.208.255\n80.70.231.0-80.70.231.255\n80.76.174.0-80.76.174.255\n80.77.169.0-80.77.169.255\n80.80.161.0-80.80.161.255\n80.83.28.0-80.83.28.255\n80.83.240.0-80.83.240.255\n80.88.243.0-80.88.243.255\n80.91.176.0-80.91.176.255\n80.93.31.0-80.93.31.255\n80.96.255.0-80.96.255.255\n80.97.208.0-80.97.208.255\n80.202.12.0-80.202.12.255\n80.228.66.0-80.228.66.255\n80.233.168.0-80.233.168.255\n80.252.129.0-80.252.129.255\n80.252.131.0-80.252.131.255\n80.253.19.0-80.253.19.255\n80.253.29.0-80.253.30.255\n80.254.96.0-80.254.96.255\n81.3.201.0-81.3.201.255\n81.5.81.0-81.5.81.255\n81.10.128.0-81.10.128.255\n81.17.82.0-81.17.82.255\n81.20.240.0-81.20.240.255\n81.24.29.0-81.24.29.255\n81.30.226.0-81.30.226.255\n81.88.148.0-81.88.148.255\n81.163.63.0-81.163.63.255\n81.167.38.0-81.167.38.255\n81.175.29.0-81.175.29.255\n81.177.123.0-81.177.123.255\n81.180.120.0-81.180.120.255\n81.192.190.0-81.192.191.255\n81.200.2.0-81.200.3.255\n81.209.95.0-81.209.95.255\n81.218.16.0-81.218.16.255\n82.76.79.0-82.76.79.255\n82.77.159.0-82.77.159.255\n82.85.138.0-82.85.138.255\n82.94.228.0-82.94.228.255\n82.94.234.0-82.94.234.255\n82.102.155.0-82.102.155.255\n82.102.181.0-82.102.181.255\n82.102.187.0-82.102.187.255\n82.112.161.0-82.112.161.255\n82.113.19.0-82.113.19.255\n82.114.163.0-82.114.163.255\n82.117.119.0-82.117.119.255\n82.129.128.0-82.129.128.255\n82.129.130.0-82.129.130.255\n82.135.118.0-82.135.118.255\n82.147.54.0-82.147.54.255\n82.148.98.0-82.148.98.255\n82.148.105.0-82.148.105.255\n82.148.110.0-82.148.110.255\n82.148.119.0-82.148.119.255\n82.148.124.0-82.148.124.255\n82.193.82.0-82.193.82.255\n82.194.0.0-82.194.0.255\n82.206.179.0-82.206.179.255\n82.212.91.0-82.212.91.255\n82.221.224.0-82.221.224.255\n83.94.121.0-83.94.121.255\n83.100.221.0-83.100.221.255\n83.139.106.0-83.139.106.255\n83.140.66.0-83.140.66.255\n83.142.166.0-83.142.166.255\n83.167.19.0-83.167.19.255\n83.167.64.0-83.167.64.255\n83.169.197.0-83.169.197.255\n83.174.196.0-83.174.196.255\n83.174.198.0-83.174.198.255\n83.175.145.0-83.175.145.255\n83.219.135.0-83.219.135.255\n83.233.10.0-83.233.10.255\n83.233.164.0-83.233.164.255\n83.255.235.0-83.255.235.255\n84.15.64.0-84.15.64.255\n84.39.249.0-84.39.249.255\n84.46.102.0-84.46.102.255\n84.54.161.0-84.54.161.255\n84.208.42.0-84.208.42.255\n84.235.58.0-84.235.58.255\n84.235.77.0-84.235.77.255\n84.240.234.0-84.240.234.255\n84.244.62.0-84.244.62.255\n85.14.28.0-85.14.28.255\n85.91.7.0-85.91.7.255\n85.112.116.0-85.112.117.255\n85.112.121.0-85.112.121.255\n85.113.32.0-85.113.32.255\n85.114.126.0-85.114.126.255\n85.114.182.0-85.114.182.255\n85.118.123.0-85.118.123.255\n85.134.33.0-85.134.33.255\n85.158.132.0-85.158.132.255\n85.172.1.0-85.172.1.255\n85.182.250.0-85.182.250.255\n85.187.222.0-85.187.222.255\n85.194.196.0-85.194.198.255\n85.194.249.0-85.194.250.255\n85.233.229.0-85.233.229.255\n85.234.4.0-85.234.4.255\n85.239.127.0-85.239.127.255\n86.38.6.0-86.38.6.255\n86.51.24.0-86.51.24.255\n86.60.255.0-86.60.255.255\n86.62.126.0-86.62.126.255\n87.76.32.0-87.76.32.255\n87.79.22.0-87.79.22.255\n87.119.3.0-87.119.3.255\n87.126.158.0-87.126.158.255\n87.226.176.0-87.226.176.255\n87.229.142.0-87.229.142.255\n87.229.144.0-87.229.144.255\n87.245.195.0-87.245.198.255\n87.245.200.0-87.245.200.255\n88.87.68.0-88.87.68.255\n88.201.14.0-88.201.15.255\n88.204.142.0-88.204.142.255\n88.212.9.0-88.212.9.255\n88.216.174.0-88.216.174.255\n88.217.135.0-88.217.135.255\n88.222.2.0-88.222.2.255\n89.25.120.0-89.25.120.255\n89.25.215.0-89.25.215.255\n89.47.210.0-89.47.210.255\n89.127.198.0-89.127.198.255\n89.185.72.0-89.185.72.255\n89.187.219.0-89.187.219.255\n89.189.161.0-89.189.161.255\n89.201.175.0-89.201.175.255\n89.212.69.0-89.212.69.255\n89.218.72.0-89.218.72.255\n89.221.194.0-89.221.194.255\n89.221.200.0-89.221.201.255\n89.228.4.0-89.228.4.255\n89.250.0.0-89.250.0.255\n90.150.4.0-90.150.4.255\n90.150.80.0-90.150.80.255\n90.150.83.0-90.150.83.255\n90.157.127.0-90.157.127.255\n90.189.105.0-90.189.105.255\n90.201.124.0-90.201.124.255\n90.211.177.0-90.211.177.255\n90.222.188.0-90.222.188.255\n90.223.244.0-90.223.244.255\n91.103.72.0-91.103.72.255\n91.106.37.0-91.106.37.255\n91.142.149.0-91.142.149.255\n91.144.134.0-91.144.134.255\n91.144.138.0-91.144.138.255\n91.144.157.0-91.144.157.255\n91.144.165.0-91.144.165.255\n91.184.109.0-91.184.109.255\n91.185.2.0-91.185.2.255\n91.185.4.0-91.185.4.255\n91.185.100.0-91.185.100.255\n91.189.221.0-91.189.221.255\n91.192.65.0-91.192.65.255\n91.192.67.0-91.192.67.255\n91.195.131.0-91.195.131.255\n91.202.206.0-91.202.206.255\n91.202.254.0-91.202.254.255\n91.204.136.0-91.204.136.255\n91.204.176.0-91.204.176.255\n91.205.69.0-91.205.69.255\n91.211.58.0-91.211.58.255\n91.213.30.0-91.213.30.255\n91.214.215.0-91.214.215.255\n91.218.4.0-91.218.5.255\n91.219.138.0-91.219.138.255\n91.226.120.0-91.226.120.255\n91.229.148.0-91.229.148.255\n91.230.210.0-91.230.210.255\n91.232.101.0-91.232.101.255\n91.235.179.0-91.235.180.255\n91.240.80.0-91.240.80.255\n91.245.214.0-91.245.214.255\n91.246.119.0-91.246.119.255\n91.247.2.0-91.247.2.255\n92.46.47.0-92.46.47.255\n92.46.70.0-92.46.70.255\n92.51.99.0-92.51.99.255\n92.62.75.0-92.62.75.255\n92.87.11.0-92.87.11.255\n92.87.156.0-92.87.156.255\n92.87.232.0-92.87.232.255\n92.126.121.0-92.126.121.255\n92.126.123.0-92.126.123.255\n92.126.155.0-92.126.155.255\n92.226.2.0-92.226.2.255\n92.244.237.0-92.244.237.255\n92.246.5.0-92.246.5.255\n92.246.12.0-92.246.12.255\n93.57.114.0-93.57.114.255\n93.62.101.0-93.62.101.255\n93.87.90.0-93.87.90.255\n93.88.163.0-93.88.164.255\n93.89.223.0-93.89.223.255\n93.90.210.0-93.90.210.255\n93.91.155.0-93.91.155.255\n93.91.193.0-93.91.193.255\n93.100.204.0-93.100.204.255\n93.123.23.0-93.123.23.255\n93.123.128.0-93.123.128.255\n93.183.211.0-93.183.211.255\n93.184.1.0-93.184.1.255\n93.186.108.0-93.186.108.255\n93.191.15.0-93.191.15.255\n94.20.252.0-94.20.252.255\n94.21.255.0-94.21.255.255\n94.24.228.0-94.24.228.255\n94.24.237.0-94.24.237.255\n94.25.137.0-94.25.137.255\n94.25.217.0-94.25.217.255\n94.31.189.0-94.31.189.255\n94.53.12.0-94.53.12.255\n94.79.46.0-94.79.46.255\n94.100.228.0-94.100.228.255\n94.128.0.0-94.128.0.255\n94.128.4.0-94.128.4.255\n94.128.13.0-94.128.13.255\n94.128.254.0-94.128.254.255\n94.129.129.0-94.129.131.255\n94.129.254.0-94.129.254.255\n94.137.63.0-94.137.63.255\n94.140.255.0-94.140.255.255\n94.142.38.0-94.142.38.255\n94.143.40.0-94.143.40.255\n94.156.188.0-94.156.188.255\n94.190.64.0-94.190.64.255\n94.190.68.0-94.190.68.255\n94.228.16.0-94.228.16.255\n94.228.193.0-94.228.193.255\n94.228.205.0-94.228.205.255\n94.230.91.0-94.230.91.255\n94.230.140.0-94.230.140.255\n94.231.129.0-94.231.129.255\n94.232.220.0-94.232.220.255\n94.245.201.0-94.245.201.255\n94.247.63.0-94.247.63.255\n94.255.0.0-94.255.0.255\n95.30.216.0-95.30.219.255\n95.54.196.0-95.54.196.255\n95.57.218.0-95.57.218.255\n95.59.126.0-95.59.126.255\n95.66.1.0-95.66.1.255\n95.66.10.0-95.66.10.255\n95.67.12.0-95.67.12.255\n95.83.191.0-95.83.191.255\n95.107.145.0-95.107.145.255\n95.143.84.0-95.143.84.255\n95.154.114.0-95.154.114.255\n95.158.47.0-95.158.47.255\n95.158.130.0-95.158.130.255\n95.159.73.0-95.159.73.255\n95.161.237.0-95.161.237.255\n95.168.222.0-95.168.222.255\n95.170.192.0-95.170.192.255\n95.170.194.0-95.170.194.255\n95.180.157.0-95.180.157.255\n95.181.16.0-95.181.16.255\n95.189.102.0-95.189.102.255\n95.189.122.0-95.189.122.255\n95.209.200.0-95.209.200.255\n96.4.190.0-96.4.190.255\n96.5.123.0-96.5.123.255\n96.9.91.0-96.9.91.255\n96.20.0.0-96.20.0.255\n96.21.0.0-96.21.0.255\n96.23.20.0-96.23.20.255\n96.27.183.0-96.27.183.255\n96.30.112.0-96.30.112.255\n96.31.1.0-96.31.1.255\n96.43.49.0-96.43.49.255\n96.47.87.0-96.47.87.255\n96.63.131.0-96.63.131.255\n96.127.240.0-96.127.240.255\n96.127.250.0-96.127.250.255\n97.75.181.0-97.75.181.255\n98.124.44.0-98.124.44.255\n101.53.58.0-101.53.58.255\n101.78.13.0-101.78.13.255\n101.96.118.0-101.96.118.255\n101.98.9.0-101.98.9.255\n101.99.2.0-101.99.2.255\n101.99.49.0-101.99.49.255\n101.100.179.0-101.100.179.255\n101.100.190.0-101.100.190.255\n101.203.171.0-101.203.171.255\n103.1.139.0-103.1.139.255\n103.2.116.0-103.2.116.255\n103.3.32.0-103.3.32.255\n103.4.110.0-103.4.110.255\n103.5.34.0-103.5.35.255\n103.7.78.0-103.7.78.255\n103.7.249.0-103.7.249.255\n103.9.105.0-103.9.105.255\n103.9.112.0-103.9.112.255\n103.10.20.0-103.10.20.255\n103.10.65.0-103.10.65.255\n103.10.67.0-103.10.67.255\n103.11.28.0-103.11.28.255\n103.11.60.0-103.11.62.255\n103.12.72.0-103.12.72.255\n103.12.172.0-103.12.172.255\n103.12.179.0-103.12.179.255\n103.12.237.0-103.12.237.255\n103.13.116.0-103.13.116.255\n103.13.250.0-103.13.250.255\n103.15.42.0-103.15.42.255\n103.15.61.0-103.15.61.255\n103.15.244.0-103.15.244.255\n103.16.152.0-103.16.152.255\n103.16.204.0-103.16.205.255\n103.16.207.0-103.16.207.255\n103.17.99.0-103.17.99.255\n103.17.203.0-103.17.203.255\n103.17.215.0-103.17.215.255\n103.18.157.0-103.18.157.255\n103.19.254.0-103.19.254.255\n103.20.141.0-103.20.141.255\n103.21.25.0-103.21.25.255\n103.21.42.0-103.21.43.255\n103.21.167.0-103.21.167.255\n103.21.169.0-103.21.169.255\n103.22.242.0-103.22.242.255\n103.25.178.0-103.25.178.255\n103.25.229.0-103.25.229.255\n103.26.211.0-103.26.211.255\n103.28.94.0-103.28.94.255\n103.29.146.0-103.29.146.255\n103.30.113.0-103.30.113.255\n103.31.46.0-103.31.46.255\n103.35.170.0-103.35.170.255\n103.37.30.0-103.37.30.255\n103.37.34.0-103.37.34.255\n103.40.227.0-103.40.227.255\n103.41.23.0-103.41.23.255\n103.42.208.0-103.42.208.255\n103.43.149.0-103.43.149.255\n103.44.15.0-103.44.15.255\n103.44.50.0-103.44.50.255\n103.44.150.0-103.44.151.255\n103.44.156.0-103.44.156.255\n103.46.233.0-103.46.233.255\n103.47.153.0-103.47.153.255\n103.50.76.0-103.50.76.255\n103.54.40.0-103.54.40.255\n103.55.88.0-103.55.88.255\n103.55.147.0-103.55.147.255\n103.56.230.0-103.56.230.255\n103.57.40.0-103.57.40.255\n103.59.200.0-103.59.200.255\n103.59.211.0-103.59.211.255\n103.60.174.0-103.60.174.255\n103.66.70.0-103.66.70.255\n103.67.228.0-103.67.228.255\n103.70.141.0-103.70.141.255\n103.192.46.0-103.192.46.255\n103.196.232.0-103.196.232.255\n103.200.39.0-103.200.39.255\n103.203.231.0-103.203.231.255\n103.206.10.0-103.206.10.255\n103.206.152.0-103.206.152.255\n103.209.19.0-103.209.19.255\n103.210.49.0-103.210.49.255\n103.214.129.0-103.214.129.255\n103.214.200.0-103.214.200.255\n103.215.25.0-103.215.25.255\n103.217.105.0-103.217.105.255\n103.224.186.0-103.224.186.255\n103.224.194.0-103.224.194.255\n103.225.0.0-103.225.1.255\n103.225.124.0-103.225.124.255\n103.225.178.0-103.225.178.255\n103.226.184.0-103.226.184.255\n103.229.129.0-103.229.129.255\n103.231.230.0-103.231.230.255\n103.233.36.0-103.233.38.255\n103.234.120.0-103.234.120.255\n103.234.122.0-103.234.122.255\n103.236.176.0-103.236.176.255\n103.241.59.0-103.241.59.255\n103.242.12.0-103.242.12.255\n103.242.22.0-103.242.22.255\n103.242.58.0-103.242.58.255\n103.243.113.0-103.243.113.255\n103.243.115.0-103.243.115.255\n103.244.186.0-103.244.186.255\n103.246.46.0-103.246.46.255\n103.248.32.0-103.248.32.255\n103.249.65.0-103.249.65.255\n103.250.87.0-103.250.87.255\n103.250.152.0-103.250.152.255\n103.250.184.0-103.250.184.255\n103.250.189.0-103.250.189.255\n103.251.18.0-103.251.18.255\n103.251.244.0-103.251.244.255\n103.255.4.0-103.255.5.255\n103.255.7.0-103.255.7.255\n104.153.249.0-104.153.249.255\n104.155.72.0-104.155.72.255\n104.166.32.0-104.166.32.255\n104.193.66.0-104.193.66.255\n104.193.69.0-104.193.69.255\n104.199.63.0-104.199.63.255\n104.199.230.0-104.199.230.255\n104.237.160.0-104.237.163.255\n104.237.172.0-104.237.172.255\n104.237.174.0-104.237.174.255\n104.237.188.0-104.237.190.255\n105.112.8.0-105.112.8.255\n105.187.242.0-105.187.242.255\n105.203.250.0-105.203.250.255\n106.0.60.0-106.0.60.255\n106.1.140.0-106.1.140.255\n106.1.151.0-106.1.151.255\n106.1.167.0-106.1.167.255\n106.1.220.0-106.1.220.255\n106.51.40.0-106.51.40.255\n106.51.113.0-106.51.113.255\n106.103.1.0-106.103.2.255\n106.162.192.0-106.162.192.255\n106.162.198.0-106.162.200.255\n106.162.216.0-106.162.216.255\n107.161.13.0-107.161.13.255\n108.177.8.0-108.177.15.255\n108.177.96.0-108.177.98.255\n108.177.103.0-108.177.104.255\n108.177.112.0-108.177.112.255\n108.177.119.0-108.177.121.255\n108.177.125.0-108.177.125.255\n108.177.127.0-108.177.127.255\n109.60.129.0-109.60.129.255\n109.70.190.0-109.70.190.255\n109.88.203.0-109.88.203.255\n109.105.109.0-109.105.109.255\n109.110.33.0-109.110.33.255\n109.127.2.0-109.127.2.255\n109.167.228.0-109.167.228.255\n109.173.137.0-109.173.137.255\n109.194.25.0-109.194.25.255\n109.194.73.0-109.194.73.255\n109.194.89.0-109.194.89.255\n109.194.105.0-109.194.105.255\n109.194.121.0-109.194.121.255\n109.194.137.0-109.194.137.255\n109.194.169.0-109.194.169.255\n109.194.185.0-109.194.185.255\n109.194.201.0-109.194.201.255\n109.194.233.0-109.194.233.255\n109.195.9.0-109.195.9.255\n109.195.25.0-109.195.25.255\n109.195.41.0-109.195.41.255\n109.195.73.0-109.195.73.255\n109.195.89.0-109.195.89.255\n109.195.105.0-109.195.105.255\n109.195.121.0-109.195.121.255\n109.195.153.0-109.195.153.255\n109.195.169.0-109.195.169.255\n109.195.185.0-109.195.185.255\n109.195.233.0-109.195.233.255\n109.195.249.0-109.195.249.255\n109.199.81.0-109.199.81.255\n109.224.13.0-109.224.13.255\n109.224.40.0-109.224.41.255\n109.224.43.0-109.224.43.255\n109.225.113.0-109.225.113.255\n109.226.50.0-109.226.50.255\n109.226.232.0-109.226.232.255\n109.226.240.0-109.226.240.255\n109.229.163.0-109.229.163.255\n109.230.180.0-109.230.180.255\n109.231.231.0-109.231.231.255\n109.239.139.0-109.239.139.255\n109.245.221.0-109.245.221.255\n109.248.208.0-109.248.208.255\n110.50.81.0-110.50.81.255\n110.76.130.0-110.76.130.255\n110.93.194.0-110.93.194.255\n110.163.42.0-110.163.42.255\n110.164.4.0-110.164.10.255\n110.164.12.0-110.164.14.255\n110.164.16.0-110.164.16.255\n110.164.18.0-110.164.19.255\n110.164.22.0-110.164.23.255\n111.84.96.0-111.84.96.255\n111.84.224.0-111.84.225.255\n111.86.157.0-111.86.157.255\n111.92.162.0-111.92.162.255\n111.94.248.0-111.94.249.255\n111.95.240.0-111.95.240.255\n111.119.161.0-111.119.161.255\n111.168.255.0-111.168.255.255\n112.72.5.0-112.72.5.255\n112.133.228.0-112.133.228.255\n112.197.5.0-112.197.5.255\n112.197.7.0-112.197.8.255\n112.197.10.0-112.197.10.255\n112.197.12.0-112.197.13.255\n112.215.88.0-112.215.88.255\n112.215.101.0-112.215.101.255\n112.215.126.0-112.215.126.255\n112.215.183.0-112.215.184.255\n112.215.207.0-112.215.207.255\n113.171.18.0-113.171.19.255\n113.171.192.0-113.171.192.255\n113.171.198.0-113.171.198.255\n113.171.202.0-113.171.202.255\n113.171.216.0-113.171.216.255\n113.171.220.0-113.171.220.255\n113.171.232.0-113.171.232.255\n113.171.236.0-113.171.247.255\n113.171.251.0-113.171.253.255\n113.197.108.0-113.197.108.255\n114.4.4.0-114.4.4.255\n114.4.7.0-114.4.7.255\n114.4.160.0-114.4.160.255\n114.31.1.0-114.31.1.255\n114.31.31.0-114.31.31.255\n114.108.204.0-114.108.205.255\n114.108.207.0-114.108.207.255\n114.120.192.0-114.120.192.255\n114.120.225.0-114.120.225.255\n114.121.194.0-114.121.194.255\n114.121.226.0-114.121.226.255\n114.125.1.0-114.125.1.255\n114.125.33.0-114.125.33.255\n114.125.97.0-114.125.97.255\n114.125.129.0-114.125.129.255\n114.125.145.0-114.125.145.255\n114.125.161.0-114.125.161.255\n114.125.192.0-114.125.192.255\n114.130.6.0-114.130.6.255\n115.84.108.0-115.84.108.255\n115.84.159.0-115.84.159.255\n115.87.70.0-115.87.71.255\n115.127.52.0-115.127.52.255\n115.164.12.0-115.164.12.255\n115.164.140.0-115.164.140.255\n115.166.169.0-115.166.169.255\n115.167.72.0-115.167.72.255\n115.167.74.0-115.167.74.255\n115.167.76.0-115.167.76.255\n115.178.26.0-115.178.27.255\n115.186.17.0-115.186.17.255\n115.186.97.0-115.186.97.255\n115.254.97.0-115.254.97.255\n115.254.106.0-115.254.106.255\n115.254.121.0-115.254.121.255\n116.58.204.0-116.58.204.255\n116.68.215.0-116.68.215.255\n116.93.47.0-116.93.47.255\n116.202.230.0-116.202.230.255\n116.212.147.0-116.212.147.255\n117.102.78.0-117.102.78.255\n117.102.117.0-117.102.117.255\n117.111.0.0-117.111.0.255\n117.219.224.0-117.219.232.255\n118.69.247.0-118.69.247.255\n118.69.249.0-118.69.249.255\n118.98.26.0-118.98.26.255\n118.98.30.0-118.98.30.255\n118.98.36.0-118.98.36.255\n118.98.76.0-118.98.77.255\n118.98.106.0-118.98.106.255\n118.98.109.0-118.98.111.255\n118.107.75.0-118.107.75.255\n118.143.88.0-118.143.88.255\n118.179.14.0-118.179.14.255\n119.2.100.0-119.2.100.255\n119.9.76.0-119.9.76.255\n119.11.250.0-119.11.250.255\n119.15.80.0-119.15.80.255\n119.40.97.0-119.40.97.255\n119.110.118.0-119.110.118.255\n119.149.187.0-119.149.188.255\n119.153.111.0-119.153.112.255\n119.155.138.0-119.155.138.255\n119.160.91.0-119.160.91.255\n119.160.114.0-119.160.114.255\n119.160.125.0-119.160.125.255\n119.161.83.0-119.161.83.255\n119.224.142.0-119.224.142.255\n119.235.0.0-119.235.0.255\n119.235.103.0-119.235.103.255\n120.28.5.0-120.28.5.255\n120.28.12.0-120.28.12.255\n120.28.26.0-120.28.26.255\n120.28.53.0-120.28.53.255\n120.89.6.0-120.89.6.255\n120.89.97.0-120.89.97.255\n121.78.42.0-121.78.42.255\n121.78.52.0-121.78.52.255\n121.78.206.0-121.78.206.255\n121.123.238.0-121.123.238.255\n121.158.53.0-121.158.53.255\n122.2.152.0-122.2.153.255\n122.2.215.0-122.2.215.255\n122.56.60.0-122.56.60.255\n122.56.115.0-122.56.115.255\n122.149.3.0-122.149.3.255\n122.154.58.0-122.154.58.255\n122.154.76.0-122.154.76.255\n122.154.133.0-122.154.133.255\n122.154.160.0-122.154.160.255\n122.154.244.0-122.154.244.255\n122.201.16.0-122.201.16.255\n122.202.129.0-122.202.129.255\n122.251.255.0-122.251.255.255\n122.255.117.0-122.255.117.255\n123.108.201.0-123.108.201.255\n123.108.243.0-123.108.243.255\n123.108.252.0-123.108.252.255\n123.136.105.0-123.136.105.255\n123.136.114.0-123.136.114.255\n123.176.0.0-123.176.0.255\n123.205.250.0-123.205.250.255\n123.241.78.0-123.241.78.255\n123.241.255.0-123.241.255.255\n124.40.230.0-124.40.230.255\n124.40.233.0-124.40.233.255\n124.40.244.0-124.40.245.255\n124.108.16.0-124.108.16.255\n124.108.18.0-124.108.18.255\n124.109.34.0-124.109.34.255\n124.153.4.0-124.153.4.255\n124.153.255.0-124.153.255.255\n124.158.72.0-124.158.72.255\n124.216.0.0-124.216.0.255\n124.217.179.0-124.217.179.255\n124.248.162.0-124.248.162.255\n125.99.168.0-125.99.168.255\n125.214.167.0-125.214.167.255\n125.234.48.0-125.234.55.255\n125.234.160.0-125.234.160.255\n125.235.17.0-125.235.17.255\n125.235.30.0-125.235.31.255\n125.235.36.0-125.235.36.255\n128.0.31.0-128.0.31.255\n128.0.86.0-128.0.86.255\n128.0.169.0-128.0.169.255\n128.74.248.0-128.74.251.255\n128.139.200.0-128.139.200.255\n128.205.159.0-128.205.159.255\n128.210.224.0-128.210.224.255\n129.66.96.0-129.66.96.255\n130.111.19.0-130.111.19.255\n130.206.193.0-130.206.193.255\n131.0.95.0-131.0.95.255\n131.0.245.0-131.0.245.255\n131.0.250.0-131.0.250.255\n131.72.76.0-131.72.76.255\n131.100.108.0-131.100.108.255\n131.161.24.0-131.161.24.255\n131.161.109.0-131.161.109.255\n131.161.234.0-131.161.234.255\n131.221.20.0-131.221.20.255\n131.221.169.0-131.221.169.255\n131.221.224.0-131.221.224.255\n131.255.157.0-131.255.157.255\n131.255.212.0-131.255.212.255\n132.198.200.0-132.198.200.255\n132.239.253.0-132.239.253.255\n132.255.148.0-132.255.148.255\n132.255.236.0-132.255.236.255\n134.0.218.0-134.0.218.255\n134.19.215.0-134.19.215.255\n134.90.151.0-134.90.151.255\n135.0.199.0-135.0.199.255\n137.207.250.0-137.207.250.255\n138.0.73.0-138.0.73.255\n138.0.153.0-138.0.153.255\n138.0.199.0-138.0.199.255\n138.0.204.0-138.0.204.255\n138.36.0.0-138.36.0.255\n138.59.209.0-138.59.209.255\n138.97.127.0-138.97.127.255\n138.97.163.0-138.97.163.255\n138.99.133.0-138.99.133.255\n138.99.226.0-138.99.226.255\n138.99.246.0-138.99.246.255\n138.117.71.0-138.117.72.255\n138.121.75.0-138.121.75.255\n138.122.84.0-138.122.84.255\n138.122.110.0-138.122.110.255\n138.122.223.0-138.122.223.255\n138.185.138.0-138.185.138.255\n138.185.180.0-138.185.180.255\n138.186.0.0-138.186.0.255\n138.186.122.0-138.186.122.255\n138.204.143.0-138.204.143.255\n138.204.159.0-138.204.159.255\n138.219.2.0-138.219.2.255\n138.219.152.0-138.219.152.255\n139.175.107.0-139.175.107.255\n140.113.14.0-140.113.14.255\n140.197.248.0-140.197.249.255\n140.211.86.0-140.211.86.255\n142.161.4.0-142.161.4.255\n142.161.132.0-142.161.132.255\n142.163.38.0-142.163.38.255\n142.165.4.0-142.165.4.255\n142.166.12.0-142.166.12.255\n142.166.129.0-142.166.129.255\n142.166.149.0-142.166.149.255\n142.166.242.0-142.166.242.255\n142.176.121.0-142.176.121.255\n143.137.72.0-143.137.72.255\n143.137.113.0-143.137.113.255\n143.202.124.0-143.202.124.255\n143.208.136.0-143.208.136.255\n143.208.211.0-143.208.211.255\n143.215.193.0-143.215.193.255\n143.255.44.0-143.255.44.255\n144.48.163.0-144.48.163.255\n144.131.80.0-144.131.80.255\n145.255.14.0-145.255.14.255\n146.88.60.0-146.88.60.255\n146.115.8.0-146.115.8.255\n146.115.22.0-146.115.22.255\n146.120.79.0-146.120.79.255\n146.158.95.0-146.158.95.255\n146.186.20.0-146.186.20.255\n146.247.1.0-146.247.1.255\n148.245.203.0-148.245.203.255\n149.126.86.0-149.126.86.255\n149.165.180.0-149.165.180.255\n149.255.152.0-149.255.152.255\n149.255.254.0-149.255.255.255\n150.100.16.0-150.100.16.255\n150.101.213.0-150.101.213.255\n150.129.7.0-150.129.7.255\n150.129.59.0-150.129.59.255\n150.129.146.0-150.129.146.255\n150.199.22.0-150.199.22.255\n150.199.24.0-150.199.24.255\n150.242.21.0-150.242.21.255\n150.242.84.0-150.242.84.255\n151.236.167.0-151.236.167.255\n151.248.100.0-151.248.100.255\n152.231.110.0-152.231.111.255\n154.65.36.0-154.65.36.255\n154.66.245.0-154.66.245.255\n154.67.1.0-154.67.1.255\n154.73.81.0-154.73.81.255\n154.126.74.0-154.126.74.255\n155.69.253.0-155.69.253.255\n155.232.240.0-155.232.240.255\n157.157.135.0-157.157.135.255\n157.161.155.0-157.161.155.255\n157.197.92.0-157.197.93.255\n159.134.168.0-159.134.168.255\n159.148.69.0-159.148.69.255\n159.180.253.0-159.180.253.255\n159.192.0.0-159.192.0.255\n160.3.24.0-160.3.24.255\n160.19.221.0-160.19.221.255\n160.202.147.0-160.202.147.255\n161.0.238.0-161.0.238.255\n161.132.34.0-161.132.34.255\n162.211.40.0-162.211.40.255\n162.212.12.0-162.212.12.255\n162.212.208.0-162.212.208.255\n162.221.128.0-162.221.128.255\n162.246.0.0-162.246.0.255\n162.247.80.0-162.247.80.255\n162.252.127.0-162.252.127.255\n162.253.24.0-162.253.24.255\n162.254.10.0-162.254.10.255\n163.28.18.0-163.28.18.255\n163.28.38.0-163.28.38.255\n163.28.51.0-163.28.51.255\n163.28.83.0-163.28.83.255\n163.28.116.0-163.28.116.255\n163.28.130.0-163.28.130.255\n163.44.26.0-163.44.26.255\n163.53.140.0-163.53.140.255\n163.153.215.0-163.153.215.255\n164.40.244.0-164.40.244.255\n164.58.76.0-164.58.76.255\n164.58.87.0-164.58.87.255\n164.67.18.0-164.67.18.255\n164.85.63.0-164.85.63.255\n164.113.94.0-164.113.94.255\n164.215.74.0-164.215.74.255\n165.98.72.0-165.98.72.255\n165.165.38.0-165.165.38.255\n165.166.67.0-165.166.67.255\n165.254.153.0-165.254.153.255\n166.62.221.0-166.62.221.255\n166.70.146.0-166.70.146.255\n167.142.232.0-167.142.232.255\n167.205.23.0-167.205.23.255\n167.206.10.0-167.206.10.255\n167.206.12.0-167.206.12.255\n167.206.145.0-167.206.145.255\n167.206.245.0-167.206.245.255\n167.206.252.0-167.206.252.255\n167.249.134.0-167.249.134.255\n168.90.8.0-168.90.9.255\n168.90.64.0-168.90.64.255\n168.90.91.0-168.90.91.255\n168.90.131.0-168.90.131.255\n168.90.226.0-168.90.226.255\n168.121.53.0-168.121.53.255\n168.121.228.0-168.121.228.255\n168.187.143.0-168.187.143.255\n168.194.15.0-168.194.15.255\n168.194.64.0-168.194.64.255\n168.205.130.0-168.205.130.255\n170.0.176.0-170.0.176.255\n170.51.240.0-170.51.240.255\n170.51.244.0-170.51.244.255\n170.84.132.0-170.84.132.255\n170.84.206.0-170.84.206.255\n170.150.112.0-170.150.112.255\n170.150.168.0-170.150.168.255\n170.233.116.0-170.233.116.255\n170.254.11.0-170.254.11.255\n172.56.128.0-172.56.134.255\n172.56.136.0-172.56.136.255\n172.56.138.0-172.56.142.255\n172.56.144.0-172.56.144.255\n172.56.146.0-172.56.146.255\n172.217.0.0-172.217.13.255\n172.217.16.0-172.217.31.255\n172.217.60.0-172.217.60.255\n172.217.129.0-172.217.130.255\n173.44.117.0-173.44.117.255\n173.44.125.0-173.44.125.255\n173.194.0.0-173.194.5.255\n173.194.7.0-173.194.8.255\n173.194.10.0-173.194.32.255\n173.194.44.0-173.194.44.255\n173.194.48.0-173.194.51.255\n173.194.53.0-173.194.61.255\n173.194.63.0-173.194.63.255\n173.194.66.0-173.194.70.255\n173.194.73.0-173.194.74.255\n173.194.76.0-173.194.76.255\n173.194.78.0-173.194.79.255\n173.194.113.0-173.194.113.255\n173.194.122.0-173.194.122.255\n173.194.128.0-173.194.144.255\n173.194.146.0-173.194.158.255\n173.194.160.0-173.194.167.255\n173.194.175.0-173.194.223.255\n173.218.181.0-173.218.181.255\n173.218.248.0-173.218.248.255\n173.219.93.0-173.219.93.255\n173.219.136.0-173.219.136.255\n173.224.96.0-173.224.96.255\n173.237.115.0-173.237.115.255\n173.237.125.0-173.237.125.255\n174.140.109.0-174.140.109.255\n175.28.1.0-175.28.1.255\n175.100.94.0-175.100.94.255\n175.101.69.0-175.101.69.255\n176.62.72.0-176.62.72.255\n176.97.160.0-176.97.160.255\n176.99.94.0-176.99.94.255\n176.101.253.0-176.101.253.255\n176.106.225.0-176.106.225.255\n176.112.160.0-176.112.160.255\n176.114.27.0-176.114.27.255\n176.115.127.0-176.115.127.255\n176.116.160.0-176.116.160.255\n176.117.255.0-176.117.255.255\n176.118.240.0-176.118.240.255\n176.122.49.0-176.122.49.255\n176.126.59.0-176.126.59.255\n176.221.96.0-176.221.96.255\n176.222.164.0-176.222.164.255\n176.222.187.0-176.222.187.255\n176.222.191.0-176.222.191.255\n176.241.81.0-176.241.81.255\n176.255.201.0-176.255.201.255\n177.10.57.0-177.10.57.255\n177.10.98.0-177.10.98.255\n177.10.120.0-177.10.120.255\n177.10.160.0-177.10.160.255\n177.10.253.0-177.10.253.255\n177.11.153.0-177.11.153.255\n177.12.63.0-177.12.63.255\n177.12.127.0-177.12.127.255\n177.20.208.0-177.20.208.255\n177.21.96.0-177.21.96.255\n177.22.32.0-177.22.32.255\n177.22.96.0-177.22.96.255\n177.23.168.0-177.23.168.255\n177.23.197.0-177.23.197.255\n177.35.32.0-177.35.32.255\n177.35.203.0-177.35.203.255\n177.36.3.0-177.36.3.255\n177.36.38.0-177.36.38.255\n177.36.88.0-177.36.88.255\n177.36.217.0-177.36.217.255\n177.37.69.0-177.37.69.255\n177.38.206.0-177.38.206.255\n177.38.247.0-177.38.247.255\n177.39.144.0-177.39.144.255\n177.43.115.0-177.43.115.255\n177.43.165.0-177.43.165.255\n177.43.170.0-177.43.170.255\n177.43.196.0-177.43.196.255\n177.43.235.0-177.43.235.255\n177.43.239.0-177.43.239.255\n177.44.140.0-177.44.140.255\n177.44.255.0-177.44.255.255\n177.46.79.0-177.46.79.255\n177.47.62.0-177.47.62.255\n177.47.130.0-177.47.130.255\n177.47.173.0-177.47.173.255\n177.53.147.0-177.53.147.255\n177.54.236.0-177.54.236.255\n177.55.10.0-177.55.10.255\n177.55.12.0-177.55.13.255\n177.55.15.0-177.55.18.255\n177.55.62.0-177.55.62.255\n177.55.150.0-177.55.150.255\n177.55.244.0-177.55.244.255\n177.65.111.0-177.65.111.255\n177.66.96.0-177.66.96.255\n177.66.115.0-177.66.115.255\n177.66.245.0-177.66.245.255\n177.67.85.0-177.67.85.255\n177.69.110.0-177.69.110.255\n177.70.66.0-177.70.66.255\n177.71.7.0-177.71.7.255\n177.72.143.0-177.72.143.255\n177.72.178.0-177.72.178.255\n177.72.198.0-177.72.198.255\n177.73.10.0-177.73.10.255\n177.74.241.0-177.74.241.255\n177.75.56.0-177.75.56.255\n177.75.75.0-177.75.75.255\n177.84.67.0-177.84.67.255\n177.84.167.0-177.84.167.255\n177.85.119.0-177.85.119.255\n177.85.200.0-177.85.200.255\n177.86.158.0-177.86.158.255\n177.91.160.0-177.91.160.255\n177.91.162.0-177.91.162.255\n177.91.255.0-177.91.255.255\n177.92.139.0-177.92.139.255\n177.99.179.0-177.99.179.255\n177.99.185.0-177.99.185.255\n177.99.203.0-177.99.203.255\n177.101.143.0-177.101.143.255\n177.104.114.0-177.104.114.255\n177.107.188.0-177.107.188.255\n177.107.191.0-177.107.191.255\n177.124.192.0-177.124.192.255\n177.125.27.0-177.125.27.255\n177.125.168.0-177.125.168.255\n177.125.210.0-177.125.210.255\n177.126.2.0-177.126.2.255\n177.126.124.0-177.126.124.255\n177.126.126.0-177.126.126.255\n177.126.175.0-177.126.175.255\n177.128.193.0-177.128.193.255\n177.128.223.0-177.128.223.255\n177.129.8.0-177.129.8.255\n177.129.16.0-177.129.16.255\n177.129.156.0-177.129.156.255\n177.130.15.0-177.130.15.255\n177.130.53.0-177.130.53.255\n177.130.79.0-177.130.79.255\n177.131.1.0-177.131.1.255\n177.131.55.0-177.131.55.255\n177.135.84.0-177.135.84.255\n177.135.94.0-177.135.94.255\n177.135.103.0-177.135.103.255\n177.135.107.0-177.135.107.255\n177.135.110.0-177.135.110.255\n177.135.135.0-177.135.135.255\n177.135.151.0-177.135.151.255\n177.135.177.0-177.135.177.255\n177.135.245.0-177.135.245.255\n177.136.113.0-177.136.113.255\n177.136.122.0-177.136.122.255\n177.137.225.0-177.137.225.255\n177.154.1.0-177.154.1.255\n177.154.39.0-177.154.39.255\n177.154.223.0-177.154.223.255\n177.155.0.0-177.155.0.255\n177.155.141.0-177.155.141.255\n177.155.163.0-177.155.163.255\n177.155.208.0-177.155.208.255\n177.159.106.0-177.159.106.255\n177.159.161.0-177.159.162.255\n177.159.237.0-177.159.237.255\n177.183.157.0-177.183.157.255\n177.184.128.0-177.184.128.255\n177.190.81.0-177.190.81.255\n177.190.119.0-177.190.119.255\n177.193.95.0-177.193.95.255\n177.194.223.0-177.194.223.255\n177.200.160.0-177.200.160.255\n177.200.184.0-177.200.184.255\n177.200.253.0-177.200.253.255\n177.207.254.0-177.207.254.255\n177.221.73.0-177.221.73.255\n177.222.0.0-177.222.0.255\n177.222.254.0-177.222.254.255\n177.223.13.0-177.223.13.255\n177.223.56.0-177.223.56.255\n177.233.249.0-177.233.249.255\n178.19.252.0-178.19.252.255\n178.22.168.0-178.22.168.255\n178.23.236.0-178.23.236.255\n178.35.137.0-178.35.137.255\n178.45.249.0-178.45.249.255\n178.45.251.0-178.45.251.255\n178.45.253.0-178.45.253.255\n178.49.129.0-178.49.129.255\n178.49.157.0-178.49.157.255\n178.59.100.0-178.59.100.255\n178.59.102.0-178.59.102.255\n178.60.128.0-178.60.128.255\n178.60.195.0-178.60.195.255\n178.76.255.0-178.76.255.255\n178.88.163.0-178.88.163.255\n178.130.15.0-178.130.15.255\n178.132.81.0-178.132.81.255\n178.134.0.0-178.134.0.255\n178.159.49.0-178.159.49.255\n178.168.3.0-178.168.3.255\n178.209.67.0-178.209.67.255\n178.215.223.0-178.215.223.255\n178.218.118.0-178.218.118.255\n178.235.206.0-178.235.206.255\n178.236.130.0-178.236.130.255\n178.236.133.0-178.236.133.255\n178.248.80.0-178.248.80.255\n178.250.208.0-178.250.208.255\n178.251.141.0-178.251.141.255\n179.1.4.0-179.1.4.255\n179.5.71.0-179.5.71.255\n179.6.58.0-179.6.58.255\n179.6.61.0-179.6.61.255\n179.6.63.0-179.6.63.255\n179.6.122.0-179.6.122.255\n179.6.190.0-179.6.190.255\n179.6.254.0-179.6.255.255\n179.31.53.0-179.31.53.255\n179.49.8.0-179.49.8.255\n179.49.15.0-179.49.15.255\n179.49.17.0-179.49.17.255\n179.49.26.0-179.49.26.255\n179.57.193.0-179.57.193.255\n179.60.91.0-179.60.91.255\n179.62.49.0-179.62.49.255\n179.62.81.0-179.62.81.255\n179.63.244.0-179.63.244.255\n179.96.9.0-179.96.9.255\n179.96.24.0-179.96.24.255\n179.96.35.0-179.96.35.255\n179.96.60.0-179.96.60.255\n179.96.250.0-179.96.250.255\n179.97.41.0-179.97.42.255\n179.97.196.0-179.97.196.255\n179.106.0.0-179.106.0.255\n179.106.47.0-179.106.47.255\n179.106.173.0-179.106.173.255\n179.107.0.0-179.107.0.255\n179.107.26.0-179.107.26.255\n179.108.128.0-179.108.128.255\n179.108.192.0-179.108.192.255\n179.124.5.0-179.124.5.255\n179.124.138.0-179.124.138.255\n179.124.224.0-179.124.224.255\n179.127.81.0-179.127.81.255\n179.127.128.0-179.127.128.255\n179.127.142.0-179.127.142.255\n179.127.254.0-179.127.254.255\n179.154.111.0-179.154.111.255\n179.154.159.0-179.154.159.255\n179.154.191.0-179.154.191.255\n179.155.130.0-179.155.130.255\n179.183.24.0-179.183.24.255\n179.183.28.0-179.183.28.255\n179.184.5.0-179.184.5.255\n179.184.10.0-179.184.10.255\n179.184.63.0-179.184.63.255\n179.184.89.0-179.184.89.255\n179.184.115.0-179.184.115.255\n179.184.204.0-179.184.204.255\n179.185.163.0-179.185.163.255\n179.185.194.0-179.185.194.255\n179.189.22.0-179.189.22.255\n179.189.65.0-179.189.65.255\n179.189.182.0-179.189.182.255\n179.189.248.0-179.189.248.255\n179.190.108.0-179.190.108.255\n179.191.16.0-179.191.16.255\n179.216.95.0-179.216.95.255\n179.216.159.0-179.216.159.255\n179.232.3.0-179.232.3.255\n179.232.65.0-179.232.65.255\n179.232.159.0-179.232.159.255\n179.233.130.0-179.233.130.255\n179.233.225.0-179.233.225.255\n179.234.65.0-179.234.65.255\n179.234.143.0-179.234.143.255\n179.235.25.0-179.235.25.255\n179.235.34.0-179.235.34.255\n180.87.217.0-180.87.217.255\n180.93.23.0-180.93.23.255\n180.93.32.0-180.93.32.255\n180.93.80.0-180.93.80.255\n180.149.5.0-180.149.5.255\n180.149.59.0-180.149.61.255\n180.149.91.0-180.149.91.255\n180.150.1.0-180.150.1.255\n180.188.250.0-180.188.250.255\n180.211.201.0-180.211.201.255\n180.214.232.0-180.214.232.255\n180.234.2.0-180.234.2.255\n180.234.129.0-180.234.129.255\n181.10.24.0-181.10.24.255\n181.10.28.0-181.10.28.255\n181.10.135.0-181.10.135.255\n181.15.168.0-181.15.168.255\n181.15.215.0-181.15.215.255\n181.15.220.0-181.15.221.255\n181.16.211.0-181.16.211.255\n181.30.239.0-181.30.246.255\n181.40.16.0-181.40.16.255\n181.41.251.0-181.41.251.255\n181.47.186.0-181.47.186.255\n181.47.248.0-181.47.248.255\n181.47.254.0-181.47.254.255\n181.48.252.0-181.48.252.255\n181.48.254.0-181.48.255.255\n181.49.124.0-181.49.124.255\n181.49.182.0-181.49.187.255\n181.49.192.0-181.49.192.255\n181.64.63.0-181.64.63.255\n181.64.130.0-181.64.132.255\n181.65.115.0-181.65.115.255\n181.111.164.0-181.111.164.255\n181.114.54.0-181.114.54.255\n181.114.113.0-181.114.113.255\n181.119.4.0-181.119.4.255\n181.174.80.0-181.174.80.255\n181.174.127.0-181.174.127.255\n181.174.135.0-181.174.135.255\n181.176.244.0-181.176.244.255\n181.177.20.0-181.177.20.255\n181.188.0.0-181.188.0.255\n181.189.248.0-181.189.248.255\n181.192.0.0-181.192.0.255\n181.192.63.0-181.192.63.255\n181.197.82.0-181.197.82.255\n181.198.79.0-181.198.80.255\n181.199.154.0-181.199.154.255\n181.199.158.0-181.199.158.255\n181.209.15.0-181.209.15.255\n181.210.15.0-181.210.15.255\n181.224.253.0-181.224.253.255\n181.225.140.0-181.225.140.255\n182.18.178.0-182.18.178.255\n182.48.85.0-182.48.85.255\n182.50.68.0-182.50.68.255\n182.79.194.0-182.79.194.255\n182.79.238.0-182.79.238.255\n182.79.251.0-182.79.251.255\n182.79.253.0-182.79.254.255\n182.163.240.0-182.163.240.255\n182.176.41.0-182.176.41.255\n182.176.45.0-182.176.45.255\n182.176.130.0-182.176.131.255\n182.176.138.0-182.176.138.255\n182.176.173.0-182.176.173.255\n182.239.95.0-182.239.95.255\n182.239.127.0-182.239.127.255\n182.248.204.0-182.248.204.255\n182.253.60.0-182.253.60.255\n182.253.220.0-182.253.220.255\n183.78.5.0-183.78.5.255\n183.78.64.0-183.78.64.255\n183.78.96.0-183.78.96.255\n183.87.151.0-183.87.151.255\n183.91.18.0-183.91.18.255\n183.91.188.0-183.91.188.255\n183.91.238.0-183.91.238.255\n183.182.97.0-183.182.97.255\n184.150.152.0-184.150.153.255\n184.150.168.0-184.150.168.255\n184.150.182.0-184.150.183.255\n184.150.186.0-184.150.186.255\n184.170.67.0-184.170.67.255\n185.2.108.0-185.2.108.255\n185.3.1.0-185.3.1.255\n185.4.253.0-185.4.253.255\n185.5.161.0-185.5.161.255\n185.6.12.0-185.6.12.255\n185.11.245.0-185.11.245.255\n185.13.115.0-185.13.115.255\n185.13.132.0-185.13.132.255\n185.14.68.0-185.14.68.255\n185.16.25.0-185.16.25.255\n185.19.98.0-185.19.98.255\n185.22.34.0-185.22.34.255\n185.23.64.0-185.23.64.255\n185.27.107.0-185.27.107.255\n185.27.217.0-185.27.217.255\n185.34.21.0-185.34.21.255\n185.37.85.0-185.37.85.255\n185.38.0.0-185.38.0.255\n185.38.241.0-185.38.241.255\n185.39.160.0-185.39.160.255\n185.42.244.0-185.42.244.255\n185.48.9.0-185.48.9.255\n185.48.127.0-185.48.127.255\n185.48.136.0-185.48.136.255\n185.51.215.0-185.51.215.255\n185.51.222.0-185.51.222.255\n185.52.116.0-185.52.116.255\n185.52.118.0-185.52.118.255\n185.53.235.0-185.53.235.255\n185.54.61.0-185.54.61.255\n185.54.63.0-185.54.63.255\n185.54.255.0-185.54.255.255\n185.57.71.0-185.57.71.255\n185.58.203.0-185.58.203.255\n185.59.69.0-185.59.69.255\n185.59.195.0-185.59.195.255\n185.61.94.0-185.61.94.255\n185.69.7.0-185.69.7.255\n185.71.141.0-185.71.141.255\n185.73.88.0-185.73.88.255\n185.74.230.0-185.74.230.255\n185.76.178.0-185.76.178.255\n185.78.112.0-185.78.112.255\n185.90.125.0-185.90.125.255\n185.91.19.0-185.91.19.255\n185.91.96.0-185.91.96.255\n185.95.204.0-185.95.204.255\n185.98.25.0-185.98.25.255\n185.99.35.0-185.99.35.255\n185.100.209.0-185.100.209.255\n185.101.18.0-185.101.18.255\n185.104.158.0-185.104.158.255\n185.104.254.0-185.104.254.255\n185.105.196.0-185.105.196.255\n185.112.104.0-185.112.104.255\n185.112.190.0-185.112.190.255\n185.112.234.0-185.112.234.255\n185.117.9.0-185.117.9.255\n185.119.13.0-185.119.13.255\n185.128.39.0-185.128.39.255\n185.135.68.0-185.135.68.255\n185.138.120.0-185.138.121.255\n186.0.181.0-186.0.181.255\n186.0.234.0-186.0.234.255\n186.1.18.0-186.1.18.255\n186.1.197.0-186.1.197.255\n186.2.131.0-186.2.131.255\n186.2.134.0-186.2.134.255\n186.15.250.0-186.15.251.255\n186.16.15.0-186.16.15.255\n186.16.31.0-186.16.31.255\n186.27.124.0-186.27.124.255\n186.31.119.0-186.31.119.255\n186.42.100.0-186.42.100.255\n186.46.72.0-186.46.72.255\n186.46.140.0-186.46.140.255\n186.47.201.0-186.47.202.255\n186.68.154.0-186.68.154.255\n186.68.247.0-186.68.247.255\n186.73.72.0-186.73.72.255\n186.73.79.0-186.73.79.255\n186.96.91.0-186.96.91.255\n186.96.222.0-186.96.222.255\n186.102.190.0-186.102.191.255\n186.124.123.0-186.124.123.255\n186.148.159.0-186.148.159.255\n186.151.236.0-186.151.236.255\n186.160.223.0-186.160.223.255\n186.166.151.0-186.166.151.255\n186.176.224.0-186.176.224.255\n186.177.65.0-186.177.66.255\n186.177.192.0-186.177.192.255\n186.178.0.0-186.178.0.255\n186.179.71.0-186.179.71.255\n186.179.252.0-186.179.252.255\n186.183.22.0-186.183.22.255\n186.192.17.0-186.192.17.255\n186.192.145.0-186.192.145.255\n186.193.221.0-186.193.221.255\n186.194.17.0-186.194.17.255\n186.194.48.0-186.194.48.255\n186.195.109.0-186.195.109.255\n186.207.162.0-186.207.162.255\n186.208.1.0-186.208.1.255\n186.208.80.0-186.208.80.255\n186.208.210.0-186.208.210.255\n186.208.225.0-186.208.225.255\n186.209.32.0-186.209.32.255\n186.209.75.0-186.209.75.255\n186.209.78.0-186.209.78.255\n186.211.31.0-186.211.31.255\n186.211.109.0-186.211.109.255\n186.214.37.0-186.214.37.255\n186.215.92.0-186.215.92.255\n186.215.155.0-186.215.155.255\n186.215.194.0-186.215.194.255\n186.215.208.0-186.215.208.255\n186.216.108.0-186.216.108.255\n186.216.190.0-186.216.191.255\n186.219.128.0-186.219.128.255\n186.219.218.0-186.219.218.255\n186.223.131.0-186.223.131.255\n186.223.162.0-186.223.162.255\n186.223.194.0-186.223.194.255\n186.224.227.0-186.224.227.255\n186.225.147.0-186.225.147.255\n186.225.220.0-186.225.220.255\n186.226.128.0-186.226.128.255\n186.226.160.0-186.226.160.255\n186.226.186.0-186.226.186.255\n186.228.156.0-186.228.156.255\n186.229.52.0-186.229.53.255\n186.229.96.0-186.229.99.255\n186.229.127.0-186.229.127.255\n186.230.63.0-186.230.63.255\n186.231.74.0-186.231.74.255\n186.232.44.0-186.232.44.255\n186.232.197.0-186.232.197.255\n186.233.16.0-186.233.16.255\n186.233.72.0-186.233.72.255\n186.235.31.0-186.235.31.255\n186.235.80.0-186.235.80.255\n186.235.144.0-186.235.144.255\n186.235.160.0-186.235.160.255\n186.235.189.0-186.235.189.255\n186.237.52.0-186.237.52.255\n186.248.32.0-186.248.32.255\n186.249.69.0-186.249.69.255\n186.249.163.0-186.249.164.255\n186.249.216.0-186.249.216.255\n186.250.162.0-186.250.162.255\n186.250.215.0-186.250.215.255\n186.251.10.0-186.251.10.255\n186.251.16.0-186.251.16.255\n186.251.179.0-186.251.179.255\n186.251.200.0-186.251.200.255\n187.1.14.0-187.1.14.255\n187.1.17.0-187.1.17.255\n187.1.89.0-187.1.89.255\n187.1.113.0-187.1.113.255\n187.1.185.0-187.1.185.255\n187.2.74.0-187.2.74.255\n187.2.81.0-187.2.81.255\n187.2.95.0-187.2.95.255\n187.3.241.0-187.3.241.255\n187.7.117.0-187.7.117.255\n187.7.130.0-187.7.130.255\n187.7.215.0-187.7.215.255\n187.7.230.0-187.7.230.255\n187.17.48.0-187.17.48.255\n187.17.155.0-187.17.155.255\n187.18.184.0-187.18.184.255\n187.18.187.0-187.18.187.255\n187.19.96.0-187.19.96.255\n187.19.127.0-187.19.127.255\n187.19.145.0-187.19.145.255\n187.21.77.0-187.21.77.255\n187.22.65.0-187.22.65.255\n187.23.64.0-187.23.64.255\n187.23.73.0-187.23.73.255\n187.23.232.0-187.23.232.255\n187.33.50.0-187.33.50.255\n187.33.247.0-187.33.247.255\n187.36.193.0-187.36.194.255\n187.39.177.0-187.39.177.255\n187.44.0.0-187.44.0.255\n187.44.111.0-187.44.111.255\n187.44.155.0-187.44.155.255\n187.49.81.0-187.49.81.255\n187.49.136.0-187.49.136.255\n187.58.66.0-187.58.66.255\n187.60.249.0-187.60.249.255\n187.61.121.0-187.61.121.255\n187.63.166.0-187.63.166.255\n187.65.3.0-187.65.3.255\n187.66.78.0-187.66.78.255\n187.72.192.0-187.72.192.255\n187.73.144.0-187.73.144.255\n187.85.85.0-187.85.85.255\n187.86.12.0-187.86.12.255\n187.86.49.0-187.86.49.255\n187.86.80.0-187.86.80.255\n187.86.180.0-187.86.180.255\n187.87.196.0-187.87.196.255\n187.87.223.0-187.87.223.255\n187.94.94.0-187.94.94.255\n187.94.208.0-187.94.208.255\n187.95.1.0-187.95.1.255\n187.95.255.0-187.95.255.255\n187.102.71.0-187.102.71.255\n187.102.112.0-187.102.112.255\n187.103.72.0-187.103.72.255\n187.105.162.0-187.105.162.255\n187.106.140.0-187.106.140.255\n187.108.224.0-187.108.224.255\n187.109.16.0-187.109.16.255\n187.109.206.0-187.109.206.255\n187.109.238.0-187.109.238.255\n187.110.64.0-187.110.64.255\n187.110.238.0-187.110.238.255\n187.111.81.0-187.111.81.255\n187.111.144.0-187.111.144.255\n187.114.222.0-187.114.222.255\n187.115.146.0-187.115.146.255\n187.115.167.0-187.115.167.255\n187.120.240.0-187.120.240.255\n187.121.160.0-187.121.160.255\n187.122.121.0-187.122.121.255\n187.122.190.0-187.122.190.255\n187.122.250.0-187.122.250.255\n187.123.28.0-187.123.28.255\n187.123.120.0-187.123.120.255\n187.160.243.0-187.160.243.255\n187.160.254.0-187.160.254.255\n187.162.178.0-187.162.178.255\n187.180.31.0-187.180.31.255\n187.180.159.0-187.180.159.255\n187.181.68.0-187.181.68.255\n187.181.125.0-187.181.125.255\n187.189.67.0-187.189.67.255\n187.189.89.0-187.189.89.255\n187.189.157.0-187.189.157.255\n187.189.206.0-187.189.206.255\n187.190.14.0-187.190.14.255\n187.252.80.0-187.252.80.255\n187.252.82.0-187.252.84.255\n187.254.78.0-187.254.78.255\n188.0.128.0-188.0.128.255\n188.0.185.0-188.0.185.255\n188.21.9.0-188.21.9.255\n188.35.142.0-188.35.142.255\n188.43.61.0-188.43.61.255\n188.43.64.0-188.43.64.255\n188.43.66.0-188.43.69.255\n188.43.87.0-188.43.87.255\n188.43.126.0-188.43.126.255\n188.68.163.0-188.68.163.255\n188.93.174.0-188.93.174.255\n188.112.3.0-188.112.3.255\n188.113.128.0-188.113.128.255\n188.116.219.0-188.116.220.255\n188.130.175.0-188.130.175.255\n188.162.160.0-188.162.160.255\n188.169.0.0-188.169.0.255\n188.191.168.0-188.191.168.255\n188.234.130.0-188.234.130.255\n188.234.140.0-188.234.140.255\n188.244.8.0-188.244.8.255\n188.247.240.0-188.247.240.255\n188.254.87.0-188.254.87.255\n189.1.48.0-189.1.48.255\n189.1.145.0-189.1.145.255\n189.4.5.0-189.4.5.255\n189.4.7.0-189.4.7.255\n189.4.66.0-189.4.66.255\n189.4.70.0-189.4.70.255\n189.5.53.0-189.5.53.255\n189.5.130.0-189.5.130.255\n189.6.76.0-189.6.76.255\n189.7.8.0-189.7.8.255\n189.7.16.0-189.7.16.255\n189.7.75.0-189.7.75.255\n189.7.104.0-189.7.104.255\n189.7.112.0-189.7.112.255\n189.7.120.0-189.7.120.255\n189.7.128.0-189.7.128.255\n189.7.176.0-189.7.176.255\n189.7.184.0-189.7.184.255\n189.7.200.0-189.7.200.255\n189.7.208.0-189.7.208.255\n189.7.216.0-189.7.216.255\n189.14.52.0-189.14.52.255\n189.14.78.0-189.14.78.255\n189.26.123.0-189.26.123.255\n189.28.163.0-189.28.163.255\n189.31.143.0-189.31.143.255\n189.34.253.0-189.34.253.255\n189.38.33.0-189.38.33.255\n189.39.116.0-189.39.116.255\n189.39.126.0-189.39.126.255\n189.39.153.0-189.39.153.255\n189.39.192.0-189.39.192.255\n189.45.15.0-189.45.15.255\n189.45.193.0-189.45.193.255\n189.50.145.0-189.50.145.255\n189.51.127.0-189.51.127.255\n189.51.155.0-189.51.155.255\n189.55.196.0-189.55.196.255\n189.58.99.0-189.58.99.255\n189.59.93.0-189.59.93.255\n189.63.251.0-189.63.251.255\n189.73.192.0-189.73.192.255\n189.76.142.0-189.76.142.255\n189.84.66.0-189.84.66.255\n189.85.81.0-189.85.81.255\n189.86.41.0-189.86.41.255\n189.89.27.0-189.89.27.255\n189.89.161.0-189.89.161.255\n189.90.45.0-189.90.45.255\n189.90.96.0-189.90.96.255\n189.90.243.0-189.90.243.255\n189.91.114.0-189.91.114.255\n189.103.27.0-189.103.27.255\n189.103.191.0-189.103.191.255\n189.112.10.0-189.112.10.255\n189.113.79.0-189.113.79.255\n189.115.42.0-189.115.42.255\n189.124.80.0-189.124.80.255\n189.124.133.0-189.124.133.255\n189.126.48.0-189.126.48.255\n189.126.224.0-189.126.224.255\n189.193.189.0-189.193.189.255\n189.194.54.0-189.194.54.255\n189.194.93.0-189.194.94.255\n189.194.132.0-189.194.132.255\n189.194.236.0-189.194.236.255\n189.195.42.0-189.195.42.255\n189.195.64.0-189.195.64.255\n189.195.96.0-189.195.96.255\n189.195.131.0-189.195.131.255\n189.195.168.0-189.195.168.255\n189.195.222.0-189.195.222.255\n189.196.29.0-189.196.29.255\n189.196.168.0-189.196.168.255\n189.196.189.0-189.196.189.255\n189.197.62.0-189.197.62.255\n189.197.77.0-189.197.77.255\n189.197.79.0-189.197.79.255\n189.197.168.0-189.197.168.255\n189.197.190.0-189.197.191.255\n189.198.130.0-189.198.130.255\n189.198.141.0-189.198.141.255\n189.198.158.0-189.198.158.255\n189.198.236.0-189.198.236.255\n189.198.250.0-189.198.250.255\n189.199.19.0-189.199.19.255\n189.199.71.0-189.199.71.255\n189.199.81.0-189.199.81.255\n189.199.103.0-189.199.103.255\n189.199.105.0-189.199.105.255\n189.199.250.0-189.199.250.255\n189.203.151.0-189.203.151.255\n189.203.155.0-189.203.155.255\n189.203.166.0-189.203.168.255\n189.203.232.0-189.203.232.255\n189.204.116.0-189.204.116.255\n189.205.57.0-189.205.57.255\n189.212.93.0-189.212.93.255\n189.215.132.0-189.215.132.255\n189.215.134.0-189.215.134.255\n189.215.200.0-189.215.200.255\n189.216.0.0-189.216.0.255\n189.216.4.0-189.216.4.255\n189.218.235.0-189.218.235.255\n189.247.132.0-189.247.138.255\n189.247.140.0-189.247.143.255\n189.247.145.0-189.247.145.255\n189.247.147.0-189.247.155.255\n189.247.160.0-189.247.161.255\n189.247.168.0-189.247.169.255\n190.0.175.0-190.0.175.255\n190.2.82.0-190.2.82.255\n190.5.159.0-190.5.159.255\n190.5.171.0-190.5.171.255\n190.5.191.0-190.5.191.255\n190.5.222.0-190.5.222.255\n190.5.235.0-190.5.235.255\n190.6.220.0-190.6.220.255\n190.6.222.0-190.6.222.255\n190.8.63.0-190.8.63.255\n190.11.146.0-190.11.146.255\n190.13.226.0-190.13.226.255\n190.14.163.0-190.14.163.255\n190.15.32.0-190.15.32.255\n190.15.100.0-190.15.100.255\n190.45.0.0-190.45.0.255\n190.52.39.0-190.52.39.255\n190.52.206.0-190.52.206.255\n190.54.2.0-190.54.2.255\n190.55.61.0-190.55.61.255\n190.56.231.0-190.56.231.255\n190.57.158.0-190.57.158.255\n190.58.136.0-190.58.136.255\n190.63.32.0-190.63.32.255\n190.63.135.0-190.63.135.255\n190.82.63.0-190.82.63.255\n190.92.11.0-190.92.11.255\n190.92.20.0-190.92.20.255\n190.92.89.0-190.92.89.255\n190.94.74.0-190.94.74.255\n190.94.130.0-190.94.130.255\n190.94.176.0-190.94.176.255\n190.96.8.0-190.96.8.255\n190.96.100.0-190.96.100.255\n190.97.0.0-190.97.0.255\n190.99.74.0-190.99.74.255\n190.102.57.0-190.102.57.255\n190.103.183.0-190.103.183.255\n190.103.220.0-190.103.220.255\n190.104.6.0-190.104.7.255\n190.104.150.0-190.104.150.255\n190.104.250.0-190.104.250.255\n190.107.224.0-190.107.224.255\n190.108.82.0-190.108.82.255\n190.110.97.0-190.110.97.255\n190.112.180.0-190.112.180.255\n190.112.219.0-190.112.219.255\n190.113.97.0-190.113.97.255\n190.115.112.0-190.115.112.255\n190.116.191.0-190.116.191.255\n190.120.207.0-190.120.207.255\n190.121.11.0-190.121.11.255\n190.121.104.0-190.121.104.255\n190.121.155.0-190.121.155.255\n190.121.237.0-190.121.237.255\n190.122.64.0-190.122.64.255\n190.122.192.0-190.122.192.255\n190.123.95.0-190.123.95.255\n190.124.161.0-190.124.161.255\n190.129.124.0-190.129.124.255\n190.142.193.0-190.142.193.255\n190.143.134.0-190.143.134.255\n190.145.255.0-190.145.255.255\n190.150.50.0-190.150.50.255\n190.153.58.0-190.153.58.255\n190.160.0.0-190.160.0.255\n190.164.254.0-190.164.254.255\n190.166.8.0-190.166.8.255\n190.166.41.0-190.166.41.255\n190.167.204.0-190.167.204.255\n190.167.241.0-190.167.241.255\n190.181.111.0-190.181.111.255\n190.182.24.0-190.182.24.255\n190.183.231.0-190.183.231.255\n190.184.224.0-190.184.224.255\n190.184.255.0-190.184.255.255\n190.186.210.0-190.186.210.255\n190.197.65.0-190.197.65.255\n190.208.14.0-190.208.14.255\n190.210.113.0-190.210.113.255\n190.211.101.0-190.211.101.255\n190.211.175.0-190.211.175.255\n190.212.166.0-190.212.166.255\n190.216.191.0-190.216.191.255\n190.217.154.0-190.217.154.255\n190.235.154.0-190.235.155.255\n190.238.117.0-190.238.117.255\n190.240.1.0-190.240.2.255\n190.240.6.0-190.240.6.255\n190.241.121.0-190.241.121.255\n190.248.1.0-190.248.1.255\n190.248.34.0-190.248.35.255\n191.5.47.0-191.5.47.255\n191.5.198.0-191.5.198.255\n191.6.20.0-191.6.20.255\n191.6.136.0-191.6.136.255\n191.7.28.0-191.7.28.255\n191.7.51.0-191.7.51.255\n191.7.136.0-191.7.136.255\n191.7.213.0-191.7.213.255\n191.32.26.0-191.32.26.255\n191.32.58.0-191.32.58.255\n191.32.235.0-191.32.235.255\n191.33.82.0-191.33.82.255\n191.33.177.0-191.33.177.255\n191.33.230.0-191.33.230.255\n191.34.35.0-191.34.35.255\n191.34.161.0-191.34.161.255\n191.34.252.0-191.34.252.255\n191.37.0.0-191.37.0.255\n191.37.167.0-191.37.167.255\n191.98.136.0-191.98.136.255\n191.99.254.0-191.99.255.255\n191.103.96.0-191.103.96.255\n191.103.126.0-191.103.126.255\n191.179.1.0-191.179.1.255\n191.183.80.0-191.183.80.255\n191.187.224.0-191.187.224.255\n191.189.255.0-191.189.255.255\n191.240.237.0-191.240.237.255\n191.241.237.0-191.241.237.255\n191.242.112.0-191.242.112.255\n191.242.179.0-191.242.179.255\n191.243.156.0-191.243.157.255\n191.250.26.0-191.250.26.255\n191.251.119.0-191.251.119.255\n191.251.192.0-191.251.192.255\n191.251.197.0-191.251.197.255\n191.253.208.0-191.253.208.255\n192.31.228.0-192.31.228.255\n192.70.222.0-192.70.222.255\n192.116.22.0-192.116.22.255\n192.119.20.0-192.119.21.255\n192.119.28.0-192.119.28.255\n192.122.185.0-192.122.185.255\n192.124.225.0-192.124.225.255\n192.124.233.0-192.124.233.255\n192.154.121.0-192.154.121.255\n192.189.138.0-192.189.138.255\n192.225.241.0-192.225.241.255\n192.232.16.0-192.232.16.255\n192.248.3.0-192.248.3.255\n192.254.96.0-192.254.96.255\n193.0.255.0-193.0.255.255\n193.4.115.0-193.4.115.255\n193.28.236.0-193.28.236.255\n193.33.240.0-193.33.240.255\n193.51.224.0-193.51.224.255\n193.90.147.0-193.90.147.255\n193.92.133.0-193.92.133.255\n193.95.12.0-193.95.13.255\n193.95.144.0-193.95.144.255\n193.134.255.0-193.134.255.255\n193.170.141.0-193.170.141.255\n193.189.184.0-193.189.184.255\n193.192.226.0-193.192.226.255\n193.192.250.0-193.192.250.255\n193.206.135.0-193.206.135.255\n193.212.4.0-193.212.4.255\n193.229.108.0-193.229.108.255\n194.9.24.0-194.9.25.255\n194.24.134.0-194.24.134.255\n194.44.4.0-194.44.4.255\n194.54.234.0-194.54.234.255\n194.78.0.0-194.78.0.255\n194.78.99.0-194.78.99.255\n194.90.196.0-194.90.196.255\n194.106.173.0-194.106.173.255\n194.116.101.0-194.116.101.255\n194.122.80.0-194.122.80.255\n194.122.82.0-194.122.82.255\n194.134.26.0-194.134.26.255\n194.150.129.0-194.150.129.255\n194.158.92.0-194.158.92.255\n194.182.232.0-194.182.232.255\n194.183.149.0-194.183.149.255\n194.199.78.0-194.199.78.255\n194.210.238.0-194.210.238.255\n195.8.11.0-195.8.12.255\n195.12.176.0-195.12.177.255\n195.13.189.0-195.13.189.255\n195.13.231.0-195.13.231.255\n195.14.151.0-195.14.151.255\n195.14.153.0-195.14.153.255\n195.39.213.0-195.39.213.255\n195.43.73.0-195.43.73.255\n195.46.107.0-195.46.107.255\n195.46.177.0-195.46.177.255\n195.49.27.0-195.49.27.255\n195.64.213.0-195.64.213.255\n195.72.240.0-195.72.240.255\n195.78.217.0-195.78.217.255\n195.80.179.0-195.80.179.255\n195.94.233.0-195.94.233.255\n195.95.178.0-195.95.178.255\n195.98.65.0-195.98.65.255\n195.111.111.0-195.111.111.255\n195.113.214.0-195.113.214.255\n195.122.16.0-195.122.16.255\n195.122.30.0-195.122.30.255\n195.162.39.0-195.162.39.255\n195.176.255.0-195.176.255.255\n195.177.197.0-195.177.197.255\n195.187.242.0-195.187.242.255\n195.191.238.0-195.191.238.255\n195.202.131.0-195.202.131.255\n195.208.12.0-195.208.12.255\n195.216.237.0-195.216.237.255\n195.218.169.0-195.218.169.255\n195.239.122.0-195.239.122.255\n195.249.20.0-195.249.20.255\n195.249.23.0-195.249.23.255\n196.0.3.0-196.0.3.255\n196.23.168.0-196.23.168.255\n196.27.66.0-196.27.66.255\n196.29.35.0-196.29.35.255\n196.44.149.0-196.44.149.255\n196.46.1.0-196.46.1.255\n196.46.123.0-196.46.123.255\n196.49.8.0-196.49.8.255\n196.201.223.0-196.201.223.255\n196.202.246.0-196.202.246.255\n196.203.81.0-196.203.81.255\n196.203.102.0-196.203.102.255\n196.203.188.0-196.203.188.255\n196.204.32.0-196.204.32.255\n196.207.198.0-196.207.198.255\n197.136.0.0-197.136.0.255\n197.149.150.0-197.149.150.255\n197.155.95.0-197.155.95.255\n197.157.244.0-197.157.244.255\n197.158.80.0-197.158.80.255\n197.159.29.0-197.159.29.255\n197.160.155.0-197.160.155.255\n197.199.183.0-197.199.183.255\n197.199.253.0-197.199.254.255\n197.218.0.0-197.218.0.255\n197.220.0.0-197.220.0.255\n197.221.233.0-197.221.233.255\n197.232.44.0-197.232.44.255\n197.235.0.0-197.235.0.255\n197.243.124.0-197.243.124.255\n197.251.230.0-197.251.230.255\n197.253.18.0-197.253.18.255\n198.7.237.0-198.7.237.255\n198.20.48.0-198.20.48.255\n198.32.232.0-198.32.232.255\n198.49.182.0-198.49.182.255\n198.52.15.0-198.52.15.255\n198.70.66.0-198.70.71.255\n198.70.244.0-198.70.250.255\n198.92.97.0-198.92.97.255\n198.142.187.0-198.142.187.255\n198.231.29.0-198.231.29.255\n198.235.201.0-198.235.201.255\n198.236.245.0-198.236.245.255\n199.36.119.0-199.36.119.255\n199.47.189.0-199.47.189.255\n199.59.103.0-199.59.103.255\n199.83.198.0-199.83.198.255\n199.85.229.0-199.85.229.255\n199.85.252.0-199.85.252.255\n199.102.192.0-199.102.192.255\n199.180.84.0-199.180.84.255\n199.185.92.0-199.185.92.255\n199.192.116.0-199.192.116.255\n199.212.24.0-199.212.24.255\n199.241.168.0-199.241.168.255\n199.244.212.0-199.244.212.255\n200.0.56.0-200.0.56.255\n200.2.125.0-200.2.125.255\n200.3.21.0-200.3.21.255\n200.3.169.0-200.3.169.255\n200.7.94.0-200.7.94.255\n200.7.182.0-200.7.182.255\n200.7.241.0-200.7.241.255\n200.10.177.0-200.10.177.255\n200.10.225.0-200.10.226.255\n200.11.154.0-200.11.154.255\n200.14.228.0-200.14.229.255\n200.16.69.0-200.16.69.255\n200.17.7.0-200.17.7.255\n200.26.170.0-200.26.170.255\n200.28.0.0-200.28.0.255\n200.28.6.0-200.28.12.255\n200.29.113.0-200.29.113.255\n200.29.255.0-200.29.255.255\n200.30.192.0-200.30.193.255\n200.31.96.0-200.31.96.255\n200.33.115.0-200.33.115.255\n200.36.99.0-200.36.99.255\n200.40.3.0-200.40.3.255\n200.40.172.0-200.40.172.255\n200.42.246.0-200.42.246.255\n200.49.63.0-200.49.63.255\n200.49.120.0-200.49.120.255\n200.49.185.0-200.49.185.255\n200.50.67.0-200.50.67.255\n200.50.171.0-200.50.171.255\n200.50.241.0-200.50.241.255\n200.50.248.0-200.50.248.255\n200.52.21.0-200.52.21.255\n200.53.245.0-200.53.245.255\n200.55.230.0-200.55.230.255\n200.56.193.0-200.56.193.255\n200.58.65.0-200.58.65.255\n200.59.113.0-200.59.113.255\n200.62.26.0-200.62.26.255\n200.63.105.0-200.63.105.255\n200.63.120.0-200.63.120.255\n200.63.214.0-200.63.214.255\n200.73.1.0-200.73.1.255\n200.75.201.0-200.75.201.255\n200.77.120.0-200.77.120.255\n200.77.137.0-200.77.137.255\n200.77.139.0-200.77.139.255\n200.77.168.0-200.77.168.255\n200.77.222.0-200.77.222.255\n200.81.125.0-200.81.125.255\n200.85.99.0-200.85.99.255\n200.89.75.0-200.89.75.255\n200.90.6.0-200.90.6.255\n200.90.46.0-200.90.46.255\n200.91.33.0-200.91.33.255\n200.92.227.0-200.92.227.255\n200.94.238.0-200.94.238.255\n200.97.85.0-200.97.85.255\n200.104.251.0-200.104.251.255\n200.104.253.0-200.104.253.255\n200.105.131.0-200.105.131.255\n200.107.255.0-200.107.255.255\n200.108.53.0-200.108.53.255\n200.109.224.0-200.109.224.255\n200.110.122.0-200.110.122.255\n200.110.188.0-200.110.188.255\n200.112.190.0-200.112.190.255\n200.113.255.0-200.113.255.255\n200.114.47.0-200.114.47.255\n200.115.86.0-200.115.90.255\n200.115.92.0-200.115.94.255\n200.123.36.0-200.123.36.255\n200.124.254.0-200.124.254.255\n200.129.233.0-200.129.233.255\n200.130.63.0-200.130.63.255\n200.131.47.0-200.131.47.255\n200.133.23.0-200.133.23.255\n200.141.140.0-200.141.140.255\n200.142.191.0-200.142.191.255\n200.144.184.0-200.144.184.255\n200.149.119.0-200.149.119.255\n200.150.4.0-200.150.4.255\n200.152.250.0-200.152.251.255\n200.160.96.0-200.160.97.255\n200.160.104.0-200.160.104.255\n200.165.96.0-200.165.96.255\n200.169.124.0-200.169.124.255\n200.172.62.0-200.172.62.255\n200.175.185.0-200.175.185.255\n200.175.196.0-200.175.196.255\n200.175.224.0-200.175.224.255\n200.187.83.0-200.187.83.255\n200.187.85.0-200.187.85.255\n200.188.128.0-200.188.128.255\n200.189.63.0-200.189.63.255\n200.189.87.0-200.189.87.255\n200.195.155.0-200.195.155.255\n200.195.190.0-200.195.190.255\n200.199.211.0-200.199.211.255\n200.216.39.0-200.216.39.255\n200.216.56.0-200.216.56.255\n200.216.90.0-200.216.90.255\n200.220.141.0-200.220.141.255\n200.229.223.0-200.229.223.255\n200.237.143.0-200.237.143.255\n200.240.237.0-200.240.237.255\n201.0.223.0-201.0.225.255\n201.0.228.0-201.0.229.255\n201.0.231.0-201.0.232.255\n201.0.235.0-201.0.238.255\n201.0.240.0-201.0.240.255\n201.0.244.0-201.0.246.255\n201.0.248.0-201.0.250.255\n201.6.8.0-201.6.8.255\n201.6.16.0-201.6.16.255\n201.6.48.0-201.6.48.255\n201.16.48.0-201.16.48.255\n201.16.57.0-201.16.57.255\n201.16.59.0-201.16.59.255\n201.16.134.0-201.16.134.255\n201.17.29.0-201.17.31.255\n201.17.165.0-201.17.165.255\n201.17.170.0-201.17.170.255\n201.20.107.0-201.20.107.255\n201.20.117.0-201.20.117.255\n201.21.214.0-201.21.215.255\n201.23.161.0-201.23.161.255\n201.30.4.0-201.30.4.255\n201.31.84.0-201.31.84.255\n201.33.170.0-201.33.170.255\n201.33.232.0-201.33.232.255\n201.33.240.0-201.33.240.255\n201.34.205.0-201.34.205.255\n201.46.241.0-201.46.241.255\n201.46.252.0-201.46.252.255\n201.47.112.0-201.47.112.255\n201.47.158.0-201.47.158.255\n201.48.53.0-201.48.53.255\n201.48.56.0-201.48.56.255\n201.49.80.0-201.49.81.255\n201.49.97.0-201.49.97.255\n201.54.66.0-201.54.66.255\n201.54.166.0-201.54.166.255\n201.55.137.0-201.55.137.255\n201.55.233.0-201.55.233.255\n201.56.167.0-201.56.167.255\n201.57.54.0-201.57.54.255\n201.57.60.0-201.57.60.255\n201.57.89.0-201.57.89.255\n201.57.155.0-201.57.155.255\n201.57.227.0-201.57.227.255\n201.62.48.0-201.62.48.255\n201.64.116.0-201.64.116.255\n201.64.241.0-201.64.241.255\n201.67.193.0-201.67.193.255\n201.76.0.0-201.76.0.255\n201.76.28.0-201.76.28.255\n201.76.65.0-201.76.65.255\n201.77.64.0-201.77.64.255\n201.77.112.0-201.77.112.255\n201.82.12.0-201.82.12.255\n201.82.108.0-201.82.108.255\n201.86.233.0-201.86.233.255\n201.87.209.0-201.87.209.255\n201.94.160.0-201.94.160.255\n201.94.177.0-201.94.177.255\n201.130.49.0-201.130.49.255\n201.130.51.0-201.130.53.255\n201.130.196.0-201.130.196.255\n201.130.208.0-201.130.208.255\n201.132.92.0-201.132.92.255\n201.132.200.0-201.132.201.255\n201.148.102.0-201.148.102.255\n201.148.124.0-201.148.124.255\n201.149.62.0-201.149.62.255\n201.150.255.0-201.150.255.255\n201.151.207.0-201.151.207.255\n201.157.30.0-201.157.30.255\n201.157.200.0-201.157.201.255\n201.159.220.0-201.159.220.255\n201.162.64.0-201.162.64.255\n201.163.0.0-201.163.0.255\n201.163.253.0-201.163.253.255\n201.165.0.0-201.165.0.255\n201.165.116.0-201.165.116.255\n201.165.118.0-201.165.118.255\n201.165.221.0-201.165.221.255\n201.165.255.0-201.165.255.255\n201.167.5.0-201.167.5.255\n201.167.51.0-201.167.51.255\n201.167.56.0-201.167.56.255\n201.167.64.0-201.167.64.255\n201.167.93.0-201.167.93.255\n201.168.67.0-201.168.67.255\n201.173.124.0-201.173.124.255\n201.174.48.0-201.174.48.255\n201.174.77.0-201.174.77.255\n201.174.82.0-201.174.82.255\n201.174.96.0-201.174.98.255\n201.174.112.0-201.174.112.255\n201.175.77.0-201.175.77.255\n201.191.202.0-201.191.202.255\n201.191.214.0-201.191.214.255\n201.215.120.0-201.215.120.255\n201.217.3.0-201.217.3.255\n201.217.205.0-201.217.205.255\n201.217.246.0-201.217.246.255\n201.218.56.0-201.218.56.255\n201.218.65.0-201.218.65.255\n201.219.100.0-201.219.100.255\n201.220.160.0-201.220.160.255\n201.221.95.0-201.221.95.255\n201.221.130.0-201.221.130.255\n201.227.61.0-201.227.61.255\n201.229.1.0-201.229.1.255\n201.230.36.0-201.230.36.255\n201.241.118.0-201.241.118.255\n201.248.76.0-201.248.76.255\n201.248.78.0-201.248.78.255\n202.3.240.0-202.3.240.255\n202.4.173.0-202.4.173.255\n202.28.85.0-202.28.85.255\n202.28.87.0-202.28.87.255\n202.38.180.0-202.38.180.255\n202.39.143.0-202.39.143.255\n202.40.221.0-202.40.221.255\n202.51.65.0-202.51.65.255\n202.51.67.0-202.51.67.255\n202.51.73.0-202.51.73.255\n202.51.247.0-202.51.247.255\n202.56.33.0-202.56.33.255\n202.58.96.0-202.58.97.255\n202.60.105.0-202.60.105.255\n202.62.92.0-202.62.92.255\n202.67.33.0-202.67.33.255\n202.67.35.0-202.67.35.255\n202.67.37.0-202.67.37.255\n202.67.39.0-202.67.39.255\n202.67.43.0-202.67.43.255\n202.67.46.0-202.67.47.255\n202.69.11.0-202.69.12.255\n202.69.15.0-202.69.15.255\n202.69.185.0-202.69.185.255\n202.70.50.0-202.70.50.255\n202.71.1.0-202.71.1.255\n202.75.141.0-202.75.141.255\n202.75.147.0-202.75.147.255\n202.75.191.0-202.75.191.255\n202.78.83.0-202.78.83.255\n202.78.113.0-202.78.113.255\n202.86.162.0-202.86.162.255\n202.88.68.0-202.88.68.255\n202.88.147.0-202.88.147.255\n202.88.152.0-202.88.152.255\n202.88.157.0-202.88.157.255\n202.88.175.0-202.88.175.255\n202.88.186.0-202.88.186.255\n202.88.193.0-202.88.193.255\n202.89.241.0-202.89.241.255\n202.90.152.0-202.90.152.255\n202.90.156.0-202.90.156.255\n202.93.153.0-202.93.153.255\n202.122.145.0-202.122.146.255\n202.124.127.0-202.124.127.255\n202.128.15.0-202.128.15.255\n202.129.8.0-202.129.8.255\n202.129.236.0-202.129.236.255\n202.134.14.0-202.134.14.255\n202.136.91.0-202.136.91.255\n202.141.239.0-202.141.239.255\n202.142.160.0-202.142.160.255\n202.142.224.0-202.142.225.255\n202.144.191.0-202.144.191.255\n202.148.204.0-202.148.204.255\n202.151.87.0-202.151.87.255\n202.152.47.0-202.152.47.255\n202.152.130.0-202.152.130.255\n202.153.85.0-202.153.85.255\n202.155.135.0-202.155.135.255\n202.158.57.0-202.158.57.255\n202.160.9.0-202.160.9.255\n202.163.106.0-202.163.106.255\n202.163.122.0-202.163.122.255\n202.163.174.0-202.163.174.255\n202.166.193.0-202.166.193.255\n202.168.156.0-202.168.156.255\n202.169.173.0-202.169.173.255\n202.169.175.0-202.169.175.255\n202.169.193.0-202.169.193.255\n202.179.1.0-202.179.1.255\n202.181.19.0-202.181.19.255\n202.208.170.0-202.208.170.255\n202.216.0.0-202.216.0.255\n202.220.161.0-202.220.161.255\n202.224.62.0-202.224.62.255\n202.224.83.0-202.224.83.255\n202.231.177.0-202.231.177.255\n202.248.151.0-202.248.151.255\n202.248.248.0-202.248.248.255\n203.5.76.0-203.5.76.255\n203.13.161.0-203.13.161.255\n203.66.124.0-203.66.124.255\n203.66.155.0-203.66.155.255\n203.66.169.0-203.66.169.255\n203.66.180.0-203.66.180.255\n203.66.182.0-203.66.182.255\n203.78.32.0-203.78.32.255\n203.78.36.0-203.78.37.255\n203.79.253.0-203.79.253.255\n203.82.75.0-203.82.77.255\n203.82.82.0-203.82.82.255\n203.82.95.0-203.82.95.255\n203.91.113.0-203.91.113.255\n203.94.209.0-203.94.209.255\n203.94.229.0-203.94.229.255\n203.99.50.0-203.99.50.255\n203.109.178.0-203.109.178.255\n203.113.48.0-203.113.53.255\n203.113.55.0-203.113.55.255\n203.113.76.0-203.113.81.255\n203.113.129.0-203.113.130.255\n203.113.160.0-203.113.163.255\n203.113.189.0-203.113.189.255\n203.114.135.0-203.114.135.255\n203.116.165.0-203.116.165.255\n203.116.189.0-203.116.189.255\n203.117.34.0-203.117.35.255\n203.118.141.0-203.118.141.255\n203.118.143.0-203.118.143.255\n203.118.245.0-203.118.245.255\n203.121.59.0-203.121.59.255\n203.121.225.0-203.121.225.255\n203.133.8.0-203.133.8.255\n203.133.72.0-203.133.72.255\n203.139.206.0-203.139.206.255\n203.142.74.0-203.142.74.255\n203.145.84.0-203.145.84.255\n203.146.98.0-203.146.98.255\n203.151.116.0-203.151.116.255\n203.152.112.0-203.152.112.255\n203.165.13.0-203.165.14.255\n203.171.242.0-203.171.242.255\n203.176.177.0-203.176.178.255\n203.184.5.0-203.184.5.255\n203.184.7.0-203.184.7.255\n203.189.185.0-203.189.185.255\n203.192.208.0-203.192.208.255\n203.207.55.0-203.207.55.255\n203.210.6.0-203.210.8.255\n203.211.0.0-203.211.0.255\n203.211.8.0-203.211.8.255\n203.217.98.0-203.217.98.255\n203.223.36.0-203.223.36.255\n203.233.10.0-203.233.10.255\n203.233.18.0-203.233.18.255\n203.233.37.0-203.233.37.255\n203.233.63.0-203.233.63.255\n203.233.88.0-203.233.88.255\n203.233.92.0-203.233.92.255\n203.233.96.0-203.233.96.255\n203.233.126.0-203.233.126.255\n203.248.132.0-203.248.132.255\n203.248.180.0-203.248.180.255\n203.248.210.0-203.248.210.255\n203.252.15.0-203.252.15.255\n204.9.80.0-204.9.80.255\n204.11.134.0-204.11.134.255\n204.17.140.0-204.17.140.255\n204.85.30.0-204.85.30.255\n204.111.84.0-204.111.84.255\n204.116.80.0-204.116.80.255\n204.186.48.0-204.186.48.255\n204.186.55.0-204.186.55.255\n204.186.215.0-204.186.215.255\n204.239.67.0-204.239.67.255\n205.144.216.0-205.144.216.255\n205.158.11.0-205.158.11.255\n205.213.108.0-205.213.108.255\n205.213.114.0-205.213.114.255\n205.237.38.0-205.237.38.255\n205.237.60.0-205.237.60.255\n206.40.112.0-206.40.112.255\n206.71.231.0-206.71.231.255\n206.80.249.0-206.80.249.255\n206.82.17.0-206.82.17.255\n206.117.11.0-206.117.11.255\n206.124.214.0-206.124.214.255\n206.126.112.0-206.126.112.255\n206.131.134.0-206.131.134.255\n206.166.0.0-206.166.0.255\n206.167.212.0-206.167.212.255\n206.167.221.0-206.167.221.255\n206.181.8.0-206.181.8.255\n206.192.244.0-206.192.244.255\n206.223.218.0-206.223.218.255\n206.248.149.0-206.248.149.255\n206.248.151.0-206.248.151.255\n206.248.169.0-206.248.169.255\n207.34.103.0-207.34.103.255\n207.47.131.0-207.47.131.255\n207.70.147.0-207.70.147.255\n207.134.64.0-207.134.64.255\n207.172.61.0-207.172.61.255\n207.172.159.0-207.172.159.255\n207.172.193.0-207.172.193.255\n207.173.228.0-207.173.228.255\n207.181.192.0-207.181.192.255\n207.191.178.0-207.191.178.255\n207.192.195.0-207.192.195.255\n207.192.241.0-207.192.241.255\n207.204.159.0-207.204.159.255\n207.219.213.0-207.219.213.255\n207.229.143.0-207.229.143.255\n207.237.69.0-207.237.69.255\n207.238.18.0-207.238.18.255\n207.238.252.0-207.238.252.255\n207.248.95.0-207.248.95.255\n207.255.26.0-207.255.26.255\n208.49.194.0-208.49.194.255\n208.53.243.0-208.53.243.255\n208.54.2.0-208.54.2.255\n208.54.4.0-208.54.4.255\n208.54.16.0-208.54.19.255\n208.54.34.0-208.54.34.255\n208.54.66.0-208.54.66.255\n208.54.74.0-208.54.74.255\n208.64.172.0-208.64.172.255\n208.65.152.0-208.65.152.255\n208.65.155.0-208.65.155.255\n208.66.189.0-208.66.189.255\n208.66.246.0-208.66.246.255\n208.68.35.0-208.68.35.255\n208.73.255.0-208.73.255.255\n208.77.78.0-208.77.78.255\n208.84.221.0-208.84.221.255\n208.90.107.0-208.90.107.255\n208.93.196.0-208.93.196.255\n208.104.242.0-208.104.242.255\n208.111.59.0-208.111.59.255\n208.117.225.0-208.117.229.255\n208.117.233.0-208.117.233.255\n208.117.240.0-208.117.240.255\n208.117.243.0-208.117.244.255\n208.117.246.0-208.117.246.255\n208.117.249.0-208.117.249.255\n208.117.253.0-208.117.253.255\n208.124.110.0-208.124.110.255\n208.138.46.0-208.138.46.255\n208.180.1.0-208.180.1.255\n208.180.32.0-208.180.32.255\n208.180.168.0-208.180.168.255\n208.181.12.0-208.181.12.255\n208.187.128.0-208.187.128.255\n209.33.32.0-209.33.32.255\n209.33.235.0-209.33.235.255\n209.52.144.0-209.52.144.255\n209.52.146.0-209.52.146.255\n209.52.189.0-209.52.189.255\n209.55.113.0-209.55.113.255\n209.56.124.0-209.56.124.255\n209.81.111.0-209.81.111.255\n209.85.144.0-209.85.145.255\n209.85.147.0-209.85.147.255\n209.85.164.0-209.85.165.255\n209.85.200.0-209.85.203.255\n209.85.224.0-209.85.235.255\n209.85.239.0-209.85.239.255\n209.90.173.0-209.90.173.255\n209.91.104.0-209.91.105.255\n209.91.176.0-209.91.176.255\n209.91.216.0-209.91.216.255\n209.115.217.0-209.115.217.255\n209.116.150.0-209.116.150.255\n209.116.186.0-209.116.186.255\n209.118.7.0-209.118.7.255\n209.118.99.0-209.118.99.255\n209.118.208.0-209.118.208.255\n209.131.254.0-209.131.254.255\n209.132.160.0-209.132.160.255\n209.141.120.0-209.141.121.255\n209.143.6.0-209.143.6.255\n209.145.112.0-209.145.112.255\n209.148.113.0-209.148.113.255\n209.148.195.0-209.148.196.255\n209.148.198.0-209.148.199.255\n209.148.210.0-209.148.210.255\n209.183.147.0-209.183.147.255\n209.191.218.0-209.191.218.255\n209.221.59.0-209.221.59.255\n209.221.127.0-209.221.127.255\n209.226.57.0-209.226.57.255\n210.1.255.0-210.1.255.255\n210.2.177.0-210.2.177.255\n210.7.45.0-210.7.45.255\n210.19.223.0-210.19.223.255\n210.61.221.0-210.61.221.255\n210.92.119.0-210.92.119.255\n210.94.153.0-210.94.153.255\n210.139.253.0-210.139.253.255\n210.143.70.0-210.143.70.255\n210.143.147.0-210.143.147.255\n210.158.146.0-210.158.146.255\n210.171.10.0-210.171.10.255\n210.187.22.0-210.187.22.255\n210.187.25.0-210.187.25.255\n210.191.74.0-210.191.74.255\n210.209.18.0-210.209.18.255\n210.236.185.0-210.236.185.255\n210.242.125.0-210.242.125.255\n210.242.127.0-210.242.128.255\n210.245.14.0-210.245.14.255\n210.253.46.0-210.253.46.255\n211.1.149.0-211.1.149.255\n211.49.146.0-211.49.146.255\n211.76.107.0-211.76.107.255\n211.76.114.0-211.76.114.255\n211.76.116.0-211.76.117.255\n211.76.123.0-211.76.123.255\n211.77.50.0-211.77.50.255\n211.117.39.0-211.117.39.255\n211.124.13.0-211.124.13.255\n211.175.187.0-211.175.187.255\n211.239.234.0-211.239.234.255\n212.0.195.0-212.0.195.255\n212.1.249.0-212.1.250.255\n212.2.108.0-212.2.108.255\n212.6.83.0-212.6.83.255\n212.9.14.0-212.9.14.255\n212.10.212.0-212.10.212.255\n212.19.24.0-212.19.24.255\n212.20.18.0-212.20.18.255\n212.29.228.0-212.29.228.255\n212.30.5.0-212.30.5.255\n212.33.231.0-212.33.231.255\n212.34.3.0-212.34.3.255\n212.34.13.0-212.34.13.255\n212.39.82.0-212.39.82.255\n212.40.1.0-212.40.1.255\n212.40.34.0-212.40.34.255\n212.40.98.0-212.40.98.255\n212.40.135.0-212.40.135.255\n212.42.193.0-212.42.193.255\n212.43.1.0-212.43.1.255\n212.52.60.0-212.52.60.255\n212.56.131.0-212.56.132.255\n212.57.191.0-212.57.191.255\n212.73.69.0-212.73.70.255\n212.76.17.0-212.76.17.255\n212.88.109.0-212.88.109.255\n212.89.5.0-212.89.5.255\n212.92.207.0-212.92.207.255\n212.96.65.0-212.96.65.255\n212.96.85.0-212.96.85.255\n212.96.93.0-212.96.94.255\n212.104.78.0-212.104.78.255\n212.106.207.0-212.106.207.255\n212.106.221.0-212.106.221.255\n212.109.17.0-212.109.17.255\n212.109.19.0-212.109.19.255\n212.112.37.0-212.112.37.255\n212.112.117.0-212.112.117.255\n212.113.49.0-212.113.49.255\n212.113.52.0-212.113.52.255\n212.113.185.0-212.113.185.255\n212.120.241.0-212.120.241.255\n212.122.6.0-212.122.6.255\n212.122.14.0-212.122.14.255\n212.126.109.0-212.126.109.255\n212.126.115.0-212.126.115.255\n212.142.160.0-212.142.160.255\n212.143.195.0-212.143.195.255\n212.146.69.0-212.146.69.255\n212.179.17.0-212.179.17.255\n212.179.154.0-212.179.154.255\n212.179.180.0-212.179.180.255\n212.188.7.0-212.188.7.255\n212.188.10.0-212.188.10.255\n212.188.15.0-212.188.15.255\n212.188.34.0-212.188.35.255\n212.188.49.0-212.188.49.255\n212.191.227.0-212.191.227.255\n212.191.236.0-212.191.236.255\n212.247.8.0-212.247.8.255\n213.30.5.0-213.30.5.255\n213.30.114.0-213.30.114.255\n213.34.205.0-213.34.205.255\n213.57.23.0-213.57.25.255\n213.59.210.0-213.59.210.255\n213.59.221.0-213.59.221.255\n213.59.237.0-213.59.237.255\n213.81.154.0-213.81.154.255\n213.85.209.0-213.85.209.255\n213.87.125.0-213.87.125.255\n213.94.75.0-213.94.75.255\n213.105.64.0-213.105.64.255\n213.139.46.0-213.139.46.255\n213.140.213.0-213.140.213.255\n213.145.140.0-213.145.140.255\n213.151.35.0-213.151.35.255\n213.151.210.0-213.151.210.255\n213.152.1.0-213.152.1.255\n213.153.32.0-213.153.32.255\n213.155.151.0-213.155.151.255\n213.157.199.0-213.157.199.255\n213.157.220.0-213.157.220.255\n213.157.222.0-213.157.222.255\n213.158.11.0-213.158.11.255\n213.158.160.0-213.158.160.255\n213.158.163.0-213.158.163.255\n213.158.172.0-213.158.172.255\n213.158.178.0-213.158.178.255\n213.158.188.0-213.158.189.255\n213.163.23.0-213.163.23.255\n213.189.65.0-213.189.66.255\n213.190.196.0-213.190.196.255\n213.207.140.0-213.207.140.255\n213.208.156.0-213.208.156.255\n213.233.153.0-213.233.153.255\n213.240.44.0-213.240.44.255\n213.241.87.0-213.241.89.255\n213.253.9.0-213.253.9.255\n216.8.161.0-216.8.161.255\n216.8.252.0-216.8.252.255\n216.11.246.0-216.11.246.255\n216.12.120.0-216.12.120.255\n216.16.11.0-216.16.11.255\n216.21.170.0-216.21.170.255\n216.36.151.0-216.36.151.255\n216.46.132.0-216.46.132.255\n216.50.39.0-216.50.39.255\n216.50.166.0-216.50.166.255\n216.58.192.0-216.58.214.255\n216.58.216.0-216.58.223.255\n216.59.116.0-216.59.116.255\n216.66.105.0-216.66.105.255\n216.68.10.0-216.68.10.255\n216.68.248.0-216.68.248.255\n216.93.235.0-216.93.235.255\n216.99.127.0-216.99.127.255\n216.123.194.0-216.123.194.255\n216.126.108.0-216.126.108.255\n216.147.171.0-216.147.171.255\n216.152.163.0-216.152.163.255\n216.162.127.0-216.162.127.255\n216.167.240.0-216.167.240.255\n216.169.73.0-216.169.73.255\n216.177.189.0-216.177.189.255\n216.197.242.0-216.197.242.255\n216.211.1.0-216.211.1.255\n216.218.72.0-216.218.72.255\n216.221.127.0-216.221.127.255\n216.229.87.0-216.229.87.255\n216.238.225.0-216.238.225.255\n216.239.32.0-216.239.32.255\n216.239.34.0-216.239.36.255\n216.239.38.0-216.239.38.255\n216.239.90.0-216.239.90.255\n216.254.140.0-216.254.140.255\n217.13.217.0-217.13.217.255\n217.14.201.0-217.14.201.255\n217.15.105.0-217.15.105.255\n217.18.145.0-217.18.145.255\n217.18.243.0-217.18.243.255\n217.19.150.0-217.19.150.255\n217.25.28.0-217.25.28.255\n217.64.139.0-217.64.139.255\n217.69.176.0-217.69.176.255\n217.69.185.0-217.69.185.255\n217.69.188.0-217.69.188.255\n217.73.128.0-217.73.128.255\n217.73.160.0-217.73.160.255\n217.75.205.0-217.75.205.255\n217.76.5.0-217.76.5.255\n217.76.77.0-217.76.78.255\n217.115.45.0-217.115.45.255\n217.116.48.0-217.116.48.255\n217.116.142.0-217.116.143.255\n217.119.118.0-217.119.118.255\n217.147.40.0-217.147.40.255\n217.174.48.0-217.174.48.255\n217.197.249.0-217.197.249.255\n218.189.25.0-218.189.25.255\n218.208.3.0-218.208.3.255\n218.219.168.0-218.219.169.255\n218.253.0.0-218.253.0.255\n219.88.188.0-219.88.189.255\n219.117.33.0-219.117.33.255\n219.117.35.0-219.117.35.255\n219.124.146.0-219.124.146.255\n220.102.0.0-220.102.0.255\n220.148.241.0-220.148.241.255\n220.152.33.0-220.152.33.255\n220.158.148.0-220.158.148.255\n220.225.89.0-220.225.89.255\n220.255.0.0-220.255.0.255\n220.255.2.0-220.255.2.255\n220.255.5.0-220.255.6.255\n221.120.207.0-221.120.207.255\n221.133.0.0-221.133.0.255\n221.133.8.0-221.133.8.255\n221.144.116.0-221.144.116.255\n222.165.163.0-222.165.163.255\n222.251.134.0-222.251.134.255\n223.25.7.0-223.25.7.255\n223.26.69.0-223.26.69.255\n223.27.200.0-223.27.200.255\n223.27.237.0-223.27.237.255\n223.62.225.0-223.62.225.255\n223.62.232.0-223.62.233.255\n223.196.4.0-223.196.4.255\n223.196.9.0-223.196.9.255\n223.196.67.0-223.196.67.255\n223.196.78.0-223.196.78.255\n223.196.81.0-223.196.82.255\n223.196.116.0-223.196.116.255\n223.224.12.0-223.224.12.255\n223.255.227.0-223.255.227.255\n223.255.229.0-223.255.229.255\n"
  },
  {
    "path": "code/default/gae_proxy/local/ip_range.txt",
    "content": "8.8.4.0/24\n8.8.8.0/24\n8.35.200.0/21\n34.0.228.0/22\n34.0.232.0/21\n34.1.64.0/18\n34.2.32.0/19\n34.2.64.0/18\n34.2.128.0/17\n34.3.0.0/23\n34.3.3.0/24\n34.3.4.0/24\n34.3.8.0/21\n34.3.16.0/20\n34.3.32.0/19\n34.3.64.0/18\n34.4.0.0/14\n34.13.64.0/22\n34.13.72.0/21\n34.13.80.0/20\n34.13.96.0/19\n34.14.128.0/17\n34.15.0.0/16\n34.34.192.0/20\n34.34.208.0/21\n34.34.224.0/19\n34.43.0.0/16\n34.50.128.0/19\n34.52.0.0/17\n34.64.0.0/19\n34.96.0.0/18\n34.98.0.0/18\n34.98.136.0/21\n34.98.144.0/20\n34.98.160.0/19\n34.98.192.0/18\n34.99.0.0/16\n34.100.0.0/17\n34.101.0.0/20\n34.101.16.0/23\n34.101.19.0/24\n34.101.28.0/22\n34.103.0.0/16\n34.104.0.0/20\n34.104.16.0/21\n34.104.24.0/23\n34.104.26.0/24\n34.104.28.0/22\n34.104.32.0/20\n34.104.48.0/24\n34.104.53.0/24\n34.104.54.0/23\n34.109.0.0/16\n34.110.0.0/17\n34.113.0.0/16\n34.114.0.0/15\n34.116.8.0/21\n34.116.16.0/20\n34.116.32.0/19\n34.118.208.0/20\n34.118.224.0/20\n34.119.0.0/16\n34.124.64.0/19\n34.124.96.0/20\n34.126.0.0/18\n34.126.224.0/19\n34.127.128.0/19\n34.127.160.0/20\n34.127.176.0/24\n34.127.181.0/24\n34.127.182.0/23\n34.127.192.0/18\n34.128.0.0/19\n34.128.38.0/23\n34.128.40.0/23\n34.128.50.0/23\n34.128.56.0/23\n34.128.192.0/18\n34.143.0.0/17\n34.144.0.0/17\n34.144.128.0/18\n34.152.70.0/23\n34.152.82.0/23\n34.152.88.0/21\n34.152.96.0/19\n34.152.128.0/17\n34.153.0.0/19\n34.153.34.0/23\n34.153.36.0/23\n34.153.39.0/24\n34.153.56.0/23\n34.153.60.0/22\n34.153.64.0/18\n34.153.192.0/19\n34.153.226.0/23\n34.153.228.0/23\n34.153.231.0/24\n34.153.248.0/23\n34.153.252.0/22\n34.156.0.0/16\n34.157.10.0/23\n34.157.86.0/24\n34.157.120.0/24\n34.157.122.0/23\n34.157.138.0/23\n34.157.214.0/24\n34.157.218.0/23\n34.157.248.0/24\n34.158.0.0/16\n34.167.0.0/16\n34.177.0.0/19\n34.177.38.0/23\n34.177.56.0/21\n34.177.64.0/18\n34.177.128.0/17\n34.178.0.0/16\n34.180.0.0/16\n34.183.0.0/16\n34.184.0.0/13\n35.187.128.0/20\n35.190.96.0/20\n35.190.240.0/20\n35.191.0.0/16\n35.199.128.0/20\n35.201.32.0/21\n35.201.40.0/24\n35.201.42.0/23\n35.201.44.0/22\n35.201.48.0/20\n35.203.192.0/20\n35.203.208.0/23\n35.203.220.0/22\n35.203.224.0/21\n35.203.240.0/20\n35.206.0.0/21\n35.206.8.0/23\n35.206.12.0/22\n35.206.16.0/20\n35.218.0.0/16\n35.219.192.0/19\n35.220.28.0/23\n35.220.30.0/24\n35.229.0.0/20\n35.230.192.0/19\n35.230.224.0/20\n35.235.128.0/18\n35.235.192.0/20\n35.235.208.0/21\n35.235.224.0/19\n35.242.28.0/23\n35.242.30.0/24\n35.243.16.0/20\n35.243.48.0/21\n57.140.192.0/18\n64.15.112.0/20\n64.233.160.0/19\n66.22.228.0/23\n66.102.0.0/20\n66.249.64.0/19\n70.32.128.0/19\n72.14.192.0/18\n74.125.0.0/16\n104.154.0.0/20\n104.154.112.0/24\n104.154.122.0/23\n104.154.124.0/22\n104.155.240.0/20\n104.196.64.0/24\n104.196.72.0/21\n104.196.80.0/20\n104.199.64.0/23\n104.199.240.0/23\n104.237.160.0/19\n107.178.192.0/20\n107.178.224.0/20\n108.170.192.0/18\n108.177.0.0/17\n130.211.0.0/22\n136.22.160.0/20\n136.22.176.0/21\n136.22.184.0/23\n136.22.186.0/24\n136.124.0.0/15\n142.250.0.0/15\n146.148.0.0/23\n152.65.208.0/22\n152.65.214.0/23\n152.65.218.0/23\n152.65.222.0/23\n152.65.224.0/19\n162.120.128.0/17\n172.110.32.0/21\n172.217.0.0/16\n172.253.0.0/16\n173.194.0.0/16\n192.178.0.0/15\n193.186.4.0/24\n199.36.154.0/23\n199.36.156.0/24\n199.192.112.0/23\n199.192.114.0/24\n199.223.237.0/24\n199.223.238.0/23\n207.223.160.0/20\n208.65.152.0/22\n208.68.108.0/22\n208.81.188.0/22\n208.117.224.0/19\n209.85.128.0/17\n216.58.192.0/19\n216.73.80.0/20\n216.239.32.0/19\n2001:4860::/32\n2404:6800::/32\n2404:f340::/32\n2600:1900::/34\n2600:1900:4100::/43\n2600:1900:4130::/44\n2600:1900:4190::/44\n2600:1900:41f0::/44\n2600:1900:4200::/41\n2600:1900:42b0::/44\n2600:1900:42c0::/42\n2600:1900:4300::/40\n2600:1900:4400::/38\n2600:1900:4800::/37\n2600:1900:5000::/38\n2600:1900:5410::/44\n2600:1900:5420::/43\n2600:1900:5440::/42\n2600:1900:5480::/41\n2600:1900:5500::/40\n2600:1900:5600::/39\n2600:1900:5800::/37\n2600:1900:6000::/35\n2600:1900:8010::/44\n2600:1900:8020::/43\n2600:1900:8040::/42\n2600:1900:8080::/41\n2600:1900:8100::/40\n2600:1900:8200::/39\n2600:1900:8400::/38\n2600:1900:8800::/37\n2600:1900:9000::/36\n2600:1900:a000::/35\n2600:1900:c000::/34\n2600:1901:1::/48\n2600:1901:2::/47\n2600:1901:4::/46\n2600:1901:8::/45\n2600:1901:10::/44\n2600:1901:20::/43\n2600:1901:40::/42\n2600:1901:80::/41\n2600:1901:100::/40\n2600:1901:200::/39\n2600:1901:400::/38\n2600:1901:800::/37\n2600:1901:1000::/36\n2600:1901:2000::/35\n2600:1901:4000::/44\n2600:1901:4020::/43\n2600:1901:4040::/42\n2600:1901:4080::/41\n2600:1901:4100::/40\n2600:1901:4200::/39\n2600:1901:4400::/38\n2600:1901:4800::/37\n2600:1901:5000::/36\n2600:1901:6000::/35\n2600:1901:8000::/40\n2600:1901:8190::/44\n2600:1901:81a0::/44\n2600:1901:81d0::/44\n2600:1901:81e0::/44\n2600:1901:8200::/39\n2600:1901:8400::/38\n2600:1901:8800::/37\n2600:1901:9000::/36\n2600:1901:a000::/35\n2600:1901:c000::/34\n2600:1902::/31\n2600:1904::/30\n2600:1908::/29\n2605:ef80::/32\n2606:40::/32\n2606:73c0::/32\n2607:1c0:241:40::/60\n2607:1c0:300::/40\n2607:f8b0::/32\n2620:11a:a000::/40\n2620:120:e000::/40\n2800:3f0::/32\n2a00:1450::/32\n2c0f:fb50::/32"
  },
  {
    "path": "code/default/gae_proxy/local/ipv6_list.txt",
    "content": "2607:f8b0:4003:c04::99 google.com gws 100 0 0\n2a00:1450:4009:811::2014 google.com gws 100 0 0\n2a00:1450:401b:804::2014 google.com gws 100 0 0\n2607:f8b0:4020:804::2014 google.com gws 100 0 0\n2a00:1450:400d:809::2014 google.com gws 100 0 0\n2607:f8b0:4005:80a::2014 google.com gws 100 0 0\n2404:6800:4001:806::2014 google.com gws 100 0 0\n2a00:1450:4013:c04::99 google.com gws 100 0 0\n2800:3f0:4001:807::2014 google.com gws 100 0 0\n2a00:1450:4017:80a::2014 google.com gws 100 0 0\n2a00:1450:4007:811::2014 google.com gws 100 0 0\n2607:f8b0:400d:c01::99 google.com gws 100 0 0\n2a00:1450:4002:805::2014 google.com gws 100 0 0\n2800:3f0:4004:809::2014 google.com gws 100 0 0\n2800:3f0:4005:403::2014 google.com gws 100 0 0\n2404:6800:4003:808::2014 google.com gws 100 0 0\n2a00:1450:4009:803::2014 google.com gws 100 0 0\n2a00:1450:4018:803::2014 google.com gws 100 0 0\n2607:f8b0:4007:808::2014 google.com gws 100 0 0\n2404:6800:4005:800::2014 google.com gws 100 0 0\n2607:f8b0:4005:806::2014 google.com gws 100 0 0\n2607:f8b0:4004:80c::2014 google.com gws 100 0 0\n64:ff9b::acd9:c299 google.com gws 100 0 0\n2a00:1450:400a:801::2014 google.com gws 100 0 0\n2a00:1450:4017:804::2014 google.com gws 100 0 0\n2a00:1450:4009:810::2014 google.com gws 100 0 0\n2607:f8b0:4007:80c::2014 google.com gws 100 0 0\n2404:6800:4006:80a::2014 google.com gws 100 0 0\n2a00:1450:4016:809::2014 google.com gws 100 0 0\n2a00:1450:4010:c03::99 google.com gws 100 0 0\n2607:f8b0:4003:c15::99 google.com gws 100 0 0\n2a00:1450:4009:808::2014 google.com gws 100 0 0\n2a00:1450:4006:801::2014 google.com gws 100 0 0\n2a00:1450:4003:803::2014 google.com gws 100 0 0\n2404:6800:4008:802::2014 google.com gws 100 0 0\n2607:f8b0:4002:c07::99 google.com gws 100 0 0\n2a00:1450:400f:80b::2014 google.com gws 100 0 0\n2a00:1450:401b:803::2014 google.com gws 100 0 0\n2a00:1450:4009:801::2014 google.com gws 100 0 0\n2607:f8b0:400e:c09::99 google.com gws 100 0 0\n2404:6800:4009:801::2014 google.com gws 100 0 0\n2404:6800:4009:805::2014 google.com gws 100 0 0\n2404:6800:4004:81a::2014 google.com gws 100 0 0\n2a00:1450:4006:807::2014 google.com gws 100 0 0\n2607:f8b0:4000:817::2014 google.com gws 100 0 0\n2607:f8b0:4000:80c::2014 google.com gws 100 0 0\n2607:f8b0:4004:80f::2014 google.com gws 100 0 0\n2607:f8b0:4003:c17::99 google.com gws 100 0 0\n2607:f8b0:4009:803::2014 google.com gws 100 0 0\n2404:6800:4006:807::2014 google.com gws 100 0 0\n2607:f8b0:400a:808::2014 google.com gws 100 0 0\n2607:f8b0:400b:80f::2014 google.com gws 100 0 0\n2a00:1450:4009:812::2014 google.com gws 100 0 0\n2404:6800:4002:803::2014 google.com gws 100 0 0\n2607:f8b0:4020:807::2014 google.com gws 100 0 0\n2a00:1450:4016:80a::2014 google.com gws 100 0 0\n2800:3f0:4001:805::2014 google.com gws 100 0 0\n2607:f8b0:4009:810::2014 google.com gws 100 0 0\n2a00:1450:4018:802::2014 google.com gws 100 0 0\n2800:3f0:4005:401::2014 google.com gws 100 0 0\n2607:f8b0:4003:c12::99 google.com gws 100 0 0\n2607:f8b0:4012:805::2014 google.com gws 100 0 0\n2404:6800:4007:80f::2014 google.com gws 100 0 0\n2607:f8b0:400d:c0f::99 google.com gws 100 0 0\n2607:f8b0:4004:805::2014 google.com gws 100 0 0\n2a00:1450:4019:801::2014 google.com gws 100 0 0\n2404:6800:4006:808::2014 google.com gws 100 0 0\n2607:f8b0:4005:807::2014 google.com gws 100 0 0\n2c0f:fb50:4002:802::2014 google.com gws 100 0 0\n2a00:1450:401a:805::2014 google.com gws 100 0 0\n2a00:1450:4003:80b::2014 google.com gws 100 0 0\n2a00:1450:4016:807::2014 google.com gws 100 0 0\n2a00:1450:400e:80d::2014 google.com gws 100 0 0\n2404:6800:400a:807::2014 google.com gws 100 0 0\n2607:f8b0:4008:810::2014 google.com gws 100 0 0\n2607:f8b0:400d:c0b::99 google.com gws 100 0 0\n2a00:1450:4007:809::2014 google.com gws 100 0 0\n2607:f8b0:4009:801::2014 google.com gws 100 0 0\n2607:f8b0:4002:c06::99 google.com gws 100 0 0\n2404:6800:4004:818::2014 google.com gws 100 0 0\n2607:f8b0:4001:c0e::99 google.com gws 100 0 0\n2607:f8b0:4001:c1b::99 google.com gws 100 0 0\n2a00:1450:4013:c01::99 google.com gws 100 0 0\n2800:3f0:4001:814::2014 google.com gws 100 0 0\n2404:6800:4007:807::2014 google.com gws 100 0 0\n2607:f8b0:400f:800::2014 google.com gws 100 0 0\n2404:6800:4004:80b::2014 google.com gws 100 0 0\n2a00:1450:401b:805::2014 google.com gws 100 0 0\n2607:f8b0:4007:806::2014 google.com gws 100 0 0\n2404:6800:4005:804::2014 google.com gws 100 0 0\n2a00:1450:4003:801::2014 google.com gws 100 0 0\n2a00:1450:4006:802::2014 google.com gws 100 0 0\n2607:f8b0:4009:80c::2014 google.com gws 100 0 0\n2800:3f0:4004:807::2014 google.com gws 100 0 0\n2607:f8b0:4009:812::2014 google.com gws 100 0 0\n2404:6800:4009:807::2014 google.com gws 100 0 0\n2607:f8b0:4008:803::2014 google.com gws 100 0 0\n2a00:1450:4005:80a::2014 google.com gws 100 0 0\n2a00:1450:4016:808::2014 google.com gws 100 0 0\n2800:3f0:4001:80f::2014 google.com gws 100 0 0\n2404:6800:4008:c04::99 google.com gws 100 0 0\n2a00:1450:4002:808::2014 google.com gws 100 0 0\n2404:6800:4001:800::2014 google.com gws 100 0 0\n2800:3f0:4002:804::2014 google.com gws 100 0 0\n2a00:1450:4013:c03::99 google.com gws 100 0 0\n2404:6800:4004:800::2014 google.com gws 100 0 0\n2607:f8b0:400f:805::2014 google.com gws 100 0 0\n2607:f8b0:4009:80a::2014 google.com gws 100 0 0\n2a00:1450:4017:807::2014 google.com gws 100 0 0\n2a00:1450:400e:805::2014 google.com gws 100 0 0\n2a00:1450:4005:800::2014 google.com gws 100 0 0\n2a00:1450:4007:816::2014 google.com gws 100 0 0\n2a00:1450:4003:809::2014 google.com gws 100 0 0\n2a00:1450:4001:824::2014 google.com gws 100 0 0\n2607:f8b0:4003:c00::99 google.com gws 100 0 0\n2a00:1450:400c:c04::99 google.com gws 100 0 0\n2404:6800:4004:807::2014 google.com gws 100 0 0\n2607:f8b0:4005:805::2014 google.com gws 100 0 0\n2607:f8b0:400e:c03::99 google.com gws 100 0 0\n2404:6800:4001:80f::2014 google.com gws 100 0 0\n2607:f8b0:4009:811::2014 google.com gws 100 0 0\n2a00:1450:4010:c09::99 google.com gws 100 0 0\n2607:f8b0:4006:810::2014 google.com gws 100 0 0\n2607:f8b0:4002:c08::99 google.com gws 100 0 0\n2a00:1450:4009:804::2014 google.com gws 100 0 0\n2a00:1450:400e:806::2014 google.com gws 100 0 0\n2404:6800:4002:804::2014 google.com gws 100 0 0\n2a00:1450:4009:807::2014 google.com gws 100 0 0\n2607:f8b0:400a:800::2014 google.com gws 100 0 0\n64:ff9b::4a7d:1899 google.com gws 100 0 0\n2800:3f0:4002:808::2014 google.com gws 100 0 0\n2800:3f0:4002:809::2014 google.com gws 100 0 0\n2a00:1450:400c:c08::99 google.com gws 100 0 0\n2800:3f0:4004:800::2014 google.com gws 100 0 0\n2a00:1450:401b:807::2014 google.com gws 100 0 0\n2607:f8b0:400b:809::2014 google.com gws 100 0 0\n2607:f8b0:4009:809::2014 google.com gws 100 0 0\n2a00:1450:4009:80f::2014 google.com gws 100 0 0\n2a00:1450:4007:813::2014 google.com gws 100 0 0\n2607:f8b0:4002:c09::99 google.com gws 100 0 0\n2404:6800:4003:802::2014 google.com gws 100 0 0\n2a00:1450:4003:807::2014 google.com gws 100 0 0\n2a00:1450:4001:820::2014 google.com gws 100 0 0\n2607:f8b0:4006:803::2014 google.com gws 100 0 0\n2404:6800:4009:802::2014 google.com gws 100 0 0\n2607:f8b0:4006:815::2014 google.com gws 100 0 0\n2a00:1450:4009:814::2014 google.com gws 100 0 0\n2a00:1450:401b:806::2014 google.com gws 100 0 0\n2607:f8b0:4000:811::2014 google.com gws 100 0 0\n2404:6800:4012::2014 google.com gws 100 0 0\n2a00:1450:4007:817::2014 google.com gws 100 0 0\n2404:6800:4009:80a::2014 google.com gws 100 0 0\n2404:6800:4005:805::2014 google.com gws 100 0 0\n2a00:1450:401b:800::2014 google.com gws 100 0 0\n2a00:1450:400e:802::2014 google.com gws 100 0 0\n2404:6800:4006:803::2014 google.com gws 100 0 0\n2404:6800:4007:80b::2014 google.com gws 100 0 0\n2607:f8b0:4009:80b::2014 google.com gws 100 0 0\n2607:f8b0:4009:802::2014 google.com gws 100 0 0\n2800:3f0:4002:805::2014 google.com gws 100 0 0\n2a00:1450:4010:c01::99 google.com gws 100 0 0\n2404:6800:4004:80e::2014 google.com gws 100 0 0\n2607:f8b0:4000:806::2014 google.com gws 100 0 0\n2404:6800:4005:80c::2014 google.com gws 100 0 0\n2607:f8b0:4012:80b::2014 google.com gws 100 0 0\n2607:f8b0:4004:804::2014 google.com gws 100 0 0\n2404:6800:4003:807::2014 google.com gws 100 0 0\n2607:f8b0:4000:813::2014 google.com gws 100 0 0\n2404:6800:4005:808::2014 google.com gws 100 0 0\n2800:3f0:4001:80a::2014 google.com gws 100 0 0\n2607:f8b0:4009:806::2014 google.com gws 100 0 0\n2404:6800:4001:801::2014 google.com gws 100 0 0\n2607:f8b0:4000:808::2014 google.com gws 100 0 0\n2a00:1450:4019:802::2014 google.com gws 100 0 0\n2404:6800:4004:806::2014 google.com gws 100 0 0\n2a00:1450:400d:805::2014 google.com gws 100 0 0\n2607:f8b0:4009:80f::2014 google.com gws 100 0 0\n2a00:1450:400f:806::2014 google.com gws 100 0 0\n2a00:1450:4007:80e::2014 google.com gws 100 0 0\n2404:6800:4007:801::2014 google.com gws 100 0 0\n2607:f8b0:4006:80f::2014 google.com gws 100 0 0\n2a00:1450:401b:802::2014 google.com gws 100 0 0\n2a00:1450:400d:808::2014 google.com gws 100 0 0\n2404:6800:400a:806::2014 google.com gws 100 0 0\n2404:6800:400a:80b::2014 google.com gws 100 0 0\n2800:3f0:4001:815::2014 google.com gws 100 0 0\n2607:f8b0:4000:804::2014 google.com gws 100 0 0\n2607:f8b0:4009:815::2014 google.com gws 100 0 0\n2a00:1450:400e:804::2014 google.com gws 100 0 0\n2a00:1450:4017:80b::2014 google.com gws 100 0 0\n2607:f8b0:4008:813::2014 google.com gws 100 0 0\n2404:6800:4001:80c::2014 google.com gws 100 0 0\n2a00:1450:4001:80b::2014 google.com gws 100 0 0\n2404:6800:4001:803::2014 google.com gws 100 0 0\n2a00:1450:4018:800::2014 google.com gws 100 0 0\n2a00:1450:400f:809::2014 google.com gws 100 0 0\n2607:f8b0:4003:c05::99 google.com gws 100 0 0\n2a00:1450:400c:c07::99 google.com gws 100 0 0\n2a00:1450:4003:805::2014 google.com gws 100 0 0\n2800:3f0:4001:806::2014 google.com gws 100 0 0\n2a00:1450:4001:81b::2014 google.com gws 100 0 0\n2a00:1450:4010:c02::99 google.com gws 100 0 0\n2607:f8b0:4009:804::2014 google.com gws 100 0 0\n2607:f8b0:4002:c02::99 google.com gws 100 0 0\n2404:6800:4008:c07::99 google.com gws 100 0 0\n2a00:1450:4001:806::2014 google.com gws 100 0 0\n2a00:1450:4002:807::2014 google.com gws 100 0 0\n2a00:1450:4007:808::2014 google.com gws 100 0 0\n2607:f8b0:4003:c19::99 google.com gws 100 0 0\n2a00:1450:400f:80c::2014 google.com gws 100 0 0\n2607:f8b0:4003:c01::99 google.com gws 100 0 0\n2404:6800:4005:801::2014 google.com gws 100 0 0\n2404:6800:4004:80c::2014 google.com gws 100 0 0\n2607:f8b0:4006:804::2014 google.com gws 100 0 0\n2404:6800:4009:804::2014 google.com gws 100 0 0\n2a00:1450:400e:808::2014 google.com gws 100 0 0\n2607:f8b0:4007:80e::2014 google.com gws 100 0 0\n2a00:1450:400a:802::2014 google.com gws 100 0 0\n2a00:1450:4001:815::2014 google.com gws 100 0 0\n2404:6800:4009:808::2014 google.com gws 100 0 0\n2607:f8b0:4005:80b::2014 google.com gws 100 0 0\n2a00:1450:400f:808::2014 google.com gws 100 0 0\n2a00:1450:4001:808::2014 google.com gws 100 0 2\n2404:6800:4009:80e::2014 google.com gws 100 0 0\n2a00:1450:4016:80b::2014 google.com gws 100 0 0\n2404:6800:4005:80b::2014 google.com gws 100 0 0\n2a00:1450:4007:80c::2014 google.com gws 100 0 0\n2607:f8b0:4006:819::2014 google.com gws 100 0 0\n2607:f8b0:400b:80c::2014 google.com gws 100 0 0\n2a00:1450:4002:809::2014 google.com gws 100 0 0\n2607:f8b0:4000:814::2014 google.com gws 100 0 0\n2404:6800:4009:809::2014 google.com gws 100 0 0\n2404:6800:4005:810::2014 google.com gws 100 0 0\n2607:f8b0:4007:804::2014 google.com gws 100 0 0\n2607:f8b0:4004:801::2014 google.com gws 100 0 0\n2a00:1450:400f:80a::2014 google.com gws 100 0 0\n2607:f8b0:400f:804::2014 google.com gws 100 0 0\n2607:f8b0:4007:800::2014 google.com gws 100 0 0\n2607:f8b0:4004:80e::2014 google.com gws 100 0 0\n2a00:1450:4009:80c::2014 google.com gws 100 0 0\n2607:f8b0:4000:812::2014 google.com gws 100 0 0\n2404:6800:4001:80d::2014 google.com gws 100 0 0\n2404:6800:4007:808::2014 google.com gws 100 0 0\n2404:6800:4005:807::2014 google.com gws 100 0 0\n2a00:1450:4014:80c::2014 google.com gws 100 0 0\n2607:f8b0:4000:815::2014 google.com gws 100 0 0\n2800:3f0:4003:c00::99 google.com gws 100 0 0\n2a00:1450:400f:807::2014 google.com gws 100 0 0\n2404:6800:4009:806::2014 google.com gws 100 0 0\n2800:3f0:4004:806::2014 google.com gws 100 0 0\n2404:6800:4005:803::2014 google.com gws 100 0 0\n2607:f8b0:4000:80e::2014 google.com gws 100 0 0\n2607:f8b0:400a:803::2014 google.com gws 100 0 0\n2a00:1450:4007:805::2014 google.com gws 100 0 0\n2404:6800:4008:c01::99 google.com gws 100 0 0\n2404:6800:4009:80d::2014 google.com gws 100 0 0\n2404:6800:400a:80c::2014 google.com gws 100 0 0\n2a00:1450:400e:80a::2014 google.com gws 100 0 0\n2607:f8b0:4006:811::2014 google.com gws 100 0 0\n2a00:1450:4016:80d::2014 google.com gws 100 0 0\n2607:f8b0:4000:802::2014 google.com gws 100 0 0\n2404:6800:4004:809::2014 google.com gws 100 0 0\n2a00:1450:4007:812::2014 google.com gws 100 0 0\n2404:6800:4004:80a::2014 google.com gws 100 0 0\n2a00:1450:4017:806::2014 google.com gws 100 0 0\n2a00:1450:4017:808::2014 google.com gws 100 0 0\n2800:3f0:4002:80a::2014 google.com gws 100 0 0\n2a00:1450:4005:80b::2014 google.com gws 100 0 0\n2a00:1450:4002:806::2014 google.com gws 100 0 0\n2607:f8b0:4006:802::2014 google.com gws 100 0 0\n2800:3f0:4001:802::2014 google.com gws 100 0 0\n2404:6800:4005:806::2014 google.com gws 100 0 0\n2a00:1450:4007:814::2014 google.com gws 100 0 0\n2607:f8b0:4008:802::2014 google.com gws 100 0 0\n2800:3f0:4004:805::2014 google.com gws 100 0 0\n2a00:1450:4007:80a::2014 google.com gws 100 0 0\n2a00:1450:4009:802::2014 google.com gws 100 0 0\n2404:6800:4003:c01::99 google.com gws 100 0 0\n2404:6800:4007:800::2014 google.com gws 100 0 0\n2a00:1450:4001:821::2014 google.com gws 100 0 0\n2404:6800:4004:801::2014 google.com gws 100 0 0\n2607:f8b0:4008:80c::2014 google.com gws 100 0 0\n2404:6800:4004:80f::2014 google.com gws 100 0 0\n2607:f8b0:4002:c00::99 google.com gws 100 0 0\n2404:6800:4003:c04::99 google.com gws 100 0 0\n2404:6800:4006:802::2014 google.com gws 100 0 0\n2607:f8b0:4006:81a::2014 google.com gws 100 0 0\n2607:f8b0:4005:801::2014 google.com gws 100 0 0\n2404:6800:4001:804::2014 google.com gws 100 0 0\n2a00:1450:4009:815::2014 google.com gws 100 0 0\n2607:f8b0:4007:802::2014 google.com gws 100 0 0\n2404:6800:4008:801::2014 google.com gws 100 0 0\n2a00:1450:400e:803::2014 google.com gws 100 0 0\n2607:f8b0:4007:80b::2014 google.com gws 100 0 0\n2a00:1450:4007:80f::2014 google.com gws 100 0 0\n2607:f8b0:4004:80d::2014 google.com gws 100 0 0\n2800:3f0:4004:808::2014 google.com gws 100 0 0\n2a00:1450:4010:c0f::99 google.com gws 100 0 0\n2a00:1450:4009:809::2014 google.com gws 100 0 0\n2404:6800:4006:806::2014 google.com gws 100 0 0\n2404:6800:4003:c03::99 google.com gws 100 0 0\n2404:6800:4004:80d::2014 google.com gws 100 0 0\n2607:f8b0:4006:813::2014 google.com gws 100 0 0\n2a00:1450:4010:c08::99 google.com gws 100 0 0\n2607:f8b0:4009:808::2014 google.com gws 100 0 0\n2a00:1450:4017:800::2014 google.com gws 100 0 0\n2a00:1450:4014:801::2014 google.com gws 100 0 0\n2a00:1450:4003:80a::2014 google.com gws 100 0 0\n2607:f8b0:4020:805::2014 google.com gws 100 0 0\n2607:f8b0:4012:808::2014 google.com gws 100 0 0\n2a00:1450:400e:80c::2014 google.com gws 100 0 0\n2a00:1450:4001:81f::2014 google.com gws 100 0 0\n2800:3f0:4001:80c::2014 google.com gws 100 0 0\n2607:f8b0:4007:809::2014 google.com gws 100 0 0\n2607:f8b0:4006:812::2014 google.com gws 100 0 0\n2a00:1450:4010:c0d::99 google.com gws 100 0 0\n2607:f8b0:400b:808::2014 google.com gws 100 0 0\n2a00:1450:4007:80d::2014 google.com gws 100 0 0\n2800:3f0:4005:400::2014 google.com gws 100 0 0\n2a00:1450:4017:801::2014 google.com gws 100 0 0\n2607:f8b0:4006:800::2014 google.com gws 100 0 0\n2607:f8b0:4009:816::2014 google.com gws 100 0 0\n2404:6800:400a:808::2014 google.com gws 100 0 0\n2607:f8b0:400a:804::2014 google.com gws 100 0 0\n2a00:1450:4016:800::2014 google.com gws 100 0 0\n2607:f8b0:4004:810::2014 google.com gws 100 0 0\n2c0f:fb50:4002:803::2014 google.com gws 100 0 0\n2607:f8b0:4006:814::2014 google.com gws 100 0 0\n2800:3f0:4003:c02::99 google.com gws 100 0 0\n2404:6800:4009:810::2014 google.com gws 100 0 0\n2404:6800:4005:809::2014 google.com gws 100 0 0\n2a00:1450:4003:804::2014 google.com gws 100 0 0\n2404:6800:4003:c02::99 google.com gws 100 0 0\n2607:f8b0:4006:801::2014 google.com gws 100 0 0\n2404:6800:4005:80d::2014 google.com gws 100 0 0\n2a00:1450:4016:806::2014 google.com gws 100 0 0\n2a00:1450:4014:80d::2014 google.com gws 100 0 0\n2a00:1450:4009:800::2014 google.com gws 100 0 0\n2a00:1450:400c:c0c::99 google.com gws 100 0 0\n2404:6800:4005:811::2014 google.com gws 100 0 0\n2a00:1450:4010:c05::99 google.com gws 100 0 0\n2a00:1450:4003:806::2014 google.com gws 100 0 0\n2607:f8b0:400b:80d::2014 google.com gws 100 0 0\n2800:3f0:4004:801::2014 google.com gws 100 0 0\n2a00:1450:4017:809::2014 google.com gws 100 0 0\n2a00:1450:4010:c0e::99 google.com gws 100 0 0\n2404:6800:4009:803::2014 google.com gws 100 0 0\n2a00:1450:4007:815::2014 google.com gws 100 0 0\n2404:6800:4009:800::2014 google.com gws 100 0 0\n2a00:1450:4001:816::2014 google.com gws 100 0 0\n2800:3f0:4001:803::2014 google.com gws 100 0 0\n2a00:1450:4013:c00::99 google.com gws 100 0 0\n2a00:1450:4009:80d::2014 google.com gws 100 0 0\n2607:f8b0:4002:c0c::99 google.com gws 100 0 0\n2a00:1450:4009:80e::2014 google.com gws 100 0 0\n2a00:1450:4009:813::2014 google.com gws 100 0 0\n2a00:1450:4014:800::2014 google.com gws 100 0 0\n2607:f8b0:4007:80d::2014 google.com gws 100 0 0\n2404:6800:4005:802::2014 google.com gws 100 0 0\n2404:6800:4005:80f::2014 google.com gws 100 0 0\n2404:6800:4004:819::2014 google.com gws 100 0 0\n2800:3f0:4001:80d::2014 google.com gws 100 0 0\n2607:f8b0:4004:802::2014 google.com gws 100 0 0\n2a00:1450:4010:c0b::99 google.com gws 100 0 0\n2404:6800:4009:80c::2014 google.com gws 100 0 0\n2404:6800:4009:80b::2014 google.com gws 100 0 0\n2a00:1450:4002:80b::2014 google.com gws 100 0 0\n2607:f8b0:4012:804::2014 google.com gws 100 0 0\n2a00:1450:4001:81d::2014 google.com gws 600 0 0\n2800:3f0:4001:810::2014 google.com gws 600 0 0\n2607:f8b0:4006:80e::2014 google.com gws 600 0 0\n2a00:1450:4001:819::2014 google.com gws 600 0 0\n2a00:1450:4013:c07::99 google.com gws 600 0 0\n2a00:1450:4019:803::2014 google.com gws 600 0 0\n2607:f8b0:4005:802::2014 google.com gws 600 0 0\n2404:6800:4002:80a::2014 google.com gws 600 0 0\n2a00:1450:4019:800::2014 google.com gws 600 0 0\n2404:6800:4006:804::2014 google.com gws 600 0 0\n2404:6800:4004:81b::2014 google.com gws 600 0 0\n2a00:1450:4002:800::2014 google.com gws 600 0 0\n2607:f8b0:4012:80a::2014 google.com gws 600 0 0\n2607:f8b0:400f:806::2014 google.com gws 600 0 0\n2a00:1450:400e:809::2014 google.com gws 600 0 0\n2607:f8b0:400b:80e::2014 google.com gws 600 0 0\n2404:6800:4002:802::2014 google.com gws 600 0 0\n2800:3f0:4001:80b::2014 google.com gws 600 0 0\n2404:6800:4003:c00::99 google.com gws 600 0 0\n2800:3f0:4005:402::2014 google.com gws 600 0 0\n2607:f8b0:4008:811::2014 google.com gws 600 0 0\n2607:f8b0:4004:800::2014 google.com gws 600 0 0\n2404:6800:4004:808::2014 google.com gws 600 0 0\n2a00:1450:4002:802::2014 google.com gws 600 0 0\n2a00:1450:4002:80a::2014 google.com gws 600 0 0\n2404:6800:4003:80a::2014 google.com gws 600 0 0\n2607:f8b0:4008:805::2014 google.com gws 600 0 0\n2c0f:fb50:4003:801::2014 google.com gws 600 0 0\n2607:f8b0:4004:80b::2014 google.com gws 600 0 0\n2a00:1450:4007:810::2014 google.com gws 600 0 0\n2607:f8b0:4000:80d::2014 google.com gws 600 0 0\n2a00:1450:4010:c07::99 google.com gws 600 0 0\n2404:6800:4012:1::2014 google.com gws 600 0 0\n2607:f8b0:4003:c09::99 google.com gws 600 0 0\n2800:3f0:4001:808::2014 google.com gws 600 0 0\n2a00:1450:4001:817::2014 google.com gws 600 0 0\n2404:6800:4005:80a::2014 google.com gws 600 0 0\n2a00:1450:4003:802::2014 google.com gws 600 0 0\n2607:f8b0:4008:80e::2014 google.com gws 600 0 0\n2607:f8b0:4005:804::2014 google.com gws 600 0 0\n2a00:1450:4010:c0a::99 google.com gws 600 0 0\n2a00:1450:400d:803::2014 google.com gws 600 0 0\n2607:f8b0:4009:807::2014 google.com gws 600 0 0\n2607:f8b0:4004:803::2014 google.com gws 600 0 0\n2800:3f0:4001:809::2014 google.com gws 600 0 0\n2607:f8b0:4006:818::2014 google.com gws 600 0 0\n2607:f8b0:400f:807::2014 google.com gws 600 0 0\n2800:3f0:4001:816::2014 google.com gws 600 0 0\n2a00:1450:4006:808::2014 google.com gws 600 0 0\n2404:6800:4008:c00::99 google.com gws 600 0 0\n2607:f8b0:4009:80d::2014 google.com gws 600 0 0\n2800:3f0:4003:c01::99 google.com gws 600 0 0\n2a00:1450:400e:807::2014 google.com gws 600 0 0\n2607:f8b0:4002:c03::99 google.com gws 600 0 0\n2404:6800:4003:804::2014 google.com gws 600 0 0\n2a00:1450:4001:81c::2014 google.com gws 100 1 0\n2a00:1450:400d:806::2014 google.com gws 100 1 0\n2a00:1450:4001:81a::2014 google.com gws 100 1 0\n2a00:1450:4001:825::2014 google.com gws 100 1 0\n2800:3f0:4001:817::2014 google.com gws 100 1 0\n"
  },
  {
    "path": "code/default/gae_proxy/local/ipv6_tunnel/IPV6_note.TXT",
    "content": "#ͣáip helper\nnet stop \"ip helper\"\n\n#áip helper\nnet start \"ip helper\"\n\n#ʾTeredoϢ\nnetsh interface ipv6 show teredo\n\n#Teredo6to4isatap\nnetsh interface teredo set state default\nnetsh interface 6to4 set state default\nnetsh interface isatap set state default\n\n#رպжTeredo6to4isatap\nnetsh interface teredo set state disable\nnetsh interface 6to4 set state disabled\nnetsh interface isatap set state disabled\n\n#Teredo\nnetsh interface Teredo set state type=default\n\n#Teredo\nnetsh interface teredo set state server=teredo.remlab.net\nnetsh interface teredo set state server=teredo-debian.remlab.net\nnetsh interface teredo set state server=teredo.trex.fi\n\n#TeredoΪteredo.ipv6.microsoft.comteredoϣ\nnetsh interface ipv6 set teredo client teredo.ipv6.microsoft.com\n\n#isatapPINGͨ\nnetsh int IPV6 isatap set router isatap.scu.edu.cn\n\n#ֶWindows7IPv6ֵ֧覴\nnetsh interface IPV6 set global randomizeidentifiers=disabled\n\n#Teredo\nnetsh interface ipv6 set teredo enterpriseclient\nnetsh int ter set state enterpriseclient\n\n#ֶ㣨IPv4ñӣIPv6ַ\n#IPv4ַ\nhttp://ip-lookup.net/conversion.php\n#޸ıIPv6ַ\n#ǰ׺ 48\n\n#google ipv6 dns:\n2001:4860:4860::8888\n2001:4860:4860::8844\n\n#opendns ipv6 dns:\n2620:0:ccc::2\n2620:0:ccd::2\n\n#HE ipv6 dns:\n2001:470:20::2\n\nipconfig /all\nipconfig /flushdns\nnetsh int ipv6 show int\nnetsh int ipv6 show route\n\n#teredo״̬ǲqualified\nnetsh int ipv6 show teredo\n\n#ɾ·\nroute DELETE ::/0\n\n#· (һҪһ)\nnetsh int ipv6 add route ::/0 \"Teredo Tunneling Pseudo-Interface\"\n\n#ڡstart.bat䣬ʵXXִ\nnetsh int ipv6 add route ::/0 \"Teredo Tunneling Pseudo-Interface\"\nSET PYTHONPATH=\"%~dp0%start.vbs\" console\n\n#ȼ\nnetsh int ipv6 show prefix\nnetsh int ipv6 set prefix 2002::/16 30 1\nnetsh int ipv6 set prefix 2001::/32 5 1\n\n#鿴Teredo Tunneling Pseudo-Interface ӿ\nroute print\n\n#ʾIPv6ַ\nnetsh interface ipv6 show address\n\n#ʾIPv6·\nnetsh interface ipv6 show route\n\n#ipv6\nnetsh interface ipv6 reset\n\n#\" 2\"ԼҪ\nnetsh interface set interface \" 2\" disabled\nnetsh interface set interface \" 2\" enabled\n\n#IPV6վ\n\nhttp://test-ipv6.com/\n#ժҪֲɺ뵽Ŀв鿴\n#ȫǡɹġ\n\nhttp://www.kame.net/kame-mosaic.html\n#IPv6Կڹ꣬IPv4ڹ겻"
  },
  {
    "path": "code/default/gae_proxy/local/ipv6_tunnel/__init__.py",
    "content": "\nimport sys\nimport platform\n\nfrom .common import test_teredo\n\nif \"arm\" in platform.machine():\n    from .unknown import state, state_pp, switch_pp, enable, disable, set_best_server\nelif sys.platform == \"win32\":\n    from .win10 import state, state_pp, switch_pp, enable, disable, set_best_server\nelif sys.platform.startswith(\"linux\"):\n    from .linux import state, state_pp, switch_pp, enable, disable, set_best_server\nelif sys.platform == \"darwin\":\n    from .darwin import state, state_pp, switch_pp, enable, disable, set_best_server\nelse:\n    from .unknown import state, state_pp, switch_pp, enable, disable, set_best_server\n"
  },
  {
    "path": "code/default/gae_proxy/local/ipv6_tunnel/common.py",
    "content": "import os\nimport shlex\nimport subprocess\n\nfrom .pteredor import teredo_prober\nimport env_info\nimport utils\nfrom xlog import getLogger\nxlog = getLogger(\"gae_proxy\")\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nroot_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir, os.pardir))\ndata_path = os.path.join(env_info.data_path, \"gae_proxy\")\nif not os.path.isdir(data_path):\n    data_path = current_path\n\nlog_file = os.path.join(data_path, \"ipv6_tunnel.log\")\n\nif os.path.isfile(log_file):\n    os.remove(log_file)\n\n\nclass Log(object):\n    def __init__(self):\n        self.fd = open(log_file, \"a\")\n\n    def write(self, content):\n        self.fd.write(content + \"\\n\")\n        self.fd.flush()\n\n    def close(self):\n        self.fd.close()\n\n\npteredor_is_running = False\n\n\ndef new_pteredor(probe_nat=True):\n    if os.path.isfile(log_file):\n        try:\n            os.remove(log_file)\n        except Exception as e:\n            xlog.warn(\"remove %s fail:%r\", log_file, e)\n\n    global pteredor_is_running, usable\n    pteredor_is_running = probe_nat\n    prober = teredo_prober(probe_nat=probe_nat)\n\n    if prober.nat_type in ('cone', 'restricted'):\n        usable = 'usable'\n    elif prober.nat_type == 'offline':\n        usable = 'unusable'\n    else:\n        usable = 'unknown'\n\n    if probe_nat:\n        pteredor_is_running = False\n        log = Log()\n        log.write('qualified: %s\\nNAT type: %s' % (prober.qualified, prober.nat_type))\n        log.close()\n    return prober\n\n\ndef test_teredo(probe_nat=True, probe_server=True):\n    if pteredor_is_running:\n        return \"Script is running, please retry later.\"\n\n    server = ''\n    if probe_server:\n        server = ' and the best server is %s.' % best_server(probe_nat=probe_nat)\n    else:\n        new_pteredor()\n\n    return 'teredor test result is %s.%s' % (usable, server)\n\n\ndef best_server(probe_nat=False):\n    best_server = None\n    prober = new_pteredor(probe_nat=probe_nat)\n    prober.qualified = True\n    if not probe_nat:\n        prober.nat_type = 'unknown'\n        prober.rs_cone_flag = 0\n\n    global pteredor_is_running\n    pteredor_is_running = True\n    server_list = prober.eval_servers()\n    pteredor_is_running = False\n\n    for qualified, server, _, _ in server_list:\n        if qualified:\n            best_server = server[0]\n            break\n    log = Log()\n    if best_server:\n        log.write('best server is: %s.' % best_server)\n    else:\n        xlog.warning('no server detected, return default: teredo.remlab.net.')\n        log.write('no server detected, return default: teredo.remlab.net.')\n        best_server = \"teredo.remlab.net\"\n    log.close()\n    return best_server\n\n\ndef run(cmd):\n    cmd = shlex.split(cmd)\n\n    try:\n        # hide console in MS windows\n        startupinfo = subprocess.STARTUPINFO()\n        startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW\n        startupinfo.wShowWindow = subprocess.SW_HIDE\n\n        #out = subprocess.check_output(cmd, startupinfo=startupinfo)\n        process = subprocess.Popen(cmd, stdout=subprocess.PIPE, startupinfo=startupinfo)\n        out, unused_err = process.communicate()\n        retcode = process.poll()\n        if retcode:\n            return out + b\"\\n retcode:%s\\n unused_err:%s\\n\" % (retcode, unused_err)\n    except Exception as e:\n        out = \"Exception:%r\" % e\n\n    return utils.to_str(out, coding=\"gb18030\")\n\n\ndef run_cmds(cmds):\n    log = Log()\n    cmd_pl = cmds.split(\"\\n\")\n    outs = []\n    for cmd in cmd_pl:\n        if not cmd:\n            continue\n\n        if cmd.startswith(\"#\"):\n            log.write(\"%s\" % cmd)\n            continue\n\n        log.write(\"\\n>: %s\\n------------------------------------\" % cmd)\n        out = run(cmd)\n        log.write(out)\n        outs.append(out)\n    log.close()\n    return \"\\r\\n\".join(outs)\n\n\ndef get_line_value(r, n):\n    r = utils.to_str(r)\n    rls = r.split(\"\\r\\n\")\n    if len(rls) < n + 1:\n        return None\n\n    lp = rls[n].split(\":\")\n    if len(lp) < 2:\n        return None\n\n    value = lp[1].strip()\n    return value\n"
  },
  {
    "path": "code/default/gae_proxy/local/ipv6_tunnel/darwin.py",
    "content": "#!/usr/bin/env python2\n# coding:utf-8\n\nimport os\nimport sys\nfrom .common import *\n\n\ndef state():\n    return \"Developing\"\n\n\ndef state_pp():\n    return \"Developing\"\n\n\ndef switch_pp():\n    return \"Developing\"\n\n\ndef enable(is_local=False):\n    return \"Developing\"\n\n\ndef disable(is_local=False):\n    return \"Developing\"\n\n\ndef set_best_server(is_local=False):\n    return \"Developing\"\n"
  },
  {
    "path": "code/default/gae_proxy/local/ipv6_tunnel/disable_ipv6.bat",
    "content": "@echo off\necho Get Admin\n::ver|findstr \"[6,10]\\.[0-9]\\.[0-9][0-9]*\" > nul && (goto Main)\n::ver|findstr \"[3-5]\\.[0-9]\\.[0-9][0-9]*\" > nul && (goto isBelowNT6)\n\n:: :isBelowNT6\n\n:Main\n@echo off\ncd /d \"%~dp0\"\ncacls.exe \"%SystemDrive%\\System Volume Information\" >nul 2>nul\nif %errorlevel%==0 goto Admin\nif exist \"%temp%\\getadmin.vbs\" del /f /q \"%temp%\\getadmin.vbs\"\necho Set RequestUAC = CreateObject^(\"Shell.Application\"^)>\"%temp%\\getadmin.vbs\"\necho RequestUAC.ShellExecute \"%~s0\",\"\",\"\",\"runas\",1 >>\"%temp%\\getadmin.vbs\"\necho WScript.Quit >>\"%temp%\\getadmin.vbs\"\n\"%temp%\\getadmin.vbs\" /f\nif exist \"%temp%\\getadmin.vbs\" del /f /q \"%temp%\\getadmin.vbs\"\nexit\n\n:Admin\n\nnetsh interface teredo set state disable\nnetsh interface 6to4 set state disabled\nnetsh interface isatap set state disabled\n"
  },
  {
    "path": "code/default/gae_proxy/local/ipv6_tunnel/enable_ipv6.bat",
    "content": ":: XX-Net\n:: Enable IPV6\n:: https://github.com/XX-net/XX-Net-dev/issues/53\n\n:: https://www.zhihu.com/question/34541107/answer/137174053\n@echo off\necho Get Admin\n::ver|findstr \"[6,10]\\.[0-9]\\.[0-9][0-9]*\" > nul && (goto Main)\n::ver|findstr \"[3-5]\\.[0-9]\\.[0-9][0-9]*\" > nul && (goto isBelowNT6)\n\n:: :isBelowNT6\n\n:Main\n@echo off\ncd /d \"%~dp0\"\ncacls.exe \"%SystemDrive%\\System Volume Information\" >nul 2>nul\nif %errorlevel%==0 goto Admin\nif exist \"%temp%\\getadmin.vbs\" del /f /q \"%temp%\\getadmin.vbs\"\necho Set RequestUAC = CreateObject^(\"Shell.Application\"^)>\"%temp%\\getadmin.vbs\"\necho RequestUAC.ShellExecute \"%~s0\",\"\",\"\",\"runas\",1 >>\"%temp%\\getadmin.vbs\"\necho WScript.Quit >>\"%temp%\\getadmin.vbs\"\n\"%temp%\\getadmin.vbs\" /f\nif exist \"%temp%\\getadmin.vbs\" del /f /q \"%temp%\\getadmin.vbs\"\nexit\n\n:Admin\n@echo off\n\n\nsc config RpcEptMapper start= auto\nsc start RpcEptMapper\n\nsc config DcomLaunch start= auto\nsc start DcomLaunch\n\nsc config RpcSs start= auto\nsc start RpcSs\n\nsc config nsi start= auto\nsc start nsi\n\nsc config Winmgmt start= auto\nsc start Winmgmt\n\nsc config Dhcp start= auto\nsc start Dhcp\n\nsc config WinHttpAutoProxySvc start= auto\nsc start WinHttpAutoProxySvc\n\nsc config iphlpsvc start= auto\nsc start iphlpsvc\n\n:: Reset IPv6\nnetsh interface ipv6 reset\n\n:: Reset Group Policy Teredo\n..\\..\\..\\..\\..\\python3.8.2\\python.exe win_reset_gp.py\n\nnetsh interface teredo set state type=enterpriseclient servername=teredo.remlab.net.\n\n:: Keep teredo interface route (not needed with reset?)\n:: route DELETE ::/0\n:: netsh interface ipv6 add route ::/0 \"Teredo Tunneling Pseudo-Interface\"\n\n:: Set IPv6 prefixpolicies\n:: See https://tools.ietf.org/html/rfc3484\n:: 2002::/16 6to4 tunnel\n:: 2001::/32 teredo tunnel; not default\nnetsh interface ipv6 add prefixpolicy ::1/128 50 0\nnetsh interface ipv6 set prefixpolicy ::1/128 50 0\nnetsh interface ipv6 add prefixpolicy ::/0 40 1\nnetsh interface ipv6 set prefixpolicy ::/0 40 1\nnetsh interface ipv6 add prefixpolicy 2002::/16 30 2\nnetsh interface ipv6 set prefixpolicy 2002::/16 30 2\nnetsh interface ipv6 add prefixpolicy 2001::/32 25 5\nnetsh interface ipv6 set prefixpolicy 2001::/32 25 5\nnetsh interface ipv6 add prefixpolicy ::/96 20 3\nnetsh interface ipv6 set prefixpolicy ::/96 20 3\nnetsh interface ipv6 add prefixpolicy ::ffff:0:0/96 10 4\nnetsh interface ipv6 set prefixpolicy ::ffff:0:0/96 10 4\n\n:: Fix look up AAAA on teredo\n:: http://technet.microsoft.com/en-us/library/bb727035.aspx\n:: http://ipv6-or-no-ipv6.blogspot.com/2009/02/teredo-ipv6-on-vista-no-aaaa-resolving.html\nReg add HKLM\\SYSTEM\\CurrentControlSet\\services\\Dnscache\\Parameters /v AddrConfigControl /t REG_DWORD /d 0 /f\n\n:: Enable all IPv6 parts\nReg add HKLM\\SYSTEM\\CurrentControlSet\\Services\\Tcpip6\\Parameters /v DisabledComponents /t REG_DWORD /d 0 /f\n\n\nipconfig /flushdns\n\nset time=%date:~0,4%-%date:~5,2%-%date:~8,2%_%time:~0,2%%time:~3,2%%time:~6,2%\n@call :output>..\\..\\..\\..\\..\\data\\gae_proxy\\ipv6-state%time%.txt\n\n@echo Over\n@echo Reboot system at first time!\nexit\n\n:output\n@echo off\nipconfig /all\nnetsh interface ipv6 show teredo\nnetsh interface ipv6 show route\nnetsh interface ipv6 show interface\nnetsh interface ipv6 show prefixpolicies\nnetsh interface ipv6 show address\nroute print\nnotepad ..\\..\\..\\..\\..\\data\\gae_proxy\\ipv6-state%time%.txt\n"
  },
  {
    "path": "code/default/gae_proxy/local/ipv6_tunnel/linux.py",
    "content": "#!/usr/bin/env python2\n# coding:utf-8\n\nimport os\nimport sys\nfrom .common import *\n\n\ndef state():\n    return \"Developing\"\n\n\ndef state_pp():\n    return \"Developing\"\n\n\ndef switch_pp():\n    return \"Developing\"\n\n\ndef enable(is_local=False):\n    return \"Developing\"\n\n\ndef disable(is_local=False):\n    return \"Developing\"\n\n\ndef set_best_server(is_local=False):\n    return \"Developing\"\n"
  },
  {
    "path": "code/default/gae_proxy/local/ipv6_tunnel/pteredor.py",
    "content": "#!/usr/bin/env python\n# coding:utf-8\n\n# A tool to help evaluate the teredo servers.\n# Thanks XndroidDev\n# Author: SeaHOH <seahoh@gmail.com>\n# Compatible: Python 2.7 & 3.4 & 3.5 & 3.6\n# References:\n#   https://tools.ietf.org/html/rfc4380 5.1 5.2\n#   https://tools.ietf.org/html/rfc4861 4.1 4.2\n#   https://tools.ietf.org/html/rfc2460 8.1\n#   https://github.com/XndroidDev/Xndroid/blob/master/fqrouter/manager/teredo.py\n\n__version__ = '0.1.0'\n\nimport sys\n\nif sys.platform == 'win32' and sys.version_info[0] < 3:\n    import win_inet_pton\n\nimport os\nimport socket\nimport random\nimport struct\nimport collections\nimport time\nimport logging\nimport select\nimport errno\nimport subprocess\nimport threading\nfrom six.moves import queue as Queue\n\n\ntry:\n    _real_raw_input = raw_input\n\n\n    def raw_input(s='', file=sys.stdout):\n        if isinstance(s, str):\n            file.write(s.encode(sys.getfilesystemencoding(), 'replace'))\n            return _real_raw_input()\n        else:\n            return _real_raw_input(s)\nexcept NameError:\n    raw_input = input\n\nlogger = logging.getLogger('pteredor')\n\nteredo_timeout = 4\nteredo_port = 3544\nlink_local_addr = 'fe80::ffff:ffff:ffff'\nall_router_multicast = 'ff02::2'\nteredo_server_list = [\n    # limited\n    # 'teredo.ginzado.ne.jp',\n    # disuse\n    # 'debian-miredo.progsoc.org',\n    # 'teredo.autotrans.consulintel.com',\n    # 'teredo.ngix.ne.kr',\n    # 'teredo.managemydedi.com',\n    # 'teredo.ipv6.microsoft.com',\n    # 'win8.ipv6.microsoft.com',\n    'teredo.remlab.net',\n    'teredo2.remlab.net',\n    'teredo-debian.remlab.net',\n    'teredo.trex.fi',\n    'teredo.iks-jena.de',\n    'win10.ipv6.microsoft.com',\n    'win1710.ipv6.microsoft.com',\n    'win1711.ipv6.microsoft.com'\n]\n\n\ndef creat_rs_nonce():\n    return struct.pack('d', random.randint(0, 1 << 62))\n\n\ndef creat_ipv6_rs_msg(checksum=None):\n    return struct.pack('!2BH4x', 133, 0, checksum or 0)\n\n\ndef in_checksum(data):\n    n = len(data)\n    f = '%dH' % (n // 2)\n    if n % 2:\n        f += 'B'\n    s = sum(struct.unpack(f, data))\n    while (s >> 16):\n        s = (s & 0xffff) + (s >> 16)\n    s = ~s & 0xffff\n    return socket.ntohs(s)\n\n\nclass teredo_rs_packet(object):\n    def __init__(self, nonce=None):\n        self.rs_src = socket.inet_pton(socket.AF_INET6, link_local_addr)\n        self.rs_dst = socket.inet_pton(socket.AF_INET6, all_router_multicast)\n        self._icmpv6_rs_msg = creat_ipv6_rs_msg()\n        self.nonce = nonce or creat_rs_nonce()\n        self.rs_src = bytearray(self.rs_src)\n        self.teredo_header = self.creat_teredo_header()\n\n    def creat_teredo_header(self):\n        return struct.pack('!H2x8sx', 1, self.nonce)\n\n    def creat_ipv6_pseudo_header(self):\n        return struct.pack('!16s16sI3xB',\n                           bytes(self.rs_src),\n                           self.rs_dst,\n                           58,\n                           len(self._icmpv6_rs_msg)\n                           )\n\n    def creat_rs_packet(self, cone=None):\n        self.rs_src[8] = 0x80 if cone else 0\n        pseudo_header = self.creat_ipv6_pseudo_header()\n        checksum = in_checksum(self._icmpv6_rs_msg + pseudo_header)\n        rs_msg = creat_ipv6_rs_msg(checksum)\n        return self.teredo_header + struct.pack('!B4x3B16s16s',\n                                                0x60,\n                                                len(rs_msg),\n                                                58,\n                                                255,\n                                                bytes(self.rs_src),\n                                                self.rs_dst\n                                                ) + rs_msg\n\n    @property\n    def type_cone(self):\n        if not hasattr(self, '_type_cone'):\n            self._type_cone = self.creat_rs_packet(True)\n        return self._type_cone\n\n    @property\n    def type_restricted(self):\n        if not hasattr(self, '_type_restricted'):\n            self._type_restricted = self.creat_rs_packet()\n        return self._type_restricted\n\n\ndef get_sock(port):\n    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)\n    while True:\n        try:\n            _port = port or random.randint(1025, 5000)\n            print(('try bind local port:', _port))\n            sock.bind(('0.0.0.0', _port))\n            return sock\n        except socket.error as e:\n            if port:\n                print(('bind local port %d fail: %r' % (_port, e)))\n                return\n            if e.args[0] == errno.EADDRINUSE:\n                pass\n\n\ndef is_ipv4(ip):\n    try:\n        socket.inet_aton(ip)\n    except:\n        return False\n    else:\n        return True\n\n\ndef resolve(host):\n    try:\n        return socket.gethostbyname_ex(host)[-1]\n    except:\n        return []\n\n\ndef ip2int(ip):\n    return struct.unpack('>I', socket.inet_aton(ip))[0]\n\n\ndef int2ip(int):\n    return socket.inet_ntoa(struct.pack('>I', int))\n\n\ndef get_second_server_ip(ip):\n    return int2ip(ip2int(ip) + 1)\n\n\ndef remove_same_server(server_ip_list):\n    logger.debug('input ip: %s' % server_ip_list)\n    cleared_list = set()\n    for ip1 in server_ip_list:\n        _ip1 = ip2int(ip1)\n        for ip2 in server_ip_list:\n            b = _ip1 - ip2int(ip2)\n            if b in (1, -1):\n                cleared_list.add(ip1 if b < 0 else ip2)\n                break\n        if b not in (1, -1):\n            cleared_list.add(ip1)\n    logger.debug('cleared ip: %s' % cleared_list)\n    return cleared_list\n\n\ndef str2hex(str):\n    str = bytearray(str)\n    h = ['']\n    for c in str:\n        if c > 0xf:\n            h.append(hex(c)[2:])\n        else:\n            h.append('0' + hex(c)[2:])\n    return '\\\\x'.join(h)\n\n\nclass deque(collections.deque):\n\n    def put(self, v):\n        self.append(v)\n\n    def get(self):\n        try:\n            return self.popleft()\n        except:\n            return None\n\n\nclass default_prober_dict(dict):\n\n    def __init__(self):\n        self['nonce'] = None\n        self['rs_packet'] = None\n        self['ra_packets'] = deque()\n\n\nclass teredo_prober(object):\n    _stoped = None\n    nat_type = 'null'\n    qualified = False\n    rs_cone_flag = 1\n    timeout = teredo_timeout\n    teredo_port = teredo_port\n\n    def __init__(self, server_list=teredo_server_list, local_port=None,\n                 remote_port=None, probe_nat=True):\n        self.teredo_sock = get_sock(local_port)\n        if remote_port:\n            self.teredo_port = remote_port\n        self.prober_dict = collections.defaultdict(default_prober_dict)\n        self.ip2server = collections.defaultdict(list)\n        server_ip_list = []\n        if isinstance(server_list, str):\n            server_list = [server_list]\n        for server in server_list:\n            if is_ipv4(server):\n                server_ip_list.append(server)\n            else:\n                ip_list = resolve(server)\n                for ip in ip_list:\n                    self.ip2server[ip].append(server)\n                server_ip_list += ip_list\n        self.server_ip_list = remove_same_server(server_ip_list)\n        if len(self.server_ip_list) < 1:\n            msg = 'Servers could not be resolved, %r.' % server_list\n            print(msg)\n            raise Exception(msg)\n        elif len(self.server_ip_list) < 2:\n            print(('Need input more teredo servers, now is %d.'\n                   % len(self.server_ip_list)))\n        threading.Thread(target=self.receive_loop, name=\"teredo_recieve_loop\").start()\n        if probe_nat:\n            self.nat_type = self.nat_type_probe()\n\n    def unpack_indication(self, data):\n        return struct.unpack('!2s4s', data[2:8])\n\n    def handle_ra_packet(self, ipv6_pkt):\n        server_ip = socket.inet_ntoa(ipv6_pkt[76:80])\n        cone_flag = bytearray(ipv6_pkt)[32] >> 7 & 1\n        logger.debug('ipv6_pkt ; RA_cone = %s\\nsrc:%s\\ndst:%s' % (\n            cone_flag,\n            str2hex(ipv6_pkt[8:24]),\n            str2hex(ipv6_pkt[24:40])))\n        return server_ip, cone_flag\n\n    def receive_ra_packet(self):\n        data, addr = self.teredo_sock.recvfrom(10240)\n        received_ip, port = addr\n        if port != self.teredo_port or len(data) < 40:\n            logger.debug('ipv6_pkt ;1 drop:\\n%s' % str2hex(data))\n            return\n        auth_pkt = indicate_pkt = ipv6_pkt = None\n        if data[0:2] == b'\\x00\\x01':\n            auth_len = 13 + sum(struct.unpack('2B', data[2:4]))\n            auth_pkt = data[0:auth_len]\n            if data[auth_len:auth_len + 2] == b'\\x00\\x00':\n                indicate_pkt = data[auth_len:auth_len + 8]\n                ipv6_pkt = data[auth_len + 8:]\n        if (auth_pkt is None or\n                indicate_pkt is None or\n                ipv6_pkt is None or\n                bytearray(ipv6_pkt)[0] & 0xf0 != 0x60 or\n                bytearray(ipv6_pkt)[40] != 134 or\n                struct.unpack('!H', ipv6_pkt[4:6])[0] + 40 != len(ipv6_pkt)\n        ):\n            logger.debug('ipv6_pkt ;2 drop:\\n%s' % str2hex(data))\n            return\n        server_ip, ra_cone_flag = self.handle_ra_packet(ipv6_pkt)\n        logger.debug('server ip: %s ; received ip: %s' % (server_ip, received_ip))\n        if (received_ip != server_ip and\n                received_ip != get_second_server_ip(server_ip) or\n                auth_pkt[4:12] != self.prober_dict[server_ip]['rs_packet'].nonce\n        ):\n            logger.debug('ipv6_pkt ;3 drop:\\n%s' % str2hex(data))\n            return\n        qualified = ra_cone_flag, indicate_pkt\n        self.prober_dict[received_ip]['ra_packets'].put(qualified)\n\n    def receive_loop(self):\n        while not self._stoped:\n            try:\n                rd, _, _ = select.select([self.teredo_sock], [], [], 0.5)\n                if rd and not self._stoped:\n                    self.receive_ra_packet()\n            except Exception as e:\n                logger.exception('receive procedure fail once: %r', e)\n                pass\n\n    def send_rs_packet(self, rs_packet, dst_ip):\n        rs_packet = rs_packet.type_cone if self.rs_cone_flag else rs_packet.type_restricted\n        logger.debug('send ; RS_cone = %s\\n%s' % (self.rs_cone_flag, str2hex(rs_packet)))\n        self.teredo_sock.sendto(rs_packet, (dst_ip, self.teredo_port))\n\n    def qualify(self, server_ip, second_server_ip=None):\n        rs_packet = self.prober_dict[server_ip]['rs_packet']\n        if rs_packet is None:\n            self.prober_dict[server_ip]['rs_packet'] = rs_packet = teredo_rs_packet()\n        dst_ip = second_server_ip or server_ip\n        self.send_rs_packet(rs_packet, dst_ip)\n\n        begin_recv = time.time()\n        while time.time() < self.timeout + begin_recv:\n            qualified = self.prober_dict[dst_ip]['ra_packets'].get()\n            if qualified:\n                return qualified\n            time.sleep(0.01)\n\n    def qualify_loop(self, server_ip, second_server=None):\n        if second_server:\n            self.rs_cone_flag = 0\n            second_server_ip = get_second_server_ip(server_ip)\n        else:\n            second_server_ip = None\n        for i in range(3):\n            try:\n                return self.qualify(server_ip, second_server_ip)\n            except Exception as e:\n                logger.exception('qualify procedure fail once: %r', e)\n\n    def nat_type_probe(self):\n        print('Starting probe NAT type...')\n        self.nat_type = 'probing'\n        server_ip_list = self.server_ip_list.copy()\n        self.rs_cone_flag = 1\n        for server_ip in server_ip_list:\n            qualified = self.qualify_loop(server_ip)\n            if qualified:\n                break\n        if qualified is None:\n            self.rs_cone_flag = 0\n            while server_ip_list:\n                server_ip = server_ip_list.pop()\n                qualified = self.qualify_loop(server_ip)\n                if qualified:\n                    break\n        if qualified is None:\n            self.qualified = False\n            return 'offline'\n        ra_cone_flag, first_indicate = qualified\n        if ra_cone_flag:\n            self.qualified = True\n            return 'cone'\n        qualified = None\n        qualified = self.qualify_loop(server_ip, second_server=True)\n        if qualified is None:\n            self.last_server_ip = server_ip\n            self.qualified = True\n            return 'unknown'\n        ra_cone_flag, second_indicate = qualified\n        if first_indicate == second_indicate:\n            self.qualified = True\n            return 'restricted'\n        else:\n            self.qualified = False\n            return 'symmetric'\n\n    def _eval_servers(self, server_ip, queue_obj):\n        start = time.time()\n        qualified = self.qualify_loop(server_ip)\n        cost = int((time.time() - start) * 1000)\n        queue_obj.put((bool(qualified), self.ip2server[server_ip], server_ip, cost))\n\n    def eval_servers(self):\n        if self.nat_type == 'null':\n            self.nat_type = self.nat_type_probe()\n        elif self.nat_type == 'probing':\n            print('Is probing NAT type now, pleace wait...')\n        while self.nat_type == 'probing':\n            time.sleep(0.1)\n        if not self.qualified:\n            print(('This device can not use teredo tunnel, the NAT type is %s!'\n                   % self.nat_type))\n            return []\n        print('Starting evaluate servers...')\n        self.clear()\n        eval_list = []\n        queue_obj = Queue.Queue()\n        for server_ip in self.server_ip_list:\n            threading.Thread(target=self._eval_servers, args=(server_ip, queue_obj), name=\"teredor_eval\").start()\n        for _ in self.server_ip_list:\n            eval_list.append(queue_obj.get())\n        return eval_list\n\n    def close(self):\n        self._stoped = True\n        self.clear()\n        if self.teredo_sock:\n            self.teredo_sock.close()\n            self.teredo_sock = None\n\n    def clear(self):\n        for server_ip in self.server_ip_list:\n            second_server_ip = get_second_server_ip(server_ip)\n            self.prober_dict.pop(server_ip, None)\n            self.prober_dict.pop(second_server_ip, None)\n\n\nlocal_ip_startswith = tuple(\n    ['192.168', '10.'] +\n    ['100.%d.' % (64 + n) for n in range(1 << 6)] +\n    ['172.%d.' % (16 + n) for n in range(1 << 4)]\n)\n\nimport locale\n\nzh_locale = None\ntry:\n    zh_locale = locale.getdefaultlocale()[0] == 'zh_CN'\nexcept:\n    if sys.platform == \"darwin\":\n        try:\n            oot = os.pipe()\n            p = subprocess.Popen(['/usr/bin/defaults',\n                                  'read',\n                                  'NSGlobalDomain',\n                                  'AppleLanguages'], stdout=oot[1])\n            p.communicate()\n            zh_locale = b'zh' in os.read(oot[0], 10000)\n        except:\n            pass\n\nif zh_locale:\n    help_info = '''\npteredor [-p <port>] [-P <port>] [-h] [<server1> [<server2> [...]]]\n      -p  \\u8bbe\\u7f6e\\u672c\\u5730\\u5ba2\\u6237\\u7aef\\u7aef\\u53e3\\u3002\n      -P  \\u8bbe\\u7f6e\\u8fdc\\u7a0b\\u670d\\u52a1\\u7aef\\u7aef\\u53e3\\u3002\n      -h  \\u663e\\u793a\\u672c\\u5e2e\\u52a9\\u4fe1\\u606f\\u3002\n\n          Teredo server \\u662f\\u4e00\\u4e2a\\u4e3b\\u673a\\u540d\\uff0c\\u53ef\\u4ee5\\u4f7f\\u7528\\u57df\\u540d\\u6216 IP\\u3002\n\n'''\n    result_info = '\\n\\u7ecf\\u68c0\\u6d4b\\uff0c\\u63a8\\u8350\\u670d\\u52a1\\u5668\\u662f %r.'\n    wait_info = '\\u8bf7\\u7b49\\u5f85 10 \\u79d2\\u949f\\u2026\\u2026'\n    resume_info = 'Teredo \\u5ba2\\u6237\\u7aef\\u5df2\\u6062\\u590d\\u8fd0\\u884c\\u3002'\n    warn_1 = '\\u53c2\\u6570 \"-p\" \\u9519\\u8bef\\uff1a\\u7aef\\u53e3\\u5fc5\\u987b\\u662f\\u4e00\\u4e2a\\u6570\\u5b57\\u3002'\n    warn_2 = '\\u53c2\\u6570 \"-P\" \\u9519\\u8bef\\uff1a\\u7aef\\u53e3\\u5fc5\\u987b\\u662f\\u4e00\\u4e2a\\u6570\\u5b57\\u3002'\n    warn_3 = '\\u5f53\\u524d\\u8bbe\\u5907\\u53ef\\u80fd\\u65e0\\u6cd5\\u6b63\\u5e38\\u4f7f\\u7528 teredo \\u96a7\\u9053\\uff0cNAT \\u7c7b\\u578b\\u662f %s\\uff01'\n    warn_4 = '\\u65e0\\u6cd5\\u5224\\u65ad NAT \\u7c7b\\u578b\\u3002'\n    confirm_stop = '\\u662f\\u5426\\u5148\\u6682\\u65f6\\u5173\\u95ed teredo \\u5ba2\\u6237\\u7aef\\uff08IPv6\\uff09\\u518d\\u8fdb\\u884c\\u6d4b\\u8bd5\\uff1f\\uff08Y/N\\uff09'\n    confirm_set = '\\u4f60\\u60f3\\u8981\\u5c06 teredo \\u670d\\u52a1\\u5668\\u8bbe\\u7f6e\\u4e3a\\u672c\\u6d4b\\u8bd5\\u7684\\u63a8\\u8350\\u503c\\u5417\\uff1f\\uff08Y/N\\uff09'\n    confirm_reset = '\\u4f60\\u60f3\\u8981\\u91cd\\u7f6e teredo \\u5ba2\\u6237\\u7aef\\u7684\\u5237\\u65b0\\u95f4\\u9694\\u5417\\uff1f\\uff08Y/N\\uff09'\n    confirm_over = '\\u6309\\u56de\\u8f66\\u952e\\u7ed3\\u675f\\u2026\\u2026'\n    confirm_force = '\\u4f60\\u60f3\\u8981\\u7ee7\\u7eed\\u8fdb\\u884c\\u6d4b\\u8bd5\\u5417\\uff1f\\uff08Y/N\\uff09'\n    nat_type_result = 'NAT \\u7c7b\\u578b\\u662f %s\\u3002'\nelse:\n    help_info = '''\npteredor [-p <port>] [-P <port>] [-h] [<server1> [<server2> [...]]]\n      -p  Set the local port num. (client)\n      -P  Set the remote port num. (server)\n      -h  Show this help.\n\n          The teredo server is a host name (domain or IP).\n\n'''\n    result_info = '\\nThe recommend server is %r.'\n    wait_info = 'Please wait 10 seconds...'\n    resume_info = 'The teredo cilent has resumed.'\n    warn_1 = 'The value of parameter \"-p\" error: local port must be a number.'\n    warn_2 = 'The value of parameter \"-P\" error: remote port must be a number.'\n    warn_3 = 'This device may not be able to use teredo tunnel, the NAT type is %s!'\n    warn_4 = 'We can not judge the NAT type.'\n    confirm_stop = 'Stop teredo cilent for run prober, Y/N? '\n    confirm_set = 'Do you want to set recommend teredo server, Y/N? '\n    confirm_reset = 'Do you want to reset refreshinterval to the default value, Y/N? '\n    confirm_over = 'Press enter to over...'\n    confirm_force = 'Do you want to force probe and set the teredo servers, Y/N? '\n    nat_type_result = 'The NAT type is %s.'\n\nif os.name == 'nt':\n    from . import win32runas\n\n    if win32runas.is_admin():\n        runas = os.system\n    else:\n        def runas(cmd):\n            cmd = tuple(cmd.split(None, 1))\n            if len(cmd) == 1:\n                cmd += None,\n            win32runas.runas(cmd[1], cmd[0])\n\n\ndef main(local_port=None, remote_port=None, *args):\n    server_list = [] + teredo_server_list\n    for arg in args:\n        if isinstance(arg, str):\n            server_list.append(arg)\n        elif isinstance(arg, list):\n            server_list += arg\n        elif isinstance(arg, tuple):\n            server_list += list(arg)\n    prober = teredo_prober(server_list, local_port=local_port, remote_port=remote_port)\n    need_probe = recommend = None\n    if not prober.qualified:\n        print((warn_3 % prober.nat_type))\n        if (prober.nat_type == 'symmetric' and\n                input(confirm_force).lower() == 'y'):\n            need_probe = True\n            prober.qualified = True\n    elif prober.nat_type == 'unknown':\n        print(warn_4)\n        recommend = prober.ip2server[prober.last_server_ip]\n    else:\n        print((nat_type_result % prober.nat_type))\n        need_probe = True\n    if need_probe:\n        qualified_list = prober.eval_servers()\n        for qualified, server, server_ip, cost in qualified_list:\n            print(('%s %s %s' % (server_ip, server, '%sms' % cost if qualified else 'timedout')))\n        recommend = qualified_list[0][1]\n    prober.close()\n    return recommend, prober.nat_type\n\n\ndef test():\n    logging.basicConfig(level=logging.DEBUG)\n    blank_rs_packet = bytearray(\n        b'\\x00\\x01\\x00\\x00\\x8a\\xde\\xb0\\xd0\\x2e\\xea\\x0b\\xfc\\x00'\n        b'\\x60\\x00\\x00\\x00\\x00\\x08\\x3a\\xff\\xfe\\x80\\x00\\x00\\x00\\x00\\x00\\x00'\n        b'\\x00\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x02\\x00\\x00\\x00\\x00\\x00\\x00'\n        b'\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x85\\x00\\x7d\\x37\\x00\\x00\\x00\\x00')\n    nonce = creat_rs_nonce()\n    blank_rs_packet[4:12] = nonce\n    assert (teredo_rs_packet(nonce).type_restricted == bytes(blank_rs_packet))\n\n    server_list = ['teredo.remlab.net', 'win1710.ipv6.microsoft.com']\n    prober = teredo_prober(server_list, probe_nat=False)\n    prober.timeout = 4\n    server_ip_list = prober.server_ip_list.copy()\n    server_ip = server_ip_list.pop()\n    for _ in range(2):\n        print((prober.qualify_loop(server_ip)))\n        prober.rs_cone_flag = prober.rs_cone_flag ^ 1\n    server_ip = server_ip_list.pop()\n    for _ in range(2):\n        print((prober.qualify_loop(server_ip)))\n        prober.rs_cone_flag = prober.rs_cone_flag ^ 1\n    #    prober.close()\n\n    print((main()))\n    input(confirm_over)\n    sys.exit(0)\n\n\nif '__main__' == __name__:\n    #    test()\n    args = sys.argv[1:]\n    if '-h' in args:\n        args.remove('-h')\n        print(help_info)\n        if not args:\n            input(confirm_over)\n            sys.exit(0)\n    try:\n        local_port = args[args.index('-p') + 1]\n        args.remove('-p')\n        args.remove(local_port)\n        try:\n            local_port = int(local_port)\n        except:\n            local_port = None\n            print(warn_1)\n    except:\n        local_port = None\n    try:\n        remote_port = args[args.index('-P') + 1]\n        args.remove('-P')\n        args.remove(remote_port)\n        try:\n            remote_port = int(remote_port)\n        except:\n            remote_port = None\n            print(warn_2)\n    except:\n        remote_port = None\n    done_disabled = False\n    if os.name == 'nt':\n        if input(confirm_stop).lower() == 'y':\n            if runas('netsh interface teredo set state disable'):\n                done_disabled = True\n        win32runas.runas(\"win_reset_gp.py\")\n        print((os.system('netsh interface teredo show state')))\n    recommend, nat_type = main(*args, local_port=local_port, remote_port=remote_port)\n    print((result_info % recommend))\n    if os.name == 'nt':\n        ip = [a for a in os.popen('route print').readlines() if ' 0.0.0.0 ' in a][0].split()[-2]\n        if nat_type == 'cone':\n            client = 'client'\n        else:\n            import platform\n\n            client_ext = 'natawareclient' if platform.version()[0] > '6' else 'enterpriseclient'\n            client = client_ext if ip.startswith(local_ip_startswith) else 'client'\n    if recommend:\n        if os.name == 'nt' and \\\n                input(confirm_set).lower() == 'y':\n            cmd = 'netsh interface teredo set state type=%s servername=%s.'\n            if input(confirm_reset).lower() == 'y':\n                cmd += ' refreshinterval=default'\n            if not remote_port:\n                cmd += ' clientport=default'\n            runas(cmd % (client, recommend[0]))\n            print(wait_info)\n            time.sleep(10)\n            print((os.system('netsh interface teredo show state')))\n            done_disabled = False\n    if done_disabled:\n        if runas('netsh interface teredo set state type=%s' % client):\n            print(resume_info)\n    input(confirm_over)\n"
  },
  {
    "path": "code/default/gae_proxy/local/ipv6_tunnel/unknown.py",
    "content": "#!/usr/bin/env python2\n# coding:utf-8\n\nimport os\nimport sys\nfrom .common import *\n\n\ndef state():\n    return \"Developing\"\n\n\ndef state_pp():\n    return \"Developing\"\n\n\ndef switch_pp():\n    return \"Developing\"\n\n\ndef enable(is_local=False):\n    return \"Developing\"\n\n\ndef disable(is_local=False):\n    return \"Developing\"\n\n\ndef set_best_server(is_local=False):\n    return \"Developing\"\n"
  },
  {
    "path": "code/default/gae_proxy/local/ipv6_tunnel/win10.py",
    "content": "#!/usr/bin/env python2\n# coding:utf-8\n\nimport os\nimport sys\nimport time\nimport socket\nimport platform\n\nimport env_info\nfrom .common import *\nfrom . import win32runas\nfrom .pteredor import local_ip_startswith\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\npython_path = os.path.abspath( os.path.join(current_path, os.pardir, os.pardir))\nroot_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))\ndata_path = os.path.join(env_info.data_path, \"gae_proxy\")\nif not os.path.isdir(data_path):\n    data_path = current_path\n\nif __name__ == \"__main__\":\n    noarch_lib = os.path.abspath( os.path.join(python_path, 'lib', 'noarch'))\n    sys.path.append(noarch_lib)\n\n    if sys.platform == \"win32\":\n        win32_lib = os.path.abspath( os.path.join(python_path, 'lib', 'win32'))\n        sys.path.append(win32_lib)\n\n\n# TODO：Help to reset ipv6 if system Teredo Interface not exist\n# download http://download.microsoft.com/download/3/F/3/3F3CA0F7-2FAF-4C51-8DDF-3516B4D91975/MicrosoftEasyFix20164.mini.diagcab\n\n\n# TODO: Win7 need to change the interface name as the real one.\n# can use ifconfig to get it.\n\n# TODO; Win10 Home and Win10 Profession is different.\n\nenable_ipv6_temp = os.path.join(current_path, 'enable_ipv6_temp.bat')\ndisable_ipv6_temp = os.path.join(current_path, 'disable_ipv6_temp.bat')\nset_best_server_temp = os.path.join(current_path, 'set_best_server_temp.bat')\n\nenable_cmds = \"\"\"\n@echo Starting...\n@set log_file=\"{}\"\n\n@echo Config servers...\n@call:[config servers]>>%log_file%\n\n@echo Reset IPv6...\n@call:[reset ipv6]>>%log_file%\n\n@echo Set IPv6 Tunnel...\n@call:[set ipv6]>>%log_file%\n\n@call:[print state]>>%log_file%\n\n@echo Over\n@echo Reboot system at first time!\n@pause\nexit\n\n\n:[config servers]\nsc config RpcEptMapper start= auto\nsc start RpcEptMapper\n\nsc config DcomLaunch start= auto\nsc start DcomLaunch\n\nsc config RpcSs start= auto\nsc start RpcSs\n\nsc config nsi start= auto\nsc start nsi\n\nsc config Winmgmt start= auto\nsc start Winmgmt\n\nsc config Dhcp start= auto\nsc start Dhcp\n\nsc config WinHttpAutoProxySvc start= auto\nsc start WinHttpAutoProxySvc\n\nsc config iphlpsvc start= auto\nsc start iphlpsvc\n\ngoto :eof\n\n\n:[reset ipv6]\nnetsh interface ipv6 reset\nipconfig /flushdns\ngoto :eof\n\n\n:[set ipv6]\n:: Reset Group Policy Teredo\nSET PYTHONPATH=\nSET PYTHONHOME=\n\"{}\" \"{}\\\\win_reset_gp.py\"\n\n\"\"\".format(log_file, sys.executable, current_path) + \\\n\"\"\"\nnetsh interface teredo set state type={} servername={}.\n\n:: Set IPv6 prefixpolicies\n:: See https://tools.ietf.org/html/rfc3484\n:: 2002::/16 6to4 tunnel\n:: 2001::/32 teredo tunnel; not default\nnetsh interface ipv6 add prefixpolicy ::1/128 50 0\nnetsh interface ipv6 set prefixpolicy ::1/128 50 0\nnetsh interface ipv6 add prefixpolicy ::/0 40 1\nnetsh interface ipv6 set prefixpolicy ::/0 40 1\nnetsh interface ipv6 add prefixpolicy 2002::/16 30 2\nnetsh interface ipv6 set prefixpolicy 2002::/16 30 2\nnetsh interface ipv6 add prefixpolicy 2001::/32 25 5\nnetsh interface ipv6 set prefixpolicy 2001::/32 25 5\nnetsh interface ipv6 add prefixpolicy ::/96 20 3\nnetsh interface ipv6 set prefixpolicy ::/96 20 3\nnetsh interface ipv6 add prefixpolicy ::ffff:0:0/96 10 4\nnetsh interface ipv6 set prefixpolicy ::ffff:0:0/96 10 4\n\n:: Fix look up AAAA on teredo\n:: http://technet.microsoft.com/en-us/library/bb727035.aspx\n:: http://ipv6-or-no-ipv6.blogspot.com/2009/02/teredo-ipv6-on-vista-no-aaaa-resolving.html\nReg add HKLM\\SYSTEM\\CurrentControlSet\\services\\Dnscache\\Parameters /v AddrConfigControl /t REG_DWORD /d 0 /f\n\n:: Enable all IPv6 parts\nReg add HKLM\\SYSTEM\\CurrentControlSet\\Services\\Tcpip6\\Parameters /v DisabledComponents /t REG_DWORD /d 0 /f\n\ngoto :eof\n\n\n:[print state]\n:: Show state\nipconfig /all\nnetsh interface ipv6 show teredo\nnetsh interface ipv6 show route\nnetsh interface ipv6 show interface\nnetsh interface ipv6 show prefixpolicies\nnetsh interface ipv6 show address\nroute print\ngoto :eof\n\"\"\"\n\n\ndisable_cmds=\"\"\"\nnetsh interface teredo set state disable\nnetsh interface 6to4 set state disabled\nnetsh interface isatap set state disabled\n\"\"\"\n\nhas_admin = win32runas.is_admin()\n\n# Use this if need admin\n# Don't hide the console window\ndef elevate(script_path, clear_log=True):\n    global script_is_running\n    if not script_is_running:\n        script_is_running = True\n\n        if clear_log and os.path.isfile(log_file):\n            try:\n                os.remove(log_file)\n            except Exception as e:\n                xlog.warn(\"remove %s fail:%r\", log_file, e)\n\n        try:\n            win32runas.runas(None, script_path)\n            return True\n        except Exception as e:\n            xlog.warning('elevate e:%r', e)\n        finally:\n            script_is_running = False\n\nscript_is_running = False\nlast_get_state_time = 0\nlast_set_server_time = 0\nlast_state = \"unknown\"\n\nclient_ext = 'natawareclient' if platform.version()[0] > '6' else 'enterpriseclient'\n\ndef client_type():\n    try:\n        ip = [line for line in run(\"route print\").split(\"\\r\\n\") if \" 0.0.0.0 \" in line][0].split()[-2]\n    except:\n        xlog.warning('route setting may wrong, please check.')\n        return 'client'\n    return client_ext if ip.startswith(local_ip_startswith) else 'client'\n\n\ndef get_teredo_interface():\n    r = run(\"ipconfig /all\")\n    return \"Developing\"\n\n\ndef state():\n    global last_get_state_time, last_state\n    if time.time() - last_get_state_time < 5:\n        return last_state\n\n    last_get_state_time = time.time()\n    r = run(\"netsh interface teredo show state\")\n    xlog.debug(\"netsh state: %s\", r)\n    type = get_line_value(r, 2)\n    if type == \"disabled\":\n        last_state = \"disabled\"\n    else:\n        last_state = get_line_value(r, 6) or \"unknown\"\n        if \"probe\" in last_state:\n            last_state = \"probe\"\n\n    return last_state\n\n\ndef state_pp():\n    return \"Developing\"\n\n\ndef switch_pp():\n    return \"Developing\"\n\n\ndef enable(is_local=False):\n    if not is_local:\n        return \"Please operating on local host.\"\n\n    if script_is_running or pteredor_is_running:\n        return \"Script is running, please retry later.\"\n    else:\n        new_enable_cmds = enable_cmds.format(client_type(), best_server())\n        with open(enable_ipv6_temp, 'w') as fp:\n            fp.write(new_enable_cmds)\n        done = elevate(enable_ipv6_temp, False)\n\n        if done:\n            global last_set_server_time\n            last_set_server_time = time.time()\n            return \"IPv6 tunnel is enabled, please reboot system.\"\n        else:\n            return \"Enable IPv6 tunnel fail, you must authorized as admin.\"\n\n\ndef disable(is_local=False):\n    if not is_local:\n        return \"Please operating on local host.\"\n\n    if script_is_running or pteredor_is_running:\n        return \"Script is running, please retry later.\"\n    else:\n        with open(disable_ipv6_temp, 'w') as fp:\n            fp.write(disable_cmds)\n        done = elevate(disable_ipv6_temp)\n\n        if done:\n            return \"IPv6 tunnel is disabled.\"\n        else:\n            return \"Disable IPv6 tunnel fail, you must authorized as admin.\"\n\n\ndef set_best_server(is_local=False):\n    # Allow remote if has admin\n    if not is_local and not has_admin:\n        return \"Please operating on local host.\"\n\n    if script_is_running or pteredor_is_running:\n        return \"Script is running, please retry later.\"\n    else:\n        global last_set_server_time\n        now = time.time()\n        wait_time = 3 - (now - last_set_server_time) // 60\n        if wait_time > 0:\n            return \"Don't do this repeated, please retry in %d minutes later.\" % wait_time\n\n        set_server_cmds = (\"netsh interface teredo set state %s %s. default default default\"\n                           % (client_type(), best_server()))\n        with open(set_best_server_temp, 'w') as fp:\n            fp.write(set_server_cmds)\n        done = elevate(set_best_server_temp, False)\n\n\n        if done:\n            last_set_server_time = now\n            return \"Set teredo server is completed.\"\n        else:\n            return \"Set teredo server fail, you must authorized as admin.\"\n\n\nif __name__ == '__main__':\n    enable(True)\n"
  },
  {
    "path": "code/default/gae_proxy/local/ipv6_tunnel/win32runas.py",
    "content": "# coding:utf-8\n# run as admin in Windows\n\nimport os\nimport sys\nimport ctypes\nimport subprocess\nfrom ctypes import c_ulong, c_char_p, c_int, c_void_p\nfrom ctypes.wintypes import HANDLE, DWORD, HWND, HINSTANCE, HKEY\n\n\ndef is_admin():\n    try:\n        return ctypes.windll.shell32.IsUserAnAdmin()\n    except:\n        return False\n\ndef encode_for_locale(s):\n    if s is None:\n        return\n    return s.encode('mbcs')\n\nif os.name == 'nt':\n    class ShellExecuteInfo(ctypes.Structure):\n        _fields_ = [('cbSize', DWORD),\n                    ('fMask', c_ulong),\n                    ('hwnd', HWND),\n                    ('lpVerb', c_char_p),\n                    ('lpFile', c_char_p),\n                    ('lpParameters', c_char_p),\n                    ('lpDirectory', c_char_p),\n                    ('nShow', c_int),\n                    ('hInstApp', HINSTANCE),\n                    ('lpIDList', c_void_p),\n                    ('lpClass', c_char_p),\n                    ('hKeyClass', HKEY),\n                    ('dwHotKey', DWORD),\n                    ('hIcon', HANDLE),\n                    ('hProcess', HANDLE)]\n\n    SEE_MASK_NOCLOSEPROCESS = 0x00000040\n    ShellExecuteEx = ctypes.windll.Shell32.ShellExecuteEx\n    ShellExecuteEx.argtypes = ctypes.POINTER(ShellExecuteInfo),\n    WaitForSingleObject = ctypes.windll.kernel32.WaitForSingleObject\n    SE_ERR_CODES = {\n        0: 'Out of memory or resources',\n        2: 'File not found',\n        3: 'Path not found',\n        5: 'Access denied',\n        8: 'Out of memory',\n        26: 'Cannot share an open file',\n        27: 'File association information not complete',\n        28: 'DDE operation timed out',\n        29: 'DDE operation failed',\n        30: 'DDE operation is busy',\n        31: 'File association not available',\n        32: 'Dynamic-link library not found',\n    }\n    sys.argv[0] = os.path.abspath(sys.argv[0])\n\ndef runas(args=sys.argv, executable=sys.executable, cwd=None,\n          nShow=1, waitClose=True, waitTimeout=-1):\n    if not 0 <= nShow <= 10:\n        nShow = 1\n    err = None\n    try:\n        if args is not None and not isinstance(args, str):\n            args = subprocess.list2cmdline(args)\n        pExecInfo = ShellExecuteInfo()\n        pExecInfo.cbSize = ctypes.sizeof(pExecInfo)\n        pExecInfo.fMask |= SEE_MASK_NOCLOSEPROCESS\n        pExecInfo.lpVerb = b'open' if is_admin() else b'runas'\n        pExecInfo.lpFile = encode_for_locale(executable)\n        pExecInfo.lpParameters = encode_for_locale(args)\n        pExecInfo.lpDirectory = encode_for_locale(cwd)\n        pExecInfo.nShow = nShow\n        if ShellExecuteEx(pExecInfo):\n            if waitClose:\n                WaitForSingleObject(pExecInfo.hProcess, waitTimeout)\n                return True\n            else:\n                return pExecInfo.hProcess\n        else:\n            err = SE_ERR_CODES.get(pExecInfo.hInstApp, 'unknown')\n    except Exception as e:\n        err = e\n    if err:\n        print(('runas failed! error: %r' % err))\n\nif __name__ == '__main__':\n    if len(sys.argv) > 1:\n       runas(sys.argv[2:], sys.argv[1])\n"
  },
  {
    "path": "code/default/gae_proxy/local/ipv6_tunnel/win_reset_gp.py",
    "content": "# coding:utf-8\n\nimport os\nimport sys\nimport platform\nimport ctypes\nimport win32runas\n\n\ndef win32_notify( msg='msg', title='Title'):\n    res = ctypes.windll.user32.MessageBoxW(None, msg, title, 1)\n    # Yes:1 No:2\n    return res == 1\n\n\ndef reset_teredo():\n    gp_split = b'[\\x00'\n    gp_teredo = 'v6Transition\\x00;Teredo'\n    gp_teredo = '\\x00'.join(b for b in gp_teredo).encode()\n\n    with open(gp_regpol_file, 'rb') as f:\n        gp_regpol_old = f.read().split(gp_split)\n\n    gp_regpol_new = [gp for gp in gp_regpol_old if gp_teredo not in gp]\n\n    if len(gp_regpol_new) != len(gp_regpol_old) and \\\n            win32_notify('发现组策略 Teredo 设置，是否重置？', '提醒'):\n        with open(gp_regpol_file, 'wb') as f:\n            f.write(gp_split.join(gp_regpol_new))\n        os.system(sysnative + '\\\\gpupdate /target:computer /force')\n\n\nif '__main__' == __name__:\n    if os.name != 'nt':\n        sys.exit(0)\n\n    sysver = platform.version()\n    if sysver < '6':\n        # Teredo item was added to Group Policy starting with Windows Vista\n        sys.exit(0)\n\n    windir = os.environ.get('windir')\n    if not windir:\n        sys.exit(-1)\n\n    sys64 = os.path.exists(windir + '\\\\SysWOW64')\n    pe32 = platform.architecture()[0] == '32bit'\n    sysalias = 'Sysnative' if sys64 and pe32 else 'System32'\n    sysnative = '%s\\\\%s' % (windir, sysalias)\n    gp_regpol_file = sysnative + '\\\\GroupPolicy\\\\Machine\\\\Registry.pol'\n\n    if os.path.exists(gp_regpol_file):\n        if not win32runas.is_admin():\n            win32runas.runas()\n            sys.exit(0)\n        reset_teredo()\n"
  },
  {
    "path": "code/default/gae_proxy/local/proxy.py",
    "content": "#!/usr/bin/env python2\n# coding:utf-8\n# Based on GAppProxy 2.0.0 by Du XiaoGang <dugang.2008@gmail.com>\n# Based on WallProxy 0.4.0 by Hust Moon <www.ehust@gmail.com>\n# Contributor:\n#      Phus Lu           <phus.lu@gmail.com>\n#      Hewig Xu          <hewigovens@gmail.com>\n#      Ayanamist Yang    <ayanamist@gmail.com>\n#      V.E.O             <V.E.O@tom.com>\n#      Max Lv            <max.c.lv@gmail.com>\n#      AlsoTang          <alsotang@gmail.com>\n#      Christopher Meng  <cickumqt@gmail.com>\n#      Yonsm Guo         <YonsmGuo@gmail.com>\n#      Parkman           <cseparkman@gmail.com>\n#      Ming Bai          <mbbill@gmail.com>\n#      Bin Yu            <yubinlove1991@gmail.com>\n#      lileixuan         <lileixuan@gmail.com>\n#      Cong Ding         <cong@cding.org>\n#      Zhang Youfu       <zhangyoufu@gmail.com>\n#      Lu Wei            <luwei@barfoo>\n#      Harmony Meow      <harmony.meow@gmail.com>\n#      logostream        <logostream@gmail.com>\n#      Rui Wang          <isnowfy@gmail.com>\n#      Wang Wei Qiang    <wwqgtxx@gmail.com>\n#      Felix Yan         <felixonmars@gmail.com>\n#      QXO               <qxodream@gmail.com>\n#      Geek An           <geekan@foxmail.com>\n#      Poly Rabbit       <mcx_221@foxmail.com>\n#      oxnz              <yunxinyi@gmail.com>\n#      Shusen Liu        <liushusen.smart@gmail.com>\n#      Yad Smood         <y.s.inside@gmail.com>\n#      Chen Shuang       <cs0x7f@gmail.com>\n#      cnfuyu            <cnfuyu@gmail.com>\n#      cuixin            <steven.cuixin@gmail.com>\n\n\n\nimport sys\nimport os\nimport traceback\nimport platform\nimport threading\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nroot_path = os.path.abspath( os.path.join(current_path, os.pardir, os.pardir))\ngae_proxy_path = os.path.join(root_path, \"gae_proxy\")\n\npython_path = root_path\nnoarch_lib = os.path.abspath( os.path.join(python_path, 'lib', 'noarch'))\nsys.path.append(noarch_lib)\n\nimport env_info\ndata_path = env_info.data_path\ndata_gae_proxy_path = os.path.join(data_path, 'gae_proxy')\n\n\nif sys.platform == \"win32\":\n    win32_lib = os.path.abspath( os.path.join(python_path, 'lib', 'win32'))\n    sys.path.append(win32_lib)\nelif sys.platform.startswith(\"linux\"):\n    linux_lib = os.path.abspath( os.path.join(python_path, 'lib', 'linux'))\n    sys.path.append(linux_lib)\nelif sys.platform == \"darwin\":\n    darwin_lib = os.path.abspath( os.path.join(python_path, 'lib', 'darwin'))\n    sys.path.append(darwin_lib)\n    extra_lib = \"/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python\"\n    sys.path.append(extra_lib)\n\n\n__file__ = os.path.abspath(__file__)\nif os.path.islink(__file__):\n    __file__ = getattr(os, 'readlink', lambda x: x)(__file__)\nwork_path = os.path.dirname(os.path.abspath(__file__))\nos.chdir(work_path)\n\nsys.path.append(root_path)\nfrom gae_proxy.local.cert_util import CertUtil\nfrom gae_proxy.local import proxy_handler\nfrom gae_proxy.local.front import front, direct_front\n\n\ndef check_create_data_path():\n    if not os.path.isdir(data_path):\n        os.mkdir(data_path)\n\n    if not os.path.isdir(data_gae_proxy_path):\n        os.mkdir(data_gae_proxy_path)\n\n\nfrom xlog import getLogger\nxlog = getLogger(\"gae_proxy\")\nxlog.set_buffer(1000)\n\nimport simple_http_server\nimport env_info\n\n\nproxy_server = None\n# launcher/module_init will check this value for start/stop finished\nready = False\n\n\ndef log_info():\n    xlog.info('------------------------------------------------------')\n    xlog.info('Python Version     : %s', platform.python_version())\n    xlog.info('OS                 : %s', env_info.os_detail())\n    xlog.info('Listen Address     : %s:%d', front.config.listen_ip, front.config.listen_port)\n    if front.config.PROXY_ENABLE:\n        xlog.info('%s Proxy    : %s:%s', front.config.PROXY_TYPE, front.config.PROXY_HOST, front.config.PROXY_PORT)\n\n    if len(front.config.GAE_APPIDS):\n        xlog.info('GAE APPID          : %s', '|'.join(front.config.GAE_APPIDS))\n    else:\n        xlog.info(\"Using public APPID\")\n    xlog.info('------------------------------------------------------')\n\n\ndef main(args):\n    global ready, proxy_server\n    no_mess_system = args.get(\"no_mess_system\", 0)\n    allow_remote = args.get(\"allow_remote\", 0)\n\n    check_create_data_path()\n\n    log_info()\n\n    threading.Thread(target=CertUtil.init_ca, args=(no_mess_system,), name=\"init_ca\").start()\n\n    listen_ips = front.config.listen_ip\n    if isinstance(listen_ips, str):\n        listen_ips = [listen_ips]\n    else:\n        listen_ips = list(listen_ips)\n\n    if allow_remote and (\"0.0.0.0\" not in listen_ips or \"::\" not in listen_ips):\n        listen_ips = [(\"0.0.0.0\"), ]\n    addresses = [(listen_ip, front.config.listen_port) for listen_ip in listen_ips]\n\n    front.start()\n    direct_front.start()\n\n    proxy_server = simple_http_server.HTTPServer(\n        addresses, proxy_handler.GAEProxyHandler, logger=xlog)\n\n    ready = True  # checked by launcher.module_init\n    \n    proxy_server.serve_forever()\n\n\n# called by launcher/module/stop\ndef terminate():\n    global ready, proxy_server\n\n    xlog.info(\"start to terminate GAE_Proxy\")\n    ready = False\n    front.stop()\n    direct_front.stop()\n    proxy_server.shutdown()\n\n\nif __name__ == '__main__':\n    try:\n        main({})\n    except Exception:\n        traceback.print_exc(file=sys.stdout)\n    except KeyboardInterrupt:\n        terminate()\n        sys.exit()\n"
  },
  {
    "path": "code/default/gae_proxy/local/proxy_handler.py",
    "content": "#!/usr/bin/env python\n# coding:utf-8\n\n\n\"\"\"\nGAEProxyHandler is the handler of http proxy port. default to 8087\n\n    if HTTP request:\n        do_METHOD()\n\n    elif HTTPS request:\n        do_CONNECT()\n\n\nWhat is Direct mode:\n    if user access google site like www.google.com, client.google.com,\n    we don't need forward request to GAE server.\n    we can send the original request to google ip directly.\n    because most google ip act as general front server.\n\n    Youtube content server do not support direct mode.\n\n    look direct_handler.py for more detail.\n\nWhat GAE mode:\n    Google App Engine support urlfetch for proxy.\n    every google account can apply 12 appid.\n    after deploy server code under gae_proxy/server/gae to GAE server, user can\n    use GAE server as http proxy.\n\n    Here is the global link view:\n\n     Browser => GAE_proxy => GAE server => target http/https server.\n\n    look gae_hander.py for more detail.\n\"\"\"\n\nimport errno\nimport socket\nimport ssl\n\ntry:\n    import OpenSSL\n    NetWorkIOError = (socket.error, ssl.SSLError, OpenSSL.SSL.Error, OSError)\nexcept:\n    NetWorkIOError = (socket.error, ssl.SSLError, OSError)\n\n\ntry:\n    from urllib.parse import urlparse\nexcept ImportError:\n    from urlparse import urlparse\n\nfrom xlog import getLogger\nxlog = getLogger(\"gae_proxy\")\nimport simple_http_client\nimport simple_http_server\nfrom gae_proxy.local.cert_util import CertUtil\nfrom gae_proxy.local import gae_handler\nfrom gae_proxy.local import direct_handler\nfrom gae_proxy.local import web_control\nimport utils\nfrom gae_proxy.local.front import front\n\n\nclass GAEProxyHandler(simple_http_server.HttpServerHandler):\n    gae_support_methods = tuple([b\"GET\", b\"POST\", b\"HEAD\", b\"PUT\", b\"DELETE\", b\"PATCH\"])\n    # GAE don't support command like OPTION\n\n    bufsize = 65535\n    local_names = []\n    self_check_response_data = b\"HTTP/1.1 200 OK\\r\\n\" \\\n                               b\"Access-Control-Allow-Origin: *\\r\\n\" \\\n                               b\"Cache-Control: no-cache, no-store, must-revalidate\\r\\n\" \\\n                               b\"Pragma: no-cache\\r\\n\" \\\n                               b\"Expires: 0\\r\\n\" \\\n                               b\"Content-Type: text/plain\\r\\n\" \\\n                               b\"Keep-Alive:\\r\\n\" \\\n                               b\"Persist:\\r\\n\" \\\n                               b\"Connection: Keep-Alive, Persist\\r\\n\" \\\n                               b\"Content-Length: 2\\r\\n\\r\\nOK\"\n    fake_host = utils.to_bytes(web_control.get_fake_host())\n\n    def setup(self):\n        self.__class__.do_GET = self.__class__.do_METHOD\n        self.__class__.do_PUT = self.__class__.do_METHOD\n        self.__class__.do_POST = self.__class__.do_METHOD\n        self.__class__.do_HEAD = self.__class__.do_METHOD\n        self.__class__.do_DELETE = self.__class__.do_METHOD\n        self.__class__.do_OPTIONS = self.__class__.do_METHOD\n\n    def forward_local(self):\n        \"\"\"\n        If browser send localhost:xxx request to GAE_proxy,\n        we forward it to localhost.\n        \"\"\"\n        request_headers = dict((k.title(), v) for k, v in list(self.headers.items()))\n        payload = b''\n        if b'Content-Length' in request_headers:\n            try:\n                payload_len = int(request_headers.get(b'Content-Length', 0))\n                payload = self.rfile.read(payload_len)\n            except Exception as e:\n                xlog.warn('forward_local read payload failed:%s', e)\n                return\n\n        response = simple_http_client.request(self.command, self.path, request_headers, payload)\n        if not response:\n            xlog.warn(\"forward_local fail, command:%s, path:%s, headers: %s, payload: %s\",\n                self.command, self.path, request_headers, payload)\n            return\n\n        out_list = []\n        out_list.append(b\"HTTP/1.1 %d\\r\\n\" % response.status)\n        for key in response.headers:\n            key = key.title()\n            out_list.append(b\"%s: %s\\r\\n\" % (key, response.headers[key]))\n        out_list.append(b\"\\r\\n\")\n        out_list.append(response.text)\n\n        self.wfile.write(b\"\".join(out_list))\n\n    def send_method_allows(self, headers, payload):\n        xlog.debug(\"send method allow list for:%s %s\", self.command, self.path)\n        # Refer: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests\n\n        response = \\\n                b\"HTTP/1.1 200 OK\\r\\n\"\\\n                b\"Access-Control-Allow-Credentials: true\\r\\n\"\\\n                b\"Access-Control-Allow-Methods: GET, POST, HEAD, PUT, DELETE, PATCH\\r\\n\"\\\n                b\"Access-Control-Max-Age: 1728000\\r\\n\"\\\n                b\"Content-Length: 0\\r\\n\"\n\n        req_header = headers.get(b\"Access-Control-Request-Headers\", b\"\")\n        if req_header:\n            response += b\"Access-Control-Allow-Headers: %s\\r\\n\" % req_header\n\n        origin = headers.get(b\"Origin\", b\"\")\n        if origin:\n            response += b\"Access-Control-Allow-Origin: %s\\r\\n\" % origin\n        else:\n            response += b\"Access-Control-Allow-Origin: *\\r\\n\"\n\n        response += b\"\\r\\n\"\n\n        self.wfile.write(response)\n\n    def is_local(self, hosts):\n        if 0 == len(self.local_names):\n            self.local_names.append(b'localhost')\n            self.local_names.append(socket.gethostname().lower())\n            try:\n                self.local_names.append(socket.gethostbyname_ex(socket.gethostname())[-1])\n            except socket.gaierror:\n                # TODO Append local IP address to local_names\n                pass\n\n        for s in hosts:\n            s = s.lower()\n            if s.startswith(b'127.') \\\n                    or s.startswith(b'192.168.') \\\n                    or s.startswith(b'10.') \\\n                    or s.startswith(b'169.254.') \\\n                    or s in self.local_names:\n                # xlog.debug(s)\n                return True\n\n        return False\n\n    def do_CONNECT(self):\n        \"\"\"deploy fake cert to client\"\"\"\n        host, _, port = self.path.rpartition(b':')\n        port = int(port)\n        if port not in (80, 443):\n            xlog.warn(\"CONNECT %s port:%d not support\", host, port)\n            return\n\n        certfile = CertUtil.get_cert(host)\n        self.wfile.write(b'HTTP/1.1 200 Connection Established\\r\\n\\r\\n')\n        self.wfile.flush()\n        #self.conntunnel = True\n \n        leadbyte = self.connection.recv(1, socket.MSG_PEEK)\n        if leadbyte in (b'\\x80', b'\\x16'):\n            try:\n                ssl_sock = ssl.wrap_socket(self.connection, keyfile=CertUtil.cert_keyfile, certfile=certfile, server_side=True)\n            except ssl.SSLError as e:\n                xlog.info('ssl error: %s, create full domain cert for host:%s', e, host)\n                certfile = CertUtil.get_cert(host, full_name=True)\n                return\n            except Exception as e:\n                if e.args[0] not in (errno.ECONNABORTED, errno.ECONNRESET):\n                    xlog.exception('ssl.wrap_socket(self.connection=%r) failed: %s path:%s, errno:%s', self.connection, e, self.path, e.args[0])\n                return\n\n            self.__realwfile = self.wfile\n            self.__realrfile = self.rfile\n            self.connection = ssl_sock\n            self.rfile = self.connection.makefile('rb', self.bufsize)\n            self.wfile = self.connection.makefile('wb', 0)\n\n        self.close_connection = 0\n\n    def do_METHOD(self):\n        self.req_payload = None\n        host = self.headers.get(b'Host', b'')\n        host_ip, _, port = host.rpartition(b':')\n\n        if self.is_local([host, host_ip]):\n            xlog.debug(\"Browse localhost by proxy\")\n            return self.forward_local()\n        elif host == self.fake_host:\n            # xlog.debug(\"%s %s\", self.command, self.path)\n            # for web_ui status page\n            # auto detect browser proxy setting is work\n            return self.wfile.write(self.self_check_response_data)\n\n        #if not (front.config.use_ipv6 == \"force_ipv6\" and \\\n        #        check_local_network.IPv6.is_ok() or \\\n        #        front.config.use_ipv6 != \"force_ipv6\" and \\\n        #        check_local_network.is_ok()):\n        #    self.close_connection = 1\n        #    xlog.warn(\"network fail on do_METHOD, use_ipv6:%s\", front.config.use_ipv6)\n        #    return\n\n        if isinstance(self.connection, ssl.SSLSocket):\n            schema = b\"https\"\n        else:\n            schema = b\"http\"\n\n        if self.path[0:1] == b'/':\n            self.host = self.headers[b'Host']\n            self.url = b'%s://%s%s' % (schema, host, self.path)\n        else:\n            self.url = self.path\n            self.parsed_url = urlparse(self.path)\n            self.host = self.parsed_url[1]\n            if len(self.parsed_url[4]):\n                self.path = b'?'.join([self.parsed_url[2], self.parsed_url[4]])\n            else:\n                self.path = self.parsed_url[2]\n\n        if len(self.url) > 2083 and self.host.endswith(front.config.GOOGLE_ENDSWITH):\n            return self.go_DIRECT()\n\n        if self.host in front.config.HOSTS_GAE:\n            return self.go_AGENT()\n\n        # redirect http request to https request\n        # avoid key word filter when pass through GFW\n        if host in front.config.HOSTS_DIRECT:\n            return self.go_DIRECT()\n\n        if host.endswith(front.config.HOSTS_GAE_ENDSWITH):\n            return self.go_AGENT()\n\n        if host.endswith(front.config.HOSTS_DIRECT_ENDSWITH):\n            return self.go_DIRECT()\n\n        return self.go_AGENT()\n\n    # Called by do_METHOD and do_CONNECT_AGENT\n    def go_AGENT(self):\n        request_headers = dict((k.title(), v) for k, v in list(self.headers.items()))\n        payload = self.read_payload()\n\n        if self.command == b\"OPTIONS\":\n            xlog.warn(\"go_AGENT OPTIONS not supported by GAE\")\n            return self.send_method_allows(request_headers, payload)\n\n        if self.command not in self.gae_support_methods:\n            xlog.warn(\"Method %s not support in GAEProxy for %s\", self.command, self.path)\n            return self.wfile.write(('HTTP/1.1 404 Not Found\\r\\n\\r\\n').encode())\n\n        xlog.debug(\"GAE %s %s from:%s\", self.command, self.url, self.address_string())\n        if gae_handler.handler(self.command, self.host, self.url, request_headers, payload, self.wfile, self.go_DIRECT) != \"ok\":\n            self.close_connection = 1\n\n    def go_DIRECT(self):\n        if not self.url.startswith(b\"https\"):\n            xlog.debug(\"Host:%s Direct redirect to https\", self.host)\n            return self.wfile.write(b'HTTP/1.1 301\\r\\nLocation: %s\\r\\nContent-Length: 0\\r\\n\\r\\n' % self.url.replace(b'http://', b'https://', 1))\n\n        request_headers = dict((k.title(), v) for k, v in list(self.headers.items()))\n        payload = self.read_payload()\n\n        xlog.debug(\"DIRECT %s %s from:%s\", self.command, self.url, self.address_string())\n        if direct_handler.handler(self.command, self.host, self.path, request_headers, payload, self.wfile) != \"ok\":\n            self.close_connection = 1\n\n    def read_payload(self):\n        def get_crlf(rfile):\n            crlf = rfile.readline(2)\n            if crlf != b\"\\r\\n\":\n                xlog.warn(\"chunk header read fail crlf\")\n\n        if self.req_payload is not None:\n            return self.req_payload\n\n        payload = b''\n        if b'Content-Length' in self.headers:\n            try:\n                payload_len = int(self.headers.get(b'Content-Length', 0))\n                #xlog.debug(\"payload_len:%d %s %s\", payload_len, self.command, self.path)\n                payload = self.rfile.read(payload_len)\n            except NetWorkIOError as e:\n                xlog.error('handle_method_urlfetch read payload failed:%s', e)\n                return\n        elif b'Transfer-Encoding' in self.headers:\n            # chunked, used by facebook android client\n            payload = \"\"\n            while True:\n                chunk_size_str = self.rfile.readline(65537)\n                chunk_size_list = chunk_size_str.split(b\";\")\n                chunk_size = int(b\"0x\"+chunk_size_list[0], 0)\n                if len(chunk_size_list) > 1 and chunk_size_list[1] != b\"\\r\\n\":\n                    xlog.warn(\"chunk ext: %s\", chunk_size_str)\n                if chunk_size == 0:\n                    while True:\n                        line = self.rfile.readline(65537)\n                        if line == b\"\\r\\n\":\n                            break\n                        else:\n                            xlog.warn(\"entity header:%s\", line)\n                    break\n                payload += self.rfile.read(chunk_size)\n                get_crlf(self.rfile)\n\n        self.req_payload = payload\n        return payload\n\n# called by smart_router\ndef wrap_ssl(sock, host, port, client_address):\n    certfile = CertUtil.get_cert(host or b'www.google.com')\n    ssl_sock = ssl.wrap_socket(sock, keyfile=CertUtil.cert_keyfile,\n                               certfile=certfile, server_side=True)\n    return ssl_sock\n\n"
  },
  {
    "path": "code/default/gae_proxy/local/sni_manager.py",
    "content": "import random\nimport os\nfrom front_base.random_get_slice import RandomGetSlice\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\n\n\nclass SniManager(object):\n    plus = ['-', '', \".\"]\n    end = [\"com\", \"net\", \"ml\", \"org\", \"us\"]\n\n    def __init__(self, logger):\n        self.logger = logger\n\n        fn = os.path.join(current_path, \"sni_slice.txt\")\n        self.slice = RandomGetSlice(fn, 20, '|')\n\n    def get(self):\n        return None\n\n        n = random.randint(2, 3)\n        ws = []\n        for i in range(0, n):\n            w = self.slice.get()\n            ws.append(w)\n\n        p = random.choice(self.plus)\n\n        name = p.join(ws)\n        name += \".\" + random.choice(self.end)\n\n        return name\n"
  },
  {
    "path": "code/default/gae_proxy/local/sni_slice.txt",
    "content": "people|history|way|art|world|information|map|two|family|government|health|system|computer|meat|year|thanks|music|person|reading|method|data|food|understanding|theory|law|bird|literature|problem|software|control|knowledge|power|ability|economics|love|internet|television|science|library|nature|fact|product|idea|temperature|investment|area|society|activity|story|industry|media|thing|oven|community|definition|safety|quality|development|language|management|player|variety|video|week|security|country|exam|movie|organization|equipment|physics|analysis|policy|series|thought|basis|boyfriend|direction|strategy|technology|army|camera|freedom|paper|environment|child|instance|month|truth|marketing|university|writing|article|department|difference|goal|news|audience|fishing|growth|income|marriage|user|combination|failure|meaning|medicine|philosophy|teacher|communication|night|chemistry|disease|disk|energy|nation|road|role|soup|advertising|location|success|addition|apartment|education|math|moment|painting|politics|attention|decision|event|property|shopping|student|wood|competition|distribution|entertainment|office|population|president|unit|category|cigarette|context|introduction|opportunity|performance|driver|flight|length|magazine|newspaper|relationship|teaching|cell|dealer|debate|finding|lake|member|message|phone|scene|appearance|association|concept|customer|death|discussion|housing|inflation|insurance|mood|woman|advice|blood|effort|expression|importance|opinion|payment|reality|responsibility|situation|skill|statement|wealth|application|city|county|depth|estate|foundation|grandmother|heart|perspective|photo|recipe|studio|topic|collection|depression|imagination|passion|percentage|resource|setting|ad|agency|college|connection|criticism|debt|description|memory|patience|secretary|solution|administration|aspect|attitude|director|personality|psychology|recommendation|response|selection|storage|version|alcohol|argument|complaint|contract|emphasis|highway|loss|membership|possession|preparation|steak|union|agreement|cancer|currency|employment|engineering|entry|interaction|limit|mixture|preference|region|republic|seat|tradition|virus|actor|classroom|delivery|device|difficulty|drama|election|engine|football|guidance|hotel|match|owner|priority|protection|suggestion|tension|variation|anxiety|atmosphere|awareness|bread|climate|comparison|confusion|construction|elevator|emotion|employee|employer|guest|height|leadership|mall|manager|operation|recording|respect|sample|transportation|boring|charity|cousin|disaster|editor|efficiency|excitement|extent|feedback|guitar|homework|leader|mom|outcome|permission|presentation|promotion|reflection|refrigerator|resolution|revenue|session|singer|tennis|basket|bonus|cabinet|childhood|church|clothes|coffee|dinner|drawing|hair|hearing|initiative|judgment|lab|measurement|mode|mud|orange|poetry|police|possibility|procedure|queen|ratio|relation|restaurant|satisfaction|sector|signature|significance|song|tooth|town|vehicle|volume|wife|accident|airport|appointment|arrival|assumption|baseball|chapter|committee|conversation|database|enthusiasm|error|explanation|farmer|gate|girl|hall|historian|hospital|injury|instruction|maintenance|manufacturer|meal|perception|pie|poem|presence|proposal|reception|replacement|revolution|river|son|speech|tea|village|warning|winner|worker|writer|assistance|breath|buyer|chest|chocolate|conclusion|contribution|cookie|courage|dad|desk|drawer|establishment|examination|garbage|grocery|honey|impression|improvement|independence|insect|inspection|inspector|king|ladder|menu|penalty|piano|potato|profession|professor|quantity|reaction|requirement|salad|sister|supermarket|tongue|weakness|wedding|affair|ambition|analyst|apple|assignment|assistant|bathroom|bedroom|beer|birthday|celebration|championship|cheek|client|consequence|departure|diamond|dirt|ear|fortune|friendship|funeral|gene|girlfriend|hat|indication|intention|lady|midnight|negotiation|obligation|passenger|pizza|platform|poet|pollution|recognition|reputation|shirt|sir|speaker|stranger|surgery|sympathy|tale|throat|trainer|uncle|youth|time|work|film|water|money|example|while|business|study|game|life|form|air|day|place|number|part|field|fish|back|process|heat|hand|experience|job|book|end|point|type|home|economy|value|body|market|guide|interest|state|radio|course|company|price|size|card|list|mind|trade|line|care|group|risk|word|fat|force|key|light|training|name|school|top|amount|level|order|practice|research|sense|service|piece|web|boss|sport|fun|house|page|term|test|answer|sound|focus|matter|kind|soil|board|oil|picture|access|garden|range|rate|reason|future|site|demand|exercise|image|case|cause|coast|action|age|bad|boat|record|result|section|building|mouse|cash|class|nothing|period|plan|store|tax|side|subject|space|rule|stock|weather|chance|figure|man|model|source|beginning|earth|program|chicken|design|feature|head|material|purpose|question|rock|salt|act|birth|car|dog|object|scale|sun|note|profit|rent|speed|style|war|bank|craft|half|inside|outside|standard|bus|exchange|eye|fire|position|pressure|stress|advantage|benefit|box|frame|issue|step|cycle|face|item|metal|paint|review|room|screen|structure|view|account|ball|discipline|medium|share|balance|bit|black|bottom|choice|gift|impact|machine|shape|tool|wind|address|average|career|culture|morning|pot|sign|table|task|condition|contact|credit|egg|hope|ice|network|north|square|attempt|date|effect|link|post|star|voice|capital|challenge|friend|self|shot|brush|couple|exit|front|function|lack|living|plant|plastic|spot|summer|taste|theme|track|wing|brain|button|click|desire|foot|gas|influence|notice|rain|wall|base|damage|distance|feeling|pair|savings|staff|sugar|target|text|animal|author|budget|discount|file|ground|lesson|minute|officer|phase|reference|register|sky|stage|stick|title|trouble|bowl|bridge|campaign|character|club|edge|evidence|fan|letter|lock|maximum|novel|option|pack|park|plenty|quarter|skin|sort|weight|baby|background|carry|dish|factor|fruit|glass|joint|master|muscle|red|strength|traffic|trip|vegetable|appeal|chart|gear|ideal|kitchen|land|log|mother|net|party|principle|relative|sale|season|signal|spirit|street|tree|wave|belt|bench|commission|copy|drop|minimum|path|progress|project|sea|south|status|stuff|ticket|tour|angle|blue|breakfast|confidence|daughter|degree|doctor|dot|dream|duty|essay|father|fee|finance|hour|juice|luck|milk|mouth|peace|pipe|stable|storm|substance|team|trick|afternoon|bat|beach|blank|catch|chain|consideration|cream|crew|detail|gold|interview|kid|mark|mission|pain|pleasure|score|screw|sex|shop|shower|suit|tone|window|agent|band|bath|block|bone|calendar|candidate|cap|coat|contest|corner|court|cup|district|door|east|finger|garage|guarantee|hole|hook|implement|layer|lecture|lie|manner|meeting|nose|parking|partner|profile|rice|routine|schedule|swimming|telephone|tip|winter|airline|bag|battle|bed|bill|bother|cake|code|curve|designer|dimension|dress|ease|emergency|evening|extension|farm|fight|gap|grade|holiday|horror|horse|host|husband|loan|mistake|mountain|nail|noise|occasion|package|patient|pause|phrase|proof|race|relief|sand|sentence|shoulder|smoke|stomach|string|tourist|towel|vacation|west|wheel|wine|arm|aside|associate|bet|blow|border|branch|breast|brother|buddy|bunch|chip|coach|cross|document|draft|dust|expert|floor|god|golf|habit|iron|judge|knife|landscape|league|mail|mess|native|opening|parent|pattern|pin|pool|pound|request|salary|shame|shelter|shoe|silver|tackle|tank|trust|assist|bake|bar|bell|bike|blame|boy|brick|chair|closet|clue|collar|comment|conference|devil|diet|fear|fuel|glove|jacket|lunch|monitor|mortgage|nurse|pace|panic|peak|plane|reward|row|sandwich|shock|spite|spray|surprise|till|transition|weekend|welcome|yard|alarm|bend|bicycle|bite|blind|bottle|cable|candle|clerk|cloud|concert|counter|flower|grandfather|harm|knee|lawyer|leather|load|mirror|neck|pension|plate|purple|ruin|ship|skirt|slice|snow|specialist|stroke|switch|trash|tune|zone|anger|award|bid|bitter|boot|bug|camp|candy|carpet|cat|champion|channel|clock|comfort|cow|crack|engineer|entrance|fault|grass|guy|hell|highlight|incident|island|joke|jury|leg|lip|mate|motor|nerve|passage|pen|pride|priest|prize|promise|resident|resort|ring|roof|rope|sail|scheme|script|sock|station|toe|tower|truck|witness|a|you|it|can|will|if|one|many|most|other|use|make|good|look|help|go|great|being|few|might|still|public|read|keep|start|give|human|local|general|she|specific|long|play|feel|high|tonight|put|common|set|change|simple|past|big|possible|particular|today|major|personal|current|national|cut|natural|physical|show|try|check|second|call|move|pay|let|increase|single|individual|turn|ask|buy|guard|hold|main|offer|potential|professional|international|travel|cook|alternative|following|special|working|whole|dance|excuse|cold|commercial|low|purchase|deal|primary|worth|fall|necessary|positive|produce|search|present|spend|talk|creative|tell|cost|drive|green|support|glad|remove|return|run|complex|due|effective|middle|regular|reserve|independent|leave|original|reach|rest|serve|watch|beautiful|charge|active|break|negative|safe|stay|visit|visual|affect|cover|report|rise|walk|white|beyond|junior|pick|unique|anything|classic|final|lift|mix|private|stop|teach|western|concern|familiar|fly|official|broad|comfortable|gain|maybe|rich|save|stand|young|heavy|hello|lead|listen|valuable|worry|handle|leading|meet|release|sell|finish|normal|press|ride|secret|spread|spring|tough|wait|brown|deep|display|flow|hit|objective|shoot|touch|cancel|chemical|cry|dump|extreme|push|conflict|eat|fill|formal|jump|kick|opposite|pass|pitch|remote|total|treat|vast|abuse|beat|burn|deposit|print|raise|sleep|somewhere|advance|anywhere|consist|dark|double|draw|equal|fix|hire|internal|join|kill|sensitive|tap|win|attack|claim|constant|drag|drink|guess|minor|pull|raw|soft|solid|wear|weird|wonder|annual|count|dead|doubt|feed|forever|impress|nobody|repeat|round|sing|slide|strip|whereas|wish|combine|command|dig|divide|equivalent|hang|hunt|initial|march|mention|spiritual|survey|tie|adult|brief|crazy|escape|gather|hate|prior|repair|rough|sad|scratch|sick|strike|employ|external|hurt|illegal|laugh|lay|mobile|nasty|ordinary|respond|royal|senior|split|strain|struggle|swim|train|upper|wash|yellow|convert|crash|dependent|fold|funny|grab|hide|miss|permit|quote|recover|resolve|roll|sink|slip|spare|suspect|sweet|swing|twist|upstairs|usual|abroad|brave|calm|concentrate|estimate|grand|male|mine|prompt|quiet|refuse|regret|reveal|rush|shake|shift|shine|steal|suck|surround|anybody|bear|brilliant|dare|dear|delay|drunk|female|hurry|inevitable|invite|kiss|neat|pop|punch|quit|reply|representative|resist|rip|rub|silly|smile|spell|stretch|stupid|tear|temporary|tomorrow|wake|wrap|yesterday"
  },
  {
    "path": "code/default/gae_proxy/local/web_control.py",
    "content": "#!/usr/bin/env python\n# coding:utf-8\n\n\nimport platform\nimport json\nimport os\nimport re\nimport subprocess\nimport sys\nimport datetime\nimport locale\nimport time\nimport hashlib\nimport ssl\n\ntry:\n    from urllib.parse import urlparse, parse_qs\nexcept ImportError:\n    from urlparse import urlparse, parse_qs\n    \nimport simple_http_server\nimport simple_http_client\nimport env_info\nimport utils\n\nimport env_info\nfrom xlog import getLogger\nxlog = getLogger(\"gae_proxy\")\nfrom .config import config, direct_config\nfrom . import check_local_network\nfrom . import cert_util\nfrom . import ipv6_tunnel\nfrom .front import front, direct_front\nfrom . import download_gae_lib\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\n\nroot_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))\ntop_path = os.path.abspath(os.path.join(root_path, os.pardir, os.pardir))\ndata_path = os.path.join(env_info.data_path, 'gae_proxy')\nweb_ui_path = os.path.join(current_path, os.path.pardir, \"web_ui\")\n\n\ndef get_fake_host():\n    return \"deja.com\"\n\n\ndef test_appid_exist(ssl_sock, appid):\n    request_data = 'GET /_gh/ HTTP/1.1\\r\\nHost: %s.appspot.com\\r\\n\\r\\n' % appid\n    ssl_sock.send(request_data.encode())\n    response = simple_http_client.Response(ssl_sock)\n\n    response.begin()\n    if response.status == 404:\n        # xlog.warn(\"app check %s status:%d\", appid, response.status)\n        return False\n\n    if response.status == 503:\n        # out of quota\n        return True\n\n    if response.status != 200:\n        xlog.warn(\"test appid %s status:%d\", appid, response.status)\n\n    content = response.read()\n    if b\"GoAgent\" not in content:\n        # xlog.warn(\"app check %s content:%s\", appid, content)\n        return False\n\n    return True\n\n\ndef test_appid(appid):\n    for i in range(0, 3):\n        ssl_sock = direct_front.connect_manager.get_ssl_connection()\n        if not ssl_sock:\n            continue\n\n        try:\n            return test_appid_exist(ssl_sock, appid)\n        except Exception as e:\n            xlog.warn(\"check_appid %s %r\", appid, e)\n            continue\n\n    return False\n\n\ndef test_appids(appids):\n    appid_list = appids.split(\"|\")\n    fail_appid_list = []\n    for appid in appid_list:\n        if not test_appid(appid):\n            fail_appid_list.append(appid)\n        else:\n            # return success if one appid is work\n            # just reduce wait time\n            # here can be more ui friendly.\n            return []\n    return fail_appid_list\n\n\ndef get_openssl_version():\n    return \"%s %s h2:%s\" % (ssl.OPENSSL_VERSION,\n                            front.openssl_context.supported_protocol(),\n                            front.openssl_context.support_alpn_npn)\n\n\ndeploy_proc = None\n\n\nclass ControlHandler(simple_http_server.HttpServerHandler):\n    def __init__(self, client_address, headers, command, path, rfile, wfile):\n        self.client_address = client_address\n        self.headers = headers\n        self.command = command\n        self.path = path\n        self.rfile = rfile\n        self.wfile = wfile\n\n    def do_CONNECT(self):\n        self.wfile.write(b'HTTP/1.1 403\\r\\nConnection: close\\r\\n\\r\\n')\n\n    def do_GET(self):\n        path = urlparse(self.path).path\n        if path == \"/log\":\n            return self.req_log_handler()\n        elif path == \"/status\":\n            return self.req_status_handler()\n        else:\n            xlog.debug('GAEProxy Web_control %s %s %s ', self.address_string(), self.command, self.path)\n\n\n        if path == '/deploy':\n            return self.req_deploy_handler()\n        elif path == \"/config\":\n            return self.req_config_handler()\n        elif path == \"/ip_list\":\n            return self.req_ip_list_handler()\n        elif path == \"/scan_ip\":\n            return self.req_scan_ip_handler()\n        elif path == \"/ssl_pool\":\n            return self.req_ssl_pool_handler()\n        elif path == \"/workers\":\n            return self.req_workers_handler()\n        elif path == \"/download_cert\":\n            return self.req_download_cert_handler()\n        elif path == \"/is_ready\":\n            return self.req_is_ready_handler()\n        elif path == \"/test_ip\":\n            return self.req_test_ip_handler()\n        elif path == \"/check_ip\":\n            return self.req_check_ip_handler()\n        elif path == \"/debug\":\n            return self.req_debug_handler()\n        elif path.startswith(\"/ipv6_tunnel\"):\n            return self.req_ipv6_tunnel_handler()\n        elif path == \"/quit\":\n            front.stop()\n            direct_front.stop()\n            data = b\"Quit\"\n            self.wfile.write((b'HTTP/1.1 200\\r\\nContent-Type: %s\\r\\nContent-Length: %s\\r\\n\\r\\n' % (b'text/plain', len(data))).encode())\n            self.wfile.write(data)\n            #sys.exit(0)\n            #quit()\n            #os._exit(0)\n            return\n        elif path.startswith(\"/wizard/\"):\n            file_path = os.path.abspath(os.path.join(web_ui_path, '/'.join(path.split('/')[1:])))\n            if not os.path.isfile(file_path):\n                self.wfile.write(b'HTTP/1.1 404 Not Found\\r\\n\\r\\n')\n                xlog.warn('%s %s %s wizard file %s not found', self.address_string(), self.command, self.path, file_path)\n                return\n\n            if file_path.endswith('.html'):\n                mimetype = 'text/html'\n            elif file_path.endswith('.png'):\n                mimetype = 'image/png'\n            elif file_path.endswith('.jpg') or file_path.endswith('.jpeg'):\n                mimetype = 'image/jpeg'\n            else:\n                mimetype = 'application/octet-stream'\n\n            self.send_file(file_path, mimetype)\n            return\n        else:\n            xlog.warn('Control Req %s %s %s ', self.address_string(), self.command, self.path)\n\n        # check for '..', which will leak file\n        if re.search(r'(\\.{2})', self.path) is not None:\n            self.wfile.write(b'HTTP/1.1 404\\r\\n\\r\\n')\n            xlog.warn('%s %s %s haking', self.address_string(), self.command, self.path )\n            return\n\n\n        filename = os.path.normpath('./' + path)\n        if self.path.startswith(('http://', 'https://')):\n            data = b'HTTP/1.1 200\\r\\nCache-Control: max-age=86400\\r\\nExpires:Oct, 01 Aug 2100 00:00:00 GMT\\r\\nConnection: close\\r\\n'\n\n            data += b'\\r\\n'\n            self.wfile.write(data)\n            xlog.info('%s \"%s %s HTTP/1.1\" 200 -', self.address_string(), self.command, self.path)\n        elif os.path.isfile(filename):\n            if filename.endswith('.pac'):\n                mimetype = 'text/plain'\n            else:\n                mimetype = 'application/octet-stream'\n            #self.send_file(filename, mimetype)\n        else:\n            self.wfile.write(b'HTTP/1.1 404\\r\\nContent-Type: text/plain\\r\\nConnection: close\\r\\n\\r\\n404 Not Found')\n            xlog.info('%s \"%s %s HTTP/1.1\" 404 -', self.address_string(), self.command, self.path)\n\n    def do_POST(self):\n        try:\n            refer = self.headers.getheader('Referer')\n            netloc = urlparse(refer).netloc\n            if not netloc.startswith(\"127.0.0.1\") and not netloc.startswitch(\"localhost\"):\n                xlog.warn(\"web control ref:%s refuse\", netloc)\n                return\n        except:\n            pass\n\n        xlog.debug ('GAEProxy web_control %s %s %s ', self.address_string(), self.command, self.path)\n\n        path = urlparse(self.path).path\n        if path == '/deploy':\n            return self.req_deploy_handler()\n        elif path == \"/config\":\n            return self.req_config_handler()\n        elif path == \"/scan_ip\":\n            return self.req_scan_ip_handler()\n        elif path.startswith(\"/importip\"):\n            return self.req_importip_handler()\n        else:\n            self.wfile.write(b'HTTP/1.1 404\\r\\nContent-Type: text/plain\\r\\nConnection: close\\r\\n\\r\\n404 Not Found')\n            xlog.info('%s \"%s %s HTTP/1.1\" 404 -', self.address_string(), self.command, self.path)\n\n    def req_log_handler(self):\n        req = urlparse(self.path).query\n        reqs = parse_qs(req, keep_blank_values=True)\n        reqs = self.unpack_reqs(reqs)\n        data = ''\n\n        cmd = \"get_last\"\n        if reqs[\"cmd\"]:\n            cmd = reqs[\"cmd\"]\n\n        if cmd == \"get_last\":\n            max_line = int(reqs[\"max_line\"])\n            data = xlog.get_last_lines(max_line)\n        elif cmd == \"get_new\":\n            last_no = int(reqs[\"last_no\"])\n            data = xlog.get_new_lines(last_no)\n        else:\n            xlog.error('WebUI log from:%s unknown cmd:%s path:%s ', self.address_string(), self.command, self.path)\n\n        mimetype = 'text/plain'\n        self.send_response_nc(mimetype, data)\n\n    def get_launcher_version(self):\n        return \"unknown\"\n\n    @staticmethod\n    def xxnet_version():\n        version_file = os.path.join(root_path, \"version.txt\")\n        try:\n            with open(version_file, \"r\") as fd:\n                version = fd.read()\n            return version\n        except Exception as e:\n            xlog.exception(\"xxnet_version fail\")\n        return \"get_version_fail\"\n\n    def get_os_language(self):\n        if hasattr(self, \"lang_code\"):\n            return self.lang_code\n\n        try:\n            lang_code, code_page = locale.getdefaultlocale()\n            #('en_GB', 'cp1252'), en_US,\n            self.lang_code = lang_code\n            return lang_code\n        except:\n            #Mac fail to run this\n            pass\n\n        if sys.platform == \"darwin\":\n            try:\n                oot = os.pipe()\n                p = subprocess.Popen([\"/usr/bin/defaults\", 'read', 'NSGlobalDomain', 'AppleLanguages'],stdout=oot[1])\n                p.communicate()\n                lang_code = os.read(oot[0],10000)\n                self.lang_code = lang_code\n                return lang_code\n            except:\n                pass\n\n        lang_code = 'Unknown'\n        return lang_code\n\n    def req_status_handler(self):\n        if \"User-Agent\" in self.headers:\n            user_agent = self.headers[\"User-Agent\"]\n        else:\n            user_agent = \"\"\n\n        if config.PROXY_ENABLE:\n            lan_proxy = \"%s://%s:%s\" % (config.PROXY_TYPE, config.PROXY_HOST, config.PROXY_PORT)\n        else:\n            lan_proxy = \"Disable\"\n\n        res_arr = {\n            \"sys_platform\": \"%s, %s\" % (platform.machine(), platform.platform()),\n            \"os_system\": platform.system(),\n            \"os_version\": platform.version(),\n            \"os_release\": platform.release(),\n            \"architecture\": platform.architecture(),\n            \"os_detail\": env_info.os_detail(),\n            \"language\": self.get_os_language(),\n            \"browser\": user_agent,\n            \"xxnet_version\": self.xxnet_version(),\n            \"python_version\": platform.python_version(),\n            \"openssl_version\": get_openssl_version(),\n\n            \"proxy_listen\": str(config.listen_ip) + \":\" + str(config.listen_port),\n            \"use_ipv6\": config.use_ipv6,\n            \"lan_proxy\": lan_proxy,\n\n            \"gae_appid\": \"|\".join(config.GAE_APPIDS),\n            \"working_appid\": \"|\".join(front.appid_manager.working_appid_list),\n            \"out_of_quota_appids\": \"|\".join(front.appid_manager.out_of_quota_appids),\n            \"not_exist_appids\": \"|\".join(front.appid_manager.not_exist_appids),\n\n            \"ipv4_state\": check_local_network.IPv4.get_stat(),\n            \"ipv6_state\": check_local_network.IPv6.get_stat(),\n            #\"ipv6_tunnel\": ipv6_tunnel.state(),\n            \"all_ip_num\": len(front.ip_manager.ip_list),\n            \"good_ipv4_num\": front.ip_manager.good_ipv4_num,\n            \"good_ipv6_num\": front.ip_manager.good_ipv6_num,\n            \"connected_link_new\": len(front.connect_manager.new_conn_pool.pool),\n            \"connection_pool_min\": config.https_connection_pool_min,\n            \"worker_h1\": front.http_dispatcher.h1_num,\n            \"worker_h2\": front.http_dispatcher.h2_num,\n            \"is_idle\": int(front.http_dispatcher.is_idle()),\n            \"scan_ip_thread_num\": front.ip_manager.scan_thread_count,\n            \"ip_quality\": front.ip_manager.ip_quality(),\n\n            \"fake_host\": get_fake_host()\n        }\n        data = json.dumps(res_arr, indent=0, sort_keys=True)\n        self.send_response_nc('text/html', data)\n\n    def req_config_handler(self):\n        req = urlparse(self.path).query\n        reqs = parse_qs(req, keep_blank_values=True)\n        data = ''\n\n        appid_updated = False\n\n        try:\n            if reqs['cmd'] == ['get_config']:\n                ret_config = {\n                    \"appid\": \"|\".join(config.GAE_APPIDS),\n                    \"auto_adjust_scan_ip_thread_num\": config.auto_adjust_scan_ip_thread_num,\n                    \"scan_ip_thread_num\": config.max_scan_ip_thread_num,\n                    \"use_ipv6\": config.use_ipv6,\n                    \"setting_level\": config.setting_level,\n                    \"connect_receive_buffer\": config.connect_receive_buffer,\n                }\n                data = json.dumps(ret_config, default=lambda o: o.__dict__)\n            elif reqs['cmd'] == ['set_config']:\n                appids = self.postvars['appid']\n                if appids != \"|\".join(config.GAE_APPIDS):\n                    if appids and (front.ip_manager.good_ipv4_num + front.ip_manager.good_ipv6_num):\n                        fail_appid_list = test_appids(appids)\n                        if len(fail_appid_list):\n                            fail_appid = \"|\".join(fail_appid_list)\n                            data = json.dumps({\"res\": \"fail\",\n                                               \"reason\": \"appid fail:\" + fail_appid\n                                               })\n                            return\n\n                    appid_updated = True\n                    if appids:\n                        xlog.info(\"set appids:%s\", appids)\n                        config.GAE_APPIDS = appids.split(\"|\")\n                    else:\n                        config.GAE_APPIDS = []\n\n                config.save()\n\n                config.load()\n                front.appid_manager.reset_appid()\n                if appid_updated:\n                    front.http_dispatcher.close_all_worker()\n\n                front.ip_manager.reset()\n\n                data = '{\"res\":\"success\"}'\n                #http_request(\"http://127.0.0.1:8085/init_module?module=gae_proxy&cmd=restart\")\n            elif reqs['cmd'] == ['set_config_level']:\n                setting_level = self.postvars['setting_level']\n                if setting_level:\n                    xlog.info(\"set globa config level to %s\", setting_level)\n                    config.set_level(setting_level)\n                    direct_config.set_level(setting_level)\n                    front.ip_manager.load_config()\n                    front.ip_manager.adjust_scan_thread_num()\n                    front.ip_manager.remove_slowest_ip()\n                    front.ip_manager.search_more_ip()\n\n                connect_receive_buffer = int(self.postvars['connect_receive_buffer'])\n                if 8192 <= connect_receive_buffer <= 2097152 and connect_receive_buffer != config.connect_receive_buffer:\n                    xlog.info(\"set connect receive buffer to %dKB\", connect_receive_buffer // 1024)\n                    config.connect_receive_buffer = connect_receive_buffer\n                    config.save()\n                    config.load()\n\n                    front.connect_manager.new_conn_pool.clear()\n                    direct_front.connect_manager.new_conn_pool.clear()\n                    front.http_dispatcher.close_all_worker()\n                    for _, http_dispatcher in list(direct_front.dispatchs.items()):\n                        http_dispatcher.close_all_worker()\n\n                data = '{\"res\":\"success\"}'\n        except Exception as e:\n            xlog.exception(\"req_config_handler except:%s\", e)\n            data = '{\"res\":\"fail\", \"except\":\"%s\"}' % e\n        finally:\n            self.send_response_nc('text/html', data)\n\n    def req_deploy_handler(self):\n        global deploy_proc\n        req = urlparse(self.path).query\n        reqs = parse_qs(req, keep_blank_values=True)\n        data = ''\n\n        log_path = os.path.abspath(os.path.join(current_path, os.pardir, \"server\", 'upload.log'))\n        time_now = datetime.datetime.today().strftime('%H:%M:%S-%a/%d/%b/%Y')\n\n        if reqs['cmd'] == ['deploy']:\n            appid = self.postvars['appid']\n            debug = int(self.postvars['debug'])\n\n            if deploy_proc and deploy_proc.poll() == None:\n                xlog.warn(\"deploy is running, request denied.\")\n                data = '{\"res\":\"deploy is running\", \"time\":\"%s\"}' % time_now\n\n            else:\n                try:\n                    download_gae_lib.check_lib_or_download()\n\n                    if os.path.isfile(log_path):\n                        os.remove(log_path)\n                    script_path = os.path.abspath(os.path.join(current_path, os.pardir, \"server\", 'uploader.py'))\n\n                    args = [sys.executable, script_path, appid]\n                    if debug:\n                        args.append(\"-debug\")\n\n                    deploy_proc = subprocess.Popen(args)\n                    xlog.info(\"deploy begin.\")\n                    data = '{\"res\":\"success\", \"time\":\"%s\"}' % time_now\n                except Exception as e:\n                    data = '{\"res\":\"%s\", \"time\":\"%s\"}' % (e, time_now)\n\n        elif reqs['cmd'] == ['cancel']:\n            if deploy_proc and deploy_proc.poll() == None:\n                deploy_proc.kill()\n                data = '{\"res\":\"deploy is killed\", \"time\":\"%s\"}' % time_now\n            else:\n                data = '{\"res\":\"deploy is not running\", \"time\":\"%s\"}' % time_now\n\n        elif reqs['cmd'] == ['get_log']:\n            if deploy_proc and os.path.isfile(log_path):\n                with open(log_path, \"r\") as f:\n                    content = f.read()\n            else:\n                content = \"\"\n\n            status = 'init'\n            if deploy_proc:\n                if deploy_proc.poll() == None:\n                    status = 'running'\n                else:\n                    status = 'finished'\n\n            data = json.dumps({'status': status, 'log': content, 'time': time_now})\n\n        self.send_response_nc('text/html', data)\n\n    def req_importip_handler(self):\n        req = urlparse(self.path).query\n        reqs = parse_qs(req, keep_blank_values=True)\n        data = ''\n\n        if reqs['cmd'] == ['importip']:\n            count = 0\n            ip_list = self.postvars['ipList']\n            lines = ip_list.split(\"\\n\")\n            for line in lines:\n                addresses = line.split('|')\n                for ip in addresses:\n                    ip = ip.strip()\n                    if not utils.check_ip_valid(ip):\n                        continue\n                    if front.ip_manager.add_ip(ip, 100, \"google.com\", \"gws\"):\n                        count += 1\n            data = '{\"res\":\"%s\"}' % count\n            front.ip_manager.save(force=True)\n\n        elif reqs['cmd'] == ['exportip']:\n            data = '{\"res\":\"'\n            for ip in front.ip_manager.ip_list:\n                if front.ip_manager.ip_dict[ip]['fail_times'] > 0:\n                    continue\n                data += \"%s|\" % ip\n            data = data[0: len(data) - 1]\n            data += '\"}'\n\n        self.send_response_nc('text/html', data)\n\n    def req_test_ip_handler(self):\n        req = urlparse(self.path).query\n        reqs = parse_qs(req, keep_blank_values=True)\n        reqs = self.unpack_reqs(reqs)\n\n        ip = reqs['ip']\n        result = front.check_ip.check_ip(ip)\n        if not result or not result.ok:\n            data = \"{'res':'fail'}\"\n        else:\n            data = json.dumps(\"{'ip':'%s', 'handshake':'%s', 'server':'%s', 'domain':'%s'}\" %\n                  (ip, result.handshake_time, result.server_type, result.domain))\n\n        self.send_response_nc('text/html', data)\n\n    def req_ip_list_handler(self):\n        time_now = time.time()\n        data = \"<html><body><div  style='float: left; white-space:nowrap;font-family: monospace;'>\"\n        data += \"time:%d  pointer:%d<br>\\r\\n\" % (time_now, front.ip_manager.ip_pointer)\n        data += \"<table><tr><th>N</th><th>IP</th><th>HS</th><th>Fails</th>\"\n        data += \"<th>down_fail</th><th>links</th>\"\n        data += \"<th>get_time</th><th>success_time</th><th>fail_time</th><th>down_fail_time</th>\"\n        data += \"<th>data_active</th><th>transfered_data</th><th>Trans</th>\"\n        data += \"<th>history</th></tr>\\n\"\n        i = 1\n        for ip in front.ip_manager.gws_ip_list:\n            handshake_time = front.ip_manager.ip_dict[ip][\"handshake_time\"]\n\n            fail_times = front.ip_manager.ip_dict[ip][\"fail_times\"]\n            down_fail = front.ip_manager.ip_dict[ip][\"down_fail\"]\n            links = front.ip_manager.ip_dict[ip][\"links\"]\n\n            get_time = front.ip_manager.ip_dict[ip][\"get_time\"]\n            if get_time:\n                get_time = time_now - get_time\n\n            success_time = front.ip_manager.ip_dict[ip][\"success_time\"]\n            if success_time:\n                success_time = time_now - success_time\n\n            fail_time = front.ip_manager.ip_dict[ip][\"fail_time\"]\n            if fail_time:\n                fail_time = time_now - fail_time\n\n            down_fail_time = front.ip_manager.ip_dict[ip][\"down_fail_time\"]\n            if down_fail_time:\n                down_fail_time = time_now - down_fail_time\n\n            data_active = front.ip_manager.ip_dict[ip][\"data_active\"]\n            if data_active:\n                active_time = time_now - data_active\n            else:\n                active_time = 0\n\n            history = front.ip_manager.ip_dict[ip][\"history\"]\n            t0 = 0\n            str_out = ''\n            for item in history:\n                t = item[0]\n                v = item[1]\n                if t0 == 0:\n                    t0 = t\n                time_per = int((t - t0) * 1000)\n                t0 = t\n                str_out += \"%d(%s) \" % (time_per, v)\n            data += \"<tr><td>%d</td><td>%s</td><td>%d</td><td>%d</td><td>%d</td><td>%d</td><td>%d</td><td>%d</td><td>%d</td>\" \\\n                    \"<td>%d</td><td>%d</td><td>%s</td></tr>\\n\" % \\\n                    (i, ip, handshake_time, fail_times, down_fail, links, get_time, success_time, fail_time, down_fail_time,\n                    active_time, str_out)\n            i += 1\n\n        data += \"</table></div></body></html>\"\n        mimetype = 'text/html'\n        self.send_response_nc(mimetype, data)\n\n    def req_scan_ip_handler(self):\n        req = urlparse(self.path).query\n        reqs = parse_qs(req, keep_blank_values=True)\n        reqs = self.unpack_reqs(reqs)\n\n        data = \"\"\n        if reqs['cmd'] == 'get_range':\n            data = front.ipv4_source.load_range_content()\n        elif reqs['cmd'] == 'update':\n            #update ip_range if needed\n            content = self.postvars['ip_range']\n\n            #check ip_range checksums, update if needed\n            default_digest = hashlib.md5(utils.to_bytes(front.ipv4_source.load_range_content(default=True))).hexdigest()\n            old_digest = hashlib.md5(utils.to_bytes(front.ipv4_source.load_range_content())).hexdigest()\n            new_digest = hashlib.md5(utils.to_bytes(content)).hexdigest()\n\n            if new_digest == default_digest:\n                front.ipv4_source.remove_user_range()\n\n            else:\n                if old_digest != new_digest:\n                    front.ipv4_source.update_range_content(content)\n\n            if old_digest != new_digest:\n                front.ipv4_source.load_ip_range()\n\n            #update auto_adjust_scan_ip and scan_ip_thread_num\n            should_auto_adjust_scan_ip = int(self.postvars['auto_adjust_scan_ip_thread_num'])\n            thread_num_for_scan_ip = int(self.postvars['scan_ip_thread_num'])\n\n            use_ipv6 = self.postvars['use_ipv6']\n            if config.use_ipv6 != use_ipv6:\n                xlog.debug(\"use_ipv6 change to %s\", use_ipv6)\n                config.use_ipv6 = use_ipv6\n\n            #update user config settings\n            config.auto_adjust_scan_ip_thread_num = should_auto_adjust_scan_ip\n            config.max_scan_ip_thread_num = thread_num_for_scan_ip\n            config.save()\n            config.load()\n\n            front.ip_manager.adjust_scan_thread_num()\n\n            #reponse \n            data='{\"res\":\"success\"}'\n\n        mimetype = 'text/plain'\n        self.send_response_nc(mimetype, data)\n\n    def req_ssl_pool_handler(self):\n        data = \"New conn:\\n\"\n        data += front.connect_manager.new_conn_pool.to_string()\n\n        for host in front.connect_manager.host_conn_pool:\n            data += \"\\nHost:%s\\n\" % host\n            data += front.connect_manager.host_conn_pool[host].to_string()\n\n        mimetype = 'text/plain'\n        self.send_response_nc(mimetype, data)\n\n    def req_workers_handler(self):\n        data = front.http_dispatcher.to_string()\n\n        mimetype = 'text/plain'\n        self.send_response_nc(mimetype, data)\n\n    def req_download_cert_handler(self):\n        filename = cert_util.CertUtil.ca_keyfile\n        if not os.path.isfile(filename):\n            xlog.warn(\"CA file not exist, download cert failed.\")\n            return self.send_not_found()\n\n        with open(filename, 'rb') as fp:\n            data = fp.read()\n        mimetype = 'application/x-x509-ca-cert'\n\n        self.wfile.write(('HTTP/1.1 200\\r\\nContent-Disposition: inline; filename=CA.crt\\r\\nContent-Type: %s\\r\\nContent-Length: %s\\r\\n\\r\\n' % (mimetype, len(data))).encode())\n        self.wfile.write(data)\n\n    def req_is_ready_handler(self):\n        data = \"%s\" % config.cert_import_ready\n\n        mimetype = 'text/plain'\n        self.send_response_nc(mimetype, data)\n\n    def req_check_ip_handler(self):\n        req = urlparse(self.path).query\n        reqs = parse_qs(req, keep_blank_values=True)\n        data = \"\"\n        if reqs['cmd'] == ['get_process']:\n            all_ip_num = len(front.ip_manager.ip_dict)\n            left_num = front.ip_manager.scan_exist_ip_queue.qsize()\n            good_num = (front.ip_manager.good_ipv4_num + front.ip_manager.good_ipv6_num)\n            data = json.dumps(dict(all_ip_num=all_ip_num, left_num=left_num, good_num=good_num))\n            self.send_response_nc('text/plain', data)\n        elif reqs['cmd'] == ['start']:\n            left_num = front.ip_manager.scan_exist_ip_queue.qsize()\n            if left_num:\n                self.send_response_nc('text/plain', '{\"res\":\"fail\", \"reason\":\"running\"}')\n            else:\n                front.ip_manager.start_scan_all_exist_ip()\n                self.send_response_nc('text/plain', '{\"res\":\"success\"}')\n        elif reqs['cmd'] == ['stop']:\n            left_num = front.ip_manager.scan_exist_ip_queue.qsize()\n            if not left_num:\n                self.send_response_nc('text/plain', '{\"res\":\"fail\", \"reason\":\"not running\"}')\n            else:\n                front.ip_manager.stop_scan_all_exist_ip()\n                self.send_response_nc('text/plain', '{\"res\":\"success\"}')\n        else:\n            return self.send_not_exist()\n\n    def req_debug_handler(self):\n        data = \"\"\n        for obj in [front.connect_manager, front.http_dispatcher]:\n            data += \"%s\\r\\n\" % obj.__class__\n            for attr in dir(obj):\n                if attr.startswith(\"__\"):\n                    continue\n                data += \"    %s = %s\\r\\n\" % (attr, getattr(obj, attr))\n\n        mimetype = 'text/plain'\n        self.send_response_nc(mimetype, data)\n\n    def req_ipv6_tunnel_handler(self):\n        req = urlparse(self.path).query\n        reqs = parse_qs(req, keep_blank_values=True)\n        reqs = self.unpack_reqs(reqs)\n        data = ''\n\n        log_path = os.path.join(data_path, \"ipv6_tunnel.log\")\n        time_now = datetime.datetime.today().strftime('%H:%M:%S-%a/%d/%b/%Y')\n\n        client_ip = self.client_address[0]\n        is_local = client_ip.endswith(\"127.0.0.1\") or client_ip == \"::1\"\n\n        if reqs['cmd'] in [['enable'],\n                           ['disable'],\n                           ['test_teredo'],\n                           ['test_teredo_usability'],\n                           ['test_teredo_server'],\n                           ['set_best_server']]:\n            cmd = reqs['cmd']\n            xlog.info(\"ipv6_tunnel switch %s\", cmd)\n\n            # Don't remove log file at here.\n\n            if cmd == \"enable\":\n                result = ipv6_tunnel.enable(is_local)\n            elif cmd == \"disable\":\n                result = ipv6_tunnel.disable(is_local)\n            elif cmd == \"test_teredo\":\n                result = ipv6_tunnel.test_teredo()\n            elif cmd == \"test_teredo_usability\":\n                result = ipv6_tunnel.test_teredo(probe_server=False)\n            elif cmd == \"test_teredo_server\":\n                result = ipv6_tunnel.test_teredo(probe_nat=False)\n            elif cmd == \"set_best_server\":\n                result = ipv6_tunnel.set_best_server(is_local)\n            else:\n                xlog.warn(\"unknown cmd:%s\", cmd)\n                result = None\n\n            xlog.info(\"ipv6_tunnel switch %s, result: %s\", cmd, result)\n\n            data = json.dumps({'res': result, 'time': time_now})\n\n        elif reqs['cmd'] == ['get_log']:\n            if os.path.isfile(log_path):\n                with open(log_path, \"r\") as f:\n                    content = f.read()\n            else:\n                content = \"\"\n\n            status = ipv6_tunnel.state()\n\n            data = json.dumps({'status': status, 'log': content, 'time': time_now})\n\n        elif reqs['cmd'] == ['get_priority']:\n            data = json.dumps({'res': ipv6_tunnel.state_pp(), 'time': time_now})\n\n        elif reqs['cmd'] == ['switch_pp']:\n            data = json.dumps({'res': ipv6_tunnel.switch_pp(), 'time': time_now})\n\n        self.send_response_nc('text/html', data)\n\n"
  },
  {
    "path": "code/default/gae_proxy/server/.gitignore",
    "content": ".DS_Store\n*~\n*.pyc\n.appcfg_cookies\nupload.log\n"
  },
  {
    "path": "code/default/gae_proxy/server/README.md",
    "content": "## 设置使用密码：\n如果你担心流量被别人使用，可以设置使用密码。  \n编辑main.py 里的 __password____\n注意在客户端中也需要设置一样的密码才能访问。  \n一般你不泄露appid，别人是无法使用你的流量的。  \n\n## 下载gcloud 并安装\nhttps://cloud.google.com/sdk/docs/install\n\n## 登陆google账户，选择部署的appid\n  需要先指定代理服务器，可以使用X-tunnel作为代理服务器，端口1080。 \n  `gcloud config set proxy/type socks5`  \n  `gcloud config set proxy/address localhost`  \n  `gcloud config set proxy/port 1080`   \n  请先确认X-Tunnel 已经登陆并可以访问google服务。  \n\n  参考这里：  \n  https://cloud.google.com/sdk/docs/proxy-settings\n\n  登陆并选择需要部署的appid：  \n `gcloud init`  \n  \n\n## 未绑定信用卡的需要绑定:\n  https://console.cloud.google.com/billing/enable\n\n## 部署：\n`cd XX-Net/code/default/gae_proxy/server/gae`  \n`gcloud app deploy`  \n\n  "
  },
  {
    "path": "code/default/gae_proxy/server/gae/.gcloudignore",
    "content": "# This file specifies files that are *not* uploaded to Google Cloud\n# using gcloud. It follows the same syntax as .gitignore, with the addition of\n# \"#!include\" directives (which insert the entries of the given .gitignore-style\n# file at that point).\n#\n# For more information, run:\n#   $ gcloud topic gcloudignore\n#\n.gcloudignore\n# If you would like to upload your .git directory, .gitignore file or files\n# from your .gitignore file, remove the corresponding line\n# below:\n.git\n.gitignore\n\n# Python pycache:\n__pycache__/\n# Ignored by the build system\n/setup.cfg"
  },
  {
    "path": "code/default/gae_proxy/server/gae/app.yaml",
    "content": "instance_class: F1\nautomatic_scaling:\n  max_instances: 1\n\nruntime: python312\napp_engine_apis: true\n\nentrypoint: gunicorn -c gunicorn.conf.py --timeout 60 -b :$PORT main:app"
  },
  {
    "path": "code/default/gae_proxy/server/gae/gunicorn.conf.py",
    "content": "# Recommended number of workers based on instance size:\n# https://cloud.google.com/appengine/docs/standard/python3/runtime#entrypoint_best_practices\nthreads = 20\n# Use an asynchronous worker as most of the work is waiting for websites to load\nworker_class = 'gthread'"
  },
  {
    "path": "code/default/gae_proxy/server/gae/main.py",
    "content": "import os\nimport time\nfrom datetime import timedelta, datetime, tzinfo\nimport struct\nimport zlib\nimport logging\nfrom urllib.parse import urlparse\nimport http.client as httplib\nimport json\nimport threading\nimport re\n\nimport psutil\nimport flask\nfrom flask import Flask, request\nimport requests\n\nfrom google.cloud import storage\nfrom google.appengine.api import urlfetch\nfrom google.appengine.runtime import apiproxy_errors\nfrom google.appengine.api.taskqueue.taskqueue import MAX_URL_LENGTH\nfrom google.appengine.api import urlfetch_stub\nfrom google.appengine.api import apiproxy_stub_map\n\napiproxy_stub_map.apiproxy = apiproxy_stub_map.APIProxyStubMap()\napiproxy_stub_map.apiproxy.RegisterStub('urlfetch', urlfetch_stub.URLFetchServiceStub())\n\nlogging.basicConfig(format='%(asctime)s - %(message)s', level=logging.INFO)\n\napp = Flask(__name__)\ntry:\n    storage_client = storage.Client()\n\n    project_id = os.environ.get(\"GOOGLE_CLOUD_PROJECT\")\n    bucket_name = f\"{project_id}.appspot.com\"\n    bucket = storage_client.bucket(bucket_name)\n    blob_name = \"band_usage_info\"\nexcept Exception as e:\n    logging.warning(\"init blob fail:%r\", e)\n    storage_client = None\n\n__password__ = ''\n\nURLFETCH_MAX = 2\nURLFETCH_DEFLATE_MAXSIZE = 4 * 1024 * 1024\nURLFETCH_TIMEOUT = 30\nallowed_traffic = 1024 * 1024 * 1024 * 0.90\ngae_support_methods = tuple([\"GET\", \"POST\", \"HEAD\", \"PUT\", \"DELETE\", \"PATCH\"])\n\n\ndef map_with_parameter(function, datas, args):\n    plist = []\n    for data in datas:\n        d_out = function(data, args)\n        plist.append(d_out)\n    return plist\n\n\ndef to_bytes(data, coding='utf-8'):\n    if isinstance(data, bytes):\n        return data\n    if isinstance(data, str):\n        return data.encode(coding)\n    if isinstance(data, dict):\n        return dict(map_with_parameter(to_bytes, data.items(), coding))\n    if isinstance(data, tuple):\n        return tuple(map_with_parameter(to_bytes, data, coding))\n    if isinstance(data, list):\n        return list(map_with_parameter(to_bytes, data, coding))\n    if isinstance(data, int):\n        return to_bytes(str(data))\n    if data is None:\n        return data\n    return bytes(data)\n\n\ndef to_str(data, coding='utf-8'):\n    if isinstance(data, str):\n        return data\n    if isinstance(data, bytes):\n        return data.decode(coding)\n    if isinstance(data, bytearray):\n        return data.decode(coding)\n    if isinstance(data, dict):\n        return dict(map_with_parameter(to_str, data.items(), coding))\n    if isinstance(data, tuple):\n        return tuple(map_with_parameter(to_str, data, coding))\n    if isinstance(data, list):\n        return list(map_with_parameter(to_str, data, coding))\n    if isinstance(data, int):\n        return str(data)\n    if data is None:\n        return data\n    return str(data)\n\n\ndef inflate(data):\n    return zlib.decompress(data, -zlib.MAX_WBITS)\n\n\ndef deflate(data):\n    return zlib.compress(data)[2:-4]\n\n\ndef unpack_request(payload):\n    head_len = struct.unpack('!h', payload[0:2])[0]\n    head = payload[2:2+head_len]\n    body = payload[2+head_len:]\n\n    head = inflate(head)\n    lines = head.split(b\"\\r\\n\")\n    method, url = lines[0].split()[:2]\n    headers = {}\n    kwargs = {}\n    for line in lines[1:]:\n        ls = line.split(b\": \")\n        k = ls[0]\n        if not k:\n            continue\n\n        v = b\"\".join(ls[1:])\n        if k.startswith(b\"X-URLFETCH-\"):\n            k = k[11:]\n            kwargs[k] = v\n        else:\n            headers[k] = v\n\n    if headers.get(b\"Content-Encoding\") == b\"deflate\":\n        body = inflate(body)\n        del headers[b\"Content-Encoding\"]\n\n    method = to_str(method)\n    url = to_str(url)\n    headers = to_str(headers)\n    kwargs = to_str(kwargs)\n    if method == \"GET\" and \"Content-Length\" in headers:\n        del headers[\"Content-Length\"]\n\n    return method, url, headers, body, kwargs\n\n\ndef pack_response(status, headers, app_msg, content):\n    if app_msg:\n        headers.pop('content-length', None)\n        headers['Content-Length'] = str(len(app_msg))\n\n    headers = to_bytes(headers)\n\n    data = b'HTTP/1.1 %d %s\\r\\n%s\\r\\n\\r\\n%s' % \\\n           (status,\n            to_bytes(httplib.responses.get(status, 'Unknown')),\n            b'\\r\\n'.join(b'%s: %s' % (k.title(), v) for k, v in headers.items()),\n            app_msg)\n\n    data = deflate(data)\n    head_len_pack = struct.pack('!h', len(data))\n    out = head_len_pack + data + to_bytes(content)\n    return out\n\n\nclass Pacific(tzinfo):\n    def utcoffset(self, dt):\n        return timedelta(hours=-8) + self.dst(dt)\n\n    def dst(self, dt):\n        # DST starts last Sunday in March\n        d = datetime(dt.year, 3, 12)   # ends last Sunday in October\n        self.dston = d - timedelta(days=d.weekday() + 1)\n        d = datetime(dt.year, 11, 6)\n        self.dstoff = d - timedelta(days=d.weekday() + 1)\n        if self.dston <=  dt.replace(tzinfo=None) < self.dstoff:\n            return timedelta(hours=1)\n        else:\n            return timedelta(0)\n\n    def tzname(self,dt):\n         return \"Pacific\"\n\n\ndef get_pacific_date():\n    tz = Pacific()\n    sa_time = datetime.now(tz)\n    return sa_time.strftime('%Y-%m-%d')\n\n\ndef get_store_info():\n    if not storage_client:\n        return {}\n\n    try:\n        blob = bucket.blob(blob_name)\n        content = blob.download_as_string()\n        info = json.loads(content)\n        return info\n    except Exception as e:\n        logging.exception(\"get_store_info e:%r\", e)\n        return {}\n\n\nstore_info = get_store_info()\nstore_save_time = time.time()\nstore_change_time = 0\ntraffic = 0\ntimer_th = None\n\n\ndef get_store(key, default_value=None):\n    global store_info\n    return store_info.get(key, default_value)\n\n\ndef set_store(key, value):\n    global store_info\n    store_info[key] = value\n\n\ndef save_store():\n    global store_info, store_save_time, traffic\n    if not storage_client:\n        return\n\n    store_info = get_store_info()\n\n    try:\n        store_info[\"traffic\"] = store_info.get(\"traffic\", 0) + traffic\n        traffic = 0\n        content = json.dumps(store_info)\n        blob = bucket.blob(blob_name)\n        blob.upload_from_string(content)\n\n        store_save_time = time.time()\n        logging.info(\"save_store:%s\", content)\n    except Exception as e:\n        logging.exception(\"save_store e:%r\", e)\n\n\ndef timer_worker():\n    global store_info, store_save_time, store_change_time, timer_th\n\n    time.sleep(60 * 14)\n    if store_change_time > store_save_time and time.time() - store_save_time > 60:\n        logging.info(\"timer save store\")\n        save_store()\n    timer_th = None\n\n\n@app.route(\"/reset_traffic\", methods=['GET'])\ndef reset_traffic():\n    global traffic\n    traffic = 0\n    set_store(\"traffic\", 0)\n    save_store()\n    return 'Traffic reset finished.'\n\n\ndef is_traffic_exceed():\n    global traffic\n    reset_date = get_store(\"reset_date\", None)\n\n    pacific_date = get_pacific_date()\n    if reset_date != pacific_date:\n        set_store(\"reset_date\", pacific_date)\n        traffic = 0\n        set_store(\"traffic\", 0)\n        save_store()\n        return False\n\n    traffic_sum = get_store(\"traffic\", 0) + traffic\n\n    if traffic_sum > allowed_traffic:\n        return True\n    else:\n        return False\n\n\ndef count_traffic(add_traffic):\n    global timer_th, traffic, store_change_time\n    traffic += add_traffic\n    store_change_time = time.time()\n\n    if not timer_th:\n        timer_th = threading.Thread(target=timer_worker)\n        timer_th.start()\n\n\n@app.route(\"/\")\ndef root():\n    out = \"GoAgent 服务端已经升级到 python3 版本。 <br>\\nVersion: 4.0.0\"\n    return out\n\n\n@app.route(\"/info\", methods=['GET'])\ndef info():\n    global store_info, traffic\n    save_store()\n\n    out_list = list()\n    out_list.append(f\"store: <pre>{json.dumps(store_info, indent=2)}</pre>\")\n\n    traffic_sum = int(store_info.get(\"traffic\", 0)) + traffic\n    out_list.append('Usage: %f %%\\r\\n' % (traffic_sum * 100 / allowed_traffic))\n\n    tz = Pacific()\n    sa_time = datetime.now(tz)\n    pacific_time = sa_time.strftime('%Y-%m-%d %H:%M:%S')\n    out_list.append(\"American Pacific time:%s\" % pacific_time)\n\n    out_list.append(f\"CPU num:{psutil.cpu_count()}\")\n    out_list.append(f\"CPU percent:{psutil.cpu_percent(interval=1)}\")\n    mem = psutil.virtual_memory()\n    out_list.append(f\"Mem total:{mem.total}\")\n    out_list.append(f\"Mem used:{mem.used}\")\n    out_list.append(f\"Mem available:{mem.available}\")\n    out_list.append(f\"Mem percent:{mem.percent}\")\n    net = psutil.net_io_counters()\n    out_list.append(f\"net sent:{net.bytes_sent}\")\n    out_list.append(f\"net recv:{net.bytes_recv}\")\n\n    env = json.dumps(dict(os.environ), indent=2)\n    out_list.append(f\"<br>env: <pre>{env}</pre>\")\n\n    return \"<br>\\r\\n\".join(out_list)\n\n\n@app.route(\"/_gh/\", methods=['GET'])\ndef check():\n    logging.debug(\"req headers:%s\", request.headers)\n    return \"GoAgent works\"\n\n\ndef req_by_requests(method, url, req_headers, req_body, kwargs):\n    timeout = int(kwargs.get('timeout', URLFETCH_TIMEOUT))\n    verify = bool(int(kwargs.get('validate', 0)))\n\n    errors = []\n    for i in range(int(kwargs.get('fetchmax', URLFETCH_MAX))):\n        try:\n            # t0 = time.time()\n            res = requests.request(method, url, headers=req_headers, data=req_body, timeout=timeout, verify=verify,\n                                   stream=True, allow_redirects=False)\n            # t1 = time.time()\n            # logging.info(f\"cost:{t1-t0} {method} {url} res:{res.status_code}\")\n            break\n        except Exception as e:\n            logging.warning(\"request %s %s %s %s %s e:%r\", method, url, req_headers, timeout, verify, e)\n            errors.append(str(e))\n            if i == 0 and method == 'GET':\n                timeout *= 2\n    else:\n        error_string = '<br />\\n'.join(errors)\n        logging.info('%s %s error:%s', method, url, error_string)\n        return 502, {}, \"502 Urlfetch Error: \" + error_string\n\n    res_code = res.status_code\n    res_headers = dict(res.headers)\n    content_length = int(res_headers.get(\"Content-Length\", 0))\n\n    maxsize = int(kwargs.get('maxsize', URLFETCH_DEFLATE_MAXSIZE))\n    if (method == \"GET\" and res_code == 200 and content_length and maxsize and content_length > maxsize and\n            \"Range\" not in req_headers and\n            res_headers.get('Accept-Ranges', '').lower() == 'bytes'):\n\n        res_code = 206\n        res_headers['Content-Range'] = 'bytes 0-%d/%d' % (maxsize - 1, content_length)\n        res_content = res.raw.read(maxsize)\n        logging.info(\"get %s data len:%d max:%d\", url, content_length, maxsize)\n    else:\n        res_content = res.raw.read()\n\n    if \"Transfer-Encoding\" in res_headers:\n        del res_headers[\"Transfer-Encoding\"]\n\n    res_headers[\"X-Head-Content-Length\"] = res_headers[\"Content-Length\"] = len(res_content)\n    return res_code, res_headers, res_content\n\n\ndef req_by_urlfetch(method, url, req_headers, req_body, kwargs):\n    timeout = int(kwargs.get('timeout', URLFETCH_TIMEOUT))\n    maxsize = int(kwargs.get('maxsize', URLFETCH_DEFLATE_MAXSIZE))\n    verify = bool(int(kwargs.get('validate', 0)))\n\n    errors = []\n    allow_truncated = False\n    for i in range(int(kwargs.get('fetchmax', URLFETCH_MAX))):\n        try:\n            t0 = time.time()\n\n            res = urlfetch.fetch(url, req_body, method, req_headers,\n                allow_truncated=allow_truncated,\n                follow_redirects=False,\n                deadline=timeout,\n                validate_certificate=False)\n            # res = requests.request(method, url, headers=req_headers, data=req_body, timeout=timeout, verify=verify,\n            #                        stream=True, allow_redirects=False)\n            t1 = time.time()\n            logging.info(f\"cost:{t1-t0} {method} {url} res:{res.status_code}\")\n            break\n\n        except apiproxy_errors.OverQuotaError as e:\n            logging.info('%s %s OverQuotaError:%r', method, url, e)\n            return 510, {}, \"510 Traffic exceed\"\n        except urlfetch.SSLCertificateError as e:\n            errors.append('%r, should validate=0 ?' % e)\n            logging.warning('%r, timeout=%s', e, timeout)\n\n            return 502, {}, \"502 SSLCertificateError\"\n        except urlfetch.DeadlineExceededError as e:\n            errors.append('%r, timeout=%s' % (e, timeout))\n            logging.warning('DeadlineExceededError(timeout=%s, url=%r)', timeout, url)\n            time.sleep(1)\n\n            allow_truncated = True\n            m = re.search(r'=\\s*(\\d+)-', req_headers.get('Range') or req_headers.get('range') or '')\n            if m is None:\n                req_headers['Range'] = 'bytes=0-%d' % (maxsize)\n            else:\n                req_headers.pop('Range', '')\n                req_headers.pop('range', '')\n                start = int(m.group(1))\n                req_headers['Range'] = 'bytes=%s-%d' % (start, start + maxsize)\n\n            timeout *= 2\n        except urlfetch.DownloadError as e:\n            errors.append('%r, timeout=%s' % (e, timeout))\n            logging.warning('DownloadError(timeout=%s, url=%r)', timeout, url)\n            time.sleep(1)\n            timeout *= 2\n        except urlfetch.ResponseTooLargeError as e:\n            errors.append('%r, timeout=%s' % (e, timeout))\n            response = e.response\n            logging.warning('ResponseTooLargeError(timeout=%s, url=%r) response(%r)',\n                timeout, url, response)\n\n            m = re.search(r'=\\s*(\\d+)-', req_headers.get('Range') or req_headers.get('range') or '')\n            if m is None:\n                req_headers['Range'] = 'bytes=0-%d' % (maxsize)\n            else:\n                req_headers.pop('Range', '')\n                req_headers.pop('range', '')\n                start = int(m.group(1))\n                req_headers['Range'] = 'bytes=%s-%d' % (start, start + (maxsize))\n            timeout *= 2\n        except Exception as e:\n            logging.warning(\"request %s %s %s %s %s e:%r\", method, url, req_headers, timeout, verify, e)\n            errors.append(str(e))\n            if i == 0 and method == 'GET':\n                timeout *= 2\n    else:\n        error_string = '<br />\\n'.join(errors)\n        logging.warning('%s %s error:%s', method, url, error_string)\n        return 502, {}, \"502 Urlfetch Error: \" + error_string\n\n    res_code = res.status_code\n    res_headers = dict(res.headers)\n    content_length = int(res_headers.get(\"Content-Length\", 0))\n\n    if (method == \"GET\" and res_code == 200 and content_length and maxsize and content_length > maxsize and\n            \"Range\" not in req_headers and res_headers.get('Accept-Ranges', '').lower() == 'bytes'):\n\n        res_code = 206\n        res_headers['Content-Range'] = 'bytes 0-%d/%d' % (maxsize - 1, content_length)\n        res_content = res.content[:maxsize]\n        logging.info(\"get %s data len:%d max:%d\", url, content_length, maxsize)\n    else:\n        res_content = res.content\n\n    if \"Transfer-Encoding\" in res_headers:\n        del res_headers[\"Transfer-Encoding\"]\n\n    res_headers[\"X-Head-Content-Length\"] = res_headers[\"Content-Length\"] = len(res_content)\n    return res_code, res_headers, res_content\n\n\n@app.route(\"/_gh/\", methods=['POST'])\ndef proxy():\n    if is_traffic_exceed():\n        logging.info('Traffic exceed')\n        return \"510 Traffic exceed\", 510\n\n    t0 = time.time()\n    try:\n        method, url, req_headers, req_body, kwargs = unpack_request(request.data)\n    except Exception as e:\n        logging.exception(\"unpack request:%r\", e)\n        return \"500 Bad Request\", 500\n\n    # logging.info('from:%s method:%s url:%s kwargs:%s -', request.remote_addr, method, url, kwargs)\n\n    # 参数使用\n    if __password__ != kwargs.get('password', ''):\n        logging.info('wrong password')\n        return \"401 Wrong password\", 401\n\n    netloc = urlparse(url).netloc\n    if netloc.startswith(('127.0.0.', '::1', 'localhost')):\n        return \"GoAgent is Running\", 400\n\n    if len(url) > MAX_URL_LENGTH or method not in gae_support_methods:\n        res_code, res_headers, res_body = req_by_requests(method, url, req_headers, req_body, kwargs)\n    else:\n        res_code, res_headers, res_body = req_by_urlfetch(method, url, req_headers, req_body, kwargs)\n\n    res_data = pack_response(res_code, res_headers, b\"\", res_body)\n    t1 = time.time()\n    cost = t1 - t0\n\n    logging.info(\"cost:%f %s %s res_len:%d\", cost, method, url, len(res_body))\n\n    count_traffic(len(request.data) + len(res_data))\n\n    resp = flask.Response(res_data)\n    resp.headers['Content-Type'] = 'image/gif'\n    return resp\n\n\nif __name__ == \"__main__\":\n    # This is used when running locally only. When deploying to Google App\n    # Engine, a webserver process such as Gunicorn will serve the app.\n    app.run(host=\"127.0.0.1\", port=8080, debug=True)\n"
  },
  {
    "path": "code/default/gae_proxy/server/gae/requirements.txt",
    "content": "Flask==3.0.0\nrequests\ngunicorn\ngoogle-cloud-storage\nappengine-python-standard\npsutil"
  },
  {
    "path": "code/default/gae_proxy/tests/test_protocol.py",
    "content": "from unittest import TestCase\nimport os\nimport sys\nfrom os.path import join\nimport http.client as httplib\nimport json\nimport struct\nimport zlib\nimport traceback\nimport requests\nimport logging\nlogging.basicConfig(format='%(asctime)s - %(message)s', level=logging.DEBUG)\n\nlogger = logging.getLogger('simple_example')\nlogger.setLevel(logging.DEBUG)\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\ngae_path = os.path.abspath( os.path.join(current_path, os.pardir))\ndefault_path = os.path.abspath( os.path.join(gae_path, os.pardir))\n# local_path = join(gae_path, \"local\")\n# sys.path.append(local_path)\nsys.path.append(join(default_path, \"lib\", \"noarch\"))\nimport utils\nimport xlog\n\n\nskip_request_headers = frozenset([\n                          b'Vary',\n                          b'Via',\n                          b'Proxy-Authorization',\n                          b'Proxy-Connection',\n                          b'Upgrade',\n                          b'X-Google-Cache-Control',\n                          b'X-Forwarded-For',\n                          b'X-Chrome-Variations',\n                          ])\nskip_response_headers = frozenset([\n                          # http://en.wikipedia.org/wiki/Chunked_transfer_encoding\n                          b'Connection',\n                          b'Upgrade',\n                          b'Alt-Svc',\n                          b'Alternate-Protocol',\n                          b'X-Head-Content-Length',\n                          b'X-Google-Cache-Control',\n                          b'X-Chrome-Variations',\n                          ])\n\n\ndef inflate(data):\n    return zlib.decompress(data, -zlib.MAX_WBITS)\n\n\ndef deflate(data):\n    return zlib.compress(data)[2:-4]\n\nclass Conf(object):\n    GAE_PASSWORD = \"\"\n    GAE_VALIDATE = 0\n    JS_MAXSIZE = 10000\n    AUTORANGE_MAXSIZE = 256000\n\n\nconfig = Conf()\n\n\ndef pack_request(method, url, headers, body, kwargs):\n    method = utils.to_bytes(method)\n    url = utils.to_bytes(url)\n    headers = utils.to_bytes(headers)\n    body = utils.to_bytes(body)\n    kwargs = utils.to_bytes(kwargs)\n    if body:\n        if len(body) < 10 * 1024 * 1024 and b'Content-Encoding' not in headers:\n            # 可以压缩\n            zbody = deflate(body)\n            if len(zbody) < len(body):\n                body = zbody\n                headers[b'Content-Encoding'] = b'deflate'\n        if len(body) > 10 * 1024 * 1024:\n            xlog.warn(\"body len:%d %s %s\", len(body), utils.to_bytes(method), utils.to_bytes(url))\n        headers[b'Content-Length'] = utils.to_bytes(str(len(body)))\n\n    # GAE don't allow set `Host` header\n    if b'Host' in headers:\n        del headers[b'Host']\n\n    # gae 用的参数\n    if config.GAE_PASSWORD:\n        kwargs[b'password'] = config.GAE_PASSWORD\n\n    # kwargs['options'] =\n    kwargs[b'validate'] = config.GAE_VALIDATE\n    if url.endswith(b\".js\"):\n        kwargs[b'maxsize'] = config.JS_MAXSIZE\n    else:\n        kwargs[b'maxsize'] = config.AUTORANGE_MAXSIZE\n    # gae 用的参数　ｅｎｄ\n\n    payload = b'%s %s HTTP/1.1\\r\\n' % (method, url)\n    payload += b''.join(b'%s: %s\\r\\n' % (k, v)\n                       for k, v in list(headers.items()) if k not in skip_request_headers)\n    # for k, v in headers.items():\n    #    xlog.debug(\"Send %s: %s\", k, v)\n    for k, v in kwargs.items():\n        if isinstance(v, int):\n            payload += b'X-URLFETCH-%s: %d\\r\\n' % (k, v)\n        else:\n            payload += b'X-URLFETCH-%s: %s\\r\\n' % (k, utils.to_bytes(v))\n\n    payload = deflate(payload)\n\n    body = b'%s%s%s' % (struct.pack('!h', len(payload)), payload, body)\n    request_headers = {}\n    request_headers[b'Content-Length'] = str(len(body))\n    # request_headers 只有上面一项\n\n    return request_headers, body\n\n\ndef unpack_request(payload):\n    head_len = struct.unpack('!h', payload[0:2])[0]\n    print(head_len)\n    head = payload[2:2+head_len]\n    body = payload[2+head_len:]\n\n    head = inflate(head)\n    lines = head.split(b\"\\r\\n\")\n    method, url = lines[0].split()[:2]\n    headers = {}\n    kwargs = {}\n    for line in lines[1:]:\n        ls = line.split(b\": \")\n        k = ls[0]\n        if not k:\n            continue\n\n        v = b\"\".join(ls[1:])\n        if k.startswith(b\"X-URLFETCH-\"):\n            k = k[11:]\n            kwargs[k] = v\n        else:\n            headers[k] = v\n\n    timeout = int(kwargs.get(b\"timeout\", 30))\n    if headers.get(b\"Content-Encoding\") == b\"deflate\":\n        body = inflate(body)\n        del headers[b\"Content-Encoding\"]\n\n    return method, url, headers, body, timeout, kwargs\n\n\ndef pack_response(status, headers, app_msg, content):\n    if app_msg:\n        headers.pop('content-length', None)\n        headers['Content-Length'] = str(len(app_msg))\n\n    headers = utils.to_bytes(headers)\n\n    data = b'HTTP/1.1 %d %s\\r\\n%s\\r\\n\\r\\n%s' % \\\n           (status,\n            utils.to_bytes(httplib.responses.get(status, 'Unknown')),\n            b'\\r\\n'.join(b'%s: %s' % (k.title(), v) for k, v in headers.items()),\n            app_msg)\n    data = deflate(data)\n    return struct.pack('!h', len(data)) + data + content\n\n\ndef unpack_response(body):\n    try:\n        data = body[:2]\n        if not data:\n            raise Exception(600, \"get protocol head fail\")\n\n        if len(data) !=2:\n            raise Exception(600, \"get protocol head fail, data:%s, len:%d\" % (data, len(data)))\n\n        headers_length, = struct.unpack('!h', data)\n        data = body[2:2+headers_length]\n        if not data:\n            raise Exception(600,\n                \"get protocol head fail, len:%d\" % headers_length)\n\n        raw_response_line, headers_data = inflate(data).split(b'\\r\\n', 1)\n        rl = raw_response_line.split()\n        status_code = int(rl[1])\n        if len(rl) >=3:\n            reason = rl[2].strip()\n        else:\n            reason = b\"\"\n\n        headers_block, app_msg = headers_data.split(b'\\r\\n\\r\\n', 1)\n        headers_pairs = headers_block.split(b'\\r\\n')\n        headers = {}\n        for pair in headers_pairs:\n            if not pair:\n                break\n            k, v = pair.split(b': ', 1)\n            headers[k] = v\n\n        content = body[2+headers_length:]\n        return status_code, reason, headers, app_msg, content\n    except Exception as e:\n        raise Exception(600, \"unpack protocol:%r at:%s\" % (e, traceback.format_exc()))\n\n\nclass TestProtocol(TestCase):\n    def test_req(self):\n        method = b\"POST\"\n        url = b\"https://cloud.google.com/\"\n        info = {\n            \"req\": \"a\",\n            \"type\": \"b\"\n        }\n        body = utils.to_bytes(json.dumps(info))\n        headers = {\n            \"Content-Length\": str(len(body)),\n            \"Content-Type\": \"application/json\"\n        }\n        headers = utils.to_bytes(headers)\n        timeout = 30\n\n        request_headers, payload = pack_request(method, url, headers, body, timeout)\n\n        method1, url1, headers1, body1, timeout1, kwargs = unpack_request(payload)\n        print(f\"method:{method1}\")\n        print(f\"url1:{url1}\")\n        print(f\"headers1:{headers1}\")\n        print(f\"body1:{body1}\")\n        print(f\"timeout1:{timeout1}\")\n        print(f\"kwargs:{kwargs}\")\n\n    def test_response(self):\n        status = 200\n        headers = {\n            b\"Cookie\": b\"abc\"\n        }\n        content = b\"ABC\"\n        payload = pack_response(status, headers, b\"\", content)\n\n        status_code, reason, res_headers, app_msg, body = unpack_response(payload)\n        self.assertEqual(status, status_code)\n        # self.assertEqual(headers, res_headers)\n        self.assertEqual(content, body)\n        print(f\"status:{status_code}\")\n        print(f\"reason:{reason}\")\n        logging.debug(f\"res_headers:{res_headers}\")\n        logger.debug(f\"body:{body}\")\n\n    def test_pack_real_response(self):\n        res = requests.get(\"https://github.com\")\n        status = res.status_code\n        headers = dict(res.headers)\n        content = res.content\n        payload = pack_response(status, headers, b\"\", content)\n\n        status_code, reason, res_headers, app_msg, body = unpack_response(payload)\n        self.assertEqual(status, status_code)\n        # self.assertEqual(headers, res_headers)\n        self.assertEqual(content, body)\n        print(f\"status:{status_code}\")\n        print(f\"reason:{reason}\")\n        print(f\"res_headers:{res_headers}\")\n        logging.debug(f\"body:{body}\")\n\n    def test_req_local(self, url=\"http://speedtest.ftp.otenet.gr/files/test10Mb.db\"):\n        method = \"GET\"\n        body = \"\"\n        headers = {\n            # \"Content-Length\": str(len(body)),\n            # \"Content-Type\": \"application/json\"\n            \"Accept-Encoding\": \"gzip, br\"\n        }\n        kwargs = {\n            \"timeout\": \"30\"\n        }\n\n        request_headers, payload = pack_request(method, url, headers, body, kwargs)\n\n        res = requests.post(\"http://localhost:8080/_gh/\", data=payload)\n\n        status_code, reason, res_headers, app_msg, body = unpack_response(res.content)\n        logging.debug(f\"status:{status_code}\")\n        logging.debug(f\"reason:{reason}\")\n        res_headers = utils.to_str(res_headers)\n        logging.debug(f\"res_headers:{json.dumps(res_headers, indent=2)}\")\n        logging.debug(f\"body_len:{len(body)}\")\n        logging.debug(f\"body_100:{body[:100]}\")\n\n    def test_local_req(self):\n        url = \"http://github.com\"\n        self.test_req_local(url)"
  },
  {
    "path": "code/default/gae_proxy/web_ui/advanced.html",
    "content": "<ul class=\"nav nav-tabs\">\n    <li><a class=\"advanced_tab\" id=\"scan_setting\" data-toggle=\"tab\">{{ _( \"Scan Settings\" ) }}</a></li>\n    <li><a class=\"advanced_tab\" id=\"import_ip\" data-toggle=\"tab\">{{ _( \"Import IP\" ) }}</a></li>\n    <li><a class=\"advanced_tab\" id=\"export_ip\" data-toggle=\"tab\">{{ _( \"Export IP\" ) }}</a></li>\n    <li><a class=\"advanced_tab\" id=\"check_ip\" data-toggle=\"tab\">{{ _( \"Check IP\" ) }}</a></li>\n    <li><a class=\"advanced_tab\" id=\"ipv6_tunnel\" data-toggle=\"tab\">{{ _( \"IPv6 Tunnel\" ) }}</a></li>\n    <li><a class=\"advanced_tab\" id=\"global_setting\" data-toggle=\"tab\">{{ _( \"Global Settings\" ) }}</a></li>\n</ul>\n<div id=\"advanced_content\" class=\"tab-content\">\n    <div id=\"tab_content\" class=\"tab-pane fade in active\">\n    </div>\n</div>\n<script type=\"text/javascript\">\n    title('{{ _(\"GAEProxy Advanced Configuration\") }}');\n</script>\n<script type=\"text/javascript\">\n    $(\".advanced_tab\").click(function () {\n        var id = $(this).attr('id');\n        var url = \"/module/gae_proxy/\" + id + \".html\";\n        $(\"#tab_content\").load(url);\n        location.hash = \"#\" + id;\n    });\n    if (location.hash == \"\") {\n        var id = \"scan_setting\";\n    } else {\n        var id = location.hash.substr(1);\n    }\n    location.hash = \"#\" + id;\n    $(location.hash).parent().addClass(\"active\");\n    var url = \"/module/gae_proxy/\" + id + \".html\";\n    $(\"#tab_content\").load(url);\n</script>\n"
  },
  {
    "path": "code/default/gae_proxy/web_ui/check_ip.html",
    "content": "<!--[if lte IE 9]>\n<div class=\"alert alert-warning\">\n    {{ _( \"Your browser is obsolete. Partial functionality will not be available.\" ) }}<br>\n    {{ _( \"The latest Chrome browser is recommended.\" ) }}\n</div>\n<![endif]-->\n<h4>{{ _( \"Status\" ) }}</h4>\n<table id=\"status\" class=\"table table-bordered table-striped\">\n    <thead>\n        <tr>\n            <th width=\"25%\">{{ _( \"Property\" ) }}</th>\n            <th>{{ _( \"Value\" ) }}</th>\n        </tr>\n    </thead>\n    <tbody>\n        <tr>\n            <td>{{ _( \"All IP Number\" ) }}</td>\n            <td id=\"all-ip-num\"></td>\n        </tr>\n        <tr>\n            <td>{{ _( \"Left Number\" ) }}</td>\n            <td id=\"left-num\"></td>\n        </tr>\n        <tr>\n            <td>{{ _( \"Good IP Number\" ) }}</td>\n            <td id=\"good-num\"></td>\n        </tr>\n    </tbody>\n</table>\n<div class=\"row-fluid\">\n    <div class=\"span12\">\n        <button class=\"btn btn-primary btn-block\" id=\"check_start\" type=\"submit\">{{ _( \"Run\" ) }}</button>\n    </div> <!-- .span12 -->\n</div> <!-- .row-fluid -->\n\n<script type=\"text/javascript\">\n    function updateStatus(selector, content) {\n        var previousContent = $(selector).html();\n        if (String(previousContent) !== String(content)) {\n            $(selector).html(content);\n        }\n    }\n\n    function updateProcess() {\n        $.ajax({\n            type: 'GET',\n            url: '/module/gae_proxy/control/check_ip?cmd=get_process',\n            dataType: 'JSON',\n            success: function (result) {\n                var updates = {\n                    '#all-ip-num': result['all_ip_num'],\n                    '#left-num': result['left_num'],\n                    '#good-num': result['good_num']\n                };\n                for (var item in updates) {\n                    updateStatus(item, updates[item]);\n                }\n\n                if (result['left_num'] === 0) {\n                    enableStartButton();\n                } else {\n                    disableStartButton();\n                }\n\n                if (!tipHasClose()) {\n                    tipClose();\n                }\n            },\n            error: function (result) {\n                tip('{{ _(\"No response from process: \")}}{{ _(\"GAEProxy\")}}{{ _(\". It might have already exited.\")}}', 'warning', false);\n            }\n        });\n    }\n    function enableStartButton() {\n        if ($('#check_start').hasClass(\"btn-inverse\")) {\n            $('#check_start').removeClass('btn-inverse');\n            $('#check_start').addClass('btn-primary');\n            $('#check_start').html('{{ _( \"Run\" ) }}');\n        }\n    }\n    function disableStartButton() {\n        if ($('#check_start').hasClass(\"btn-primary\")) {\n            $('#check_start').removeClass('btn-primary');\n            $('#check_start').addClass('btn-inverse');\n            $('#check_start').html('{{ _( \"Stop\" ) }}');\n        }\n    }\n</script>\n\n<script type=\"text/javascript\">\n    $('button.btn').click(function () {\n        if ($('#check_start').html() == '{{ _( \"Run\" ) }}') {\n            $.ajax({\n                type: 'GET',\n                url: '/module/gae_proxy/control/check_ip?cmd=start',\n                dataType: 'JSON',\n                success: function (result) {\n                    window.timer.play();\n\n                    disableStartButton();\n\n                    if (!tipHasClose()) {\n                        tipClose();\n                    }\n                },\n                error: function (result) {\n                    tip('{{ _(\"No response from process: \")}}{{ _(\"GAEProxy\")}}{{ _(\". It might have already exited.\")}}', 'warning', false);\n                }\n            });\n        } else {\n            $.ajax({\n                type: 'GET',\n                url: '/module/gae_proxy/control/check_ip?cmd=stop',\n                dataType: 'JSON',\n                success: function (result) {\n                    if (!tipHasClose()) {\n                        tipClose();\n                    }\n                },\n                error: function (result) {\n                    tip('{{ _(\"No response from process: \")}}{{ _(\"GAEProxy\")}}{{ _(\". It might have already exited.\")}}', 'warning', false);\n                }\n            });\n        }\n    });\n</script>\n\n<script type=\"text/javascript\">\n    $(function () {\n        window.timer = $.timer(function () {\n            updateProcess();\n        });\n\n        window.timer.set({\n            time: 1000,\n            autostart: true\n        });\n\n        updateProcess();\n    });\n</script>"
  },
  {
    "path": "code/default/gae_proxy/web_ui/config.html",
    "content": "<form id=\"gae_proxy-config\" method=\"POST\" onSubmit=\"onSubmit(); return false;\">\n    <div class=\"row-fluid\">\n        <div class=\"span2\">\n            <label for=\"gae-appid\">GAE AppID </label>\n        </div> <!-- .span2 -->\n        <div id=\"gae-appid-field\" class=\"span10\">\n            <input id=\"gae-appid\" type=\"text\" placeholder='{{ _( \"Public AppIDs used by default\" ) }}'/>\n            <div id=\"public-appid-tip\" class=\"hide\">\n                <p>\n                    <span color=\"red\">{{ _( \"The public AppIDs are disabled to access videos or download files.\" ) }}</span>\n                    <a href=\"https://github.com/XX-net/XX-Net/wiki/Register-Google-appid\" target=\"_blank\">({{ _( \"How to apply\" ) }})</a>\n                </p>\n            </div>\n            <div id=\"gae-appid-tip\" class=\"hide\">\n                <p>\n                    <span>{{ _( \"Attention: inaccessable before AppIDs are deployed.\" ) }}</span>\n                </p>\n            </div>\n        </div> <!-- .span10 -->\n    </div> <!-- .row-fluid -->\n    <div class=\"row-fluid\">\n        <div class=\"span12\">\n            <button class=\"btn btn-primary btn-block\" type=\"submit\">{{ _( \"Save\" ) }}</button>\n        </div> <!-- .span12 -->\n    </div> <!-- .row-fluid -->\n</form> <!-- #gae_proxy-config -->\n<div class=\"row-fluid\">\n    <div class=\"span12\">\n        {{ _( \"Advanced tricks:\" ) }} <a href=\"https://github.com/XX-net/XX-Net/wiki/GoAgent-manual-config\" target=\"_blank\">{{ _( \"By the configuration file\" ) }}</a>\n    </div> <!-- .span4 -->\n</div> <!-- .row-fluid -->\n\n<!-- JavaScript -->\n<script type=\"text/javascript\">\n    title('{{ _( \"GAEProxy Configuration\" ) }}');\n</script>\n<script type=\"text/javascript\">\n    $('#gae-appid-field').click(function () {\n        $('#gae-appid-tip').removeClass('hide');\n    });\n    $('#gae-appid-field').click(function (event) {\n        event.stopPropagation();\n    });\n    $('html').click(function () {\n        $('#gae-appid-tip').addClass('hide');\n    });\n</script>\n<script type=\"text/javascript\">\n    $(function () {\n        $.ajax({\n            type: 'POST',\n            url: '/module/gae_proxy/control/config?cmd=get_config',\n            dataType: 'JSON',\n            success: function (result) {\n                $('#gae-appid').val(result['appid']);\n                if (!result['appid'] || result['appid'] == '') {\n                    $('#public-appid-tip').removeClass(\"hide\");\n                }\n            },\n            error: function () {\n                tip('{{ _( \"Failed reading the settings.\" ) }}', 'error');\n            }\n        });\n    });\n</script>\n<script type=\"text/javascript\">\n    function onSubmit() {\n        var gaeAppId          = $('#gae-appid').val();\n\n        tip('{{ _( \"Checking settings ...\" ) }}', 'info');\n\n        return setAppID(gaeAppId);\n    }\n</script>\n<script type=\"text/javascript\">\n    function setAppID(gaeAppId) {\n        var config = {\n            'appid': gaeAppId\n        };\n        $.ajax({\n            type: 'POST',\n            url: '/module/gae_proxy/control/config?cmd=set_config',\n            data: config,\n            dataType: 'JSON',\n            success: function (result) {\n                if (result['res'] == 'success') {\n                    tip('{{ _( \"Settings saved successfully.\" ) }}', 'success');\n                } else {\n                    if (result['reason'].indexOf(\"appid fail\") > -1) {\n                        tip('{{ _( \"AppID invalid:\" ) }}' + result['reason'].substring(11) + '{{ _( \", deploy AppID before using.\" ) }}', 'error');\n                    } else {\n                        tip('{{ _( \"Failed saving settings: \" ) }}' + result['reason'], 'error');\n                    }\n                }\n            },\n            error: function () {\n                tip('{{ _( \"Failed saving settings.\" ) }}', 'error');\n            }\n        });\n    }\n</script>\n"
  },
  {
    "path": "code/default/gae_proxy/web_ui/deploy.html",
    "content": "<h2>{{ _( \"Deploy XX-Net onto GAE\" ) }}</h2>\n<div class=\"alert alert-info fade in\">\n    <p class=\"message\">{{ _( \"Current status: \" ) }}{{ _( \"idle\" ) }}</p>\n</div> <!-- .alert -->\n<ul class=\"nav nav-tabs\">\n    <li class=\"active\"><a href=\"#authentication\" data-toggle=\"tab\">{{ _( \"Authorization\" ) }}</a></li>\n    <li><a href=\"#logs\" data-toggle=\"tab\">{{ _( \"Log\" ) }}</a></li>\n</ul>\n<div id=\"deploy\" class=\"tab-content\">\n    <div id=\"authentication\" class=\"tab-pane fade in active\">\n        <form method=\"POST\" onSubmit=\"return false;\">\n            <div class=\"row-fluid\">\n                <div class=\"span4\">\n                    <label for=\"gae-appid\">GAE AppID (<a href=\"https://github.com/XX-net/XX-Net/wiki/how-to-create-my-appids\" target=\"_blank\">{{ _( \"How to apply\" ) }}</a>)</label>\n                </div> <!-- .span4 -->\n                <div class=\"span8\">\n                    <input id=\"gae-appid\" type=\"text\" placeholder='{{ _(\"Delimit multiple AppIDs with |\") }}'/>\n                </div> <!-- .span8 -->\n            </div> <!-- .row-fluid -->\n            <div class=\"row-fluid\">\n                <div class=\"span4\">\n                    <label for=\"show-debug-log\">{{ _( \"Show Debug Log\" ) }}</label>\n                </div> <!-- .span4 -->\n                <div class=\"span8\">\n                    <input id=\"show-debug-log\" type=\"checkbox\" data-toggle=\"switch\"/>\n                </div> <!-- .span8 -->\n            </div> <!-- .row-fluid -->\n            <div class=\"row-fluid\">\n                <div class=\"span12\">\n                    <button class=\"btn btn-primary btn-block\" type=\"submit\">{{ _(\"Start to deploy\") }}</button>\n                </div> <!-- .span12 -->\n            </div> <!-- .row-fluid -->\n        </form>\n        <p class=\"tip\">* {{ _( \"Auth window will popup, make sure don't block popup in browser.\" ) }}</p>\n    </div> <!-- #authentication -->\n    <div id=\"logs\" class=\"tab-pane fade\">\n        <div id=\"log\" class=\"span12\"></div>\n    </div> <!-- #log -->\n</div> <!-- #tab-content -->\n\n<!-- JavaScript -->\n<script type=\"text/javascript\">\n    $(function () {\n        $('[data-toggle=switch]').wrap('<div class=\"switch\" />').parent().bootstrapSwitch();\n    });\n\n    $('#show-debug-log').parent().removeClass('switch-off');\n</script>\n<script type=\"text/javascript\">\n    $(function () {\n        window.status = 'init';\n        window.isAutoScrollLog = true;\n\n        window.timer = $.timer(function () {\n            getDeployStatus();\n        });\n\n        window.timer.set({\n            time: 1000,\n            autostart: true\n        });\n    });\n</script>\n<script type=\"text/javascript\">\n    $('#log').scroll(function () {\n        var preservedHeight = $('#log').height() + 10,\n            scrollHeight    = $('#log')[0].scrollHeight,\n            scrollTop       = $('#log').scrollTop();\n\n        window.isAutoScrollLog = (scrollTop + preservedHeight === scrollHeight);\n    });\n</script>\n<script type=\"text/javascript\">\n    $(function () {\n        resizeLogWindow();\n    });\n\n    $(window).resize(function () {\n        resizeLogWindow();\n    });\n\n    function resizeLogWindow() {\n        var windowHeight = $(window).height(),\n            preservedHeight = 300;\n\n        $('#log').css('height', windowHeight - preservedHeight);\n    }\n</script>\n<script type=\"text/javascript\">\n    function updateLog(logContent) {\n        $('#log').html(logContent.replace(/\\n/g, '<br>'));\n    }\n\n    function getDeployStatus() {\n        $.ajax({\n            type: 'GET',\n            url: '/module/gae_proxy/control/deploy?cmd=get_log',\n            dataType: 'JSON',\n            success: function (result) {\n                if (window.status == 'running') {\n                    if (result['status'] == 'init') {\n                        window.timer.stop();\n                        $('.alert').html('{{ _(\"Current status: \") }}{{ _(\"XX-Net was reset.\") }}');\n\n                        changeButtonStatus('start');\n                    } else if (result['status'] == 'running') {\n                        updateLog(result['log']);\n                    } else if (result['status'] == 'finished') {\n                        window.timer.stop();\n                        window.status = 'finished';\n                        $('.alert').html('{{ _(\"Current status: \") }}{{ _(\"Deployment completed.\") }} <br>{{ _(\"Please go to \") }}<a href=\"/?module=gae_proxy&menu=config\">{{ _(\"the configuration page \") }}</a>{{ _(\"to set AppID to enable them.\") }}');\n\n                        updateLog(result['log']);\n                        changeButtonStatus('start');\n                    } else {\n                        window.timer.stop();\n                        $('.alert').html('{{ _(\"Current status: \") }}{{ _(\"An exception occurred.\") }}<br>{{ _(\"The exception info: \") }}' + result['status']);\n\n                        updateLog(result['log']);\n                    }\n                } else { // window.status == 'init' || window.status == 'finished' || undefined\n                    if (result['status'] == 'init') {\n                        window.timer.stop();\n                        $('.alert').html('{{ _(\"Current status: \") }}{{ _(\"idle\") }}');\n                    } else if (result['status'] == 'running') {\n                        window.status = 'running';\n                        $('.alert').html('{{ _(\"Current status: \") }}{{ _(\"deploying ...\") }}');\n\n                        updateLog(result['log']);\n                        changeButtonStatus('cancel');\n                    } else if (result['status'] == 'finished') {\n                        window.timer.stop();\n                        window.status = 'finished';\n                        $('.alert').html('{{ _(\"Current status: \") }}{{ _(\"Deployment completed.\") }}');\n\n                        updateLog(result['log']);\n                    } else {\n                        window.timer.stop();\n                        $('.alert').html('{{ _(\"Current status: \") }}{{ _(\"An exception occurred.\") }}<br>{{ _(\"The exception info: \") }}' + result['status']);\n                        updateLog(result['log']);\n                    }\n                }\n                if (window.isAutoScrollLog == true) {\n                    $('#log').scrollTop($('#log')[0].scrollHeight);\n                }\n            }\n        });\n    }\n</script>\n<script type=\"text/javascript\">\n    function changeButtonStatus(status) {\n        if (status == 'start') {\n            $('button.btn').removeClass('btn-danger');\n            $('button.btn').addClass('btn-primary');\n            $('button.btn').html('{{ _(\"Start to deploy\") }}');\n        } else if (status == 'cancel') {\n            $('button.btn').removeClass('btn-primary');\n            $('button.btn').addClass('btn-danger');\n            $('button.btn').html('{{ _(\"Terminate deploying\") }}');\n        }\n    }\n</script>\n<script type=\"text/javascript\">\n    $('button.btn').click(function () {\n        if ($('button.btn').html() == '{{ _(\"Start to deploy\") }}') {\n            onStart();\n        } else if ($('button.btn').html() == '{{ _(\"Terminate deploying\") }}') {\n            onCancel();\n        }\n    });\n</script>\n<script type=\"text/javascript\">\n    function onStart() {\n        var appId        = $('#gae-appid').val();\n        var debug        = $('#show-debug-log').is(':checked') ? 1 : 0;\n        var errorMessage = getErrorMessage(appId);\n\n        if (errorMessage.length != 0) {\n            $('.alert').removeClass('alert-info');\n            $('.alert').addClass('alert-error');\n            $('.alert').html(errorMessage);\n            return;\n        } else {\n            $('.alert').removeClass('alert-error');\n            $('.alert').addClass('alert-info');\n        }\n\n        deployProcess(appId, debug);\n        changeButtonStatus('cancel');\n    }\n</script>\n<script type=\"text/javascript\">\n    function onCancel() {\n        $.ajax({\n            type: 'POST',\n            url: '/module/gae_proxy/control/deploy?cmd=cancel',\n            dataType: 'JSON',\n            success: function (result) {\n                changeButtonStatus('start');\n                $('.alert').html('{{ _(\"Current status: \") }}{{ _(\"Deployment cancelled.\") }}');\n            },\n            error: function (result) {\n                $('.alert').html('{{ _(\"Current status: \") }} {{ _(\"An exception occurred.\") }}<br>{{ _(\"The exception info: \") }}' + result);\n            }\n        });\n    }\n</script>\n<script type=\"text/javascript\">\n    function getErrorMessage(appId) {\n        var errorMessage = '';\n\n        if (appId.length == 0 || !isAppIdValid(appId)) {\n            errorMessage += '{{ _(\"Your AppID is either empty or invalid.\") }}<br>';\n        }\n\n        return errorMessage;\n    }\n</script>\n<script type=\"text/javascript\">\n    function deployProcess(appId, debug) {\n        var authentication = {\n            'appid': appId,\n            'debug': debug\n        };\n\n        $.ajax({\n            type: 'POST',\n            url: '/module/gae_proxy/control/deploy?cmd=deploy',\n            data: authentication,\n            dataType: 'JSON',\n            success: function (result) {\n                window.timer.play();\n                $('.nav-tabs a:last').tab('show');\n            }\n        });\n    }\n</script>\n<script type=\"text/javascript\">\n    function isAppIdValid(appId) {\n        var pattern = new RegExp(/^[0-9a-z\\-|]+$/i);\n        return pattern.test(appId);\n    }\n</script>\n"
  },
  {
    "path": "code/default/gae_proxy/web_ui/export_ip.html",
    "content": "<form method=\"POST\" onSubmit=\"onSubmit(); return false;\">\n    <div class=\"row-fluid\">\n        <div class=\"span2\">\n            <label for=\"ip-format\">{{ _( \"Export format\" ) }}</label>\n        </div> <!-- .span2 -->\n        <div class=\"span10\">\n            <select id=\"ip-format\">\n                <option value=\"1\" selected>{{ _( \"IP|IP|IP (GoGo Tester/GoAgent format)\" ) }}</option>\n                <option value=\"2\">{{ _( \"New line delimiter\" ) }}</option>\n            </select>\n        </div> <!-- .span10 -->\n    </div> <!-- .row-fluid -->\n    <div class=\"row-fluid\">\n        <div class=\"span2\">\n            <label for=\"ip-list\">{{ _( \"IP address list\" ) }}</label>\n        </div> <!-- .span2 -->\n        <div class=\"span10\">\n            <textarea id=\"ip-list\" rows=\"10\"></textarea>\n        </div> <!-- .span10 -->\n    </div> <!-- .row-fluid -->\n    <div class=\"row-fluid\">\n        <div class=\"span12\">\n            <button class=\"btn btn-primary btn-block\" type=\"submit\">{{ _( \"Run\" ) }}</button>\n        </div> <!-- .span12 -->\n    </div> <!-- .row-fluid -->\n</form> <!-- #import-export-ip -->\n\n<script type=\"text/javascript\">\n    function doExportAction(ipFormat) {\n        $.ajax({\n            type: 'POST',\n            url: '/module/gae_proxy/control/importip?cmd=exportip',\n            dataType: 'JSON',\n            success: function (result) {\n                var ipList = result['res'];\n                tip('{{ _(\"Succeeded exporting \") }}' + ipList.split('|').length + '{{ _(\" IP addresses.\") }}', 'success');\n                ipList = conversionFormat('1', ipFormat, ipList);\n                $('#ip-list').val(ipList);\n            },\n            error: function () {\n                tip('{{ _(\"Failed exporting the IP addresses.\") }}', 'error');\n            }\n        });\n    }\n</script>\n<script type=\"text/javascript\">\n    function conversionFormat(originalFormat, targetFormat, sourceData) {\n        if (originalFormat === targetFormat) {\n            return sourceData;\n        }\n\n        var ipList;\n        switch (originalFormat) { //由源数据转换为中间格式\n            case '1': //IP|IP|IP\n                ipList = sourceData.split(\"|\");\n                break;\n            case '2': //换行分割\n                ipList = sourceData.split(\"\\n\");\n                break;\n            case '3': //智能正则匹配\n                var tmp = ' ' + sourceData;\n                var regex = /(?!\\d)[^\\d](([1-9]?\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.([1-9]?\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}(?!\\d))/gm;\n                var regexResult;\n                ipList = [];\n                while (true) {\n                    regexResult = regex.exec(tmp);\n                    if (regexResult === null) break;\n                    ipList.push(regexResult[1]);\n                }\n                break;\n        }\n\n        var result;\n        switch (targetFormat) { // convert from the interim format to the destination format由中间格式转换为目标格式\n            case '1': //IP|IP|IP\n                result = '';\n                for (var id in ipList) {\n                    result += ipList[id] + '|';\n                }\n                result = result.substr(0, result.length - 1);\n                break;\n            case '2': //New line delimiter换行分割\n                result = '';\n                for (var id in ipList) {\n                    result += ipList[id] + '\\n';\n                }\n                break;\n        }\n\n        return result;\n    }\n</script>\n<script type=\"text/javascript\">\n    function onSubmit() {\n        var ipFormat = $('#ip-format').val();\n\n        return doExportAction(ipFormat);\n    }\n</script>\n"
  },
  {
    "path": "code/default/gae_proxy/web_ui/global_setting.html",
    "content": "\n        <form method=\"POST\" onSubmit=\"return false;\">\n            <div class=\"row-fluid\">\n                <div class=\"span3\" title=\"{{ _( \"Switch ON to submit setting level\") }}\">\n                    <label for=\"submit-setting-level\">{{ _( \"Submit setting level\") }}</label>\n                </div> <!-- .span3 -->\n                <div class=\"span9\">\n                    <input id=\"submit-setting-level\" type=\"checkbox\" data-toggle=\"switch\"/>\n                </div> <!-- .span9 -->\n            </div> <!-- .row-fluid -->\n            <div class=\"row-fluid\" title=\"{{ _( \"Passive mode consumes less system resources\") }}\">\n                <div class=\"span3\">\n                    <label for=\"setting-level\">{{ _( \"Setting level\" ) }}</label>\n                </div> <!-- .span4 -->\n                <div class=\"span6\">\n                    <select id=\"setting-level\">\n                        <option value=\"passive\">{{ _( \"Passive\" ) }}</option>\n                        <option value=\"conservative\">{{ _( \"Conservative\" ) }}</option>\n                        <option value=\"normal\">{{ _( \"Normal\" ) }}</option>\n                        <option value=\"radical\">{{ _( \"Radical\" ) }}</option>\n                        <option value=\"extreme\">{{ _( \"Extreme\" ) }}</option>\n                    </select>\n                </div> <!-- .span8 -->\n            </div> <!-- .row-fluid -->\n            <div class=\"row-fluid\">\n                <div class=\"span3\" title=\"{{ _( \"Customized an adequate value for your network connection. large values will provide a larger bandwidth limit, but may result in tunnel connection unstable.\") }}\">\n                    <label for=\"connect-receive-buffer\">{{ _(\"Connect receive buffer size\") }}\n                        (8~2048KB)</label>\n                </div> <!-- .span3 -->\n                <div class=\"span6\">\n                    <input id=\"connect-receive-buffer\" type=\"number\" min=\"8\" max=\"2048\"/>\n                </div> <!-- .span6 -->\n            </div> <!-- .row-fluid -->\n            <div class=\"row-fluid\">\n                <div class=\"span12\">\n                    <button class=\"btn btn-primary btn-block\" id=\"submit\" type=\"submit\">{{ _(\"Submit\") }}</button>\n                </div> <!-- .span12 -->\n            </div> <!-- .row-fluid -->\n        </form>\n\n<script type=\"text/javascript\">\n    $(function () {\n        $('[data-toggle=switch]').wrap('<div class=\"switch\" />').parent().bootstrapSwitch();\n    });\n</script>\n<script type=\"text/javascript\">\n    $(function () {\n        $.ajax({\n            type: 'POST',\n            url: '/module/gae_proxy/control/config?cmd=get_config',\n            dataType: 'JSON',\n            success: function (result) {\n                $('#setting-level').val(result['setting_level']);\n                $('#connect-receive-buffer').val(parseInt(Number(result['connect_receive_buffer']) / 1024));\n            },\n            error: function () {\n                tip('{{ _(\"Failed reading the settings.\") }}', 'error');\n            }\n        });\n    });\n</script>\n<script type=\"text/javascript\">\n    $('#submit').click(function () {\n        var isChecked = $(\"#submit-setting-level\").is(':checked');\n\n        var connect_receive_buffer = Number($('#connect-receive-buffer').val());\n        connect_receive_buffer = Math.max(Math.min(connect_receive_buffer, 2048), 8);\n        $('#connect-receive-buffer').val(connect_receive_buffer);\n\n        $.ajax({\n            type: 'POST',\n            url: '/module/gae_proxy/control/config?cmd=set_config_level',\n            data: {\n                \"setting_level\": isChecked ? $('#setting-level').val() : null,\n                \"connect_receive_buffer\": connect_receive_buffer * 1024\n            },\n            dataType: 'JSON',\n            success: function (result) {\n                if (result['res'] == 'success') {\n                    tip('{{ _(\"Settings saved successfully.\") }}', 'success');\n\n                    if (isChecked) {\n                        $(\"#submit-setting-level\").parent().removeClass('switch-on');\n                        $(\"#submit-setting-level\").parent().addClass('switch-off');\n                        $(\"#submit-setting-level\").prop('checked', false);\n                    }\n                } else {\n                    tip('{{ _(\"Unkown error occurred.\") }}', 'error');\n                }\n            }\n        });\n    });\n</script>\n"
  },
  {
    "path": "code/default/gae_proxy/web_ui/import_ip.html",
    "content": "<form method=\"POST\" onSubmit=\"onSubmit(); return false;\">\n    <div class=\"row-fluid\">\n        <div class=\"span2\">\n            <label for=\"ip-list\">{{ _( \"IP list\" ) }}</label>\n        </div> <!-- .span2 -->\n        <div class=\"span10\">\n            <textarea id=\"ip-list\" rows=\"10\"></textarea>\n        </div> <!-- .span10 -->\n    </div> <!-- .row-fluid -->\n    <div class=\"row-fluid\">\n        <div class=\"span12\">\n            <button class=\"btn btn-primary btn-block\" type=\"submit\">{{ _( \"Run\" ) }}</button>\n        </div> <!-- .span12 -->\n    </div> <!-- .row-fluid -->\n</form> <!-- #import-export-ip -->\n\n<script type=\"text/javascript\">\n    function onSubmit() {\n        var ipList = $('#ip-list').val();\n\n        return doImportAction(ipList);\n    }\n</script>\n<script type=\"text/javascript\">\n    function doImportAction(ipList) {\n        var postData = {\n            'ipList': ipList\n        };\n        $.ajax({\n            type: 'POST',\n            url: '/module/gae_proxy/control/importip?cmd=importip',\n            data: postData,\n            dataType: 'JSON',\n            success: function (result) {\n                tip('{{ _( \"Success import \") }}' + result['res'] + '{{ _( \" IP.\") }}', 'success');\n            },\n            error: function () {\n                tip('{{ _( \"Failed importing IP.\") }}');\n            }\n        });\n    }\n</script>\n"
  },
  {
    "path": "code/default/gae_proxy/web_ui/ipv6_tunnel.html",
    "content": "    <h4>{{ _( \"Status\" ) }}</h4>\n    <table id=\"status\" class=\"table table-bordered table-striped\">\n        <thead>\n            <tr>\n                <th width=\"25%\">{{ _( \"Property\" ) }}</th>\n                <th>{{ _( \"Value\" ) }}</th>\n            </tr>\n        </thead>\n        <tbody>\n            <tr>\n                <td>{{ _( \"Teredo Tunnel\" ) }}</td>\n                <td id=\"teredo-tunnel\"></td>\n            </tr>\n        </tbody>\n    </table>\n    <div class=\"row-fluid\">\n        <h4>{{ _( \"Tips\" ) }}</h4>\n        <ol>\n            <li>{{ _( \"Enable operations usually only needs to be performed once at each device.\" ) }}</li>\n            <li>{{ _( \"After changing the server, it takes 10-90 seconds to successfully establish a new teredo tunnel.\" ) }}</li>\n            <li>{{ _( \"To use teredo tunnel, win user must keep firewall enabled, and allow outbound.\" ) }}</li>\n            <li>{{ _( \"Non-win users can also use the test button to get the fastest server for change manually.\" ) }}</li>\n        </ol>\n    </div> <!-- .row-fluid -->\n    <div class=\"row-fluid\">\n        <div class=\"span4\">\n            <button class=\"btn btn-primary btn-block\" id=\"switch_ipv6_tunnel_enable\" type=\"submit\">{{ _( \"Enable\" ) }}</button>\n            <button class=\"btn btn-primary btn-block\" id=\"switch_ipv6_tunnel_disable\" type=\"submit\">{{ _( \"Disable\" ) }}</button>\n        </div> <!-- .span4 -->\n        <div class=\"span4\">\n            <button class=\"btn btn-primary btn-block\" id=\"teredo_tunnel_change_server\" type=\"submit\">{{ _( \"Change teredo server\" ) }}</button>\n            <button class=\"btn btn-primary btn-block\" id=\"teredo_tunnel_test\" type=\"submit\">{{ _( \"Test teredo\" ) }}</button>\n        </div> <!-- .span4 -->\n        <div class=\"span4\">\n            <button class=\"btn btn-primary btn-block\" id=\"teredo_tunnel_test_usability\" type=\"submit\">{{ _( \"Test teredo usability only\" ) }}</button>\n            <button class=\"btn btn-primary btn-block\" id=\"teredo_tunnel_test_server\" type=\"submit\">{{ _( \"Test teredo server only\" ) }}</button>\n        </div> <!-- .span4 -->\n        <!--\n        <div class=\"span3\">\n            <button class=\"btn btn-block\" id=\"priority_teredo_first\" type=\"submit\" disabled=\"disabled\">{{ _( \"Switch teredo first\" ) }}</button>\n            <button class=\"btn btn-block\" id=\"priority_origin_first\" type=\"submit\" disabled=\"disabled\">{{ _( \"Switch origin first\" ) }}</button>\n        </div>\n        -->\n    </div> <!-- .row-fluid -->\n    <div class=\"row-fluid\">\n        <div class=\"span12\">\n            <div id=\"logs\" class=\"tab-pane\">\n                <div id=\"log\" class=\"span12\"></div>\n            </div> <!-- #log -->\n        </div>\n    </div>\n\n<script type=\"text/javascript\">\n    function enableButton(buttonId) {\n        var button = $('#' + buttonId);\n        if (button.attr(\"disabled\") == \"disabled\") {\n            button.attr(\"disabled\", null);\n            button.addClass('btn-primary');\n        }\n    }\n    function disableButton(buttonId) {\n        var button = $('#' + buttonId);\n        if (button.attr(\"disabled\") != \"disabled\") {\n            button.attr(\"disabled\", \"disabled\");\n            button.removeClass('btn-primary');\n        }\n    }\n    /*function getPriority() {\n        $.ajax({\n            type: 'GET',\n            url: '/module/gae_proxy/control/ipv6_tunnel?cmd=get_priority',\n            dataType: 'JSON',\n            success: function (result) {\n                if (result['res'] == null) {\n                    tip('{{ _(\"No teredo prefix policiy is found.\") }}', 'info');\n                    return;\n                }\n                if (result['res'] == 'teredo') {\n                    disableButton('priority_teredo_first');\n                } else {\n                    enableButton('priority_teredo_first');\n                }\n                if (result['res'] == 'origin') {\n                    disableButton('priority_origin_first');\n                } else {\n                    enableButton('priority_origin_first');\n                }\n            },\n            error: function (result) {\n                    tip('{{ _(\"Failed reading the prefix policies.\") }}', 'error');\n            }\n        });\n    }\n    $(function () {\n        getPriority();\n    });*/\n</script>\n<script type=\"text/javascript\">\n    function updateStatus(selector, content) {\n        var previousContent = $(selector).html();\n        if (String(previousContent) != String(content)) {\n            $(selector).html(content);\n        }\n    }\n</script>\n<script type=\"text/javascript\">\n    var scriptIsRunning = false;\n\n    $('button.btn').click(function () {\n        var cmd = \"stop\";\n        var id = $(this).attr('id');\n        var teredoStatus = $('td#teredo-tunnel').html();\n        if (id == 'switch_ipv6_tunnel_enable') {\n            if ((teredoStatus == '{{ _(\"qualified\")}}' ||\n                 teredoStatus == '{{ _(\"probe\")}}' ||\n                 teredoStatus == '{{ _(\"dormant\")}}' ||\n                 teredoStatus == '{{ _(\"offline\")}}') &&\n                !confirm('{{ _(\"IPv6 Tunnel\")}}{{ _( \"enabled\" ) }}{{ _( \", are you sure to continue?\" ) }}')) {\n                return;\n            }\n            cmd = \"enable\";\n        } else if (id == 'switch_ipv6_tunnel_disable') {\n            if (teredoStatus == '{{ _(\"disabled\")}}' &&\n                !confirm('{{ _(\"IPv6 Tunnel\")}}{{ _( \"disabled\" ) }}{{ _( \", are you sure to continue?\" ) }}')) {\n                return;\n            }\n            cmd = \"disable\";\n        } else if (id == 'teredo_tunnel_test') {\n            cmd = \"test_teredo\";\n        } else if (id == 'teredo_tunnel_test_usability') {\n            cmd = \"test_teredo_usability\";\n        } else if (id == 'teredo_tunnel_test_server') {\n            cmd = \"test_teredo_server\";\n        } else if (id == 'teredo_tunnel_change_server') {\n            cmd = \"set_best_server\";\n        /*} else if (id == 'priority_teredo_first') {\n            cmd = \"switch_pp\";\n        } else if (id == 'priority_origin_first') {\n            cmd = \"switch_pp\";*/\n        } else {\n            return;\n        }\n\n        if (scriptIsRunning == true) {\n            tip('{{ _(\"Script is running, please retry later.\") }}', 'warning');\n            return;\n        }\n        \n        window.timer.play();\n        tip('{{ _(\"Current status: \") }}\"' + $(this).html() + '\" {{ _(\"Running ...\") }}', 'info');\n        scriptIsRunning = true;\n\n        $.ajax({\n            type: 'GET',\n            url: '/module/gae_proxy/control/ipv6_tunnel?cmd=' + cmd,\n            dataType: 'JSON',\n            success: function (result) {\n                window.timer.stop();\n                /*\n                $('.alert').html('{{ _(\"Current status: \") }}{{ _(\"idle\") }}');\n                if (!tipHasClose()) {\n                    tipClose();\n                }*/\n                scriptIsRunning = false;\n                tip(result['res'], 'info');\n                updateProcess();\n                /*if (cmd == \"switch_pp\") {\n                    getPriority();\n                }*/\n            },\n            error: function (result) {\n                window.timer.stop();\n                scriptIsRunning = false;\n                tip('{{ _(\"No response from process: \")}}{{ _(\"GAEProxy\")}}{{ _(\". It might have already exited.\")}}', 'warning', false);\n                updateProcess();\n                /*if (cmd == \"switch_pp\") {\n                    getPriority();\n                }*/\n            }\n        });\n    });\n</script>\n<script type=\"text/javascript\">\n    function updateLog(logContent) {\n        $('#log').html(logContent.replace(/\\n/g, '<br>'));\n    }\n\n    function updateProcess() {\n        $.ajax({\n            type: 'GET',\n            url: '/module/gae_proxy/control/ipv6_tunnel?cmd=get_log',\n            dataType: 'JSON',\n            success: function (result) {\n                if (result['status'] == 'offline') {\n                    updateStatus('td#teredo-tunnel', '{{ _(\"offline\")}}');\n                } else if (result['status'] == 'probe') {\n                    updateStatus('td#teredo-tunnel', '{{ _(\"probe\")}}');\n                } else if (result['status'] == 'qualified') {\n                    updateStatus('td#teredo-tunnel', '{{ _(\"qualified\")}} ({{ _(\"Still not connected? Wait for a while, or\")}}<a href=\"/?module=gae_proxy&menu=advanced#global_setting\">{{ _(\"try to reduce the connection buffer size\")}}</a>)');\n                } else if (result['status'] == 'dormant') {\n                    updateStatus('td#teredo-tunnel', '{{ _(\"dormant\")}}');\n                } else if (result['status'] == 'disabled') {\n                    updateStatus('td#teredo-tunnel', '{{ _(\"disabled\")}}');\n                } else if (result['status'] == 'unknown') {\n                    updateStatus('td#teredo-tunnel', '{{ _(\"unknown\")}}');\n                }\n                updateLog(result['log']);\n\n                if (window.isAutoScrollLog == true) {\n                    $('#log').scrollTop($('#log')[0].scrollHeight);\n                }\n            }\n        });\n    }\n</script>\n<script type=\"text/javascript\">\n    $(function () {\n        window.timer = $.timer(function () {\n            updateProcess();\n        });\n\n        window.timer.set({\n            time: 1000,\n            autostart: false\n        });\n\n        updateProcess();\n    });\n</script>\n<script type=\"text/javascript\">\n    $(function () {\n        resizeLogWindow();\n    });\n    $(window).resize(function () {\n        resizeLogWindow();\n    });\n    function resizeLogWindow() {\n        var windowHeight    = $(window).height(),\n            preservedHeight = 600;\n\n        $('#log').css('height', windowHeight - preservedHeight);\n    }\n</script>"
  },
  {
    "path": "code/default/gae_proxy/web_ui/logging.html",
    "content": "<div id=\"log-container\" class=\"row-fluid\">\n    <div id=\"log\" class=\"span12\"></div> <!-- #log -->\n</div> <!-- #log-container -->\n\n<style type=\"text/css\">\n    .DUMMY { color: black }\n    .DEBUG { color: #21610b }\n    .INFO { color: blue }\n    .WARNING { color: #ff8000 }\n    .ERROR { color: #fe2e2e }\n    .CRITICAL { color: #d7df01 }\n</style>\n<!-- JavaScript -->\n<script type=\"text/javascript\">\n    title('{{ _(\"GAEProxy Log\") }}');\n</script>\n<script type=\"text/javascript\">\n    $(function () {\n        resizeLogWindow();\n    });\n    $(window).resize(function () {\n        resizeLogWindow();\n    });\n</script>\n<script type=\"text/javascript\">\n    function resizeLogWindow() {\n        var windowHeight    = $(window).height(),\n            preservedHeight = 170;\n\n        $('#log').css('height', windowHeight - preservedHeight);\n    }\n</script>\n<script type=\"text/javascript\">\n    $(function() {\n        window.previousOffset     = 0;\n        window.offset             = 1;\n        window.logLineNum         = 0;\n        window.isAutoScrollLog    = true;\n        window.isgetLogProcessing = false;\n\n        var timer = $.timer(function () {\n            getLog();\n        });\n        timer.set({\n            time: 500,\n            autostart: true\n        });\n    });\n</script>\n<script type=\"text/javascript\">\n    $(function () {\n        getLog();\n    });\n</script>\n<script type=\"text/javascript\">\n    $('#log').scroll(function () {\n        var preservedHeight = $('#log').height() + 10,\n            scrollHeight    = $('#log')[0].scrollHeight,\n            scrollTop       = $('#log').scrollTop();\n\n        window.isAutoScrollLog = (scrollTop + preservedHeight === scrollHeight);\n    });\n</script>\n<script type=\"text/javascript\">\n    function scrollLog() {\n        if (window.isAutoScrollLog) {\n            $('#log').scrollTop($('#log')[0].scrollHeight);\n        }\n    }\n</script>\n<script type=\"text/javascript\">\n    function getLog() {\n        if ( window.isgetLogProcessing ) { return }\n        if ( !window.isAutoScrollLog ) { return }\n        window.isgetLogProcessing = true;\n        var pageRequests = {\n            'cmd': 'get_new',\n            'last_no': offset\n        };\n        $.ajax({\n            type: 'GET',\n            url: '/module/gae_proxy/control/log',\n            data: pageRequests,\n            dataType: 'JSON',\n            success: function (result) {\n                var newlines = document.createDocumentFragment();\n                var newlineNum = 0;\n                $.each(result, function (lineNumber, log) {\n                    window.offset = lineNumber;\n\n                    var logTemplate = '<p class=\"%s\">%s</p>\\n';\n                    if (window.previousOffset != window.offset) {\n                        var newline = $(logTemplate.format(getLogLevel(log), log));\n                        $(newlines).append(newline);\n                        newlineNum += 1;\n                    }\n                });\n                window.logLineNum += newlineNum;\n                $('#log').append(newlines);\n                var maxLineNum = 1000;\n                var cutStep = 10;\n                if (window.logLineNum > maxLineNum + cutStep) {\n                    var numToCut = window.logLineNum - maxLineNum;\n                    var textblock = $('#log').html();\n                    var lines = textblock.split('\\n');\n                    lines.splice(0, numToCut);\n                    var newtext = lines.join('\\n');\n                    $('#log').html(newtext);\n                    window.logLineNum -= numToCut;\n                }\n\n                scrollLog();\n                window.previousOffset = window.offset;\n                window.isgetLogProcessing = false;\n            },\n            error: function (xml, info, obj) {\n                window.isgetLogProcessing = false;\n            }\n        });\n    }\n</script>\n<script type=\"text/javascript\">\n    function getLogLevel(log) {\n        if (log.indexOf('[DEBUG]') != -1) {\n            return 'DEBUG';\n        } else if (log.indexOf('[INFO]') != -1) {\n            return 'INFO';\n        } else if (log.indexOf('[WARNING]') != -1) {\n            return 'WARNING';\n        } else if (log.indexOf('[ERROR]') != -1) {\n            return 'ERROR';\n        } else if (log.indexOf('[CRITICAL]') != -1) {\n            return 'CRITICAL';\n        } else return 'DUMMY';\n    }\n</script>\n"
  },
  {
    "path": "code/default/gae_proxy/web_ui/menu.json",
    "content": "{\n  \"module_title\": \"GAEProxy\",\n  \"menu_sort_id\": 1,\n  \"sub_menus\": {\n    \"1\":{\n      \"title\": \"{{ _(\"Status\") }}\",\n      \"url\": \"status\"\n    },\n    \"2\":{\n      \"title\": \"{{ _(\"Configuration\") }}\",\n      \"url\": \"config\"\n    },\n    \"4\":{\n      \"title\": \"{{ _(\"Advanced\") }}\",\n      \"url\": \"advanced\"\n    },\n    \"5\":{\n      \"title\": \"{{ _(\"Log\") }}\",\n      \"url\": \"logging\"\n    }\n  }\n}"
  },
  {
    "path": "code/default/gae_proxy/web_ui/scan_setting.html",
    "content": "\n        <form method=\"POST\" onSubmit=\"return false;\">\n            <div class=\"row-fluid\">\n                <div class=\"span3\">\n                    <label for=\"auto-adjust-scan-ip-thread-num\">{{ _(\"Auto-adjust scan thread count\") }}<a href=\"https://github.com/XX-net/XX-Net/wiki/GoAgent-Auto-adjust-scan-ip-thread-num\" target=\"_blank\">({{ _(\"Help\") }})</a></label>\n                </div> <!-- .span3 -->\n                <div class=\"span9\">\n                    <input id=\"auto-adjust-scan-ip-thread-num\" type=\"checkbox\" data-toggle=\"switch\"/>\n                </div> <!-- .span9 -->\n            </div> <!-- .row-fluid -->\n            <div class=\"row-fluid\">\n                <div class=\"span3\">\n                    <label for=\"scan-ip-thread-num\">{{ _(\"Max scan thread count\") }}\n                        (0~<span id=\"display-max-scan-thread\"></span>)</label>\n                </div> <!-- .span3 -->\n                <div class=\"span6\">\n                    <input id=\"scan-ip-thread-num\" type=\"number\" min=\"0\"/>\n                </div> <!-- .span6 -->\n            </div> <!-- .row-fluid -->\n            <div class=\"row-fluid\">\n                <div class=\"span3\">\n                    <label for=\"use-ipv6\">{{ _( \"IP mode\" ) }}</label>\n                </div> <!-- .span4 -->\n                <div class=\"span6\">\n                    <select id=\"use-ipv6\">\n                        <option value=\"auto\">{{ _( \"AUTO\" ) }}</option>\n                        <option value=\"force_ipv4\">{{ _( \"Force-IPv4\" ) }}</option>\n                        <option value=\"force_ipv6\">{{ _( \"Force-IPv6\" ) }}</option>\n                    </select>\n                </div> <!-- .span8 -->\n            </div> <!-- .row-fluid -->\n            <div class=\"row-fluid\">\n                <div class=\"span3\">\n                    <label for=\"ip-range-content\">{{ _(\"IP range list\") }}(<a href=\"https://github.com/XX-net/XX-Net/wiki/GoAgent-Scan-Ip-Range-Format\" target=\"_blank\">{{ _(\"Supporting formats\") }}</a>)</label>\n                </div> <!-- .span3 -->\n                <div class=\"span9\">\n                    <textarea id=\"ip-range-content\" rows=\"10\"></textarea>\n                </div> <!-- .span9 -->\n            </div> <!-- .row-fluid -->\n            <div class=\"row-fluid\">\n                <div class=\"span12\">\n                    <button class=\"btn btn-primary btn-block\" id=\"submit\" type=\"submit\">{{ _(\"Submit\") }}</button>\n                </div> <!-- .span12 -->\n            </div> <!-- .row-fluid -->\n        </form>\n<script type=\"text/javascript\">\n    $(function () {\n        $('[data-toggle=switch]').wrap('<div class=\"switch\" />').parent().bootstrapSwitch();\n    });\n</script>\n<script type=\"text/javascript\">\n    $(function () {\n        $.ajax({\n            type: 'POST',\n            url: '/module/gae_proxy/control/config?cmd=get_config',\n            dataType: 'JSON',\n            success: function (result) {\n                if (result['auto_adjust_scan_ip_thread_num'] != 0) {\n                    $(\"#auto-adjust-scan-ip-thread-num\").parent().removeClass('switch-off');\n                    $(\"#auto-adjust-scan-ip-thread-num\").parent().addClass('switch-on');\n\n                    $(\"#auto-adjust-scan-ip-thread-num\").prop('checked', true);\n                }\n                $('#scan-ip-thread-num').val(result['scan_ip_thread_num']);\n\n                $('#use-ipv6').val(result['use_ipv6']);\n            },\n            error: function () {\n                tip('{{ _(\"Failed reading the settings.\") }}', 'error');\n            }\n        });\n    });\n\n    $('#ip-range-content').load('/module/gae_proxy/control/scan_ip?cmd=get_range');\n</script>\n<script type=\"text/javascript\">\n    $(function () {\n        window.MAX_SCAN_THREAD = 200;\n        $('#scan-ip-thread-num').attr(\"max\", window.MAX_SCAN_THREAD);\n        $('#display-max-scan-thread').text(window.MAX_SCAN_THREAD);\n    });\n</script>\n<script type=\"text/javascript\">\n    $('#submit').click(function () {\n        // set_auto_adjust_scan_ip_thread_num\n        var isChecked = $(\"#auto-adjust-scan-ip-thread-num\").is(':checked');\n\n        // scan-ip-thread-num\n        var scanIpThreadNum = $('#scan-ip-thread-num').val();\n        if (scanIpThreadNum > window.MAX_SCAN_THREAD) {\n            tip('{{ _(\"Scan IP thread is larger than the max number.\") }}', 'error');\n            return;\n        }\n\n        // ip-range\n        var ipRangeContent = $('#ip-range-content').val();\n\n        $.ajax({\n            type: 'POST',\n            url: '/module/gae_proxy/control/scan_ip?cmd=update',\n            data: {\n                \"auto_adjust_scan_ip_thread_num\": isChecked ? 1 : 0,\n                \"scan_ip_thread_num\": scanIpThreadNum,\n                \"ip_range\": ipRangeContent,\n                \"use_ipv6\": $('#use-ipv6').val()\n            },\n            dataType: 'JSON',\n            success: function (result) {\n                if (result['res'] == 'success') {\n                    tip('{{ _(\"Settings saved successfully.\") }}', 'success');\n                } else {\n                    tip('{{ _(\"Unkown error occurred.\") }}', 'error');\n                }\n            }\n        });\n    });\n</script>\n"
  },
  {
    "path": "code/default/gae_proxy/web_ui/status.html",
    "content": "<!--[if lte IE 9]>\n<div class=\"alert alert-warning\">\n    {{ _( \"Your browser is obsolete. Partial functionality will not be available.\" ) }}<br>\n    {{ _( \"The latest Chrome browser is recommended.\" ) }}\n</div>\n<![endif]-->\n\n<div id=\"noob-info\" class=\"\"></div>\n\n<div id=\"details\" hidden>\n    <h4>{{ _( \"Status\" ) }}</h4>\n    <table id=\"status\" class=\"table table-bordered table-striped\">\n        <thead>\n            <tr>\n                <th width=\"25%\">{{ _( \"Property\" ) }}</th>\n                <th>{{ _( \"Value\" ) }}</th>\n            </tr>\n        </thead>\n        <tbody>\n            <tr>\n                <td>{{ _( \"IPv4 Status\" ) }}</td>\n                <td id=\"ipv4-status\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"IPv6 Status\" ) }}(<a href=\"https://github.com/XX-net/XX-Net/wiki/%E5%A6%82%E4%BD%95%E5%BC%80%E5%90%AFIPv6\" target=\"_blank\">{{ _( \"How enable\" ) }}</a>)</td>\n                <td id=\"ipv6-status\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"Good IPv4 Number\" ) }}</td>\n                <td id=\"good-ipv4-num\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"Good IPv6 Number\" ) }}</td>\n                <td id=\"good-ipv6-num\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"All IP Number\" ) }}</td>\n                <td id=\"all-ip-num\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"Status\" ) }}</td>\n                <td id=\"is-idle\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"IP Quality\" ) }}</td>\n                <td id=\"ip-quality\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"Connection Pool\" ) }}(<a href=\"https://github.com/XX-net/XX-Net/wiki/GoAgent-Connection-status\" target=\"_blank\">{{ _( \"Help\" ) }}</a>)</td>\n                <td id=\"connection-status\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"Browser Proxy Setting\" ) }}</td>\n                <td id=\"browser-proxy-setting\"></td>\n            </tr>\n            <tr id=\"tr_ca-status\">\n                <td>{{ _( \"CA status\" ) }}(<a href=\"/module/gae_proxy/control/download_cert\">{{ _( \"Download\" ) }}</a>)</td>\n                <td id=\"ca-status\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"Number of IP-Scanning Threads\" ) }}(<a href=\"/?module=gae_proxy&menu=advanced#scan_setting\">{{ _( \"Settings\" ) }}</a>)</td>\n                <td id=\"scan-ip-thread-num\"></td>\n            </tr>\n        </tbody>\n    </table>\n\n    <h4>{{ _( \"Configuration\" ) }}</h4>\n    <table id=\"setting\" class=\"table table-bordered table-striped\">\n        <thead>\n            <tr>\n                <th width=\"25%\">{{ _( \"Property\" ) }}</th>\n                <th>{{ _( \"Value\" ) }}</th>\n            </tr>\n        </thead>\n        <tbody>\n            <tr hidden>\n                <td>{{ _( \"System Proxy Status\" ) }}</td>\n                <td id=\"proxy-status\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"Listening At\" ) }}</td>\n                <td id=\"proxy-listen\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"IP mode\" ) }}</td>\n                <td id=\"use-ipv6\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"LAN proxy\" ) }}</td>\n                <td id=\"lan-proxy\"></td>\n            </tr>\n        </tbody>\n    </table>\n\n    <h4>AppID</h4>\n    <table id=\"appids\" class=\"table table-bordered table-striped\">\n        <thead>\n            <tr>\n                <th width=\"25%\">{{ _( \"Property\" ) }}</th>\n                <th width=\"75%\">{{ _( \"Value\" ) }}</th>\n            </tr>\n        </thead>\n        <tbody>\n            <tr id=\"hidden-appids\">\n                <td>{{ _( \"working AppIDs\" ) }}</td>\n                <td id=\"working-appid\"></td>\n            </tr>\n            <tr id=\"tr-out-of-quota-appids\">\n                <td>{{ _( \"out-of-quota AppIDs\" ) }}</td>\n                <td id=\"out-of-quota-appids\"></td>\n            </tr>\n            <tr id=\"tr-not-exist-appids\">\n                <td>{{ _( \"not-exist AppIDs\" ) }}</td>\n                <td id=\"not-exist-appids\"></td>\n            </tr>\n        </tbody>\n    </table>\n\n    <h4>{{ _( \"System Info\" ) }}</h4>\n    <table id=\"version\" class=\"table table-bordered table-striped\">\n        <thead>\n            <tr>\n                <th width=\"25%\">{{ _( \"Property\" ) }}</th>\n                <th width=\"75%\">{{ _( \"Value\" ) }}</th>\n            </tr>\n        </thead>\n        <tbody>\n            <tr>\n                <td>APP Version</td>\n                <td id=\"xxnet-version\"></td>\n            </tr>\n            <tr>\n                <td>Python Version</td>\n                <td id=\"python-version\"></td>\n            </tr>\n            <tr>\n                <td>OpenSSL Version</td>\n                <td id=\"openssl-version\"></td>\n            </tr>\n            <tr>\n                <td>System Platform</td>\n                <td id=\"sys-platform\"></td>\n            </tr>\n            <tr>\n                <td>OS System</td>\n                <td id=\"os-system\"></td>\n            </tr>\n            <tr>\n                <td>OS Version</td>\n                <td id=\"os-version\"></td>\n            </tr>\n            <tr>\n                <td>OS Release</td>\n                <td id=\"os-release\"></td>\n            </tr>\n            <tr>\n                <td>OS Detail</td>\n                <td id=\"os-detail\"></td>\n            </tr>\n            <tr>\n                <td>Language</td>\n                <td id=\"language\"></td>\n            </tr>\n            <tr>\n                <td>Architecture</td>\n                <td id=\"architecture\"></td>\n            </tr>\n            <tr>\n                <td>Browser</td>\n                <td id=\"browser\"></td>\n            </tr>\n        </tbody>\n    </table>\n\n    <button id=\"pop-up-report\" class=\"btn btn-primary\">{{ _( \"Diagnostic Info\" ) }}</button>\n    <br><br>\n    <div id=\"tip\">\n            {{ _(\"Check\") }} <a href=\"https://github.com/XX-net/XX-Net/issues\">{{ _(\"GitHub issues\") }}</a> {{ _(\"or\")}} <a href=\"https://groups.google.com/forum/#!forum/xx-net\">{{ _(\"Google Group Discussions\") }}</a><br>\n    </div>\n    <br><br>\n</div> <!-- #details -->\n\n<!-- Toggle #details-->\n<div class=\"row-fluid\">\n    <div class=\"span3 bold\">{{ _( \"Show Details\" ) }}</div> <!-- .span4 -->\n    <div class=\"span9\">\n        <input id=\"show-detail\" type=\"checkbox\"/>\n    </div> <!-- .span8 -->\n</div>\n\n<div id=\"report-issue-modal\" class=\"modal hide fade\">\n    <div class=\"modal-header\">\n        <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-hidden=\"true\">&times;</button>\n        <h3>{{ _( \"Diagnostic Info\" ) }}</h3>\n    </div> <!-- .modal-header -->\n    <div class=\"modal-body\">\n        <p> * {{ _( \"Post to Github issue needs to sign in your Github account\" ) }}</p>\n        <textarea id=\"DiagInfo\" onmouseover=\"this.focus();this.select()\"></textarea>\n    </div>\n    <div class=\"modal-footer\">\n    </div> <!-- .modal-footer -->\n</div> <!-- #report-issue-modal -->\n\n<!-- JavaScript -->\n<script type=\"text/javascript\">\n    title('{{ _( \"GAE Proxy Status Info\" ) }}');\n</script>\n<script type=\"text/javascript\">\n    function OneKeyReport() {\n        $.ajax({\n            type: 'GET',\n            url: '/module/gae_proxy/control/status',\n            dataType: 'JSON',\n            success: function (result) {\n                var information = [\n                    'sys-platform: ' + result['sys_platform'],\n                    'os-system: ' + result['os_system'],\n                    'os-version: ' + result['os_version'],\n                    'os-release: ' + result['os_release'],\n                    'os-detail: ' + result['os_detail'],\n                    'architecture: ' + String(result['architecture'].concat()),\n                    'browser: ' + result['browser'],\n                    'xxnet-version: ' + result['xxnet_version'],\n                    'python-version: ' + result['python_version'],\n                    'openssl-version: ' + result['openssl_version'],\n\n                    'lan-proxy: ' + result['lan_proxy'],\n                    'use-ipv6: ' + result['use_ipv6'],\n                    'gws-ip-num: ' + 'total:' + result['all_ip_num'] + ' ipv4:' + result['good_ipv4_num'] + ' ipv6:' + result['good_ipv6_num'],\n                    'ipv4-status: ' + result['ipv4_state'],\n                    'ipv6-status: ' + result['ipv6_state'],\n                    'connected-link: ' + 'new:' + result['connected_link_new'],\n                    'worker: ' + 'h1:' + result['worker_h1'] + ' h2:' + result['worker_h2'],\n                    'scan-ip-thread-num: ' + result['scan_ip_thread_num'],\n                    'ip-quality: ' + result['ip_quality'],\n                    'is-idle: ' + result['is_idle'],\n                    'proxy_state: ' + test_http_proxy_setting(),\n                    'ca_state: ' + test_https_proxy_setting(),\n\n                    'Appid_Working: ' + (result['working_appid'].length != 0),\n                    'Appids_Out_Of_Quota: ' + (result['out_of_quota_appids'].length != 0),\n                    'Appids_Not_Exist: ' + (result['not_exist_appids'].length != 0),\n                    'Using_Public_Appid: ' + is_public_appid(result['gae_appid'])\n                ];\n\n                updateProperty(\"textarea#DiagInfo\", \"XX-Net Status:\\n\\n\" + information.join(\"\\n\"));\n\n                IssueURL = 'https://github.com/XX-net/XX-Net/issues/new?body={{ _( \"-----------%0AProblem Description:%0APlease describe your problem, running logs may be needed.%0A%0A-----------%0ADiagnostic information:%0A\" ) }}' + encodeURIComponent(information.join(\"\\n\")) + \";\";\n                $(\"a#one-key-issue\").attr(\"href\", IssueURL);\n                GGroupURL = \"https://groups.google.com/forum/#!forum/xx-net\";\n                // The one-key generaton function is to be designed as Github does有待设计类似Github Issue的一键生成功能\n                $(\"a#go-to-google-group\").attr(\"href\", GGroupURL);\n            }\n        })\n    }\n</script>\n<script type=\"text/javascript\">\n\n    window.fake_host = \"\";\n\n    documentReadyToRun.push(function () {\n        var timer = $.timer(function () {\n            if ($(\"#details\").is(\":visible\")) {\n                updateDetailStatus();\n            }\n            updateNoobStatus();\n        });\n\n        timer.set({\n            time: 1000,\n            autostart: true\n        });\n\n        updateDetailStatus();\n        updateNoobStatus();\n        update_show_detail();\n    });\n\n    $(\"#pop-up-report\").click(function () {\n        OneKeyReport();\n        $('#report-issue-modal').modal();\n    });\n\n</script>\n<script type=\"text/javascript\">\n    function updateProperty(selector, content, attrclass) {\n        var previousContent = $(selector).html();\n        if (String(previousContent) != String(content)) {\n            $(selector).html(content);\n        }\n        if (attrclass) {\n            $(selector).attr(\"class\", attrclass);\n        }\n    }\n\n    function updateDetailStatus() {\n        $.ajax({\n            type: 'GET',\n            url: '/module/gae_proxy/control/status',\n            dataType: 'JSON',\n            success: function (result) {\n                if (test_http_proxy_setting() == \"OK\") {\n                    var ca_status_str = test_https_proxy_setting();\n                } else {\n                    var ca_status_str = \"Fail\";\n                }\n\n                var ip_mode = {\n                    \"auto\": '{{ _( \"AUTO\" ) }}',\n                    \"force_ipv4\": '{{ _( \"Force-IPv4\" ) }}',\n                    \"force_ipv6\": '{{ _( \"Force-IPv6\" ) }}'\n                };\n\n                if (result['ipv6_state'] == 'Fail') {\n                    result['ipv6_state'] += ' (<a href=\"/?module=gae_proxy&menu=advanced#ipv6_tunnel\">{{ _( \"try repair\" ) }}</a>)';\n                }\n\n                var updates = {\n                    'td#sys-platform': result['sys_platform'],\n                    'td#os-system': result['os_system'],\n                    'td#os-version': result['os_version'],\n                    'td#os-release': result['os_release'],\n                    'td#os-detail': result['os_detail'],\n                    'td#language': result['language'],\n                    'td#architecture': String(result['architecture'].concat()),\n                    'td#browser': result['browser'],\n                    'td#xxnet-version': result['xxnet_version'],\n                    'td#python-version': result['python_version'],\n                    'td#openssl-version': result['openssl_version'],\n\n                    'td#lan-proxy': (result['lan_proxy'] === 'Disable') ? '{{ _( \"Disable\" ) }}' : result['lan_proxy'],\n                    'td#proxy-listen': result['proxy_listen'],\n                    'td#use-ipv6': ip_mode[result['use_ipv6']],\n                    'td#working-appid': appid_string(result['gae_appid'], result['working_appid']),\n                    'td#out-of-quota-appids': result['out_of_quota_appids'],\n                    'td#not-exist-appids': result['not_exist_appids'],\n\n                    'td#ipv4-status': result['ipv4_state'],\n                    'td#ipv6-status': result['ipv6_state'],\n                    'td#good-ipv4-num': result['good_ipv4_num'],\n                    'td#good-ipv6-num': result['good_ipv6_num'],\n                    'td#all-ip-num': result['all_ip_num'],\n                    'td#is-idle': result['is_idle'] ? '{{ _( \"idle\" ) }}' : '{{ _( \"working\" ) }}',\n                    'td#connection-status': connection_status_string(result['connected_link_new'], result['worker_h1'], result['worker_h2']),\n                    'td#browser-proxy-setting': test_http_proxy_setting(),\n                    'td#ca-status': ca_status_str,\n                    'td#scan-ip-thread-num': result['scan_ip_thread_num'],\n                    'td#ip-quality': result['ip_quality']\n                };\n\n                if (window.fake_host == \"\") {\n                    window.fake_host = result[\"fake_host\"];\n                    test_http_proxy_setting();\n                    test_https_proxy_setting();\n                }\n                for (var item in updates) {\n                    updateProperty(item, updates[item]);\n                }\n\n                if (result['out_of_quota_appids'] === \"\") {\n                    $('#tr-out-of-quota-appids').hide();\n                } else {\n                    $('#tr-out-of-quota-appids').show();\n                }\n\n                if (result['not_exist_appids'] === \"\") {\n                    $('#tr-not-exist-appids').hide();\n                } else {\n                    $('#tr-not-exist-appids').show();\n                }\n\n                if (!tipHasClose()) {\n                    tipClose();\n                }\n            },\n            error: function (result) {\n                var formValue = $('#sys-platform').html();\n\n                if (tipHasClose()) {\n                    $('html, body').animate({\n                        scrollTop: 0\n                    }, 'slow');\n                }\n\n                if (formValue == '') {\n                    tip('{{ _(\"The status page is empty. Highly likely that \")}}{{ _(\"GAEProxy\")}}{{ _(\" failed getting started. Please follow \")}}<a href=\"https://github.com/XX-net/XX-Net/wiki/How-to-get-start-error-log\" target=\"_blank\">{{ _(\"guide\")}}</a>{{ _(\" to troubleshoot.\")}}<br>', 'warning', false);\n                }\n            }\n        });\n    }\n\n    function updateNoobStatus() {\n        $.ajax({\n            type: 'GET',\n            url: '/module/gae_proxy/control/status',\n            dataType: 'JSON',\n            success: function (result) {\n                if (result['ipv4_state'] == \"Fail\" && result['ipv6_state'] == \"Fail\") {\n                    return updateProperty('#noob-info', '{{ _( \"Your local network failed, please check your network and firewall.\" ) }}', 'none');\n                } else {\n                    if (result['use_ipv6'] == \"force_ipv6\" && result['ipv6_state'] == \"Fail\") {\n                        return updateProperty('#noob-info', '\"{{ _( \"Force-IPv6\" ) }}\"{{ _( \" not available, Please check.\" ) }}', 'none');\n                    } else if (result['use_ipv6'] == \"force_ipv4\" && result['ipv4_state'] == \"Fail\") {\n                        return updateProperty('#noob-info', '\"{{ _( \"Force-IPv4\" ) }}\"{{ _( \" not available, Please check.\" ) }}', 'none');\n                    }\n                }\n\n                if (result['good_ipv4_num'] + result['good_ipv6_num'] < 1) {\n                    if (result['scan_ip_thread_num'] < 1) {\n                        return updateProperty('#noob-info', '{{ _( \"You may want to $1turn on IP scaner$2.\" ) }}'.replace('$1', '<a href=\\\"./?module=gae_proxy&menu=advanced#scan_setting\\\">').replace('$2', '</a>'), 'none');\n                    } else {\n                        if (result['ipv6_state'] == \"Fail\") {\n                            return updateProperty('#noob-info', '{{ _( \"You can try <a href=\\\"https://github.com/XX-net/XX-Net/wiki/How-to-turn-on-IPv6\\\">turn on IPv6</a> or <a href=\\\"https://github.com/XX-net/XX-Net/wiki/How-to-use-XTunnel\\\">use X-Tunnel</a>.\" ) }}', 'none');\n                        } else {\n                            return updateProperty('#noob-info', '{{ _( \"XX-Net is scanning IP. Please wait about half an hour.\" ) }}', 'none');\n                        }\n                    }\n                }\n\n                if (is_public_appid(result['gae_appid'])) {\n                    if (result['out_of_quota_appids'].length > 2000) {\n                        return updateProperty('#noob-info', '{{ _( \"Public AppID out of quota, Please <a href=\\\"https://github.com/XX-net/XX-Net/wiki/how-to-create-my-appids\\\" target=\\\"_blank\\\">deploy your own AppID</a>.\" ) }}', 'none');\n                    }\n                } else {\n                    if (result['working_appid'] == \"\") {\n                        if (result['out_of_quota_appids'].length > 0){\n                            return updateProperty('#noob-info', '{{ _( \"Your AppID out of quota, Please <a href=\\\"https://github.com/XX-net/XX-Net/wiki/how-to-create-my-appids\\\" target=\\\"_blank\\\">deploy more AppID</a>.\" ) }}', 'none');\n                        } else {\n                            return updateProperty('#noob-info', '{{ _( \"No working AppID. Please check.\" ) }}', 'none');\n                        }\n                    }\n                }\n\n                if ((result['connected_link_new'] + result['worker_h1'] + result['worker_h2']) < 1) {\n                    if (result['connection_pool_min'] > 0) {\n                        return updateProperty('#noob-info', '{{ _( \"Connection not established yet.\" ) }}', 'none');\n                    } else if (result['is_idle']) {\n                        return updateProperty('#noob-info', '{{ _( \"System is Idle.\" ) }} ({{ _( \"Normal\" ) }})', 'fluent');\n                    } else {\n                        return updateProperty('#noob-info', '{{ _( \"Connection not established yet.\" ) }}', 'none');\n                    }\n                }\n\n                if (test_http_proxy_setting() == \"Fail\") {\n                    return updateProperty('#noob-info', '<a href=\"https://github.com/XX-net/XX-Net/wiki/%E8%AE%BE%E7%BD%AE%E4%BB%A3%E7%90%86\" target=\"_blank\">' + '{{ _( \"Please check your browser proxy setting.\" ) }}' + '</a>', 'none');\n                } else if (test_http_proxy_setting() == \"Detecting\") {\n                    return updateProperty('#noob-info', '{{ _( \"Detecting ...\" ) }}', 'none');\n                }\n\n                if (test_https_proxy_setting() == \"Fail\") {\n                    return updateProperty('#noob-info', '<a href=\"https://github.com/XX-net/XX-Net/wiki/GoAgent-Import-CA\" target=\"_blank\">' + '{{ _( \"Please import certificates to your browser.\" ) }}' + '</a>', 'none');\n                } else if (test_https_proxy_setting() == \"Detecting\") {\n                    return updateProperty('#noob-info', '{{ _( \"Detecting ...\" ) }}', 'none');\n                }\n\n                if (is_public_appid(result['gae_appid'])) {\n                    if (result['out_of_quota_appids'].length > 200) {\n                        return updateProperty('#noob-info', '{{ _( \"You are using public AppIDs. You are recommended to <a href=\\\"https://github.com/XX-net/XX-Net/wiki/how-to-create-my-appids\\\" target=\\\"_blank\\\">deploy your own AppID</a>.\" ) }}', 'hard');\n                    }\n                }\n\n                return updateProperty('#noob-info', \"XX-Net \" + result['xxnet_version'].trim() + '{{ _( \", Everything is OK. Welcome to the FREE Internet.\" ) }}', 'fluent');\n\n            },\n            error: function (result) {\n                var infoValue = $('#noob-info').html();\n                if (infoValue == '') {\n                    tip('{{ _(\"The status page is empty. Highly likely that \")}}{{ _(\"XX-Net\")}}{{ _(\" failed getting started. Please follow \")}}<a href=\"https://github.com/XX-net/XX-Net/wiki/How-to-get-start-error-log\" target=\"_blank\">{{ _(\"guide\")}}</a>{{ _(\" to troubleshoot.\")}}<br>', 'warning', false);\n                } else {\n                    updateProperty('#noob-info', '{{ _(\"No response from process: \")}}{{ _(\"GAEProxy\")}}{{ _(\". It might have already exited.\")}}', 'none');\n                }\n            }\n        });\n    }\n    function appid_string(gae_appid, working_appid) {\n        if (is_public_appid(gae_appid)) {\n            return '{{ _( \"You are using public AppIDs.\" ) }}';\n        } else {\n            if(working_appid.length > 0){\n                return working_appid;\n            }else{\n                return '{{ _( \"Your AppID out of quota, Please <a href=\\\"https://github.com/XX-net/XX-Net/wiki/how-to-create-my-appids\\\" target=\\\"_blank\\\">deploy more AppID</a>.\" ) }}';\n            }\n        }\n    }\n    function is_public_appid(appids) {\n        if (appids.length > 0) {\n            return false;\n        } else {\n            return true;\n        }\n    }\n    function connection_status_string(connected_link_new, worker_h1, worker_h2) {\n        return conn_str = '{{ _( \"new:\" ) }}' + connected_link_new + ' ' + '{{ _( \"h1:\" ) }}' + worker_h1 + ' ' + '{{ _( \"h2:\" ) }}' + worker_h2;\n    }\n\n    function test_http_proxy_setting() {\n        if (window.http_proxy_setting === \"OK\" || window.https_proxy_setting === \"OK\") {\n            return \"OK\";\n        }\n\n        if (window.fake_host == \"\") {\n            return \"Fail\";\n        }\n\n        $.ajax({\n            type: 'POST',\n            dataType: 'text',\n            crossDomain: true,\n            timeout: 1000,\n            url: 'http://' + window.fake_host + '/xxnet',\n            success: function (result) {\n                if (result == \"OK\") {\n                    window.http_proxy_setting = \"OK\";\n                } else {\n                    window.http_proxy_setting = \"Fail\";\n                }\n            },\n            error: function (result, textStatus, errorThrown) {\n                window.http_proxy_setting = \"Fail\";\n            }\n        });\n\n        if (window.http_proxy_setting === \"Fail\") {\n            return \"Fail\";\n        }\n        return \"Detecting\";\n    }\n\n    function test_https_proxy_setting() {\n        if (window.https_proxy_setting === \"OK\") {\n            return \"OK\";\n        }\n\n        if (window.fake_host == \"\") {\n            return \"Fail\";\n        }\n\n        $.ajax({\n            type: 'POST',\n            dataType: 'text',\n            crossDomain: true,\n            timeout: 1000,\n            url: 'https://' + window.fake_host + '/xxnet',\n            success: function (result) {\n                if (result == \"OK\") {\n                    window.https_proxy_setting = \"OK\";\n                } else {\n                    window.https_proxy_setting = \"Fail\";\n                }\n            },\n            error: function (result, textStatus, errorThrown) {\n                window.https_proxy_setting = \"Fail\";\n            }\n        });\n\n        if (window.https_proxy_setting === \"Fail\") {\n            return \"Fail\";\n        }\n        return \"Detecting\";\n    }\n    test_http_proxy_setting();\n    test_https_proxy_setting();\n\n    $(function () {\n        $('#show-detail').wrap('<div class=\"switch\" />').parent().bootstrapSwitch();\n    });\n\n    $('#show-detail').change(function () {\n        var isChecked = $(this).is(':checked'),\n            key       = 'show_detail',\n            value     = isChecked ? 1 : 0;\n        if (isChecked) {\n            $(\"#details\").slideDown();\n        } else {\n            $(\"#details\").slideUp();\n        }\n\n        setConfig(key, value);\n    });\n\n    function update_show_detail() {\n        var pageRequests = {\n            'cmd': 'get_config'\n        };\n        $.ajax({\n            type: 'GET',\n            url: '/config',\n            data: pageRequests,\n            dataType: 'JSON',\n            success: function (result) {\n                if (result['show_detail'] != 0) {\n                    $(\"#show-detail\").parent().removeClass('switch-off');\n                    $(\"#show-detail\").parent().addClass('switch-on');\n                    $(\"#show-detail\").prop('checked', true);\n                    $(\"#details\").slideDown();\n                } else {\n                    $(\"#show-detail\").parent().addClass('switch-off');\n                    $(\"#show-detail\").parent().removeClass('switch-on');\n                    $(\"#show-detail\").prop('checked', false);\n                    $(\"#details\").slideUp();\n                }\n            }\n        });\n    }\n</script>\n"
  },
  {
    "path": "code/default/launcher/__init__.py",
    "content": ""
  },
  {
    "path": "code/default/launcher/autorun.py",
    "content": "#!/usr/bin/env python\n\"\"\"A simple crossplatform autostart helper\"\"\"\n\nimport os\nimport sys\n\nfrom config import app_name\nfrom xlog import getLogger\n\nxlog = getLogger(\"launcher\")\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nroot_path = os.path.abspath(os.path.join(current_path, os.pardir))\ntop_path = os.path.abspath(os.path.join(root_path, os.pardir, os.pardir))\n\nif sys.platform == 'win32':\n    import winreg\n\n    _registry = winreg.ConnectRegistry(None, winreg.HKEY_CURRENT_USER)\n\n\n    def get_runonce():\n        return winreg.OpenKey(_registry, r\"Software\\Microsoft\\Windows\\CurrentVersion\\Run\", 0, winreg.KEY_ALL_ACCESS)\n\n\n    def add(name, application):\n        \"\"\"add a new autostart entry\"\"\"\n        key = get_runonce()\n        winreg.SetValueEx(key, name, 0, winreg.REG_SZ, application)\n        winreg.CloseKey(key)\n\n\n    def exists(name):\n        \"\"\"check if an autostart entry exists\"\"\"\n        key = get_runonce()\n        exists = True\n        try:\n            winreg.QueryValueEx(key, name)\n        except:  # WindowsError\n            exists = False\n        winreg.CloseKey(key)\n        return exists\n\n\n    def remove(name):\n        if not exists(name):\n            return\n\n        \"\"\"delete an autostart entry\"\"\"\n        key = get_runonce()\n        winreg.DeleteValue(key, name)\n        winreg.CloseKey(key)\n\n\n    run_cmd = \"\\\"\" + os.path.join(top_path, \"start.vbs\") + \"\\\"\"\nelif sys.platform.startswith('linux'):\n    _xdg_config_home = os.environ.get(\"XDG_CONFIG_HOME\", \"~/.config\")\n    home_config_path = os.path.expanduser(_xdg_config_home)\n    _xdg_user_autostart = os.path.join(home_config_path, \"autostart\")\n\n\n    def getfilename(name):\n        \"\"\"get the filename of an autostart (.desktop) file\"\"\"\n        return os.path.join(_xdg_user_autostart, name + \".desktop\")\n\n\n    def add(name, application):\n        if not os.path.isdir(home_config_path):\n            xlog.warn(\"autorun linux config path not found:%s\", home_config_path)\n            return\n\n        if not os.path.isdir(_xdg_user_autostart):\n            try:\n                os.mkdir(_xdg_user_autostart)\n            except Exception as e:\n                xlog.warn(\"Enable auto start, create path:%s fail:%r\", _xdg_user_autostart, e)\n                return\n\n        \"\"\"add a new autostart entry\"\"\"\n        desktop_entry = \"[Desktop Entry]\\n\" \\\n                        \"Name=%s\\n\" \\\n                        \"Exec=%s\\n\" \\\n                        \"Type=Application\\n\" \\\n                        \"Terminal=false\\n\" \\\n                        \"X-GNOME-Autostart-enabled=true\" % (name, application)\n        with open(getfilename(name), \"w\") as f:\n            f.write(desktop_entry)\n\n\n    def exists(name):\n        \"\"\"check if an autostart entry exists\"\"\"\n        return os.path.exists(getfilename(name))\n\n\n    def remove(name):\n        \"\"\"delete an autostart entry\"\"\"\n        if (exists(name)):\n            os.unlink(getfilename(name))\n\n\n    run_cmd = os.path.join(top_path, \"start\")\nelif sys.platform == 'darwin':\n    plist_template = \"\"\"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>Label</key>\n\t<string>com.xxnet.launcher</string>\n\n\t<key>LimitLoadToSessionType</key>\n\t<string>Aqua</string>\n\n\t<key>ProgramArguments</key>\n\t<array>\n\t  <string>%s</string>\n\t  <string>-hungup</string>\n\t</array>\n\n\t<key>RunAtLoad</key>\n\t<true/>\n\n\t<key>StandardErrorPath</key>\n\t<string>/dev/null</string>\n\t<key>StandardOutPath</key>\n\t<string>/dev/null</string>\n</dict>\n</plist>\"\"\"\n\n    run_cmd = os.path.join(top_path, \"start\")\n    from os.path import expanduser\n\n    home = expanduser(\"~\")\n    launch_path = os.path.join(home, \"Library/LaunchAgents\")\n\n    plist_file_path = os.path.join(launch_path, \"com.xxnet.launcher.plist\")\n\n\n    def add(name, cmd):\n        file_content = plist_template % cmd\n        xlog.info(\"create file:%s\", plist_file_path)\n\n        if not os.path.isdir(launch_path):\n            os.mkdir(launch_path, 0o755)\n\n        with open(plist_file_path, \"w\") as f:\n            f.write(file_content)\n\n\n    def remove(name):\n        if (os.path.isfile(plist_file_path)):\n            os.unlink(plist_file_path)\n            xlog.info(\"remove file:%s\", plist_file_path)\nelse:\n    def add(name, cmd):\n        pass\n\n\n    def remove(name):\n        pass\n\n\ndef enable():\n    add(app_name, run_cmd)\n\n\ndef disable():\n    remove(app_name)\n\n\ndef test():\n    assert not exists(\"test_xxx\")\n    try:\n        add(\"test_xxx\", \"test\")\n        assert exists(\"test_xxx\")\n    finally:\n        remove(\"test_xxx\")\n    assert not exists(\"test_xxx\")\n\n\nif __name__ == \"__main__\":\n    test()\n"
  },
  {
    "path": "code/default/launcher/babel.config",
    "content": "# Extraction from Python source files\n#[python: **.py]\n\n# Extraction from HTML and YAML templates\n[jinja2: **/web_ui/**.html]\n[jinja2: **/web_ui/**.yaml]\n\nencoding = utf-8\n"
  },
  {
    "path": "code/default/launcher/config.py",
    "content": "#!/usr/bin/env python\n\nimport os\nimport subprocess\nimport locale\nimport json\n\nimport sys_platform\nfrom simple_http_client import request\nimport xconfig\nfrom xlog import getLogger\nxlog = getLogger(\"launcher\")\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nversion_path = os.path.abspath(os.path.join(current_path, os.pardir))\nroot_path = os.path.abspath(os.path.join(version_path, os.pardir, os.pardir))\n\nimport env_info\ndata_path = env_info.data_path\nconfig_path = os.path.join(data_path, 'launcher', 'config.json')\n\n\nconfig = xconfig.Config(config_path)\n\nconfig.set_var(\"control_ip\", \"127.0.0.1\")\nconfig.set_var(\"control_port\", 8085)\nconfig.set_var(\"allowed_refers\", [\"\"])\n\n# System config\nconfig.set_var(\"language\", \"\")  # en_US,\nconfig.set_var(\"allow_remote_connect\", 0)\nconfig.set_var(\"show_systray\", 1)\nconfig.set_var(\"show_android_notification\", 1)\nconfig.set_var(\"no_mess_system\", 0)\nconfig.set_var(\"auto_start\", 0)\nconfig.set_var(\"popup_webui\", 1)\nconfig.set_var(\"webui_auth\", {})\n\nconfig.set_var(\"gae_show_detail\", 0)\nconfig.set_var(\"show_compat_suggest\", 1)\nconfig.set_var(\"proxy_by_app\", 0)\nconfig.set_var(\"enabled_app_list\", [])\n\n# version control\nconfig.set_var(\"check_update\", \"notice-stable\") # can be: \"dont-check\", \"stable\", \"notice-stable\", \"test\", \"notice-test\"\nconfig.set_var(\"keep_old_ver_num\", 1)\nconfig.set_var(\"postUpdateStat\", \"noChange\") # \"noChange\", \"isNew\", \"isPostUpdate\"\nconfig.set_var(\"current_version\", \"\")\nconfig.set_var(\"ignore_version\", \"\")\nconfig.set_var(\"last_run_version\", \"\")\nconfig.set_var(\"skip_stable_version\", \"\")\nconfig.set_var(\"skip_test_version\", \"\")\n\n# update:\nconfig.set_var(\"last_path\", \"\")\nconfig.set_var(\"update_uuid\", \"\")\n\n# savedisk\nconfig.set_var(\"clear_cache\", 0)\nconfig.set_var(\"del_win\", 0)\nconfig.set_var(\"del_mac\", 0)\nconfig.set_var(\"del_linux\", 0)\nconfig.set_var(\"del_gae\", 0)\nconfig.set_var(\"del_gae_server\", 0)\nconfig.set_var(\"del_xtunnel\", 0)\nconfig.set_var(\"del_smartroute\", 0)\n\n# Module\nconfig.set_var(\"all_modules\", [\"launcher\", \"gae_proxy\", \"x_tunnel\", \"smart_router\"])\nconfig.set_var(\"enable_launcher\", 1)\nconfig.set_var(\"enable_x_tunnel\", 1)\nconfig.set_var(\"enable_gae_proxy\", 0)\nconfig.set_var(\"enable_smart_router\", 1)\n\nconfig.set_var(\"os_proxy_mode\", \"pac\") # can be: gae, x_tunnel, smart_router, disable\n\n# Proxy\nconfig.set_var(\"global_proxy_enable\", 0)\nconfig.set_var(\"global_proxy_type\", \"HTTP\") # can be: HTTP/ SOCKS4/ SOCKs5\nconfig.set_var(\"global_proxy_host\", \"\")\nconfig.set_var(\"global_proxy_port\", 0)\nconfig.set_var(\"global_proxy_username\", \"\")\nconfig.set_var(\"global_proxy_password\", \"\")\n\ntry:\n    config.load()\nexcept Exception as e:\n    xlog.warn(\"loading config e:%r\", e)\n\napp_name = \"XX-Net\"\nvalid_language = ['en_US', 'fa_IR', 'zh_CN', 'ru_RU']\ntry:\n    fp = os.path.join(root_path, \"code\", \"app_info.json\")\n    with open(fp, \"r\") as fd:\n        app_info = json.load(fd)\n        app_name = app_info[\"app_name\"]\nexcept Exception as e:\n    print(\"load app_info except:\", e)\n    pass\n\n\ndef _get_os_language():\n\n    if sys_platform.platform == \"mac\":\n        try:\n            lang_code = subprocess.check_output([\"/usr/bin/defaults\", 'read', 'NSGlobalDomain', 'AppleLanguages'])\n            if b'zh' in lang_code:\n                return 'zh_CN'\n            elif b'en' in lang_code:\n                return 'en_US'\n            elif b'fa' in lang_code:\n                return 'fa_IR'\n            elif b'ru' in lang_code:\n                return 'ru_RU'\n\n        except:\n            pass\n    elif sys_platform.platform == \"android\":\n        try:\n            res = request(\"GET\", \"http://localhost:8084/env/\")\n            dat = json.loads(res.text)\n            lang_code = dat[\"lang_code\"]\n            xlog.debug(\"lang_code:%s\", lang_code)\n            if 'zh' in lang_code:\n                return 'zh_CN'\n            elif 'en' in lang_code:\n                return 'en_US'\n            elif 'fa' in lang_code:\n                return 'fa_IR'\n            elif 'ru' in lang_code:\n                return 'ru_RU'\n            else:\n                return None\n        except Exception as e:\n            xlog.warn(\"get lang except:%r\", e)\n            return \"zh_CN\"\n    elif sys_platform.platform == \"ios\":\n        lang_code = os.environ[\"IOS_LANG\"]\n        if 'zh' in lang_code:\n            return 'zh_CN'\n        elif 'en' in lang_code:\n            return 'en_US'\n        elif 'fa' in lang_code:\n            return 'fa_IR'\n        elif 'ru' in lang_code:\n            return 'ru_RU'\n        else:\n            return None\n    else:\n        try:\n            lang_code, code_page = locale.getdefaultlocale()\n            # ('en_GB', 'cp1252'), en_US,\n            return lang_code\n        except:\n            # Mac fail to run this\n            pass\n\n\ndef get_language():\n    if config.language:\n        lang = config.language\n    else:\n        lang = _get_os_language()\n\n    if lang not in valid_language:\n        lang = 'en_US'\n\n    return lang\n"
  },
  {
    "path": "code/default/launcher/create_shortcut.js",
    "content": "function getParent(path) {\r\n    var fso = new ActiveXObject(\"Scripting.FileSystemObject\")\r\n    return fso.GetParentFolderName(path)\r\n}\r\n\r\nfunction CreateShortcut(app_name) {\r\n    var wsh = new ActiveXObject('WScript.Shell');\r\n    var fso = new ActiveXObject(\"Scripting.FileSystemObject\");\r\n    system_folder = fso.GetSpecialFolder(1)\r\n    target_path = '\"' + system_folder + '\\\\wscript.exe\"';\r\n    xxnet_path = getParent(getParent(getParent(wsh.CurrentDirectory)));\r\n    //var shell = new ActiveXObject(\"WScript.Shell\");\r\n    //shell.Popup(xxnet_path); // for debugging\r\n    argument_file = '\"' + xxnet_path + '\\\\start.vbs\"';\r\n    icon_path = wsh.CurrentDirectory + '\\\\web_ui\\\\img\\\\' + app_name + '\\\\favicon.ico';\r\n\r\n    link = wsh.CreateShortcut(wsh.SpecialFolders(\"Desktop\") + '\\\\' + app_name + '.lnk');\r\n    link.TargetPath = target_path;\r\n    link.Arguments = argument_file;\r\n    link.WindowStyle = 7;\r\n    link.IconLocation = icon_path;\r\n    link.Description = app_name;\r\n    link.WorkingDirectory = xxnet_path;\r\n    link.Save();\r\n}\r\n\r\n\r\nfunction main() {\r\n    var app_name = WScript.arguments(0);\r\n    CreateShortcut(app_name);\r\n}\r\n\r\nmain();\r\n"
  },
  {
    "path": "code/default/launcher/download.vbs",
    "content": "Sub DownloadFile1(url, strPath)\r\n    dim xHttp: Set xHttp = createobject(\"Microsoft.XMLHTTP\")\r\n    dim bStrm: Set bStrm = createobject(\"Adodb.Stream\")\r\n    xHttp.Open \"GET\", url, False\r\n    xHttp.Send\r\n\r\n    with bStrm\r\n        .type = 1 '//binary\r\n        .open\r\n        .write xHttp.responseBody\r\n        .savetofile strPath, 2 '//overwrite\r\n    end with\r\n\r\nEnd Sub\r\n\r\n\r\nSub DownloadFile2(url, strPath)\r\n    set WinHttpReq =CreateObject(\"WinHttp.WinHttpRequest.5.1\")\r\n    WinHttpReq.Open \"GET\", url, False\r\n    WinHttpReq.Send\r\n\r\n    dim BinStream: Set BinStream = createobject(\"Adodb.Stream\")\r\n    BinStream.Type = 1\r\n    BinStream.Open\r\n    BinStream.Write WinHttpReq.ResponseBody\r\n    BinStream.SaveToFile strPath\r\nEnd Sub"
  },
  {
    "path": "code/default/launcher/download_modules.py",
    "content": "import os\nimport threading\nimport time\nimport zipfile\nimport shutil\n\nfrom update_from_github import request, xlog, hash_file_sum\nimport env_info\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nroot_path = os.path.abspath(os.path.join(current_path, os.pardir))\ntop_path = os.path.abspath(os.path.join(root_path, os.pardir, os.pardir))\n\n\ndef download_file(url, filename, sha256=None):\n    org_url = url\n    if os.path.isfile(filename):\n        return True\n\n    for i in range(0, 4):\n        try:\n            xlog.info(\"download %s to %s, retry:%d\", url, filename, i)\n            req = request(url, i, timeout=120)\n            if not req:\n                time.sleep(60)\n                continue\n\n            if req.status == 302:\n                url = req.headers[b\"Location\"]\n                continue\n\n            start_time = time.time()\n            timeout = 300\n\n            if req.chunked:\n\n                downloaded = 0\n                with open(filename, 'wb') as fp:\n                    while True:\n                        time_left = timeout - (time.time() - start_time)\n                        if time_left < 0:\n                            raise Exception(\"time out\")\n\n                        dat = req.read(timeout=time_left)\n                        if not dat:\n                            break\n\n                        fp.write(dat)\n                        downloaded += len(dat)\n\n                return True\n            else:\n                file_size = int(req.getheader(b'Content-Length', 0))\n\n                left = file_size\n                downloaded = 0\n                with open(filename, 'wb') as fp:\n                    while True:\n                        chunk_len = min(65536, left)\n                        if not chunk_len:\n                            break\n\n                        chunk = req.read(chunk_len)\n                        if not chunk:\n                            break\n                        fp.write(chunk)\n                        downloaded += len(chunk)\n                        left -= len(chunk)\n\n            if downloaded != file_size:\n                xlog.warn(\"download size:%d, need size:%d, download fail.\", downloaded, file_size)\n                os.remove(filename)\n                continue\n            else:\n                if sha256 and sha256 != hash_file_sum(filename):\n                    xlog.warn(\"donwload %s checksum fail.\", filename)\n                    return False\n                else:\n                    xlog.info(\"download %s to %s success.\", org_url, filename)\n                    return True\n        except Exception as e:\n            xlog.exception(\"download %s to %s fail:%r\", org_url, filename, e)\n            continue\n    xlog.warn(\"download %s fail\", org_url)\n\n\ndef download_unzip(url, extract_path):\n    if os.path.isdir(extract_path):\n        return True\n\n    data_root = env_info.data_path\n    download_path = os.path.join(data_root, 'downloads')\n    if not os.path.isdir(download_path):\n        os.mkdir(download_path)\n\n    fn = url.split(\"/\")[-1]\n    dfn = os.path.join(download_path, fn)\n\n    if not download_file(url, dfn):\n        xlog.warn(\"download file %s fail.\", url)\n        return\n\n    try:\n        os.mkdir(extract_path)\n        with zipfile.ZipFile(dfn, \"r\") as dz:\n            dz.extractall(extract_path)\n            dz.close()\n        xlog.info(\"Extract %s to %s success.\", fn, extract_path)\n    except Exception as e:\n        xlog.warn(\"unzip %s fail:%r\", dfn, e)\n        shutil.rmtree(extract_path)\n        raise e\n    os.remove(dfn)\n\n\ndef get_sha256(fn):\n    sha256_dict = {}\n    with open(fn, \"r\") as fd:\n        for line in fd.readlines():\n            if not line:\n                break\n            n, sha256 = line.split()[:2]\n            sha256_dict[n] = sha256\n        return sha256_dict\n\n\ndef download_worker():\n    switchyomega_path = os.path.join(top_path, \"SwitchyOmega\")\n    if not os.path.isdir(switchyomega_path):\n        return\n\n    time.sleep(150)\n    sha256_fn = os.path.join(switchyomega_path, \"Sha256.txt\")\n    download_file(\"https://raw.githubusercontent.com/XX-net/XX-Net/master/SwitchyOmega/Sha256.txt\", sha256_fn)\n    sha256_dict = get_sha256(sha256_fn)\n    download_file(\"https://github.com/XX-net/XX-Net/releases/download/5.1.1/SwitchyOmega.zip\",\n                  os.path.join(switchyomega_path, \"SwitchyOmega.zip\"), sha256_dict.get(\"SwitchyOmega.zip\", None))\n    download_file(\"https://github.com/XX-net/XX-Net/releases/download/3.15.0/AutoProxy.xpi\",\n                  os.path.join(switchyomega_path, \"AutoProxy.xpi\"), sha256_dict.get(\"AutoProxy.xpi\", None))\n\n\ndef start_download():\n    th = threading.Thread(target=download_worker, name=\"file_downloader\")\n    th.start()\n    return True\n"
  },
  {
    "path": "code/default/launcher/global_var.py",
    "content": "running = True"
  },
  {
    "path": "code/default/launcher/gtk_tray.py",
    "content": "#!/usr/bin/env python\n# coding:utf-8\n# Contributor:\n#      Phus Lu        <phus.lu@gmail.com>\nimport os\nimport sys\nimport webbrowser\n\nfrom config import config, app_name\nfrom xlog import getLogger\n\nxlog = getLogger(\"launcher\")\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\n\n\nif __name__ == \"__main__\":\n    python_path = os.path.abspath(os.path.join(current_path, os.pardir))\n    noarch_lib = os.path.abspath(os.path.join(python_path, 'lib', 'noarch'))\n    sys.path.append(noarch_lib)\n\n# Only enable AppIndicator in the DEs that are Unity and QT-based\nenable_appind = False\nif 'XDG_CURRENT_DESKTOP' in os.environ:\n    cur_desktops = os.environ['XDG_CURRENT_DESKTOP'].split(':')\n    if {'Unity', 'KDE', 'LXQt', 'ENLIGHTENMENT'}.intersection(cur_desktops):\n        enable_appind = True\n\ntry:\n    import pygtk\n\n    pygtk.require('2.0')\n    import gtk\n    import gtk.gdk as gdk\n\n    use_gi = False\n    xlog.info('Using PyGTK as the GUI Backend.')\nexcept:\n    # How to install gi:\n    # The simple way:\n    #    sudo apt-get install python3-gi\n    # For virtualenv users - The vext way\n    #    pip install vext\n    #    pip install vext.gi\n    # The pure python developer way:\n    #    Install a bunch of developer stuff:\n    #      sudo apt-get install pkg-config libcairo2-dev gcc python3-dev libgirepository1.0-dev\n    #    Install the python packages:\n    #      pip install gobject PyGObject\n    import gi\n\n    gi.require_version('Gtk', '3.0')\n    gi.require_version('Gdk', '3.0')\n    from gi.repository import Gtk as gtk\n    from gi.repository import Gdk as gdk\n\n    use_gi = True\n    xlog.info('Using PyGObject as the GUI Backend.')\n\ngdk.threads_init()\n\nimport module_init\n\nif use_gi:\n    try:\n        gi.require_version('Notify', '0.7')\n        from gi.repository import Notify as notify\n\n        notify.init(app_name + ' Notify')\n        new_notification = notify.Notification.new\n    except:\n        xlog.warn(\"import Notify fail, please install libnotify if possible.\")\n        notify = None\n\n    try:\n        assert (enable_appind)\n        gi.require_version('AppIndicator3', '0.1')\n        from gi.repository import AppIndicator3 as appindicator\n\n        new_appindicator = appindicator.Indicator.new\n        appind_category = appindicator.IndicatorCategory.APPLICATION_STATUS\n        appind_status = appindicator.IndicatorStatus.ACTIVE\n    except:\n        appindicator = None\n        popup_trayicon_menu = lambda m, s, b, t: m.popup(None, None, gtk.StatusIcon.position_menu, s, b, t)\nelse:\n    try:\n        import pynotify as notify\n\n        notify.init(app_name + ' Notify')\n        new_notification = notify.Notification\n    except:\n        xlog.warn(\"import pynotify fail, please install python-notify if possible.\")\n        notify = None\n\n    try:\n        assert (enable_appind)\n        import appindicator\n\n        new_appindicator = appindicator.Indicator\n        appind_category = appindicator.CATEGORY_APPLICATION_STATUS\n        appind_status = appindicator.STATUS_ACTIVE\n    except:\n        appindicator = None\n        popup_trayicon_menu = lambda m, s, b, t: m.popup(None, None, gtk.status_icon_position_menu, b, t, s)\n\n\nclass Gtk_tray():\n    notify_list = []\n\n    def __init__(self):\n        logo_filename = os.path.join(os.path.abspath(current_path), 'web_ui', 'img', app_name, 'favicon.ico')\n\n        if appindicator:\n            self.trayicon = self.appind_trayicon(logo_filename)\n            xlog.info('AppIndicator found and used.')\n        else:\n            self.trayicon = self.gtk_trayicon(logo_filename)\n            xlog.info('Gtk.StatusIcon used.')\n\n    def appind_trayicon(self, logo_filename):\n        trayicon = new_appindicator(app_name, 'indicator-messages', appind_category)\n        trayicon.set_status(appind_status)\n        trayicon.set_attention_icon('indicator-messages-new')\n        trayicon.set_icon(logo_filename)\n        trayicon.set_menu(self.make_menu())\n        try:  # this method does not exist when using pygtk and python2-appindicator\n            trayicon.set_title(app_name)\n        except:\n            pass\n\n        return trayicon\n\n    def gtk_trayicon(self, logo_filename):\n        trayicon = gtk.StatusIcon()\n        trayicon.set_from_file(logo_filename)\n\n        trayicon.connect('popup-menu', lambda i, b, t: popup_trayicon_menu(self.make_menu(), trayicon, b, t))\n        trayicon.connect('activate', self.show_control_web)\n        trayicon.set_tooltip_text(app_name)\n        trayicon.set_title(app_name)\n        trayicon.set_visible(True)\n\n        return trayicon\n\n    def make_menu(self):\n        menu = gtk.Menu()\n        itemlist = [('Config', self.on_show),\n                    ('Reset Each Module', self.on_restart_each_module),\n                    ('Quit', self.on_quit)]\n        for text, callback in itemlist:\n            item = gtk.MenuItem(text)\n            item.connect('activate', callback)\n            item.show()\n            menu.append(item)\n        menu.show()\n        return menu\n\n    def on_show(self, widget=None, data=None):\n        self.show_control_web()\n\n    def notify_general(self, msg=\"msg\", title=\"Title\", buttons={}, timeout=3600):\n        if not notify:\n            return False\n\n        n = new_notification('Test', msg)\n        for k in buttons:\n            data = buttons[k][\"data\"]\n            label = buttons[k][\"label\"]\n            callback = buttons[k][\"callback\"]\n            n.add_action(data, label, callback)\n        n.set_timeout(timeout)\n        n.show()\n        self.notify_list.append(n)\n        return True\n\n    def show_control_web(self, widget=None, data=None):\n        host_port = config.control_port\n        webbrowser.open_new(\"http://127.0.0.1:%s/\" % host_port)\n\n    def on_restart_each_module(self, widget=None, data=None):\n        module_init.stop_all()\n        module_init.start_all_auto()\n\n    def on_quit(self, widget=None, data=None):\n        module_init.stop_all()\n        os._exit(0)\n        gtk.main_quit()\n\n    def serve_forever(self):\n        gdk.threads_enter()\n        gtk.main()\n        gdk.threads_leave()\n\n\nsys_tray = Gtk_tray()\n\n\ndef main():\n    sys_tray.serve_forever()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "code/default/launcher/lang/fa_IR/LC_MESSAGES/messages.po",
    "content": "\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: PROJECT VERSION\\n\"\n\"Report-Msgid-Bugs-To: EMAIL@ADDRESS\\n\"\n\"POT-Creation-Date: 2022-02-25 02:08-0500\\n\"\n\"PO-Revision-Date: 2015-12-06 09:18+0800\\n\"\n\"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n\"\n\"Language: fa_IR\\n\"\n\"Language-Team: fa_IR <LL@li.org>\\n\"\n\"Plural-Forms: nplurals=1; plural=0\\n\"\n\"MIME-Version: 1.0\\n\"\n\"Content-Type: text/plain; charset=utf-8\\n\"\n\"Content-Transfer-Encoding: 8bit\\n\"\n\"Generated-By: Babel 2.14.0\\n\"\n\nmsgid \"Hello!\"\nmsgstr \"سلام!\"\n\nmsgid \"You seem to be on your first visit.\"\nmsgstr \"به نظر می رسد شما در اولین دیدار خود هستید.\"\n\nmsgid \"Learn more\"\nmsgstr \"بیشتر بدانید\"\n\nmsgid \"Notice\"\nmsgstr \"توجه کنید\"\n\nmsgid \"click to view\"\nmsgstr \"برای مشاهده کلیک کنید\"\n\nmsgid \"Version\"\nmsgstr \"نسخه\"\n\nmsgid \"Project main page\"\nmsgstr \"صفحه اصلی پروژه\"\n\nmsgid \"Official Web Site\"\nmsgstr \"وب سایت رسمی\"\n\nmsgid \"Telegram group\"\nmsgstr \"گروه تلگرام\"\n\nmsgid \"Telegram Channel\"\nmsgstr \"کانال تلگرام\"\n\nmsgid \"Bug feedback\"\nmsgstr \"بازخورد اشکال\"\n\nmsgid \"When submitting a bug, please attach \"\nmsgstr \"هنگام ارسال یک اشکال، لطفا ضمیمه\"\n\nmsgid \"the status page \"\nmsgstr \"صفحه وضعیت \"\n\nmsgid \"info and \"\nmsgstr \"اطلاعات و \"\n\nmsgid \"the log page \"\nmsgstr \"صفحه ورود به سیستم \"\n\nmsgid \"contents\"\nmsgstr \"فهرست\"\n\nmsgid \"Collect debug info\"\nmsgstr \"اطلاعات اشکال زدایی را جمع آوری کنید\"\n\nmsgid \"Download\"\nmsgstr \"دانلود کنید\"\n\nmsgid \"Thanks to the following projects\"\nmsgstr \"تشکر از پروژه های زیر\"\n\nmsgid \"About\"\nmsgstr \"در باره\"\n\nmsgid \"General Settings\"\nmsgstr \"تنظیمات عمومی\"\n\nmsgid \"System Version\"\nmsgstr \"نسخه آزمایشی\"\n\nmsgid \"LAN Proxy Setting\"\nmsgstr \"تنظیم پروکسی LAN\"\n\nmsgid \"App List\"\nmsgstr \"فهرست برنامه\"\n\nmsgid \"System Configuration\"\nmsgstr \"گزینه های پیکربندی سیستم\"\n\nmsgid \"Configuration\"\nmsgstr \"پیکربندی\"\n\nmsgid \"Configuring the service[%s]. This page will refresh within %s seconds.\"\nmsgstr \"پیکربندی سرویس [٪ s] را. این صفحه را در عرض٪ s ثانیه تازه کردن.\"\n\nmsgid \"GAE Proxy\"\nmsgstr \"GAE پروکسی\"\n\nmsgid \"X-Tunnel\"\nmsgstr \"\"\n\nmsgid \"Smart Router\"\nmsgstr \"روتر هوشمند\"\n\nmsgid \"Proxy by APP\"\nmsgstr \"پروکسی توسط APP\"\n\nmsgid \"\"\n\"Select which APP should be proxied. You need to restart VPN after change \"\n\"this.\"\nmsgstr \"انتخاب کنید کدام APP باید پروکسی باشد. \"\n\nmsgid \"Select All\"\nmsgstr \"همه را انتخاب کنید\"\n\nmsgid \"Save\"\nmsgstr \"ذخیره کنید\"\n\nmsgid \"Settings saved successfully, Please restart VPN.\"\nmsgstr \"تنظیمات با موفقیت ذخیره شده است.\"\n\nmsgid \"Failed saving settings: \"\nmsgstr \"تنظیمات ذخیره نشد:\"\n\nmsgid \"Failed saving settings.\"\nmsgstr \"تنظیمات ذخیره نشد.\"\n\nmsgid \"Language\"\nmsgstr \"زبان\"\n\nmsgid \"Auto-Startup\"\nmsgstr \"خودکار راه اندازی\"\n\nmsgid \"Popup Status Page on Startup\"\nmsgstr \"پنجره وضعیت صفحه در راه اندازی\"\n\nmsgid \"Allow remote\"\nmsgstr \"اجازه دسترسی از راه دور\"\n\nmsgid \"Help\"\nmsgstr \"کمک\"\n\nmsgid \"Display System Tray(Restarting APP Required)\"\nmsgstr \"نمایش سینی سیستم (شروع مجدد __ مورد نیاز)\"\n\nmsgid \"Display Notification\"\nmsgstr \"نمایش اعلان\"\n\nmsgid \"Display Windows software compatibility suggestions\"\nmsgstr \"نمایش پیشنهادات سازگاری نرم افزار ویندوز\"\n\nmsgid \"Feedback\"\nmsgstr \"بازخورد اشکال\"\n\nmsgid \"Run as Green Software\"\nmsgstr \"به عنوان نرم افزار سبز اجرا شود\"\n\nmsgid \"Module management\"\nmsgstr \"ماژول مدیریت\"\n\nmsgid \"Enable\"\nmsgstr \"فعال کردن\"\n\nmsgid \"Restarting all remote, wait to refresh.\"\nmsgstr \"راه‌اندازی مجدد تمام ریموت‌ها، منتظر بمانید تا بازخوانی شود.\"\n\nmsgid \"Auto-Upgrade to\"\nmsgstr \"خودکار ارتقا به\"\n\nmsgid \"Do not upgrade\"\nmsgstr \"ارتقاء نکنید\"\n\nmsgid \"Notice stable version\"\nmsgstr \"به نسخه پایدار توجه کنید\"\n\nmsgid \"Stable version\"\nmsgstr \"نسخه پایدار\"\n\nmsgid \"Notice test version\"\nmsgstr \"نسخه آزمایشی توجه کنید\"\n\nmsgid \"Test version\"\nmsgstr \"نسخه آزمایشی\"\n\nmsgid \"Check the latest version\"\nmsgstr \"بررسی آخرین نسخه\"\n\nmsgid \"Current version\"\nmsgstr \"نسخه فعلی\"\n\nmsgid \"Version of the test one\"\nmsgstr \"نسخه از آزمون یک\"\n\nmsgid \"Update now\"\nmsgstr \"به روز رسانی در حال حاضر\"\n\nmsgid \"Version of the stable one\"\nmsgstr \"نسخه از یکی از با ثبات\"\n\nmsgid \"Keep old versions count\"\nmsgstr \"تعداد نسخه های قدیمی را نگه دارید\"\n\nmsgid \"keep all\"\nmsgstr \"همه را نگه دارید\"\n\nmsgid \"Manually Manage\"\nmsgstr \"مدیریت دستی\"\n\nmsgid \"Advanced\"\nmsgstr \"پیشرفته\"\n\nmsgid \"All versions download page\"\nmsgstr \"صفحه دانلود همه نسخه ها\"\n\nmsgid \"Released version\"\nmsgstr \"نسخه آزمایشی\"\n\nmsgid \"Released\"\nmsgstr \"منتشر شد\"\n\nmsgid \"Download & Change to\"\nmsgstr \"دانلود کنید\"\n\nmsgid \"no hash check\"\nmsgstr \"بدون هش چک\"\n\nmsgid \"Local version\"\nmsgstr \"نسخه پایدار\"\n\nmsgid \"Local\"\nmsgstr \"محلی\"\n\nmsgid \"Change to this version\"\nmsgstr \"بررسی آخرین نسخه\"\n\nmsgid \"Delete\"\nmsgstr \"حذف\"\n\nmsgid \"Settings saved successfully.\"\nmsgstr \"تنظیمات با موفقیت ذخیره شده است.\"\n\nmsgid \"Settings save fail:\"\nmsgstr \"تنظیمات با موفقیت ذخیره شده است.\"\n\nmsgid \"Deleted successfully.\"\nmsgstr \"موفقیت خارج\"\n\nmsgid \"Deleting local version fail.\"\nmsgstr \"حذف نسخه محلی انجام نشد.\"\n\nmsgid \"Failed getting local versions.\"\nmsgstr \"دریافت نسخه های محلی ناموفق بود.\"\n\n\nmsgid \"Failed getting released versions.\"\nmsgstr \"نسخه های منتشر نشد.\"\n\nmsgid \"(Remote Web Control Enabled)\"\nmsgstr \"(کنترل وب از راه دور فعال شده)\"\n\nmsgid \"Adaptive width\"\nmsgstr \"عرض تطبیقی\"\n\nmsgid \"Exit\"\nmsgstr \"خروج\"\n\nmsgid \"Menu\"\nmsgstr \"منو\"\n\nmsgid \"Remind me later\"\nmsgstr \"بعدا به من یادآوری کن\"\n\nmsgid \"Do not remind me this version\"\nmsgstr \"این نسخه را به من یادآوری نکنید\"\n\nmsgid \"View changes\"\nmsgstr \"مشاهده تغییرات\"\n\nmsgid \"Exited successfully.\"\nmsgstr \"موفقیت خارج\"\n\nmsgid \"Exitting failed.\"\nmsgstr \"Exitting شکست خورده\"\n\nmsgid \"Exitting failed. A network error occurred.\"\nmsgstr \"Exitting شکست خورده است. یک خطای شبکه رخ داده است.\"\n\nmsgid \"new to this version?\"\nmsgstr \"نسخه آزمایشی\"\n\nmsgid \"Unkown error occured. Please refresh the page and try again.\"\nmsgstr \"خطای ناشناخته رخ داد. لطفا صفحه را تازه کنید و دوباره امتحان \"\n\nmsgid \"Updating in progress ...\"\nmsgstr \"به روز رسانی در حال انجام ...\"\n\nmsgid \"New \"\nmsgstr \"جدید\"\n\nmsgid \"Finished.\"\nmsgstr \"تمام شده.\"\n\nmsgid \"Downloading ...\"\nmsgstr \"بارگیری ...\"\n\nmsgid \"Download completed.\"\nmsgstr \"بارگیری کامل\"\n\nmsgid \"Log\"\nmsgstr \"ورود به سیستم\"\n\nmsgid \"Your browser is obsolete. Partial functionality will not be available.\"\nmsgstr \"مرورگر شما منسوخ است.عملکرد جزئی در دسترس نخواهد بود.\"\n\n\nmsgid \"The latest Chrome browser is recommended.\"\nmsgstr \"آخرین مرورگر Chrome توصیه می شود.\"\n\nmsgid \"Search\"\nmsgstr \"جستجو کردن\"\n\nmsgid \"Search all issues\"\nmsgstr \"همه موضوعات را جستجو کنید\"\n\nmsgid \"Status\"\nmsgstr \"وضعیت\"\n\nmsgid \"Property\"\nmsgstr \"ویژگی\"\n\nmsgid \"Value\"\nmsgstr \"ارزش\"\n\nmsgid \"Browser Proxy Setting\"\nmsgstr \"تنظیم پروکسی مرورگر\"\n\nmsgid \"CA status\"\nmsgstr \"وضعیت CA\"\n\nmsgid \"System Proxy\"\nmsgstr \"پروکسی سیستم\"\n\nmsgid \"Modules\"\nmsgstr \"ماژول\"\n\nmsgid \"Launcher Web UI\"\nmsgstr \"UI Launcher Web UI\"\n\nmsgid \"LAN proxy\"\nmsgstr \"پروکسی LAN\"\n\nmsgid \"System Info\"\nmsgstr \"اطلاعات سیستم\"\n\nmsgid \"Diagnostic Info\"\nmsgstr \"اطلاعات تشخیصی\"\n\nmsgid \"Check\"\nmsgstr \"بررسی کنید\"\n\nmsgid \"GitHub issues\"\nmsgstr \"مشکلات GitHub\"\n\nmsgid \"or\"\nmsgstr \"یا\"\n\nmsgid \"Google Group Discussions\"\nmsgstr \"بحث های گروهی گوگل\"\n\nmsgid \"Show Details\"\nmsgstr \"نمایش جزئیات\"\n\nmsgid \"Post to Github issue needs to sign in your Github account\"\nmsgstr \"مسئله ارسال به Github باید وارد حساب Github شما شود\"\n\nmsgid \"Status Info\"\nmsgstr \"اطلاعات وضعیت\"\n\nmsgid \"\"\n\"-----------%0AProblem Description:%0APlease describe your problem, \"\n\"running logs may be needed.%0A%0A-----------%0ADiagnostic information:%0A\"\nmsgstr \"-----------%0توضیحات مشکل:%0APلطفاً مشکل خود را شرح دهید، ممکن است به اجرای گزارش‌ها نیاز باشد.%0A%0A-----------%0ADاطلاعات تشخیصی:%0A\"\n\nmsgid \"disable\"\nmsgstr \"فعال کردن\"\n\nmsgid \"idle\"\nmsgstr \"بیکار\"\n\nmsgid \"working\"\nmsgstr \"کار کردن\"\n\nmsgid \"The status page is empty. Highly likely that \"\nmsgstr \"صفحه وضعیت خالی است. \"\n\nmsgid \" failed getting started. Please follow \"\nmsgstr \"شروع ناموفق. \"\n\nmsgid \"guide\"\nmsgstr \"راهنما\"\n\nmsgid \" to troubleshoot.\"\nmsgstr \"عیب یابی.\"\n\nmsgid \"Your local network failed, please check your network and firewall.\"\nmsgstr \"شبکه محلی شما ناموفق بود، لطفاً شبکه و فایروال خود را بررسی کنید.\"\n\nmsgid \"Force-IPv6\"\nmsgstr \"نیرو-IPV6\"\n\nmsgid \" not available, Please check.\"\nmsgstr \"در دسترس نیست، لطفا بررسی کنید.\"\n\nmsgid \"Force-IPv4\"\nmsgstr \"نیرو-IPV4\"\n\nmsgid \"You may want to $1turn on IP scaner$2.\"\nmsgstr \"ممکن است بخواهید $1 را در IP scaner$2 روشن کنید.\"\n\nmsgid \"\"\n\"You can try <a href=\\\"https://github.com/XX-net/XX-Net/wiki/How-to-turn-\"\n\"on-IPv6\\\">turn on IPv6</a> or <a href=\\\"https://github.com/XX-net/XX-\"\n\"Net/wiki/How-to-use-XTunnel\\\">use X-Tunnel</a>.\"\nmsgstr \"می‌توانید <a href=\\\"https://github.com/XX-net/XX-Net/wiki/How-to-turn-on-IPv6\\\">IPv6 را روشن کنید</a> یا < \"\n\nmsgid \"XX-Net is scanning IP. Please wait about half an hour.\"\nmsgstr \"XX-Net در حال اسکن IP است. \"\n\nmsgid \"\"\n\"Public AppID out of quota, Please <a href=\\\"https://github.com/XX-net/XX-\"\n\"Net/wiki/how-to-create-my-appids\\\" target=\\\"_blank\\\">deploy your own \"\n\"AppID</a>.\"\nmsgstr \"Public AppID خارج از سهمیه، لطفا <a href=\\\"https://github.com/XX-net/XX-Net/wiki/how-to-create-my-appids\\\" target=\\\"_blank\\ \"\n\nmsgid \"\"\n\"Your AppID out of quota, Please <a href=\\\"https://github.com/XX-net/XX-\"\n\"Net/wiki/how-to-create-my-appids\\\" target=\\\"_blank\\\">deploy more \"\n\"AppID</a>.\"\nmsgstr \"شناسه برنامه شما خارج از حد نصاب است، لطفا <a href=\\\"https://github.com/XX-net/XX-Net/wiki/how-to-create-my-appids\\\" target=\\\"_blank\\ \"\n\nmsgid \"No working AppID. Please check.\"\nmsgstr \"AppID کار نمی کند. \"\n\nmsgid \"System is Idle.\"\nmsgstr \"سیستم بیکار است.\"\n\nmsgid \"Connection not established yet.\"\nmsgstr \"هنوز اتصال برقرار نشده است.\"\n\nmsgid \"Please check your browser proxy setting.\"\nmsgstr \"لطفاً تنظیمات پروکسی مرورگر خود را بررسی کنید.\"\n\nmsgid \"Detecting ...\"\nmsgstr \"تشخیص ...\"\n\nmsgid \"Please import certificates to your browser.\"\nmsgstr \"لطفاً گواهی ها را به مرورگر خود وارد کنید.\"\n\nmsgid \"\"\n\"You are using public AppIDs. You are recommended to <a \"\n\"href=\\\"https://github.com/XX-net/XX-Net/wiki/how-to-create-my-appids\\\" \"\n\"target=\\\"_blank\\\">deploy your own AppID</a>.\"\nmsgstr \"شما از AppID های عمومی استفاده می کنید. \"\n\nmsgid \", Everything is OK. Welcome to the FREE Internet.\"\nmsgstr \"، همه چیز اوکی است. \"\n\nmsgid \"No response from process: \"\nmsgstr \"بدون پاسخ از فرآیند:\"\n\nmsgid \". It might have already exited.\"\nmsgstr \"بشرممکن است قبلاً خارج شده باشد.\"\n\nmsgid \"Global PAC Proxy set\"\nmsgstr \"مجموعه پروکسی جهانی PAC\"\n\nmsgid \"Global GAEProxy Proxy set\"\nmsgstr \"مجموعه پروکسی جهانی GAEProxy\"\n\nmsgid \"Global X-Tunnel Proxy set\"\nmsgstr \"مجموعه پروکسی تونل ایکس جهانی\"\n\nmsgid \"Global Smart-Router Proxy set\"\nmsgstr \"مجموعه پروکسی روتر هوشمند جهانی\"\n\nmsgid \"Global Proxy disabled\"\nmsgstr \"پروکسی جهانی غیرفعال است\"\n\n\n\n"
  },
  {
    "path": "code/default/launcher/lang/ru_RU/LC_MESSAGES/messages.po",
    "content": "#\nmsgid \"\"\nmsgstr \"\"\n\nmsgid \"Hello!\"\nmsgstr \"Привет!\"\n\nmsgid \"You seem to be on your first visit.\"\nmsgstr \"Вы, кажется, находитесь в своем первом визите.\"\n\nmsgid \"Learn more\"\nmsgstr \"Узнать больше\"\n\nmsgid \"Notice\"\nmsgstr \"Уведомление\"\n\nmsgid \"click to view\"\nmsgstr \"Нажмите, чтобы просмотреть\"\n\nmsgid \"Version\"\nmsgstr \"Версия\"\n\nmsgid \"Project main page\"\nmsgstr \"Главная страница проекта\"\n\nmsgid \"Official Web Site\"\nmsgstr \"Официальный веб-сайт\"\n\nmsgid \"Telegram group\"\nmsgstr \"Telegram Group\"\n\nmsgid \"Telegram Channel\"\nmsgstr \"Телеграмма канал\"\n\nmsgid \"Bug feedback\"\nmsgstr \"Обратная связь с ошибкой\"\n\nmsgid \"When submitting a bug, please attach \"\nmsgstr \"При отправке ошибки, пожалуйста, прикрепите\"\n\nmsgid \"the status page \"\nmsgstr \"страница статуса\"\n\nmsgid \"info and \"\nmsgstr \"Информация и\"\n\nmsgid \"the log page \"\nmsgstr \"страница журнала\"\n\nmsgid \"contents\"\nmsgstr \"содержимое\"\n\nmsgid \"Collect debug info\"\nmsgstr \"Соберите информацию отладки\"\n\nmsgid \"Download\"\nmsgstr \"Скачать\"\n\nmsgid \"Thanks to the following projects\"\nmsgstr \"Спасибо следующим проектам\"\n\nmsgid \"About\"\nmsgstr \"О\"\n\nmsgid \"General Settings\"\nmsgstr \"общие настройки\"\n\nmsgid \"System Version\"\nmsgstr \"Системная версия\"\n\nmsgid \"LAN Proxy Setting\"\nmsgstr \"Настройка прокси -сервера LAN\"\n\nmsgid \"App List\"\nmsgstr \"Список приложений\"\n\nmsgid \"System Configuration\"\nmsgstr \"Конфигурация системы\"\n\nmsgid \"Configuring the service[%s]. This page will refresh within %s seconds.\"\nmsgstr \"\"\n\"Настройка службы [%s].Эта страница будет освежаться в течение %с секунд.\"\n\nmsgid \"GAE Proxy\"\nmsgstr \"GAE Proxy\"\n\nmsgid \"X-Tunnel\"\nmsgstr \"X-Tunnel\"\n\nmsgid \"Smart Router\"\nmsgstr \"Умный маршрутизатор\"\n\nmsgid \"Proxy by APP\"\nmsgstr \"Прокси от приложения\"\n\nmsgid \"\"\n\"Select which APP should be proxied. You need to restart VPN after change \"\n\"this.\"\nmsgstr \"\"\n\"Выберите, какое приложение должно быть прокси.Вам нужно перезапустить VPN \"\n\"после изменения.\"\n\nmsgid \"Select All\"\nmsgstr \"Выбрать все\"\n\nmsgid \"Save\"\nmsgstr \"Сохранять\"\n\nmsgid \"Settings saved successfully, Please restart VPN.\"\nmsgstr \"Настройки успешно сохранились, пожалуйста, перезапустите VPN.\"\n\nmsgid \"Failed saving settings: \"\nmsgstr \"Неудачные настройки сохранения:\"\n\nmsgid \"Failed saving settings.\"\nmsgstr \"Неудачные настройки сохранения.\"\n\nmsgid \"Language\"\nmsgstr \"Язык\"\n\nmsgid \"Auto-Startup\"\nmsgstr \"Auto-Startup\"\n\nmsgid \"Popup Status Page on Startup\"\nmsgstr \"Страница статуса всплывающего окна в стартапе\"\n\nmsgid \"Allow Remote\"\nmsgstr \"Разрешить удаленное\"\n\nmsgid \"Help\"\nmsgstr \"Помощь\"\n\nmsgid \"Display System Tray(Restarting APP Required)\"\nmsgstr \"Показать системный лоток (приложение перезагрузки требуется)\"\n\nmsgid \"Display Notification\"\nmsgstr \"Отображение уведомления\"\n\nmsgid \"Display Windows software compatibility suggestions\"\nmsgstr \"\"\n\"Показать предложения по совместимости программного обеспечения Windows\"\n\nmsgid \"Feedback\"\nmsgstr \"Обратная связь\"\n\nmsgid \"Run as Green Software\"\nmsgstr \"Работать как зеленое программное обеспечение\"\n\nmsgid \"Module management\"\nmsgstr \"Управление модулем\"\n\nmsgid \"Enable\"\nmsgstr \"Давать возможность\"\n\nmsgid \"Restarting all remote, wait to refresh.\"\nmsgstr \"Перезапустив все удаленные, подождите, чтобы обновить.\"\n\nmsgid \"Auto-Upgrade to\"\nmsgstr \"Автоматическое обновление до\"\n\nmsgid \"Do not upgrade\"\nmsgstr \"Не обновляйтесь\"\n\nmsgid \"Notice stable version\"\nmsgstr \"Обратите внимание на стабильную версию\"\n\nmsgid \"Stable version\"\nmsgstr \"Стабильная версия\"\n\nmsgid \"Notice test version\"\nmsgstr \"Обратите внимание на тестовую версию\"\n\nmsgid \"Test version\"\nmsgstr \"Тестовая версия\"\n\nmsgid \"Check the latest version\"\nmsgstr \"Проверьте последнюю версию\"\n\nmsgid \"Current version\"\nmsgstr \"Текущая версия\"\n\nmsgid \"Version of the test one\"\nmsgstr \"Версия тестирования\"\n\nmsgid \"Update now\"\nmsgstr \"Обновить сейчас\"\n\nmsgid \"Version of the stable one\"\nmsgstr \"Версия стабильного\"\n\nmsgid \"Keep old versions count\"\nmsgstr \"Сохраняйте старые версии\"\n\nmsgid \"keep all\"\nmsgstr \"сохранить все\"\n\nmsgid \"Manually Manage\"\nmsgstr \"Вручную управлять\"\n\nmsgid \"Advanced\"\nmsgstr \"Передовой\"\n\nmsgid \"All versions download page\"\nmsgstr \"Страница загрузки всех версий\"\n\nmsgid \"Released version\"\nmsgstr \"Выпущенная версия\"\n\nmsgid \"Released\"\nmsgstr \"Выпущенный\"\n\nmsgid \"Download & Change to\"\nmsgstr \"Скачать и изменить на\"\n\nmsgid \"no hash check\"\nmsgstr \"НЕТ ХАШКА\"\n\nmsgid \"Local version\"\nmsgstr \"Местная версия\"\n\nmsgid \"Local\"\nmsgstr \"Местный\"\n\nmsgid \"Change to this version\"\nmsgstr \"Изменить эту версию\"\n\nmsgid \"Delete\"\nmsgstr \"Удалить\"\n\nmsgid \"Settings saved successfully.\"\nmsgstr \"Настройки успешно сохранились.\"\n\nmsgid \"Settings save fail:\"\nmsgstr \"Настройки Сохранить\"\n\nmsgid \"Deleted successfully.\"\nmsgstr \"Удален успешно.\"\n\nmsgid \"Deleting local version fail.\"\nmsgstr \"Удаление локальной версии не удастся.\"\n\nmsgid \"Failed getting local versions.\"\nmsgstr \"Не удалось получить местные версии.\"\n\nmsgid \"Failed getting released versions.\"\nmsgstr \"Не удалось получить выпущенные версии.\"\n\nmsgid \"(Remote Web Control Enabled)\"\nmsgstr \"(Удаленный веб -управление включен)\"\n\nmsgid \"Adaptive width\"\nmsgstr \"Адаптивная ширина\"\n\nmsgid \"Exit\"\nmsgstr \"Выход\"\n\nmsgid \"Menu\"\nmsgstr \"Меню\"\n\nmsgid \"Remind me later\"\nmsgstr \"Напомни мне позже\"\n\nmsgid \"Do not remind me this version\"\nmsgstr \"Не напоминайте мне эту версию\"\n\nmsgid \"View changes\"\nmsgstr \"Просмотреть изменения\"\n\nmsgid \"Exited successfully.\"\nmsgstr \"Вышел успешно.\"\n\nmsgid \"Exitting failed.\"\nmsgstr \"Выпуск не удался.\"\n\nmsgid \"Exitting failed. A network error occurred.\"\nmsgstr \"Выпуск не удался.Произошла сетевая ошибка.\"\n\nmsgid \"new to this version?\"\nmsgstr \"новичок в этой версии?\"\n\nmsgid \"Unkown error occured. Please refresh the page and try again.\"\nmsgstr \"\"\n\"Произошла неизвестная ошибка.Пожалуйста, обновите страницу и попробуйте еще \"\n\"раз.\"\n\nmsgid \"Updating in progress ...\"\nmsgstr \"Обновление в процессе ...\"\n\nmsgid \"New \"\nmsgstr \"Новый\"\n\nmsgid \"Finished.\"\nmsgstr \"Законченный.\"\n\nmsgid \"Downloading ...\"\nmsgstr \"Загрузка ...\"\n\nmsgid \"Download completed.\"\nmsgstr \"Загрузка завершена.\"\n\nmsgid \"Info\"\nmsgstr \"Информация\"\n\nmsgid \"System\"\nmsgstr \"Система\"\n\nmsgid \"Log\"\nmsgstr \"Бревно\"\n\nmsgid \"Your browser is obsolete. Partial functionality will not be available.\"\nmsgstr \"Ваш браузер устарел.Частичная функциональность не будет доступна.\"\n\nmsgid \"The latest Chrome browser is recommended.\"\nmsgstr \"Рекомендуется последний Chrome Browser.\"\n\nmsgid \"Search\"\nmsgstr \"Поиск\"\n\nmsgid \"Search all issues\"\nmsgstr \"Ищите все проблемы\"\n\nmsgid \"Status\"\nmsgstr \"Положение дел\"\n\nmsgid \"Property\"\nmsgstr \"Свойство\"\n\nmsgid \"Value\"\nmsgstr \"Ценить\"\n\nmsgid \"Browser Proxy Setting\"\nmsgstr \"Настройка прокси браузера\"\n\nmsgid \"CA status\"\nmsgstr \"Статус CA\"\n\nmsgid \"System Proxy\"\nmsgstr \"Системный прокси\"\n\nmsgid \"Modules\"\nmsgstr \"Модули\"\n\nmsgid \"Launcher Web UI\"\nmsgstr \"Интернет -пользовательский интерфейс\"\n\nmsgid \"LAN proxy\"\nmsgstr \"LAN Proxy\"\n\nmsgid \"System Info\"\nmsgstr \"Системная информация\"\n\nmsgid \"Diagnostic Info\"\nmsgstr \"Диагностическая информация\"\n\nmsgid \"Check\"\nmsgstr \"Проверять\"\n\nmsgid \"GitHub issues\"\nmsgstr \"GitHub выпуски\"\n\nmsgid \"or\"\nmsgstr \"или\"\n\nmsgid \"Google Group Discussions\"\nmsgstr \"Google Group обсуждения\"\n\nmsgid \"Show Details\"\nmsgstr \"Показать детали\"\n\nmsgid \"Post to Github issue needs to sign in your Github account\"\nmsgstr \"Размещение в GitHub. Выпуск должен войти в свою учетную запись GitHub\"\n\nmsgid \"Status Info\"\nmsgstr \"Информация о статусе\"\n\nmsgid \"\"\n\"-----------%0AProblem Description:%0APlease describe your problem, running \"\n\"logs may be needed.%0A%0A-----------%0ADiagnostic information:%0A\"\nmsgstr \"\"\n\"-----------%0a Описание проблемы:%0a, пожалуйста, опишите свою проблему, \"\n\"необходимы журналы.%0a%0a -----------%0a Диагностическая информация:%0A\"\n\nmsgid \"disable\"\nmsgstr \"запрещать\"\n\nmsgid \"idle\"\nmsgstr \"праздный\"\n\nmsgid \"working\"\nmsgstr \"работающий\"\n\nmsgid \"The status page is empty. Highly likely that \"\nmsgstr \"Страница статуса пуста.Весьма вероятно, что\"\n\nmsgid \" failed getting started. Please follow \"\nmsgstr \"Не удалось начать.Пожалуйста, следуйте\"\n\nmsgid \"guide\"\nmsgstr \"гид\"\n\nmsgid \" to troubleshoot.\"\nmsgstr \"Устранение неполадок.\"\n\nmsgid \"Your local network failed, please check your network and firewall.\"\nmsgstr \"\"\n\"Ваша локальная сеть потерпела неудачу, пожалуйста, проверьте свою сеть и \"\n\"брандмауэр.\"\n\nmsgid \"Force-IPv6\"\nmsgstr \"Force-Ipv6\"\n\nmsgid \" not available, Please check.\"\nmsgstr \"Недоступно, пожалуйста, проверьте.\"\n\nmsgid \"Force-IPv4\"\nmsgstr \"Force-Ipv4\"\n\nmsgid \"You may want to $1turn on IP scaner$2.\"\nmsgstr \"Вы можете захотеть провести 1 доллар на IP Scanner $ 2.\"\n\nmsgid \"\"\n\"You can try <a href=\\\"https://github.com/XX-net/XX-Net/wiki/How-to-turn-on-\"\n\"IPv6\\\">turn on IPv6</a> or <a href=\\\"https://github.com/XX-net/XX-\"\n\"Net/wiki/How-to-use-XTunnel\\\">use X-Tunnel</a>.\"\nmsgstr \"\"\n\"Вы можете попробовать <a href=\\\"https://github.com/xx-net/xx-net/wiki/how-\"\n\"to-turn-on-ipv6\\\"> включить ipv6 </a> или <href = \\\"https://github.com/xx-\"\n\"net/xx-net/wiki/how-to-use-xtunnel\\\"> x-tunnel </a>.\"\n\nmsgid \"XX-Net is scanning IP. Please wait about half an hour.\"\nmsgstr \"XX-сеть-это сканирование IP.Пожалуйста, подождите около получаса.\"\n\nmsgid \"\"\n\"Public AppID out of quota, Please <a href=\\\"https://github.com/XX-net/XX-\"\n\"Net/wiki/how-to-create-my-appids\\\" target=\\\"_blank\\\">deploy your own \"\n\"AppID</a>.\"\nmsgstr \"\"\n\"Публичная приложение из квоты, пожалуйста, <a href=\\\"https://github.com/xx-\"\n\"net/xx-net/wiki/how-to-create-my-appids\\\" target=\\\"_blank\\\"> развернуть свой\"\n\" собственный Appid</a>.\"\n\nmsgid \"\"\n\"Your AppID out of quota, Please <a href=\\\"https://github.com/XX-net/XX-\"\n\"Net/wiki/how-to-create-my-appids\\\" target=\\\"_blank\\\">deploy more AppID</a>.\"\nmsgstr \"\"\n\"Ваша приложение из квоты, пожалуйста, <a href=\\\"https://github.com/xx-\"\n\"net/xx-net/wiki/how-to-create-my-appids\\\" target=\\\"_blank\\\"> развернуть \"\n\"более аппликацию </a>.\"\n\nmsgid \"No working AppID. Please check.\"\nmsgstr \"Нет рабочей Аппид.Пожалуйста, проверьте.\"\n\nmsgid \"System is Idle.\"\nmsgstr \"Система бездействует.\"\n\nmsgid \"Connection not established yet.\"\nmsgstr \"Соединение еще не установлено.\"\n\nmsgid \"Please check your browser proxy setting.\"\nmsgstr \"Пожалуйста, проверьте настройку прокси браузера.\"\n\nmsgid \"Detecting ...\"\nmsgstr \"Обнаружение ...\"\n\nmsgid \"Please import certificates to your browser.\"\nmsgstr \"Пожалуйста, импортируйте сертификаты в ваш браузер.\"\n\nmsgid \"\"\n\"You are using public AppIDs. You are recommended to <a \"\n\"href=\\\"https://github.com/XX-net/XX-Net/wiki/how-to-create-my-appids\\\" \"\n\"target=\\\"_blank\\\">deploy your own AppID</a>.\"\nmsgstr \"\"\n\"Вы используете публичные приставки.Вас рекомендуется <a \"\n\"href=\\\"https://github.com/xx-net/xx-net/wiki/how-to-create-my-appids\\\" \"\n\"target=\\\"_blank\\\"> развернуть свое собственное Appid </a>.\"\n\nmsgid \", Everything is OK. Welcome to the FREE Internet.\"\nmsgstr \", Все в порядке.Добро пожаловать в бесплатный интернет.\"\n\nmsgid \"No response from process: \"\nmsgstr \"Нет ответа от процесса:\"\n\nmsgid \". It might have already exited.\"\nmsgstr \"ПолемЭто могло бы уже выйти.\"\n\nmsgid \"Global PAC Proxy set\"\nmsgstr \"Global PAC Proxy Set\"\n\nmsgid \"Global GAEProxy Proxy set\"\nmsgstr \"Глобальный набор GaeProxy Proxy\"\n\nmsgid \"Global X-Tunnel Proxy set\"\nmsgstr \"Глобальный набор прокси X-Tunnel\"\n\nmsgid \"Global Smart-Router Proxy set\"\nmsgstr \"Глобальный набор прокси-карт с интеллектуальными маркировками\"\n\nmsgid \"Global Proxy disabled\"\nmsgstr \"Global Proxy отключен\"\n"
  },
  {
    "path": "code/default/launcher/lang/zh_CN/LC_MESSAGES/messages.po",
    "content": "\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: PROJECT VERSION\\n\"\n\"Report-Msgid-Bugs-To: xxnet.dev@gmail.com\\n\"\n\"POT-Creation-Date: 2022-02-25 02:08-0500\\n\"\n\"PO-Revision-Date: 2017-12-29 12:00+0800\\n\"\n\"Last-Translator: Emphasia@github\\n\"\n\"Language: zh_Hans_CN\\n\"\n\"Language-Team: zh_Hans_CN <LL@li.org>\\n\"\n\"Plural-Forms: nplurals=2; plural=(n != 1)\\n\"\n\"MIME-Version: 1.0\\n\"\n\"Content-Type: text/plain; charset=utf-8\\n\"\n\"Content-Transfer-Encoding: 8bit\\n\"\n\"Generated-By: Babel 2.14.0\\n\"\n\nmsgid \"Hello!\"\nmsgstr \"您好！\"\n\nmsgid \"You seem to be on your first visit.\"\nmsgstr \"您似乎是初次到访。\"\n\nmsgid \"Learn more\"\nmsgstr \"了解更多\"\n\nmsgid \"Notice\"\nmsgstr \"公告\"\n\nmsgid \"click to view\"\nmsgstr \"点击查看\"\n\nmsgid \"Version\"\nmsgstr \"版本\"\n\nmsgid \"Project main page\"\nmsgstr \"项目主页\"\n\nmsgid \"Official Web Site\"\nmsgstr \"官网\"\n\nmsgid \"Telegram group\"\nmsgstr \"电报群\"\n\nmsgid \"Telegram Channel\"\nmsgstr \"电报频道\"\n\nmsgid \"Bug feedback\"\nmsgstr \"问题反馈\"\n\nmsgid \"When submitting a bug, please attach \"\nmsgstr \"报告问题时, 请附上\"\n\nmsgid \"the status page \"\nmsgstr \"状态页\"\n\nmsgid \"info and \"\nmsgstr \"信息和\"\n\nmsgid \"the log page \"\nmsgstr \"日志页\"\n\nmsgid \"contents\"\nmsgstr \"内容\"\n\nmsgid \"Collect debug info\"\nmsgstr \"收集调试信息\"\n\nmsgid \"Download\"\nmsgstr \"下载\"\n\nmsgid \"Thanks to the following projects\"\nmsgstr \"感谢以下项目\"\n\nmsgid \"About\"\nmsgstr \"关于\"\n\nmsgid \"General Settings\"\nmsgstr \"通用\"\n\nmsgid \"System Version\"\nmsgstr \"版本\"\n\nmsgid \"LAN Proxy Setting\"\nmsgstr \"前置代理\"\n\nmsgid \"App List\"\nmsgstr \"应用列表\"\n\nmsgid \"System Configuration\"\nmsgstr \"系统配置 \"\n\nmsgid \"Configuring the service[%s]. This page will refresh within %s seconds.\"\nmsgstr \"正在配置服务 [%s], 页面将在 %s 秒后刷新。\"\n\nmsgid \"GAE Proxy\"\nmsgstr \"GAE前置代理\"\n\nmsgid \"X-Tunnel\"\nmsgstr \"\"\n\nmsgid \"Smart Router\"\nmsgstr \"智能路由\"\n\nmsgid \"Proxy by APP\"\nmsgstr \"选择要代理的APP\"\n\nmsgid \"\"\n\"Select which APP should be proxied. You need to restart VPN after change \"\n\"this.\"\nmsgstr \"选择应该代理哪个APP。 更改此设置后，您需要重新启动 VPN。\"\n\nmsgid \"Select All\"\nmsgstr \"全选 \"\n\nmsgid \"Save\"\nmsgstr \"保存\"\n\nmsgid \"Settings saved successfully, Please restart VPN.\"\nmsgstr \"设置保存成功，请重启VPN\"\n\nmsgid \"Failed saving settings: \"\nmsgstr \"保存配置失败：\"\n\nmsgid \"Failed saving settings.\"\nmsgstr \"保存配置失败。\"\n\nmsgid \"Language\"\nmsgstr \"语言\"\n\nmsgid \"Auto-Startup\"\nmsgstr \"开机自动启动\"\n\nmsgid \"Popup Status Page on Startup\"\nmsgstr \"启动时弹出状态页\"\n\nmsgid \"Allow Remote\"\nmsgstr \"允许远程访问\"\n\nmsgid \"Help\"\nmsgstr \"帮助\"\n\nmsgid \"Display System Tray(Restarting APP Required)\"\nmsgstr \"显示托盘图标(需要重启代理)\"\n\nmsgid \"Display Notification\"\nmsgstr \"显示通知\"\n\nmsgid \"Display Windows software compatibility suggestions\"\nmsgstr \"显示 Windows 软件兼容性建议\"\n\nmsgid \"Feedback\"\nmsgstr \"反馈\"\n\nmsgid \"Run as Green Software\"\nmsgstr \"以绿色方式运行\"\n\nmsgid \"Module management\"\nmsgstr \"模块管理\"\n\nmsgid \"Enable\"\nmsgstr \"启用\"\n\nmsgid \"Restarting all remote, wait to refresh.\"\nmsgstr \"正在重启所有远程程序，请等待刷新。\"\n\nmsgid \"Auto-Upgrade to\"\nmsgstr \"自动升级到\"\n\nmsgid \"Do not upgrade\"\nmsgstr \"不升级\"\n\nmsgid \"Notice stable version\"\nmsgstr \"通知稳定版\"\n\nmsgid \"Stable version\"\nmsgstr \"稳定版\"\n\nmsgid \"Notice test version\"\nmsgstr \"通知测试版\"\n\nmsgid \"Test version\"\nmsgstr \"测试版\"\n\nmsgid \"Check the latest version\"\nmsgstr \"检查最新版本\"\n\nmsgid \"Current version\"\nmsgstr \"当前版本\"\n\nmsgid \"Version of the test one\"\nmsgstr \"测试版\"\n\nmsgid \"Update now\"\nmsgstr \"立即更新\"\n\nmsgid \"Version of the stable one\"\nmsgstr \"稳定版\"\n\nmsgid \"Keep old versions count\"\nmsgstr \"保留的旧版本数\"\n\nmsgid \"keep all\"\nmsgstr \"保留全部\"\n\nmsgid \"Manually Manage\"\nmsgstr \"手动管理\"\n\nmsgid \"Advanced\"\nmsgstr \"高级\"\n\nmsgid \"All versions download page\"\nmsgstr \"全部已发布版本\"\n\nmsgid \"Released version\"\nmsgstr \"发布版本\"\n\nmsgid \"Released\"\nmsgstr \"发布的\"\n\nmsgid \"Download & Change to\"\nmsgstr \"下载并切至\"\n\nmsgid \"no hash check\"\nmsgstr \"不校验\"\n\nmsgid \"Local version\"\nmsgstr \"本地版本\"\n\nmsgid \"Local\"\nmsgstr \"本地的\"\n\nmsgid \"Change to this version\"\nmsgstr \"切至此版本\"\n\nmsgid \"Delete\"\nmsgstr \"删除此版本\"\n\nmsgid \"Settings saved successfully.\"\nmsgstr \"保存设置成功。\"\n\nmsgid \"Settings save fail:\"\nmsgstr \"保存设置失败：\"\n\nmsgid \"Deleted successfully.\"\nmsgstr \"删除成功。\"\n\nmsgid \"Deleting local version fail.\"\nmsgstr \"删除本地版本失败。\"\n\nmsgid \"Failed getting local versions.\"\nmsgstr \"获取本地版本失败。\"\n\nmsgid \"Failed getting released versions.\"\nmsgstr \"获取发布版本失败。\"\n\nmsgid \"(Remote Web Control Enabled)\"\nmsgstr \"(已允许远程访问)\"\n\nmsgid \"Adaptive width\"\nmsgstr \"自适应宽度\"\n\nmsgid \"Exit\"\nmsgstr \"退出\"\n\nmsgid \"Menu\"\nmsgstr \"菜单\"\n\nmsgid \"Remind me later\"\nmsgstr \"以后再提醒我\"\n\nmsgid \"Do not remind me this version\"\nmsgstr \"忽略此版本\"\n\nmsgid \"View changes\"\nmsgstr \"显示变动\"\n\nmsgid \"Exited successfully.\"\nmsgstr \"退出成功。\"\n\nmsgid \"Exitting failed.\"\nmsgstr \"退出失败。\"\n\nmsgid \"Exitting failed. A network error occurred.\"\nmsgstr \"退出失败，遇到网络错误。\"\n\nmsgid \"new to this version?\"\nmsgstr \"第一次使用此版本？\"\n\nmsgid \"Unkown error occured. Please refresh the page and try again.\"\nmsgstr \"发生未知错误，请刷新页面重试。\"\n\nmsgid \"Updating in progress ...\"\nmsgstr \"更新进行中...\"\n\nmsgid \"New \"\nmsgstr \"新\"\n\nmsgid \"Finished.\"\nmsgstr \"\"\n\nmsgid \"Downloading ...\"\nmsgstr \"下载中...\"\n\nmsgid \"Download completed.\"\nmsgstr \"下载完成。\"\n\nmsgid \"Info\"\nmsgstr \"信息和\"\n\nmsgid \"System\"\nmsgstr \"系统\"\n\nmsgid \"Log\"\nmsgstr \"日志\"\n\nmsgid \"Your browser is obsolete. Partial functionality will not be available.\"\nmsgstr \"您的浏览器版本过低, 部分功能将无法使用。\"\n\nmsgid \"The latest Chrome browser is recommended.\"\nmsgstr \"建议您使用最新版本的 Chrome 浏览器。\"\n\nmsgid \"Search\"\nmsgstr \"搜索\"\n\nmsgid \"Search all issues\"\nmsgstr \"在 issue 中搜索（支持 GitHub issue 搜索参数）\"\n\nmsgid \"Status\"\nmsgstr \"状态\"\n\nmsgid \"Property\"\nmsgstr \"属性\"\n\nmsgid \"Value\"\nmsgstr \"值\"\n\nmsgid \"Browser Proxy Setting\"\nmsgstr \"浏览器代理设置\"\n\nmsgid \"CA status\"\nmsgstr \"CA 证书状态\"\n\nmsgid \"System Proxy\"\nmsgstr \"系统代理\"\n\nmsgid \"Modules\"\nmsgstr \"模块\"\n\nmsgid \"Launcher Web UI\"\nmsgstr \"Web 控制页\"\n\nmsgid \"LAN proxy\"\nmsgstr \"前置代理\"\n\nmsgid \"System Info\"\nmsgstr \"系统信息\"\n\nmsgid \"Diagnostic Info\"\nmsgstr \"诊断信息\"\n\nmsgid \"Check\"\nmsgstr \"查看\"\n\nmsgid \"GitHub issues\"\nmsgstr \"GitHub 问题讨论区\"\n\nmsgid \"or\"\nmsgstr \"或\"\n\nmsgid \"Google Group Discussions\"\nmsgstr \"Google Group 讨论组\"\n\nmsgid \"Show Details\"\nmsgstr \"显示详细信息\"\n\nmsgid \"Post to Github issue needs to sign in your Github account\"\nmsgstr \"贴到 GitHub 问题区需要登录 GitHub 账号\"\n\nmsgid \"Status Info\"\nmsgstr \" 状态信息\"\n\nmsgid \"\"\n\"-----------%0AProblem Description:%0APlease describe your problem, \"\n\"running logs may be needed.%0A%0A-----------%0ADiagnostic information:%0A\"\nmsgstr \"-----------%0A问题描述：%0A请在此描述你遇到的问题，必要时贴出相关的日志信息。%0A%0A-----------%0A诊断信息：%0A\"\n\nmsgid \"disable\"\nmsgstr \"禁用\"\n\nmsgid \"idle\"\nmsgstr \"空闲\"\n\nmsgid \"working\"\nmsgstr \"工作\"\n\nmsgid \"The status page is empty. Highly likely that \"\nmsgstr \"状态页显示空白, 很可能 \"\n\nmsgid \" failed getting started. Please follow \"\nmsgstr \" 启动失败, 请按 \"\n\nmsgid \"guide\"\nmsgstr \"指导\"\n\nmsgid \" to troubleshoot.\"\nmsgstr \"去解决。\"\n\nmsgid \"Your local network failed, please check your network and firewall.\"\nmsgstr \"网络无法连接，请检查网络和防火墙设置。\"\n\nmsgid \"Force-IPv6\"\nmsgstr \"仅 IPv6\"\n\nmsgid \" not available, Please check.\"\nmsgstr \" 不可用，请检查。\"\n\nmsgid \"Force-IPv4\"\nmsgstr \"仅 IPv4\"\n\nmsgid \"You may want to $1turn on IP scaner$2.\"\nmsgstr \"您应该考虑$1开启 IP 扫描器$2。\"\n\nmsgid \"\"\n\"You can try <a href=\\\"https://github.com/XX-net/XX-Net/wiki/How-to-turn-\"\n\"on-IPv6\\\">turn on IPv6</a> or <a href=\\\"https://github.com/XX-net/XX-\"\n\"Net/wiki/How-to-use-XTunnel\\\">use X-Tunnel</a>.\"\nmsgstr \"\"\n\"你可以尝试 <a href=\\\"https://github.com/XX-net/XX-\"\n\"Net/wiki/%E5%A6%82%E4%BD%95%E5%BC%80%E5%90%AFIPv6\\\">开启 IPv6</a> 或 <a \"\n\"href=\\\"https://github.com/XX-net/XX-\"\n\"Net/wiki/x-tunnel%E4%BD%BF%E7%94%A8%E6%95%99%E7%A8%8B\\\">使用X-Tunnel</a>。\"\n\nmsgid \"XX-Net is scanning IP. Please wait about half an hour.\"\nmsgstr \"等待扫描IP，建议开启 IPv6。\"\n\nmsgid \"\"\n\"Public AppID out of quota, Please <a href=\\\"https://github.com/XX-net/XX-\"\n\"Net/wiki/how-to-create-my-appids\\\" target=\\\"_blank\\\">deploy your own \"\n\"AppID</a>.\"\nmsgstr \"\"\n\"公共 AppID 配额已用完，请<a href=\\\"https://github.com/XX-net/XX-Net/wiki/how-to-\"\n\"create-my-appids\\\" target=\\\"_blank\\\">部署私有 AppID</a>。\"\n\nmsgid \"\"\n\"Your AppID out of quota, Please <a href=\\\"https://github.com/XX-net/XX-\"\n\"Net/wiki/how-to-create-my-appids\\\" target=\\\"_blank\\\">deploy more \"\n\"AppID</a>.\"\nmsgstr \"\"\n\"您的 AppID 流量已用完，请<a href=\\\"https://github.com/XX-net/XX-Net/wiki/how-to-\"\n\"create-my-appids\\\" target=\\\"_blank\\\">部署更多 AppID</a>。\"\n\nmsgid \"No working AppID. Please check.\"\nmsgstr \"没有可用 AppID，请检查。\"\n\nmsgid \"System is Idle.\"\nmsgstr \"系统空闲。\"\n\nmsgid \"Connection not established yet.\"\nmsgstr \"连接尚未建立。\"\n\nmsgid \"Please check your browser proxy setting.\"\nmsgstr \"请检查浏览器代理设置。\"\n\nmsgid \"Detecting ...\"\nmsgstr \"正在自检...\"\n\nmsgid \"Please import certificates to your browser.\"\nmsgstr \"请导入浏览器 CA 证书。\"\n\nmsgid \"\"\n\"You are using public AppIDs. You are recommended to <a \"\n\"href=\\\"https://github.com/XX-net/XX-Net/wiki/how-to-create-my-appids\\\" \"\n\"target=\\\"_blank\\\">deploy your own AppID</a>.\"\nmsgstr \"\"\n\"您正在使用公共 AppID，因为资源有限，使用上存在限制，建议<a href=\\\"https://github.com/XX-net/XX-\"\n\"Net/wiki/how-to-create-my-appids\\\" target=\\\"_blank\\\">部署私有 AppID</a>。\"\n\nmsgid \", Everything is OK. Welcome to the FREE Internet.\"\nmsgstr \"，一切正常，你可以访问真正的互联网了。\"\n\nmsgid \"No response from process: \"\nmsgstr \"进程：\"\n\nmsgid \". It might have already exited.\"\nmsgstr \" 无响应, 可能已退出。\"\n\nmsgid \"Global PAC Proxy set\"\nmsgstr \"全局 PAC 代理\"\n\nmsgid \"Global GAEProxy Proxy set\"\nmsgstr \"全局 GAEProxy 代理\"\n\nmsgid \"Global X-Tunnel Proxy set\"\nmsgstr \"全局 X-Tunnel 代理\"\n\nmsgid \"Global Smart-Router Proxy set\"\nmsgstr \"全局 Smart-Router 代理\"\n\nmsgid \"Global Proxy disabled\"\nmsgstr \"全局代理禁用\"\n\n"
  },
  {
    "path": "code/default/launcher/mac_helper.c",
    "content": "#include <stdio.h>\n#include <string.h>\n#include <unistd.h>\n\nint main(int argc, const char * argv[]) {\n    if (geteuid() != 0) {\n        fprintf(stderr, \"Must be run as root!\\n\");\n        return 1;\n    }\n    if (argc == 4 && strcmp(argv[1], \"enableauto\") == 0) {\n        execl(\"/usr/sbin/networksetup\", \"networksetup\", \"-setautoproxyurl\", argv[2], argv[3], NULL);\n    } else if (argc == 5 && strcmp(argv[1], \"enablehttp\") == 0) {\n        execl(\"/usr/sbin/networksetup\", \"networksetup\", \"-setwebproxy\", argv[2], argv[3], argv[4], NULL);\n    } else if (argc == 5 && strcmp(argv[1], \"enablehttps\") == 0) {\n        execl(\"/usr/sbin/networksetup\", \"networksetup\", \"-setsecurewebproxy\", argv[2], argv[3], argv[4], NULL);\n    } else if (argc == 3 && strcmp(argv[1], \"disableauto\") == 0) {\n        execl(\"/usr/sbin/networksetup\", \"networksetup\", \"-setautoproxystate\", argv[2], \"off\", NULL);\n    } else if (argc == 3 && strcmp(argv[1], \"disablehttp\") == 0) {\n        execl(\"/usr/sbin/networksetup\", \"networksetup\", \"-setwebproxystate\", argv[2], \"off\", NULL);\n    } else if (argc == 3 && strcmp(argv[1], \"disablehttps\") == 0) {\n        execl(\"/usr/sbin/networksetup\", \"networksetup\", \"-setsecurewebproxystate\", argv[2], \"off\", NULL);\n    } else {\n        fprintf(stderr, \"Usage:\\n\");\n        fprintf(stderr, \"%s enableauto <networkservice> <url>\\n\", argv[0]);\n        fprintf(stderr, \"%s enablehttp <networkservice> <domain> <port number>\\n\", argv[0]);\n        fprintf(stderr, \"%s enablehttps <networkservice> <domain> <port number>\\n\", argv[0]);\n        fprintf(stderr, \"%s disableauto <networkservice>\\n\", argv[0]);\n        fprintf(stderr, \"%s disablehttp <networkservice>\\n\", argv[0]);\n        fprintf(stderr, \"%s disablehttps <networkservice>\\n\", argv[0]);\n    }\n    return 0;\n}\n"
  },
  {
    "path": "code/default/launcher/mac_tray.py",
    "content": "#!/usr/bin/env python3\n# coding:utf-8\n\nimport os\nimport shutil\nimport sys\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nhelper_path = os.path.join('/tmp', 'helper')\n\nif __name__ == \"__main__\":\n    default_path = os.path.abspath(os.path.join(current_path, os.pardir))\n    noarch_lib = os.path.abspath(os.path.join(default_path, 'lib', 'noarch'))\n    sys.path.append(noarch_lib)\n    osx_lib = os.path.join(default_path, 'lib', 'darwin')\n    sys.path.append(osx_lib)\n    extra_lib = \"/System/Library/Frameworks/Python.framework/Versions/3.8/Extras/lib/python/PyObjC\"\n    sys.path.append(extra_lib)\n\nfrom config import config, app_name\nimport module_init\nimport subprocess\nimport webbrowser\n\nfrom xlog import getLogger\nxlog = getLogger(\"launcher\")\n\nimport AppKit\nimport SystemConfiguration\nfrom PyObjCTools import AppHelper\n\n\nclass MacTrayObject(AppKit.NSObject):\n    def __init__(self):\n        pass\n\n    def applicationDidFinishLaunching_(self, notification):\n        setupHelper()\n        loadConfig()\n        self.setupUI()\n        self.registerObserver()\n\n    def setupUI(self):\n        self.autoGaeProxyMenuItem = None\n        self.globalGaeProxyMenuItem = None\n        self.globalXTunnelMenuItem = None\n        self.globalSmartRouterMenuItem = None\n\n        self.statusbar = AppKit.NSStatusBar.systemStatusBar()\n        self.statusitem = self.statusbar.statusItemWithLength_(\n            AppKit.NSSquareStatusItemLength)  # NSSquareStatusItemLength #NSVariableStatusItemLength\n\n        # Set initial image icon\n        icon_path = os.path.join(current_path, \"web_ui\", \"img\", app_name, \"favicon-mac.ico\")\n        image = AppKit.NSImage.alloc().initByReferencingFile_(icon_path)\n        image.setScalesWhenResized_(True)\n        image.setSize_((20, 20))\n        self.statusitem.setImage_(image)\n\n        # Let it highlight upon clicking\n        self.statusitem.setHighlightMode_(1)\n        self.statusitem.setToolTip_(app_name)\n\n        # Get current selected mode\n        proxyState = getProxyState(currentService)\n\n        # Build a very simple menu\n        self.menu = AppKit.NSMenu.alloc().initWithTitle_(app_name)\n\n        menuitem = AppKit.NSMenuItem.alloc().initWithTitle_action_keyEquivalent_('Config', 'config:', '')\n        self.menu.addItem_(menuitem)\n\n        menuitem = AppKit.NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(getCurrentServiceMenuItemTitle(), None, '')\n        self.menu.addItem_(menuitem)\n        self.currentServiceMenuItem = menuitem\n\n        if config.enable_gae_proxy == 1:\n            menuitem = AppKit.NSMenuItem.alloc().initWithTitle_action_keyEquivalent_('Enable Auto GAEProxy',\n                                                                                     'enableAutoProxy:', '')\n            if proxyState == 'pac':\n                menuitem.setState_(AppKit.NSOnState)\n            self.menu.addItem_(menuitem)\n            self.autoGaeProxyMenuItem = menuitem\n\n            menuitem = AppKit.NSMenuItem.alloc().initWithTitle_action_keyEquivalent_('Enable Global GAEProxy',\n                                                                                     'enableGlobalProxy:', '')\n            if proxyState == 'gae':\n                menuitem.setState_(AppKit.NSOnState)\n            self.menu.addItem_(menuitem)\n            self.globalGaeProxyMenuItem = menuitem\n\n        if config.enable_x_tunnel == 1:\n            menuitem = AppKit.NSMenuItem.alloc().initWithTitle_action_keyEquivalent_('Enable Global X-Tunnel',\n                                                                                     'enableGlobalXTunnel:', '')\n            if proxyState == 'x_tunnel':\n                menuitem.setState_(AppKit.NSOnState)\n            self.menu.addItem_(menuitem)\n            self.globalXTunnelMenuItem = menuitem\n\n        if config.enable_smart_router == 1:\n            menuitem = AppKit.NSMenuItem.alloc().initWithTitle_action_keyEquivalent_('Enable Global Smart-Router',\n                                                                                     'enableGlobalSmartRouter:', '')\n            if proxyState == 'smart_router':\n                menuitem.setState_(AppKit.NSOnState)\n            self.menu.addItem_(menuitem)\n            self.globalSmartRouterMenuItem = menuitem\n\n        menuitem = AppKit.NSMenuItem.alloc().initWithTitle_action_keyEquivalent_('Disable Proxy', 'disableProxy:',\n                                                                                 '')\n        if proxyState == 'disable':\n            menuitem.setState_(AppKit.NSOnState)\n        self.menu.addItem_(menuitem)\n        self.disableGaeProxyMenuItem = menuitem\n\n        # Reset Menu Item\n        menuitem = AppKit.NSMenuItem.alloc().initWithTitle_action_keyEquivalent_('Reset Each Module',\n                                                                                 'restartEachModule:', '')\n        self.menu.addItem_(menuitem)\n        # Default event\n        menuitem = AppKit.NSMenuItem.alloc().initWithTitle_action_keyEquivalent_('Quit', 'windowWillClose:', '')\n        self.menu.addItem_(menuitem)\n        # Bind it to the status item\n        self.statusitem.setMenu_(self.menu)\n\n        # Hide dock icon\n        AppKit.NSApp.setActivationPolicy_(AppKit.NSApplicationActivationPolicyProhibited)\n\n    def updateStatusBarMenu(self):\n        self.currentServiceMenuItem.setTitle_(getCurrentServiceMenuItemTitle())\n\n        # Remove Tick before All Menu Items\n        if self.autoGaeProxyMenuItem:\n            self.autoGaeProxyMenuItem.setState_(AppKit.NSOffState)\n        if self.globalGaeProxyMenuItem:\n            self.globalGaeProxyMenuItem.setState_(AppKit.NSOffState)\n        if self.globalXTunnelMenuItem:\n            self.globalXTunnelMenuItem.setState_(AppKit.NSOffState)\n        if self.globalSmartRouterMenuItem:\n            self.globalSmartRouterMenuItem.setState_(AppKit.NSOffState)\n        self.disableGaeProxyMenuItem.setState_(AppKit.NSOffState)\n\n        # Get current selected mode\n        proxyState = getProxyState(currentService)\n\n        # Update Tick before Menu Item\n        if proxyState == 'pac' and self.autoGaeProxyMenuItem:\n            self.autoGaeProxyMenuItem.setState_(AppKit.NSOnState)\n        elif proxyState == 'gae' and self.globalGaeProxyMenuItem:\n            self.globalGaeProxyMenuItem.setState_(AppKit.NSOnState)\n        elif proxyState == 'x_tunnel' and self.globalXTunnelMenuItem:\n            self.globalXTunnelMenuItem.setState_(AppKit.NSOnState)\n        elif proxyState == 'smart_router' and self.globalSmartRouterMenuItem:\n            self.globalSmartRouterMenuItem.setState_(AppKit.NSOnState)\n        else:\n            self.disableGaeProxyMenuItem.setState_(AppKit.NSOnState)\n\n        # Trigger autovalidation\n        self.menu.update()\n\n    def validateMenuItem_(self, menuItem):\n        return currentService or (menuItem != self.autoGaeProxyMenuItem and\n                                  menuItem != self.globalGaeProxyMenuItem and\n                                  menuItem != self.globalXTunnelMenuItem and\n                                  menuItem != self.globalSmartRouterMenuItem and\n                                  menuItem != self.disableGaeProxyMenuItem)\n\n    def presentAlert_withTitle_(self, msg, title):\n        self.performSelectorOnMainThread_withObject_waitUntilDone_('presentAlertWithInfo:', [title, msg], True)\n        return self.alertReturn\n\n    def presentAlertWithInfo_(self, info):\n        alert = AppKit.NSAlert.alloc().init()\n        alert.setMessageText_(info[0])\n        alert.setInformativeText_(info[1])\n        alert.addButtonWithTitle_(\"OK\")\n        alert.addButtonWithTitle_(\"Cancel\")\n        self.alertReturn = alert.runModal() == AppKit.NSAlertFirstButtonReturn\n\n    def registerObserver(self):\n        nc = AppKit.NSWorkspace.sharedWorkspace().notificationCenter()\n        nc.addObserver_selector_name_object_(self, 'windowWillClose:', AppKit.NSWorkspaceWillPowerOffNotification, None)\n\n    def windowWillClose_(self, notification):\n        executeResult = subprocess.check_output(['networksetup', '-listallnetworkservices'])\n        services = executeResult.split(b'\\n')\n        services = [service for service in services if service and service.find(b'*') == -1 and getProxyState(\n            service) != 'disable']  # Remove disabled services and empty lines\n\n        if len(services) > 0:\n            self.disableProxy_(True)\n\n        module_init.stop_all()\n        os._exit(0)\n        AppKit.NSApp.terminate_(self)\n\n    def config_(self, notification):\n        host_port = config.control_port\n        webbrowser.open_new(\"http://127.0.0.1:%s/\" % host_port)\n\n    def restartEachModule_(self, _):\n        module_init.stop_all()\n        module_init.start_all_auto()\n\n    def enableAutoProxy_(self, _):\n        try:\n            helperDisableGlobalProxy(currentService)\n            helperEnableAutoProxy(currentService)\n        except:\n            disableGlobalProxyCommand = getDisableGlobalProxyCommand(currentService)\n            enableAutoProxyCommand = getEnableAutoProxyCommand(currentService)\n            executeCommand = 'do shell script \"%s;%s\" with administrator privileges' % (\n            disableGlobalProxyCommand, enableAutoProxyCommand)\n\n            xlog.info(\"try enable auto proxy:%s\", executeCommand)\n            subprocess.call(['osascript', '-e', executeCommand])\n        config.os_proxy_mode = \"pac\"\n        config.save()\n        self.updateStatusBarMenu()\n\n    def enableGlobalProxy_(self, _):\n        try:\n            helperDisableAutoProxy(currentService)\n            helperEnableGlobalProxy(currentService)\n        except:\n            disableAutoProxyCommand = getDisableAutoProxyCommand(currentService)\n            enableGlobalProxyCommand = getEnableGlobalProxyCommand(currentService)\n            executeCommand = 'do shell script \"%s;%s\" with administrator privileges' % (\n            disableAutoProxyCommand, enableGlobalProxyCommand)\n\n            xlog.info(\"try enable global proxy:%s\", executeCommand)\n            subprocess.call(['osascript', '-e', executeCommand])\n        config.os_proxy_mode = \"gae\"\n        config.save()\n        self.updateStatusBarMenu()\n\n    def enableGlobalXTunnel_(self, _):\n        try:\n            helperDisableAutoProxy(currentService)\n            helperEnableXTunnelProxy(currentService)\n        except:\n            disableAutoProxyCommand = getDisableAutoProxyCommand(currentService)\n            enableXTunnelProxyCommand = getEnableXTunnelProxyCommand(currentService)\n            executeCommand = 'do shell script \"%s;%s\" with administrator privileges' % (\n            disableAutoProxyCommand, enableXTunnelProxyCommand)\n\n            xlog.info(\"try enable global x-tunnel proxy:%s\", executeCommand)\n            subprocess.call(['osascript', '-e', executeCommand])\n        config.os_proxy_mode = \"x_tunnel\"\n        config.save()\n        self.updateStatusBarMenu()\n\n    def enableGlobalSmartRouter_(self, _):\n        try:\n            helperDisableAutoProxy(currentService)\n            helperEnableSmartRouterProxy(currentService)\n        except:\n            disableAutoProxyCommand = getDisableAutoProxyCommand(currentService)\n            enableSmartRouterCommand = getEnableSmartRouterProxyCommand(currentService)\n            executeCommand = 'do shell script \"%s;%s\" with administrator privileges' % (\n            disableAutoProxyCommand, enableSmartRouterCommand)\n\n            xlog.info(\"try enable global smart-router proxy:%s\", executeCommand)\n            subprocess.call(['osascript', '-e', executeCommand])\n        config.os_proxy_mode = \"smart_router\"\n        config.save()\n        self.updateStatusBarMenu()\n\n    def disableProxy_(self, is_quit=False):\n        try:\n            helperDisableAutoProxy(currentService)\n            helperDisableGlobalProxy(currentService)\n        except:\n            disableAutoProxyCommand = getDisableAutoProxyCommand(currentService)\n            disableGlobalProxyCommand = getDisableGlobalProxyCommand(currentService)\n            executeCommand = 'do shell script \"%s;%s\" with administrator privileges' % (\n            disableAutoProxyCommand, disableGlobalProxyCommand)\n\n            xlog.info(\"try disable proxy:%s\", executeCommand)\n            subprocess.call(['osascript', '-e', executeCommand])\n\n        if is_quit != True:\n            # in case \"Disable proxy\" trigger by menu, is_quit will be a {NSMenuItem}\n            config.os_proxy_mode = \"disable\"\n            config.save()\n        self.updateStatusBarMenu()\n\n\ndef setupHelper():\n    try:\n        with open(os.devnull) as devnull:\n            subprocess.check_call(helper_path, stderr=devnull)\n    except:\n        if os.path.exists(helper_path):\n            os.remove(helper_path)\n        shutil.copyfile(os.path.join(current_path, 'mac_helper'), helper_path)\n\n        chownCommand = \"chown root \\\\\\\"%s\\\\\\\"\" % helper_path\n        chmodCommand = \"chmod 4755 \\\\\\\"%s\\\\\\\"\" % helper_path\n        executeCommand = 'do shell script \"%s;%s\" with administrator privileges' % (\n            chownCommand,\n            chmodCommand\n        )\n\n        xlog.info(\"try setup helper:%s\", executeCommand)\n        subprocess.call(['osascript', '-e', executeCommand])\n\n\ndef getCurrentServiceMenuItemTitle():\n    if currentService:\n        return 'Connection: %s' % currentService\n    else:\n        return 'Connection: None'\n\n\ndef getProxyState(service):\n    if not service:\n        return\n\n    # Check if auto proxy is enabled\n    executeResult = subprocess.check_output(['networksetup', '-getautoproxyurl', service])\n    if (executeResult.find(b'http://127.0.0.1:8086/proxy.pac\\nEnabled: Yes') != -1):\n        return \"pac\"\n\n    # Check if global proxy is enabled\n    executeResult = subprocess.check_output(['networksetup', '-getwebproxy', service])\n    if (executeResult.find(b'Enabled: Yes\\nServer: 127.0.0.1\\nPort: 8087') != -1):\n        return \"gae\"\n\n    # Check if global proxy is enabled\n    if (executeResult.find(b'Enabled: Yes\\nServer: 127.0.0.1\\nPort: 1080') != -1):\n        return \"x_tunnel\"\n\n    if (executeResult.find(b'Enabled: Yes\\nServer: 127.0.0.1\\nPort: 8086') != -1):\n        return \"smart_router\"\n\n    return \"disable\"\n\n\n# Generate commands for Apple Script\ndef getEnableAutoProxyCommand(service):\n    return \"networksetup -setautoproxyurl \\\\\\\"%s\\\\\\\" \\\\\\\"http://127.0.0.1:8086/proxy.pac\\\\\\\"\" % service\n\n\ndef getDisableAutoProxyCommand(service):\n    return \"networksetup -setautoproxystate \\\\\\\"%s\\\\\\\" off\" % service\n\n\ndef getEnableGlobalProxyCommand(service):\n    enableHttpProxyCommand = \"networksetup -setwebproxy \\\\\\\"%s\\\\\\\" 127.0.0.1 8087\" % service\n    enableHttpsProxyCommand = \"networksetup -setsecurewebproxy \\\\\\\"%s\\\\\\\" 127.0.0.1 8087\" % service\n    return \"%s;%s\" % (enableHttpProxyCommand, enableHttpsProxyCommand)\n\n\ndef getEnableXTunnelProxyCommand(service):\n    enableHttpProxyCommand = \"networksetup -setwebproxy \\\\\\\"%s\\\\\\\" 127.0.0.1 1080\" % service\n    enableHttpsProxyCommand = \"networksetup -setsecurewebproxy \\\\\\\"%s\\\\\\\" 127.0.0.1 1080\" % service\n    return \"%s;%s\" % (enableHttpProxyCommand, enableHttpsProxyCommand)\n\n\ndef getEnableSmartRouterProxyCommand(service):\n    enableHttpProxyCommand = \"networksetup -setwebproxy \\\\\\\"%s\\\\\\\" 127.0.0.1 8086\" % service\n    enableHttpsProxyCommand = \"networksetup -setsecurewebproxy \\\\\\\"%s\\\\\\\" 127.0.0.1 8086\" % service\n    return \"%s;%s\" % (enableHttpProxyCommand, enableHttpsProxyCommand)\n\n\ndef getDisableGlobalProxyCommand(service):\n    disableHttpProxyCommand = \"networksetup -setwebproxystate \\\\\\\"%s\\\\\\\" off\" % service\n    disableHttpsProxyCommand = \"networksetup -setsecurewebproxystate \\\\\\\"%s\\\\\\\" off\" % service\n    return \"%s;%s\" % (disableHttpProxyCommand, disableHttpsProxyCommand)\n\n\n# Call helper\ndef helperEnableAutoProxy(service):\n    subprocess.check_call([helper_path, 'enableauto', service, 'http://127.0.0.1:8086/proxy.pac'])\n\n\ndef helperDisableAutoProxy(service):\n    subprocess.check_call([helper_path, 'disableauto', service])\n\n\ndef helperEnableGlobalProxy(service):\n    subprocess.check_call([helper_path, 'enablehttp', service, '127.0.0.1', '8087'])\n    subprocess.check_call([helper_path, 'enablehttps', service, '127.0.0.1', '8087'])\n\n\ndef helperEnableXTunnelProxy(service):\n    subprocess.check_call([helper_path, 'enablehttp', service, '127.0.0.1', '1080'])\n    subprocess.check_call([helper_path, 'enablehttps', service, '127.0.0.1', '1080'])\n\n\ndef helperEnableSmartRouterProxy(service):\n    subprocess.check_call([helper_path, 'enablehttp', service, '127.0.0.1', '8086'])\n    subprocess.check_call([helper_path, 'enablehttps', service, '127.0.0.1', '8086'])\n\n\ndef helperDisableGlobalProxy(service):\n    subprocess.check_call([helper_path, 'disablehttp', service])\n    subprocess.check_call([helper_path, 'disablehttps', service])\n\n\ndef loadConfig():\n    if not currentService:\n        return\n    proxy_setting = config.os_proxy_mode\n    if getProxyState(currentService) == proxy_setting:\n        return\n    try:\n        if proxy_setting == \"pac\" and config.enable_smart_router:\n            helperDisableGlobalProxy(currentService)\n            helperEnableAutoProxy(currentService)\n        elif proxy_setting == \"gae\" and config.enable_gae_proxy:\n            helperDisableAutoProxy(currentService)\n            helperEnableGlobalProxy(currentService)\n        elif proxy_setting == \"x_tunnel\" and config.enable_x_tunnel:\n            helperDisableAutoProxy(currentService)\n            helperEnableXTunnelProxy(currentService)\n        elif proxy_setting == \"smart_router\" and config.enable_smart_router:\n            helperDisableAutoProxy(currentService)\n            helperEnableSmartRouterProxy(currentService)\n        else:\n            helperDisableAutoProxy(currentService)\n            helperDisableGlobalProxy(currentService)\n        # else:\n        #     xlog.warn(\"proxy_setting:%r\", proxy_setting)\n    except Exception as e:\n        xlog.warn(\"helper failed:%r, please manually reset proxy settings after switching connection\", e)\n\n\nsys_tray = MacTrayObject.alloc().init()\ncurrentService = None\n\n\ndef fetchCurrentService(protocol):\n    global currentService\n    status = SystemConfiguration.SCDynamicStoreCopyValue(None, \"State:/Network/Global/\" + protocol)\n    if not status:\n        currentService = None\n        return\n    serviceID = status['PrimaryService']\n    service = SystemConfiguration.SCDynamicStoreCopyValue(None, \"Setup:/Network/Service/\" + serviceID)\n    if not service:\n        currentService = None\n        return\n    currentService = service['UserDefinedName']\n\n\n@AppKit.objc.callbackFor(AppKit.CFNotificationCenterAddObserver)\ndef networkChanged(center, observer, name, object, userInfo):\n    fetchCurrentService('IPv4')\n    loadConfig()\n    sys_tray.updateStatusBarMenu()\n\n\n# Note: the following code can't run in class\ndef serve_forever():\n    app = AppKit.NSApplication.sharedApplication()\n    app.setDelegate_(sys_tray)\n\n    # Listen for network change\n    nc = AppKit.CFNotificationCenterGetDarwinNotifyCenter()\n    AppKit.CFNotificationCenterAddObserver(nc, None, networkChanged, \"com.apple.system.config.network_change\", None,\n                                           AppKit.CFNotificationSuspensionBehaviorDeliverImmediately)\n\n    fetchCurrentService('IPv4')\n    AppHelper.runEventLoop()\n\n\ndef on_quit(widget=None, data=None):\n    # helperDisableAutoProxy(currentService)\n    # helperDisableGlobalProxy(currentService)\n    sys_tray.windowWillClose_(None)\n\n\ndef main():\n    serve_forever()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "code/default/launcher/module_init.py",
    "content": "import subprocess\nimport threading\nimport os\nimport sys\nfrom config import config\n\nfrom xlog import getLogger\nxlog = getLogger(\"launcher\")\nimport web_control\nimport time\n\nproc_handler = {}\n\nxargs = {}\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nroot_path = os.path.abspath(os.path.join(current_path, os.pardir))\nif root_path not in sys.path:\n    sys.path.append(root_path)\n\nimport env_info\ndata_launcher_path = os.path.join(env_info.data_path, 'launcher')\nrunning_file = os.path.join(data_launcher_path, \"Running.Lck\")\n\n\ndef start(module):\n    if module == \"all\":\n        modules = [\"gae_proxy\", \"smart_router\", \"x_tunnel\"]\n        for m in modules:\n            if not getattr(config,\"enable_\" + m):\n                continue\n\n            start(m)\n        return\n\n    elif not os.path.isdir(os.path.join(root_path, module)):\n        return\n\n    try:\n        if module not in config.all_modules:\n            xlog.error(\"module not exist %s\", module)\n            raise Exception()\n\n        if module in proc_handler:\n            xlog.error(\"module %s is running\", module)\n            return \"module is running\"\n\n        if module not in proc_handler:\n            proc_handler[module] = {}\n\n        if os.path.isfile(os.path.join(root_path, module, \"__init__.py\")):\n            if \"imp\" not in proc_handler[module]:\n                proc_handler[module][\"imp\"] = __import__(module, globals(), locals(), ['local'], 0)\n\n            _local = proc_handler[module][\"imp\"].local\n            p = threading.Thread(target=_local.start, args=([xargs]), name=\"%s_start\" % module)\n            p.daemon = True\n            p.start()\n            proc_handler[module][\"proc\"] = p\n\n            while not _local.is_ready():\n                time.sleep(0.1)\n        else:\n            script_path = os.path.join(root_path, module, 'start.py')\n            if not os.path.isfile(script_path):\n                xlog.warn(\"start module script not exist:%s\", script_path)\n                return \"fail\"\n\n            proc_handler[module][\"proc\"] = subprocess.Popen([sys.executable, script_path], shell=False)\n\n        xlog.info(\"module %s started\", module)\n\n    except Exception as e:\n        xlog.exception(\"start module %s fail:%s\", module, e)\n        raise\n    return \"start success.\"\n\n\ndef stop(module):\n    try:\n        if module == \"all\":\n            modules = list(proc_handler)\n            for m in modules:\n                stop(m)\n            return\n\n        elif module not in proc_handler:\n            xlog.error(\"module %s not running\", module)\n            return\n\n        if os.path.isfile(os.path.join(root_path, module, \"__init__.py\")):\n\n            _local = proc_handler[module][\"imp\"].local\n            xlog.debug(\"start to terminate %s module\", module)\n            _local.stop()\n            xlog.debug(\"module %s stopping\", module)\n            while _local.is_ready():\n                time.sleep(0.1)\n        else:\n            proc_handler[module][\"proc\"].terminate()  # Sends SIGTERM\n            proc_handler[module][\"proc\"].wait()\n\n        del proc_handler[module]\n\n        xlog.info(\"module %s stopped\", module)\n    except Exception as e:\n        xlog.exception(\"stop module %s fail:%s\", module, e)\n        return \"Except:%s\" % e\n    return \"stop success.\"\n\n\ndef call_each_module(api_name, args):\n    for module in proc_handler:\n        try:\n            apis = proc_handler[module][\"imp\"].local.apis\n            if not hasattr(apis, api_name):\n                continue\n            api = getattr(apis, api_name)\n            api(args)\n        except Exception as e:\n            xlog.exception(\"call %s api:%s, except:%r\", module, api_name, e)\n\n\ndef start_all_auto():    \n    global running_file\n    if not os.path.isfile(running_file):\n        open(running_file, 'a').close()\n\n    for module in config.all_modules:\n        if module in [\"launcher\"]:\n            continue\n        if not os.path.isdir(os.path.join(root_path, module)):\n            continue\n        if getattr(config, \"enable_\" + module):\n            start_time = time.time()\n            start(module)\n            # web_control.confirm_module_ready(config.get([\"modules\", module, \"control_port\"], 0))\n            finished_time = time.time()\n            xlog.info(\"start %s time cost:%d ms\", module, (finished_time - start_time) * 1000)\n\n\ndef stop_all():\n    global running_file\n    running_modules = [k for k in proc_handler]\n    for module in running_modules:\n        stop(module)\n\n    try:\n        os.remove(running_file)\n    except:\n        pass"
  },
  {
    "path": "code/default/launcher/non_tray.py",
    "content": "#!/usr/bin/env python\n# coding:utf-8\n\nimport os\nimport time\n\nimport global_var\n\n\nclass None_tray():\n    def notify_general(self, msg=\"msg\", title=\"Title\", buttons={}, timeout=3600):\n        pass\n\n    def on_quit(self, widget=None, data=None):\n        import module_init\n\n        global_var.running = False\n        module_init.stop_all()\n        os._exit(0)\n\n    def serve_forever(self):\n        while global_var.running:\n            time.sleep(10)\n\n\nsys_tray = None_tray()\n\n\ndef main():\n    sys_tray.serve_forever()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "code/default/launcher/post_update.py",
    "content": "import os\nimport shutil\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nroot_path = os.path.abspath(os.path.join(current_path, os.pardir))\ntop_path = os.path.abspath(os.path.join(root_path, os.pardir, os.pardir))\n\nfrom xlog import getLogger\nxlog = getLogger(\"launcher\")\nfrom config import config\n\n\ndef check():\n    import update_from_github\n    current_version = update_from_github.current_version()\n    last_run_version = config.last_run_version\n    if last_run_version == \"0.0.0\":\n        postUpdateStat = \"isNew\"\n    elif last_run_version != current_version:\n        postUpdateStat = \"isPostUpdate\"\n        run(last_run_version)\n    else:\n        return\n    config.postUpdateStat = postUpdateStat\n    config.last_run_version = current_version\n    config.save()\n\n\ndef run(last_run_version):\n    if config.auto_start == 1:\n        import autorun\n        autorun.enable()\n\n    if os.path.isdir(os.path.join(top_path, 'launcher')):\n        shutil.rmtree(os.path.join(top_path, 'launcher'))  # launcher is for auto-update from 2.X\n"
  },
  {
    "path": "code/default/launcher/setup.py",
    "content": "#!/usr/bin/env python\n\nfrom config import config\nimport os\nimport re\nimport shutil\nimport subprocess\nimport sys\nimport time\nimport zipfile\n\ntry:\n    from urllib.request import build_opener, ProxyHandler\nexcept ImportError:\n    from urllib2 import build_opener, ProxyHandler\n\nimport env_info\nfrom xlog import getLogger\nxlog = getLogger(\"launcher\")\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\npython_path = os.path.abspath(os.path.join(current_path, os.pardir))\nnoarch_lib = os.path.abspath(os.path.join(python_path, 'lib', 'noarch'))\nsys.path.append(noarch_lib)\n\nopener = build_opener()\n\nroot_path = os.path.abspath(os.path.join(current_path, os.pardir))\ndownload_path = os.path.join(env_info.data_path, 'downloads')\n\nxxnet_unzip_path = \"\"\n\n\ndef get_XXNet():\n    global xxnet_unzip_path\n\n    def download_file(url, file):\n        try:\n            xlog.info(\"download %s to %s\", url, file)\n            req = opener.open(url)\n            CHUNK = 16 * 1024\n            with open(file, 'wb') as fp:\n                while True:\n                    chunk = req.read(CHUNK)\n                    if not chunk:\n                        break\n                    fp.write(chunk)\n            return True\n        except:\n            xlog.info(\"download %s to %s fail\", url, file)\n            return False\n\n    def get_xxnet_url_version(readme_file):\n\n        try:\n            fd = open(readme_file, \"r\")\n            lines = fd.readlines()\n            p = re.compile(r'https://codeload.github.com/XX-net/XX-Net/zip/([0-9]+)\\.([0-9]+)\\.([0-9]+)')\n            for line in lines:\n                m = p.match(line)\n                if m:\n                    version = m.group(1) + \".\" + m.group(2) + \".\" + m.group(3)\n                    return m.group(0), version\n        except Exception as e:\n            xlog.exception(\"get version fail:%s\", e)\n        raise \"get_version_fail:\" % readme_file\n\n    readme_url = \"https://raw.githubusercontent.com/XX-net/XX-Net/master/README.md\"\n    readme_targe = os.path.join(download_path, \"README.md\")\n    if not os.path.isdir(download_path):\n        os.mkdir(download_path)\n    if not download_file(readme_url, readme_targe):\n        raise \"get README fail:\" + readme_url\n    xxnet_url, xxnet_version = get_xxnet_url_version(readme_targe)\n    xxnet_unzip_path = os.path.join(download_path, \"XX-Net-%s\" % xxnet_version)\n    xxnet_zip_file = os.path.join(download_path, \"XX-Net-%s.zip\" % xxnet_version)\n\n    if not download_file(xxnet_url, xxnet_zip_file):\n        raise \"download xxnet zip fail:\" + download_path\n\n    with zipfile.ZipFile(xxnet_zip_file, \"r\") as dz:\n        dz.extractall(download_path)\n        dz.close()\n\n\ndef install_xxnet_files():\n    def sha1_file(filename):\n        import hashlib\n\n        BLOCKSIZE = 65536\n        hasher = hashlib.sha1()\n        try:\n            with open(filename, 'rb') as afile:\n                buf = afile.read(BLOCKSIZE)\n                while len(buf) > 0:\n                    hasher.update(buf)\n                    buf = afile.read(BLOCKSIZE)\n            return hasher.hexdigest()\n        except:\n            return False\n        pass\n\n    for root, subdirs, files in os.walk(xxnet_unzip_path):\n        # print(\"root:\", root)\n        relate_path = root[len(xxnet_unzip_path) + 1:]\n        for subdir in subdirs:\n\n            target_path = os.path.join(root_path, relate_path, subdir)\n            if not os.path.isdir(target_path):\n                xlog.info(\"mkdir %s\", target_path)\n                os.mkdir(target_path)\n\n        for filename in files:\n            if relate_path == os.path.join(\"data\", \"gae_proxy\") and filename == \"config.ini\":\n                continue\n            if relate_path == os.path.join(\"data\", \"launcher\") and filename == \"config.yaml\":\n                continue\n            src_file = os.path.join(root, filename)\n            dst_file = os.path.join(root_path, relate_path, filename)\n            if not os.path.isfile(dst_file) or sha1_file(src_file) != sha1_file(dst_file):\n                shutil.copy(src_file, dst_file)\n                xlog.info(\"copy %s => %s\", src_file, dst_file)\n\n\ndef update_environment():\n    get_XXNet()\n    install_xxnet_files()\n\n\ndef wait_xxnet_exit():\n    def http_request(url, method=\"GET\"):\n        proxy_handler = ProxyHandler({})\n        opener = build_opener(proxy_handler)\n        try:\n            req = opener.open(url)\n            return req\n        except Exception as e:\n            # logging.exception(\"web_control http_request:%s fail:%s\", url, e)\n            return False\n\n    for i in range(20):\n        host_port = config.control_port\n        req_url = \"http://127.0.0.1:{port}/quit\".format(port=host_port)\n        if http_request(req_url) is False:\n            return True\n        time.sleep(1)\n    return False\n\n\ndef run_new_start_script():\n    current_path = os.path.dirname(os.path.abspath(__file__))\n    start_sript = os.path.abspath(os.path.join(current_path, \"start.py\"))\n    subprocess.Popen([sys.executable, start_sript], shell=False)\n\n\ndef main():\n    wait_xxnet_exit()\n    update_environment()\n\n    time.sleep(2)\n    xlog.info(\"setup start run new launcher\")\n    run_new_start_script()\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "code/default/launcher/simple_i18n.py",
    "content": "\nimport os\nimport sys\n\nimport utils\nfrom config import get_language\nfrom xlog import getLogger\nxlog = getLogger(\"launcher\")\n\n\nclass SimpleI18N(object):\n    def __init__(self):\n        self.lang = get_language()\n        xlog.debug(\"lang: %s\", self.lang)\n        self.base_po_dict = {}\n\n    def add_translate(self, key, value):\n        self.base_po_dict[key] = value\n\n    @staticmethod\n    def po_loader(file):\n        if sys.version_info[0] == 2:\n            fp = open(file, \"r\")\n        else:\n            fp = open(file, \"rb\")\n\n        po_dict = {}\n        while True:\n            line = fp.readline()\n            line = utils.to_bytes(line)\n            if not line:\n                break\n\n            if len(line) < 2:\n                continue\n\n            if line.startswith(b\"#\"):\n                continue\n\n            if line.startswith(b\"msgid \"):\n                key = line[7:-2]\n                value = b\"\"\n                while True:\n                    line = fp.readline()\n                    line = utils.to_bytes(line)\n                    if not line:\n                        break\n\n                    if line.startswith(b\"\\\"\"):\n                        key += line[1:-2]\n                    elif line.startswith(b\"msgstr \"):\n                        value += line[8:-2]\n                        break\n                    else:\n                        break\n\n                while True:\n                    line = fp.readline()\n                    line = utils.to_bytes(line)\n                    if not line:\n                        break\n\n                    if line.startswith(b\"\\\"\"):\n                        value += line[1:-2]\n                    else:\n                        break\n\n                if key == b\"\":\n                    continue\n\n                po_dict[key] = value\n\n        return po_dict\n\n    def _render(self, po_dict, content):\n        po_dict = utils.merge_two_dict(po_dict, self.base_po_dict)\n\n        out_arr = []\n\n        cp = 0\n        while True:\n            bp = content.find(b\"{{\", cp)\n            if bp == -1:\n                break\n\n            ep = content.find(b\"}}\", bp)\n            if ep == -1:\n                # print((content[bp:]))\n                break\n\n            b1p = content.find(b\"_(\", bp, ep)\n            if b1p == -1:\n                # print((content[bp:]))\n                continue\n            b2p = content.find(b\"\\\"\", b1p + 2, b1p + 4)\n            if b2p == -1:\n                # print((content[bp:]))\n                continue\n\n            e1p = content.find(b\")\", ep - 2, ep)\n            if e1p == -1:\n                # print((content[bp:]))\n                continue\n\n            e2p = content.find(b\"\\\"\", e1p - 2, e1p)\n            if e2p == -1:\n                # print((content[bp:]))\n                continue\n\n            out_arr.append(content[cp:bp])\n            key = content[b2p + 1:e2p]\n            if po_dict.get(key, b\"\") == b\"\":\n                out_arr.append(key)\n            else:\n                out_arr.append(po_dict[key])\n\n            cp = ep + 2\n\n        out_arr.append(content[cp:])\n\n        return b\"\".join(out_arr)\n\n    def render(self, lang_path, template_file):\n        po_file = os.path.join(lang_path, self.lang, \"LC_MESSAGES\", \"messages.po\")\n\n        if sys.version_info[0] == 2:\n            fp = open(template_file, \"r\")\n            content = fp.read()\n        else:\n            fp = open(template_file, \"rb\")\n            content = fp.read()\n\n        if not os.path.isfile(po_file):\n            return self._render(dict(), content)\n        else:\n            po_dict = self.po_loader(po_file)\n            return self._render(po_dict, content)\n\n    def render_content(self, lang_path, content):\n        po_file = os.path.join(lang_path, self.lang, \"LC_MESSAGES\", \"messages.po\")\n        if not os.path.isfile(po_file):\n            return self._render(dict(), content)\n        else:\n            po_dict = self.po_loader(po_file)\n            return self._render(po_dict, content)\n"
  },
  {
    "path": "code/default/launcher/start.py",
    "content": "#!/usr/bin/env python3\n# coding:utf-8\n\nimport platform\nimport os\nimport sys\nimport time\nimport traceback\nimport atexit\n\n# reduce resource request for threading\n# for OpenWrt\nimport threading\ntry:\n    threading.stack_size(64 * 1024)\nexcept:\n    pass\n\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nsys.path.append(current_path)\ndefault_path = os.path.abspath(os.path.join(current_path, os.path.pardir))\nnoarch_lib = os.path.abspath(os.path.join(default_path, 'lib', 'noarch'))\nsys.path.append(noarch_lib)\n\nimport env_info\ndata_path = env_info.data_path\ndata_launcher_path = os.path.join(data_path, 'launcher')\n\n\ndef create_data_path():\n    if not os.path.isdir(data_path):\n        os.mkdir(data_path)\n\n    if not os.path.isdir(data_launcher_path):\n        os.mkdir(data_launcher_path)\n\n    data_gae_proxy_path = os.path.join(data_path, 'gae_proxy')\n    if not os.path.isdir(data_gae_proxy_path):\n        os.mkdir(data_gae_proxy_path)\n\n\ncreate_data_path()\n\nfrom xlog import getLogger\nlog_file = os.path.join(data_launcher_path, \"launcher.log\")\nxlog = getLogger(\"launcher\", log_path=data_launcher_path, save_start_log=500, save_warning_log=True)\nxlog.set_buffer(100)\n\nimport sys_platform\nfrom config import config\nimport web_control\nimport module_init\nimport update\nimport update_from_github\nimport download_modules\nimport global_var\n\n\ncurrent_version = update_from_github.current_version()\n\nxlog.info(\"start Version %s\", current_version)\nxlog.info(\"Python version: %s\", sys.version)\nxlog.info(\"System: %s|%s|%s\", platform.system(), platform.version(), platform.architecture())\nxlog.info(\"data path: %s\", data_path)\n\nfrom front_base import openssl_wrap\nxlog.info(\"TLS implementation: %s\", openssl_wrap.implementation)\n\ntry:\n    import OpenSSL\nexcept Exception as e2:\n    print(\"import pyOpenSSL fail:\", e2)\n\nrunning_file = os.path.join(data_launcher_path, \"Running.Lck\")\n\n\ndef uncaught_exception_handler(etype, value, tb):\n    if etype == KeyboardInterrupt:  # Ctrl + C on console\n        xlog.warn(\"KeyboardInterrupt, exiting...\")\n        global_var.running = False\n        module_init.stop_all()\n        os._exit(0)\n\n    exc_info = ''.join(traceback.format_exception(etype, value, tb))\n    print((\"uncaught Exception:\\n\" + exc_info))\n    xlog.error(\"uncaught Exception, type=%s value=%s traceback:%s\", etype, value, exc_info)\n    # sys.exit(1)\n\n\nsys.excepthook = uncaught_exception_handler\n\n\ndef exit_handler():\n    xlog.info('Stopping all modules before exit!')\n    global_var.running = False\n    module_init.stop_all()\n    web_control.stop()\n\n\natexit.register(exit_handler)\n\nhas_desktop = sys_platform.has_desktop\n\n\ndef main():\n    # change path to launcher\n    global __file__\n    __file__ = os.path.abspath(__file__)\n    if os.path.islink(__file__):\n        __file__ = getattr(os, 'readlink', lambda x: x)(__file__)\n    os.chdir(os.path.dirname(os.path.abspath(__file__)))\n\n    if sys.platform == \"win32\":\n        import win_compat_suggest\n\n        if config.show_compat_suggest:\n            win_compat_suggest.main()\n\n        ports_resolve_solution = win_compat_suggest.Win10PortReserveSolution()\n        if not ports_resolve_solution.check_and_resolve():\n            return\n    elif sys.platform == \"darwin\":\n        import resource\n        new_soft_limit = 4096\n        new_hard_limit = 4096\n        resource.setrlimit(resource.RLIMIT_NOFILE, (new_soft_limit, new_hard_limit))\n        xlog.info(f\"New open file limits set to: Soft={new_soft_limit}, Hard={new_hard_limit}\")\n\n    web_control.confirm_xxnet_not_running()\n\n    import post_update\n    post_update.check()\n\n    allow_remote = 0\n    no_mess_system = 0\n    no_popup = 0\n    no_systray = 0\n    if len(sys.argv) > 1:\n        for s in sys.argv[1:]:\n            xlog.info(\"command args:%s\", s)\n            if s == \"-allow_remote\":\n                allow_remote = 1\n            elif s == \"-no_mess_system\":\n                no_mess_system = 1\n            elif s == \"-no_popup\":\n                no_popup = 1\n            elif s == \"-no_systray\":\n                no_systray = 1\n\n    if allow_remote or config.allow_remote_connect:\n        xlog.info(\"start with allow remote connect.\")\n        module_init.xargs[\"allow_remote\"] = 1\n\n    if os.getenv(\"NOT_MESS_SYSTEM\", \"0\") != \"0\" or no_mess_system or config.no_mess_system:\n        xlog.info(\"start with no_mess_system, no CA will be imported to system, not create desktop.\")\n        module_init.xargs[\"no_mess_system\"] = 1\n        update.should_create_desktop_shortcut = False\n\n    if os.path.isfile(running_file):\n        restart_from_except = True\n    else:\n        restart_from_except = False\n\n    update.start()\n    # put update before start all modules, generate uuid for x-tunnel.\n\n    module_init.start_all_auto()\n    web_control.start(allow_remote)\n\n    if has_desktop and config.popup_webui == 1 and not restart_from_except and not no_popup:\n        host_port = config.control_port\n        import webbrowser\n        url = \"http://localhost:%s/\" % host_port\n        xlog.debug(\"Popup %s on startup\", url)\n        webbrowser.open(url)\n\n    if has_desktop:\n        download_modules.start_download()\n    update_from_github.cleanup()\n\n    if config.show_systray and not no_systray:\n        sys_platform.show_systray()\n    else:\n        while global_var.running:\n            time.sleep(10)\n\n\ntry:\n    main()\nexcept KeyboardInterrupt:  # Ctrl + C on console\n    global_var.running = False\n    module_init.stop_all()\n    os._exit(0)\n    sys.exit()\nexcept Exception as e:\n    xlog.exception(\"launcher except:%r\", e)\n    input(\"Press Enter to continue...\")\n"
  },
  {
    "path": "code/default/launcher/sys_platform.py",
    "content": "\nimport sys\nimport os\n\nfrom xlog import getLogger\n\nxlog = getLogger(\"launcher\")\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\ndefault_path = os.path.abspath(os.path.join(current_path, os.pardir))\n\nimport global_var\n\n\nif sys.platform.startswith(\"linux\"):\n    if os.path.isfile(\"/system/bin/dalvikvm\") or os.path.isfile(\"/system/bin/dalvikvm64\") or \\\n            \"android.googlesource.com\" in sys.version:\n        xlog.info(\"This is Android\")\n        has_desktop = False\n        platform = \"android\"\n        platform_lib = \"\"\n\n        def show_systray():\n            from non_tray import sys_tray\n            sys_tray.serve_forever()\n\n        def on_quit():\n            sys_tray.on_quit()\n\n    else:\n        def X_is_running():\n            try:\n                from subprocess import Popen, PIPE\n                p = Popen([\"xset\", \"-q\"], stdout=PIPE, stderr=PIPE)\n                p.communicate()\n                return p.returncode == 0\n            except:\n                return False\n\n\n        def has_gi():\n            try:\n                import gi\n                gi.require_version('Gtk', '3.0')\n                from gi.repository import Gtk as gtk\n                return True\n            except Exception as e:\n                xlog.warn(\"load gi fail:%r, SysTray will not show.\", e)\n                return False\n\n\n        def has_pygtk():\n            try:\n                import pygtk\n                pygtk.require('2.0')\n                import gtk\n                return True\n            except:\n                return False\n\n\n        platform = \"linux\"\n        platform_lib = os.path.join(default_path, 'lib', 'linux')\n        sys.path.append(platform_lib)\n\n        if X_is_running() and (has_pygtk() or has_gi()):\n            has_desktop = True\n        else:\n            has_desktop = False\n\n\n        def show_systray():\n            global sys_tray\n            if has_desktop:\n                try:\n                    from gtk_tray import sys_tray\n                except:\n                    from non_tray import sys_tray\n            else:\n                from non_tray import sys_tray\n\n            sys_tray.serve_forever()\n\n        def on_quit():\n            global sys_tray\n            if has_desktop:\n                from gtk_tray import sys_tray\n            sys_tray.on_quit()\n\nelif sys.platform == \"win32\":\n    has_desktop = True\n\n    platform = \"windows\"\n    platform_lib = os.path.join(default_path, 'lib', 'win32')\n    sys.path.append(platform_lib)\n\n\n    def show_systray():\n        from win_tray import sys_tray\n        sys_tray.serve_forever()\n\n\n    def on_quit():\n        from win_tray import sys_tray\n        sys_tray.on_quit()\n\nelif sys.platform == \"darwin\":\n    has_desktop = True\n    platform = \"mac\"\n    platform_lib = os.path.abspath(os.path.join(default_path, 'lib', 'darwin'))\n    sys.path.append(platform_lib)\n\n    extra_lib = \"/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/PyObjc\"\n    sys.path.append(extra_lib)\n\n    def show_systray():\n        global sys_tray\n        try:\n            import mac_tray as sys_tray\n        except Exception as e:\n            xlog.warn(\"import mac_tray except:%r, Please try run 'sudo pip3 install -U PyObjC Pillow' by yourself.\", e)\n            from non_tray import sys_tray\n        sys_tray.serve_forever()\n\n    def on_quit():\n        global sys_tray\n        sys_tray.on_quit()\n\nelif sys.platform == \"ios\":\n    xlog.info(\"This is iOS\")\n    has_desktop = False\n    platform = \"ios\"\n    platform_lib = \"\"\n\n    import time\n    import gc\n    gc.set_threshold(200, 12, 12)\n\n    def show_systray():\n        while global_var.running:\n            time.sleep(30)\n            count = gc.get_count()\n            c = gc.collect()\n            xlog.debug(\"GC: count: %d,%d,%d Collect:%d\", count[0], count[1], count[2], c)\n\n    def on_quit():\n        from non_tray import sys_tray\n        sys_tray.on_quit()\n\nelse:\n    xlog.warn((\"detect platform fail:%s\" % sys.platform))\n\n    platform = \"unknown\"\n    has_desktop = False\n    platform_lib = \"\"\n    from non_tray import sys_tray\n\n    def show_systray():\n        sys_tray.serve_forever()\n\n    def on_quit():\n        sys_tray.on_quit()\n"
  },
  {
    "path": "code/default/launcher/tests/integrate_testing.py",
    "content": "import json\nimport os\nimport time\nimport sys\nfrom subprocess import Popen, PIPE, STDOUT\nimport threading\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\ndefault_path = os.path.abspath(os.path.join(current_path, os.path.pardir, os.path.pardir))\nroot_path = os.path.abspath(os.path.join(default_path, os.path.pardir, os.path.pardir))\n\nnoarch_lib = os.path.abspath(os.path.join(default_path, 'lib', 'noarch'))\nsys.path.append(noarch_lib)\n\nimport utils\nimport simple_http_server\nfrom dnslib.dns import DNSRecord, DNSHeader, DNSQuestion\nimport socket\n\nimport simple_http_client\nfrom xlog import getLogger\nxlog = getLogger(\"test\")\n\n\nclass ServiceTesting(object):\n    def __init__(self):\n        self.xtunnel_login_status = False\n        self.running = True\n\n        self.pth = None\n        self.log_fp = None\n        self.log_fn = None\n\n        # Lock for one integrate testing at the same time.\n        # github act running in local will run multi python version in same VM, so we need to lock to avoid conflict.\n        while True:\n            try:\n                res = simple_http_client.request(\"GET\", \"http://127.0.0.1:8888/test\")\n                if res and res.status == 200:\n                    time.sleep(1)\n                    continue\n                else:\n                    break\n            except:\n                break\n\n        self.lock_server = simple_http_server.HTTPServer(('', 8888), simple_http_server.TestHttpServer, \".\")\n        self.lock_server.start()\n\n        if self.check_web_console():\n            xlog.info(\"APP was running externally.\")\n            self.th = None\n            return\n\n        self.log_fn = os.path.join(root_path, \"running.log\")\n        if sys.version_info[0] == 3:\n            self.log_fp = open(self.log_fn, \"wb\")\n        else:\n            self.log_fp = open(self.log_fn, \"w\")\n\n        self.th = threading.Thread(target=self.start_xxnet)\n        self.th.start()\n\n    def __del__(self):\n        if self.log_fp:\n            self.log_fp.close()\n            self.log_fp = None\n\n    def run(self):\n        self.get_xxnet_web_console()\n        self.xtunnel_logout()\n        self.smart_route_dns_query()\n        self.smart_route_proxy_http()\n        self.smart_route_proxy_socks4()\n        self.smart_route_proxy_socks5()\n\n        self.xtunnel_token_login()\n        self.xtunnel_proxy_http()\n        self.xtunnel_proxy_socks4()\n        self.xtunnel_proxy_socks5()\n\n        if not self.th:\n            return\n\n        self.stop_xxnet()\n\n        self.check_log()\n\n        self.lock_server.shutdown()\n\n        for _ in range(30):\n            if not self.th:\n                return\n\n            time.sleep(1)\n\n        # If APP not exit, kill all python to exit, this script will also be killed.\n        self.kill_python()\n\n    def check_web_console(self):\n        try:\n            res = simple_http_client.request(\"GET\", \"http://127.0.0.1:8085/\", timeout=1)\n            return res is not None and res.status in [200, 404]\n            # 404 is because act running locally may lost some folder. just bypass this error.\n        except Exception as e:\n            # xlog.debug(\"get web_console fail:%r\", e)\n            return False\n\n    def get_xxnet_web_console(self, timeout=50):\n        xlog.info(\"Start get xxnet web console.\")\n        t0 = time.time()\n        t_end = t0 + timeout\n        while time.time() < t_end and self.running:\n            if not self.check_web_console():\n                time.sleep(1)\n                continue\n\n            xlog.info(\"Got web console success.\")\n            return\n\n        xlog.warn(\"Get Web Console timeout.\")\n\n    def xtunnel_logout(self):\n        xlog.info(\"Start testing XTunnel logout\")\n        res = simple_http_client.request(\"POST\", \"http://127.0.0.1:8085/module/x_tunnel/control/logout\", timeout=10)\n        self.assertEqual(res.status, 200)\n        self.xtunnel_login_status = False\n        xlog.info(\"Finished testing XTunnel logout\")\n\n    def smart_route_proxy_http(self):\n        xlog.info(\"Start testing SmartRouter HTTP proxy protocol\")\n        proxy = \"http://localhost:8086\"\n        res = simple_http_client.request(\"GET\", \"https://github.com/\", proxy=proxy, timeout=20)\n        self.assertEqual(res.status, 200)\n        xlog.info(\"Finished testing SmartRouter HTTP proxy protocol\")\n\n    def smart_route_proxy_socks4(self):\n        xlog.info(\"Start testing SmartRouter SOCKS4 proxy protocol\")\n        proxy = \"socks4://localhost:8086\"\n        res = simple_http_client.request(\"GET\", \"https://github.com/\", proxy=proxy, timeout=15)\n        self.assertEqual(res.status, 200)\n        xlog.info(\"Finished testing SmartRouter SOCKS4 proxy protocol\")\n\n    def smart_route_proxy_socks5(self):\n        xlog.info(\"Start testing SmartRouter SOCKS5 proxy protocol\")\n        proxy = \"socks5://localhost:8086\"\n        res = simple_http_client.request(\"GET\", \"https://github.com/\", proxy=proxy, timeout=15)\n        self.assertEqual(res.status, 200)\n        xlog.info(\"Finished testing SmartRouter SOCKS5 proxy protocol\")\n\n    def smart_route_dns_query(self):\n        xlog.info(\"Start testing SmartRouter DNS Query\")\n        domain = \"appsec.hicloud.com\"\n        d = DNSRecord(DNSHeader(123))\n        d.add_question(DNSQuestion(domain, 1))\n        req4_pack = d.pack()\n\n        for port in [8053, 53]:\n            sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)\n            sock.sendto(req4_pack, (\"127.0.0.1\", port))\n            sock.settimeout(5)\n\n            try:\n                response, server = sock.recvfrom(8192)\n            except Exception as e:\n                xlog.warn(\"recv fail for port:%s e:%r\", port, e)\n                continue\n\n            p = DNSRecord.parse(response)\n            for r in p.rr:\n                ip = utils.to_bytes(str(r.rdata))\n                xlog.info(\"IP:%s\" % ip)\n                self.assertEqual(utils.check_ip_valid(ip), True)\n\n            xlog.info(\"Finished testing SmartRouter DNS Query\")\n            return\n\n    def xtunnel_token_login(self):\n        xlog.info(\"Start testing XTunnel login\")\n        headers = {\n            \"Content-Type\": \"application/json\"\n        }\n        data = {\n            \"login_token\": os.getenv(\"XTUNNEL_TOKEN\"),\n        }\n        data = json.dumps(data)\n        res = simple_http_client.request(\"POST\", \"http://127.0.0.1:8085/module/x_tunnel/control/token_login\",\n                                         headers=headers, body=data, timeout=60)\n        self.assertEqual(res.status, 200)\n        self.xtunnel_login_status = True\n        xlog.info(\"Finished testing XTunnel login\")\n\n    def xtunnel_proxy_http(self):\n        xlog.info(\"Start testing XTunnel HTTP proxy protocol\")\n        if not self.xtunnel_login_status:\n            self.xtunnel_token_login()\n        proxy = \"http://localhost:1080\"\n        for _ in range(3):\n            res = simple_http_client.request(\"GET\", \"https://github.com/\", proxy=proxy, timeout=30)\n            if not res:\n                time.sleep(5)\n                continue\n            self.assertEqual(res.status, 200)\n            xlog.info(\"Finished testing XTunnel HTTP proxy protocol\")\n\n        self.assertEqual(res.status, 200)\n\n    def xtunnel_proxy_socks4(self):\n        xlog.info(\"Start testing XTunnel Socks4 proxy protocol\")\n        if not self.xtunnel_login_status:\n            self.xtunnel_token_login()\n        proxy = \"socks4://localhost:1080\"\n        res = simple_http_client.request(\"GET\", \"https://github.com/\", proxy=proxy, timeout=15)\n        self.assertEqual(res.status, 200)\n        xlog.info(\"Finished testing XTunnel Socks4 proxy protocol\")\n\n    def xtunnel_proxy_socks5(self):\n        xlog.info(\"Start testing XTunnel Socks5 proxy protocol\")\n        if not self.xtunnel_login_status:\n            self.xtunnel_token_login()\n        proxy = \"socks5://localhost:1080\"\n        res = simple_http_client.request(\"GET\", \"https://github.com/\", proxy=proxy, timeout=15)\n        self.assertEqual(res.status, 200)\n        xlog.info(\"Finished testing XTunnel Socks5 proxy protocol\")\n\n    def start_xxnet(self):\n        py_bin = sys.executable\n        start_script = os.path.join(default_path, \"launcher\", \"start.py\")\n        cmd = [py_bin, start_script]\n        xlog.info(\"start APP cmd: %s\" % cmd)\n        try:\n            self.pth = Popen(cmd, stdout=PIPE, stderr=STDOUT)  # , preexec_fn=os.setsid, shell=True, , bufsize=1\n            for line in iter(self.pth.stdout.readline, b''):\n                self.log_fp.write(line)\n                self.log_fp.flush()\n                line = line.strip()\n                xlog.info(\"LOG|%s\", line)\n                if not self.running:\n                    break\n        except Exception as e:\n            xlog.exception(\"run %s error:%r\", cmd, e)\n\n        xlog.info(\"xxnet quit.\")\n        self.running = False\n        self.th = None\n\n    def stop_xxnet(self):\n        xlog.info(\"call api to Quit xxnet\")\n        try:\n            res = simple_http_client.request(\"GET\", \"http://127.0.0.1:8085/quit\", timeout=0.5)\n            if res:\n                xlog.info(\"Quit API res:%s\", res.text)\n            else:\n                xlog.info(\"Quit API request failed.\")\n        except Exception as e:\n            xlog.info(\"Quit API except:%r\", e)\n\n    def kill_python(self):\n        self.running = False\n        xlog.info(\"start kill python\")\n        if sys.platform == \"win32\":\n            # This will kill this script as well.\n            os.system(\"taskkill /F /im python.exe\")\n        else:\n            os.system(\"pkill -9 -f 'start.py'\")\n        xlog.info(\"Finished kill python\")\n\n    def check_log(self):\n        if not self.log_fn:\n            # Debugging mode, running xxnet manually, check by human.\n            return\n\n        with open(self.log_fn, \"r\") as fp:\n            for line in fp.readlines():\n                line = line.strip()\n                line = utils.to_str(line)\n\n                self.assertNotIn(\"[ERROR]\", line)\n\n        xlog.info(\"Log Check passed!\")\n\n    def assertEqual(self, a, b):\n        if not a == b:\n            raise Exception(\"%s not equal %s\" % (a, b))\n\n    def assertNotIn(self, a, b):\n        if a in b:\n            raise Exception(\"%s in %s\" % (a, b))\n\n\ndef run_testing():\n    testing = ServiceTesting()\n    try:\n        testing.run()\n    except Exception as e:\n        xlog.exception(\"test failed:%r\", e)\n        testing.stop_xxnet()\n        testing.kill_python()\n        exit(1)\n\n\nif __name__ == \"__main__\":\n    run_testing()\n"
  },
  {
    "path": "code/default/launcher/tests/test_update.py",
    "content": "import os.path\nimport unittest\nimport tempfile\nimport os\n\nfrom launcher.update_from_github import download_file\n\n\nclass UpdateTest(unittest.TestCase):\n    def test_download(self):\n        tp = tempfile.gettempdir()\n        fn = os.path.join(tp, \"v4.txt\")\n        res = download_file(\"https://raw.githubusercontent.com/XX-net/XX-Net/master/code/default/update_v4.txt\", fn)\n        self.assertTrue(res)\n\n\n"
  },
  {
    "path": "code/default/launcher/tests/test_web_api.py",
    "content": "from unittest import TestCase\nimport json\n\nimport simple_http_client\n\n\nclass TestAPi(TestCase):\n    def setUp(self):\n        self.base_url = \"http://localhost:8085\"\n\n    def test_set_proxy_applist(self):\n        url = self.base_url + \"/set_proxy_applist\"\n        headers = {\n            \"Content-Type\": \"application/json\"\n        }\n        info = {\n            'proxy_by_app': \"true\",\n            'enabled_app_list[]': [\n                \"com.google.android.youtube\"\n            ]\n        }\n        dat = json.dumps(info)\n\n        res = simple_http_client.request(\"POST\", url, headers=headers, body=dat)\n        print(res.text)\n"
  },
  {
    "path": "code/default/launcher/tests/test_win_port_reserve.py",
    "content": "from unittest import TestCase\nimport sys\n\nfrom launcher.win_compat_suggest import Win10PortReserveSolution\n\nempty_output = [\n    b'\\r\\n',\n    b'Protocol tcp Port Exclusion Ranges\\r\\n',\n    b'\\r\\n',\n    b'Start Port    End Port      \\r\\n',\n    b'----------    --------      \\r\\n',\n    b'\\r\\n',\n    b'* - Administered port exclusions.\\r\\n',\n    b'\\r\\n'\n]\n\nvalid_output = [\n    b'\\r\\n',\n    b'Protocol tcp Port Exclusion Ranges\\r\\n',\n    b'\\r\\n',\n    b'Start Port    End Port      \\r\\n',\n    b'----------    --------      \\r\\n',\n    b'     49795       49894      \\r\\n',\n    b'     49895       49994      \\r\\n',\n    b'     50000       50059     *\\r\\n',\n    b'\\r\\n',\n    b'* - Administered port exclusions.\\r\\n',\n    b'\\r\\n'\n]\n\n\nclass TestW10PortReserve(TestCase):\n    def setUp(self):\n        if sys.platform == \"win32\":\n            self.s = Win10PortReserveSolution()\n        else:\n            self.s = None\n\n    def test_detect(self):\n        if not self.s:\n            return\n\n        res = self.s.is_port_reserve_conflict()\n        print(res)\n\n    def test_reset(self):\n        if not self.s:\n            return\n\n        self.s.change_reserved_port_range()\n\n    def test_resolve(self):\n        if not self.s:\n            return\n\n        self.s.check_and_resolve()\n"
  },
  {
    "path": "code/default/launcher/tests/try_run.py",
    "content": "import logging\nimport sys\nimport os\nfrom subprocess import Popen, PIPE, STDOUT\n\nfrom logging import getLogger\nxlog = getLogger(\"test\")\nxlog.setLevel(logging.DEBUG)\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\ndefault_path = os.path.abspath(os.path.join(current_path, os.path.pardir, os.path.pardir))\n\n\nclass T(object):\n    def start_xxnet(self):\n        py_bin = sys.executable\n        start_script = os.path.join(default_path, \"launcher\", \"start.py\")\n        cmd = [py_bin, start_script]\n        xlog.info(\"cmd: %s\" % cmd)\n        try:\n            self.pth = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT, bufsize=1)  # , preexec_fn=os.setsid\n            # for line in stream.stdout:\n            for line in iter(self.pth.stdout.readline, b''):\n                line = line.strip()\n                xlog.info(b\"LOG|%s\" % line)\n                print(line)\n                # self.assertNotIn(b\"[ERROR]\", line)\n        except Exception as e:\n            xlog.exception(\"run %s error:%r\", cmd, e)\n\n        xlog.info(\"xxnet exit.\")\n        self.running = False\n        self.th = None\n\n\nif __name__ == \"__main__\":\n    t = T()\n    t.start_xxnet()\n"
  },
  {
    "path": "code/default/launcher/tests/try_smartroute_sock4.py",
    "content": "import simple_http_client\n\n\ndef smart_route_proxy_socks4():\n    proxy = \"socks4://localhost:8086\"\n    res = simple_http_client.request(\"GET\", \"https://github.com/\", proxy=proxy, timeout=1000)\n    return res\n\n\nif __name__ == \"__main__\":\n    smart_route_proxy_socks4()\n"
  },
  {
    "path": "code/default/launcher/unzip.vbs",
    "content": "\r\nSub Unzip(ZipFile, ExtractTo)\r\n    Dim objShell: set objShell = CreateObject(\"Shell.Application\")\r\n    Dim FilesInZip\r\n    dim ns\r\n    ZipFile = GetAbslutePath(ZipFile)\r\n    ExtractTo = GetAbslutePath(ExtractTo)\r\n    x = CreateDir(ExtractTo)\r\n    set ns = objShell.NameSpace(ZipFile)\r\n    set FilesInZip = ns.items()\r\n    objShell.NameSpace(ExtractTo).CopyHere(FilesInZip)\r\nEnd Sub"
  },
  {
    "path": "code/default/launcher/update.py",
    "content": "#!/usr/bin/env python\n# coding:utf-8\n\nimport os, stat\nimport json\nimport time\nimport threading\nimport zipfile\nimport sys\nimport platform\nimport uuid\n\n\ntry:\n    from urllib.request import build_opener, HTTPSHandler, ProxyHandler\nexcept ImportError:\n    from urllib2 import build_opener, HTTPSHandler, ProxyHandler\n\ntry:\n    reduce         # Python 2\nexcept NameError:  # Python 3\n    from functools import reduce\n\nimport utils\nfrom xlog import getLogger\nxlog = getLogger(\"launcher\")\nfrom config import config, app_name\nimport update_from_github\nimport sys_platform\nimport global_var\nimport env_info\n\nupdate_url = \"https://xxnet-update.appspot.com/update.json\"\n\nupdate_content = \"\"\nupdate_dict = {}\nnew_gae_proxy_version = \"\"\ngae_proxy_path = \"\"\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nroot_path = os.path.abspath(os.path.join(current_path, os.pardir))\ndata_root = env_info.data_path\n\nshould_create_desktop_shortcut = True\n\n\ndef get_opener():\n    autoproxy = '127.0.0.1:8086'\n\n    # import ssl\n    # if getattr(ssl, \"create_default_context\", None):\n    #     cafile = os.path.join(data_root, \"gae_proxy\", \"CA.crt\")\n    #     if not os.path.isfile(cafile):\n    #         cafile = None\n    #     context = ssl.create_default_context(purpose=ssl.Purpose.SERVER_AUTH,\n    #                                          cafile=cafile)\n    #     https_handler = HTTPSHandler(context=context)\n    #\n    #     opener = build_opener(ProxyHandler({'http': autoproxy, 'https': autoproxy}), https_handler)\n    # else:\n    opener = build_opener(ProxyHandler({'http': autoproxy, 'https': autoproxy}))\n    return opener\n\n\ndef version_to_bin(s):\n    return reduce(lambda a, b: a << 8 | b, list(map(int, s.split(\".\"))))\n\n\ndef compare_versions(v1, v2):\n      \"\"\"Compare two version strings and return -1, 0, or 1.\"\"\"\n      def parse_version(version):\n          return [int(x) for x in version.split('.')]\n\n      parts1 = parse_version(v1)\n      parts2 = parse_version(v2)\n\n      # Pad with zeros to make lengths equal\n      max_len = max(len(parts1), len(parts2))\n      parts1 += [0] * (max_len - len(parts1))\n      parts2 += [0] * (max_len - len(parts2))\n\n      if parts1 < parts2:\n          return -1\n      elif parts1 > parts2:\n          return 1\n      else:\n          return 0\n\n\ndef download_file(url, file):\n    try:\n        xlog.info(\"download %s to %s\", url, file)\n        opener = get_opener()\n        req = opener.open(url, cafile=\"\")\n        CHUNK = 16 * 1024\n        with open(file, 'wb') as fp:\n            while True:\n                chunk = req.read(CHUNK)\n                if not chunk: break\n                fp.write(chunk)\n        return True\n    except:\n        xlog.info(\"download %s to %s fail\", url, file)\n        return False\n\n\ndef sha1_file(filename):\n    import hashlib\n\n    BLOCKSIZE = 65536\n    hasher = hashlib.sha1()\n    try:\n        with open(filename, 'rb') as afile:\n            buf = afile.read(BLOCKSIZE)\n            while len(buf) > 0:\n                hasher.update(buf)\n                buf = afile.read(BLOCKSIZE)\n        return hasher.hexdigest()\n    except:\n        return False\n\n\ndef install_module(module, new_version):\n    import module_init\n    import os, subprocess, sys\n\n    current_path = os.path.dirname(os.path.abspath(__file__))\n    new_module_version_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir, module, new_version))\n\n    # check path exist\n    if not os.path.isdir(new_module_version_path):\n        xlog.error(\"install module %s dir %s not exist\", module, new_module_version_path)\n        return\n\n    # call setup.py\n    setup_script = os.path.join(new_module_version_path, \"setup.py\")\n    if not os.path.isfile(setup_script):\n        xlog.warn(\"update %s fail. setup script %s not exist\", module, setup_script)\n        return\n\n    config.current_version = str(new_version)\n    config.save()\n\n    if module == \"launcher\":\n        module_init.stop_all()\n        import web_control\n        web_control.stop()\n\n        subprocess.Popen([sys.executable, setup_script], shell=False)\n\n        os._exit(0)\n\n    else:\n        xlog.info(\"Setup %s version %s ...\", module, new_version)\n        try:\n            module_init.stop(module)\n\n            subprocess.call([sys.executable, setup_script], shell=False)\n            xlog.info(\"Finished new version setup.\")\n\n            xlog.info(\"Restarting new version ...\")\n            module_init.start(module)\n        except Exception as e:\n            xlog.error(\"install module %s %s fail:%s\", module, new_version, e)\n\n\ndef download_module(module, new_version):\n    import os\n    global update_content, update_dict\n\n    current_path = os.path.dirname(os.path.abspath(__file__))\n    download_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir, 'data', 'downloads'))\n    if not os.path.isdir(download_path):\n        os.mkdir(download_path)\n\n    try:\n        for source in update_dict[\"modules\"][module][\"versions\"][new_version][\"sources\"]:\n            url = source[\"url\"]\n            filename = module + \"-\" + new_version + \".zip\"\n\n            file_path = os.path.join(download_path, filename)\n\n            if os.path.isfile(file_path) and sha1_file(file_path) == update_dict[\"modules\"][module][\"versions\"][new_version][\"sha1\"]:\n                pass\n            elif not download_file(url, file_path):\n                xlog.warn(\"download %s fail\", url)\n                continue\n\n            sha1 = sha1_file(file_path)\n            if update_dict[\"modules\"][module][\"versions\"][new_version][\"sha1\"] != sha1:\n                xlog.warn(\"download %s sha1 wrong\", url)\n                continue\n\n            module_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir, module))\n            if not os.path.isdir(module_path):\n                os.mkdir(module_path)\n\n            version_path = os.path.join(module_path, new_version)\n            if os.path.isdir(version_path):\n                xlog.error(\"module dir exist:%s, download exist.\", version_path)\n                return\n\n            with zipfile.ZipFile(file_path, \"r\") as dz:\n                dz.extractall(module_path)\n                dz.close()\n\n            import shutil\n            unzip_path = os.path.abspath(os.path.join(module_path, module + \"-\" + new_version))\n            tag_path = os.path.abspath(os.path.join(module_path, new_version))\n            shutil.move(unzip_path, tag_path)\n\n            msg = \"Module %s new version %s downloaded, Install?\" % (module, new_version)\n            if sys.platform == \"linux\" or sys.platform == \"linux2\":\n                from gtk_tray import sys_tray\n                data_install = \"%s|%s|install\" % (module, new_version)\n                data_ignore = \"%s|%s|ignore\" % (module, new_version)\n                buttons = {1: {\"data\": data_install, \"label\": \"Install\", 'callback': general_gtk_callback},\n                           2: {\"data\": data_ignore, \"label\": \"Ignore\", 'callback': general_gtk_callback}}\n                sys_tray.notify_general(msg=msg, title=\"Install\", buttons=buttons)\n            elif sys.platform == \"win32\":\n                from win_tray import sys_tray\n                if sys_tray.dialog_yes_no(msg, \"Install\", None, None) == 1:\n                    install_module(module, new_version)\n                else:\n                    ignore_module(module, new_version)\n            elif sys.platform == \"darwin\":\n                from  mac_tray import sys_tray\n                if sys_tray.presentAlert_withTitle_(msg, \"Install\"):\n                    install_module(module, new_version)\n                else:\n                    ignore_module(module, new_version)\n\n            else:\n                install_module(module, new_version)\n\n            break\n\n    except Exception as e:\n        xlog.warn(\"get gae_proxy source fail, content:%s err:%s\", update_content, e)\n\n\ndef ignore_module(module, new_version):\n    config.ignore_version = str(new_version)\n    config.save()\n\n\ndef general_gtk_callback(widget=None, data=None):\n    args = data.split('|')\n    if len(args) != 3:\n        xlog.error(\"general_gtk_callback data:%s\", data)\n        return\n\n    module = args[0]\n    new_version = args[1]\n    action = args[2]\n\n    if action == \"download\":\n        download_module(module, new_version)\n    elif action == \"install\":\n        install_module(module, new_version)\n    elif action == \"ignore\":\n        ignore_module(module, new_version)\n\n\ndef check_update():\n    try:\n        if update_from_github.update_info == \"dont-check\":\n            return\n\n        # check_push_update()  # server broken\n\n        update_rule = config.check_update\n        if update_rule not in (\"stable\", \"notice-stable\", \"test\", \"notice-test\"):\n            return\n\n        try:\n            versions = update_from_github.get_github_versions()\n        except Exception as e:\n            xlog.warn(\"check_update get version failed. e:%r\", e)\n            return\n\n        current_version = update_from_github.current_version()\n        test_version, stable_version = versions[0][1], versions[1][1]\n        if test_version != config.skip_test_version:\n            if update_rule == \"notice-test\":\n                if compare_versions(current_version, test_version) < 0:\n                    xlog.info(\"checked new test version %s\", test_version)\n                    update_from_github.update_info = '{\"type\":\"test\", \"version\":\"%s\"}' % test_version\n            elif update_rule == \"test\":\n                if compare_versions(current_version, test_version) < 0:\n                    xlog.info(\"update to test version %s\", test_version)\n                    update_from_github.update_version(test_version)\n        if stable_version != config.skip_stable_version:\n            if update_rule == \"notice-stable\":\n                if compare_versions(current_version, stable_version) < 0:\n                    xlog.info(\"checked new stable version %s\", stable_version)\n                    update_from_github.update_info = '{\"type\":\"stable\", \"version\":\"%s\"}' % stable_version\n            elif update_rule == \"stable\":\n                if compare_versions(current_version, stable_version) < 0:\n                    xlog.info(\"update to stable version %s\", stable_version)\n                    update_from_github.update_version(stable_version)\n    except IOError as e:\n        xlog.exception(\"check update fail:%r\", e)\n    except Exception as e:\n        xlog.exception(\"check_update fail:%r\", e)\n    finally:\n        if update_from_github.update_info == \"init\":\n            update_from_github.update_info = \"\"\n\n\ndef check_push_update():\n    global update_content, update_dict\n    try:\n        opener = get_opener()\n\n        req_url = update_url + \"?uuid=\" + get_uuid() \\\n                  + \"&version=\" + update_from_github.current_version() \\\n                  + \"&platform=\" + platform.platform()\n        try:\n            res = opener.open(req_url)\n            update_content = res.read()\n        except Exception as e:\n            xlog.exception(\"check_update get content fail:%r\", e)\n            return False\n\n        update_dict = json.loads(utils.to_str(update_content))\n        return True\n    except Exception as e:\n        xlog.exception(\"check_update except:%s\", e)\n        return\n\n\ndef create_desktop_shortcut():\n    import sys\n    import subprocess\n\n    work_path = os.path.dirname(os.path.abspath(__file__))\n    os.chdir(work_path)\n\n    if sys.platform.startswith(\"linux\"):\n        def create_xwindows_shortcut():\n            if os.getenv(\"DESKTOP_SESSION\", \"unknown\") == \"unknown\":  # make sure this is desktop linux\n                return\n\n            desktop_path = os.path.join(os.path.join(os.path.expanduser('~')), 'Desktop')\n            if not os.path.isdir(desktop_path):\n                return\n\n            xxnet_path = os.path.abspath(os.path.join(root_path, os.pardir, os.pardir))\n            content = \"[Desktop Entry]\\n\" + \\\n                      \"Version=1.0\\n\" + \\\n                      \"Type=Application\\n\" + \\\n                      \"Name=\" + app_name + \"\\n\" +\\\n                      \"Comment=\\n\" + \\\n                      \"Exec=sh -c \\\"\" + xxnet_path + \"/start\\\"\\n\" + \\\n                      \"Icon=\" + xxnet_path + \"/code/default/launcher/web_ui/img/\" + app_name + \"/favicon.ico\\n\" + \\\n                      \"Path=\\n\" + \\\n                      \"Terminal=false\\n\" + \\\n                      \"StartupNotify=false\\n\"\n\n            fp = os.path.join(desktop_path, app_name + \".desktop\")\n            with open(fp, \"w\") as fd:\n                fd.write(content)\n            os.chmod(fp, 0o0744)\n\n        create_xwindows_shortcut()\n\n    elif sys.platform == \"win32\":\n        # import ctypes\n        # msg = u\"是否在桌面创建图标？\"\n        # title = app_name\n        #res = ctypes.windll.user32.MessageBoxW(None, msg, title, 1)\n        # Yes:1 No:2\n        #if res == 2:\n        #    return\n\n        subprocess.call([\"Wscript.exe\", \"//E:JScript\", \"create_shortcut.js\", app_name], shell=False)\n\n\ndef notify_install_tcpz_for_winXp():\n    import ctypes\n    ctypes.windll.user32.MessageBoxW(None, \"请使用tcp-z对 tcpip.sys 打补丁，解决链接并发限制！\", \"Patch XP needed\", 0)\n\n\ndef check_new_machine():\n    current_path = os.path.dirname(os.path.abspath(__file__))\n    if current_path != config.last_path:\n        config.last_path = current_path\n        config.save()\n\n        if sys.platform == \"win32\" and platform.release() == \"XP\":\n            notify_install_tcpz_for_winXp()\n\n        if sys_platform.has_desktop and should_create_desktop_shortcut:\n            xlog.info(\"generate desktop shortcut\")\n            create_desktop_shortcut()\n\n\ndef update_check_loop():\n    check_new_machine()\n\n    # wait gae_proxy to start\n    # update need gae_proxy as proxy\n    time.sleep(500)\n\n    while global_var.running:\n        check_update()\n        time.sleep(3600 * 24)\n\n\ndef start():\n    get_uuid()\n    p = threading.Thread(target=update_check_loop, name=\"check_update\")\n    p.daemon = True\n    p.start()\n\n\ndef need_new_uuid():\n    if not config.update_uuid:\n        xlog.info(\"need_new_uuid: uuid is empty\")\n        return True\n    return False\n\n\ndef generate_new_uuid():\n    xx_net_uuid = str(uuid.uuid4())\n    config.update_uuid = xx_net_uuid\n    xlog.info(\"generate uuid:%s\", xx_net_uuid)\n    config.save()\n\n\ndef get_uuid():\n    if need_new_uuid():\n        generate_new_uuid()\n\n    xx_net_uuid = config.update_uuid\n    xlog.info(\"get uuid:%s\", xx_net_uuid)\n    return xx_net_uuid\n\n\nif __name__ == \"__main__\":\n    #get_uuid()\n    #check_update()\n    #sys_tray.serve_forever()\n    # create_desktop_shortcut()\n    print(compare_versions(\"2.1.1\", \"2.1.0\"))\n"
  },
  {
    "path": "code/default/launcher/update_from_github.py",
    "content": "import os\nimport sys\nimport time\nimport subprocess\nimport threading\nimport re\nimport zipfile\nimport shutil\nimport stat\nimport glob\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nroot_path = os.path.abspath(os.path.join(current_path, os.pardir))\ntop_path = os.path.abspath(os.path.join(root_path, os.pardir, os.pardir))\ncode_path = os.path.abspath(os.path.join(root_path, os.pardir))\nimport env_info\ndata_root = env_info.data_path\npython_path = root_path\nnoarch_lib = os.path.join(python_path, 'lib', 'noarch')\nsys.path.append(noarch_lib)\n\nimport utils\nimport simple_http_client\nimport global_var\nfrom xlog import getLogger\n\nxlog = getLogger(\"launcher\")\ntry:\n    from config import config\nexcept:\n    from .config import config\n\nif not os.path.isdir(data_root):\n    os.mkdir(data_root)\n\ndownload_path = os.path.join(data_root, 'downloads')\nif not os.path.isdir(download_path):\n    os.mkdir(download_path)\n\nprogress = {}  # link => {\"size\", 'downloaded', status:downloading|canceled|finished:failed}\nprogress[\"update_status\"] = \"Idle\"\nupdate_info = \"init\"\n\n\ndef init_update_info(check_update):\n    global update_info\n    if check_update == \"dont-check\":\n        update_info = \"dont-check\"\n    elif config.check_update == update_info:\n        update_info = \"init\"\n    elif check_update != \"init\":\n        update_info = \"\"\n\n\ninit_update_info(config.check_update)\n\n\ndef request(url, retry=0, timeout=30):\n    if retry == 0:\n        if config.global_proxy_enable == 1:\n            client = simple_http_client.Client(proxy={\n                \"type\": config.global_proxy_type,\n                \"host\": config.global_proxy_host,\n                \"port\": config.global_proxy_port,\n                \"user\": config.global_proxy_username,\n                \"pass\": config.global_proxy_password,\n            }, timeout=timeout)\n        else:\n            client = simple_http_client.Client(timeout=timeout)\n    else:\n        cert = os.path.join(data_root, \"gae_proxy\", \"CA.crt\")\n        client = simple_http_client.Client(proxy={\n            \"type\": \"http\",\n            \"host\": \"127.0.0.1\",\n            \"port\": 8086,\n            \"user\": None,\n            \"pass\": None\n        }, timeout=timeout, cert=cert)\n\n    res = client.request(\"GET\", url, read_payload=False)\n    return res\n\n\ndef download_file(url, filename):\n    if url not in progress:\n        progress[url] = {}\n        progress[url][\"status\"] = \"downloading\"\n        progress[url][\"size\"] = 1\n        progress[url][\"downloaded\"] = 0\n    else:\n        if progress[url][\"status\"] == \"downloading\":\n            xlog.warn(\"url in downloading, %s\", url)\n            return False\n\n    for i in range(0, 2):\n        try:\n            xlog.info(\"download %s to %s, retry:%d\", url, filename, i)\n            req = request(url, i, timeout=120)\n            if not req:\n                continue\n\n            start_time = time.time()\n            timeout = 300\n\n            if req.chunked:\n                # don't known the file size, set to large for show the progress\n                progress[url][\"size\"] = 20 * 1024 * 1024\n\n                downloaded = 0\n                with open(filename, 'wb') as fp:\n                    while global_var.running:\n                        time_left = timeout - (time.time() - start_time)\n                        if time_left < 0:\n                            raise Exception(\"time out\")\n\n                        dat = req.read(timeout=time_left)\n                        if not dat:\n                            break\n\n                        fp.write(dat)\n                        downloaded += len(dat)\n                        progress[url][\"downloaded\"] = downloaded\n\n                progress[url][\"status\"] = \"finished\"\n                return True\n            else:\n                file_size = progress[url][\"size\"] = int(req.getheader(b'Content-Length', 0))\n\n                left = file_size\n                downloaded = 0\n                with open(filename, 'wb') as fp:\n                    while global_var.running:\n                        chunk_len = min(65536, left)\n                        if not chunk_len:\n                            break\n\n                        chunk = req.read(chunk_len)\n                        if not chunk:\n                            break\n                        fp.write(chunk)\n                        downloaded += len(chunk)\n                        progress[url][\"downloaded\"] = downloaded\n                        left -= len(chunk)\n\n            if downloaded != progress[url][\"size\"]:\n                xlog.warn(\"download size:%d, need size:%d, download fail.\", downloaded, progress[url][\"size\"])\n                continue\n            else:\n                progress[url][\"status\"] = \"finished\"\n                return True\n        except Exception as e:\n            xlog.exception(\"download %s to %s fail:%r\", url, filename, e)\n            continue\n\n    progress[url][\"status\"] = \"failed\"\n    return False\n\n\ndef parse_update_versions(readme_file):\n    versions = []\n    try:\n        fd = open(readme_file, \"rb\")\n        lines = fd.readlines()\n        p = re.compile(br'https://codeload.github.com/XX-net/XX-Net/zip/([0-9]+)\\.([0-9]+)\\.([0-9]+) ([0-9a-fA-F]*)')\n        for line in lines:\n            m = p.match(line)\n            if m:\n                version = m.group(1) + b\".\" + m.group(2) + b\".\" + m.group(3)\n                hashsum = m.group(4).lower()\n                versions.append([m.group(0), version, hashsum])\n                versions = utils.to_str(versions)\n                if len(versions) == 2:\n                    return versions\n    except Exception as e:\n        xlog.exception(\"xxnet_version fail:%r\", e)\n\n    raise Exception(\"get_version_fail:%s\" % readme_file)\n\n\ndef current_version():\n    readme_file = os.path.join(root_path, \"version.txt\")\n    try:\n        with open(readme_file) as fd:\n            content = fd.read()\n            p = re.compile(r'([0-9]+)\\.([0-9]+)\\.([0-9]+)')\n            m = p.match(content)\n            if m:\n                version = m.group(1) + \".\" + m.group(2) + \".\" + m.group(3)\n                return version\n    except:\n        xlog.warn(\"get_version_fail in update_from_github\")\n\n    return \"get_version_fail\"\n\n\ndef get_github_versions():\n    readme_url = \"https://raw.githubusercontent.com/XX-net/XX-Net/master/code/default/update_v5.txt\"\n    readme_target = os.path.join(download_path, \"version.txt\")\n\n    if not download_file(readme_url, readme_target):\n        raise IOError(\"get update file %s fail:\" % readme_url)\n\n    versions = parse_update_versions(readme_target)\n    return versions\n\n\ndef get_hash_sum(version):\n    versions = get_github_versions()\n    for v in versions:\n        if v[1] == version:\n            return v[2]\n\n\ndef hash_file_sum(filename):\n    import hashlib\n\n    BLOCKSIZE = 65536\n    hasher = hashlib.sha256()\n    try:\n        with open(filename, 'rb') as afile:\n            buf = afile.read(BLOCKSIZE)\n            while len(buf) > 0:\n                hasher.update(buf)\n                buf = afile.read(BLOCKSIZE)\n        return hasher.hexdigest()\n    except:\n        return False\n\n\ndef overwrite(xxnet_version, xxnet_unzip_path):\n    progress[\"update_status\"] = \"Overwriting\"\n    try:\n        for root, subdirs, files in os.walk(xxnet_unzip_path):\n            relate_path = root[len(xxnet_unzip_path) + 1:]\n            target_relate_path = relate_path\n            if sys.platform == 'win32':\n                if target_relate_path.startswith(\"code\\\\default\"):\n                    target_relate_path = \"code\\\\\" + xxnet_version + relate_path[12:]\n            else:\n                if target_relate_path.startswith(\"code/default\"):\n                    target_relate_path = \"code/\" + xxnet_version + relate_path[12:]\n\n            for subdir in subdirs:\n                if relate_path == \"code\" and subdir == \"default\":\n                    subdir = xxnet_version\n\n                target_path = os.path.join(top_path, target_relate_path, subdir)\n                if not os.path.isdir(target_path):\n                    xlog.info(\"mkdir %s\", target_path)\n                    os.mkdir(target_path)\n\n            for filename in files:\n                src_file = os.path.join(root, filename)\n                dst_file = os.path.join(top_path, target_relate_path, filename)\n                if relate_path == 'code' and filename == 'app_info.json':\n                    continue\n\n                if not os.path.isfile(dst_file) or hash_file_sum(src_file) != hash_file_sum(dst_file):\n                    xlog.info(\"copy %s => %s\", src_file, dst_file)\n                    # modify by outofmemo, files in '/sdcard' are not allowed to chmod for Android\n                    # and shutil.copy() will call shutil.copymode()\n                    if sys.platform != 'win32' and os.path.isfile(\"/system/bin/dalvikvm\") == False and os.path.isfile(\n                            \"/system/bin/dalvikvm64\") == False and os.path.isfile(dst_file):\n                        st = os.stat(dst_file)\n                        shutil.copy(src_file, dst_file)\n                        if st.st_mode & stat.S_IEXEC:\n                            os.chmod(dst_file, st.st_mode)\n                    else:\n                        shutil.copyfile(src_file, dst_file)\n\n    except Exception as e:\n        xlog.warn(\"update overwrite fail:%r\", e)\n        progress[\"update_status\"] = \"Overwrite Fail:%r\" % e\n        raise e\n    xlog.info(\"update file finished.\")\n\n\ndef download_overwrite_new_version(xxnet_version, checkhash=1):\n    global update_progress\n\n    xxnet_url = 'https://codeload.github.com/XX-net/XX-Net/zip/%s' % xxnet_version\n    xxnet_zip_file = os.path.join(download_path, \"XX-Net-%s.zip\" % xxnet_version)\n    xxnet_unzip_path = os.path.join(download_path, \"XX-Net-%s\" % xxnet_version)\n\n    progress[\"update_status\"] = \"Downloading %s\" % xxnet_url\n    if not download_file(xxnet_url, xxnet_zip_file):\n        progress[\"update_status\"] = \"Download Fail.\"\n        raise Exception(\"download xxnet zip fail:%s\" % xxnet_zip_file)\n\n    if checkhash:\n        hash_sum = get_hash_sum(xxnet_version)\n        if len(hash_sum) and hash_file_sum(xxnet_zip_file) != hash_sum:\n            progress[\"update_status\"] = \"Download Checksum Fail.\"\n            xlog.warn(\"downloaded xxnet zip checksum fail:%s\" % xxnet_zip_file)\n            raise Exception(\"downloaded xxnet zip checksum fail:%s\" % xxnet_zip_file)\n    else:\n        xlog.debug(\"skip checking downloaded file hash\")\n\n    xlog.info(\"update download %s finished.\", download_path)\n\n    xlog.info(\"update start unzip\")\n    progress[\"update_status\"] = \"Unziping\"\n    try:\n        with zipfile.ZipFile(xxnet_zip_file, \"r\") as dz:\n            dz.extractall(download_path)\n            dz.close()\n    except Exception as e:\n        xlog.warn(\"unzip %s fail:%r\", xxnet_zip_file, e)\n        progress[\"update_status\"] = \"Unzip Fail:%s\" % e\n        raise e\n    xlog.info(\"update finished unzip\")\n\n    overwrite(xxnet_version, xxnet_unzip_path)\n\n    os.remove(xxnet_zip_file)\n    shutil.rmtree(xxnet_unzip_path, ignore_errors=True)\n\n\ndef get_local_versions():\n    def get_folder_version(folder):\n        f = os.path.join(code_path, folder, \"version.txt\")\n        try:\n            with open(f) as fd:\n                content = fd.read()\n                p = re.compile(r'([0-9]+)\\.([0-9]+)\\.([0-9]+)')\n                m = p.match(content)\n                if m:\n                    version = m.group(1) + \".\" + m.group(2) + \".\" + m.group(3)\n                    return version\n        except:\n            return False\n\n    files_in_code_path = os.listdir(code_path)\n    local_versions = []\n    for name in files_in_code_path:\n        if os.path.isdir(os.path.join(code_path, name)):\n            v = get_folder_version(name)\n            if v:\n                local_versions.append([v, name])\n    local_versions.sort(key=lambda s: list(map(int, s[0].split('.'))), reverse=True)\n    return local_versions\n\n\ndef get_current_version_dir():\n    current_dir = os.path.split(root_path)[-1]\n    return current_dir\n\n\ndef del_version(version):\n    if version == get_current_version_dir():\n        xlog.warn(\"try to delect current version.\")\n        return False\n\n    try:\n        shutil.rmtree(os.path.join(top_path, \"code\", version))\n        return True\n    except Exception as e:\n        xlog.warn(\"deleting fail: %s\", e)\n        return False\n\n\ndef update_current_version(version):\n    start_script = os.path.join(top_path, \"code\", version, \"launcher\", \"start.py\")\n    if not os.path.isfile(start_script):\n        xlog.warn(\"set version %s not exist\", version)\n        return False\n\n    current_version_file = os.path.join(top_path, \"code\", \"version.txt\")\n    with open(current_version_file, \"w\") as fd:\n        fd.write(version)\n    return True\n\n\ndef restart_xxnet(version=None):\n    import module_init\n    module_init.stop_all()\n\n    import web_control\n    web_control.stop()\n    # New process will hold the listen port\n    # We should close all listen port before create new process\n    xlog.info(\"Close web control port.\")\n\n    if version is None:\n        current_version_file = os.path.join(top_path, \"code\", \"version.txt\")\n        with open(current_version_file, \"r\") as fd:\n            version = fd.read()\n\n    xlog.info(\"restart to xx-net version:%s\", version)\n\n    start_script = os.path.join(top_path, \"code\", version, \"launcher\", \"start.py\")\n    subprocess.Popen([sys.executable, start_script])\n    time.sleep(20)\n\n    xlog.info(\"Exit old process...\")\n    os._exit(0)\n\n\ndef update_version(version, checkhash=1):\n    global update_progress, update_info\n    _update_info = update_info\n    update_info = \"\"\n    try:\n        download_overwrite_new_version(version, checkhash)\n\n        update_current_version(version)\n\n        progress[\"update_status\"] = \"Restarting\"\n        xlog.info(\"update try restart xxnet\")\n        restart_xxnet(version)\n    except Exception as e:\n        xlog.warn(\"update version %s fail:%r\", version, e)\n        update_info = _update_info\n\n\ndef start_update_version(version, checkhash=1):\n    if progress[\"update_status\"] != \"Idle\" and \"Fail\" not in progress[\"update_status\"]:\n        return progress[\"update_status\"]\n\n    progress[\"update_status\"] = \"Start update\"\n    th = threading.Thread(target=update_version, args=(version, checkhash), name=\"update_version\")\n    th.start()\n    return True\n\n\ndef cleanup():\n    def rm_paths(path_list):\n        del_fullpaths = []\n        for ps in path_list:\n            pt = os.path.join(top_path, ps)\n            pt = glob.glob(pt)\n            del_fullpaths += pt\n        if del_fullpaths:\n            xlog.info(\"DELETE: %s\", ' , '.join(del_fullpaths))\n\n            for pt in del_fullpaths:\n                try:\n                    if os.path.isfile(pt):\n                        os.remove(pt)\n                    elif os.path.isdir(pt):\n                        shutil.rmtree(pt)\n                except:\n                    pass\n\n    keep_old_num = config.keep_old_ver_num  # default keep several old versions\n    if keep_old_num < 99 and keep_old_num >= 0:  # 99 means don't delete any old version\n        del_paths = []\n        local_vs = get_local_versions()\n        for i in range(len(local_vs)):\n            if local_vs[i][0] == current_version():\n                for u in range(i + keep_old_num + 1, len(local_vs)):\n                    del_paths.append(\"code/\" + local_vs[u][1] + \"/\")\n                break\n        if del_paths:\n            rm_paths(del_paths)\n\n    del_paths = []\n    if config.clear_cache:\n        del_paths += [\n            \"data/*/*.*.log\",\n            \"data/*/*.log.*\",\n            \"data/downloads/XX-Net-*.zip\"\n        ]\n\n    if config.del_win:\n        del_paths += [\n            \"code/*/lib/win32/\"\n        ]\n    if config.del_mac:\n        del_paths += [\n            \"code/*/lib/darwin/\"\n        ]\n    if config.del_linux:\n        del_paths += [\n            \"code/*/lib/linux/\"\n        ]\n    if config.del_gae:\n        del_paths += [\n            \"code/*/gae_proxy/\"\n        ]\n    if config.del_gae_server:\n        del_paths += [\n            \"code/*/gae_proxy/server/\"\n        ]\n    if config.del_xtunnel:\n        del_paths += [\n            \"code/*/x_tunnel/\"\n        ]\n    if config.del_smartroute:\n        del_paths += [\n            \"code/*/smart_router/\"\n        ]\n\n    if del_paths:\n        rm_paths(del_paths)\n"
  },
  {
    "path": "code/default/launcher/web_control.py",
    "content": "#!/usr/bin/env python\n# coding:utf-8\n\nimport os, sys\nimport errno\nimport re\nimport socket, ssl\nimport time\nimport threading\nimport json\nimport cgi\nimport traceback\nimport base64\n\ntry:\n    from urllib.parse import urlparse, urlencode, parse_qs\n    from urllib.request import urlopen, Request\n    from urllib.error import HTTPError\nexcept ImportError:\n    from urlparse import urlparse, parse_qs\n    from urllib import urlencode\n    from urllib2 import urlopen, Request, HTTPError\n\ntry:\n    from urllib.request import ProxyHandler\n    from urllib.request import build_opener\nexcept ImportError:\n    from urllib2 import ProxyHandler\n    from urllib2 import build_opener\n\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\ndefault_path = os.path.abspath(os.path.join(current_path, os.pardir))\nif __name__ == \"__main__\":\n    noarch_lib = os.path.abspath(os.path.join(default_path, 'lib', 'noarch'))\n    sys.path.append(noarch_lib)\n\n\nimport sys_platform\nfrom xlog import getLogger, keep_log\n\nxlog = getLogger(\"launcher\")\nimport module_init\nfrom config import config, valid_language, app_name\nimport autorun\nimport update\nimport update_from_github\nimport simple_http_client\nimport simple_http_server\nimport utils\nfrom simple_i18n import SimpleI18N\nimport env_info\n\nNetWorkIOError = (socket.error, ssl.SSLError, OSError)\n\ncurrent_version = utils.to_bytes(update_from_github.current_version())\ni18n_translator = SimpleI18N()\ni18n_translator.add_translate(b\"APP_NAME\", utils.to_bytes(app_name))\ni18n_translator.add_translate(b\"APP_VERSION\", current_version)\nmodule_menus = {}\n\n\nclass FakeHttpHandler(simple_http_server.HttpServerHandler):\n    def handle_one_request(self):\n        # This function will replace simple_http_server HttpHandler.handle_one_request to hold all http requests.\n        # Doing this is to simulate bug.\n        self.close_connection = 0\n\n\nCORS_header = {\n    \"Allow\": \"GET,POST,OPTIONS\",\n    \"Access-Control-Allow-Origin\": \"*\",\n    \"Access-Control-Allow-Methods\": \"GET,POST,OPTIONS\",\n    \"Access-Control-Allow-Headers\": \"Authorization,Content-Type,Sec-Fetch-Site,Sec-Fetch-Mode,Sec-Fetch-Dest\",\n    \"Connection\": \"close\",\n}\n\n\nclass Http_Handler(simple_http_server.HttpServerHandler):\n    deploy_proc = None\n\n    def load_module_menus(self):\n        global module_menus\n        new_module_menus = {}\n\n        modules = config.all_modules\n        for module in modules:\n            if getattr(config, \"enable_\" + module) != 1:\n                continue\n\n            menu_path = os.path.join(default_path, module, \"web_ui\", \"menu.json\")  # launcher & gae_proxy modules\n            if not os.path.isfile(menu_path):\n                continue\n\n            # i18n code lines (Both the locale dir & the template dir are module-dependent)\n            locale_dir = os.path.abspath(os.path.join(default_path, module, 'lang'))\n            stream = i18n_translator.render(locale_dir, menu_path)\n            module_menu = json.loads(utils.to_str(stream))\n            new_module_menus[module] = module_menu\n\n        module_menus = sorted(iter(new_module_menus.items()), key=lambda k_and_v: (k_and_v[1]['menu_sort_id']))\n        # for k,v in self.module_menus:\n        #    xlog.debug(\"m:%s id:%d\", k, v['menu_sort_id'])\n\n    def do_OPTIONS(self):\n        # xlog.debug('%s \"%s headers:%s from:%s', self.command, self.path, self.headers, self.address_string())\n        try:\n            origin = utils.to_str(self.headers.get(b'Origin'))\n            # if origin not in self.config.allow_web_origins:\n            #     return\n\n            header = {\n                \"Allow\": \"GET,POST,PUT,PATCH,DELETE,HEAD,OPTIONS\",\n                \"Access-Control-Allow-Origin\": origin,\n                \"Access-Control-Allow-Methods\": \"GET,POST,PUT,PATCH,DELETE,HEAD,OPTIONS\",\n                \"Access-Control-Allow-Headers\": \"Authorization,Content-Type\",\n            }\n            return self.send_response(headers=header)\n        except Exception as e:\n            xlog.exception(\"options fail:%r\", e)\n            return self.send_not_found()\n\n    def do_POST(self):\n        self.headers = utils.to_str(self.headers)\n        self.path = utils.to_str(self.path)\n\n        refer = self.headers.get('Referer')\n        if refer:\n            refer_loc = urlparse(refer).netloc\n            host = self.headers.get('Host')\n            if refer_loc != host and refer_loc not in config.allowed_refers:\n                xlog.warn(\"web control ref:%s host:%s\", refer_loc, host)\n                return\n\n            self.set_CORS(CORS_header)\n\n        try:\n            content_type = self.headers.get('Content-Type', \"\")\n            ctype, pdict = cgi.parse_header(content_type)\n            if ctype == 'multipart/form-data':\n                self.postvars = cgi.parse_multipart(self.rfile, pdict)\n            elif ctype == 'application/x-www-form-urlencoded':\n                length = int(self.headers.get('Content-Length'))\n                content = self.rfile.read(length)\n                self.postvars = parse_qs(content, keep_blank_values=True)\n                self.postvars = self.unpack_reqs(self.postvars)\n            elif ctype == 'application/json':\n                length = int(self.headers.get('Content-Length'))\n                content = self.rfile.read(length)\n                self.postvars = json.loads(content)\n            else:\n                self.postvars = {}\n                content = b''\n        except Exception as e:\n            xlog.exception(\"do_POST %s except:%r\", self.path, e)\n            self.postvars = {}\n\n        url_path_list = self.path.split('/')\n        url_path = urlparse(self.path).path\n        if len(url_path_list) >= 3 and url_path_list[1] == \"module\":\n            module = url_path_list[2]\n            if len(url_path_list) >= 4 and url_path_list[3] == \"control\":\n                if module not in module_init.proc_handler:\n                    xlog.warn(\"request %s no module in path\", self.path)\n                    return self.send_not_found()\n\n                path = '/' + '/'.join(url_path_list[4:])\n                controler = module_init.proc_handler[module][\"imp\"].local.web_control. \\\n                    ControlHandler(self.client_address, self.headers, self.command, path, self.rfile, self.wfile)\n                controler.set_CORS(self.res_headers)\n                controler.postvars = utils.to_str(self.postvars)\n                try:\n                    controler.do_POST()\n                    return\n                except Exception as e:\n                    xlog.exception(\"POST %s except:%r\", path, e)\n\n        elif url_path == \"/set_proxy_applist\":\n            return self.set_proxy_applist()\n\n        elif url_path.startswith(\"/openai/\"):\n            status, res_headers, res_body = module_init.proc_handler[\"x_tunnel\"][\"imp\"].local.openai_handler.handle_openai(\n                \"POST\", url_path, self.headers, content, self.connection)\n            return self.send_response(content=res_body, headers=res_headers, status=status)\n\n        else:\n            self.send_not_found()\n            xlog.info('%s \"%s %s HTTP/1.1\" 404 -', self.address_string(), self.command, self.path)\n\n    def do_GET(self):\n        self.headers = utils.to_str(self.headers)\n        self.path = utils.to_str(self.path)\n\n        refer = self.headers.get('Referer')\n        if refer:\n            refer_loc = urlparse(refer).netloc\n            host = self.headers.get('Host')\n            if refer_loc != host and refer_loc not in config.allowed_refers:\n                xlog.warn(\"web control ref:%s host:%s\", refer_loc, host)\n                return\n\n            self.set_CORS(CORS_header)\n\n        # check for '..', which will leak file\n        if re.search(r'(\\.{2})', self.path) is not None:\n            self.wfile.write(b'HTTP/1.1 404\\r\\n\\r\\n')\n            xlog.warn('%s %s %s haking', self.address_string(), self.command, self.path)\n            return\n\n        if config.webui_auth:\n            auth = self.headers.get(\"Authorization\")\n            if not auth or not auth.startswith(\"Basic \"):\n                return self.send_response(content=\"\", headers={\n                    \"WWW-Authenticate\": 'Basic realm=\"Access to admin\"'\n                }, status=401)\n\n            try:\n                user_pass = base64.b64decode(auth[6:])\n                user_pass = utils.to_str(user_pass)\n                user, password = user_pass.split(\":\")[0:2]\n            except Exception as e:\n                xlog.warn(\"decode auth fail:%r\", e)\n                return self.send_response(content=\"\", headers={\n                    \"WWW-Authenticate\": 'Basic realm=\"Access to admin\"'\n                }, status=401)\n\n            if config.webui_auth.get(user) != password:\n                return self.send_response(content=\"\", headers={\n                    \"WWW-Authenticate\": 'Basic realm=\"Access to admin\"'\n                }, status=401)\n\n        url_path = urlparse(self.path).path\n        if url_path == '/':\n            return self.req_index_handler()\n\n        url_path_list = self.path.split('/')\n        if len(url_path_list) >= 3 and url_path_list[1] == \"module\":\n            module = url_path_list[2]\n            if len(url_path_list) >= 4 and url_path_list[3] == \"control\":\n                if module not in module_init.proc_handler:\n                    xlog.warn(\"request %s no module in path\", url_path)\n                    self.send_not_found()\n                    return\n\n                if \"imp\" not in module_init.proc_handler[module]:\n                    xlog.warn(\"request module:%s start fail\", module)\n                    self.send_not_found()\n                    return\n\n                path = '/' + '/'.join(url_path_list[4:])\n                controler = module_init.proc_handler[module][\"imp\"].local.web_control.ControlHandler(\n                    self.client_address, self.headers, self.command, path, self.rfile, self.wfile)\n                controler.set_CORS(self.res_headers)\n                controler.do_GET()\n                return\n            else:\n                relate_path = '/'.join(url_path_list[3:])\n                file_path = os.path.join(default_path, module, \"web_ui\", relate_path)\n                if not os.path.isfile(file_path):\n                    return self.send_not_found()\n\n                # i18n code lines (Both the locale dir & the template dir are module-dependent)\n                locale_dir = os.path.abspath(os.path.join(default_path, module, 'lang'))\n                content = i18n_translator.render(locale_dir, file_path)\n                return self.send_response('text/html', content)\n        else:\n            file_path = os.path.join(current_path, 'web_ui' + url_path)\n\n        if os.path.isfile(file_path):\n            if file_path.endswith('.js'):\n                mimetype = 'application/javascript'\n            elif file_path.endswith('.css'):\n                mimetype = 'text/css'\n            elif file_path.endswith('.html'):\n                mimetype = 'text/html'\n            elif file_path.endswith('.jpg'):\n                mimetype = 'image/jpeg'\n            elif file_path.endswith('.png'):\n                mimetype = 'image/png'\n            else:\n                mimetype = 'text/plain'\n            self.send_file(file_path, mimetype)\n        else:\n            xlog.debug('launcher web_control %s %s %s ', self.address_string(), self.command, self.path)\n            if url_path == '/config':\n                self.req_config_handler()\n            elif url_path == \"/log\":\n                return self.req_log_handler()\n            elif url_path == \"/keep_log\":\n                return self.req_keep_log_handler()\n            elif url_path == \"/suck_threads\":\n                return self.req_suck_threads()\n            elif url_path == \"/hold_8085\":\n                return self.req_hold_8085()\n            elif url_path == '/update':\n                self.req_update_handler()\n            elif url_path == '/config_proxy':\n                self.req_config_proxy_handler()\n            elif url_path == '/installed_app':\n                self.req_get_installed_app()\n            elif url_path == '/init_module':\n                self.req_init_module_handler()\n            elif url_path == '/quit':\n                content = b'System: %s Exited successfully.' % utils.to_bytes(sys_platform.platform)\n                try:\n                    self.send_response('text/html', content)\n                    self.wfile.flush()\n                except:\n                    pass\n\n                xlog.info(\"start quit\")\n                if sys_platform.platform in [\"android\", \"ios\"]:\n                    try:\n                        xlog.info(\"request http://localhost:8084/quit/\")\n                        simple_http_client.request(\"GET\", \"http://localhost:8084/quit/\", timeout=1)\n                    except Exception as e:\n                        xlog.warn(\"request http://localhost:8084/quit/ e:%r\", e)\n                        pass\n\n                sys_platform.on_quit()\n            elif url_path == \"/debug\":\n                self.req_debug_handler()\n            elif url_path == \"/log_files\":\n                self.req_log_files()\n            elif url_path == \"/mem_info\":\n                self.req_mem_info_handler()\n            elif url_path == \"/gc\":\n                self.req_gc_handler()\n            elif url_path == '/restart':\n                self.send_response('text/html', '{\"status\":\"success\"}')\n                update_from_github.restart_xxnet()\n            else:\n                self.send_not_found()\n                xlog.info('%s \"%s %s HTTP/1.1\" 404 -', self.address_string(), self.command, self.path)\n\n    def req_index_handler(self):\n        req = urlparse(self.path).query\n        reqs = parse_qs(req, keep_blank_values=True)\n\n        try:\n            target_module = reqs['module'][0]\n            target_menu = reqs['menu'][0]\n        except:\n            if config.enable_x_tunnel:\n                target_module = 'x_tunnel'\n                target_menu = 'config'\n            # elif config.get(['modules', 'smart_router', 'auto_start'], 0) == 1:\n            #     target_module = 'smart_router'\n            #     target_menu = 'config'\n            elif config.enable_gae_proxy:\n                target_module = 'gae_proxy'\n                target_menu = 'status'\n            else:\n                target_module = 'launcher'\n                target_menu = 'about'\n\n        if len(module_menus) == 0:\n            self.load_module_menus()\n\n        # i18n code lines (Both the locale dir & the template dir are module-dependent)\n        locale_dir = os.path.abspath(os.path.join(current_path, 'lang'))\n        fn = os.path.join(current_path, \"web_ui\", \"index.html\")\n        try:\n            index_content = i18n_translator.render(locale_dir, fn)\n        except Exception as e:\n            xlog.warn(\"render %s except:%r\", fn, e)\n            return self.send_not_found()\n\n        menu_content = b''\n        for module, v in module_menus:\n            # xlog.debug(\"m:%s id:%d\", module, v['menu_sort_id'])\n            title = v[\"module_title\"]\n            menu_content += b'<li class=\"nav-header\">%s</li>\\n' % utils.to_bytes(title)\n            for sub_id in v['sub_menus']:\n                list_meta = b''\n                web_id = v['sub_menus'][sub_id].get(\"id\")\n                if web_id:\n                    list_meta += b' id=\"%s\"' % sub_id\n\n                sub_title = v['sub_menus'][sub_id]['title']\n                if \"url\" in v['sub_menus'][sub_id]:\n                    sub_url = v['sub_menus'][sub_id]['url']\n                    if target_module == module and target_menu == sub_url:\n                        list_meta += b'class=\"active\"'\n\n                    menu_content += b'<li %s><a href=\"/?module=%s&menu=%s\">%s</a></li>\\n' % utils.to_bytes(\n                        (list_meta, module, sub_url, sub_title))\n                elif \"api_url\" in v['sub_menus'][sub_id]:\n                    api_url = v['sub_menus'][sub_id][\"api_url\"]\n                    menu_content += b'<li %s><a href=\"%s\">%s</a></li>\\n' % utils.to_bytes(\n                        (list_meta, api_url, sub_title))\n\n        right_content_file = os.path.join(default_path, target_module, \"web_ui\", target_menu + \".html\")\n        if os.path.isfile(right_content_file):\n            # i18n code lines (Both the locale dir & the template dir are module-dependent)\n            locale_dir = os.path.abspath(os.path.join(default_path, target_module, 'lang'))\n            right_content = i18n_translator.render(locale_dir, os.path.join(default_path, target_module, \"web_ui\",\n                                                                            target_menu + \".html\"))\n        else:\n            right_content = b\"\"\n\n        data = index_content % (config.enable_gae_proxy, menu_content, right_content)\n        self.send_response('text/html', data)\n\n    def req_config_handler(self):\n        req = urlparse(self.path).query\n        reqs = parse_qs(req, keep_blank_values=True)\n        reqs = self.unpack_reqs(reqs)\n        data = ''\n\n        if reqs['cmd'] == 'get_config':\n\n            if module_init.xargs.get(\"allow_remote\", 0):\n                allow_remote_connect = 1\n            else:\n                allow_remote_connect = config.allow_remote_connect\n\n            dat = {\n                \"platform\": sys_platform.platform,\n                \"check_update\": config.check_update,\n                \"language\": config.language or i18n_translator.lang,\n                \"popup_webui\": config.popup_webui,\n                \"allow_remote_connect\": allow_remote_connect,\n                \"allow_remote_switch\": config.allow_remote_connect,\n                \"show_systray\": config.show_systray,\n                \"show_android_notification\": config.show_android_notification,\n                \"auto_start\": config.auto_start,\n                \"show_detail\": config.gae_show_detail,\n                \"gae_proxy_enable\": config.enable_gae_proxy,\n                \"x_tunnel_enable\": config.enable_x_tunnel,\n                \"smart_router_enable\": config.enable_smart_router,\n                \"system-proxy\": config.os_proxy_mode,\n                \"show-compat-suggest\": config.show_compat_suggest,\n                \"no_mess_system\": config.no_mess_system,\n                \"keep_old_ver_num\": config.keep_old_ver_num,\n                \"postUpdateStat\": config.postUpdateStat,\n            }\n            data = json.dumps(dat)\n        elif reqs['cmd'] == 'set_config':\n            if 'skip_version' in reqs:\n                skip_version = reqs['skip_version']\n                skip_version_type = reqs['skip_version_type']\n                if skip_version_type not in [\"stable\", \"test\"]:\n                    data = '{\"res\":\"fail\"}'\n                else:\n                    setattr(config, \"skip_%s_version\" % skip_version_type, skip_version)\n                    config.save()\n                    if skip_version in update_from_github.update_info:\n                        update_from_github.update_info = ''\n                    data = '{\"res\":\"success\"}'\n            elif 'check_update' in reqs:\n                check_update = reqs['check_update']\n                if check_update not in [\"dont-check\", \"stable\", \"notice-stable\", \"test\", \"notice-test\"]:\n                    data = '{\"res\":\"fail, check_update:%s\"}' % check_update\n                else:\n                    if config.check_update != check_update:\n                        update_from_github.init_update_info(check_update)\n                        config.check_update = check_update\n                        config.save()\n\n                    data = '{\"res\":\"success\"}'\n            elif 'language' in reqs:\n                language = reqs['language']\n\n                if language not in valid_language:\n                    data = '{\"res\":\"fail, language:%s\"}' % language\n                else:\n                    config.language = language\n                    config.save()\n\n                    i18n_translator.lang = language\n                    self.load_module_menus()\n\n                    data = '{\"res\":\"success\"}'\n            elif 'popup_webui' in reqs:\n                popup_webui = int(reqs['popup_webui'])\n                if popup_webui != 0 and popup_webui != 1:\n                    data = '{\"res\":\"fail, popup_webui:%s\"}' % popup_webui\n                else:\n                    config.popup_webui = popup_webui\n                    config.save()\n\n                    data = '{\"res\":\"success\"}'\n            elif 'allow_remote_switch' in reqs:\n                allow_remote_switch = int(reqs['allow_remote_switch'])\n                if allow_remote_switch != 0 and allow_remote_switch != 1:\n                    data = '{\"res\":\"fail, allow_remote_connect:%s\"}' % allow_remote_switch\n                else:\n\n                    try:\n                        del module_init.xargs[\"allow_remote\"]\n                    except:\n                        pass\n\n                    if allow_remote_switch:\n                        module_init.call_each_module(\"set_bind_ip\", {\n                            \"ip\": \"0.0.0.0\"\n                        })\n                    else:\n                        module_init.call_each_module(\"set_bind_ip\", {\n                            \"ip\": \"127.0.0.1\"\n                        })\n\n                    config.allow_remote_connect = allow_remote_switch\n                    config.save()\n\n                    xlog.debug(\"restart web control.\")\n                    stop()\n                    module_init.stop_all()\n                    time.sleep(1)\n                    start(allow_remote_switch)\n                    module_init.start_all_auto()\n\n                    xlog.debug(\"launcher web control restarted.\")\n                    data = '{\"res\":\"success\"}'\n            elif 'show_systray' in reqs:\n                show_systray = int(reqs['show_systray'])\n                if show_systray != 0 and show_systray != 1:\n                    data = '{\"res\":\"fail, show_systray:%s\"}' % show_systray\n                else:\n                    config.show_systray = show_systray\n                    config.save()\n\n                    data = '{\"res\":\"success\"}'\n            elif 'show_android_notification' in reqs:\n                show_android_notification = int(reqs['show_android_notification'])\n                if show_android_notification != 0 and show_android_notification != 1:\n                    data = '{\"res\":\"fail, show_systray:%s\"}' % show_android_notification\n                else:\n                    config.show_android_notification = show_android_notification\n                    config.save()\n\n                    data = '{\"res\":\"success\"}'\n            elif 'show_compat_suggest' in reqs:\n                show_compat_suggest = int(reqs['show_compat_suggest'])\n                if show_compat_suggest != 0 and show_compat_suggest != 1:\n                    data = '{\"res\":\"fail, show_compat_suggest:%s\"}' % show_compat_suggest\n                else:\n                    config.show_compat_suggest = show_compat_suggest\n                    config.save()\n\n                    data = '{\"res\":\"success\"}'\n            elif 'no_mess_system' in reqs:\n                no_mess_system = int(reqs['no_mess_system'])\n                if no_mess_system != 0 and no_mess_system != 1:\n                    data = '{\"res\":\"fail, no_mess_system:%s\"}' % no_mess_system\n                else:\n                    config.no_mess_system = no_mess_system\n                    config.save()\n\n                    data = '{\"res\":\"success\"}'\n            elif 'keep_old_ver_num' in reqs:\n                keep_old_ver_num = int(reqs['keep_old_ver_num'])\n                if keep_old_ver_num < 0 or keep_old_ver_num > 99:\n                    data = '{\"res\":\"fail, keep_old_ver_num:%s not in range 0 to 99\"}' % keep_old_ver_num\n                else:\n                    config.keep_old_ver_num = keep_old_ver_num\n                    config.save()\n\n                    data = '{\"res\":\"success\"}'\n            elif 'auto_start' in reqs:\n                auto_start = int(reqs['auto_start'])\n                if auto_start != 0 and auto_start != 1:\n                    data = '{\"res\":\"fail, auto_start:%s\"}' % auto_start\n                else:\n                    if auto_start:\n                        autorun.enable()\n                    else:\n                        autorun.disable()\n\n                    config.auto_start = auto_start\n                    config.save()\n\n                    data = '{\"res\":\"success\"}'\n            elif 'show_detail' in reqs:\n                show_detail = int(reqs['show_detail'])\n                if show_detail != 0 and show_detail != 1:\n                    data = '{\"res\":\"fail, show_detail:%s\"}' % show_detail\n                else:\n                    config.gae_show_detail = show_detail\n                    config.save()\n\n                    data = '{\"res\":\"success\"}'\n            elif 'gae_proxy_enable' in reqs:\n                gae_proxy_enable = int(reqs['gae_proxy_enable'])\n                if gae_proxy_enable != 0 and gae_proxy_enable != 1:\n                    data = '{\"res\":\"fail, gae_proxy_enable:%s\"}' % gae_proxy_enable\n                else:\n                    config.enable_gae_proxy = gae_proxy_enable\n                    config.save()\n                    if gae_proxy_enable:\n                        module_init.start(\"gae_proxy\")\n                    else:\n                        module_init.stop(\"gae_proxy\")\n\n                    if config.enable_smart_router:\n                        module_init.stop(\"smart_router\")\n                        module_init.start(\"smart_router\")\n\n                    self.load_module_menus()\n                    data = '{\"res\":\"success\"}'\n            elif 'x_tunnel_enable' in reqs:\n                x_tunnel_enable = int(reqs['x_tunnel_enable'])\n                if x_tunnel_enable != 0 and x_tunnel_enable != 1:\n                    data = '{\"res\":\"fail, x_tunnel_enable:%s\"}' % x_tunnel_enable\n                else:\n                    config.enable_x_tunnel = x_tunnel_enable\n                    config.save()\n                    if x_tunnel_enable:\n                        module_init.start(\"x_tunnel\")\n                    else:\n                        module_init.stop(\"x_tunnel\")\n                    self.load_module_menus()\n                    data = '{\"res\":\"success\"}'\n            elif 'smart_router_enable' in reqs:\n                smart_router_enable = int(reqs['smart_router_enable'])\n                if smart_router_enable != 0 and smart_router_enable != 1:\n                    data = '{\"res\":\"fail, smart_router_enable:%s\"}' % smart_router_enable\n                else:\n                    config.enable_smart_router = smart_router_enable\n                    config.save()\n                    if smart_router_enable:\n                        module_init.start(\"smart_router\")\n                    else:\n                        module_init.stop(\"smart_router\")\n                    self.load_module_menus()\n                    data = '{\"res\":\"success\"}'\n            elif 'postUpdateStat' in reqs:\n                postUpdateStat = reqs['postUpdateStat']\n                if postUpdateStat not in [\"noChange\", \"isNew\", \"isPostUpdate\"]:\n                    data = '{\"res\":\"fail, postUpdateStat:%s\"}' % postUpdateStat\n                else:\n                    config.postUpdateStat = postUpdateStat\n                    config.save()\n                    data = '{\"res\":\"success\"}'\n            else:\n                data = '{\"res\":\"fail\"}'\n        elif reqs['cmd'] == 'get_version':\n            current_version = update_from_github.current_version()\n            data = '{\"current_version\":\"%s\"}' % current_version\n\n        self.send_response('text/html', data)\n\n    def req_update_handler(self):\n        req = urlparse(self.path).query\n        reqs = parse_qs(req, keep_blank_values=True)\n        data = ''\n\n        if reqs['cmd'] == ['get_info']:\n            data = update_from_github.update_info\n            if data == '' or data[0] != '{':\n                data = '{\"type\":\"%s\"}' % data\n        elif reqs['cmd'] == ['set_info']:\n            update_from_github.update_info = reqs['info']\n            data = '{\"res\":\"success\"}'\n        elif reqs['cmd'] == ['start_check']:\n            update_from_github.init_update_info(reqs['check_update'])\n            update.check_update()\n            data = '{\"res\":\"success\"}'\n        elif reqs['cmd'] == ['get_progress']:\n            data = json.dumps(update_from_github.progress)\n        elif reqs['cmd'] == ['get_new_version']:\n            current_version = update_from_github.current_version()\n            github_versions = update_from_github.get_github_versions()\n            data = '{\"res\":\"success\", \"test_version\":\"%s\", \"stable_version\":\"%s\", \"current_version\":\"%s\"}' % (\n            github_versions[0][1], github_versions[1][1], current_version)\n            xlog.info(\"%s\", data)\n        elif reqs['cmd'] == ['update_version']:\n            version = reqs['version']\n\n            checkhash = 1\n            if 'checkhash' in reqs and reqs['checkhash'] == '0':\n                checkhash = 0\n\n            update_from_github.start_update_version(version, checkhash)\n            data = '{\"res\":\"success\"}'\n        elif reqs['cmd'] == ['set_localversion']:\n            version = reqs['version']\n\n            if update_from_github.update_current_version(version):\n                data = '{\"res\":\"success\"}'\n            else:\n                data = '{\"res\":\"false\", \"reason\": \"version not exist\"}'\n        elif reqs['cmd'] == ['get_localversions']:\n            local_versions = update_from_github.get_local_versions()\n\n            s = \"\"\n            for v in local_versions:\n                if not s == \"\":\n                    s += \",\"\n                s += ' { \"v\":\"%s\" , \"folder\":\"%s\" } ' % (v[0], v[1])\n            data = '[  %s  ]' % (s)\n        elif reqs['cmd'] == ['del_localversion']:\n            if update_from_github.del_version(reqs['version']):\n                data = '{\"res\":\"success\"}'\n            else:\n                data = '{\"res\":\"fail\"}'\n\n        self.send_response('text/html', data)\n\n    def req_config_proxy_handler(self):\n        req = urlparse(self.path).query\n        reqs = parse_qs(req, keep_blank_values=True)\n        data = ''\n\n        if reqs['cmd'] == ['get_config']:\n            data = {\n                \"enable\": config.global_proxy_enable,\n                \"type\": config.global_proxy_type,\n                \"host\": config.global_proxy_host,\n                \"port\": config.global_proxy_port,\n                \"user\": config.global_proxy_username,\n                \"passwd\": config.global_proxy_password,\n            }\n            data = json.dumps(data)\n        elif reqs['cmd'] == ['set_config']:\n            enable = int(reqs['enable'])\n            type = reqs['type']\n            host = reqs['host']\n            port = int(reqs['port'])\n            user = reqs['user']\n            passwd = reqs['passwd']\n\n            if int(enable) and not test_proxy(type, host, port, user, passwd):\n                return self.send_response('text/html', '{\"res\":\"fail\", \"reason\": \"test proxy fail\"}')\n\n            config.global_proxy_enable = enable\n            config.global_proxy_type = type\n            config.global_proxy_host = host\n            config.global_proxy_port = port\n            config.global_proxy_username = user\n            config.global_proxy_password = passwd\n            config.save()\n\n            module_init.call_each_module(\"set_proxy\", {\n                \"enable\": enable,\n                \"type\": type,\n                \"host\": host,\n                \"port\": port,\n                \"user\": user,\n                \"passwd\": passwd\n            })\n\n            data = '{\"res\":\"success\"}'\n        self.send_response('text/html', data)\n\n    def req_get_installed_app(self):\n        if sys_platform.platform != 'android':\n            # simulate data for developing\n            data = {\n                \"proxy_by_app\": config.proxy_by_app,\n                \"installed_app_list\": [\n                    {\n                        \"name\": \"Test\",\n                        \"package\": \"com.test\"\n                    },{\n                        \"name\": \"APP\",\n                        \"package\": \"com.app\"\n                    },{\n                        \"name\": \"com.google.foundation.Foundation.Application.\",\n                        \"package\": \"com.google.application\"\n                    }\n                ]\n            }\n            time.sleep(5)\n        else:\n            res = simple_http_client.request(\"GET\", \"http://localhost:8084/installed_app_list/\")\n            data = json.loads(res.text)\n            data[\"proxy_by_app\"] = config.proxy_by_app\n\n        for app in data[\"installed_app_list\"]:\n            package = app[\"package\"]\n            if package in config.enabled_app_list:\n                app[\"enable\"] = True\n            else:\n                app[\"enable\"] = False\n\n        if config.proxy_by_app:\n            # Pass the config in html.\n            content = '<div id=\"proxy_by_app_config\" checked hidden></div>'\n        else:\n            content = '<div id=\"proxy_by_app_config\" hidden></div>'\n\n        for app in data[\"installed_app_list\"]:\n            if app[\"enable\"]:\n                checked = \" checked \"\n            else:\n                checked = \"\"\n\n            content += '<div class=\"row-fluid\"> <div class=\"config_label\" >'\\\n                        + app[\"name\"] \\\n                        + '</div><div class=\"config_switch\"><input class=\"app_item\" id=\"'\\\n                        + app['package']\\\n                        + '\" type=\"checkbox\" data-toggle=\"switch\" '\\\n                        + checked\\\n                        + '/></div></div>\\n'\\\n\n        # jquery can't work on dynamic insert elements.\n        # load html content from backend is the best way to make it works.\n\n        return self.send_response(\"text/html\", content)\n\n    def set_proxy_applist(self):\n        self.postvars = utils.to_str(self.postvars)\n        xlog.debug(\"set_proxy_applist %r\", self.postvars)\n        config.proxy_by_app = int(self.postvars.get('proxy_by_app') == \"true\")\n        config.enabled_app_list = self.postvars.get(\"enabled_app_list[]\", [])\n        xlog.debug(\"set_proxy_applist proxy_by_app:%s\", config.proxy_by_app)\n        xlog.debug(\"set_proxy_applist enabled_app_list:%s\", config.enabled_app_list)\n        config.save()\n\n        data = {\n            \"res\": \"success\"\n        }\n        self.send_response(\"text/html\", json.dumps(data))\n\n    def req_init_module_handler(self):\n        req = urlparse(self.path).query\n        reqs = self.unpack_reqs(parse_qs(req, keep_blank_values=True))\n        data = ''\n\n        try:\n            module = reqs['module']\n            config.load()\n\n            if reqs['cmd'] == 'start':\n                result = module_init.start(module)\n                data = '{ \"module\": \"%s\", \"cmd\": \"start\", \"result\": \"%s\" }' % (module, result)\n            elif reqs['cmd'] == 'stop':\n                result = module_init.stop(module)\n                data = '{ \"module\": \"%s\", \"cmd\": \"stop\", \"result\": \"%s\" }' % (module, result)\n            elif reqs['cmd'] == 'restart':\n                result_stop = module_init.stop(module)\n                result_start = module_init.start(module)\n                data = '{ \"module\": \"%s\", \"cmd\": \"restart\", \"stop_result\": \"%s\", \"start_result\": \"%s\" }' % (\n                module, result_stop, result_start)\n        except Exception as e:\n            xlog.exception(\"init_module except:%s\", e)\n\n        self.send_response(\"text/html\", data, headers={\"Access-Control-Allow-Origin\": \"*\"})\n\n    def req_keep_log_handler(self):\n        keep_log()\n        data = \"Keep log success.\"\n\n        mimetype = 'text/plain'\n        self.send_response(mimetype, data)\n\n    def req_suck_threads(self):\n        self.send_response('text/plain', \"Start suck threads\")\n        while True:\n            threading.Thread(target=time.sleep, args=(1000,)).start()\n\n    def req_hold_8085(self):\n        global server\n        self.send_response('text/plain', \"Hold 8085\")\n        server.handler = FakeHttpHandler\n\n    def req_log_handler(self):\n        req = urlparse(self.path).query\n        reqs = self.unpack_reqs(parse_qs(req, keep_blank_values=True))\n        data = ''\n\n        if reqs[\"cmd\"]:\n            cmd = reqs[\"cmd\"]\n        else:\n            cmd = \"get_last\"\n\n        if cmd == \"get_last\":\n            max_line = int(reqs[\"max_line\"])\n            data = xlog.get_last_lines(max_line)\n        elif cmd == \"get_new\":\n            last_no = int(reqs[\"last_no\"])\n            data = xlog.get_new_lines(last_no)\n        else:\n            xlog.error('xtunnel log cmd:%s', cmd)\n\n        mimetype = 'text/plain'\n        self.send_response(mimetype, data)\n\n    def req_gc_handler(self):\n        req = urlparse(self.path).query\n        reqs = parse_qs(req, keep_blank_values=True)\n\n        import gc\n        count = gc.get_count()\n\n        if \"collect\" in reqs:\n            gc.collect()\n\n        self.send_response(\"text/plain\", \"gc collected, count:%d,%d,%d\" % count)\n\n    @staticmethod\n    def list_fds():\n        \"\"\"List process currently open FDs and their target \"\"\"\n        if not sys.platform.startswith('linux'):\n            return \"\"\n\n        dat = \"\"\n        base = '/proc/self/fd'\n        of = list(os.listdir(base))\n        dat += \"Num: %d\\r\\n\" % (len(of))\n        for num in of:\n            path = None\n            try:\n                path = os.readlink(os.path.join(base, num))\n            except OSError as err:\n                # Last FD is always the \"listdir\" one (which may be closed)\n                if err.errno != errno.ENOENT:\n                    path = str(err)\n            except Exception as e:\n                path = str(e)\n            dat += \" [%s]: %s\\r\\n\" % (num, path)\n\n        return dat\n\n    def req_debug_handler(self):\n        dat = \"\"\n\n        try:\n            dat += \"Opened files: \\r\\n%s \\r\\n\" % self.list_fds()\n\n            dat += \"thread num:%d\\r\\n\" % threading.active_count()\n            for thread in threading.enumerate():\n                dat += \"\\nThread: %s \\r\\n\" % (thread.name)\n                stack = sys._current_frames()[thread.ident]\n                st = traceback.extract_stack(stack)\n                stl = traceback.format_list(st)\n                dat += \" \\n\".join(stl)\n\n        except Exception as e:\n            xlog.exception(\"debug:%r\", e)\n\n        self.send_response(\"text/plain\", dat)\n\n    def req_log_files(self):\n        # pack data folder and response\n        x_tunnel_local = os.path.abspath(os.path.join(default_path, 'x_tunnel', 'local'))\n        sys.path.append(x_tunnel_local)\n        from upload_logs import pack_logs\n\n        data = pack_logs(200 * 1024 * 1024)\n        self.send_response(\"application/zip\", data)\n\n    def req_mem_info_handler(self):\n        global mem_stat\n        req = urlparse(self.path).query\n        reqs = parse_qs(req, keep_blank_values=True)\n\n        try:\n            import tracemalloc\n            import gc\n            import os\n            import linecache\n\n            python_lib = os.path.dirname(os.__file__)\n            gc.collect()\n\n            if not mem_stat:\n                tracemalloc.start()\n\n            if not mem_stat or \"reset\" in reqs:\n                mem_stat = tracemalloc.take_snapshot()\n\n            snapshot = tracemalloc.take_snapshot()\n\n            if \"compare\" in reqs:\n                top_stats = snapshot.compare_to(mem_stat, 'traceback')\n            else:\n                top_stats = snapshot.statistics('traceback')\n\n            dat = \"\"\n            for stat in top_stats[:100]:\n                print((\"%s memory blocks: %.1f KiB\" % (stat.count, stat.size / 1024)))\n                lines = stat.traceback.format()\n                ll = \"\\n\".join(lines)\n                ln = len(lines)\n                pl = \"\"\n                for i in range(ln, 0, -1):\n                    line = lines[i - 1]\n                    print(line)\n                    if line[8:].startswith(python_lib):\n                        break\n                    if not line.startswith(\"  File\"):\n                        pl = line\n                        continue\n                    if not line[8:].startswith(default_path):\n                        break\n                    ll = line[8:] + \"\\n\" + pl\n\n                if ll[0] == \"[\":\n                    pass\n\n                dat += \"%d KB, count:%d %s\\n\" % (stat.size / 1024, stat.count, ll)\n\n            if hasattr(threading, \"_start_trace\"):\n                dat += \"\\n\\nThread stat:\\n\"\n                for path in threading._start_trace:\n                    n = threading._start_trace[path]\n                    if n <= 1:\n                        continue\n                    dat += \"%s => %d\\n\\n\" % (path, n)\n\n            dat += \"thread num:%d<br>\" % threading.active_count()\n\n            self.send_response(\"text/plain\", dat)\n        except Exception as e:\n            xlog.exception(\"debug:%r\", e)\n            self.send_response(\"text/html\", \"no mem_top\")\n\n\nmem_stat = None\n\n\ndef test_proxy(type, host, port, user, passwd):\n    if not host:\n        return False\n\n    if host == \"127.0.0.1\":\n        if port in [8087, 1080, 8086]:\n            xlog.warn(\"set LAN Proxy to %s:%d fail.\", host, port)\n            return False\n\n    client = simple_http_client.Client(proxy={\n        \"type\": type,\n        \"host\": host,\n        \"port\": int(port),\n        \"user\": user if len(user) else None,\n        \"pass\": passwd if len(passwd) else None\n    }, timeout=3)\n\n    urls = [\n        \"https://www.microsoft.com\",\n        \"https://www.apple.com\",\n        \"https://code.jquery.com\",\n        \"https://cdn.bootcss.com\",\n        \"https://cdnjs.cloudflare.com\"]\n\n    for url in urls:\n        header = {\n            \"user-agent\": \"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36\",\n            \"accept\": \"application/json, text/javascript, */*; q=0.01\",\n            \"accept-encoding\": \"gzip, deflate, sdch\",\n            \"accept-language\": 'en-US,en;q=0.8,ja;q=0.6,zh-CN;q=0.4,zh;q=0.2',\n            \"connection\": \"keep-alive\"\n        }\n        try:\n            response = client.request(\"HEAD\", url, header, \"\")\n            if response:\n                return True\n        except Exception as e:\n            xlog.exception(\"test_proxy %s fail:%r\", url, e)\n            pass\n\n    return False\n\n\nserver = None\n\n\ndef start(allow_remote=0):\n    global server\n    # should use config.yaml to bind ip\n    if not allow_remote:\n        allow_remote = config.allow_remote_connect\n    host_ip = config.control_ip\n    host_port = config.control_port\n\n    if allow_remote:\n        xlog.info(\"allow remote access WebUI\")\n\n    listen_ips = []\n    if allow_remote and (\"0.0.0.0\" not in listen_ips or \"::\" not in listen_ips):\n        listen_ips.append(\"0.0.0.0\")\n    else:\n        if isinstance(host_ip, str):\n            listen_ips = [host_ip]\n        else:\n            listen_ips = list(host_ip)\n\n    addresses = [(listen_ip, host_port) for listen_ip in listen_ips]\n\n    xlog.info(\"begin to start web control:%s\", addresses)\n\n    server = simple_http_server.HTTPServer(addresses, Http_Handler, logger=xlog, max_thread=2048)\n    server.start()\n\n    xlog.info(\"launcher web control started.\")\n\n\ndef stop():\n    global server\n    xlog.info(\"begin to exit web control\")\n    server.shutdown()\n    xlog.info(\"launcher web control exited.\")\n\n\ndef http_request(url, method=\"GET\", timeout=30):\n    proxy_handler = ProxyHandler({})\n    opener = build_opener(proxy_handler)\n    try:\n        req = opener.open(url, timeout=timeout)\n        return req\n    except Exception as e:\n        # xlog.exception(\"web_control http_request:%s fail:%s\", url, e)\n        return False\n\n\ndef confirm_xxnet_not_running():\n    # if xxnet is already running, try exit it\n    is_xxnet_exit = False\n    host_port = config.control_port\n    req_url = \"http://127.0.0.1:{port}/quit\".format(port=host_port)\n    xlog.debug(\"start confirm_xxnet_exit url:%s\", req_url)\n\n    for i in range(30):\n        if http_request(req_url, timeout=5) == False:\n            xlog.debug(\"good, xxnet:%s clear!\" % host_port)\n            is_xxnet_exit = True\n            break\n        else:\n            xlog.debug(\"<%d>: try to terminate xxnet:%s\" % (i, host_port))\n        time.sleep(1)\n    xlog.debug(\"finished confirm_xxnet_exit\")\n    return is_xxnet_exit\n\n\ndef confirm_module_ready(port):\n    if port == 0:\n        xlog.error(\"confirm_module_ready with port: 0\")\n        time.sleep(1)\n        return False\n\n    for i in range(200):\n        req = http_request(\"http://127.0.0.1:%d/is_ready\" % port)\n        if req == False:\n            time.sleep(1)\n            continue\n\n        content = req.read(1024)\n        req.close()\n        # xlog.debug(\"cert_import_ready return:%s\", content)\n        if content == \"True\":\n            return True\n        else:\n            time.sleep(1)\n    return False\n\n\nif __name__ == \"__main__\":\n    pass\n    # confirm_xxnet_exit()\n"
  },
  {
    "path": "code/default/launcher/web_ui/about.html",
    "content": "\n<div id=\"welcome\" class=\"hero-unit hide\" style=\"padding-left: 70px;\">\n    <button type=\"button\" class=\"close\" onclick=\"welcomeClose();\" aria-hidden=\"true\">&times;</button>\n    <h1 id=\"welcome-title\">{{ _( \"Hello!\" ) }}</h1>\n    <p id=\"welcome-message\">{{ _( \"You seem to be on your first visit.\" ) }}</p>\n    <a id=\"btn-learnmore\" class=\"btn btn-primary btn-large\">{{ _( \"Learn more\" ) }}</a>\n</div>\n\n<div id=\"notice\" class=\"well\">\n    <label for=\"notice-content\" class=\"fluid-down-control\">\n        <i class=\"icon icon-chevron-right\"></i> <b>{{ _( \"Notice\" ) }} ({{ _( \"click to view\" ) }})</b>\n    </label>\n    <ul id=\"notice-content\" style=\"display:none; overflow:auto; width:auto; height:auto; max-height:200px; list-style-type:circle\"></ul>\n    <!--<svg height=\"16\" version=\"1.1\" viewBox=\"0 0 14 16\" width=\"14\"><path fill-rule=\"evenodd\" d=\"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z\"></path></svg>-->\n    <br/>\n</div> <!-- #notice -->\n\n<div id=\"about\">\n    <div class=\"row-fluid\">\n        <div class=\"span3\"><strong>{{ _( \"Version\" ) }}</strong></div> <!-- .span4 -->\n        <div class=\"span7\" id=\"about_current_version\"> </div> <!-- .span8 -->\n    </div> <!-- .div.fluid -->\n    <div class=\"row-fluid\">\n        <div class=\"span3\"><strong>{{ _( \"Project main page\" ) }}</strong></div> <!-- .span4 -->\n        <div class=\"span3\"><a href=\"https://github.com/XX-net/XX-Net\" target=\"_blank\">XX-Net@GitHub</a></div> <!-- .span8 -->\n        <div class=\"span3\"><a href=\"https://gitlab.com/XX-net/XX-Net\" target=\"_blank\">XX-Net@GitLab</a></div> <!-- .span8 -->\n    </div> <!-- .div.fluid -->\n    <div class=\"row-fluid\">\n        <div class=\"span3\"><strong>{{ _( \"Official Web Site\" ) }}</strong></div> <!-- .span4 -->\n        <div class=\"span4\"><a href=\"https://xx-net.com\" target=\"_blank\">https://xx-net.com</a></div> <!-- .span8 -->\n    </div> <!-- .div.fluid -->\n    <div class=\"row-fluid\">\n        <div class=\"span3\"><strong>{{ _( \"Telegram group\" ) }}</strong></div> <!-- .span4 -->\n        <div class=\"span4\"><a href=\"https://t.me/xxnetshare\" target=\"_blank\">https://t.me/xxnetshare</a></div> <!-- .span8 -->\n    </div> <!-- .div.fluid -->\n    <div class=\"row-fluid\">\n        <div class=\"span3\"><strong>{{ _( \"Telegram Channel\" ) }}</strong></div> <!-- .span4 -->\n        <div class=\"span5\"><a href=\"https://t.me/XXNETCHANNEL\" target=\"_blank\">https://t.me/XXNETCHANNEL</a></div> <!-- .span8 -->\n    </div> <!-- .div.fluid -->\n    <div class=\"row-fluid\">\n        <div class=\"span3\"><strong>{{ _( \"Bug feedback\" ) }}</strong></div> <!-- .span4 -->\n        <div class=\"span8\">\n            <a href=\"https://github.com/XX-net/XX-Net/issues\" target=\"_blank\">GitHub@XX-Net/Issues</a>\n            ({{ _( \"When submitting a bug, please attach \" ) }}<a href=\"http://127.0.0.1:8085/?module=gae_proxy&menu=status\" target=\"_blank\">{{ _( \"the status page \" ) }}</a>{{ _( \"info and \" ) }}<a href=\"http://127.0.0.1:8085/?module=gae_proxy&menu=logging\" target=\"_blank\">{{ _( \"the log page \" ) }}</a>{{ _( \"contents\" ) }})\n        </div> <!-- .span8 -->\n    </div> <!-- .div.fluid -->\n    <div class=\"row-fluid\">\n        <div class=\"span3\"><strong>Wiki</strong></div> <!-- .span4 -->\n        <div class=\"span8\">\n            <a href=\"https://github.com/XX-net/XX-Net/wiki\" target=\"_blank\">GitHub/XX-Net/Wiki</a>\n        </div> <!-- .span8 -->\n    </div> <!-- .div.fluid -->\n    <div class=\"row-fluid\">\n        <div class=\"span3\"><strong>Twitter</strong></div> <!-- .span4 -->\n        <div class=\"span8\">\n            <a href=\"https://twitter.com/XXNetDev\" target=\"_blank\">@XXNetDev</a>\n        </div> <!-- .span8 -->\n    </div> <!-- .div.fluid -->\n    <div class=\"row-fluid\">\n        <div class=\"span3\"><strong>{{ _( \"Collect debug info\" ) }}</strong></div> <!-- .span4 -->\n        <div class=\"span8\">\n            <a href=\"/log_files\" target=\"_blank\">\n                <button class=\"btn btn-primary ladda-button\" data-style=\"slide-up\" id=\"check-new-version\">{{ _( \"Download\" ) }}</button>\n            </a>\n        </div> <!-- .span8 -->\n    </div> <!-- .div.fluid -->\n</div> <!-- #about -->\n\n\n<div id=\"thanks\">\n    <h3>{{ _( \"Thanks to the following projects\" ) }}</h3>\n    <ol>\n        <li>GoAgent</li>\n        <li>fqrouter</li>\n        <li>Xndroid</li>\n        <li>goagentfindip</li>\n        <li>GoGoTester</li>\n        <li>EasyGoAgent</li>\n        <li>Cloudflare</li>\n        <li>Google</li>\n    </ol>\n</div> <!-- #thanks -->\n<!-- JavaScript -->\n<script type=\"text/javascript\">\n    title('{{ _( \"About\" ) }} {{ _( \"APP_NAME\" ) }}');\n</script>\n<script type=\"text/javascript\">\n    var pageRequests = {\n        'cmd': 'get_version'\n    };\n    $.ajax({\n        type: 'GET',\n        url: '/config',\n        data: pageRequests,\n        dataType: 'JSON',\n        success: function (result) {\n            document.getElementById(\"about_current_version\").appendChild(document.createTextNode(result['current_version']));\n        }\n    });\n\n    $('#notice').click(function () {\n        if ($('#notice-content', this).html() == '') {\n            getNotice();\n        }\n    });\n\n</script>\n"
  },
  {
    "path": "code/default/launcher/web_ui/config.html",
    "content": "\n<ul class=\"nav nav-tabs\">\n    <li class=\"active\"><a class=\"config_tab\" id=\"general\" data-toggle=\"tab\">{{ _( \"General Settings\" ) }}</a></li>\n    <li><a class=\"config_tab\" id=\"update\" data-toggle=\"tab\">{{ _( \"System Version\" ) }}</a></li>\n    <li><a class=\"config_tab\" id=\"proxy\" data-toggle=\"tab\">{{ _( \"LAN Proxy Setting\" ) }}</a></li>\n    <li id=\"app_list\" hidden><a class=\"config_tab\" id=\"applist\" data-toggle=\"tab\">{{ _( \"App List\" ) }}</a></li>\n</ul>\n\n<div id=\"config_content\" class=\"tab-content\">\n    <div id=\"tab_content\" class=\"tab-pane fade in active\">\n    </div>\n</div>\n\n\n<!-- JavaScript -->\n<script type=\"text/javascript\">\n    title('{{ _( \"System Configuration\" ) }}');\n</script>\n\n<script type=\"text/javascript\">\n    $(\".config_tab\").click(function () {\n        var id = $(this).attr('id');\n        var url = \"/module/launcher/config_\" + id + \".html\";\n        $(\"#tab_content\").load(url);\n    });\n    $(\"#tab_content\").load(\"/module/launcher/config_general.html\");\n</script>\n\n<script type=\"text/javascript\">\n    function restartingService(serviceNameSlug) {\n        var serviceName     = '',\n            restatingTime   = 5,\n            messageTemplate = '{{ _( \"Configuring the service[%s]. This page will refresh within %s seconds.\" ) }}';\n\n        switch (serviceNameSlug) {\n            case 'gae_proxy_enable':\n                serviceName = '{{ _( \"GAE Proxy\" ) }}';\n                break;\n            case 'x_tunnel_enable':\n                serviceName = '{{ _( \"X-Tunnel\" ) }}';\n                break;\n            case 'smart_router_enable':\n                serviceName = '{{ _( \"Smart Router\" ) }}';\n                break;\n            default:\n                serviceName = 'Unknown';\n                break;\n        }\n\n        tip(messageTemplate.format(serviceName, restatingTime), 'warning');\n\n        setTimeout(function () {\n            location.reload();\n        }, restatingTime * 1000);\n    }\n\n\n    $(function () {\n        var pageRequests = {\n            'cmd': 'get_config'\n        };\n\n        $.ajax({\n            type: 'GET',\n            url: '/config',\n            data: pageRequests,\n            dataType: 'JSON',\n            success: function (result) {\n                if (result['platform'] == 'android' ) {\n                    $(\"#app_list\").show();\n                } else {\n                    $(\"#app_list\").hide();\n                }\n            },\n            error: function () {\n                displayErrorMessage();\n            }\n        });\n    });\n</script>\n"
  },
  {
    "path": "code/default/launcher/web_ui/config_applist.html",
    "content": "<div class=\"row-fluid\">\n    <div class=\"config_label\">\n        <label for=\"proxy_by_app\">{{ _( \"Proxy by APP\" ) }} </label>\n    </div> <!-- .span4 -->\n    <div class=\"config_switch\">\n        <input id=\"proxy_by_app\" type=\"checkbox\" data-toggle=\"switch\"/>\n    </div> <!-- .span8 -->\n</div> <!-- .row-fluid -->\n\n<div id=\"loading_animation\">\n    <img src=\"img/loading-buffering.gif\">\n</div>\n\n<p class=\"tip\">* {{ _( \"Select which APP should be proxied. You need to restart VPN after change this.\" ) }}</p>\n\n<div id=\"app_config\" style=\"display: none\">\n    <div class=\"row-fluid\">\n        <div class=\"config_label\">\n            <label for=\"select_all\">{{ _( \"Select All\" ) }} </label>\n        </div> <!-- .span4 -->\n        <div class=\"config_switch\">\n            <input id=\"select_all\" type=\"checkbox\" data-toggle=\"switch\"/>\n        </div> <!-- .span8 -->\n    </div> <!-- .row-fluid -->\n\n    <hr>\n    <div id=\"installed-app-list\">\n    </div>\n</div>\n\n<div class=\"row-fluid\">\n    <div class=\"span12\">\n        <button class=\"btn btn-primary btn-block\" id=\"save_app_config\">{{ _( \"Save\" ) }}</button>\n    </div> <!-- .span12 -->\n</div> <!-- .row-fluid -->\n\n<script type=\"text/javascript\">\n\n    $('#proxy_by_app').change(function () {\n        var isChecked = $(this).is(':checked');\n        if (isChecked) {\n            $('#app_config').slideDown();\n        } else {\n            $('#app_config').slideUp();\n        }\n    });\n\n\n    $('#select_all').change(function () {\n        var isChecked = $(this).is(':checked');\n        if (isChecked) {\n            enabled_app_list = [];\n            $('.app_item').each(function(i, obj) {\n                obj.checked = true;\n                obj.parentElement.classList.remove(\"switch-off\");\n                obj.parentElement.classList.add(\"switch-on\");\n            });\n\n        } else {\n            $('.app_item').each(function(i, obj) {\n                obj.checked = false;\n                obj.parentElement.classList.remove(\"switch-on\");\n                obj.parentElement.classList.add(\"switch-off\");\n            });\n        }\n    });\n\n    $(function () {\n        $(\"#installed-app-list\").load('/installed_app', function() {\n            $('[data-toggle=switch]').wrap('<div class=\"switch\" />').parent().bootstrapSwitch();\n\n            if ($(\"#proxy_by_app_config\").attr( \"checked\" ) == \"checked\") {\n                $('#proxy_by_app').parent().removeClass(\"switch-off\");\n                $('#proxy_by_app').parent().addClass(\"switch-on\");\n                $('#proxy_by_app').attr('checked','checked');\n\n                $('#app_config').slideDown();\n            }\n            $(\"#loading_animation\").hide();\n        });\n    });\n\n    $(\"#save_app_config\").click( function() {\n        var enabled_app_list = [];\n        var apps = $('.app_item');\n        for (var i=0; i<apps.length; i++) {\n            var obj = apps[i];\n            if (obj.checked) {\n                enabled_app_list.push(obj.id);\n                console.log(obj.id);\n            }\n        }\n\n        var config = {\n            'proxy_by_app': $('#proxy_by_app').is(':checked'),\n            'enabled_app_list': enabled_app_list\n        };\n\n        $.ajax({\n            type: 'POST',\n            url: '/set_proxy_applist',\n            data: config,\n            dataType: 'JSON',\n            success: function (result) {\n                if (result['res'] == 'success') {\n                    tip('{{ _( \"Settings saved successfully, Please restart VPN.\" ) }}', 'success');\n                } else {\n                    tip('{{ _( \"Failed saving settings: \" ) }}'+ result['reason'], 'error');\n                }\n            },\n            error: function () {\n                tip('{{ _( \"Failed saving settings.\" ) }}', 'error');\n            }\n        });\n    });\n\n</script>"
  },
  {
    "path": "code/default/launcher/web_ui/config_general.html",
    "content": "<div id=\"options\">\n    <div class=\"row-fluid\">\n        <div class=\"span4\">\n            <label for=\"language\">{{ _( \"Language\" ) }}</label>\n        </div>\n        <div class=\"span3\">\n            <select id=\"language\">\n                <!-- <option value=\"de_DE\">Deutsch</option> -->\n                <option value=\"en_US\">English</option>\n                <!-- <option value=\"es_VE\">Español</option> -->\n                <option value=\"fa_IR\">فارسی</option>\n                <!-- <option value=\"ja_JP\">日本語</option> -->\n                <option value=\"zh_CN\">简体中文</option>\n                <option value=\"ru_RU\">русский</option>\n            </select>\n        </div>\n    </div>\n    <div class=\"row-fluid\" id=\"auto-startup\">\n        <div class=\"config_label\">{{ _( \"Auto-Startup\" ) }}</div> <!-- .span4 -->\n        <div class=\"config_switch\">\n            <input id=\"auto-start\" type=\"checkbox\" data-toggle=\"switch\"/>\n        </div> <!-- .span8 -->\n    </div> <!-- .row-fluid -->\n    <div class=\"row-fluid\" id=\"popup_web_console\">\n        <div class=\"config_label\">{{ _( \"Popup Status Page on Startup\" ) }}</div> <!-- .span4 -->\n        <div class=\"config_switch\">\n            <input id=\"popup-webui\" type=\"checkbox\" data-toggle=\"switch\"/>\n        </div> <!-- .span8 -->\n    </div> <!-- .row-fluid -->\n    <div class=\"row-fluid\" id=\"allow_remote\">\n        <div class=\"config_label\">{{ _( \"Allow Remote\" ) }}<a href=\"https://github.com/XX-net/XX-Net/wiki/AllowRemoteConnectToWebControl\" target=\"_blank\">({{ _( \"Help\" ) }})</a></div> <!-- .span4 -->\n        <div class=\"config_switch\">\n            <input id=\"allow-remote\" type=\"checkbox\" data-toggle=\"switch\"/>\n        </div> <!-- .span8 -->\n    </div> <!-- .row-fluid -->\n    <div class=\"row-fluid\" id=\"show_systray\">\n        <div class=\"config_label\">{{ _( \"Display System Tray(Restarting APP Required)\" ) }}</div> <!-- .span4 -->\n        <div class=\"config_switch\">\n            <input id=\"show-systray\" type=\"checkbox\" data-toggle=\"switch\"/>\n        </div> <!-- .span8 -->\n    </div> <!-- .row-fluid -->\n    <div class=\"row-fluid\" id=\"show_android_notification_\">\n        <div class=\"config_label\">{{ _( \"Display Notification\" ) }}</div> <!-- .span4 -->\n        <div class=\"config_switch\">\n            <input id=\"show_android_notification\" type=\"checkbox\" data-toggle=\"switch\"/>\n        </div> <!-- .span8 -->\n    </div> <!-- .row-fluid -->\n    <div class=\"row-fluid\" id=\"display_windows_suggestion\">\n        <div class=\"config_label\">{{ _( \"Display Windows software compatibility suggestions\" ) }}<a href=\"https://github.com/XX-net/XX-Net/issues/10957\" target=\"_blank\">({{ _( \"Feedback\" ) }})</a></div> <!-- .span4 -->\n        <div class=\"config_switch\">\n            <input id=\"show-compat-suggest\" type=\"checkbox\" data-toggle=\"switch\"/>\n        </div> <!-- .span8 -->\n    </div> <!-- .row-fluid -->\n    <div class=\"row-fluid\" id=\"run_as_green_software\">\n        <div class=\"config_label\">{{ _( \"Run as Green Software\" ) }}<a href=\"https://github.com/XX-net/XX-Net/wiki/%E4%BB%A5%E7%BB%BF%E8%89%B2%E8%BD%AF%E4%BB%B6%E8%BF%90%E8%A1%8C\" target=\"_blank\">({{ _( \"Help\" ) }})</a></div> <!-- .span4 -->\n        <div class=\"config_switch\">\n            <input id=\"no-mess-system\" type=\"checkbox\" data-toggle=\"switch\"/>\n        </div> <!-- .span8 -->\n    </div> <!-- .row-fluid -->\n\n    <div class=\"row-fluid\">\n        <div class=\"span4\">\n            <label for=\"modules-manager\" class=\"pull-down-control\">\n                <i class=\"icon icon-chevron-right\"></i> {{ _( \"Module management\" ) }}\n            </label>\n        </div> <!-- .span4 -->\n    </div> <!-- .row-fluid -->\n    <div id=\"modules-manager\" style=\"display: none;\">\n        <hr>\n        <div class=\"row-fluid\">\n            <div class=\"config_label\">{{ _( \"Enable\" ) }} {{ _( \"GAE Proxy\" ) }}</div> <!-- .span4 -->\n            <div class=\"config_switch\">\n                <input id=\"gae_proxy-enable\" type=\"checkbox\" data-toggle=\"switch\"/> <!--disabled-->\n            </div> <!-- .span8 -->\n        </div> <!-- .row-fluid -->\n        <div class=\"row-fluid\">\n            <div class=\"config_label\">{{ _( \"Enable\" ) }} {{ _( \"X-Tunnel\" ) }}</div> <!-- .span4 -->\n            <div class=\"config_switch\">\n                <input id=\"x-tunnel-enable\" type=\"checkbox\" data-toggle=\"switch\"/>\n            </div> <!-- .span8 -->\n        </div> <!-- .row-fluid -->\n        <div class=\"row-fluid\" id=\"smart_router_model\">\n            <div class=\"config_label\">{{ _( \"Enable\" ) }} {{ _( \"Smart Router\" ) }}</div> <!-- .span4 -->\n            <div class=\"config_switch\">\n                <input id=\"smart-router-enable\" type=\"checkbox\" data-toggle=\"switch\"/>\n            </div> <!-- .span8 -->\n        </div> <!-- .row-fluid -->\n        <hr>\n    </div> <!-- #advanced-options -->\n</div> <!-- #options -->\n\n<script type=\"text/javascript\">\n    $(function () {\n        $('[data-toggle=switch]').wrap('<div class=\"switch\" />').parent().bootstrapSwitch();\n    });\n</script>\n<script type=\"text/javascript\">\n    $('.pull-down-control').click(function () {\n        var isShown = $('i.icon', this).hasClass('icon-chevron-down');\n        var id = $(this).attr('for');\n\n        if (!isShown) {\n            $('i.icon', this).removeClass('icon-chevron-right');\n            $('i.icon', this).addClass('icon-chevron-down');\n            $('#' + id).slideDown();\n        } else {\n            $('i.icon', this).removeClass('icon-chevron-down');\n            $('i.icon', this).addClass('icon-chevron-right');\n            $('#' + id).slideUp();\n        }\n    });\n</script>\n<script type=\"text/javascript\">\n    $(function () {\n        getConfig_Init();\n    });\n\n    function getConfig_Init() {\n        var pageRequests = {\n            'cmd': 'get_config'\n        };\n\n        $.ajax({\n            type: 'GET',\n            url: '/config',\n            data: pageRequests,\n            dataType: 'JSON',\n            success: function (result) {\n                if (result['auto_start'] != 0) {\n                    $(\"#auto-start\").parent().removeClass('switch-off');\n                    $(\"#auto-start\").parent().addClass('switch-on');\n\n                    $(\"#auto-start\").prop('checked', true);\n                }\n                if (result['popup_webui'] != 0) {\n                    $(\"#popup-webui\").parent().removeClass('switch-off');\n                    $(\"#popup-webui\").parent().addClass('switch-on');\n\n                    $(\"#popup-webui\").prop('checked', true);\n                }\n                if (result['allow_remote_switch'] != 0) {\n                    $(\"#allow-remote\").parent().removeClass('switch-off');\n                    $(\"#allow-remote\").parent().addClass('switch-on');\n\n                    $(\"#allow-remote\").prop('checked', true);\n                }\n                if (result['show_systray'] != 0) {\n                    $(\"#show-systray\").parent().removeClass('switch-off');\n                    $(\"#show-systray\").parent().addClass('switch-on');\n\n                    $(\"#show-systray\").prop('checked', true);\n                }\n                if (result['show_android_notification'] != 0) {\n                    $(\"#show_android_notification\").parent().removeClass('switch-off');\n                    $(\"#show_android_notification\").parent().addClass('switch-on');\n\n                    $(\"#show_android_notification\").prop('checked', true);\n                }\n                if (result['show-compat-suggest'] != 0) {\n                    $(\"#show-compat-suggest\").parent().removeClass('switch-off');\n                    $(\"#show-compat-suggest\").parent().addClass('switch-on');\n\n                    $(\"#show-compat-suggest\").prop('checked', true);\n                }\n                if (result['no_mess_system'] != 0) {\n                    $(\"#no-mess-system\").parent().removeClass('switch-off');\n                    $(\"#no-mess-system\").parent().addClass('switch-on');\n\n                    $(\"#no-mess-system\").prop('checked', true);\n                }\n                if (result['gae_proxy_enable'] != 0) {\n                    $(\"#gae_proxy-enable\").parent().removeClass('switch-off');\n                    $(\"#gae_proxy-enable\").parent().addClass('switch-on');\n\n                    $(\"#gae_proxy-enable\").prop('checked', true);\n                    //$(\"#gae_proxy-enable\").prop('disabled', true);\n                    //$(\"#gae_proxy-enable\").parent().parent().addClass(\"deactivate\");\n                }\n                if (result['x_tunnel_enable'] != 0) {\n                    $(\"#x-tunnel-enable\").parent().removeClass('switch-off');\n                    $(\"#x-tunnel-enable\").parent().addClass('switch-on');\n\n                    $(\"#x-tunnel-enable\").prop('checked', true);\n                }\n                if (result['smart_router_enable'] != 0) {\n                    $(\"#smart-router-enable\").parent().removeClass('switch-off');\n                    $(\"#smart-router-enable\").parent().addClass('switch-on');\n\n                    $(\"#smart-router-enable\").prop('checked', true);\n                }\n                $(\"#language\").val(result['language']);\n\n                if (result['platform'] != 'windows') {\n                    $(\"#display_windows_suggestion\").hide();\n                }\n                if (result['platform'] == 'android' || result['platform'] == 'ios') {\n                    $(\"#auto-startup\").hide();\n                    $(\"#popup_web_console\").hide();\n                    $(\"#show_systray\").hide();\n                    $(\"#run_as_green_software\").hide();\n                    $(\"#smart_router_model\").hide();\n                }\n                if (result['platform'] == 'ios') {\n                    // currently not support,\n                    // listen to 0.0.0.0 lead to failed access from 127.0.0.1 in iOS.\n                    $(\"#allow_remote\").hide();\n                }\n                if (result['platform'] != 'android') {\n                    $(\"#show_android_notification_\").hide();\n                }\n            },\n            error: function () {\n                displayErrorMessage();\n            }\n        });\n    }\n</script>\n<script type=\"text/javascript\">\n    $('#language').change(function() {\n        var key   = 'language',\n            value = $(this).val();\n\n        setConfig(key, value);\n\n        setTimeout(function () {\n            location.reload();\n        }, 500);\n    });\n\n    $('#auto-start').change(function () {\n        var isChecked = $(this).is(':checked'),\n            key       = 'auto_start',\n            value     = isChecked ? 1 : 0;\n\n        setConfig(key, value);\n    });\n\n    $('#show-systray').change(function () {\n        var isChecked = $(this).is(':checked'),\n            key       = 'show_systray',\n            value     = isChecked ? 1 : 0;\n\n        setConfig(key, value);\n    });\n\n    $('#show_android_notification').change(function () {\n        var isChecked = $(this).is(':checked'),\n            key       = 'show_android_notification',\n            value     = isChecked ? 1 : 0;\n\n        setConfig(key, value);\n    });\n\n    $('#show-compat-suggest').change(function () {\n        var isChecked = $(this).is(':checked'),\n            key       = 'show_compat_suggest',\n            value     = isChecked ? 1 : 0;\n\n        setConfig(key, value);\n    });\n\n    $('#no-mess-system').change(function () {\n        var isChecked = $(this).is(':checked'),\n            key       = 'no_mess_system',\n            value     = isChecked ? 1 : 0;\n\n        setConfig(key, value);\n    });\n\n    $('#popup-webui').change(function () {\n        var isChecked = $(this).is(':checked'),\n            key       = 'popup_webui',\n            value     = isChecked ? 1 : 0;\n\n        setConfig(key, value);\n    });\n\n    $('#allow-remote').change(function () {\n        var isChecked = $(this).is(':checked'),\n            key       = 'allow_remote_switch',\n            value     = isChecked ? 1 : 0;\n\n        tip('{{ _( \"Restarting all remote, wait to refresh.\" ) }}', 'info');\n\n        setTimeout(function () {\n            location.reload();\n        }, 8 * 1000);\n\n        setConfig(key, value);\n    });\n\n    $('#gae_proxy-enable').change(function () {\n        var isChecked = $(this).is(':checked'),\n            key       = 'gae_proxy_enable',\n            value     = isChecked ? 1 : 0;\n\n        setConfig(key, value);\n    });\n\n    $('#x-tunnel-enable').change(function () {\n        var isChecked = $(this).is(':checked'),\n            key       = 'x_tunnel_enable',\n            value     = isChecked ? 1 : 0;\n\n        setConfig(key, value);\n    });\n\n    $('#smart-router-enable').change(function () {\n        var isChecked = $(this).is(':checked'),\n            key       = 'smart_router_enable',\n            value     = isChecked ? 1 : 0;\n\n        setConfig(key, value);\n    });\n</script>\n"
  },
  {
    "path": "code/default/launcher/web_ui/config_proxy.html",
    "content": "    <form id=\"config_proxy\" method=\"POST\" onSubmit=\"onSubmit(); return false;\">\n        <div class=\"row-fluid\">\n            <div class=\"span4\">\n                <label for=\"enable-proxy\">{{ _( \"LAN proxy\" ) }} <a href=\"https://github.com/XX-net/XX-Net/wiki/GoAgent-Intranet-proxy\" target=\"_blank\">({{ _( \"Help\" ) }})</a></label>\n            </div> <!-- .span4 -->\n            <div class=\"span8\">\n                <input id=\"enable-proxy\" type=\"checkbox\" data-toggle=\"switch\"/>\n            </div> <!-- .span8 -->\n        </div> <!-- .row-fluid -->\n        <p class=\"tip\">* {{ _( \"Generally not needed, only those who need internal proxy to access the external network (companies, Intranet, campus, etc.) need to configure this.\" ) }}</p>\n        <div id=\"proxy-options\" style=\"display: none;\">\n            <div class=\"row-fluid\">\n                <div class=\"span4\">\n                    <label for=\"proxy-type\">{{ _( \"Proxy type\" ) }}</label>\n                </div> <!-- .span4 -->\n                <div class=\"span8\">\n                    <select id=\"proxy-type\">\n                        <option value=\"HTTP\">HTTP</option>\n                        <option value=\"SOCKS4\">SOCKS 4</option>\n                        <option value=\"SOCKS5\">SOCKS 5</option>\n                    </select>\n                </div> <!-- .span8 -->\n            </div> <!-- .row-fluid -->\n            <div class=\"row-fluid\">\n                <div class=\"span4\">\n                    <label for=\"proxy-host\">{{ _( \"Proxy IP address or domain name\" ) }}</label>\n                </div> <!-- .span4 -->\n                <div class=\"span8\">\n                    <input id=\"proxy-host\" type=\"text\" placeholder=\"Example: 127.0.0.1\"/>\n                </div> <!-- .span8 -->\n            </div> <!-- .row-fluid -->\n            <div class=\"row-fluid\">\n                <div class=\"span4\">\n                    <label for=\"proxy-port\">{{ _( \"Port\" ) }}</label>\n                </div> <!-- .span4 -->\n                <div class=\"span8\">\n                    <input id=\"proxy-port\" type=\"number\" min=\"1\" max=\"65535\" placeholder=\"Example: 8080\"/>\n                </div> <!-- .span8 -->\n            </div> <!-- .row-fluid -->\n            <div class=\"row-fluid\">\n                <div class=\"span4\">\n                    <label for=\"proxy-username\">{{ _( \"User name\" ) }}</label>\n                </div> <!-- .span4 -->\n                <div class=\"span8\">\n                    <input id=\"proxy-username\" type=\"text\"/>\n                </div> <!-- .span8 -->\n            </div> <!-- .row-fluid -->\n            <div class=\"row-fluid\">\n                <div class=\"span4\">\n                    <label for=\"proxy-password\">{{ _( \"Password\" ) }}</label>\n                </div> <!-- .span4 -->\n                <div class=\"span8\">\n                    <input id=\"proxy-password\" type=\"password\"/>\n                </div> <!-- .span8 -->\n            </div> <!-- .row-fluid -->\n        </div> <!-- #proxy-options -->\n\n        <div class=\"row-fluid\">\n            <div class=\"span12\">\n                <button class=\"btn btn-primary btn-block\" type=\"submit\">{{ _( \"Save\" ) }}</button>\n            </div> <!-- .span12 -->\n        </div> <!-- .row-fluid -->\n    </form>\n\n<script type=\"text/javascript\">\n    $(function () {\n        $('[data-toggle=switch]').wrap('<div class=\"switch\" />').parent().bootstrapSwitch();\n    });\n</script>\n\n<script type=\"text/javascript\">\n    $('#enable-proxy').change(function () {\n        var isChecked = $(this).is(':checked');\n        if (isChecked) {\n            $('#proxy-options').slideDown();\n        } else {\n            $('#proxy-options').slideUp();\n        }\n    });\n</script>\n\n<script type=\"text/javascript\">\n    $(function () {\n        $.ajax({\n            type: 'GET',\n            url: '/config_proxy?cmd=get_config',\n            dataType: 'JSON',\n            success: function (result) {\n                if (typeof(result['enable']) != 'undefined' && result['enable'] != 0) {\n                    $('#enable-proxy').parent().removeClass('switch-off');\n                    $('#enable-proxy').parent().addClass('switch-on');\n                    $('#enable-proxy').prop('checked', true);\n                    $('#proxy-options').slideDown();\n                }\n                $('#proxy-type').val(result['type']);\n                $('#proxy-host').val(result['host']);\n                $('#proxy-port').val(result['port']);\n                $('#proxy-username').val(result['user']);\n                $('#proxy-password').val(result['passwd']);\n            },\n            error: function () {\n                tip('{{ _( \"Failed reading the settings.\" ) }}', 'error');\n            }\n        });\n    });\n</script>\n\n<script type=\"text/javascript\">\n    function onSubmit() {\n        var enable = $('#enable-proxy').is(':checked') ? 1 : 0;\n        var host = $('#proxy-host').val();\n        var port = $('#proxy-port').val();\n        if (enable) {\n            if ((host == \"127.0.0.1\" || host == \"localhost\") && (port == 8086 || port == 8087 || port == 1080)) {\n                tip('{{ _( \"Do you really need LAN proxy? <a href=\"https://github.com/XX-net/XX-Net/wiki/LAN-proxy-setting\">Help</a>.\" ) }}', 'error');\n                return;\n            }\n        }\n\n        var config = {\n            'enable': enable,\n            'type': $('#proxy-type').val(),\n            'host': host,\n            'port': port,\n            'user': $('#proxy-username').val(),\n            'passwd': $('#proxy-password').val()\n        };\n\n        tip('{{ _( \"Checking settings ...\" ) }}', 'info');\n\n        $.ajax({\n            type: 'GET',\n            url: '/config_proxy?cmd=set_config',\n            data: config,\n            dataType: 'JSON',\n            success: function (result) {\n                if (result['res'] == 'success') {\n                    tip('{{ _( \"Settings saved successfully.\" ) }}', 'success');\n                } else {\n                    tip('{{ _( \"Failed saving settings: \" ) }}'+ result['reason'], 'error');\n                }\n            },\n            error: function () {\n                tip('{{ _( \"Failed saving settings.\" ) }}', 'error');\n            }\n        });\n    }\n</script>\n"
  },
  {
    "path": "code/default/launcher/web_ui/config_update.html",
    "content": "    <div id=\"update-options\">\n        <div class=\"row-fluid\">\n            <div class=\"span3\">\n                <label for=\"check-update\">{{ _( \"Auto-Upgrade to\" ) }}: <a href=\"https://github.com/XX-net/XX-Net/wiki/Auto-update\" target=\"_blank\">({{ _( \"Help\" ) }})</a></label>\n            </div>\n            <div class=\"span3\">\n                <select id=\"check-update\">\n                    <option value=\"dont-check\">{{ _( \"Do not upgrade\" ) }}</option>\n                    <option value=\"notice-stable\">{{ _( \"Notice stable version\" ) }}</option>\n                    <option value=\"stable\">{{ _( \"Stable version\" ) }}</option>\n                    <option value=\"notice-test\">{{ _( \"Notice test version\" ) }}</option>\n                    <option value=\"test\">{{ _( \"Test version\" ) }}</option>\n                </select>\n            </div>\n            <div class=\"span2\">\n                <button class=\"btn btn-primary ladda-button\" data-style=\"slide-up\" id=\"check-new-version\">{{ _( \"Check the latest version\" ) }}</button>\n            </div>\n            <div class=\"span1\" id=\"check-new-version-process\">\n            </div>\n        </div> <!-- .row-fluid -->\n        <div class=\"row-fluid version-line hide\">\n            <div class=\"span2\">\n                <label for=\"current-version-no\">{{ _( \"Current version\" ) }}: </label>\n            </div>\n            <div class=\"span4\" id=\"current-version-no\" style=\"margin-top:10px\"></div>\n        </div> <!-- .row-fluid -->\n        <div class=\"row-fluid version-line hide\">\n            <div class=\"span2\">\n                <label for=\"test-version-no\">{{ _( \"Version of the test one\" ) }}: </label>\n            </div>\n            <div class=\"span4\" id=\"test-version-no\" style=\"margin-top:10px\"></div>\n            <div class=\"span2\">\n                <button class=\"btn btn-warning update-button ladda-button\" data-style=\"expand-right\" id=\"update-test-version\">{{ _( \"Update now\" ) }}</button>\n            </div>\n        </div> <!-- .row-fluid -->\n        <div class=\"row-fluid version-line hide\">\n            <div class=\"span2\">\n                <label for=\"stable-version-no\">{{ _( \"Version of the stable one\" ) }}: </label>\n            </div>\n            <div class=\"span4\" id=\"stable-version-no\" style=\"margin-top:10px\"></div>\n            <div class=\"span2\">\n                <button class=\"btn btn-primary update-button ladda-button\" data-style=\"expand-right\" id=\"update-stable-version\">{{ _( \"Update now\" ) }}</button>\n            </div>\n        </div> <!-- .row-fluid -->\n        <hr/>\n        <div class=\"row-fluid\">\n            <div class=\"span3\">\n                <label>\n                    {{ _( \"Keep old versions count\" ) }}\n                    <br/>\n                    (0~99, 99 = {{ _( \"keep all\" ) }})\n                </label>\n            </div>\n            <div class=\"span3\">\n                <input id=\"keep_old_ver_num\" type=\"number\" min=0 max=99 value=\"abc\"/>\n            </div>\n            <div class=\"span3\">\n                <button id=\"save_keep_old_ver_num\" class=\"btn btn-primary\">{{ _( \"Save\" ) }}</button>\n            </div>\n        </div>\n    </div> <!-- #advanced-options -->\n    <hr/>\n\n    <div class=\"row-fluid\">\n        <div class=\"span4\">\n            <label for=\"manual-update\" class=\"pull-down-control\">\n                <i class=\"icon icon-chevron-right\"></i> {{ _( \"Manually Manage\" ) }} ({{ _( \"Advanced\" ) }})\n            </label>\n        </div> <!-- .span4 -->\n    </div>\n    <div id=\"manual-update\" style=\"display: none;\">\n        <br/>\n        <div class=\"row-fluid\">\n            <a href=\"https://github.com/XX-net/XX-Net/releases\" target=\"_blank\">{{ _( \"All versions download page\" ) }}</a>\n        </div>\n        <br/>\n        <div class=\"row-fluid\">\n            <div class=\"span3\">\n                <label>{{ _( \"Released version\" ) }} :</label>\n            </div>\n            <div class=\"span3\">\n                <select id=\"released-versions-selector\">\n                    <option>{{ _( \"Released\" ) }}</option>\n                </select>\n            </div>\n            <div class=\"span3\">\n                <button class=\"btn btn-primary ladda-button\" data-style=\"slide-up\" id=\"manual-upgrade-to\">{{ _( \"Download & Change to\" ) }} ({{ _( \"no hash check\" ) }})</button>\n            </div>\n        </div>\n        <br>\n        <div class=\"row-fluid\">\n            <div class=\"span3\">\n                <label>{{ _( \"Local version\" ) }} :</label>\n            </div>\n            <div class=\"span3\">\n                <select id=\"local-versions-selector\">\n                    <option>{{ _( \"Local\" ) }}</option>\n                </select>\n            </div>\n            <div class=\"span3\">\n                <button class=\"btn btn-primary ladda-button\" data-style=\"slide-up\" id=\"set-as-local-version\">{{ _( \"Change to this version\" ) }}</button>\n            </div>\n            <div class=\"span3\">\n                <button class=\"btn btn-warning ladda-button\" data-style=\"slide-up\" id=\"delete-local-version\">{{ _( \"Delete\" ) }}</button>\n            </div>\n        </div>\n    </div>\n\n<script type=\"text/javascript\">\n    $('.pull-down-control').click(function () {\n        var isShown = $('i.icon', this).hasClass('icon-chevron-down');\n        var id = $(this).attr('for');\n\n        if (!isShown) {\n            $('i.icon', this).removeClass('icon-chevron-right');\n            $('i.icon', this).addClass('icon-chevron-down');\n            $('#' + id).slideDown();\n        } else {\n            $('i.icon', this).removeClass('icon-chevron-down');\n            $('i.icon', this).addClass('icon-chevron-right');\n            $('#' + id).slideUp();\n        }\n    });\n</script>\n<script type=\"text/javascript\">\n    function updateGetConfig() {\n        var pageRequests = {\n            'cmd': 'get_config'\n        };\n\n        $.ajax({\n            type: 'GET',\n            url: '/config',\n            data: pageRequests,\n            dataType: 'JSON',\n            success: function (result) {\n                $(\"#check-update\").val(result['check_update']);\n            },\n            error: function () {\n                displayErrorMessage();\n            }\n        });\n    }\n\n    $(function () {\n        updateGetConfig();\n    });\n</script>\n<script type=\"text/javascript\">\n    function versionCompare(v1, v2, options) {\n        var lexicographical = options && options.lexicographical,\n            zeroExtend = options && options.zeroExtend,\n            v1parts = v1.split('.'),\n            v2parts = v2.split('.');\n\n        function isValidPart(x) {\n            return (lexicographical ? /^\\d+[A-Za-z]*$/ : /^\\d+$/).test(x);\n        }\n\n        if (!v1parts.every(isValidPart) || !v2parts.every(isValidPart)) {\n            return NaN;\n        }\n\n        if (zeroExtend) {\n            while (v1parts.length < v2parts.length) v1parts.push(\"0\");\n            while (v2parts.length < v1parts.length) v2parts.push(\"0\");\n        }\n\n        if (!lexicographical) {\n            v1parts = v1parts.map(Number);\n            v2parts = v2parts.map(Number);\n        }\n\n        for (var i = 0; i < v1parts.length; ++i) {\n            if (v2parts.length == i) {\n                return 1;\n            }\n\n            if (v1parts[i] == v2parts[i]) {\n                continue;\n            }\n            else if (v1parts[i] > v2parts[i]) {\n                return 1;\n            }\n            else {\n                return -1;\n            }\n        }\n\n        if (v1parts.length != v2parts.length) {\n            return -1;\n        }\n\n        return 0;\n    }\n\n    $('#check-new-version').click(function () {\n        check_new_version();\n    });\n\n    function check_new_version() {\n        var button = $('#check-new-version');\n        var loading = Ladda.create(button[0]);\n        loading.start();\n\n        var pageRequests = {\n            'cmd': 'get_new_version'\n        };\n\n        $.ajax({\n            type: 'GET',\n            url: '/update',\n            data: pageRequests,\n            dataType: 'JSON',\n            success: function (result) {\n                if (result['res'] === 'success') {\n                    $('#current-version-no').html(result['current_version']);\n                    $('#test-version-no').html(result['test_version']);\n                    $('#stable-version-no').html(result['stable_version']);\n\n                    if (versionCompare(result['test_version'], result['current_version']) <= 0) {\n                        $('#update-test-version').addClass(\"hide\");\n                    }\n                    if (versionCompare(result['stable_version'], result['current_version']) <= 0) {\n                        $('#update-stable-version').addClass(\"hide\");\n                    }\n\n                    $('.version-line').removeClass('hide');\n                    $('.alert').removeClass('alert-error').addClass('hide');\n                } else {\n                    displayErrorMessage();\n                }\n                $('#check-new-version-process').addClass('hide');\n            },\n            error: function () {\n                displayErrorMessage();\n                $('#check-new-version-process').addClass('hide');\n            },\n            complete: function () {\n                loading.stop();\n            }\n        });\n    }\n</script>\n<script type=\"text/javascript\">\n    $('#check-update').change(function () {\n        var key   = 'check_update',\n            value = $(this).val();\n\n        if (value === 'dont-check') {\n            stopUpdateCheck()\n        } else {\n            startUpdateCheck()\n        }\n        setConfig(key, value);\n    });\n\n    $('.update-button').click(function () {\n        var id = $(this).attr('id');\n        if (id === 'update-test-version') {\n            versionToUpdate = $('#test-version-no').html();\n            //window.updating_button = $('#update-test-version');\n        } else if (id === 'update-stable-version') {\n            versionToUpdate = $('#stable-version-no').html();\n            //window.updating_button = $('#update-stable-version');\n        }\n\n        window.loading = Ladda.create(this);\n        window.loading.start();\n\n        updateVersion();\n    });\n</script>\n<script type=\"text/javascript\">\n    $(function () {\n        var pageRequests = {\n            'cmd': 'get_config'\n        };\n        $.ajax({\n            type: 'GET',\n            url: '/config',\n            data: pageRequests,\n            dataType: 'JSON',\n            success: function (result) {\n                if (result['keep_old_ver_num'] >= 0 && result['keep_old_ver_num'] <= 99) {\n                    $(\"#keep_old_ver_num\").val(result['keep_old_ver_num']);\n                } else {\n                    //$(\"#keep_old_ver_num\").val(-1);\n                }\n            },\n            error: function () {\n                displayErrorMessage();\n            }\n        });\n    });\n\n    $(\"#save_keep_old_ver_num\").click(function () {\n        keep_old_ver_num = $(\"#keep_old_ver_num\").val();\n\n        if (!(keep_old_ver_num >= 0 && keep_old_ver_num <= 99 )) return;\n\n        setConfig('keep_old_ver_num', keep_old_ver_num);\n    });\n</script>\n<script type=\"text/javascript\">\n    $('#manual-upgrade-to').click(function () {\n        versionToUpdate = $(\"#released-versions-selector\").val();\n\n        window.loading = Ladda.create(this);\n        window.loading.start();\n\n        updateVersionWithoutHashCheck();\n    });\n\n    $('#set-as-local-version').click(function () {\n        var pageRequests = {\n            'cmd': 'set_localversion',\n            'version': $(\"#local-versions-selector\").val()\n        };\n        $.ajax({\n            type: 'GET',\n            url: '/update',\n            data: pageRequests,\n            dataType: 'JSON',\n            success: function (result) {\n                if (result['res'] === 'success') {\n                    tip('{{ _( \"Settings saved successfully.\" ) }}', 'success');\n                } else {\n                    tip('{{ _( \"Settings save fail:\" ) }}' + result['reason'], 'warning');\n                }\n            },\n            error: function () {\n                displayErrorMessage();\n            }\n        });\n    });\n\n    $('#delete-local-version').click(function () {\n        var pageRequests = {\n            'cmd': 'del_localversion',\n            'version': $(\"#local-versions-selector\").val()\n        };\n        $.ajax({\n            type: 'GET',\n            url: '/update',\n            data: pageRequests,\n            dataType: 'JSON',\n            success: function (result) {\n                if (result['res'] === 'success') {\n                    tip('{{ _( \"Deleted successfully.\" ) }}', 'success');\n                } else {\n                    tip('{{ _( \"Deleting local version fail.\" ) }}', 'warning');\n                }\n            },\n            error: function () {\n                displayErrorMessage();\n            }\n        });\n    });\n\n    $(\"#local-versions-selector\").focus(function () {\n        get_localversions();\n    });\n    $(\"#released-versions-selector\").focus(function () {\n        get_releasedversions();\n    });\n    function get_localversions() {\n        var pageRequests = {\n            'cmd': 'get_localversions'\n        };\n        $.ajax({\n            type: 'GET',\n            url: '/update',\n            data: pageRequests,\n            dataType: 'json',\n            success: function (result) {\n                $(\"#local-versions-selector\").html(\"\");\n\n                for (var i in result) {\n                    var v = result[i]['v'];\n                    var f = result[i]['folder'];\n                    if (f !== v) {\n                        v += '(\"' + f + '\")'\n                    }\n                    var new_option = document.getElementById(\"local-versions-selector\").appendChild(document.createElement(\"option\"));\n                    new_option.value = f;\n                    new_option.text = v;\n                }\n            },\n            error: function () {\n                tip('{{ _( \"Failed getting local versions.\" ) }}', 'error');\n            }\n        });\n    }\n\n    var current_version = \"\";\n    var pageRequests = {\n        'cmd': 'get_version'\n    };\n    $.ajax({\n        type: 'GET',\n        url: '/config',\n        data: pageRequests,\n        dataType: 'JSON',\n        success: function (result) {\n            current_version = result['current_version'];\n        }\n    });\n\n    function get_releasedversions() {\n        $.ajax({\n            type: 'GET',\n            url: 'https://api.github.com/repos/XX-net/XX-Net/releases',\n            dataType: 'json',\n            success: function (result) {\n                $(\"#released-versions-selector\").html(\"\");\n\n                for (var i in result) {\n                    var ver = result[i]['tag_name'];\n                    if ( ver[0] != current_version[0]) {\n                        continue;\n                    }\n                    var new_option = document.getElementById(\"released-versions-selector\").appendChild(document.createElement(\"option\"));\n                    new_option.value = ver;\n                    new_option.text = ver;\n                }\n            },\n            error: function () {\n                tip('{{ _( \"Failed getting released versions.\" ) }}', 'error');\n            }\n        });\n    }\n</script>\n"
  },
  {
    "path": "code/default/launcher/web_ui/css/bootstrap-responsive.css",
    "content": "/*!\n * Bootstrap Responsive v2.3.2\n *\n * Copyright 2012 Twitter, Inc\n * Licensed under the Apache License v2.0\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Designed and built with all the love in the world @twitter by @mdo and @fat.\n */\n.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:\"\"}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}@-ms-viewport{width:device-width}.hidden{display:none;visibility:hidden}.visible-phone{display:none!important}.visible-tablet{display:none!important}.hidden-desktop{display:none!important}.visible-desktop{display:inherit!important}@media(min-width:768px) and (max-width:979px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-tablet{display:inherit!important}.hidden-tablet{display:none!important}}@media(max-width:767px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-phone{display:inherit!important}.hidden-phone{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:inherit!important}.hidden-print{display:none!important}}@media(min-width:1200px){.row{margin-left:-30px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:\"\"}.row:after{clear:both}[class*=\"span\"]{float:left;min-height:1px;margin-left:30px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px}.span12{width:1170px}.span11{width:1070px}.span10{width:970px}.span9{width:870px}.span8{width:770px}.span7{width:670px}.span6{width:570px}.span5{width:470px}.span4{width:370px}.span3{width:270px}.span2{width:170px}.span1{width:70px}.offset12{margin-left:1230px}.offset11{margin-left:1130px}.offset10{margin-left:1030px}.offset9{margin-left:930px}.offset8{margin-left:830px}.offset7{margin-left:730px}.offset6{margin-left:630px}.offset5{margin-left:530px}.offset4{margin-left:430px}.offset3{margin-left:330px}.offset2{margin-left:230px}.offset1{margin-left:130px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:\"\"}.row-fluid:after{clear:both}.row-fluid [class*=\"span\"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*=\"span\"]:first-child{margin-left:0}.row-fluid .controls-row [class*=\"span\"]+[class*=\"span\"]{margin-left:2.564102564102564%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%}.row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%}.row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%}.row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%}.row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%}.row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%}.row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%}.row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%}.row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%}.row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%}.row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%}.row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%}.row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%}.row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%}.row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%}.row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%}.row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%}.row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%}.row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%}.row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%}.row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%}.row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%}.row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%}.row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%}.row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%}.row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%}.row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%}.row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%}.row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%}.row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%}.row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%}.row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%}.row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%}.row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%}.row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*=\"span\"]+[class*=\"span\"]{margin-left:30px}input.span12,textarea.span12,.uneditable-input.span12{width:1156px}input.span11,textarea.span11,.uneditable-input.span11{width:1056px}input.span10,textarea.span10,.uneditable-input.span10{width:956px}input.span9,textarea.span9,.uneditable-input.span9{width:856px}input.span8,textarea.span8,.uneditable-input.span8{width:756px}input.span7,textarea.span7,.uneditable-input.span7{width:656px}input.span6,textarea.span6,.uneditable-input.span6{width:556px}input.span5,textarea.span5,.uneditable-input.span5{width:456px}input.span4,textarea.span4,.uneditable-input.span4{width:356px}input.span3,textarea.span3,.uneditable-input.span3{width:256px}input.span2,textarea.span2,.uneditable-input.span2{width:156px}input.span1,textarea.span1,.uneditable-input.span1{width:56px}.thumbnails{margin-left:-30px}.thumbnails>li{margin-left:30px}.row-fluid .thumbnails{margin-left:0}}@media(min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:\"\"}.row:after{clear:both}[class*=\"span\"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px}.span12{width:724px}.span11{width:662px}.span10{width:600px}.span9{width:538px}.span8{width:476px}.span7{width:414px}.span6{width:352px}.span5{width:290px}.span4{width:228px}.span3{width:166px}.span2{width:104px}.span1{width:42px}.offset12{margin-left:764px}.offset11{margin-left:702px}.offset10{margin-left:640px}.offset9{margin-left:578px}.offset8{margin-left:516px}.offset7{margin-left:454px}.offset6{margin-left:392px}.offset5{margin-left:330px}.offset4{margin-left:268px}.offset3{margin-left:206px}.offset2{margin-left:144px}.offset1{margin-left:82px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:\"\"}.row-fluid:after{clear:both}.row-fluid [class*=\"span\"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.7624309392265194%;*margin-left:2.709239449864817%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*=\"span\"]:first-child{margin-left:0}.row-fluid .controls-row [class*=\"span\"]+[class*=\"span\"]{margin-left:2.7624309392265194%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.43646408839778%;*width:91.38327259903608%}.row-fluid .span10{width:82.87292817679558%;*width:82.81973668743387%}.row-fluid .span9{width:74.30939226519337%;*width:74.25620077583166%}.row-fluid .span8{width:65.74585635359117%;*width:65.69266486422946%}.row-fluid .span7{width:57.18232044198895%;*width:57.12912895262725%}.row-fluid .span6{width:48.61878453038674%;*width:48.56559304102504%}.row-fluid .span5{width:40.05524861878453%;*width:40.00205712942283%}.row-fluid .span4{width:31.491712707182323%;*width:31.43852121782062%}.row-fluid .span3{width:22.92817679558011%;*width:22.87498530621841%}.row-fluid .span2{width:14.3646408839779%;*width:14.311449394616199%}.row-fluid .span1{width:5.801104972375691%;*width:5.747913483013988%}.row-fluid .offset12{margin-left:105.52486187845304%;*margin-left:105.41847889972962%}.row-fluid .offset12:first-child{margin-left:102.76243093922652%;*margin-left:102.6560479605031%}.row-fluid .offset11{margin-left:96.96132596685082%;*margin-left:96.8549429881274%}.row-fluid .offset11:first-child{margin-left:94.1988950276243%;*margin-left:94.09251204890089%}.row-fluid .offset10{margin-left:88.39779005524862%;*margin-left:88.2914070765252%}.row-fluid .offset10:first-child{margin-left:85.6353591160221%;*margin-left:85.52897613729868%}.row-fluid .offset9{margin-left:79.8342541436464%;*margin-left:79.72787116492299%}.row-fluid .offset9:first-child{margin-left:77.07182320441989%;*margin-left:76.96544022569647%}.row-fluid .offset8{margin-left:71.2707182320442%;*margin-left:71.16433525332079%}.row-fluid .offset8:first-child{margin-left:68.50828729281768%;*margin-left:68.40190431409427%}.row-fluid .offset7{margin-left:62.70718232044199%;*margin-left:62.600799341718584%}.row-fluid .offset7:first-child{margin-left:59.94475138121547%;*margin-left:59.838368402492065%}.row-fluid .offset6{margin-left:54.14364640883978%;*margin-left:54.037263430116376%}.row-fluid .offset6:first-child{margin-left:51.38121546961326%;*margin-left:51.27483249088986%}.row-fluid .offset5{margin-left:45.58011049723757%;*margin-left:45.47372751851417%}.row-fluid .offset5:first-child{margin-left:42.81767955801105%;*margin-left:42.71129657928765%}.row-fluid .offset4{margin-left:37.01657458563536%;*margin-left:36.91019160691196%}.row-fluid .offset4:first-child{margin-left:34.25414364640884%;*margin-left:34.14776066768544%}.row-fluid .offset3{margin-left:28.45303867403315%;*margin-left:28.346655695309746%}.row-fluid .offset3:first-child{margin-left:25.69060773480663%;*margin-left:25.584224756083227%}.row-fluid .offset2{margin-left:19.88950276243094%;*margin-left:19.783119783707537%}.row-fluid .offset2:first-child{margin-left:17.12707182320442%;*margin-left:17.02068884448102%}.row-fluid .offset1{margin-left:11.32596685082873%;*margin-left:11.219583872105325%}.row-fluid .offset1:first-child{margin-left:8.56353591160221%;*margin-left:8.457152932878806%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*=\"span\"]+[class*=\"span\"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:710px}input.span11,textarea.span11,.uneditable-input.span11{width:648px}input.span10,textarea.span10,.uneditable-input.span10{width:586px}input.span9,textarea.span9,.uneditable-input.span9{width:524px}input.span8,textarea.span8,.uneditable-input.span8{width:462px}input.span7,textarea.span7,.uneditable-input.span7{width:400px}input.span6,textarea.span6,.uneditable-input.span6{width:338px}input.span5,textarea.span5,.uneditable-input.span5{width:276px}input.span4,textarea.span4,.uneditable-input.span4{width:214px}input.span3,textarea.span3,.uneditable-input.span3{width:152px}input.span2,textarea.span2,.uneditable-input.span2{width:90px}input.span1,textarea.span1,.uneditable-input.span1{width:28px}}@media(max-width:767px){body{padding-right:20px;padding-left:20px}.navbar-fixed-top,.navbar-fixed-bottom,.navbar-static-top{margin-right:-20px;margin-left:-20px}.container-fluid{padding:0}.dl-horizontal dt{float:none;width:auto;clear:none;text-align:left}.dl-horizontal dd{margin-left:0}.container{width:auto}.row-fluid{width:100%}.row,.thumbnails{margin-left:0}.thumbnails>li{float:none;margin-left:0}[class*=\"span\"],.uneditable-input[class*=\"span\"],.row-fluid [class*=\"span\"]{display:block;float:none;width:100%;margin-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*=\"offset\"]:first-child{margin-left:0}.input-large,.input-xlarge,.input-xxlarge,input[class*=\"span\"],select[class*=\"span\"],textarea[class*=\"span\"],.uneditable-input{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.input-prepend input,.input-append input,.input-prepend input[class*=\"span\"],.input-append input[class*=\"span\"]{display:inline-block;width:auto}.controls-row [class*=\"span\"]+[class*=\"span\"]{margin-left:0}.modal{position:fixed;top:20px;right:20px;left:20px;width:auto;margin:0}.modal.fade{top:-100px}.modal.fade.in{top:20px}}@media(max-width:480px){.nav-collapse{-webkit-transform:translate3d(0,0,0)}.page-header h1 small{display:block;line-height:20px}input[type=\"checkbox\"],input[type=\"radio\"]{border:1px solid #ccc}.form-horizontal .control-label{float:none;width:auto;padding-top:0;text-align:left}.form-horizontal .controls{margin-left:0}.form-horizontal .control-list{padding-top:0}.form-horizontal .form-actions{padding-right:10px;padding-left:10px}.media .pull-left,.media .pull-right{display:block;float:none;margin-bottom:10px}.media-object{margin-right:0;margin-left:0}.modal{top:10px;right:10px;left:10px}.modal-header .close{padding:10px;margin:-10px}.carousel-caption{position:static}}@media(max-width:979px){body{padding-top:0}.navbar-fixed-top,.navbar-fixed-bottom{position:static}.navbar-fixed-top{margin-bottom:20px}.navbar-fixed-bottom{margin-top:20px}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px}.navbar .container{width:auto;padding:0}.navbar .brand{padding-right:10px;padding-left:10px;margin:0 0 0 -5px}.nav-collapse{clear:both}.nav-collapse .nav{float:none;margin:0 0 10px}.nav-collapse .nav>li{float:none}.nav-collapse .nav>li>a{margin-bottom:2px}.nav-collapse .nav>.divider-vertical{display:none}.nav-collapse .nav .nav-header{color:#777;text-shadow:none}.nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#777;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.nav-collapse .dropdown-menu li+li a{margin-bottom:2px}.nav-collapse .nav>li>a:hover,.nav-collapse .nav>li>a:focus,.nav-collapse .dropdown-menu a:hover,.nav-collapse .dropdown-menu a:focus{background-color:#f2f2f2}.navbar-inverse .nav-collapse .nav>li>a,.navbar-inverse .nav-collapse .dropdown-menu a{color:#999}.navbar-inverse .nav-collapse .nav>li>a:hover,.navbar-inverse .nav-collapse .nav>li>a:focus,.navbar-inverse .nav-collapse .dropdown-menu a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:focus{background-color:#111}.nav-collapse.in .btn-group{padding:0;margin-top:5px}.nav-collapse .dropdown-menu{position:static;top:auto;left:auto;display:none;float:none;max-width:none;padding:0;margin:0 15px;background-color:transparent;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.nav-collapse .open>.dropdown-menu{display:block}.nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none}.nav-collapse .dropdown-menu .divider{display:none}.nav-collapse .nav>li>.dropdown-menu:before,.nav-collapse .nav>li>.dropdown-menu:after{display:none}.nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:10px 15px;margin:10px 0;border-top:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1)}.navbar-inverse .nav-collapse .navbar-form,.navbar-inverse .nav-collapse .navbar-search{border-top-color:#111;border-bottom-color:#111}.navbar .nav-collapse .nav.pull-right{float:none;margin-left:0}.nav-collapse,.nav-collapse.collapse{height:0;overflow:hidden}.navbar .btn-navbar{display:block}.navbar-static .navbar-inner{padding-right:10px;padding-left:10px}}@media(min-width:980px){.nav-collapse.collapse{height:auto!important;overflow:visible!important}}"
  },
  {
    "path": "code/default/launcher/web_ui/css/bootstrap.css",
    "content": ".clearfix {\n\t*zoom: 1\n}\n\n.clearfix:before,.clearfix:after {\n\tdisplay: table;\n\tline-height: 0;\n\tcontent: \"\"\n}\n\n.clearfix:after {\n\tclear: both\n}\n\n.hide-text {\n\tfont: 0/0 a;\n\tcolor: transparent;\n\ttext-shadow: none;\n\tbackground-color: transparent;\n\tborder: 0\n}\n\n.input-block-level {\n\tdisplay: block;\n\twidth: 100%;\n\tmin-height: 30px;\n\t-webkit-box-sizing: border-box;\n\t-moz-box-sizing: border-box;\n\tbox-sizing: border-box\n}\n\narticle,aside,details,figcaption,figure,footer,header,hgroup,nav,section {\n\tdisplay: block\n}\n\naudio,canvas,video {\n\tdisplay: inline-block;\n\t*display: inline;\n\t*zoom: 1\n}\n\naudio:not([controls]) {\n\tdisplay: none\n}\n\nhtml {\n\tfont-size: 100%;\n\t-webkit-text-size-adjust: 100%;\n\t-ms-text-size-adjust: 100%\n}\n\na:focus {\n\toutline: thin dotted #333;\n\toutline: 5px auto -webkit-focus-ring-color;\n\toutline-offset: -2px\n}\n\na:hover,a:active {\n\toutline: 0\n}\n\nsub,sup {\n\tposition: relative;\n\tfont-size: 75%;\n\tline-height: 0;\n\tvertical-align: baseline\n}\n\nsup {\n\ttop: -0.5em\n}\n\nsub {\n\tbottom: -0.25em\n}\n\nimg {\n\twidth: auto\\9;\n\theight: auto;\n\tmax-width: 100%;\n\tvertical-align: middle;\n\tborder: 0;\n\t-ms-interpolation-mode: bicubic\n}\n\n#map_canvas img,.google-maps img {\n\tmax-width: none\n}\n\nbutton,input,select,textarea {\n\tmargin: 0;\n\tfont-size: 100%;\n\tvertical-align: middle\n}\n\nbutton,input {\n\t*overflow: visible;\n\tline-height: normal\n}\n\nbutton::-moz-focus-inner,input::-moz-focus-inner {\n\tpadding: 0;\n\tborder: 0\n}\n\nbutton,html input[type=\"button\"],input[type=\"reset\"],input[type=\"submit\"] {\n\tcursor: pointer;\n\t-webkit-appearance: button\n}\n\nlabel,select,button,input[type=\"button\"],input[type=\"reset\"],input[type=\"submit\"],input[type=\"radio\"],input[type=\"checkbox\"] {\n\tcursor: pointer\n}\n\ninput[type=\"search\"] {\n\t-webkit-box-sizing: content-box;\n\t-moz-box-sizing: content-box;\n\tbox-sizing: content-box;\n\t-webkit-appearance: textfield\n}\n\ninput[type=\"search\"]::-webkit-search-decoration,input[type=\"search\"]::-webkit-search-cancel-button {\n\t-webkit-appearance: none\n}\n\ntextarea {\n\toverflow: auto;\n\tvertical-align: top\n}\n\n@media print {\n\t* {\n\t\tcolor: #000!important;\n\t\ttext-shadow: none!important;\n\t\tbackground: transparent!important;\n\t\tbox-shadow: none!important\n\t}\n\n\ta,a:visited {\n\t\ttext-decoration: underline\n\t}\n\n\ta[href]:after {\n\t\tcontent: \" (\" attr(href) \")\"\n\t}\n\n\tabbr[title]:after {\n\t\tcontent: \" (\" attr(title) \")\"\n\t}\n\n\t.ir a:after,a[href^=\"javascript:\"]:after,a[href^=\"#\"]:after {\n\t\tcontent: \"\"\n\t}\n\n\tpre,blockquote {\n\t\tborder: 1px solid #999;\n\t\tpage-break-inside: avoid\n\t}\n\n\tthead {\n\t\tdisplay: table-header-group\n\t}\n\n\ttr,img {\n\t\tpage-break-inside: avoid\n\t}\n\n\timg {\n\t\tmax-width: 100%!important\n\t}@\tpage {\n\t\tmargin: .5cm\n\t}\n\n\tp,h2,h3 {\n\t\torphans: 3;\n\t\twidows: 3\n\t}\n\n\th2,h3 {\n\t\tpage-break-after: avoid\n\t}\n}\n\nbody {\n\tmargin: 0;\n\tfont-family: \"Helvetica Neue\",Helvetica,Arial,sans-serif;\n\tfont-size: 14px;\n\tline-height: 20px;\n\tcolor: #333;\n\tbackground-color: #fff\n}\n\na {\n\tcolor: #08c;\n\ttext-decoration: none\n}\n\na:hover,a:focus {\n\tcolor: #005580;\n\ttext-decoration: underline\n}\n\n.img-rounded {\n\t-webkit-border-radius: 6px;\n\t-moz-border-radius: 6px;\n\tborder-radius: 6px\n}\n\n.img-polaroid {\n\tpadding: 4px;\n\tbackground-color: #fff;\n\tborder: 1px solid #ccc;\n\tborder: 1px solid rgba(0,0,0,0.2);\n\t-webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.1);\n\t-moz-box-shadow: 0 1px 3px rgba(0,0,0,0.1);\n\tbox-shadow: 0 1px 3px rgba(0,0,0,0.1)\n}\n\n.img-circle {\n\t-webkit-border-radius: 500px;\n\t-moz-border-radius: 500px;\n\tborder-radius: 500px\n}\n\n.row {\n\tmargin-left: -20px;\n\t*zoom: 1\n}\n\n.row:before,.row:after {\n\tdisplay: table;\n\tline-height: 0;\n\tcontent: \"\"\n}\n\n.row:after {\n\tclear: both\n}[class*=\"span\"] {\n\tfloat: left;\n\tmin-height: 1px;\n\tmargin-left: 20px\n}\n\n.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container {\n\twidth: 940px\n}\n\n.span12 {\n\twidth: 940px\n}\n\n.span11 {\n\twidth: 860px\n}\n\n.span10 {\n\twidth: 780px\n}\n\n.span9 {\n\twidth: 700px\n}\n\n.span8 {\n\twidth: 620px\n}\n\n.span7 {\n\twidth: 540px\n}\n\n.span6 {\n\twidth: 460px\n}\n\n.span5 {\n\twidth: 380px\n}\n\n.span4 {\n\twidth: 300px\n}\n\n.span3 {\n\twidth: 220px\n}\n\n.span2 {\n\twidth: 140px\n}\n\n.span1 {\n\twidth: 60px\n}\n\n.offset12 {\n\tmargin-left: 980px\n}\n\n.offset11 {\n\tmargin-left: 900px\n}\n\n.offset10 {\n\tmargin-left: 820px\n}\n\n.offset9 {\n\tmargin-left: 740px\n}\n\n.offset8 {\n\tmargin-left: 660px\n}\n\n.offset7 {\n\tmargin-left: 580px\n}\n\n.offset6 {\n\tmargin-left: 500px\n}\n\n.offset5 {\n\tmargin-left: 420px\n}\n\n.offset4 {\n\tmargin-left: 340px\n}\n\n.offset3 {\n\tmargin-left: 260px\n}\n\n.offset2 {\n\tmargin-left: 180px\n}\n\n.offset1 {\n\tmargin-left: 100px\n}\n\n.row-fluid {\n\twidth: 100%;\n\t*zoom: 1\n}\n\n.row-fluid:before,.row-fluid:after {\n\tdisplay: table;\n\tline-height: 0;\n\tcontent: \"\"\n}\n\n.row-fluid:after {\n\tclear: both\n}\n\n.row-fluid [class*=\"span\"] {\n\tdisplay: block;\n\tfloat: left;\n\twidth: 100%;\n\tmin-height: 30px;\n\tmargin-left: 2.127659574468085%;\n\t*margin-left: 2.074468085106383%;\n\t-webkit-box-sizing: border-box;\n\t-moz-box-sizing: border-box;\n\tbox-sizing: border-box\n}\n\n.row-fluid [class*=\"span\"]:first-child {\n\tmargin-left: 0\n}\n\n.row-fluid .controls-row [class*=\"span\"]+[class*=\"span\"] {\n\tmargin-left: 2.127659574468085%\n}\n\n.row-fluid .span12 {\n\twidth: 100%;\n\t*width: 99.94680851063829%\n}\n\n.row-fluid .span11 {\n\twidth: 91.48936170212765%;\n\t*width: 91.43617021276594%\n}\n\n.row-fluid .span10 {\n\twidth: 82.97872340425532%;\n\t*width: 82.92553191489361%\n}\n\n.row-fluid .span9 {\n\twidth: 74.46808510638297%;\n\t*width: 74.41489361702126%\n}\n\n.row-fluid .span8 {\n\twidth: 65.95744680851064%;\n\t*width: 65.90425531914893%\n}\n\n.row-fluid .span7 {\n\twidth: 57.44680851063829%;\n\t*width: 57.39361702127659%\n}\n\n.row-fluid .span6 {\n\twidth: 48.93617021276595%;\n\t*width: 48.88297872340425%\n}\n\n.row-fluid .span5 {\n\twidth: 40.42553191489362%;\n\t*width: 40.37234042553192%\n}\n\n.row-fluid .span4 {\n\twidth: 31.914893617021278%;\n\t*width: 31.861702127659576%\n}\n\n.row-fluid .span3 {\n\twidth: 23.404255319148934%;\n\t*width: 23.351063829787233%\n}\n\n.row-fluid .span2 {\n\twidth: 14.893617021276595%;\n\t*width: 14.840425531914894%\n}\n\n.row-fluid .span1 {\n\twidth: 6.382978723404255%;\n\t*width: 6.329787234042553%\n}\n\n.row-fluid .offset12 {\n\tmargin-left: 104.25531914893617%;\n\t*margin-left: 104.14893617021275%\n}\n\n.row-fluid .offset12:first-child {\n\tmargin-left: 102.12765957446808%;\n\t*margin-left: 102.02127659574467%\n}\n\n.row-fluid .offset11 {\n\tmargin-left: 95.74468085106382%;\n\t*margin-left: 95.6382978723404%\n}\n\n.row-fluid .offset11:first-child {\n\tmargin-left: 93.61702127659574%;\n\t*margin-left: 93.51063829787232%\n}\n\n.row-fluid .offset10 {\n\tmargin-left: 87.23404255319149%;\n\t*margin-left: 87.12765957446807%\n}\n\n.row-fluid .offset10:first-child {\n\tmargin-left: 85.1063829787234%;\n\t*margin-left: 84.99999999999999%\n}\n\n.row-fluid .offset9 {\n\tmargin-left: 78.72340425531914%;\n\t*margin-left: 78.61702127659572%\n}\n\n.row-fluid .offset9:first-child {\n\tmargin-left: 76.59574468085106%;\n\t*margin-left: 76.48936170212764%\n}\n\n.row-fluid .offset8 {\n\tmargin-left: 70.2127659574468%;\n\t*margin-left: 70.10638297872339%\n}\n\n.row-fluid .offset8:first-child {\n\tmargin-left: 68.08510638297872%;\n\t*margin-left: 67.9787234042553%\n}\n\n.row-fluid .offset7 {\n\tmargin-left: 61.70212765957446%;\n\t*margin-left: 61.59574468085106%\n}\n\n.row-fluid .offset7:first-child {\n\tmargin-left: 59.574468085106375%;\n\t*margin-left: 59.46808510638297%\n}\n\n.row-fluid .offset6 {\n\tmargin-left: 53.191489361702125%;\n\t*margin-left: 53.085106382978715%\n}\n\n.row-fluid .offset6:first-child {\n\tmargin-left: 51.063829787234035%;\n\t*margin-left: 50.95744680851063%\n}\n\n.row-fluid .offset5 {\n\tmargin-left: 44.68085106382979%;\n\t*margin-left: 44.57446808510638%\n}\n\n.row-fluid .offset5:first-child {\n\tmargin-left: 42.5531914893617%;\n\t*margin-left: 42.4468085106383%\n}\n\n.row-fluid .offset4 {\n\tmargin-left: 36.170212765957444%;\n\t*margin-left: 36.06382978723405%\n}\n\n.row-fluid .offset4:first-child {\n\tmargin-left: 34.04255319148936%;\n\t*margin-left: 33.93617021276596%\n}\n\n.row-fluid .offset3 {\n\tmargin-left: 27.659574468085104%;\n\t*margin-left: 27.5531914893617%\n}\n\n.row-fluid .offset3:first-child {\n\tmargin-left: 25.53191489361702%;\n\t*margin-left: 25.425531914893618%\n}\n\n.row-fluid .offset2 {\n\tmargin-left: 19.148936170212764%;\n\t*margin-left: 19.04255319148936%\n}\n\n.row-fluid .offset2:first-child {\n\tmargin-left: 17.02127659574468%;\n\t*margin-left: 16.914893617021278%\n}\n\n.row-fluid .offset1 {\n\tmargin-left: 10.638297872340425%;\n\t*margin-left: 10.53191489361702%\n}\n\n.row-fluid .offset1:first-child {\n\tmargin-left: 8.51063829787234%;\n\t*margin-left: 8.404255319148938%\n}[class*=\"span\"].hide,.row-fluid [class*=\"span\"].hide {\n\tdisplay: none\n}[class*=\"span\"].pull-right,.row-fluid [class*=\"span\"].pull-right {\n\tfloat: right\n}\n\n.container {\n\tmargin-right: auto;\n\tmargin-left: auto;\n\t*zoom: 1\n}\n\n.container:before,.container:after {\n\tdisplay: table;\n\tline-height: 0;\n\tcontent: \"\"\n}\n\n.container:after {\n\tclear: both\n}\n\n.container-fluid {\n\tpadding-right: 20px;\n\tpadding-left: 20px;\n\t*zoom: 1\n}\n\n.container-fluid:before,.container-fluid:after {\n\tdisplay: table;\n\tline-height: 0;\n\tcontent: \"\"\n}\n\n.container-fluid:after {\n\tclear: both\n}\n\np {\n\tmargin: 0 0 10px\n}\n\n.lead {\n\tmargin-bottom: 20px;\n\tfont-size: 21px;\n\tfont-weight: 200;\n\tline-height: 30px\n}\n\nsmall {\n\tfont-size: 85%\n}\n\nstrong {\n\tfont-weight: bold\n}\n\nem {\n\tfont-style: italic\n}\n\ncite {\n\tfont-style: normal\n}\n\n.muted {\n\tcolor: #999\n}\n\na.muted:hover,a.muted:focus {\n\tcolor: #808080\n}\n\n.text-warning {\n\tcolor: #c09853\n}\n\na.text-warning:hover,a.text-warning:focus {\n\tcolor: #a47e3c\n}\n\n.text-error {\n\tcolor: #b94a48\n}\n\na.text-error:hover,a.text-error:focus {\n\tcolor: #953b39\n}\n\n.text-info {\n\tcolor: #3a87ad\n}\n\na.text-info:hover,a.text-info:focus {\n\tcolor: #2d6987\n}\n\n.text-success {\n\tcolor: #468847\n}\n\na.text-success:hover,a.text-success:focus {\n\tcolor: #356635\n}\n\n.text-left {\n\ttext-align: left\n}\n\n.text-right {\n\ttext-align: right\n}\n\n.text-center {\n\ttext-align: center\n}\n\nh1,h2,h3,h4,h5,h6 {\n\tmargin: 10px 0;\n\tfont-family: inherit;\n\tfont-weight: bold;\n\tline-height: 20px;\n\tcolor: inherit;\n\ttext-rendering: optimizelegibility\n}\n\nh1 small,h2 small,h3 small,h4 small,h5 small,h6 small {\n\tfont-weight: normal;\n\tline-height: 1;\n\tcolor: #999\n}\n\nh1,h2,h3 {\n\tline-height: 40px\n}\n\nh1 {\n\tfont-size: 38.5px\n}\n\nh2 {\n\tfont-size: 31.5px\n}\n\nh3 {\n\tfont-size: 24.5px\n}\n\nh4 {\n\tfont-size: 17.5px\n}\n\nh5 {\n\tfont-size: 14px\n}\n\nh6 {\n\tfont-size: 11.9px\n}\n\nh1 small {\n\tfont-size: 24.5px\n}\n\nh2 small {\n\tfont-size: 17.5px\n}\n\nh3 small {\n\tfont-size: 14px\n}\n\nh4 small {\n\tfont-size: 14px\n}\n\n.page-header {\n\tpadding-bottom: 9px;\n\tmargin: 20px 0 30px;\n\tborder-bottom: 1px solid #eee\n}\n\nul,ol {\n\tpadding: 0;\n\tmargin: 0 0 10px 25px\n}\n\nul ul,ul ol,ol ol,ol ul {\n\tmargin-bottom: 0\n}\n\nli {\n\tline-height: 20px\n}\n\nul.unstyled,ol.unstyled {\n\tmargin-left: 0;\n\tlist-style: none\n}\n\nul.inline,ol.inline {\n\tmargin-left: 0;\n\tlist-style: none\n}\n\nul.inline>li,ol.inline>li {\n\tdisplay: inline-block;\n\t*display: inline;\n\tpadding-right: 5px;\n\tpadding-left: 5px;\n\t*zoom: 1\n}\n\ndl {\n\tmargin-bottom: 20px\n}\n\ndt,dd {\n\tline-height: 20px\n}\n\ndt {\n\tfont-weight: bold\n}\n\ndd {\n\tmargin-left: 10px\n}\n\n.dl-horizontal {\n\t*zoom: 1\n}\n\n.dl-horizontal:before,.dl-horizontal:after {\n\tdisplay: table;\n\tline-height: 0;\n\tcontent: \"\"\n}\n\n.dl-horizontal:after {\n\tclear: both\n}\n\n.dl-horizontal dt {\n\tfloat: left;\n\twidth: 160px;\n\toverflow: hidden;\n\tclear: left;\n\ttext-align: right;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap\n}\n\n.dl-horizontal dd {\n\tmargin-left: 180px\n}\n\nhr {\n\tmargin: 20px 0;\n\tborder: 0;\n\tborder-top: 1px solid #eee;\n\tborder-bottom: 1px solid #fff\n}\n\nabbr[title],abbr[data-original-title] {\n\tcursor: help;\n\tborder-bottom: 1px dotted #999\n}\n\nabbr.initialism {\n\tfont-size: 90%;\n\ttext-transform: uppercase\n}\n\nblockquote {\n\tpadding: 0 0 0 15px;\n\tmargin: 0 0 20px;\n\tborder-left: 5px solid #eee\n}\n\nblockquote p {\n\tmargin-bottom: 0;\n\tfont-size: 17.5px;\n\tfont-weight: 300;\n\tline-height: 1.25\n}\n\nblockquote small {\n\tdisplay: block;\n\tline-height: 20px;\n\tcolor: #999\n}\n\nblockquote small:before {\n\tcontent: '\\2014 \\00A0'\n}\n\nblockquote.pull-right {\n\tfloat: right;\n\tpadding-right: 15px;\n\tpadding-left: 0;\n\tborder-right: 5px solid #eee;\n\tborder-left: 0\n}\n\nblockquote.pull-right p,blockquote.pull-right small {\n\ttext-align: right\n}\n\nblockquote.pull-right small:before {\n\tcontent: ''\n}\n\nblockquote.pull-right small:after {\n\tcontent: '\\00A0 \\2014'\n}\n\nq:before,q:after,blockquote:before,blockquote:after {\n\tcontent: \"\"\n}\n\naddress {\n\tdisplay: block;\n\tmargin-bottom: 20px;\n\tfont-style: normal;\n\tline-height: 20px\n}\n\ncode,pre {\n\tpadding: 0 3px 2px;\n\tfont-family: Monaco,Menlo,Consolas,\"Courier New\",monospace;\n\tfont-size: 12px;\n\tcolor: #333;\n\t-webkit-border-radius: 3px;\n\t-moz-border-radius: 3px;\n\tborder-radius: 3px\n}\n\ncode {\n\tpadding: 2px 4px;\n\tcolor: #d14;\n\twhite-space: nowrap;\n\tbackground-color: #f7f7f9;\n\tborder: 1px solid #e1e1e8\n}\n\npre {\n\tdisplay: block;\n\tpadding: 9.5px;\n\tmargin: 0 0 10px;\n\tfont-size: 13px;\n\tline-height: 20px;\n\tword-break: break-all;\n\tword-wrap: break-word;\n\twhite-space: pre;\n\twhite-space: pre-wrap;\n\tbackground-color: #f5f5f5;\n\tborder: 1px solid #ccc;\n\tborder: 1px solid rgba(0,0,0,0.15);\n\t-webkit-border-radius: 4px;\n\t-moz-border-radius: 4px;\n\tborder-radius: 4px\n}\n\npre.prettyprint {\n\tmargin-bottom: 20px\n}\n\npre code {\n\tpadding: 0;\n\tcolor: inherit;\n\twhite-space: pre;\n\twhite-space: pre-wrap;\n\tbackground-color: transparent;\n\tborder: 0\n}\n\n.pre-scrollable {\n\tmax-height: 340px;\n\toverflow-y: scroll\n}\n\nfieldset {\n\tpadding: 0;\n\tmargin: 0;\n\tborder: 0\n}\n\nlegend {\n\tdisplay: block;\n\twidth: 100%;\n\tpadding: 0;\n\tmargin-bottom: 20px;\n\tfont-size: 21px;\n\tline-height: 40px;\n\tcolor: #333;\n\tborder: 0;\n\tborder-bottom: 1px solid #e5e5e5\n}\n\nlegend small {\n\tfont-size: 15px;\n\tcolor: #999\n}\n\nlabel,input,button,select,textarea {\n\tfont-size: 14px;\n\tfont-weight: normal;\n\tline-height: 20px\n}\n\ninput,button,select,textarea {\n\tfont-family: \"Microsoft YaHei\",\"Sogoe UI\",Arial,sans-serif\n}\n\nlabel {\n\tdisplay: block;\n\tmargin-bottom: 5px\n}\n\nselect,textarea,input[type=\"text\"],input[type=\"password\"],input[type=\"datetime\"],input[type=\"datetime-local\"],input[type=\"date\"],input[type=\"month\"],input[type=\"time\"],input[type=\"week\"],input[type=\"number\"],input[type=\"email\"],input[type=\"url\"],input[type=\"search\"],input[type=\"tel\"],input[type=\"color\"],.uneditable-input {\n\tdisplay: inline-block;\n\theight: 20px;\n\tpadding: 4px 6px;\n\tfont-size: 14px;\n\tline-height: 20px;\n\tcolor: #555;\n\tvertical-align: middle;\n\t-webkit-border-radius: 4px;\n\t-moz-border-radius: 4px;\n\tborder-radius: 4px\n}\n\ninput,textarea,.uneditable-input {\n\twidth: 206px\n}\n\ntextarea {\n\theight: auto\n}\n\ntextarea,input[type=\"text\"],input[type=\"password\"],input[type=\"datetime\"],input[type=\"datetime-local\"],input[type=\"date\"],input[type=\"month\"],input[type=\"time\"],input[type=\"week\"],input[type=\"number\"],input[type=\"email\"],input[type=\"url\"],input[type=\"search\"],input[type=\"tel\"],input[type=\"color\"],.uneditable-input {\n\tbackground-color: #fff;\n\tborder: 1px solid #ccc;\n\t-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);\n\t-moz-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);\n\tbox-shadow: inset 0 1px 1px rgba(0,0,0,0.075);\n\t-webkit-transition: border linear .2s,box-shadow linear .2s;\n\t-moz-transition: border linear .2s,box-shadow linear .2s;\n\t-o-transition: border linear .2s,box-shadow linear .2s;\n\ttransition: border linear .2s,box-shadow linear .2s\n}\n\ntextarea:focus,input[type=\"text\"]:focus,input[type=\"password\"]:focus,input[type=\"datetime\"]:focus,input[type=\"datetime-local\"]:focus,input[type=\"date\"]:focus,input[type=\"month\"]:focus,input[type=\"time\"]:focus,input[type=\"week\"]:focus,input[type=\"number\"]:focus,input[type=\"email\"]:focus,input[type=\"url\"]:focus,input[type=\"search\"]:focus,input[type=\"tel\"]:focus,input[type=\"color\"]:focus,.uneditable-input:focus {\n\tborder-color: rgba(82,168,236,0.8);\n\toutline: 0;\n\toutline: thin dotted \\9;\n\t-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);\n\t-moz-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);\n\tbox-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)\n}\n\ninput[type=\"radio\"],input[type=\"checkbox\"] {\n\tmargin: 4px 0 0;\n\tmargin-top: 1px \\9;\n\t*margin-top: 0;\n\tline-height: normal\n}\n\ninput[type=\"file\"],input[type=\"image\"],input[type=\"submit\"],input[type=\"reset\"],input[type=\"button\"],input[type=\"radio\"],input[type=\"checkbox\"] {\n\twidth: auto\n}\n\nselect,input[type=\"file\"] {\n\theight: 30px;\n\t*margin-top: 4px;\n\tline-height: 30px\n}\n\nselect {\n\twidth: 220px;\n\tbackground-color: #fff;\n\tborder: 1px solid #ccc\n}\n\nselect[multiple],select[size] {\n\theight: auto\n}\n\nselect:focus,input[type=\"file\"]:focus,input[type=\"radio\"]:focus,input[type=\"checkbox\"]:focus {\n\toutline: thin dotted #333;\n\toutline: 5px auto -webkit-focus-ring-color;\n\toutline-offset: -2px\n}\n\n.uneditable-input,.uneditable-textarea {\n\tcolor: #999;\n\tcursor: not-allowed;\n\tbackground-color: #fcfcfc;\n\tborder-color: #ccc;\n\t-webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,0.025);\n\t-moz-box-shadow: inset 0 1px 2px rgba(0,0,0,0.025);\n\tbox-shadow: inset 0 1px 2px rgba(0,0,0,0.025)\n}\n\n.uneditable-input {\n\toverflow: hidden;\n\twhite-space: nowrap\n}\n\n.uneditable-textarea {\n\twidth: auto;\n\theight: auto\n}\n\ninput:-moz-placeholder,textarea:-moz-placeholder {\n\tcolor: #999\n}\n\ninput:-ms-input-placeholder,textarea:-ms-input-placeholder {\n\tcolor: #999\n}\n\ninput::-webkit-input-placeholder,textarea::-webkit-input-placeholder {\n\tcolor: #999\n}\n\n.radio,.checkbox {\n\tmin-height: 20px;\n\tpadding-left: 20px\n}\n\n.radio input[type=\"radio\"],.checkbox input[type=\"checkbox\"] {\n\tfloat: left;\n\tmargin-left: -20px\n}\n\n.controls>.radio:first-child,.controls>.checkbox:first-child {\n\tpadding-top: 5px\n}\n\n.radio.inline,.checkbox.inline {\n\tdisplay: inline-block;\n\tpadding-top: 5px;\n\tmargin-bottom: 0;\n\tvertical-align: middle\n}\n\n.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline {\n\tmargin-left: 10px\n}\n\n.input-mini {\n\twidth: 60px\n}\n\n.input-small {\n\twidth: 90px\n}\n\n.input-medium {\n\twidth: 150px\n}\n\n.input-large {\n\twidth: 210px\n}\n\n.input-xlarge {\n\twidth: 270px\n}\n\n.input-xxlarge {\n\twidth: 530px\n}\n\ninput[class*=\"span\"],select[class*=\"span\"],textarea[class*=\"span\"],.uneditable-input[class*=\"span\"],.row-fluid input[class*=\"span\"],.row-fluid select[class*=\"span\"],.row-fluid textarea[class*=\"span\"],.row-fluid .uneditable-input[class*=\"span\"] {\n\tfloat: none;\n\tmargin-left: 0\n}\n\n.input-append input[class*=\"span\"],.input-append .uneditable-input[class*=\"span\"],.input-prepend input[class*=\"span\"],.input-prepend .uneditable-input[class*=\"span\"],.row-fluid input[class*=\"span\"],.row-fluid select[class*=\"span\"],.row-fluid textarea[class*=\"span\"],.row-fluid .uneditable-input[class*=\"span\"],.row-fluid .input-prepend [class*=\"span\"],.row-fluid .input-append [class*=\"span\"] {\n\tdisplay: inline-block\n}\n\ninput,textarea,.uneditable-input {\n\tmargin-left: 0\n}\n\n.controls-row [class*=\"span\"]+[class*=\"span\"] {\n\tmargin-left: 20px\n}\n\ninput.span12,textarea.span12,.uneditable-input.span12 {\n\twidth: 926px\n}\n\ninput.span11,textarea.span11,.uneditable-input.span11 {\n\twidth: 846px\n}\n\ninput.span10,textarea.span10,.uneditable-input.span10 {\n\twidth: 766px\n}\n\ninput.span9,textarea.span9,.uneditable-input.span9 {\n\twidth: 686px\n}\n\ninput.span8,textarea.span8,.uneditable-input.span8 {\n\twidth: 606px\n}\n\ninput.span7,textarea.span7,.uneditable-input.span7 {\n\twidth: 526px\n}\n\ninput.span6,textarea.span6,.uneditable-input.span6 {\n\twidth: 446px\n}\n\ninput.span5,textarea.span5,.uneditable-input.span5 {\n\twidth: 366px\n}\n\ninput.span4,textarea.span4,.uneditable-input.span4 {\n\twidth: 286px\n}\n\ninput.span3,textarea.span3,.uneditable-input.span3 {\n\twidth: 206px\n}\n\ninput.span2,textarea.span2,.uneditable-input.span2 {\n\twidth: 126px\n}\n\ninput.span1,textarea.span1,.uneditable-input.span1 {\n\twidth: 46px\n}\n\n.controls-row {\n\t*zoom: 1\n}\n\n.controls-row:before,.controls-row:after {\n\tdisplay: table;\n\tline-height: 0;\n\tcontent: \"\"\n}\n\n.controls-row:after {\n\tclear: both\n}\n\n.controls-row [class*=\"span\"],.row-fluid .controls-row [class*=\"span\"] {\n\tfloat: left\n}\n\n.controls-row .checkbox[class*=\"span\"],.controls-row .radio[class*=\"span\"] {\n\tpadding-top: 5px\n}\n\ninput[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly] {\n\tcursor: not-allowed;\n\tbackground-color: #eee\n}\n\ninput[type=\"radio\"][disabled],input[type=\"checkbox\"][disabled],input[type=\"radio\"][readonly],input[type=\"checkbox\"][readonly] {\n\tbackground-color: transparent\n}\n\n.control-group.warning .control-label,.control-group.warning .help-block,.control-group.warning .help-inline {\n\tcolor: #c09853\n}\n\n.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea {\n\tcolor: #c09853\n}\n\n.control-group.warning input,.control-group.warning select,.control-group.warning textarea {\n\tborder-color: #c09853;\n\t-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);\n\t-moz-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);\n\tbox-shadow: inset 0 1px 1px rgba(0,0,0,0.075)\n}\n\n.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus {\n\tborder-color: #a47e3c;\n\t-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;\n\t-moz-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;\n\tbox-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e\n}\n\n.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on {\n\tcolor: #c09853;\n\tbackground-color: #fcf8e3;\n\tborder-color: #c09853\n}\n\n.control-group.error .control-label,.control-group.error .help-block,.control-group.error .help-inline {\n\tcolor: #b94a48\n}\n\n.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea {\n\tcolor: #b94a48\n}\n\n.control-group.error input,.control-group.error select,.control-group.error textarea {\n\tborder-color: #b94a48;\n\t-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);\n\t-moz-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);\n\tbox-shadow: inset 0 1px 1px rgba(0,0,0,0.075)\n}\n\n.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus {\n\tborder-color: #953b39;\n\t-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;\n\t-moz-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;\n\tbox-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392\n}\n\n.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on {\n\tcolor: #b94a48;\n\tbackground-color: #f2dede;\n\tborder-color: #b94a48\n}\n\n.control-group.success .control-label,.control-group.success .help-block,.control-group.success .help-inline {\n\tcolor: #468847\n}\n\n.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea {\n\tcolor: #468847\n}\n\n.control-group.success input,.control-group.success select,.control-group.success textarea {\n\tborder-color: #468847;\n\t-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);\n\t-moz-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);\n\tbox-shadow: inset 0 1px 1px rgba(0,0,0,0.075)\n}\n\n.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus {\n\tborder-color: #356635;\n\t-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;\n\t-moz-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;\n\tbox-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b\n}\n\n.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on {\n\tcolor: #468847;\n\tbackground-color: #dff0d8;\n\tborder-color: #468847\n}\n\n.control-group.info .control-label,.control-group.info .help-block,.control-group.info .help-inline {\n\tcolor: #3a87ad\n}\n\n.control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea {\n\tcolor: #3a87ad\n}\n\n.control-group.info input,.control-group.info select,.control-group.info textarea {\n\tborder-color: #3a87ad;\n\t-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);\n\t-moz-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);\n\tbox-shadow: inset 0 1px 1px rgba(0,0,0,0.075)\n}\n\n.control-group.info input:focus,.control-group.info select:focus,.control-group.info textarea:focus {\n\tborder-color: #2d6987;\n\t-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;\n\t-moz-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;\n\tbox-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3\n}\n\n.control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on {\n\tcolor: #3a87ad;\n\tbackground-color: #d9edf7;\n\tborder-color: #3a87ad\n}\n\ninput:focus:invalid,textarea:focus:invalid,select:focus:invalid {\n\tcolor: #b94a48;\n\tborder-color: #ee5f5b\n}\n\ninput:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus {\n\tborder-color: #e9322d;\n\t-webkit-box-shadow: 0 0 6px #f8b9b7;\n\t-moz-box-shadow: 0 0 6px #f8b9b7;\n\tbox-shadow: 0 0 6px #f8b9b7\n}\n\n.form-actions {\n\tpadding: 19px 20px 20px;\n\tmargin-top: 20px;\n\tmargin-bottom: 20px;\n\tbackground-color: #f5f5f5;\n\tborder-top: 1px solid #e5e5e5;\n\t*zoom: 1\n}\n\n.form-actions:before,.form-actions:after {\n\tdisplay: table;\n\tline-height: 0;\n\tcontent: \"\"\n}\n\n.form-actions:after {\n\tclear: both\n}\n\n.help-block,.help-inline {\n\tcolor: #595959\n}\n\n.help-block {\n\tdisplay: block;\n\tmargin-bottom: 10px\n}\n\n.help-inline {\n\tdisplay: inline-block;\n\t*display: inline;\n\tpadding-left: 5px;\n\tvertical-align: middle;\n\t*zoom: 1\n}\n\n.input-append,.input-prepend {\n\tdisplay: inline-block;\n\tmargin-bottom: 10px;\n\tfont-size: 0;\n\twhite-space: nowrap;\n\tvertical-align: middle\n}\n\n.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input,.input-append .dropdown-menu,.input-prepend .dropdown-menu,.input-append .popover,.input-prepend .popover {\n\tfont-size: 14px\n}\n\n.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input {\n\tposition: relative;\n\tmargin-bottom: 0;\n\t*margin-left: 0;\n\tvertical-align: top;\n\t-webkit-border-radius: 0 4px 4px 0;\n\t-moz-border-radius: 0 4px 4px 0;\n\tborder-radius: 0 4px 4px 0\n}\n\n.input-append input:focus,.input-prepend input:focus,.input-append select:focus,.input-prepend select:focus,.input-append .uneditable-input:focus,.input-prepend .uneditable-input:focus {\n\tz-index: 2\n}\n\n.input-append .add-on,.input-prepend .add-on {\n\tdisplay: inline-block;\n\twidth: auto;\n\theight: 20px;\n\tmin-width: 16px;\n\tpadding: 4px 5px;\n\tfont-size: 14px;\n\tfont-weight: normal;\n\tline-height: 20px;\n\ttext-align: center;\n\ttext-shadow: 0 1px 0 #fff;\n\tbackground-color: #eee;\n\tborder: 1px solid #ccc\n}\n\n.input-append .add-on,.input-prepend .add-on,.input-append .btn,.input-prepend .btn,.input-append .btn-group>.dropdown-toggle,.input-prepend .btn-group>.dropdown-toggle {\n\tvertical-align: top;\n\t-webkit-border-radius: 0;\n\t-moz-border-radius: 0;\n\tborder-radius: 0\n}\n\n.input-append .active,.input-prepend .active {\n\tbackground-color: #a9dba9;\n\tborder-color: #46a546\n}\n\n.input-prepend .add-on,.input-prepend .btn {\n\tmargin-right: -1px\n}\n\n.input-prepend .add-on:first-child,.input-prepend .btn:first-child {\n\t-webkit-border-radius: 4px 0 0 4px;\n\t-moz-border-radius: 4px 0 0 4px;\n\tborder-radius: 4px 0 0 4px\n}\n\n.input-append input,.input-append select,.input-append .uneditable-input {\n\t-webkit-border-radius: 4px 0 0 4px;\n\t-moz-border-radius: 4px 0 0 4px;\n\tborder-radius: 4px 0 0 4px\n}\n\n.input-append input+.btn-group .btn:last-child,.input-append select+.btn-group .btn:last-child,.input-append .uneditable-input+.btn-group .btn:last-child {\n\t-webkit-border-radius: 0 4px 4px 0;\n\t-moz-border-radius: 0 4px 4px 0;\n\tborder-radius: 0 4px 4px 0\n}\n\n.input-append .add-on,.input-append .btn,.input-append .btn-group {\n\tmargin-left: -1px\n}\n\n.input-append .add-on:last-child,.input-append .btn:last-child,.input-append .btn-group:last-child>.dropdown-toggle {\n\t-webkit-border-radius: 0 4px 4px 0;\n\t-moz-border-radius: 0 4px 4px 0;\n\tborder-radius: 0 4px 4px 0\n}\n\n.input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input {\n\t-webkit-border-radius: 0;\n\t-moz-border-radius: 0;\n\tborder-radius: 0\n}\n\n.input-prepend.input-append input+.btn-group .btn,.input-prepend.input-append select+.btn-group .btn,.input-prepend.input-append .uneditable-input+.btn-group .btn {\n\t-webkit-border-radius: 0 4px 4px 0;\n\t-moz-border-radius: 0 4px 4px 0;\n\tborder-radius: 0 4px 4px 0\n}\n\n.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child {\n\tmargin-right: -1px;\n\t-webkit-border-radius: 4px 0 0 4px;\n\t-moz-border-radius: 4px 0 0 4px;\n\tborder-radius: 4px 0 0 4px\n}\n\n.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child {\n\tmargin-left: -1px;\n\t-webkit-border-radius: 0 4px 4px 0;\n\t-moz-border-radius: 0 4px 4px 0;\n\tborder-radius: 0 4px 4px 0\n}\n\n.input-prepend.input-append .btn-group:first-child {\n\tmargin-left: 0\n}\n\ninput.search-query {\n\tpadding-right: 14px;\n\tpadding-right: 4px \\9;\n\tpadding-left: 14px;\n\tpadding-left: 4px \\9;\n\tmargin-bottom: 0;\n\t-webkit-border-radius: 15px;\n\t-moz-border-radius: 15px;\n\tborder-radius: 15px\n}\n\n.form-search .input-append .search-query,.form-search .input-prepend .search-query {\n\t-webkit-border-radius: 0;\n\t-moz-border-radius: 0;\n\tborder-radius: 0\n}\n\n.form-search .input-append .search-query {\n\t-webkit-border-radius: 14px 0 0 14px;\n\t-moz-border-radius: 14px 0 0 14px;\n\tborder-radius: 14px 0 0 14px\n}\n\n.form-search .input-append .btn {\n\t-webkit-border-radius: 0 14px 14px 0;\n\t-moz-border-radius: 0 14px 14px 0;\n\tborder-radius: 0 14px 14px 0\n}\n\n.form-search .input-prepend .search-query {\n\t-webkit-border-radius: 0 14px 14px 0;\n\t-moz-border-radius: 0 14px 14px 0;\n\tborder-radius: 0 14px 14px 0\n}\n\n.form-search .input-prepend .btn {\n\t-webkit-border-radius: 14px 0 0 14px;\n\t-moz-border-radius: 14px 0 0 14px;\n\tborder-radius: 14px 0 0 14px\n}\n\n.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append {\n\tdisplay: inline-block;\n\t*display: inline;\n\tmargin-bottom: 0;\n\tvertical-align: middle;\n\t*zoom: 1\n}\n\n.form-search .hide,.form-inline .hide,.form-horizontal .hide {\n\tdisplay: none\n}\n\n.form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group {\n\tdisplay: inline-block\n}\n\n.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend {\n\tmargin-bottom: 0\n}\n\n.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox {\n\tpadding-left: 0;\n\tmargin-bottom: 0;\n\tvertical-align: middle\n}\n\n.form-search .radio input[type=\"radio\"],.form-search .checkbox input[type=\"checkbox\"],.form-inline .radio input[type=\"radio\"],.form-inline .checkbox input[type=\"checkbox\"] {\n\tfloat: left;\n\tmargin-right: 3px;\n\tmargin-left: 0\n}\n\nlegend+.control-group {\n\tmargin-top: 20px;\n\t-webkit-margin-top-collapse: separate\n}\n\n.form-horizontal .control-group {\n\tmargin-bottom: 20px;\n\t*zoom: 1\n}\n\n.form-horizontal .control-group:before,.form-horizontal .control-group:after {\n\tdisplay: table;\n\tline-height: 0;\n\tcontent: \"\"\n}\n\n.form-horizontal .control-group:after {\n\tclear: both\n}\n\n.form-horizontal .control-label {\n\tfloat: left;\n\twidth: 160px;\n\tpadding-top: 5px;\n\ttext-align: right\n}\n\n.form-horizontal .controls {\n\t*display: inline-block;\n\t*padding-left: 20px;\n\tmargin-left: 180px;\n\t*margin-left: 0\n}\n\n.form-horizontal .controls:first-child {\n\t*padding-left: 180px\n}\n\n.form-horizontal .help-block {\n\tmargin-bottom: 0\n}\n\n.form-horizontal input+.help-block,.form-horizontal select+.help-block,.form-horizontal textarea+.help-block,.form-horizontal .uneditable-input+.help-block,.form-horizontal .input-prepend+.help-block,.form-horizontal .input-append+.help-block {\n\tmargin-top: 10px\n}\n\n.form-horizontal .form-actions {\n\tpadding-left: 180px\n}\n\ntable {\n\tmax-width: 100%;\n\tbackground-color: transparent;\n\tborder-collapse: collapse;\n\tborder-spacing: 0\n}\n\n.table {\n\twidth: 100%;\n\tmargin-bottom: 20px\n}\n\n.table th,.table td {\n\tpadding: 8px;\n\tline-height: 20px;\n\ttext-align: left;\n\tvertical-align: top;\n\tborder-top: 1px solid #ddd\n}\n\n.table th {\n\tfont-weight: bold\n}\n\n.table thead th {\n\tvertical-align: bottom\n}\n\n.table caption+thead tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.table thead:first-child tr:first-child td {\n\tborder-top: 0\n}\n\n.table tbody+tbody {\n\tborder-top: 2px solid #ddd\n}\n\n.table .table {\n\tbackground-color: #fff\n}\n\n.table-condensed th,.table-condensed td {\n\tpadding: 4px 5px\n}\n\n.table-bordered {\n\tborder: 1px solid #ddd;\n\tborder-collapse: separate;\n\t*border-collapse: collapse;\n\tborder-left: 0;\n\t-webkit-border-radius: 4px;\n\t-moz-border-radius: 4px;\n\tborder-radius: 4px\n}\n\n.table-bordered th,.table-bordered td {\n\tborder-left: 1px solid #ddd\n}\n\n.table-bordered caption+thead tr:first-child th,.table-bordered caption+tbody tr:first-child th,.table-bordered caption+tbody tr:first-child td,.table-bordered colgroup+thead tr:first-child th,.table-bordered colgroup+tbody tr:first-child th,.table-bordered colgroup+tbody tr:first-child td,.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td {\n\tborder-top: 0\n}\n\n.table-bordered thead:first-child tr:first-child>th:first-child,.table-bordered tbody:first-child tr:first-child>td:first-child,.table-bordered tbody:first-child tr:first-child>th:first-child {\n\t-webkit-border-top-left-radius: 4px;\n\tborder-top-left-radius: 4px;\n\t-moz-border-radius-topleft: 4px\n}\n\n.table-bordered thead:first-child tr:first-child>th:last-child,.table-bordered tbody:first-child tr:first-child>td:last-child,.table-bordered tbody:first-child tr:first-child>th:last-child {\n\t-webkit-border-top-right-radius: 4px;\n\tborder-top-right-radius: 4px;\n\t-moz-border-radius-topright: 4px\n}\n\n.table-bordered thead:last-child tr:last-child>th:first-child,.table-bordered tbody:last-child tr:last-child>td:first-child,.table-bordered tbody:last-child tr:last-child>th:first-child,.table-bordered tfoot:last-child tr:last-child>td:first-child,.table-bordered tfoot:last-child tr:last-child>th:first-child {\n\t-webkit-border-bottom-left-radius: 4px;\n\tborder-bottom-left-radius: 4px;\n\t-moz-border-radius-bottomleft: 4px\n}\n\n.table-bordered thead:last-child tr:last-child>th:last-child,.table-bordered tbody:last-child tr:last-child>td:last-child,.table-bordered tbody:last-child tr:last-child>th:last-child,.table-bordered tfoot:last-child tr:last-child>td:last-child,.table-bordered tfoot:last-child tr:last-child>th:last-child {\n\t-webkit-border-bottom-right-radius: 4px;\n\tborder-bottom-right-radius: 4px;\n\t-moz-border-radius-bottomright: 4px\n}\n\n.table-bordered tfoot+tbody:last-child tr:last-child td:first-child {\n\t-webkit-border-bottom-left-radius: 0;\n\tborder-bottom-left-radius: 0;\n\t-moz-border-radius-bottomleft: 0\n}\n\n.table-bordered tfoot+tbody:last-child tr:last-child td:last-child {\n\t-webkit-border-bottom-right-radius: 0;\n\tborder-bottom-right-radius: 0;\n\t-moz-border-radius-bottomright: 0\n}\n\n.table-bordered caption+thead tr:first-child th:first-child,.table-bordered caption+tbody tr:first-child td:first-child,.table-bordered colgroup+thead tr:first-child th:first-child,.table-bordered colgroup+tbody tr:first-child td:first-child {\n\t-webkit-border-top-left-radius: 4px;\n\tborder-top-left-radius: 4px;\n\t-moz-border-radius-topleft: 4px\n}\n\n.table-bordered caption+thead tr:first-child th:last-child,.table-bordered caption+tbody tr:first-child td:last-child,.table-bordered colgroup+thead tr:first-child th:last-child,.table-bordered colgroup+tbody tr:first-child td:last-child {\n\t-webkit-border-top-right-radius: 4px;\n\tborder-top-right-radius: 4px;\n\t-moz-border-radius-topright: 4px\n}\n\n.table-striped tbody>tr:nth-child(odd)>td,.table-striped tbody>tr:nth-child(odd)>th {\n\tbackground-color: #f9f9f9\n}\n\n.table-hover tbody tr:hover>td,.table-hover tbody tr:hover>th {\n\tbackground-color: #f5f5f5\n}\n\ntable td[class*=\"span\"],table th[class*=\"span\"],.row-fluid table td[class*=\"span\"],.row-fluid table th[class*=\"span\"] {\n\tdisplay: table-cell;\n\tfloat: none;\n\tmargin-left: 0\n}\n\n.table td.span1,.table th.span1 {\n\tfloat: none;\n\twidth: 44px;\n\tmargin-left: 0\n}\n\n.table td.span2,.table th.span2 {\n\tfloat: none;\n\twidth: 124px;\n\tmargin-left: 0\n}\n\n.table td.span3,.table th.span3 {\n\tfloat: none;\n\twidth: 204px;\n\tmargin-left: 0\n}\n\n.table td.span4,.table th.span4 {\n\tfloat: none;\n\twidth: 284px;\n\tmargin-left: 0\n}\n\n.table td.span5,.table th.span5 {\n\tfloat: none;\n\twidth: 364px;\n\tmargin-left: 0\n}\n\n.table td.span6,.table th.span6 {\n\tfloat: none;\n\twidth: 444px;\n\tmargin-left: 0\n}\n\n.table td.span7,.table th.span7 {\n\tfloat: none;\n\twidth: 524px;\n\tmargin-left: 0\n}\n\n.table td.span8,.table th.span8 {\n\tfloat: none;\n\twidth: 604px;\n\tmargin-left: 0\n}\n\n.table td.span9,.table th.span9 {\n\tfloat: none;\n\twidth: 684px;\n\tmargin-left: 0\n}\n\n.table td.span10,.table th.span10 {\n\tfloat: none;\n\twidth: 764px;\n\tmargin-left: 0\n}\n\n.table td.span11,.table th.span11 {\n\tfloat: none;\n\twidth: 844px;\n\tmargin-left: 0\n}\n\n.table td.span12,.table th.span12 {\n\tfloat: none;\n\twidth: 924px;\n\tmargin-left: 0\n}\n\n.table tbody tr.success>td {\n\tbackground-color: #dff0d8\n}\n\n.table tbody tr.error>td {\n\tbackground-color: #f2dede\n}\n\n.table tbody tr.warning>td {\n\tbackground-color: #fcf8e3\n}\n\n.table tbody tr.info>td {\n\tbackground-color: #d9edf7\n}\n\n.table-hover tbody tr.success:hover>td {\n\tbackground-color: #d0e9c6\n}\n\n.table-hover tbody tr.error:hover>td {\n\tbackground-color: #ebcccc\n}\n\n.table-hover tbody tr.warning:hover>td {\n\tbackground-color: #faf2cc\n}\n\n.table-hover tbody tr.info:hover>td {\n\tbackground-color: #c4e3f3\n}[class^=\"icon-\"],[class*=\" icon-\"] {\n\tdisplay: inline-block;\n\twidth: 14px;\n\theight: 14px;\n\tmargin-top: 1px;\n\t*margin-right: .3em;\n\tline-height: 14px;\n\tvertical-align: text-top;\n\tbackground-image: url(\"../img/glyphicons-halflings.png\");\n\tbackground-position: 14px 14px;\n\tbackground-repeat: no-repeat\n}\n\n.icon-white,.nav-pills>.active>a>[class^=\"icon-\"],.nav-pills>.active>a>[class*=\" icon-\"],.nav-list>.active>a>[class^=\"icon-\"],.nav-list>.active>a>[class*=\" icon-\"],.navbar-inverse .nav>.active>a>[class^=\"icon-\"],.navbar-inverse .nav>.active>a>[class*=\" icon-\"],.dropdown-menu>li>a:hover>[class^=\"icon-\"],.dropdown-menu>li>a:focus>[class^=\"icon-\"],.dropdown-menu>li>a:hover>[class*=\" icon-\"],.dropdown-menu>li>a:focus>[class*=\" icon-\"],.dropdown-menu>.active>a>[class^=\"icon-\"],.dropdown-menu>.active>a>[class*=\" icon-\"],.dropdown-submenu:hover>a>[class^=\"icon-\"],.dropdown-submenu:focus>a>[class^=\"icon-\"],.dropdown-submenu:hover>a>[class*=\" icon-\"],.dropdown-submenu:focus>a>[class*=\" icon-\"] {\n\tbackground-image: url(\"../img/glyphicons-halflings-white.png\")\n}\n\n.icon-glass {\n\tbackground-position: 0 0\n}\n\n.icon-music {\n\tbackground-position: -24px 0\n}\n\n.icon-search {\n\tbackground-position: -48px 0\n}\n\n.icon-envelope {\n\tbackground-position: -72px 0\n}\n\n.icon-heart {\n\tbackground-position: -96px 0\n}\n\n.icon-star {\n\tbackground-position: -120px 0\n}\n\n.icon-star-empty {\n\tbackground-position: -144px 0\n}\n\n.icon-user {\n\tbackground-position: -168px 0\n}\n\n.icon-film {\n\tbackground-position: -192px 0\n}\n\n.icon-th-large {\n\tbackground-position: -216px 0\n}\n\n.icon-th {\n\tbackground-position: -240px 0\n}\n\n.icon-th-list {\n\tbackground-position: -264px 0\n}\n\n.icon-ok {\n\tbackground-position: -288px 0\n}\n\n.icon-remove {\n\tbackground-position: -312px 0\n}\n\n.icon-zoom-in {\n\tbackground-position: -336px 0\n}\n\n.icon-zoom-out {\n\tbackground-position: -360px 0\n}\n\n.icon-off {\n\tbackground-position: -384px 0\n}\n\n.icon-signal {\n\tbackground-position: -408px 0\n}\n\n.icon-cog {\n\tbackground-position: -432px 0\n}\n\n.icon-trash {\n\tbackground-position: -456px 0\n}\n\n.icon-home {\n\tbackground-position: 0 -24px\n}\n\n.icon-file {\n\tbackground-position: -24px -24px\n}\n\n.icon-time {\n\tbackground-position: -48px -24px\n}\n\n.icon-road {\n\tbackground-position: -72px -24px\n}\n\n.icon-download-alt {\n\tbackground-position: -96px -24px\n}\n\n.icon-download {\n\tbackground-position: -120px -24px\n}\n\n.icon-upload {\n\tbackground-position: -144px -24px\n}\n\n.icon-inbox {\n\tbackground-position: -168px -24px\n}\n\n.icon-play-circle {\n\tbackground-position: -192px -24px\n}\n\n.icon-repeat {\n\tbackground-position: -216px -24px\n}\n\n.icon-refresh {\n\tbackground-position: -240px -24px\n}\n\n.icon-list-alt {\n\tbackground-position: -264px -24px\n}\n\n.icon-lock {\n\tbackground-position: -287px -24px\n}\n\n.icon-flag {\n\tbackground-position: -312px -24px\n}\n\n.icon-headphones {\n\tbackground-position: -336px -24px\n}\n\n.icon-volume-off {\n\tbackground-position: -360px -24px\n}\n\n.icon-volume-down {\n\tbackground-position: -384px -24px\n}\n\n.icon-volume-up {\n\tbackground-position: -408px -24px\n}\n\n.icon-qrcode {\n\tbackground-position: -432px -24px\n}\n\n.icon-barcode {\n\tbackground-position: -456px -24px\n}\n\n.icon-tag {\n\tbackground-position: 0 -48px\n}\n\n.icon-tags {\n\tbackground-position: -25px -48px\n}\n\n.icon-book {\n\tbackground-position: -48px -48px\n}\n\n.icon-bookmark {\n\tbackground-position: -72px -48px\n}\n\n.icon-print {\n\tbackground-position: -96px -48px\n}\n\n.icon-camera {\n\tbackground-position: -120px -48px\n}\n\n.icon-font {\n\tbackground-position: -144px -48px\n}\n\n.icon-bold {\n\tbackground-position: -167px -48px\n}\n\n.icon-italic {\n\tbackground-position: -192px -48px\n}\n\n.icon-text-height {\n\tbackground-position: -216px -48px\n}\n\n.icon-text-width {\n\tbackground-position: -240px -48px\n}\n\n.icon-align-left {\n\tbackground-position: -264px -48px\n}\n\n.icon-align-center {\n\tbackground-position: -288px -48px\n}\n\n.icon-align-right {\n\tbackground-position: -312px -48px\n}\n\n.icon-align-justify {\n\tbackground-position: -336px -48px\n}\n\n.icon-list {\n\tbackground-position: -360px -48px\n}\n\n.icon-indent-left {\n\tbackground-position: -384px -48px\n}\n\n.icon-indent-right {\n\tbackground-position: -408px -48px\n}\n\n.icon-facetime-video {\n\tbackground-position: -432px -48px\n}\n\n.icon-picture {\n\tbackground-position: -456px -48px\n}\n\n.icon-pencil {\n\tbackground-position: 0 -72px\n}\n\n.icon-map-marker {\n\tbackground-position: -24px -72px\n}\n\n.icon-adjust {\n\tbackground-position: -48px -72px\n}\n\n.icon-tint {\n\tbackground-position: -72px -72px\n}\n\n.icon-edit {\n\tbackground-position: -96px -72px\n}\n\n.icon-share {\n\tbackground-position: -120px -72px\n}\n\n.icon-check {\n\tbackground-position: -144px -72px\n}\n\n.icon-move {\n\tbackground-position: -168px -72px\n}\n\n.icon-step-backward {\n\tbackground-position: -192px -72px\n}\n\n.icon-fast-backward {\n\tbackground-position: -216px -72px\n}\n\n.icon-backward {\n\tbackground-position: -240px -72px\n}\n\n.icon-play {\n\tbackground-position: -264px -72px\n}\n\n.icon-pause {\n\tbackground-position: -288px -72px\n}\n\n.icon-stop {\n\tbackground-position: -312px -72px\n}\n\n.icon-forward {\n\tbackground-position: -336px -72px\n}\n\n.icon-fast-forward {\n\tbackground-position: -360px -72px\n}\n\n.icon-step-forward {\n\tbackground-position: -384px -72px\n}\n\n.icon-eject {\n\tbackground-position: -408px -72px\n}\n\n.icon-chevron-left {\n\tbackground-position: -432px -72px\n}\n\n.icon-chevron-right {\n\tbackground-position: -456px -72px\n}\n\n.icon-plus-sign {\n\tbackground-position: 0 -96px\n}\n\n.icon-minus-sign {\n\tbackground-position: -24px -96px\n}\n\n.icon-remove-sign {\n\tbackground-position: -48px -96px\n}\n\n.icon-ok-sign {\n\tbackground-position: -72px -96px\n}\n\n.icon-question-sign {\n\tbackground-position: -96px -96px\n}\n\n.icon-info-sign {\n\tbackground-position: -120px -96px\n}\n\n.icon-screenshot {\n\tbackground-position: -144px -96px\n}\n\n.icon-remove-circle {\n\tbackground-position: -168px -96px\n}\n\n.icon-ok-circle {\n\tbackground-position: -192px -96px\n}\n\n.icon-ban-circle {\n\tbackground-position: -216px -96px\n}\n\n.icon-arrow-left {\n\tbackground-position: -240px -96px\n}\n\n.icon-arrow-right {\n\tbackground-position: -264px -96px\n}\n\n.icon-arrow-up {\n\tbackground-position: -289px -96px\n}\n\n.icon-arrow-down {\n\tbackground-position: -312px -96px\n}\n\n.icon-share-alt {\n\tbackground-position: -336px -96px\n}\n\n.icon-resize-full {\n\tbackground-position: -360px -96px\n}\n\n.icon-resize-small {\n\tbackground-position: -384px -96px\n}\n\n.icon-plus {\n\tbackground-position: -408px -96px\n}\n\n.icon-minus {\n\tbackground-position: -433px -96px\n}\n\n.icon-asterisk {\n\tbackground-position: -456px -96px\n}\n\n.icon-exclamation-sign {\n\tbackground-position: 0 -120px\n}\n\n.icon-gift {\n\tbackground-position: -24px -120px\n}\n\n.icon-leaf {\n\tbackground-position: -48px -120px\n}\n\n.icon-fire {\n\tbackground-position: -72px -120px\n}\n\n.icon-eye-open {\n\tbackground-position: -96px -120px\n}\n\n.icon-eye-close {\n\tbackground-position: -120px -120px\n}\n\n.icon-warning-sign {\n\tbackground-position: -144px -120px\n}\n\n.icon-plane {\n\tbackground-position: -168px -120px\n}\n\n.icon-calendar {\n\tbackground-position: -192px -120px\n}\n\n.icon-random {\n\twidth: 16px;\n\tbackground-position: -216px -120px\n}\n\n.icon-comment {\n\tbackground-position: -240px -120px\n}\n\n.icon-magnet {\n\tbackground-position: -264px -120px\n}\n\n.icon-chevron-up {\n\tbackground-position: -288px -120px\n}\n\n.icon-chevron-down {\n\tbackground-position: -313px -119px\n}\n\n.icon-retweet {\n\tbackground-position: -336px -120px\n}\n\n.icon-shopping-cart {\n\tbackground-position: -360px -120px\n}\n\n.icon-folder-close {\n\twidth: 16px;\n\tbackground-position: -384px -120px\n}\n\n.icon-folder-open {\n\twidth: 16px;\n\tbackground-position: -408px -120px\n}\n\n.icon-resize-vertical {\n\tbackground-position: -432px -119px\n}\n\n.icon-resize-horizontal {\n\tbackground-position: -456px -118px\n}\n\n.icon-hdd {\n\tbackground-position: 0 -144px\n}\n\n.icon-bullhorn {\n\tbackground-position: -24px -144px\n}\n\n.icon-bell {\n\tbackground-position: -48px -144px\n}\n\n.icon-certificate {\n\tbackground-position: -72px -144px\n}\n\n.icon-thumbs-up {\n\tbackground-position: -96px -144px\n}\n\n.icon-thumbs-down {\n\tbackground-position: -120px -144px\n}\n\n.icon-hand-right {\n\tbackground-position: -144px -144px\n}\n\n.icon-hand-left {\n\tbackground-position: -168px -144px\n}\n\n.icon-hand-up {\n\tbackground-position: -192px -144px\n}\n\n.icon-hand-down {\n\tbackground-position: -216px -144px\n}\n\n.icon-circle-arrow-right {\n\tbackground-position: -240px -144px\n}\n\n.icon-circle-arrow-left {\n\tbackground-position: -264px -144px\n}\n\n.icon-circle-arrow-up {\n\tbackground-position: -288px -144px\n}\n\n.icon-circle-arrow-down {\n\tbackground-position: -312px -144px\n}\n\n.icon-globe {\n\tbackground-position: -336px -144px\n}\n\n.icon-wrench {\n\tbackground-position: -360px -144px\n}\n\n.icon-tasks {\n\tbackground-position: -384px -144px\n}\n\n.icon-filter {\n\tbackground-position: -408px -144px\n}\n\n.icon-briefcase {\n\tbackground-position: -432px -144px\n}\n\n.icon-fullscreen {\n\tbackground-position: -456px -144px\n}\n\n.dropup,.dropdown {\n\tposition: relative\n}\n\n.dropdown-toggle {\n\t*margin-bottom: -3px\n}\n\n.dropdown-toggle:active,.open .dropdown-toggle {\n\toutline: 0\n}\n\n.caret {\n\tdisplay: inline-block;\n\twidth: 0;\n\theight: 0;\n\tvertical-align: top;\n\tborder-top: 4px solid #000;\n\tborder-right: 4px solid transparent;\n\tborder-left: 4px solid transparent;\n\tcontent: \"\"\n}\n\n.dropdown .caret {\n\tmargin-top: 8px;\n\tmargin-left: 2px\n}\n\n.dropdown-menu {\n\tposition: absolute;\n\ttop: 100%;\n\tleft: 0;\n\tz-index: 1000;\n\tdisplay: none;\n\tfloat: left;\n\tmin-width: 160px;\n\tpadding: 5px 0;\n\tmargin: 2px 0 0;\n\tlist-style: none;\n\tbackground-color: #fff;\n\tborder: 1px solid #ccc;\n\tborder: 1px solid rgba(0,0,0,0.2);\n\t*border-right-width: 2px;\n\t*border-bottom-width: 2px;\n\t-webkit-border-radius: 6px;\n\t-moz-border-radius: 6px;\n\tborder-radius: 6px;\n\t-webkit-box-shadow: 0 5px 10px rgba(0,0,0,0.2);\n\t-moz-box-shadow: 0 5px 10px rgba(0,0,0,0.2);\n\tbox-shadow: 0 5px 10px rgba(0,0,0,0.2);\n\t-webkit-background-clip: padding-box;\n\t-moz-background-clip: padding;\n\tbackground-clip: padding-box\n}\n\n.dropdown-menu.pull-right {\n\tright: 0;\n\tleft: auto\n}\n\n.dropdown-menu .divider {\n\t*width: 100%;\n\theight: 1px;\n\tmargin: 9px 1px;\n\t*margin: -5px 0 5px;\n\toverflow: hidden;\n\tbackground-color: #e5e5e5;\n\tborder-bottom: 1px solid #fff\n}\n\n.dropdown-menu>li>a {\n\tdisplay: block;\n\tpadding: 3px 20px;\n\tclear: both;\n\tfont-weight: normal;\n\tline-height: 20px;\n\tcolor: #333;\n\twhite-space: nowrap\n}\n\n.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus,.dropdown-submenu:hover>a,.dropdown-submenu:focus>a {\n\tcolor: #fff;\n\ttext-decoration: none;\n\tbackground-color: #0081c2;\n\tbackground-image: -moz-linear-gradient(top,#08c,#0077b3);\n\tbackground-image: -webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));\n\tbackground-image: -webkit-linear-gradient(top,#08c,#0077b3);\n\tbackground-image: -o-linear-gradient(top,#08c,#0077b3);\n\tbackground-image: linear-gradient(to bottom,#08c,#0077b3);\n\tbackground-repeat: repeat-x;\n\tfilter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)\n}\n\n.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus {\n\tcolor: #fff;\n\ttext-decoration: none;\n\tbackground-color: #0081c2;\n\tbackground-image: -moz-linear-gradient(top,#08c,#0077b3);\n\tbackground-image: -webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));\n\tbackground-image: -webkit-linear-gradient(top,#08c,#0077b3);\n\tbackground-image: -o-linear-gradient(top,#08c,#0077b3);\n\tbackground-image: linear-gradient(to bottom,#08c,#0077b3);\n\tbackground-repeat: repeat-x;\n\toutline: 0;\n\tfilter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)\n}\n\n.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus {\n\tcolor: #999\n}\n\n.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus {\n\ttext-decoration: none;\n\tcursor: default;\n\tbackground-color: transparent;\n\tbackground-image: none;\n\tfilter: progid:DXImageTransform.Microsoft.gradient(enabled=false)\n}\n\n.open {\n\t*z-index: 1000\n}\n\n.open>.dropdown-menu {\n\tdisplay: block\n}\n\n.dropdown-backdrop {\n\tposition: fixed;\n\ttop: 0;\n\tright: 0;\n\tbottom: 0;\n\tleft: 0;\n\tz-index: 990\n}\n\n.pull-right>.dropdown-menu {\n\tright: 0;\n\tleft: auto\n}\n\n.dropup .caret,.navbar-fixed-bottom .dropdown .caret {\n\tborder-top: 0;\n\tborder-bottom: 4px solid #000;\n\tcontent: \"\"\n}\n\n.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu {\n\ttop: auto;\n\tbottom: 100%;\n\tmargin-bottom: 1px\n}\n\n.dropdown-submenu {\n\tposition: relative\n}\n\n.dropdown-submenu>.dropdown-menu {\n\ttop: 0;\n\tleft: 100%;\n\tmargin-top: -6px;\n\tmargin-left: -1px;\n\t-webkit-border-radius: 0 6px 6px 6px;\n\t-moz-border-radius: 0 6px 6px 6px;\n\tborder-radius: 0 6px 6px 6px\n}\n\n.dropdown-submenu:hover>.dropdown-menu {\n\tdisplay: block\n}\n\n.dropup .dropdown-submenu>.dropdown-menu {\n\ttop: auto;\n\tbottom: 0;\n\tmargin-top: 0;\n\tmargin-bottom: -2px;\n\t-webkit-border-radius: 5px 5px 5px 0;\n\t-moz-border-radius: 5px 5px 5px 0;\n\tborder-radius: 5px 5px 5px 0\n}\n\n.dropdown-submenu>a:after {\n\tdisplay: block;\n\tfloat: right;\n\twidth: 0;\n\theight: 0;\n\tmargin-top: 5px;\n\tmargin-right: -10px;\n\tborder-color: transparent;\n\tborder-left-color: #ccc;\n\tborder-style: solid;\n\tborder-width: 5px 0 5px 5px;\n\tcontent: \" \"\n}\n\n.dropdown-submenu:hover>a:after {\n\tborder-left-color: #fff\n}\n\n.dropdown-submenu.pull-left {\n\tfloat: none\n}\n\n.dropdown-submenu.pull-left>.dropdown-menu {\n\tleft: -100%;\n\tmargin-left: 10px;\n\t-webkit-border-radius: 6px 0 6px 6px;\n\t-moz-border-radius: 6px 0 6px 6px;\n\tborder-radius: 6px 0 6px 6px\n}\n\n.dropdown .dropdown-menu .nav-header {\n\tpadding-right: 20px;\n\tpadding-left: 20px\n}\n\n.typeahead {\n\tz-index: 1051;\n\tmargin-top: 2px;\n\t-webkit-border-radius: 4px;\n\t-moz-border-radius: 4px;\n\tborder-radius: 4px\n}\n\n.well {\n\tmin-height: 20px;\n\tpadding: 19px;\n\tmargin-bottom: 20px;\n\tbackground-color: #f5f5f5;\n\tborder: 1px solid #e3e3e3;\n\t-webkit-border-radius: 4px;\n\t-moz-border-radius: 4px;\n\tborder-radius: 4px;\n\t-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.05);\n\t-moz-box-shadow: inset 0 1px 1px rgba(0,0,0,0.05);\n\tbox-shadow: inset 0 1px 1px rgba(0,0,0,0.05)\n}\n\n.well blockquote {\n\tborder-color: #ddd;\n\tborder-color: rgba(0,0,0,0.15)\n}\n\n.well-large {\n\tpadding: 24px;\n\t-webkit-border-radius: 6px;\n\t-moz-border-radius: 6px;\n\tborder-radius: 6px\n}\n\n.well-small {\n\tpadding: 9px;\n\t-webkit-border-radius: 3px;\n\t-moz-border-radius: 3px;\n\tborder-radius: 3px\n}\n\n.fade {\n\topacity: 0;\n\t-webkit-transition: opacity .15s linear;\n\t-moz-transition: opacity .15s linear;\n\t-o-transition: opacity .15s linear;\n\ttransition: opacity .15s linear\n}\n\n.fade.in {\n\topacity: 1\n}\n\n.collapse {\n\tposition: relative;\n\theight: 0;\n\toverflow: hidden;\n\t-webkit-transition: height .35s ease;\n\t-moz-transition: height .35s ease;\n\t-o-transition: height .35s ease;\n\ttransition: height .35s ease\n}\n\n.collapse.in {\n\theight: auto\n}\n\n.close {\n\tfloat: right;\n\tfont-size: 20px;\n\tfont-weight: bold;\n\tline-height: 20px;\n\tcolor: #000;\n\ttext-shadow: 0 1px 0 #fff;\n\topacity: .2;\n\tfilter: alpha(opacity=20)\n}\n\n.close:hover,.close:focus {\n\tcolor: #000;\n\ttext-decoration: none;\n\tcursor: pointer;\n\topacity: .4;\n\tfilter: alpha(opacity=40)\n}\n\nbutton.close {\n\tpadding: 0;\n\tcursor: pointer;\n\tbackground: transparent;\n\tborder: 0;\n\t-webkit-appearance: none\n}\n\n.btn {\n\tcolor: #333;\n\tbackground-color: #fff;\n\tdisplay: inline-block;\n\tpadding: 6px 12px;\n\tmargin-bottom: 0;\n\tfont-size: 14px;\n\tfont-weight: normal;\n\tline-height: 1.428571429;\n\ttext-align: center;\n\twhite-space: nowrap;\n\tvertical-align: middle;\n\tcursor: pointer;\n\t-webkit-user-select: none;\n\t-moz-user-select: none;\n\t-ms-user-select: none;\n\t-o-user-select: none;\n\tuser-select: none;\n\tbackground-image: none;\n\tborder: 1px solid #ccc;\n\tborder-radius: 4px\n}\n\n.btn:hover,.btn:focus,.btn:active,.btn.active,.btn.disabled,.btn[disabled] {\n\tcolor: #333;\n\tbackground-color: #ebebeb;\n\tborder-color: #adadad\n}\n\n.btn:active,.btn.active {\n\tbackground-color: #ccc \\9\n}\n\n.btn:first-child {\n\t*margin-left: 0\n}\n\n.btn:hover,.btn:focus {\n\tcolor: #333;\n\ttext-decoration: none;\n\tbackground-position: 0 -15px;\n\t-webkit-transition: background-position .1s linear;\n\t-moz-transition: background-position .1s linear;\n\t-o-transition: background-position .1s linear;\n\ttransition: background-position .1s linear\n}\n\n.btn:focus {\n\toutline: thin dotted #333;\n\toutline: 5px auto -webkit-focus-ring-color;\n\toutline-offset: -2px\n}\n\n.btn.active,.btn:active {\n\tbackground-image: none;\n\toutline: 0;\n\t-webkit-box-shadow: inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);\n\t-moz-box-shadow: inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);\n\tbox-shadow: inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)\n}\n\n.btn.disabled,.btn[disabled] {\n\tcursor: default;\n\tbackground-image: none;\n\topacity: .65;\n\tfilter: alpha(opacity=65);\n\t-webkit-box-shadow: none;\n\t-moz-box-shadow: none;\n\tbox-shadow: none\n}\n\n.btn-large {\n\tpadding: 11px 19px;\n\tfont-size: 17.5px;\n\t-webkit-border-radius: 6px;\n\t-moz-border-radius: 6px;\n\tborder-radius: 6px\n}\n\n.btn-large [class^=\"icon-\"],.btn-large [class*=\" icon-\"] {\n\tmargin-top: 4px\n}\n\n.btn-small {\n\tpadding: 2px 10px;\n\tfont-size: 11.9px;\n\t-webkit-border-radius: 3px;\n\t-moz-border-radius: 3px;\n\tborder-radius: 3px\n}\n\n.btn-small [class^=\"icon-\"],.btn-small [class*=\" icon-\"] {\n\tmargin-top: 0\n}\n\n.btn-mini [class^=\"icon-\"],.btn-mini [class*=\" icon-\"] {\n\tmargin-top: -1px\n}\n\n.btn-mini {\n\tpadding: 0 6px;\n\tfont-size: 10.5px;\n\t-webkit-border-radius: 3px;\n\t-moz-border-radius: 3px;\n\tborder-radius: 3px\n}\n\n.btn-block {\n\tdisplay: block;\n\twidth: 100%;\n\tpadding-right: 0;\n\tpadding-left: 0;\n\t-webkit-box-sizing: border-box;\n\t-moz-box-sizing: border-box;\n\tbox-sizing: border-box\n}\n\n.btn-block+.btn-block {\n\tmargin-top: 5px\n}\n\ninput[type=\"submit\"].btn-block,input[type=\"reset\"].btn-block,input[type=\"button\"].btn-block {\n\twidth: 100%\n}\n\n.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active {\n\tcolor: rgba(255,255,255,0.75)\n}\n\n.btn-primary {\n\tcolor: #fff;\n\tbackground: #1b93d1;\n\tborder: 1px solid #15709e\n}\n\n.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled] {\n\tcolor: #fff;\n\tbackground-color: #3276b1;\n\tborder-color: #285e8e\n}\n\n.btn-primary:active,.btn-primary.active {\n\tbackground-color: #039 \\9\n}\n\n.btn-warning {\n\tcolor: #fff;\n\tbackground-color: #f0ad4e;\n\tborder-color: #eea236\n}\n\n.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled] {\n\tcolor: #fff;\n\tbackground-color: #ed9c28;\n\tborder-color: #d58512\n}\n\n.btn-warning:active,.btn-warning.active {\n\tbackground-color: #c67605 \\9\n}\n\n.btn-danger {\n\tcolor: #fff;\n\tbackground-color: #d9534f;\n\tborder-color: #d43f3a\n}\n\n.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled] {\n\tcolor: #fff;\n\tbackground-color: #d2322d;\n\tborder-color: #ac2925\n}\n\n.btn-danger:active,.btn-danger.active {\n\tbackground-color: #942a25 \\9\n}\n\n.btn-success {\n\tcolor: #fff;\n\tbackground-color: #5cb85c;\n\tborder-color: #4cae4c\n}\n\n.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled] {\n\tcolor: #fff;\n\tbackground-color: #47a447;\n\tborder-color: #398439\n}\n\n.btn-success:active,.btn-success.active {\n\tbackground-color: #408140 \\9\n}\n\n.btn-info {\n\tcolor: #fff;\n\tbackground-color: #5bc0de;\n\tborder-color: #46b8da\n}\n\n.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled] {\n\tcolor: #fff;\n\tbackground-color: #39b3d7;\n\tborder-color: #269abc\n}\n\n.btn-info:active,.btn-info.active {\n\tbackground-color: #24748c \\9\n}\n\n.btn-inverse {\n\tcolor: #fff;\n\ttext-shadow: 0 -1px 0 rgba(0,0,0,0.25);\n\tbackground-color: #363636;\n\t*background-color: #222;\n\tbackground-image: -moz-linear-gradient(top,#444,#222);\n\tbackground-image: -webkit-gradient(linear,0 0,0 100%,from(#444),to(#222));\n\tbackground-image: -webkit-linear-gradient(top,#444,#222);\n\tbackground-image: -o-linear-gradient(top,#444,#222);\n\tbackground-image: linear-gradient(to bottom,#444,#222);\n\tbackground-repeat: repeat-x;\n\tborder-color: #222 #222 #000;\n\tborder-color: rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);\n\tfilter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444',endColorstr='#ff222222',GradientType=0);\n\tfilter: progid:DXImageTransform.Microsoft.gradient(enabled=false)\n}\n\n.btn-inverse:hover,.btn-inverse:focus,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled] {\n\tcolor: #fff;\n\tbackground-color: #222;\n\t*background-color: #151515\n}\n\n.btn-inverse:active,.btn-inverse.active {\n\tbackground-color: #080808 \\9\n}\n\nbutton.btn,input[type=\"submit\"].btn {\n\t*padding-top: 3px;\n\t*padding-bottom: 3px\n}\n\nbutton.btn::-moz-focus-inner,input[type=\"submit\"].btn::-moz-focus-inner {\n\tpadding: 0;\n\tborder: 0\n}\n\nbutton.btn.btn-large,input[type=\"submit\"].btn.btn-large {\n\t*padding-top: 7px;\n\t*padding-bottom: 7px\n}\n\nbutton.btn.btn-small,input[type=\"submit\"].btn.btn-small {\n\t*padding-top: 3px;\n\t*padding-bottom: 3px\n}\n\nbutton.btn.btn-mini,input[type=\"submit\"].btn.btn-mini {\n\t*padding-top: 1px;\n\t*padding-bottom: 1px\n}\n\n.btn-link,.btn-link:active,.btn-link[disabled] {\n\tbackground-color: transparent;\n\tbackground-image: none;\n\t-webkit-box-shadow: none;\n\t-moz-box-shadow: none;\n\tbox-shadow: none\n}\n\n.btn-link {\n\tcolor: #08c;\n\tcursor: pointer;\n\tborder-color: transparent;\n\t-webkit-border-radius: 0;\n\t-moz-border-radius: 0;\n\tborder-radius: 0\n}\n\n.btn-link:hover,.btn-link:focus {\n\tcolor: #005580;\n\ttext-decoration: underline;\n\tbackground-color: transparent\n}\n\n.btn-link[disabled]:hover,.btn-link[disabled]:focus {\n\tcolor: #333;\n\ttext-decoration: none\n}\n\n.btn-group {\n\tposition: relative;\n\tdisplay: inline-block;\n\t*display: inline;\n\t*margin-left: .3em;\n\tfont-size: 0;\n\twhite-space: nowrap;\n\tvertical-align: middle;\n\t*zoom: 1\n}\n\n.btn-group:first-child {\n\t*margin-left: 0\n}\n\n.btn-group+.btn-group {\n\tmargin-left: 5px\n}\n\n.btn-toolbar {\n\tmargin-top: 10px;\n\tmargin-bottom: 10px;\n\tfont-size: 0\n}\n\n.btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group {\n\tmargin-left: 5px\n}\n\n.btn-group>.btn {\n\tposition: relative;\n\t-webkit-border-radius: 0;\n\t-moz-border-radius: 0;\n\tborder-radius: 0\n}\n\n.btn-group>.btn+.btn {\n\tmargin-left: -1px\n}\n\n.btn-group>.btn,.btn-group>.dropdown-menu,.btn-group>.popover {\n\tfont-size: 14px\n}\n\n.btn-group>.btn-mini {\n\tfont-size: 10.5px\n}\n\n.btn-group>.btn-small {\n\tfont-size: 11.9px\n}\n\n.btn-group>.btn-large {\n\tfont-size: 17.5px\n}\n\n.btn-group>.btn:first-child {\n\tmargin-left: 0;\n\t-webkit-border-bottom-left-radius: 4px;\n\tborder-bottom-left-radius: 4px;\n\t-webkit-border-top-left-radius: 4px;\n\tborder-top-left-radius: 4px;\n\t-moz-border-radius-bottomleft: 4px;\n\t-moz-border-radius-topleft: 4px\n}\n\n.btn-group>.btn:last-child,.btn-group>.dropdown-toggle {\n\t-webkit-border-top-right-radius: 4px;\n\tborder-top-right-radius: 4px;\n\t-webkit-border-bottom-right-radius: 4px;\n\tborder-bottom-right-radius: 4px;\n\t-moz-border-radius-topright: 4px;\n\t-moz-border-radius-bottomright: 4px\n}\n\n.btn-group>.btn.large:first-child {\n\tmargin-left: 0;\n\t-webkit-border-bottom-left-radius: 6px;\n\tborder-bottom-left-radius: 6px;\n\t-webkit-border-top-left-radius: 6px;\n\tborder-top-left-radius: 6px;\n\t-moz-border-radius-bottomleft: 6px;\n\t-moz-border-radius-topleft: 6px\n}\n\n.btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle {\n\t-webkit-border-top-right-radius: 6px;\n\tborder-top-right-radius: 6px;\n\t-webkit-border-bottom-right-radius: 6px;\n\tborder-bottom-right-radius: 6px;\n\t-moz-border-radius-topright: 6px;\n\t-moz-border-radius-bottomright: 6px\n}\n\n.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active {\n\tz-index: 2\n}\n\n.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle {\n\toutline: 0\n}\n\n.btn-group>.btn+.dropdown-toggle {\n\t*padding-top: 5px;\n\tpadding-right: 8px;\n\t*padding-bottom: 5px;\n\tpadding-left: 8px;\n\t-webkit-box-shadow: inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);\n\t-moz-box-shadow: inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);\n\tbox-shadow: inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)\n}\n\n.btn-group>.btn-mini+.dropdown-toggle {\n\t*padding-top: 2px;\n\tpadding-right: 5px;\n\t*padding-bottom: 2px;\n\tpadding-left: 5px\n}\n\n.btn-group>.btn-small+.dropdown-toggle {\n\t*padding-top: 5px;\n\t*padding-bottom: 4px\n}\n\n.btn-group>.btn-large+.dropdown-toggle {\n\t*padding-top: 7px;\n\tpadding-right: 12px;\n\t*padding-bottom: 7px;\n\tpadding-left: 12px\n}\n\n.btn-group.open .dropdown-toggle {\n\tbackground-image: none;\n\t-webkit-box-shadow: inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);\n\t-moz-box-shadow: inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);\n\tbox-shadow: inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)\n}\n\n.btn-group.open .btn.dropdown-toggle {\n\tbackground-color: #e6e6e6\n}\n\n.btn-group.open .btn-primary.dropdown-toggle {\n\tbackground-color: #04c\n}\n\n.btn-group.open .btn-warning.dropdown-toggle {\n\tbackground-color: #f89406\n}\n\n.btn-group.open .btn-danger.dropdown-toggle {\n\tbackground-color: #bd362f\n}\n\n.btn-group.open .btn-success.dropdown-toggle {\n\tbackground-color: #51a351\n}\n\n.btn-group.open .btn-info.dropdown-toggle {\n\tbackground-color: #2f96b4\n}\n\n.btn-group.open .btn-inverse.dropdown-toggle {\n\tbackground-color: #222\n}\n\n.btn .caret {\n\tmargin-top: 8px;\n\tmargin-left: 0\n}\n\n.btn-large .caret {\n\tmargin-top: 6px\n}\n\n.btn-large .caret {\n\tborder-top-width: 5px;\n\tborder-right-width: 5px;\n\tborder-left-width: 5px\n}\n\n.btn-mini .caret,.btn-small .caret {\n\tmargin-top: 8px\n}\n\n.dropup .btn-large .caret {\n\tborder-bottom-width: 5px\n}\n\n.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret {\n\tborder-top-color: #fff;\n\tborder-bottom-color: #fff\n}\n\n.btn-group-vertical {\n\tdisplay: inline-block;\n\t*display: inline;\n\t*zoom: 1\n}\n\n.btn-group-vertical>.btn {\n\tdisplay: block;\n\tfloat: none;\n\tmax-width: 100%;\n\t-webkit-border-radius: 0;\n\t-moz-border-radius: 0;\n\tborder-radius: 0\n}\n\n.btn-group-vertical>.btn+.btn {\n\tmargin-top: -1px;\n\tmargin-left: 0\n}\n\n.btn-group-vertical>.btn:first-child {\n\t-webkit-border-radius: 4px 4px 0 0;\n\t-moz-border-radius: 4px 4px 0 0;\n\tborder-radius: 4px 4px 0 0\n}\n\n.btn-group-vertical>.btn:last-child {\n\t-webkit-border-radius: 0 0 4px 4px;\n\t-moz-border-radius: 0 0 4px 4px;\n\tborder-radius: 0 0 4px 4px\n}\n\n.btn-group-vertical>.btn-large:first-child {\n\t-webkit-border-radius: 6px 6px 0 0;\n\t-moz-border-radius: 6px 6px 0 0;\n\tborder-radius: 6px 6px 0 0\n}\n\n.btn-group-vertical>.btn-large:last-child {\n\t-webkit-border-radius: 0 0 6px 6px;\n\t-moz-border-radius: 0 0 6px 6px;\n\tborder-radius: 0 0 6px 6px\n}\n\n.alert {\n\tfont-size: 13px;\n\tpadding: 8px 35px 8px 14px;\n\tmargin-bottom: 20px;\n\ttext-shadow: 0 1px 0 rgba(255,255,255,0.5);\n\tbackground-color: #fcf8e3;\n\tborder: 1px solid #fbeed5;\n\t-webkit-border-radius: 4px;\n\t-moz-border-radius: 4px;\n\tborder-radius: 4px\n}\n\n.alert,.alert h4 {\n\tcolor: #c09853\n}\n\n.alert h4 {\n\tmargin: 0\n}\n\n.alert .close {\n\tposition: relative;\n\ttop: -2px;\n\tright: -21px;\n\tline-height: 20px\n}\n\n.alert-success {\n\tcolor: #468847;\n\tbackground-color: #dff0d8;\n\tborder-color: #d6e9c6\n}\n\n.alert-success h4 {\n\tcolor: #468847\n}\n\n.alert-danger,.alert-error {\n\tcolor: #b94a48;\n\tbackground-color: #f2dede;\n\tborder-color: #eed3d7\n}\n\n.alert-danger h4,.alert-error h4 {\n\tcolor: #b94a48\n}\n\n.alert-info {\n\tcolor: #3a87ad;\n\tbackground-color: #d9edf7;\n\tborder-color: #bce8f1\n}\n\n.alert-info h4 {\n\tcolor: #3a87ad\n}\n\n.alert-block {\n\tpadding-top: 14px;\n\tpadding-bottom: 14px\n}\n\n.alert-block>p,.alert-block>ul {\n\tmargin-bottom: 0\n}\n\n.alert-block p+p {\n\tmargin-top: 5px\n}\n\n.nav {\n\tmargin-left: 0;\n\tlist-style: none\n}\n\n.nav>li>a {\n\tdisplay: block\n}\n\n.nav>li>a:hover,.nav>li>a:focus {\n\ttext-decoration: none;\n\tbackground-color: #eee\n}\n\n.nav>li>a>img {\n\tmax-width: none\n}\n\n.nav>.pull-right {\n\tfloat: right\n}\n\n.nav-header {\n\tdisplay: block;\n\tpadding: 3px 15px;\n\tfont-size: 11px;\n\tfont-weight: bold;\n\tline-height: 20px;\n\tcolor: #999;\n\ttext-shadow: 0 1px 0 rgba(255,255,255,0.5);\n\ttext-transform: uppercase\n}\n\n.nav li+.nav-header {\n\tmargin-top: 9px\n}\n\n.nav-list {\n\tpadding-right: 15px;\n\tpadding-left: 15px;\n\tmargin-bottom: 0\n}\n\n.nav-list>li>a,.nav-list .nav-header {\n\tmargin-right: -15px;\n\tmargin-left: -15px;\n\ttext-shadow: 0 1px 0 rgba(255,255,255,0.5)\n}\n\n.nav-list>li>a {\n\tpadding: 3px 15px\n}\n\n.nav-list>.active>a,.nav-list>.active>a:hover,.nav-list>.active>a:focus {\n\tcolor: #fff;\n\ttext-shadow: 0 -1px 0 rgba(0,0,0,0.2);\n\tbackground-color: #08c\n}\n\n.nav-list [class^=\"icon-\"],.nav-list [class*=\" icon-\"] {\n\tmargin-right: 2px\n}\n\n.nav-list .divider {\n\t*width: 100%;\n\theight: 1px;\n\tmargin: 9px 1px;\n\t*margin: -5px 0 5px;\n\toverflow: hidden;\n\tbackground-color: #e5e5e5;\n\tborder-bottom: 1px solid #fff\n}\n\n.nav-tabs,.nav-pills {\n\t*zoom: 1\n}\n\n.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after {\n\tdisplay: table;\n\tline-height: 0;\n\tcontent: \"\"\n}\n\n.nav-tabs:after,.nav-pills:after {\n\tclear: both\n}\n\n.nav-tabs>li,.nav-pills>li {\n\tfloat: left\n}\n\n.nav-tabs>li>a,.nav-pills>li>a {\n\tpadding-right: 12px;\n\tpadding-left: 12px;\n\tmargin-right: 2px;\n\tline-height: 14px\n}\n\n.nav-tabs {\n\tborder-bottom: 1px solid #ddd\n}\n\n.nav-tabs>li {\n\tmargin-bottom: -1px\n}\n\n.nav-tabs>li>a {\n\tpadding-top: 8px;\n\tpadding-bottom: 8px;\n\tline-height: 20px;\n\tborder: 1px solid transparent;\n\t-webkit-border-radius: 4px 4px 0 0;\n\t-moz-border-radius: 4px 4px 0 0;\n\tborder-radius: 4px 4px 0 0\n}\n\n.nav-tabs>li>a:hover,.nav-tabs>li>a:focus {\n\tborder-color: #eee #eee #ddd\n}\n\n.nav-tabs>.active>a,.nav-tabs>.active>a:hover,.nav-tabs>.active>a:focus {\n\tcolor: #555;\n\tcursor: default;\n\tbackground-color: #fff;\n\tborder: 1px solid #ddd;\n\tborder-bottom-color: transparent\n}\n\n.nav-pills>li>a {\n\tpadding-top: 8px;\n\tpadding-bottom: 8px;\n\tmargin-top: 2px;\n\tmargin-bottom: 2px;\n\t-webkit-border-radius: 5px;\n\t-moz-border-radius: 5px;\n\tborder-radius: 5px\n}\n\n.nav-pills>.active>a,.nav-pills>.active>a:hover,.nav-pills>.active>a:focus {\n\tcolor: #fff;\n\tbackground-color: #08c\n}\n\n.nav-stacked>li {\n\tfloat: none\n}\n\n.nav-stacked>li>a {\n\tmargin-right: 0\n}\n\n.nav-tabs.nav-stacked {\n\tborder-bottom: 0\n}\n\n.nav-tabs.nav-stacked>li>a {\n\tborder: 1px solid #ddd;\n\t-webkit-border-radius: 0;\n\t-moz-border-radius: 0;\n\tborder-radius: 0\n}\n\n.nav-tabs.nav-stacked>li:first-child>a {\n\t-webkit-border-top-right-radius: 4px;\n\tborder-top-right-radius: 4px;\n\t-webkit-border-top-left-radius: 4px;\n\tborder-top-left-radius: 4px;\n\t-moz-border-radius-topright: 4px;\n\t-moz-border-radius-topleft: 4px\n}\n\n.nav-tabs.nav-stacked>li:last-child>a {\n\t-webkit-border-bottom-right-radius: 4px;\n\tborder-bottom-right-radius: 4px;\n\t-webkit-border-bottom-left-radius: 4px;\n\tborder-bottom-left-radius: 4px;\n\t-moz-border-radius-bottomright: 4px;\n\t-moz-border-radius-bottomleft: 4px\n}\n\n.nav-tabs.nav-stacked>li>a:hover,.nav-tabs.nav-stacked>li>a:focus {\n\tz-index: 2;\n\tborder-color: #ddd\n}\n\n.nav-pills.nav-stacked>li>a {\n\tmargin-bottom: 3px\n}\n\n.nav-pills.nav-stacked>li:last-child>a {\n\tmargin-bottom: 1px\n}\n\n.nav-tabs .dropdown-menu {\n\t-webkit-border-radius: 0 0 6px 6px;\n\t-moz-border-radius: 0 0 6px 6px;\n\tborder-radius: 0 0 6px 6px\n}\n\n.nav-pills .dropdown-menu {\n\t-webkit-border-radius: 6px;\n\t-moz-border-radius: 6px;\n\tborder-radius: 6px\n}\n\n.nav .dropdown-toggle .caret {\n\tmargin-top: 6px;\n\tborder-top-color: #08c;\n\tborder-bottom-color: #08c\n}\n\n.nav .dropdown-toggle:hover .caret,.nav .dropdown-toggle:focus .caret {\n\tborder-top-color: #005580;\n\tborder-bottom-color: #005580\n}\n\n.nav-tabs .dropdown-toggle .caret {\n\tmargin-top: 8px\n}\n\n.nav .active .dropdown-toggle .caret {\n\tborder-top-color: #fff;\n\tborder-bottom-color: #fff\n}\n\n.nav-tabs .active .dropdown-toggle .caret {\n\tborder-top-color: #555;\n\tborder-bottom-color: #555\n}\n\n.nav>.dropdown.active>a:hover,.nav>.dropdown.active>a:focus {\n\tcursor: pointer\n}\n\n.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover,.nav>li.dropdown.open.active>a:focus {\n\tcolor: #fff;\n\tbackground-color: #999;\n\tborder-color: #999\n}\n\n.nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret,.nav li.dropdown.open a:focus .caret {\n\tborder-top-color: #fff;\n\tborder-bottom-color: #fff;\n\topacity: 1;\n\tfilter: alpha(opacity=100)\n}\n\n.tabs-stacked .open>a:hover,.tabs-stacked .open>a:focus {\n\tborder-color: #999\n}\n\n.tabbable {\n\t*zoom: 1\n}\n\n.tabbable:before,.tabbable:after {\n\tdisplay: table;\n\tline-height: 0;\n\tcontent: \"\"\n}\n\n.tabbable:after {\n\tclear: both\n}\n\n.tab-content {\n\toverflow: auto\n}\n\n.tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs {\n\tborder-bottom: 0\n}\n\n.tab-content>.tab-pane,.pill-content>.pill-pane {\n\tdisplay: none;\n\tpadding-left: 10px\n}\n\n.tab-content>.active,.pill-content>.active {\n\tdisplay: block\n}\n\n.tabs-below>.nav-tabs {\n\tborder-top: 1px solid #ddd\n}\n\n.tabs-below>.nav-tabs>li {\n\tmargin-top: -1px;\n\tmargin-bottom: 0\n}\n\n.tabs-below>.nav-tabs>li>a {\n\t-webkit-border-radius: 0 0 4px 4px;\n\t-moz-border-radius: 0 0 4px 4px;\n\tborder-radius: 0 0 4px 4px\n}\n\n.tabs-below>.nav-tabs>li>a:hover,.tabs-below>.nav-tabs>li>a:focus {\n\tborder-top-color: #ddd;\n\tborder-bottom-color: transparent\n}\n\n.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover,.tabs-below>.nav-tabs>.active>a:focus {\n\tborder-color: transparent #ddd #ddd #ddd\n}\n\n.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li {\n\tfloat: none\n}\n\n.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a {\n\tmin-width: 74px;\n\tmargin-right: 0;\n\tmargin-bottom: 3px\n}\n\n.tabs-left>.nav-tabs {\n\tfloat: left;\n\tmargin-right: 19px;\n\tborder-right: 1px solid #ddd\n}\n\n.tabs-left>.nav-tabs>li>a {\n\tmargin-right: -1px;\n\t-webkit-border-radius: 4px 0 0 4px;\n\t-moz-border-radius: 4px 0 0 4px;\n\tborder-radius: 4px 0 0 4px\n}\n\n.tabs-left>.nav-tabs>li>a:hover,.tabs-left>.nav-tabs>li>a:focus {\n\tborder-color: #eee #ddd #eee #eee\n}\n\n.tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover,.tabs-left>.nav-tabs .active>a:focus {\n\tborder-color: #ddd transparent #ddd #ddd;\n\t*border-right-color: #fff\n}\n\n.tabs-right>.nav-tabs {\n\tfloat: right;\n\tmargin-left: 19px;\n\tborder-left: 1px solid #ddd\n}\n\n.tabs-right>.nav-tabs>li>a {\n\tmargin-left: -1px;\n\t-webkit-border-radius: 0 4px 4px 0;\n\t-moz-border-radius: 0 4px 4px 0;\n\tborder-radius: 0 4px 4px 0\n}\n\n.tabs-right>.nav-tabs>li>a:hover,.tabs-right>.nav-tabs>li>a:focus {\n\tborder-color: #eee #eee #eee #ddd\n}\n\n.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover,.tabs-right>.nav-tabs .active>a:focus {\n\tborder-color: #ddd #ddd #ddd transparent;\n\t*border-left-color: #fff\n}\n\n.nav>.disabled>a {\n\tcolor: #999\n}\n\n.nav>.disabled>a:hover,.nav>.disabled>a:focus {\n\ttext-decoration: none;\n\tcursor: default;\n\tbackground-color: transparent\n}\n\n.navbar {\n\t*position: relative;\n\t*z-index: 2;\n\tmargin-bottom: 20px;\n\toverflow: visible\n}\n\n.navbar-inner {\n\tmin-height: 40px;\n\tpadding-right: 20px;\n\tpadding-left: 20px;\n\tbackground-color: #fafafa;\n\tbackground-image: -moz-linear-gradient(top,#fff,#f2f2f2);\n\tbackground-image: -webkit-gradient(linear,0 0,0 100%,from(#fff),to(#f2f2f2));\n\tbackground-image: -webkit-linear-gradient(top,#fff,#f2f2f2);\n\tbackground-image: -o-linear-gradient(top,#fff,#f2f2f2);\n\tbackground-image: linear-gradient(to bottom,#fff,#f2f2f2);\n\tbackground-repeat: repeat-x;\n\tborder: 1px solid #d4d4d4;\n\t-webkit-border-radius: 4px;\n\t-moz-border-radius: 4px;\n\tborder-radius: 4px;\n\tfilter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#fff2f2f2',GradientType=0);\n\t*zoom: 1;\n\t-webkit-box-shadow: 0 1px 4px rgba(0,0,0,0.065);\n\t-moz-box-shadow: 0 1px 4px rgba(0,0,0,0.065);\n\tbox-shadow: 0 1px 4px rgba(0,0,0,0.065)\n}\n\n.navbar-inner:before,.navbar-inner:after {\n\tdisplay: table;\n\tline-height: 0;\n\tcontent: \"\"\n}\n\n.navbar-inner:after {\n\tclear: both\n}\n\n.navbar .container {\n\twidth: auto\n}\n\n.nav-collapse.collapse {\n\theight: auto;\n\toverflow: visible\n}\n\n.navbar .brand {\n\tdisplay: block;\n\tfloat: left;\n\tpadding: 10px 20px 10px;\n\tmargin-left: -20px;\n\tfont-size: 20px;\n\tfont-weight: 200;\n\tcolor: #777;\n\ttext-shadow: 0 1px 0 #fff\n}\n\n.navbar .brand:hover,.navbar .brand:focus {\n\ttext-decoration: none\n}\n\n.navbar-text {\n\tmargin-bottom: 0;\n\tline-height: 40px;\n\tcolor: #777\n}\n\n.navbar-link {\n\tcolor: #777\n}\n\n.navbar-link:hover,.navbar-link:focus {\n\tcolor: #333\n}\n\n.navbar .divider-vertical {\n\theight: 40px;\n\tmargin: 0 9px;\n\tborder-right: 1px solid #fff;\n\tborder-left: 1px solid #f2f2f2\n}\n\n.navbar .btn,.navbar .btn-group {\n\tmargin-top: 5px\n}\n\n.navbar .btn-group .btn,.navbar .input-prepend .btn,.navbar .input-append .btn,.navbar .input-prepend .btn-group,.navbar .input-append .btn-group {\n\tmargin-top: 0\n}\n\n.navbar-form {\n\tmargin-bottom: 0;\n\t*zoom: 1\n}\n\n.navbar-form:before,.navbar-form:after {\n\tdisplay: table;\n\tline-height: 0;\n\tcontent: \"\"\n}\n\n.navbar-form:after {\n\tclear: both\n}\n\n.navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox {\n\tmargin-top: 5px\n}\n\n.navbar-form input,.navbar-form select,.navbar-form .btn {\n\tdisplay: inline-block;\n\tmargin-bottom: 0\n}\n\n.navbar-form input[type=\"image\"],.navbar-form input[type=\"checkbox\"],.navbar-form input[type=\"radio\"] {\n\tmargin-top: 3px\n}\n\n.navbar-form .input-append,.navbar-form .input-prepend {\n\tmargin-top: 5px;\n\twhite-space: nowrap\n}\n\n.navbar-form .input-append input,.navbar-form .input-prepend input {\n\tmargin-top: 0\n}\n\n.navbar-search {\n\tposition: relative;\n\tfloat: left;\n\tmargin-top: 5px;\n\tmargin-bottom: 0\n}\n\n.navbar-search .search-query {\n\tpadding: 4px 14px;\n\tmargin-bottom: 0;\n\tfont-family: \"Helvetica Neue\",Helvetica,Arial,sans-serif;\n\tfont-size: 13px;\n\tfont-weight: normal;\n\tline-height: 1;\n\t-webkit-border-radius: 15px;\n\t-moz-border-radius: 15px;\n\tborder-radius: 15px\n}\n\n.navbar-static-top {\n\tposition: static;\n\tmargin-bottom: 0\n}\n\n.navbar-static-top .navbar-inner {\n\t-webkit-border-radius: 0;\n\t-moz-border-radius: 0;\n\tborder-radius: 0\n}\n\n.navbar-fixed-top,.navbar-fixed-bottom {\n\tposition: fixed;\n\tright: 0;\n\tleft: 0;\n\tz-index: 1030;\n\tmargin-bottom: 0\n}\n\n.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner {\n\tborder-width: 0 0 1px\n}\n\n.navbar-fixed-bottom .navbar-inner {\n\tborder-width: 1px 0 0\n}\n\n.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner {\n\tpadding-right: 0;\n\tpadding-left: 0;\n\t-webkit-border-radius: 0;\n\t-moz-border-radius: 0;\n\tborder-radius: 0\n}\n\n.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container {\n\twidth: 940px\n}\n\n.navbar-fixed-top {\n\ttop: 0\n}\n\n.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner {\n\t-webkit-box-shadow: 0 1px 10px rgba(0,0,0,0.1);\n\t-moz-box-shadow: 0 1px 10px rgba(0,0,0,0.1);\n\tbox-shadow: 0 1px 10px rgba(0,0,0,0.1)\n}\n\n.navbar-fixed-bottom {\n\tbottom: 0\n}\n\n.navbar-fixed-bottom .navbar-inner {\n\t-webkit-box-shadow: 0 -1px 10px rgba(0,0,0,0.1);\n\t-moz-box-shadow: 0 -1px 10px rgba(0,0,0,0.1);\n\tbox-shadow: 0 -1px 10px rgba(0,0,0,0.1)\n}\n\n.navbar .nav {\n\tposition: relative;\n\tleft: 0;\n\tdisplay: block;\n\tfloat: left;\n\tmargin: 0 10px 0 0\n}\n\n.navbar .nav.pull-right {\n\tfloat: right;\n\tmargin-right: 0\n}\n\n.navbar .nav>li {\n\tfloat: left\n}\n\n.navbar .nav>li>a {\n\tfloat: none;\n\tpadding: 10px 15px 10px;\n\tcolor: #777;\n\ttext-decoration: none;\n\ttext-shadow: 0 1px 0 #fff\n}\n\n.navbar .nav .dropdown-toggle .caret {\n\tmargin-top: 8px\n}\n\n.navbar .nav>li>a:focus,.navbar .nav>li>a:hover {\n\tcolor: #333;\n\ttext-decoration: none;\n\tbackground-color: transparent\n}\n\n.navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus {\n\tcolor: #555;\n\ttext-decoration: none;\n\tbackground-color: #e5e5e5;\n\t-webkit-box-shadow: inset 0 3px 8px rgba(0,0,0,0.125);\n\t-moz-box-shadow: inset 0 3px 8px rgba(0,0,0,0.125);\n\tbox-shadow: inset 0 3px 8px rgba(0,0,0,0.125)\n}\n\n.navbar .btn-navbar {\n\tdisplay: none;\n\tfloat: right;\n\tpadding: 7px 10px;\n\tmargin-right: 5px;\n\tmargin-left: 5px;\n\tcolor: #fff;\n\ttext-shadow: 0 -1px 0 rgba(0,0,0,0.25);\n\tbackground-color: #ededed;\n\t*background-color: #e5e5e5;\n\tbackground-image: -moz-linear-gradient(top,#f2f2f2,#e5e5e5);\n\tbackground-image: -webkit-gradient(linear,0 0,0 100%,from(#f2f2f2),to(#e5e5e5));\n\tbackground-image: -webkit-linear-gradient(top,#f2f2f2,#e5e5e5);\n\tbackground-image: -o-linear-gradient(top,#f2f2f2,#e5e5e5);\n\tbackground-image: linear-gradient(to bottom,#f2f2f2,#e5e5e5);\n\tbackground-repeat: repeat-x;\n\tborder-color: #e5e5e5 #e5e5e5 #bfbfbf;\n\tborder-color: rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);\n\tfilter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2',endColorstr='#ffe5e5e5',GradientType=0);\n\tfilter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n\t-webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);\n\t-moz-box-shadow: inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);\n\tbox-shadow: inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075)\n}\n\n.navbar .btn-navbar:hover,.navbar .btn-navbar:focus,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled] {\n\tcolor: #fff;\n\tbackground-color: #e5e5e5;\n\t*background-color: #d9d9d9\n}\n\n.navbar .btn-navbar:active,.navbar .btn-navbar.active {\n\tbackground-color: #ccc \\9\n}\n\n.navbar .btn-navbar .icon-bar {\n\tdisplay: block;\n\twidth: 18px;\n\theight: 2px;\n\tbackground-color: #f5f5f5;\n\t-webkit-border-radius: 1px;\n\t-moz-border-radius: 1px;\n\tborder-radius: 1px;\n\t-webkit-box-shadow: 0 1px 0 rgba(0,0,0,0.25);\n\t-moz-box-shadow: 0 1px 0 rgba(0,0,0,0.25);\n\tbox-shadow: 0 1px 0 rgba(0,0,0,0.25)\n}\n\n.btn-navbar .icon-bar+.icon-bar {\n\tmargin-top: 3px\n}\n\n.navbar .nav>li>.dropdown-menu:before {\n\tposition: absolute;\n\ttop: -7px;\n\tleft: 9px;\n\tdisplay: inline-block;\n\tborder-right: 7px solid transparent;\n\tborder-bottom: 7px solid #ccc;\n\tborder-left: 7px solid transparent;\n\tborder-bottom-color: rgba(0,0,0,0.2);\n\tcontent: ''\n}\n\n.navbar .nav>li>.dropdown-menu:after {\n\tposition: absolute;\n\ttop: -6px;\n\tleft: 10px;\n\tdisplay: inline-block;\n\tborder-right: 6px solid transparent;\n\tborder-bottom: 6px solid #fff;\n\tborder-left: 6px solid transparent;\n\tcontent: ''\n}\n\n.navbar-fixed-bottom .nav>li>.dropdown-menu:before {\n\ttop: auto;\n\tbottom: -7px;\n\tborder-top: 7px solid #ccc;\n\tborder-bottom: 0;\n\tborder-top-color: rgba(0,0,0,0.2)\n}\n\n.navbar-fixed-bottom .nav>li>.dropdown-menu:after {\n\ttop: auto;\n\tbottom: -6px;\n\tborder-top: 6px solid #fff;\n\tborder-bottom: 0\n}\n\n.navbar .nav li.dropdown>a:hover .caret,.navbar .nav li.dropdown>a:focus .caret {\n\tborder-top-color: #333;\n\tborder-bottom-color: #333\n}\n\n.navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle {\n\tcolor: #555;\n\tbackground-color: #e5e5e5\n}\n\n.navbar .nav li.dropdown>.dropdown-toggle .caret {\n\tborder-top-color: #777;\n\tborder-bottom-color: #777\n}\n\n.navbar .nav li.dropdown.open>.dropdown-toggle .caret,.navbar .nav li.dropdown.active>.dropdown-toggle .caret,.navbar .nav li.dropdown.open.active>.dropdown-toggle .caret {\n\tborder-top-color: #555;\n\tborder-bottom-color: #555\n}\n\n.navbar .pull-right>li>.dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right {\n\tright: 0;\n\tleft: auto\n}\n\n.navbar .pull-right>li>.dropdown-menu:before,.navbar .nav>li>.dropdown-menu.pull-right:before {\n\tright: 12px;\n\tleft: auto\n}\n\n.navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after {\n\tright: 13px;\n\tleft: auto\n}\n\n.navbar .pull-right>li>.dropdown-menu .dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right .dropdown-menu {\n\tright: 100%;\n\tleft: auto;\n\tmargin-right: -1px;\n\tmargin-left: 0;\n\t-webkit-border-radius: 6px 0 6px 6px;\n\t-moz-border-radius: 6px 0 6px 6px;\n\tborder-radius: 6px 0 6px 6px\n}\n\n.navbar-inverse .navbar-inner {\n\tbackground-color: #1b1b1b;\n\tbackground-image: -moz-linear-gradient(top,#222,#111);\n\tbackground-image: -webkit-gradient(linear,0 0,0 100%,from(#222),to(#111));\n\tbackground-image: -webkit-linear-gradient(top,#222,#111);\n\tbackground-image: -o-linear-gradient(top,#222,#111);\n\tbackground-image: linear-gradient(to bottom,#222,#111);\n\tbackground-repeat: repeat-x;\n\tborder-color: #252525;\n\tfilter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222',endColorstr='#ff111111',GradientType=0)\n}\n\n.navbar-inverse .brand,.navbar-inverse .nav>li>a {\n\tcolor: #999;\n\ttext-shadow: 0 -1px 0 rgba(0,0,0,0.25)\n}\n\n.navbar-inverse .brand:hover,.navbar-inverse .nav>li>a:hover,.navbar-inverse .brand:focus,.navbar-inverse .nav>li>a:focus {\n\tcolor: #fff\n}\n\n.navbar-inverse .brand {\n\tcolor: #999\n}\n\n.navbar-inverse .navbar-text {\n\tcolor: #999\n}\n\n.navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover {\n\tcolor: #fff;\n\tbackground-color: transparent\n}\n\n.navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus {\n\tcolor: #fff;\n\tbackground-color: #111\n}\n\n.navbar-inverse .navbar-link {\n\tcolor: #999\n}\n\n.navbar-inverse .navbar-link:hover,.navbar-inverse .navbar-link:focus {\n\tcolor: #fff\n}\n\n.navbar-inverse .divider-vertical {\n\tborder-right-color: #222;\n\tborder-left-color: #111\n}\n\n.navbar-inverse .nav li.dropdown.open>.dropdown-toggle,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle {\n\tcolor: #fff;\n\tbackground-color: #111\n}\n\n.navbar-inverse .nav li.dropdown>a:hover .caret,.navbar-inverse .nav li.dropdown>a:focus .caret {\n\tborder-top-color: #fff;\n\tborder-bottom-color: #fff\n}\n\n.navbar-inverse .nav li.dropdown>.dropdown-toggle .caret {\n\tborder-top-color: #999;\n\tborder-bottom-color: #999\n}\n\n.navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle .caret {\n\tborder-top-color: #fff;\n\tborder-bottom-color: #fff\n}\n\n.navbar-inverse .navbar-search .search-query {\n\tcolor: #fff;\n\tbackground-color: #515151;\n\tborder-color: #111;\n\t-webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);\n\t-moz-box-shadow: inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);\n\tbox-shadow: inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);\n\t-webkit-transition: none;\n\t-moz-transition: none;\n\t-o-transition: none;\n\ttransition: none\n}\n\n.navbar-inverse .navbar-search .search-query:-moz-placeholder {\n\tcolor: #ccc\n}\n\n.navbar-inverse .navbar-search .search-query:-ms-input-placeholder {\n\tcolor: #ccc\n}\n\n.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder {\n\tcolor: #ccc\n}\n\n.navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused {\n\tpadding: 5px 15px;\n\tcolor: #333;\n\ttext-shadow: 0 1px 0 #fff;\n\tbackground-color: #fff;\n\tborder: 0;\n\toutline: 0;\n\t-webkit-box-shadow: 0 0 3px rgba(0,0,0,0.15);\n\t-moz-box-shadow: 0 0 3px rgba(0,0,0,0.15);\n\tbox-shadow: 0 0 3px rgba(0,0,0,0.15)\n}\n\n.navbar-inverse .btn-navbar {\n\tcolor: #fff;\n\ttext-shadow: 0 -1px 0 rgba(0,0,0,0.25);\n\tbackground-color: #0e0e0e;\n\t*background-color: #040404;\n\tbackground-image: -moz-linear-gradient(top,#151515,#040404);\n\tbackground-image: -webkit-gradient(linear,0 0,0 100%,from(#151515),to(#040404));\n\tbackground-image: -webkit-linear-gradient(top,#151515,#040404);\n\tbackground-image: -o-linear-gradient(top,#151515,#040404);\n\tbackground-image: linear-gradient(to bottom,#151515,#040404);\n\tbackground-repeat: repeat-x;\n\tborder-color: #040404 #040404 #000;\n\tborder-color: rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);\n\tfilter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515',endColorstr='#ff040404',GradientType=0);\n\tfilter: progid:DXImageTransform.Microsoft.gradient(enabled=false)\n}\n\n.navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:focus,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled] {\n\tcolor: #fff;\n\tbackground-color: #040404;\n\t*background-color: #000\n}\n\n.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active {\n\tbackground-color: #000 \\9\n}\n\n.breadcrumb {\n\tbackground-color: #f5f5f5;\n\tmargin: 0 0 20px;\n\tlist-style: none;\n\t-webkit-border-radius: 4px;\n\t-moz-border-radius: 4px;\n\tborder-radius: 4px\n}\n\n.breadcrumb>li {\n\tdisplay: inline-block;\n\t*display: inline;\n\ttext-shadow: 0 1px 0 #fff;\n\t*zoom: 1\n}\n\n.breadcrumb>li>.divider {\n\tpadding: 0 5px;\n\tcolor: #ccc\n}\n\n.breadcrumb>.active {\n\tcolor: #999\n}\n\n.pagination {\n\tmargin: 20px 0\n}\n\n.pagination ul {\n\tdisplay: inline-block;\n\t*display: inline;\n\tmargin-bottom: 0;\n\tmargin-left: 0;\n\t-webkit-border-radius: 4px;\n\t-moz-border-radius: 4px;\n\tborder-radius: 4px;\n\t*zoom: 1;\n\t-webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.05);\n\t-moz-box-shadow: 0 1px 2px rgba(0,0,0,0.05);\n\tbox-shadow: 0 1px 2px rgba(0,0,0,0.05)\n}\n\n.pagination ul>li {\n\tdisplay: inline\n}\n\n.pagination ul>li>a,.pagination ul>li>span {\n\tfloat: left;\n\tpadding: 4px 12px;\n\tline-height: 20px;\n\ttext-decoration: none;\n\tbackground-color: #fff;\n\tborder: 1px solid #ddd;\n\tborder-left-width: 0\n}\n\n.pagination ul>li>a:hover,.pagination ul>li>a:focus,.pagination ul>.active>a,.pagination ul>.active>span {\n\tbackground-color: #f5f5f5\n}\n\n.pagination ul>.active>a,.pagination ul>.active>span {\n\tcolor: #999;\n\tcursor: default\n}\n\n.pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover,.pagination ul>.disabled>a:focus {\n\tcolor: #999;\n\tcursor: default;\n\tbackground-color: transparent\n}\n\n.pagination ul>li:first-child>a,.pagination ul>li:first-child>span {\n\tborder-left-width: 1px;\n\t-webkit-border-bottom-left-radius: 4px;\n\tborder-bottom-left-radius: 4px;\n\t-webkit-border-top-left-radius: 4px;\n\tborder-top-left-radius: 4px;\n\t-moz-border-radius-bottomleft: 4px;\n\t-moz-border-radius-topleft: 4px\n}\n\n.pagination ul>li:last-child>a,.pagination ul>li:last-child>span {\n\t-webkit-border-top-right-radius: 4px;\n\tborder-top-right-radius: 4px;\n\t-webkit-border-bottom-right-radius: 4px;\n\tborder-bottom-right-radius: 4px;\n\t-moz-border-radius-topright: 4px;\n\t-moz-border-radius-bottomright: 4px\n}\n\n.pagination-centered {\n\ttext-align: center\n}\n\n.pagination-right {\n\ttext-align: right\n}\n\n.pagination-large ul>li>a,.pagination-large ul>li>span {\n\tpadding: 11px 19px;\n\tfont-size: 17.5px\n}\n\n.pagination-large ul>li:first-child>a,.pagination-large ul>li:first-child>span {\n\t-webkit-border-bottom-left-radius: 6px;\n\tborder-bottom-left-radius: 6px;\n\t-webkit-border-top-left-radius: 6px;\n\tborder-top-left-radius: 6px;\n\t-moz-border-radius-bottomleft: 6px;\n\t-moz-border-radius-topleft: 6px\n}\n\n.pagination-large ul>li:last-child>a,.pagination-large ul>li:last-child>span {\n\t-webkit-border-top-right-radius: 6px;\n\tborder-top-right-radius: 6px;\n\t-webkit-border-bottom-right-radius: 6px;\n\tborder-bottom-right-radius: 6px;\n\t-moz-border-radius-topright: 6px;\n\t-moz-border-radius-bottomright: 6px\n}\n\n.pagination-mini ul>li:first-child>a,.pagination-small ul>li:first-child>a,.pagination-mini ul>li:first-child>span,.pagination-small ul>li:first-child>span {\n\t-webkit-border-bottom-left-radius: 3px;\n\tborder-bottom-left-radius: 3px;\n\t-webkit-border-top-left-radius: 3px;\n\tborder-top-left-radius: 3px;\n\t-moz-border-radius-bottomleft: 3px;\n\t-moz-border-radius-topleft: 3px\n}\n\n.pagination-mini ul>li:last-child>a,.pagination-small ul>li:last-child>a,.pagination-mini ul>li:last-child>span,.pagination-small ul>li:last-child>span {\n\t-webkit-border-top-right-radius: 3px;\n\tborder-top-right-radius: 3px;\n\t-webkit-border-bottom-right-radius: 3px;\n\tborder-bottom-right-radius: 3px;\n\t-moz-border-radius-topright: 3px;\n\t-moz-border-radius-bottomright: 3px\n}\n\n.pagination-small ul>li>a,.pagination-small ul>li>span {\n\tpadding: 2px 10px;\n\tfont-size: 11.9px\n}\n\n.pagination-mini ul>li>a,.pagination-mini ul>li>span {\n\tpadding: 0 6px;\n\tfont-size: 10.5px\n}\n\n.pager {\n\tmargin: 20px 0;\n\ttext-align: center;\n\tlist-style: none;\n\t*zoom: 1\n}\n\n.pager:before,.pager:after {\n\tdisplay: table;\n\tline-height: 0;\n\tcontent: \"\"\n}\n\n.pager:after {\n\tclear: both\n}\n\n.pager li {\n\tdisplay: inline\n}\n\n.pager li>a,.pager li>span {\n\tdisplay: inline-block;\n\tpadding: 5px 14px;\n\tbackground-color: #fff;\n\tborder: 1px solid #ddd;\n\t-webkit-border-radius: 15px;\n\t-moz-border-radius: 15px;\n\tborder-radius: 15px\n}\n\n.pager li>a:hover,.pager li>a:focus {\n\ttext-decoration: none;\n\tbackground-color: #f5f5f5\n}\n\n.pager .next>a,.pager .next>span {\n\tfloat: right\n}\n\n.pager .previous>a,.pager .previous>span {\n\tfloat: left\n}\n\n.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span {\n\tcolor: #999;\n\tcursor: default;\n\tbackground-color: #fff\n}\n\n.modal-backdrop {\n\tposition: fixed;\n\ttop: 0;\n\tright: 0;\n\tbottom: 0;\n\tleft: 0;\n\tz-index: 1040;\n\tbackground-color: #000\n}\n\n.modal-backdrop.fade {\n\topacity: 0\n}\n\n.modal-backdrop,.modal-backdrop.fade.in {\n\topacity: .8;\n\tfilter: alpha(opacity=80)\n}\n\n.modal {\n\tposition: absolute;\n\ttop: 10%;\n\tleft: 15%;\n\tright: 15%;\n\tmargin: auto;\n\tz-index: 1050;\n\twidth: 560px;\n\tbackground-color: #fff;\n\tborder: 1px solid #999;\n\tborder: 1px solid rgba(0,0,0,0.3);\n\t*border: 1px solid #999;\n\t-webkit-border-radius: 6px;\n\t-moz-border-radius: 6px;\n\tborder-radius: 6px;\n\toutline: 0;\n\t-webkit-box-shadow: 0 3px 7px rgba(0,0,0,0.3);\n\t-moz-box-shadow: 0 3px 7px rgba(0,0,0,0.3);\n\tbox-shadow: 0 3px 7px rgba(0,0,0,0.3);\n\t-webkit-background-clip: padding-box;\n\t-moz-background-clip: padding-box;\n\tbackground-clip: padding-box\n}\n\n.modal.fade {\n\ttop: -25%;\n\t-webkit-transition: opacity .3s linear,top .3s ease-out;\n\t-moz-transition: opacity .3s linear,top .3s ease-out;\n\t-o-transition: opacity .3s linear,top .3s ease-out;\n\ttransition: opacity .3s linear,top .3s ease-out\n}\n\n.modal.fade.in {\n\ttop: 10%\n}\n\n.modal-header {\n\tpadding: 9px 15px;\n\tborder-bottom: 1px solid #eee\n}\n\n.modal-header .close {\n\tmargin-top: 2px\n}\n\n.modal-header h3 {\n\tmargin: 0;\n\tline-height: 30px\n}\n\n.modal-body {\n\tposition: relative;\n\tpadding: 15px;\n\toverflow: auto\n}\n\n.modal-form {\n\tmargin-bottom: 0\n}\n\n.modal-footer {\n\tpadding: 14px 15px 15px;\n\tmargin-bottom: 0;\n\ttext-align: right;\n\tbackground-color: #f5f5f5;\n\tborder-top: 1px solid #ddd;\n\t-webkit-border-radius: 0 0 6px 6px;\n\t-moz-border-radius: 0 0 6px 6px;\n\tborder-radius: 0 0 6px 6px;\n\t*zoom: 1;\n\t-webkit-box-shadow: inset 0 1px 0 #fff;\n\t-moz-box-shadow: inset 0 1px 0 #fff;\n\tbox-shadow: inset 0 1px 0 #fff\n}\n\n.modal-footer:before,.modal-footer:after {\n\tdisplay: table;\n\tline-height: 0;\n\tcontent: \"\"\n}\n\n.modal-footer:after {\n\tclear: both\n}\n\n.modal-footer .btn+.btn {\n\tmargin-bottom: 0;\n\tmargin-left: 5px\n}\n\n.modal-footer .btn-group .btn+.btn {\n\tmargin-left: -1px\n}\n\n.modal-footer .btn-block+.btn-block {\n\tmargin-left: 0\n}\n\n.tooltip {\n\tposition: absolute;\n\tz-index: 1030;\n\tdisplay: block;\n\tfont-size: 11px;\n\tline-height: 1.4;\n\topacity: 0;\n\tfilter: alpha(opacity=0);\n\tvisibility: visible\n}\n\n.tooltip.in {\n\topacity: .8;\n\tfilter: alpha(opacity=80)\n}\n\n.tooltip.top {\n\tpadding: 5px 0;\n\tmargin-top: -3px\n}\n\n.tooltip.right {\n\tpadding: 0 5px;\n\tmargin-left: 3px\n}\n\n.tooltip.bottom {\n\tpadding: 5px 0;\n\tmargin-top: 3px\n}\n\n.tooltip.left {\n\tpadding: 0 5px;\n\tmargin-left: -3px\n}\n\n.tooltip-inner {\n\tmax-width: 200px;\n\tpadding: 8px;\n\tcolor: #fff;\n\ttext-align: center;\n\ttext-decoration: none;\n\tbackground-color: #000;\n\t-webkit-border-radius: 4px;\n\t-moz-border-radius: 4px;\n\tborder-radius: 4px\n}\n\n.tooltip-arrow {\n\tposition: absolute;\n\twidth: 0;\n\theight: 0;\n\tborder-color: transparent;\n\tborder-style: solid\n}\n\n.tooltip.top .tooltip-arrow {\n\tbottom: 0;\n\tleft: 50%;\n\tmargin-left: -5px;\n\tborder-top-color: #000;\n\tborder-width: 5px 5px 0\n}\n\n.tooltip.right .tooltip-arrow {\n\ttop: 50%;\n\tleft: 0;\n\tmargin-top: -5px;\n\tborder-right-color: #000;\n\tborder-width: 5px 5px 5px 0\n}\n\n.tooltip.left .tooltip-arrow {\n\ttop: 50%;\n\tright: 0;\n\tmargin-top: -5px;\n\tborder-left-color: #000;\n\tborder-width: 5px 0 5px 5px\n}\n\n.tooltip.bottom .tooltip-arrow {\n\ttop: 0;\n\tleft: 50%;\n\tmargin-left: -5px;\n\tborder-bottom-color: #000;\n\tborder-width: 0 5px 5px\n}\n\n.popover {\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tz-index: 1010;\n\tdisplay: none;\n\tmax-width: 276px;\n\tpadding: 1px;\n\ttext-align: left;\n\twhite-space: normal;\n\tbackground-color: #fff;\n\tborder: 1px solid #ccc;\n\tborder: 1px solid rgba(0,0,0,0.2);\n\t-webkit-border-radius: 6px;\n\t-moz-border-radius: 6px;\n\tborder-radius: 6px;\n\t-webkit-box-shadow: 0 5px 10px rgba(0,0,0,0.2);\n\t-moz-box-shadow: 0 5px 10px rgba(0,0,0,0.2);\n\tbox-shadow: 0 5px 10px rgba(0,0,0,0.2);\n\t-webkit-background-clip: padding-box;\n\t-moz-background-clip: padding;\n\tbackground-clip: padding-box\n}\n\n.popover.top {\n\tmargin-top: -10px\n}\n\n.popover.right {\n\tmargin-left: 10px\n}\n\n.popover.bottom {\n\tmargin-top: 10px\n}\n\n.popover.left {\n\tmargin-left: -10px\n}\n\n.popover-title {\n\tpadding: 8px 14px;\n\tmargin: 0;\n\tfont-size: 14px;\n\tfont-weight: normal;\n\tline-height: 18px;\n\tbackground-color: #f7f7f7;\n\tborder-bottom: 1px solid #ebebeb;\n\t-webkit-border-radius: 5px 5px 0 0;\n\t-moz-border-radius: 5px 5px 0 0;\n\tborder-radius: 5px 5px 0 0\n}\n\n.popover-title:empty {\n\tdisplay: none\n}\n\n.popover-content {\n\tpadding: 9px 14px\n}\n\n.popover .arrow,.popover .arrow:after {\n\tposition: absolute;\n\tdisplay: block;\n\twidth: 0;\n\theight: 0;\n\tborder-color: transparent;\n\tborder-style: solid\n}\n\n.popover .arrow {\n\tborder-width: 11px\n}\n\n.popover .arrow:after {\n\tborder-width: 10px;\n\tcontent: \"\"\n}\n\n.popover.top .arrow {\n\tbottom: -11px;\n\tleft: 50%;\n\tmargin-left: -11px;\n\tborder-top-color: #999;\n\tborder-top-color: rgba(0,0,0,0.25);\n\tborder-bottom-width: 0\n}\n\n.popover.top .arrow:after {\n\tbottom: 1px;\n\tmargin-left: -10px;\n\tborder-top-color: #fff;\n\tborder-bottom-width: 0\n}\n\n.popover.right .arrow {\n\ttop: 50%;\n\tleft: -11px;\n\tmargin-top: -11px;\n\tborder-right-color: #999;\n\tborder-right-color: rgba(0,0,0,0.25);\n\tborder-left-width: 0\n}\n\n.popover.right .arrow:after {\n\tbottom: -10px;\n\tleft: 1px;\n\tborder-right-color: #fff;\n\tborder-left-width: 0\n}\n\n.popover.bottom .arrow {\n\ttop: -11px;\n\tleft: 50%;\n\tmargin-left: -11px;\n\tborder-bottom-color: #999;\n\tborder-bottom-color: rgba(0,0,0,0.25);\n\tborder-top-width: 0\n}\n\n.popover.bottom .arrow:after {\n\ttop: 1px;\n\tmargin-left: -10px;\n\tborder-bottom-color: #fff;\n\tborder-top-width: 0\n}\n\n.popover.left .arrow {\n\ttop: 50%;\n\tright: -11px;\n\tmargin-top: -11px;\n\tborder-left-color: #999;\n\tborder-left-color: rgba(0,0,0,0.25);\n\tborder-right-width: 0\n}\n\n.popover.left .arrow:after {\n\tright: 1px;\n\tbottom: -10px;\n\tborder-left-color: #fff;\n\tborder-right-width: 0\n}\n\n.thumbnails {\n\tmargin-left: -20px;\n\tlist-style: none;\n\t*zoom: 1\n}\n\n.thumbnails:before,.thumbnails:after {\n\tdisplay: table;\n\tline-height: 0;\n\tcontent: \"\"\n}\n\n.thumbnails:after {\n\tclear: both\n}\n\n.row-fluid .thumbnails {\n\tmargin-left: 0\n}\n\n.thumbnails>li {\n\tfloat: left;\n\tmargin-bottom: 20px;\n\tmargin-left: 20px\n}\n\n.thumbnail {\n\tdisplay: block;\n\tpadding: 4px;\n\tline-height: 20px;\n\tborder: 1px solid #ddd;\n\t-webkit-border-radius: 4px;\n\t-moz-border-radius: 4px;\n\tborder-radius: 4px;\n\t-webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.055);\n\t-moz-box-shadow: 0 1px 3px rgba(0,0,0,0.055);\n\tbox-shadow: 0 1px 3px rgba(0,0,0,0.055);\n\t-webkit-transition: all .2s ease-in-out;\n\t-moz-transition: all .2s ease-in-out;\n\t-o-transition: all .2s ease-in-out;\n\ttransition: all .2s ease-in-out\n}\n\na.thumbnail:hover,a.thumbnail:focus {\n\tborder-color: #08c;\n\t-webkit-box-shadow: 0 1px 4px rgba(0,105,214,0.25);\n\t-moz-box-shadow: 0 1px 4px rgba(0,105,214,0.25);\n\tbox-shadow: 0 1px 4px rgba(0,105,214,0.25)\n}\n\n.thumbnail>img {\n\tdisplay: block;\n\tmax-width: 100%;\n\tmargin-right: auto;\n\tmargin-left: auto\n}\n\n.thumbnail .caption {\n\tpadding: 9px;\n\tcolor: #555\n}\n\n.media,.media-body {\n\toverflow: hidden;\n\t*overflow: visible;\n\tzoom: 1\n}\n\n.media,.media .media {\n\tmargin-top: 15px\n}\n\n.media:first-child {\n\tmargin-top: 0\n}\n\n.media-object {\n\tdisplay: block\n}\n\n.media-heading {\n\tmargin: 0 0 5px\n}\n\n.media>.pull-left {\n\tmargin-right: 10px\n}\n\n.media>.pull-right {\n\tmargin-left: 10px\n}\n\n.media-list {\n\tmargin-left: 0;\n\tlist-style: none\n}\n\n.label,.badge {\n\tdisplay: inline-block;\n\tpadding: 2px 4px;\n\tfont-size: 11.844px;\n\tfont-weight: bold;\n\tline-height: 14px;\n\tcolor: #fff;\n\ttext-shadow: 0 -1px 0 rgba(0,0,0,0.25);\n\twhite-space: nowrap;\n\tvertical-align: baseline;\n\tbackground-color: #999\n}\n\n.label {\n\t-webkit-border-radius: 3px;\n\t-moz-border-radius: 3px;\n\tborder-radius: 3px\n}\n\n.badge {\n\tpadding-right: 9px;\n\tpadding-left: 9px;\n\t-webkit-border-radius: 9px;\n\t-moz-border-radius: 9px;\n\tborder-radius: 9px\n}\n\n.label:empty,.badge:empty {\n\tdisplay: none\n}\n\na.label:hover,a.label:focus,a.badge:hover,a.badge:focus {\n\tcolor: #fff;\n\ttext-decoration: none;\n\tcursor: pointer\n}\n\n.label-important,.badge-important {\n\tbackground-color: #b94a48\n}\n\n.label-important[href],.badge-important[href] {\n\tbackground-color: #953b39\n}\n\n.label-warning,.badge-warning {\n\tbackground-color: #f89406\n}\n\n.label-warning[href],.badge-warning[href] {\n\tbackground-color: #c67605\n}\n\n.label-success,.badge-success {\n\tbackground-color: #468847\n}\n\n.label-success[href],.badge-success[href] {\n\tbackground-color: #356635\n}\n\n.label-info,.badge-info {\n\tbackground-color: #3a87ad\n}\n\n.label-info[href],.badge-info[href] {\n\tbackground-color: #2d6987\n}\n\n.label-inverse,.badge-inverse {\n\tbackground-color: #333\n}\n\n.label-inverse[href],.badge-inverse[href] {\n\tbackground-color: #1a1a1a\n}\n\n.btn .label,.btn .badge {\n\tposition: relative;\n\ttop: -1px\n}\n\n.btn-mini .label,.btn-mini .badge {\n\ttop: 0\n}\n\n@-webkit-keyframes progress-bar-stripes {\n\tfrom {\n\t\tbackground-position: 40px 0\n\t}\n\n\tto {\n\t\tbackground-position: 0 0\n\t}\n}\n\n@-moz-keyframes progress-bar-stripes {\n\tfrom {\n\t\tbackground-position: 40px 0\n\t}\n\n\tto {\n\t\tbackground-position: 0 0\n\t}\n}\n\n@-ms-keyframes progress-bar-stripes {\n\tfrom {\n\t\tbackground-position: 40px 0\n\t}\n\n\tto {\n\t\tbackground-position: 0 0\n\t}\n}\n\n@-o-keyframes progress-bar-stripes {\n\tfrom {\n\t\tbackground-position: 0 0\n\t}\n\n\tto {\n\t\tbackground-position: 40px 0\n\t}\n}\n\n@keyframes progress-bar-stripes {\n\tfrom {\n\t\tbackground-position: 40px 0\n\t}\n\n\tto {\n\t\tbackground-position: 0 0\n\t}\n}\n\n.progress {\n\theight: 20px;\n\tmargin-bottom: 20px;\n\toverflow: hidden;\n\tbackground-color: #f7f7f7;\n\tbackground-image: -moz-linear-gradient(top,#f5f5f5,#f9f9f9);\n\tbackground-image: -webkit-gradient(linear,0 0,0 100%,from(#f5f5f5),to(#f9f9f9));\n\tbackground-image: -webkit-linear-gradient(top,#f5f5f5,#f9f9f9);\n\tbackground-image: -o-linear-gradient(top,#f5f5f5,#f9f9f9);\n\tbackground-image: linear-gradient(to bottom,#f5f5f5,#f9f9f9);\n\tbackground-repeat: repeat-x;\n\t-webkit-border-radius: 4px;\n\t-moz-border-radius: 4px;\n\tborder-radius: 4px;\n\tfilter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#fff9f9f9',GradientType=0);\n\t-webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,0.1);\n\t-moz-box-shadow: inset 0 1px 2px rgba(0,0,0,0.1);\n\tbox-shadow: inset 0 1px 2px rgba(0,0,0,0.1)\n}\n\n.progress .bar {\n\tfloat: left;\n\twidth: 0;\n\theight: 100%;\n\tfont-size: 12px;\n\tcolor: #fff;\n\ttext-align: center;\n\ttext-shadow: 0 -1px 0 rgba(0,0,0,0.25);\n\tbackground-color: #0e90d2;\n\tbackground-image: -moz-linear-gradient(top,#149bdf,#0480be);\n\tbackground-image: -webkit-gradient(linear,0 0,0 100%,from(#149bdf),to(#0480be));\n\tbackground-image: -webkit-linear-gradient(top,#149bdf,#0480be);\n\tbackground-image: -o-linear-gradient(top,#149bdf,#0480be);\n\tbackground-image: linear-gradient(to bottom,#149bdf,#0480be);\n\tbackground-repeat: repeat-x;\n\tfilter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf',endColorstr='#ff0480be',GradientType=0);\n\t-webkit-box-shadow: inset 0 -1px 0 rgba(0,0,0,0.15);\n\t-moz-box-shadow: inset 0 -1px 0 rgba(0,0,0,0.15);\n\tbox-shadow: inset 0 -1px 0 rgba(0,0,0,0.15);\n\t-webkit-box-sizing: border-box;\n\t-moz-box-sizing: border-box;\n\tbox-sizing: border-box;\n\t-webkit-transition: width .6s ease;\n\t-moz-transition: width .6s ease;\n\t-o-transition: width .6s ease;\n\ttransition: width .6s ease\n}\n\n.progress .bar+.bar {\n\t-webkit-box-shadow: inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);\n\t-moz-box-shadow: inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);\n\tbox-shadow: inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15)\n}\n\n.progress-striped .bar {\n\tbackground-color: #149bdf;\n\tbackground-image: -webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));\n\tbackground-image: -webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);\n\tbackground-image: -moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);\n\tbackground-image: -o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);\n\tbackground-image: linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);\n\t-webkit-background-size: 40px 40px;\n\t-moz-background-size: 40px 40px;\n\t-o-background-size: 40px 40px;\n\tbackground-size: 40px 40px\n}\n\n.progress.active .bar {\n\t-webkit-animation: progress-bar-stripes 2s linear infinite;\n\t-moz-animation: progress-bar-stripes 2s linear infinite;\n\t-ms-animation: progress-bar-stripes 2s linear infinite;\n\t-o-animation: progress-bar-stripes 2s linear infinite;\n\tanimation: progress-bar-stripes 2s linear infinite\n}\n\n.progress-danger .bar,.progress .bar-danger {\n\tbackground-color: #dd514c;\n\tbackground-image: -moz-linear-gradient(top,#ee5f5b,#c43c35);\n\tbackground-image: -webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#c43c35));\n\tbackground-image: -webkit-linear-gradient(top,#ee5f5b,#c43c35);\n\tbackground-image: -o-linear-gradient(top,#ee5f5b,#c43c35);\n\tbackground-image: linear-gradient(to bottom,#ee5f5b,#c43c35);\n\tbackground-repeat: repeat-x;\n\tfilter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffc43c35',GradientType=0)\n}\n\n.progress-danger.progress-striped .bar,.progress-striped .bar-danger {\n\tbackground-color: #ee5f5b;\n\tbackground-image: -webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));\n\tbackground-image: -webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);\n\tbackground-image: -moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);\n\tbackground-image: -o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);\n\tbackground-image: linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)\n}\n\n.progress-success .bar,.progress .bar-success {\n\tbackground-color: #5eb95e;\n\tbackground-image: -moz-linear-gradient(top,#62c462,#57a957);\n\tbackground-image: -webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#57a957));\n\tbackground-image: -webkit-linear-gradient(top,#62c462,#57a957);\n\tbackground-image: -o-linear-gradient(top,#62c462,#57a957);\n\tbackground-image: linear-gradient(to bottom,#62c462,#57a957);\n\tbackground-repeat: repeat-x;\n\tfilter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff57a957',GradientType=0)\n}\n\n.progress-success.progress-striped .bar,.progress-striped .bar-success {\n\tbackground-color: #62c462;\n\tbackground-image: -webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));\n\tbackground-image: -webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);\n\tbackground-image: -moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);\n\tbackground-image: -o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);\n\tbackground-image: linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)\n}\n\n.progress-info .bar,.progress .bar-info {\n\tbackground-color: #4bb1cf;\n\tbackground-image: -moz-linear-gradient(top,#5bc0de,#339bb9);\n\tbackground-image: -webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#339bb9));\n\tbackground-image: -webkit-linear-gradient(top,#5bc0de,#339bb9);\n\tbackground-image: -o-linear-gradient(top,#5bc0de,#339bb9);\n\tbackground-image: linear-gradient(to bottom,#5bc0de,#339bb9);\n\tbackground-repeat: repeat-x;\n\tfilter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff339bb9',GradientType=0)\n}\n\n.progress-info.progress-striped .bar,.progress-striped .bar-info {\n\tbackground-color: #5bc0de;\n\tbackground-image: -webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));\n\tbackground-image: -webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);\n\tbackground-image: -moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);\n\tbackground-image: -o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);\n\tbackground-image: linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)\n}\n\n.progress-warning .bar,.progress .bar-warning {\n\tbackground-color: #faa732;\n\tbackground-image: -moz-linear-gradient(top,#fbb450,#f89406);\n\tbackground-image: -webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));\n\tbackground-image: -webkit-linear-gradient(top,#fbb450,#f89406);\n\tbackground-image: -o-linear-gradient(top,#fbb450,#f89406);\n\tbackground-image: linear-gradient(to bottom,#fbb450,#f89406);\n\tbackground-repeat: repeat-x;\n\tfilter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0)\n}\n\n.progress-warning.progress-striped .bar,.progress-striped .bar-warning {\n\tbackground-color: #fbb450;\n\tbackground-image: -webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));\n\tbackground-image: -webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);\n\tbackground-image: -moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);\n\tbackground-image: -o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);\n\tbackground-image: linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)\n}\n\n.accordion {\n\tmargin-bottom: 20px\n}\n\n.accordion-group {\n\tmargin-bottom: 2px;\n\tborder: 1px solid #e5e5e5;\n\t-webkit-border-radius: 4px;\n\t-moz-border-radius: 4px;\n\tborder-radius: 4px\n}\n\n.accordion-heading {\n\tborder-bottom: 0\n}\n\n.accordion-heading .accordion-toggle {\n\tdisplay: block;\n\tpadding: 8px 15px\n}\n\n.accordion-toggle {\n\tcursor: pointer\n}\n\n.accordion-inner {\n\tpadding: 9px 15px;\n\tborder-top: 1px solid #e5e5e5\n}\n\n.carousel {\n\tposition: relative;\n\tline-height: 1\n}\n\n.carousel-inner {\n\tposition: relative;\n\twidth: 100%;\n\toverflow: hidden\n}\n\n.carousel-inner>.item {\n\tposition: relative;\n\tdisplay: none;\n\t-webkit-transition: .6s ease-in-out left;\n\t-moz-transition: .6s ease-in-out left;\n\t-o-transition: .6s ease-in-out left;\n\ttransition: .6s ease-in-out left\n}\n\n.carousel-inner>.item>img,.carousel-inner>.item>a>img {\n\tdisplay: block;\n\tmargin: 0 auto;\n\tline-height: 1\n}\n\n.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev {\n\tdisplay: block\n}\n\n.carousel-inner>.active {\n\tleft: 0\n}\n\n.carousel-inner>.next,.carousel-inner>.prev {\n\tposition: absolute;\n\ttop: 0;\n\twidth: 100%\n}\n\n.carousel-inner>.next {\n\tleft: 100%\n}\n\n.carousel-inner>.prev {\n\tleft: -100%\n}\n\n.carousel-inner>.next.left,.carousel-inner>.prev.right {\n\tleft: 0\n}\n\n.carousel-inner>.active.left {\n\tleft: -100%\n}\n\n.carousel-inner>.active.right {\n\tleft: 100%\n}\n\n.carousel-control {\n\tposition: absolute;\n\ttop: 40%;\n\tleft: 15px;\n\twidth: 40px;\n\theight: 40px;\n\tmargin-top: -20px;\n\tfont-size: 60px;\n\tfont-weight: 100;\n\tline-height: 30px;\n\tcolor: #fff;\n\ttext-align: center;\n\tbackground: #222;\n\tborder: 3px solid #fff;\n\t-webkit-border-radius: 23px;\n\t-moz-border-radius: 23px;\n\tborder-radius: 23px;\n\topacity: .5;\n\tfilter: alpha(opacity=50)\n}\n\n.carousel-control.right {\n\tright: 15px;\n\tleft: auto\n}\n\n.carousel-control:hover,.carousel-control:focus {\n\tcolor: #fff;\n\ttext-decoration: none;\n\topacity: .9;\n\tfilter: alpha(opacity=90)\n}\n\n.carousel-indicators {\n\tcursor: pointer;\n\tposition: absolute;\n\tbottom: 15px;\n\tright: 15px;\n\tz-index: 5;\n\tmargin: 0;\n\tlist-style: none\n}\n\n.carousel-indicators li {\n\tdisplay: block;\n\tfloat: left;\n\twidth: 10px;\n\theight: 10px;\n\tmargin-left: 5px;\n\ttext-indent: -999px;\n\tbackground-color: #ccc;\n\tbackground-color: rgba(255,255,255,0.25);\n\tborder-radius: 5px\n}\n\n.carousel-indicators .active {\n\tbackground-color: #fff\n}\n\n.carousel-caption {\n\tposition: absolute;\n\tright: 0;\n\tbottom: 0;\n\tleft: 0;\n\tpadding: 15px;\n\tbackground: #333;\n\tbackground: rgba(0,0,0,0.75)\n}\n\n.carousel-caption h4,.carousel-caption p {\n\tline-height: 20px;\n\tcolor: #fff\n}\n\n.carousel-caption h4 {\n\tmargin: 0 0 5px\n}\n\n.carousel-caption p {\n\tmargin-bottom: 0\n}\n\n.hero-unit {\n\tpadding: 35px;\n\tmargin-bottom: 30px;\n\tfont-size: 18px;\n\tfont-weight: 200;\n\tline-height: 30px;\n\tcolor: inherit;\n\tbackground-color: #eee;\n\t-webkit-border-radius: 6px;\n\t-moz-border-radius: 6px;\n\tborder-radius: 6px\n}\n\n.hero-unit h1 {\n\tmargin-top: 10px;\n\tmargin-bottom: 10px;\n\tfont-size: 45px;\n\tline-height: 1.1;\n\tletter-spacing: -1px;\n\tcolor: inherit\n}\n\n.hero-unit p {\n\tmargin-top: 5px;\n\tmargin-bottom: 5px;\n\tline-height: 1.1;\n}\n\n.hero-unit .btn {\n\tmargin-top: 10px;\n\tmargin-bottom: 0;\n}\n\n.hero-unit li {\n\tline-height: 30px\n}\n\n.pull-right {\n\tfloat: right\n}\n\n.pull-left {\n\tfloat: left\n}\n\n.hide {\n\tdisplay: none\n}\n\n.show {\n\tdisplay: block\n}\n\n.invisible {\n\tvisibility: hidden\n}\n\n.affix {\n\tposition: fixed\n}"
  },
  {
    "path": "code/default/launcher/web_ui/css/flat-ui.css",
    "content": "/*!\n * Flat UI Free v2.0.0 (http://designmodo.github.io/Flat-UI/)\n * Copyright 2013-2014 Designmodo, Inc.\n */\n .fui-arrow-right,.fui-arrow-left,.fui-cmd,.fui-check-inverted,.fui-heart,.fui-location,.fui-plus,.fui-check,.fui-cross,.fui-list,.fui-new,.fui-video,.fui-photo,.fui-volume,.fui-time,.fui-eye,.fui-chat,.fui-search,.fui-user,.fui-mail,.fui-lock,.fui-gear,.fui-radio-unchecked,.fui-radio-checked,.fui-checkbox-unchecked,.fui-checkbox-checked,.fui-calendar-solid,.fui-pause,.fui-play,.fui-check-inverted-2 {\n\tdisplay: inline-block;\n\tfont-family: 'Flat-UI-Icons';\n\tspeak: none;\n\tfont-style: normal;\n\tfont-weight: normal;\n\tfont-variant: normal;\n\ttext-transform: none;\n\t-webkit-font-smoothing: antialiased\n}\n\n.fui-arrow-right:before {\n\tcontent: \"\\e02c\"\n}\n\n.fui-arrow-left:before {\n\tcontent: \"\\e02d\"\n}\n\n.fui-cmd:before {\n\tcontent: \"\\e02f\"\n}\n\n.fui-check-inverted:before {\n\tcontent: \"\\e006\"\n}\n\n.fui-heart:before {\n\tcontent: \"\\e007\"\n}\n\n.fui-location:before {\n\tcontent: \"\\e008\"\n}\n\n.fui-plus:before {\n\tcontent: \"\\e009\"\n}\n\n.fui-check:before {\n\tcontent: \"\\e00a\"\n}\n\n.fui-cross:before {\n\tcontent: \"\\e00b\"\n}\n\n.fui-list:before {\n\tcontent: \"\\e00c\"\n}\n\n.fui-new:before {\n\tcontent: \"\\e00d\"\n}\n\n.fui-video:before {\n\tcontent: \"\\e00e\"\n}\n\n.fui-photo:before {\n\tcontent: \"\\e00f\"\n}\n\n.fui-volume:before {\n\tcontent: \"\\e010\"\n}\n\n.fui-time:before {\n\tcontent: \"\\e011\"\n}\n\n.fui-eye:before {\n\tcontent: \"\\e012\"\n}\n\n.fui-chat:before {\n\tcontent: \"\\e013\"\n}\n\n.fui-search:before {\n\tcontent: \"\\e01c\"\n}\n\n.fui-user:before {\n\tcontent: \"\\e01d\"\n}\n\n.fui-mail:before {\n\tcontent: \"\\e01e\"\n}\n\n.fui-lock:before {\n\tcontent: \"\\e01f\"\n}\n\n.fui-gear:before {\n\tcontent: \"\\e024\"\n}\n\n.fui-radio-unchecked:before {\n\tcontent: \"\\e02b\"\n}\n\n.fui-radio-checked:before {\n\tcontent: \"\\e032\"\n}\n\n.fui-checkbox-unchecked:before {\n\tcontent: \"\\e033\"\n}\n\n.fui-checkbox-checked:before {\n\tcontent: \"\\e034\"\n}\n\n.fui-calendar-solid:before {\n\tcontent: \"\\e022\"\n}\n\n.fui-pause:before {\n\tcontent: \"\\e03b\"\n}\n\n.fui-play:before {\n\tcontent: \"\\e03c\"\n}\n\n.fui-check-inverted-2:before {\n\tcontent: \"\\e000\"\n}\n\n.inline-block {\n\tdisplay: inline-block;\n\tzoom: 1;\n\t*display: inline\n}\n\n.clearfix {\n\t*zoom: 1\n}\n\n.clearfix:before,.clearfix:after {\n\tdisplay: table;\n\tcontent: \"\"\n}\n\n.clearfix:after {\n\tclear: both\n}\n\n.drop-ie-gradient {\n\tfilter: unquote(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\")\n}\n\n.dropdown-arrow-inverse {\n\tborder-bottom-color: #34495e!important;\n\tborder-top-color: #34495e!important\n}\n\n.demo-headline {\n\tpadding: 73px 0 110px;\n\ttext-align: center\n}\n\n.demo-logo {\n\tfont-size: 90px;\n\tfont-weight: 900;\n\tletter-spacing: -2px;\n\tline-height: 100px\n}\n\n.demo-logo .logo {\n\tbackground: url(../img/demo/logo-mask.png) center 0 no-repeat;\n\tbackground-size: 256px 186px;\n\theight: 186px;\n\tmargin: 0 auto 26px;\n\toverflow: hidden;\n\ttext-indent: -9999em;\n\twidth: 256px\n}\n\n.demo-logo small {\n\tcolor: rgba(52,73,94,0.30000000000000004);\n\tdisplay: block;\n\tfont-size: 22px;\n\tfont-weight: 700;\n\tletter-spacing: -1px;\n\tpadding-top: 5px\n}\n\n.demo-row {\n\tmargin-bottom: 20px\n}\n\n.demo-panel-title {\n\tmargin-bottom: 20px;\n\tpadding-top: 20px\n}\n\n.demo-panel-title small {\n\tcolor: #798795;\n\tfont-size: inherit;\n\tfont-weight: 400\n}\n\n.demo-navigation {\n\tmargin-bottom: -4px;\n\tmargin-top: -10px\n}\n\n.demo-pager {\n\tmargin-top: -10px\n}\n\n.demo-tooltips {\n\theight: 126px\n}\n\n.demo-tooltips .tooltip {\n\tleft: -8px!important;\n\tposition: relative!important;\n\ttop: -8px!important\n}\n\n.demo-headings {\n\tmargin-bottom: 12px\n}\n\n.demo-tiles {\n\tmargin-bottom: 46px\n}\n\n.demo-icons {\n\tfont-size: 32px;\n\tmargin-left: -15px\n}\n\n.demo-icons .demo-content {\n\tmargin: 0 0 0 -36px\n}\n\n.demo-icons .demo-content>span {\n\tdisplay: inline-block;\n\tmargin: 0 0 32px 36px;\n\twidth: 24px;\n\tfont-size: 24px\n}\n\n.demo-icons-tooltip {\n\tbottom: 0;\n\tcolor: #c2c8cf;\n\tfont-size: 12px;\n\tleft: 100%;\n\tmargin-left: 0!important;\n\tposition: absolute;\n\twidth: 80px\n}\n\n.demo-illustrations {\n\tmargin-top: 40px;\n\t*zoom: 1\n}\n\n.demo-illustrations:before,.demo-illustrations:after {\n\tdisplay: table;\n\tcontent: \"\"\n}\n\n.demo-illustrations:after {\n\tclear: both\n}\n\n.demo-illustrations .demo-content {\n\tmargin: 0 0 0 -40px;\n\tpadding-top: 20px\n}\n\n.demo-illustrations .demo-content>div {\n\tfloat: left;\n\twidth: 100px;\n\theight: 100px;\n\tmargin: 0 0 80px 40px;\n\ttext-align: center\n}\n\n.demo-illustrations img {\n\tdisplay: inline-block;\n\tmax-height: 100px;\n\tmax-width: 100px;\n\tvertical-align: baseline\n}\n\n.demo-samples {\n\tmargin-bottom: 46px\n}\n\n.demo-video {\n\tpadding-top: 95px;\n\t-webkit-border-radius: 6px;\n\t-moz-border-radius: 6px;\n\tborder-radius: 6px\n}\n\n.demo-download-section {\n\tfloat: none;\n\tmargin: 0 auto;\n\tpadding: 60px 0 90px 20px;\n\ttext-align: center\n}\n\n.demo-download-section [class*='fui-'] {\n\tmargin: 3px 0 -3px\n}\n\n.demo-download {\n\tbackground-color: #ebedef;\n\theight: 120px;\n\tmargin: 0 auto 32px;\n\tpadding: 40px 28px 30px 32px;\n\ttext-align: center;\n\twidth: 130px;\n\t-webkit-border-radius: 50%;\n\t-moz-border-radius: 50%;\n\tborder-radius: 50%\n}\n\n.demo-download img {\n\theight: 104px;\n\twidth: 82px\n}\n\n.demo-download-text {\n\tfont-size: 15px;\n\tpadding: 20px 0;\n\ttext-align: center\n}\n\n.demo-text-box a:hover {\n\tcolor: #1abc9c\n}\n\n.demo-browser {\n\tbackground: #2c3e50 url(../img/demo/browser.png) 0 0 no-repeat;\n\tbackground-size: 659px 42px;\n\tcolor: #fff;\n\tmargin: 0 41px 140px 0;\n\tpadding-top: 42px;\n\t-webkit-border-radius: 0 0 6px 6px;\n\t-moz-border-radius: 0 0 6px 6px;\n\tborder-radius: 0 0 6px 6px\n}\n\n.demo-browser-side {\n\tfloat: left;\n\tpadding: 22px 20px;\n\twidth: 111px\n}\n\n.demo-browser-side>h5 {\n\tmargin-bottom: 3px;\n\ttext-transform: none\n}\n\n.demo-browser-side>h6 {\n\tfont-size: 11px;\n\tfont-weight: 300;\n\tline-height: 18px;\n\tmargin-top: 3px;\n\ttext-transform: none\n}\n\n.demo-browser-author {\n\tbackground: url(../img/demo/browser-author.jpg) center center no-repeat;\n\tborder: 3px solid #fff;\n\tdisplay: block;\n\theight: 84px;\n\tmargin: 0 auto;\n\twidth: 84px;\n\t-webkit-border-radius: 50%;\n\t-moz-border-radius: 50%;\n\tborder-radius: 50%\n}\n\n.demo-browser-action {\n\tpadding: 30px 0 12px\n}\n\n.demo-browser-action>.btn {\n\tpadding: 9px 0 10px 11px!important;\n\ttext-align: left;\n\t-webkit-border-radius: 3px;\n\t-moz-border-radius: 3px;\n\tborder-radius: 3px\n}\n\n.demo-browser-action>.btn:before {\n\tcolor: #fff;\n\tcontent: '\\e009';\n\tfont-size: 16px;\n\tfont-family: 'Flat-UI-Icons';\n\tfont-weight: 300;\n\tmargin-right: 12px;\n\tposition: relative;\n\ttop: 1px;\n\t-webkit-font-smoothing: antialiased\n}\n\n.demo-browser-content {\n\tbackground-color: #34495e;\n\toverflow: hidden;\n\tpadding: 21px 0 0 20px;\n\t-webkit-border-radius: 0 0 6px;\n\t-moz-border-radius: 0 0 6px;\n\tborder-radius: 0 0 6px\n}\n\n.demo-browser-content>img {\n\tborder: 6px solid #fff;\n\tfloat: left;\n\tmargin: 0 15px 20px 0;\n\twidth: 134px\n}\n\n@media only screen and (-webkit-min-device-pixel-ratio:2),only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (-moz-min-device-pixel-ratio:2),only screen and (-o-min-device-pixel-ratio:3/2),only screen and (-o-min-device-pixel-ratio:2/1),only screen and (min--moz-device-pixel-ratio:1.5),only screen and (min-device-pixel-ratio:1.5),only screen and (min-device-pixel-ratio:2) {\n\t.logo {\n\t\tbackground-image: url(../img/demo/logo-mask-2x.png)\n\t}\n\n\t.demo-browser {\n\t\tbackground-image: url(../img/demo/browser-2x.png)\n\t}\n}\n\nbody {\n\tcolor: #34495e;\n\tfont-family: \"Lato\",sans-serif;\n\tfont-size: 14px;\n\tline-height: 1.231\n}\n\ninput,button,select,textarea {\n\tfont-family: \"Lato\",sans-serif;\n\tfont-size: 14px\n}\n\na {\n\tcolor: #08c;\n\ttext-decoration: underline;\n\t-webkit-transition: .25s;\n\t-moz-transition: .25s;\n\t-o-transition: .25s;\n\ttransition: .25s;\n\t-webkit-backface-visibility: hidden\n}\n\na:hover {\n\tcolor: #333;\n\ttext-decoration: none\n}\n\nh1 {\n\tfont-size: 32px;\n\tfont-weight: 900\n}\n\nh2 {\n\tfont-size: 26px;\n\tfont-weight: 700;\n\tmargin-bottom: 2px\n}\n\nh3 {\n\tfont-size: 24px;\n\tfont-weight: 700;\n\tmargin-bottom: 4px;\n\tmargin-top: 2px\n}\n\nh4 {\n\tfont-size: 18px;\n\tfont-weight: 500;\n\tmargin-top: 4px\n}\n\nh5 {\n\tfont-size: 16px;\n\tfont-weight: 500;\n\ttext-transform: uppercase\n}\n\nh6 {\n\tfont-size: 13px;\n\tfont-weight: 500;\n\ttext-transform: uppercase\n}\n\n.btn,.btn-group>.btn,.btn-group>.dropdown-menu,.btn-group>.popover {\n\tfont-size: 14.994px;\n\tfont-weight: 500\n}\n\n.btn {\n\tborder: 0;\n\tbackground: #bdc3c7;\n\tcolor: #fff;\n\tpadding: 9px 12px 10px;\n\tline-height: 22px;\n\ttext-decoration: none;\n\ttext-shadow: none;\n\t-webkit-border-radius: 6px;\n\t-moz-border-radius: 6px;\n\tborder-radius: 6px;\n\t-webkit-box-shadow: none;\n\t-moz-box-shadow: none;\n\tbox-shadow: none;\n\t-webkit-transition: .25s;\n\t-moz-transition: .25s;\n\t-o-transition: .25s;\n\ttransition: .25s;\n\t-webkit-backface-visibility: hidden\n}\n\n.btn:hover,.btn:focus,.btn-group:focus .btn.dropdown-toggle {\n\tbackground-color: #cacfd2;\n\tcolor: #fff;\n\toutline: 0;\n\t-webkit-transition: .25s;\n\t-moz-transition: .25s;\n\t-o-transition: .25s;\n\ttransition: .25s;\n\t-webkit-backface-visibility: hidden\n}\n\n.btn:active,.btn-group.open .btn.dropdown-toggle,.btn.active {\n\tbackground-color: #a1a6a9;\n\tcolor: rgba(255,255,255,0.75);\n\t-webkit-box-shadow: none;\n\t-moz-box-shadow: none;\n\tbox-shadow: none\n}\n\n.btn.disabled,.btn[disabled] {\n\tbackground-color: #bdc3c7;\n\tcolor: rgba(255,255,255,0.75);\n\t-webkit-box-shadow: none;\n\t-moz-box-shadow: none;\n\tbox-shadow: none;\n\topacity: .7;\n\tfilter: alpha(opacity=70)\n}\n\n.btn.btn-large {\n\tfont-size: 16.996px;\n\tline-height: 20px;\n\tpadding: 12px 18px 13px\n}\n\n.btn.btn-large>[class^=\"fui-\"] {\n\ttop: 0\n}\n\n.btn.btn-large>[class^=\"fui-\"].pull-right {\n\tmargin-right: -2px\n}\n\n.btn.btn-primary {\n\tbackground-color: #1b93d1;\n}\n\n.btn.btn-primary:hover,\n.btn.btn-primary:focus,\n.btn-group:focus .btn.btn-primary.dropdown-toggle {\n\tbackground-color: #3276b1;\n}\n\n.btn.btn-primary:active,\n.btn-group.open .btn.btn-primary.dropdown-toggle,\n.btn.btn-primary.active {\n\tbackground-color: #039;\n}\n\n.btn.btn-info {\n\tbackground-color: #3498db\n}\n\n.btn.btn-info:hover,.btn.btn-info:focus,.btn-group:focus .btn.btn-info.dropdown-toggle {\n\tbackground-color: #5dade2\n}\n\n.btn.btn-info:active,.btn-group.open .btn.btn-info.dropdown-toggle,.btn.btn-info.active {\n\tbackground-color: #2c81ba\n}\n\n.btn.btn-danger {\n\tbackground-color: #e74c3c\n}\n\n.btn.btn-danger:hover,.btn.btn-danger:focus,.btn-group:focus .btn.btn-danger.dropdown-toggle {\n\tbackground-color: #ec7063\n}\n\n.btn.btn-danger:active,.btn-group.open .btn.btn-danger.dropdown-toggle,.btn.btn-danger.active {\n\tbackground-color: #c44133\n}\n\n.btn.btn-success {\n\tbackground-color: #2ecc71\n}\n\n.btn.btn-success:hover,.btn.btn-success:focus,.btn-group:focus .btn.btn-success.dropdown-toggle {\n\tbackground-color: #58d68d\n}\n\n.btn.btn-success:active,.btn-group.open .btn.btn-success.dropdown-toggle,.btn.btn-success.active {\n\tbackground-color: #27ad60\n}\n\n.btn.btn-warning {\n\tbackground-color: #f1c40f\n}\n\n.btn.btn-warning:hover,.btn.btn-warning:focus,.btn-group:focus .btn.btn-warning.dropdown-toggle {\n\tbackground-color: #f5d313\n}\n\n.btn.btn-warning:active,.btn-group.open .btn.btn-warning.dropdown-toggle,.btn.btn-warning.active {\n\tbackground-color: #cda70d\n}\n\n.btn.btn-inverse {\n\tbackground-color: #34495e\n}\n\n.btn.btn-inverse:hover,.btn.btn-inverse:focus,.btn-group:focus .btn.btn-inverse.dropdown-toggle {\n\tbackground-color: #415b76\n}\n\n.btn.btn-inverse:active,.btn-group.open .btn.btn-inverse.dropdown-toggle,.btn.btn-inverse.active {\n\tbackground-color: #2c3e50\n}\n\n.btn>[class^=\"fui-\"] {\n\tmargin: 0 4px;\n\tposition: relative;\n\ttop: 1px;\n\tvertical-align: top;\n\tdisplay: inline-block;\n\tzoom: 1;\n\t*display: inline\n}\n\n.btn>[class^=\"fui-\"].pull-right {\n\tmargin-right: 0\n}\n\n.btn-toolbar .btn.active {\n\tcolor: #fff\n}\n\n.btn-toolbar .btn:first-child {\n\t-webkit-border-radius: 6px 0 0 6px;\n\t-moz-border-radius: 6px 0 0 6px;\n\tborder-radius: 6px 0 0 6px\n}\n\n.btn-toolbar .btn:last-child {\n\t-webkit-border-radius: 0 6px 6px 0;\n\t-moz-border-radius: 0 6px 6px 0;\n\tborder-radius: 0 6px 6px 0\n}\n\n.btn-toolbar .btn>[class^=\"fui-\"] {\n\tfont-size: 16px;\n\ttop: 0\n}\n\n.btn-tip {\n\tfont-weight: 300;\n\tpadding-left: 10px\n}\n\n.btn-group>.btn {\n\tborder-radius: 0;\n\ttext-align: center\n}\n\n.btn-group>.btn:active+.btn,.btn-group>.btn.active+.btn {\n\tborder-left-color: transparent\n}\n\n.btn-group>.btn:first-of-type {\n\tborder-top-left-radius: 6px;\n\tborder-bottom-left-radius: 6px\n}\n\n.btn-group>.btn:last-of-type {\n\tborder-top-right-radius: 6px;\n\tborder-bottom-right-radius: 6px\n}\n\n.btn-group>.btn+.btn {\n\tmargin-left: 0\n}\n\n.btn-group>.btn+.dropdown-toggle {\n\tborder-left: 2px solid rgba(52,73,94,0.15);\n\tpadding-left: 13px;\n\tpadding-right: 13px;\n\t-webkit-box-shadow: none;\n\t-moz-box-shadow: none;\n\tbox-shadow: none\n}\n\n.btn-group>.btn+.dropdown-toggle .caret {\n\tmargin-left: 3px;\n\tmargin-right: 3px\n}\n\n.btn-group>.btn.btn-huge+.dropdown-toggle .caret {\n\tmargin-left: 7px;\n\tmargin-right: 7px\n}\n\n.btn-group>.btn.btn-small+.dropdown-toggle .caret {\n\tmargin-left: 0;\n\tmargin-right: 0\n}\n\n.caret {\n\tborder-left-width: 6px;\n\tborder-right-width: 6px;\n\tborder-top-width: 8px;\n\tborder-bottom-color: #34495e;\n\tborder-style: solid;\n\tborder-bottom-style: none;\n\tborder-top-color: #34495e;\n\t-webkit-transition: .25s;\n\t-moz-transition: .25s;\n\t-o-transition: .25s;\n\ttransition: .25s;\n\t-webkit-backface-visibility: hidden\n}\n\n.dropup .caret,.dropup .btn-large .caret,.navbar-fixed-bottom .dropdown .caret {\n\tborder-bottom-width: 8px\n}\n\n.btn-mini .caret,.btn-small .caret,.btn-large .caret {\n\tmargin-top: 7px\n}\n\n.btn-large .caret {\n\tborder-top-width: 8px;\n\tborder-right-width: 6px;\n\tborder-left-width: 6px\n}\n\n.navbar {\n\tfont-size: 15.988px\n}\n\n.navbar .brand {\n\tborder-radius: 6px 0 0 6px;\n\tcolor: #526476;\n\tfont-size: 23.996px;\n\tfont-weight: 700;\n\tmargin-left: 0;\n\tpadding: 23px 28px 24px 32px;\n\ttext-shadow: none\n}\n\n.navbar .brand:hover,.navbar .brand:focus {\n\tcolor: #1abc9c\n}\n\n.navbar .brand[class*=\"fui-\"] {\n\tfont-weight: normal\n}\n\n.navbar .nav {\n\tmargin-right: 0\n}\n\n.navbar .nav>li {\n\tposition: relative\n}\n\n.navbar .nav>li:hover>ul {\n\topacity: 1;\n\ttop: 100%;\n\tvisibility: visible;\n\tz-index: 100;\n\t-webkit-transform: scale(1,1);\n\tdisplay: block\\9\n}\n\n.navbar .nav>li.active>a,.navbar .nav>li.active>a:hover,.navbar .nav>li.active>a:focus {\n\tbackground: 0;\n\tcolor: #1abc9c;\n\t-webkit-box-shadow: none;\n\t-moz-box-shadow: none;\n\tbox-shadow: none\n}\n\n.navbar .nav>li>ul {\n\tpadding-top: 13px;\n\ttop: 80%\n}\n\n.navbar .nav>li>ul:before {\n\tcontent: \"\";\n\tborder-style: solid;\n\tborder-width: 0 9px 9px 9px;\n\tborder-color: transparent transparent #34495e transparent;\n\theight: 0;\n\tposition: absolute;\n\tleft: 15px;\n\ttop: 5px;\n\twidth: 0;\n\t-webkit-transform: rotate(360deg)\n}\n\n.navbar .nav>li>ul li:hover ul {\n\topacity: 1;\n\t-webkit-transform: scale(1,1);\n\tvisibility: visible;\n\tdisplay: block\\9\n}\n\n.navbar .nav>li>ul li ul {\n\tleft: 100%\n}\n\n.navbar .nav>li>a {\n\tcolor: #526476;\n\tfont-weight: 700;\n\tfont-size: 14.994px;\n\tpadding: 29px 20px 27px;\n\ttext-shadow: none;\n\t-webkit-transition: background-color .25s,color .25s,border-bottom-color .25s;\n\t-moz-transition: background-color .25s,color .25s,border-bottom-color .25s;\n\t-o-transition: background-color .25s,color .25s,border-bottom-color .25s;\n\ttransition: background-color .25s,color .25s,border-bottom-color .25s;\n\t-webkit-backface-visibility: hidden\n}\n\n.navbar .nav>li>a:hover,.navbar .nav>li>a:focus {\n\tcolor: #1abc9c\n}\n\n.navbar .nav>li>a[class*=\"fui-\"] {\n\tfont-size: 24px;\n\tfont-weight: normal\n}\n\n.navbar .nav>li>a>[class*=\"fui-\"] {\n\tfont-size: 24px;\n\tmargin: -4px 0 0;\n\tposition: relative;\n\ttop: 4px\n}\n\n.navbar .nav>li>a>[class*=\"fui-\"]+* {\n\tmargin-left: 12px\n}\n\n.navbar .nav>li:first-child>a {\n\t-webkit-border-radius: 0 0 0 6px;\n\t-moz-border-radius: 0 0 0 6px;\n\tborder-radius: 0 0 0 6px\n}\n\n.navbar .nav ul {\n\tborder-radius: 4px;\n\tleft: 0;\n\tlist-style-type: none;\n\tmargin-left: 0;\n\topacity: 0;\n\tposition: absolute;\n\ttop: 0;\n\twidth: 234px;\n\tz-index: -100;\n\t-webkit-transform: scale(1,0.99);\n\t-webkit-transform-origin: 0 0;\n\tvisibility: hidden;\n\t-webkit-transition: .3s ease-out;\n\t-moz-transition: .3s ease-out;\n\t-o-transition: .3s ease-out;\n\ttransition: .3s ease-out;\n\t-webkit-backface-visibility: hidden\n}\n\n.navbar .nav ul ul {\n\tleft: 95%;\n\tpadding-left: 5px\n}\n\n.navbar .nav ul li {\n\tbackground-color: #34495e;\n\tpadding: 0 3px 3px;\n\tposition: relative\n}\n\n.navbar .nav ul li:first-child {\n\tborder-radius: 6px 6px 0 0;\n\tpadding-top: 3px\n}\n\n.navbar .nav ul li:last-child {\n\tborder-radius: 0 0 6px 6px\n}\n\n.navbar .nav ul li.active>a,.navbar .nav ul li.active>a:hover,.navbar .nav ul li.active>a:focus {\n\tbackground-color: #1abc9c;\n\tcolor: #fff;\n\tpadding-left: 9px;\n\tpadding-right: 9px\n}\n\n.navbar .nav ul li.active+li>a {\n\tpadding-left: 9px;\n\tpadding-right: 9px\n}\n\n.navbar .nav ul a {\n\tborder-radius: 2px;\n\tcolor: #fff;\n\tdisplay: block;\n\tfont-size: 14px;\n\tpadding: 6px 9px;\n\ttext-decoration: none\n}\n\n.navbar .nav ul a:hover {\n\tbackground-color: #1abc9c\n}\n\n.navbar .btn-navbar {\n\tbackground: 0;\n\tborder: 0;\n\tcolor: #34495e;\n\tmargin: 21px 15px 17px;\n\ttext-shadow: none;\n\t-webkit-box-shadow: none;\n\t-moz-box-shadow: none;\n\tbox-shadow: none\n}\n\n.navbar .btn-navbar:hover,.navbar .btn-navbar:focus {\n\tbackground: 0;\n\tcolor: #1abc9c\n}\n\n.navbar .btn-navbar:before {\n\tcontent: \"\\e00c\";\n\tfont-family: \"Flat-UI-Icons\";\n\tfont-size: 21.994px;\n\tfont-style: normal;\n\tfont-weight: normal;\n\t-webkit-font-smoothing: antialiased\n}\n\n.navbar .btn-navbar .icon-bar {\n\tdisplay: none\n}\n\n.navbar-inner {\n\tbackground: #eceef0;\n\tborder: 0;\n\tpadding-left: 0;\n\tpadding-right: 0;\n\t-webkit-border-radius: 6px;\n\t-moz-border-radius: 6px;\n\tborder-radius: 6px;\n\tfilter: unquote(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\");\n\t-webkit-box-shadow: none;\n\t-moz-box-shadow: none;\n\tbox-shadow: none\n}\n\n.navbar-inverse {\n\tfont-size: 16.996px\n}\n\n.navbar-inverse .navbar-inner {\n\tbackground: #34495e;\n\tfilter: unquote(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\");\n    padding: 5px;\n}\n\n.navbar-inverse .brand {\n\tborder-bottom: 2px solid #2c3e50;\n\tborder-right: 2px solid #2c3e50;\n\tcolor: #fff;\n\tpadding: 10px 28px 11px 32px\n}\n\n.navbar-inverse .btn-navbar {\n\tcolor: #fff;\n\tmargin: 7px 10px\n}\n\n.navbar-inverse .nav>li:first-child.active>a {\n\tpadding-left: 20px\n}\n\n.navbar-inverse .nav>li:first-child>a {\n\tborder-left: none\n}\n\n.navbar-inverse .nav>li.active>a,.navbar-inverse .nav>li.active>a:hover,.navbar-inverse .nav>li.active>a:focus {\n\tbackground-color: #1abc9c;\n\tborder-bottom-color: #08c;\n\tborder-left: none;\n\tcolor: #fff;\n\tpadding-left: 22px;\n\t-webkit-box-shadow: none;\n\t-moz-box-shadow: none;\n\tbox-shadow: none\n}\n\n.navbar-inverse .nav>li.active+li>a {\n\tborder-left: none;\n\tpadding-left: 22px\n}\n\n.navbar-inverse .nav>li>a {\n\tfont-size: 16.002px;\n\tborder-bottom: 2px solid #2c3e50;\n\tborder-left: 2px solid #2c3e50;\n\tcolor: #fff;\n\tpadding: 16px 20px 15px\n}\n\n.navbar-inverse .nav.pull-right>li>a {\n\tborder-radius: 0 6px 6px 0\n}\n\n.navbar-unread,.navbar-new {\n\tfont-family: \"Lato\",sans-serif;\n\tbackground-color: #1abc9c;\n\tborder-radius: 50%;\n\tcolor: #fff;\n\tfont-size: 0;\n\tfont-weight: 700;\n\theight: 6px;\n\tline-height: 14px;\n\tposition: absolute;\n\tright: 12px;\n\ttext-align: center;\n\ttop: 28px;\n\twidth: 6px;\n\tz-index: 10\n}\n\n.active .navbar-unread,.active .navbar-new {\n\tbackground-color: #fff;\n\tdisplay: none\n}\n\n.navbar-inverse .navbar-unread,.navbar-inverse .navbar-new {\n\ttop: 15px\n}\n\n.navbar-new {\n\tbackground-color: #e74c3c;\n\tfont-size: 12px;\n\tline-height: 17px;\n\theight: 18px;\n\tmargin: -9px -1px;\n\tmin-width: 16px;\n\tpadding: 0 1px;\n\twidth: auto;\n\t-webkit-font-smoothing: subpixel-antialiased\n}\n\n.navbar.navbar-inverse .nav li.dropdown.open>.dropdown-toggle {\n\tbackground-color: #1abc9c;\n\tborder-bottom-color: #08c;\n\tcolor: #fff\n}\n\n.navbar.navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret {\n\tborder-bottom-color: #fff!important;\n\tborder-top-color: #fff!important\n}\n\n.navbar .nav li.dropdown.open>.dropdown-toggle {\n\tbackground: 0;\n\tcolor: #1abc9c\n}\n\n.navbar .nav li.dropdown.open>.dropdown-toggle .caret {\n\tborder-bottom-color: #1abc9c!important;\n\tborder-top-color: #1abc9c!important\n}\n\n.navbar .nav li.dropdown.open .dropdown-menu {\n\topacity: 1;\n\ttop: 100%;\n\tvisibility: visible;\n\tz-index: 1000;\n\t-webkit-transform: none\n}\n\n.navbar .nav li.dropdown>.dropdown-toggle {\n\toutline: 0\n}\n\n.navbar .nav li.dropdown>.dropdown-toggle:hover .caret,.navbar .nav li.dropdown>.dropdown-toggle:focus .caret {\n\tborder-bottom-color: #1abc9c;\n\tborder-top-color: #1abc9c\n}\n\n.navbar .nav li.dropdown>.dropdown-toggle .caret {\n\tborder-left-width: 6px;\n\tborder-right-width: 6px;\n\tborder-top-width: 8px;\n\tborder-bottom-color: #4c6a89;\n\tborder-top-color: #4c6a89;\n\tmargin-left: 10px;\n\tmargin-top: 7px\n}\n\n.navbar .nav li.dropdown .dropdown-menu {\n\tbackground-color: #34495e;\n\topacity: 0;\n\tpadding: 0;\n\tvisibility: hidden\n}\n\n.navbar .nav li.dropdown .dropdown-menu:before {\n\tdisplay: none\n}\n\n.navbar .nav li.dropdown .dropdown-menu:after {\n\tborder-bottom-color: #34495e\n}\n\n.navbar .nav li.dropdown .dropdown-menu>li>a {\n\tborder-radius: 3px;\n\tcolor: #fff;\n\tpadding: 6px 8px 8px\n}\n\n.navbar .nav li.dropdown .dropdown-menu .divider {\n\tbackground-color: #2c3e50;\n\tborder-bottom: 0;\n\tmargin: 2px 0 5px;\n\tpadding: 0;\n\theight: 2px\n}\n\n.select {\n\tdisplay: inline-block;\n\tmargin-bottom: 10px\n}[class*=\"span\"]>.select[class*=\"span\"] {\n\tmargin-left: 0\n}\n\n.select[class*=\"span\"] .btn {\n\twidth: 100%;\n\t-webkit-box-sizing: border-box;\n\t-moz-box-sizing: border-box;\n\tbox-sizing: border-box\n}\n\n.select.select-block {\n\tdisplay: block;\n\tfloat: none;\n\tmargin-left: 0;\n\twidth: auto\n}\n\n.select.select-block .btn {\n\twidth: 100%;\n\t-webkit-box-sizing: border-box;\n\t-moz-box-sizing: border-box;\n\tbox-sizing: border-box\n}\n\n.select .btn {\n\twidth: 220px\n}\n\n.select .btn.btn-huge .filter-option {\n\tleft: 20px;\n\tright: 40px;\n\ttop: 16px\n}\n\n.select .btn.btn-huge .caret {\n\tright: 20px\n}\n\n.select .btn.btn-large .filter-option {\n\tleft: 18px;\n\tright: 38px;\n\ttop: 12px\n}\n\n.select .btn.btn-small .filter-option {\n\tleft: 13px;\n\tright: 33px;\n\ttop: 7px\n}\n\n.select .btn.btn-small .caret {\n\tright: 13px\n}\n\n.select .btn.btn-mini .filter-option {\n\tleft: 13px;\n\tright: 33px;\n\ttop: 5px\n}\n\n.select .btn.btn-mini .caret {\n\tright: 13px\n}\n\n.select .btn .filter-option {\n\theight: 26px;\n\tleft: 13px;\n\toverflow: hidden;\n\tposition: absolute;\n\tright: 33px;\n\ttext-align: left;\n\ttop: 10px\n}\n\n.select .btn .caret {\n\tposition: absolute;\n\tright: 16px\n}\n\n.select .btn .dropdown-toggle {\n\t-webkit-border-radius: 6px;\n\t-moz-border-radius: 6px;\n\tborder-radius: 6px\n}\n\n.select .btn .dropdown-menu {\n\tmin-width: 100%;\n\t-webkit-box-sizing: border-box;\n\t-moz-box-sizing: border-box;\n\tbox-sizing: border-box\n}\n\n.select .btn .dropdown-menu dt {\n\tcursor: default;\n\tdisplay: block;\n\tpadding: 3px 20px\n}\n\n.select .btn .dropdown-menu li:not(.disabled)>a:hover small {\n\tcolor: rgba(255,255,255,0.004)\n}\n\n.select .btn .dropdown-menu li>a {\n\tmin-height: 20px\n}\n\n.select .btn .dropdown-menu li>a.opt {\n\tpadding-left: 35px\n}\n\n.select .btn .dropdown-menu li small {\n\tpadding-left: .5em\n}\n\n.select .btn .dropdown-menu li>dt small {\n\tfont-weight: normal\n}\n\n.select .btn>.disabled,.select .btn .dropdown-menu li.disabled>a {\n\tcursor: default\n}\n\n.select .caret {\n\tborder-left-width: 6px;\n\tborder-right-width: 6px;\n\tborder-top-width: 8px;\n\tborder-bottom-color: #fff;\n\tborder-style: solid;\n\tborder-bottom-style: none;\n\tborder-top-color: #fff;\n\t-webkit-transition: .25s;\n\t-moz-transition: .25s;\n\t-o-transition: .25s;\n\ttransition: .25s;\n\t-webkit-backface-visibility: hidden\n}\n\ntextarea,input[type=\"text\"],input[type=\"password\"],input[type=\"datetime\"],input[type=\"datetime-local\"],input[type=\"date\"],input[type=\"month\"],input[type=\"time\"],input[type=\"week\"],input[type=\"number\"],input[type=\"email\"],input[type=\"url\"],input[type=\"search\"],input[type=\"tel\"],input[type=\"color\"],.uneditable-input {\n\tborder: 2px solid #bdc3c7;\n\tcolor: #34495e;\n\tfont-family: \"Lato\",sans-serif;\n\tfont-size: 14px;\n\tpadding: 8px 5px;\n\theight: 21px;\n\ttext-indent: 6px;\n\t-webkit-appearance: none;\n\t-webkit-border-radius: 6px;\n\t-moz-border-radius: 6px;\n\tborder-radius: 6px;\n\t-webkit-box-shadow: none;\n\t-moz-box-shadow: none;\n\tbox-shadow: none;\n\t-webkit-transition: border .25s linear,color .25s linear;\n\t-moz-transition: border .25s linear,color .25s linear;\n\t-o-transition: border .25s linear,color .25s linear;\n\ttransition: border .25s linear,color .25s linear;\n\t-webkit-backface-visibility: hidden\n}\n\ntextarea:-moz-placeholder,input[type=\"text\"]:-moz-placeholder,input[type=\"password\"]:-moz-placeholder,input[type=\"datetime\"]:-moz-placeholder,input[type=\"datetime-local\"]:-moz-placeholder,input[type=\"date\"]:-moz-placeholder,input[type=\"month\"]:-moz-placeholder,input[type=\"time\"]:-moz-placeholder,input[type=\"week\"]:-moz-placeholder,input[type=\"number\"]:-moz-placeholder,input[type=\"email\"]:-moz-placeholder,input[type=\"url\"]:-moz-placeholder,input[type=\"search\"]:-moz-placeholder,input[type=\"tel\"]:-moz-placeholder,input[type=\"color\"]:-moz-placeholder,.uneditable-input:-moz-placeholder {\n\tcolor: #b2bcc5\n}\n\ntextarea::-webkit-input-placeholder,input[type=\"text\"]::-webkit-input-placeholder,input[type=\"password\"]::-webkit-input-placeholder,input[type=\"datetime\"]::-webkit-input-placeholder,input[type=\"datetime-local\"]::-webkit-input-placeholder,input[type=\"date\"]::-webkit-input-placeholder,input[type=\"month\"]::-webkit-input-placeholder,input[type=\"time\"]::-webkit-input-placeholder,input[type=\"week\"]::-webkit-input-placeholder,input[type=\"number\"]::-webkit-input-placeholder,input[type=\"email\"]::-webkit-input-placeholder,input[type=\"url\"]::-webkit-input-placeholder,input[type=\"search\"]::-webkit-input-placeholder,input[type=\"tel\"]::-webkit-input-placeholder,input[type=\"color\"]::-webkit-input-placeholder,.uneditable-input::-webkit-input-placeholder {\n\tcolor: #b2bcc5\n}\n\ntextarea.placeholder,input[type=\"text\"].placeholder,input[type=\"password\"].placeholder,input[type=\"datetime\"].placeholder,input[type=\"datetime-local\"].placeholder,input[type=\"date\"].placeholder,input[type=\"month\"].placeholder,input[type=\"time\"].placeholder,input[type=\"week\"].placeholder,input[type=\"number\"].placeholder,input[type=\"email\"].placeholder,input[type=\"url\"].placeholder,input[type=\"search\"].placeholder,input[type=\"tel\"].placeholder,input[type=\"color\"].placeholder,.uneditable-input.placeholder {\n\tcolor: #b2bcc5\n}\n\n.control-group.focus textarea,.control-group.focus input[type=\"text\"],.control-group.focus input[type=\"password\"],.control-group.focus input[type=\"datetime\"],.control-group.focus input[type=\"datetime-local\"],.control-group.focus input[type=\"date\"],.control-group.focus input[type=\"month\"],.control-group.focus input[type=\"time\"],.control-group.focus input[type=\"week\"],.control-group.focus input[type=\"number\"],.control-group.focus input[type=\"email\"],.control-group.focus input[type=\"url\"],.control-group.focus input[type=\"search\"],.control-group.focus input[type=\"tel\"],.control-group.focus input[type=\"color\"],.control-group.focus .uneditable-input,textarea:focus,input[type=\"text\"]:focus,input[type=\"password\"]:focus,input[type=\"datetime\"]:focus,input[type=\"datetime-local\"]:focus,input[type=\"date\"]:focus,input[type=\"month\"]:focus,input[type=\"time\"]:focus,input[type=\"week\"]:focus,input[type=\"number\"]:focus,input[type=\"email\"]:focus,input[type=\"url\"]:focus,input[type=\"search\"]:focus,input[type=\"tel\"]:focus,input[type=\"color\"]:focus,.uneditable-input:focus {\n\tborder-color: rgba(82,168,236,0.8);\n\t-webkit-box-shadow: none;\n\t-moz-box-shadow: none;\n\tbox-shadow: none\n}\n\n.row-fluid textarea,.row-fluid input[type=\"text\"],.row-fluid input[type=\"password\"],.row-fluid input[type=\"datetime\"],.row-fluid input[type=\"datetime-local\"],.row-fluid input[type=\"date\"],.row-fluid input[type=\"month\"],.row-fluid input[type=\"time\"],.row-fluid input[type=\"week\"],.row-fluid input[type=\"number\"],.row-fluid input[type=\"email\"],.row-fluid input[type=\"url\"],.row-fluid input[type=\"search\"],.row-fluid input[type=\"tel\"],.row-fluid input[type=\"color\"],.row-fluid .uneditable-input {\n\theight: 41px;\n\twidth: 100%\n}\n\ntextarea.flat,input[type=\"text\"].flat,input[type=\"password\"].flat,input[type=\"datetime\"].flat,input[type=\"datetime-local\"].flat,input[type=\"date\"].flat,input[type=\"month\"].flat,input[type=\"time\"].flat,input[type=\"week\"].flat,input[type=\"number\"].flat,input[type=\"email\"].flat,input[type=\"url\"].flat,input[type=\"search\"].flat,input[type=\"tel\"].flat,input[type=\"color\"].flat,.uneditable-input.flat {\n\tborder-color: transparent\n}\n\ntextarea.flat:hover,input[type=\"text\"].flat:hover,input[type=\"password\"].flat:hover,input[type=\"datetime\"].flat:hover,input[type=\"datetime-local\"].flat:hover,input[type=\"date\"].flat:hover,input[type=\"month\"].flat:hover,input[type=\"time\"].flat:hover,input[type=\"week\"].flat:hover,input[type=\"number\"].flat:hover,input[type=\"email\"].flat:hover,input[type=\"url\"].flat:hover,input[type=\"search\"].flat:hover,input[type=\"tel\"].flat:hover,input[type=\"color\"].flat:hover,.uneditable-input.flat:hover {\n\tborder-color: #bdc3c7\n}\n\ntextarea.flat:focus,input[type=\"text\"].flat:focus,input[type=\"password\"].flat:focus,input[type=\"datetime\"].flat:focus,input[type=\"datetime-local\"].flat:focus,input[type=\"date\"].flat:focus,input[type=\"month\"].flat:focus,input[type=\"time\"].flat:focus,input[type=\"week\"].flat:focus,input[type=\"number\"].flat:focus,input[type=\"email\"].flat:focus,input[type=\"url\"].flat:focus,input[type=\"search\"].flat:focus,input[type=\"tel\"].flat:focus,input[type=\"color\"].flat:focus,.uneditable-input.flat:focus {\n\tborder-color: rgba(82,168,236,0.8);\n}\n\n.control-group.error textarea,.control-group.error input[type=\"text\"],.control-group.error input[type=\"password\"],.control-group.error input[type=\"datetime\"],.control-group.error input[type=\"datetime-local\"],.control-group.error input[type=\"date\"],.control-group.error input[type=\"month\"],.control-group.error input[type=\"time\"],.control-group.error input[type=\"week\"],.control-group.error input[type=\"number\"],.control-group.error input[type=\"email\"],.control-group.error input[type=\"url\"],.control-group.error input[type=\"search\"],.control-group.error input[type=\"tel\"],.control-group.error input[type=\"color\"],.control-group.error .uneditable-input {\n\tborder-color: #e74c3c;\n\tcolor: #e74c3c;\n\t-webkit-box-shadow: none;\n\t-moz-box-shadow: none;\n\tbox-shadow: none\n}\n\n.control-group.error textarea:focus,.control-group.error input[type=\"text\"]:focus,.control-group.error input[type=\"password\"]:focus,.control-group.error input[type=\"datetime\"]:focus,.control-group.error input[type=\"datetime-local\"]:focus,.control-group.error input[type=\"date\"]:focus,.control-group.error input[type=\"month\"]:focus,.control-group.error input[type=\"time\"]:focus,.control-group.error input[type=\"week\"]:focus,.control-group.error input[type=\"number\"]:focus,.control-group.error input[type=\"email\"]:focus,.control-group.error input[type=\"url\"]:focus,.control-group.error input[type=\"search\"]:focus,.control-group.error input[type=\"tel\"]:focus,.control-group.error input[type=\"color\"]:focus,.control-group.error .uneditable-input:focus {\n\t-webkit-box-shadow: none;\n\t-moz-box-shadow: none;\n\tbox-shadow: none\n}\n\n.control-group.success textarea,.control-group.success input[type=\"text\"],.control-group.success input[type=\"password\"],.control-group.success input[type=\"datetime\"],.control-group.success input[type=\"datetime-local\"],.control-group.success input[type=\"date\"],.control-group.success input[type=\"month\"],.control-group.success input[type=\"time\"],.control-group.success input[type=\"week\"],.control-group.success input[type=\"number\"],.control-group.success input[type=\"email\"],.control-group.success input[type=\"url\"],.control-group.success input[type=\"search\"],.control-group.success input[type=\"tel\"],.control-group.success input[type=\"color\"],.control-group.success .uneditable-input {\n\tborder-color: #2ecc71;\n\tcolor: #2ecc71;\n\t-webkit-box-shadow: none;\n\t-moz-box-shadow: none;\n\tbox-shadow: none\n}\n\n.control-group.success textarea:focus,.control-group.success input[type=\"text\"]:focus,.control-group.success input[type=\"password\"]:focus,.control-group.success input[type=\"datetime\"]:focus,.control-group.success input[type=\"datetime-local\"]:focus,.control-group.success input[type=\"date\"]:focus,.control-group.success input[type=\"month\"]:focus,.control-group.success input[type=\"time\"]:focus,.control-group.success input[type=\"week\"]:focus,.control-group.success input[type=\"number\"]:focus,.control-group.success input[type=\"email\"]:focus,.control-group.success input[type=\"url\"]:focus,.control-group.success input[type=\"search\"]:focus,.control-group.success input[type=\"tel\"]:focus,.control-group.success input[type=\"color\"]:focus,.control-group.success .uneditable-input:focus {\n\t-webkit-box-shadow: none;\n\t-moz-box-shadow: none;\n\tbox-shadow: none\n}\n\n.control-group.warning textarea,.control-group.warning input[type=\"text\"],.control-group.warning input[type=\"password\"],.control-group.warning input[type=\"datetime\"],.control-group.warning input[type=\"datetime-local\"],.control-group.warning input[type=\"date\"],.control-group.warning input[type=\"month\"],.control-group.warning input[type=\"time\"],.control-group.warning input[type=\"week\"],.control-group.warning input[type=\"number\"],.control-group.warning input[type=\"email\"],.control-group.warning input[type=\"url\"],.control-group.warning input[type=\"search\"],.control-group.warning input[type=\"tel\"],.control-group.warning input[type=\"color\"],.control-group.warning .uneditable-input {\n\tborder-color: #f1c40f;\n\tcolor: #f1c40f;\n\t-webkit-box-shadow: none;\n\t-moz-box-shadow: none;\n\tbox-shadow: none\n}\n\n.control-group.warning textarea:focus,.control-group.warning input[type=\"text\"]:focus,.control-group.warning input[type=\"password\"]:focus,.control-group.warning input[type=\"datetime\"]:focus,.control-group.warning input[type=\"datetime-local\"]:focus,.control-group.warning input[type=\"date\"]:focus,.control-group.warning input[type=\"month\"]:focus,.control-group.warning input[type=\"time\"]:focus,.control-group.warning input[type=\"week\"]:focus,.control-group.warning input[type=\"number\"]:focus,.control-group.warning input[type=\"email\"]:focus,.control-group.warning input[type=\"url\"]:focus,.control-group.warning input[type=\"search\"]:focus,.control-group.warning input[type=\"tel\"]:focus,.control-group.warning input[type=\"color\"]:focus,.control-group.warning .uneditable-input:focus {\n\t-webkit-box-shadow: none;\n\t-moz-box-shadow: none;\n\tbox-shadow: none\n}\n\n.control-group.info textarea,.control-group.info input[type=\"text\"],.control-group.info input[type=\"password\"],.control-group.info input[type=\"datetime\"],.control-group.info input[type=\"datetime-local\"],.control-group.info input[type=\"date\"],.control-group.info input[type=\"month\"],.control-group.info input[type=\"time\"],.control-group.info input[type=\"week\"],.control-group.info input[type=\"number\"],.control-group.info input[type=\"email\"],.control-group.info input[type=\"url\"],.control-group.info input[type=\"search\"],.control-group.info input[type=\"tel\"],.control-group.info input[type=\"color\"],.control-group.info .uneditable-input {\n\tborder-color: #3498db;\n\tcolor: #3498db;\n\t-webkit-box-shadow: none;\n\t-moz-box-shadow: none;\n\tbox-shadow: none\n}\n\n.control-group.info textarea:focus,.control-group.info input[type=\"text\"]:focus,.control-group.info input[type=\"password\"]:focus,.control-group.info input[type=\"datetime\"]:focus,.control-group.info input[type=\"datetime-local\"]:focus,.control-group.info input[type=\"date\"]:focus,.control-group.info input[type=\"month\"]:focus,.control-group.info input[type=\"time\"]:focus,.control-group.info input[type=\"week\"]:focus,.control-group.info input[type=\"number\"]:focus,.control-group.info input[type=\"email\"]:focus,.control-group.info input[type=\"url\"]:focus,.control-group.info input[type=\"search\"]:focus,.control-group.info input[type=\"tel\"]:focus,.control-group.info input[type=\"color\"]:focus,.control-group.info .uneditable-input:focus {\n\t-webkit-box-shadow: none;\n\t-moz-box-shadow: none;\n\tbox-shadow: none\n}\n\n.control-group textarea,.control-group input[type=\"text\"],.control-group input[type=\"password\"],.control-group input[type=\"datetime\"],.control-group input[type=\"datetime-local\"],.control-group input[type=\"date\"],.control-group input[type=\"month\"],.control-group input[type=\"time\"],.control-group input[type=\"week\"],.control-group input[type=\"number\"],.control-group input[type=\"email\"],.control-group input[type=\"url\"],.control-group input[type=\"search\"],.control-group input[type=\"tel\"],.control-group input[type=\"color\"],.control-group .uneditable-input {\n\tmargin-bottom: 0\n}\n\n.control-group {\n\tposition: relative\n}\n\n.control-group>.input-icon {\n\tposition: absolute;\n\ttop: 2px;\n\tright: 2px;\n\tline-height: 37px;\n\tvertical-align: middle;\n\tfont-size: 19.991999999999997px;\n\tcolor: #b2bcc5;\n\tbackground-color: #fff;\n\tpadding: 0 10px;\n\t-webkit-border-radius: 6px;\n\t-moz-border-radius: 6px;\n\tborder-radius: 6px\n}\n\n.control-group input:focus+.input-icon {\n\tcolor: #34495e\n}\n\n.control-group.huge>.input-icon {\n\tline-height: 49px\n}\n\n.control-group.large>.input-icon {\n\tline-height: 41px\n}\n\n.control-group.small>.input-icon {\n\tfont-size: 15.988px;\n\tline-height: 30px\n}\n\n.control-group.success>.input-icon,.control-group.success input+.input-icon {\n\tcolor: #2ecc71\n}\n\n.control-group.warning>.input-icon,.control-group.warning input+.input-icon {\n\tcolor: #f1c40f\n}\n\n.control-group.error>.input-icon,.control-group.error input+.input-icon {\n\tcolor: #e74c3c\n}\n\n.control-group.disabled>.input-icon,.control-group.disabled input+.input-icon {\n\tcolor: #d5dbdb;\n\tbackground-color: #f4f6f6\n}\n\ninput[disabled],input[readonly],textarea[disabled],textarea[readonly] {\n\tbackground-color: #f4f6f6;\n\tborder-color: #d5dbdb;\n\tcolor: #d5dbdb;\n\tcursor: default\n}\n\ninput,textarea,.uneditable-input {\n\twidth: 192px\n}\n\ntextarea {\n\theight: auto;\n\tfont-size: 14.994px;\n\tline-height: 24px;\n\tpadding: 5px 11px;\n\ttext-indent: 0\n}\n\n.row-fluid textarea {\n\theight: auto;\n\twidth: 100%!important\n}\n\ntextarea[class*=\"span\"] {\n\twidth: 100%!important;\n\t-webkit-box-sizing: border-box;\n\t-moz-box-sizing: border-box;\n\tbox-sizing: border-box\n}\n\n.checkbox,.radio {\n\tmargin-bottom: 12px;\n\tpadding-left: 32px;\n\tposition: relative;\n\t-webkit-transition: color .25s linear;\n\t-moz-transition: color .25s linear;\n\t-o-transition: color .25s linear;\n\ttransition: color .25s linear;\n\t-webkit-backface-visibility: hidden\n}\n\n.checkbox input,.radio input {\n\toutline: none!important;\n\tdisplay: none\n}\n\n.checkbox .icons,.radio .icons {\n\tcolor: #bdc3c7;\n\tdisplay: block;\n\theight: 20px;\n\tleft: 0;\n\tposition: absolute;\n\ttop: 0;\n\twidth: 20px;\n\ttext-align: center;\n\tline-height: 20px;\n\tfont-size: 20px;\n\t-webkit-transition: color .25s linear;\n\t-moz-transition: color .25s linear;\n\t-o-transition: color .25s linear;\n\ttransition: color .25s linear;\n\t-webkit-backface-visibility: hidden\n}\n\n.checkbox .icons .first-icon-icon,.radio .icons .first-icon-icon,.checkbox .icons .second-icon,.radio .icons .second-icon {\n\tposition: absolute;\n\tleft: 0;\n\ttop: 0;\n\topacity: 1;\n\tfilter: alpha(opacity=100)\n}\n\n.checkbox .icons .second-icon,.radio .icons .second-icon {\n\topacity: 0;\n\tfilter: alpha(opacity=0)\n}\n\n.checkbox:hover .first-icon,.radio:hover .first-icon {\n\topacity: 0;\n\tfilter: alpha(opacity=0)\n}\n\n.checkbox:hover .second-icon,.radio:hover .second-icon {\n\topacity: 1;\n\tfilter: alpha(opacity=100)\n}\n\n.checkbox.checked,.radio.checked {\n\tcolor: #08c\n}\n\n.checkbox.checked .icons,.radio.checked .icons {\n\tcolor: #1abc9c\n}\n\n.checkbox.checked .first-icon,.radio.checked .first-icon {\n\topacity: 0;\n\tfilter: alpha(opacity=0)\n}\n\n.checkbox.checked .second-icon,.radio.checked .second-icon {\n\topacity: 1;\n\tfilter: alpha(opacity=100)\n}\n\n.checkbox.disabled,.radio.disabled {\n\tcursor: default;\n\tcolor: #e6e8ea\n}\n\n.checkbox.disabled .icons,.radio.disabled .icons {\n\tcolor: #e6e8ea\n}\n\n.checkbox.disabled .first-icon,.radio.disabled .first-icon {\n\topacity: 1;\n\tfilter: alpha(opacity=100)\n}\n\n.checkbox.disabled .second-icon,.radio.disabled .second-icon {\n\topacity: 0;\n\tfilter: alpha(opacity=0)\n}\n\n.checkbox.disabled.checked .icons,.radio.disabled.checked .icons {\n\tcolor: #e6e8ea\n}\n\n.checkbox.disabled.checked .first-icon,.radio.disabled.checked .first-icon {\n\topacity: 0;\n\tfilter: alpha(opacity=0)\n}\n\n.checkbox.disabled.checked .second-icon,.radio.disabled.checked .second-icon {\n\topacity: 1;\n\tfilter: alpha(opacity=100)\n}\n\n.tagsinput {\n\tbackground: white;\n\tborder: 2px solid #1abc9c;\n\tborder-radius: 6px;\n\theight: 100px;\n\tmargin-bottom: 18px;\n\tpadding: 6px 1px 1px 6px;\n\toverflow-y: auto;\n\ttext-align: left\n}\n\n.tagsinput .tag {\n\tborder-radius: 4px;\n\tbackground-color: #1abc9c;\n\tcolor: #fff;\n\tcursor: pointer;\n\tmargin-right: 5px;\n\tmargin-bottom: 5px;\n\toverflow: hidden;\n\tline-height: 15px;\n\tpadding: 6px 13px 8px 19px;\n\tposition: relative;\n\tvertical-align: middle;\n\tdisplay: inline-block;\n\tzoom: 1;\n\t*display: inline;\n\t-webkit-transition: .14s linear;\n\t-moz-transition: .14s linear;\n\t-o-transition: .14s linear;\n\ttransition: .14s linear;\n\t-webkit-backface-visibility: hidden\n}\n\n.tagsinput .tag:hover {\n\tbackground-color: #08c;\n\tcolor: #fff;\n\tpadding-left: 12px;\n\tpadding-right: 20px\n}\n\n.tagsinput .tag:hover .tagsinput-remove-link {\n\tcolor: #fff;\n\topacity: 1;\n\tdisplay: block\\9\n}\n\n.tagsinput input {\n\tbackground: transparent;\n\tborder: 0;\n\tcolor: #34495e;\n\tfont-family: \"Lato\",sans-serif;\n\tfont-size: 14px;\n\tmargin: 0;\n\tpadding: 0 0 0 5px;\n\toutline: 0;\n\tmargin-right: 5px;\n\tmargin-bottom: 5px;\n\twidth: 12px\n}\n\n.tagsinput-remove-link {\n\tbottom: 0;\n\tcolor: #fff;\n\tcursor: pointer;\n\tfont-size: 12px;\n\topacity: 0;\n\tpadding: 7px 7px 5px 0;\n\tposition: absolute;\n\tright: 0;\n\ttext-align: right;\n\ttext-decoration: none;\n\ttop: 0;\n\twidth: 100%;\n\tz-index: 2;\n\tdisplay: none\\9\n}\n\n.tagsinput-remove-link:before {\n\tcolor: #fff;\n\tcontent: \"\\e00b\";\n\tfont-family: \"Flat-UI-Icons\"\n}\n\n.tagsinput-add-container {\n\tvertical-align: middle;\n\tdisplay: inline-block;\n\tzoom: 1;\n\t*display: inline\n}\n\n.tagsinput-add {\n\tbackground-color: #d6dbdf;\n\tborder-radius: 3px;\n\tcolor: #fff;\n\tcursor: pointer;\n\tmargin-bottom: 5px;\n\tpadding: 6px 9px;\n\tdisplay: inline-block;\n\tzoom: 1;\n\t*display: inline;\n\t-webkit-transition: .25s;\n\t-moz-transition: .25s;\n\t-o-transition: .25s;\n\ttransition: .25s;\n\t-webkit-backface-visibility: hidden\n}\n\n.tagsinput-add:hover {\n\tbackground-color: #1abc9c\n}\n\n.tagsinput-add:before {\n\tcontent: \"\\e009\";\n\tfont-family: \"Flat-UI-Icons\"\n}\n\n.tags_clear {\n\tclear: both;\n\twidth: 100%;\n\theight: 0\n}\n\n.not_valid {\n\tbackground: #fbd8db!important;\n\tcolor: #90111a!important\n}\n\n.progress {\n\tbackground: #ebedef;\n\tborder-radius: 32px;\n\theight: 12px;\n\t-webkit-box-shadow: none;\n\t-moz-box-shadow: none;\n\tbox-shadow: none;\n\tfilter: unquote(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\")\n}\n\n.progress .bar {\n\tbackground: #1abc9c;\n\t-webkit-box-shadow: none!important;\n\t-moz-box-shadow: none!important;\n\tbox-shadow: none!important;\n\tfilter: unquote(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\")\n}\n\n.progress .bar-success {\n\tbackground-color: #2ecc71;\n\tfilter: unquote(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\")\n}\n\n.progress .bar-warning {\n\tbackground-color: #f1c40f;\n\tfilter: unquote(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\")\n}\n\n.progress .bar-danger {\n\tbackground-color: #e74c3c;\n\tfilter: unquote(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\")\n}\n\n.progress .bar-info {\n\tbackground-color: #3498db;\n\tfilter: unquote(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\")\n}\n\n.ui-slider {\n\tbackground: #ebedef;\n\tborder-radius: 32px;\n\theight: 12px;\n\t-webkit-box-shadow: none;\n\t-moz-box-shadow: none;\n\tbox-shadow: none;\n\tfilter: unquote(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\");\n\tmargin-bottom: 20px;\n\tposition: relative\n}\n\n.ui-slider .bar {\n\tbackground: #1abc9c;\n\t-webkit-box-shadow: none!important;\n\t-moz-box-shadow: none!important;\n\tbox-shadow: none!important;\n\tfilter: unquote(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\")\n}\n\n.ui-slider .bar-success {\n\tbackground-color: #2ecc71;\n\tfilter: unquote(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\")\n}\n\n.ui-slider .bar-warning {\n\tbackground-color: #f1c40f;\n\tfilter: unquote(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\")\n}\n\n.ui-slider .bar-danger {\n\tbackground-color: #e74c3c;\n\tfilter: unquote(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\")\n}\n\n.ui-slider .bar-info {\n\tbackground-color: #3498db;\n\tfilter: unquote(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\")\n}\n\n.ui-slider-handle {\n\tbackground-color: #08c;\n\tborder-radius: 50%;\n\tcursor: pointer;\n\theight: 18px;\n\tmargin-left: -9px;\n\tposition: absolute;\n\ttop: -3px;\n\twidth: 18px;\n\tz-index: 2;\n\t-webkit-transition: background .25s;\n\t-moz-transition: background .25s;\n\t-o-transition: background .25s;\n\ttransition: background .25s;\n\t-webkit-backface-visibility: hidden\n}\n\n.ui-slider-handle[style*='100'] {\n\tmargin-left: -15px\n}\n\n.ui-slider-handle:hover,.ui-slider-handle:focus {\n\tbackground-color: #48c9b0;\n\toutline: 0\n}\n\n.ui-slider-handle:active {\n\tbackground-color: #08c\n}\n\n.ui-slider-range {\n\tbackground-color: #1abc9c;\n\tborder-radius: 30px 0 0 30px;\n\tdisplay: block;\n\theight: 100%;\n\tposition: absolute;\n\tz-index: 1\n}\n\n.ui-slider-segment {\n\tbackground-color: #d9dbdd;\n\tborder-radius: 50%;\n\tfloat: left;\n\theight: 6px;\n\tmargin: 3px -6px 0 0;\n\twidth: 6px\n}\n\n.ui-slider-value {\n\tfloat: right;\n\tfont-weight: 500;\n\tmargin-top: 12px\n}\n\n.ui-slider-value.first {\n\tclear: left;\n\tfloat: left\n}\n\n.pager {\n\tbackground-color: #34495e;\n\tborder-radius: 6px;\n\tcolor: #fff;\n\tfont-size: 16px;\n\tfont-weight: 700;\n\tdisplay: inline-block;\n\tzoom: 1;\n\t*display: inline\n}\n\n.pager li:first-child>a,.pager li:first-child>span {\n\tborder-left: none;\n\t-webkit-border-radius: 6px 0 0 6px;\n\t-moz-border-radius: 6px 0 0 6px;\n\tborder-radius: 6px 0 0 6px\n}\n\n.pager li.pager-center {\n\tpadding: 9px 15px 10px;\n\tpadding-left: 0;\n\tpadding-right: 0;\n\tdisplay: inline-block;\n\tzoom: 1;\n\t*display: inline\n}\n\n.pager li>a,.pager li>span {\n\tbackground: 0;\n\tborder: 0;\n\tborder-left: 2px solid #2c3e50;\n\tcolor: #fff;\n\tpadding: 9px 15px 10px;\n\ttext-decoration: none;\n\twhite-space: nowrap;\n\t-webkit-border-radius: 0 6px 6px 0;\n\t-moz-border-radius: 0 6px 6px 0;\n\tborder-radius: 0 6px 6px 0\n}\n\n.pager li>a:hover,.pager li>span:hover,.pager li>a:focus,.pager li>span:focus {\n\tbackground-color: #2c3e50\n}\n\n.pager li>a:active,.pager li>span:active {\n\tbackground-color: #2c3e50\n}\n\n.pager li>a [class*=\"fui-\"]+span,.pager li>span [class*=\"fui-\"]+span {\n\tmargin-left: 8px\n}\n\n.pager li>a span+[class*=\"fui-\"],.pager li>span span+[class*=\"fui-\"] {\n\tmargin-left: 8px\n}\n\n.pagination {\n\tposition: relative\n}\n\n.pagination ul {\n\tbackground: #d6dbdf;\n\tcolor: #fff;\n\tvertical-align: top;\n\t-webkit-border-radius: 6px;\n\t-moz-border-radius: 6px;\n\tborder-radius: 6px;\n\t-webkit-box-shadow: none;\n\t-moz-box-shadow: none;\n\tbox-shadow: none\n}\n\n.pagination ul li {\n\tdisplay: inline-block;\n\tmargin-right: -3px;\n\tvertical-align: top\n}\n\n.pagination ul li.active>a,.pagination ul li.active>span {\n\tbackground-color: #1abc9c;\n\tcolor: #fff\n}\n\n.pagination ul li.active.previous>a,.pagination ul li.active.next>a,.pagination ul li.active.previous>span,.pagination ul li.active.next>span {\n\tmargin: 0\n}\n\n.pagination ul li.active.previous>a,.pagination ul li.active.next>a,.pagination ul li.active.previous>span,.pagination ul li.active.next>span,.pagination ul li.active.previous>a:hover,.pagination ul li.active.next>a:hover,.pagination ul li.active.previous>span:hover,.pagination ul li.active.next>span:hover,.pagination ul li.active.previous>a:focus,.pagination ul li.active.next>a:focus,.pagination ul li.active.previous>span:focus,.pagination ul li.active.next>span:focus {\n\tbackground-color: #1abc9c;\n\tcolor: #fff\n}\n\n.pagination ul li:first-child {\n\t-webkit-border-radius: 6px 0 0 6px;\n\t-moz-border-radius: 6px 0 0 6px;\n\tborder-radius: 6px 0 0 6px\n}\n\n.pagination ul li:first-child>a,.pagination ul li:first-child>span {\n\t-webkit-border-radius: 6px 0 0 6px;\n\t-moz-border-radius: 6px 0 0 6px;\n\tborder-radius: 6px 0 0 6px\n}\n\n.pagination ul li:first-child.previous+li>a,.pagination ul li:first-child.previous+li>span {\n\tborder-left-width: 5px\n}\n\n.pagination ul li:first-child>a,.pagination ul li:first-child>span {\n\tborder-left: none\n}\n\n.pagination ul li:last-child {\n\tmargin-right: 0;\n\t-webkit-border-radius: 0 6px 6px 0;\n\t-moz-border-radius: 0 6px 6px 0;\n\tborder-radius: 0 6px 6px 0\n}\n\n.pagination ul li:last-child>a,.pagination ul li:last-child>span,.pagination ul li:last-child>a:hover,.pagination ul li:last-child>span:hover,.pagination ul li:last-child>a:focus,.pagination ul li:last-child>span:focus {\n\t-webkit-border-radius: 0 6px 6px 0;\n\t-moz-border-radius: 0 6px 6px 0;\n\tborder-radius: 0 6px 6px 0\n}\n\n.pagination ul li.previous>a,.pagination ul li.next>a,.pagination ul li.previous>span,.pagination ul li.next>span {\n\tbackground: transparent;\n\tborder: 0;\n\tborder-right: 2px solid #e4e7ea;\n\tfont-size: 15.988px;\n\tmargin: 0 9px 0 0;\n\tpadding: 12px 17px;\n\tmin-width: auto;\n\t-webkit-border-radius: 6px 0 0 6px;\n\t-moz-border-radius: 6px 0 0 6px;\n\tborder-radius: 6px 0 0 6px;\n\t-webkit-box-shadow: none!important;\n\t-moz-box-shadow: none!important;\n\tbox-shadow: none!important\n}\n\n.pagination ul li.previous>a,.pagination ul li.next>a,.pagination ul li.previous>span,.pagination ul li.next>span,.pagination ul li.previous>a:hover,.pagination ul li.next>a:hover,.pagination ul li.previous>span:hover,.pagination ul li.next>span:hover,.pagination ul li.previous>a:focus,.pagination ul li.next>a:focus,.pagination ul li.previous>span:focus,.pagination ul li.next>span:focus {\n\tborder-color: #e4e7ea!important\n}\n\n.pagination ul li.next {\n\tmargin-left: 9px\n}\n\n.pagination ul li.next>a,.pagination ul li.next>span {\n\tborder-left: 2px solid #e4e7ea;\n\tborder-right: 0;\n\tmargin: 0;\n\t-webkit-border-radius: 0 6px 6px 0;\n\t-moz-border-radius: 0 6px 6px 0;\n\tborder-radius: 0 6px 6px 0\n}\n\n.pagination ul li.active>a,.pagination ul li.active>span {\n\tbackground-color: #fff;\n\tborder-color: #fff;\n\tborder-width: 2px!important;\n\tcolor: #d6dbdf;\n\tmargin: 10px 5px 9px\n}\n\n.pagination ul li.active>a:hover,.pagination ul li.active>span:hover,.pagination ul li.active>a:focus,.pagination ul li.active>span:focus {\n\tbackground-color: #fff;\n\tborder-color: #fff;\n\tcolor: #d6dbdf;\n\t-webkit-box-shadow: none;\n\t-moz-box-shadow: none;\n\tbox-shadow: none\n}\n\n.pagination ul li.active.previous,.pagination ul li.active.next {\n\tborder-color: #e4e7ea\n}\n\n.pagination ul li.active.previous {\n\tmargin-right: 6px\n}\n\n.pagination ul li>a,.pagination ul li>span {\n\tbackground: #fff;\n\tborder: 5px solid #d6dbdf;\n\tcolor: #fff;\n\tline-height: 16px;\n\tmin-height: 17px;\n\tmin-width: auto;\n\toutline: 0;\n\tpadding: 0 4px;\n\tmargin: 7px 2px 6px;\n\ttext-align: center;\n\t-webkit-border-radius: 50px;\n\t-moz-border-radius: 50px;\n\tborder-radius: 50px;\n\t-webkit-transition: background .2s ease-out,border-color 0s ease-out,color .2s ease-out;\n\t-moz-transition: background .2s ease-out,border-color 0s ease-out,color .2s ease-out;\n\t-o-transition: background .2s ease-out,border-color 0s ease-out,color .2s ease-out;\n\ttransition: background .2s ease-out,border-color 0s ease-out,color .2s ease-out;\n\t-webkit-backface-visibility: hidden\n}\n\n.pagination ul li>a:hover,.pagination ul li>span:hover,.pagination ul li>a:focus,.pagination ul li>span:focus {\n\tbackground-color: #1abc9c;\n\tborder-color: #1abc9c;\n\tcolor: #fff;\n\t-webkit-transition: background .2s ease-out,border-color .2s ease-out,color .2s ease-out;\n\t-moz-transition: background .2s ease-out,border-color .2s ease-out,color .2s ease-out;\n\t-o-transition: background .2s ease-out,border-color .2s ease-out,color .2s ease-out;\n\ttransition: background .2s ease-out,border-color .2s ease-out,color .2s ease-out;\n\t-webkit-backface-visibility: hidden\n}\n\n.pagination ul li>a:active,.pagination ul li>span:active {\n\tbackground-color: #08c;\n\tborder-color: #08c;\n\tcolor: #fff\n}\n\n.pagination>.btn.previous,.pagination>.btn.next {\n\tmargin-right: 8px;\n\tfont-size: 14px;\n\tpadding-left: 23px;\n\tpadding-right: 23px\n}\n\n.pagination>.btn.previous [class*=\"fui-\"],.pagination>.btn.next [class*=\"fui-\"] {\n\tfont-size: 16px;\n\tmargin-left: -2px;\n\tmargin-top: -2px\n}\n\n.pagination>.btn.next {\n\tmargin-left: 8px;\n\tmargin-right: 0\n}\n\n.pagination>.btn.next [class*=\"fui-\"] {\n\tmargin-right: -2px;\n\tmargin-left: 4px\n}\n\n.tooltip {\n\tfont-size: 14px\n}\n\n.tooltip.in {\n\topacity: 1\n}\n\n.tooltip.top {\n\tpadding-bottom: 9px\n}\n\n.tooltip.top .tooltip-arrow {\n\tborder-top-color: #34495e;\n\tborder-width: 9px 9px 0;\n\tbottom: 0;\n\tmargin-left: -9px\n}\n\n.tooltip.right .tooltip-arrow {\n\tborder-right-color: #34495e;\n\tborder-width: 9px 9px 9px 0;\n\tmargin-top: -9px;\n\tleft: -3px\n}\n\n.tooltip.bottom {\n\tpadding-top: 8px\n}\n\n.tooltip.bottom .tooltip-arrow {\n\tborder-bottom-color: #34495e;\n\tborder-width: 0 9px 9px;\n\tmargin-left: -9px;\n\ttop: -1px\n}\n\n.tooltip.left .tooltip-arrow {\n\tborder-left-color: #34495e;\n\tborder-width: 9px 0 9px 9px;\n\tmargin-top: -9px;\n\tright: -3px\n}\n\n.tooltip-inner {\n\tbackground-color: #34495e;\n\tline-height: 17.99px;\n\tpadding: 12px 12px;\n\ttext-align: center;\n\twidth: 183px;\n\t-webkit-border-radius: 6px;\n\t-moz-border-radius: 6px;\n\tborder-radius: 6px\n}\n\n.dropdown-menu {\n\tbackground-color: #f3f4f5;\n\tborder: 0;\n\tdisplay: block;\n\tmargin-top: 8px;\n\topacity: 0;\n\tpadding: 0;\n\tvisibility: hidden;\n\twidth: 100%;\n\t-webkit-box-shadow: none;\n\t-moz-box-shadow: none;\n\tbox-shadow: none;\n\t-webkit-transition: .25s;\n\t-moz-transition: .25s;\n\t-o-transition: .25s;\n\ttransition: .25s;\n\t-webkit-backface-visibility: hidden\n}\n\n.dropdown-menu.typeahead {\n\tdisplay: none;\n\topacity: 1;\n\tvisibility: visible;\n\twidth: auto;\n\tmargin-top: 2px\n}\n\n.open>.dropdown-menu {\n\tmargin-top: 18px;\n\topacity: 1;\n\tvisibility: visible\n}\n\n.dropdown-menu li:first-child dt+a {\n\tborder-radius: 0\n}\n\n.dropdown-menu li:first-child>a {\n\tborder-radius: 6px 6px 0 0;\n\tpadding-top: 8px\n}\n\n.dropdown-menu li:last-child>a {\n\tborder-radius: 0 0 6px 6px;\n\tpadding-bottom: 10px\n}\n\n.dropdown-menu li.active>a,.dropdown-menu li.selected>a,.dropdown-menu li.active>a.highlighted,.dropdown-menu li.selected>a.highlighted {\n\tbackground: #1abc9c;\n\tcolor: #fff\n}\n\n.dropdown-menu li.active>a:hover,.dropdown-menu li.selected>a:hover,.dropdown-menu li.active>a.highlighted:hover,.dropdown-menu li.selected>a.highlighted:hover,.dropdown-menu li.active>a:focus,.dropdown-menu li.selected>a:focus,.dropdown-menu li.active>a.highlighted:focus,.dropdown-menu li.selected>a.highlighted:focus {\n\tbackground: #08c;\n\tcolor: #fff\n}\n\n.dropdown-menu li>a {\n\tcolor: rgba(52,73,94,0.75);\n\tpadding: 6px 15px 8px;\n\ttext-decoration: none;\n\t*zoom: 1;\n\t-webkit-transition: background-color .25s;\n\t-moz-transition: background-color .25s;\n\t-o-transition: background-color .25s;\n\ttransition: background-color .25s;\n\t-webkit-backface-visibility: hidden\n}\n\n.dropdown-menu li>a:before,.dropdown-menu li>a:after {\n\tdisplay: table;\n\tcontent: \"\"\n}\n\n.dropdown-menu li>a:after {\n\tclear: both\n}\n\n.dropdown-menu li>a:hover,.dropdown-menu li>a:active,.dropdown-menu li>a:focus {\n\tbackground: #e1e4e7;\n\tcolor: inherit;\n\toutline: 0\n}\n\n.dropdown-menu li>a.highlighted {\n\tbackground: #c9cfd4;\n\tcolor: #fff\n}\n\n.dropdown-menu li>a.highlighted:hover,.dropdown-menu li>a.highlighted:focus {\n\tbackground: #bac1c8;\n\tcolor: #fff\n}\n\n.dropdown-menu li>a:before {\n\tfloat: right;\n\tmargin-top: 3px\n}\n\n.dropdown-menu li dt {\n\tfont-weight: 300;\n\tmargin-bottom: 3px;\n\tmargin-top: 12px;\n\tpadding: 0 15px\n}\n\n.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu {\n\tmargin-bottom: 8px\n}\n\n.dropup .dropdown-arrow,.navbar-fixed-bottom .dropdown .dropdown-arrow {\n\tborder-bottom: 0;\n\tborder-top: 8px outset #f3f4f5;\n\tbottom: 100%;\n\ttop: auto\n}\n\n.navbar-fixed-bottom .nav>li>ul:before {\n\tborder-bottom: 0;\n\tborder-top: 9px outset #34495e;\n\tbottom: 4px;\n\ttop: auto\n}\n\n.open.dropup>.dropdown-menu {\n\tmargin-bottom: 18px\n}\n\n.open.dropup>.dropdown-arrow {\n\tmargin-bottom: 10px\n}\n\n.open.dropup>.dropdown-arrow.dropdown-arrow-inverse {\n\tborder-top-color: #34495e\n}\n\n.open>.dropdown-arrow {\n\tmargin-top: 9px;\n\topacity: 1\n}\n\n.dropdown-arrow {\n\tborder-style: solid;\n\tborder-width: 0 9px 9px 9px;\n\tborder-color: transparent transparent #f3f4f5 transparent;\n\theight: 0;\n\tmargin-top: 0;\n\topacity: 0;\n\tposition: absolute;\n\tright: 13px;\n\ttop: 100%;\n\twidth: 0;\n\tz-index: 10;\n\t-webkit-transform: rotate(360deg);\n\t-webkit-transition: .25s;\n\t-moz-transition: .25s;\n\t-o-transition: .25s;\n\ttransition: .25s;\n\t-webkit-backface-visibility: hidden\n}\n\n.dropdown-inverse {\n\tbackground-color: #34495e;\n\tcolor: #ccc;\n\tpadding: 4px 0 6px\n}\n\n.dropdown-inverse li {\n\tmargin: 0 4px -2px\n}\n\n.dropdown-inverse li:first-child>a,.dropdown-inverse li:last-child>a {\n\tborder-radius: 2px;\n\tpadding-bottom: 7px;\n\tpadding-top: 5px\n}\n\n.dropdown-inverse li:first-child dt+a,.dropdown-inverse li:last-child dt+a {\n\tborder-radius: 2px\n}\n\n.dropdown-inverse li.active>a,.dropdown-inverse li.selected>a {\n\tbackground: #1abc9c;\n\tcolor: #fff;\n\tposition: relative;\n\tz-index: 1\n}\n\n.dropdown-inverse li dt {\n\tpadding-left: 11px;\n\tpadding-right: 11px\n}\n\n.dropdown-inverse li .divider {\n\tmargin-left: 11px;\n\tmargin-right: 11px\n}\n\n.dropdown-inverse li>a {\n\tborder-radius: 2px;\n\tcolor: #fff;\n\tpadding: 5px 11px 7px\n}\n\n.dropdown-inverse li>a:hover,.dropdown-inverse li>a:active,.dropdown-inverse li>a:focus {\n\tbackground: #2c3e50\n}\n\n.dropdown-inverse li>a.highlighted {\n\tbackground: #526476\n}\n\n.dropdown-inverse li>a.highlighted:hover,.dropdown-inverse li>a.highlighted:focus {\n\tbackground: #677786\n}\n\n.dropdown-inverse li .divider {\n\tbackground-color: #526476;\n\tborder-bottom-color: #526476\n}\n\n.has-switch {\n\tborder-radius: 30px;\n\tdisplay: inline-block;\n\tcursor: pointer;\n\tline-height: 1.231;\n\toverflow: hidden;\n\tposition: relative;\n\ttext-align: left;\n\twidth: 80px;\n\t-webkit-mask: url('../img/switch-mask.png') 0 0 no-repeat;\n\tmask: url('../img/switch-mask.png') 0 0 no-repeat;\n\t-webkit-user-select: none;\n\t-moz-user-select: none;\n\t-ms-user-select: none;\n\t-o-user-select: none;\n\tuser-select: none\n}\n\n.has-switch.deactivate {\n\topacity: .5;\n\tfilter: alpha(opacity=50);\n\tcursor: default!important\n}\n\n.has-switch.deactivate label,.has-switch.deactivate span {\n\tcursor: default!important\n}\n\n.has-switch>div {\n\twidth: 162%;\n\tposition: relative;\n\ttop: 0\n}\n\n.has-switch>div.switch-animate {\n\t-webkit-transition: left .25s ease-out;\n\t-moz-transition: left .25s ease-out;\n\t-o-transition: left .25s ease-out;\n\ttransition: left .25s ease-out;\n\t-webkit-backface-visibility: hidden\n}\n\n.has-switch>div.switch-off {\n\tleft: -63%\n}\n\n.has-switch>div.switch-off label {\n\tbackground-color: #7f8c9a;\n\tborder-color: #bdc3c7;\n\t-webkit-box-shadow: -1px 0 0 rgba(255,255,255,0.5);\n\t-moz-box-shadow: -1px 0 0 rgba(255,255,255,0.5);\n\tbox-shadow: -1px 0 0 rgba(255,255,255,0.5)\n}\n\n.has-switch>div.switch-on {\n\tleft: 0\n}\n\n.has-switch>div.switch-on label {\n\tbackground-color: #08c\n}\n\n.has-switch input[type=checkbox] {\n\tdisplay: none\n}\n\n.has-switch span {\n\tcursor: pointer;\n\tfont-size: 14.994px;\n\tfont-weight: 700;\n\tfloat: left;\n\theight: 29px;\n\tline-height: 19px;\n\tmargin: 0;\n\tpadding-bottom: 6px;\n\tpadding-top: 5px;\n\tposition: relative;\n\ttext-align: center;\n\twidth: 50%;\n\tz-index: 1;\n\t-webkit-box-sizing: border-box;\n\t-moz-box-sizing: border-box;\n\tbox-sizing: border-box;\n\t-webkit-transition: .25s ease-out;\n\t-moz-transition: .25s ease-out;\n\t-o-transition: .25s ease-out;\n\ttransition: .25s ease-out;\n\t-webkit-backface-visibility: hidden\n}\n\n.has-switch span.switch-left {\n\tborder-radius: 30px 0 0 30px;\n\tbackground-color: #34495e;\n\tcolor: #ccc;\n\tborder-left: 1px solid transparent\n}\n\n.has-switch span.switch-right {\n\tborder-radius: 0 30px 30px 0;\n\tbackground-color: #bdc3c7;\n\tcolor: #fff;\n\ttext-indent: 7px\n}\n\n.has-switch span.switch-right [class*=\"fui-\"] {\n\ttext-indent: 0\n}\n\n.has-switch label {\n\tborder: 4px solid #34495e;\n\tborder-radius: 50%;\n\tfloat: left;\n\theight: 21px;\n\tmargin: 0 -15px 0 -14px;\n\tpadding: 0;\n\tposition: relative;\n\tvertical-align: middle;\n\twidth: 21px;\n\tz-index: 100;\n\t-webkit-transition: .25s ease-out;\n\t-moz-transition: .25s ease-out;\n\t-o-transition: .25s ease-out;\n\ttransition: .25s ease-out;\n\t-webkit-backface-visibility: hidden\n}\n\n.switch-square {\n\tborder-radius: 6px;\n\t-webkit-mask: url('../img/switch-mask.png') 0 0 no-repeat;\n\tmask: url('../img/switch-mask.png') 0 0 no-repeat\n}\n\n.switch-square>div.switch-off label {\n\tborder-color: #7f8c9a;\n\tborder-radius: 6px 0 0 6px\n}\n\n.switch-square span.switch-left {\n\tborder-radius: 6px 0 0 6px\n}\n\n.switch-square span.switch-left [class*=\"fui-\"] {\n\ttext-indent: -10px\n}\n\n.switch-square span.switch-right {\n\tborder-radius: 0 6px 6px 0\n}\n\n.switch-square span.switch-right [class*=\"fui-\"] {\n\ttext-indent: 5px\n}\n\n.switch-square label {\n\tborder-radius: 0 6px 6px 0;\n\tborder-color: #1abc9c\n}\n\n.share {\n\tbackground-color: #eff0f2;\n\tposition: relative;\n\t-webkit-border-radius: 6px;\n\t-moz-border-radius: 6px;\n\tborder-radius: 6px\n}\n\n.share:before {\n\tcontent: \"\";\n\tborder-style: solid;\n\tborder-width: 0 9px 9px 9px;\n\tborder-color: transparent transparent #eff0f2 transparent;\n\theight: 0;\n\tposition: absolute;\n\tleft: 23px;\n\ttop: -9px;\n\twidth: 0;\n\t-webkit-transform: rotate(360deg)\n}\n\n.share ul {\n\tlist-style-type: none;\n\tmargin: 0;\n\tpadding: 15px\n}\n\n.share li {\n\tpadding-top: 11px;\n\t*zoom: 1\n}\n\n.share li:before,.share li:after {\n\tdisplay: table;\n\tcontent: \"\"\n}\n\n.share li:after {\n\tclear: both\n}\n\n.share li:first-child {\n\tpadding-top: 0\n}\n\n.share .toggle {\n\tfloat: right;\n\tmargin: 0\n}\n\n.share .btn {\n\t-webkit-border-radius: 0 0 6px 6px;\n\t-moz-border-radius: 0 0 6px 6px;\n\tborder-radius: 0 0 6px 6px\n}\n\n.share-label {\n\tfloat: left;\n\tfont-size: 15px;\n\tpadding-top: 5px;\n\twidth: 50%\n}\n\n.palette {\n\tcolor: #fff;\n\tmargin: 0;\n\tpadding: 15px;\n\ttext-transform: uppercase\n}\n\n.palette dt {\n\tdisplay: block;\n\tfont-weight: 500;\n\topacity: .8;\n\tfilter: alpha(opacity=80)\n}\n\n.palette dd {\n\tfont-weight: 200;\n\tmargin-left: 0;\n\topacity: .8;\n\tfilter: alpha(opacity=80)\n}\n\n.palette-turquoise {\n\tbackground-color: #1abc9c\n}\n\n.palette-green-sea {\n\tbackground-color: #08c\n}\n\n.palette-emerland {\n\tbackground-color: #2ecc71\n}\n\n.palette-nephritis {\n\tbackground-color: #27ae60\n}\n\n.palette-peter-river {\n\tbackground-color: #3498db\n}\n\n.palette-belize-hole {\n\tbackground-color: #2980b9\n}\n\n.palette-amethyst {\n\tbackground-color: #9b59b6\n}\n\n.palette-wisteria {\n\tbackground-color: #8e44ad\n}\n\n.palette-wet-asphalt {\n\tbackground-color: #34495e\n}\n\n.palette-midnight-blue {\n\tbackground-color: #2c3e50\n}\n\n.palette-sun-flower {\n\tbackground-color: #f1c40f\n}\n\n.palette-orange {\n\tbackground-color: #f39c12\n}\n\n.palette-carrot {\n\tbackground-color: #e67e22\n}\n\n.palette-pumpkin {\n\tbackground-color: #d35400\n}\n\n.palette-alizarin {\n\tbackground-color: #e74c3c\n}\n\n.palette-pomegranate {\n\tbackground-color: #c0392b\n}\n\n.palette-clouds {\n\tbackground-color: #ecf0f1\n}\n\n.palette-silver {\n\tbackground-color: #bdc3c7\n}\n\n.palette-concrete {\n\tbackground-color: #95a5a6\n}\n\n.palette-asbestos {\n\tbackground-color: #7f8c8d\n}\n\n.palette-clouds {\n\tcolor: #bdc3c7\n}\n\n.palette-paragraph {\n\tcolor: #7f8c8d;\n\tfont-size: 12px;\n\tline-height: 17px\n}\n\n.palette-paragraph span {\n\tcolor: #bdc3c7\n}\n\n.palette-headline {\n\tcolor: #7f8c8d;\n\tfont-weight: 700;\n\tmargin-top: -5px\n}\n\n.tile {\n\tbackground-color: #eff0f2;\n\tborder-radius: 6px;\n\tpadding: 14px;\n\tposition: relative;\n\ttext-align: center\n}\n\n.tile.tile-hot:before {\n\tbackground: url(../img/tile/ribbon.png) 0 0 no-repeat;\n\tbackground-size: 82px 82px;\n\tcontent: '';\n\theight: 82px;\n\tposition: absolute;\n\tright: -4px;\n\ttop: -4px;\n\twidth: 82px\n}\n\n.tile p {\n\tfont-size: 15px;\n\tmargin-bottom: 33px\n}\n\n.tile-image {\n\theight: 100px;\n\tmargin: 31px 0 27px;\n\tvertical-align: bottom\n}\n\n.tile-image.big-illustration {\n\theight: 111px;\n\tmargin-top: 20px;\n\twidth: 112px\n}\n\n.tile-title {\n\tfont-size: 20px;\n\tmargin: 0\n}\n\n@media only screen and (-webkit-min-device-pixel-ratio:2),only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (-moz-min-device-pixel-ratio:2),only screen and (-o-min-device-pixel-ratio:3/2),only screen and (-o-min-device-pixel-ratio:2/1),only screen and (-moz-min-device-pixel-ratio:1.5),only screen and (min-device-pixel-ratio:1.5),only screen and (min-device-pixel-ratio:2) {\n\t.tile.tile-hot:before {\n\t\tbackground-image: url(../img/tile/ribbon-2x.png)\n\t}\n}\n\n.todo {\n\tbackground-color: #2c3e50;\n\tcolor: #798795;\n\tmargin-bottom: 20px;\n\t-webkit-border-radius: 8px 8px 6px 6px;\n\t-moz-border-radius: 8px 8px 6px 6px;\n\tborder-radius: 8px 8px 6px 6px\n}\n\n.todo ul {\n\tmargin: 0;\n\tlist-style-type: none\n}\n\n.todo li {\n\tbackground: #34495e url(../img/todo/todo.png) 92% center no-repeat;\n\tbackground-size: 20px 20px;\n\tcursor: pointer;\n\tmargin-top: 2px;\n\tpadding: 18px 42px 17px 25px;\n\tposition: relative;\n\t-webkit-transition: .25s;\n\t-moz-transition: .25s;\n\t-o-transition: .25s;\n\ttransition: .25s;\n\t-webkit-backface-visibility: hidden\n}\n\n.todo li:first-child {\n\tmargin-top: 0\n}\n\n.todo li:last-child {\n\t-webkit-border-radius: 0 0 6px 6px;\n\t-moz-border-radius: 0 0 6px 6px;\n\tborder-radius: 0 0 6px 6px;\n\tpadding-bottom: 18px\n}\n\n.todo li.todo-done {\n\tbackground: transparent url(../img/todo/done.png) 92% center no-repeat;\n\tbackground-size: 20px 20px;\n\tcolor: #1abc9c\n}\n\n.todo li.todo-done .todo-name {\n\tcolor: #1abc9c\n}\n\n.todo-search {\n\tposition: relative;\n\tbackground: #1abc9c;\n\tbackground-size: 16px 16px;\n\tborder-radius: 6px 6px 0 0;\n\tcolor: #34495e;\n\tpadding: 19px 25px 20px\n}\n\n.todo-search:before {\n\tposition: absolute;\n\tfont-family: 'Flat-UI-Icons';\n\tcontent: \"\\e01c\";\n\tfont-size: 16px;\n\tdisplay: inline-block;\n\ttop: 50%;\n\tleft: 92%;\n\tmargin: -0.5em 0 0 -1em\n}\n\ninput.todo-search-field {\n\tbackground: 0;\n\tborder: 0;\n\tcolor: #34495e;\n\tfont-size: 19px;\n\tfont-weight: 700;\n\tmargin: 0;\n\tline-height: 23px;\n\tpadding: 5px 0;\n\ttext-indent: 0;\n\t-webkit-box-shadow: none;\n\t-moz-box-shadow: none;\n\tbox-shadow: none\n}\n\ninput.todo-search-field:-moz-placeholder {\n\tcolor: #34495e\n}\n\ninput.todo-search-field::-webkit-input-placeholder {\n\tcolor: #34495e\n}\n\ninput.todo-search-field.placeholder {\n\tcolor: #34495e\n}\n\n.todo-icon {\n\tfloat: left;\n\tfont-size: 24px;\n\tpadding: 11px 22px 0 0\n}\n\n.todo-content {\n\tpadding-top: 1px;\n\toverflow: hidden\n}\n\n.todo-name {\n\tcolor: #fff;\n\tfont-size: 17px;\n\tmargin: 1px 0 3px\n}\n\n@media only screen and (-webkit-min-device-pixel-ratio:2),only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (-moz-min-device-pixel-ratio:2),only screen and (-o-min-device-pixel-ratio:3/2),only screen and (-o-min-device-pixel-ratio:2/1),only screen and (-moz-min-device-pixel-ratio:1.5),only screen and (min-device-pixel-ratio:1.5),only screen and (min-device-pixel-ratio:2) {\n\t.todo li {\n\t\tbackground-image: url(../img/todo/todo-2x.png)\n\t}\n\n\t.todo li.todo-done {\n\t\tbackground-image: url(../img/todo/done-2x.png)\n\t}\n\n\t.todo-search {\n\t\tbackground-image: url(../img/todo/search-2x.png)\n\t}\n}\n\nfooter {\n\tbackground-color: #edeff1;\n\tcolor: #bac1c8;\n\tfont-size: 15px;\n\tpadding: 0\n}\n\nfooter a {\n\tcolor: #9aa4af;\n\tfont-weight: 700\n}\n\nfooter p {\n\tfont-size: 15px;\n\tline-height: 20px\n}\n\n.footer-title {\n\tmargin: 0 0 22px;\n\tpadding-top: 21px\n}\n\n.footer-brand {\n\tdisplay: block;\n\tmargin-bottom: 26px;\n\twidth: 220px\n}\n\n.footer-brand img {\n\twidth: 216px\n}\n\n.footer-banner {\n\tbackground-color: #1abc9c;\n\tcolor: #d1f2eb;\n\tmargin-left: 42px;\n\tmin-height: 286px;\n\tpadding: 0 30px 30px\n}\n\n.footer-banner .footer-title {\n\tcolor: #fff\n}\n\n.footer-banner a {\n\tcolor: #b7f5e9;\n\ttext-decoration: underline\n}\n\n.footer-banner a:hover {\n\ttext-decoration: none\n}\n\n.footer-banner ul {\n\tlist-style-type: none;\n\tmargin: 0 0 26px\n}\n\n.footer-banner ul li {\n\tborder-top: 1px solid #1bc5a3;\n\tline-height: 19px;\n\tpadding: 6px 0\n}\n\n.footer-banner ul li:first-child {\n\tborder-top: 0;\n\tpadding-top: 1px\n}\n\n.video-js {\n\tbackground-color: transparent;\n\tmargin-top: -95px;\n\tposition: relative;\n\tpadding: 0;\n\tfont-size: 10px;\n\tvertical-align: middle;\n\t-webkit-border-radius: 6px 6px 0 0;\n\t-moz-border-radius: 6px 6px 0 0;\n\tborder-radius: 6px 6px 0 0;\n\t-webkit-backface-visibility: hidden;\n\t-moz-backface-visibility: hidden;\n\t-ms-backface-visibility: hidden;\n\tbackface-visibility: hidden\n}\n\n.video-js .vjs-tech {\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\twidth: 100%;\n\theight: 100%;\n\t-webkit-border-radius: 6px 6px 0 0;\n\t-moz-border-radius: 6px 6px 0 0;\n\tborder-radius: 6px 6px 0 0\n}\n\n.video-js:-moz-full-screen {\n\tposition: absolute\n}\n\nbody.vjs-full-window {\n\tpadding: 0;\n\tmargin: 0;\n\theight: 100%;\n\toverflow-y: auto\n}\n\n.video-js.vjs-fullscreen {\n\tposition: fixed;\n\toverflow: hidden;\n\tz-index: 1000;\n\tleft: 0;\n\ttop: 0;\n\tbottom: 0;\n\tright: 0;\n\twidth: 100%!important;\n\theight: 100%!important;\n\t_position: absolute\n}\n\n.video-js:-webkit-full-screen {\n\twidth: 100%!important;\n\theight: 100%!important\n}\n\n.vjs-poster {\n\tmargin: 0 auto;\n\tpadding: 0;\n\tcursor: pointer;\n\tposition: relative;\n\twidth: 100%;\n\tmax-height: 100%;\n\t-webkit-border-radius: 6px 6px 0 0;\n\t-moz-border-radius: 6px 6px 0 0;\n\tborder-radius: 6px 6px 0 0\n}\n\n.video-js .vjs-text-track-display {\n\ttext-align: center;\n\tposition: absolute;\n\tbottom: 4em;\n\tleft: 1em;\n\tright: 1em;\n\tfont-family: \"Lato\",sans-serif\n}\n\n.video-js .vjs-text-track {\n\tdisplay: none;\n\tcolor: #fff;\n\tfont-size: 1.4em;\n\ttext-align: center;\n\tmargin-bottom: .1em;\n\tbackground: #000;\n\tbackground: rgba(0,0,0,0.5)\n}\n\n.video-js .vjs-subtitles {\n\tcolor: #fff\n}\n\n.video-js .vjs-captions {\n\tcolor: #fc6\n}\n\n.vjs-tt-cue {\n\tdisplay: block\n}\n\n.vjs-fade-in {\n\tvisibility: visible!important;\n\topacity: 1!important;\n\t-webkit-transition: visibility 0s linear 0s,opacity .3s linear;\n\t-moz-transition: visibility 0s linear 0s,opacity .3s linear;\n\t-o-transition: visibility 0s linear 0s,opacity .3s linear;\n\ttransition: visibility 0s linear 0s,opacity .3s linear;\n\t-webkit-backface-visibility: hidden\n}\n\n.vjs-fade-out {\n\tvisibility: hidden!important;\n\topacity: 0!important;\n\t-webkit-transition: visibility 0s linear 1.5s,opacity 1.5s linear;\n\t-moz-transition: visibility 0s linear 1.5s,opacity 1.5s linear;\n\t-o-transition: visibility 0s linear 1.5s,opacity 1.5s linear;\n\ttransition: visibility 0s linear 1.5s,opacity 1.5s linear;\n\t-webkit-backface-visibility: hidden\n}\n\n.vjs-controls {\n\tposition: absolute;\n\tbottom: -47px;\n\tleft: 0;\n\tright: 0;\n\tmargin: 0;\n\tpadding: 0;\n\theight: 47px;\n\tcolor: #fff;\n\tbackground: #273747;\n\t-webkit-border-radius: 0 0 6px 6px;\n\t-moz-border-radius: 0 0 6px 6px;\n\tborder-radius: 0 0 6px 6px\n}\n\n.vjs-controls.vjs-fade-out {\n\tvisibility: visible!important;\n\topacity: 1!important\n}\n\n.vjs-control {\n\tbackground-position: center center;\n\tbackground-repeat: no-repeat;\n\tposition: relative;\n\tfloat: left;\n\ttext-align: center;\n\tmargin: 0;\n\tpadding: 0;\n\theight: 18px;\n\twidth: 18px\n}\n\n.vjs-control:focus {\n\toutline: 0\n}\n\n.vjs-control div {\n\tbackground-position: center center;\n\tbackground-repeat: no-repeat\n}\n\n.vjs-control-text {\n\tborder: 0;\n\tclip: rect(0 0 0 0);\n\theight: 1px;\n\tmargin: -1px;\n\toverflow: hidden;\n\tpadding: 0;\n\tposition: absolute;\n\twidth: 1px\n}\n\n.vjs-play-control {\n\tcursor: pointer!important;\n\theight: 47px;\n\tleft: 0;\n\tposition: absolute;\n\ttop: 0;\n\twidth: 58px\n}\n\n.vjs-play-control div {\n\tposition: relative;\n\theight: 47px\n}\n\n.vjs-play-control div:before,.vjs-play-control div:after {\n\tposition: absolute;\n\tfont-family: \"Flat-UI-Icons\";\n\tcolor: #1abc9c;\n\tfont-size: 16px;\n\ttop: 50%;\n\tleft: 50%;\n\tmargin: -0.55em 0 0 -0.5em;\n\t-webkit-transition: color .25s,opacity .25s;\n\t-moz-transition: color .25s,opacity .25s;\n\t-o-transition: color .25s,opacity .25s;\n\ttransition: color .25s,opacity .25s;\n\t-webkit-backface-visibility: hidden\n}\n\n.vjs-play-control div:after {\n\tcontent: \"\\e03b\"\n}\n\n.vjs-play-control div:before {\n\tcontent: \"\\e03c\"\n}\n\n.vjs-paused .vjs-play-control:hover div:before {\n\tcolor: #08c\n}\n\n.vjs-paused .vjs-play-control div:after {\n\topacity: 0;\n\tfilter: alpha(opacity=0)\n}\n\n.vjs-paused .vjs-play-control div:before {\n\topacity: 1;\n\tfilter: alpha(opacity=100)\n}\n\n.vjs-playing .vjs-play-control:hover div:after {\n\tcolor: #08c\n}\n\n.vjs-playing .vjs-play-control div:after {\n\topacity: 1;\n\tfilter: alpha(opacity=100)\n}\n\n.vjs-playing .vjs-play-control div:before {\n\topacity: 0;\n\tfilter: alpha(opacity=0)\n}\n\n.vjs-rewind-control {\n\twidth: 5em;\n\tcursor: pointer!important\n}\n\n.vjs-rewind-control div {\n\twidth: 19px;\n\theight: 16px;\n\tbackground: none transparent;\n\tmargin: .5em auto 0\n}\n\n.vjs-mute-control {\n\tbackground: url(../img/video/volume-full.png) center -48px no-repeat;\n\tbackground-size: 16px 64px;\n\tcursor: pointer!important;\n\tposition: absolute;\n\tright: 51px;\n\ttop: 14px\n}\n\n.vjs-mute-control:hover div,.vjs-mute-control:focus div {\n\topacity: 0\n}\n\n.vjs-mute-control.vjs-vol-0,.vjs-mute-control.vjs-vol-0 div {\n\tbackground-image: url(../img/video/volume-off.png)\n}\n\n.vjs-mute-control div {\n\tbackground: #273747 url(../img/video/volume-full.png) no-repeat center 2px;\n\tbackground-size: 16px 64px;\n\theight: 18px;\n\t-webkit-transition: opacity .25s;\n\t-moz-transition: opacity .25s;\n\t-o-transition: opacity .25s;\n\ttransition: opacity .25s;\n\t-webkit-backface-visibility: hidden\n}\n\n.vjs-volume-control,.vjs-volume-level,.vjs-volume-handle,.vjs-volume-bar {\n\tdisplay: none\n}\n\n.vjs-progress-control {\n\tposition: absolute;\n\tleft: 60px;\n\tright: 180px;\n\theight: 12px;\n\twidth: auto;\n\ttop: 18px;\n\tbackground: #425669;\n\t-webkit-border-radius: 32px;\n\t-moz-border-radius: 32px;\n\tborder-radius: 32px\n}\n\n.vjs-progress-holder {\n\tposition: relative;\n\tcursor: pointer!important;\n\tpadding: 0;\n\tmargin: 0;\n\theight: 12px\n}\n\n.vjs-play-progress,.vjs-load-progress {\n\tposition: absolute;\n\tdisplay: block;\n\theight: 12px;\n\tmargin: 0;\n\tpadding: 0;\n\tleft: 0;\n\ttop: 0;\n\t-webkit-border-radius: 32px;\n\t-moz-border-radius: 32px;\n\tborder-radius: 32px\n}\n\n.vjs-play-progress {\n\tbackground: #1abc9c;\n\tleft: -1px\n}\n\n.vjs-load-progress {\n\tbackground: #d6dbdf;\n\t-webkit-border-radius: 32px 0 0 32px;\n\t-moz-border-radius: 32px 0 0 32px;\n\tborder-radius: 32px 0 0 32px\n}\n\n.vjs-load-progress[style*='100%'],.vjs-load-progress[style*='99%'] {\n\t-webkit-border-radius: 32px;\n\t-moz-border-radius: 32px;\n\tborder-radius: 32px\n}\n\n.vjs-seek-handle {\n\tbackground-color: #08c;\n\tposition: absolute;\n\twidth: 18px;\n\theight: 18px;\n\tmargin: -3px 0 0 1px;\n\tleft: 0;\n\ttop: 0;\n\t-webkit-transition: background-color .25s;\n\t-moz-transition: background-color .25s;\n\t-o-transition: background-color .25s;\n\ttransition: background-color .25s;\n\t-webkit-backface-visibility: hidden;\n\t-webkit-border-radius: 50%;\n\t-moz-border-radius: 50%;\n\tborder-radius: 50%\n}\n\n.vjs-seek-handle[style*='95.'] {\n\tmargin-left: 3px\n}\n\n.vjs-seek-handle[style='left: 0%;'] {\n\tmargin-left: -2px\n}\n\n.vjs-seek-handle:hover,.vjs-seek-handle:focus {\n\tbackground-color: #148d75\n}\n\n.vjs-seek-handle:active {\n\tbackground-color: #117a65\n}\n\n.vjs-time-controls {\n\tposition: absolute;\n\theight: 20px;\n\twidth: 50px;\n\ttop: 16px;\n\tfont: 300 13px \"Lato\",sans-serif\n}\n\n.vjs-current-time {\n\tright: 128px;\n\ttext-align: right\n}\n\n.vjs-duration {\n\tcolor: #5d6d7e;\n\tright: 69px;\n\ttext-align: left\n}\n\n.vjs-remaining-time {\n\tdisplay: none\n}\n\n.vjs-time-divider {\n\tcolor: #5d6d7e;\n\tfont-size: 14px;\n\tposition: absolute;\n\tright: 121px;\n\ttop: 15px\n}\n\n.vjs-secondary-controls {\n\tfloat: right\n}\n\n.vjs-fullscreen-control {\n\tbackground-image: url(../img/video/fullscreen.png);\n\tbackground-position: center -47px;\n\tbackground-size: 15px 64px;\n\tcursor: pointer!important;\n\tposition: absolute;\n\tright: 17px;\n\ttop: 13px\n}\n\n.vjs-fullscreen-control:hover div,.vjs-fullscreen-control:focus div {\n\topacity: 0\n}\n\n.vjs-fullscreen-control div {\n\theight: 18px;\n\tbackground: url(../img/video/fullscreen.png) no-repeat center 2px;\n\tbackground-size: 15px 64px;\n\t-webkit-transition: opacity .25s;\n\t-moz-transition: opacity .25s;\n\t-o-transition: opacity .25s;\n\ttransition: opacity .25s;\n\t-webkit-backface-visibility: hidden\n}\n\n.vjs-menu-button {\n\tdisplay: none!important\n}\n\n@-webkit-keyframes sharp .sharp-keyframes();\n\n@-moz-keyframes sharp .sharp-keyframes();\n\n@-o-keyframes sharp .sharp-keyframes();\n\n@keyframes sharp .sharp-keyframes();\n\n.vjs-loading-spinner {\n\tbackground: #ebedee;\n\tdisplay: none;\n\theight: 16px;\n\tleft: 50%;\n\tmargin: -8px 0 0 -8px;\n\tposition: absolute;\n\ttop: 50%;\n\twidth: 16px;\n\t-webkit-animation: sharp 2s ease infinite;\n\t-moz-animation: sharp 2s ease infinite;\n\t-o-animation: sharp 2s ease infinite;\n\tanimation: sharp 2s ease infinite;\n\t-webkit-border-radius: 10px;\n\t-moz-border-radius: 10px;\n\tborder-radius: 10px\n}\n\n.login {\n\tbackground: url(../img/login/imac.png) 0 0 no-repeat;\n\tbackground-size: 940px 778px;\n\tcolor: #fff;\n\tmargin-bottom: 77px;\n\tpadding: 38px 38px 267px;\n\tposition: relative\n}\n\n.login-screen {\n\tbackground-color: #1abc9c;\n\tmin-height: 317px;\n\tpadding: 123px 199px 33px 306px\n}\n\n.login-icon {\n\tleft: 200px;\n\tposition: absolute;\n\ttop: 160px;\n\twidth: 96px\n}\n\n.login-icon>img {\n\tdisplay: block;\n\tmargin-bottom: 6px;\n\twidth: 100%\n}\n\n.login-icon>h4 {\n\tfont-size: 17px;\n\tfont-weight: 200;\n\tline-height: 34px;\n\topacity: .95;\n\tfilter: alpha(opacity=95)\n}\n\n.login-icon>h4 small {\n\tcolor: inherit;\n\tdisplay: block;\n\tfont-size: inherit;\n\tfont-weight: 700\n}\n\n.login-form {\n\tbackground-color: #edeff1;\n\tpadding: 24px 23px 20px;\n\tposition: relative;\n\t-webkit-border-radius: 6px;\n\t-moz-border-radius: 6px;\n\tborder-radius: 6px\n}\n\n.login-form:before {\n\tcontent: '';\n\tborder-style: solid;\n\tborder-width: 12px 12px 12px 0;\n\tborder-color: transparent #edeff1 transparent transparent;\n\theight: 0;\n\tposition: absolute;\n\tleft: -12px;\n\ttop: 35px;\n\twidth: 0;\n\t-webkit-transform: rotate(360deg)\n}\n\n.login-form .control-group {\n\tmargin-bottom: 6px;\n\tposition: relative\n}\n\n.login-form .login-field {\n\tborder-color: transparent;\n\tfont-size: 17px;\n\tpadding-bottom: 11px;\n\tpadding-top: 11px;\n\ttext-indent: 3px;\n\twidth: 299px;\n\tmargin-bottom: 10px!important\n}\n\n.login-form .login-field:focus+.login-field-icon {\n\tcolor: #1abc9c\n}\n\n.login-form .login-field-icon {\n\tcolor: #bfc9ca;\n\tfont-size: 16px;\n\tposition: absolute;\n\tright: 13px;\n\ttop: 14px;\n\t-webkit-transition: .25s;\n\t-moz-transition: .25s;\n\t-o-transition: .25s;\n\ttransition: .25s;\n\t-webkit-backface-visibility: hidden\n}\n\n.login-link {\n\tcolor: #bfc9ca;\n\tdisplay: block;\n\tfont-size: 13px;\n\tmargin-top: 15px;\n\ttext-align: center\n}\n\n@media only screen and (-webkit-min-device-pixel-ratio:2),only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (-moz-min-device-pixel-ratio:2),only screen and (-o-min-device-pixel-ratio:3/2),only screen and (-o-min-device-pixel-ratio:2/1),only screen and (-moz-min-device-pixel-ratio:1.5),only screen and (min-device-pixel-ratio:1.5),only screen and (min-device-pixel-ratio:2) {\n\t.login {\n\t\tbackground-image: url(../img/login/imac-2x.png)\n\t}\n}\n\n.last-col {\n\toverflow: hidden\n}\n\n.ptn,.pvn,.pan {\n\tpadding-top: 0\n}\n\n.ptx,.pvx,.pax {\n\tpadding-top: 3px\n}\n\n.pts,.pvs,.pas {\n\tpadding-top: 5px\n}\n\n.ptm,.pvm,.pam {\n\tpadding-top: 10px\n}\n\n.ptl,.pvl,.pal {\n\tpadding-top: 20px\n}\n\n.prn,.phn,.pan {\n\tpadding-right: 0\n}\n\n.prx,.phx,.pax {\n\tpadding-right: 3px\n}\n\n.prs,.phs,.pas {\n\tpadding-right: 5px\n}\n\n.prm,.phm,.pam {\n\tpadding-right: 10px\n}\n\n.prl,.phl,.pal {\n\tpadding-right: 20px\n}\n\n.pbn,.pvn,.pan {\n\tpadding-bottom: 0\n}\n\n.pbx,.pvx,.pax {\n\tpadding-bottom: 3px\n}\n\n.pbs,.pvs,.pas {\n\tpadding-bottom: 5px\n}\n\n.pbm,.pvm,.pam {\n\tpadding-bottom: 10px\n}\n\n.pbl,.pvl,.pal {\n\tpadding-bottom: 20px\n}\n\n.pln,.phn,.pan {\n\tpadding-left: 0\n}\n\n.plx,.phx,.pax {\n\tpadding-left: 3px\n}\n\n.pls,.phs,.pas {\n\tpadding-left: 5px\n}\n\n.plm,.phm,.pam {\n\tpadding-left: 10px\n}\n\n.pll,.phl,.pal {\n\tpadding-left: 20px\n}\n\n.mtn,.mvn,.man {\n\tmargin-top: 0\n}\n\n.mtx,.mvx,.max {\n\tmargin-top: 3px\n}\n\n.mts,.mvs,.mas {\n\tmargin-top: 5px\n}\n\n.mtm,.mvm,.mam {\n\tmargin-top: 10px\n}\n\n.mtl,.mvl,.mal {\n\tmargin-top: 20px\n}\n\n.mrn,.mhn,.man {\n\tmargin-right: 0\n}\n\n.mrx,.mhx,.max {\n\tmargin-right: 3px\n}\n\n.mrs,.mhs,.mas {\n\tmargin-right: 5px\n}\n\n.mrm,.mhm,.mam {\n\tmargin-right: 10px\n}\n\n.mrl,.mhl,.mal {\n\tmargin-right: 20px\n}\n\n.mbn,.mvn,.man {\n\tmargin-bottom: 0\n}\n\n.mbx,.mvx,.max {\n\tmargin-bottom: 3px\n}\n\n.mbs,.mvs,.mas {\n\tmargin-bottom: 5px\n}\n\n.mbm,.mvm,.mam {\n\tmargin-bottom: 10px\n}\n\n.mbl,.mvl,.mal {\n\tmargin-bottom: 20px\n}\n\n.mln,.mhn,.man {\n\tmargin-left: 0\n}\n\n.mlx,.mhx,.max {\n\tmargin-left: 3px\n}\n\n.mls,.mhs,.mas {\n\tmargin-left: 5px\n}\n\n.mlm,.mhm,.mam {\n\tmargin-left: 10px\n}\n\n.mll,.mhl,.mal {\n\tmargin-left: 20px\n}"
  },
  {
    "path": "code/default/launcher/web_ui/css/primer-markdown.css",
    "content": ".markdown-body {\n    color: #24292e;\n    min-width: 888px;\n    padding: 15px;\n    overflow: auto;\n    font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n    font-size: 16px;\n    line-height: 1.5;\n    word-wrap: break-word\n}\n\n.markdown-body::before {\n    display: table;\n    content: \"\"\n}\n\n.markdown-body::after {\n    display: table;\n    clear: both;\n    content: \"\"\n}\n\n.markdown-body > *:first-child {\n    margin-top: 0 !important\n}\n\n.markdown-body > *:last-child {\n    margin-bottom: 0 !important\n}\n\n.markdown-body a:not([href]) {\n    color: inherit;\n    text-decoration: none\n}\n\n.markdown-body .absent {\n    color: #cb2431\n}\n\n.markdown-body .anchor {\n    float: left;\n    padding-right: 4px;\n    margin-left: -20px;\n    line-height: 1\n}\n\n.markdown-body .anchor:focus {\n    outline: none\n}\n\n.markdown-body p, .markdown-body blockquote, .markdown-body ul, .markdown-body ol, .markdown-body dl, .markdown-body table, .markdown-body pre {\n    margin-top: 0;\n    margin-bottom: 16px\n}\n\n.markdown-body hr {\n    height: .25em;\n    padding: 0;\n    margin: 24px 0;\n    background-color: #e1e4e8;\n    border: 0\n}\n\n.markdown-body blockquote {\n    padding: 0 1em;\n    color: #6a737d;\n    border-left: 0.25em solid #dfe2e5\n}\n\n.markdown-body blockquote > :first-child {\n    margin-top: 0\n}\n\n.markdown-body blockquote > :last-child {\n    margin-bottom: 0\n}\n\n.markdown-body kbd {\n    display: inline-block;\n    padding: 3px 5px;\n    font-size: 11px;\n    line-height: 10px;\n    color: #444d56;\n    vertical-align: middle;\n    background-color: #fafbfc;\n    border: solid 1px #c6cbd1;\n    border-bottom-color: #959da5;\n    border-radius: 3px;\n    box-shadow: inset 0 -1px 0 #959da5\n}\n\n.markdown-body h1, .markdown-body h2, .markdown-body h3, .markdown-body h4, .markdown-body h5, .markdown-body h6 {\n    margin-top: 24px;\n    margin-bottom: 16px;\n    font-weight: 600;\n    line-height: 1.25\n}\n\n.markdown-body h1 .octicon-link, .markdown-body h2 .octicon-link, .markdown-body h3 .octicon-link, .markdown-body h4 .octicon-link, .markdown-body h5 .octicon-link, .markdown-body h6 .octicon-link {\n    color: #1b1f23;\n    vertical-align: middle;\n    visibility: hidden\n}\n\n.markdown-body h1:hover .anchor, .markdown-body h2:hover .anchor, .markdown-body h3:hover .anchor, .markdown-body h4:hover .anchor, .markdown-body h5:hover .anchor, .markdown-body h6:hover .anchor {\n    text-decoration: none\n}\n\n.markdown-body h1:hover .anchor .octicon-link, .markdown-body h2:hover .anchor .octicon-link, .markdown-body h3:hover .anchor .octicon-link, .markdown-body h4:hover .anchor .octicon-link, .markdown-body h5:hover .anchor .octicon-link, .markdown-body h6:hover .anchor .octicon-link {\n    visibility: visible\n}\n\n.markdown-body h1 tt, .markdown-body h1 code, .markdown-body h2 tt, .markdown-body h2 code, .markdown-body h3 tt, .markdown-body h3 code, .markdown-body h4 tt, .markdown-body h4 code, .markdown-body h5 tt, .markdown-body h5 code, .markdown-body h6 tt, .markdown-body h6 code {\n    font-size: inherit\n}\n\n.markdown-body h1 {\n    padding-bottom: 0.3em;\n    font-size: 2em;\n    border-bottom: 1px solid #eaecef\n}\n\n.markdown-body h2 {\n    padding-bottom: 0.3em;\n    font-size: 1.5em;\n    border-bottom: 1px solid #eaecef\n}\n\n.markdown-body h3 {\n    font-size: 1.25em\n}\n\n.markdown-body h4 {\n    font-size: 1em\n}\n\n.markdown-body h5 {\n    font-size: 0.875em\n}\n\n.markdown-body h6 {\n    font-size: 0.85em;\n    color: #6a737d\n}\n\n.markdown-body ul, .markdown-body ol {\n    padding-left: 2em\n}\n\n.markdown-body ul.no-list, .markdown-body ol.no-list {\n    padding: 0;\n    list-style-type: none\n}\n\n.markdown-body ul ul, .markdown-body ul ol, .markdown-body ol ol, .markdown-body ol ul {\n    margin-top: 0;\n    margin-bottom: 0\n}\n\n.markdown-body li {\n    word-wrap: break-all\n}\n\n.markdown-body li > p {\n    margin-top: 16px\n}\n\n.markdown-body li + li {\n    margin-top: .25em\n}\n\n.markdown-body dl {\n    padding: 0\n}\n\n.markdown-body dl dt {\n    padding: 0;\n    margin-top: 16px;\n    font-size: 1em;\n    font-style: italic;\n    font-weight: 600\n}\n\n.markdown-body dl dd {\n    padding: 0 16px;\n    margin-bottom: 16px\n}\n\n.markdown-body table {\n    display: block;\n    width: 100%;\n    overflow: auto\n}\n\n.markdown-body table th {\n    font-weight: 600\n}\n\n.markdown-body table th, .markdown-body table td {\n    padding: 6px 13px;\n    border: 1px solid #dfe2e5\n}\n\n.markdown-body table tr {\n    background-color: #fff;\n    border-top: 1px solid #c6cbd1\n}\n\n.markdown-body table tr:nth-child(2n) {\n    background-color: #f6f8fa\n}\n\n.markdown-body table img {\n    background-color: transparent\n}\n\n.markdown-body img {\n    max-width: 100%;\n    box-sizing: content-box;\n    background-color: #fff\n}\n\n.markdown-body img[align=right] {\n    padding-left: 20px\n}\n\n.markdown-body img[align=left] {\n    padding-right: 20px\n}\n\n.markdown-body .emoji {\n    max-width: none;\n    vertical-align: text-top;\n    background-color: transparent\n}\n\n.markdown-body span.frame {\n    display: block;\n    overflow: hidden\n}\n\n.markdown-body span.frame > span {\n    display: block;\n    float: left;\n    width: auto;\n    padding: 7px;\n    margin: 13px 0 0;\n    overflow: hidden;\n    border: 1px solid #dfe2e5\n}\n\n.markdown-body span.frame span img {\n    display: block;\n    float: left\n}\n\n.markdown-body span.frame span span {\n    display: block;\n    padding: 5px 0 0;\n    clear: both;\n    color: #24292e\n}\n\n.markdown-body span.align-center {\n    display: block;\n    overflow: hidden;\n    clear: both\n}\n\n.markdown-body span.align-center > span {\n    display: block;\n    margin: 13px auto 0;\n    overflow: hidden;\n    text-align: center\n}\n\n.markdown-body span.align-center span img {\n    margin: 0 auto;\n    text-align: center\n}\n\n.markdown-body span.align-right {\n    display: block;\n    overflow: hidden;\n    clear: both\n}\n\n.markdown-body span.align-right > span {\n    display: block;\n    margin: 13px 0 0;\n    overflow: hidden;\n    text-align: right\n}\n\n.markdown-body span.align-right span img {\n    margin: 0;\n    text-align: right\n}\n\n.markdown-body span.float-left {\n    display: block;\n    float: left;\n    margin-right: 13px;\n    overflow: hidden\n}\n\n.markdown-body span.float-left span {\n    margin: 13px 0 0\n}\n\n.markdown-body span.float-right {\n    display: block;\n    float: right;\n    margin-left: 13px;\n    overflow: hidden\n}\n\n.markdown-body span.float-right > span {\n    display: block;\n    margin: 13px auto 0;\n    overflow: hidden;\n    text-align: right\n}\n\n.markdown-body code, .markdown-body tt {\n    padding: 0.2em 0.4em;\n    margin: 0;\n    font-size: 85%;\n    color: #24292e;\n    background-color: rgba(27, 31, 35, 0.05);\n    border-radius: 3px\n}\n\n.markdown-body code br, .markdown-body tt br {\n    display: none\n}\n\n.markdown-body del code {\n    text-decoration: inherit\n}\n\n.markdown-body pre {\n    word-wrap: normal\n}\n\n.markdown-body pre > code {\n    padding: 0;\n    margin: 0;\n    font-size: 100%;\n    word-break: normal;\n    white-space: pre;\n    background: transparent;\n    border: 0\n}\n\n.markdown-body .highlight {\n    margin-bottom: 16px\n}\n\n.markdown-body .highlight pre {\n    margin-bottom: 0;\n    word-break: normal\n}\n\n.markdown-body .highlight pre, .markdown-body pre {\n    padding: 16px;\n    overflow: auto;\n    font-size: 85%;\n    line-height: 1.45;\n    background-color: #f6f8fa;\n    border-radius: 3px\n}\n\n.markdown-body pre code, .markdown-body pre tt {\n    display: inline;\n    max-width: auto;\n    padding: 0;\n    margin: 0;\n    overflow: visible;\n    line-height: inherit;\n    word-wrap: normal;\n    background-color: transparent;\n    border: 0\n}\n\n.markdown-body .csv-data td, .markdown-body .csv-data th {\n    padding: 5px;\n    overflow: hidden;\n    font-size: 12px;\n    line-height: 1;\n    text-align: left;\n    white-space: nowrap\n}\n\n.markdown-body .csv-data .blob-num {\n    padding: 10px 8px 9px;\n    text-align: right;\n    background: #fff;\n    border: 0\n}\n\n.markdown-body .csv-data tr {\n    border-top: 0\n}\n\n.markdown-body .csv-data th {\n    font-weight: 600;\n    background: #f6f8fa;\n    border-top: 0\n}\n"
  },
  {
    "path": "code/default/launcher/web_ui/css/style.css",
    "content": "html, body {\n    font-family: \"Microsoft YaHei\", \"Segoe UI Light\", \"Segoe UI\", \"Heiti SC\";\n    margin: 0;\n    padding: 0;\n}\n\n.container-fluid{\n    padding-left: 1rem;\n    padding-right: 1rem;\n}\n\nbutton,\ninput,\nselect,\ntextarea {\n    font-family:  \"Microsoft YaHei\", \"Segoe UI Light\", \"Segoe UI\", \"Heiti SC\" !important;\n}\n\na {\n    text-decoration: none !important;\n    cursor: pointer;\n}\n\nselect {\n    border: 2px solid #bdc3c7;\n    color: #34495e;\n    display: inline-block;\n    font-family: \"Lato\", sans-serif;\n    font-size: 14px;\n    padding: 8px 5px;\n    height: 41px;\n    text-indent: 6px;\n    width: 100%;\n    -webkit-border-radius: 6px;\n       -moz-border-radius: 6px;\n            border-radius: 6px;\n    -webkit-box-shadow: none;\n       -moz-box-shadow: none;\n            box-shadow: none;\n    -webkit-transition: border .25s linear,color .25s linear;\n       -moz-transition: border .25s linear,color .25s linear;\n         -o-transition: border .25s linear,color .25s linear;\n            transition: border .25s linear,color .25s linear;\n}\n\nbutton.btn-danger,\nbutton[type=submit] {\n    margin-top: 10px;\n}\n\nselect:focus {\n    border-color: #3498db;\n    outline: none;\n}\n\n.navbar-fixed-top {\n    position:fixed;\n    top:0;\n    width:100%;\n}\n\ndiv#header a {\n    color: #fff;\n    text-decoration: none;\n}\n\ndiv#header div#logo {\n    padding: 4px 0;\n}\n\ndiv#header div#logo img {\n    height: 32px;\n    max-height: 32px;\n}\n\n#version_on_logo {\n    margin: 0 5px;\n    font-size: 70%;\n}\n\ndiv#header a#resize-window-trigger,\ndiv#header a#menu-button,\ndiv#header a#quit-trigger {\n    display: block;\n    padding-top: 8px;\n}\n\ndiv#header img {\n    max-height: 22px;\n}\n\n.align-right {\n    position: absolute;\n    top: 5px;\n    right: 30px;\n}\n\ndiv#content {\n    margin: 40px auto 0;\n    padding-top: 3rem;\n}\n\ndiv#content div#sidebar a {\n    text-decoration: none;\n}\n\ndiv#content h2 {\n    margin: 0 0 20px;\n}\n\ndiv#content div.alert p.message {\n    margin-bottom: 0;\n}\n\ndiv#content form div.row-fluid {\n    margin-bottom: 10px;\n}\n\ndiv#content div.row-fluid > div.span4 > label {\n    font-weight: bold;\n    margin: 10px 0 0;\n}\ndiv#content div.row-fluid > div.span3 > label {\n    font-weight: bold;\n    margin: 10px 0 0;\n}\ndiv#content div.row-fluid > div.span2 > label {\n    font-weight: bold;\n    margin: 10px 0 0;\n}\ndiv#content div.row-fluid > div.span1 > label {\n    font-weight: bold;\n    margin: 10px 0 0;\n}\n\ndiv#content form div.row-fluid > div.span4 > label > a {\n    font-weight: normal;\n    text-decoration: none;\n}\n\ndiv#content input[type=text],\ndiv#content input[type=number],\ndiv#content input[type=password] {\n    -webkit-box-sizing: border-box;\n       -moz-box-sizing: border-box;\n            box-sizing: border-box;\n}\n\ndiv#content div#advanced-options,\ndiv#content div#module-switch {\n    padding-left: 20px;\n}\n\ndiv#content textarea {\n    color: #34495e;\n    height: 285px;\n    max-width: 100%;\n    resize: none;\n    -webkit-box-sizing: border-box;\n       -moz-box-sizing: border-box;\n            box-sizing: border-box;\n}\n\ndiv#content ul.nav-tabs {\n    margin-bottom: 0;\n}\n\ndiv#content div.tab-content {\n    border: 1px solid #ddd;\n    border-top: none;\n    min-height: 360px;\n    padding: 20px 10px;\n}\n\n/* Style for config.html in PHP-Proxy */\ndiv#content form#gae_proxy-php-config div.row-fluid div.span4 label[for=enable-php-proxy] {\n    margin-top: 5px;\n}\n\ndiv#content form#gae_proxy-php-config div.row-fluid div.span4 label[for=enable-php-proxy] > a {\n    font-weight: normal;\n    text-decoration: none;\n}\n\n/* Style for status.html */\ntable#status td {\n    word-wrap: break-word;\n}\n\ntable#plan th {\n    text-align:center;\n}\ntable#plan td {\n    text-align:center;\n    vertical-align:middle;\n}\ntable#quota_list_table th {\n    text-align:center;\n}\ntable#quota_list_table td {\n    text-align:center;\n    vertical-align:middle;\n}\n\ndiv#report-issue-modal {\n    position: fixed;\n}\n\n/* Style for logging.html */\ndiv#log {\n    background-color: #f4f6f6;\n    border: 2px solid #d5dbdb;\n    border-radius: 6px;\n    color: #34495e;\n    font-size: 14.994px;\n    height: 285px;\n    line-height: 24px;\n    max-width: 100%;\n    overflow-y: auto;\n    padding: 5px 11px;\n    text-indent: 0;\n}\n\ndiv#log > p {\n    margin-bottom: 0;\n    word-wrap: break-word;\n}\n\ntd#working-appid {\n    word-wrap: break-word;\n    word-break: break-all;\n}\n/* Styles for deploy.html */\ndiv#content div#deploy p.tip {\n    font-size: 13px;\n    margin-top: 5px;\n}\n\n/* Styles for about.html */\ndiv#content div#about a {\n    text-decoration: none;\n}\n\ndiv#content div#about div.row-fluid div.span4 {\n    font-weight: bold;\n}\n\ndiv#content div#thanks ul {\n    list-style: none;\n    margin: 0;\n}\n\ndiv#content div#thanks li {\n    line-height: 150%;\n}\n\n/* Styles for config.html in System */\ndiv#content div#options div.row-fluid {\n    margin-bottom: 10px;\n}\n\ndiv#content div#options div.row-fluid div.span4, .bold {\n    font-weight: bold;\n    padding-top: 5px;\n}\n\n#noob-info {\n    padding: 10px;\n    margin: 40px 0;\n    color: #b94a48;\n    background-color: #f2dede;\n    border:1px solid;\n    border-color: #eed3d7;\n    border-radius: 4px;\n    transition: color .3s,background .3s,border .3s;\n}\n\n#noob-info.hard {\n    color: #468847;\n    background-color: #dff0d8;\n    border-color: #d6e9c6;\n}\n\n#noob-info.fluent {\n    color: #146C98;\n    background-color: #d9edf7;\n    border-color: #bce8f1;\n}\n\n#update-notify, .popnotify {\n    padding: 6px;\n    margin: 10px 0;\n    background-color: #dff0d8;\n    border:1px solid;\n    border-color: #cfe0c8;\n    border-radius: 4px;\n    transition: color .3s,background .3s,border .3s;\n    \n}\n#update-message{\n    font-size: 120%;\n    color: #507050;\n}\n.update-notify-action {\n    float: right;\n    color: #0072E3;\n    cursor: pointer;\n    margin: 0 6px;\n}\n\n#update-notify-close {\n    float: right;\n    cursor: pointer;\n    margin-left: 7px;\n    color: #b94a48;\n    \n}\n\n#details, #update-options, #modules-manager{\n    overflow: hidden;\n}\n\n/* Style for config.html in X-Tunnel */\n.modal h5 {\n    margin: 0;\n}\n\ndiv#info.tab-pane div.section {\n    margin-bottom: 20px;\n}\n\ndiv#info.tab-pane form#login-form,\ndiv#info.tab-pane form#register-form {\n    max-width: 640px;\n}\n\ndiv#info.tab-pane div#account-information p, \ndiv#help.tab-pane p {\n    margin-top: 10px;\n}\n\ndiv#plans.tab-pane h1.price {\n    text-align: center;\n}\n\ndiv#plans.tab-pane ul.details {\n    color: #8e8e8e;\n    list-style: none;\n    margin: 0;\n}\n\ndiv#plans.tab-pane ul.details div.span4.text-right {\n    color: #747474;\n    font-weight: bold;\n}\n\ndiv#history.tab-pane > div.row-fluid {\n    margin-bottom: 10px;\n}\n\ndiv#history.tab-pane h4 {\n    padding-top: 5px;    \n}\n\n/* Smaller than standard 1200 (devices and browsers) */\n@media only screen and (max-width: 1199px) {\n}\n\n/* Portrait size to standard 1200 (devices and browsers) */\n@media only screen and (min-width: 960px) and (max-width: 1199px) {\n    div.container {\n        width: 960px;\n    }\n}\n\n/* Smaller than standard 960 (devices and browsers) */\n@media only screen and (max-width: 959px) {\n}\n\n/* Tablet Portrait size to standard 960 (devices and browsers) */\n@media only screen and (min-width: 768px) and (max-width: 959px) {\n    div.container {\n        width: 768px;\n    }\n}\n\n/* All Mobile Sizes (devices and browser) */\n@media only screen and (max-width: 767px) {\n    div#header {\n        margin: 0;\n    }\n\n    div#header div.span8 {\n        display: none;\n    }\n\n    div#header div#logo {\n        text-align: center;\n    }\n}\n\n/* Mobile Landscape Size to Tablet Portrait (devices and browsers) */\n@media only screen and (min-width: 480px) and (max-width: 767px) {\n    div.container {\n        width: 480px;\n    }\n}\n\n/* Mobile Portrait Size to Mobile Landscape Size (devices and browsers) */\n@media only screen and (max-width: 479px) {\n    div.container {\n        width: 320px;\n    }\n}\n\n.config_label {\n    display: inline-block;\n    font-weight: bold;\n    margin: 10px 0 0;\n    max-width:  100%;\n    overflow: hidden;\n}\n.config_switch {\n    float: right;\n    padding-right: 1rem;\n    margin: 10px 0 0;\n}\n\n#loading_animation {\n  height: 250px;\n  top: 50%;\n  text-align: center;\n}\n.p80 {\n  max-width: 600px;\n  text-align: center;\n}\n.plan-block {\n  margin-left: 10px;\n  margin-top: 10px;\n  margin-bottom: 10px;\n  text-align: center;\n\n}"
  },
  {
    "path": "code/default/launcher/web_ui/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\"> <!-- See http://www.w3schools.com/tags/ref_language_codes.asp -->\n<head>\n    <meta http-equiv=\"Content-Type\" content=\"text/html\" charset=\"UTF-8\">\n    <title>{{ _( \"APP_NAME\" ) }}</title>\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <!-- CSS -->\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"/css/bootstrap.css\">\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"/css/bootstrap-responsive.css\">\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"/css/flat-ui.css\">\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"/css/ladda-themeless.min.css\">\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"/css/style.css\">\n    <link rel=\"icon\" href='/img/{{ _( \"APP_NAME\" ) }}/favicon.ico'>\n    <!-- JavaScript -->\n    <script type=\"text/javascript\" src=\"/js/jquery-1.11.2.min.js\"></script>\n    <script type=\"text/javascript\" src=\"/js/bootstrap.min.js\"></script>\n    <script type=\"text/javascript\" src=\"/js/flat-ui.js\"></script>\n    <script type=\"text/javascript\" src=\"/js/jquery.timer.js\"></script>\n    <script type=\"text/javascript\" src=\"/js/spin.min.js\"></script>\n    <script type=\"text/javascript\" src=\"/js/ladda.min.js\"></script>\n    <script type=\"text/javascript\" src=\"/js/site.js\"></script>\n    <!--[if lte IE 9]>\n    <script type=\"text/javascript\" src=\"/js/jquery.placeholder.min.js\"></script>\n    <script type=\"text/javascript\" src=\"/js/jquery.xdomainrequest.min.js\"></script>\n    <![endif]-->\n</head>\n<script type=\"text/javascript\">\n    var documentReadyToRun = new Array();\n\n    // Disable zoom in/out in iOS WebView.\n    var meta = document.createElement('meta');\n    meta.name = 'viewport';\n    meta.content = 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no';\n    var head = document.getElementsByTagName('head')[0];\n    head.appendChild(meta);\n\n    var gae_enabled = %d;\n</script>\n<body>\n<div id=\"header\" class=\"navbar navbar-inverse navbar-fixed-top\">\n    <div class=\"navbar-inner\">\n        <div class=\"container\">\n            <div class=\"row-fluid\">\n                <div id=\"logo\">\n                    <a href=\"/\" title='{{ _( \"APP_NAME\" ) }}'>\n                        <img src='/img/{{ _( \"APP_NAME\" ) }}/logo.png' alt=\"Logo\">\n                        {{ _( \"APP_NAME\" ) }}\n                        <span id=\"version_on_logo\" class=\"\"></span>\n                    </a>\n                    <a id=\"remote-connection-identifier\" style=\"display: none;\" href=\"/?module=launcher&menu=config\">{{\n                        _( \"(Remote Web Control Enabled)\" ) }}</a>\n                </div> <!-- #logo -->\n                <div class=\"align-right d-md-block\">\n                    <ul class=\"inline\">\n                        <li>\n                            <a id=\"resize-window-trigger\" href=\"javascript:void(0);\"\n                               title='{{ _( \"Adaptive width\" ) }}'>\n                                <img src=\"/img/fixed-width.png\" alt=\"resize-window\">\n                            </a>\n                        </li>\n                        <li>\n                            <a id=\"quit-trigger\" href=\"javascript:void(0);\" title='{{ _( \"Exit\" ) }}'>\n                                <img src=\"/img/quit.png\" alt=\"quit\">\n                            </a>\n                        </li>\n                    </ul>\n                </div> <!-- .span4 -->\n\n                <div class=\"align-right d-md-none\">\n                    <ul class=\"inline\">\n                        <li>\n                            <a id=\"menu-button\" href=\"javascript:void(0);\" title='{{ _( \"Menu\" ) }}'>\n                                <img src=\"/img/menu.png\" alt=\"menu\">\n                            </a>\n                        </li>\n                    </ul>\n                </div> <!-- .span4 -->\n\n            </div> <!-- .row-fluid -->\n        </div> <!-- .container -->\n    </div> <!-- .navbar-inner -->\n</div> <!-- #header -->\n<div id=\"content\">\n    <div class=\"container\">\n        <div class=\"row-fluid\">\n            <div id=\"sidebar\" class=\"d-md-block span3\">\n                <div class=\"sidebar-nav well\">\n                    <ul class=\"nav nav-list\">%s</ul>\n                </div> <!-- .sidebar-nav -->\n            </div> <!-- #sidebar -->\n            <div class=\"span9\" id=\"contents\">\n                <div id=\"update-notify\" class=\"alert fade in hide\">\n                    <span id=\"update-notify-close\">×</span>\n                    <span id=\"update-now\" class=\"update-notify-action\">{{ _( \"Update now\" ) }}</span>\n                    <span id=\"update-next\" class=\"update-notify-action\">{{ _( \"Remind me later\" ) }}</span>\n                    <span id=\"update-skip\"\n                          class=\"update-notify-action\">{{ _( \"Do not remind me this version\" ) }}</span>\n                    <span id=\"update-message\"></span>\n                    <span> &nbsp; <a id=\"update-viewchanges\" target=\"_blank\">{{ _( \"View changes\" ) }}</a></span>\n                </div> <!-- #update-notify -->\n                <div id=\"update-progress-bar\" class=\"popnotify fade in hide\">\n                    <span class=\"\"></span>\n                </div> <!-- #update-progress-bar -->\n                <h2 id=\"title\"></h2>\n                <div id=\"tip\" class=\"alert fade in hide\">\n                    <button id=\"tip-close\" type=\"button\" class=\"close\">×</button>\n                    <p id=\"tip-message\" class=\"message\"></p>\n                </div> <!-- #tip -->\n                %s\n            </div>\n        </div> <!-- .row-fluid -->\n    </div> <!-- .container -->\n</div> <!-- #content -->\n<!-- JavaScript -->\n<!-- Placed at the end of the document so the pages load faster -->\n<script type=\"text/javascript\">\n    function on_resize() {\n        var viewportWidth = $(window).width();\n        var viewportHeight = $(window).height();\n\n        //console.log(\"resize w:\" + viewportWidth + \" h:\" + viewportHeight);\n        if (viewportWidth < 768) {\n            $('.d-md-block').addClass('hide');\n            $('.d-md-none').removeClass('hide');\n\n            $('.container').addClass('container-fluid');\n            $('.container').removeClass('container');\n        } else {\n            $('.d-md-block').removeClass('hide');\n            $('.d-md-none').addClass('hide');\n\n            $('.container-fluid').addClass('container');\n            $('.container-fluid').removeClass('container-fluid');\n        }\n    }\n\n    $(window).resize(function() {\n        on_resize();\n    });\n\n    $(function () {\n        window.isFullWidth = false;\n        window.wiki_ISSUEID = 9696; //as default, an wiki/help issue, for failed-getting-releasenote-issue condition\n        window.RELEASENOTE_ISSUEID = window.wiki_ISSUEID;\n        window.welcomeISSUEID = window.wiki_ISSUEID;\n\n        on_resize();\n    });\n\n\n</script>\n<script type=\"text/javascript\">\n    $('.fluid-down-control').click(function () {\n        var isShown = $('i.icon', this).hasClass('icon-chevron-down');\n        var id = $(this).attr('for');\n\n        if (!isShown) {\n            $('i.icon', this).removeClass('icon-chevron-right');\n            $('i.icon', this).addClass('icon-chevron-down');\n            $('#' + id).slideDown();\n        } else {\n            $('i.icon', this).removeClass('icon-chevron-down');\n            $('i.icon', this).addClass('icon-chevron-right');\n            $('#' + id).slideUp();\n        }\n    });\n\n\n</script>\n<script type=\"text/javascript\">\n\n    $('#menu-button').click(function () {\n      if ($('#sidebar').hasClass('hide')) {\n        $('#sidebar').removeClass('hide');\n        $('#contents').addClass('hide');\n      } else {\n        $('#sidebar').addClass('hide');\n        $('#contents').removeClass('hide');\n      }\n    });\n\n    $('#resize-window-trigger').click(function () {\n        isFullWidth = !isFullWidth;\n\n        if (isFullWidth) {\n            $('img', this).attr('src', '/img/full-width.png');\n            $('.container').addClass('container-fluid');\n            $('.container').removeClass('container');\n        } else {\n            $('img', this).attr('src', '/img/fixed-width.png');\n            $('.container-fluid').addClass('container');\n            $('.container-fluid').removeClass('container-fluid');\n        }\n    });\n\n    $('#quit-trigger').click(function () {\n        $.ajax({\n            type: 'GET',\n            url: '/quit',\n            dataType: 'JSON',\n            success: function (result) {\n                if (result['status'] == 'success') {\n                    tip('{{ _( \"Exited successfully.\" ) }}', 'success');\n                } else {\n                    tip('{{ _( \"Exitting failed.\" ) }}', 'error');\n                }\n            },\n            error: function () {\n                tip('{{ _( \"Exitting failed. A network error occurred.\" ) }}', 'error');\n            }\n        });\n    });\n\n    $('#btn-learnmore').click(function () {\n        popIssue(window.welcomeISSUEID);\n        setTimeout(function () {\n            $('#welcome').addClass('hide');\n        }, 1000);\n    });\n\n    function welcomeClose() {\n        $('#welcome').addClass('hide');\n        setConfig('postUpdateStat', \"noChange\");\n    }\n\n    function updateWelcome() {\n        switch (getConfig('postUpdateStat')) {\n            case \"noChange\":\n                $('#welcome').addClass('hide');\n                break;\n            case \"isNew\":\n                $('#welcome-title').text('{{ _( \"Hello!\" ) }}');\n                $('#welcome-message').text('{{ _( \"You seem to be on your first visit.\" ) }}');\n                window.welcomeISSUEID = window.wiki_ISSUEID;\n                $('#welcome').removeClass('hide');\n                setTimeout(welcomeClose(), 15 * 1000);\n                break;\n            case \"isPostUpdate\":\n                $('#welcome-title').text('{{ _( \"Hello!\" ) }}');\n                $('#welcome-message').text('{{ _( \"new to this version?\" ) }}');\n                window.welcomeISSUEID = window.RELEASENOTE_ISSUEID;\n                $('#welcome').removeClass('hide');\n                setTimeout(welcomeClose(), 15 * 1000);\n                break;\n            default:\n        }\n    }\n\n    function updateNotice(contents, appendMode) {\n        //appendMode = appendMode || false;\n        if (!contents || contents.length <= 0) return;\n\n        var content = document.getElementById('notice-content');\n        if (!appendMode) {\n            content.innerHTML = '';\n        }\n\n        var i, limit = 30;\n        var cur = content.firstChild;\n        for (i = 0; i < limit && cur && contents.length > 0; i++) {\n            var issue = contents[0];\n            if (cur.id.substring(6) < issue[0]) {\n                var li = document.createElement('li');\n                li.setAttribute('id', \"issue_\" + issue[0]);\n                var a = document.createElement('a');\n                a.textContent = issue[1];\n                a.href = issue[2];\n                a.issueid = issue[0];\n                a.onclick = function() {\n                    popIssue(this.issueid);\n                    return false;\n                }\n                li.appendChild(a);\n                content.insertBefore(li, cur);\n                contents.shift();\n            } else if (cur.id.substring(6) == issue[0]) {\n                cur = cur.nextSibling;\n                contents.shift();\n            } else if (cur.id.substring(6) > issue[0]) {\n                cur = cur.nextSibling;\n            } else {\n                displayErrorMessage();\n            }\n        }\n        if (contents.length > 0) {\n            while (i < limit && contents.length > 0) {\n                var issue = contents.shift();\n                var li = document.createElement('li');\n                li.setAttribute('id', \"issue_\" + issue[0]);\n                var a = document.createElement('a');\n                a.textContent = issue[1];\n                a.href = issue[2];\n                a.issueid = issue[0];\n                a.onclick = function() {\n                    popIssue(this.issueid);\n                    return false;\n                }\n                li.appendChild(a);\n                content.appendChild(li);\n                i++;\n            }\n            return;\n        }\n        //if (cur && i >= limit) { //exceed limit, do nothing for now }\n    }\n\n    function getIssuesByLabels(labels, callback, repo) {\n        repo = repo || \"XX-net/XX-Net\";\n        //var APIurl = \"https://api.github.com/repos/XX-net/XX-Net/issues?\" + \"no:label\"; //for test, get all commits without label\n        var APIurl = \"https://api.github.com/repos/\" + repo + \"/issues?page=1&labels=\" + labels; //console.log('APIurl='+APIurl);\n        $.ajax({\n            type: 'GET',\n            url: APIurl,\n            dataType: 'JSON',\n            success: callback,\n            error: function (result) {\n                console.log(\"Failed loading issues of \" + labels + \".\");\n            }\n        });\n    }\n\n    function getNoticeCallback(result) {\n        var t = [];\n        for (var i = 0; i < result.length; i++) {\n            var issue = result[i];\n            t.push([issue.number, issue.title, issue.html_url]);\n        }\n        updateNotice(t, true);\n    }\n\n    function getNotice() {\n        var pageRequests = {\n            'cmd': 'get_version'\n        };\n        $.ajax({\n            type: 'GET',\n            url: '/config',\n            data: pageRequests,\n            dataType: 'JSON',\n            success: function (result) {\n                var currentVerBig = result['current_version'].replace(/(\\d+)$/, \"x\");\n                var currentVerBigSplit = currentVerBig.split('.');\n                currentVerBigSplit[1] = parseInt(currentVerBigSplit[1]) + 1;\n                var currentVerNextBig = currentVerBigSplit.join('.');\n                getIssuesByLabels(\"公告\", getNoticeCallback);\n                getIssuesByLabels(currentVerBig, getNoticeCallback);\n                getIssuesByLabels(currentVerNextBig, getNoticeCallback);\n            }\n        });\n    }\n\n    function getRELEASENOTE_ISSUEID_Callback(result) {\n        if (result.length === 0) {\n            //console.log(\"NO RELEASENOTE_ISSUEID related to '\" + currentVer + \"'.\");\n            return;\n        }\n        var issueURL = result[0]['url'].split('/');\n        window.RELEASENOTE_ISSUEID = issueURL[7];\n    }\n\n    function getRELEASENOTE_ISSUEID(version) {\n        var versionSplit = version.split('.');\n        versionSplit[2] = 'x';\n        var versionSplitBig = versionSplit.join('.');\n        getIssuesByLabels(\"发布,\" + versionSplitBig, getRELEASENOTE_ISSUEID_Callback);\n        updateWelcome();\n    }\n\n\n</script>\n<script type=\"text/javascript\">\n    function getConfig(key) {\n        var result;\n        var pageRequests = {\n            'cmd': 'get_config'\n        };\n        $.ajax({\n            async: false,\n            type: 'GET',\n            url: '/config',\n            data: pageRequests,\n            dataType: 'JSON',\n            success: function (res) {\n                result = res;\n            },\n            error: function (res) {\n                result = res;\n            }\n        });\n        if (key) {\n            var res = result;\n            result = \"nomatch\";\n            Object.keys(res).forEach(function (t) {\n                if (t === key) {\n                    result = res[t];\n                    //return;\n                }\n            });\n        }\n        return result;\n    }\n\n    function setConfig(key, value) {\n        //var result;\n        var pageRequests = {\n            'cmd': 'set_config'\n        };\n        pageRequests[key] = value;\n        $.ajax({\n            //async: false,\n            type: 'GET',\n            url: '/config',\n            data: pageRequests,\n            dataType: 'JSON',\n            success: function (result) {\n                if (result && (result['res'] === 'success')) {\n                    if (key === 'postUpdateStat') return;\n                    tip('{{ _( \"Settings saved successfully.\" ) }}', 'success');\n                    if (key === 'gae_proxy_enable' || key === 'x_tunnel_enable' || key === 'smart_router_enable') {\n                        restartingService(key); //call from config.html\n                    }\n                } else {\n                    displayErrorMessage();\n                }\n            },\n            error: function (result) {\n                displayErrorMessage();\n            }\n        });\n        //return result;\n    }\n\n    function displayErrorMessage() {\n        tip('{{ _( \"Unkown error occured. Please refresh the page and try again.\" ) }}', 'error');\n    }\n\n\n</script>\n<script type=\"text/javascript\">\n    init_main();\n    function init_main() {\n        var pageRequests = {\n            'cmd': 'get_version'\n        };\n        $.ajax({\n            type: 'GET',\n            url: '/config',\n            data: pageRequests,\n            dataType: 'JSON',\n            success: function (result) {\n                var currentVer = result['current_version'];\n                document.getElementById(\"version_on_logo\").appendChild(document.createTextNode(currentVer));\n\n                // getRELEASENOTE_ISSUEID(currentVer);\n            }\n        });\n\n        if (getConfig('allow_remote_connect') !== 0) {\n            $('#remote-connection-identifier').show();\n        }\n    }\n\n\n</script>\n<script type=\"text/javascript\">\n    var checkUpdateTimeout = 600000;\n    var checkUpdateTimer;\n    var versionToUpdate;\n    var versionType;\n\n    function startUpdateCheck() {\n        $('#update-notify').addClass('hide');\n\n        var pageRequests = {\n            'cmd': 'start_check',\n            'check_update': $('#check-update').val()//getConfig('check-update')\n        };\n        $.ajax({\n            type: 'GET',\n            url: '/update',\n            data: pageRequests,\n            dataType: 'JSON',\n            success: function (result) {\n                if (result['res'] === 'success') {\n                    getUpdateInfo();\n                    checkUpdateTimer.play();\n                } else {\n                    tip(result['reason'], \"warning\");\n                }\n            },\n            error: function () {\n                displayErrorMessage();\n            }\n        });\n    }\n\n    function stopUpdateCheck() {\n        $('#update-notify').addClass('hide');\n        checkUpdateTimer.stop();\n\n        var pageRequests = {\n            'cmd': 'set_info',\n            'info': 'dont-check'\n        };\n        $.ajax({\n            type: 'GET',\n            url: '/update',\n            data: pageRequests,\n            dataType: 'JSON',\n            success: function (result) {\n                if (result['res'] !== 'success') {\n                    tip(result['reason'], 'warning');\n                }\n            },\n            error: function () {\n                displayErrorMessage();\n            }\n        });\n    }\n\n    function clearUpdateInfo() {\n        $('#update-notify').addClass('hide');\n\n        var pageRequests = {\n            'cmd': 'set_info',\n            'info': ''\n        };\n        $.ajax({\n            type: 'GET',\n            url: '/update',\n            data: pageRequests,\n            dataType: 'JSON',\n            success: function (result) {\n                if (result['res'] !== 'success') {\n                    tip(result['reason'], \"warning\");\n                }\n            },\n            error: function () {\n                displayErrorMessage();\n            }\n        });\n    }\n\n    function skipUpdateVersion() {\n        $('#update-notify').addClass('hide');\n        checkUpdateTimer.stop();\n\n        var pageRequests = {\n            'cmd': 'set_config',\n            'skip_version': versionToUpdate,\n            'skip_version_type': versionType\n        };\n        $.ajax({\n            type: 'GET',\n            url: '/config',\n            data: pageRequests,\n            dataType: 'JSON',\n            success: function (result) {\n                if (result['res'] !== 'success') {\n                    tip(result['reason'], \"warning\");\n                }\n            },\n            error: function () {\n                displayErrorMessage();\n            }\n        });\n    }\n\n    function updateBase(checkhash) {\n        $('#update-notify').addClass('hide');\n\n        var pageRequests = {\n            'cmd': 'update_version',\n            'version': versionToUpdate,\n            'checkhash': checkhash || 0\n        };\n        versionToUpdate = null;\n        $.ajax({\n            type: 'GET',\n            url: '/update',\n            data: pageRequests,\n            dataType: 'JSON',\n            success: function (result) {\n                if (result['res'] === 'success') {\n                    tip('{{ _( \"Updating in progress ...\" ) }}', \"info\");\n                    window.updateProgress_timer.play();\n                } else {\n                    tip(result['reason'], \"warning\");\n                }\n            },\n            error: function () {\n                displayErrorMessage();\n            }\n        });\n    }\n    function updateVersion() {\n        updateBase(1);\n    }\n    function updateVersionWithoutHashCheck() {\n        updateBase(0);\n    }\n\n    function getUpdateInfo() {\n        if (!$('#update-notify').hasClass('hide') ||\n            !$('#update-progress-bar').hasClass('hide')) {\n            return;\n        }\n\n        var pageRequests = {\n            'cmd': 'get_info'\n        };\n        $.ajax({\n            type: 'GET',\n            url: '/update',\n            data: pageRequests,\n            dataType: 'JSON',\n            success: function (result) {\n                versionType = result['type'];\n                switch (versionType) {\n                    case 'init':\n                        window.setTimeout(startUpdateCheck, 1000);\n                        break;\n                    case 'dont-check':\n                        //stopUpdateCheck();\n                        $('#update-notify').addClass('hide');\n                        checkUpdateTimer.stop();\n                        break;\n                    default:\n                        versionToUpdate = result['version'];\n                        if (versionType && versionToUpdate) {\n                            switch (versionType) {\n                                case 'stable':\n                                    var popText = '{{ _( \"New \" ) }}{{ _( \"Stable version\" ) }} ' + versionToUpdate;\n                                    break;\n                                case 'test':\n                                    var popText = '{{ _( \"New \" ) }}{{ _( \"Test version\" ) }} ' + versionToUpdate;\n                            }\n                            $('#update-message').text(popText);\n                            $('#update-viewchanges').attr(\"href\", \"https://github.com/XX-net/XX-Net/releases/tag/\" + versionToUpdate);\n                            $('#update-notify').removeClass('hide');\n                        }\n                }\n            }\n        });\n    }\n\n    function updateProgress() { //TODO: 完善tip（详细信息、翻译, etc.)\n        $.getJSON('update?cmd=get_progress', function (result) {\n            Object.keys(result).forEach(function (v) {\n                if (v === \"update_status\") {\n                    var stat = result[v];\n                    switch (stat) {\n                        case \"Idle\":\n                            window.updateProgress_timer.stop();\n                            break;\n                        case \"Finished\":\n                            tip('{{ _( \"Finished.\" ) }}', 'info');\n                            window.loading.stop();\n                            window.updateProgress_timer.stop();\n                            break;\n                        default:\n                            if (stat.indexOf('Fail') > -1) {\n                                tip(stat, 'warning');\n                                window.updateProgress_timer.stop();\n                            } else {\n                                tip(stat, 'info');\n                            }\n                    }\n                    /*\n                    if (stat === \"Idle\") {\n                        window.updateProgress_timer.stop();\n                        return;\n                    }\n                    /*\n                    if ($('#upgrade-pull-icon').hasClass('icon-chevron-right')) {\n                        var current_version = $('#current-version-no').html();\n                        if (current_version === \"\") {\n                            $('#current-version-no').html(\" \"); // avoid check next time.\n                            check_new_version();\n                        }\n\n                        $('.version-line').slideDown('fast');\n\n                        $('#upgrade-pull-icon').removeClass('icon-chevron-right');\n                        $('#upgrade-pull-icon').addClass('icon-chevron-down');\n                        $('#update-options').slideDown();\n                    }\n\n                    if (stat === \"Finished\") {\n                        tip(stat, 'info');\n                        window.loading.stop();\n                        window.updateProgress_timer.stop();\n                        //return;\n                    } else if (stat.indexOf('Fail') > -1) {\n                        tip(stat, 'warning');\n                        window.updateProgress_timer.stop();\n                    } else {\n                        tip(stat, 'info');\n                    }\n                    */\n                } else if (v.indexOf('XX-Net/zip') > -1) {\n                    if (!window.updating_button) {\n                        var p = v.indexOf('XX-Net/zip') + 11;\n                        var version = v.substring(p, v.length);\n                        var button;\n                        if (version === $('#test-version-no').html()) {\n                            button = $('#update-test-version');\n                        } else if (version === $('#stable-version-no').html()) {\n                            button = $('#update-stable-version');\n                        } else if ($('.active a').attr('href') === '/?module=launcher&menu=config') {\n                            return;\n                        } else {\n                            button = $('#update-progress-bar').find('span');\n                            $('#update-progress-bar').removeClass('hide');\n                        }\n                        window.updating_button = button;\n                    }\n                    $('#update-notify').addClass('hide');\n\n                    if (!window.loading) {\n                        window.loading = Ladda.create(window.updating_button[0]);\n                        window.loading.start();\n                    }\n                    var data = result[v];\n                    if (data.status === 'downloading') {\n                        var progress = (+data.downloaded / +data.size) * 100;\n                        window.loading.setProgress(progress);\n                        window.updating_button.html('{{ _( \"Downloading ...\" ) }}' + parseInt(progress) + '&#37;');\n                    } else if (data.status === \"finished\") {\n                        window.updating_button.html('{{ _( \"Download completed.\" ) }}');\n                        window.updating_button.prop('disabled', true);\n                        window.updating_button = null;\n                        window.setTimeout(function clearProgressBar() {\n                            $('#update-progress-bar').addClass('hide');\n                        }, 5000);\n                        window.loading.stop();\n                        window.updateProgress_timer.stop();\n                    }\n                }\n            });\n        });\n    }\n\n    $(document).ready(function () {\n        var rfn;\n        for (rfn in documentReadyToRun) {\n            documentReadyToRun[rfn]();\n        }\n        window.updateProgress_timer = $.timer(updateProgress, 1000, true);\n        updateProgress();\n        checkUpdateTimer = $.timer(getUpdateInfo, checkUpdateTimeout, true);\n        window.setTimeout(getUpdateInfo, 300*1000);\n    });\n\n    $('#update-now').click(updateVersion);\n    $('#update-next').click(clearUpdateInfo);\n    $('#update-skip').click(skipUpdateVersion);\n    $('#update-notify-close').click(clearUpdateInfo);\n    // site.js fix\n    $('#tip-close').click(tipClose);\n\n\n</script>\n<div id=\"display-issue-modal\" class=\"modal hide fade\" style=\"width: auto;\">\n    <div class=\"modal-header\">\n        <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-hidden=\"true\">&times;</button>\n        <h3 id=\"display-issue-model-title\">{{ _( \"Info\" ) }}</h3>\n    </div> <!-- .modal-header -->\n    <div id=\"display-issue-modal-body\" class=\"modal-body\">\n    </div> <!-- .modal-body -->\n    <div class=\"modal-footer\">\n    </div> <!-- .modal-footer -->\n</div> <!-- #display-issue-modal -->\n<link rel=\"stylesheet\" type=\"text/css\" href=\"/css/primer-markdown.css\">\n<script type=\"text/javascript\">\n    function renderMD(rawText, mode, context) {\n        if (rawText === undefined) {\n            throw new Error(\"rawText undefined\");\n        }\n        var res = document.createElement('div');\n        res.setAttribute('class', 'markdown-body');\n        var rq = {\n            'text': rawText,\n            'mode': mode || 'gfm',\n            'context': context || 'XX-net/XX-Net'\n        };\n        $.ajax({\n            async: false,\n            type: 'POST',\n            url: 'https://api.github.com/markdown',\n            data: JSON.stringify(rq),\n            contentType: 'application/json',\n            dataType: 'html',// Accept: application/vnd.github.v3.html+json\n            // timeout: 1000,\n            success: function (result) {\n                res.innerHTML = result;\n            },\n            error: function (result) {\n                throw new Error(\"Failed rendering.\");\n            }\n        });\n        return res;\n    }\n\n    function popIssue(issueID, repo) {\n        repo = repo || 'XX-net/XX-Net';\n        issueID = issueID || window.RELEASENOTE_ISSUEID;\n        try {\n            var APIurl = 'https://api.github.com/repos/' + repo + '/issues/' + issueID;\n            $.ajax({\n                //async: false,\n                type: 'GET',\n                url: APIurl,\n                dataType: 'JSON',\n                success: function (result) {\n                    var title = document.getElementById('display-issue-model-title');\n                    title.innerHTML = '<a href=\"' + result['html_url'] + '\" target=\"_blank\" style=\"color: grey\">' + result['title'] + '</a>';\n                    var rawText = result['body'];\n                    var rendered;\n                    try {\n                        rendered = renderMD(rawText);\n                    }\n                    catch (err) {\n                        throw err;\n                    }\n                    var body = document.getElementById('display-issue-modal-body');\n                    body.innerHTML = rendered.outerHTML;\n                    // body.style('https://unpkg.com/primer-markdown/build/build.css');\n                    $('#display-issue-modal').modal();\n                },\n                error: function (result) {\n                    throw new Error(\"Failed loading.\");\n                }\n            });\n        }\n        catch (err) {\n            // console.log(err.message);\n            // tip('{ { _( err ) }}', 'error');\n        }\n    }\n\n\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "code/default/launcher/web_ui/js/flat-ui.js",
    "content": "/*!\n * Flat UI Free v2.0.0 (http://designmodo.github.io/Flat-UI/)\n * Copyright 2013-2014 Designmodo, Inc.\n */\n/* ============================================================\n * bootstrapSwitch v1.3 by Larentis Mattia @spiritualGuru\n * http://www.larentis.eu/switch/\n * ============================================================\n * Licensed under the Apache License, Version 2.0\n * http://www.apache.org/licenses/LICENSE-2.0\n * ============================================================ */\n\n!function ($) {\n  \"use strict\";\n\n  $.fn['bootstrapSwitch'] = function (method) {\n    var methods = {\n      init: function () {\n        return this.each(function () {\n            var $element = $(this)\n              , $div\n              , $switchLeft\n              , $switchRight\n              , $label\n              , myClasses = \"\"\n              , classes = $element.attr('class')\n              , color\n              , moving\n              , onLabel = \"ON\"\n              , offLabel = \"OFF\"\n              , icon = false;\n\n            $.each(['switch-mini', 'switch-small', 'switch-large'], function (i, el) {\n              if (classes.indexOf(el) >= 0)\n                myClasses = el;\n            });\n\n            $element.addClass('has-switch');\n\n            if ($element.data('on') !== undefined)\n              color = \"switch-\" + $element.data('on');\n\n            if ($element.data('on-label') !== undefined)\n              onLabel = $element.data('on-label');\n\n            if ($element.data('off-label') !== undefined)\n              offLabel = $element.data('off-label');\n\n            if ($element.data('icon') !== undefined)\n              icon = $element.data('icon');\n\n            $switchLeft = $('<span>')\n              .addClass(\"switch-left\")\n              .addClass(myClasses)\n              .addClass(color)\n              .html(onLabel);\n\n            color = '';\n            if ($element.data('off') !== undefined)\n              color = \"switch-\" + $element.data('off');\n\n            $switchRight = $('<span>')\n              .addClass(\"switch-right\")\n              .addClass(myClasses)\n              .addClass(color)\n              .html(offLabel);\n\n            $label = $('<label>')\n              .html(\"&nbsp;\")\n              .addClass(myClasses)\n              .attr('for', $element.find('input').attr('id'));\n\n            if (icon) {\n              $label.html('<i class=\"' + icon + '\"></i>');\n            }\n\n            $div = $element.find(':checkbox').wrap($('<div>')).parent().data('animated', false);\n\n            if ($element.data('animated') !== false)\n              $div.addClass('switch-animate').data('animated', true);\n\n            $div\n              .append($switchLeft)\n              .append($label)\n              .append($switchRight);\n\n            $element.find('>div').addClass(\n              $element.find('input').is(':checked') ? 'switch-on' : 'switch-off'\n            );\n\n            if ($element.find('input').is(':disabled'))\n              $(this).addClass('deactivate');\n\n            var changeStatus = function ($this) {\n              $this.siblings('label').trigger('mousedown').trigger('mouseup').trigger('click');\n            };\n\n            $element.on('keydown', function (e) {\n              if (e.keyCode === 32) {\n                e.stopImmediatePropagation();\n                e.preventDefault();\n                changeStatus($(e.target).find('span:first'));\n              }\n            });\n\n            $switchLeft.on('click', function (e) {\n              changeStatus($(this));\n            });\n\n            $switchRight.on('click', function (e) {\n              changeStatus($(this));\n            });\n\n            $element.find('input').on('change', function (e) {\n              var $this = $(this)\n                , $element = $this.parent()\n                , thisState = $this.is(':checked')\n                , state = $element.is('.switch-off');\n\n              e.preventDefault();\n\n              $element.css('left', '');\n\n              if (state === thisState) {\n\n                if (thisState)\n                  $element.removeClass('switch-off').addClass('switch-on');\n                else $element.removeClass('switch-on').addClass('switch-off');\n\n                if ($element.data('animated') !== false)\n                  $element.addClass(\"switch-animate\");\n\n                $element.parent().trigger('switch-change', {'el': $this, 'value': thisState})\n              }\n            });\n\n            $element.find('label').on('mousedown touchstart', function (e) {\n              var $this = $(this);\n              moving = false;\n\n              e.preventDefault();\n              e.stopImmediatePropagation();\n\n              $this.closest('div').removeClass('switch-animate');\n\n              if ($this.closest('.has-switch').is('.deactivate'))\n                $this.unbind('click');\n              else {\n                $this.on('mousemove touchmove', function (e) {\n                  var $element = $(this).closest('.switch')\n                    , relativeX = (e.pageX || e.originalEvent.targetTouches[0].pageX) - $element.offset().left\n                    , percent = (relativeX / $element.width()) * 100\n                    , left = 25\n                    , right = 75;\n\n                  moving = true;\n\n                  if (percent < left)\n                    percent = left;\n                  else if (percent > right)\n                    percent = right;\n\n                  $element.find('>div').css('left', (percent - right) + \"%\")\n                });\n\n                $this.on('click touchend', function (e) {\n                  var $this = $(this)\n                    , $target = $(e.target)\n                    , $myCheckBox = $target.siblings('input');\n\n                  e.stopImmediatePropagation();\n                  e.preventDefault();\n\n                  $this.unbind('mouseleave');\n\n                  if (moving)\n                    $myCheckBox.prop('checked', !(parseInt($this.parent().css('left')) < -25));\n                  else $myCheckBox.prop(\"checked\", !$myCheckBox.is(\":checked\"));\n\n                  moving = false;\n                  $myCheckBox.trigger('change');\n                });\n\n                $this.on('mouseleave', function (e) {\n                  var $this = $(this)\n                    , $myCheckBox = $this.siblings('input');\n\n                  e.preventDefault();\n                  e.stopImmediatePropagation();\n\n                  $this.unbind('mouseleave');\n                  $this.trigger('mouseup');\n\n                  $myCheckBox.prop('checked', !(parseInt($this.parent().css('left')) < -25)).trigger('change');\n                });\n\n                $this.on('mouseup', function (e) {\n                  e.stopImmediatePropagation();\n                  e.preventDefault();\n\n                  $(this).unbind('mousemove');\n                });\n              }\n            });\n          }\n        );\n      },\n      toggleActivation: function () {\n        $(this).toggleClass('deactivate');\n      },\n      isActive: function () {\n        return !$(this).hasClass('deactivate');\n      },\n      setActive: function (active) {\n        if (active)\n          $(this).removeClass('deactivate');\n        else $(this).addClass('deactivate');\n      },\n      toggleState: function (skipOnChange) {\n        var $input = $(this).find('input:checkbox');\n        $input.prop('checked', !$input.is(':checked')).trigger('change', skipOnChange);\n      },\n      setState: function (value, skipOnChange) {\n        $(this).find('input:checkbox').prop('checked', value).trigger('change', skipOnChange);\n      },\n      status: function () {\n        return $(this).find('input:checkbox').is(':checked');\n      },\n      destroy: function () {\n        var $div = $(this).find('div')\n          , $checkbox;\n\n        $div.find(':not(input:checkbox)').remove();\n\n        $checkbox = $div.children();\n        $checkbox.unwrap().unwrap();\n\n        $checkbox.unbind('change');\n\n        return $checkbox;\n      }\n    };\n\n    if (methods[method])\n      return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));\n    else if (typeof method === 'object' || !method)\n      return methods.init.apply(this, arguments);\n    else\n      $.error('Method ' + method + ' does not exist!');\n  };\n}(jQuery);\n\n$(function () {\n  $('.switch')['bootstrapSwitch']();\n});\n\n\n/* =============================================================\n * flatui-checkbox.js v0.0.2\n * ============================================================ */\n\n!function ($) {\n\n /* CHECKBOX PUBLIC CLASS DEFINITION\n  * ============================== */\n\n  var Checkbox = function (element, options) {\n    this.init(element, options);\n  }\n\n  Checkbox.prototype = {\n\n    constructor: Checkbox\n\n  , init: function (element, options) {\n    var $el = this.$element = $(element)\n\n    this.options = $.extend({}, $.fn.checkbox.defaults, options);\n    $el.before(this.options.template);\n    this.setState();\n  }\n\n  , setState: function () {\n      var $el = this.$element\n        , $parent = $el.closest('.checkbox');\n\n        $el.prop('disabled') && $parent.addClass('disabled');\n        $el.prop('checked') && $parent.addClass('checked');\n    }\n\n  , toggle: function () {\n      var ch = 'checked'\n        , $el = this.$element\n        , $parent = $el.closest('.checkbox')\n        , checked = $el.prop(ch)\n        , e = $.Event('toggle')\n\n      if ($el.prop('disabled') == false) {\n        $parent.toggleClass(ch) && checked ? $el.removeAttr(ch) : $el.attr(ch, true);\n        $el.trigger(e).trigger('change');\n      }\n    }\n\n  , setCheck: function (option) {\n      var d = 'disabled'\n        , ch = 'checked'\n        , $el = this.$element\n        , $parent = $el.closest('.checkbox')\n        , checkAction = option == 'check' ? true : false\n        , e = $.Event(option)\n\n      $parent[checkAction ? 'addClass' : 'removeClass' ](ch) && checkAction ? $el.attr(ch, true) : $el.removeAttr(ch);\n      $el.trigger(e).trigger('change');\n    }\n  }\n\n\n /* CHECKBOX PLUGIN DEFINITION\n  * ======================== */\n\n  var old = $.fn.checkbox\n\n  $.fn.checkbox = function (option) {\n    return this.each(function () {\n      var $this = $(this)\n        , data = $this.data('checkbox')\n        , options = $.extend({}, $.fn.checkbox.defaults, $this.data(), typeof option == 'object' && option);\n      if (!data) $this.data('checkbox', (data = new Checkbox(this, options)));\n      if (option == 'toggle') data.toggle()\n      if (option == 'check' || option == 'uncheck') data.setCheck(option)\n      else if (option) data.setState();\n    });\n  }\n\n  $.fn.checkbox.defaults = {\n    template: '<span class=\"icons\"><span class=\"first-icon fui-checkbox-unchecked\"></span><span class=\"second-icon fui-checkbox-checked\"></span></span>'\n  }\n\n\n /* CHECKBOX NO CONFLICT\n  * ================== */\n\n  $.fn.checkbox.noConflict = function () {\n    $.fn.checkbox = old;\n    return this;\n  }\n\n\n /* CHECKBOX DATA-API\n  * =============== */\n\n  $(document).on('click.checkbox.data-api', '[data-toggle^=checkbox], .checkbox', function (e) {\n    var $checkbox = $(e.target);\n    e && e.preventDefault() && e.stopPropagation();\n    if (!$checkbox.hasClass('checkbox')) $checkbox = $checkbox.closest('.checkbox');\n    $checkbox.find(':checkbox').checkbox('toggle');\n  });\n\n  $(window).on('load', function () {\n    $('[data-toggle=\"checkbox\"]').each(function () {\n      var $checkbox = $(this);\n      $checkbox.checkbox();\n    });\n  });\n\n}(window.jQuery);\n\n\n/* =============================================================\n * flatui-radio.js v0.0.2\n * ============================================================ */\n\n!function ($) {\n\n /* RADIO PUBLIC CLASS DEFINITION\n  * ============================== */\n\n  var Radio = function (element, options) {\n    this.init(element, options);\n  }\n\n  Radio.prototype = {\n\n    constructor: Radio\n\n  , init: function (element, options) {\n      var $el = this.$element = $(element)\n\n      this.options = $.extend({}, $.fn.radio.defaults, options);\n      $el.before(this.options.template);\n      this.setState();\n    }\n\n  , setState: function () {\n      var $el = this.$element\n        , $parent = $el.closest('.radio');\n\n        $el.prop('disabled') && $parent.addClass('disabled');\n        $el.prop('checked') && $parent.addClass('checked');\n    }\n\n  , toggle: function () {\n      var d = 'disabled'\n        , ch = 'checked'\n        , $el = this.$element\n        , checked = $el.prop(ch)\n        , $parent = $el.closest('.radio')\n        , $parentWrap = $el.closest('form').length ? $el.closest('form') : $el.closest('body')\n        , $elemGroup = $parentWrap.find(':radio[name=\"' + $el.attr('name') + '\"]')\n        , e = $.Event('toggle')\n\n        $elemGroup.not($el).each(function () {\n          var $el = $(this)\n            , $parent = $(this).closest('.radio');\n\n            if ($el.prop(d) == false) {\n              $parent.removeClass(ch) && $el.attr(ch, false).trigger('change');\n            }\n        });\n\n        if ($el.prop(d) == false) {\n          if (checked == false) $parent.addClass(ch) && $el.attr(ch, true);\n          $el.trigger(e);\n\n          if (checked !== $el.prop(ch)) {\n            $el.trigger('change');\n          }\n        }\n    }\n\n  , setCheck: function (option) {\n      var ch = 'checked'\n        , $el = this.$element\n        , $parent = $el.closest('.radio')\n        , checkAction = option == 'check' ? true : false\n        , checked = $el.prop(ch)\n        , $parentWrap = $el.closest('form').length ? $el.closest('form') : $el.closest('body')\n        , $elemGroup = $parentWrap.find(':radio[name=\"' + $el['attr']('name') + '\"]')\n        , e = $.Event(option)\n\n      $elemGroup.not($el).each(function () {\n        var $el = $(this)\n          , $parent = $(this).closest('.radio');\n\n          $parent.removeClass(ch) && $el.removeAttr(ch);\n      });\n\n      $parent[checkAction ? 'addClass' : 'removeClass'](ch) && checkAction ? $el.attr(ch, true) : $el.removeAttr(ch);\n      $el.trigger(e);\n\n      if (checked !== $el.prop(ch)) {\n        $el.trigger('change');\n      }\n    }\n  }\n\n\n /* RADIO PLUGIN DEFINITION\n  * ======================== */\n\n  var old = $.fn.radio\n\n  $.fn.radio = function (option) {\n    return this.each(function () {\n      var $this = $(this)\n        , data = $this.data('radio')\n        , options = $.extend({}, $.fn.radio.defaults, $this.data(), typeof option == 'object' && option);\n      if (!data) $this.data('radio', (data = new Radio(this, options)));\n      if (option == 'toggle') data.toggle()\n      if (option == 'check' || option == 'uncheck') data.setCheck(option)\n      else if (option) data.setState();\n    });\n  }\n\n  $.fn.radio.defaults = {\n    template: '<span class=\"icons\"><span class=\"first-icon fui-radio-unchecked\"></span><span class=\"second-icon fui-radio-checked\"></span></span>'\n  }\n\n\n /* RADIO NO CONFLICT\n  * ================== */\n\n  $.fn.radio.noConflict = function () {\n    $.fn.radio = old;\n    return this;\n  }\n\n\n /* RADIO DATA-API\n  * =============== */\n\n  $(document).on('click.radio.data-api', '[data-toggle^=radio], .radio', function (e) {\n    var $radio = $(e.target);\n    e && e.preventDefault() && e.stopPropagation();\n    if (!$radio.hasClass('radio')) $radio = $radio.closest('.radio');\n    $radio.find(':radio').radio('toggle');\n  });\n\n  $(window).on('load', function () {\n    $('[data-toggle=\"radio\"]').each(function () {\n      var $radio = $(this);\n      $radio.radio();\n    });\n  });\n\n}(window.jQuery);"
  },
  {
    "path": "code/default/launcher/web_ui/js/jquery.timer.js",
    "content": "/**\r\n * jquery.timer.js\r\n *\r\n * Copyright (c) 2011 Jason Chavannes <jason.chavannes@gmail.com>\r\n *\r\n * http://jchavannes.com/jquery-timer\r\n *\r\n * Permission is hereby granted, free of charge, to any person\r\n * obtaining a copy of this software and associated documentation\r\n * files (the \"Software\"), to deal in the Software without\r\n * restriction, including without limitation the rights to use, copy,\r\n * modify, merge, publish, distribute, sublicense, and/or sell copies\r\n * of the Software, and to permit persons to whom the Software is\r\n * furnished to do so, subject to the following conditions:\r\n *\r\n * The above copyright notice and this permission notice shall be\r\n * included in all copies or substantial portions of the Software.\r\n *\r\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\r\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r\n * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r\n * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r\n * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n * SOFTWARE.\r\n */\r\n\r\n;(function($) {\r\n\t$.timer = function(func, time, autostart) {\r\n\t \tthis.set = function(func, time, autostart) {\r\n\t \t\tthis.init = true;\r\n\t \t \tif(typeof func == 'object') {\r\n\t\t \t \tvar paramList = ['autostart', 'time'];\r\n\t \t \t \tfor(var arg in paramList) {if(func[paramList[arg]] != undefined) {eval(paramList[arg] + \" = func[paramList[arg]]\");}};\r\n \t \t\t\tfunc = func.action;\r\n\t \t \t}\r\n\t \t \tif(typeof func == 'function') {this.action = func;}\r\n\t\t \tif(!isNaN(time)) {this.intervalTime = time;}\r\n\t\t \tif(autostart && !this.isActive) {\r\n\t\t\t \tthis.isActive = true;\r\n\t\t\t \tthis.setTimer();\r\n\t\t \t}\r\n\t\t \treturn this;\r\n\t \t};\r\n\t \tthis.once = function(time) {\r\n\t\t\tvar timer = this;\r\n\t \t \tif(isNaN(time)) {time = 0;}\r\n\t\t\twindow.setTimeout(function() {timer.action();}, time);\r\n\t \t\treturn this;\r\n\t \t};\r\n\t\tthis.play = function(reset) {\r\n\t\t\tif(!this.isActive) {\r\n\t\t\t\tif(reset) {this.setTimer();}\r\n\t\t\t\telse {this.setTimer(this.remaining);}\r\n\t\t\t\tthis.isActive = true;\r\n\t\t\t}\r\n\t\t\treturn this;\r\n\t\t};\r\n\t\tthis.pause = function() {\r\n\t\t\tif(this.isActive) {\r\n\t\t\t\tthis.isActive = false;\r\n\t\t\t\tthis.remaining -= new Date() - this.last;\r\n\t\t\t\tthis.clearTimer();\r\n\t\t\t}\r\n\t\t\treturn this;\r\n\t\t};\r\n\t\tthis.stop = function() {\r\n\t\t\tthis.isActive = false;\r\n\t\t\tthis.remaining = this.intervalTime;\r\n\t\t\tthis.clearTimer();\r\n\t\t\treturn this;\r\n\t\t};\r\n\t\tthis.toggle = function(reset) {\r\n\t\t\tif(this.isActive) {this.pause();}\r\n\t\t\telse if(reset) {this.play(true);}\r\n\t\t\telse {this.play();}\r\n\t\t\treturn this;\r\n\t\t};\r\n\t\tthis.reset = function() {\r\n\t\t\tthis.isActive = false;\r\n\t\t\tthis.play(true);\r\n\t\t\treturn this;\r\n\t\t};\r\n\t\tthis.clearTimer = function() {\r\n\t\t\twindow.clearTimeout(this.timeoutObject);\r\n\t\t};\r\n\t \tthis.setTimer = function(time) {\r\n\t\t\tvar timer = this;\r\n\t \t \tif(typeof this.action != 'function') {return;}\r\n\t \t \tif(isNaN(time)) {time = this.intervalTime;}\r\n\t\t \tthis.remaining = time;\r\n\t \t \tthis.last = new Date();\r\n\t\t\tthis.clearTimer();\r\n\t\t\tthis.timeoutObject = window.setTimeout(function() {timer.go();}, time);\r\n\t\t};\r\n\t \tthis.go = function() {\r\n\t \t\tif(this.isActive) {\r\n\t \t\t\tthis.action();\r\n\t \t\t\tthis.setTimer();\r\n\t \t\t}\r\n\t \t};\r\n\r\n\t \tif(this.init) {\r\n\t \t\treturn new $.timer(func, time, autostart);\r\n\t \t} else {\r\n\t\t\tthis.set(func, time, autostart);\r\n\t \t\treturn this;\r\n\t \t}\r\n\t};\r\n})(jQuery);"
  },
  {
    "path": "code/default/launcher/web_ui/js/site.js",
    "content": "/* String format */\nString.prototype.format = function() {\n    var newStr = this, i = 0;\n    while (/%s/.test(newStr)) {\n        newStr = newStr.replace(\"%s\", arguments[i++])\n    }\n    return newStr;\n}\n\n/* JavaScript for UI */\nfunction title(title) {\n    $('#title').text(title);\n}\n\nfunction tip(message, type, allowOff) {\n    if( allowOff === undefined ) {\n        allowOff = true;\n    }\n    if( type === undefined ) {\n        type = 'info';\n    }\n\n    $('#tip').removeClass('alert-info');\n    $('#tip').removeClass('alert-warning');\n    $('#tip').removeClass('alert-success');\n    $('#tip').removeClass('alert-error');\n    $('#tip').removeClass('hide');\n\n    $('#tip').addClass('alert-' + type);\n\n    $('#tip-message').html(message);\n\n    if( allowOff === true ) {\n        $('#tip-close').css('display', '');\n    } else {\n        $('#tip-close').css('display', 'none');\n    }\n}\nfunction tipClose() {\n    $('#tip').addClass('hide');\n}\nfunction tipHasClose() {\n    return $('#tip').hasClass('hide');\n}\n\n$('#tip-close').click(function() {\n    tipClose();\n});"
  },
  {
    "path": "code/default/launcher/web_ui/logging.html",
    "content": "<div id=\"log-container\" class=\"row-fluid\">\n    <div id=\"log\" class=\"span12\"></div> <!-- #log -->\n</div> <!-- #log-container -->\n\n<script type=\"text/javascript\">\n    title('{{ _(\"System\") }} {{ _(\"Log\") }}');\n</script>\n<style type=\"text/css\">\n    .DUMMY { color: black }\n    .DEBUG { color: #21610b }\n    .INFO { color: blue }\n    .WARNING { color: #ff8000 }\n    .ERROR { color: #fe2e2e }\n    .CRITICAL { color: #d7df01 }\n</style>\n<script type=\"text/javascript\">\n    $(function () {\n        resizeLogWindow();\n    });\n\n    $(window).resize(function () {\n        resizeLogWindow();\n    });\n</script>\n<script type=\"text/javascript\">\n    function resizeLogWindow() {\n        var windowHeight    = $(window).height(),\n            preservedHeight = 170;\n\n        $('#log').css('height', windowHeight - preservedHeight);\n    }\n</script>\n<script type=\"text/javascript\">\n    $(function () {\n        window.previousOffset     = 0;\n        window.offset             = 1;\n        window.logLineNum         = 0;\n        window.isAutoScrollLog    = true;\n        window.isgetLogProcessing = false;\n\n        var timer = $.timer(function () {\n            getLog();\n        });\n        timer.set({\n            time: 500,\n            autostart: true\n        });\n    });\n</script>\n<script type=\"text/javascript\">\n    $(function () {\n        getLog();\n    });\n</script>\n<script type=\"text/javascript\">\n    $('#log').scroll(function () {\n        var preservedHeight = $('#log').height() + 10,\n            scrollHeight    = $('#log')[0].scrollHeight,\n            scrollTop       = $('#log').scrollTop();\n\n        window.isAutoScrollLog = (scrollTop + preservedHeight === scrollHeight);\n    });\n</script>\n<script type=\"text/javascript\">\n    function scrollLog() {\n        if (window.isAutoScrollLog) {\n            $('#log').scrollTop($('#log')[0].scrollHeight);\n        }\n    }\n</script>\n<script type=\"text/javascript\">\n    function getLog() {\n        if (window.isgetLogProcessing) {\n            return;\n        }\n        if (!window.isAutoScrollLog) {\n            return;\n        }\n        window.isgetLogProcessing = true;\n\n        var pageRequests = {\n            'cmd': 'get_new',\n            'last_no': offset\n        };\n        $.ajax({\n            type: 'GET',\n            url: '/log',\n            data: pageRequests,\n            dataType: 'JSON',\n            success: function (result) {\n                var newlines = document.createDocumentFragment();\n                var newlineNum = 0;\n                $.each(result, function (lineNumber, log) {\n                    window.offset = lineNumber;\n\n                    var logTemplate = '<p class=\"%s\">%s</p>\\n';\n                    if (window.previousOffset != window.offset) {\n                        var newline = $(logTemplate.format(getLogLevel(log), log));\n                        $(newlines).append(newline);\n                        newlineNum += 1;\n                    }\n                });\n                window.logLineNum += newlineNum;\n                $('#log').append(newlines);\n                var maxLineNum = 1000;\n                var cutStep = 10;\n                if (window.logLineNum > maxLineNum + cutStep) {\n                    var numToCut = window.logLineNum - maxLineNum;\n                    var textblock = $('#log').html();\n                    var lines = textblock.split('\\n');\n                    lines.splice(0, numToCut);\n                    var newtext = lines.join('\\n');\n                    $('#log').html(newtext);\n                    window.logLineNum -= numToCut;\n                }\n\n                scrollLog();\n                window.previousOffset = window.offset;\n                window.isgetLogProcessing = false;\n            },\n            error: function (xml, info, obj) {\n                window.isgetLogProcessing = false;\n            }\n        });\n    }\n</script>\n<script type=\"text/javascript\">\n    function getLogLevel(log) {\n        if (log.indexOf('[DEBUG]') != -1) {\n            return 'DEBUG';\n        } else if (log.indexOf('[INFO]') != -1) {\n            return 'INFO';\n        } else if (log.indexOf('[WARNING]') != -1) {\n            return 'WARNING';\n        } else if (log.indexOf('[ERROR]') != -1) {\n            return 'ERROR';\n        } else if (log.indexOf('[CRITICAL]') != -1) {\n            return 'CRITICAL';\n        } else return 'DUMMY';\n    }\n</script>\n"
  },
  {
    "path": "code/default/launcher/web_ui/menu.json",
    "content": "{\n  \"module_title\": \"{{ _( \"System\" ) }}\",\n  \"menu_sort_id\": 100,\n  \"sub_menus\": {\n     \"2\":{\n       \"title\": \"{{ _( \"Configuration\" ) }}\",\n       \"url\": \"config\"\n     },\n     \"3\":{\n       \"title\": \"{{ _( \"About\" ) }}\",\n       \"url\": \"about\"\n     },\n     \"4\":{\n       \"title\": \"{{ _(\"Log\") }}\",\n       \"url\": \"logging\"\n     },\n     \"5\":{\n       \"title\": \"{{ _( \"Exit\" ) }}\",\n       \"api_url\": \"/quit\"\n     }\n  }\n}\n"
  },
  {
    "path": "code/default/launcher/web_ui/status.html",
    "content": "<!--[if lte IE 9]>\n<div class=\"alert alert-warning\">\n    {{ _( \"Your browser is obsolete. Partial functionality will not be available.\" ) }}<br>\n    {{ _( \"The latest Chrome browser is recommended.\" ) }}\n</div>\n<![endif]-->\n\n<div id=\"noob-info\" class=\"\"></div>\n\n<div id=\"details\" hidden>\n\n    <div id=\"search\">\n        <h4>{{ _( \"Search\" ) }}</h4>\n        <form accept-charset=\"UTF-8\" action=\"https://github.com/XX-net/XX-Net/issues\" data-pjax=\"true\" method=\"get\" target=\"_blank\" onsubmit=\"q.value='is:issue is:open '+q.value\">\n            <div style=\"margin:0;padding:0;display:inline\"><input name=\"utf8\" type=\"hidden\" value=\"✓\"></div>\n            <input id=\"issues-search\" name=\"q\" placeholder='{{ _( \"Search all issues\" ) }}' type=\"text\"> <!-- value=\"is:issue is:open \" -->\n            <!--<svg style=\"margin:0;padding:0;display:inline-block\" height=\"16\" width=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\"><path fill-rule=\"evenodd\" d=\"M15.7 13.3l-3.81-3.83A5.93 5.93 0 0 0 13 6c0-3.31-2.69-6-6-6S1 2.69 1 6s2.69 6 6 6c1.3 0 2.48-.41 3.47-1.11l3.83 3.81c.19.2.45.3.7.3.25 0 .52-.09.7-.3a.996.996 0 0 0 0-1.41v.01zM7 10.7c-2.59 0-4.7-2.11-4.7-4.7 0-2.59 2.11-4.7 4.7-4.7 2.59 0 4.7 2.11 4.7 4.7 0 2.59-2.11 4.7-4.7 4.7z\"/></svg>-->\n        </form>\n        <br/>\n    </div> <!-- #search -->\n\n    <h4>{{ _( \"Status\" ) }}</h4>\n    <table id=\"status\" class=\"table table-bordered table-striped\">\n        <thead>\n            <tr>\n                <th width=\"25%\">{{ _( \"Property\" ) }}</th>\n                <th>{{ _( \"Value\" ) }}</th>\n            </tr>\n        </thead>\n        <tbody>\n            <tr>\n                <td>{{ _( \"Status\" ) }}</td>\n                <td id=\"is-idle\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"Browser Proxy Setting\" ) }}</td>\n                <td id=\"browser-proxy-setting\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"CA status\" ) }}(<a href=\"/module/gae_proxy/control/download_cert\">{{ _( \"Download\" ) }}</a>)</td>\n                <td id=\"ca-status\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"System Proxy\" ) }}</td>\n                <td id=\"system-proxy\"></td>\n            </tr>\n        </tbody>\n    </table>\n\n    <h4>{{ _( \"Modules\" ) }}</h4>\n    <table id=\"modules\" class=\"table table-bordered table-striped\">\n        <thead>\n            <tr>\n                <th width=\"25%\">{{ _( \"Property\" ) }}</th>\n                <th>{{ _( \"Value\" ) }}</th>\n            </tr>\n        </thead>\n        <tbody>\n            <tr>\n                <td>{{ _( \"Launcher Web UI\" ) }}</td>\n                <td id=\"launcher\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"GAE Proxy\" ) }}</td>\n                <td id=\"gaeproxy-status\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"X-Tunnel\" ) }}</td>\n                <td id=\"xtunnel-status\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"Smart Router\" ) }}</td>\n                <td id=\"smartrouter-status\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"LAN proxy\" ) }}</td>\n                <td id=\"lan-proxy\"></td>\n            </tr>\n        </tbody>\n    </table>\n\n    <h4>{{ _( \"System Info\" ) }}</h4>\n    <table id=\"version\" class=\"table table-bordered table-striped\">\n        <thead>\n            <tr>\n                <th width=\"25%\">{{ _( \"Property\" ) }}</th>\n                <th width=\"75%\">{{ _( \"Value\" ) }}</th>\n            </tr>\n        </thead>\n        <tbody>\n            <tr>\n                <td>{{ _( \"APP_NAME\" ) }} Version</td>\n                <td id=\"xxnet-version\"></td>\n            </tr>\n            <tr>\n                <td>Python Version</td>\n                <td id=\"python-version\"></td>\n            </tr>\n            <tr>\n                <td>OpenSSL Version</td>\n                <td id=\"openssl-version\"></td>\n            </tr>\n            <tr>\n                <td>System Platform</td>\n                <td id=\"sys-platform\"></td>\n            </tr>\n            <tr>\n                <td>OS System</td>\n                <td id=\"os-system\"></td>\n            </tr>\n            <tr>\n                <td>OS Version</td>\n                <td id=\"os-version\"></td>\n            </tr>\n            <tr>\n                <td>OS Release</td>\n                <td id=\"os-release\"></td>\n            </tr>\n            <tr>\n                <td>OS Detail</td>\n                <td id=\"os-detail\"></td>\n            </tr>\n            <tr>\n                <td>Language</td>\n                <td id=\"language\"></td>\n            </tr>\n            <tr>\n                <td>Architecture</td>\n                <td id=\"architecture\"></td>\n            </tr>\n            <tr>\n                <td>Browser</td>\n                <td id=\"browser\"></td>\n            </tr>\n        </tbody>\n    </table>\n\n    <button id=\"pop-up-report\" class=\"btn btn-primary\">{{ _( \"Diagnostic Info\" ) }}</button>\n    <br><br>\n    <div id=\"tip\">{{ _(\"Check\") }} <a href=\"https://github.com/XX-net/XX-Net/issues\">{{ _(\"GitHub issues\") }}</a> {{ _(\"or\")}} <a href=\"https://groups.google.com/forum/#!forum/xx-net\">{{ _(\"Google Group Discussions\") }}</a></div>\n    <br><br>\n</div> <!-- #details -->\n\n<!-- Toggle #details-->\n<div class=\"row-fluid\">\n    <div class=\"span3 bold\">{{ _( \"Show Details\" ) }}</div>\n    <div class=\"span9\">\n        <input id=\"show-detail\" type=\"checkbox\"/>\n    </div>\n</div>\n\n<div id=\"report-issue-modal\" class=\"modal hide fade\">\n    <div class=\"modal-header\">\n        <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-hidden=\"true\">&times;</button>\n        <h3>{{ _( \"Diagnostic Info\" ) }}</h3>\n    </div> <!-- .modal-header -->\n    <div class=\"modal-body\">\n        <p> * {{ _( \"Post to Github issue needs to sign in your Github account\" ) }}</p>\n        <textarea id=\"DiagInfo\" onmouseover=\"this.focus();this.select()\"></textarea>\n    </div> <!-- .modal-body -->\n    <div class=\"modal-footer\">\n    </div> <!-- .modal-footer -->\n</div> <!-- #report-issue-modal -->\n\n<!-- JavaScript -->\n<script type=\"text/javascript\">\n    title('{{ _( \"APP_NAME\" ) }} {{ _( \"Status Info\" ) }}');\n</script>\n<script type=\"text/javascript\">\n    function OneKeyReport() {\n        $.ajax({\n            type: 'GET',\n            url: '/module/gae_proxy/control/status',\n            dataType: 'JSON',\n            success: function (result) {\n                var information = [\n                    'sys-platform: ' + result['sys_platform'],\n                    'os-system: ' + result['os_system'],\n                    'os-version: ' + result['os_version'],\n                    'os-release: ' + result['os_release'],\n                    'os-detail: ' + result['os_detail'],\n                    'architecture: ' + String(result['architecture'].concat()),\n                    'browser: ' + result['browser'],\n                    'xxnet-version: ' + result['xxnet_version'],\n                    'python-version: ' + result['python_version'],\n                    'openssl-version: ' + result['openssl_version'],\n\n                    'lan-proxy: ' + result['lan_proxy'],\n                    'use-ipv6: ' + result['use_ipv6'],\n                    'gws-ip-num: ' + 'total:' + result['ip_num'] + ' ipv4:' + result['good_ipv4_num'] + ' ipv6:' + result['good_ipv6_num'],\n                    'ipv4-status: ' + result['ipv4_state'],\n                    'ipv6-status: ' + result['ipv6_state'],\n                    'connected-link: ' + 'new:' + result['connected_link_new'] + ' used:' + result['connected_link_used'],\n                    'worker: ' + 'h1:' + result['worker_h1'] + ' h2:' + result['worker_h2'],\n                    'scan-ip-thread-num: ' + result['scan_ip_thread_num'],\n                    'ip-quality: ' + result['ip_quality'],\n                    'is-idle: ' + result['is_idle'],\n                    'block-stat: ' + result['block_stat'],\n                    'proxy_state: ' + test_http_proxy_setting(),\n                    'ca_state: ' + test_https_proxy_setting(),\n\n                    'Appid_Working: ' + (result['working_appid'].length != 0),\n                    'Appids_Out_Of_Quota: ' + (result['out_of_quota_appids'].length != 0),\n                    'Appids_Not_Exist: ' + (result['not_exist_appids'].length != 0),\n                    'Using_Public_Appid: ' + is_public_appid(result['gae_appid'])\n                ];\n\n                updateProperty(\"textarea#DiagInfo\", {{ _( \"APP_NAME\" ) }} + \" Status:\\n\\n\" + information.join(\"\\n\"));\n\n                IssueURL = 'https://github.com/XX-net/XX-Net/issues/new?body={{ _( \"-----------%0AProblem Description:%0APlease describe your problem, running logs may be needed.%0A%0A-----------%0ADiagnostic information:%0A\" ) }}' + encodeURIComponent(information.join(\"\\n\")) + \";\";\n                $(\"a#one-key-issue\").attr(\"href\", IssueURL);\n                GGroupURL = \"https://groups.google.com/forum/#!forum/xx-net\";\n                // The one-key generaton function is to be designed as Github does有待设计类似Github Issue的一键生成功能\n                $(\"a#go-to-google-group\").attr(\"href\", GGroupURL);\n            }\n        })\n    }\n\n    $(\"#pop-up-report\").click(function () {\n        OneKeyReport();\n        $('#report-issue-modal').modal();\n    });\n</script>\n<script type=\"text/javascript\">\n\n    window.fake_host = \"\";\n\n    documentReadyToRun.push(function () {\n        var timer = $.timer(function () {\n            if ($(\"#details\").is(\":visible\")) {\n                updateDetailStatus();\n            }\n            updateNoobStatus();\n        });\n\n        timer.set({\n            time: 1000,\n            autostart: true\n        });\n\n        updateDetailStatus();\n        updateNoobStatus();\n        update_show_detail();\n    });\n</script>\n<script type=\"text/javascript\">\n    function updateProperty(selector, content, attrclass) {\n        var previousContent = $(selector).html();\n        if (String(previousContent) !== String(content)) {\n            $(selector).html(content);\n        }\n        if (attrclass) {\n            $(selector).attr(\"class\", attrclass);\n        }\n    }\n\n    function updateDetailStatus() {\n        $.ajax({\n            type: 'GET',\n            url: '/module/gae_proxy/control/status',\n            dataType: 'JSON',\n            success: function (result) {\n                if (window.fake_host !== result[\"fake_host\"]) {\n                    window.fake_host = result[\"fake_host\"];\n                    test_http_proxy_setting();\n                    test_https_proxy_setting();\n                }\n\n                var updates = {\n                    'td#sys-platform': result['sys_platform'],\n                    'td#os-system': result['os_system'],\n                    'td#os-version': result['os_version'],\n                    'td#os-release': result['os_release'],\n                    'td#os-detail': result['os_detail'],\n                    'td#language': result['language'],\n                    'td#architecture': String(result['architecture'].concat()),\n                    'td#browser': result['browser'],\n                    'td#xxnet-version': result['xxnet_version'],\n                    'td#python-version': result['python_version'],\n                    'td#openssl-version': result['openssl_version'],\n\n                    'td#lan-proxy': (result['lan_proxy'] === 'Disable') ? '{{ _( \"disable\" ) }}' : result['lan_proxy'],\n\n                    'td#is-idle': result['is_idle'] ? '{{ _( \"idle\" ) }}' : '{{ _( \"working\" ) }}',\n                    'td#browser-proxy-setting': test_http_proxy_setting(),\n                    'td#ca-status': (test_http_proxy_setting() === \"OK\") ? test_https_proxy_setting() : \"Fail\",\n                    'td#block-stat': result['block_stat']\n                };\n                for (var item in updates) {\n                    updateProperty(item, updates[item]);\n                }\n\n                if (!tipHasClose()) {\n                    tipClose();\n                }\n            },\n            error: function (result) {\n                var formValue = $('#sys-platform').html();\n\n                if (tipHasClose()) {\n                    $('html, body').animate({\n                        scrollTop: 0\n                    }, 'slow');\n                }\n\n                if (formValue === '') {\n                    tip('{{ _(\"The status page is empty. Highly likely that \")}}{{ _( \"APP_NAME\" ) }}{{ _(\" failed getting started. Please follow \")}}<a href=\"https://github.com/XX-net/XX-Net/wiki/How-to-get-start-error-log\" target=\"_blank\">{{ _(\"guide\")}}</a>{{ _(\" to troubleshoot.\")}}<br>', 'warning', false);\n                }\n            }\n        });\n    }\n\n    function updateNoobStatus() {\n        $.ajax({\n            type: 'GET',\n            url: '/module/gae_proxy/control/status',\n            dataType: 'JSON',\n            success: function (result) {\n                if (result['ipv4_state'] == \"Fail\" && result['ipv6_state'] == \"Fail\") {\n                    return updateProperty('#noob-info', '{{ _( \"Your local network failed, please check your network and firewall.\" ) }}', 'none');\n                } else {\n                    if (result['use_ipv6'] == \"force_ipv6\" && result['ipv6_state'] == \"Fail\") {\n                        return updateProperty('#noob-info', '\"{{ _( \"Force-IPv6\" ) }}\"{{ _( \" not available, Please check.\" ) }}', 'none');\n                    } else if (result['use_ipv6'] == \"force_ipv4\" && result['ipv4_state'] == \"Fail\") {\n                        return updateProperty('#noob-info', '\"{{ _( \"Force-IPv4\" ) }}\"{{ _( \" not available, Please check.\" ) }}', 'none');\n                    }\n                }\n\n                if (result['good_ipv4_num'] + result['good_ipv6_num'] < 1) {\n                    if (result['scan_ip_thread_num'] < 1) {\n                        return updateProperty('#noob-info', '{{ _( \"You may want to $1turn on IP scaner$2.\" ) }}'.replace('$1', '<a href=\\\"./?module=gae_proxy&menu=advanced#scan_ip\\\">').replace('$2', '</a>'), 'none');\n                    } else {\n                        if (result['ipv6_state'] == \"Fail\") {\n                            return updateProperty('#noob-info', '{{ _( \"You can try <a href=\\\"https://github.com/XX-net/XX-Net/wiki/How-to-turn-on-IPv6\\\">turn on IPv6</a> or <a href=\\\"https://github.com/XX-net/XX-Net/wiki/How-to-use-XTunnel\\\">use X-Tunnel</a>.\" ) }}', 'none');\n                        } else {\n                            return updateProperty('#noob-info', '{{ _( \"XX-Net is scanning IP. Please wait about half an hour.\" ) }}', 'none');\n                        }\n                    }\n                }\n\n                if (is_public_appid(result['gae_appid'])) {\n                    if (result['out_of_quota_appids'].length > 2000) {\n                        return updateProperty('#noob-info', '{{ _( \"Public AppID out of quota, Please <a href=\\\"https://github.com/XX-net/XX-Net/wiki/how-to-create-my-appids\\\" target=\\\"_blank\\\">deploy your own AppID</a>.\" ) }}', 'none');\n                    }\n                } else {\n                    if (result['working_appid'] == \"\") {\n                        if (result['out_of_quota_appids'].length > 0){\n                            return updateProperty('#noob-info', '{{ _( \"Your AppID out of quota, Please <a href=\\\"https://github.com/XX-net/XX-Net/wiki/how-to-create-my-appids\\\" target=\\\"_blank\\\">deploy more AppID</a>.\" ) }}', 'none');\n                        } else {\n                            return updateProperty('#noob-info', '{{ _( \"No working AppID. Please check.\" ) }}', 'none');\n                        }\n                    }\n                }\n\n                if ((result['connected_link_new'] + result['worker_h1'] + result['worker_h2']) < 1) {\n                    if (result['is_idle']) {\n                        return updateProperty('#noob-info', '{{ _( \"System is Idle.\" ) }}', 'fluent');\n                    } else {\n                        return updateProperty('#noob-info', '{{ _( \"Connection not established yet.\" ) }}', 'none');\n                    }\n                }\n\n                if (test_http_proxy_setting() == \"Fail\") {\n                    return updateProperty('#noob-info', '<a href=\"https://github.com/XX-net/XX-Net/wiki/%E8%AE%BE%E7%BD%AE%E4%BB%A3%E7%90%86\" target=\"_blank\">' + '{{ _( \"Please check your browser proxy setting.\" ) }}' + '</a>', 'none');\n                } else if (test_http_proxy_setting() == \"Detecting\") {\n                    return updateProperty('#noob-info', '{{ _( \"Detecting ...\" ) }}', 'none');\n                }\n\n                if (test_https_proxy_setting() == \"Fail\") {\n                    return updateProperty('#noob-info', '<a href=\"https://github.com/XX-net/XX-Net/wiki/GoAgent-Import-CA\" target=\"_blank\">' + '{{ _( \"Please import certificates to your browser.\" ) }}' + '</a>', 'none');\n                } else if (test_https_proxy_setting() == \"Detecting\") {\n                    return updateProperty('#noob-info', '{{ _( \"Detecting ...\" ) }}', 'none');\n                }\n\n                if (is_public_appid(result['gae_appid'])) {\n                    if (result['out_of_quota_appids'].length > 200) {\n                        return updateProperty('#noob-info', '{{ _( \"You are using public AppIDs. You are recommended to <a href=\\\"https://github.com/XX-net/XX-Net/wiki/how-to-create-my-appids\\\" target=\\\"_blank\\\">deploy your own AppID</a>.\" ) }}', 'hard');\n                    }\n                }\n\n                return updateProperty('#noob-info', {{ _( \"APP_NAME\" ) }} + \" \" + result['xxnet_version'].trim() + '{{ _( \", Everything is OK. Welcome to the FREE Internet.\" ) }}', 'fluent');\n\n            },\n            error: function (result) {\n                var infoValue = $('#noob-info').html();\n                if (infoValue == '') {\n                    tip('{{ _(\"The status page is empty. Highly likely that \")}}{{ _( \"APP_NAME\" ) }}{{ _(\" failed getting started. Please follow \")}}<a href=\"https://github.com/XX-net/XX-Net/wiki/How-to-get-start-error-log\" target=\"_blank\">{{ _(\"guide\")}}</a>{{ _(\" to troubleshoot.\")}}<br>', 'warning', false);\n                } else {\n                    updateProperty('#noob-info', '{{ _(\"No response from process: \")}}{{ _( \"APP_NAME\" ) }}{{ _(\". It might have already exited.\")}}', 'none');\n                }\n            }\n        });\n    }\n\n    function is_public_appid(appids) {\n        return appids.length <= 1;\n    }\n\n    function test_http_proxy_setting() {\n        if (window.http_proxy_setting === \"OK\" || window.https_proxy_setting === \"OK\") {\n            return \"OK\";\n        }\n\n        if (window.fake_host === \"\") {\n            return \"Fail\";\n        }\n\n        $.ajax({\n            type: 'POST',\n            dataType: 'text',\n            crossDomain: true,\n            timeout: 1000,\n            url: 'http://' + window.fake_host + '/xxnet',\n            success: function (result) {\n                window.http_proxy_setting = result === \"OK\" ? \"OK\" : \"Fail\";\n            },\n            error: function (result, textStatus, errorThrown) {\n                window.http_proxy_setting = \"Fail\";\n            }\n        });\n\n        if (window.http_proxy_setting === \"Fail\") {\n            return \"Fail\";\n        }\n        return \"Detecting\";\n    }\n    function test_https_proxy_setting() {\n        if (window.https_proxy_setting === \"OK\") {\n            return \"OK\";\n        }\n\n        if (window.fake_host === \"\") {\n            return \"Fail\";\n        }\n\n        $.ajax({\n            type: 'POST',\n            dataType: 'text',\n            crossDomain: true,\n            timeout: 1000,\n            url: 'https://' + window.fake_host + '/xxnet',\n            success: function (result) {\n                window.https_proxy_setting = (result === \"OK\") ? \"OK\" : \"Fail\";\n            },\n            error: function (result, textStatus, errorThrown) {\n                window.https_proxy_setting = \"Fail\";\n            }\n        });\n\n        if (window.https_proxy_setting === \"Fail\") {\n            return \"Fail\";\n        }\n        return \"Detecting\";\n    }\n    test_http_proxy_setting();\n    test_https_proxy_setting();\n\n    $(function () {\n        $('#show-detail').wrap('<div class=\"switch\" />').parent().bootstrapSwitch();\n    });\n\n    $('#show-detail').change(function () {\n        var isChecked = $(this).is(':checked'),\n            key       = 'show_detail',\n            value     = isChecked ? 1 : 0;\n        if (isChecked) {\n            $(\"#details\").slideDown();\n        } else {\n            $(\"#details\").slideUp();\n        }\n\n        setConfig(key, value);\n    });\n\n    function update_show_detail() {\n        var pageRequests = {\n            'cmd': 'get_config'\n        };\n        $.ajax({\n            type: 'GET',\n            url: '/config',\n            data: pageRequests,\n            dataType: 'JSON',\n            success: function (result) {\n                if (result['show_detail'] !== 0) {\n                    $(\"#show-detail\").parent().removeClass('switch-off');\n                    $(\"#show-detail\").parent().addClass('switch-on');\n                    $(\"#show-detail\").prop('checked', true);\n                    $(\"#details\").slideDown();\n                } else {\n                    $(\"#show-detail\").parent().addClass('switch-off');\n                    $(\"#show-detail\").parent().removeClass('switch-on');\n                    $(\"#show-detail\").prop('checked', false);\n                    $(\"#details\").slideUp();\n                }\n\n                switch(result['system-proxy']) {\n                    case \"pac\": updateProperty('td#system-proxy', '{{ _( \"Global PAC Proxy set\" ) }}'); break;\n                    case \"gae\": updateProperty('td#system-proxy', '{{ _( \"Global GAEProxy Proxy set\" ) }}'); break;\n                    case \"x_tunnel\": updateProperty('td#system-proxy', '{{ _( \"Global X-Tunnel Proxy set\" ) }}'); break;\n                    case \"smart_router\": updateProperty('td#system-proxy', '{{ _( \"Global Smart-Router Proxy set\" ) }}'); break;\n                    case \"disable\": updateProperty('td#system-proxy', '{{ _( \"Global Proxy disabled\" ) }}'); break;\n                    default:\n                }\n                updateProperty('td#launcher', '@127.0.0.1:8085');\n                if (result['gae_proxy_enable']) {\n                    updateProperty('td#gaeproxy-status', '@127.0.0.1:8087'); //proxy_url\n                } else {\n                    updateProperty('td#gaeproxy-status', '{{ _( \"disable\" ) }}');\n                }\n                if (result['x_tunnel_enable']) {\n                    updateProperty('td#xtunnel-status', '@127.0.0.1:1080'); //proxy_url\n                } else {\n                    updateProperty('td#xtunnel-status', '{{ _( \"disable\" ) }}');\n                }\n                if (result['smart_router_enable']) {\n                    updateProperty('td#smartrouter-status', '@127.0.0.1:8086'); //proxy_url\n                } else {\n                    updateProperty('td#smartrouter-status', '{{ _( \"disable\" ) }}');\n                }\n                /*\n                if (result['lan_proxy'] !== 'disable') {\n                    updateProperty('td#lan-proxy', result['lan_proxy']); //proxy_url\n                } else {\n                    updateProperty('td#lan-proxy', '{{ _( \"disable\" ) }}');\n                }\n                */\n            }\n        });\n    }\n</script>\n"
  },
  {
    "path": "code/default/launcher/win_compat_suggest.py",
    "content": "# coding:utf-8\nimport json\nimport os\nimport ctypes\nimport collections\nimport locale\nimport subprocess\n\nimport env_info\nfrom launcher.config import get_language\nfrom config import app_name, config\nfrom xlog import getLogger\nxlog = getLogger(\"launcher\")\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nversion_path = os.path.abspath(os.path.join(current_path, os.path.pardir))\nroot_path = os.path.abspath(os.path.join(version_path, os.path.pardir, os.path.pardir))\ndata_path = env_info.data_path\n\n\nclass Win10PortReserveSolution(object):\n    def __init__(self):\n        self.service_ports = self.get_service_ports()\n\n    def check_and_resolve(self):\n        if self.is_port_reserve_conflict():\n            language = get_language()\n            if language == \"zh_CN\":\n                res = self.notify(\"端口被系统保留\", \"服务端口被系统保留，是否修改系统保留端口？\")\n            else:\n                res = self.notify(\"Service Port was Reserved\",\n                                  \"The service ports was reserved by system, Do you want to change the served port?\")\n\n            if res == 1:  # Clicked \"Yes\"\n                xlog.info(\"User click Yes, start change reserve port range\")\n                self.change_reserved_port_range()\n\n                if language == \"zh_CN\":\n                    self.notify(\"请重启电脑\", \"系统保留端口已经修改，请重启电脑.\")\n                else:\n                    self.notify(\"Computer Restart Required\",\n                                \"System port reserve range changed, please restart your computer to make chage.\")\n                return False\n            else:\n                xlog.info(\"User click No\")\n\n        return True\n\n    @staticmethod\n    def run_cmd(cmd):\n        try:\n            proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n            out = proc.stdout\n            lines = out.readlines()\n            return lines\n        except Exception as e:\n            xlog.warn(\"Win10PortReserveSolution run cmd %s error:%r\", cmd, e)\n            return []\n\n    @staticmethod\n    def get_config_value(fn, key, default_value):\n        if not os.path.isfile(fn):\n            return default_value\n\n        try:\n            with open(fn, \"r\") as fd:\n                dat = json.load(fd)\n                value = dat.get(key, default_value)\n                return value\n        except Exception as e:\n            xlog.warn(\"load config %s except:%r\", fn, e)\n            return default_value\n\n    def get_service_ports(self):\n        web_console_port = config.control_port\n        smart_router_config_fn = os.path.join(data_path, \"smart_router\", \"config.json\")\n        smart_router_socks_port = self.get_config_value(smart_router_config_fn, \"proxy_port\", 8086)\n        smart_router_dns_port = self.get_config_value(smart_router_config_fn, \"dns_backup_port\", 8053)\n\n        x_tunnel_config_fn = os.path.join(data_path, \"x_tunnel\", \"client.json\")\n        x_tunnel_port = self.get_config_value(x_tunnel_config_fn, \"socks_port\", 1080)\n\n        return [web_console_port, smart_router_socks_port, smart_router_dns_port, x_tunnel_port]\n\n    def is_port_reserve_conflict(self):\n        cmd = \"netsh int ipv4 show excludedportrange protocol=tcp\"\n        lines = self.run_cmd(cmd)\n        for line in lines:\n            if not line.startswith(b\" \"):\n                continue\n\n            range_str = line.split()\n            try:\n                p0 = int(range_str[0])\n                p1 = int(range_str[1])\n            except Exception as e:\n                xlog.warn(\"parse reserve port fail, line:%s, e:%r\", line, e)\n                continue\n\n            # xlog.debug(\"range:%d - %d\", p0, p1)\n            for port in self.service_ports:\n                if p0 < port < p1:\n                    xlog.info(\"found port reserved range:%d - %d, expect %d\", p0, p1, port)\n                    return True\n\n        return False\n\n    def search_port_range(self):\n        port_number = 16384\n        for port_start in range(10000, 45000, 5000):\n            port_end = port_start + port_number\n            acceptable = True\n            for port in self.service_ports:\n                if port_start <= port <= port_end:\n                    acceptable = False\n                    break\n\n            if acceptable:\n                return [port_start, port_number]\n\n    def change_reserved_port_range(self):\n        ports = self.search_port_range()\n        if not ports:\n            xlog.warn(\"Can't found acceptable ports\")\n            return\n\n        exec = b\"netsh\"\n        args = b\"int ipv4 set dynamic tcp start=%d num=%d\" % (ports[0], ports[1])\n        import win32elevate\n        win32elevate.elevateAdminRun(args, exec)\n\n    @staticmethod\n    def notify(title=\"Title\", msg=\"msg\"):\n        import ctypes\n        res = ctypes.windll.user32.MessageBoxW(None, msg, title, 1)\n        # Yes:1 No:2\n        return res\n\n\ndef get_process_list():\n    process_list = []\n    if os.name != \"nt\":\n        return process_list\n\n    Process = collections.namedtuple(\"Process\", \"filename name\")\n    PROCESS_QUERY_INFORMATION = 0x0400\n    PROCESS_VM_READ = 0x0010\n    lpidProcess = (ctypes.c_ulong * 1024)()\n    cbNeeded = ctypes.c_ulong()\n\n    ctypes.windll.psapi.EnumProcesses(ctypes.byref(lpidProcess), ctypes.sizeof(lpidProcess), ctypes.byref(cbNeeded))\n    nReturned = cbNeeded.value // ctypes.sizeof(cbNeeded)\n    pidProcess = [i for i in lpidProcess][:nReturned]\n    has_queryimage = hasattr(ctypes.windll.kernel32, \"QueryFullProcessImageNameA\")\n\n    for pid in pidProcess:\n        hProcess = ctypes.windll.kernel32.OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 0, pid)\n        if hProcess:\n            modname = ctypes.create_string_buffer(2048)\n            count = ctypes.c_ulong(ctypes.sizeof(modname))\n            if has_queryimage:\n                ctypes.windll.kernel32.QueryFullProcessImageNameA(hProcess, 0, ctypes.byref(modname),\n                                                                  ctypes.byref(count))\n            else:\n                ctypes.windll.psapi.GetModuleFileNameExA(hProcess, 0, ctypes.byref(modname), ctypes.byref(count))\n\n            path = modname.value.decode(\"mbcs\")\n            filename = os.path.basename(path)\n            name, ext = os.path.splitext(filename)\n            process_list.append(Process(filename=filename, name=name))\n            ctypes.windll.kernel32.CloseHandle(hProcess)\n\n    return process_list\n\n\n_blacklist = {\n    # (u\"测试\", \"Test\"): [\n    #    u\"汉字测试\",\n    #    \"explorer\",\n    #    \"Python\",\n    # ],\n    (\"渣雷\", \"Xhunder\"): [\n        \"ThunderPlatform\",\n        \"ThunderFW\",\n        \"ThunderLiveUD\",\n        \"ThunderService\",\n        \"ThunderSmartLimiter\",\n        \"ThunderWelcome\",\n        \"DownloadSDKServer\",\n        \"LimitingDriver\",\n        \"LiteUD\",\n        \"LiteViewBundleInst\",\n        \"XLNXService \",\n        \"XLServicePlatform\",\n        \"XLGameBoot\",\n        \"XMPBoot\",\n    ],\n    (\"百毒\", \"Baidu\"): [\n        \"BaiduSdSvc\",\n        \"BaiduSdTray\",\n        \"BaiduSd\",\n        \"BaiduAn\",\n        \"bddownloader\",\n        \"baiduansvx\",\n    ],\n    (\"流氓 360\", \"360\"): [\n        \"360sd\",\n        \"360tray\",\n        \"360Safe\",\n        \"safeboxTray\",\n        \"360safebox\",\n        \"360se\",\n    ],\n    (\"疼讯复制机\", \"Tencent\"): [\n        \"QQPCRTP\",\n        \"QQPCTray\",\n        \"QQProtect\",\n    ],\n    (\"金山\", \"Kingsoft\"): [\n        \"kismain\",\n        \"ksafe\",\n        \"KSafeSvc\",\n        \"KSafeTray\",\n        \"KAVStart\",\n        \"KWatch\",\n        \"KMailMon\",\n    ],\n    (\"瑞星\", \"Rising\"): [\n        \"rstray\",\n        \"ravmond\",\n        \"rsmain\",\n    ],\n    (\"江民\", \"Jiangmin\"): [\n        \"KVMonXP\",\n        \"kvsrvxp\",\n        \"kvxp\",\n    ],\n    (\"2345 不安全\", \"2345\"): [\n        \"2345MPCSafe\",\n    ],\n    (\"天网防火墙\", \"SkyNet\"): [\n        \"PFW\",\n    ],\n}\n\n_title = app_name + \" 兼容性建议\", app_name + \" compatibility suggest\"\n_notice = (\n    \"某些软件可能和 \" + app_name + \" 存在冲突，导致 CPU 占用过高或者无法正常使用。\"\n    \"如有此现象建议暂时退出以下软件来保证\" + app_name + \"正常运行：\\n\",\n    \"Some software may conflict with This app, \"\n    \"causing the CPU to be overused or not working properly.\"\n    \"If this is the case, it is recommended to temporarily quit the following \"\n    \"software to ensure \" + app_name + \" running:\\n\",\n    \"\\n你可以在配置页面关闭此建议。\",\n    \"\\nYou can close this suggestion on the configuration page.\",\n)\n\n\ndef main():\n    if os.name != \"nt\":\n        return\n\n    lang = 0 if locale.getdefaultlocale()[0] == \"zh_CN\" else 1\n    blacklist = {}\n    for k, v in list(_blacklist.items()):\n        for name in v:\n            blacklist[name] = k[lang]\n\n    processlist = dict((process.name.lower(), process) for process in get_process_list())\n    softwares = [name for name in blacklist if name.lower() in processlist]\n\n    if softwares:\n        displaylist = {}\n        for software in softwares:\n            company = blacklist[software]\n            if company not in displaylist:\n                displaylist[company] = []\n            displaylist[company].append(software)\n\n        displaystr = [_notice[lang], ]\n        for company, softwares in list(displaylist.items()):\n            displaystr.append(\"    %s: \\n\\t%s\" % (company,\n                                                  \"\\n\\t\".join(\n                                                      processlist[name.lower()].filename for name in softwares)))\n\n        title = _title[lang]\n        displaystr.append(_notice[lang + 2])\n        error = \"\\n\".join(displaystr)\n\n        ctypes.windll.user32.MessageBoxW(None, error, title, 48)\n\n\nif \"__main__\" == __name__:\n    if os.name != \"nt\":\n        import sys\n\n        sys.exit(0)\n    main()\n"
  },
  {
    "path": "code/default/launcher/win_tray.py",
    "content": "#!/usr/bin/env python\n# coding:utf-8\n\n\nif __name__ == \"__main__\":\n    import os, sys\n    current_path = os.path.dirname(os.path.abspath(__file__))\n    python_path = os.path.abspath(os.path.join(current_path, os.pardir))\n    noarch_lib = os.path.abspath(os.path.join(python_path, 'lib', 'noarch'))\n    sys.path.append(noarch_lib)\n    win32_lib = os.path.abspath(os.path.join(python_path, 'lib', 'win32'))\n    sys.path.append(win32_lib)\n\nimport webbrowser\nimport os\nimport ctypes\nimport winreg as winreg\nimport win32_proxy_manager\nimport module_init\nimport update\nfrom config import config, app_name\n\nfrom xlog import getLogger\nxlog = getLogger(\"launcher\")\nfrom systray import SysTrayIcon, win32_adapter\n\nimport locale\nlang_code, code_page = locale.getdefaultlocale()\n\n\nclass Win_tray():\n    def __init__(self):\n        icon_path = os.path.join(os.path.dirname(__file__), \"web_ui\", \"img\", app_name, \"favicon.ico\")\n        self.systray = SysTrayIcon(icon_path, app_name, self.make_menu(), self.on_quit, left_click=self.on_show, right_click=self.on_right_click)\n\n        reg_path = r'Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings'\n        self.INTERNET_SETTINGS = winreg.OpenKey(winreg.HKEY_CURRENT_USER, reg_path, 0, winreg.KEY_ALL_ACCESS)\n\n        proxy_setting = config.os_proxy_mode\n        if proxy_setting == \"pac\":\n            self.on_enable_pac()\n        elif proxy_setting == \"gae\" and config.enable_gae_proxy == 1:\n            self.on_enable_gae_proxy()\n        elif proxy_setting == \"x_tunnel\" and config.enable_x_tunnel == 1:\n            self.on_enable_x_tunnel()\n        elif proxy_setting == \"smart_router\" and config.enable_smart_router == 1:\n            self.on_enable_smart_router()\n        elif proxy_setting == \"disable\":\n            # Don't disable proxy setting, just do nothing.\n            pass\n        else:\n            xlog.warn(\"proxy_setting:%r\", proxy_setting)\n\n    def get_proxy_state(self):\n        try:\n            AutoConfigURL, reg_type = winreg.QueryValueEx(self.INTERNET_SETTINGS, 'AutoConfigURL')\n            if AutoConfigURL:\n                if AutoConfigURL == \"http://127.0.0.1:8086/proxy.pac\":\n                    return \"pac\"\n                else:\n                    return \"unknown\"\n        except:\n            pass\n\n        try:\n            ProxyEnable, reg_type = winreg.QueryValueEx(self.INTERNET_SETTINGS, 'ProxyEnable')\n            if ProxyEnable:\n                ProxyServer, reg_type = winreg.QueryValueEx(self.INTERNET_SETTINGS, 'ProxyServer')\n                if ProxyServer == \"127.0.0.1:8087\":\n                    return \"gae\"\n                if ProxyServer == \"127.0.0.1:1080\":\n                    return \"x_tunnel\"\n                if ProxyServer == \"127.0.0.1:8086\":\n                    return \"smart_router\"\n                else:\n                    return \"unknown\"\n        except:\n            pass\n\n        return \"disable\"\n\n    def on_right_click(self):\n        self.systray.update(menu=self.make_menu())\n        self.systray._show_menu()\n\n    def make_menu(self):\n        proxy_stat = self.get_proxy_state()\n        gae_proxy_checked = win32_adapter.fState.MFS_CHECKED if proxy_stat == \"gae\" else 0\n        x_tunnel_checked = win32_adapter.fState.MFS_CHECKED if proxy_stat == \"x_tunnel\" else 0\n        smart_router_checked = win32_adapter.fState.MFS_CHECKED if proxy_stat == \"smart_router\" else 0\n        pac_checked = win32_adapter.fState.MFS_CHECKED if proxy_stat == \"pac\" else 0\n        disable_checked = win32_adapter.fState.MFS_CHECKED if proxy_stat == \"disable\" else 0\n\n        if lang_code == \"zh_CN\":\n            menu_options = [(\"设置\", None, self.on_show, 0)]\n            if config.enable_gae_proxy == 1:\n                menu_options.append((\"全局通过GAEProxy代理\", None, self.on_enable_gae_proxy, gae_proxy_checked))\n\n            if config.enable_x_tunnel == 1:\n                menu_options.append((\"全局通过X-Tunnel代理\", None, self.on_enable_x_tunnel, x_tunnel_checked))\n\n            if config.enable_smart_router == 1:\n                menu_options.append((\"全局通过智能路由代理\", None, self.on_enable_smart_router, smart_router_checked))\n\n            menu_options += [\n                (\"全局PAC智能代理\", None, self.on_enable_pac, pac_checked),\n                (\"取消全局代理\", None, self.on_disable_proxy, disable_checked),\n                (\"重启各模块\", None, self.on_restart_each_module, 0),\n                ('退出', None, SysTrayIcon.QUIT, False)]\n        else:\n            menu_options = [(\"Config\", None, self.on_show, 0)]\n            if config.enable_gae_proxy == 1:\n                menu_options.append((\"Set Global GAEProxy Proxy\", None, self.on_enable_gae_proxy, gae_proxy_checked))\n\n            if config.enable_x_tunnel == 1:\n                menu_options.append((\"Set Global X-Tunnel Proxy\", None, self.on_enable_x_tunnel, x_tunnel_checked))\n\n            if config.enable_smart_router == 1:\n                menu_options.append((\"Set Global Smart-Router Proxy\", None, self.on_enable_smart_router, smart_router_checked))\n\n            menu_options += [\n                (\"Set Global PAC Proxy\", None, self.on_enable_pac, pac_checked),\n                (\"Disable Global Proxy\", None, self.on_disable_proxy, disable_checked),\n                (\"Reset Each module\", None, self.on_restart_each_module, 0),\n                ('Quit', None, SysTrayIcon.QUIT, False)]\n\n        return tuple(menu_options)\n\n    def on_show(self, widget=None, data=None):\n        self.show_control_web()\n\n    def on_restart_each_module(self, widget=None, data=None):\n        module_init.stop_all()\n        module_init.start_all_auto()\n\n    def on_check_update(self, widget=None, data=None):\n        update.check_update()\n\n    def on_enable_gae_proxy(self, widget=None, data=None):\n        win32_proxy_manager.set_proxy(\"127.0.0.1:8087\")\n        config.os_proxy_mode = \"gae\"\n        config.save()\n\n    def on_enable_x_tunnel(self, widget=None, data=None):\n        win32_proxy_manager.set_proxy(\"127.0.0.1:1080\")\n        config.os_proxy_mode = \"x_tunnel\"\n        config.save()\n\n    def on_enable_smart_router(self, widget=None, data=None):\n        win32_proxy_manager.set_proxy(\"127.0.0.1:8086\")\n        config.os_proxy_mode = \"smart_router\"\n        config.save()\n\n    def on_enable_pac(self, widget=None, data=None):\n        win32_proxy_manager.set_proxy(\"http://127.0.0.1:8086/proxy.pac\")\n        config.os_proxy_mode = \"pac\"\n        config.save()\n\n    def on_disable_proxy(self, widget=None, data=None):\n        win32_proxy_manager.disable_proxy()\n        config.os_proxy_mode = \"disable\"\n        config.save()\n\n    def show_control_web(self, widget=None, data=None):\n        host_port = config.control_port\n        url = \"http://127.0.0.1:%s/\" % host_port\n        xlog.debug(\"Popup %s by tray\", url)\n        webbrowser.open(url)\n        ctypes.windll.user32.ShowWindow(ctypes.windll.kernel32.GetConsoleWindow(), 0)\n\n    def on_quit(self, widget=None, data=None):\n        if self.get_proxy_state() != \"unknown\":\n            win32_proxy_manager.disable_proxy()\n\n        module_init.stop_all()\n        nid = win32_adapter.NotifyData(self.systray._hwnd, 0)\n        win32_adapter.Shell_NotifyIcon(2, ctypes.byref(nid))\n        os._exit(0)\n\n    def serve_forever(self):\n        self.systray._message_loop_func()\n\n    def dialog_yes_no(self, msg=\"msg\", title=\"Title\", data=None, callback=None):\n        res = ctypes.windll.user32.MessageBoxW(None, msg, title, 1)\n        # Yes:1 No:2\n        if callback:\n            callback(data, res)\n        return res\n\n\nsys_tray = Win_tray()\n\n\ndef main():\n    ctypes.windll.user32.ShowWindow(ctypes.windll.kernel32.GetConsoleWindow(), 0)\n    sys_tray.serve_forever()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "code/default/lib/noarch/asn1crypto/__init__.py",
    "content": "# coding: utf-8\nfrom __future__ import unicode_literals, division, absolute_import, print_function\n\nfrom .version import __version__, __version_info__\n\n__all__ = [\n    '__version__',\n    '__version_info__',\n    'load_order',\n]\n\n\ndef load_order():\n    \"\"\"\n    Returns a list of the module and sub-module names for asn1crypto in\n    dependency load order, for the sake of live reloading code\n\n    :return:\n        A list of unicode strings of module names, as they would appear in\n        sys.modules, ordered by which module should be reloaded first\n    \"\"\"\n\n    return [\n        'asn1crypto._errors',\n        'asn1crypto._int',\n        'asn1crypto._ordereddict',\n        'asn1crypto._teletex_codec',\n        'asn1crypto._types',\n        'asn1crypto._inet',\n        'asn1crypto._iri',\n        'asn1crypto.version',\n        'asn1crypto.pem',\n        'asn1crypto.util',\n        'asn1crypto.parser',\n        'asn1crypto.core',\n        'asn1crypto.algos',\n        'asn1crypto.keys',\n        'asn1crypto.x509',\n        'asn1crypto.crl',\n        'asn1crypto.csr',\n        'asn1crypto.ocsp',\n        'asn1crypto.cms',\n        'asn1crypto.pdf',\n        'asn1crypto.pkcs12',\n        'asn1crypto.tsp',\n        'asn1crypto',\n    ]\n"
  },
  {
    "path": "code/default/lib/noarch/asn1crypto/_errors.py",
    "content": "# coding: utf-8\n\n\"\"\"\nExports the following items:\n\n - unwrap()\n - APIException()\n\"\"\"\n\nfrom __future__ import unicode_literals, division, absolute_import, print_function\n\nimport re\nimport textwrap\n\n\nclass APIException(Exception):\n    \"\"\"\n    An exception indicating an API has been removed from asn1crypto\n    \"\"\"\n\n    pass\n\n\ndef unwrap(string, *params):\n    \"\"\"\n    Takes a multi-line string and does the following:\n\n     - dedents\n     - converts newlines with text before and after into a single line\n     - strips leading and trailing whitespace\n\n    :param string:\n        The string to format\n\n    :param *params:\n        Params to interpolate into the string\n\n    :return:\n        The formatted string\n    \"\"\"\n\n    output = textwrap.dedent(string)\n\n    # Unwrap lines, taking into account bulleted lists, ordered lists and\n    # underlines consisting of = signs\n    if output.find('\\n') != -1:\n        output = re.sub('(?<=\\\\S)\\n(?=[^ \\n\\t\\\\d\\\\*\\\\-=])', ' ', output)\n\n    if params:\n        output = output % params\n\n    output = output.strip()\n\n    return output\n"
  },
  {
    "path": "code/default/lib/noarch/asn1crypto/_inet.py",
    "content": "# coding: utf-8\nfrom __future__ import unicode_literals, division, absolute_import, print_function\n\nimport socket\nimport struct\n\nfrom ._errors import unwrap\nfrom ._types import byte_cls, bytes_to_list, str_cls, type_name\n\n\ndef inet_ntop(address_family, packed_ip):\n    \"\"\"\n    Windows compatibility shim for socket.inet_ntop().\n\n    :param address_family:\n        socket.AF_INET for IPv4 or socket.AF_INET6 for IPv6\n\n    :param packed_ip:\n        A byte string of the network form of an IP address\n\n    :return:\n        A unicode string of the IP address\n    \"\"\"\n\n    if address_family not in set([socket.AF_INET, socket.AF_INET6]):\n        raise ValueError(unwrap(\n            '''\n            address_family must be socket.AF_INET (%s) or socket.AF_INET6 (%s),\n            not %s\n            ''',\n            repr(socket.AF_INET),\n            repr(socket.AF_INET6),\n            repr(address_family)\n        ))\n\n    if not isinstance(packed_ip, byte_cls):\n        raise TypeError(unwrap(\n            '''\n            packed_ip must be a byte string, not %s\n            ''',\n            type_name(packed_ip)\n        ))\n\n    required_len = 4 if address_family == socket.AF_INET else 16\n    if len(packed_ip) != required_len:\n        raise ValueError(unwrap(\n            '''\n            packed_ip must be %d bytes long - is %d\n            ''',\n            required_len,\n            len(packed_ip)\n        ))\n\n    if address_family == socket.AF_INET:\n        return '%d.%d.%d.%d' % tuple(bytes_to_list(packed_ip))\n\n    octets = struct.unpack(b'!HHHHHHHH', packed_ip)\n\n    runs_of_zero = {}\n    longest_run = 0\n    zero_index = None\n    for i, octet in enumerate(octets + (-1,)):\n        if octet != 0:\n            if zero_index is not None:\n                length = i - zero_index\n                if length not in runs_of_zero:\n                    runs_of_zero[length] = zero_index\n                longest_run = max(longest_run, length)\n                zero_index = None\n        elif zero_index is None:\n            zero_index = i\n\n    hexed = [hex(o)[2:] for o in octets]\n\n    if longest_run < 2:\n        return ':'.join(hexed)\n\n    zero_start = runs_of_zero[longest_run]\n    zero_end = zero_start + longest_run\n\n    return ':'.join(hexed[:zero_start]) + '::' + ':'.join(hexed[zero_end:])\n\n\ndef inet_pton(address_family, ip_string):\n    \"\"\"\n    Windows compatibility shim for socket.inet_ntop().\n\n    :param address_family:\n        socket.AF_INET for IPv4 or socket.AF_INET6 for IPv6\n\n    :param ip_string:\n        A unicode string of an IP address\n\n    :return:\n        A byte string of the network form of the IP address\n    \"\"\"\n\n    if address_family not in set([socket.AF_INET, socket.AF_INET6]):\n        raise ValueError(unwrap(\n            '''\n            address_family must be socket.AF_INET (%s) or socket.AF_INET6 (%s),\n            not %s\n            ''',\n            repr(socket.AF_INET),\n            repr(socket.AF_INET6),\n            repr(address_family)\n        ))\n\n    if not isinstance(ip_string, str_cls):\n        raise TypeError(unwrap(\n            '''\n            ip_string must be a unicode string, not %s\n            ''',\n            type_name(ip_string)\n        ))\n\n    if address_family == socket.AF_INET:\n        octets = ip_string.split('.')\n        error = len(octets) != 4\n        if not error:\n            ints = []\n            for o in octets:\n                o = int(o)\n                if o > 255 or o < 0:\n                    error = True\n                    break\n                ints.append(o)\n\n        if error:\n            raise ValueError(unwrap(\n                '''\n                ip_string must be a dotted string with four integers in the\n                range of 0 to 255, got %s\n                ''',\n                repr(ip_string)\n            ))\n\n        return struct.pack(b'!BBBB', *ints)\n\n    error = False\n    omitted = ip_string.count('::')\n    if omitted > 1:\n        error = True\n    elif omitted == 0:\n        octets = ip_string.split(':')\n        error = len(octets) != 8\n    else:\n        begin, end = ip_string.split('::')\n        begin_octets = begin.split(':')\n        end_octets = end.split(':')\n        missing = 8 - len(begin_octets) - len(end_octets)\n        octets = begin_octets + (['0'] * missing) + end_octets\n\n    if not error:\n        ints = []\n        for o in octets:\n            o = int(o, 16)\n            if o > 65535 or o < 0:\n                error = True\n                break\n            ints.append(o)\n\n        return struct.pack(b'!HHHHHHHH', *ints)\n\n    raise ValueError(unwrap(\n        '''\n        ip_string must be a valid ipv6 string, got %s\n        ''',\n        repr(ip_string)\n    ))\n"
  },
  {
    "path": "code/default/lib/noarch/asn1crypto/_int.py",
    "content": "# coding: utf-8\nfrom __future__ import unicode_literals, division, absolute_import, print_function\n\n\ndef fill_width(bytes_, width):\n    \"\"\"\n    Ensure a byte string representing a positive integer is a specific width\n    (in bytes)\n\n    :param bytes_:\n        The integer byte string\n\n    :param width:\n        The desired width as an integer\n\n    :return:\n        A byte string of the width specified\n    \"\"\"\n\n    while len(bytes_) < width:\n        bytes_ = b'\\x00' + bytes_\n    return bytes_\n"
  },
  {
    "path": "code/default/lib/noarch/asn1crypto/_iri.py",
    "content": "# coding: utf-8\n\n\"\"\"\nFunctions to convert unicode IRIs into ASCII byte string URIs and back. Exports\nthe following items:\n\n - iri_to_uri()\n - uri_to_iri()\n\"\"\"\n\nfrom __future__ import unicode_literals, division, absolute_import, print_function\n\nfrom encodings import idna  # noqa\nimport codecs\nimport re\nimport sys\n\nfrom ._errors import unwrap\nfrom ._types import byte_cls, str_cls, type_name, bytes_to_list, int_types\n\nif sys.version_info < (3,):\n    from urlparse import urlsplit, urlunsplit\n    from urllib import (\n        quote as urlquote,\n        unquote as unquote_to_bytes,\n    )\n\nelse:\n    from urllib.parse import (\n        quote as urlquote,\n        unquote_to_bytes,\n        urlsplit,\n        urlunsplit,\n    )\n\n\ndef iri_to_uri(value, normalize=False):\n    \"\"\"\n    Encodes a unicode IRI into an ASCII byte string URI\n\n    :param value:\n        A unicode string of an IRI\n\n    :param normalize:\n        A bool that controls URI normalization\n\n    :return:\n        A byte string of the ASCII-encoded URI\n    \"\"\"\n\n    if not isinstance(value, str_cls):\n        raise TypeError(unwrap(\n            '''\n            value must be a unicode string, not %s\n            ''',\n            type_name(value)\n        ))\n\n    scheme = None\n    # Python 2.6 doesn't split properly is the URL doesn't start with http:// or https://\n    if sys.version_info < (2, 7) and not value.startswith('http://') and not value.startswith('https://'):\n        real_prefix = None\n        prefix_match = re.match('^[^:]*://', value)\n        if prefix_match:\n            real_prefix = prefix_match.group(0)\n            value = 'http://' + value[len(real_prefix):]\n        parsed = urlsplit(value)\n        if real_prefix:\n            value = real_prefix + value[7:]\n            scheme = _urlquote(real_prefix[:-3])\n    else:\n        parsed = urlsplit(value)\n\n    if scheme is None:\n        scheme = _urlquote(parsed.scheme)\n    hostname = parsed.hostname\n    if hostname is not None:\n        hostname = hostname.encode('idna')\n    # RFC 3986 allows userinfo to contain sub-delims\n    username = _urlquote(parsed.username, safe='!$&\\'()*+,;=')\n    password = _urlquote(parsed.password, safe='!$&\\'()*+,;=')\n    port = parsed.port\n    if port is not None:\n        port = str_cls(port).encode('ascii')\n\n    netloc = b''\n    if username is not None:\n        netloc += username\n        if password:\n            netloc += b':' + password\n        netloc += b'@'\n    if hostname is not None:\n        netloc += hostname\n    if port is not None:\n        default_http = scheme == b'http' and port == b'80'\n        default_https = scheme == b'https' and port == b'443'\n        if not normalize or (not default_http and not default_https):\n            netloc += b':' + port\n\n    # RFC 3986 allows a path to contain sub-delims, plus \"@\" and \":\"\n    path = _urlquote(parsed.path, safe='/!$&\\'()*+,;=@:')\n    # RFC 3986 allows the query to contain sub-delims, plus \"@\", \":\" , \"/\" and \"?\"\n    query = _urlquote(parsed.query, safe='/?!$&\\'()*+,;=@:')\n    # RFC 3986 allows the fragment to contain sub-delims, plus \"@\", \":\" , \"/\" and \"?\"\n    fragment = _urlquote(parsed.fragment, safe='/?!$&\\'()*+,;=@:')\n\n    if normalize and query is None and fragment is None and path == b'/':\n        path = None\n\n    # Python 2.7 compat\n    if path is None:\n        path = ''\n\n    output = urlunsplit((scheme, netloc, path, query, fragment))\n    if isinstance(output, str_cls):\n        output = output.encode('latin1')\n    return output\n\n\ndef uri_to_iri(value):\n    \"\"\"\n    Converts an ASCII URI byte string into a unicode IRI\n\n    :param value:\n        An ASCII-encoded byte string of the URI\n\n    :return:\n        A unicode string of the IRI\n    \"\"\"\n\n    if not isinstance(value, byte_cls):\n        raise TypeError(unwrap(\n            '''\n            value must be a byte string, not %s\n            ''',\n            type_name(value)\n        ))\n\n    parsed = urlsplit(value)\n\n    scheme = parsed.scheme\n    if scheme is not None:\n        scheme = scheme.decode('ascii')\n\n    username = _urlunquote(parsed.username, remap=[':', '@'])\n    password = _urlunquote(parsed.password, remap=[':', '@'])\n    hostname = parsed.hostname\n    if hostname:\n        hostname = hostname.decode('idna')\n    port = parsed.port\n    if port and not isinstance(port, int_types):\n        port = port.decode('ascii')\n\n    netloc = ''\n    if username is not None:\n        netloc += username\n        if password:\n            netloc += ':' + password\n        netloc += '@'\n    if hostname is not None:\n        netloc += hostname\n    if port is not None:\n        netloc += ':' + str_cls(port)\n\n    path = _urlunquote(parsed.path, remap=['/'], preserve=True)\n    query = _urlunquote(parsed.query, remap=['&', '='], preserve=True)\n    fragment = _urlunquote(parsed.fragment)\n\n    return urlunsplit((scheme, netloc, path, query, fragment))\n\n\ndef _iri_utf8_errors_handler(exc):\n    \"\"\"\n    Error handler for decoding UTF-8 parts of a URI into an IRI. Leaves byte\n    sequences encoded in %XX format, but as part of a unicode string.\n\n    :param exc:\n        The UnicodeDecodeError exception\n\n    :return:\n        A 2-element tuple of (replacement unicode string, integer index to\n        resume at)\n    \"\"\"\n\n    bytes_as_ints = bytes_to_list(exc.object[exc.start:exc.end])\n    replacements = ['%%%02x' % num for num in bytes_as_ints]\n    return (''.join(replacements), exc.end)\n\n\ncodecs.register_error('iriutf8', _iri_utf8_errors_handler)\n\n\ndef _urlquote(string, safe=''):\n    \"\"\"\n    Quotes a unicode string for use in a URL\n\n    :param string:\n        A unicode string\n\n    :param safe:\n        A unicode string of character to not encode\n\n    :return:\n        None (if string is None) or an ASCII byte string of the quoted string\n    \"\"\"\n\n    if string is None or string == '':\n        return None\n\n    # Anything already hex quoted is pulled out of the URL and unquoted if\n    # possible\n    escapes = []\n    if re.search('%[0-9a-fA-F]{2}', string):\n        # Try to unquote any percent values, restoring them if they are not\n        # valid UTF-8. Also, requote any safe chars since encoded versions of\n        # those are functionally different than the unquoted ones.\n        def _try_unescape(match):\n            byte_string = unquote_to_bytes(match.group(0))\n            unicode_string = byte_string.decode('utf-8', 'iriutf8')\n            for safe_char in list(safe):\n                unicode_string = unicode_string.replace(safe_char, '%%%02x' % ord(safe_char))\n            return unicode_string\n        string = re.sub('(?:%[0-9a-fA-F]{2})+', _try_unescape, string)\n\n        # Once we have the minimal set of hex quoted values, removed them from\n        # the string so that they are not double quoted\n        def _extract_escape(match):\n            escapes.append(match.group(0).encode('ascii'))\n            return '\\x00'\n        string = re.sub('%[0-9a-fA-F]{2}', _extract_escape, string)\n\n    output = urlquote(string.encode('utf-8'), safe=safe.encode('utf-8'))\n    if not isinstance(output, byte_cls):\n        output = output.encode('ascii')\n\n    # Restore the existing quoted values that we extracted\n    if len(escapes) > 0:\n        def _return_escape(_):\n            return escapes.pop(0)\n        output = re.sub(b'%00', _return_escape, output)\n\n    return output\n\n\ndef _urlunquote(byte_string, remap=None, preserve=None):\n    \"\"\"\n    Unquotes a URI portion from a byte string into unicode using UTF-8\n\n    :param byte_string:\n        A byte string of the data to unquote\n\n    :param remap:\n        A list of characters (as unicode) that should be re-mapped to a\n        %XX encoding. This is used when characters are not valid in part of a\n        URL.\n\n    :param preserve:\n        A bool - indicates that the chars to be remapped if they occur in\n        non-hex form, should be preserved. E.g. / for URL path.\n\n    :return:\n        A unicode string\n    \"\"\"\n\n    if byte_string is None:\n        return byte_string\n\n    if byte_string == b'':\n        return ''\n\n    if preserve:\n        replacements = ['\\x1A', '\\x1C', '\\x1D', '\\x1E', '\\x1F']\n        preserve_unmap = {}\n        for char in remap:\n            replacement = replacements.pop(0)\n            preserve_unmap[replacement] = char\n            byte_string = byte_string.replace(char.encode('ascii'), replacement.encode('ascii'))\n\n    byte_string = unquote_to_bytes(byte_string)\n\n    if remap:\n        for char in remap:\n            byte_string = byte_string.replace(char.encode('ascii'), ('%%%02x' % ord(char)).encode('ascii'))\n\n    output = byte_string.decode('utf-8', 'iriutf8')\n\n    if preserve:\n        for replacement, original in preserve_unmap.items():\n            output = output.replace(replacement, original)\n\n    return output\n"
  },
  {
    "path": "code/default/lib/noarch/asn1crypto/_ordereddict.py",
    "content": "# Copyright (c) 2009 Raymond Hettinger\n#\n# Permission is hereby granted, free of charge, to any person\n# obtaining a copy of this software and associated documentation files\n# (the \"Software\"), to deal in the Software without restriction,\n# including without limitation the rights to use, copy, modify, merge,\n# publish, distribute, sublicense, and/or sell copies of the Software,\n# and to permit persons to whom the Software is furnished to do so,\n# subject to the following conditions:\n#\n#     The above copyright notice and this permission notice shall be\n#     included in all copies or substantial portions of the Software.\n#\n#     THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n#     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n#     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n#     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n#     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n#     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n#     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n#     OTHER DEALINGS IN THE SOFTWARE.\n\nimport sys\n\nif not sys.version_info < (2, 7):\n\n    from collections import OrderedDict\n\nelse:\n\n    from UserDict import DictMixin\n\n    class OrderedDict(dict, DictMixin):\n\n        def __init__(self, *args, **kwds):\n            if len(args) > 1:\n                raise TypeError('expected at most 1 arguments, got %d' % len(args))\n            try:\n                self.__end\n            except AttributeError:\n                self.clear()\n            self.update(*args, **kwds)\n\n        def clear(self):\n            self.__end = end = []\n            end += [None, end, end]  # sentinel node for doubly linked list\n            self.__map = {}          # key --> [key, prev, next]\n            dict.clear(self)\n\n        def __setitem__(self, key, value):\n            if key not in self:\n                end = self.__end\n                curr = end[1]\n                curr[2] = end[1] = self.__map[key] = [key, curr, end]\n            dict.__setitem__(self, key, value)\n\n        def __delitem__(self, key):\n            dict.__delitem__(self, key)\n            key, prev, next_ = self.__map.pop(key)\n            prev[2] = next_\n            next_[1] = prev\n\n        def __iter__(self):\n            end = self.__end\n            curr = end[2]\n            while curr is not end:\n                yield curr[0]\n                curr = curr[2]\n\n        def __reversed__(self):\n            end = self.__end\n            curr = end[1]\n            while curr is not end:\n                yield curr[0]\n                curr = curr[1]\n\n        def popitem(self, last=True):\n            if not self:\n                raise KeyError('dictionary is empty')\n            if last:\n                key = reversed(self).next()\n            else:\n                key = iter(self).next()\n            value = self.pop(key)\n            return key, value\n\n        def __reduce__(self):\n            items = [[k, self[k]] for k in self]\n            tmp = self.__map, self.__end\n            del self.__map, self.__end\n            inst_dict = vars(self).copy()\n            self.__map, self.__end = tmp\n            if inst_dict:\n                return (self.__class__, (items,), inst_dict)\n            return self.__class__, (items,)\n\n        def keys(self):\n            return list(self)\n\n        setdefault = DictMixin.setdefault\n        update = DictMixin.update\n        pop = DictMixin.pop\n        values = DictMixin.values\n        items = DictMixin.items\n        iterkeys = DictMixin.iterkeys\n        itervalues = DictMixin.itervalues\n        iteritems = DictMixin.iteritems\n\n        def __repr__(self):\n            if not self:\n                return '%s()' % (self.__class__.__name__,)\n            return '%s(%r)' % (self.__class__.__name__, self.items())\n\n        def copy(self):\n            return self.__class__(self)\n\n        @classmethod\n        def fromkeys(cls, iterable, value=None):\n            d = cls()\n            for key in iterable:\n                d[key] = value\n            return d\n\n        def __eq__(self, other):\n            if isinstance(other, OrderedDict):\n                if len(self) != len(other):\n                    return False\n                for p, q in zip(self.items(), other.items()):\n                    if p != q:\n                        return False\n                return True\n            return dict.__eq__(self, other)\n\n        def __ne__(self, other):\n            return not self == other\n"
  },
  {
    "path": "code/default/lib/noarch/asn1crypto/_teletex_codec.py",
    "content": "# coding: utf-8\n\n\"\"\"\nImplementation of the teletex T.61 codec. Exports the following items:\n\n - register()\n\"\"\"\n\nfrom __future__ import unicode_literals, division, absolute_import, print_function\n\nimport codecs\n\n\nclass TeletexCodec(codecs.Codec):\n\n    def encode(self, input_, errors='strict'):\n        return codecs.charmap_encode(input_, errors, ENCODING_TABLE)\n\n    def decode(self, input_, errors='strict'):\n        return codecs.charmap_decode(input_, errors, DECODING_TABLE)\n\n\nclass TeletexIncrementalEncoder(codecs.IncrementalEncoder):\n\n    def encode(self, input_, final=False):\n        return codecs.charmap_encode(input_, self.errors, ENCODING_TABLE)[0]\n\n\nclass TeletexIncrementalDecoder(codecs.IncrementalDecoder):\n\n    def decode(self, input_, final=False):\n        return codecs.charmap_decode(input_, self.errors, DECODING_TABLE)[0]\n\n\nclass TeletexStreamWriter(TeletexCodec, codecs.StreamWriter):\n\n    pass\n\n\nclass TeletexStreamReader(TeletexCodec, codecs.StreamReader):\n\n    pass\n\n\ndef teletex_search_function(name):\n    \"\"\"\n    Search function for teletex codec that is passed to codecs.register()\n    \"\"\"\n\n    if name != 'teletex':\n        return None\n\n    return codecs.CodecInfo(\n        name='teletex',\n        encode=TeletexCodec().encode,\n        decode=TeletexCodec().decode,\n        incrementalencoder=TeletexIncrementalEncoder,\n        incrementaldecoder=TeletexIncrementalDecoder,\n        streamreader=TeletexStreamReader,\n        streamwriter=TeletexStreamWriter,\n    )\n\n\ndef register():\n    \"\"\"\n    Registers the teletex codec\n    \"\"\"\n\n    codecs.register(teletex_search_function)\n\n\n# http://en.wikipedia.org/wiki/ITU_T.61\nDECODING_TABLE = (\n    '\\u0000'\n    '\\u0001'\n    '\\u0002'\n    '\\u0003'\n    '\\u0004'\n    '\\u0005'\n    '\\u0006'\n    '\\u0007'\n    '\\u0008'\n    '\\u0009'\n    '\\u000A'\n    '\\u000B'\n    '\\u000C'\n    '\\u000D'\n    '\\u000E'\n    '\\u000F'\n    '\\u0010'\n    '\\u0011'\n    '\\u0012'\n    '\\u0013'\n    '\\u0014'\n    '\\u0015'\n    '\\u0016'\n    '\\u0017'\n    '\\u0018'\n    '\\u0019'\n    '\\u001A'\n    '\\u001B'\n    '\\u001C'\n    '\\u001D'\n    '\\u001E'\n    '\\u001F'\n    '\\u0020'\n    '\\u0021'\n    '\\u0022'\n    '\\ufffe'\n    '\\ufffe'\n    '\\u0025'\n    '\\u0026'\n    '\\u0027'\n    '\\u0028'\n    '\\u0029'\n    '\\u002A'\n    '\\u002B'\n    '\\u002C'\n    '\\u002D'\n    '\\u002E'\n    '\\u002F'\n    '\\u0030'\n    '\\u0031'\n    '\\u0032'\n    '\\u0033'\n    '\\u0034'\n    '\\u0035'\n    '\\u0036'\n    '\\u0037'\n    '\\u0038'\n    '\\u0039'\n    '\\u003A'\n    '\\u003B'\n    '\\u003C'\n    '\\u003D'\n    '\\u003E'\n    '\\u003F'\n    '\\u0040'\n    '\\u0041'\n    '\\u0042'\n    '\\u0043'\n    '\\u0044'\n    '\\u0045'\n    '\\u0046'\n    '\\u0047'\n    '\\u0048'\n    '\\u0049'\n    '\\u004A'\n    '\\u004B'\n    '\\u004C'\n    '\\u004D'\n    '\\u004E'\n    '\\u004F'\n    '\\u0050'\n    '\\u0051'\n    '\\u0052'\n    '\\u0053'\n    '\\u0054'\n    '\\u0055'\n    '\\u0056'\n    '\\u0057'\n    '\\u0058'\n    '\\u0059'\n    '\\u005A'\n    '\\u005B'\n    '\\ufffe'\n    '\\u005D'\n    '\\ufffe'\n    '\\u005F'\n    '\\ufffe'\n    '\\u0061'\n    '\\u0062'\n    '\\u0063'\n    '\\u0064'\n    '\\u0065'\n    '\\u0066'\n    '\\u0067'\n    '\\u0068'\n    '\\u0069'\n    '\\u006A'\n    '\\u006B'\n    '\\u006C'\n    '\\u006D'\n    '\\u006E'\n    '\\u006F'\n    '\\u0070'\n    '\\u0071'\n    '\\u0072'\n    '\\u0073'\n    '\\u0074'\n    '\\u0075'\n    '\\u0076'\n    '\\u0077'\n    '\\u0078'\n    '\\u0079'\n    '\\u007A'\n    '\\ufffe'\n    '\\u007C'\n    '\\ufffe'\n    '\\ufffe'\n    '\\u007F'\n    '\\u0080'\n    '\\u0081'\n    '\\u0082'\n    '\\u0083'\n    '\\u0084'\n    '\\u0085'\n    '\\u0086'\n    '\\u0087'\n    '\\u0088'\n    '\\u0089'\n    '\\u008A'\n    '\\u008B'\n    '\\u008C'\n    '\\u008D'\n    '\\u008E'\n    '\\u008F'\n    '\\u0090'\n    '\\u0091'\n    '\\u0092'\n    '\\u0093'\n    '\\u0094'\n    '\\u0095'\n    '\\u0096'\n    '\\u0097'\n    '\\u0098'\n    '\\u0099'\n    '\\u009A'\n    '\\u009B'\n    '\\u009C'\n    '\\u009D'\n    '\\u009E'\n    '\\u009F'\n    '\\u00A0'\n    '\\u00A1'\n    '\\u00A2'\n    '\\u00A3'\n    '\\u0024'\n    '\\u00A5'\n    '\\u0023'\n    '\\u00A7'\n    '\\u00A4'\n    '\\ufffe'\n    '\\ufffe'\n    '\\u00AB'\n    '\\ufffe'\n    '\\ufffe'\n    '\\ufffe'\n    '\\ufffe'\n    '\\u00B0'\n    '\\u00B1'\n    '\\u00B2'\n    '\\u00B3'\n    '\\u00D7'\n    '\\u00B5'\n    '\\u00B6'\n    '\\u00B7'\n    '\\u00F7'\n    '\\ufffe'\n    '\\ufffe'\n    '\\u00BB'\n    '\\u00BC'\n    '\\u00BD'\n    '\\u00BE'\n    '\\u00BF'\n    '\\ufffe'\n    '\\u0300'\n    '\\u0301'\n    '\\u0302'\n    '\\u0303'\n    '\\u0304'\n    '\\u0306'\n    '\\u0307'\n    '\\u0308'\n    '\\ufffe'\n    '\\u030A'\n    '\\u0327'\n    '\\u0332'\n    '\\u030B'\n    '\\u0328'\n    '\\u030C'\n    '\\ufffe'\n    '\\ufffe'\n    '\\ufffe'\n    '\\ufffe'\n    '\\ufffe'\n    '\\ufffe'\n    '\\ufffe'\n    '\\ufffe'\n    '\\ufffe'\n    '\\ufffe'\n    '\\ufffe'\n    '\\ufffe'\n    '\\ufffe'\n    '\\ufffe'\n    '\\ufffe'\n    '\\ufffe'\n    '\\u2126'\n    '\\u00C6'\n    '\\u00D0'\n    '\\u00AA'\n    '\\u0126'\n    '\\ufffe'\n    '\\u0132'\n    '\\u013F'\n    '\\u0141'\n    '\\u00D8'\n    '\\u0152'\n    '\\u00BA'\n    '\\u00DE'\n    '\\u0166'\n    '\\u014A'\n    '\\u0149'\n    '\\u0138'\n    '\\u00E6'\n    '\\u0111'\n    '\\u00F0'\n    '\\u0127'\n    '\\u0131'\n    '\\u0133'\n    '\\u0140'\n    '\\u0142'\n    '\\u00F8'\n    '\\u0153'\n    '\\u00DF'\n    '\\u00FE'\n    '\\u0167'\n    '\\u014B'\n    '\\ufffe'\n)\nENCODING_TABLE = codecs.charmap_build(DECODING_TABLE)\n"
  },
  {
    "path": "code/default/lib/noarch/asn1crypto/_types.py",
    "content": "# coding: utf-8\nfrom __future__ import unicode_literals, division, absolute_import, print_function\n\nimport inspect\nimport sys\n\n\nif sys.version_info < (3,):\n    str_cls = unicode  # noqa\n    byte_cls = str\n    int_types = (int, long)  # noqa\n\n    def bytes_to_list(byte_string):\n        return [ord(b) for b in byte_string]\n\n    chr_cls = chr\n\nelse:\n    str_cls = str\n    byte_cls = bytes\n    int_types = int\n\n    bytes_to_list = list\n\n    def chr_cls(num):\n        return bytes([num])\n\n\ndef type_name(value):\n    \"\"\"\n    Returns a user-readable name for the type of an object\n\n    :param value:\n        A value to get the type name of\n\n    :return:\n        A unicode string of the object's type name\n    \"\"\"\n\n    if inspect.isclass(value):\n        cls = value\n    else:\n        cls = value.__class__\n    if cls.__module__ in set(['builtins', '__builtin__']):\n        return cls.__name__\n    return '%s.%s' % (cls.__module__, cls.__name__)\n"
  },
  {
    "path": "code/default/lib/noarch/asn1crypto/algos.py",
    "content": "# coding: utf-8\n\n\"\"\"\nASN.1 type classes for various algorithms using in various aspects of public\nkey cryptography. Exports the following items:\n\n - AlgorithmIdentifier()\n - AnyAlgorithmIdentifier()\n - DigestAlgorithm()\n - DigestInfo()\n - DSASignature()\n - EncryptionAlgorithm()\n - HmacAlgorithm()\n - KdfAlgorithm()\n - Pkcs5MacAlgorithm()\n - SignedDigestAlgorithm()\n\nOther type classes are defined that help compose the types listed above.\n\"\"\"\n\nfrom __future__ import unicode_literals, division, absolute_import, print_function\n\nfrom ._errors import unwrap\nfrom ._int import fill_width\nfrom .util import int_from_bytes, int_to_bytes\nfrom .core import (\n    Any,\n    Choice,\n    Integer,\n    Null,\n    ObjectIdentifier,\n    OctetString,\n    Sequence,\n    Void,\n)\n\n\n# Structures and OIDs in this file are pulled from\n# https://tools.ietf.org/html/rfc3279, https://tools.ietf.org/html/rfc4055,\n# https://tools.ietf.org/html/rfc5758, https://tools.ietf.org/html/rfc7292,\n# http://www.emc.com/collateral/white-papers/h11302-pkcs5v2-1-password-based-cryptography-standard-wp.pdf\n\nclass AlgorithmIdentifier(Sequence):\n    _fields = [\n        ('algorithm', ObjectIdentifier),\n        ('parameters', Any, {'optional': True}),\n    ]\n\n\nclass _ForceNullParameters(object):\n    \"\"\"\n    Various structures based on AlgorithmIdentifier require that the parameters\n    field be core.Null() for certain OIDs. This mixin ensures that happens.\n    \"\"\"\n\n    # The following attribute, plus the parameters spec callback and custom\n    # __setitem__ are all to handle a situation where parameters should not be\n    # optional and must be Null for certain OIDs. More info at\n    # https://tools.ietf.org/html/rfc4055#page-15 and\n    # https://tools.ietf.org/html/rfc4055#section-2.1\n    _null_algos = set([\n        '1.2.840.113549.1.1.1',    # rsassa_pkcs1v15 / rsaes_pkcs1v15 / rsa\n        '1.2.840.113549.1.1.11',   # sha256_rsa\n        '1.2.840.113549.1.1.12',   # sha384_rsa\n        '1.2.840.113549.1.1.13',   # sha512_rsa\n        '1.2.840.113549.1.1.14',   # sha224_rsa\n        '1.3.14.3.2.26',           # sha1\n        '2.16.840.1.101.3.4.2.4',  # sha224\n        '2.16.840.1.101.3.4.2.1',  # sha256\n        '2.16.840.1.101.3.4.2.2',  # sha384\n        '2.16.840.1.101.3.4.2.3',  # sha512\n    ])\n\n    def _parameters_spec(self):\n        if self._oid_pair == ('algorithm', 'parameters'):\n            algo = self['algorithm'].native\n            if algo in self._oid_specs:\n                return self._oid_specs[algo]\n\n        if self['algorithm'].dotted in self._null_algos:\n            return Null\n\n        return None\n\n    _spec_callbacks = {\n        'parameters': _parameters_spec\n    }\n\n    # We have to override this since the spec callback uses the value of\n    # algorithm to determine the parameter spec, however default values are\n    # assigned before setting a field, so a default value can't be based on\n    # another field value (unless it is a default also). Thus we have to\n    # manually check to see if the algorithm was set and parameters is unset,\n    # and then fix the value as appropriate.\n    def __setitem__(self, key, value):\n        res = super(_ForceNullParameters, self).__setitem__(key, value)\n        if key != 'algorithm':\n            return res\n        if self['algorithm'].dotted not in self._null_algos:\n            return res\n        if self['parameters'].__class__ != Void:\n            return res\n        self['parameters'] = Null()\n        return res\n\n\nclass HmacAlgorithmId(ObjectIdentifier):\n    _map = {\n        '1.3.14.3.2.10': 'des_mac',\n        '1.2.840.113549.2.7': 'sha1',\n        '1.2.840.113549.2.8': 'sha224',\n        '1.2.840.113549.2.9': 'sha256',\n        '1.2.840.113549.2.10': 'sha384',\n        '1.2.840.113549.2.11': 'sha512',\n        '1.2.840.113549.2.12': 'sha512_224',\n        '1.2.840.113549.2.13': 'sha512_256',\n        '2.16.840.1.101.3.4.2.13': 'sha3_224',\n        '2.16.840.1.101.3.4.2.14': 'sha3_256',\n        '2.16.840.1.101.3.4.2.15': 'sha3_384',\n        '2.16.840.1.101.3.4.2.16': 'sha3_512',\n    }\n\n\nclass HmacAlgorithm(Sequence):\n    _fields = [\n        ('algorithm', HmacAlgorithmId),\n        ('parameters', Any, {'optional': True}),\n    ]\n\n\nclass DigestAlgorithmId(ObjectIdentifier):\n    _map = {\n        '1.2.840.113549.2.2': 'md2',\n        '1.2.840.113549.2.5': 'md5',\n        '1.3.14.3.2.26': 'sha1',\n        '2.16.840.1.101.3.4.2.4': 'sha224',\n        '2.16.840.1.101.3.4.2.1': 'sha256',\n        '2.16.840.1.101.3.4.2.2': 'sha384',\n        '2.16.840.1.101.3.4.2.3': 'sha512',\n        '2.16.840.1.101.3.4.2.5': 'sha512_224',\n        '2.16.840.1.101.3.4.2.6': 'sha512_256',\n        '2.16.840.1.101.3.4.2.7': 'sha3_224',\n        '2.16.840.1.101.3.4.2.8': 'sha3_256',\n        '2.16.840.1.101.3.4.2.9': 'sha3_384',\n        '2.16.840.1.101.3.4.2.10': 'sha3_512',\n        '2.16.840.1.101.3.4.2.11': 'shake128',\n        '2.16.840.1.101.3.4.2.12': 'shake256',\n        '2.16.840.1.101.3.4.2.17': 'shake128_len',\n        '2.16.840.1.101.3.4.2.18': 'shake256_len',\n    }\n\n\nclass DigestAlgorithm(_ForceNullParameters, Sequence):\n    _fields = [\n        ('algorithm', DigestAlgorithmId),\n        ('parameters', Any, {'optional': True}),\n    ]\n\n\n# This structure is what is signed with a SignedDigestAlgorithm\nclass DigestInfo(Sequence):\n    _fields = [\n        ('digest_algorithm', DigestAlgorithm),\n        ('digest', OctetString),\n    ]\n\n\nclass MaskGenAlgorithmId(ObjectIdentifier):\n    _map = {\n        '1.2.840.113549.1.1.8': 'mgf1',\n    }\n\n\nclass MaskGenAlgorithm(Sequence):\n    _fields = [\n        ('algorithm', MaskGenAlgorithmId),\n        ('parameters', Any, {'optional': True}),\n    ]\n\n    _oid_pair = ('algorithm', 'parameters')\n    _oid_specs = {\n        'mgf1': DigestAlgorithm\n    }\n\n\nclass TrailerField(Integer):\n    _map = {\n        1: 'trailer_field_bc',\n    }\n\n\nclass RSASSAPSSParams(Sequence):\n    _fields = [\n        (\n            'hash_algorithm',\n            DigestAlgorithm,\n            {\n                'explicit': 0,\n                'default': {'algorithm': 'sha1'},\n            }\n        ),\n        (\n            'mask_gen_algorithm',\n            MaskGenAlgorithm,\n            {\n                'explicit': 1,\n                'default': {\n                    'algorithm': 'mgf1',\n                    'parameters': {'algorithm': 'sha1'},\n                },\n            }\n        ),\n        (\n            'salt_length',\n            Integer,\n            {\n                'explicit': 2,\n                'default': 20,\n            }\n        ),\n        (\n            'trailer_field',\n            TrailerField,\n            {\n                'explicit': 3,\n                'default': 'trailer_field_bc',\n            }\n        ),\n    ]\n\n\nclass SignedDigestAlgorithmId(ObjectIdentifier):\n    _map = {\n        '1.3.14.3.2.3': 'md5_rsa',\n        '1.3.14.3.2.29': 'sha1_rsa',\n        '1.3.14.7.2.3.1': 'md2_rsa',\n        '1.2.840.113549.1.1.2': 'md2_rsa',\n        '1.2.840.113549.1.1.4': 'md5_rsa',\n        '1.2.840.113549.1.1.5': 'sha1_rsa',\n        '1.2.840.113549.1.1.14': 'sha224_rsa',\n        '1.2.840.113549.1.1.11': 'sha256_rsa',\n        '1.2.840.113549.1.1.12': 'sha384_rsa',\n        '1.2.840.113549.1.1.13': 'sha512_rsa',\n        '1.2.840.113549.1.1.10': 'rsassa_pss',\n        '1.2.840.10040.4.3': 'sha1_dsa',\n        '1.3.14.3.2.13': 'sha1_dsa',\n        '1.3.14.3.2.27': 'sha1_dsa',\n        '2.16.840.1.101.3.4.3.1': 'sha224_dsa',\n        '2.16.840.1.101.3.4.3.2': 'sha256_dsa',\n        '1.2.840.10045.4.1': 'sha1_ecdsa',\n        '1.2.840.10045.4.3.1': 'sha224_ecdsa',\n        '1.2.840.10045.4.3.2': 'sha256_ecdsa',\n        '1.2.840.10045.4.3.3': 'sha384_ecdsa',\n        '1.2.840.10045.4.3.4': 'sha512_ecdsa',\n        '2.16.840.1.101.3.4.3.9': 'sha3_224_ecdsa',\n        '2.16.840.1.101.3.4.3.10': 'sha3_256_ecdsa',\n        '2.16.840.1.101.3.4.3.11': 'sha3_384_ecdsa',\n        '2.16.840.1.101.3.4.3.12': 'sha3_512_ecdsa',\n        # For when the digest is specified elsewhere in a Sequence\n        '1.2.840.113549.1.1.1': 'rsassa_pkcs1v15',\n        '1.2.840.10040.4.1': 'dsa',\n        '1.2.840.10045.4': 'ecdsa',\n        # RFC 8410 -- https://tools.ietf.org/html/rfc8410\n        '1.3.101.112': 'ed25519',\n        '1.3.101.113': 'ed448',\n    }\n\n    _reverse_map = {\n        'dsa': '1.2.840.10040.4.1',\n        'ecdsa': '1.2.840.10045.4',\n        'md2_rsa': '1.2.840.113549.1.1.2',\n        'md5_rsa': '1.2.840.113549.1.1.4',\n        'rsassa_pkcs1v15': '1.2.840.113549.1.1.1',\n        'rsassa_pss': '1.2.840.113549.1.1.10',\n        'sha1_dsa': '1.2.840.10040.4.3',\n        'sha1_ecdsa': '1.2.840.10045.4.1',\n        'sha1_rsa': '1.2.840.113549.1.1.5',\n        'sha224_dsa': '2.16.840.1.101.3.4.3.1',\n        'sha224_ecdsa': '1.2.840.10045.4.3.1',\n        'sha224_rsa': '1.2.840.113549.1.1.14',\n        'sha256_dsa': '2.16.840.1.101.3.4.3.2',\n        'sha256_ecdsa': '1.2.840.10045.4.3.2',\n        'sha256_rsa': '1.2.840.113549.1.1.11',\n        'sha384_ecdsa': '1.2.840.10045.4.3.3',\n        'sha384_rsa': '1.2.840.113549.1.1.12',\n        'sha512_ecdsa': '1.2.840.10045.4.3.4',\n        'sha512_rsa': '1.2.840.113549.1.1.13',\n        'sha3_224_ecdsa': '2.16.840.1.101.3.4.3.9',\n        'sha3_256_ecdsa': '2.16.840.1.101.3.4.3.10',\n        'sha3_384_ecdsa': '2.16.840.1.101.3.4.3.11',\n        'sha3_512_ecdsa': '2.16.840.1.101.3.4.3.12',\n        'ed25519': '1.3.101.112',\n        'ed448': '1.3.101.113',\n    }\n\n\nclass SignedDigestAlgorithm(_ForceNullParameters, Sequence):\n    _fields = [\n        ('algorithm', SignedDigestAlgorithmId),\n        ('parameters', Any, {'optional': True}),\n    ]\n\n    _oid_pair = ('algorithm', 'parameters')\n    _oid_specs = {\n        'rsassa_pss': RSASSAPSSParams,\n    }\n\n    @property\n    def signature_algo(self):\n        \"\"\"\n        :return:\n            A unicode string of \"rsassa_pkcs1v15\", \"rsassa_pss\", \"dsa\",\n            \"ecdsa\", \"ed25519\" or \"ed448\"\n        \"\"\"\n\n        algorithm = self['algorithm'].native\n\n        algo_map = {\n            'md2_rsa': 'rsassa_pkcs1v15',\n            'md5_rsa': 'rsassa_pkcs1v15',\n            'sha1_rsa': 'rsassa_pkcs1v15',\n            'sha224_rsa': 'rsassa_pkcs1v15',\n            'sha256_rsa': 'rsassa_pkcs1v15',\n            'sha384_rsa': 'rsassa_pkcs1v15',\n            'sha512_rsa': 'rsassa_pkcs1v15',\n            'rsassa_pkcs1v15': 'rsassa_pkcs1v15',\n            'rsassa_pss': 'rsassa_pss',\n            'sha1_dsa': 'dsa',\n            'sha224_dsa': 'dsa',\n            'sha256_dsa': 'dsa',\n            'dsa': 'dsa',\n            'sha1_ecdsa': 'ecdsa',\n            'sha224_ecdsa': 'ecdsa',\n            'sha256_ecdsa': 'ecdsa',\n            'sha384_ecdsa': 'ecdsa',\n            'sha512_ecdsa': 'ecdsa',\n            'sha3_224_ecdsa': 'ecdsa',\n            'sha3_256_ecdsa': 'ecdsa',\n            'sha3_384_ecdsa': 'ecdsa',\n            'sha3_512_ecdsa': 'ecdsa',\n            'ecdsa': 'ecdsa',\n            'ed25519': 'ed25519',\n            'ed448': 'ed448',\n        }\n        if algorithm in algo_map:\n            return algo_map[algorithm]\n\n        raise ValueError(unwrap(\n            '''\n            Signature algorithm not known for %s\n            ''',\n            algorithm\n        ))\n\n    @property\n    def hash_algo(self):\n        \"\"\"\n        :return:\n            A unicode string of \"md2\", \"md5\", \"sha1\", \"sha224\", \"sha256\",\n            \"sha384\", \"sha512\", \"sha512_224\", \"sha512_256\" or \"shake256\"\n        \"\"\"\n\n        algorithm = self['algorithm'].native\n\n        algo_map = {\n            'md2_rsa': 'md2',\n            'md5_rsa': 'md5',\n            'sha1_rsa': 'sha1',\n            'sha224_rsa': 'sha224',\n            'sha256_rsa': 'sha256',\n            'sha384_rsa': 'sha384',\n            'sha512_rsa': 'sha512',\n            'sha1_dsa': 'sha1',\n            'sha224_dsa': 'sha224',\n            'sha256_dsa': 'sha256',\n            'sha1_ecdsa': 'sha1',\n            'sha224_ecdsa': 'sha224',\n            'sha256_ecdsa': 'sha256',\n            'sha384_ecdsa': 'sha384',\n            'sha512_ecdsa': 'sha512',\n            'ed25519': 'sha512',\n            'ed448': 'shake256',\n        }\n        if algorithm in algo_map:\n            return algo_map[algorithm]\n\n        if algorithm == 'rsassa_pss':\n            return self['parameters']['hash_algorithm']['algorithm'].native\n\n        raise ValueError(unwrap(\n            '''\n            Hash algorithm not known for %s\n            ''',\n            algorithm\n        ))\n\n\nclass Pbkdf2Salt(Choice):\n    _alternatives = [\n        ('specified', OctetString),\n        ('other_source', AlgorithmIdentifier),\n    ]\n\n\nclass Pbkdf2Params(Sequence):\n    _fields = [\n        ('salt', Pbkdf2Salt),\n        ('iteration_count', Integer),\n        ('key_length', Integer, {'optional': True}),\n        ('prf', HmacAlgorithm, {'default': {'algorithm': 'sha1'}}),\n    ]\n\n\nclass KdfAlgorithmId(ObjectIdentifier):\n    _map = {\n        '1.2.840.113549.1.5.12': 'pbkdf2'\n    }\n\n\nclass KdfAlgorithm(Sequence):\n    _fields = [\n        ('algorithm', KdfAlgorithmId),\n        ('parameters', Any, {'optional': True}),\n    ]\n    _oid_pair = ('algorithm', 'parameters')\n    _oid_specs = {\n        'pbkdf2': Pbkdf2Params\n    }\n\n\nclass DHParameters(Sequence):\n    \"\"\"\n    Original Name: DHParameter\n    Source: ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-3.asc section 9\n    \"\"\"\n\n    _fields = [\n        ('p', Integer),\n        ('g', Integer),\n        ('private_value_length', Integer, {'optional': True}),\n    ]\n\n\nclass KeyExchangeAlgorithmId(ObjectIdentifier):\n    _map = {\n        '1.2.840.113549.1.3.1': 'dh',\n    }\n\n\nclass KeyExchangeAlgorithm(Sequence):\n    _fields = [\n        ('algorithm', KeyExchangeAlgorithmId),\n        ('parameters', Any, {'optional': True}),\n    ]\n    _oid_pair = ('algorithm', 'parameters')\n    _oid_specs = {\n        'dh': DHParameters,\n    }\n\n\nclass Rc2Params(Sequence):\n    _fields = [\n        ('rc2_parameter_version', Integer, {'optional': True}),\n        ('iv', OctetString),\n    ]\n\n\nclass Rc5ParamVersion(Integer):\n    _map = {\n        16: 'v1-0'\n    }\n\n\nclass Rc5Params(Sequence):\n    _fields = [\n        ('version', Rc5ParamVersion),\n        ('rounds', Integer),\n        ('block_size_in_bits', Integer),\n        ('iv', OctetString, {'optional': True}),\n    ]\n\n\nclass Pbes1Params(Sequence):\n    _fields = [\n        ('salt', OctetString),\n        ('iterations', Integer),\n    ]\n\n\nclass CcmParams(Sequence):\n    # https://tools.ietf.org/html/rfc5084\n    # aes_ICVlen: 4 | 6 | 8 | 10 | 12 | 14 | 16\n    _fields = [\n        ('aes_nonce', OctetString),\n        ('aes_icvlen', Integer),\n    ]\n\n\nclass PSourceAlgorithmId(ObjectIdentifier):\n    _map = {\n        '1.2.840.113549.1.1.9': 'p_specified',\n    }\n\n\nclass PSourceAlgorithm(Sequence):\n    _fields = [\n        ('algorithm', PSourceAlgorithmId),\n        ('parameters', Any, {'optional': True}),\n    ]\n\n    _oid_pair = ('algorithm', 'parameters')\n    _oid_specs = {\n        'p_specified': OctetString\n    }\n\n\nclass RSAESOAEPParams(Sequence):\n    _fields = [\n        (\n            'hash_algorithm',\n            DigestAlgorithm,\n            {\n                'explicit': 0,\n                'default': {'algorithm': 'sha1'}\n            }\n        ),\n        (\n            'mask_gen_algorithm',\n            MaskGenAlgorithm,\n            {\n                'explicit': 1,\n                'default': {\n                    'algorithm': 'mgf1',\n                    'parameters': {'algorithm': 'sha1'}\n                }\n            }\n        ),\n        (\n            'p_source_algorithm',\n            PSourceAlgorithm,\n            {\n                'explicit': 2,\n                'default': {\n                    'algorithm': 'p_specified',\n                    'parameters': b''\n                }\n            }\n        ),\n    ]\n\n\nclass DSASignature(Sequence):\n    \"\"\"\n    An ASN.1 class for translating between the OS crypto library's\n    representation of an (EC)DSA signature and the ASN.1 structure that is part\n    of various RFCs.\n\n    Original Name: DSS-Sig-Value\n    Source: https://tools.ietf.org/html/rfc3279#section-2.2.2\n    \"\"\"\n\n    _fields = [\n        ('r', Integer),\n        ('s', Integer),\n    ]\n\n    @classmethod\n    def from_p1363(cls, data):\n        \"\"\"\n        Reads a signature from a byte string encoding accordint to IEEE P1363,\n        which is used by Microsoft's BCryptSignHash() function.\n\n        :param data:\n            A byte string from BCryptSignHash()\n\n        :return:\n            A DSASignature object\n        \"\"\"\n\n        r = int_from_bytes(data[0:len(data) // 2])\n        s = int_from_bytes(data[len(data) // 2:])\n        return cls({'r': r, 's': s})\n\n    def to_p1363(self):\n        \"\"\"\n        Dumps a signature to a byte string compatible with Microsoft's\n        BCryptVerifySignature() function.\n\n        :return:\n            A byte string compatible with BCryptVerifySignature()\n        \"\"\"\n\n        r_bytes = int_to_bytes(self['r'].native)\n        s_bytes = int_to_bytes(self['s'].native)\n\n        int_byte_length = max(len(r_bytes), len(s_bytes))\n        r_bytes = fill_width(r_bytes, int_byte_length)\n        s_bytes = fill_width(s_bytes, int_byte_length)\n\n        return r_bytes + s_bytes\n\n\nclass EncryptionAlgorithmId(ObjectIdentifier):\n    _map = {\n        '1.3.14.3.2.7': 'des',\n        '1.2.840.113549.3.7': 'tripledes_3key',\n        '1.2.840.113549.3.2': 'rc2',\n        '1.2.840.113549.3.4': 'rc4',\n        '1.2.840.113549.3.9': 'rc5',\n        # From http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html#AES\n        '2.16.840.1.101.3.4.1.1': 'aes128_ecb',\n        '2.16.840.1.101.3.4.1.2': 'aes128_cbc',\n        '2.16.840.1.101.3.4.1.3': 'aes128_ofb',\n        '2.16.840.1.101.3.4.1.4': 'aes128_cfb',\n        '2.16.840.1.101.3.4.1.5': 'aes128_wrap',\n        '2.16.840.1.101.3.4.1.6': 'aes128_gcm',\n        '2.16.840.1.101.3.4.1.7': 'aes128_ccm',\n        '2.16.840.1.101.3.4.1.8': 'aes128_wrap_pad',\n        '2.16.840.1.101.3.4.1.21': 'aes192_ecb',\n        '2.16.840.1.101.3.4.1.22': 'aes192_cbc',\n        '2.16.840.1.101.3.4.1.23': 'aes192_ofb',\n        '2.16.840.1.101.3.4.1.24': 'aes192_cfb',\n        '2.16.840.1.101.3.4.1.25': 'aes192_wrap',\n        '2.16.840.1.101.3.4.1.26': 'aes192_gcm',\n        '2.16.840.1.101.3.4.1.27': 'aes192_ccm',\n        '2.16.840.1.101.3.4.1.28': 'aes192_wrap_pad',\n        '2.16.840.1.101.3.4.1.41': 'aes256_ecb',\n        '2.16.840.1.101.3.4.1.42': 'aes256_cbc',\n        '2.16.840.1.101.3.4.1.43': 'aes256_ofb',\n        '2.16.840.1.101.3.4.1.44': 'aes256_cfb',\n        '2.16.840.1.101.3.4.1.45': 'aes256_wrap',\n        '2.16.840.1.101.3.4.1.46': 'aes256_gcm',\n        '2.16.840.1.101.3.4.1.47': 'aes256_ccm',\n        '2.16.840.1.101.3.4.1.48': 'aes256_wrap_pad',\n        # From PKCS#5\n        '1.2.840.113549.1.5.13': 'pbes2',\n        '1.2.840.113549.1.5.1': 'pbes1_md2_des',\n        '1.2.840.113549.1.5.3': 'pbes1_md5_des',\n        '1.2.840.113549.1.5.4': 'pbes1_md2_rc2',\n        '1.2.840.113549.1.5.6': 'pbes1_md5_rc2',\n        '1.2.840.113549.1.5.10': 'pbes1_sha1_des',\n        '1.2.840.113549.1.5.11': 'pbes1_sha1_rc2',\n        # From PKCS#12\n        '1.2.840.113549.1.12.1.1': 'pkcs12_sha1_rc4_128',\n        '1.2.840.113549.1.12.1.2': 'pkcs12_sha1_rc4_40',\n        '1.2.840.113549.1.12.1.3': 'pkcs12_sha1_tripledes_3key',\n        '1.2.840.113549.1.12.1.4': 'pkcs12_sha1_tripledes_2key',\n        '1.2.840.113549.1.12.1.5': 'pkcs12_sha1_rc2_128',\n        '1.2.840.113549.1.12.1.6': 'pkcs12_sha1_rc2_40',\n        # PKCS#1 v2.2\n        '1.2.840.113549.1.1.1': 'rsaes_pkcs1v15',\n        '1.2.840.113549.1.1.7': 'rsaes_oaep',\n    }\n\n\nclass EncryptionAlgorithm(_ForceNullParameters, Sequence):\n    _fields = [\n        ('algorithm', EncryptionAlgorithmId),\n        ('parameters', Any, {'optional': True}),\n    ]\n\n    _oid_pair = ('algorithm', 'parameters')\n    _oid_specs = {\n        'des': OctetString,\n        'tripledes_3key': OctetString,\n        'rc2': Rc2Params,\n        'rc5': Rc5Params,\n        'aes128_cbc': OctetString,\n        'aes192_cbc': OctetString,\n        'aes256_cbc': OctetString,\n        'aes128_ofb': OctetString,\n        'aes192_ofb': OctetString,\n        'aes256_ofb': OctetString,\n        # From RFC5084\n        'aes128_ccm': CcmParams,\n        'aes192_ccm': CcmParams,\n        'aes256_ccm': CcmParams,\n        # From PKCS#5\n        'pbes1_md2_des': Pbes1Params,\n        'pbes1_md5_des': Pbes1Params,\n        'pbes1_md2_rc2': Pbes1Params,\n        'pbes1_md5_rc2': Pbes1Params,\n        'pbes1_sha1_des': Pbes1Params,\n        'pbes1_sha1_rc2': Pbes1Params,\n        # From PKCS#12\n        'pkcs12_sha1_rc4_128': Pbes1Params,\n        'pkcs12_sha1_rc4_40': Pbes1Params,\n        'pkcs12_sha1_tripledes_3key': Pbes1Params,\n        'pkcs12_sha1_tripledes_2key': Pbes1Params,\n        'pkcs12_sha1_rc2_128': Pbes1Params,\n        'pkcs12_sha1_rc2_40': Pbes1Params,\n        # PKCS#1 v2.2\n        'rsaes_oaep': RSAESOAEPParams,\n    }\n\n    @property\n    def kdf(self):\n        \"\"\"\n        Returns the name of the key derivation function to use.\n\n        :return:\n            A unicode from of one of the following: \"pbkdf1\", \"pbkdf2\",\n            \"pkcs12_kdf\"\n        \"\"\"\n\n        encryption_algo = self['algorithm'].native\n\n        if encryption_algo == 'pbes2':\n            return self['parameters']['key_derivation_func']['algorithm'].native\n\n        if encryption_algo.find('.') == -1:\n            if encryption_algo.find('_') != -1:\n                encryption_algo, _ = encryption_algo.split('_', 1)\n\n                if encryption_algo == 'pbes1':\n                    return 'pbkdf1'\n\n                if encryption_algo == 'pkcs12':\n                    return 'pkcs12_kdf'\n\n            raise ValueError(unwrap(\n                '''\n                Encryption algorithm \"%s\" does not have a registered key\n                derivation function\n                ''',\n                encryption_algo\n            ))\n\n        raise ValueError(unwrap(\n            '''\n            Unrecognized encryption algorithm \"%s\", can not determine key\n            derivation function\n            ''',\n            encryption_algo\n        ))\n\n    @property\n    def kdf_hmac(self):\n        \"\"\"\n        Returns the HMAC algorithm to use with the KDF.\n\n        :return:\n            A unicode string of one of the following: \"md2\", \"md5\", \"sha1\",\n            \"sha224\", \"sha256\", \"sha384\", \"sha512\"\n        \"\"\"\n\n        encryption_algo = self['algorithm'].native\n\n        if encryption_algo == 'pbes2':\n            return self['parameters']['key_derivation_func']['parameters']['prf']['algorithm'].native\n\n        if encryption_algo.find('.') == -1:\n            if encryption_algo.find('_') != -1:\n                _, hmac_algo, _ = encryption_algo.split('_', 2)\n                return hmac_algo\n\n            raise ValueError(unwrap(\n                '''\n                Encryption algorithm \"%s\" does not have a registered key\n                derivation function\n                ''',\n                encryption_algo\n            ))\n\n        raise ValueError(unwrap(\n            '''\n            Unrecognized encryption algorithm \"%s\", can not determine key\n            derivation hmac algorithm\n            ''',\n            encryption_algo\n        ))\n\n    @property\n    def kdf_salt(self):\n        \"\"\"\n        Returns the byte string to use as the salt for the KDF.\n\n        :return:\n            A byte string\n        \"\"\"\n\n        encryption_algo = self['algorithm'].native\n\n        if encryption_algo == 'pbes2':\n            salt = self['parameters']['key_derivation_func']['parameters']['salt']\n\n            if salt.name == 'other_source':\n                raise ValueError(unwrap(\n                    '''\n                    Can not determine key derivation salt - the\n                    reserved-for-future-use other source salt choice was\n                    specified in the PBKDF2 params structure\n                    '''\n                ))\n\n            return salt.native\n\n        if encryption_algo.find('.') == -1:\n            if encryption_algo.find('_') != -1:\n                return self['parameters']['salt'].native\n\n            raise ValueError(unwrap(\n                '''\n                Encryption algorithm \"%s\" does not have a registered key\n                derivation function\n                ''',\n                encryption_algo\n            ))\n\n        raise ValueError(unwrap(\n            '''\n            Unrecognized encryption algorithm \"%s\", can not determine key\n            derivation salt\n            ''',\n            encryption_algo\n        ))\n\n    @property\n    def kdf_iterations(self):\n        \"\"\"\n        Returns the number of iterations that should be run via the KDF.\n\n        :return:\n            An integer\n        \"\"\"\n\n        encryption_algo = self['algorithm'].native\n\n        if encryption_algo == 'pbes2':\n            return self['parameters']['key_derivation_func']['parameters']['iteration_count'].native\n\n        if encryption_algo.find('.') == -1:\n            if encryption_algo.find('_') != -1:\n                return self['parameters']['iterations'].native\n\n            raise ValueError(unwrap(\n                '''\n                Encryption algorithm \"%s\" does not have a registered key\n                derivation function\n                ''',\n                encryption_algo\n            ))\n\n        raise ValueError(unwrap(\n            '''\n            Unrecognized encryption algorithm \"%s\", can not determine key\n            derivation iterations\n            ''',\n            encryption_algo\n        ))\n\n    @property\n    def key_length(self):\n        \"\"\"\n        Returns the key length to pass to the cipher/kdf. The PKCS#5 spec does\n        not specify a way to store the RC5 key length, however this tends not\n        to be a problem since OpenSSL does not support RC5 in PKCS#8 and OS X\n        does not provide an RC5 cipher for use in the Security Transforms\n        library.\n\n        :raises:\n            ValueError - when the key length can not be determined\n\n        :return:\n            An integer representing the length in bytes\n        \"\"\"\n\n        encryption_algo = self['algorithm'].native\n\n        if encryption_algo[0:3] == 'aes':\n            return {\n                'aes128_': 16,\n                'aes192_': 24,\n                'aes256_': 32,\n            }[encryption_algo[0:7]]\n\n        cipher_lengths = {\n            'des': 8,\n            'tripledes_3key': 24,\n        }\n\n        if encryption_algo in cipher_lengths:\n            return cipher_lengths[encryption_algo]\n\n        if encryption_algo == 'rc2':\n            rc2_parameter_version = self['parameters']['rc2_parameter_version'].native\n\n            # See page 24 of\n            # http://www.emc.com/collateral/white-papers/h11302-pkcs5v2-1-password-based-cryptography-standard-wp.pdf\n            encoded_key_bits_map = {\n                160: 5,   # 40-bit\n                120: 8,   # 64-bit\n                58: 16,   # 128-bit\n            }\n\n            if rc2_parameter_version in encoded_key_bits_map:\n                return encoded_key_bits_map[rc2_parameter_version]\n\n            if rc2_parameter_version >= 256:\n                return rc2_parameter_version\n\n            if rc2_parameter_version is None:\n                return 4  # 32-bit default\n\n            raise ValueError(unwrap(\n                '''\n                Invalid RC2 parameter version found in EncryptionAlgorithm\n                parameters\n                '''\n            ))\n\n        if encryption_algo == 'pbes2':\n            key_length = self['parameters']['key_derivation_func']['parameters']['key_length'].native\n            if key_length is not None:\n                return key_length\n\n            # If the KDF params don't specify the key size, we can infer it from\n            # the encryption scheme for all schemes except for RC5. However, in\n            # practical terms, neither OpenSSL or OS X support RC5 for PKCS#8\n            # so it is unlikely to be an issue that is run into.\n\n            return self['parameters']['encryption_scheme'].key_length\n\n        if encryption_algo.find('.') == -1:\n            return {\n                'pbes1_md2_des': 8,\n                'pbes1_md5_des': 8,\n                'pbes1_md2_rc2': 8,\n                'pbes1_md5_rc2': 8,\n                'pbes1_sha1_des': 8,\n                'pbes1_sha1_rc2': 8,\n                'pkcs12_sha1_rc4_128': 16,\n                'pkcs12_sha1_rc4_40': 5,\n                'pkcs12_sha1_tripledes_3key': 24,\n                'pkcs12_sha1_tripledes_2key': 16,\n                'pkcs12_sha1_rc2_128': 16,\n                'pkcs12_sha1_rc2_40': 5,\n            }[encryption_algo]\n\n        raise ValueError(unwrap(\n            '''\n            Unrecognized encryption algorithm \"%s\"\n            ''',\n            encryption_algo\n        ))\n\n    @property\n    def encryption_mode(self):\n        \"\"\"\n        Returns the name of the encryption mode to use.\n\n        :return:\n            A unicode string from one of the following: \"cbc\", \"ecb\", \"ofb\",\n            \"cfb\", \"wrap\", \"gcm\", \"ccm\", \"wrap_pad\"\n        \"\"\"\n\n        encryption_algo = self['algorithm'].native\n\n        if encryption_algo[0:7] in set(['aes128_', 'aes192_', 'aes256_']):\n            return encryption_algo[7:]\n\n        if encryption_algo[0:6] == 'pbes1_':\n            return 'cbc'\n\n        if encryption_algo[0:7] == 'pkcs12_':\n            return 'cbc'\n\n        if encryption_algo in set(['des', 'tripledes_3key', 'rc2', 'rc5']):\n            return 'cbc'\n\n        if encryption_algo == 'pbes2':\n            return self['parameters']['encryption_scheme'].encryption_mode\n\n        raise ValueError(unwrap(\n            '''\n            Unrecognized encryption algorithm \"%s\"\n            ''',\n            encryption_algo\n        ))\n\n    @property\n    def encryption_cipher(self):\n        \"\"\"\n        Returns the name of the symmetric encryption cipher to use. The key\n        length can be retrieved via the .key_length property to disabiguate\n        between different variations of TripleDES, AES, and the RC* ciphers.\n\n        :return:\n            A unicode string from one of the following: \"rc2\", \"rc5\", \"des\",\n            \"tripledes\", \"aes\"\n        \"\"\"\n\n        encryption_algo = self['algorithm'].native\n\n        if encryption_algo[0:7] in set(['aes128_', 'aes192_', 'aes256_']):\n            return 'aes'\n\n        if encryption_algo in set(['des', 'rc2', 'rc5']):\n            return encryption_algo\n\n        if encryption_algo == 'tripledes_3key':\n            return 'tripledes'\n\n        if encryption_algo == 'pbes2':\n            return self['parameters']['encryption_scheme'].encryption_cipher\n\n        if encryption_algo.find('.') == -1:\n            return {\n                'pbes1_md2_des': 'des',\n                'pbes1_md5_des': 'des',\n                'pbes1_md2_rc2': 'rc2',\n                'pbes1_md5_rc2': 'rc2',\n                'pbes1_sha1_des': 'des',\n                'pbes1_sha1_rc2': 'rc2',\n                'pkcs12_sha1_rc4_128': 'rc4',\n                'pkcs12_sha1_rc4_40': 'rc4',\n                'pkcs12_sha1_tripledes_3key': 'tripledes',\n                'pkcs12_sha1_tripledes_2key': 'tripledes',\n                'pkcs12_sha1_rc2_128': 'rc2',\n                'pkcs12_sha1_rc2_40': 'rc2',\n            }[encryption_algo]\n\n        raise ValueError(unwrap(\n            '''\n            Unrecognized encryption algorithm \"%s\"\n            ''',\n            encryption_algo\n        ))\n\n    @property\n    def encryption_block_size(self):\n        \"\"\"\n        Returns the block size of the encryption cipher, in bytes.\n\n        :return:\n            An integer that is the block size in bytes\n        \"\"\"\n\n        encryption_algo = self['algorithm'].native\n\n        if encryption_algo[0:7] in set(['aes128_', 'aes192_', 'aes256_']):\n            return 16\n\n        cipher_map = {\n            'des': 8,\n            'tripledes_3key': 8,\n            'rc2': 8,\n        }\n        if encryption_algo in cipher_map:\n            return cipher_map[encryption_algo]\n\n        if encryption_algo == 'rc5':\n            return self['parameters']['block_size_in_bits'].native // 8\n\n        if encryption_algo == 'pbes2':\n            return self['parameters']['encryption_scheme'].encryption_block_size\n\n        if encryption_algo.find('.') == -1:\n            return {\n                'pbes1_md2_des': 8,\n                'pbes1_md5_des': 8,\n                'pbes1_md2_rc2': 8,\n                'pbes1_md5_rc2': 8,\n                'pbes1_sha1_des': 8,\n                'pbes1_sha1_rc2': 8,\n                'pkcs12_sha1_rc4_128': 0,\n                'pkcs12_sha1_rc4_40': 0,\n                'pkcs12_sha1_tripledes_3key': 8,\n                'pkcs12_sha1_tripledes_2key': 8,\n                'pkcs12_sha1_rc2_128': 8,\n                'pkcs12_sha1_rc2_40': 8,\n            }[encryption_algo]\n\n        raise ValueError(unwrap(\n            '''\n            Unrecognized encryption algorithm \"%s\"\n            ''',\n            encryption_algo\n        ))\n\n    @property\n    def encryption_iv(self):\n        \"\"\"\n        Returns the byte string of the initialization vector for the encryption\n        scheme. Only the PBES2 stores the IV in the params. For PBES1, the IV\n        is derived from the KDF and this property will return None.\n\n        :return:\n            A byte string or None\n        \"\"\"\n\n        encryption_algo = self['algorithm'].native\n\n        if encryption_algo in set(['rc2', 'rc5']):\n            return self['parameters']['iv'].native\n\n        # For DES/Triple DES and AES the IV is the entirety of the parameters\n        octet_string_iv_oids = set([\n            'des',\n            'tripledes_3key',\n            'aes128_cbc',\n            'aes192_cbc',\n            'aes256_cbc',\n            'aes128_ofb',\n            'aes192_ofb',\n            'aes256_ofb',\n        ])\n        if encryption_algo in octet_string_iv_oids:\n            return self['parameters'].native\n\n        if encryption_algo == 'pbes2':\n            return self['parameters']['encryption_scheme'].encryption_iv\n\n        # All of the PBES1 algos use their KDF to create the IV. For the pbkdf1,\n        # the KDF is told to generate a key that is an extra 8 bytes long, and\n        # that is used for the IV. For the PKCS#12 KDF, it is called with an id\n        # of 2 to generate the IV. In either case, we can't return the IV\n        # without knowing the user's password.\n        if encryption_algo.find('.') == -1:\n            return None\n\n        raise ValueError(unwrap(\n            '''\n            Unrecognized encryption algorithm \"%s\"\n            ''',\n            encryption_algo\n        ))\n\n\nclass Pbes2Params(Sequence):\n    _fields = [\n        ('key_derivation_func', KdfAlgorithm),\n        ('encryption_scheme', EncryptionAlgorithm),\n    ]\n\n\nclass Pbmac1Params(Sequence):\n    _fields = [\n        ('key_derivation_func', KdfAlgorithm),\n        ('message_auth_scheme', HmacAlgorithm),\n    ]\n\n\nclass Pkcs5MacId(ObjectIdentifier):\n    _map = {\n        '1.2.840.113549.1.5.14': 'pbmac1',\n    }\n\n\nclass Pkcs5MacAlgorithm(Sequence):\n    _fields = [\n        ('algorithm', Pkcs5MacId),\n        ('parameters', Any),\n    ]\n\n    _oid_pair = ('algorithm', 'parameters')\n    _oid_specs = {\n        'pbmac1': Pbmac1Params,\n    }\n\n\nEncryptionAlgorithm._oid_specs['pbes2'] = Pbes2Params\n\n\nclass AnyAlgorithmId(ObjectIdentifier):\n    _map = {}\n\n    def _setup(self):\n        _map = self.__class__._map\n        for other_cls in (EncryptionAlgorithmId, SignedDigestAlgorithmId, DigestAlgorithmId):\n            for oid, name in other_cls._map.items():\n                _map[oid] = name\n\n\nclass AnyAlgorithmIdentifier(_ForceNullParameters, Sequence):\n    _fields = [\n        ('algorithm', AnyAlgorithmId),\n        ('parameters', Any, {'optional': True}),\n    ]\n\n    _oid_pair = ('algorithm', 'parameters')\n    _oid_specs = {}\n\n    def _setup(self):\n        Sequence._setup(self)\n        specs = self.__class__._oid_specs\n        for other_cls in (EncryptionAlgorithm, SignedDigestAlgorithm):\n            for oid, spec in other_cls._oid_specs.items():\n                specs[oid] = spec\n"
  },
  {
    "path": "code/default/lib/noarch/asn1crypto/cms.py",
    "content": "# coding: utf-8\n\n\"\"\"\nASN.1 type classes for cryptographic message syntax (CMS). Structures are also\ncompatible with PKCS#7. Exports the following items:\n\n - AuthenticatedData()\n - AuthEnvelopedData()\n - CompressedData()\n - ContentInfo()\n - DigestedData()\n - EncryptedData()\n - EnvelopedData()\n - SignedAndEnvelopedData()\n - SignedData()\n\nOther type classes are defined that help compose the types listed above.\n\nMost CMS structures in the wild are formatted as ContentInfo encapsulating one of the other types.\n\"\"\"\n\nfrom __future__ import unicode_literals, division, absolute_import, print_function\n\ntry:\n    import zlib\nexcept (ImportError):\n    zlib = None\n\nfrom .algos import (\n    _ForceNullParameters,\n    DigestAlgorithm,\n    EncryptionAlgorithm,\n    EncryptionAlgorithmId,\n    HmacAlgorithm,\n    KdfAlgorithm,\n    RSAESOAEPParams,\n    SignedDigestAlgorithm,\n)\nfrom .core import (\n    Any,\n    BitString,\n    Choice,\n    Enumerated,\n    GeneralizedTime,\n    Integer,\n    ObjectIdentifier,\n    OctetBitString,\n    OctetString,\n    ParsableOctetString,\n    Sequence,\n    SequenceOf,\n    SetOf,\n    UTCTime,\n    UTF8String,\n)\nfrom .crl import CertificateList\nfrom .keys import PublicKeyInfo\nfrom .ocsp import OCSPResponse\nfrom .x509 import Attributes, Certificate, Extensions, GeneralName, GeneralNames, Name\n\n\n# These structures are taken from\n# ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-6.asc\n\nclass ExtendedCertificateInfo(Sequence):\n    _fields = [\n        ('version', Integer),\n        ('certificate', Certificate),\n        ('attributes', Attributes),\n    ]\n\n\nclass ExtendedCertificate(Sequence):\n    _fields = [\n        ('extended_certificate_info', ExtendedCertificateInfo),\n        ('signature_algorithm', SignedDigestAlgorithm),\n        ('signature', OctetBitString),\n    ]\n\n\n# These structures are taken from https://tools.ietf.org/html/rfc5652,\n# https://tools.ietf.org/html/rfc5083, http://tools.ietf.org/html/rfc2315,\n# https://tools.ietf.org/html/rfc5940, https://tools.ietf.org/html/rfc3274,\n# https://tools.ietf.org/html/rfc3281\n\n\nclass CMSVersion(Integer):\n    _map = {\n        0: 'v0',\n        1: 'v1',\n        2: 'v2',\n        3: 'v3',\n        4: 'v4',\n        5: 'v5',\n    }\n\n\nclass CMSAttributeType(ObjectIdentifier):\n    _map = {\n        '1.2.840.113549.1.9.3': 'content_type',\n        '1.2.840.113549.1.9.4': 'message_digest',\n        '1.2.840.113549.1.9.5': 'signing_time',\n        '1.2.840.113549.1.9.6': 'counter_signature',\n        # https://datatracker.ietf.org/doc/html/rfc2633#section-2.5.2\n        '1.2.840.113549.1.9.15': 'smime_capabilities',\n        # https://tools.ietf.org/html/rfc2633#page-26\n        '1.2.840.113549.1.9.16.2.11': 'encrypt_key_pref',\n        # https://tools.ietf.org/html/rfc3161#page-20\n        '1.2.840.113549.1.9.16.2.14': 'signature_time_stamp_token',\n        # https://tools.ietf.org/html/rfc6211#page-5\n        '1.2.840.113549.1.9.52': 'cms_algorithm_protection',\n        # https://docs.microsoft.com/en-us/previous-versions/hh968145(v%3Dvs.85)\n        '1.3.6.1.4.1.311.2.4.1': 'microsoft_nested_signature',\n        # Some places refer to this as SPC_RFC3161_OBJID, others szOID_RFC3161_counterSign.\n        # https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-crypt_algorithm_identifier\n        # refers to szOID_RFC3161_counterSign as \"1.2.840.113549.1.9.16.1.4\",\n        # but that OID is also called szOID_TIMESTAMP_TOKEN. Because of there being\n        # no canonical source for this OID, we give it our own name\n        '1.3.6.1.4.1.311.3.3.1': 'microsoft_time_stamp_token',\n    }\n\n\nclass Time(Choice):\n    _alternatives = [\n        ('utc_time', UTCTime),\n        ('generalized_time', GeneralizedTime),\n    ]\n\n\nclass ContentType(ObjectIdentifier):\n    _map = {\n        '1.2.840.113549.1.7.1': 'data',\n        '1.2.840.113549.1.7.2': 'signed_data',\n        '1.2.840.113549.1.7.3': 'enveloped_data',\n        '1.2.840.113549.1.7.4': 'signed_and_enveloped_data',\n        '1.2.840.113549.1.7.5': 'digested_data',\n        '1.2.840.113549.1.7.6': 'encrypted_data',\n        '1.2.840.113549.1.9.16.1.2': 'authenticated_data',\n        '1.2.840.113549.1.9.16.1.9': 'compressed_data',\n        '1.2.840.113549.1.9.16.1.23': 'authenticated_enveloped_data',\n    }\n\n\nclass CMSAlgorithmProtection(Sequence):\n    _fields = [\n        ('digest_algorithm', DigestAlgorithm),\n        ('signature_algorithm', SignedDigestAlgorithm, {'implicit': 1, 'optional': True}),\n        ('mac_algorithm', HmacAlgorithm, {'implicit': 2, 'optional': True}),\n    ]\n\n\nclass SetOfContentType(SetOf):\n    _child_spec = ContentType\n\n\nclass SetOfOctetString(SetOf):\n    _child_spec = OctetString\n\n\nclass SetOfTime(SetOf):\n    _child_spec = Time\n\n\nclass SetOfAny(SetOf):\n    _child_spec = Any\n\n\nclass SetOfCMSAlgorithmProtection(SetOf):\n    _child_spec = CMSAlgorithmProtection\n\n\nclass CMSAttribute(Sequence):\n    _fields = [\n        ('type', CMSAttributeType),\n        ('values', None),\n    ]\n\n    _oid_specs = {}\n\n    def _values_spec(self):\n        return self._oid_specs.get(self['type'].native, SetOfAny)\n\n    _spec_callbacks = {\n        'values': _values_spec\n    }\n\n\nclass CMSAttributes(SetOf):\n    _child_spec = CMSAttribute\n\n\nclass IssuerSerial(Sequence):\n    _fields = [\n        ('issuer', GeneralNames),\n        ('serial', Integer),\n        ('issuer_uid', OctetBitString, {'optional': True}),\n    ]\n\n\nclass AttCertVersion(Integer):\n    _map = {\n        0: 'v1',\n        1: 'v2',\n    }\n\n\nclass AttCertSubject(Choice):\n    _alternatives = [\n        ('base_certificate_id', IssuerSerial, {'explicit': 0}),\n        ('subject_name', GeneralNames, {'explicit': 1}),\n    ]\n\n\nclass AttCertValidityPeriod(Sequence):\n    _fields = [\n        ('not_before_time', GeneralizedTime),\n        ('not_after_time', GeneralizedTime),\n    ]\n\n\nclass AttributeCertificateInfoV1(Sequence):\n    _fields = [\n        ('version', AttCertVersion, {'default': 'v1'}),\n        ('subject', AttCertSubject),\n        ('issuer', GeneralNames),\n        ('signature', SignedDigestAlgorithm),\n        ('serial_number', Integer),\n        ('att_cert_validity_period', AttCertValidityPeriod),\n        ('attributes', Attributes),\n        ('issuer_unique_id', OctetBitString, {'optional': True}),\n        ('extensions', Extensions, {'optional': True}),\n    ]\n\n\nclass AttributeCertificateV1(Sequence):\n    _fields = [\n        ('ac_info', AttributeCertificateInfoV1),\n        ('signature_algorithm', SignedDigestAlgorithm),\n        ('signature', OctetBitString),\n    ]\n\n\nclass DigestedObjectType(Enumerated):\n    _map = {\n        0: 'public_key',\n        1: 'public_key_cert',\n        2: 'other_objy_types',\n    }\n\n\nclass ObjectDigestInfo(Sequence):\n    _fields = [\n        ('digested_object_type', DigestedObjectType),\n        ('other_object_type_id', ObjectIdentifier, {'optional': True}),\n        ('digest_algorithm', DigestAlgorithm),\n        ('object_digest', OctetBitString),\n    ]\n\n\nclass Holder(Sequence):\n    _fields = [\n        ('base_certificate_id', IssuerSerial, {'implicit': 0, 'optional': True}),\n        ('entity_name', GeneralNames, {'implicit': 1, 'optional': True}),\n        ('object_digest_info', ObjectDigestInfo, {'implicit': 2, 'optional': True}),\n    ]\n\n\nclass V2Form(Sequence):\n    _fields = [\n        ('issuer_name', GeneralNames, {'optional': True}),\n        ('base_certificate_id', IssuerSerial, {'explicit': 0, 'optional': True}),\n        ('object_digest_info', ObjectDigestInfo, {'explicit': 1, 'optional': True}),\n    ]\n\n\nclass AttCertIssuer(Choice):\n    _alternatives = [\n        ('v1_form', GeneralNames),\n        ('v2_form', V2Form, {'implicit': 0}),\n    ]\n\n\nclass IetfAttrValue(Choice):\n    _alternatives = [\n        ('octets', OctetString),\n        ('oid', ObjectIdentifier),\n        ('string', UTF8String),\n    ]\n\n\nclass IetfAttrValues(SequenceOf):\n    _child_spec = IetfAttrValue\n\n\nclass IetfAttrSyntax(Sequence):\n    _fields = [\n        ('policy_authority', GeneralNames, {'implicit': 0, 'optional': True}),\n        ('values', IetfAttrValues),\n    ]\n\n\nclass SetOfIetfAttrSyntax(SetOf):\n    _child_spec = IetfAttrSyntax\n\n\nclass SvceAuthInfo(Sequence):\n    _fields = [\n        ('service', GeneralName),\n        ('ident', GeneralName),\n        ('auth_info', OctetString, {'optional': True}),\n    ]\n\n\nclass SetOfSvceAuthInfo(SetOf):\n    _child_spec = SvceAuthInfo\n\n\nclass RoleSyntax(Sequence):\n    _fields = [\n        ('role_authority', GeneralNames, {'implicit': 0, 'optional': True}),\n        ('role_name', GeneralName, {'explicit': 1}),\n    ]\n\n\nclass SetOfRoleSyntax(SetOf):\n    _child_spec = RoleSyntax\n\n\nclass ClassList(BitString):\n    _map = {\n        0: 'unmarked',\n        1: 'unclassified',\n        2: 'restricted',\n        3: 'confidential',\n        4: 'secret',\n        5: 'top_secret',\n    }\n\n\nclass SecurityCategory(Sequence):\n    _fields = [\n        ('type', ObjectIdentifier, {'implicit': 0}),\n        ('value', Any, {'explicit': 1}),\n    ]\n\n\nclass SetOfSecurityCategory(SetOf):\n    _child_spec = SecurityCategory\n\n\nclass Clearance(Sequence):\n    _fields = [\n        ('policy_id', ObjectIdentifier),\n        ('class_list', ClassList, {'default': set(['unclassified'])}),\n        ('security_categories', SetOfSecurityCategory, {'optional': True}),\n    ]\n\n\nclass SetOfClearance(SetOf):\n    _child_spec = Clearance\n\n\nclass BigTime(Sequence):\n    _fields = [\n        ('major', Integer),\n        ('fractional_seconds', Integer),\n        ('sign', Integer, {'optional': True}),\n    ]\n\n\nclass LeapData(Sequence):\n    _fields = [\n        ('leap_time', BigTime),\n        ('action', Integer),\n    ]\n\n\nclass SetOfLeapData(SetOf):\n    _child_spec = LeapData\n\n\nclass TimingMetrics(Sequence):\n    _fields = [\n        ('ntp_time', BigTime),\n        ('offset', BigTime),\n        ('delay', BigTime),\n        ('expiration', BigTime),\n        ('leap_event', SetOfLeapData, {'optional': True}),\n    ]\n\n\nclass SetOfTimingMetrics(SetOf):\n    _child_spec = TimingMetrics\n\n\nclass TimingPolicy(Sequence):\n    _fields = [\n        ('policy_id', SequenceOf, {'spec': ObjectIdentifier}),\n        ('max_offset', BigTime, {'explicit': 0, 'optional': True}),\n        ('max_delay', BigTime, {'explicit': 1, 'optional': True}),\n    ]\n\n\nclass SetOfTimingPolicy(SetOf):\n    _child_spec = TimingPolicy\n\n\nclass AttCertAttributeType(ObjectIdentifier):\n    _map = {\n        '1.3.6.1.5.5.7.10.1': 'authentication_info',\n        '1.3.6.1.5.5.7.10.2': 'access_identity',\n        '1.3.6.1.5.5.7.10.3': 'charging_identity',\n        '1.3.6.1.5.5.7.10.4': 'group',\n        '2.5.4.72': 'role',\n        '2.5.4.55': 'clearance',\n        '1.3.6.1.4.1.601.10.4.1': 'timing_metrics',\n        '1.3.6.1.4.1.601.10.4.2': 'timing_policy',\n    }\n\n\nclass AttCertAttribute(Sequence):\n    _fields = [\n        ('type', AttCertAttributeType),\n        ('values', None),\n    ]\n\n    _oid_specs = {\n        'authentication_info': SetOfSvceAuthInfo,\n        'access_identity': SetOfSvceAuthInfo,\n        'charging_identity': SetOfIetfAttrSyntax,\n        'group': SetOfIetfAttrSyntax,\n        'role': SetOfRoleSyntax,\n        'clearance': SetOfClearance,\n        'timing_metrics': SetOfTimingMetrics,\n        'timing_policy': SetOfTimingPolicy,\n    }\n\n    def _values_spec(self):\n        return self._oid_specs.get(self['type'].native, SetOfAny)\n\n    _spec_callbacks = {\n        'values': _values_spec\n    }\n\n\nclass AttCertAttributes(SequenceOf):\n    _child_spec = AttCertAttribute\n\n\nclass AttributeCertificateInfoV2(Sequence):\n    _fields = [\n        ('version', AttCertVersion),\n        ('holder', Holder),\n        ('issuer', AttCertIssuer),\n        ('signature', SignedDigestAlgorithm),\n        ('serial_number', Integer),\n        ('att_cert_validity_period', AttCertValidityPeriod),\n        ('attributes', AttCertAttributes),\n        ('issuer_unique_id', OctetBitString, {'optional': True}),\n        ('extensions', Extensions, {'optional': True}),\n    ]\n\n\nclass AttributeCertificateV2(Sequence):\n    # Handle the situation where a V2 cert is encoded as V1\n    _bad_tag = 1\n\n    _fields = [\n        ('ac_info', AttributeCertificateInfoV2),\n        ('signature_algorithm', SignedDigestAlgorithm),\n        ('signature', OctetBitString),\n    ]\n\n\nclass OtherCertificateFormat(Sequence):\n    _fields = [\n        ('other_cert_format', ObjectIdentifier),\n        ('other_cert', Any),\n    ]\n\n\nclass CertificateChoices(Choice):\n    _alternatives = [\n        ('certificate', Certificate),\n        ('extended_certificate', ExtendedCertificate, {'implicit': 0}),\n        ('v1_attr_cert', AttributeCertificateV1, {'implicit': 1}),\n        ('v2_attr_cert', AttributeCertificateV2, {'implicit': 2}),\n        ('other', OtherCertificateFormat, {'implicit': 3}),\n    ]\n\n    def validate(self, class_, tag, contents):\n        \"\"\"\n        Ensures that the class and tag specified exist as an alternative. This\n        custom version fixes parsing broken encodings there a V2 attribute\n        # certificate is encoded as a V1\n\n        :param class_:\n            The integer class_ from the encoded value header\n\n        :param tag:\n            The integer tag from the encoded value header\n\n        :param contents:\n            A byte string of the contents of the value - used when the object\n            is explicitly tagged\n\n        :raises:\n            ValueError - when value is not a valid alternative\n        \"\"\"\n\n        super(CertificateChoices, self).validate(class_, tag, contents)\n        if self._choice == 2:\n            if AttCertVersion.load(Sequence.load(contents)[0].dump()).native == 'v2':\n                self._choice = 3\n\n\nclass CertificateSet(SetOf):\n    _child_spec = CertificateChoices\n\n\nclass ContentInfo(Sequence):\n    _fields = [\n        ('content_type', ContentType),\n        ('content', Any, {'explicit': 0, 'optional': True}),\n    ]\n\n    _oid_pair = ('content_type', 'content')\n    _oid_specs = {}\n\n\nclass SetOfContentInfo(SetOf):\n    _child_spec = ContentInfo\n\n\nclass EncapsulatedContentInfo(Sequence):\n    _fields = [\n        ('content_type', ContentType),\n        ('content', ParsableOctetString, {'explicit': 0, 'optional': True}),\n    ]\n\n    _oid_pair = ('content_type', 'content')\n    _oid_specs = {}\n\n\nclass IssuerAndSerialNumber(Sequence):\n    _fields = [\n        ('issuer', Name),\n        ('serial_number', Integer),\n    ]\n\n\nclass SignerIdentifier(Choice):\n    _alternatives = [\n        ('issuer_and_serial_number', IssuerAndSerialNumber),\n        ('subject_key_identifier', OctetString, {'implicit': 0}),\n    ]\n\n\nclass DigestAlgorithms(SetOf):\n    _child_spec = DigestAlgorithm\n\n\nclass CertificateRevocationLists(SetOf):\n    _child_spec = CertificateList\n\n\nclass SCVPReqRes(Sequence):\n    _fields = [\n        ('request', ContentInfo, {'explicit': 0, 'optional': True}),\n        ('response', ContentInfo),\n    ]\n\n\nclass OtherRevInfoFormatId(ObjectIdentifier):\n    _map = {\n        '1.3.6.1.5.5.7.16.2': 'ocsp_response',\n        '1.3.6.1.5.5.7.16.4': 'scvp',\n    }\n\n\nclass OtherRevocationInfoFormat(Sequence):\n    _fields = [\n        ('other_rev_info_format', OtherRevInfoFormatId),\n        ('other_rev_info', Any),\n    ]\n\n    _oid_pair = ('other_rev_info_format', 'other_rev_info')\n    _oid_specs = {\n        'ocsp_response': OCSPResponse,\n        'scvp': SCVPReqRes,\n    }\n\n\nclass RevocationInfoChoice(Choice):\n    _alternatives = [\n        ('crl', CertificateList),\n        ('other', OtherRevocationInfoFormat, {'implicit': 1}),\n    ]\n\n\nclass RevocationInfoChoices(SetOf):\n    _child_spec = RevocationInfoChoice\n\n\nclass SignerInfo(Sequence):\n    _fields = [\n        ('version', CMSVersion),\n        ('sid', SignerIdentifier),\n        ('digest_algorithm', DigestAlgorithm),\n        ('signed_attrs', CMSAttributes, {'implicit': 0, 'optional': True}),\n        ('signature_algorithm', SignedDigestAlgorithm),\n        ('signature', OctetString),\n        ('unsigned_attrs', CMSAttributes, {'implicit': 1, 'optional': True}),\n    ]\n\n\nclass SignerInfos(SetOf):\n    _child_spec = SignerInfo\n\n\nclass SignedData(Sequence):\n    _fields = [\n        ('version', CMSVersion),\n        ('digest_algorithms', DigestAlgorithms),\n        ('encap_content_info', None),\n        ('certificates', CertificateSet, {'implicit': 0, 'optional': True}),\n        ('crls', RevocationInfoChoices, {'implicit': 1, 'optional': True}),\n        ('signer_infos', SignerInfos),\n    ]\n\n    def _encap_content_info_spec(self):\n        # If the encap_content_info is version v1, then this could be a PKCS#7\n        # structure, or a CMS structure. CMS wraps the encoded value in an\n        # Octet String tag.\n\n        # If the version is greater than 1, it is definite CMS\n        if self['version'].native != 'v1':\n            return EncapsulatedContentInfo\n\n        # Otherwise, the ContentInfo spec from PKCS#7 will be compatible with\n        # CMS v1 (which only allows Data, an Octet String) and PKCS#7, which\n        # allows Any\n        return ContentInfo\n\n    _spec_callbacks = {\n        'encap_content_info': _encap_content_info_spec\n    }\n\n\nclass OriginatorInfo(Sequence):\n    _fields = [\n        ('certs', CertificateSet, {'implicit': 0, 'optional': True}),\n        ('crls', RevocationInfoChoices, {'implicit': 1, 'optional': True}),\n    ]\n\n\nclass RecipientIdentifier(Choice):\n    _alternatives = [\n        ('issuer_and_serial_number', IssuerAndSerialNumber),\n        ('subject_key_identifier', OctetString, {'implicit': 0}),\n    ]\n\n\nclass KeyEncryptionAlgorithmId(ObjectIdentifier):\n    _map = {\n        '1.2.840.113549.1.1.1': 'rsaes_pkcs1v15',\n        '1.2.840.113549.1.1.7': 'rsaes_oaep',\n        '2.16.840.1.101.3.4.1.5': 'aes128_wrap',\n        '2.16.840.1.101.3.4.1.8': 'aes128_wrap_pad',\n        '2.16.840.1.101.3.4.1.25': 'aes192_wrap',\n        '2.16.840.1.101.3.4.1.28': 'aes192_wrap_pad',\n        '2.16.840.1.101.3.4.1.45': 'aes256_wrap',\n        '2.16.840.1.101.3.4.1.48': 'aes256_wrap_pad',\n    }\n\n    _reverse_map = {\n        'rsa': '1.2.840.113549.1.1.1',\n        'rsaes_pkcs1v15': '1.2.840.113549.1.1.1',\n        'rsaes_oaep': '1.2.840.113549.1.1.7',\n        'aes128_wrap': '2.16.840.1.101.3.4.1.5',\n        'aes128_wrap_pad': '2.16.840.1.101.3.4.1.8',\n        'aes192_wrap': '2.16.840.1.101.3.4.1.25',\n        'aes192_wrap_pad': '2.16.840.1.101.3.4.1.28',\n        'aes256_wrap': '2.16.840.1.101.3.4.1.45',\n        'aes256_wrap_pad': '2.16.840.1.101.3.4.1.48',\n    }\n\n\nclass KeyEncryptionAlgorithm(_ForceNullParameters, Sequence):\n    _fields = [\n        ('algorithm', KeyEncryptionAlgorithmId),\n        ('parameters', Any, {'optional': True}),\n    ]\n\n    _oid_pair = ('algorithm', 'parameters')\n    _oid_specs = {\n        'rsaes_oaep': RSAESOAEPParams,\n    }\n\n\nclass KeyTransRecipientInfo(Sequence):\n    _fields = [\n        ('version', CMSVersion),\n        ('rid', RecipientIdentifier),\n        ('key_encryption_algorithm', KeyEncryptionAlgorithm),\n        ('encrypted_key', OctetString),\n    ]\n\n\nclass OriginatorIdentifierOrKey(Choice):\n    _alternatives = [\n        ('issuer_and_serial_number', IssuerAndSerialNumber),\n        ('subject_key_identifier', OctetString, {'implicit': 0}),\n        ('originator_key', PublicKeyInfo, {'implicit': 1}),\n    ]\n\n\nclass OtherKeyAttribute(Sequence):\n    _fields = [\n        ('key_attr_id', ObjectIdentifier),\n        ('key_attr', Any),\n    ]\n\n\nclass RecipientKeyIdentifier(Sequence):\n    _fields = [\n        ('subject_key_identifier', OctetString),\n        ('date', GeneralizedTime, {'optional': True}),\n        ('other', OtherKeyAttribute, {'optional': True}),\n    ]\n\n\nclass KeyAgreementRecipientIdentifier(Choice):\n    _alternatives = [\n        ('issuer_and_serial_number', IssuerAndSerialNumber),\n        ('r_key_id', RecipientKeyIdentifier, {'implicit': 0}),\n    ]\n\n\nclass RecipientEncryptedKey(Sequence):\n    _fields = [\n        ('rid', KeyAgreementRecipientIdentifier),\n        ('encrypted_key', OctetString),\n    ]\n\n\nclass RecipientEncryptedKeys(SequenceOf):\n    _child_spec = RecipientEncryptedKey\n\n\nclass KeyAgreeRecipientInfo(Sequence):\n    _fields = [\n        ('version', CMSVersion),\n        ('originator', OriginatorIdentifierOrKey, {'explicit': 0}),\n        ('ukm', OctetString, {'explicit': 1, 'optional': True}),\n        ('key_encryption_algorithm', KeyEncryptionAlgorithm),\n        ('recipient_encrypted_keys', RecipientEncryptedKeys),\n    ]\n\n\nclass KEKIdentifier(Sequence):\n    _fields = [\n        ('key_identifier', OctetString),\n        ('date', GeneralizedTime, {'optional': True}),\n        ('other', OtherKeyAttribute, {'optional': True}),\n    ]\n\n\nclass KEKRecipientInfo(Sequence):\n    _fields = [\n        ('version', CMSVersion),\n        ('kekid', KEKIdentifier),\n        ('key_encryption_algorithm', KeyEncryptionAlgorithm),\n        ('encrypted_key', OctetString),\n    ]\n\n\nclass PasswordRecipientInfo(Sequence):\n    _fields = [\n        ('version', CMSVersion),\n        ('key_derivation_algorithm', KdfAlgorithm, {'implicit': 0, 'optional': True}),\n        ('key_encryption_algorithm', KeyEncryptionAlgorithm),\n        ('encrypted_key', OctetString),\n    ]\n\n\nclass OtherRecipientInfo(Sequence):\n    _fields = [\n        ('ori_type', ObjectIdentifier),\n        ('ori_value', Any),\n    ]\n\n\nclass RecipientInfo(Choice):\n    _alternatives = [\n        ('ktri', KeyTransRecipientInfo),\n        ('kari', KeyAgreeRecipientInfo, {'implicit': 1}),\n        ('kekri', KEKRecipientInfo, {'implicit': 2}),\n        ('pwri', PasswordRecipientInfo, {'implicit': 3}),\n        ('ori', OtherRecipientInfo, {'implicit': 4}),\n    ]\n\n\nclass RecipientInfos(SetOf):\n    _child_spec = RecipientInfo\n\n\nclass EncryptedContentInfo(Sequence):\n    _fields = [\n        ('content_type', ContentType),\n        ('content_encryption_algorithm', EncryptionAlgorithm),\n        ('encrypted_content', OctetString, {'implicit': 0, 'optional': True}),\n    ]\n\n\nclass EnvelopedData(Sequence):\n    _fields = [\n        ('version', CMSVersion),\n        ('originator_info', OriginatorInfo, {'implicit': 0, 'optional': True}),\n        ('recipient_infos', RecipientInfos),\n        ('encrypted_content_info', EncryptedContentInfo),\n        ('unprotected_attrs', CMSAttributes, {'implicit': 1, 'optional': True}),\n    ]\n\n\nclass SignedAndEnvelopedData(Sequence):\n    _fields = [\n        ('version', CMSVersion),\n        ('recipient_infos', RecipientInfos),\n        ('digest_algorithms', DigestAlgorithms),\n        ('encrypted_content_info', EncryptedContentInfo),\n        ('certificates', CertificateSet, {'implicit': 0, 'optional': True}),\n        ('crls', CertificateRevocationLists, {'implicit': 1, 'optional': True}),\n        ('signer_infos', SignerInfos),\n    ]\n\n\nclass DigestedData(Sequence):\n    _fields = [\n        ('version', CMSVersion),\n        ('digest_algorithm', DigestAlgorithm),\n        ('encap_content_info', None),\n        ('digest', OctetString),\n    ]\n\n    def _encap_content_info_spec(self):\n        # If the encap_content_info is version v1, then this could be a PKCS#7\n        # structure, or a CMS structure. CMS wraps the encoded value in an\n        # Octet String tag.\n\n        # If the version is greater than 1, it is definite CMS\n        if self['version'].native != 'v1':\n            return EncapsulatedContentInfo\n\n        # Otherwise, the ContentInfo spec from PKCS#7 will be compatible with\n        # CMS v1 (which only allows Data, an Octet String) and PKCS#7, which\n        # allows Any\n        return ContentInfo\n\n    _spec_callbacks = {\n        'encap_content_info': _encap_content_info_spec\n    }\n\n\nclass EncryptedData(Sequence):\n    _fields = [\n        ('version', CMSVersion),\n        ('encrypted_content_info', EncryptedContentInfo),\n        ('unprotected_attrs', CMSAttributes, {'implicit': 1, 'optional': True}),\n    ]\n\n\nclass AuthenticatedData(Sequence):\n    _fields = [\n        ('version', CMSVersion),\n        ('originator_info', OriginatorInfo, {'implicit': 0, 'optional': True}),\n        ('recipient_infos', RecipientInfos),\n        ('mac_algorithm', HmacAlgorithm),\n        ('digest_algorithm', DigestAlgorithm, {'implicit': 1, 'optional': True}),\n        # This does not require the _spec_callbacks approach of SignedData and\n        # DigestedData since AuthenticatedData was not part of PKCS#7\n        ('encap_content_info', EncapsulatedContentInfo),\n        ('auth_attrs', CMSAttributes, {'implicit': 2, 'optional': True}),\n        ('mac', OctetString),\n        ('unauth_attrs', CMSAttributes, {'implicit': 3, 'optional': True}),\n    ]\n\n\nclass AuthEnvelopedData(Sequence):\n    _fields = [\n        ('version', CMSVersion),\n        ('originator_info', OriginatorInfo, {'implicit': 0, 'optional': True}),\n        ('recipient_infos', RecipientInfos),\n        ('auth_encrypted_content_info', EncryptedContentInfo),\n        ('auth_attrs', CMSAttributes, {'implicit': 1, 'optional': True}),\n        ('mac', OctetString),\n        ('unauth_attrs', CMSAttributes, {'implicit': 2, 'optional': True}),\n    ]\n\n\nclass CompressionAlgorithmId(ObjectIdentifier):\n    _map = {\n        '1.2.840.113549.1.9.16.3.8': 'zlib',\n    }\n\n\nclass CompressionAlgorithm(Sequence):\n    _fields = [\n        ('algorithm', CompressionAlgorithmId),\n        ('parameters', Any, {'optional': True}),\n    ]\n\n\nclass CompressedData(Sequence):\n    _fields = [\n        ('version', CMSVersion),\n        ('compression_algorithm', CompressionAlgorithm),\n        ('encap_content_info', EncapsulatedContentInfo),\n    ]\n\n    _decompressed = None\n\n    @property\n    def decompressed(self):\n        if self._decompressed is None:\n            if zlib is None:\n                raise SystemError('The zlib module is not available')\n            self._decompressed = zlib.decompress(self['encap_content_info']['content'].native)\n        return self._decompressed\n\n\nclass RecipientKeyIdentifier(Sequence):\n    _fields = [\n        ('subjectKeyIdentifier', OctetString),\n        ('date', GeneralizedTime, {'optional': True}),\n        ('other', OtherKeyAttribute, {'optional': True}),\n    ]\n\n\nclass SMIMEEncryptionKeyPreference(Choice):\n    _alternatives = [\n        ('issuer_and_serial_number', IssuerAndSerialNumber, {'implicit': 0}),\n        ('recipientKeyId', RecipientKeyIdentifier, {'implicit': 1}),\n        ('subjectAltKeyIdentifier', PublicKeyInfo, {'implicit': 2}),\n    ]\n\n\nclass SMIMEEncryptionKeyPreferences(SetOf):\n    _child_spec = SMIMEEncryptionKeyPreference\n\n\nclass SMIMECapabilityIdentifier(Sequence):\n    _fields = [\n        ('capability_id', EncryptionAlgorithmId),\n        ('parameters', Any, {'optional': True}),\n    ]\n\n\nclass SMIMECapabilites(SequenceOf):\n    _child_spec = SMIMECapabilityIdentifier\n\n\nclass SetOfSMIMECapabilites(SetOf):\n    _child_spec = SMIMECapabilites\n\n\nContentInfo._oid_specs = {\n    'data': OctetString,\n    'signed_data': SignedData,\n    'enveloped_data': EnvelopedData,\n    'signed_and_enveloped_data': SignedAndEnvelopedData,\n    'digested_data': DigestedData,\n    'encrypted_data': EncryptedData,\n    'authenticated_data': AuthenticatedData,\n    'compressed_data': CompressedData,\n    'authenticated_enveloped_data': AuthEnvelopedData,\n}\n\n\nEncapsulatedContentInfo._oid_specs = {\n    'signed_data': SignedData,\n    'enveloped_data': EnvelopedData,\n    'signed_and_enveloped_data': SignedAndEnvelopedData,\n    'digested_data': DigestedData,\n    'encrypted_data': EncryptedData,\n    'authenticated_data': AuthenticatedData,\n    'compressed_data': CompressedData,\n    'authenticated_enveloped_data': AuthEnvelopedData,\n}\n\n\nCMSAttribute._oid_specs = {\n    'content_type': SetOfContentType,\n    'message_digest': SetOfOctetString,\n    'signing_time': SetOfTime,\n    'counter_signature': SignerInfos,\n    'signature_time_stamp_token': SetOfContentInfo,\n    'cms_algorithm_protection': SetOfCMSAlgorithmProtection,\n    'microsoft_nested_signature': SetOfContentInfo,\n    'microsoft_time_stamp_token': SetOfContentInfo,\n    'encrypt_key_pref': SMIMEEncryptionKeyPreferences,\n    'smime_capabilities': SetOfSMIMECapabilites,\n}\n"
  },
  {
    "path": "code/default/lib/noarch/asn1crypto/core.py",
    "content": "# coding: utf-8\n\n\"\"\"\nASN.1 type classes for universal types. Exports the following items:\n\n - load()\n - Any()\n - Asn1Value()\n - BitString()\n - BMPString()\n - Boolean()\n - CharacterString()\n - Choice()\n - EmbeddedPdv()\n - Enumerated()\n - GeneralizedTime()\n - GeneralString()\n - GraphicString()\n - IA5String()\n - InstanceOf()\n - Integer()\n - IntegerBitString()\n - IntegerOctetString()\n - Null()\n - NumericString()\n - ObjectDescriptor()\n - ObjectIdentifier()\n - OctetBitString()\n - OctetString()\n - PrintableString()\n - Real()\n - RelativeOid()\n - Sequence()\n - SequenceOf()\n - Set()\n - SetOf()\n - TeletexString()\n - UniversalString()\n - UTCTime()\n - UTF8String()\n - VideotexString()\n - VisibleString()\n - VOID\n - Void()\n\nOther type classes are defined that help compose the types listed above.\n\"\"\"\n\nfrom __future__ import unicode_literals, division, absolute_import, print_function\n\nfrom datetime import datetime, timedelta\nfrom fractions import Fraction\nimport binascii\nimport copy\nimport math\nimport re\nimport sys\n\nfrom . import _teletex_codec\nfrom ._errors import unwrap\nfrom ._ordereddict import OrderedDict\nfrom ._types import type_name, str_cls, byte_cls, int_types, chr_cls\nfrom .parser import _parse, _dump_header\nfrom .util import int_to_bytes, int_from_bytes, timezone, extended_datetime, create_timezone, utc_with_dst\n\nif sys.version_info <= (3,):\n    from cStringIO import StringIO as BytesIO\n\n    range = xrange  # noqa\n    _PY2 = True\n\nelse:\n    from io import BytesIO\n\n    _PY2 = False\n\n\n_teletex_codec.register()\n\n\nCLASS_NUM_TO_NAME_MAP = {\n    0: 'universal',\n    1: 'application',\n    2: 'context',\n    3: 'private',\n}\n\nCLASS_NAME_TO_NUM_MAP = {\n    'universal': 0,\n    'application': 1,\n    'context': 2,\n    'private': 3,\n    0: 0,\n    1: 1,\n    2: 2,\n    3: 3,\n}\n\nMETHOD_NUM_TO_NAME_MAP = {\n    0: 'primitive',\n    1: 'constructed',\n}\n\n\n_OID_RE = re.compile(r'^\\d+(\\.\\d+)*$')\n\n\n# A global tracker to ensure that _setup() is called for every class, even\n# if is has been called for a parent class. This allows different _fields\n# definitions for child classes. Without such a construct, the child classes\n# would just see the parent class attributes and would use them.\n_SETUP_CLASSES = {}\n\n\ndef load(encoded_data, strict=False):\n    \"\"\"\n    Loads a BER/DER-encoded byte string and construct a universal object based\n    on the tag value:\n\n     - 1: Boolean\n     - 2: Integer\n     - 3: BitString\n     - 4: OctetString\n     - 5: Null\n     - 6: ObjectIdentifier\n     - 7: ObjectDescriptor\n     - 8: InstanceOf\n     - 9: Real\n     - 10: Enumerated\n     - 11: EmbeddedPdv\n     - 12: UTF8String\n     - 13: RelativeOid\n     - 16: Sequence,\n     - 17: Set\n     - 18: NumericString\n     - 19: PrintableString\n     - 20: TeletexString\n     - 21: VideotexString\n     - 22: IA5String\n     - 23: UTCTime\n     - 24: GeneralizedTime\n     - 25: GraphicString\n     - 26: VisibleString\n     - 27: GeneralString\n     - 28: UniversalString\n     - 29: CharacterString\n     - 30: BMPString\n\n    :param encoded_data:\n        A byte string of BER or DER-encoded data\n\n    :param strict:\n        A boolean indicating if trailing data should be forbidden - if so, a\n        ValueError will be raised when trailing data exists\n\n    :raises:\n        ValueError - when strict is True and trailing data is present\n        ValueError - when the encoded value tag a tag other than listed above\n        ValueError - when the ASN.1 header length is longer than the data\n        TypeError - when encoded_data is not a byte string\n\n    :return:\n        An instance of the one of the universal classes\n    \"\"\"\n\n    return Asn1Value.load(encoded_data, strict=strict)\n\n\nclass Asn1Value(object):\n    \"\"\"\n    The basis of all ASN.1 values\n    \"\"\"\n\n    # The integer 0 for primitive, 1 for constructed\n    method = None\n\n    # An integer 0 through 3 - see CLASS_NUM_TO_NAME_MAP for value\n    class_ = None\n\n    # An integer 1 or greater indicating the tag number\n    tag = None\n\n    # An alternate tag allowed for this type - used for handling broken\n    # structures where a string value is encoded using an incorrect tag\n    _bad_tag = None\n\n    # If the value has been implicitly tagged\n    implicit = False\n\n    # If explicitly tagged, a tuple of 2-element tuples containing the\n    # class int and tag int, from innermost to outermost\n    explicit = None\n\n    # The BER/DER header bytes\n    _header = None\n\n    # Raw encoded value bytes not including class, method, tag, length header\n    contents = None\n\n    # The BER/DER trailer bytes\n    _trailer = b''\n\n    # The native python representation of the value - this is not used by\n    # some classes since they utilize _bytes or _unicode\n    _native = None\n\n    @classmethod\n    def load(cls, encoded_data, strict=False, **kwargs):\n        \"\"\"\n        Loads a BER/DER-encoded byte string using the current class as the spec\n\n        :param encoded_data:\n            A byte string of BER or DER-encoded data\n\n        :param strict:\n            A boolean indicating if trailing data should be forbidden - if so, a\n            ValueError will be raised when trailing data exists\n\n        :return:\n            An instance of the current class\n        \"\"\"\n\n        if not isinstance(encoded_data, byte_cls):\n            raise TypeError('encoded_data must be a byte string, not %s' % type_name(encoded_data))\n\n        spec = None\n        if cls.tag is not None:\n            spec = cls\n\n        value, _ = _parse_build(encoded_data, spec=spec, spec_params=kwargs, strict=strict)\n        return value\n\n    def __init__(self, explicit=None, implicit=None, no_explicit=False, tag_type=None, class_=None, tag=None,\n                 optional=None, default=None, contents=None, method=None):\n        \"\"\"\n        The optional parameter is not used, but rather included so we don't\n        have to delete it from the parameter dictionary when passing as keyword\n        args\n\n        :param explicit:\n            An int tag number for explicit tagging, or a 2-element tuple of\n            class and tag.\n\n        :param implicit:\n            An int tag number for implicit tagging, or a 2-element tuple of\n            class and tag.\n\n        :param no_explicit:\n            If explicit tagging info should be removed from this instance.\n            Used internally to allow contructing the underlying value that\n            has been wrapped in an explicit tag.\n\n        :param tag_type:\n            None for normal values, or one of \"implicit\", \"explicit\" for tagged\n            values. Deprecated in favor of explicit and implicit params.\n\n        :param class_:\n            The class for the value - defaults to \"universal\" if tag_type is\n            None, otherwise defaults to \"context\". Valid values include:\n             - \"universal\"\n             - \"application\"\n             - \"context\"\n             - \"private\"\n            Deprecated in favor of explicit and implicit params.\n\n        :param tag:\n            The integer tag to override - usually this is used with tag_type or\n            class_. Deprecated in favor of explicit and implicit params.\n\n        :param optional:\n            Dummy parameter that allows \"optional\" key in spec param dicts\n\n        :param default:\n            The default value to use if the value is currently None\n\n        :param contents:\n            A byte string of the encoded contents of the value\n\n        :param method:\n            The method for the value - no default value since this is\n            normally set on a class. Valid values include:\n             - \"primitive\" or 0\n             - \"constructed\" or 1\n\n        :raises:\n            ValueError - when implicit, explicit, tag_type, class_ or tag are invalid values\n        \"\"\"\n\n        try:\n            if self.__class__ not in _SETUP_CLASSES:\n                cls = self.__class__\n                # Allow explicit to be specified as a simple 2-element tuple\n                # instead of requiring the user make a nested tuple\n                if cls.explicit is not None and isinstance(cls.explicit[0], int_types):\n                    cls.explicit = (cls.explicit, )\n                if hasattr(cls, '_setup'):\n                    self._setup()\n                _SETUP_CLASSES[cls] = True\n\n            # Normalize tagging values\n            if explicit is not None:\n                if isinstance(explicit, int_types):\n                    if class_ is None:\n                        class_ = 'context'\n                    explicit = (class_, explicit)\n                # Prevent both explicit and tag_type == 'explicit'\n                if tag_type == 'explicit':\n                    tag_type = None\n                    tag = None\n\n            if implicit is not None:\n                if isinstance(implicit, int_types):\n                    if class_ is None:\n                        class_ = 'context'\n                    implicit = (class_, implicit)\n                # Prevent both implicit and tag_type == 'implicit'\n                if tag_type == 'implicit':\n                    tag_type = None\n                    tag = None\n\n            # Convert old tag_type API to explicit/implicit params\n            if tag_type is not None:\n                if class_ is None:\n                    class_ = 'context'\n                if tag_type == 'explicit':\n                    explicit = (class_, tag)\n                elif tag_type == 'implicit':\n                    implicit = (class_, tag)\n                else:\n                    raise ValueError(unwrap(\n                        '''\n                        tag_type must be one of \"implicit\", \"explicit\", not %s\n                        ''',\n                        repr(tag_type)\n                    ))\n\n            if explicit is not None:\n                # Ensure we have a tuple of 2-element tuples\n                if len(explicit) == 2 and isinstance(explicit[1], int_types):\n                    explicit = (explicit, )\n                for class_, tag in explicit:\n                    invalid_class = None\n                    if isinstance(class_, int_types):\n                        if class_ not in CLASS_NUM_TO_NAME_MAP:\n                            invalid_class = class_\n                    else:\n                        if class_ not in CLASS_NAME_TO_NUM_MAP:\n                            invalid_class = class_\n                        class_ = CLASS_NAME_TO_NUM_MAP[class_]\n                    if invalid_class is not None:\n                        raise ValueError(unwrap(\n                            '''\n                            explicit class must be one of \"universal\", \"application\",\n                            \"context\", \"private\", not %s\n                            ''',\n                            repr(invalid_class)\n                        ))\n                    if tag is not None:\n                        if not isinstance(tag, int_types):\n                            raise TypeError(unwrap(\n                                '''\n                                explicit tag must be an integer, not %s\n                                ''',\n                                type_name(tag)\n                            ))\n                    if self.explicit is None:\n                        self.explicit = ((class_, tag), )\n                    else:\n                        self.explicit = self.explicit + ((class_, tag), )\n\n            elif implicit is not None:\n                class_, tag = implicit\n                if class_ not in CLASS_NAME_TO_NUM_MAP:\n                    raise ValueError(unwrap(\n                        '''\n                        implicit class must be one of \"universal\", \"application\",\n                        \"context\", \"private\", not %s\n                        ''',\n                        repr(class_)\n                    ))\n                if tag is not None:\n                    if not isinstance(tag, int_types):\n                        raise TypeError(unwrap(\n                            '''\n                            implicit tag must be an integer, not %s\n                            ''',\n                            type_name(tag)\n                        ))\n                self.class_ = CLASS_NAME_TO_NUM_MAP[class_]\n                self.tag = tag\n                self.implicit = True\n            else:\n                if class_ is not None:\n                    if class_ not in CLASS_NAME_TO_NUM_MAP:\n                        raise ValueError(unwrap(\n                            '''\n                            class_ must be one of \"universal\", \"application\",\n                            \"context\", \"private\", not %s\n                            ''',\n                            repr(class_)\n                        ))\n                    self.class_ = CLASS_NAME_TO_NUM_MAP[class_]\n\n                if self.class_ is None:\n                    self.class_ = 0\n\n                if tag is not None:\n                    self.tag = tag\n\n            if method is not None:\n                if method not in set([\"primitive\", 0, \"constructed\", 1]):\n                    raise ValueError(unwrap(\n                        '''\n                        method must be one of \"primitive\" or \"constructed\",\n                        not %s\n                        ''',\n                        repr(method)\n                    ))\n                if method == \"primitive\":\n                    method = 0\n                elif method == \"constructed\":\n                    method = 1\n                self.method = method\n\n            if no_explicit:\n                self.explicit = None\n\n            if contents is not None:\n                self.contents = contents\n\n            elif default is not None:\n                self.set(default)\n\n        except (ValueError, TypeError) as e:\n            args = e.args[1:]\n            e.args = (e.args[0] + '\\n    while constructing %s' % type_name(self),) + args\n            raise e\n\n    def __str__(self):\n        \"\"\"\n        Since str is different in Python 2 and 3, this calls the appropriate\n        method, __unicode__() or __bytes__()\n\n        :return:\n            A unicode string\n        \"\"\"\n\n        if _PY2:\n            return self.__bytes__()\n        else:\n            return self.__unicode__()\n\n    def __repr__(self):\n        \"\"\"\n        :return:\n            A unicode string\n        \"\"\"\n\n        if _PY2:\n            return '<%s %s b%s>' % (type_name(self), id(self), repr(self.dump()))\n        else:\n            return '<%s %s %s>' % (type_name(self), id(self), repr(self.dump()))\n\n    def __bytes__(self):\n        \"\"\"\n        A fall-back method for print() in Python 2\n\n        :return:\n            A byte string of the output of repr()\n        \"\"\"\n\n        return self.__repr__().encode('utf-8')\n\n    def __unicode__(self):\n        \"\"\"\n        A fall-back method for print() in Python 3\n\n        :return:\n            A unicode string of the output of repr()\n        \"\"\"\n\n        return self.__repr__()\n\n    def _new_instance(self):\n        \"\"\"\n        Constructs a new copy of the current object, preserving any tagging\n\n        :return:\n            An Asn1Value object\n        \"\"\"\n\n        new_obj = self.__class__()\n        new_obj.class_ = self.class_\n        new_obj.tag = self.tag\n        new_obj.implicit = self.implicit\n        new_obj.explicit = self.explicit\n        return new_obj\n\n    def __copy__(self):\n        \"\"\"\n        Implements the copy.copy() interface\n\n        :return:\n            A new shallow copy of the current Asn1Value object\n        \"\"\"\n\n        new_obj = self._new_instance()\n        new_obj._copy(self, copy.copy)\n        return new_obj\n\n    def __deepcopy__(self, memo):\n        \"\"\"\n        Implements the copy.deepcopy() interface\n\n        :param memo:\n            A dict for memoization\n\n        :return:\n            A new deep copy of the current Asn1Value object\n        \"\"\"\n\n        new_obj = self._new_instance()\n        memo[id(self)] = new_obj\n        new_obj._copy(self, copy.deepcopy)\n        return new_obj\n\n    def copy(self):\n        \"\"\"\n        Copies the object, preserving any special tagging from it\n\n        :return:\n            An Asn1Value object\n        \"\"\"\n\n        return copy.deepcopy(self)\n\n    def retag(self, tagging, tag=None):\n        \"\"\"\n        Copies the object, applying a new tagging to it\n\n        :param tagging:\n            A dict containing the keys \"explicit\" and \"implicit\". Legacy\n            API allows a unicode string of \"implicit\" or \"explicit\".\n\n        :param tag:\n            A integer tag number. Only used when tagging is a unicode string.\n\n        :return:\n            An Asn1Value object\n        \"\"\"\n\n        # This is required to preserve the old API\n        if not isinstance(tagging, dict):\n            tagging = {tagging: tag}\n        new_obj = self.__class__(explicit=tagging.get('explicit'), implicit=tagging.get('implicit'))\n        new_obj._copy(self, copy.deepcopy)\n        return new_obj\n\n    def untag(self):\n        \"\"\"\n        Copies the object, removing any special tagging from it\n\n        :return:\n            An Asn1Value object\n        \"\"\"\n\n        new_obj = self.__class__()\n        new_obj._copy(self, copy.deepcopy)\n        return new_obj\n\n    def _copy(self, other, copy_func):\n        \"\"\"\n        Copies the contents of another Asn1Value object to itself\n\n        :param object:\n            Another instance of the same class\n\n        :param copy_func:\n            An reference of copy.copy() or copy.deepcopy() to use when copying\n            lists, dicts and objects\n        \"\"\"\n\n        if self.__class__ != other.__class__:\n            raise TypeError(unwrap(\n                '''\n                Can not copy values from %s object to %s object\n                ''',\n                type_name(other),\n                type_name(self)\n            ))\n\n        self.contents = other.contents\n        self._native = copy_func(other._native)\n\n    def debug(self, nest_level=1):\n        \"\"\"\n        Show the binary data and parsed data in a tree structure\n        \"\"\"\n\n        prefix = '  ' * nest_level\n\n        # This interacts with Any and moves the tag, implicit, explicit, _header,\n        # contents, _footer to the parsed value so duplicate data isn't present\n        has_parsed = hasattr(self, 'parsed')\n\n        _basic_debug(prefix, self)\n        if has_parsed:\n            self.parsed.debug(nest_level + 2)\n        elif hasattr(self, 'chosen'):\n            self.chosen.debug(nest_level + 2)\n        else:\n            if _PY2 and isinstance(self.native, byte_cls):\n                print('%s    Native: b%s' % (prefix, repr(self.native)))\n            else:\n                print('%s    Native: %s' % (prefix, self.native))\n\n    def dump(self, force=False):\n        \"\"\"\n        Encodes the value using DER\n\n        :param force:\n            If the encoded contents already exist, clear them and regenerate\n            to ensure they are in DER format instead of BER format\n\n        :return:\n            A byte string of the DER-encoded value\n        \"\"\"\n\n        contents = self.contents\n\n        # If the length is indefinite, force the re-encoding\n        if self._header is not None and self._header[-1:] == b'\\x80':\n            force = True\n\n        if self._header is None or force:\n            if isinstance(self, Constructable) and self._indefinite:\n                self.method = 0\n\n            header = _dump_header(self.class_, self.method, self.tag, self.contents)\n\n            if self.explicit is not None:\n                for class_, tag in self.explicit:\n                    header = _dump_header(class_, 1, tag, header + self.contents) + header\n\n            self._header = header\n            self._trailer = b''\n\n        return self._header + contents + self._trailer\n\n\nclass ValueMap():\n    \"\"\"\n    Basic functionality that allows for mapping values from ints or OIDs to\n    python unicode strings\n    \"\"\"\n\n    # A dict from primitive value (int or OID) to unicode string. This needs\n    # to be defined in the source code\n    _map = None\n\n    # A dict from unicode string to int/OID. This is automatically generated\n    # from _map the first time it is needed\n    _reverse_map = None\n\n    def _setup(self):\n        \"\"\"\n        Generates _reverse_map from _map\n        \"\"\"\n\n        cls = self.__class__\n        if cls._map is None or cls._reverse_map is not None:\n            return\n        cls._reverse_map = {}\n        for key, value in cls._map.items():\n            cls._reverse_map[value] = key\n\n\nclass Castable(object):\n    \"\"\"\n    A mixin to handle converting an object between different classes that\n    represent the same encoded value, but with different rules for converting\n    to and from native Python values\n    \"\"\"\n\n    def cast(self, other_class):\n        \"\"\"\n        Converts the current object into an object of a different class. The\n        new class must use the ASN.1 encoding for the value.\n\n        :param other_class:\n            The class to instantiate the new object from\n\n        :return:\n            An instance of the type other_class\n        \"\"\"\n\n        if other_class.tag != self.__class__.tag:\n            raise TypeError(unwrap(\n                '''\n                Can not covert a value from %s object to %s object since they\n                use different tags: %d versus %d\n                ''',\n                type_name(other_class),\n                type_name(self),\n                other_class.tag,\n                self.__class__.tag\n            ))\n\n        new_obj = other_class()\n        new_obj.class_ = self.class_\n        new_obj.implicit = self.implicit\n        new_obj.explicit = self.explicit\n        new_obj._header = self._header\n        new_obj.contents = self.contents\n        new_obj._trailer = self._trailer\n        if isinstance(self, Constructable):\n            new_obj.method = self.method\n            new_obj._indefinite = self._indefinite\n        return new_obj\n\n\nclass Constructable(object):\n    \"\"\"\n    A mixin to handle string types that may be constructed from chunks\n    contained within an indefinite length BER-encoded container\n    \"\"\"\n\n    # Instance attribute indicating if an object was indefinite\n    # length when parsed - affects parsing and dumping\n    _indefinite = False\n\n    def _merge_chunks(self):\n        \"\"\"\n        :return:\n            A concatenation of the native values of the contained chunks\n        \"\"\"\n\n        if not self._indefinite:\n            return self._as_chunk()\n\n        pointer = 0\n        contents_len = len(self.contents)\n        output = None\n\n        while pointer < contents_len:\n            # We pass the current class as the spec so content semantics are preserved\n            sub_value, pointer = _parse_build(self.contents, pointer, spec=self.__class__)\n            if output is None:\n                output = sub_value._merge_chunks()\n            else:\n                output += sub_value._merge_chunks()\n\n        if output is None:\n            return self._as_chunk()\n\n        return output\n\n    def _as_chunk(self):\n        \"\"\"\n        A method to return a chunk of data that can be combined for\n        constructed method values\n\n        :return:\n            A native Python value that can be added together. Examples include\n            byte strings, unicode strings or tuples.\n        \"\"\"\n\n        return self.contents\n\n    def _setable_native(self):\n        \"\"\"\n        Returns a native value that can be round-tripped into .set(), to\n        result in a DER encoding. This differs from .native in that .native\n        is designed for the end use, and may account for the fact that the\n        merged value is further parsed as ASN.1, such as in the case of\n        ParsableOctetString() and ParsableOctetBitString().\n\n        :return:\n            A python value that is valid to pass to .set()\n        \"\"\"\n\n        return self.native\n\n    def _copy(self, other, copy_func):\n        \"\"\"\n        Copies the contents of another Constructable object to itself\n\n        :param object:\n            Another instance of the same class\n\n        :param copy_func:\n            An reference of copy.copy() or copy.deepcopy() to use when copying\n            lists, dicts and objects\n        \"\"\"\n\n        super(Constructable, self)._copy(other, copy_func)\n        # We really don't want to dump BER encodings, so if we see an\n        # indefinite encoding, let's re-encode it\n        if other._indefinite:\n            self.set(other._setable_native())\n\n\nclass Void(Asn1Value):\n    \"\"\"\n    A representation of an optional value that is not present. Has .native\n    property and .dump() method to be compatible with other value classes.\n    \"\"\"\n\n    contents = b''\n\n    def __eq__(self, other):\n        \"\"\"\n        :param other:\n            The other Primitive to compare to\n\n        :return:\n            A boolean\n        \"\"\"\n\n        return other.__class__ == self.__class__\n\n    def __nonzero__(self):\n        return False\n\n    def __len__(self):\n        return 0\n\n    def __iter__(self):\n        return iter(())\n\n    @property\n    def native(self):\n        \"\"\"\n        The native Python datatype representation of this value\n\n        :return:\n            None\n        \"\"\"\n\n        return None\n\n    def dump(self, force=False):\n        \"\"\"\n        Encodes the value using DER\n\n        :param force:\n            If the encoded contents already exist, clear them and regenerate\n            to ensure they are in DER format instead of BER format\n\n        :return:\n            A byte string of the DER-encoded value\n        \"\"\"\n\n        return b''\n\n\nVOID = Void()\n\n\nclass Any(Asn1Value):\n    \"\"\"\n    A value class that can contain any value, and allows for easy parsing of\n    the underlying encoded value using a spec. This is normally contained in\n    a Structure that has an ObjectIdentifier field and _oid_pair and _oid_specs\n    defined.\n    \"\"\"\n\n    # The parsed value object\n    _parsed = None\n\n    def __init__(self, value=None, **kwargs):\n        \"\"\"\n        Sets the value of the object before passing to Asn1Value.__init__()\n\n        :param value:\n            An Asn1Value object that will be set as the parsed value\n        \"\"\"\n\n        Asn1Value.__init__(self, **kwargs)\n\n        try:\n            if value is not None:\n                if not isinstance(value, Asn1Value):\n                    raise TypeError(unwrap(\n                        '''\n                        value must be an instance of Asn1Value, not %s\n                        ''',\n                        type_name(value)\n                    ))\n\n                self._parsed = (value, value.__class__, None)\n                self.contents = value.dump()\n\n        except (ValueError, TypeError) as e:\n            args = e.args[1:]\n            e.args = (e.args[0] + '\\n    while constructing %s' % type_name(self),) + args\n            raise e\n\n    @property\n    def native(self):\n        \"\"\"\n        The native Python datatype representation of this value\n\n        :return:\n            The .native value from the parsed value object\n        \"\"\"\n\n        if self._parsed is None:\n            self.parse()\n\n        return self._parsed[0].native\n\n    @property\n    def parsed(self):\n        \"\"\"\n        Returns the parsed object from .parse()\n\n        :return:\n            The object returned by .parse()\n        \"\"\"\n\n        if self._parsed is None:\n            self.parse()\n\n        return self._parsed[0]\n\n    def parse(self, spec=None, spec_params=None):\n        \"\"\"\n        Parses the contents generically, or using a spec with optional params\n\n        :param spec:\n            A class derived from Asn1Value that defines what class_ and tag the\n            value should have, and the semantics of the encoded value. The\n            return value will be of this type. If omitted, the encoded value\n            will be decoded using the standard universal tag based on the\n            encoded tag number.\n\n        :param spec_params:\n            A dict of params to pass to the spec object\n\n        :return:\n            An object of the type spec, or if not present, a child of Asn1Value\n        \"\"\"\n\n        if self._parsed is None or self._parsed[1:3] != (spec, spec_params):\n            try:\n                passed_params = spec_params or {}\n                _tag_type_to_explicit_implicit(passed_params)\n                if self.explicit is not None:\n                    if 'explicit' in passed_params:\n                        passed_params['explicit'] = self.explicit + passed_params['explicit']\n                    else:\n                        passed_params['explicit'] = self.explicit\n                contents = self._header + self.contents + self._trailer\n                parsed_value, _ = _parse_build(\n                    contents,\n                    spec=spec,\n                    spec_params=passed_params\n                )\n                self._parsed = (parsed_value, spec, spec_params)\n\n                # Once we've parsed the Any value, clear any attributes from this object\n                # since they are now duplicate\n                self.tag = None\n                self.explicit = None\n                self.implicit = False\n                self._header = b''\n                self.contents = contents\n                self._trailer = b''\n\n            except (ValueError, TypeError) as e:\n                args = e.args[1:]\n                e.args = (e.args[0] + '\\n    while parsing %s' % type_name(self),) + args\n                raise e\n        return self._parsed[0]\n\n    def _copy(self, other, copy_func):\n        \"\"\"\n        Copies the contents of another Any object to itself\n\n        :param object:\n            Another instance of the same class\n\n        :param copy_func:\n            An reference of copy.copy() or copy.deepcopy() to use when copying\n            lists, dicts and objects\n        \"\"\"\n\n        super(Any, self)._copy(other, copy_func)\n        self._parsed = copy_func(other._parsed)\n\n    def dump(self, force=False):\n        \"\"\"\n        Encodes the value using DER\n\n        :param force:\n            If the encoded contents already exist, clear them and regenerate\n            to ensure they are in DER format instead of BER format\n\n        :return:\n            A byte string of the DER-encoded value\n        \"\"\"\n\n        if self._parsed is None:\n            self.parse()\n\n        return self._parsed[0].dump(force=force)\n\n\nclass Choice(Asn1Value):\n    \"\"\"\n    A class to handle when a value may be one of several options\n    \"\"\"\n\n    # The index in _alternatives of the validated alternative\n    _choice = None\n\n    # The name of the chosen alternative\n    _name = None\n\n    # The Asn1Value object for the chosen alternative\n    _parsed = None\n\n    # Choice overrides .contents to be a property so that the code expecting\n    # the .contents attribute will get the .contents of the chosen alternative\n    _contents = None\n\n    # A list of tuples in one of the following forms.\n    #\n    # Option 1, a unicode string field name and a value class\n    #\n    # (\"name\", Asn1ValueClass)\n    #\n    # Option 2, same as Option 1, but with a dict of class params\n    #\n    # (\"name\", Asn1ValueClass, {'explicit': 5})\n    _alternatives = None\n\n    # A dict that maps tuples of (class_, tag) to an index in _alternatives\n    _id_map = None\n\n    # A dict that maps alternative names to an index in _alternatives\n    _name_map = None\n\n    @classmethod\n    def load(cls, encoded_data, strict=False, **kwargs):\n        \"\"\"\n        Loads a BER/DER-encoded byte string using the current class as the spec\n\n        :param encoded_data:\n            A byte string of BER or DER encoded data\n\n        :param strict:\n            A boolean indicating if trailing data should be forbidden - if so, a\n            ValueError will be raised when trailing data exists\n\n        :return:\n            A instance of the current class\n        \"\"\"\n\n        if not isinstance(encoded_data, byte_cls):\n            raise TypeError('encoded_data must be a byte string, not %s' % type_name(encoded_data))\n\n        value, _ = _parse_build(encoded_data, spec=cls, spec_params=kwargs, strict=strict)\n        return value\n\n    def _setup(self):\n        \"\"\"\n        Generates _id_map from _alternatives to allow validating contents\n        \"\"\"\n\n        cls = self.__class__\n        cls._id_map = {}\n        cls._name_map = {}\n        for index, info in enumerate(cls._alternatives):\n            if len(info) < 3:\n                info = info + ({},)\n                cls._alternatives[index] = info\n            id_ = _build_id_tuple(info[2], info[1])\n            cls._id_map[id_] = index\n            cls._name_map[info[0]] = index\n\n    def __init__(self, name=None, value=None, **kwargs):\n        \"\"\"\n        Checks to ensure implicit tagging is not being used since it is\n        incompatible with Choice, then forwards on to Asn1Value.__init__()\n\n        :param name:\n            The name of the alternative to be set - used with value.\n            Alternatively this may be a dict with a single key being the name\n            and the value being the value, or a two-element tuple of the name\n            and the value.\n\n        :param value:\n            The alternative value to set - used with name\n\n        :raises:\n            ValueError - when implicit param is passed (or legacy tag_type param is \"implicit\")\n        \"\"\"\n\n        _tag_type_to_explicit_implicit(kwargs)\n\n        Asn1Value.__init__(self, **kwargs)\n\n        try:\n            if kwargs.get('implicit') is not None:\n                raise ValueError(unwrap(\n                    '''\n                    The Choice type can not be implicitly tagged even if in an\n                    implicit module - due to its nature any tagging must be\n                    explicit\n                    '''\n                ))\n\n            if name is not None:\n                if isinstance(name, dict):\n                    if len(name) != 1:\n                        raise ValueError(unwrap(\n                            '''\n                            When passing a dict as the \"name\" argument to %s,\n                            it must have a single key/value - however %d were\n                            present\n                            ''',\n                            type_name(self),\n                            len(name)\n                        ))\n                    name, value = list(name.items())[0]\n\n                if isinstance(name, tuple):\n                    if len(name) != 2:\n                        raise ValueError(unwrap(\n                            '''\n                            When passing a tuple as the \"name\" argument to %s,\n                            it must have two elements, the name and value -\n                            however %d were present\n                            ''',\n                            type_name(self),\n                            len(name)\n                        ))\n                    value = name[1]\n                    name = name[0]\n\n                if name not in self._name_map:\n                    raise ValueError(unwrap(\n                        '''\n                        The name specified, \"%s\", is not a valid alternative\n                        for %s\n                        ''',\n                        name,\n                        type_name(self)\n                    ))\n\n                self._choice = self._name_map[name]\n                _, spec, params = self._alternatives[self._choice]\n\n                if not isinstance(value, spec):\n                    value = spec(value, **params)\n                else:\n                    value = _fix_tagging(value, params)\n                self._parsed = value\n\n        except (ValueError, TypeError) as e:\n            args = e.args[1:]\n            e.args = (e.args[0] + '\\n    while constructing %s' % type_name(self),) + args\n            raise e\n\n    @property\n    def contents(self):\n        \"\"\"\n        :return:\n            A byte string of the DER-encoded contents of the chosen alternative\n        \"\"\"\n\n        if self._parsed is not None:\n            return self._parsed.contents\n\n        return self._contents\n\n    @contents.setter\n    def contents(self, value):\n        \"\"\"\n        :param value:\n            A byte string of the DER-encoded contents of the chosen alternative\n        \"\"\"\n\n        self._contents = value\n\n    @property\n    def name(self):\n        \"\"\"\n        :return:\n            A unicode string of the field name of the chosen alternative\n        \"\"\"\n        if not self._name:\n            self._name = self._alternatives[self._choice][0]\n        return self._name\n\n    def parse(self):\n        \"\"\"\n        Parses the detected alternative\n\n        :return:\n            An Asn1Value object of the chosen alternative\n        \"\"\"\n\n        if self._parsed is None:\n            try:\n                _, spec, params = self._alternatives[self._choice]\n                self._parsed, _ = _parse_build(self._contents, spec=spec, spec_params=params)\n            except (ValueError, TypeError) as e:\n                args = e.args[1:]\n                e.args = (e.args[0] + '\\n    while parsing %s' % type_name(self),) + args\n                raise e\n        return self._parsed\n\n    @property\n    def chosen(self):\n        \"\"\"\n        :return:\n            An Asn1Value object of the chosen alternative\n        \"\"\"\n\n        return self.parse()\n\n    @property\n    def native(self):\n        \"\"\"\n        The native Python datatype representation of this value\n\n        :return:\n            The .native value from the contained value object\n        \"\"\"\n\n        return self.chosen.native\n\n    def validate(self, class_, tag, contents):\n        \"\"\"\n        Ensures that the class and tag specified exist as an alternative\n\n        :param class_:\n            The integer class_ from the encoded value header\n\n        :param tag:\n            The integer tag from the encoded value header\n\n        :param contents:\n            A byte string of the contents of the value - used when the object\n            is explicitly tagged\n\n        :raises:\n            ValueError - when value is not a valid alternative\n        \"\"\"\n\n        id_ = (class_, tag)\n\n        if self.explicit is not None:\n            if self.explicit[-1] != id_:\n                raise ValueError(unwrap(\n                    '''\n                    %s was explicitly tagged, but the value provided does not\n                    match the class and tag\n                    ''',\n                    type_name(self)\n                ))\n\n            ((class_, _, tag, _, _, _), _) = _parse(contents, len(contents))\n            id_ = (class_, tag)\n\n        if id_ in self._id_map:\n            self._choice = self._id_map[id_]\n            return\n\n        # This means the Choice was implicitly tagged\n        if self.class_ is not None and self.tag is not None:\n            if len(self._alternatives) > 1:\n                raise ValueError(unwrap(\n                    '''\n                    %s was implicitly tagged, but more than one alternative\n                    exists\n                    ''',\n                    type_name(self)\n                ))\n            if id_ == (self.class_, self.tag):\n                self._choice = 0\n                return\n\n        asn1 = self._format_class_tag(class_, tag)\n        asn1s = [self._format_class_tag(pair[0], pair[1]) for pair in self._id_map]\n\n        raise ValueError(unwrap(\n            '''\n            Value %s did not match the class and tag of any of the alternatives\n            in %s: %s\n            ''',\n            asn1,\n            type_name(self),\n            ', '.join(asn1s)\n        ))\n\n    def _format_class_tag(self, class_, tag):\n        \"\"\"\n        :return:\n            A unicode string of a human-friendly representation of the class and tag\n        \"\"\"\n\n        return '[%s %s]' % (CLASS_NUM_TO_NAME_MAP[class_].upper(), tag)\n\n    def _copy(self, other, copy_func):\n        \"\"\"\n        Copies the contents of another Choice object to itself\n\n        :param object:\n            Another instance of the same class\n\n        :param copy_func:\n            An reference of copy.copy() or copy.deepcopy() to use when copying\n            lists, dicts and objects\n        \"\"\"\n\n        super(Choice, self)._copy(other, copy_func)\n        self._choice = other._choice\n        self._name = other._name\n        self._parsed = copy_func(other._parsed)\n\n    def dump(self, force=False):\n        \"\"\"\n        Encodes the value using DER\n\n        :param force:\n            If the encoded contents already exist, clear them and regenerate\n            to ensure they are in DER format instead of BER format\n\n        :return:\n            A byte string of the DER-encoded value\n        \"\"\"\n\n        # If the length is indefinite, force the re-encoding\n        if self._header is not None and self._header[-1:] == b'\\x80':\n            force = True\n\n        self._contents = self.chosen.dump(force=force)\n        if self._header is None or force:\n            self._header = b''\n            if self.explicit is not None:\n                for class_, tag in self.explicit:\n                    self._header = _dump_header(class_, 1, tag, self._header + self._contents) + self._header\n        return self._header + self._contents\n\n\nclass Concat(object):\n    \"\"\"\n    A class that contains two or more encoded child values concatentated\n    together. THIS IS NOT PART OF THE ASN.1 SPECIFICATION! This exists to handle\n    the x509.TrustedCertificate() class for OpenSSL certificates containing\n    extra information.\n    \"\"\"\n\n    # A list of the specs of the concatenated values\n    _child_specs = None\n\n    _children = None\n\n    @classmethod\n    def load(cls, encoded_data, strict=False):\n        \"\"\"\n        Loads a BER/DER-encoded byte string using the current class as the spec\n\n        :param encoded_data:\n            A byte string of BER or DER encoded data\n\n        :param strict:\n            A boolean indicating if trailing data should be forbidden - if so, a\n            ValueError will be raised when trailing data exists\n\n        :return:\n            A Concat object\n        \"\"\"\n\n        return cls(contents=encoded_data, strict=strict)\n\n    def __init__(self, value=None, contents=None, strict=False):\n        \"\"\"\n        :param value:\n            A native Python datatype to initialize the object value with\n\n        :param contents:\n            A byte string of the encoded contents of the value\n\n        :param strict:\n            A boolean indicating if trailing data should be forbidden - if so, a\n            ValueError will be raised when trailing data exists in contents\n\n        :raises:\n            ValueError - when an error occurs with one of the children\n            TypeError - when an error occurs with one of the children\n        \"\"\"\n\n        if contents is not None:\n            try:\n                contents_len = len(contents)\n                self._children = []\n\n                offset = 0\n                for spec in self._child_specs:\n                    if offset < contents_len:\n                        child_value, offset = _parse_build(contents, pointer=offset, spec=spec)\n                    else:\n                        child_value = spec()\n                    self._children.append(child_value)\n\n                if strict and offset != contents_len:\n                    extra_bytes = contents_len - offset\n                    raise ValueError('Extra data - %d bytes of trailing data were provided' % extra_bytes)\n\n            except (ValueError, TypeError) as e:\n                args = e.args[1:]\n                e.args = (e.args[0] + '\\n    while constructing %s' % type_name(self),) + args\n                raise e\n\n        if value is not None:\n            if self._children is None:\n                self._children = [None] * len(self._child_specs)\n            for index, data in enumerate(value):\n                self.__setitem__(index, data)\n\n    def __str__(self):\n        \"\"\"\n        Since str is different in Python 2 and 3, this calls the appropriate\n        method, __unicode__() or __bytes__()\n\n        :return:\n            A unicode string\n        \"\"\"\n\n        if _PY2:\n            return self.__bytes__()\n        else:\n            return self.__unicode__()\n\n    def __bytes__(self):\n        \"\"\"\n        A byte string of the DER-encoded contents\n        \"\"\"\n\n        return self.dump()\n\n    def __unicode__(self):\n        \"\"\"\n        :return:\n            A unicode string\n        \"\"\"\n\n        return repr(self)\n\n    def __repr__(self):\n        \"\"\"\n        :return:\n            A unicode string\n        \"\"\"\n\n        return '<%s %s %s>' % (type_name(self), id(self), repr(self.dump()))\n\n    def __copy__(self):\n        \"\"\"\n        Implements the copy.copy() interface\n\n        :return:\n            A new shallow copy of the Concat object\n        \"\"\"\n\n        new_obj = self.__class__()\n        new_obj._copy(self, copy.copy)\n        return new_obj\n\n    def __deepcopy__(self, memo):\n        \"\"\"\n        Implements the copy.deepcopy() interface\n\n        :param memo:\n            A dict for memoization\n\n        :return:\n            A new deep copy of the Concat object and all child objects\n        \"\"\"\n\n        new_obj = self.__class__()\n        memo[id(self)] = new_obj\n        new_obj._copy(self, copy.deepcopy)\n        return new_obj\n\n    def copy(self):\n        \"\"\"\n        Copies the object\n\n        :return:\n            A Concat object\n        \"\"\"\n\n        return copy.deepcopy(self)\n\n    def _copy(self, other, copy_func):\n        \"\"\"\n        Copies the contents of another Concat object to itself\n\n        :param object:\n            Another instance of the same class\n\n        :param copy_func:\n            An reference of copy.copy() or copy.deepcopy() to use when copying\n            lists, dicts and objects\n        \"\"\"\n\n        if self.__class__ != other.__class__:\n            raise TypeError(unwrap(\n                '''\n                Can not copy values from %s object to %s object\n                ''',\n                type_name(other),\n                type_name(self)\n            ))\n\n        self._children = copy_func(other._children)\n\n    def debug(self, nest_level=1):\n        \"\"\"\n        Show the binary data and parsed data in a tree structure\n        \"\"\"\n\n        prefix = '  ' * nest_level\n        print('%s%s Object #%s' % (prefix, type_name(self), id(self)))\n        print('%s  Children:' % (prefix,))\n        for child in self._children:\n            child.debug(nest_level + 2)\n\n    def dump(self, force=False):\n        \"\"\"\n        Encodes the value using DER\n\n        :param force:\n            If the encoded contents already exist, clear them and regenerate\n            to ensure they are in DER format instead of BER format\n\n        :return:\n            A byte string of the DER-encoded value\n        \"\"\"\n\n        contents = b''\n        for child in self._children:\n            contents += child.dump(force=force)\n        return contents\n\n    @property\n    def contents(self):\n        \"\"\"\n        :return:\n            A byte string of the DER-encoded contents of the children\n        \"\"\"\n\n        return self.dump()\n\n    def __len__(self):\n        \"\"\"\n        :return:\n            Integer\n        \"\"\"\n\n        return len(self._children)\n\n    def __getitem__(self, key):\n        \"\"\"\n        Allows accessing children by index\n\n        :param key:\n            An integer of the child index\n\n        :raises:\n            KeyError - when an index is invalid\n\n        :return:\n            The Asn1Value object of the child specified\n        \"\"\"\n\n        if key > len(self._child_specs) - 1 or key < 0:\n            raise KeyError(unwrap(\n                '''\n                No child is definition for position %d of %s\n                ''',\n                key,\n                type_name(self)\n            ))\n\n        return self._children[key]\n\n    def __setitem__(self, key, value):\n        \"\"\"\n        Allows settings children by index\n\n        :param key:\n            An integer of the child index\n\n        :param value:\n            An Asn1Value object to set the child to\n\n        :raises:\n            KeyError - when an index is invalid\n            ValueError - when the value is not an instance of Asn1Value\n        \"\"\"\n\n        if key > len(self._child_specs) - 1 or key < 0:\n            raise KeyError(unwrap(\n                '''\n                No child is defined for position %d of %s\n                ''',\n                key,\n                type_name(self)\n            ))\n\n        if not isinstance(value, Asn1Value):\n            raise ValueError(unwrap(\n                '''\n                Value for child %s of %s is not an instance of\n                asn1crypto.core.Asn1Value\n                ''',\n                key,\n                type_name(self)\n            ))\n\n        self._children[key] = value\n\n    def __iter__(self):\n        \"\"\"\n        :return:\n            An iterator of child values\n        \"\"\"\n\n        return iter(self._children)\n\n\nclass Primitive(Asn1Value):\n    \"\"\"\n    Sets the class_ and method attributes for primitive, universal values\n    \"\"\"\n\n    class_ = 0\n\n    method = 0\n\n    def __init__(self, value=None, default=None, contents=None, **kwargs):\n        \"\"\"\n        Sets the value of the object before passing to Asn1Value.__init__()\n\n        :param value:\n            A native Python datatype to initialize the object value with\n\n        :param default:\n            The default value if no value is specified\n\n        :param contents:\n            A byte string of the encoded contents of the value\n        \"\"\"\n\n        Asn1Value.__init__(self, **kwargs)\n\n        try:\n            if contents is not None:\n                self.contents = contents\n\n            elif value is not None:\n                self.set(value)\n\n            elif default is not None:\n                self.set(default)\n\n        except (ValueError, TypeError) as e:\n            args = e.args[1:]\n            e.args = (e.args[0] + '\\n    while constructing %s' % type_name(self),) + args\n            raise e\n\n    def set(self, value):\n        \"\"\"\n        Sets the value of the object\n\n        :param value:\n            A byte string\n        \"\"\"\n\n        if not isinstance(value, byte_cls):\n            raise TypeError(unwrap(\n                '''\n                %s value must be a byte string, not %s\n                ''',\n                type_name(self),\n                type_name(value)\n            ))\n\n        self._native = value\n        self.contents = value\n        self._header = None\n        if self._trailer != b'':\n            self._trailer = b''\n\n    def dump(self, force=False):\n        \"\"\"\n        Encodes the value using DER\n\n        :param force:\n            If the encoded contents already exist, clear them and regenerate\n            to ensure they are in DER format instead of BER format\n\n        :return:\n            A byte string of the DER-encoded value\n        \"\"\"\n\n        # If the length is indefinite, force the re-encoding\n        if self._header is not None and self._header[-1:] == b'\\x80':\n            force = True\n\n        if force:\n            native = self.native\n            self.contents = None\n            self.set(native)\n\n        return Asn1Value.dump(self)\n\n    def __ne__(self, other):\n        return not self == other\n\n    def __eq__(self, other):\n        \"\"\"\n        :param other:\n            The other Primitive to compare to\n\n        :return:\n            A boolean\n        \"\"\"\n\n        if not isinstance(other, Primitive):\n            return False\n\n        if self.contents != other.contents:\n            return False\n\n        # We compare class tag numbers since object tag numbers could be\n        # different due to implicit or explicit tagging\n        if self.__class__.tag != other.__class__.tag:\n            return False\n\n        if self.__class__ == other.__class__ and self.contents == other.contents:\n            return True\n\n        # If the objects share a common base class that is not too low-level\n        # then we can compare the contents\n        self_bases = (set(self.__class__.__bases__) | set([self.__class__])) - set([Asn1Value, Primitive, ValueMap])\n        other_bases = (set(other.__class__.__bases__) | set([other.__class__])) - set([Asn1Value, Primitive, ValueMap])\n        if self_bases | other_bases:\n            return self.contents == other.contents\n\n        # When tagging is going on, do the extra work of constructing new\n        # objects to see if the dumped representation are the same\n        if self.implicit or self.explicit or other.implicit or other.explicit:\n            return self.untag().dump() == other.untag().dump()\n\n        return self.dump() == other.dump()\n\n\nclass AbstractString(Constructable, Primitive):\n    \"\"\"\n    A base class for all strings that have a known encoding. In general, we do\n    not worry ourselves with confirming that the decoded values match a specific\n    set of characters, only that they are decoded into a Python unicode string\n    \"\"\"\n\n    # The Python encoding name to use when decoding or encoded the contents\n    _encoding = 'latin1'\n\n    # Instance attribute of (possibly-merged) unicode string\n    _unicode = None\n\n    def set(self, value):\n        \"\"\"\n        Sets the value of the string\n\n        :param value:\n            A unicode string\n        \"\"\"\n\n        if not isinstance(value, str_cls):\n            raise TypeError(unwrap(\n                '''\n                %s value must be a unicode string, not %s\n                ''',\n                type_name(self),\n                type_name(value)\n            ))\n\n        self._unicode = value\n        self.contents = value.encode(self._encoding)\n        self._header = None\n        if self._indefinite:\n            self._indefinite = False\n            self.method = 0\n        if self._trailer != b'':\n            self._trailer = b''\n\n    def __unicode__(self):\n        \"\"\"\n        :return:\n            A unicode string\n        \"\"\"\n\n        if self.contents is None:\n            return ''\n        if self._unicode is None:\n            self._unicode = self._merge_chunks().decode(self._encoding)\n        return self._unicode\n\n    def _copy(self, other, copy_func):\n        \"\"\"\n        Copies the contents of another AbstractString object to itself\n\n        :param object:\n            Another instance of the same class\n\n        :param copy_func:\n            An reference of copy.copy() or copy.deepcopy() to use when copying\n            lists, dicts and objects\n        \"\"\"\n\n        super(AbstractString, self)._copy(other, copy_func)\n        self._unicode = other._unicode\n\n    @property\n    def native(self):\n        \"\"\"\n        The native Python datatype representation of this value\n\n        :return:\n            A unicode string or None\n        \"\"\"\n\n        if self.contents is None:\n            return None\n\n        return self.__unicode__()\n\n\nclass Boolean(Primitive):\n    \"\"\"\n    Represents a boolean in both ASN.1 and Python\n    \"\"\"\n\n    tag = 1\n\n    def set(self, value):\n        \"\"\"\n        Sets the value of the object\n\n        :param value:\n            True, False or another value that works with bool()\n        \"\"\"\n\n        self._native = bool(value)\n        self.contents = b'\\x00' if not value else b'\\xff'\n        self._header = None\n        if self._trailer != b'':\n            self._trailer = b''\n\n    # Python 2\n    def __nonzero__(self):\n        \"\"\"\n        :return:\n            True or False\n        \"\"\"\n        return self.__bool__()\n\n    def __bool__(self):\n        \"\"\"\n        :return:\n            True or False\n        \"\"\"\n        return self.contents != b'\\x00'\n\n    @property\n    def native(self):\n        \"\"\"\n        The native Python datatype representation of this value\n\n        :return:\n            True, False or None\n        \"\"\"\n\n        if self.contents is None:\n            return None\n\n        if self._native is None:\n            self._native = self.__bool__()\n        return self._native\n\n\nclass Integer(Primitive, ValueMap):\n    \"\"\"\n    Represents an integer in both ASN.1 and Python\n    \"\"\"\n\n    tag = 2\n\n    def set(self, value):\n        \"\"\"\n        Sets the value of the object\n\n        :param value:\n            An integer, or a unicode string if _map is set\n\n        :raises:\n            ValueError - when an invalid value is passed\n        \"\"\"\n\n        if isinstance(value, str_cls):\n            if self._map is None:\n                raise ValueError(unwrap(\n                    '''\n                    %s value is a unicode string, but no _map provided\n                    ''',\n                    type_name(self)\n                ))\n\n            if value not in self._reverse_map:\n                raise ValueError(unwrap(\n                    '''\n                    %s value, %s, is not present in the _map\n                    ''',\n                    type_name(self),\n                    value\n                ))\n\n            value = self._reverse_map[value]\n\n        elif not isinstance(value, int_types):\n            raise TypeError(unwrap(\n                '''\n                %s value must be an integer or unicode string when a name_map\n                is provided, not %s\n                ''',\n                type_name(self),\n                type_name(value)\n            ))\n\n        self._native = self._map[value] if self._map and value in self._map else value\n\n        self.contents = int_to_bytes(value, signed=True)\n        self._header = None\n        if self._trailer != b'':\n            self._trailer = b''\n\n    def __int__(self):\n        \"\"\"\n        :return:\n            An integer\n        \"\"\"\n        return int_from_bytes(self.contents, signed=True)\n\n    @property\n    def native(self):\n        \"\"\"\n        The native Python datatype representation of this value\n\n        :return:\n            An integer or None\n        \"\"\"\n\n        if self.contents is None:\n            return None\n\n        if self._native is None:\n            self._native = self.__int__()\n            if self._map is not None and self._native in self._map:\n                self._native = self._map[self._native]\n        return self._native\n\n\nclass _IntegerBitString(object):\n    \"\"\"\n    A mixin for IntegerBitString and BitString to parse the contents as an integer.\n    \"\"\"\n\n    # Tuple of 1s and 0s; set through native\n    _unused_bits = ()\n\n    def _as_chunk(self):\n        \"\"\"\n        Parse the contents of a primitive BitString encoding as an integer value.\n        Allows reconstructing indefinite length values.\n\n        :raises:\n            ValueError - when an invalid value is passed\n\n        :return:\n            A list with one tuple (value, bits, unused_bits) where value is an integer\n            with the value of the BitString, bits is the bit count of value and\n            unused_bits is a tuple of 1s and 0s.\n        \"\"\"\n\n        if self._indefinite:\n            # return an empty chunk, for cases like \\x23\\x80\\x00\\x00\n            return []\n\n        unused_bits_len = ord(self.contents[0]) if _PY2 else self.contents[0]\n        value = int_from_bytes(self.contents[1:])\n        bits = (len(self.contents) - 1) * 8\n\n        if not unused_bits_len:\n            return [(value, bits, ())]\n\n        if len(self.contents) == 1:\n            # Disallowed by X.690 §8.6.2.3\n            raise ValueError('Empty bit string has {0} unused bits'.format(unused_bits_len))\n\n        if unused_bits_len > 7:\n            # Disallowed by X.690 §8.6.2.2\n            raise ValueError('Bit string has {0} unused bits'.format(unused_bits_len))\n\n        unused_bits = _int_to_bit_tuple(value & ((1 << unused_bits_len) - 1), unused_bits_len)\n        value >>= unused_bits_len\n        bits -= unused_bits_len\n\n        return [(value, bits, unused_bits)]\n\n    def _chunks_to_int(self):\n        \"\"\"\n        Combines the chunks into a single value.\n\n        :raises:\n            ValueError - when an invalid value is passed\n\n        :return:\n            A tuple (value, bits, unused_bits) where value is an integer with the\n            value of the BitString, bits is the bit count of value and unused_bits\n            is a tuple of 1s and 0s.\n        \"\"\"\n\n        if not self._indefinite:\n            # Fast path\n            return self._as_chunk()[0]\n\n        value = 0\n        total_bits = 0\n        unused_bits = ()\n\n        # X.690 §8.6.3 allows empty indefinite encodings\n        for chunk, bits, unused_bits in self._merge_chunks():\n            if total_bits & 7:\n                # Disallowed by X.690 §8.6.4\n                raise ValueError('Only last chunk in a bit string may have unused bits')\n            total_bits += bits\n            value = (value << bits) | chunk\n\n        return value, total_bits, unused_bits\n\n    def _copy(self, other, copy_func):\n        \"\"\"\n        Copies the contents of another _IntegerBitString object to itself\n\n        :param object:\n            Another instance of the same class\n\n        :param copy_func:\n            An reference of copy.copy() or copy.deepcopy() to use when copying\n            lists, dicts and objects\n        \"\"\"\n\n        super(_IntegerBitString, self)._copy(other, copy_func)\n        self._unused_bits = other._unused_bits\n\n    @property\n    def unused_bits(self):\n        \"\"\"\n        The unused bits of the bit string encoding.\n\n        :return:\n            A tuple of 1s and 0s\n        \"\"\"\n\n        # call native to set _unused_bits\n        self.native\n\n        return self._unused_bits\n\n\nclass BitString(_IntegerBitString, Constructable, Castable, Primitive, ValueMap):\n    \"\"\"\n    Represents a bit string from ASN.1 as a Python tuple of 1s and 0s\n    \"\"\"\n\n    tag = 3\n\n    _size = None\n\n    def _setup(self):\n        \"\"\"\n        Generates _reverse_map from _map\n        \"\"\"\n\n        ValueMap._setup(self)\n\n        cls = self.__class__\n        if cls._map is not None:\n            cls._size = max(self._map.keys()) + 1\n\n    def set(self, value):\n        \"\"\"\n        Sets the value of the object\n\n        :param value:\n            An integer or a tuple of integers 0 and 1\n\n        :raises:\n            ValueError - when an invalid value is passed\n        \"\"\"\n\n        if isinstance(value, set):\n            if self._map is None:\n                raise ValueError(unwrap(\n                    '''\n                    %s._map has not been defined\n                    ''',\n                    type_name(self)\n                ))\n\n            bits = [0] * self._size\n            self._native = value\n            for index in range(0, self._size):\n                key = self._map.get(index)\n                if key is None:\n                    continue\n                if key in value:\n                    bits[index] = 1\n\n            value = ''.join(map(str_cls, bits))\n\n        elif value.__class__ == tuple:\n            if self._map is None:\n                self._native = value\n            else:\n                self._native = set()\n                for index, bit in enumerate(value):\n                    if bit:\n                        name = self._map.get(index, index)\n                        self._native.add(name)\n            value = ''.join(map(str_cls, value))\n\n        else:\n            raise TypeError(unwrap(\n                '''\n                %s value must be a tuple of ones and zeros or a set of unicode\n                strings, not %s\n                ''',\n                type_name(self),\n                type_name(value)\n            ))\n\n        if self._map is not None:\n            if len(value) > self._size:\n                raise ValueError(unwrap(\n                    '''\n                    %s value must be at most %s bits long, specified was %s long\n                    ''',\n                    type_name(self),\n                    self._size,\n                    len(value)\n                ))\n            # A NamedBitList must have trailing zero bit truncated. See\n            # https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf\n            # section 11.2,\n            # https://tools.ietf.org/html/rfc5280#page-134 and\n            # https://www.ietf.org/mail-archive/web/pkix/current/msg10443.html\n            value = value.rstrip('0')\n        size = len(value)\n\n        size_mod = size % 8\n        extra_bits = 0\n        if size_mod != 0:\n            extra_bits = 8 - size_mod\n            value += '0' * extra_bits\n\n        size_in_bytes = int(math.ceil(size / 8))\n\n        if extra_bits:\n            extra_bits_byte = int_to_bytes(extra_bits)\n        else:\n            extra_bits_byte = b'\\x00'\n\n        if value == '':\n            value_bytes = b''\n        else:\n            value_bytes = int_to_bytes(int(value, 2))\n        if len(value_bytes) != size_in_bytes:\n            value_bytes = (b'\\x00' * (size_in_bytes - len(value_bytes))) + value_bytes\n\n        self.contents = extra_bits_byte + value_bytes\n        self._unused_bits = (0,) * extra_bits\n        self._header = None\n        if self._indefinite:\n            self._indefinite = False\n            self.method = 0\n        if self._trailer != b'':\n            self._trailer = b''\n\n    def __getitem__(self, key):\n        \"\"\"\n        Retrieves a boolean version of one of the bits based on a name from the\n        _map\n\n        :param key:\n            The unicode string of one of the bit names\n\n        :raises:\n            ValueError - when _map is not set or the key name is invalid\n\n        :return:\n            A boolean if the bit is set\n        \"\"\"\n\n        is_int = isinstance(key, int_types)\n        if not is_int:\n            if not isinstance(self._map, dict):\n                raise ValueError(unwrap(\n                    '''\n                    %s._map has not been defined\n                    ''',\n                    type_name(self)\n                ))\n\n            if key not in self._reverse_map:\n                raise ValueError(unwrap(\n                    '''\n                    %s._map does not contain an entry for \"%s\"\n                    ''',\n                    type_name(self),\n                    key\n                ))\n\n        if self._native is None:\n            self.native\n\n        if self._map is None:\n            if len(self._native) >= key + 1:\n                return bool(self._native[key])\n            return False\n\n        if is_int:\n            key = self._map.get(key, key)\n\n        return key in self._native\n\n    def __setitem__(self, key, value):\n        \"\"\"\n        Sets one of the bits based on a name from the _map\n\n        :param key:\n            The unicode string of one of the bit names\n\n        :param value:\n            A boolean value\n\n        :raises:\n            ValueError - when _map is not set or the key name is invalid\n        \"\"\"\n\n        is_int = isinstance(key, int_types)\n        if not is_int:\n            if self._map is None:\n                raise ValueError(unwrap(\n                    '''\n                    %s._map has not been defined\n                    ''',\n                    type_name(self)\n                ))\n\n            if key not in self._reverse_map:\n                raise ValueError(unwrap(\n                    '''\n                    %s._map does not contain an entry for \"%s\"\n                    ''',\n                    type_name(self),\n                    key\n                ))\n\n        if self._native is None:\n            self.native\n\n        if self._map is None:\n            new_native = list(self._native)\n            max_key = len(new_native) - 1\n            if key > max_key:\n                new_native.extend([0] * (key - max_key))\n            new_native[key] = 1 if value else 0\n            self._native = tuple(new_native)\n\n        else:\n            if is_int:\n                key = self._map.get(key, key)\n\n            if value:\n                if key not in self._native:\n                    self._native.add(key)\n            else:\n                if key in self._native:\n                    self._native.remove(key)\n\n        self.set(self._native)\n\n    @property\n    def native(self):\n        \"\"\"\n        The native Python datatype representation of this value\n\n        :return:\n            If a _map is set, a set of names, or if no _map is set, a tuple of\n            integers 1 and 0. None if no value.\n        \"\"\"\n\n        # For BitString we default the value to be all zeros\n        if self.contents is None:\n            if self._map is None:\n                self.set(())\n            else:\n                self.set(set())\n\n        if self._native is None:\n            int_value, bit_count, self._unused_bits = self._chunks_to_int()\n            bits = _int_to_bit_tuple(int_value, bit_count)\n\n            if self._map:\n                self._native = set()\n                for index, bit in enumerate(bits):\n                    if bit:\n                        name = self._map.get(index, index)\n                        self._native.add(name)\n            else:\n                self._native = bits\n        return self._native\n\n\nclass OctetBitString(Constructable, Castable, Primitive):\n    \"\"\"\n    Represents a bit string in ASN.1 as a Python byte string\n    \"\"\"\n\n    tag = 3\n\n    # Instance attribute of (possibly-merged) byte string\n    _bytes = None\n\n    # Tuple of 1s and 0s; set through native\n    _unused_bits = ()\n\n    def set(self, value):\n        \"\"\"\n        Sets the value of the object\n\n        :param value:\n            A byte string\n\n        :raises:\n            ValueError - when an invalid value is passed\n        \"\"\"\n\n        if not isinstance(value, byte_cls):\n            raise TypeError(unwrap(\n                '''\n                %s value must be a byte string, not %s\n                ''',\n                type_name(self),\n                type_name(value)\n            ))\n\n        self._bytes = value\n        # Set the unused bits to 0\n        self.contents = b'\\x00' + value\n        self._unused_bits = ()\n        self._header = None\n        if self._indefinite:\n            self._indefinite = False\n            self.method = 0\n        if self._trailer != b'':\n            self._trailer = b''\n\n    def __bytes__(self):\n        \"\"\"\n        :return:\n            A byte string\n        \"\"\"\n\n        if self.contents is None:\n            return b''\n        if self._bytes is None:\n            if not self._indefinite:\n                self._bytes, self._unused_bits = self._as_chunk()[0]\n            else:\n                chunks = self._merge_chunks()\n                self._unused_bits = ()\n                for chunk in chunks:\n                    if self._unused_bits:\n                        # Disallowed by X.690 §8.6.4\n                        raise ValueError('Only last chunk in a bit string may have unused bits')\n                    self._unused_bits = chunk[1]\n                self._bytes = b''.join(chunk[0] for chunk in chunks)\n\n        return self._bytes\n\n    def _copy(self, other, copy_func):\n        \"\"\"\n        Copies the contents of another OctetBitString object to itself\n\n        :param object:\n            Another instance of the same class\n\n        :param copy_func:\n            An reference of copy.copy() or copy.deepcopy() to use when copying\n            lists, dicts and objects\n        \"\"\"\n\n        super(OctetBitString, self)._copy(other, copy_func)\n        self._bytes = other._bytes\n        self._unused_bits = other._unused_bits\n\n    def _as_chunk(self):\n        \"\"\"\n        Allows reconstructing indefinite length values\n\n        :raises:\n            ValueError - when an invalid value is passed\n\n        :return:\n            List with one tuple, consisting of a byte string and an integer (unused bits)\n        \"\"\"\n\n        unused_bits_len = ord(self.contents[0]) if _PY2 else self.contents[0]\n        if not unused_bits_len:\n            return [(self.contents[1:], ())]\n\n        if len(self.contents) == 1:\n            # Disallowed by X.690 §8.6.2.3\n            raise ValueError('Empty bit string has {0} unused bits'.format(unused_bits_len))\n\n        if unused_bits_len > 7:\n            # Disallowed by X.690 §8.6.2.2\n            raise ValueError('Bit string has {0} unused bits'.format(unused_bits_len))\n\n        mask = (1 << unused_bits_len) - 1\n        last_byte = ord(self.contents[-1]) if _PY2 else self.contents[-1]\n\n        # zero out the unused bits in the last byte.\n        zeroed_byte = last_byte & ~mask\n        value = self.contents[1:-1] + (chr(zeroed_byte) if _PY2 else bytes((zeroed_byte,)))\n\n        unused_bits = _int_to_bit_tuple(last_byte & mask, unused_bits_len)\n\n        return [(value, unused_bits)]\n\n    @property\n    def native(self):\n        \"\"\"\n        The native Python datatype representation of this value\n\n        :return:\n            A byte string or None\n        \"\"\"\n\n        if self.contents is None:\n            return None\n\n        return self.__bytes__()\n\n    @property\n    def unused_bits(self):\n        \"\"\"\n        The unused bits of the bit string encoding.\n\n        :return:\n            A tuple of 1s and 0s\n        \"\"\"\n\n        # call native to set _unused_bits\n        self.native\n\n        return self._unused_bits\n\n\nclass IntegerBitString(_IntegerBitString, Constructable, Castable, Primitive):\n    \"\"\"\n    Represents a bit string in ASN.1 as a Python integer\n    \"\"\"\n\n    tag = 3\n\n    def set(self, value):\n        \"\"\"\n        Sets the value of the object\n\n        :param value:\n            An integer\n\n        :raises:\n            ValueError - when an invalid value is passed\n        \"\"\"\n\n        if not isinstance(value, int_types):\n            raise TypeError(unwrap(\n                '''\n                %s value must be a positive integer, not %s\n                ''',\n                type_name(self),\n                type_name(value)\n            ))\n\n        if value < 0:\n            raise ValueError(unwrap(\n                '''\n                %s value must be a positive integer, not %d\n                ''',\n                type_name(self),\n                value\n            ))\n\n        self._native = value\n        # Set the unused bits to 0\n        self.contents = b'\\x00' + int_to_bytes(value, signed=True)\n        self._unused_bits = ()\n        self._header = None\n        if self._indefinite:\n            self._indefinite = False\n            self.method = 0\n        if self._trailer != b'':\n            self._trailer = b''\n\n    @property\n    def native(self):\n        \"\"\"\n        The native Python datatype representation of this value\n\n        :return:\n            An integer or None\n        \"\"\"\n\n        if self.contents is None:\n            return None\n\n        if self._native is None:\n            self._native, __, self._unused_bits = self._chunks_to_int()\n\n        return self._native\n\n\nclass OctetString(Constructable, Castable, Primitive):\n    \"\"\"\n    Represents a byte string in both ASN.1 and Python\n    \"\"\"\n\n    tag = 4\n\n    # Instance attribute of (possibly-merged) byte string\n    _bytes = None\n\n    def set(self, value):\n        \"\"\"\n        Sets the value of the object\n\n        :param value:\n            A byte string\n        \"\"\"\n\n        if not isinstance(value, byte_cls):\n            raise TypeError(unwrap(\n                '''\n                %s value must be a byte string, not %s\n                ''',\n                type_name(self),\n                type_name(value)\n            ))\n\n        self._bytes = value\n        self.contents = value\n        self._header = None\n        if self._indefinite:\n            self._indefinite = False\n            self.method = 0\n        if self._trailer != b'':\n            self._trailer = b''\n\n    def __bytes__(self):\n        \"\"\"\n        :return:\n            A byte string\n        \"\"\"\n\n        if self.contents is None:\n            return b''\n        if self._bytes is None:\n            self._bytes = self._merge_chunks()\n        return self._bytes\n\n    def _copy(self, other, copy_func):\n        \"\"\"\n        Copies the contents of another OctetString object to itself\n\n        :param object:\n            Another instance of the same class\n\n        :param copy_func:\n            An reference of copy.copy() or copy.deepcopy() to use when copying\n            lists, dicts and objects\n        \"\"\"\n\n        super(OctetString, self)._copy(other, copy_func)\n        self._bytes = other._bytes\n\n    @property\n    def native(self):\n        \"\"\"\n        The native Python datatype representation of this value\n\n        :return:\n            A byte string or None\n        \"\"\"\n\n        if self.contents is None:\n            return None\n\n        return self.__bytes__()\n\n\nclass IntegerOctetString(Constructable, Castable, Primitive):\n    \"\"\"\n    Represents a byte string in ASN.1 as a Python integer\n    \"\"\"\n\n    tag = 4\n\n    # An explicit length in bytes the integer should be encoded to. This should\n    # generally not be used since DER defines a canonical encoding, however some\n    # use of this, such as when storing elliptic curve private keys, requires an\n    # exact number of bytes, even if the leading bytes are null.\n    _encoded_width = None\n\n    def set(self, value):\n        \"\"\"\n        Sets the value of the object\n\n        :param value:\n            An integer\n\n        :raises:\n            ValueError - when an invalid value is passed\n        \"\"\"\n\n        if not isinstance(value, int_types):\n            raise TypeError(unwrap(\n                '''\n                %s value must be a positive integer, not %s\n                ''',\n                type_name(self),\n                type_name(value)\n            ))\n\n        if value < 0:\n            raise ValueError(unwrap(\n                '''\n                %s value must be a positive integer, not %d\n                ''',\n                type_name(self),\n                value\n            ))\n\n        self._native = value\n        self.contents = int_to_bytes(value, signed=False, width=self._encoded_width)\n        self._header = None\n        if self._indefinite:\n            self._indefinite = False\n            self.method = 0\n        if self._trailer != b'':\n            self._trailer = b''\n\n    @property\n    def native(self):\n        \"\"\"\n        The native Python datatype representation of this value\n\n        :return:\n            An integer or None\n        \"\"\"\n\n        if self.contents is None:\n            return None\n\n        if self._native is None:\n            self._native = int_from_bytes(self._merge_chunks())\n        return self._native\n\n    def set_encoded_width(self, width):\n        \"\"\"\n        Set the explicit enoding width for the integer\n\n        :param width:\n            An integer byte width to encode the integer to\n        \"\"\"\n\n        self._encoded_width = width\n        # Make sure the encoded value is up-to-date with the proper width\n        if self.contents is not None and len(self.contents) != width:\n            self.set(self.native)\n\n\nclass ParsableOctetString(Constructable, Castable, Primitive):\n\n    tag = 4\n\n    _parsed = None\n\n    # Instance attribute of (possibly-merged) byte string\n    _bytes = None\n\n    def __init__(self, value=None, parsed=None, **kwargs):\n        \"\"\"\n        Allows providing a parsed object that will be serialized to get the\n        byte string value\n\n        :param value:\n            A native Python datatype to initialize the object value with\n\n        :param parsed:\n            If value is None and this is an Asn1Value object, this will be\n            set as the parsed value, and the value will be obtained by calling\n            .dump() on this object.\n        \"\"\"\n\n        set_parsed = False\n        if value is None and parsed is not None and isinstance(parsed, Asn1Value):\n            value = parsed.dump()\n            set_parsed = True\n\n        Primitive.__init__(self, value=value, **kwargs)\n\n        if set_parsed:\n            self._parsed = (parsed, parsed.__class__, None)\n\n    def set(self, value):\n        \"\"\"\n        Sets the value of the object\n\n        :param value:\n            A byte string\n        \"\"\"\n\n        if not isinstance(value, byte_cls):\n            raise TypeError(unwrap(\n                '''\n                %s value must be a byte string, not %s\n                ''',\n                type_name(self),\n                type_name(value)\n            ))\n\n        self._bytes = value\n        self.contents = value\n        self._header = None\n        if self._indefinite:\n            self._indefinite = False\n            self.method = 0\n        if self._trailer != b'':\n            self._trailer = b''\n\n    def parse(self, spec=None, spec_params=None):\n        \"\"\"\n        Parses the contents generically, or using a spec with optional params\n\n        :param spec:\n            A class derived from Asn1Value that defines what class_ and tag the\n            value should have, and the semantics of the encoded value. The\n            return value will be of this type. If omitted, the encoded value\n            will be decoded using the standard universal tag based on the\n            encoded tag number.\n\n        :param spec_params:\n            A dict of params to pass to the spec object\n\n        :return:\n            An object of the type spec, or if not present, a child of Asn1Value\n        \"\"\"\n\n        if self._parsed is None or self._parsed[1:3] != (spec, spec_params):\n            parsed_value, _ = _parse_build(self.__bytes__(), spec=spec, spec_params=spec_params)\n            self._parsed = (parsed_value, spec, spec_params)\n        return self._parsed[0]\n\n    def __bytes__(self):\n        \"\"\"\n        :return:\n            A byte string\n        \"\"\"\n\n        if self.contents is None:\n            return b''\n        if self._bytes is None:\n            self._bytes = self._merge_chunks()\n        return self._bytes\n\n    def _setable_native(self):\n        \"\"\"\n        Returns a byte string that can be passed into .set()\n\n        :return:\n            A python value that is valid to pass to .set()\n        \"\"\"\n\n        return self.__bytes__()\n\n    def _copy(self, other, copy_func):\n        \"\"\"\n        Copies the contents of another ParsableOctetString object to itself\n\n        :param object:\n            Another instance of the same class\n\n        :param copy_func:\n            An reference of copy.copy() or copy.deepcopy() to use when copying\n            lists, dicts and objects\n        \"\"\"\n\n        super(ParsableOctetString, self)._copy(other, copy_func)\n        self._bytes = other._bytes\n        self._parsed = copy_func(other._parsed)\n\n    @property\n    def native(self):\n        \"\"\"\n        The native Python datatype representation of this value\n\n        :return:\n            A byte string or None\n        \"\"\"\n\n        if self.contents is None:\n            return None\n\n        if self._parsed is not None:\n            return self._parsed[0].native\n        else:\n            return self.__bytes__()\n\n    @property\n    def parsed(self):\n        \"\"\"\n        Returns the parsed object from .parse()\n\n        :return:\n            The object returned by .parse()\n        \"\"\"\n\n        if self._parsed is None:\n            self.parse()\n\n        return self._parsed[0]\n\n    def dump(self, force=False):\n        \"\"\"\n        Encodes the value using DER\n\n        :param force:\n            If the encoded contents already exist, clear them and regenerate\n            to ensure they are in DER format instead of BER format\n\n        :return:\n            A byte string of the DER-encoded value\n        \"\"\"\n\n        # If the length is indefinite, force the re-encoding\n        if self._indefinite:\n            force = True\n\n        if force:\n            if self._parsed is not None:\n                native = self.parsed.dump(force=force)\n            else:\n                native = self.native\n            self.contents = None\n            self.set(native)\n\n        return Asn1Value.dump(self)\n\n\nclass ParsableOctetBitString(ParsableOctetString):\n\n    tag = 3\n\n    def set(self, value):\n        \"\"\"\n        Sets the value of the object\n\n        :param value:\n            A byte string\n\n        :raises:\n            ValueError - when an invalid value is passed\n        \"\"\"\n\n        if not isinstance(value, byte_cls):\n            raise TypeError(unwrap(\n                '''\n                %s value must be a byte string, not %s\n                ''',\n                type_name(self),\n                type_name(value)\n            ))\n\n        self._bytes = value\n        # Set the unused bits to 0\n        self.contents = b'\\x00' + value\n        self._header = None\n        if self._indefinite:\n            self._indefinite = False\n            self.method = 0\n        if self._trailer != b'':\n            self._trailer = b''\n\n    def _as_chunk(self):\n        \"\"\"\n        Allows reconstructing indefinite length values\n\n        :raises:\n            ValueError - when an invalid value is passed\n\n        :return:\n            A byte string\n        \"\"\"\n\n        unused_bits_len = ord(self.contents[0]) if _PY2 else self.contents[0]\n        if unused_bits_len:\n            raise ValueError('ParsableOctetBitString should have no unused bits')\n\n        return self.contents[1:]\n\n\nclass Null(Primitive):\n    \"\"\"\n    Represents a null value in ASN.1 as None in Python\n    \"\"\"\n\n    tag = 5\n\n    contents = b''\n\n    def set(self, value):\n        \"\"\"\n        Sets the value of the object\n\n        :param value:\n            None\n        \"\"\"\n\n        self.contents = b''\n\n    @property\n    def native(self):\n        \"\"\"\n        The native Python datatype representation of this value\n\n        :return:\n            None\n        \"\"\"\n\n        return None\n\n\nclass ObjectIdentifier(Primitive, ValueMap):\n    \"\"\"\n    Represents an object identifier in ASN.1 as a Python unicode dotted\n    integer string\n    \"\"\"\n\n    tag = 6\n\n    # A unicode string of the dotted form of the object identifier\n    _dotted = None\n\n    @classmethod\n    def map(cls, value):\n        \"\"\"\n        Converts a dotted unicode string OID into a mapped unicode string\n\n        :param value:\n            A dotted unicode string OID\n\n        :raises:\n            ValueError - when no _map dict has been defined on the class\n            TypeError - when value is not a unicode string\n\n        :return:\n            A mapped unicode string\n        \"\"\"\n\n        if cls._map is None:\n            raise ValueError(unwrap(\n                '''\n                %s._map has not been defined\n                ''',\n                type_name(cls)\n            ))\n\n        if not isinstance(value, str_cls):\n            raise TypeError(unwrap(\n                '''\n                value must be a unicode string, not %s\n                ''',\n                type_name(value)\n            ))\n\n        return cls._map.get(value, value)\n\n    @classmethod\n    def unmap(cls, value):\n        \"\"\"\n        Converts a mapped unicode string value into a dotted unicode string OID\n\n        :param value:\n            A mapped unicode string OR dotted unicode string OID\n\n        :raises:\n            ValueError - when no _map dict has been defined on the class or the value can't be unmapped\n            TypeError - when value is not a unicode string\n\n        :return:\n            A dotted unicode string OID\n        \"\"\"\n\n        if cls not in _SETUP_CLASSES:\n            cls()._setup()\n            _SETUP_CLASSES[cls] = True\n\n        if cls._map is None:\n            raise ValueError(unwrap(\n                '''\n                %s._map has not been defined\n                ''',\n                type_name(cls)\n            ))\n\n        if not isinstance(value, str_cls):\n            raise TypeError(unwrap(\n                '''\n                value must be a unicode string, not %s\n                ''',\n                type_name(value)\n            ))\n\n        if value in cls._reverse_map:\n            return cls._reverse_map[value]\n\n        if not _OID_RE.match(value):\n            raise ValueError(unwrap(\n                '''\n                %s._map does not contain an entry for \"%s\"\n                ''',\n                type_name(cls),\n                value\n            ))\n\n        return value\n\n    def set(self, value):\n        \"\"\"\n        Sets the value of the object\n\n        :param value:\n            A unicode string. May be a dotted integer string, or if _map is\n            provided, one of the mapped values.\n\n        :raises:\n            ValueError - when an invalid value is passed\n        \"\"\"\n\n        if not isinstance(value, str_cls):\n            raise TypeError(unwrap(\n                '''\n                %s value must be a unicode string, not %s\n                ''',\n                type_name(self),\n                type_name(value)\n            ))\n\n        self._native = value\n\n        if self._map is not None:\n            if value in self._reverse_map:\n                value = self._reverse_map[value]\n\n        self.contents = b''\n        first = None\n        for index, part in enumerate(value.split('.')):\n            part = int(part)\n\n            # The first two parts are merged into a single byte\n            if index == 0:\n                first = part\n                continue\n            elif index == 1:\n                if first > 2:\n                    raise ValueError(unwrap(\n                        '''\n                        First arc must be one of 0, 1 or 2, not %s\n                        ''',\n                        repr(first)\n                    ))\n                elif first < 2 and part >= 40:\n                    raise ValueError(unwrap(\n                        '''\n                        Second arc must be less than 40 if first arc is 0 or\n                        1, not %s\n                        ''',\n                        repr(part)\n                    ))\n                part = (first * 40) + part\n\n            encoded_part = chr_cls(0x7F & part)\n            part = part >> 7\n            while part > 0:\n                encoded_part = chr_cls(0x80 | (0x7F & part)) + encoded_part\n                part = part >> 7\n            self.contents += encoded_part\n\n        self._header = None\n        if self._trailer != b'':\n            self._trailer = b''\n\n    def __unicode__(self):\n        \"\"\"\n        :return:\n            A unicode string\n        \"\"\"\n\n        return self.dotted\n\n    @property\n    def dotted(self):\n        \"\"\"\n        :return:\n            A unicode string of the object identifier in dotted notation, thus\n            ignoring any mapped value\n        \"\"\"\n\n        if self._dotted is None:\n            output = []\n\n            part = 0\n            for byte in self.contents:\n                if _PY2:\n                    byte = ord(byte)\n                part = part * 128\n                part += byte & 127\n                # Last byte in subidentifier has the eighth bit set to 0\n                if byte & 0x80 == 0:\n                    if len(output) == 0:\n                        if part >= 80:\n                            output.append(str_cls(2))\n                            output.append(str_cls(part - 80))\n                        elif part >= 40:\n                            output.append(str_cls(1))\n                            output.append(str_cls(part - 40))\n                        else:\n                            output.append(str_cls(0))\n                            output.append(str_cls(part))\n                    else:\n                        output.append(str_cls(part))\n                    part = 0\n\n            self._dotted = '.'.join(output)\n        return self._dotted\n\n    @property\n    def native(self):\n        \"\"\"\n        The native Python datatype representation of this value\n\n        :return:\n            A unicode string or None. If _map is not defined, the unicode string\n            is a string of dotted integers. If _map is defined and the dotted\n            string is present in the _map, the mapped value is returned.\n        \"\"\"\n\n        if self.contents is None:\n            return None\n\n        if self._native is None:\n            self._native = self.dotted\n        if self._map is not None and self._native in self._map:\n            self._native = self._map[self._native]\n        return self._native\n\n\nclass ObjectDescriptor(Primitive):\n    \"\"\"\n    Represents an object descriptor from ASN.1 - no Python implementation\n    \"\"\"\n\n    tag = 7\n\n\nclass InstanceOf(Primitive):\n    \"\"\"\n    Represents an instance from ASN.1 - no Python implementation\n    \"\"\"\n\n    tag = 8\n\n\nclass Real(Primitive):\n    \"\"\"\n    Represents a real number from ASN.1 - no Python implementation\n    \"\"\"\n\n    tag = 9\n\n\nclass Enumerated(Integer):\n    \"\"\"\n    Represents a enumerated list of integers from ASN.1 as a Python\n    unicode string\n    \"\"\"\n\n    tag = 10\n\n    def set(self, value):\n        \"\"\"\n        Sets the value of the object\n\n        :param value:\n            An integer or a unicode string from _map\n\n        :raises:\n            ValueError - when an invalid value is passed\n        \"\"\"\n\n        if not isinstance(value, int_types) and not isinstance(value, str_cls):\n            raise TypeError(unwrap(\n                '''\n                %s value must be an integer or a unicode string, not %s\n                ''',\n                type_name(self),\n                type_name(value)\n            ))\n\n        if isinstance(value, str_cls):\n            if value not in self._reverse_map:\n                raise ValueError(unwrap(\n                    '''\n                    %s value \"%s\" is not a valid value\n                    ''',\n                    type_name(self),\n                    value\n                ))\n\n            value = self._reverse_map[value]\n\n        elif value not in self._map:\n            raise ValueError(unwrap(\n                '''\n                %s value %s is not a valid value\n                ''',\n                type_name(self),\n                value\n            ))\n\n        Integer.set(self, value)\n\n    @property\n    def native(self):\n        \"\"\"\n        The native Python datatype representation of this value\n\n        :return:\n            A unicode string or None\n        \"\"\"\n\n        if self.contents is None:\n            return None\n\n        if self._native is None:\n            self._native = self._map[self.__int__()]\n        return self._native\n\n\nclass UTF8String(AbstractString):\n    \"\"\"\n    Represents a UTF-8 string from ASN.1 as a Python unicode string\n    \"\"\"\n\n    tag = 12\n    _encoding = 'utf-8'\n\n\nclass RelativeOid(ObjectIdentifier):\n    \"\"\"\n    Represents an object identifier in ASN.1 as a Python unicode dotted\n    integer string\n    \"\"\"\n\n    tag = 13\n\n\nclass Sequence(Asn1Value):\n    \"\"\"\n    Represents a sequence of fields from ASN.1 as a Python object with a\n    dict-like interface\n    \"\"\"\n\n    tag = 16\n\n    class_ = 0\n    method = 1\n\n    # A list of child objects, in order of _fields\n    children = None\n\n    # Sequence overrides .contents to be a property so that the mutated state\n    # of child objects can be checked to ensure everything is up-to-date\n    _contents = None\n\n    # Variable to track if the object has been mutated\n    _mutated = False\n\n    # A list of tuples in one of the following forms.\n    #\n    # Option 1, a unicode string field name and a value class\n    #\n    # (\"name\", Asn1ValueClass)\n    #\n    # Option 2, same as Option 1, but with a dict of class params\n    #\n    # (\"name\", Asn1ValueClass, {'explicit': 5})\n    _fields = []\n\n    # A dict with keys being the name of a field and the value being a unicode\n    # string of the method name on self to call to get the spec for that field\n    _spec_callbacks = None\n\n    # A dict that maps unicode string field names to an index in _fields\n    _field_map = None\n\n    # A list in the same order as _fields that has tuples in the form (class_, tag)\n    _field_ids = None\n\n    # An optional 2-element tuple that defines the field names of an OID field\n    # and the field that the OID should be used to help decode. Works with the\n    # _oid_specs attribute.\n    _oid_pair = None\n\n    # A dict with keys that are unicode string OID values and values that are\n    # Asn1Value classes to use for decoding a variable-type field.\n    _oid_specs = None\n\n    # A 2-element tuple of the indexes in _fields of the OID and value fields\n    _oid_nums = None\n\n    # Predetermined field specs to optimize away calls to _determine_spec()\n    _precomputed_specs = None\n\n    def __init__(self, value=None, default=None, **kwargs):\n        \"\"\"\n        Allows setting field values before passing everything else along to\n        Asn1Value.__init__()\n\n        :param value:\n            A native Python datatype to initialize the object value with\n\n        :param default:\n            The default value if no value is specified\n        \"\"\"\n\n        Asn1Value.__init__(self, **kwargs)\n\n        check_existing = False\n        if value is None and default is not None:\n            check_existing = True\n            if self.children is None:\n                if self.contents is None:\n                    check_existing = False\n                else:\n                    self._parse_children()\n            value = default\n\n        if value is not None:\n            try:\n                # Fields are iterated in definition order to allow things like\n                # OID-based specs. Otherwise sometimes the value would be processed\n                # before the OID field, resulting in invalid value object creation.\n                if self._fields:\n                    keys = [info[0] for info in self._fields]\n                    unused_keys = set(value.keys())\n                else:\n                    keys = value.keys()\n                    unused_keys = set(keys)\n\n                for key in keys:\n                    # If we are setting defaults, but a real value has already\n                    # been set for the field, then skip it\n                    if check_existing:\n                        index = self._field_map[key]\n                        if index < len(self.children) and self.children[index] is not VOID:\n                            if key in unused_keys:\n                                unused_keys.remove(key)\n                            continue\n\n                    if key in value:\n                        self.__setitem__(key, value[key])\n                        unused_keys.remove(key)\n\n                if len(unused_keys):\n                    raise ValueError(unwrap(\n                        '''\n                        One or more unknown fields was passed to the constructor\n                        of %s: %s\n                        ''',\n                        type_name(self),\n                        ', '.join(sorted(list(unused_keys)))\n                    ))\n\n            except (ValueError, TypeError) as e:\n                args = e.args[1:]\n                e.args = (e.args[0] + '\\n    while constructing %s' % type_name(self),) + args\n                raise e\n\n    @property\n    def contents(self):\n        \"\"\"\n        :return:\n            A byte string of the DER-encoded contents of the sequence\n        \"\"\"\n\n        if self.children is None:\n            return self._contents\n\n        if self._is_mutated():\n            self._set_contents()\n\n        return self._contents\n\n    @contents.setter\n    def contents(self, value):\n        \"\"\"\n        :param value:\n            A byte string of the DER-encoded contents of the sequence\n        \"\"\"\n\n        self._contents = value\n\n    def _is_mutated(self):\n        \"\"\"\n        :return:\n            A boolean - if the sequence or any children (recursively) have been\n            mutated\n        \"\"\"\n\n        mutated = self._mutated\n        if self.children is not None:\n            for child in self.children:\n                if isinstance(child, Sequence) or isinstance(child, SequenceOf):\n                    mutated = mutated or child._is_mutated()\n\n        return mutated\n\n    def _lazy_child(self, index):\n        \"\"\"\n        Builds a child object if the child has only been parsed into a tuple so far\n        \"\"\"\n\n        child = self.children[index]\n        if child.__class__ == tuple:\n            child = self.children[index] = _build(*child)\n        return child\n\n    def __len__(self):\n        \"\"\"\n        :return:\n            Integer\n        \"\"\"\n        # We inline this check to prevent method invocation each time\n        if self.children is None:\n            self._parse_children()\n\n        return len(self.children)\n\n    def __getitem__(self, key):\n        \"\"\"\n        Allows accessing fields by name or index\n\n        :param key:\n            A unicode string of the field name, or an integer of the field index\n\n        :raises:\n            KeyError - when a field name or index is invalid\n\n        :return:\n            The Asn1Value object of the field specified\n        \"\"\"\n\n        # We inline this check to prevent method invocation each time\n        if self.children is None:\n            self._parse_children()\n\n        if not isinstance(key, int_types):\n            if key not in self._field_map:\n                raise KeyError(unwrap(\n                    '''\n                    No field named \"%s\" defined for %s\n                    ''',\n                    key,\n                    type_name(self)\n                ))\n            key = self._field_map[key]\n\n        if key >= len(self.children):\n            raise KeyError(unwrap(\n                '''\n                No field numbered %s is present in this %s\n                ''',\n                key,\n                type_name(self)\n            ))\n\n        try:\n            return self._lazy_child(key)\n\n        except (ValueError, TypeError) as e:\n            args = e.args[1:]\n            e.args = (e.args[0] + '\\n    while parsing %s' % type_name(self),) + args\n            raise e\n\n    def __setitem__(self, key, value):\n        \"\"\"\n        Allows settings fields by name or index\n\n        :param key:\n            A unicode string of the field name, or an integer of the field index\n\n        :param value:\n            A native Python datatype to set the field value to. This method will\n            construct the appropriate Asn1Value object from _fields.\n\n        :raises:\n            ValueError - when a field name or index is invalid\n        \"\"\"\n\n        # We inline this check to prevent method invocation each time\n        if self.children is None:\n            self._parse_children()\n\n        if not isinstance(key, int_types):\n            if key not in self._field_map:\n                raise KeyError(unwrap(\n                    '''\n                    No field named \"%s\" defined for %s\n                    ''',\n                    key,\n                    type_name(self)\n                ))\n            key = self._field_map[key]\n\n        field_name, field_spec, value_spec, field_params, _ = self._determine_spec(key)\n\n        new_value = self._make_value(field_name, field_spec, value_spec, field_params, value)\n\n        invalid_value = False\n        if isinstance(new_value, Any):\n            invalid_value = new_value.parsed is None\n        else:\n            invalid_value = new_value.contents is None\n\n        if invalid_value:\n            raise ValueError(unwrap(\n                '''\n                Value for field \"%s\" of %s is not set\n                ''',\n                field_name,\n                type_name(self)\n            ))\n\n        self.children[key] = new_value\n\n        if self._native is not None:\n            self._native[self._fields[key][0]] = self.children[key].native\n        self._mutated = True\n\n    def __delitem__(self, key):\n        \"\"\"\n        Allows deleting optional or default fields by name or index\n\n        :param key:\n            A unicode string of the field name, or an integer of the field index\n\n        :raises:\n            ValueError - when a field name or index is invalid, or the field is not optional or defaulted\n        \"\"\"\n\n        # We inline this check to prevent method invocation each time\n        if self.children is None:\n            self._parse_children()\n\n        if not isinstance(key, int_types):\n            if key not in self._field_map:\n                raise KeyError(unwrap(\n                    '''\n                    No field named \"%s\" defined for %s\n                    ''',\n                    key,\n                    type_name(self)\n                ))\n            key = self._field_map[key]\n\n        name, _, params = self._fields[key]\n        if not params or ('default' not in params and 'optional' not in params):\n            raise ValueError(unwrap(\n                '''\n                Can not delete the value for the field \"%s\" of %s since it is\n                not optional or defaulted\n                ''',\n                name,\n                type_name(self)\n            ))\n\n        if 'optional' in params:\n            self.children[key] = VOID\n            if self._native is not None:\n                self._native[name] = None\n        else:\n            self.__setitem__(key, None)\n        self._mutated = True\n\n    def __iter__(self):\n        \"\"\"\n        :return:\n            An iterator of field key names\n        \"\"\"\n\n        for info in self._fields:\n            yield info[0]\n\n    def _set_contents(self, force=False):\n        \"\"\"\n        Updates the .contents attribute of the value with the encoded value of\n        all of the child objects\n\n        :param force:\n            Ensure all contents are in DER format instead of possibly using\n            cached BER-encoded data\n        \"\"\"\n\n        if self.children is None:\n            self._parse_children()\n\n        contents = BytesIO()\n        for index, info in enumerate(self._fields):\n            child = self.children[index]\n            if child is None:\n                child_dump = b''\n            elif child.__class__ == tuple:\n                if force:\n                    child_dump = self._lazy_child(index).dump(force=force)\n                else:\n                    child_dump = child[3] + child[4] + child[5]\n            else:\n                child_dump = child.dump(force=force)\n            # Skip values that are the same as the default\n            if info[2] and 'default' in info[2]:\n                default_value = info[1](**info[2])\n                if default_value.dump() == child_dump:\n                    continue\n            contents.write(child_dump)\n        self._contents = contents.getvalue()\n\n        self._header = None\n        if self._trailer != b'':\n            self._trailer = b''\n\n    def _setup(self):\n        \"\"\"\n        Generates _field_map, _field_ids and _oid_nums for use in parsing\n        \"\"\"\n\n        cls = self.__class__\n        cls._field_map = {}\n        cls._field_ids = []\n        cls._precomputed_specs = []\n        for index, field in enumerate(cls._fields):\n            if len(field) < 3:\n                field = field + ({},)\n                cls._fields[index] = field\n            cls._field_map[field[0]] = index\n            cls._field_ids.append(_build_id_tuple(field[2], field[1]))\n\n        if cls._oid_pair is not None:\n            cls._oid_nums = (cls._field_map[cls._oid_pair[0]], cls._field_map[cls._oid_pair[1]])\n\n        for index, field in enumerate(cls._fields):\n            has_callback = cls._spec_callbacks is not None and field[0] in cls._spec_callbacks\n            is_mapped_oid = cls._oid_nums is not None and cls._oid_nums[1] == index\n            if has_callback or is_mapped_oid:\n                cls._precomputed_specs.append(None)\n            else:\n                cls._precomputed_specs.append((field[0], field[1], field[1], field[2], None))\n\n    def _determine_spec(self, index):\n        \"\"\"\n        Determine how a value for a field should be constructed\n\n        :param index:\n            The field number\n\n        :return:\n            A tuple containing the following elements:\n             - unicode string of the field name\n             - Asn1Value class of the field spec\n             - Asn1Value class of the value spec\n             - None or dict of params to pass to the field spec\n             - None or Asn1Value class indicating the value spec was derived from an OID or a spec callback\n        \"\"\"\n\n        name, field_spec, field_params = self._fields[index]\n        value_spec = field_spec\n        spec_override = None\n\n        if self._spec_callbacks is not None and name in self._spec_callbacks:\n            callback = self._spec_callbacks[name]\n            spec_override = callback(self)\n            if spec_override:\n                # Allow a spec callback to specify both the base spec and\n                # the override, for situations such as OctetString and parse_as\n                if spec_override.__class__ == tuple and len(spec_override) == 2:\n                    field_spec, value_spec = spec_override\n                    if value_spec is None:\n                        value_spec = field_spec\n                        spec_override = None\n                # When no field spec is specified, use a single return value as that\n                elif field_spec is None:\n                    field_spec = spec_override\n                    value_spec = field_spec\n                    spec_override = None\n                else:\n                    value_spec = spec_override\n\n        elif self._oid_nums is not None and self._oid_nums[1] == index:\n            oid = self._lazy_child(self._oid_nums[0]).native\n            if oid in self._oid_specs:\n                spec_override = self._oid_specs[oid]\n                value_spec = spec_override\n\n        return (name, field_spec, value_spec, field_params, spec_override)\n\n    def _make_value(self, field_name, field_spec, value_spec, field_params, value):\n        \"\"\"\n        Contructs an appropriate Asn1Value object for a field\n\n        :param field_name:\n            A unicode string of the field name\n\n        :param field_spec:\n            An Asn1Value class that is the field spec\n\n        :param value_spec:\n            An Asn1Value class that is the vaue spec\n\n        :param field_params:\n            None or a dict of params for the field spec\n\n        :param value:\n            The value to construct an Asn1Value object from\n\n        :return:\n            An instance of a child class of Asn1Value\n        \"\"\"\n\n        if value is None and 'optional' in field_params:\n            return VOID\n\n        specs_different = field_spec != value_spec\n        is_any = issubclass(field_spec, Any)\n\n        if issubclass(value_spec, Choice):\n            is_asn1value = isinstance(value, Asn1Value)\n            is_tuple = isinstance(value, tuple) and len(value) == 2\n            is_dict = isinstance(value, dict) and len(value) == 1\n            if not is_asn1value and not is_tuple and not is_dict:\n                raise ValueError(unwrap(\n                    '''\n                    Can not set a native python value to %s, which has the\n                    choice type of %s - value must be an instance of Asn1Value\n                    ''',\n                    field_name,\n                    type_name(value_spec)\n                ))\n            if is_tuple or is_dict:\n                value = value_spec(value)\n            if not isinstance(value, value_spec):\n                wrapper = value_spec()\n                wrapper.validate(value.class_, value.tag, value.contents)\n                wrapper._parsed = value\n                new_value = wrapper\n            else:\n                new_value = value\n\n        elif isinstance(value, field_spec):\n            new_value = value\n            if specs_different:\n                new_value.parse(value_spec)\n\n        elif (not specs_different or is_any) and not isinstance(value, value_spec):\n            if (not is_any or specs_different) and isinstance(value, Asn1Value):\n                raise TypeError(unwrap(\n                    '''\n                    %s value must be %s, not %s\n                    ''',\n                    field_name,\n                    type_name(value_spec),\n                    type_name(value)\n                ))\n            new_value = value_spec(value, **field_params)\n\n        else:\n            if isinstance(value, value_spec):\n                new_value = value\n            else:\n                if isinstance(value, Asn1Value):\n                    raise TypeError(unwrap(\n                        '''\n                        %s value must be %s, not %s\n                        ''',\n                        field_name,\n                        type_name(value_spec),\n                        type_name(value)\n                    ))\n                new_value = value_spec(value)\n\n            # For when the field is OctetString or OctetBitString with embedded\n            # values we need to wrap the value in the field spec to get the\n            # appropriate encoded value.\n            if specs_different and not is_any:\n                wrapper = field_spec(value=new_value.dump(), **field_params)\n                wrapper._parsed = (new_value, new_value.__class__, None)\n                new_value = wrapper\n\n        new_value = _fix_tagging(new_value, field_params)\n\n        return new_value\n\n    def _parse_children(self, recurse=False):\n        \"\"\"\n        Parses the contents and generates Asn1Value objects based on the\n        definitions from _fields.\n\n        :param recurse:\n            If child objects that are Sequence or SequenceOf objects should\n            be recursively parsed\n\n        :raises:\n            ValueError - when an error occurs parsing child objects\n        \"\"\"\n\n        cls = self.__class__\n        if self._contents is None:\n            if self._fields:\n                self.children = [VOID] * len(self._fields)\n                for index, (_, _, params) in enumerate(self._fields):\n                    if 'default' in params:\n                        if cls._precomputed_specs[index]:\n                            field_name, field_spec, value_spec, field_params, _ = cls._precomputed_specs[index]\n                        else:\n                            field_name, field_spec, value_spec, field_params, _ = self._determine_spec(index)\n                        self.children[index] = self._make_value(field_name, field_spec, value_spec, field_params, None)\n            return\n\n        try:\n            self.children = []\n            contents_length = len(self._contents)\n            child_pointer = 0\n            field = 0\n            field_len = len(self._fields)\n            parts = None\n            again = child_pointer < contents_length\n            while again:\n                if parts is None:\n                    parts, child_pointer = _parse(self._contents, contents_length, pointer=child_pointer)\n                again = child_pointer < contents_length\n\n                if field < field_len:\n                    _, field_spec, value_spec, field_params, spec_override = (\n                        cls._precomputed_specs[field] or self._determine_spec(field))\n\n                    # If the next value is optional or default, allow it to be absent\n                    if field_params and ('optional' in field_params or 'default' in field_params):\n                        if self._field_ids[field] != (parts[0], parts[2]) and field_spec != Any:\n\n                            # See if the value is a valid choice before assuming\n                            # that we have a missing optional or default value\n                            choice_match = False\n                            if issubclass(field_spec, Choice):\n                                try:\n                                    tester = field_spec(**field_params)\n                                    tester.validate(parts[0], parts[2], parts[4])\n                                    choice_match = True\n                                except (ValueError):\n                                    pass\n\n                            if not choice_match:\n                                if 'optional' in field_params:\n                                    self.children.append(VOID)\n                                else:\n                                    self.children.append(field_spec(**field_params))\n                                field += 1\n                                again = True\n                                continue\n\n                    if field_spec is None or (spec_override and issubclass(field_spec, Any)):\n                        field_spec = value_spec\n                        spec_override = None\n\n                    if spec_override:\n                        child = parts + (field_spec, field_params, value_spec)\n                    else:\n                        child = parts + (field_spec, field_params)\n\n                # Handle situations where an optional or defaulted field definition is incorrect\n                elif field_len > 0 and field + 1 <= field_len:\n                    missed_fields = []\n                    prev_field = field - 1\n                    while prev_field >= 0:\n                        prev_field_info = self._fields[prev_field]\n                        if len(prev_field_info) < 3:\n                            break\n                        if 'optional' in prev_field_info[2] or 'default' in prev_field_info[2]:\n                            missed_fields.append(prev_field_info[0])\n                        prev_field -= 1\n                    plural = 's' if len(missed_fields) > 1 else ''\n                    missed_field_names = ', '.join(missed_fields)\n                    raise ValueError(unwrap(\n                        '''\n                        Data for field %s (%s class, %s method, tag %s) does\n                        not match the field definition%s of %s\n                        ''',\n                        field + 1,\n                        CLASS_NUM_TO_NAME_MAP.get(parts[0]),\n                        METHOD_NUM_TO_NAME_MAP.get(parts[1]),\n                        parts[2],\n                        plural,\n                        missed_field_names\n                    ))\n\n                else:\n                    child = parts\n\n                if recurse:\n                    child = _build(*child)\n                    if isinstance(child, (Sequence, SequenceOf)):\n                        child._parse_children(recurse=True)\n\n                self.children.append(child)\n                field += 1\n                parts = None\n\n            index = len(self.children)\n            while index < field_len:\n                name, field_spec, field_params = self._fields[index]\n                if 'default' in field_params:\n                    self.children.append(field_spec(**field_params))\n                elif 'optional' in field_params:\n                    self.children.append(VOID)\n                else:\n                    raise ValueError(unwrap(\n                        '''\n                        Field \"%s\" is missing from structure\n                        ''',\n                        name\n                    ))\n                index += 1\n\n        except (ValueError, TypeError) as e:\n            self.children = None\n            args = e.args[1:]\n            e.args = (e.args[0] + '\\n    while parsing %s' % type_name(self),) + args\n            raise e\n\n    def spec(self, field_name):\n        \"\"\"\n        Determines the spec to use for the field specified. Depending on how\n        the spec is determined (_oid_pair or _spec_callbacks), it may be\n        necessary to set preceding field values before calling this. Usually\n        specs, if dynamic, are controlled by a preceding ObjectIdentifier\n        field.\n\n        :param field_name:\n            A unicode string of the field name to get the spec for\n\n        :return:\n            A child class of asn1crypto.core.Asn1Value that the field must be\n            encoded using\n        \"\"\"\n\n        if not isinstance(field_name, str_cls):\n            raise TypeError(unwrap(\n                '''\n                field_name must be a unicode string, not %s\n                ''',\n                type_name(field_name)\n            ))\n\n        if self._fields is None:\n            raise ValueError(unwrap(\n                '''\n                Unable to retrieve spec for field %s in the class %s because\n                _fields has not been set\n                ''',\n                repr(field_name),\n                type_name(self)\n            ))\n\n        index = self._field_map[field_name]\n        info = self._determine_spec(index)\n\n        return info[2]\n\n    @property\n    def native(self):\n        \"\"\"\n        The native Python datatype representation of this value\n\n        :return:\n            An OrderedDict or None. If an OrderedDict, all child values are\n            recursively converted to native representation also.\n        \"\"\"\n\n        if self.contents is None:\n            return None\n\n        if self._native is None:\n            if self.children is None:\n                self._parse_children(recurse=True)\n            try:\n                self._native = OrderedDict()\n                for index, child in enumerate(self.children):\n                    if child.__class__ == tuple:\n                        child = _build(*child)\n                        self.children[index] = child\n                    try:\n                        name = self._fields[index][0]\n                    except (IndexError):\n                        name = str_cls(index)\n                    self._native[name] = child.native\n            except (ValueError, TypeError) as e:\n                self._native = None\n                args = e.args[1:]\n                e.args = (e.args[0] + '\\n    while parsing %s' % type_name(self),) + args\n                raise e\n        return self._native\n\n    def _copy(self, other, copy_func):\n        \"\"\"\n        Copies the contents of another Sequence object to itself\n\n        :param object:\n            Another instance of the same class\n\n        :param copy_func:\n            An reference of copy.copy() or copy.deepcopy() to use when copying\n            lists, dicts and objects\n        \"\"\"\n\n        super(Sequence, self)._copy(other, copy_func)\n        if self.children is not None:\n            self.children = []\n            for child in other.children:\n                if child.__class__ == tuple:\n                    self.children.append(child)\n                else:\n                    self.children.append(child.copy())\n\n    def debug(self, nest_level=1):\n        \"\"\"\n        Show the binary data and parsed data in a tree structure\n        \"\"\"\n\n        if self.children is None:\n            self._parse_children()\n\n        prefix = '  ' * nest_level\n        _basic_debug(prefix, self)\n        for field_name in self:\n            child = self._lazy_child(self._field_map[field_name])\n            if child is not VOID:\n                print('%s    Field \"%s\"' % (prefix, field_name))\n                child.debug(nest_level + 3)\n\n    def dump(self, force=False):\n        \"\"\"\n        Encodes the value using DER\n\n        :param force:\n            If the encoded contents already exist, clear them and regenerate\n            to ensure they are in DER format instead of BER format\n\n        :return:\n            A byte string of the DER-encoded value\n        \"\"\"\n\n        # If the length is indefinite, force the re-encoding\n        if self._header is not None and self._header[-1:] == b'\\x80':\n            force = True\n\n        # We can't force encoding if we don't have a spec\n        if force and self._fields == [] and self.__class__ is Sequence:\n            force = False\n\n        if force:\n            self._set_contents(force=force)\n\n        if self._fields and self.children is not None:\n            for index, (field_name, _, params) in enumerate(self._fields):\n                if self.children[index] is not VOID:\n                    continue\n                if 'default' in params or 'optional' in params:\n                    continue\n                raise ValueError(unwrap(\n                    '''\n                    Field \"%s\" is missing from structure\n                    ''',\n                    field_name\n                ))\n\n        return Asn1Value.dump(self)\n\n\nclass SequenceOf(Asn1Value):\n    \"\"\"\n    Represents a sequence (ordered) of a single type of values from ASN.1 as a\n    Python object with a list-like interface\n    \"\"\"\n\n    tag = 16\n\n    class_ = 0\n    method = 1\n\n    # A list of child objects\n    children = None\n\n    # SequenceOf overrides .contents to be a property so that the mutated state\n    # of child objects can be checked to ensure everything is up-to-date\n    _contents = None\n\n    # Variable to track if the object has been mutated\n    _mutated = False\n\n    # An Asn1Value class to use when parsing children\n    _child_spec = None\n\n    def __init__(self, value=None, default=None, contents=None, spec=None, **kwargs):\n        \"\"\"\n        Allows setting child objects and the _child_spec via the spec parameter\n        before passing everything else along to Asn1Value.__init__()\n\n        :param value:\n            A native Python datatype to initialize the object value with\n\n        :param default:\n            The default value if no value is specified\n\n        :param contents:\n            A byte string of the encoded contents of the value\n\n        :param spec:\n            A class derived from Asn1Value to use to parse children\n        \"\"\"\n\n        if spec:\n            self._child_spec = spec\n\n        Asn1Value.__init__(self, **kwargs)\n\n        try:\n            if contents is not None:\n                self.contents = contents\n            else:\n                if value is None and default is not None:\n                    value = default\n\n                if value is not None:\n                    for index, child in enumerate(value):\n                        self.__setitem__(index, child)\n\n                    # Make sure a blank list is serialized\n                    if self.contents is None:\n                        self._set_contents()\n\n        except (ValueError, TypeError) as e:\n            args = e.args[1:]\n            e.args = (e.args[0] + '\\n    while constructing %s' % type_name(self),) + args\n            raise e\n\n    @property\n    def contents(self):\n        \"\"\"\n        :return:\n            A byte string of the DER-encoded contents of the sequence\n        \"\"\"\n\n        if self.children is None:\n            return self._contents\n\n        if self._is_mutated():\n            self._set_contents()\n\n        return self._contents\n\n    @contents.setter\n    def contents(self, value):\n        \"\"\"\n        :param value:\n            A byte string of the DER-encoded contents of the sequence\n        \"\"\"\n\n        self._contents = value\n\n    def _is_mutated(self):\n        \"\"\"\n        :return:\n            A boolean - if the sequence or any children (recursively) have been\n            mutated\n        \"\"\"\n\n        mutated = self._mutated\n        if self.children is not None:\n            for child in self.children:\n                if isinstance(child, Sequence) or isinstance(child, SequenceOf):\n                    mutated = mutated or child._is_mutated()\n\n        return mutated\n\n    def _lazy_child(self, index):\n        \"\"\"\n        Builds a child object if the child has only been parsed into a tuple so far\n        \"\"\"\n\n        child = self.children[index]\n        if child.__class__ == tuple:\n            child = _build(*child)\n            self.children[index] = child\n        return child\n\n    def _make_value(self, value):\n        \"\"\"\n        Constructs a _child_spec value from a native Python data type, or\n        an appropriate Asn1Value object\n\n        :param value:\n            A native Python value, or some child of Asn1Value\n\n        :return:\n            An object of type _child_spec\n        \"\"\"\n\n        if isinstance(value, self._child_spec):\n            new_value = value\n\n        elif issubclass(self._child_spec, Any):\n            if isinstance(value, Asn1Value):\n                new_value = value\n            else:\n                raise ValueError(unwrap(\n                    '''\n                    Can not set a native python value to %s where the\n                    _child_spec is Any - value must be an instance of Asn1Value\n                    ''',\n                    type_name(self)\n                ))\n\n        elif issubclass(self._child_spec, Choice):\n            if not isinstance(value, Asn1Value):\n                raise ValueError(unwrap(\n                    '''\n                    Can not set a native python value to %s where the\n                    _child_spec is the choice type %s - value must be an\n                    instance of Asn1Value\n                    ''',\n                    type_name(self),\n                    self._child_spec.__name__\n                ))\n            if not isinstance(value, self._child_spec):\n                wrapper = self._child_spec()\n                wrapper.validate(value.class_, value.tag, value.contents)\n                wrapper._parsed = value\n                value = wrapper\n            new_value = value\n\n        else:\n            return self._child_spec(value=value)\n\n        params = {}\n        if self._child_spec.explicit:\n            params['explicit'] = self._child_spec.explicit\n        if self._child_spec.implicit:\n            params['implicit'] = (self._child_spec.class_, self._child_spec.tag)\n        return _fix_tagging(new_value, params)\n\n    def __len__(self):\n        \"\"\"\n        :return:\n            An integer\n        \"\"\"\n        # We inline this checks to prevent method invocation each time\n        if self.children is None:\n            self._parse_children()\n\n        return len(self.children)\n\n    def __getitem__(self, key):\n        \"\"\"\n        Allows accessing children via index\n\n        :param key:\n            Integer index of child\n        \"\"\"\n\n        # We inline this checks to prevent method invocation each time\n        if self.children is None:\n            self._parse_children()\n\n        return self._lazy_child(key)\n\n    def __setitem__(self, key, value):\n        \"\"\"\n        Allows overriding a child via index\n\n        :param key:\n            Integer index of child\n\n        :param value:\n            Native python datatype that will be passed to _child_spec to create\n            new child object\n        \"\"\"\n\n        # We inline this checks to prevent method invocation each time\n        if self.children is None:\n            self._parse_children()\n\n        new_value = self._make_value(value)\n\n        # If adding at the end, create a space for the new value\n        if key == len(self.children):\n            self.children.append(None)\n            if self._native is not None:\n                self._native.append(None)\n\n        self.children[key] = new_value\n\n        if self._native is not None:\n            self._native[key] = self.children[key].native\n\n        self._mutated = True\n\n    def __delitem__(self, key):\n        \"\"\"\n        Allows removing a child via index\n\n        :param key:\n            Integer index of child\n        \"\"\"\n\n        # We inline this checks to prevent method invocation each time\n        if self.children is None:\n            self._parse_children()\n\n        self.children.pop(key)\n        if self._native is not None:\n            self._native.pop(key)\n\n        self._mutated = True\n\n    def __iter__(self):\n        \"\"\"\n        :return:\n            An iter() of child objects\n        \"\"\"\n\n        # We inline this checks to prevent method invocation each time\n        if self.children is None:\n            self._parse_children()\n\n        for index in range(0, len(self.children)):\n            yield self._lazy_child(index)\n\n    def __contains__(self, item):\n        \"\"\"\n        :param item:\n            An object of the type cls._child_spec\n\n        :return:\n            A boolean if the item is contained in this SequenceOf\n        \"\"\"\n\n        if item is None or item is VOID:\n            return False\n\n        if not isinstance(item, self._child_spec):\n            raise TypeError(unwrap(\n                '''\n                Checking membership in %s is only available for instances of\n                %s, not %s\n                ''',\n                type_name(self),\n                type_name(self._child_spec),\n                type_name(item)\n            ))\n\n        for child in self:\n            if child == item:\n                return True\n\n        return False\n\n    def append(self, value):\n        \"\"\"\n        Allows adding a child to the end of the sequence\n\n        :param value:\n            Native python datatype that will be passed to _child_spec to create\n            new child object\n        \"\"\"\n\n        # We inline this checks to prevent method invocation each time\n        if self.children is None:\n            self._parse_children()\n\n        self.children.append(self._make_value(value))\n\n        if self._native is not None:\n            self._native.append(self.children[-1].native)\n\n        self._mutated = True\n\n    def _set_contents(self, force=False):\n        \"\"\"\n        Encodes all child objects into the contents for this object\n\n        :param force:\n            Ensure all contents are in DER format instead of possibly using\n            cached BER-encoded data\n        \"\"\"\n\n        if self.children is None:\n            self._parse_children()\n\n        contents = BytesIO()\n        for child in self:\n            contents.write(child.dump(force=force))\n        self._contents = contents.getvalue()\n        self._header = None\n        if self._trailer != b'':\n            self._trailer = b''\n\n    def _parse_children(self, recurse=False):\n        \"\"\"\n        Parses the contents and generates Asn1Value objects based on the\n        definitions from _child_spec.\n\n        :param recurse:\n            If child objects that are Sequence or SequenceOf objects should\n            be recursively parsed\n\n        :raises:\n            ValueError - when an error occurs parsing child objects\n        \"\"\"\n\n        try:\n            self.children = []\n            if self._contents is None:\n                return\n            contents_length = len(self._contents)\n            child_pointer = 0\n            while child_pointer < contents_length:\n                parts, child_pointer = _parse(self._contents, contents_length, pointer=child_pointer)\n                if self._child_spec:\n                    child = parts + (self._child_spec,)\n                else:\n                    child = parts\n                if recurse:\n                    child = _build(*child)\n                    if isinstance(child, (Sequence, SequenceOf)):\n                        child._parse_children(recurse=True)\n                self.children.append(child)\n        except (ValueError, TypeError) as e:\n            self.children = None\n            args = e.args[1:]\n            e.args = (e.args[0] + '\\n    while parsing %s' % type_name(self),) + args\n            raise e\n\n    def spec(self):\n        \"\"\"\n        Determines the spec to use for child values.\n\n        :return:\n            A child class of asn1crypto.core.Asn1Value that child values must be\n            encoded using\n        \"\"\"\n\n        return self._child_spec\n\n    @property\n    def native(self):\n        \"\"\"\n        The native Python datatype representation of this value\n\n        :return:\n            A list or None. If a list, all child values are recursively\n            converted to native representation also.\n        \"\"\"\n\n        if self.contents is None:\n            return None\n\n        if self._native is None:\n            if self.children is None:\n                self._parse_children(recurse=True)\n            try:\n                self._native = [child.native for child in self]\n            except (ValueError, TypeError) as e:\n                args = e.args[1:]\n                e.args = (e.args[0] + '\\n    while parsing %s' % type_name(self),) + args\n                raise e\n        return self._native\n\n    def _copy(self, other, copy_func):\n        \"\"\"\n        Copies the contents of another SequenceOf object to itself\n\n        :param object:\n            Another instance of the same class\n\n        :param copy_func:\n            An reference of copy.copy() or copy.deepcopy() to use when copying\n            lists, dicts and objects\n        \"\"\"\n\n        super(SequenceOf, self)._copy(other, copy_func)\n        if self.children is not None:\n            self.children = []\n            for child in other.children:\n                if child.__class__ == tuple:\n                    self.children.append(child)\n                else:\n                    self.children.append(child.copy())\n\n    def debug(self, nest_level=1):\n        \"\"\"\n        Show the binary data and parsed data in a tree structure\n        \"\"\"\n\n        if self.children is None:\n            self._parse_children()\n\n        prefix = '  ' * nest_level\n        _basic_debug(prefix, self)\n        for child in self:\n            child.debug(nest_level + 1)\n\n    def dump(self, force=False):\n        \"\"\"\n        Encodes the value using DER\n\n        :param force:\n            If the encoded contents already exist, clear them and regenerate\n            to ensure they are in DER format instead of BER format\n\n        :return:\n            A byte string of the DER-encoded value\n        \"\"\"\n\n        # If the length is indefinite, force the re-encoding\n        if self._header is not None and self._header[-1:] == b'\\x80':\n            force = True\n\n        if force:\n            self._set_contents(force=force)\n\n        return Asn1Value.dump(self)\n\n\nclass Set(Sequence):\n    \"\"\"\n    Represents a set of fields (unordered) from ASN.1 as a Python object with a\n    dict-like interface\n    \"\"\"\n\n    method = 1\n    class_ = 0\n    tag = 17\n\n    # A dict of 2-element tuples in the form (class_, tag) as keys and integers\n    # as values that are the index of the field in _fields\n    _field_ids = None\n\n    def _setup(self):\n        \"\"\"\n        Generates _field_map, _field_ids and _oid_nums for use in parsing\n        \"\"\"\n\n        cls = self.__class__\n        cls._field_map = {}\n        cls._field_ids = {}\n        cls._precomputed_specs = []\n        for index, field in enumerate(cls._fields):\n            if len(field) < 3:\n                field = field + ({},)\n                cls._fields[index] = field\n            cls._field_map[field[0]] = index\n            cls._field_ids[_build_id_tuple(field[2], field[1])] = index\n\n        if cls._oid_pair is not None:\n            cls._oid_nums = (cls._field_map[cls._oid_pair[0]], cls._field_map[cls._oid_pair[1]])\n\n        for index, field in enumerate(cls._fields):\n            has_callback = cls._spec_callbacks is not None and field[0] in cls._spec_callbacks\n            is_mapped_oid = cls._oid_nums is not None and cls._oid_nums[1] == index\n            if has_callback or is_mapped_oid:\n                cls._precomputed_specs.append(None)\n            else:\n                cls._precomputed_specs.append((field[0], field[1], field[1], field[2], None))\n\n    def _parse_children(self, recurse=False):\n        \"\"\"\n        Parses the contents and generates Asn1Value objects based on the\n        definitions from _fields.\n\n        :param recurse:\n            If child objects that are Sequence or SequenceOf objects should\n            be recursively parsed\n\n        :raises:\n            ValueError - when an error occurs parsing child objects\n        \"\"\"\n\n        cls = self.__class__\n        if self._contents is None:\n            if self._fields:\n                self.children = [VOID] * len(self._fields)\n                for index, (_, _, params) in enumerate(self._fields):\n                    if 'default' in params:\n                        if cls._precomputed_specs[index]:\n                            field_name, field_spec, value_spec, field_params, _ = cls._precomputed_specs[index]\n                        else:\n                            field_name, field_spec, value_spec, field_params, _ = self._determine_spec(index)\n                        self.children[index] = self._make_value(field_name, field_spec, value_spec, field_params, None)\n            return\n\n        try:\n            child_map = {}\n            contents_length = len(self.contents)\n            child_pointer = 0\n            seen_field = 0\n            while child_pointer < contents_length:\n                parts, child_pointer = _parse(self.contents, contents_length, pointer=child_pointer)\n\n                id_ = (parts[0], parts[2])\n\n                field = self._field_ids.get(id_)\n                if field is None:\n                    raise ValueError(unwrap(\n                        '''\n                        Data for field %s (%s class, %s method, tag %s) does\n                        not match any of the field definitions\n                        ''',\n                        seen_field,\n                        CLASS_NUM_TO_NAME_MAP.get(parts[0]),\n                        METHOD_NUM_TO_NAME_MAP.get(parts[1]),\n                        parts[2],\n                    ))\n\n                _, field_spec, value_spec, field_params, spec_override = (\n                    cls._precomputed_specs[field] or self._determine_spec(field))\n\n                if field_spec is None or (spec_override and issubclass(field_spec, Any)):\n                    field_spec = value_spec\n                    spec_override = None\n\n                if spec_override:\n                    child = parts + (field_spec, field_params, value_spec)\n                else:\n                    child = parts + (field_spec, field_params)\n\n                if recurse:\n                    child = _build(*child)\n                    if isinstance(child, (Sequence, SequenceOf)):\n                        child._parse_children(recurse=True)\n\n                child_map[field] = child\n                seen_field += 1\n\n            total_fields = len(self._fields)\n\n            for index in range(0, total_fields):\n                if index in child_map:\n                    continue\n\n                name, field_spec, value_spec, field_params, spec_override = (\n                    cls._precomputed_specs[index] or self._determine_spec(index))\n\n                if field_spec is None or (spec_override and issubclass(field_spec, Any)):\n                    field_spec = value_spec\n                    spec_override = None\n\n                missing = False\n\n                if not field_params:\n                    missing = True\n                elif 'optional' not in field_params and 'default' not in field_params:\n                    missing = True\n                elif 'optional' in field_params:\n                    child_map[index] = VOID\n                elif 'default' in field_params:\n                    child_map[index] = field_spec(**field_params)\n\n                if missing:\n                    raise ValueError(unwrap(\n                        '''\n                        Missing required field \"%s\" from %s\n                        ''',\n                        name,\n                        type_name(self)\n                    ))\n\n            self.children = []\n            for index in range(0, total_fields):\n                self.children.append(child_map[index])\n\n        except (ValueError, TypeError) as e:\n            args = e.args[1:]\n            e.args = (e.args[0] + '\\n    while parsing %s' % type_name(self),) + args\n            raise e\n\n    def _set_contents(self, force=False):\n        \"\"\"\n        Encodes all child objects into the contents for this object.\n\n        This method is overridden because a Set needs to be encoded by\n        removing defaulted fields and then sorting the fields by tag.\n\n        :param force:\n            Ensure all contents are in DER format instead of possibly using\n            cached BER-encoded data\n        \"\"\"\n\n        if self.children is None:\n            self._parse_children()\n\n        child_tag_encodings = []\n        for index, child in enumerate(self.children):\n            child_encoding = child.dump(force=force)\n\n            # Skip encoding defaulted children\n            name, spec, field_params = self._fields[index]\n            if 'default' in field_params:\n                if spec(**field_params).dump() == child_encoding:\n                    continue\n\n            child_tag_encodings.append((child.tag, child_encoding))\n        child_tag_encodings.sort(key=lambda ct: ct[0])\n\n        self._contents = b''.join([ct[1] for ct in child_tag_encodings])\n        self._header = None\n        if self._trailer != b'':\n            self._trailer = b''\n\n\nclass SetOf(SequenceOf):\n    \"\"\"\n    Represents a set (unordered) of a single type of values from ASN.1 as a\n    Python object with a list-like interface\n    \"\"\"\n\n    tag = 17\n\n    def _set_contents(self, force=False):\n        \"\"\"\n        Encodes all child objects into the contents for this object.\n\n        This method is overridden because a SetOf needs to be encoded by\n        sorting the child encodings.\n\n        :param force:\n            Ensure all contents are in DER format instead of possibly using\n            cached BER-encoded data\n        \"\"\"\n\n        if self.children is None:\n            self._parse_children()\n\n        child_encodings = []\n        for child in self:\n            child_encodings.append(child.dump(force=force))\n\n        self._contents = b''.join(sorted(child_encodings))\n        self._header = None\n        if self._trailer != b'':\n            self._trailer = b''\n\n\nclass EmbeddedPdv(Sequence):\n    \"\"\"\n    A sequence structure\n    \"\"\"\n\n    tag = 11\n\n\nclass NumericString(AbstractString):\n    \"\"\"\n    Represents a numeric string from ASN.1 as a Python unicode string\n    \"\"\"\n\n    tag = 18\n    _encoding = 'latin1'\n\n\nclass PrintableString(AbstractString):\n    \"\"\"\n    Represents a printable string from ASN.1 as a Python unicode string\n    \"\"\"\n\n    tag = 19\n    _encoding = 'latin1'\n\n\nclass TeletexString(AbstractString):\n    \"\"\"\n    Represents a teletex string from ASN.1 as a Python unicode string\n    \"\"\"\n\n    tag = 20\n    _encoding = 'teletex'\n\n\nclass VideotexString(OctetString):\n    \"\"\"\n    Represents a videotex string from ASN.1 as a Python byte string\n    \"\"\"\n\n    tag = 21\n\n\nclass IA5String(AbstractString):\n    \"\"\"\n    Represents an IA5 string from ASN.1 as a Python unicode string\n    \"\"\"\n\n    tag = 22\n    _encoding = 'ascii'\n\n\nclass AbstractTime(AbstractString):\n    \"\"\"\n    Represents a time from ASN.1 as a Python datetime.datetime object\n    \"\"\"\n\n    @property\n    def _parsed_time(self):\n        \"\"\"\n        The parsed datetime string.\n\n        :raises:\n            ValueError - when an invalid value is passed\n\n        :return:\n            A dict with the parsed values\n        \"\"\"\n\n        string = str_cls(self)\n\n        m = self._TIMESTRING_RE.match(string)\n        if not m:\n            raise ValueError(unwrap(\n                '''\n                Error parsing %s to a %s\n                ''',\n                string,\n                type_name(self),\n            ))\n\n        groups = m.groupdict()\n\n        tz = None\n        if groups['zulu']:\n            tz = timezone.utc\n        elif groups['dsign']:\n            sign = 1 if groups['dsign'] == '+' else -1\n            tz = create_timezone(sign * timedelta(\n                hours=int(groups['dhour']),\n                minutes=int(groups['dminute'] or 0)\n            ))\n\n        if groups['fraction']:\n            # Compute fraction in microseconds\n            fract = Fraction(\n                int(groups['fraction']),\n                10 ** len(groups['fraction'])\n            ) * 1000000\n\n            if groups['minute'] is None:\n                fract *= 3600\n            elif groups['second'] is None:\n                fract *= 60\n\n            fract_usec = int(fract.limit_denominator(1))\n\n        else:\n            fract_usec = 0\n\n        return {\n            'year': int(groups['year']),\n            'month': int(groups['month']),\n            'day': int(groups['day']),\n            'hour': int(groups['hour']),\n            'minute': int(groups['minute'] or 0),\n            'second': int(groups['second'] or 0),\n            'tzinfo': tz,\n            'fraction': fract_usec,\n        }\n\n    @property\n    def native(self):\n        \"\"\"\n        The native Python datatype representation of this value\n\n        :return:\n            A datetime.datetime object, asn1crypto.util.extended_datetime object or\n            None. The datetime object is usually timezone aware. If it's naive, then\n            it's in the sender's local time; see X.680 sect. 42.3\n        \"\"\"\n\n        if self.contents is None:\n            return None\n\n        if self._native is None:\n            parsed = self._parsed_time\n\n            fraction = parsed.pop('fraction', 0)\n\n            value = self._get_datetime(parsed)\n\n            if fraction:\n                value += timedelta(microseconds=fraction)\n\n            self._native = value\n\n        return self._native\n\n\nclass UTCTime(AbstractTime):\n    \"\"\"\n    Represents a UTC time from ASN.1 as a timezone aware Python datetime.datetime object\n    \"\"\"\n\n    tag = 23\n\n    # Regular expression for UTCTime as described in X.680 sect. 43 and ISO 8601\n    _TIMESTRING_RE = re.compile(r'''\n        ^\n        # YYMMDD\n        (?P<year>\\d{2})\n        (?P<month>\\d{2})\n        (?P<day>\\d{2})\n\n        # hhmm or hhmmss\n        (?P<hour>\\d{2})\n        (?P<minute>\\d{2})\n        (?P<second>\\d{2})?\n\n        # Matches nothing, needed because GeneralizedTime uses this.\n        (?P<fraction>)\n\n        # Z or [-+]hhmm\n        (?:\n            (?P<zulu>Z)\n            |\n            (?:\n                (?P<dsign>[-+])\n                (?P<dhour>\\d{2})\n                (?P<dminute>\\d{2})\n            )\n        )\n        $\n    ''', re.X)\n\n    def set(self, value):\n        \"\"\"\n        Sets the value of the object\n\n        :param value:\n            A unicode string or a datetime.datetime object\n\n        :raises:\n            ValueError - when an invalid value is passed\n        \"\"\"\n\n        if isinstance(value, datetime):\n            if not value.tzinfo:\n                raise ValueError('Must be timezone aware')\n\n            # Convert value to UTC.\n            value = value.astimezone(utc_with_dst)\n\n            if not 1950 <= value.year <= 2049:\n                raise ValueError('Year of the UTCTime is not in range [1950, 2049], use GeneralizedTime instead')\n\n            value = value.strftime('%y%m%d%H%M%SZ')\n            if _PY2:\n                value = value.decode('ascii')\n\n        AbstractString.set(self, value)\n        # Set it to None and let the class take care of converting the next\n        # time that .native is called\n        self._native = None\n\n    def _get_datetime(self, parsed):\n        \"\"\"\n        Create a datetime object from the parsed time.\n\n        :return:\n            An aware datetime.datetime object\n        \"\"\"\n\n        # X.680 only specifies that UTCTime is not using a century.\n        # So \"18\" could as well mean 2118 or 1318.\n        # X.509 and CMS specify to use UTCTime for years earlier than 2050.\n        # Assume that UTCTime is only used for years [1950, 2049].\n        if parsed['year'] < 50:\n            parsed['year'] += 2000\n        else:\n            parsed['year'] += 1900\n\n        return datetime(**parsed)\n\n\nclass GeneralizedTime(AbstractTime):\n    \"\"\"\n    Represents a generalized time from ASN.1 as a Python datetime.datetime\n    object or asn1crypto.util.extended_datetime object in UTC\n    \"\"\"\n\n    tag = 24\n\n    # Regular expression for GeneralizedTime as described in X.680 sect. 42 and ISO 8601\n    _TIMESTRING_RE = re.compile(r'''\n        ^\n        # YYYYMMDD\n        (?P<year>\\d{4})\n        (?P<month>\\d{2})\n        (?P<day>\\d{2})\n\n        # hh or hhmm or hhmmss\n        (?P<hour>\\d{2})\n        (?:\n            (?P<minute>\\d{2})\n            (?P<second>\\d{2})?\n        )?\n\n        # Optional fraction; [.,]dddd (one or more decimals)\n        # If Seconds are given, it's fractions of Seconds.\n        # Else if Minutes are given, it's fractions of Minutes.\n        # Else it's fractions of Hours.\n        (?:\n            [,.]\n            (?P<fraction>\\d+)\n        )?\n\n        # Optional timezone. If left out, the time is in local time.\n        # Z or [-+]hh or [-+]hhmm\n        (?:\n            (?P<zulu>Z)\n            |\n            (?:\n                (?P<dsign>[-+])\n                (?P<dhour>\\d{2})\n                (?P<dminute>\\d{2})?\n            )\n        )?\n        $\n    ''', re.X)\n\n    def set(self, value):\n        \"\"\"\n        Sets the value of the object\n\n        :param value:\n            A unicode string, a datetime.datetime object or an\n            asn1crypto.util.extended_datetime object\n\n        :raises:\n            ValueError - when an invalid value is passed\n        \"\"\"\n\n        if isinstance(value, (datetime, extended_datetime)):\n            if not value.tzinfo:\n                raise ValueError('Must be timezone aware')\n\n            # Convert value to UTC.\n            value = value.astimezone(utc_with_dst)\n\n            if value.microsecond:\n                fraction = '.' + str(value.microsecond).zfill(6).rstrip('0')\n            else:\n                fraction = ''\n\n            value = value.strftime('%Y%m%d%H%M%S') + fraction + 'Z'\n            if _PY2:\n                value = value.decode('ascii')\n\n        AbstractString.set(self, value)\n        # Set it to None and let the class take care of converting the next\n        # time that .native is called\n        self._native = None\n\n    def _get_datetime(self, parsed):\n        \"\"\"\n        Create a datetime object from the parsed time.\n\n        :return:\n            A datetime.datetime object or asn1crypto.util.extended_datetime object.\n            It may or may not be aware.\n        \"\"\"\n\n        if parsed['year'] == 0:\n            # datetime does not support year 0. Use extended_datetime instead.\n            return extended_datetime(**parsed)\n        else:\n            return datetime(**parsed)\n\n\nclass GraphicString(AbstractString):\n    \"\"\"\n    Represents a graphic string from ASN.1 as a Python unicode string\n    \"\"\"\n\n    tag = 25\n    # This is technically not correct since this type can contain any charset\n    _encoding = 'latin1'\n\n\nclass VisibleString(AbstractString):\n    \"\"\"\n    Represents a visible string from ASN.1 as a Python unicode string\n    \"\"\"\n\n    tag = 26\n    _encoding = 'latin1'\n\n\nclass GeneralString(AbstractString):\n    \"\"\"\n    Represents a general string from ASN.1 as a Python unicode string\n    \"\"\"\n\n    tag = 27\n    # This is technically not correct since this type can contain any charset\n    _encoding = 'latin1'\n\n\nclass UniversalString(AbstractString):\n    \"\"\"\n    Represents a universal string from ASN.1 as a Python unicode string\n    \"\"\"\n\n    tag = 28\n    _encoding = 'utf-32-be'\n\n\nclass CharacterString(AbstractString):\n    \"\"\"\n    Represents a character string from ASN.1 as a Python unicode string\n    \"\"\"\n\n    tag = 29\n    # This is technically not correct since this type can contain any charset\n    _encoding = 'latin1'\n\n\nclass BMPString(AbstractString):\n    \"\"\"\n    Represents a BMP string from ASN.1 as a Python unicode string\n    \"\"\"\n\n    tag = 30\n    _encoding = 'utf-16-be'\n\n\ndef _basic_debug(prefix, self):\n    \"\"\"\n    Prints out basic information about an Asn1Value object. Extracted for reuse\n    among different classes that customize the debug information.\n\n    :param prefix:\n        A unicode string of spaces to prefix output line with\n\n    :param self:\n        The object to print the debugging information about\n    \"\"\"\n\n    print('%s%s Object #%s' % (prefix, type_name(self), id(self)))\n    if self._header:\n        print('%s  Header: 0x%s' % (prefix, binascii.hexlify(self._header or b'').decode('utf-8')))\n\n    has_header = self.method is not None and self.class_ is not None and self.tag is not None\n    if has_header:\n        method_name = METHOD_NUM_TO_NAME_MAP.get(self.method)\n        class_name = CLASS_NUM_TO_NAME_MAP.get(self.class_)\n\n    if self.explicit is not None:\n        for class_, tag in self.explicit:\n            print(\n                '%s    %s tag %s (explicitly tagged)' %\n                (\n                    prefix,\n                    CLASS_NUM_TO_NAME_MAP.get(class_),\n                    tag\n                )\n            )\n        if has_header:\n            print('%s      %s %s %s' % (prefix, method_name, class_name, self.tag))\n\n    elif self.implicit:\n        if has_header:\n            print('%s    %s %s tag %s (implicitly tagged)' % (prefix, method_name, class_name, self.tag))\n\n    elif has_header:\n        print('%s    %s %s tag %s' % (prefix, method_name, class_name, self.tag))\n\n    if self._trailer:\n        print('%s  Trailer: 0x%s' % (prefix, binascii.hexlify(self._trailer or b'').decode('utf-8')))\n\n    print('%s  Data: 0x%s' % (prefix, binascii.hexlify(self.contents or b'').decode('utf-8')))\n\n\ndef _tag_type_to_explicit_implicit(params):\n    \"\"\"\n    Converts old-style \"tag_type\" and \"tag\" params to \"explicit\" and \"implicit\"\n\n    :param params:\n        A dict of parameters to convert from tag_type/tag to explicit/implicit\n    \"\"\"\n\n    if 'tag_type' in params:\n        if params['tag_type'] == 'explicit':\n            params['explicit'] = (params.get('class', 2), params['tag'])\n        elif params['tag_type'] == 'implicit':\n            params['implicit'] = (params.get('class', 2), params['tag'])\n        del params['tag_type']\n        del params['tag']\n        if 'class' in params:\n            del params['class']\n\n\ndef _fix_tagging(value, params):\n    \"\"\"\n    Checks if a value is properly tagged based on the spec, and re/untags as\n    necessary\n\n    :param value:\n        An Asn1Value object\n\n    :param params:\n        A dict of spec params\n\n    :return:\n        An Asn1Value that is properly tagged\n    \"\"\"\n\n    _tag_type_to_explicit_implicit(params)\n\n    retag = False\n    if 'implicit' not in params:\n        if value.implicit is not False:\n            retag = True\n    else:\n        if isinstance(params['implicit'], tuple):\n            class_, tag = params['implicit']\n        else:\n            tag = params['implicit']\n            class_ = 'context'\n        if value.implicit is False:\n            retag = True\n        elif value.class_ != CLASS_NAME_TO_NUM_MAP[class_] or value.tag != tag:\n            retag = True\n\n    if params.get('explicit') != value.explicit:\n        retag = True\n\n    if retag:\n        return value.retag(params)\n    return value\n\n\ndef _build_id_tuple(params, spec):\n    \"\"\"\n    Builds a 2-element tuple used to identify fields by grabbing the class_\n    and tag from an Asn1Value class and the params dict being passed to it\n\n    :param params:\n        A dict of params to pass to spec\n\n    :param spec:\n        An Asn1Value class\n\n    :return:\n        A 2-element integer tuple in the form (class_, tag)\n    \"\"\"\n\n    # Handle situations where the spec is not known at setup time\n    if spec is None:\n        return (None, None)\n\n    required_class = spec.class_\n    required_tag = spec.tag\n\n    _tag_type_to_explicit_implicit(params)\n\n    if 'explicit' in params:\n        if isinstance(params['explicit'], tuple):\n            required_class, required_tag = params['explicit']\n        else:\n            required_class = 2\n            required_tag = params['explicit']\n    elif 'implicit' in params:\n        if isinstance(params['implicit'], tuple):\n            required_class, required_tag = params['implicit']\n        else:\n            required_class = 2\n            required_tag = params['implicit']\n    if required_class is not None and not isinstance(required_class, int_types):\n        required_class = CLASS_NAME_TO_NUM_MAP[required_class]\n\n    required_class = params.get('class_', required_class)\n    required_tag = params.get('tag', required_tag)\n\n    return (required_class, required_tag)\n\n\ndef _int_to_bit_tuple(value, bits):\n    \"\"\"\n    Format value as a tuple of 1s and 0s.\n\n    :param value:\n        A non-negative integer to format\n\n    :param bits:\n        Number of bits in the output\n\n    :return:\n        A tuple of 1s and 0s with bits members.\n    \"\"\"\n\n    if not value and not bits:\n        return ()\n\n    result = tuple(map(int, format(value, '0{0}b'.format(bits))))\n    if len(result) != bits:\n        raise ValueError('Result too large: {0} > {1}'.format(len(result), bits))\n\n    return result\n\n\n_UNIVERSAL_SPECS = {\n    1: Boolean,\n    2: Integer,\n    3: BitString,\n    4: OctetString,\n    5: Null,\n    6: ObjectIdentifier,\n    7: ObjectDescriptor,\n    8: InstanceOf,\n    9: Real,\n    10: Enumerated,\n    11: EmbeddedPdv,\n    12: UTF8String,\n    13: RelativeOid,\n    16: Sequence,\n    17: Set,\n    18: NumericString,\n    19: PrintableString,\n    20: TeletexString,\n    21: VideotexString,\n    22: IA5String,\n    23: UTCTime,\n    24: GeneralizedTime,\n    25: GraphicString,\n    26: VisibleString,\n    27: GeneralString,\n    28: UniversalString,\n    29: CharacterString,\n    30: BMPString\n}\n\n\ndef _build(class_, method, tag, header, contents, trailer, spec=None, spec_params=None, nested_spec=None):\n    \"\"\"\n    Builds an Asn1Value object generically, or using a spec with optional params\n\n    :param class_:\n        An integer representing the ASN.1 class\n\n    :param method:\n        An integer representing the ASN.1 method\n\n    :param tag:\n        An integer representing the ASN.1 tag\n\n    :param header:\n        A byte string of the ASN.1 header (class, method, tag, length)\n\n    :param contents:\n        A byte string of the ASN.1 value\n\n    :param trailer:\n        A byte string of any ASN.1 trailer (only used by indefinite length encodings)\n\n    :param spec:\n        A class derived from Asn1Value that defines what class_ and tag the\n        value should have, and the semantics of the encoded value. The\n        return value will be of this type. If omitted, the encoded value\n        will be decoded using the standard universal tag based on the\n        encoded tag number.\n\n    :param spec_params:\n        A dict of params to pass to the spec object\n\n    :param nested_spec:\n        For certain Asn1Value classes (such as OctetString and BitString), the\n        contents can be further parsed and interpreted as another Asn1Value.\n        This parameter controls the spec for that sub-parsing.\n\n    :return:\n        An object of the type spec, or if not specified, a child of Asn1Value\n    \"\"\"\n\n    if spec_params is not None:\n        _tag_type_to_explicit_implicit(spec_params)\n\n    if header is None:\n        return VOID\n\n    header_set = False\n\n    # If an explicit specification was passed in, make sure it matches\n    if spec is not None:\n        # If there is explicit tagging and contents, we have to split\n        # the header and trailer off before we do the parsing\n        no_explicit = spec_params and 'no_explicit' in spec_params\n        if not no_explicit and (spec.explicit or (spec_params and 'explicit' in spec_params)):\n            if spec_params:\n                value = spec(**spec_params)\n            else:\n                value = spec()\n            original_explicit = value.explicit\n            explicit_info = reversed(original_explicit)\n            parsed_class = class_\n            parsed_method = method\n            parsed_tag = tag\n            to_parse = contents\n            explicit_header = header\n            explicit_trailer = trailer or b''\n            for expected_class, expected_tag in explicit_info:\n                if parsed_class != expected_class:\n                    raise ValueError(unwrap(\n                        '''\n                        Error parsing %s - explicitly-tagged class should have been\n                        %s, but %s was found\n                        ''',\n                        type_name(value),\n                        CLASS_NUM_TO_NAME_MAP.get(expected_class),\n                        CLASS_NUM_TO_NAME_MAP.get(parsed_class, parsed_class)\n                    ))\n                if parsed_method != 1:\n                    raise ValueError(unwrap(\n                        '''\n                        Error parsing %s - explicitly-tagged method should have\n                        been %s, but %s was found\n                        ''',\n                        type_name(value),\n                        METHOD_NUM_TO_NAME_MAP.get(1),\n                        METHOD_NUM_TO_NAME_MAP.get(parsed_method, parsed_method)\n                    ))\n                if parsed_tag != expected_tag:\n                    raise ValueError(unwrap(\n                        '''\n                        Error parsing %s - explicitly-tagged tag should have been\n                        %s, but %s was found\n                        ''',\n                        type_name(value),\n                        expected_tag,\n                        parsed_tag\n                    ))\n                info, _ = _parse(to_parse, len(to_parse))\n                parsed_class, parsed_method, parsed_tag, parsed_header, to_parse, parsed_trailer = info\n\n                if not isinstance(value, Choice):\n                    explicit_header += parsed_header\n                    explicit_trailer = parsed_trailer + explicit_trailer\n\n            value = _build(*info, spec=spec, spec_params={'no_explicit': True})\n            value._header = explicit_header\n            value._trailer = explicit_trailer\n            value.explicit = original_explicit\n            header_set = True\n        else:\n            if spec_params:\n                value = spec(contents=contents, **spec_params)\n            else:\n                value = spec(contents=contents)\n\n            if spec is Any:\n                pass\n\n            elif isinstance(value, Choice):\n                value.validate(class_, tag, contents)\n                try:\n                    # Force parsing the Choice now\n                    value.contents = header + value.contents\n                    header = b''\n                    value.parse()\n                except (ValueError, TypeError) as e:\n                    args = e.args[1:]\n                    e.args = (e.args[0] + '\\n    while parsing %s' % type_name(value),) + args\n                    raise e\n\n            else:\n                if class_ != value.class_:\n                    raise ValueError(unwrap(\n                        '''\n                        Error parsing %s - class should have been %s, but %s was\n                        found\n                        ''',\n                        type_name(value),\n                        CLASS_NUM_TO_NAME_MAP.get(value.class_),\n                        CLASS_NUM_TO_NAME_MAP.get(class_, class_)\n                    ))\n                if method != value.method:\n                    # Allow parsing a primitive method as constructed if the value\n                    # is indefinite length. This is to allow parsing BER.\n                    ber_indef = method == 1 and value.method == 0 and trailer == b'\\x00\\x00'\n                    if not ber_indef or not isinstance(value, Constructable):\n                        raise ValueError(unwrap(\n                            '''\n                            Error parsing %s - method should have been %s, but %s was found\n                            ''',\n                            type_name(value),\n                            METHOD_NUM_TO_NAME_MAP.get(value.method),\n                            METHOD_NUM_TO_NAME_MAP.get(method, method)\n                        ))\n                    else:\n                        value.method = method\n                        value._indefinite = True\n                if tag != value.tag:\n                    if isinstance(value._bad_tag, tuple):\n                        is_bad_tag = tag in value._bad_tag\n                    else:\n                        is_bad_tag = tag == value._bad_tag\n                    if not is_bad_tag:\n                        raise ValueError(unwrap(\n                            '''\n                            Error parsing %s - tag should have been %s, but %s was found\n                            ''',\n                            type_name(value),\n                            value.tag,\n                            tag\n                        ))\n\n    # For explicitly tagged, un-speced parsings, we use a generic container\n    # since we will be parsing the contents and discarding the outer object\n    # anyway a little further on\n    elif spec_params and 'explicit' in spec_params:\n        original_value = Asn1Value(contents=contents, **spec_params)\n        original_explicit = original_value.explicit\n\n        to_parse = contents\n        explicit_header = header\n        explicit_trailer = trailer or b''\n        for expected_class, expected_tag in reversed(original_explicit):\n            info, _ = _parse(to_parse, len(to_parse))\n            _, _, _, parsed_header, to_parse, parsed_trailer = info\n            explicit_header += parsed_header\n            explicit_trailer = parsed_trailer + explicit_trailer\n        value = _build(*info, spec=spec, spec_params={'no_explicit': True})\n        value._header = header + value._header\n        value._trailer += trailer or b''\n        value.explicit = original_explicit\n        header_set = True\n\n    # If no spec was specified, allow anything and just process what\n    # is in the input data\n    else:\n        if tag not in _UNIVERSAL_SPECS:\n            raise ValueError(unwrap(\n                '''\n                Unknown element - %s class, %s method, tag %s\n                ''',\n                CLASS_NUM_TO_NAME_MAP.get(class_),\n                METHOD_NUM_TO_NAME_MAP.get(method),\n                tag\n            ))\n\n        spec = _UNIVERSAL_SPECS[tag]\n\n        value = spec(contents=contents, class_=class_)\n        ber_indef = method == 1 and value.method == 0 and trailer == b'\\x00\\x00'\n        if ber_indef and isinstance(value, Constructable):\n            value._indefinite = True\n        value.method = method\n\n    if not header_set:\n        value._header = header\n        value._trailer = trailer or b''\n\n    # Destroy any default value that our contents have overwritten\n    value._native = None\n\n    if nested_spec:\n        try:\n            value.parse(nested_spec)\n        except (ValueError, TypeError) as e:\n            args = e.args[1:]\n            e.args = (e.args[0] + '\\n    while parsing %s' % type_name(value),) + args\n            raise e\n\n    return value\n\n\ndef _parse_build(encoded_data, pointer=0, spec=None, spec_params=None, strict=False):\n    \"\"\"\n    Parses a byte string generically, or using a spec with optional params\n\n    :param encoded_data:\n        A byte string that contains BER-encoded data\n\n    :param pointer:\n        The index in the byte string to parse from\n\n    :param spec:\n        A class derived from Asn1Value that defines what class_ and tag the\n        value should have, and the semantics of the encoded value. The\n        return value will be of this type. If omitted, the encoded value\n        will be decoded using the standard universal tag based on the\n        encoded tag number.\n\n    :param spec_params:\n        A dict of params to pass to the spec object\n\n    :param strict:\n        A boolean indicating if trailing data should be forbidden - if so, a\n        ValueError will be raised when trailing data exists\n\n    :return:\n        A 2-element tuple:\n         - 0: An object of the type spec, or if not specified, a child of Asn1Value\n         - 1: An integer indicating how many bytes were consumed\n    \"\"\"\n\n    encoded_len = len(encoded_data)\n    info, new_pointer = _parse(encoded_data, encoded_len, pointer)\n    if strict and new_pointer != pointer + encoded_len:\n        extra_bytes = pointer + encoded_len - new_pointer\n        raise ValueError('Extra data - %d bytes of trailing data were provided' % extra_bytes)\n    return (_build(*info, spec=spec, spec_params=spec_params), new_pointer)\n"
  },
  {
    "path": "code/default/lib/noarch/asn1crypto/crl.py",
    "content": "# coding: utf-8\n\n\"\"\"\nASN.1 type classes for certificate revocation lists (CRL). Exports the\nfollowing items:\n\n - CertificateList()\n\nOther type classes are defined that help compose the types listed above.\n\"\"\"\n\nfrom __future__ import unicode_literals, division, absolute_import, print_function\n\nimport hashlib\n\nfrom .algos import SignedDigestAlgorithm\nfrom .core import (\n    Boolean,\n    Enumerated,\n    GeneralizedTime,\n    Integer,\n    ObjectIdentifier,\n    OctetBitString,\n    ParsableOctetString,\n    Sequence,\n    SequenceOf,\n)\nfrom .x509 import (\n    AuthorityInfoAccessSyntax,\n    AuthorityKeyIdentifier,\n    CRLDistributionPoints,\n    DistributionPointName,\n    GeneralNames,\n    Name,\n    ReasonFlags,\n    Time,\n)\n\n\n# The structures in this file are taken from https://tools.ietf.org/html/rfc5280\n\n\nclass Version(Integer):\n    _map = {\n        0: 'v1',\n        1: 'v2',\n        2: 'v3',\n    }\n\n\nclass IssuingDistributionPoint(Sequence):\n    _fields = [\n        ('distribution_point', DistributionPointName, {'explicit': 0, 'optional': True}),\n        ('only_contains_user_certs', Boolean, {'implicit': 1, 'default': False}),\n        ('only_contains_ca_certs', Boolean, {'implicit': 2, 'default': False}),\n        ('only_some_reasons', ReasonFlags, {'implicit': 3, 'optional': True}),\n        ('indirect_crl', Boolean, {'implicit': 4, 'default': False}),\n        ('only_contains_attribute_certs', Boolean, {'implicit': 5, 'default': False}),\n    ]\n\n\nclass TBSCertListExtensionId(ObjectIdentifier):\n    _map = {\n        '2.5.29.18': 'issuer_alt_name',\n        '2.5.29.20': 'crl_number',\n        '2.5.29.27': 'delta_crl_indicator',\n        '2.5.29.28': 'issuing_distribution_point',\n        '2.5.29.35': 'authority_key_identifier',\n        '2.5.29.46': 'freshest_crl',\n        '1.3.6.1.5.5.7.1.1': 'authority_information_access',\n    }\n\n\nclass TBSCertListExtension(Sequence):\n    _fields = [\n        ('extn_id', TBSCertListExtensionId),\n        ('critical', Boolean, {'default': False}),\n        ('extn_value', ParsableOctetString),\n    ]\n\n    _oid_pair = ('extn_id', 'extn_value')\n    _oid_specs = {\n        'issuer_alt_name': GeneralNames,\n        'crl_number': Integer,\n        'delta_crl_indicator': Integer,\n        'issuing_distribution_point': IssuingDistributionPoint,\n        'authority_key_identifier': AuthorityKeyIdentifier,\n        'freshest_crl': CRLDistributionPoints,\n        'authority_information_access': AuthorityInfoAccessSyntax,\n    }\n\n\nclass TBSCertListExtensions(SequenceOf):\n    _child_spec = TBSCertListExtension\n\n\nclass CRLReason(Enumerated):\n    _map = {\n        0: 'unspecified',\n        1: 'key_compromise',\n        2: 'ca_compromise',\n        3: 'affiliation_changed',\n        4: 'superseded',\n        5: 'cessation_of_operation',\n        6: 'certificate_hold',\n        8: 'remove_from_crl',\n        9: 'privilege_withdrawn',\n        10: 'aa_compromise',\n    }\n\n    @property\n    def human_friendly(self):\n        \"\"\"\n        :return:\n            A unicode string with revocation description that is suitable to\n            show to end-users. Starts with a lower case letter and phrased in\n            such a way that it makes sense after the phrase \"because of\" or\n            \"due to\".\n        \"\"\"\n\n        return {\n            'unspecified': 'an unspecified reason',\n            'key_compromise': 'a compromised key',\n            'ca_compromise': 'the CA being compromised',\n            'affiliation_changed': 'an affiliation change',\n            'superseded': 'certificate supersession',\n            'cessation_of_operation': 'a cessation of operation',\n            'certificate_hold': 'a certificate hold',\n            'remove_from_crl': 'removal from the CRL',\n            'privilege_withdrawn': 'privilege withdrawl',\n            'aa_compromise': 'the AA being compromised',\n        }[self.native]\n\n\nclass CRLEntryExtensionId(ObjectIdentifier):\n    _map = {\n        '2.5.29.21': 'crl_reason',\n        '2.5.29.23': 'hold_instruction_code',\n        '2.5.29.24': 'invalidity_date',\n        '2.5.29.29': 'certificate_issuer',\n    }\n\n\nclass CRLEntryExtension(Sequence):\n    _fields = [\n        ('extn_id', CRLEntryExtensionId),\n        ('critical', Boolean, {'default': False}),\n        ('extn_value', ParsableOctetString),\n    ]\n\n    _oid_pair = ('extn_id', 'extn_value')\n    _oid_specs = {\n        'crl_reason': CRLReason,\n        'hold_instruction_code': ObjectIdentifier,\n        'invalidity_date': GeneralizedTime,\n        'certificate_issuer': GeneralNames,\n    }\n\n\nclass CRLEntryExtensions(SequenceOf):\n    _child_spec = CRLEntryExtension\n\n\nclass RevokedCertificate(Sequence):\n    _fields = [\n        ('user_certificate', Integer),\n        ('revocation_date', Time),\n        ('crl_entry_extensions', CRLEntryExtensions, {'optional': True}),\n    ]\n\n    _processed_extensions = False\n    _critical_extensions = None\n    _crl_reason_value = None\n    _invalidity_date_value = None\n    _certificate_issuer_value = None\n    _issuer_name = False\n\n    def _set_extensions(self):\n        \"\"\"\n        Sets common named extensions to private attributes and creates a list\n        of critical extensions\n        \"\"\"\n\n        self._critical_extensions = set()\n\n        for extension in self['crl_entry_extensions']:\n            name = extension['extn_id'].native\n            attribute_name = '_%s_value' % name\n            if hasattr(self, attribute_name):\n                setattr(self, attribute_name, extension['extn_value'].parsed)\n            if extension['critical'].native:\n                self._critical_extensions.add(name)\n\n        self._processed_extensions = True\n\n    @property\n    def critical_extensions(self):\n        \"\"\"\n        Returns a set of the names (or OID if not a known extension) of the\n        extensions marked as critical\n\n        :return:\n            A set of unicode strings\n        \"\"\"\n\n        if not self._processed_extensions:\n            self._set_extensions()\n        return self._critical_extensions\n\n    @property\n    def crl_reason_value(self):\n        \"\"\"\n        This extension indicates the reason that a certificate was revoked.\n\n        :return:\n            None or a CRLReason object\n        \"\"\"\n\n        if self._processed_extensions is False:\n            self._set_extensions()\n        return self._crl_reason_value\n\n    @property\n    def invalidity_date_value(self):\n        \"\"\"\n        This extension indicates the suspected date/time the private key was\n        compromised or the certificate became invalid. This would usually be\n        before the revocation date, which is when the CA processed the\n        revocation.\n\n        :return:\n            None or a GeneralizedTime object\n        \"\"\"\n\n        if self._processed_extensions is False:\n            self._set_extensions()\n        return self._invalidity_date_value\n\n    @property\n    def certificate_issuer_value(self):\n        \"\"\"\n        This extension indicates the issuer of the certificate in question,\n        and is used in indirect CRLs. CRL entries without this extension are\n        for certificates issued from the last seen issuer.\n\n        :return:\n            None or an x509.GeneralNames object\n        \"\"\"\n\n        if self._processed_extensions is False:\n            self._set_extensions()\n        return self._certificate_issuer_value\n\n    @property\n    def issuer_name(self):\n        \"\"\"\n        :return:\n            None, or an asn1crypto.x509.Name object for the issuer of the cert\n        \"\"\"\n\n        if self._issuer_name is False:\n            self._issuer_name = None\n            if self.certificate_issuer_value:\n                for general_name in self.certificate_issuer_value:\n                    if general_name.name == 'directory_name':\n                        self._issuer_name = general_name.chosen\n                        break\n        return self._issuer_name\n\n\nclass RevokedCertificates(SequenceOf):\n    _child_spec = RevokedCertificate\n\n\nclass TbsCertList(Sequence):\n    _fields = [\n        ('version', Version, {'optional': True}),\n        ('signature', SignedDigestAlgorithm),\n        ('issuer', Name),\n        ('this_update', Time),\n        ('next_update', Time, {'optional': True}),\n        ('revoked_certificates', RevokedCertificates, {'optional': True}),\n        ('crl_extensions', TBSCertListExtensions, {'explicit': 0, 'optional': True}),\n    ]\n\n\nclass CertificateList(Sequence):\n    _fields = [\n        ('tbs_cert_list', TbsCertList),\n        ('signature_algorithm', SignedDigestAlgorithm),\n        ('signature', OctetBitString),\n    ]\n\n    _processed_extensions = False\n    _critical_extensions = None\n    _issuer_alt_name_value = None\n    _crl_number_value = None\n    _delta_crl_indicator_value = None\n    _issuing_distribution_point_value = None\n    _authority_key_identifier_value = None\n    _freshest_crl_value = None\n    _authority_information_access_value = None\n    _issuer_cert_urls = None\n    _delta_crl_distribution_points = None\n    _sha1 = None\n    _sha256 = None\n\n    def _set_extensions(self):\n        \"\"\"\n        Sets common named extensions to private attributes and creates a list\n        of critical extensions\n        \"\"\"\n\n        self._critical_extensions = set()\n\n        for extension in self['tbs_cert_list']['crl_extensions']:\n            name = extension['extn_id'].native\n            attribute_name = '_%s_value' % name\n            if hasattr(self, attribute_name):\n                setattr(self, attribute_name, extension['extn_value'].parsed)\n            if extension['critical'].native:\n                self._critical_extensions.add(name)\n\n        self._processed_extensions = True\n\n    @property\n    def critical_extensions(self):\n        \"\"\"\n        Returns a set of the names (or OID if not a known extension) of the\n        extensions marked as critical\n\n        :return:\n            A set of unicode strings\n        \"\"\"\n\n        if not self._processed_extensions:\n            self._set_extensions()\n        return self._critical_extensions\n\n    @property\n    def issuer_alt_name_value(self):\n        \"\"\"\n        This extension allows associating one or more alternative names with\n        the issuer of the CRL.\n\n        :return:\n            None or an x509.GeneralNames object\n        \"\"\"\n\n        if self._processed_extensions is False:\n            self._set_extensions()\n        return self._issuer_alt_name_value\n\n    @property\n    def crl_number_value(self):\n        \"\"\"\n        This extension adds a monotonically increasing number to the CRL and is\n        used to distinguish different versions of the CRL.\n\n        :return:\n            None or an Integer object\n        \"\"\"\n\n        if self._processed_extensions is False:\n            self._set_extensions()\n        return self._crl_number_value\n\n    @property\n    def delta_crl_indicator_value(self):\n        \"\"\"\n        This extension indicates a CRL is a delta CRL, and contains the CRL\n        number of the base CRL that it is a delta from.\n\n        :return:\n            None or an Integer object\n        \"\"\"\n\n        if self._processed_extensions is False:\n            self._set_extensions()\n        return self._delta_crl_indicator_value\n\n    @property\n    def issuing_distribution_point_value(self):\n        \"\"\"\n        This extension includes information about what types of revocations\n        and certificates are part of the CRL.\n\n        :return:\n            None or an IssuingDistributionPoint object\n        \"\"\"\n\n        if self._processed_extensions is False:\n            self._set_extensions()\n        return self._issuing_distribution_point_value\n\n    @property\n    def authority_key_identifier_value(self):\n        \"\"\"\n        This extension helps in identifying the public key with which to\n        validate the authenticity of the CRL.\n\n        :return:\n            None or an AuthorityKeyIdentifier object\n        \"\"\"\n\n        if self._processed_extensions is False:\n            self._set_extensions()\n        return self._authority_key_identifier_value\n\n    @property\n    def freshest_crl_value(self):\n        \"\"\"\n        This extension is used in complete CRLs to indicate where a delta CRL\n        may be located.\n\n        :return:\n            None or a CRLDistributionPoints object\n        \"\"\"\n\n        if self._processed_extensions is False:\n            self._set_extensions()\n        return self._freshest_crl_value\n\n    @property\n    def authority_information_access_value(self):\n        \"\"\"\n        This extension is used to provide a URL with which to download the\n        certificate used to sign this CRL.\n\n        :return:\n            None or an AuthorityInfoAccessSyntax object\n        \"\"\"\n\n        if self._processed_extensions is False:\n            self._set_extensions()\n        return self._authority_information_access_value\n\n    @property\n    def issuer(self):\n        \"\"\"\n        :return:\n            An asn1crypto.x509.Name object for the issuer of the CRL\n        \"\"\"\n\n        return self['tbs_cert_list']['issuer']\n\n    @property\n    def authority_key_identifier(self):\n        \"\"\"\n        :return:\n            None or a byte string of the key_identifier from the authority key\n            identifier extension\n        \"\"\"\n\n        if not self.authority_key_identifier_value:\n            return None\n\n        return self.authority_key_identifier_value['key_identifier'].native\n\n    @property\n    def issuer_cert_urls(self):\n        \"\"\"\n        :return:\n            A list of unicode strings that are URLs that should contain either\n            an individual DER-encoded X.509 certificate, or a DER-encoded CMS\n            message containing multiple certificates\n        \"\"\"\n\n        if self._issuer_cert_urls is None:\n            self._issuer_cert_urls = []\n            if self.authority_information_access_value:\n                for entry in self.authority_information_access_value:\n                    if entry['access_method'].native == 'ca_issuers':\n                        location = entry['access_location']\n                        if location.name != 'uniform_resource_identifier':\n                            continue\n                        url = location.native\n                        if url.lower()[0:7] == 'http://':\n                            self._issuer_cert_urls.append(url)\n        return self._issuer_cert_urls\n\n    @property\n    def delta_crl_distribution_points(self):\n        \"\"\"\n        Returns delta CRL URLs - only applies to complete CRLs\n\n        :return:\n            A list of zero or more DistributionPoint objects\n        \"\"\"\n\n        if self._delta_crl_distribution_points is None:\n            self._delta_crl_distribution_points = []\n\n            if self.freshest_crl_value is not None:\n                for distribution_point in self.freshest_crl_value:\n                    distribution_point_name = distribution_point['distribution_point']\n                    # RFC 5280 indicates conforming CA should not use the relative form\n                    if distribution_point_name.name == 'name_relative_to_crl_issuer':\n                        continue\n                    # This library is currently only concerned with HTTP-based CRLs\n                    for general_name in distribution_point_name.chosen:\n                        if general_name.name == 'uniform_resource_identifier':\n                            self._delta_crl_distribution_points.append(distribution_point)\n\n        return self._delta_crl_distribution_points\n\n    @property\n    def signature(self):\n        \"\"\"\n        :return:\n            A byte string of the signature\n        \"\"\"\n\n        return self['signature'].native\n\n    @property\n    def sha1(self):\n        \"\"\"\n        :return:\n            The SHA1 hash of the DER-encoded bytes of this certificate list\n        \"\"\"\n\n        if self._sha1 is None:\n            self._sha1 = hashlib.sha1(self.dump()).digest()\n        return self._sha1\n\n    @property\n    def sha256(self):\n        \"\"\"\n        :return:\n            The SHA-256 hash of the DER-encoded bytes of this certificate list\n        \"\"\"\n\n        if self._sha256 is None:\n            self._sha256 = hashlib.sha256(self.dump()).digest()\n        return self._sha256\n"
  },
  {
    "path": "code/default/lib/noarch/asn1crypto/csr.py",
    "content": "# coding: utf-8\n\n\"\"\"\nASN.1 type classes for certificate signing requests (CSR). Exports the\nfollowing items:\n\n - CertificationRequest()\n\nOther type classes are defined that help compose the types listed above.\n\"\"\"\n\nfrom __future__ import unicode_literals, division, absolute_import, print_function\n\nfrom .algos import SignedDigestAlgorithm\nfrom .core import (\n    Any,\n    BitString,\n    BMPString,\n    Integer,\n    ObjectIdentifier,\n    OctetBitString,\n    Sequence,\n    SetOf,\n    UTF8String\n)\nfrom .keys import PublicKeyInfo\nfrom .x509 import DirectoryString, Extensions, Name\n\n\n# The structures in this file are taken from https://tools.ietf.org/html/rfc2986\n# and https://tools.ietf.org/html/rfc2985\n\n\nclass Version(Integer):\n    _map = {\n        0: 'v1',\n    }\n\n\nclass CSRAttributeType(ObjectIdentifier):\n    _map = {\n        '1.2.840.113549.1.9.7': 'challenge_password',\n        '1.2.840.113549.1.9.9': 'extended_certificate_attributes',\n        '1.2.840.113549.1.9.14': 'extension_request',\n        # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-wcce/a5eaae36-e9f3-4dc5-a687-bfa7115954f1\n        '1.3.6.1.4.1.311.13.2.2': 'microsoft_enrollment_csp_provider',\n        # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-wcce/7c677cba-030d-48be-ba2b-01e407705f34\n        '1.3.6.1.4.1.311.13.2.3': 'microsoft_os_version',\n        # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-wcce/64e5ff6d-c6dd-4578-92f7-b3d895f9b9c7\n        '1.3.6.1.4.1.311.21.20': 'microsoft_request_client_info',\n    }\n\n\nclass SetOfDirectoryString(SetOf):\n    _child_spec = DirectoryString\n\n\nclass Attribute(Sequence):\n    _fields = [\n        ('type', ObjectIdentifier),\n        ('values', SetOf, {'spec': Any}),\n    ]\n\n\nclass SetOfAttributes(SetOf):\n    _child_spec = Attribute\n\n\nclass SetOfExtensions(SetOf):\n    _child_spec = Extensions\n\n\nclass MicrosoftEnrollmentCSProvider(Sequence):\n    _fields = [\n        ('keyspec', Integer),\n        ('cspname', BMPString),  # cryptographic service provider name\n        ('signature', BitString),\n    ]\n\n\nclass SetOfMicrosoftEnrollmentCSProvider(SetOf):\n    _child_spec = MicrosoftEnrollmentCSProvider\n\n\nclass MicrosoftRequestClientInfo(Sequence):\n    _fields = [\n        ('clientid', Integer),\n        ('machinename', UTF8String),\n        ('username', UTF8String),\n        ('processname', UTF8String),\n    ]\n\n\nclass SetOfMicrosoftRequestClientInfo(SetOf):\n    _child_spec = MicrosoftRequestClientInfo\n\n\nclass CRIAttribute(Sequence):\n    _fields = [\n        ('type', CSRAttributeType),\n        ('values', Any),\n    ]\n\n    _oid_pair = ('type', 'values')\n    _oid_specs = {\n        'challenge_password': SetOfDirectoryString,\n        'extended_certificate_attributes': SetOfAttributes,\n        'extension_request': SetOfExtensions,\n        'microsoft_enrollment_csp_provider': SetOfMicrosoftEnrollmentCSProvider,\n        'microsoft_os_version': SetOfDirectoryString,\n        'microsoft_request_client_info': SetOfMicrosoftRequestClientInfo,\n    }\n\n\nclass CRIAttributes(SetOf):\n    _child_spec = CRIAttribute\n\n\nclass CertificationRequestInfo(Sequence):\n    _fields = [\n        ('version', Version),\n        ('subject', Name),\n        ('subject_pk_info', PublicKeyInfo),\n        ('attributes', CRIAttributes, {'implicit': 0, 'optional': True}),\n    ]\n\n\nclass CertificationRequest(Sequence):\n    _fields = [\n        ('certification_request_info', CertificationRequestInfo),\n        ('signature_algorithm', SignedDigestAlgorithm),\n        ('signature', OctetBitString),\n    ]\n"
  },
  {
    "path": "code/default/lib/noarch/asn1crypto/keys.py",
    "content": "# coding: utf-8\n\n\"\"\"\nASN.1 type classes for public and private keys. Exports the following items:\n\n - DSAPrivateKey()\n - ECPrivateKey()\n - EncryptedPrivateKeyInfo()\n - PrivateKeyInfo()\n - PublicKeyInfo()\n - RSAPrivateKey()\n - RSAPublicKey()\n\nOther type classes are defined that help compose the types listed above.\n\"\"\"\n\nfrom __future__ import unicode_literals, division, absolute_import, print_function\n\nimport hashlib\nimport math\n\nfrom ._errors import unwrap, APIException\nfrom ._types import type_name, byte_cls\nfrom .algos import _ForceNullParameters, DigestAlgorithm, EncryptionAlgorithm, RSAESOAEPParams, RSASSAPSSParams\nfrom .core import (\n    Any,\n    Asn1Value,\n    BitString,\n    Choice,\n    Integer,\n    IntegerOctetString,\n    Null,\n    ObjectIdentifier,\n    OctetBitString,\n    OctetString,\n    ParsableOctetString,\n    ParsableOctetBitString,\n    Sequence,\n    SequenceOf,\n    SetOf,\n)\nfrom .util import int_from_bytes, int_to_bytes\n\n\nclass OtherPrimeInfo(Sequence):\n    \"\"\"\n    Source: https://tools.ietf.org/html/rfc3447#page-46\n    \"\"\"\n\n    _fields = [\n        ('prime', Integer),\n        ('exponent', Integer),\n        ('coefficient', Integer),\n    ]\n\n\nclass OtherPrimeInfos(SequenceOf):\n    \"\"\"\n    Source: https://tools.ietf.org/html/rfc3447#page-46\n    \"\"\"\n\n    _child_spec = OtherPrimeInfo\n\n\nclass RSAPrivateKeyVersion(Integer):\n    \"\"\"\n    Original Name: Version\n    Source: https://tools.ietf.org/html/rfc3447#page-45\n    \"\"\"\n\n    _map = {\n        0: 'two-prime',\n        1: 'multi',\n    }\n\n\nclass RSAPrivateKey(Sequence):\n    \"\"\"\n    Source: https://tools.ietf.org/html/rfc3447#page-45\n    \"\"\"\n\n    _fields = [\n        ('version', RSAPrivateKeyVersion),\n        ('modulus', Integer),\n        ('public_exponent', Integer),\n        ('private_exponent', Integer),\n        ('prime1', Integer),\n        ('prime2', Integer),\n        ('exponent1', Integer),\n        ('exponent2', Integer),\n        ('coefficient', Integer),\n        ('other_prime_infos', OtherPrimeInfos, {'optional': True})\n    ]\n\n\nclass RSAPublicKey(Sequence):\n    \"\"\"\n    Source: https://tools.ietf.org/html/rfc3447#page-44\n    \"\"\"\n\n    _fields = [\n        ('modulus', Integer),\n        ('public_exponent', Integer)\n    ]\n\n\nclass DSAPrivateKey(Sequence):\n    \"\"\"\n    The ASN.1 structure that OpenSSL uses to store a DSA private key that is\n    not part of a PKCS#8 structure. Reversed engineered from english-language\n    description on linked OpenSSL documentation page.\n\n    Original Name: None\n    Source: https://www.openssl.org/docs/apps/dsa.html\n    \"\"\"\n\n    _fields = [\n        ('version', Integer),\n        ('p', Integer),\n        ('q', Integer),\n        ('g', Integer),\n        ('public_key', Integer),\n        ('private_key', Integer),\n    ]\n\n\nclass _ECPoint():\n    \"\"\"\n    In both PublicKeyInfo and PrivateKeyInfo, the EC public key is a byte\n    string that is encoded as a bit string. This class adds convenience\n    methods for converting to and from the byte string to a pair of integers\n    that are the X and Y coordinates.\n    \"\"\"\n\n    @classmethod\n    def from_coords(cls, x, y):\n        \"\"\"\n        Creates an ECPoint object from the X and Y integer coordinates of the\n        point\n\n        :param x:\n            The X coordinate, as an integer\n\n        :param y:\n            The Y coordinate, as an integer\n\n        :return:\n            An ECPoint object\n        \"\"\"\n\n        x_bytes = int(math.ceil(math.log(x, 2) / 8.0))\n        y_bytes = int(math.ceil(math.log(y, 2) / 8.0))\n\n        num_bytes = max(x_bytes, y_bytes)\n\n        byte_string = b'\\x04'\n        byte_string += int_to_bytes(x, width=num_bytes)\n        byte_string += int_to_bytes(y, width=num_bytes)\n\n        return cls(byte_string)\n\n    def to_coords(self):\n        \"\"\"\n        Returns the X and Y coordinates for this EC point, as native Python\n        integers\n\n        :return:\n            A 2-element tuple containing integers (X, Y)\n        \"\"\"\n\n        data = self.native\n        first_byte = data[0:1]\n\n        # Uncompressed\n        if first_byte == b'\\x04':\n            remaining = data[1:]\n            field_len = len(remaining) // 2\n            x = int_from_bytes(remaining[0:field_len])\n            y = int_from_bytes(remaining[field_len:])\n            return (x, y)\n\n        if first_byte not in set([b'\\x02', b'\\x03']):\n            raise ValueError(unwrap(\n                '''\n                Invalid EC public key - first byte is incorrect\n                '''\n            ))\n\n        raise ValueError(unwrap(\n            '''\n            Compressed representations of EC public keys are not supported due\n            to patent US6252960\n            '''\n        ))\n\n\nclass ECPoint(OctetString, _ECPoint):\n\n    pass\n\n\nclass ECPointBitString(OctetBitString, _ECPoint):\n\n    pass\n\n\nclass SpecifiedECDomainVersion(Integer):\n    \"\"\"\n    Source: http://www.secg.org/sec1-v2.pdf page 104\n    \"\"\"\n    _map = {\n        1: 'ecdpVer1',\n        2: 'ecdpVer2',\n        3: 'ecdpVer3',\n    }\n\n\nclass FieldType(ObjectIdentifier):\n    \"\"\"\n    Original Name: None\n    Source: http://www.secg.org/sec1-v2.pdf page 101\n    \"\"\"\n\n    _map = {\n        '1.2.840.10045.1.1': 'prime_field',\n        '1.2.840.10045.1.2': 'characteristic_two_field',\n    }\n\n\nclass CharacteristicTwoBasis(ObjectIdentifier):\n    \"\"\"\n    Original Name: None\n    Source: http://www.secg.org/sec1-v2.pdf page 102\n    \"\"\"\n\n    _map = {\n        '1.2.840.10045.1.2.1.1': 'gn_basis',\n        '1.2.840.10045.1.2.1.2': 'tp_basis',\n        '1.2.840.10045.1.2.1.3': 'pp_basis',\n    }\n\n\nclass Pentanomial(Sequence):\n    \"\"\"\n    Source: http://www.secg.org/sec1-v2.pdf page 102\n    \"\"\"\n\n    _fields = [\n        ('k1', Integer),\n        ('k2', Integer),\n        ('k3', Integer),\n    ]\n\n\nclass CharacteristicTwo(Sequence):\n    \"\"\"\n    Original Name: Characteristic-two\n    Source: http://www.secg.org/sec1-v2.pdf page 101\n    \"\"\"\n\n    _fields = [\n        ('m', Integer),\n        ('basis', CharacteristicTwoBasis),\n        ('parameters', Any),\n    ]\n\n    _oid_pair = ('basis', 'parameters')\n    _oid_specs = {\n        'gn_basis': Null,\n        'tp_basis': Integer,\n        'pp_basis': Pentanomial,\n    }\n\n\nclass FieldID(Sequence):\n    \"\"\"\n    Source: http://www.secg.org/sec1-v2.pdf page 100\n    \"\"\"\n\n    _fields = [\n        ('field_type', FieldType),\n        ('parameters', Any),\n    ]\n\n    _oid_pair = ('field_type', 'parameters')\n    _oid_specs = {\n        'prime_field': Integer,\n        'characteristic_two_field': CharacteristicTwo,\n    }\n\n\nclass Curve(Sequence):\n    \"\"\"\n    Source: http://www.secg.org/sec1-v2.pdf page 104\n    \"\"\"\n\n    _fields = [\n        ('a', OctetString),\n        ('b', OctetString),\n        ('seed', OctetBitString, {'optional': True}),\n    ]\n\n\nclass SpecifiedECDomain(Sequence):\n    \"\"\"\n    Source: http://www.secg.org/sec1-v2.pdf page 103\n    \"\"\"\n\n    _fields = [\n        ('version', SpecifiedECDomainVersion),\n        ('field_id', FieldID),\n        ('curve', Curve),\n        ('base', ECPoint),\n        ('order', Integer),\n        ('cofactor', Integer, {'optional': True}),\n        ('hash', DigestAlgorithm, {'optional': True}),\n    ]\n\n\nclass NamedCurve(ObjectIdentifier):\n    \"\"\"\n    Various named curves\n\n    Original Name: None\n    Source: https://tools.ietf.org/html/rfc3279#page-23,\n            https://tools.ietf.org/html/rfc5480#page-5\n    \"\"\"\n\n    _map = {\n        # https://tools.ietf.org/html/rfc3279#page-23\n        '1.2.840.10045.3.0.1': 'c2pnb163v1',\n        '1.2.840.10045.3.0.2': 'c2pnb163v2',\n        '1.2.840.10045.3.0.3': 'c2pnb163v3',\n        '1.2.840.10045.3.0.4': 'c2pnb176w1',\n        '1.2.840.10045.3.0.5': 'c2tnb191v1',\n        '1.2.840.10045.3.0.6': 'c2tnb191v2',\n        '1.2.840.10045.3.0.7': 'c2tnb191v3',\n        '1.2.840.10045.3.0.8': 'c2onb191v4',\n        '1.2.840.10045.3.0.9': 'c2onb191v5',\n        '1.2.840.10045.3.0.10': 'c2pnb208w1',\n        '1.2.840.10045.3.0.11': 'c2tnb239v1',\n        '1.2.840.10045.3.0.12': 'c2tnb239v2',\n        '1.2.840.10045.3.0.13': 'c2tnb239v3',\n        '1.2.840.10045.3.0.14': 'c2onb239v4',\n        '1.2.840.10045.3.0.15': 'c2onb239v5',\n        '1.2.840.10045.3.0.16': 'c2pnb272w1',\n        '1.2.840.10045.3.0.17': 'c2pnb304w1',\n        '1.2.840.10045.3.0.18': 'c2tnb359v1',\n        '1.2.840.10045.3.0.19': 'c2pnb368w1',\n        '1.2.840.10045.3.0.20': 'c2tnb431r1',\n        '1.2.840.10045.3.1.2': 'prime192v2',\n        '1.2.840.10045.3.1.3': 'prime192v3',\n        '1.2.840.10045.3.1.4': 'prime239v1',\n        '1.2.840.10045.3.1.5': 'prime239v2',\n        '1.2.840.10045.3.1.6': 'prime239v3',\n        # https://tools.ietf.org/html/rfc5480#page-5\n        # http://www.secg.org/SEC2-Ver-1.0.pdf\n        '1.2.840.10045.3.1.1': 'secp192r1',\n        '1.2.840.10045.3.1.7': 'secp256r1',\n        '1.3.132.0.1': 'sect163k1',\n        '1.3.132.0.2': 'sect163r1',\n        '1.3.132.0.3': 'sect239k1',\n        '1.3.132.0.4': 'sect113r1',\n        '1.3.132.0.5': 'sect113r2',\n        '1.3.132.0.6': 'secp112r1',\n        '1.3.132.0.7': 'secp112r2',\n        '1.3.132.0.8': 'secp160r1',\n        '1.3.132.0.9': 'secp160k1',\n        '1.3.132.0.10': 'secp256k1',\n        '1.3.132.0.15': 'sect163r2',\n        '1.3.132.0.16': 'sect283k1',\n        '1.3.132.0.17': 'sect283r1',\n        '1.3.132.0.22': 'sect131r1',\n        '1.3.132.0.23': 'sect131r2',\n        '1.3.132.0.24': 'sect193r1',\n        '1.3.132.0.25': 'sect193r2',\n        '1.3.132.0.26': 'sect233k1',\n        '1.3.132.0.27': 'sect233r1',\n        '1.3.132.0.28': 'secp128r1',\n        '1.3.132.0.29': 'secp128r2',\n        '1.3.132.0.30': 'secp160r2',\n        '1.3.132.0.31': 'secp192k1',\n        '1.3.132.0.32': 'secp224k1',\n        '1.3.132.0.33': 'secp224r1',\n        '1.3.132.0.34': 'secp384r1',\n        '1.3.132.0.35': 'secp521r1',\n        '1.3.132.0.36': 'sect409k1',\n        '1.3.132.0.37': 'sect409r1',\n        '1.3.132.0.38': 'sect571k1',\n        '1.3.132.0.39': 'sect571r1',\n        # https://tools.ietf.org/html/rfc5639#section-4.1\n        '1.3.36.3.3.2.8.1.1.1': 'brainpoolp160r1',\n        '1.3.36.3.3.2.8.1.1.2': 'brainpoolp160t1',\n        '1.3.36.3.3.2.8.1.1.3': 'brainpoolp192r1',\n        '1.3.36.3.3.2.8.1.1.4': 'brainpoolp192t1',\n        '1.3.36.3.3.2.8.1.1.5': 'brainpoolp224r1',\n        '1.3.36.3.3.2.8.1.1.6': 'brainpoolp224t1',\n        '1.3.36.3.3.2.8.1.1.7': 'brainpoolp256r1',\n        '1.3.36.3.3.2.8.1.1.8': 'brainpoolp256t1',\n        '1.3.36.3.3.2.8.1.1.9': 'brainpoolp320r1',\n        '1.3.36.3.3.2.8.1.1.10': 'brainpoolp320t1',\n        '1.3.36.3.3.2.8.1.1.11': 'brainpoolp384r1',\n        '1.3.36.3.3.2.8.1.1.12': 'brainpoolp384t1',\n        '1.3.36.3.3.2.8.1.1.13': 'brainpoolp512r1',\n        '1.3.36.3.3.2.8.1.1.14': 'brainpoolp512t1',\n    }\n\n    _key_sizes = {\n        # Order values used to compute these sourced from\n        # http://cr.openjdk.java.net/~vinnie/7194075/webrev-3/src/share/classes/sun/security/ec/CurveDB.java.html\n        '1.2.840.10045.3.0.1': 21,\n        '1.2.840.10045.3.0.2': 21,\n        '1.2.840.10045.3.0.3': 21,\n        '1.2.840.10045.3.0.4': 21,\n        '1.2.840.10045.3.0.5': 24,\n        '1.2.840.10045.3.0.6': 24,\n        '1.2.840.10045.3.0.7': 24,\n        '1.2.840.10045.3.0.8': 24,\n        '1.2.840.10045.3.0.9': 24,\n        '1.2.840.10045.3.0.10': 25,\n        '1.2.840.10045.3.0.11': 30,\n        '1.2.840.10045.3.0.12': 30,\n        '1.2.840.10045.3.0.13': 30,\n        '1.2.840.10045.3.0.14': 30,\n        '1.2.840.10045.3.0.15': 30,\n        '1.2.840.10045.3.0.16': 33,\n        '1.2.840.10045.3.0.17': 37,\n        '1.2.840.10045.3.0.18': 45,\n        '1.2.840.10045.3.0.19': 45,\n        '1.2.840.10045.3.0.20': 53,\n        '1.2.840.10045.3.1.2': 24,\n        '1.2.840.10045.3.1.3': 24,\n        '1.2.840.10045.3.1.4': 30,\n        '1.2.840.10045.3.1.5': 30,\n        '1.2.840.10045.3.1.6': 30,\n        # Order values used to compute these sourced from\n        # http://www.secg.org/SEC2-Ver-1.0.pdf\n        # ceil(n.bit_length() / 8)\n        '1.2.840.10045.3.1.1': 24,\n        '1.2.840.10045.3.1.7': 32,\n        '1.3.132.0.1': 21,\n        '1.3.132.0.2': 21,\n        '1.3.132.0.3': 30,\n        '1.3.132.0.4': 15,\n        '1.3.132.0.5': 15,\n        '1.3.132.0.6': 14,\n        '1.3.132.0.7': 14,\n        '1.3.132.0.8': 21,\n        '1.3.132.0.9': 21,\n        '1.3.132.0.10': 32,\n        '1.3.132.0.15': 21,\n        '1.3.132.0.16': 36,\n        '1.3.132.0.17': 36,\n        '1.3.132.0.22': 17,\n        '1.3.132.0.23': 17,\n        '1.3.132.0.24': 25,\n        '1.3.132.0.25': 25,\n        '1.3.132.0.26': 29,\n        '1.3.132.0.27': 30,\n        '1.3.132.0.28': 16,\n        '1.3.132.0.29': 16,\n        '1.3.132.0.30': 21,\n        '1.3.132.0.31': 24,\n        '1.3.132.0.32': 29,\n        '1.3.132.0.33': 28,\n        '1.3.132.0.34': 48,\n        '1.3.132.0.35': 66,\n        '1.3.132.0.36': 51,\n        '1.3.132.0.37': 52,\n        '1.3.132.0.38': 72,\n        '1.3.132.0.39': 72,\n        # Order values used to compute these sourced from\n        # https://tools.ietf.org/html/rfc5639#section-3\n        # ceil(q.bit_length() / 8)\n        '1.3.36.3.3.2.8.1.1.1': 20,\n        '1.3.36.3.3.2.8.1.1.2': 20,\n        '1.3.36.3.3.2.8.1.1.3': 24,\n        '1.3.36.3.3.2.8.1.1.4': 24,\n        '1.3.36.3.3.2.8.1.1.5': 28,\n        '1.3.36.3.3.2.8.1.1.6': 28,\n        '1.3.36.3.3.2.8.1.1.7': 32,\n        '1.3.36.3.3.2.8.1.1.8': 32,\n        '1.3.36.3.3.2.8.1.1.9': 40,\n        '1.3.36.3.3.2.8.1.1.10': 40,\n        '1.3.36.3.3.2.8.1.1.11': 48,\n        '1.3.36.3.3.2.8.1.1.12': 48,\n        '1.3.36.3.3.2.8.1.1.13': 64,\n        '1.3.36.3.3.2.8.1.1.14': 64,\n    }\n\n    @classmethod\n    def register(cls, name, oid, key_size):\n        \"\"\"\n        Registers a new named elliptic curve that is not included in the\n        default list of named curves\n\n        :param name:\n            A unicode string of the curve name\n\n        :param oid:\n            A unicode string of the dotted format OID\n\n        :param key_size:\n            An integer of the number of bytes the private key should be\n            encoded to\n        \"\"\"\n\n        cls._map[oid] = name\n        if cls._reverse_map is not None:\n            cls._reverse_map[name] = oid\n        cls._key_sizes[oid] = key_size\n\n\nclass ECDomainParameters(Choice):\n    \"\"\"\n    Source: http://www.secg.org/sec1-v2.pdf page 102\n    \"\"\"\n\n    _alternatives = [\n        ('specified', SpecifiedECDomain),\n        ('named', NamedCurve),\n        ('implicit_ca', Null),\n    ]\n\n    @property\n    def key_size(self):\n        if self.name == 'implicit_ca':\n            raise ValueError(unwrap(\n                '''\n                Unable to calculate key_size from ECDomainParameters\n                that are implicitly defined by the CA key\n                '''\n            ))\n\n        if self.name == 'specified':\n            order = self.chosen['order'].native\n            return math.ceil(math.log(order, 2.0) / 8.0)\n\n        oid = self.chosen.dotted\n        if oid not in NamedCurve._key_sizes:\n            raise ValueError(unwrap(\n                '''\n                The asn1crypto.keys.NamedCurve %s does not have a registered key length,\n                please call asn1crypto.keys.NamedCurve.register()\n                ''',\n                repr(oid)\n            ))\n        return NamedCurve._key_sizes[oid]\n\n\nclass ECPrivateKeyVersion(Integer):\n    \"\"\"\n    Original Name: None\n    Source: http://www.secg.org/sec1-v2.pdf page 108\n    \"\"\"\n\n    _map = {\n        1: 'ecPrivkeyVer1',\n    }\n\n\nclass ECPrivateKey(Sequence):\n    \"\"\"\n    Source: http://www.secg.org/sec1-v2.pdf page 108\n    \"\"\"\n\n    _fields = [\n        ('version', ECPrivateKeyVersion),\n        ('private_key', IntegerOctetString),\n        ('parameters', ECDomainParameters, {'explicit': 0, 'optional': True}),\n        ('public_key', ECPointBitString, {'explicit': 1, 'optional': True}),\n    ]\n\n    # Ensures the key is set to the correct length when encoding\n    _key_size = None\n\n    # This is necessary to ensure the private_key IntegerOctetString is encoded properly\n    def __setitem__(self, key, value):\n        res = super(ECPrivateKey, self).__setitem__(key, value)\n\n        if key == 'private_key':\n            if self._key_size is None:\n                # Infer the key_size from the existing private key if possible\n                pkey_contents = self['private_key'].contents\n                if isinstance(pkey_contents, byte_cls) and len(pkey_contents) > 1:\n                    self.set_key_size(len(self['private_key'].contents))\n\n            elif self._key_size is not None:\n                self._update_key_size()\n\n        elif key == 'parameters' and isinstance(self['parameters'], ECDomainParameters) and \\\n                self['parameters'].name != 'implicit_ca':\n            self.set_key_size(self['parameters'].key_size)\n\n        return res\n\n    def set_key_size(self, key_size):\n        \"\"\"\n        Sets the key_size to ensure the private key is encoded to the proper length\n\n        :param key_size:\n            An integer byte length to encode the private_key to\n        \"\"\"\n\n        self._key_size = key_size\n        self._update_key_size()\n\n    def _update_key_size(self):\n        \"\"\"\n        Ensure the private_key explicit encoding width is set\n        \"\"\"\n\n        if self._key_size is not None and isinstance(self['private_key'], IntegerOctetString):\n            self['private_key'].set_encoded_width(self._key_size)\n\n\nclass DSAParams(Sequence):\n    \"\"\"\n    Parameters for a DSA public or private key\n\n    Original Name: Dss-Parms\n    Source: https://tools.ietf.org/html/rfc3279#page-9\n    \"\"\"\n\n    _fields = [\n        ('p', Integer),\n        ('q', Integer),\n        ('g', Integer),\n    ]\n\n\nclass Attribute(Sequence):\n    \"\"\"\n    Source: https://www.itu.int/rec/dologin_pub.asp?lang=e&id=T-REC-X.501-198811-S!!PDF-E&type=items page 8\n    \"\"\"\n\n    _fields = [\n        ('type', ObjectIdentifier),\n        ('values', SetOf, {'spec': Any}),\n    ]\n\n\nclass Attributes(SetOf):\n    \"\"\"\n    Source: https://tools.ietf.org/html/rfc5208#page-3\n    \"\"\"\n\n    _child_spec = Attribute\n\n\nclass PrivateKeyAlgorithmId(ObjectIdentifier):\n    \"\"\"\n    These OIDs for various public keys are reused when storing private keys\n    inside of a PKCS#8 structure\n\n    Original Name: None\n    Source: https://tools.ietf.org/html/rfc3279\n    \"\"\"\n\n    _map = {\n        # https://tools.ietf.org/html/rfc3279#page-19\n        '1.2.840.113549.1.1.1': 'rsa',\n        # https://tools.ietf.org/html/rfc4055#page-8\n        '1.2.840.113549.1.1.10': 'rsassa_pss',\n        # https://tools.ietf.org/html/rfc3279#page-18\n        '1.2.840.10040.4.1': 'dsa',\n        # https://tools.ietf.org/html/rfc3279#page-13\n        '1.2.840.10045.2.1': 'ec',\n        # https://tools.ietf.org/html/rfc8410#section-9\n        '1.3.101.110': 'x25519',\n        '1.3.101.111': 'x448',\n        '1.3.101.112': 'ed25519',\n        '1.3.101.113': 'ed448',\n    }\n\n\nclass PrivateKeyAlgorithm(_ForceNullParameters, Sequence):\n    \"\"\"\n    Original Name: PrivateKeyAlgorithmIdentifier\n    Source: https://tools.ietf.org/html/rfc5208#page-3\n    \"\"\"\n\n    _fields = [\n        ('algorithm', PrivateKeyAlgorithmId),\n        ('parameters', Any, {'optional': True}),\n    ]\n\n    _oid_pair = ('algorithm', 'parameters')\n    _oid_specs = {\n        'dsa': DSAParams,\n        'ec': ECDomainParameters,\n        'rsassa_pss': RSASSAPSSParams,\n    }\n\n\nclass PrivateKeyInfo(Sequence):\n    \"\"\"\n    Source: https://tools.ietf.org/html/rfc5208#page-3\n    \"\"\"\n\n    _fields = [\n        ('version', Integer),\n        ('private_key_algorithm', PrivateKeyAlgorithm),\n        ('private_key', ParsableOctetString),\n        ('attributes', Attributes, {'implicit': 0, 'optional': True}),\n    ]\n\n    def _private_key_spec(self):\n        algorithm = self['private_key_algorithm']['algorithm'].native\n        return {\n            'rsa': RSAPrivateKey,\n            'rsassa_pss': RSAPrivateKey,\n            'dsa': Integer,\n            'ec': ECPrivateKey,\n            # These should be treated as opaque octet strings according\n            # to RFC 8410\n            'x25519': OctetString,\n            'x448': OctetString,\n            'ed25519': OctetString,\n            'ed448': OctetString,\n        }[algorithm]\n\n    _spec_callbacks = {\n        'private_key': _private_key_spec\n    }\n\n    _algorithm = None\n    _bit_size = None\n    _public_key = None\n    _fingerprint = None\n\n    @classmethod\n    def wrap(cls, private_key, algorithm):\n        \"\"\"\n        Wraps a private key in a PrivateKeyInfo structure\n\n        :param private_key:\n            A byte string or Asn1Value object of the private key\n\n        :param algorithm:\n            A unicode string of \"rsa\", \"dsa\" or \"ec\"\n\n        :return:\n            A PrivateKeyInfo object\n        \"\"\"\n\n        if not isinstance(private_key, byte_cls) and not isinstance(private_key, Asn1Value):\n            raise TypeError(unwrap(\n                '''\n                private_key must be a byte string or Asn1Value, not %s\n                ''',\n                type_name(private_key)\n            ))\n\n        if algorithm == 'rsa' or algorithm == 'rsassa_pss':\n            if not isinstance(private_key, RSAPrivateKey):\n                private_key = RSAPrivateKey.load(private_key)\n            params = Null()\n        elif algorithm == 'dsa':\n            if not isinstance(private_key, DSAPrivateKey):\n                private_key = DSAPrivateKey.load(private_key)\n            params = DSAParams()\n            params['p'] = private_key['p']\n            params['q'] = private_key['q']\n            params['g'] = private_key['g']\n            public_key = private_key['public_key']\n            private_key = private_key['private_key']\n        elif algorithm == 'ec':\n            if not isinstance(private_key, ECPrivateKey):\n                private_key = ECPrivateKey.load(private_key)\n            else:\n                private_key = private_key.copy()\n            params = private_key['parameters']\n            del private_key['parameters']\n        else:\n            raise ValueError(unwrap(\n                '''\n                algorithm must be one of \"rsa\", \"dsa\", \"ec\", not %s\n                ''',\n                repr(algorithm)\n            ))\n\n        private_key_algo = PrivateKeyAlgorithm()\n        private_key_algo['algorithm'] = PrivateKeyAlgorithmId(algorithm)\n        private_key_algo['parameters'] = params\n\n        container = cls()\n        container._algorithm = algorithm\n        container['version'] = Integer(0)\n        container['private_key_algorithm'] = private_key_algo\n        container['private_key'] = private_key\n\n        # Here we save the DSA public key if possible since it is not contained\n        # within the PKCS#8 structure for a DSA key\n        if algorithm == 'dsa':\n            container._public_key = public_key\n\n        return container\n\n    # This is necessary to ensure any contained ECPrivateKey is the\n    # correct size\n    def __setitem__(self, key, value):\n        res = super(PrivateKeyInfo, self).__setitem__(key, value)\n\n        algorithm = self['private_key_algorithm']\n\n        # When possible, use the parameter info to make sure the private key encoding\n        # retains any necessary leading bytes, instead of them being dropped\n        if (key == 'private_key_algorithm' or key == 'private_key') and \\\n                algorithm['algorithm'].native == 'ec' and \\\n                isinstance(algorithm['parameters'], ECDomainParameters) and \\\n                algorithm['parameters'].name != 'implicit_ca' and \\\n                isinstance(self['private_key'], ParsableOctetString) and \\\n                isinstance(self['private_key'].parsed, ECPrivateKey):\n            self['private_key'].parsed.set_key_size(algorithm['parameters'].key_size)\n\n        return res\n\n    def unwrap(self):\n        \"\"\"\n        Unwraps the private key into an RSAPrivateKey, DSAPrivateKey or\n        ECPrivateKey object\n\n        :return:\n            An RSAPrivateKey, DSAPrivateKey or ECPrivateKey object\n        \"\"\"\n\n        raise APIException(\n            'asn1crypto.keys.PrivateKeyInfo().unwrap() has been removed, '\n            'please use oscrypto.asymmetric.PrivateKey().unwrap() instead')\n\n    @property\n    def curve(self):\n        \"\"\"\n        Returns information about the curve used for an EC key\n\n        :raises:\n            ValueError - when the key is not an EC key\n\n        :return:\n            A two-element tuple, with the first element being a unicode string\n            of \"implicit_ca\", \"specified\" or \"named\". If the first element is\n            \"implicit_ca\", the second is None. If \"specified\", the second is\n            an OrderedDict that is the native version of SpecifiedECDomain. If\n            \"named\", the second is a unicode string of the curve name.\n        \"\"\"\n\n        if self.algorithm != 'ec':\n            raise ValueError(unwrap(\n                '''\n                Only EC keys have a curve, this key is %s\n                ''',\n                self.algorithm.upper()\n            ))\n\n        params = self['private_key_algorithm']['parameters']\n        chosen = params.chosen\n\n        if params.name == 'implicit_ca':\n            value = None\n        else:\n            value = chosen.native\n\n        return (params.name, value)\n\n    @property\n    def hash_algo(self):\n        \"\"\"\n        Returns the name of the family of hash algorithms used to generate a\n        DSA key\n\n        :raises:\n            ValueError - when the key is not a DSA key\n\n        :return:\n            A unicode string of \"sha1\" or \"sha2\"\n        \"\"\"\n\n        if self.algorithm != 'dsa':\n            raise ValueError(unwrap(\n                '''\n                Only DSA keys are generated using a hash algorithm, this key is\n                %s\n                ''',\n                self.algorithm.upper()\n            ))\n\n        byte_len = math.log(self['private_key_algorithm']['parameters']['q'].native, 2) / 8\n\n        return 'sha1' if byte_len <= 20 else 'sha2'\n\n    @property\n    def algorithm(self):\n        \"\"\"\n        :return:\n            A unicode string of \"rsa\", \"rsassa_pss\", \"dsa\" or \"ec\"\n        \"\"\"\n\n        if self._algorithm is None:\n            self._algorithm = self['private_key_algorithm']['algorithm'].native\n        return self._algorithm\n\n    @property\n    def bit_size(self):\n        \"\"\"\n        :return:\n            The bit size of the private key, as an integer\n        \"\"\"\n\n        if self._bit_size is None:\n            if self.algorithm == 'rsa' or self.algorithm == 'rsassa_pss':\n                prime = self['private_key'].parsed['modulus'].native\n            elif self.algorithm == 'dsa':\n                prime = self['private_key_algorithm']['parameters']['p'].native\n            elif self.algorithm == 'ec':\n                prime = self['private_key'].parsed['private_key'].native\n            self._bit_size = int(math.ceil(math.log(prime, 2)))\n            modulus = self._bit_size % 8\n            if modulus != 0:\n                self._bit_size += 8 - modulus\n        return self._bit_size\n\n    @property\n    def byte_size(self):\n        \"\"\"\n        :return:\n            The byte size of the private key, as an integer\n        \"\"\"\n\n        return int(math.ceil(self.bit_size / 8))\n\n    @property\n    def public_key(self):\n        \"\"\"\n        :return:\n            If an RSA key, an RSAPublicKey object. If a DSA key, an Integer\n            object. If an EC key, an ECPointBitString object.\n        \"\"\"\n\n        raise APIException(\n            'asn1crypto.keys.PrivateKeyInfo().public_key has been removed, '\n            'please use oscrypto.asymmetric.PrivateKey().public_key.unwrap() instead')\n\n    @property\n    def public_key_info(self):\n        \"\"\"\n        :return:\n            A PublicKeyInfo object derived from this private key.\n        \"\"\"\n\n        raise APIException(\n            'asn1crypto.keys.PrivateKeyInfo().public_key_info has been removed, '\n            'please use oscrypto.asymmetric.PrivateKey().public_key.asn1 instead')\n\n    @property\n    def fingerprint(self):\n        \"\"\"\n        Creates a fingerprint that can be compared with a public key to see if\n        the two form a pair.\n\n        This fingerprint is not compatible with fingerprints generated by any\n        other software.\n\n        :return:\n            A byte string that is a sha256 hash of selected components (based\n            on the key type)\n        \"\"\"\n\n        raise APIException(\n            'asn1crypto.keys.PrivateKeyInfo().fingerprint has been removed, '\n            'please use oscrypto.asymmetric.PrivateKey().fingerprint instead')\n\n\nclass EncryptedPrivateKeyInfo(Sequence):\n    \"\"\"\n    Source: https://tools.ietf.org/html/rfc5208#page-4\n    \"\"\"\n\n    _fields = [\n        ('encryption_algorithm', EncryptionAlgorithm),\n        ('encrypted_data', OctetString),\n    ]\n\n\n# These structures are from https://tools.ietf.org/html/rfc3279\n\nclass ValidationParms(Sequence):\n    \"\"\"\n    Source: https://tools.ietf.org/html/rfc3279#page-10\n    \"\"\"\n\n    _fields = [\n        ('seed', BitString),\n        ('pgen_counter', Integer),\n    ]\n\n\nclass DomainParameters(Sequence):\n    \"\"\"\n    Source: https://tools.ietf.org/html/rfc3279#page-10\n    \"\"\"\n\n    _fields = [\n        ('p', Integer),\n        ('g', Integer),\n        ('q', Integer),\n        ('j', Integer, {'optional': True}),\n        ('validation_params', ValidationParms, {'optional': True}),\n    ]\n\n\nclass PublicKeyAlgorithmId(ObjectIdentifier):\n    \"\"\"\n    Original Name: None\n    Source: https://tools.ietf.org/html/rfc3279\n    \"\"\"\n\n    _map = {\n        # https://tools.ietf.org/html/rfc3279#page-19\n        '1.2.840.113549.1.1.1': 'rsa',\n        # https://tools.ietf.org/html/rfc3447#page-47\n        '1.2.840.113549.1.1.7': 'rsaes_oaep',\n        # https://tools.ietf.org/html/rfc4055#page-8\n        '1.2.840.113549.1.1.10': 'rsassa_pss',\n        # https://tools.ietf.org/html/rfc3279#page-18\n        '1.2.840.10040.4.1': 'dsa',\n        # https://tools.ietf.org/html/rfc3279#page-13\n        '1.2.840.10045.2.1': 'ec',\n        # https://tools.ietf.org/html/rfc3279#page-10\n        '1.2.840.10046.2.1': 'dh',\n        # https://tools.ietf.org/html/rfc8410#section-9\n        '1.3.101.110': 'x25519',\n        '1.3.101.111': 'x448',\n        '1.3.101.112': 'ed25519',\n        '1.3.101.113': 'ed448',\n    }\n\n\nclass PublicKeyAlgorithm(_ForceNullParameters, Sequence):\n    \"\"\"\n    Original Name: AlgorithmIdentifier\n    Source: https://tools.ietf.org/html/rfc5280#page-18\n    \"\"\"\n\n    _fields = [\n        ('algorithm', PublicKeyAlgorithmId),\n        ('parameters', Any, {'optional': True}),\n    ]\n\n    _oid_pair = ('algorithm', 'parameters')\n    _oid_specs = {\n        'dsa': DSAParams,\n        'ec': ECDomainParameters,\n        'dh': DomainParameters,\n        'rsaes_oaep': RSAESOAEPParams,\n        'rsassa_pss': RSASSAPSSParams,\n    }\n\n\nclass PublicKeyInfo(Sequence):\n    \"\"\"\n    Original Name: SubjectPublicKeyInfo\n    Source: https://tools.ietf.org/html/rfc5280#page-17\n    \"\"\"\n\n    _fields = [\n        ('algorithm', PublicKeyAlgorithm),\n        ('public_key', ParsableOctetBitString),\n    ]\n\n    def _public_key_spec(self):\n        algorithm = self['algorithm']['algorithm'].native\n        return {\n            'rsa': RSAPublicKey,\n            'rsaes_oaep': RSAPublicKey,\n            'rsassa_pss': RSAPublicKey,\n            'dsa': Integer,\n            # We override the field spec with ECPoint so that users can easily\n            # decompose the byte string into the constituent X and Y coords\n            'ec': (ECPointBitString, None),\n            'dh': Integer,\n            # These should be treated as opaque bit strings according\n            # to RFC 8410, and need not even be valid ASN.1\n            'x25519': (OctetBitString, None),\n            'x448': (OctetBitString, None),\n            'ed25519': (OctetBitString, None),\n            'ed448': (OctetBitString, None),\n        }[algorithm]\n\n    _spec_callbacks = {\n        'public_key': _public_key_spec\n    }\n\n    _algorithm = None\n    _bit_size = None\n    _fingerprint = None\n    _sha1 = None\n    _sha256 = None\n\n    @classmethod\n    def wrap(cls, public_key, algorithm):\n        \"\"\"\n        Wraps a public key in a PublicKeyInfo structure\n\n        :param public_key:\n            A byte string or Asn1Value object of the public key\n\n        :param algorithm:\n            A unicode string of \"rsa\"\n\n        :return:\n            A PublicKeyInfo object\n        \"\"\"\n\n        if not isinstance(public_key, byte_cls) and not isinstance(public_key, Asn1Value):\n            raise TypeError(unwrap(\n                '''\n                public_key must be a byte string or Asn1Value, not %s\n                ''',\n                type_name(public_key)\n            ))\n\n        if algorithm != 'rsa' and algorithm != 'rsassa_pss':\n            raise ValueError(unwrap(\n                '''\n                algorithm must \"rsa\", not %s\n                ''',\n                repr(algorithm)\n            ))\n\n        algo = PublicKeyAlgorithm()\n        algo['algorithm'] = PublicKeyAlgorithmId(algorithm)\n        algo['parameters'] = Null()\n\n        container = cls()\n        container['algorithm'] = algo\n        if isinstance(public_key, Asn1Value):\n            public_key = public_key.untag().dump()\n        container['public_key'] = ParsableOctetBitString(public_key)\n\n        return container\n\n    def unwrap(self):\n        \"\"\"\n        Unwraps an RSA public key into an RSAPublicKey object. Does not support\n        DSA or EC public keys since they do not have an unwrapped form.\n\n        :return:\n            An RSAPublicKey object\n        \"\"\"\n\n        raise APIException(\n            'asn1crypto.keys.PublicKeyInfo().unwrap() has been removed, '\n            'please use oscrypto.asymmetric.PublicKey().unwrap() instead')\n\n    @property\n    def curve(self):\n        \"\"\"\n        Returns information about the curve used for an EC key\n\n        :raises:\n            ValueError - when the key is not an EC key\n\n        :return:\n            A two-element tuple, with the first element being a unicode string\n            of \"implicit_ca\", \"specified\" or \"named\". If the first element is\n            \"implicit_ca\", the second is None. If \"specified\", the second is\n            an OrderedDict that is the native version of SpecifiedECDomain. If\n            \"named\", the second is a unicode string of the curve name.\n        \"\"\"\n\n        if self.algorithm != 'ec':\n            raise ValueError(unwrap(\n                '''\n                Only EC keys have a curve, this key is %s\n                ''',\n                self.algorithm.upper()\n            ))\n\n        params = self['algorithm']['parameters']\n        chosen = params.chosen\n\n        if params.name == 'implicit_ca':\n            value = None\n        else:\n            value = chosen.native\n\n        return (params.name, value)\n\n    @property\n    def hash_algo(self):\n        \"\"\"\n        Returns the name of the family of hash algorithms used to generate a\n        DSA key\n\n        :raises:\n            ValueError - when the key is not a DSA key\n\n        :return:\n            A unicode string of \"sha1\" or \"sha2\" or None if no parameters are\n            present\n        \"\"\"\n\n        if self.algorithm != 'dsa':\n            raise ValueError(unwrap(\n                '''\n                Only DSA keys are generated using a hash algorithm, this key is\n                %s\n                ''',\n                self.algorithm.upper()\n            ))\n\n        parameters = self['algorithm']['parameters']\n        if parameters.native is None:\n            return None\n\n        byte_len = math.log(parameters['q'].native, 2) / 8\n\n        return 'sha1' if byte_len <= 20 else 'sha2'\n\n    @property\n    def algorithm(self):\n        \"\"\"\n        :return:\n            A unicode string of \"rsa\", \"rsassa_pss\", \"dsa\" or \"ec\"\n        \"\"\"\n\n        if self._algorithm is None:\n            self._algorithm = self['algorithm']['algorithm'].native\n        return self._algorithm\n\n    @property\n    def bit_size(self):\n        \"\"\"\n        :return:\n            The bit size of the public key, as an integer\n        \"\"\"\n\n        if self._bit_size is None:\n            if self.algorithm == 'ec':\n                self._bit_size = int(((len(self['public_key'].native) - 1) / 2) * 8)\n            else:\n                if self.algorithm == 'rsa' or self.algorithm == 'rsassa_pss':\n                    prime = self['public_key'].parsed['modulus'].native\n                elif self.algorithm == 'dsa':\n                    prime = self['algorithm']['parameters']['p'].native\n                self._bit_size = int(math.ceil(math.log(prime, 2)))\n                modulus = self._bit_size % 8\n                if modulus != 0:\n                    self._bit_size += 8 - modulus\n\n        return self._bit_size\n\n    @property\n    def byte_size(self):\n        \"\"\"\n        :return:\n            The byte size of the public key, as an integer\n        \"\"\"\n\n        return int(math.ceil(self.bit_size / 8))\n\n    @property\n    def sha1(self):\n        \"\"\"\n        :return:\n            The SHA1 hash of the DER-encoded bytes of this public key info\n        \"\"\"\n\n        if self._sha1 is None:\n            self._sha1 = hashlib.sha1(byte_cls(self['public_key'])).digest()\n        return self._sha1\n\n    @property\n    def sha256(self):\n        \"\"\"\n        :return:\n            The SHA-256 hash of the DER-encoded bytes of this public key info\n        \"\"\"\n\n        if self._sha256 is None:\n            self._sha256 = hashlib.sha256(byte_cls(self['public_key'])).digest()\n        return self._sha256\n\n    @property\n    def fingerprint(self):\n        \"\"\"\n        Creates a fingerprint that can be compared with a private key to see if\n        the two form a pair.\n\n        This fingerprint is not compatible with fingerprints generated by any\n        other software.\n\n        :return:\n            A byte string that is a sha256 hash of selected components (based\n            on the key type)\n        \"\"\"\n\n        raise APIException(\n            'asn1crypto.keys.PublicKeyInfo().fingerprint has been removed, '\n            'please use oscrypto.asymmetric.PublicKey().fingerprint instead')\n"
  },
  {
    "path": "code/default/lib/noarch/asn1crypto/ocsp.py",
    "content": "# coding: utf-8\n\n\"\"\"\nASN.1 type classes for the online certificate status protocol (OCSP). Exports\nthe following items:\n\n - OCSPRequest()\n - OCSPResponse()\n\nOther type classes are defined that help compose the types listed above.\n\"\"\"\n\nfrom __future__ import unicode_literals, division, absolute_import, print_function\n\nfrom ._errors import unwrap\nfrom .algos import DigestAlgorithm, SignedDigestAlgorithm\nfrom .core import (\n    Boolean,\n    Choice,\n    Enumerated,\n    GeneralizedTime,\n    IA5String,\n    Integer,\n    Null,\n    ObjectIdentifier,\n    OctetBitString,\n    OctetString,\n    ParsableOctetString,\n    Sequence,\n    SequenceOf,\n)\nfrom .crl import AuthorityInfoAccessSyntax, CRLReason\nfrom .keys import PublicKeyAlgorithm\nfrom .x509 import Certificate, GeneralName, GeneralNames, Name\n\n\n# The structures in this file are taken from https://tools.ietf.org/html/rfc6960\n\n\nclass Version(Integer):\n    _map = {\n        0: 'v1'\n    }\n\n\nclass CertId(Sequence):\n    _fields = [\n        ('hash_algorithm', DigestAlgorithm),\n        ('issuer_name_hash', OctetString),\n        ('issuer_key_hash', OctetString),\n        ('serial_number', Integer),\n    ]\n\n\nclass ServiceLocator(Sequence):\n    _fields = [\n        ('issuer', Name),\n        ('locator', AuthorityInfoAccessSyntax),\n    ]\n\n\nclass RequestExtensionId(ObjectIdentifier):\n    _map = {\n        '1.3.6.1.5.5.7.48.1.7': 'service_locator',\n    }\n\n\nclass RequestExtension(Sequence):\n    _fields = [\n        ('extn_id', RequestExtensionId),\n        ('critical', Boolean, {'default': False}),\n        ('extn_value', ParsableOctetString),\n    ]\n\n    _oid_pair = ('extn_id', 'extn_value')\n    _oid_specs = {\n        'service_locator': ServiceLocator,\n    }\n\n\nclass RequestExtensions(SequenceOf):\n    _child_spec = RequestExtension\n\n\nclass Request(Sequence):\n    _fields = [\n        ('req_cert', CertId),\n        ('single_request_extensions', RequestExtensions, {'explicit': 0, 'optional': True}),\n    ]\n\n    _processed_extensions = False\n    _critical_extensions = None\n    _service_locator_value = None\n\n    def _set_extensions(self):\n        \"\"\"\n        Sets common named extensions to private attributes and creates a list\n        of critical extensions\n        \"\"\"\n\n        self._critical_extensions = set()\n\n        for extension in self['single_request_extensions']:\n            name = extension['extn_id'].native\n            attribute_name = '_%s_value' % name\n            if hasattr(self, attribute_name):\n                setattr(self, attribute_name, extension['extn_value'].parsed)\n            if extension['critical'].native:\n                self._critical_extensions.add(name)\n\n        self._processed_extensions = True\n\n    @property\n    def critical_extensions(self):\n        \"\"\"\n        Returns a set of the names (or OID if not a known extension) of the\n        extensions marked as critical\n\n        :return:\n            A set of unicode strings\n        \"\"\"\n\n        if not self._processed_extensions:\n            self._set_extensions()\n        return self._critical_extensions\n\n    @property\n    def service_locator_value(self):\n        \"\"\"\n        This extension is used when communicating with an OCSP responder that\n        acts as a proxy for OCSP requests\n\n        :return:\n            None or a ServiceLocator object\n        \"\"\"\n\n        if self._processed_extensions is False:\n            self._set_extensions()\n        return self._service_locator_value\n\n\nclass Requests(SequenceOf):\n    _child_spec = Request\n\n\nclass ResponseType(ObjectIdentifier):\n    _map = {\n        '1.3.6.1.5.5.7.48.1.1': 'basic_ocsp_response',\n    }\n\n\nclass AcceptableResponses(SequenceOf):\n    _child_spec = ResponseType\n\n\nclass PreferredSignatureAlgorithm(Sequence):\n    _fields = [\n        ('sig_identifier', SignedDigestAlgorithm),\n        ('cert_identifier', PublicKeyAlgorithm, {'optional': True}),\n    ]\n\n\nclass PreferredSignatureAlgorithms(SequenceOf):\n    _child_spec = PreferredSignatureAlgorithm\n\n\nclass TBSRequestExtensionId(ObjectIdentifier):\n    _map = {\n        '1.3.6.1.5.5.7.48.1.2': 'nonce',\n        '1.3.6.1.5.5.7.48.1.4': 'acceptable_responses',\n        '1.3.6.1.5.5.7.48.1.8': 'preferred_signature_algorithms',\n    }\n\n\nclass TBSRequestExtension(Sequence):\n    _fields = [\n        ('extn_id', TBSRequestExtensionId),\n        ('critical', Boolean, {'default': False}),\n        ('extn_value', ParsableOctetString),\n    ]\n\n    _oid_pair = ('extn_id', 'extn_value')\n    _oid_specs = {\n        'nonce': OctetString,\n        'acceptable_responses': AcceptableResponses,\n        'preferred_signature_algorithms': PreferredSignatureAlgorithms,\n    }\n\n\nclass TBSRequestExtensions(SequenceOf):\n    _child_spec = TBSRequestExtension\n\n\nclass TBSRequest(Sequence):\n    _fields = [\n        ('version', Version, {'explicit': 0, 'default': 'v1'}),\n        ('requestor_name', GeneralName, {'explicit': 1, 'optional': True}),\n        ('request_list', Requests),\n        ('request_extensions', TBSRequestExtensions, {'explicit': 2, 'optional': True}),\n    ]\n\n\nclass Certificates(SequenceOf):\n    _child_spec = Certificate\n\n\nclass Signature(Sequence):\n    _fields = [\n        ('signature_algorithm', SignedDigestAlgorithm),\n        ('signature', OctetBitString),\n        ('certs', Certificates, {'explicit': 0, 'optional': True}),\n    ]\n\n\nclass OCSPRequest(Sequence):\n    _fields = [\n        ('tbs_request', TBSRequest),\n        ('optional_signature', Signature, {'explicit': 0, 'optional': True}),\n    ]\n\n    _processed_extensions = False\n    _critical_extensions = None\n    _nonce_value = None\n    _acceptable_responses_value = None\n    _preferred_signature_algorithms_value = None\n\n    def _set_extensions(self):\n        \"\"\"\n        Sets common named extensions to private attributes and creates a list\n        of critical extensions\n        \"\"\"\n\n        self._critical_extensions = set()\n\n        for extension in self['tbs_request']['request_extensions']:\n            name = extension['extn_id'].native\n            attribute_name = '_%s_value' % name\n            if hasattr(self, attribute_name):\n                setattr(self, attribute_name, extension['extn_value'].parsed)\n            if extension['critical'].native:\n                self._critical_extensions.add(name)\n\n        self._processed_extensions = True\n\n    @property\n    def critical_extensions(self):\n        \"\"\"\n        Returns a set of the names (or OID if not a known extension) of the\n        extensions marked as critical\n\n        :return:\n            A set of unicode strings\n        \"\"\"\n\n        if not self._processed_extensions:\n            self._set_extensions()\n        return self._critical_extensions\n\n    @property\n    def nonce_value(self):\n        \"\"\"\n        This extension is used to prevent replay attacks by including a unique,\n        random value with each request/response pair\n\n        :return:\n            None or an OctetString object\n        \"\"\"\n\n        if self._processed_extensions is False:\n            self._set_extensions()\n        return self._nonce_value\n\n    @property\n    def acceptable_responses_value(self):\n        \"\"\"\n        This extension is used to allow the client and server to communicate\n        with alternative response formats other than just basic_ocsp_response,\n        although no other formats are defined in the standard.\n\n        :return:\n            None or an AcceptableResponses object\n        \"\"\"\n\n        if self._processed_extensions is False:\n            self._set_extensions()\n        return self._acceptable_responses_value\n\n    @property\n    def preferred_signature_algorithms_value(self):\n        \"\"\"\n        This extension is used by the client to define what signature algorithms\n        are preferred, including both the hash algorithm and the public key\n        algorithm, with a level of detail down to even the public key algorithm\n        parameters, such as curve name.\n\n        :return:\n            None or a PreferredSignatureAlgorithms object\n        \"\"\"\n\n        if self._processed_extensions is False:\n            self._set_extensions()\n        return self._preferred_signature_algorithms_value\n\n\nclass OCSPResponseStatus(Enumerated):\n    _map = {\n        0: 'successful',\n        1: 'malformed_request',\n        2: 'internal_error',\n        3: 'try_later',\n        5: 'sign_required',\n        6: 'unauthorized',\n    }\n\n\nclass ResponderId(Choice):\n    _alternatives = [\n        ('by_name', Name, {'explicit': 1}),\n        ('by_key', OctetString, {'explicit': 2}),\n    ]\n\n\n# Custom class to return a meaningful .native attribute from CertStatus()\nclass StatusGood(Null):\n    def set(self, value):\n        \"\"\"\n        Sets the value of the object\n\n        :param value:\n            None or 'good'\n        \"\"\"\n\n        if value is not None and value != 'good' and not isinstance(value, Null):\n            raise ValueError(unwrap(\n                '''\n                value must be one of None, \"good\", not %s\n                ''',\n                repr(value)\n            ))\n\n        self.contents = b''\n\n    @property\n    def native(self):\n        return 'good'\n\n\n# Custom class to return a meaningful .native attribute from CertStatus()\nclass StatusUnknown(Null):\n    def set(self, value):\n        \"\"\"\n        Sets the value of the object\n\n        :param value:\n            None or 'unknown'\n        \"\"\"\n\n        if value is not None and value != 'unknown' and not isinstance(value, Null):\n            raise ValueError(unwrap(\n                '''\n                value must be one of None, \"unknown\", not %s\n                ''',\n                repr(value)\n            ))\n\n        self.contents = b''\n\n    @property\n    def native(self):\n        return 'unknown'\n\n\nclass RevokedInfo(Sequence):\n    _fields = [\n        ('revocation_time', GeneralizedTime),\n        ('revocation_reason', CRLReason, {'explicit': 0, 'optional': True}),\n    ]\n\n\nclass CertStatus(Choice):\n    _alternatives = [\n        ('good', StatusGood, {'implicit': 0}),\n        ('revoked', RevokedInfo, {'implicit': 1}),\n        ('unknown', StatusUnknown, {'implicit': 2}),\n    ]\n\n\nclass CrlId(Sequence):\n    _fields = [\n        ('crl_url', IA5String, {'explicit': 0, 'optional': True}),\n        ('crl_num', Integer, {'explicit': 1, 'optional': True}),\n        ('crl_time', GeneralizedTime, {'explicit': 2, 'optional': True}),\n    ]\n\n\nclass SingleResponseExtensionId(ObjectIdentifier):\n    _map = {\n        '1.3.6.1.5.5.7.48.1.3': 'crl',\n        '1.3.6.1.5.5.7.48.1.6': 'archive_cutoff',\n        # These are CRLEntryExtension values from\n        # https://tools.ietf.org/html/rfc5280\n        '2.5.29.21': 'crl_reason',\n        '2.5.29.24': 'invalidity_date',\n        '2.5.29.29': 'certificate_issuer',\n        # https://tools.ietf.org/html/rfc6962.html#page-13\n        '1.3.6.1.4.1.11129.2.4.5': 'signed_certificate_timestamp_list',\n    }\n\n\nclass SingleResponseExtension(Sequence):\n    _fields = [\n        ('extn_id', SingleResponseExtensionId),\n        ('critical', Boolean, {'default': False}),\n        ('extn_value', ParsableOctetString),\n    ]\n\n    _oid_pair = ('extn_id', 'extn_value')\n    _oid_specs = {\n        'crl': CrlId,\n        'archive_cutoff': GeneralizedTime,\n        'crl_reason': CRLReason,\n        'invalidity_date': GeneralizedTime,\n        'certificate_issuer': GeneralNames,\n        'signed_certificate_timestamp_list': OctetString,\n    }\n\n\nclass SingleResponseExtensions(SequenceOf):\n    _child_spec = SingleResponseExtension\n\n\nclass SingleResponse(Sequence):\n    _fields = [\n        ('cert_id', CertId),\n        ('cert_status', CertStatus),\n        ('this_update', GeneralizedTime),\n        ('next_update', GeneralizedTime, {'explicit': 0, 'optional': True}),\n        ('single_extensions', SingleResponseExtensions, {'explicit': 1, 'optional': True}),\n    ]\n\n    _processed_extensions = False\n    _critical_extensions = None\n    _crl_value = None\n    _archive_cutoff_value = None\n    _crl_reason_value = None\n    _invalidity_date_value = None\n    _certificate_issuer_value = None\n\n    def _set_extensions(self):\n        \"\"\"\n        Sets common named extensions to private attributes and creates a list\n        of critical extensions\n        \"\"\"\n\n        self._critical_extensions = set()\n\n        for extension in self['single_extensions']:\n            name = extension['extn_id'].native\n            attribute_name = '_%s_value' % name\n            if hasattr(self, attribute_name):\n                setattr(self, attribute_name, extension['extn_value'].parsed)\n            if extension['critical'].native:\n                self._critical_extensions.add(name)\n\n        self._processed_extensions = True\n\n    @property\n    def critical_extensions(self):\n        \"\"\"\n        Returns a set of the names (or OID if not a known extension) of the\n        extensions marked as critical\n\n        :return:\n            A set of unicode strings\n        \"\"\"\n\n        if not self._processed_extensions:\n            self._set_extensions()\n        return self._critical_extensions\n\n    @property\n    def crl_value(self):\n        \"\"\"\n        This extension is used to locate the CRL that a certificate's revocation\n        is contained within.\n\n        :return:\n            None or a CrlId object\n        \"\"\"\n\n        if self._processed_extensions is False:\n            self._set_extensions()\n        return self._crl_value\n\n    @property\n    def archive_cutoff_value(self):\n        \"\"\"\n        This extension is used to indicate the date at which an archived\n        (historical) certificate status entry will no longer be available.\n\n        :return:\n            None or a GeneralizedTime object\n        \"\"\"\n\n        if self._processed_extensions is False:\n            self._set_extensions()\n        return self._archive_cutoff_value\n\n    @property\n    def crl_reason_value(self):\n        \"\"\"\n        This extension indicates the reason that a certificate was revoked.\n\n        :return:\n            None or a CRLReason object\n        \"\"\"\n\n        if self._processed_extensions is False:\n            self._set_extensions()\n        return self._crl_reason_value\n\n    @property\n    def invalidity_date_value(self):\n        \"\"\"\n        This extension indicates the suspected date/time the private key was\n        compromised or the certificate became invalid. This would usually be\n        before the revocation date, which is when the CA processed the\n        revocation.\n\n        :return:\n            None or a GeneralizedTime object\n        \"\"\"\n\n        if self._processed_extensions is False:\n            self._set_extensions()\n        return self._invalidity_date_value\n\n    @property\n    def certificate_issuer_value(self):\n        \"\"\"\n        This extension indicates the issuer of the certificate in question.\n\n        :return:\n            None or an x509.GeneralNames object\n        \"\"\"\n\n        if self._processed_extensions is False:\n            self._set_extensions()\n        return self._certificate_issuer_value\n\n\nclass Responses(SequenceOf):\n    _child_spec = SingleResponse\n\n\nclass ResponseDataExtensionId(ObjectIdentifier):\n    _map = {\n        '1.3.6.1.5.5.7.48.1.2': 'nonce',\n        '1.3.6.1.5.5.7.48.1.9': 'extended_revoke',\n    }\n\n\nclass ResponseDataExtension(Sequence):\n    _fields = [\n        ('extn_id', ResponseDataExtensionId),\n        ('critical', Boolean, {'default': False}),\n        ('extn_value', ParsableOctetString),\n    ]\n\n    _oid_pair = ('extn_id', 'extn_value')\n    _oid_specs = {\n        'nonce': OctetString,\n        'extended_revoke': Null,\n    }\n\n\nclass ResponseDataExtensions(SequenceOf):\n    _child_spec = ResponseDataExtension\n\n\nclass ResponseData(Sequence):\n    _fields = [\n        ('version', Version, {'explicit': 0, 'default': 'v1'}),\n        ('responder_id', ResponderId),\n        ('produced_at', GeneralizedTime),\n        ('responses', Responses),\n        ('response_extensions', ResponseDataExtensions, {'explicit': 1, 'optional': True}),\n    ]\n\n\nclass BasicOCSPResponse(Sequence):\n    _fields = [\n        ('tbs_response_data', ResponseData),\n        ('signature_algorithm', SignedDigestAlgorithm),\n        ('signature', OctetBitString),\n        ('certs', Certificates, {'explicit': 0, 'optional': True}),\n    ]\n\n\nclass ResponseBytes(Sequence):\n    _fields = [\n        ('response_type', ResponseType),\n        ('response', ParsableOctetString),\n    ]\n\n    _oid_pair = ('response_type', 'response')\n    _oid_specs = {\n        'basic_ocsp_response': BasicOCSPResponse,\n    }\n\n\nclass OCSPResponse(Sequence):\n    _fields = [\n        ('response_status', OCSPResponseStatus),\n        ('response_bytes', ResponseBytes, {'explicit': 0, 'optional': True}),\n    ]\n\n    _processed_extensions = False\n    _critical_extensions = None\n    _nonce_value = None\n    _extended_revoke_value = None\n\n    def _set_extensions(self):\n        \"\"\"\n        Sets common named extensions to private attributes and creates a list\n        of critical extensions\n        \"\"\"\n\n        self._critical_extensions = set()\n\n        for extension in self['response_bytes']['response'].parsed['tbs_response_data']['response_extensions']:\n            name = extension['extn_id'].native\n            attribute_name = '_%s_value' % name\n            if hasattr(self, attribute_name):\n                setattr(self, attribute_name, extension['extn_value'].parsed)\n            if extension['critical'].native:\n                self._critical_extensions.add(name)\n\n        self._processed_extensions = True\n\n    @property\n    def critical_extensions(self):\n        \"\"\"\n        Returns a set of the names (or OID if not a known extension) of the\n        extensions marked as critical\n\n        :return:\n            A set of unicode strings\n        \"\"\"\n\n        if not self._processed_extensions:\n            self._set_extensions()\n        return self._critical_extensions\n\n    @property\n    def nonce_value(self):\n        \"\"\"\n        This extension is used to prevent replay attacks on the request/response\n        exchange\n\n        :return:\n            None or an OctetString object\n        \"\"\"\n\n        if self._processed_extensions is False:\n            self._set_extensions()\n        return self._nonce_value\n\n    @property\n    def extended_revoke_value(self):\n        \"\"\"\n        This extension is used to signal that the responder will return a\n        \"revoked\" status for non-issued certificates.\n\n        :return:\n            None or a Null object (if present)\n        \"\"\"\n\n        if self._processed_extensions is False:\n            self._set_extensions()\n        return self._extended_revoke_value\n\n    @property\n    def basic_ocsp_response(self):\n        \"\"\"\n        A shortcut into the BasicOCSPResponse sequence\n\n        :return:\n            None or an asn1crypto.ocsp.BasicOCSPResponse object\n        \"\"\"\n\n        return self['response_bytes']['response'].parsed\n\n    @property\n    def response_data(self):\n        \"\"\"\n        A shortcut into the parsed, ResponseData sequence\n\n        :return:\n            None or an asn1crypto.ocsp.ResponseData object\n        \"\"\"\n\n        return self['response_bytes']['response'].parsed['tbs_response_data']\n"
  },
  {
    "path": "code/default/lib/noarch/asn1crypto/parser.py",
    "content": "# coding: utf-8\n\n\"\"\"\nFunctions for parsing and dumping using the ASN.1 DER encoding. Exports the\nfollowing items:\n\n - emit()\n - parse()\n - peek()\n\nOther type classes are defined that help compose the types listed above.\n\"\"\"\n\nfrom __future__ import unicode_literals, division, absolute_import, print_function\n\nimport sys\n\nfrom ._types import byte_cls, chr_cls, type_name\nfrom .util import int_from_bytes, int_to_bytes\n\n_PY2 = sys.version_info <= (3,)\n_INSUFFICIENT_DATA_MESSAGE = 'Insufficient data - %s bytes requested but only %s available'\n_MAX_DEPTH = 10\n\n\ndef emit(class_, method, tag, contents):\n    \"\"\"\n    Constructs a byte string of an ASN.1 DER-encoded value\n\n    This is typically not useful. Instead, use one of the standard classes from\n    asn1crypto.core, or construct a new class with specific fields, and call the\n    .dump() method.\n\n    :param class_:\n        An integer ASN.1 class value: 0 (universal), 1 (application),\n        2 (context), 3 (private)\n\n    :param method:\n        An integer ASN.1 method value: 0 (primitive), 1 (constructed)\n\n    :param tag:\n        An integer ASN.1 tag value\n\n    :param contents:\n        A byte string of the encoded byte contents\n\n    :return:\n        A byte string of the ASN.1 DER value (header and contents)\n    \"\"\"\n\n    if not isinstance(class_, int):\n        raise TypeError('class_ must be an integer, not %s' % type_name(class_))\n\n    if class_ < 0 or class_ > 3:\n        raise ValueError('class_ must be one of 0, 1, 2 or 3, not %s' % class_)\n\n    if not isinstance(method, int):\n        raise TypeError('method must be an integer, not %s' % type_name(method))\n\n    if method < 0 or method > 1:\n        raise ValueError('method must be 0 or 1, not %s' % method)\n\n    if not isinstance(tag, int):\n        raise TypeError('tag must be an integer, not %s' % type_name(tag))\n\n    if tag < 0:\n        raise ValueError('tag must be greater than zero, not %s' % tag)\n\n    if not isinstance(contents, byte_cls):\n        raise TypeError('contents must be a byte string, not %s' % type_name(contents))\n\n    return _dump_header(class_, method, tag, contents) + contents\n\n\ndef parse(contents, strict=False):\n    \"\"\"\n    Parses a byte string of ASN.1 BER/DER-encoded data.\n\n    This is typically not useful. Instead, use one of the standard classes from\n    asn1crypto.core, or construct a new class with specific fields, and call the\n    .load() class method.\n\n    :param contents:\n        A byte string of BER/DER-encoded data\n\n    :param strict:\n        A boolean indicating if trailing data should be forbidden - if so, a\n        ValueError will be raised when trailing data exists\n\n    :raises:\n        ValueError - when the contents do not contain an ASN.1 header or are truncated in some way\n        TypeError - when contents is not a byte string\n\n    :return:\n        A 6-element tuple:\n         - 0: integer class (0 to 3)\n         - 1: integer method\n         - 2: integer tag\n         - 3: byte string header\n         - 4: byte string content\n         - 5: byte string trailer\n    \"\"\"\n\n    if not isinstance(contents, byte_cls):\n        raise TypeError('contents must be a byte string, not %s' % type_name(contents))\n\n    contents_len = len(contents)\n    info, consumed = _parse(contents, contents_len)\n    if strict and consumed != contents_len:\n        raise ValueError('Extra data - %d bytes of trailing data were provided' % (contents_len - consumed))\n    return info\n\n\ndef peek(contents):\n    \"\"\"\n    Parses a byte string of ASN.1 BER/DER-encoded data to find the length\n\n    This is typically used to look into an encoded value to see how long the\n    next chunk of ASN.1-encoded data is. Primarily it is useful when a\n    value is a concatenation of multiple values.\n\n    :param contents:\n        A byte string of BER/DER-encoded data\n\n    :raises:\n        ValueError - when the contents do not contain an ASN.1 header or are truncated in some way\n        TypeError - when contents is not a byte string\n\n    :return:\n        An integer with the number of bytes occupied by the ASN.1 value\n    \"\"\"\n\n    if not isinstance(contents, byte_cls):\n        raise TypeError('contents must be a byte string, not %s' % type_name(contents))\n\n    info, consumed = _parse(contents, len(contents))\n    return consumed\n\n\ndef _parse(encoded_data, data_len, pointer=0, lengths_only=False, depth=0):\n    \"\"\"\n    Parses a byte string into component parts\n\n    :param encoded_data:\n        A byte string that contains BER-encoded data\n\n    :param data_len:\n        The integer length of the encoded data\n\n    :param pointer:\n        The index in the byte string to parse from\n\n    :param lengths_only:\n        A boolean to cause the call to return a 2-element tuple of the integer\n        number of bytes in the header and the integer number of bytes in the\n        contents. Internal use only.\n\n    :param depth:\n        The recursion depth when evaluating indefinite-length encoding.\n\n    :return:\n        A 2-element tuple:\n         - 0: A tuple of (class_, method, tag, header, content, trailer)\n         - 1: An integer indicating how many bytes were consumed\n    \"\"\"\n\n    if depth > _MAX_DEPTH:\n        raise ValueError('Indefinite-length recursion limit exceeded')\n\n    start = pointer\n\n    if data_len < pointer + 1:\n        raise ValueError(_INSUFFICIENT_DATA_MESSAGE % (1, data_len - pointer))\n    first_octet = ord(encoded_data[pointer]) if _PY2 else encoded_data[pointer]\n\n    pointer += 1\n\n    tag = first_octet & 31\n    constructed = (first_octet >> 5) & 1\n    # Base 128 length using 8th bit as continuation indicator\n    if tag == 31:\n        tag = 0\n        while True:\n            if data_len < pointer + 1:\n                raise ValueError(_INSUFFICIENT_DATA_MESSAGE % (1, data_len - pointer))\n            num = ord(encoded_data[pointer]) if _PY2 else encoded_data[pointer]\n            pointer += 1\n            if num == 0x80 and tag == 0:\n                raise ValueError('Non-minimal tag encoding')\n            tag *= 128\n            tag += num & 127\n            if num >> 7 == 0:\n                break\n        if tag < 31:\n            raise ValueError('Non-minimal tag encoding')\n\n    if data_len < pointer + 1:\n        raise ValueError(_INSUFFICIENT_DATA_MESSAGE % (1, data_len - pointer))\n    length_octet = ord(encoded_data[pointer]) if _PY2 else encoded_data[pointer]\n    pointer += 1\n    trailer = b''\n\n    if length_octet >> 7 == 0:\n        contents_end = pointer + (length_octet & 127)\n\n    else:\n        length_octets = length_octet & 127\n        if length_octets:\n            if data_len < pointer + length_octets:\n                raise ValueError(_INSUFFICIENT_DATA_MESSAGE % (length_octets, data_len - pointer))\n            pointer += length_octets\n            contents_end = pointer + int_from_bytes(encoded_data[pointer - length_octets:pointer], signed=False)\n\n        else:\n            # To properly parse indefinite length values, we need to scan forward\n            # parsing headers until we find a value with a length of zero. If we\n            # just scanned looking for \\x00\\x00, nested indefinite length values\n            # would not work.\n            if not constructed:\n                raise ValueError('Indefinite-length element must be constructed')\n            contents_end = pointer\n            while data_len < contents_end + 2 or encoded_data[contents_end:contents_end+2] != b'\\x00\\x00':\n                _, contents_end = _parse(encoded_data, data_len, contents_end, lengths_only=True, depth=depth+1)\n            contents_end += 2\n            trailer = b'\\x00\\x00'\n\n    if contents_end > data_len:\n        raise ValueError(_INSUFFICIENT_DATA_MESSAGE % (contents_end - pointer, data_len - pointer))\n\n    if lengths_only:\n        return (pointer, contents_end)\n\n    return (\n        (\n            first_octet >> 6,\n            constructed,\n            tag,\n            encoded_data[start:pointer],\n            encoded_data[pointer:contents_end-len(trailer)],\n            trailer\n        ),\n        contents_end\n    )\n\n\ndef _dump_header(class_, method, tag, contents):\n    \"\"\"\n    Constructs the header bytes for an ASN.1 object\n\n    :param class_:\n        An integer ASN.1 class value: 0 (universal), 1 (application),\n        2 (context), 3 (private)\n\n    :param method:\n        An integer ASN.1 method value: 0 (primitive), 1 (constructed)\n\n    :param tag:\n        An integer ASN.1 tag value\n\n    :param contents:\n        A byte string of the encoded byte contents\n\n    :return:\n        A byte string of the ASN.1 DER header\n    \"\"\"\n\n    header = b''\n\n    id_num = 0\n    id_num |= class_ << 6\n    id_num |= method << 5\n\n    if tag >= 31:\n        cont_bit = 0\n        while tag > 0:\n            header = chr_cls(cont_bit | (tag & 0x7f)) + header\n            if not cont_bit:\n                cont_bit = 0x80\n            tag = tag >> 7\n        header = chr_cls(id_num | 31) + header\n    else:\n        header += chr_cls(id_num | tag)\n\n    length = len(contents)\n    if length <= 127:\n        header += chr_cls(length)\n    else:\n        length_bytes = int_to_bytes(length)\n        header += chr_cls(0x80 | len(length_bytes))\n        header += length_bytes\n\n    return header\n"
  },
  {
    "path": "code/default/lib/noarch/asn1crypto/pdf.py",
    "content": "# coding: utf-8\n\n\"\"\"\nASN.1 type classes for PDF signature structures. Adds extra oid mapping and\nvalue parsing to asn1crypto.x509.Extension() and asn1crypto.xms.CMSAttribute().\n\"\"\"\n\nfrom __future__ import unicode_literals, division, absolute_import, print_function\n\nfrom .cms import CMSAttributeType, CMSAttribute\nfrom .core import (\n    Boolean,\n    Integer,\n    Null,\n    ObjectIdentifier,\n    OctetString,\n    Sequence,\n    SequenceOf,\n    SetOf,\n)\nfrom .crl import CertificateList\nfrom .ocsp import OCSPResponse\nfrom .x509 import (\n    Extension,\n    ExtensionId,\n    GeneralName,\n    KeyPurposeId,\n)\n\n\nclass AdobeArchiveRevInfo(Sequence):\n    _fields = [\n        ('version', Integer)\n    ]\n\n\nclass AdobeTimestamp(Sequence):\n    _fields = [\n        ('version', Integer),\n        ('location', GeneralName),\n        ('requires_auth', Boolean, {'optional': True, 'default': False}),\n    ]\n\n\nclass OtherRevInfo(Sequence):\n    _fields = [\n        ('type', ObjectIdentifier),\n        ('value', OctetString),\n    ]\n\n\nclass SequenceOfCertificateList(SequenceOf):\n    _child_spec = CertificateList\n\n\nclass SequenceOfOCSPResponse(SequenceOf):\n    _child_spec = OCSPResponse\n\n\nclass SequenceOfOtherRevInfo(SequenceOf):\n    _child_spec = OtherRevInfo\n\n\nclass RevocationInfoArchival(Sequence):\n    _fields = [\n        ('crl', SequenceOfCertificateList, {'explicit': 0, 'optional': True}),\n        ('ocsp', SequenceOfOCSPResponse, {'explicit': 1, 'optional': True}),\n        ('other_rev_info', SequenceOfOtherRevInfo, {'explicit': 2, 'optional': True}),\n    ]\n\n\nclass SetOfRevocationInfoArchival(SetOf):\n    _child_spec = RevocationInfoArchival\n\n\nExtensionId._map['1.2.840.113583.1.1.9.2'] = 'adobe_archive_rev_info'\nExtensionId._map['1.2.840.113583.1.1.9.1'] = 'adobe_timestamp'\nExtensionId._map['1.2.840.113583.1.1.10'] = 'adobe_ppklite_credential'\nExtension._oid_specs['adobe_archive_rev_info'] = AdobeArchiveRevInfo\nExtension._oid_specs['adobe_timestamp'] = AdobeTimestamp\nExtension._oid_specs['adobe_ppklite_credential'] = Null\nKeyPurposeId._map['1.2.840.113583.1.1.5'] = 'pdf_signing'\nCMSAttributeType._map['1.2.840.113583.1.1.8'] = 'adobe_revocation_info_archival'\nCMSAttribute._oid_specs['adobe_revocation_info_archival'] = SetOfRevocationInfoArchival\n"
  },
  {
    "path": "code/default/lib/noarch/asn1crypto/pem.py",
    "content": "# coding: utf-8\n\n\"\"\"\nEncoding DER to PEM and decoding PEM to DER. Exports the following items:\n\n - armor()\n - detect()\n - unarmor()\n\n\"\"\"\n\nfrom __future__ import unicode_literals, division, absolute_import, print_function\n\nimport base64\nimport re\nimport sys\n\nfrom ._errors import unwrap\nfrom ._types import type_name as _type_name, str_cls, byte_cls\n\nif sys.version_info < (3,):\n    from cStringIO import StringIO as BytesIO\nelse:\n    from io import BytesIO\n\n\ndef detect(byte_string):\n    \"\"\"\n    Detect if a byte string seems to contain a PEM-encoded block\n\n    :param byte_string:\n        A byte string to look through\n\n    :return:\n        A boolean, indicating if a PEM-encoded block is contained in the byte\n        string\n    \"\"\"\n\n    if not isinstance(byte_string, byte_cls):\n        raise TypeError(unwrap(\n            '''\n            byte_string must be a byte string, not %s\n            ''',\n            _type_name(byte_string)\n        ))\n\n    return byte_string.find(b'-----BEGIN') != -1 or byte_string.find(b'---- BEGIN') != -1\n\n\ndef armor(type_name, der_bytes, headers=None):\n    \"\"\"\n    Armors a DER-encoded byte string in PEM\n\n    :param type_name:\n        A unicode string that will be capitalized and placed in the header\n        and footer of the block. E.g. \"CERTIFICATE\", \"PRIVATE KEY\", etc. This\n        will appear as \"-----BEGIN CERTIFICATE-----\" and\n        \"-----END CERTIFICATE-----\".\n\n    :param der_bytes:\n        A byte string to be armored\n\n    :param headers:\n        An OrderedDict of the header lines to write after the BEGIN line\n\n    :return:\n        A byte string of the PEM block\n    \"\"\"\n\n    if not isinstance(der_bytes, byte_cls):\n        raise TypeError(unwrap(\n            '''\n            der_bytes must be a byte string, not %s\n            ''' % _type_name(der_bytes)\n        ))\n\n    if not isinstance(type_name, str_cls):\n        raise TypeError(unwrap(\n            '''\n            type_name must be a unicode string, not %s\n            ''',\n            _type_name(type_name)\n        ))\n\n    type_name = type_name.upper().encode('ascii')\n\n    output = BytesIO()\n    output.write(b'-----BEGIN ')\n    output.write(type_name)\n    output.write(b'-----\\n')\n    if headers:\n        for key in headers:\n            output.write(key.encode('ascii'))\n            output.write(b': ')\n            output.write(headers[key].encode('ascii'))\n            output.write(b'\\n')\n        output.write(b'\\n')\n    b64_bytes = base64.b64encode(der_bytes)\n    b64_len = len(b64_bytes)\n    i = 0\n    while i < b64_len:\n        output.write(b64_bytes[i:i + 64])\n        output.write(b'\\n')\n        i += 64\n    output.write(b'-----END ')\n    output.write(type_name)\n    output.write(b'-----\\n')\n\n    return output.getvalue()\n\n\ndef _unarmor(pem_bytes):\n    \"\"\"\n    Convert a PEM-encoded byte string into one or more DER-encoded byte strings\n\n    :param pem_bytes:\n        A byte string of the PEM-encoded data\n\n    :raises:\n        ValueError - when the pem_bytes do not appear to be PEM-encoded bytes\n\n    :return:\n        A generator of 3-element tuples in the format: (object_type, headers,\n        der_bytes). The object_type is a unicode string of what is between\n        \"-----BEGIN \" and \"-----\". Examples include: \"CERTIFICATE\",\n        \"PUBLIC KEY\", \"PRIVATE KEY\". The headers is a dict containing any lines\n        in the form \"Name: Value\" that are right after the begin line.\n    \"\"\"\n\n    if not isinstance(pem_bytes, byte_cls):\n        raise TypeError(unwrap(\n            '''\n            pem_bytes must be a byte string, not %s\n            ''',\n            _type_name(pem_bytes)\n        ))\n\n    # Valid states include: \"trash\", \"headers\", \"body\"\n    state = 'trash'\n    headers = {}\n    base64_data = b''\n    object_type = None\n\n    found_start = False\n    found_end = False\n\n    for line in pem_bytes.splitlines(False):\n        if line == b'':\n            continue\n\n        if state == \"trash\":\n            # Look for a starting line since some CA cert bundle show the cert\n            # into in a parsed format above each PEM block\n            type_name_match = re.match(b'^(?:---- |-----)BEGIN ([A-Z0-9 ]+)(?: ----|-----)', line)\n            if not type_name_match:\n                continue\n            object_type = type_name_match.group(1).decode('ascii')\n\n            found_start = True\n            state = 'headers'\n            continue\n\n        if state == 'headers':\n            if line.find(b':') == -1:\n                state = 'body'\n            else:\n                decoded_line = line.decode('ascii')\n                name, value = decoded_line.split(':', 1)\n                headers[name] = value.strip()\n                continue\n\n        if state == 'body':\n            if line[0:5] in (b'-----', b'---- '):\n                der_bytes = base64.b64decode(base64_data)\n\n                yield (object_type, headers, der_bytes)\n\n                state = 'trash'\n                headers = {}\n                base64_data = b''\n                object_type = None\n                found_end = True\n                continue\n\n            base64_data += line\n\n    if not found_start or not found_end:\n        raise ValueError(unwrap(\n            '''\n            pem_bytes does not appear to contain PEM-encoded data - no\n            BEGIN/END combination found\n            '''\n        ))\n\n\ndef unarmor(pem_bytes, multiple=False):\n    \"\"\"\n    Convert a PEM-encoded byte string into a DER-encoded byte string\n\n    :param pem_bytes:\n        A byte string of the PEM-encoded data\n\n    :param multiple:\n        If True, function will return a generator\n\n    :raises:\n        ValueError - when the pem_bytes do not appear to be PEM-encoded bytes\n\n    :return:\n        A 3-element tuple (object_name, headers, der_bytes). The object_name is\n        a unicode string of what is between \"-----BEGIN \" and \"-----\". Examples\n        include: \"CERTIFICATE\", \"PUBLIC KEY\", \"PRIVATE KEY\". The headers is a\n        dict containing any lines in the form \"Name: Value\" that are right\n        after the begin line.\n    \"\"\"\n\n    generator = _unarmor(pem_bytes)\n\n    if not multiple:\n        return next(generator)\n\n    return generator\n"
  },
  {
    "path": "code/default/lib/noarch/asn1crypto/pkcs12.py",
    "content": "# coding: utf-8\n\n\"\"\"\nASN.1 type classes for PKCS#12 files. Exports the following items:\n\n - CertBag()\n - CrlBag()\n - Pfx()\n - SafeBag()\n - SecretBag()\n\nOther type classes are defined that help compose the types listed above.\n\"\"\"\n\nfrom __future__ import unicode_literals, division, absolute_import, print_function\n\nfrom .algos import DigestInfo\nfrom .cms import ContentInfo, SignedData\nfrom .core import (\n    Any,\n    BMPString,\n    Integer,\n    ObjectIdentifier,\n    OctetString,\n    ParsableOctetString,\n    Sequence,\n    SequenceOf,\n    SetOf,\n)\nfrom .keys import PrivateKeyInfo, EncryptedPrivateKeyInfo\nfrom .x509 import Certificate, KeyPurposeId\n\n\n# The structures in this file are taken from https://tools.ietf.org/html/rfc7292\n\nclass MacData(Sequence):\n    _fields = [\n        ('mac', DigestInfo),\n        ('mac_salt', OctetString),\n        ('iterations', Integer, {'default': 1}),\n    ]\n\n\nclass Version(Integer):\n    _map = {\n        3: 'v3'\n    }\n\n\nclass AttributeType(ObjectIdentifier):\n    _map = {\n        # https://tools.ietf.org/html/rfc2985#page-18\n        '1.2.840.113549.1.9.20': 'friendly_name',\n        '1.2.840.113549.1.9.21': 'local_key_id',\n        # https://support.microsoft.com/en-us/kb/287547\n        '1.3.6.1.4.1.311.17.1': 'microsoft_local_machine_keyset',\n        # https://github.com/frohoff/jdk8u-dev-jdk/blob/master/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java\n        # this is a set of OIDs, representing key usage, the usual value is a SET of one element OID 2.5.29.37.0\n        '2.16.840.1.113894.746875.1.1': 'trusted_key_usage',\n    }\n\n\nclass SetOfAny(SetOf):\n    _child_spec = Any\n\n\nclass SetOfBMPString(SetOf):\n    _child_spec = BMPString\n\n\nclass SetOfOctetString(SetOf):\n    _child_spec = OctetString\n\n\nclass SetOfKeyPurposeId(SetOf):\n    _child_spec = KeyPurposeId\n\n\nclass Attribute(Sequence):\n    _fields = [\n        ('type', AttributeType),\n        ('values', None),\n    ]\n\n    _oid_specs = {\n        'friendly_name': SetOfBMPString,\n        'local_key_id': SetOfOctetString,\n        'microsoft_csp_name': SetOfBMPString,\n        'trusted_key_usage': SetOfKeyPurposeId,\n    }\n\n    def _values_spec(self):\n        return self._oid_specs.get(self['type'].native, SetOfAny)\n\n    _spec_callbacks = {\n        'values': _values_spec\n    }\n\n\nclass Attributes(SetOf):\n    _child_spec = Attribute\n\n\nclass Pfx(Sequence):\n    _fields = [\n        ('version', Version),\n        ('auth_safe', ContentInfo),\n        ('mac_data', MacData, {'optional': True})\n    ]\n\n    _authenticated_safe = None\n\n    @property\n    def authenticated_safe(self):\n        if self._authenticated_safe is None:\n            content = self['auth_safe']['content']\n            if isinstance(content, SignedData):\n                content = content['content_info']['content']\n            self._authenticated_safe = AuthenticatedSafe.load(content.native)\n        return self._authenticated_safe\n\n\nclass AuthenticatedSafe(SequenceOf):\n    _child_spec = ContentInfo\n\n\nclass BagId(ObjectIdentifier):\n    _map = {\n        '1.2.840.113549.1.12.10.1.1': 'key_bag',\n        '1.2.840.113549.1.12.10.1.2': 'pkcs8_shrouded_key_bag',\n        '1.2.840.113549.1.12.10.1.3': 'cert_bag',\n        '1.2.840.113549.1.12.10.1.4': 'crl_bag',\n        '1.2.840.113549.1.12.10.1.5': 'secret_bag',\n        '1.2.840.113549.1.12.10.1.6': 'safe_contents',\n    }\n\n\nclass CertId(ObjectIdentifier):\n    _map = {\n        '1.2.840.113549.1.9.22.1': 'x509',\n        '1.2.840.113549.1.9.22.2': 'sdsi',\n    }\n\n\nclass CertBag(Sequence):\n    _fields = [\n        ('cert_id', CertId),\n        ('cert_value', ParsableOctetString, {'explicit': 0}),\n    ]\n\n    _oid_pair = ('cert_id', 'cert_value')\n    _oid_specs = {\n        'x509': Certificate,\n    }\n\n\nclass CrlBag(Sequence):\n    _fields = [\n        ('crl_id', ObjectIdentifier),\n        ('crl_value', OctetString, {'explicit': 0}),\n    ]\n\n\nclass SecretBag(Sequence):\n    _fields = [\n        ('secret_type_id', ObjectIdentifier),\n        ('secret_value', OctetString, {'explicit': 0}),\n    ]\n\n\nclass SafeContents(SequenceOf):\n    pass\n\n\nclass SafeBag(Sequence):\n    _fields = [\n        ('bag_id', BagId),\n        ('bag_value', Any, {'explicit': 0}),\n        ('bag_attributes', Attributes, {'optional': True}),\n    ]\n\n    _oid_pair = ('bag_id', 'bag_value')\n    _oid_specs = {\n        'key_bag': PrivateKeyInfo,\n        'pkcs8_shrouded_key_bag': EncryptedPrivateKeyInfo,\n        'cert_bag': CertBag,\n        'crl_bag': CrlBag,\n        'secret_bag': SecretBag,\n        'safe_contents': SafeContents\n    }\n\n\nSafeContents._child_spec = SafeBag\n"
  },
  {
    "path": "code/default/lib/noarch/asn1crypto/tsp.py",
    "content": "# coding: utf-8\n\n\"\"\"\nASN.1 type classes for the time stamp protocol (TSP). Exports the following\nitems:\n\n - TimeStampReq()\n - TimeStampResp()\n\nAlso adds TimeStampedData() support to asn1crypto.cms.ContentInfo(),\nTimeStampedData() and TSTInfo() support to\nasn1crypto.cms.EncapsulatedContentInfo() and some oids and value parsers to\nasn1crypto.cms.CMSAttribute().\n\nOther type classes are defined that help compose the types listed above.\n\"\"\"\n\nfrom __future__ import unicode_literals, division, absolute_import, print_function\n\nfrom .algos import DigestAlgorithm\nfrom .cms import (\n    CMSAttribute,\n    CMSAttributeType,\n    ContentInfo,\n    ContentType,\n    EncapsulatedContentInfo,\n)\nfrom .core import (\n    Any,\n    BitString,\n    Boolean,\n    Choice,\n    GeneralizedTime,\n    IA5String,\n    Integer,\n    ObjectIdentifier,\n    OctetString,\n    Sequence,\n    SequenceOf,\n    SetOf,\n    UTF8String,\n)\nfrom .crl import CertificateList\nfrom .x509 import (\n    Attributes,\n    CertificatePolicies,\n    GeneralName,\n    GeneralNames,\n)\n\n\n# The structures in this file are based on https://tools.ietf.org/html/rfc3161,\n# https://tools.ietf.org/html/rfc4998, https://tools.ietf.org/html/rfc5544,\n# https://tools.ietf.org/html/rfc5035, https://tools.ietf.org/html/rfc2634\n\nclass Version(Integer):\n    _map = {\n        0: 'v0',\n        1: 'v1',\n        2: 'v2',\n        3: 'v3',\n        4: 'v4',\n        5: 'v5',\n    }\n\n\nclass MessageImprint(Sequence):\n    _fields = [\n        ('hash_algorithm', DigestAlgorithm),\n        ('hashed_message', OctetString),\n    ]\n\n\nclass Accuracy(Sequence):\n    _fields = [\n        ('seconds', Integer, {'optional': True}),\n        ('millis', Integer, {'implicit': 0, 'optional': True}),\n        ('micros', Integer, {'implicit': 1, 'optional': True}),\n    ]\n\n\nclass Extension(Sequence):\n    _fields = [\n        ('extn_id', ObjectIdentifier),\n        ('critical', Boolean, {'default': False}),\n        ('extn_value', OctetString),\n    ]\n\n\nclass Extensions(SequenceOf):\n    _child_spec = Extension\n\n\nclass TSTInfo(Sequence):\n    _fields = [\n        ('version', Version),\n        ('policy', ObjectIdentifier),\n        ('message_imprint', MessageImprint),\n        ('serial_number', Integer),\n        ('gen_time', GeneralizedTime),\n        ('accuracy', Accuracy, {'optional': True}),\n        ('ordering', Boolean, {'default': False}),\n        ('nonce', Integer, {'optional': True}),\n        ('tsa', GeneralName, {'explicit': 0, 'optional': True}),\n        ('extensions', Extensions, {'implicit': 1, 'optional': True}),\n    ]\n\n\nclass TimeStampReq(Sequence):\n    _fields = [\n        ('version', Version),\n        ('message_imprint', MessageImprint),\n        ('req_policy', ObjectIdentifier, {'optional': True}),\n        ('nonce', Integer, {'optional': True}),\n        ('cert_req', Boolean, {'default': False}),\n        ('extensions', Extensions, {'implicit': 0, 'optional': True}),\n    ]\n\n\nclass PKIStatus(Integer):\n    _map = {\n        0: 'granted',\n        1: 'granted_with_mods',\n        2: 'rejection',\n        3: 'waiting',\n        4: 'revocation_warning',\n        5: 'revocation_notification',\n    }\n\n\nclass PKIFreeText(SequenceOf):\n    _child_spec = UTF8String\n\n\nclass PKIFailureInfo(BitString):\n    _map = {\n        0: 'bad_alg',\n        2: 'bad_request',\n        5: 'bad_data_format',\n        14: 'time_not_available',\n        15: 'unaccepted_policy',\n        16: 'unaccepted_extensions',\n        17: 'add_info_not_available',\n        25: 'system_failure',\n    }\n\n\nclass PKIStatusInfo(Sequence):\n    _fields = [\n        ('status', PKIStatus),\n        ('status_string', PKIFreeText, {'optional': True}),\n        ('fail_info', PKIFailureInfo, {'optional': True}),\n    ]\n\n\nclass TimeStampResp(Sequence):\n    _fields = [\n        ('status', PKIStatusInfo),\n        ('time_stamp_token', ContentInfo),\n    ]\n\n\nclass MetaData(Sequence):\n    _fields = [\n        ('hash_protected', Boolean),\n        ('file_name', UTF8String, {'optional': True}),\n        ('media_type', IA5String, {'optional': True}),\n        ('other_meta_data', Attributes, {'optional': True}),\n    ]\n\n\nclass TimeStampAndCRL(Sequence):\n    _fields = [\n        ('time_stamp', EncapsulatedContentInfo),\n        ('crl', CertificateList, {'optional': True}),\n    ]\n\n\nclass TimeStampTokenEvidence(SequenceOf):\n    _child_spec = TimeStampAndCRL\n\n\nclass DigestAlgorithms(SequenceOf):\n    _child_spec = DigestAlgorithm\n\n\nclass EncryptionInfo(Sequence):\n    _fields = [\n        ('encryption_info_type', ObjectIdentifier),\n        ('encryption_info_value', Any),\n    ]\n\n\nclass PartialHashtree(SequenceOf):\n    _child_spec = OctetString\n\n\nclass PartialHashtrees(SequenceOf):\n    _child_spec = PartialHashtree\n\n\nclass ArchiveTimeStamp(Sequence):\n    _fields = [\n        ('digest_algorithm', DigestAlgorithm, {'implicit': 0, 'optional': True}),\n        ('attributes', Attributes, {'implicit': 1, 'optional': True}),\n        ('reduced_hashtree', PartialHashtrees, {'implicit': 2, 'optional': True}),\n        ('time_stamp', ContentInfo),\n    ]\n\n\nclass ArchiveTimeStampSequence(SequenceOf):\n    _child_spec = ArchiveTimeStamp\n\n\nclass EvidenceRecord(Sequence):\n    _fields = [\n        ('version', Version),\n        ('digest_algorithms', DigestAlgorithms),\n        ('crypto_infos', Attributes, {'implicit': 0, 'optional': True}),\n        ('encryption_info', EncryptionInfo, {'implicit': 1, 'optional': True}),\n        ('archive_time_stamp_sequence', ArchiveTimeStampSequence),\n    ]\n\n\nclass OtherEvidence(Sequence):\n    _fields = [\n        ('oe_type', ObjectIdentifier),\n        ('oe_value', Any),\n    ]\n\n\nclass Evidence(Choice):\n    _alternatives = [\n        ('tst_evidence', TimeStampTokenEvidence, {'implicit': 0}),\n        ('ers_evidence', EvidenceRecord, {'implicit': 1}),\n        ('other_evidence', OtherEvidence, {'implicit': 2}),\n    ]\n\n\nclass TimeStampedData(Sequence):\n    _fields = [\n        ('version', Version),\n        ('data_uri', IA5String, {'optional': True}),\n        ('meta_data', MetaData, {'optional': True}),\n        ('content', OctetString, {'optional': True}),\n        ('temporal_evidence', Evidence),\n    ]\n\n\nclass IssuerSerial(Sequence):\n    _fields = [\n        ('issuer', GeneralNames),\n        ('serial_number', Integer),\n    ]\n\n\nclass ESSCertID(Sequence):\n    _fields = [\n        ('cert_hash', OctetString),\n        ('issuer_serial', IssuerSerial, {'optional': True}),\n    ]\n\n\nclass ESSCertIDs(SequenceOf):\n    _child_spec = ESSCertID\n\n\nclass SigningCertificate(Sequence):\n    _fields = [\n        ('certs', ESSCertIDs),\n        ('policies', CertificatePolicies, {'optional': True}),\n    ]\n\n\nclass SetOfSigningCertificates(SetOf):\n    _child_spec = SigningCertificate\n\n\nclass ESSCertIDv2(Sequence):\n    _fields = [\n        ('hash_algorithm', DigestAlgorithm, {'default': {'algorithm': 'sha256'}}),\n        ('cert_hash', OctetString),\n        ('issuer_serial', IssuerSerial, {'optional': True}),\n    ]\n\n\nclass ESSCertIDv2s(SequenceOf):\n    _child_spec = ESSCertIDv2\n\n\nclass SigningCertificateV2(Sequence):\n    _fields = [\n        ('certs', ESSCertIDv2s),\n        ('policies', CertificatePolicies, {'optional': True}),\n    ]\n\n\nclass SetOfSigningCertificatesV2(SetOf):\n    _child_spec = SigningCertificateV2\n\n\nEncapsulatedContentInfo._oid_specs['tst_info'] = TSTInfo\nEncapsulatedContentInfo._oid_specs['timestamped_data'] = TimeStampedData\nContentInfo._oid_specs['timestamped_data'] = TimeStampedData\nContentType._map['1.2.840.113549.1.9.16.1.4'] = 'tst_info'\nContentType._map['1.2.840.113549.1.9.16.1.31'] = 'timestamped_data'\nCMSAttributeType._map['1.2.840.113549.1.9.16.2.12'] = 'signing_certificate'\nCMSAttribute._oid_specs['signing_certificate'] = SetOfSigningCertificates\nCMSAttributeType._map['1.2.840.113549.1.9.16.2.47'] = 'signing_certificate_v2'\nCMSAttribute._oid_specs['signing_certificate_v2'] = SetOfSigningCertificatesV2\n"
  },
  {
    "path": "code/default/lib/noarch/asn1crypto/util.py",
    "content": "# coding: utf-8\n\n\"\"\"\nMiscellaneous data helpers, including functions for converting integers to and\nfrom bytes and UTC timezone. Exports the following items:\n\n - OrderedDict()\n - int_from_bytes()\n - int_to_bytes()\n - timezone.utc\n - utc_with_dst\n - create_timezone()\n - inet_ntop()\n - inet_pton()\n - uri_to_iri()\n - iri_to_uri()\n\"\"\"\n\nfrom __future__ import unicode_literals, division, absolute_import, print_function\n\nimport math\nimport sys\nfrom datetime import datetime, date, timedelta, tzinfo\n\nfrom ._errors import unwrap\nfrom ._iri import iri_to_uri, uri_to_iri  # noqa\nfrom ._ordereddict import OrderedDict  # noqa\nfrom ._types import type_name\n\nif sys.platform == 'win32':\n    from ._inet import inet_ntop, inet_pton\nelse:\n    from socket import inet_ntop, inet_pton  # noqa\n\n\n# Python 2\nif sys.version_info <= (3,):\n\n    def int_to_bytes(value, signed=False, width=None):\n        \"\"\"\n        Converts an integer to a byte string\n\n        :param value:\n            The integer to convert\n\n        :param signed:\n            If the byte string should be encoded using two's complement\n\n        :param width:\n            If None, the minimal possible size (but at least 1),\n            otherwise an integer of the byte width for the return value\n\n        :return:\n            A byte string\n        \"\"\"\n\n        if value == 0 and width == 0:\n            return b''\n\n        # Handle negatives in two's complement\n        is_neg = False\n        if signed and value < 0:\n            is_neg = True\n            bits = int(math.ceil(len('%x' % abs(value)) / 2.0) * 8)\n            value = (value + (1 << bits)) % (1 << bits)\n\n        hex_str = '%x' % value\n        if len(hex_str) & 1:\n            hex_str = '0' + hex_str\n\n        output = hex_str.decode('hex')\n\n        if signed and not is_neg and ord(output[0:1]) & 0x80:\n            output = b'\\x00' + output\n\n        if width is not None:\n            if len(output) > width:\n                raise OverflowError('int too big to convert')\n            if is_neg:\n                pad_char = b'\\xFF'\n            else:\n                pad_char = b'\\x00'\n            output = (pad_char * (width - len(output))) + output\n        elif is_neg and ord(output[0:1]) & 0x80 == 0:\n            output = b'\\xFF' + output\n\n        return output\n\n    def int_from_bytes(value, signed=False):\n        \"\"\"\n        Converts a byte string to an integer\n\n        :param value:\n            The byte string to convert\n\n        :param signed:\n            If the byte string should be interpreted using two's complement\n\n        :return:\n            An integer\n        \"\"\"\n\n        if value == b'':\n            return 0\n\n        num = long(value.encode(\"hex\"), 16)  # noqa\n\n        if not signed:\n            return num\n\n        # Check for sign bit and handle two's complement\n        if ord(value[0:1]) & 0x80:\n            bit_len = len(value) * 8\n            return num - (1 << bit_len)\n\n        return num\n\n    class timezone(tzinfo):  # noqa\n        \"\"\"\n        Implements datetime.timezone for py2.\n        Only full minute offsets are supported.\n        DST is not supported.\n        \"\"\"\n\n        def __init__(self, offset, name=None):\n            \"\"\"\n            :param offset:\n                A timedelta with this timezone's offset from UTC\n\n            :param name:\n                Name of the timezone; if None, generate one.\n            \"\"\"\n\n            if not timedelta(hours=-24) < offset < timedelta(hours=24):\n                raise ValueError('Offset must be in [-23:59, 23:59]')\n\n            if offset.seconds % 60 or offset.microseconds:\n                raise ValueError('Offset must be full minutes')\n\n            self._offset = offset\n\n            if name is not None:\n                self._name = name\n            elif not offset:\n                self._name = 'UTC'\n            else:\n                self._name = 'UTC' + _format_offset(offset)\n\n        def __eq__(self, other):\n            \"\"\"\n            Compare two timezones\n\n            :param other:\n                The other timezone to compare to\n\n            :return:\n                A boolean\n            \"\"\"\n\n            if type(other) != timezone:\n                return False\n            return self._offset == other._offset\n\n        def __getinitargs__(self):\n            \"\"\"\n            Called by tzinfo.__reduce__ to support pickle and copy.\n\n            :return:\n                offset and name, to be used for __init__\n            \"\"\"\n\n            return self._offset, self._name\n\n        def tzname(self, dt):\n            \"\"\"\n            :param dt:\n                A datetime object; ignored.\n\n            :return:\n                Name of this timezone\n            \"\"\"\n\n            return self._name\n\n        def utcoffset(self, dt):\n            \"\"\"\n            :param dt:\n                A datetime object; ignored.\n\n            :return:\n                A timedelta object with the offset from UTC\n            \"\"\"\n\n            return self._offset\n\n        def dst(self, dt):\n            \"\"\"\n            :param dt:\n                A datetime object; ignored.\n\n            :return:\n                Zero timedelta\n            \"\"\"\n\n            return timedelta(0)\n\n    timezone.utc = timezone(timedelta(0))\n\n# Python 3\nelse:\n\n    from datetime import timezone  # noqa\n\n    def int_to_bytes(value, signed=False, width=None):\n        \"\"\"\n        Converts an integer to a byte string\n\n        :param value:\n            The integer to convert\n\n        :param signed:\n            If the byte string should be encoded using two's complement\n\n        :param width:\n            If None, the minimal possible size (but at least 1),\n            otherwise an integer of the byte width for the return value\n\n        :return:\n            A byte string\n        \"\"\"\n\n        if width is None:\n            if signed:\n                if value < 0:\n                    bits_required = abs(value + 1).bit_length()\n                else:\n                    bits_required = value.bit_length()\n                if bits_required % 8 == 0:\n                    bits_required += 1\n            else:\n                bits_required = value.bit_length()\n            width = math.ceil(bits_required / 8) or 1\n        return value.to_bytes(width, byteorder='big', signed=signed)\n\n    def int_from_bytes(value, signed=False):\n        \"\"\"\n        Converts a byte string to an integer\n\n        :param value:\n            The byte string to convert\n\n        :param signed:\n            If the byte string should be interpreted using two's complement\n\n        :return:\n            An integer\n        \"\"\"\n\n        return int.from_bytes(value, 'big', signed=signed)\n\n\ndef _format_offset(off):\n    \"\"\"\n    Format a timedelta into \"[+-]HH:MM\" format or \"\" for None\n    \"\"\"\n\n    if off is None:\n        return ''\n    mins = off.days * 24 * 60 + off.seconds // 60\n    sign = '-' if mins < 0 else '+'\n    return sign + '%02d:%02d' % divmod(abs(mins), 60)\n\n\nclass _UtcWithDst(tzinfo):\n    \"\"\"\n    Utc class where dst does not return None; required for astimezone\n    \"\"\"\n\n    def tzname(self, dt):\n        return 'UTC'\n\n    def utcoffset(self, dt):\n        return timedelta(0)\n\n    def dst(self, dt):\n        return timedelta(0)\n\n\nutc_with_dst = _UtcWithDst()\n\n_timezone_cache = {}\n\n\ndef create_timezone(offset):\n    \"\"\"\n    Returns a new datetime.timezone object with the given offset.\n    Uses cached objects if possible.\n\n    :param offset:\n        A datetime.timedelta object; It needs to be in full minutes and between -23:59 and +23:59.\n\n    :return:\n        A datetime.timezone object\n    \"\"\"\n\n    try:\n        tz = _timezone_cache[offset]\n    except KeyError:\n        tz = _timezone_cache[offset] = timezone(offset)\n    return tz\n\n\nclass extended_date(object):\n    \"\"\"\n    A datetime.datetime-like object that represents the year 0. This is just\n    to handle 0000-01-01 found in some certificates. Python's datetime does\n    not support year 0.\n\n    The proleptic gregorian calendar repeats itself every 400 years. Therefore,\n    the simplest way to format is to substitute year 2000.\n    \"\"\"\n\n    def __init__(self, year, month, day):\n        \"\"\"\n        :param year:\n            The integer 0\n\n        :param month:\n            An integer from 1 to 12\n\n        :param day:\n            An integer from 1 to 31\n        \"\"\"\n\n        if year != 0:\n            raise ValueError('year must be 0')\n\n        self._y2k = date(2000, month, day)\n\n    @property\n    def year(self):\n        \"\"\"\n        :return:\n            The integer 0\n        \"\"\"\n\n        return 0\n\n    @property\n    def month(self):\n        \"\"\"\n        :return:\n            An integer from 1 to 12\n        \"\"\"\n\n        return self._y2k.month\n\n    @property\n    def day(self):\n        \"\"\"\n        :return:\n            An integer from 1 to 31\n        \"\"\"\n\n        return self._y2k.day\n\n    def strftime(self, format):\n        \"\"\"\n        Formats the date using strftime()\n\n        :param format:\n            A strftime() format string\n\n        :return:\n            A str, the formatted date as a unicode string\n            in Python 3 and a byte string in Python 2\n        \"\"\"\n\n        # Format the date twice, once with year 2000, once with year 4000.\n        # The only differences in the result will be in the millennium. Find them and replace by zeros.\n        y2k = self._y2k.strftime(format)\n        y4k = self._y2k.replace(year=4000).strftime(format)\n        return ''.join('0' if (c2, c4) == ('2', '4') else c2 for c2, c4 in zip(y2k, y4k))\n\n    def isoformat(self):\n        \"\"\"\n        Formats the date as %Y-%m-%d\n\n        :return:\n            The date formatted to %Y-%m-%d as a unicode string in Python 3\n            and a byte string in Python 2\n        \"\"\"\n\n        return self.strftime('0000-%m-%d')\n\n    def replace(self, year=None, month=None, day=None):\n        \"\"\"\n        Returns a new datetime.date or asn1crypto.util.extended_date\n        object with the specified components replaced\n\n        :return:\n            A datetime.date or asn1crypto.util.extended_date object\n        \"\"\"\n\n        if year is None:\n            year = self.year\n        if month is None:\n            month = self.month\n        if day is None:\n            day = self.day\n\n        if year > 0:\n            cls = date\n        else:\n            cls = extended_date\n\n        return cls(\n            year,\n            month,\n            day\n        )\n\n    def __str__(self):\n        \"\"\"\n        :return:\n            A str representing this extended_date, e.g. \"0000-01-01\"\n        \"\"\"\n\n        return self.strftime('%Y-%m-%d')\n\n    def __eq__(self, other):\n        \"\"\"\n        Compare two extended_date objects\n\n        :param other:\n            The other extended_date to compare to\n\n        :return:\n            A boolean\n        \"\"\"\n\n        # datetime.date object wouldn't compare equal because it can't be year 0\n        if not isinstance(other, self.__class__):\n            return False\n        return self.__cmp__(other) == 0\n\n    def __ne__(self, other):\n        \"\"\"\n        Compare two extended_date objects\n\n        :param other:\n            The other extended_date to compare to\n\n        :return:\n            A boolean\n        \"\"\"\n\n        return not self.__eq__(other)\n\n    def _comparison_error(self, other):\n        raise TypeError(unwrap(\n            '''\n            An asn1crypto.util.extended_date object can only be compared to\n            an asn1crypto.util.extended_date or datetime.date object, not %s\n            ''',\n            type_name(other)\n        ))\n\n    def __cmp__(self, other):\n        \"\"\"\n        Compare two extended_date or datetime.date objects\n\n        :param other:\n            The other extended_date object to compare to\n\n        :return:\n            An integer smaller than, equal to, or larger than 0\n        \"\"\"\n\n        # self is year 0, other is >= year 1\n        if isinstance(other, date):\n            return -1\n\n        if not isinstance(other, self.__class__):\n            self._comparison_error(other)\n\n        if self._y2k < other._y2k:\n            return -1\n        if self._y2k > other._y2k:\n            return 1\n        return 0\n\n    def __lt__(self, other):\n        return self.__cmp__(other) < 0\n\n    def __le__(self, other):\n        return self.__cmp__(other) <= 0\n\n    def __gt__(self, other):\n        return self.__cmp__(other) > 0\n\n    def __ge__(self, other):\n        return self.__cmp__(other) >= 0\n\n\nclass extended_datetime(object):\n    \"\"\"\n    A datetime.datetime-like object that represents the year 0. This is just\n    to handle 0000-01-01 found in some certificates. Python's datetime does\n    not support year 0.\n\n    The proleptic gregorian calendar repeats itself every 400 years. Therefore,\n    the simplest way to format is to substitute year 2000.\n    \"\"\"\n\n    # There are 97 leap days during 400 years.\n    DAYS_IN_400_YEARS = 400 * 365 + 97\n    DAYS_IN_2000_YEARS = 5 * DAYS_IN_400_YEARS\n\n    def __init__(self, year, *args, **kwargs):\n        \"\"\"\n        :param year:\n            The integer 0\n\n        :param args:\n            Other positional arguments; see datetime.datetime.\n\n        :param kwargs:\n            Other keyword arguments; see datetime.datetime.\n        \"\"\"\n\n        if year != 0:\n            raise ValueError('year must be 0')\n\n        self._y2k = datetime(2000, *args, **kwargs)\n\n    @property\n    def year(self):\n        \"\"\"\n        :return:\n            The integer 0\n        \"\"\"\n\n        return 0\n\n    @property\n    def month(self):\n        \"\"\"\n        :return:\n            An integer from 1 to 12\n        \"\"\"\n\n        return self._y2k.month\n\n    @property\n    def day(self):\n        \"\"\"\n        :return:\n            An integer from 1 to 31\n        \"\"\"\n\n        return self._y2k.day\n\n    @property\n    def hour(self):\n        \"\"\"\n        :return:\n            An integer from 1 to 24\n        \"\"\"\n\n        return self._y2k.hour\n\n    @property\n    def minute(self):\n        \"\"\"\n        :return:\n            An integer from 1 to 60\n        \"\"\"\n\n        return self._y2k.minute\n\n    @property\n    def second(self):\n        \"\"\"\n        :return:\n            An integer from 1 to 60\n        \"\"\"\n\n        return self._y2k.second\n\n    @property\n    def microsecond(self):\n        \"\"\"\n        :return:\n            An integer from 0 to 999999\n        \"\"\"\n\n        return self._y2k.microsecond\n\n    @property\n    def tzinfo(self):\n        \"\"\"\n        :return:\n            If object is timezone aware, a datetime.tzinfo object, else None.\n        \"\"\"\n\n        return self._y2k.tzinfo\n\n    def utcoffset(self):\n        \"\"\"\n        :return:\n            If object is timezone aware, a datetime.timedelta object, else None.\n        \"\"\"\n\n        return self._y2k.utcoffset()\n\n    def time(self):\n        \"\"\"\n        :return:\n            A datetime.time object\n        \"\"\"\n\n        return self._y2k.time()\n\n    def date(self):\n        \"\"\"\n        :return:\n            An asn1crypto.util.extended_date of the date\n        \"\"\"\n\n        return extended_date(0, self.month, self.day)\n\n    def strftime(self, format):\n        \"\"\"\n        Performs strftime(), always returning a str\n\n        :param format:\n            A strftime() format string\n\n        :return:\n            A str of the formatted datetime\n        \"\"\"\n\n        # Format the datetime twice, once with year 2000, once with year 4000.\n        # The only differences in the result will be in the millennium. Find them and replace by zeros.\n        y2k = self._y2k.strftime(format)\n        y4k = self._y2k.replace(year=4000).strftime(format)\n        return ''.join('0' if (c2, c4) == ('2', '4') else c2 for c2, c4 in zip(y2k, y4k))\n\n    def isoformat(self, sep='T'):\n        \"\"\"\n        Formats the date as \"%Y-%m-%d %H:%M:%S\" with the sep param between the\n        date and time portions\n\n        :param set:\n            A single character of the separator to place between the date and\n            time\n\n        :return:\n            The formatted datetime as a unicode string in Python 3 and a byte\n            string in Python 2\n        \"\"\"\n\n        s = '0000-%02d-%02d%c%02d:%02d:%02d' % (self.month, self.day, sep, self.hour, self.minute, self.second)\n        if self.microsecond:\n            s += '.%06d' % self.microsecond\n        return s + _format_offset(self.utcoffset())\n\n    def replace(self, year=None, *args, **kwargs):\n        \"\"\"\n        Returns a new datetime.datetime or asn1crypto.util.extended_datetime\n        object with the specified components replaced\n\n        :param year:\n            The new year to substitute. None to keep it.\n\n        :param args:\n            Other positional arguments; see datetime.datetime.replace.\n\n        :param kwargs:\n            Other keyword arguments; see datetime.datetime.replace.\n\n        :return:\n            A datetime.datetime or asn1crypto.util.extended_datetime object\n        \"\"\"\n\n        if year:\n            return self._y2k.replace(year, *args, **kwargs)\n\n        return extended_datetime.from_y2k(self._y2k.replace(2000, *args, **kwargs))\n\n    def astimezone(self, tz):\n        \"\"\"\n        Convert this extended_datetime to another timezone.\n\n        :param tz:\n            A datetime.tzinfo object.\n\n        :return:\n            A new extended_datetime or datetime.datetime object\n        \"\"\"\n\n        return extended_datetime.from_y2k(self._y2k.astimezone(tz))\n\n    def timestamp(self):\n        \"\"\"\n        Return POSIX timestamp. Only supported in python >= 3.3\n\n        :return:\n            A float representing the seconds since 1970-01-01 UTC. This will be a negative value.\n        \"\"\"\n\n        return self._y2k.timestamp() - self.DAYS_IN_2000_YEARS * 86400\n\n    def __str__(self):\n        \"\"\"\n        :return:\n            A str representing this extended_datetime, e.g. \"0000-01-01 00:00:00.000001-10:00\"\n        \"\"\"\n\n        return self.isoformat(sep=' ')\n\n    def __eq__(self, other):\n        \"\"\"\n        Compare two extended_datetime objects\n\n        :param other:\n            The other extended_datetime to compare to\n\n        :return:\n            A boolean\n        \"\"\"\n\n        # Only compare against other datetime or extended_datetime objects\n        if not isinstance(other, (self.__class__, datetime)):\n            return False\n\n        # Offset-naive and offset-aware datetimes are never the same\n        if (self.tzinfo is None) != (other.tzinfo is None):\n            return False\n\n        return self.__cmp__(other) == 0\n\n    def __ne__(self, other):\n        \"\"\"\n        Compare two extended_datetime objects\n\n        :param other:\n            The other extended_datetime to compare to\n\n        :return:\n            A boolean\n        \"\"\"\n\n        return not self.__eq__(other)\n\n    def _comparison_error(self, other):\n        \"\"\"\n        Raises a TypeError about the other object not being suitable for\n        comparison\n\n        :param other:\n            The object being compared to\n        \"\"\"\n\n        raise TypeError(unwrap(\n            '''\n            An asn1crypto.util.extended_datetime object can only be compared to\n            an asn1crypto.util.extended_datetime or datetime.datetime object,\n            not %s\n            ''',\n            type_name(other)\n        ))\n\n    def __cmp__(self, other):\n        \"\"\"\n        Compare two extended_datetime or datetime.datetime objects\n\n        :param other:\n            The other extended_datetime or datetime.datetime object to compare to\n\n        :return:\n            An integer smaller than, equal to, or larger than 0\n        \"\"\"\n\n        if not isinstance(other, (self.__class__, datetime)):\n            self._comparison_error(other)\n\n        if (self.tzinfo is None) != (other.tzinfo is None):\n            raise TypeError(\"can't compare offset-naive and offset-aware datetimes\")\n\n        diff = self - other\n        zero = timedelta(0)\n        if diff < zero:\n            return -1\n        if diff > zero:\n            return 1\n        return 0\n\n    def __lt__(self, other):\n        return self.__cmp__(other) < 0\n\n    def __le__(self, other):\n        return self.__cmp__(other) <= 0\n\n    def __gt__(self, other):\n        return self.__cmp__(other) > 0\n\n    def __ge__(self, other):\n        return self.__cmp__(other) >= 0\n\n    def __add__(self, other):\n        \"\"\"\n        Adds a timedelta\n\n        :param other:\n            A datetime.timedelta object to add.\n\n        :return:\n            A new extended_datetime or datetime.datetime object.\n        \"\"\"\n\n        return extended_datetime.from_y2k(self._y2k + other)\n\n    def __sub__(self, other):\n        \"\"\"\n        Subtracts a timedelta or another datetime.\n\n        :param other:\n            A datetime.timedelta or datetime.datetime or extended_datetime object to subtract.\n\n        :return:\n            If a timedelta is passed, a new extended_datetime or datetime.datetime object.\n            Else a datetime.timedelta object.\n        \"\"\"\n\n        if isinstance(other, timedelta):\n            return extended_datetime.from_y2k(self._y2k - other)\n\n        if isinstance(other, extended_datetime):\n            return self._y2k - other._y2k\n\n        if isinstance(other, datetime):\n            return self._y2k - other - timedelta(days=self.DAYS_IN_2000_YEARS)\n\n        return NotImplemented\n\n    def __rsub__(self, other):\n        return -(self - other)\n\n    @classmethod\n    def from_y2k(cls, value):\n        \"\"\"\n        Revert substitution of year 2000.\n\n        :param value:\n            A datetime.datetime object which is 2000 years in the future.\n        :return:\n            A new extended_datetime or datetime.datetime object.\n        \"\"\"\n\n        year = value.year - 2000\n\n        if year > 0:\n            new_cls = datetime\n        else:\n            new_cls = cls\n\n        return new_cls(\n            year,\n            value.month,\n            value.day,\n            value.hour,\n            value.minute,\n            value.second,\n            value.microsecond,\n            value.tzinfo\n        )\n"
  },
  {
    "path": "code/default/lib/noarch/asn1crypto/version.py",
    "content": "# coding: utf-8\nfrom __future__ import unicode_literals, division, absolute_import, print_function\n\n\n__version__ = '1.5.1'\n__version_info__ = (1, 5, 1)\n"
  },
  {
    "path": "code/default/lib/noarch/asn1crypto/x509.py",
    "content": "# coding: utf-8\n\n\"\"\"\nASN.1 type classes for X.509 certificates. Exports the following items:\n\n - Attributes()\n - Certificate()\n - Extensions()\n - GeneralName()\n - GeneralNames()\n - Name()\n\nOther type classes are defined that help compose the types listed above.\n\"\"\"\n\nfrom __future__ import unicode_literals, division, absolute_import, print_function\n\nfrom contextlib import contextmanager\nfrom encodings import idna  # noqa\nimport hashlib\nimport re\nimport socket\nimport stringprep\nimport sys\nimport unicodedata\n\nfrom ._errors import unwrap\nfrom ._iri import iri_to_uri, uri_to_iri\nfrom ._ordereddict import OrderedDict\nfrom ._types import type_name, str_cls, bytes_to_list\nfrom .algos import AlgorithmIdentifier, AnyAlgorithmIdentifier, DigestAlgorithm, SignedDigestAlgorithm\nfrom .core import (\n    Any,\n    BitString,\n    BMPString,\n    Boolean,\n    Choice,\n    Concat,\n    Enumerated,\n    GeneralizedTime,\n    GeneralString,\n    IA5String,\n    Integer,\n    Null,\n    NumericString,\n    ObjectIdentifier,\n    OctetBitString,\n    OctetString,\n    ParsableOctetString,\n    PrintableString,\n    Sequence,\n    SequenceOf,\n    Set,\n    SetOf,\n    TeletexString,\n    UniversalString,\n    UTCTime,\n    UTF8String,\n    VisibleString,\n    VOID,\n)\nfrom .keys import PublicKeyInfo\nfrom .util import int_to_bytes, int_from_bytes, inet_ntop, inet_pton\n\n\n# The structures in this file are taken from https://tools.ietf.org/html/rfc5280\n# and a few other supplementary sources, mostly due to extra supported\n# extension and name OIDs\n\n\nclass DNSName(IA5String):\n\n    _encoding = 'idna'\n    _bad_tag = (12, 19)\n\n    def __ne__(self, other):\n        return not self == other\n\n    def __eq__(self, other):\n        \"\"\"\n        Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.2\n\n        :param other:\n            Another DNSName object\n\n        :return:\n            A boolean\n        \"\"\"\n\n        if not isinstance(other, DNSName):\n            return False\n\n        return self.__unicode__().lower() == other.__unicode__().lower()\n\n    def set(self, value):\n        \"\"\"\n        Sets the value of the DNS name\n\n        :param value:\n            A unicode string\n        \"\"\"\n\n        if not isinstance(value, str_cls):\n            raise TypeError(unwrap(\n                '''\n                %s value must be a unicode string, not %s\n                ''',\n                type_name(self),\n                type_name(value)\n            ))\n\n        if value.startswith('.'):\n            encoded_value = b'.' + value[1:].encode(self._encoding)\n        else:\n            encoded_value = value.encode(self._encoding)\n\n        self._unicode = value\n        self.contents = encoded_value\n        self._header = None\n        if self._trailer != b'':\n            self._trailer = b''\n\n\nclass URI(IA5String):\n\n    def set(self, value):\n        \"\"\"\n        Sets the value of the string\n\n        :param value:\n            A unicode string\n        \"\"\"\n\n        if not isinstance(value, str_cls):\n            raise TypeError(unwrap(\n                '''\n                %s value must be a unicode string, not %s\n                ''',\n                type_name(self),\n                type_name(value)\n            ))\n\n        self._unicode = value\n        self.contents = iri_to_uri(value)\n        self._header = None\n        if self._trailer != b'':\n            self._trailer = b''\n\n    def __ne__(self, other):\n        return not self == other\n\n    def __eq__(self, other):\n        \"\"\"\n        Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.4\n\n        :param other:\n            Another URI object\n\n        :return:\n            A boolean\n        \"\"\"\n\n        if not isinstance(other, URI):\n            return False\n\n        return iri_to_uri(self.native, True) == iri_to_uri(other.native, True)\n\n    def __unicode__(self):\n        \"\"\"\n        :return:\n            A unicode string\n        \"\"\"\n\n        if self.contents is None:\n            return ''\n        if self._unicode is None:\n            self._unicode = uri_to_iri(self._merge_chunks())\n        return self._unicode\n\n\nclass EmailAddress(IA5String):\n\n    _contents = None\n\n    # If the value has gone through the .set() method, thus normalizing it\n    _normalized = False\n\n    # In the wild we've seen this encoded as a UTF8String and PrintableString\n    _bad_tag = (12, 19)\n\n    @property\n    def contents(self):\n        \"\"\"\n        :return:\n            A byte string of the DER-encoded contents of the sequence\n        \"\"\"\n\n        return self._contents\n\n    @contents.setter\n    def contents(self, value):\n        \"\"\"\n        :param value:\n            A byte string of the DER-encoded contents of the sequence\n        \"\"\"\n\n        self._normalized = False\n        self._contents = value\n\n    def set(self, value):\n        \"\"\"\n        Sets the value of the string\n\n        :param value:\n            A unicode string\n        \"\"\"\n\n        if not isinstance(value, str_cls):\n            raise TypeError(unwrap(\n                '''\n                %s value must be a unicode string, not %s\n                ''',\n                type_name(self),\n                type_name(value)\n            ))\n\n        if value.find('@') != -1:\n            mailbox, hostname = value.rsplit('@', 1)\n            encoded_value = mailbox.encode('ascii') + b'@' + hostname.encode('idna')\n        else:\n            encoded_value = value.encode('ascii')\n\n        self._normalized = True\n        self._unicode = value\n        self.contents = encoded_value\n        self._header = None\n        if self._trailer != b'':\n            self._trailer = b''\n\n    def __unicode__(self):\n        \"\"\"\n        :return:\n            A unicode string\n        \"\"\"\n\n        # We've seen this in the wild as a PrintableString, and since ascii is a\n        # subset of cp1252, we use the later for decoding to be more user friendly\n        if self._unicode is None:\n            contents = self._merge_chunks()\n            if contents.find(b'@') == -1:\n                self._unicode = contents.decode('cp1252')\n            else:\n                mailbox, hostname = contents.rsplit(b'@', 1)\n                self._unicode = mailbox.decode('cp1252') + '@' + hostname.decode('idna')\n        return self._unicode\n\n    def __ne__(self, other):\n        return not self == other\n\n    def __eq__(self, other):\n        \"\"\"\n        Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.5\n\n        :param other:\n            Another EmailAddress object\n\n        :return:\n            A boolean\n        \"\"\"\n\n        if not isinstance(other, EmailAddress):\n            return False\n\n        if not self._normalized:\n            self.set(self.native)\n        if not other._normalized:\n            other.set(other.native)\n\n        if self._contents.find(b'@') == -1 or other._contents.find(b'@') == -1:\n            return self._contents == other._contents\n\n        other_mailbox, other_hostname = other._contents.rsplit(b'@', 1)\n        mailbox, hostname = self._contents.rsplit(b'@', 1)\n\n        if mailbox != other_mailbox:\n            return False\n\n        if hostname.lower() != other_hostname.lower():\n            return False\n\n        return True\n\n\nclass IPAddress(OctetString):\n    def parse(self, spec=None, spec_params=None):\n        \"\"\"\n        This method is not applicable to IP addresses\n        \"\"\"\n\n        raise ValueError(unwrap(\n            '''\n            IP address values can not be parsed\n            '''\n        ))\n\n    def set(self, value):\n        \"\"\"\n        Sets the value of the object\n\n        :param value:\n            A unicode string containing an IPv4 address, IPv4 address with CIDR,\n            an IPv6 address or IPv6 address with CIDR\n        \"\"\"\n\n        if not isinstance(value, str_cls):\n            raise TypeError(unwrap(\n                '''\n                %s value must be a unicode string, not %s\n                ''',\n                type_name(self),\n                type_name(value)\n            ))\n\n        original_value = value\n\n        has_cidr = value.find('/') != -1\n        cidr = 0\n        if has_cidr:\n            parts = value.split('/', 1)\n            value = parts[0]\n            cidr = int(parts[1])\n            if cidr < 0:\n                raise ValueError(unwrap(\n                    '''\n                    %s value contains a CIDR range less than 0\n                    ''',\n                    type_name(self)\n                ))\n\n        if value.find(':') != -1:\n            family = socket.AF_INET6\n            if cidr > 128:\n                raise ValueError(unwrap(\n                    '''\n                    %s value contains a CIDR range bigger than 128, the maximum\n                    value for an IPv6 address\n                    ''',\n                    type_name(self)\n                ))\n            cidr_size = 128\n        else:\n            family = socket.AF_INET\n            if cidr > 32:\n                raise ValueError(unwrap(\n                    '''\n                    %s value contains a CIDR range bigger than 32, the maximum\n                    value for an IPv4 address\n                    ''',\n                    type_name(self)\n                ))\n            cidr_size = 32\n\n        cidr_bytes = b''\n        if has_cidr:\n            cidr_mask = '1' * cidr\n            cidr_mask += '0' * (cidr_size - len(cidr_mask))\n            cidr_bytes = int_to_bytes(int(cidr_mask, 2))\n            cidr_bytes = (b'\\x00' * ((cidr_size // 8) - len(cidr_bytes))) + cidr_bytes\n\n        self._native = original_value\n        self.contents = inet_pton(family, value) + cidr_bytes\n        self._bytes = self.contents\n        self._header = None\n        if self._trailer != b'':\n            self._trailer = b''\n\n    @property\n    def native(self):\n        \"\"\"\n        The native Python datatype representation of this value\n\n        :return:\n            A unicode string or None\n        \"\"\"\n\n        if self.contents is None:\n            return None\n\n        if self._native is None:\n            byte_string = self.__bytes__()\n            byte_len = len(byte_string)\n            value = None\n            cidr_int = None\n            if byte_len in set([32, 16]):\n                value = inet_ntop(socket.AF_INET6, byte_string[0:16])\n                if byte_len > 16:\n                    cidr_int = int_from_bytes(byte_string[16:])\n            elif byte_len in set([8, 4]):\n                value = inet_ntop(socket.AF_INET, byte_string[0:4])\n                if byte_len > 4:\n                    cidr_int = int_from_bytes(byte_string[4:])\n            if cidr_int is not None:\n                cidr_bits = '{0:b}'.format(cidr_int)\n                cidr = len(cidr_bits.rstrip('0'))\n                value = value + '/' + str_cls(cidr)\n            self._native = value\n        return self._native\n\n    def __ne__(self, other):\n        return not self == other\n\n    def __eq__(self, other):\n        \"\"\"\n        :param other:\n            Another IPAddress object\n\n        :return:\n            A boolean\n        \"\"\"\n\n        if not isinstance(other, IPAddress):\n            return False\n\n        return self.__bytes__() == other.__bytes__()\n\n\nclass Attribute(Sequence):\n    _fields = [\n        ('type', ObjectIdentifier),\n        ('values', SetOf, {'spec': Any}),\n    ]\n\n\nclass Attributes(SequenceOf):\n    _child_spec = Attribute\n\n\nclass KeyUsage(BitString):\n    _map = {\n        0: 'digital_signature',\n        1: 'non_repudiation',\n        2: 'key_encipherment',\n        3: 'data_encipherment',\n        4: 'key_agreement',\n        5: 'key_cert_sign',\n        6: 'crl_sign',\n        7: 'encipher_only',\n        8: 'decipher_only',\n    }\n\n\nclass PrivateKeyUsagePeriod(Sequence):\n    _fields = [\n        ('not_before', GeneralizedTime, {'implicit': 0, 'optional': True}),\n        ('not_after', GeneralizedTime, {'implicit': 1, 'optional': True}),\n    ]\n\n\nclass NotReallyTeletexString(TeletexString):\n    \"\"\"\n    OpenSSL (and probably some other libraries) puts ISO-8859-1\n    into TeletexString instead of ITU T.61. We use Windows-1252 when\n    decoding since it is a superset of ISO-8859-1, and less likely to\n    cause encoding issues, but we stay strict with encoding to prevent\n    us from creating bad data.\n    \"\"\"\n\n    _decoding_encoding = 'cp1252'\n\n    def __unicode__(self):\n        \"\"\"\n        :return:\n            A unicode string\n        \"\"\"\n\n        if self.contents is None:\n            return ''\n        if self._unicode is None:\n            self._unicode = self._merge_chunks().decode(self._decoding_encoding)\n        return self._unicode\n\n\n@contextmanager\ndef strict_teletex():\n    try:\n        NotReallyTeletexString._decoding_encoding = 'teletex'\n        yield\n    finally:\n        NotReallyTeletexString._decoding_encoding = 'cp1252'\n\n\nclass DirectoryString(Choice):\n    _alternatives = [\n        ('teletex_string', NotReallyTeletexString),\n        ('printable_string', PrintableString),\n        ('universal_string', UniversalString),\n        ('utf8_string', UTF8String),\n        ('bmp_string', BMPString),\n        # This is an invalid/bad alternative, but some broken certs use it\n        ('ia5_string', IA5String),\n    ]\n\n\nclass NameType(ObjectIdentifier):\n    _map = {\n        '2.5.4.3': 'common_name',\n        '2.5.4.4': 'surname',\n        '2.5.4.5': 'serial_number',\n        '2.5.4.6': 'country_name',\n        '2.5.4.7': 'locality_name',\n        '2.5.4.8': 'state_or_province_name',\n        '2.5.4.9': 'street_address',\n        '2.5.4.10': 'organization_name',\n        '2.5.4.11': 'organizational_unit_name',\n        '2.5.4.12': 'title',\n        '2.5.4.15': 'business_category',\n        '2.5.4.17': 'postal_code',\n        '2.5.4.20': 'telephone_number',\n        '2.5.4.41': 'name',\n        '2.5.4.42': 'given_name',\n        '2.5.4.43': 'initials',\n        '2.5.4.44': 'generation_qualifier',\n        '2.5.4.45': 'unique_identifier',\n        '2.5.4.46': 'dn_qualifier',\n        '2.5.4.65': 'pseudonym',\n        '2.5.4.97': 'organization_identifier',\n        # https://www.trustedcomputinggroup.org/wp-content/uploads/Credential_Profile_EK_V2.0_R14_published.pdf\n        '2.23.133.2.1': 'tpm_manufacturer',\n        '2.23.133.2.2': 'tpm_model',\n        '2.23.133.2.3': 'tpm_version',\n        '2.23.133.2.4': 'platform_manufacturer',\n        '2.23.133.2.5': 'platform_model',\n        '2.23.133.2.6': 'platform_version',\n        # https://tools.ietf.org/html/rfc2985#page-26\n        '1.2.840.113549.1.9.1': 'email_address',\n        # Page 10 of https://cabforum.org/wp-content/uploads/EV-V1_5_5.pdf\n        '1.3.6.1.4.1.311.60.2.1.1': 'incorporation_locality',\n        '1.3.6.1.4.1.311.60.2.1.2': 'incorporation_state_or_province',\n        '1.3.6.1.4.1.311.60.2.1.3': 'incorporation_country',\n        # https://tools.ietf.org/html/rfc4519#section-2.39\n        '0.9.2342.19200300.100.1.1': 'user_id',\n        # https://tools.ietf.org/html/rfc2247#section-4\n        '0.9.2342.19200300.100.1.25': 'domain_component',\n        # http://www.alvestrand.no/objectid/0.2.262.1.10.7.20.html\n        '0.2.262.1.10.7.20': 'name_distinguisher',\n    }\n\n    # This order is largely based on observed order seen in EV certs from\n    # Symantec and DigiCert. Some of the uncommon name-related fields are\n    # just placed in what seems like a reasonable order.\n    preferred_order = [\n        'incorporation_country',\n        'incorporation_state_or_province',\n        'incorporation_locality',\n        'business_category',\n        'serial_number',\n        'country_name',\n        'postal_code',\n        'state_or_province_name',\n        'locality_name',\n        'street_address',\n        'organization_name',\n        'organizational_unit_name',\n        'title',\n        'common_name',\n        'user_id',\n        'initials',\n        'generation_qualifier',\n        'surname',\n        'given_name',\n        'name',\n        'pseudonym',\n        'dn_qualifier',\n        'telephone_number',\n        'email_address',\n        'domain_component',\n        'name_distinguisher',\n        'organization_identifier',\n        'tpm_manufacturer',\n        'tpm_model',\n        'tpm_version',\n        'platform_manufacturer',\n        'platform_model',\n        'platform_version',\n    ]\n\n    @classmethod\n    def preferred_ordinal(cls, attr_name):\n        \"\"\"\n        Returns an ordering value for a particular attribute key.\n\n        Unrecognized attributes and OIDs will be sorted lexically at the end.\n\n        :return:\n            An orderable value.\n\n        \"\"\"\n\n        attr_name = cls.map(attr_name)\n        if attr_name in cls.preferred_order:\n            ordinal = cls.preferred_order.index(attr_name)\n        else:\n            ordinal = len(cls.preferred_order)\n\n        return (ordinal, attr_name)\n\n    @property\n    def human_friendly(self):\n        \"\"\"\n        :return:\n            A human-friendly unicode string to display to users\n        \"\"\"\n\n        return {\n            'common_name': 'Common Name',\n            'surname': 'Surname',\n            'serial_number': 'Serial Number',\n            'country_name': 'Country',\n            'locality_name': 'Locality',\n            'state_or_province_name': 'State/Province',\n            'street_address': 'Street Address',\n            'organization_name': 'Organization',\n            'organizational_unit_name': 'Organizational Unit',\n            'title': 'Title',\n            'business_category': 'Business Category',\n            'postal_code': 'Postal Code',\n            'telephone_number': 'Telephone Number',\n            'name': 'Name',\n            'given_name': 'Given Name',\n            'initials': 'Initials',\n            'generation_qualifier': 'Generation Qualifier',\n            'unique_identifier': 'Unique Identifier',\n            'dn_qualifier': 'DN Qualifier',\n            'pseudonym': 'Pseudonym',\n            'email_address': 'Email Address',\n            'incorporation_locality': 'Incorporation Locality',\n            'incorporation_state_or_province': 'Incorporation State/Province',\n            'incorporation_country': 'Incorporation Country',\n            'domain_component': 'Domain Component',\n            'name_distinguisher': 'Name Distinguisher',\n            'organization_identifier': 'Organization Identifier',\n            'tpm_manufacturer': 'TPM Manufacturer',\n            'tpm_model': 'TPM Model',\n            'tpm_version': 'TPM Version',\n            'platform_manufacturer': 'Platform Manufacturer',\n            'platform_model': 'Platform Model',\n            'platform_version': 'Platform Version',\n            'user_id': 'User ID',\n        }.get(self.native, self.native)\n\n\nclass NameTypeAndValue(Sequence):\n    _fields = [\n        ('type', NameType),\n        ('value', Any),\n    ]\n\n    _oid_pair = ('type', 'value')\n    _oid_specs = {\n        'common_name': DirectoryString,\n        'surname': DirectoryString,\n        'serial_number': DirectoryString,\n        'country_name': DirectoryString,\n        'locality_name': DirectoryString,\n        'state_or_province_name': DirectoryString,\n        'street_address': DirectoryString,\n        'organization_name': DirectoryString,\n        'organizational_unit_name': DirectoryString,\n        'title': DirectoryString,\n        'business_category': DirectoryString,\n        'postal_code': DirectoryString,\n        'telephone_number': PrintableString,\n        'name': DirectoryString,\n        'given_name': DirectoryString,\n        'initials': DirectoryString,\n        'generation_qualifier': DirectoryString,\n        'unique_identifier': OctetBitString,\n        'dn_qualifier': DirectoryString,\n        'pseudonym': DirectoryString,\n        # https://tools.ietf.org/html/rfc2985#page-26\n        'email_address': EmailAddress,\n        # Page 10 of https://cabforum.org/wp-content/uploads/EV-V1_5_5.pdf\n        'incorporation_locality': DirectoryString,\n        'incorporation_state_or_province': DirectoryString,\n        'incorporation_country': DirectoryString,\n        'domain_component': DNSName,\n        'name_distinguisher': DirectoryString,\n        'organization_identifier': DirectoryString,\n        'tpm_manufacturer': UTF8String,\n        'tpm_model': UTF8String,\n        'tpm_version': UTF8String,\n        'platform_manufacturer': UTF8String,\n        'platform_model': UTF8String,\n        'platform_version': UTF8String,\n        'user_id': DirectoryString,\n    }\n\n    _prepped = None\n\n    @property\n    def prepped_value(self):\n        \"\"\"\n        Returns the value after being processed by the internationalized string\n        preparation as specified by RFC 5280\n\n        :return:\n            A unicode string\n        \"\"\"\n\n        if self._prepped is None:\n            self._prepped = self._ldap_string_prep(self['value'].native)\n        return self._prepped\n\n    def __ne__(self, other):\n        return not self == other\n\n    def __eq__(self, other):\n        \"\"\"\n        Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.1\n\n        :param other:\n            Another NameTypeAndValue object\n\n        :return:\n            A boolean\n        \"\"\"\n\n        if not isinstance(other, NameTypeAndValue):\n            return False\n\n        if other['type'].native != self['type'].native:\n            return False\n\n        return other.prepped_value == self.prepped_value\n\n    def _ldap_string_prep(self, string):\n        \"\"\"\n        Implements the internationalized string preparation algorithm from\n        RFC 4518. https://tools.ietf.org/html/rfc4518#section-2\n\n        :param string:\n            A unicode string to prepare\n\n        :return:\n            A prepared unicode string, ready for comparison\n        \"\"\"\n\n        # Map step\n        string = re.sub('[\\u00ad\\u1806\\u034f\\u180b-\\u180d\\ufe0f-\\uff00\\ufffc]+', '', string)\n        string = re.sub('[\\u0009\\u000a\\u000b\\u000c\\u000d\\u0085]', ' ', string)\n        if sys.maxunicode == 0xffff:\n            # Some installs of Python 2.7 don't support 8-digit unicode escape\n            # ranges, so we have to break them into pieces\n            # Original was: \\U0001D173-\\U0001D17A and \\U000E0020-\\U000E007F\n            string = re.sub('\\ud834[\\udd73-\\udd7a]|\\udb40[\\udc20-\\udc7f]|\\U000e0001', '', string)\n        else:\n            string = re.sub('[\\U0001D173-\\U0001D17A\\U000E0020-\\U000E007F\\U000e0001]', '', string)\n        string = re.sub(\n            '[\\u0000-\\u0008\\u000e-\\u001f\\u007f-\\u0084\\u0086-\\u009f\\u06dd\\u070f\\u180e\\u200c-\\u200f'\n            '\\u202a-\\u202e\\u2060-\\u2063\\u206a-\\u206f\\ufeff\\ufff9-\\ufffb]+',\n            '',\n            string\n        )\n        string = string.replace('\\u200b', '')\n        string = re.sub('[\\u00a0\\u1680\\u2000-\\u200a\\u2028-\\u2029\\u202f\\u205f\\u3000]', ' ', string)\n\n        string = ''.join(map(stringprep.map_table_b2, string))\n\n        # Normalize step\n        string = unicodedata.normalize('NFKC', string)\n\n        # Prohibit step\n        for char in string:\n            if stringprep.in_table_a1(char):\n                raise ValueError(unwrap(\n                    '''\n                    X.509 Name objects may not contain unassigned code points\n                    '''\n                ))\n\n            if stringprep.in_table_c8(char):\n                raise ValueError(unwrap(\n                    '''\n                    X.509 Name objects may not contain change display or\n                    zzzzdeprecated characters\n                    '''\n                ))\n\n            if stringprep.in_table_c3(char):\n                raise ValueError(unwrap(\n                    '''\n                    X.509 Name objects may not contain private use characters\n                    '''\n                ))\n\n            if stringprep.in_table_c4(char):\n                raise ValueError(unwrap(\n                    '''\n                    X.509 Name objects may not contain non-character code points\n                    '''\n                ))\n\n            if stringprep.in_table_c5(char):\n                raise ValueError(unwrap(\n                    '''\n                    X.509 Name objects may not contain surrogate code points\n                    '''\n                ))\n\n            if char == '\\ufffd':\n                raise ValueError(unwrap(\n                    '''\n                    X.509 Name objects may not contain the replacement character\n                    '''\n                ))\n\n        # Check bidirectional step - here we ensure that we are not mixing\n        # left-to-right and right-to-left text in the string\n        has_r_and_al_cat = False\n        has_l_cat = False\n        for char in string:\n            if stringprep.in_table_d1(char):\n                has_r_and_al_cat = True\n            elif stringprep.in_table_d2(char):\n                has_l_cat = True\n\n        if has_r_and_al_cat:\n            first_is_r_and_al = stringprep.in_table_d1(string[0])\n            last_is_r_and_al = stringprep.in_table_d1(string[-1])\n\n            if has_l_cat or not first_is_r_and_al or not last_is_r_and_al:\n                raise ValueError(unwrap(\n                    '''\n                    X.509 Name object contains a malformed bidirectional\n                    sequence\n                    '''\n                ))\n\n        # Insignificant space handling step\n        string = ' ' + re.sub(' +', '  ', string).strip() + ' '\n\n        return string\n\n\nclass RelativeDistinguishedName(SetOf):\n    _child_spec = NameTypeAndValue\n\n    @property\n    def hashable(self):\n        \"\"\"\n        :return:\n            A unicode string that can be used as a dict key or in a set\n        \"\"\"\n\n        output = []\n        values = self._get_values(self)\n        for key in sorted(values.keys()):\n            output.append('%s: %s' % (key, values[key]))\n        # Unit separator is used here since the normalization process for\n        # values moves any such character, and the keys are all dotted integers\n        # or under_score_words\n        return '\\x1F'.join(output)\n\n    def __ne__(self, other):\n        return not self == other\n\n    def __eq__(self, other):\n        \"\"\"\n        Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.1\n\n        :param other:\n            Another RelativeDistinguishedName object\n\n        :return:\n            A boolean\n        \"\"\"\n\n        if not isinstance(other, RelativeDistinguishedName):\n            return False\n\n        if len(self) != len(other):\n            return False\n\n        self_types = self._get_types(self)\n        other_types = self._get_types(other)\n\n        if self_types != other_types:\n            return False\n\n        self_values = self._get_values(self)\n        other_values = self._get_values(other)\n\n        for type_name_ in self_types:\n            if self_values[type_name_] != other_values[type_name_]:\n                return False\n\n        return True\n\n    def _get_types(self, rdn):\n        \"\"\"\n        Returns a set of types contained in an RDN\n\n        :param rdn:\n            A RelativeDistinguishedName object\n\n        :return:\n            A set object with unicode strings of NameTypeAndValue type field\n            values\n        \"\"\"\n\n        return set([ntv['type'].native for ntv in rdn])\n\n    def _get_values(self, rdn):\n        \"\"\"\n        Returns a dict of prepped values contained in an RDN\n\n        :param rdn:\n            A RelativeDistinguishedName object\n\n        :return:\n            A dict object with unicode strings of NameTypeAndValue value field\n            values that have been prepped for comparison\n        \"\"\"\n\n        output = {}\n        [output.update([(ntv['type'].native, ntv.prepped_value)]) for ntv in rdn]\n        return output\n\n\nclass RDNSequence(SequenceOf):\n    _child_spec = RelativeDistinguishedName\n\n    @property\n    def hashable(self):\n        \"\"\"\n        :return:\n            A unicode string that can be used as a dict key or in a set\n        \"\"\"\n\n        # Record separator is used here since the normalization process for\n        # values moves any such character, and the keys are all dotted integers\n        # or under_score_words\n        return '\\x1E'.join(rdn.hashable for rdn in self)\n\n    def __ne__(self, other):\n        return not self == other\n\n    def __eq__(self, other):\n        \"\"\"\n        Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.1\n\n        :param other:\n            Another RDNSequence object\n\n        :return:\n            A boolean\n        \"\"\"\n\n        if not isinstance(other, RDNSequence):\n            return False\n\n        if len(self) != len(other):\n            return False\n\n        for index, self_rdn in enumerate(self):\n            if other[index] != self_rdn:\n                return False\n\n        return True\n\n\nclass Name(Choice):\n    _alternatives = [\n        ('', RDNSequence),\n    ]\n\n    _human_friendly = None\n    _sha1 = None\n    _sha256 = None\n\n    @classmethod\n    def build(cls, name_dict, use_printable=False):\n        \"\"\"\n        Creates a Name object from a dict of unicode string keys and values.\n        The keys should be from NameType._map, or a dotted-integer OID unicode\n        string.\n\n        :param name_dict:\n            A dict of name information, e.g. {\"common_name\": \"Will Bond\",\n            \"country_name\": \"US\", \"organization_name\": \"Codex Non Sufficit LC\"}\n\n        :param use_printable:\n            A bool - if PrintableString should be used for encoding instead of\n            UTF8String. This is for backwards compatibility with old software.\n\n        :return:\n            An x509.Name object\n        \"\"\"\n\n        rdns = []\n        if not use_printable:\n            encoding_name = 'utf8_string'\n            encoding_class = UTF8String\n        else:\n            encoding_name = 'printable_string'\n            encoding_class = PrintableString\n\n        # Sort the attributes according to NameType.preferred_order\n        name_dict = OrderedDict(\n            sorted(\n                name_dict.items(),\n                key=lambda item: NameType.preferred_ordinal(item[0])\n            )\n        )\n\n        for attribute_name, attribute_value in name_dict.items():\n            attribute_name = NameType.map(attribute_name)\n            if attribute_name == 'email_address':\n                value = EmailAddress(attribute_value)\n            elif attribute_name == 'domain_component':\n                value = DNSName(attribute_value)\n            elif attribute_name in set(['dn_qualifier', 'country_name', 'serial_number']):\n                value = DirectoryString(\n                    name='printable_string',\n                    value=PrintableString(attribute_value)\n                )\n            else:\n                value = DirectoryString(\n                    name=encoding_name,\n                    value=encoding_class(attribute_value)\n                )\n\n            rdns.append(RelativeDistinguishedName([\n                NameTypeAndValue({\n                    'type': attribute_name,\n                    'value': value\n                })\n            ]))\n\n        return cls(name='', value=RDNSequence(rdns))\n\n    @property\n    def hashable(self):\n        \"\"\"\n        :return:\n            A unicode string that can be used as a dict key or in a set\n        \"\"\"\n\n        return self.chosen.hashable\n\n    def __len__(self):\n        return len(self.chosen)\n\n    def __ne__(self, other):\n        return not self == other\n\n    def __eq__(self, other):\n        \"\"\"\n        Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.1\n\n        :param other:\n            Another Name object\n\n        :return:\n            A boolean\n        \"\"\"\n\n        if not isinstance(other, Name):\n            return False\n        return self.chosen == other.chosen\n\n    @property\n    def native(self):\n        if self._native is None:\n            self._native = OrderedDict()\n            for rdn in self.chosen.native:\n                for type_val in rdn:\n                    field_name = type_val['type']\n                    if field_name in self._native:\n                        existing = self._native[field_name]\n                        if not isinstance(existing, list):\n                            existing = self._native[field_name] = [existing]\n                        existing.append(type_val['value'])\n                    else:\n                        self._native[field_name] = type_val['value']\n        return self._native\n\n    @property\n    def human_friendly(self):\n        \"\"\"\n        :return:\n            A human-friendly unicode string containing the parts of the name\n        \"\"\"\n\n        if self._human_friendly is None:\n            data = OrderedDict()\n            last_field = None\n            for rdn in self.chosen:\n                for type_val in rdn:\n                    field_name = type_val['type'].human_friendly\n                    last_field = field_name\n                    if field_name in data:\n                        data[field_name] = [data[field_name]]\n                        data[field_name].append(type_val['value'])\n                    else:\n                        data[field_name] = type_val['value']\n            to_join = []\n            keys = data.keys()\n            if last_field == 'Country':\n                keys = reversed(list(keys))\n            for key in keys:\n                value = data[key]\n                native_value = self._recursive_humanize(value)\n                to_join.append('%s: %s' % (key, native_value))\n\n            has_comma = False\n            for element in to_join:\n                if element.find(',') != -1:\n                    has_comma = True\n                    break\n\n            separator = ', ' if not has_comma else '; '\n            self._human_friendly = separator.join(to_join[::-1])\n\n        return self._human_friendly\n\n    def _recursive_humanize(self, value):\n        \"\"\"\n        Recursively serializes data compiled from the RDNSequence\n\n        :param value:\n            An Asn1Value object, or a list of Asn1Value objects\n\n        :return:\n            A unicode string\n        \"\"\"\n\n        if isinstance(value, list):\n            return ', '.join(\n                reversed([self._recursive_humanize(sub_value) for sub_value in value])\n            )\n        return value.native\n\n    @property\n    def sha1(self):\n        \"\"\"\n        :return:\n            The SHA1 hash of the DER-encoded bytes of this name\n        \"\"\"\n\n        if self._sha1 is None:\n            self._sha1 = hashlib.sha1(self.dump()).digest()\n        return self._sha1\n\n    @property\n    def sha256(self):\n        \"\"\"\n        :return:\n            The SHA-256 hash of the DER-encoded bytes of this name\n        \"\"\"\n\n        if self._sha256 is None:\n            self._sha256 = hashlib.sha256(self.dump()).digest()\n        return self._sha256\n\n\nclass AnotherName(Sequence):\n    _fields = [\n        ('type_id', ObjectIdentifier),\n        ('value', Any, {'explicit': 0}),\n    ]\n\n\nclass CountryName(Choice):\n    class_ = 1\n    tag = 1\n\n    _alternatives = [\n        ('x121_dcc_code', NumericString),\n        ('iso_3166_alpha2_code', PrintableString),\n    ]\n\n\nclass AdministrationDomainName(Choice):\n    class_ = 1\n    tag = 2\n\n    _alternatives = [\n        ('numeric', NumericString),\n        ('printable', PrintableString),\n    ]\n\n\nclass PrivateDomainName(Choice):\n    _alternatives = [\n        ('numeric', NumericString),\n        ('printable', PrintableString),\n    ]\n\n\nclass PersonalName(Set):\n    _fields = [\n        ('surname', PrintableString, {'implicit': 0}),\n        ('given_name', PrintableString, {'implicit': 1, 'optional': True}),\n        ('initials', PrintableString, {'implicit': 2, 'optional': True}),\n        ('generation_qualifier', PrintableString, {'implicit': 3, 'optional': True}),\n    ]\n\n\nclass TeletexPersonalName(Set):\n    _fields = [\n        ('surname', TeletexString, {'implicit': 0}),\n        ('given_name', TeletexString, {'implicit': 1, 'optional': True}),\n        ('initials', TeletexString, {'implicit': 2, 'optional': True}),\n        ('generation_qualifier', TeletexString, {'implicit': 3, 'optional': True}),\n    ]\n\n\nclass OrganizationalUnitNames(SequenceOf):\n    _child_spec = PrintableString\n\n\nclass TeletexOrganizationalUnitNames(SequenceOf):\n    _child_spec = TeletexString\n\n\nclass BuiltInStandardAttributes(Sequence):\n    _fields = [\n        ('country_name', CountryName, {'optional': True}),\n        ('administration_domain_name', AdministrationDomainName, {'optional': True}),\n        ('network_address', NumericString, {'implicit': 0, 'optional': True}),\n        ('terminal_identifier', PrintableString, {'implicit': 1, 'optional': True}),\n        ('private_domain_name', PrivateDomainName, {'explicit': 2, 'optional': True}),\n        ('organization_name', PrintableString, {'implicit': 3, 'optional': True}),\n        ('numeric_user_identifier', NumericString, {'implicit': 4, 'optional': True}),\n        ('personal_name', PersonalName, {'implicit': 5, 'optional': True}),\n        ('organizational_unit_names', OrganizationalUnitNames, {'implicit': 6, 'optional': True}),\n    ]\n\n\nclass BuiltInDomainDefinedAttribute(Sequence):\n    _fields = [\n        ('type', PrintableString),\n        ('value', PrintableString),\n    ]\n\n\nclass BuiltInDomainDefinedAttributes(SequenceOf):\n    _child_spec = BuiltInDomainDefinedAttribute\n\n\nclass TeletexDomainDefinedAttribute(Sequence):\n    _fields = [\n        ('type', TeletexString),\n        ('value', TeletexString),\n    ]\n\n\nclass TeletexDomainDefinedAttributes(SequenceOf):\n    _child_spec = TeletexDomainDefinedAttribute\n\n\nclass PhysicalDeliveryCountryName(Choice):\n    _alternatives = [\n        ('x121_dcc_code', NumericString),\n        ('iso_3166_alpha2_code', PrintableString),\n    ]\n\n\nclass PostalCode(Choice):\n    _alternatives = [\n        ('numeric_code', NumericString),\n        ('printable_code', PrintableString),\n    ]\n\n\nclass PDSParameter(Set):\n    _fields = [\n        ('printable_string', PrintableString, {'optional': True}),\n        ('teletex_string', TeletexString, {'optional': True}),\n    ]\n\n\nclass PrintableAddress(SequenceOf):\n    _child_spec = PrintableString\n\n\nclass UnformattedPostalAddress(Set):\n    _fields = [\n        ('printable_address', PrintableAddress, {'optional': True}),\n        ('teletex_string', TeletexString, {'optional': True}),\n    ]\n\n\nclass E1634Address(Sequence):\n    _fields = [\n        ('number', NumericString, {'implicit': 0}),\n        ('sub_address', NumericString, {'implicit': 1, 'optional': True}),\n    ]\n\n\nclass NAddresses(SetOf):\n    _child_spec = OctetString\n\n\nclass PresentationAddress(Sequence):\n    _fields = [\n        ('p_selector', OctetString, {'explicit': 0, 'optional': True}),\n        ('s_selector', OctetString, {'explicit': 1, 'optional': True}),\n        ('t_selector', OctetString, {'explicit': 2, 'optional': True}),\n        ('n_addresses', NAddresses, {'explicit': 3}),\n    ]\n\n\nclass ExtendedNetworkAddress(Choice):\n    _alternatives = [\n        ('e163_4_address', E1634Address),\n        ('psap_address', PresentationAddress, {'implicit': 0})\n    ]\n\n\nclass TerminalType(Integer):\n    _map = {\n        3: 'telex',\n        4: 'teletex',\n        5: 'g3_facsimile',\n        6: 'g4_facsimile',\n        7: 'ia5_terminal',\n        8: 'videotex',\n    }\n\n\nclass ExtensionAttributeType(Integer):\n    _map = {\n        1: 'common_name',\n        2: 'teletex_common_name',\n        3: 'teletex_organization_name',\n        4: 'teletex_personal_name',\n        5: 'teletex_organization_unit_names',\n        6: 'teletex_domain_defined_attributes',\n        7: 'pds_name',\n        8: 'physical_delivery_country_name',\n        9: 'postal_code',\n        10: 'physical_delivery_office_name',\n        11: 'physical_delivery_office_number',\n        12: 'extension_of_address_components',\n        13: 'physical_delivery_personal_name',\n        14: 'physical_delivery_organization_name',\n        15: 'extension_physical_delivery_address_components',\n        16: 'unformatted_postal_address',\n        17: 'street_address',\n        18: 'post_office_box_address',\n        19: 'poste_restante_address',\n        20: 'unique_postal_name',\n        21: 'local_postal_attributes',\n        22: 'extended_network_address',\n        23: 'terminal_type',\n    }\n\n\nclass ExtensionAttribute(Sequence):\n    _fields = [\n        ('extension_attribute_type', ExtensionAttributeType, {'implicit': 0}),\n        ('extension_attribute_value', Any, {'explicit': 1}),\n    ]\n\n    _oid_pair = ('extension_attribute_type', 'extension_attribute_value')\n    _oid_specs = {\n        'common_name': PrintableString,\n        'teletex_common_name': TeletexString,\n        'teletex_organization_name': TeletexString,\n        'teletex_personal_name': TeletexPersonalName,\n        'teletex_organization_unit_names': TeletexOrganizationalUnitNames,\n        'teletex_domain_defined_attributes': TeletexDomainDefinedAttributes,\n        'pds_name': PrintableString,\n        'physical_delivery_country_name': PhysicalDeliveryCountryName,\n        'postal_code': PostalCode,\n        'physical_delivery_office_name': PDSParameter,\n        'physical_delivery_office_number': PDSParameter,\n        'extension_of_address_components': PDSParameter,\n        'physical_delivery_personal_name': PDSParameter,\n        'physical_delivery_organization_name': PDSParameter,\n        'extension_physical_delivery_address_components': PDSParameter,\n        'unformatted_postal_address': UnformattedPostalAddress,\n        'street_address': PDSParameter,\n        'post_office_box_address': PDSParameter,\n        'poste_restante_address': PDSParameter,\n        'unique_postal_name': PDSParameter,\n        'local_postal_attributes': PDSParameter,\n        'extended_network_address': ExtendedNetworkAddress,\n        'terminal_type': TerminalType,\n    }\n\n\nclass ExtensionAttributes(SequenceOf):\n    _child_spec = ExtensionAttribute\n\n\nclass ORAddress(Sequence):\n    _fields = [\n        ('built_in_standard_attributes', BuiltInStandardAttributes),\n        ('built_in_domain_defined_attributes', BuiltInDomainDefinedAttributes, {'optional': True}),\n        ('extension_attributes', ExtensionAttributes, {'optional': True}),\n    ]\n\n\nclass EDIPartyName(Sequence):\n    _fields = [\n        ('name_assigner', DirectoryString, {'implicit': 0, 'optional': True}),\n        ('party_name', DirectoryString, {'implicit': 1}),\n    ]\n\n\nclass GeneralName(Choice):\n    _alternatives = [\n        ('other_name', AnotherName, {'implicit': 0}),\n        ('rfc822_name', EmailAddress, {'implicit': 1}),\n        ('dns_name', DNSName, {'implicit': 2}),\n        ('x400_address', ORAddress, {'implicit': 3}),\n        ('directory_name', Name, {'explicit': 4}),\n        ('edi_party_name', EDIPartyName, {'implicit': 5}),\n        ('uniform_resource_identifier', URI, {'implicit': 6}),\n        ('ip_address', IPAddress, {'implicit': 7}),\n        ('registered_id', ObjectIdentifier, {'implicit': 8}),\n    ]\n\n    def __ne__(self, other):\n        return not self == other\n\n    def __eq__(self, other):\n        \"\"\"\n        Does not support other_name, x400_address or edi_party_name\n\n        :param other:\n            The other GeneralName to compare to\n\n        :return:\n            A boolean\n        \"\"\"\n\n        if self.name in ('other_name', 'x400_address', 'edi_party_name'):\n            raise ValueError(unwrap(\n                '''\n                Comparison is not supported for GeneralName objects of\n                choice %s\n                ''',\n                self.name\n            ))\n\n        if other.name in ('other_name', 'x400_address', 'edi_party_name'):\n            raise ValueError(unwrap(\n                '''\n                Comparison is not supported for GeneralName objects of choice\n                %s''',\n                other.name\n            ))\n\n        if self.name != other.name:\n            return False\n\n        return self.chosen == other.chosen\n\n\nclass GeneralNames(SequenceOf):\n    _child_spec = GeneralName\n\n\nclass Time(Choice):\n    _alternatives = [\n        ('utc_time', UTCTime),\n        ('general_time', GeneralizedTime),\n    ]\n\n\nclass Validity(Sequence):\n    _fields = [\n        ('not_before', Time),\n        ('not_after', Time),\n    ]\n\n\nclass BasicConstraints(Sequence):\n    _fields = [\n        ('ca', Boolean, {'default': False}),\n        ('path_len_constraint', Integer, {'optional': True}),\n    ]\n\n\nclass AuthorityKeyIdentifier(Sequence):\n    _fields = [\n        ('key_identifier', OctetString, {'implicit': 0, 'optional': True}),\n        ('authority_cert_issuer', GeneralNames, {'implicit': 1, 'optional': True}),\n        ('authority_cert_serial_number', Integer, {'implicit': 2, 'optional': True}),\n    ]\n\n\nclass DistributionPointName(Choice):\n    _alternatives = [\n        ('full_name', GeneralNames, {'implicit': 0}),\n        ('name_relative_to_crl_issuer', RelativeDistinguishedName, {'implicit': 1}),\n    ]\n\n\nclass ReasonFlags(BitString):\n    _map = {\n        0: 'unused',\n        1: 'key_compromise',\n        2: 'ca_compromise',\n        3: 'affiliation_changed',\n        4: 'superseded',\n        5: 'cessation_of_operation',\n        6: 'certificate_hold',\n        7: 'privilege_withdrawn',\n        8: 'aa_compromise',\n    }\n\n\nclass GeneralSubtree(Sequence):\n    _fields = [\n        ('base', GeneralName),\n        ('minimum', Integer, {'implicit': 0, 'default': 0}),\n        ('maximum', Integer, {'implicit': 1, 'optional': True}),\n    ]\n\n\nclass GeneralSubtrees(SequenceOf):\n    _child_spec = GeneralSubtree\n\n\nclass NameConstraints(Sequence):\n    _fields = [\n        ('permitted_subtrees', GeneralSubtrees, {'implicit': 0, 'optional': True}),\n        ('excluded_subtrees', GeneralSubtrees, {'implicit': 1, 'optional': True}),\n    ]\n\n\nclass DistributionPoint(Sequence):\n    _fields = [\n        ('distribution_point', DistributionPointName, {'explicit': 0, 'optional': True}),\n        ('reasons', ReasonFlags, {'implicit': 1, 'optional': True}),\n        ('crl_issuer', GeneralNames, {'implicit': 2, 'optional': True}),\n    ]\n\n    _url = False\n\n    @property\n    def url(self):\n        \"\"\"\n        :return:\n            None or a unicode string of the distribution point's URL\n        \"\"\"\n\n        if self._url is False:\n            self._url = None\n            name = self['distribution_point']\n            if name.name != 'full_name':\n                raise ValueError(unwrap(\n                    '''\n                    CRL distribution points that are relative to the issuer are\n                    not supported\n                    '''\n                ))\n\n            for general_name in name.chosen:\n                if general_name.name == 'uniform_resource_identifier':\n                    url = general_name.native\n                    if url.lower().startswith(('http://', 'https://', 'ldap://', 'ldaps://')):\n                        self._url = url\n                        break\n\n        return self._url\n\n\nclass CRLDistributionPoints(SequenceOf):\n    _child_spec = DistributionPoint\n\n\nclass DisplayText(Choice):\n    _alternatives = [\n        ('ia5_string', IA5String),\n        ('visible_string', VisibleString),\n        ('bmp_string', BMPString),\n        ('utf8_string', UTF8String),\n    ]\n\n\nclass NoticeNumbers(SequenceOf):\n    _child_spec = Integer\n\n\nclass NoticeReference(Sequence):\n    _fields = [\n        ('organization', DisplayText),\n        ('notice_numbers', NoticeNumbers),\n    ]\n\n\nclass UserNotice(Sequence):\n    _fields = [\n        ('notice_ref', NoticeReference, {'optional': True}),\n        ('explicit_text', DisplayText, {'optional': True}),\n    ]\n\n\nclass PolicyQualifierId(ObjectIdentifier):\n    _map = {\n        '1.3.6.1.5.5.7.2.1': 'certification_practice_statement',\n        '1.3.6.1.5.5.7.2.2': 'user_notice',\n    }\n\n\nclass PolicyQualifierInfo(Sequence):\n    _fields = [\n        ('policy_qualifier_id', PolicyQualifierId),\n        ('qualifier', Any),\n    ]\n\n    _oid_pair = ('policy_qualifier_id', 'qualifier')\n    _oid_specs = {\n        'certification_practice_statement': IA5String,\n        'user_notice': UserNotice,\n    }\n\n\nclass PolicyQualifierInfos(SequenceOf):\n    _child_spec = PolicyQualifierInfo\n\n\nclass PolicyIdentifier(ObjectIdentifier):\n    _map = {\n        '2.5.29.32.0': 'any_policy',\n    }\n\n\nclass PolicyInformation(Sequence):\n    _fields = [\n        ('policy_identifier', PolicyIdentifier),\n        ('policy_qualifiers', PolicyQualifierInfos, {'optional': True})\n    ]\n\n\nclass CertificatePolicies(SequenceOf):\n    _child_spec = PolicyInformation\n\n\nclass PolicyMapping(Sequence):\n    _fields = [\n        ('issuer_domain_policy', PolicyIdentifier),\n        ('subject_domain_policy', PolicyIdentifier),\n    ]\n\n\nclass PolicyMappings(SequenceOf):\n    _child_spec = PolicyMapping\n\n\nclass PolicyConstraints(Sequence):\n    _fields = [\n        ('require_explicit_policy', Integer, {'implicit': 0, 'optional': True}),\n        ('inhibit_policy_mapping', Integer, {'implicit': 1, 'optional': True}),\n    ]\n\n\nclass KeyPurposeId(ObjectIdentifier):\n    _map = {\n        # https://tools.ietf.org/html/rfc5280#page-45\n        '2.5.29.37.0': 'any_extended_key_usage',\n        '1.3.6.1.5.5.7.3.1': 'server_auth',\n        '1.3.6.1.5.5.7.3.2': 'client_auth',\n        '1.3.6.1.5.5.7.3.3': 'code_signing',\n        '1.3.6.1.5.5.7.3.4': 'email_protection',\n        '1.3.6.1.5.5.7.3.5': 'ipsec_end_system',\n        '1.3.6.1.5.5.7.3.6': 'ipsec_tunnel',\n        '1.3.6.1.5.5.7.3.7': 'ipsec_user',\n        '1.3.6.1.5.5.7.3.8': 'time_stamping',\n        '1.3.6.1.5.5.7.3.9': 'ocsp_signing',\n        # http://tools.ietf.org/html/rfc3029.html#page-9\n        '1.3.6.1.5.5.7.3.10': 'dvcs',\n        # http://tools.ietf.org/html/rfc6268.html#page-16\n        '1.3.6.1.5.5.7.3.13': 'eap_over_ppp',\n        '1.3.6.1.5.5.7.3.14': 'eap_over_lan',\n        # https://tools.ietf.org/html/rfc5055#page-76\n        '1.3.6.1.5.5.7.3.15': 'scvp_server',\n        '1.3.6.1.5.5.7.3.16': 'scvp_client',\n        # https://tools.ietf.org/html/rfc4945#page-31\n        '1.3.6.1.5.5.7.3.17': 'ipsec_ike',\n        # https://tools.ietf.org/html/rfc5415#page-38\n        '1.3.6.1.5.5.7.3.18': 'capwap_ac',\n        '1.3.6.1.5.5.7.3.19': 'capwap_wtp',\n        # https://tools.ietf.org/html/rfc5924#page-8\n        '1.3.6.1.5.5.7.3.20': 'sip_domain',\n        # https://tools.ietf.org/html/rfc6187#page-7\n        '1.3.6.1.5.5.7.3.21': 'secure_shell_client',\n        '1.3.6.1.5.5.7.3.22': 'secure_shell_server',\n        # https://tools.ietf.org/html/rfc6494#page-7\n        '1.3.6.1.5.5.7.3.23': 'send_router',\n        '1.3.6.1.5.5.7.3.24': 'send_proxied_router',\n        '1.3.6.1.5.5.7.3.25': 'send_owner',\n        '1.3.6.1.5.5.7.3.26': 'send_proxied_owner',\n        # https://tools.ietf.org/html/rfc6402#page-10\n        '1.3.6.1.5.5.7.3.27': 'cmc_ca',\n        '1.3.6.1.5.5.7.3.28': 'cmc_ra',\n        '1.3.6.1.5.5.7.3.29': 'cmc_archive',\n        # https://tools.ietf.org/html/draft-ietf-sidr-bgpsec-pki-profiles-15#page-6\n        '1.3.6.1.5.5.7.3.30': 'bgpspec_router',\n        # https://www.ietf.org/proceedings/44/I-D/draft-ietf-ipsec-pki-req-01.txt\n        '1.3.6.1.5.5.8.2.2': 'ike_intermediate',\n        # https://msdn.microsoft.com/en-us/library/windows/desktop/aa378132(v=vs.85).aspx\n        # and https://support.microsoft.com/en-us/kb/287547\n        '1.3.6.1.4.1.311.10.3.1': 'microsoft_trust_list_signing',\n        '1.3.6.1.4.1.311.10.3.2': 'microsoft_time_stamp_signing',\n        '1.3.6.1.4.1.311.10.3.3': 'microsoft_server_gated',\n        '1.3.6.1.4.1.311.10.3.3.1': 'microsoft_serialized',\n        '1.3.6.1.4.1.311.10.3.4': 'microsoft_efs',\n        '1.3.6.1.4.1.311.10.3.4.1': 'microsoft_efs_recovery',\n        '1.3.6.1.4.1.311.10.3.5': 'microsoft_whql',\n        '1.3.6.1.4.1.311.10.3.6': 'microsoft_nt5',\n        '1.3.6.1.4.1.311.10.3.7': 'microsoft_oem_whql',\n        '1.3.6.1.4.1.311.10.3.8': 'microsoft_embedded_nt',\n        '1.3.6.1.4.1.311.10.3.9': 'microsoft_root_list_signer',\n        '1.3.6.1.4.1.311.10.3.10': 'microsoft_qualified_subordination',\n        '1.3.6.1.4.1.311.10.3.11': 'microsoft_key_recovery',\n        '1.3.6.1.4.1.311.10.3.12': 'microsoft_document_signing',\n        '1.3.6.1.4.1.311.10.3.13': 'microsoft_lifetime_signing',\n        '1.3.6.1.4.1.311.10.3.14': 'microsoft_mobile_device_software',\n        # https://support.microsoft.com/en-us/help/287547/object-ids-associated-with-microsoft-cryptography\n        '1.3.6.1.4.1.311.20.2.2': 'microsoft_smart_card_logon',\n        # https://opensource.apple.com/source\n        #  - /Security/Security-57031.40.6/Security/libsecurity_keychain/lib/SecPolicy.cpp\n        #  - /libsecurity_cssm/libsecurity_cssm-36064/lib/oidsalg.c\n        '1.2.840.113635.100.1.2': 'apple_x509_basic',\n        '1.2.840.113635.100.1.3': 'apple_ssl',\n        '1.2.840.113635.100.1.4': 'apple_local_cert_gen',\n        '1.2.840.113635.100.1.5': 'apple_csr_gen',\n        '1.2.840.113635.100.1.6': 'apple_revocation_crl',\n        '1.2.840.113635.100.1.7': 'apple_revocation_ocsp',\n        '1.2.840.113635.100.1.8': 'apple_smime',\n        '1.2.840.113635.100.1.9': 'apple_eap',\n        '1.2.840.113635.100.1.10': 'apple_software_update_signing',\n        '1.2.840.113635.100.1.11': 'apple_ipsec',\n        '1.2.840.113635.100.1.12': 'apple_ichat',\n        '1.2.840.113635.100.1.13': 'apple_resource_signing',\n        '1.2.840.113635.100.1.14': 'apple_pkinit_client',\n        '1.2.840.113635.100.1.15': 'apple_pkinit_server',\n        '1.2.840.113635.100.1.16': 'apple_code_signing',\n        '1.2.840.113635.100.1.17': 'apple_package_signing',\n        '1.2.840.113635.100.1.18': 'apple_id_validation',\n        '1.2.840.113635.100.1.20': 'apple_time_stamping',\n        '1.2.840.113635.100.1.21': 'apple_revocation',\n        '1.2.840.113635.100.1.22': 'apple_passbook_signing',\n        '1.2.840.113635.100.1.23': 'apple_mobile_store',\n        '1.2.840.113635.100.1.24': 'apple_escrow_service',\n        '1.2.840.113635.100.1.25': 'apple_profile_signer',\n        '1.2.840.113635.100.1.26': 'apple_qa_profile_signer',\n        '1.2.840.113635.100.1.27': 'apple_test_mobile_store',\n        '1.2.840.113635.100.1.28': 'apple_otapki_signer',\n        '1.2.840.113635.100.1.29': 'apple_test_otapki_signer',\n        '1.2.840.113625.100.1.30': 'apple_id_validation_record_signing_policy',\n        '1.2.840.113625.100.1.31': 'apple_smp_encryption',\n        '1.2.840.113625.100.1.32': 'apple_test_smp_encryption',\n        '1.2.840.113635.100.1.33': 'apple_server_authentication',\n        '1.2.840.113635.100.1.34': 'apple_pcs_escrow_service',\n        # http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.201-2.pdf\n        '2.16.840.1.101.3.6.8': 'piv_card_authentication',\n        '2.16.840.1.101.3.6.7': 'piv_content_signing',\n        # https://tools.ietf.org/html/rfc4556.html\n        '1.3.6.1.5.2.3.4': 'pkinit_kpclientauth',\n        '1.3.6.1.5.2.3.5': 'pkinit_kpkdc',\n        # https://www.adobe.com/devnet-docs/acrobatetk/tools/DigSig/changes.html\n        '1.2.840.113583.1.1.5': 'adobe_authentic_documents_trust',\n        # https://www.idmanagement.gov/wp-content/uploads/sites/1171/uploads/fpki-pivi-cert-profiles.pdf\n        '2.16.840.1.101.3.8.7': 'fpki_pivi_content_signing'\n    }\n\n\nclass ExtKeyUsageSyntax(SequenceOf):\n    _child_spec = KeyPurposeId\n\n\nclass AccessMethod(ObjectIdentifier):\n    _map = {\n        '1.3.6.1.5.5.7.48.1': 'ocsp',\n        '1.3.6.1.5.5.7.48.2': 'ca_issuers',\n        '1.3.6.1.5.5.7.48.3': 'time_stamping',\n        '1.3.6.1.5.5.7.48.5': 'ca_repository',\n    }\n\n\nclass AccessDescription(Sequence):\n    _fields = [\n        ('access_method', AccessMethod),\n        ('access_location', GeneralName),\n    ]\n\n\nclass AuthorityInfoAccessSyntax(SequenceOf):\n    _child_spec = AccessDescription\n\n\nclass SubjectInfoAccessSyntax(SequenceOf):\n    _child_spec = AccessDescription\n\n\n# https://tools.ietf.org/html/rfc7633\nclass Features(SequenceOf):\n    _child_spec = Integer\n\n\nclass EntrustVersionInfo(Sequence):\n    _fields = [\n        ('entrust_vers', GeneralString),\n        ('entrust_info_flags', BitString)\n    ]\n\n\nclass NetscapeCertificateType(BitString):\n    _map = {\n        0: 'ssl_client',\n        1: 'ssl_server',\n        2: 'email',\n        3: 'object_signing',\n        4: 'reserved',\n        5: 'ssl_ca',\n        6: 'email_ca',\n        7: 'object_signing_ca',\n    }\n\n\nclass Version(Integer):\n    _map = {\n        0: 'v1',\n        1: 'v2',\n        2: 'v3',\n    }\n\n\nclass TPMSpecification(Sequence):\n    _fields = [\n        ('family', UTF8String),\n        ('level', Integer),\n        ('revision', Integer),\n    ]\n\n\nclass SetOfTPMSpecification(SetOf):\n    _child_spec = TPMSpecification\n\n\nclass TCGSpecificationVersion(Sequence):\n    _fields = [\n        ('major_version', Integer),\n        ('minor_version', Integer),\n        ('revision', Integer),\n    ]\n\n\nclass TCGPlatformSpecification(Sequence):\n    _fields = [\n        ('version', TCGSpecificationVersion),\n        ('platform_class', OctetString),\n    ]\n\n\nclass SetOfTCGPlatformSpecification(SetOf):\n    _child_spec = TCGPlatformSpecification\n\n\nclass EKGenerationType(Enumerated):\n    _map = {\n        0: 'internal',\n        1: 'injected',\n        2: 'internal_revocable',\n        3: 'injected_revocable',\n    }\n\n\nclass EKGenerationLocation(Enumerated):\n    _map = {\n        0: 'tpm_manufacturer',\n        1: 'platform_manufacturer',\n        2: 'ek_cert_signer',\n    }\n\n\nclass EKCertificateGenerationLocation(Enumerated):\n    _map = {\n        0: 'tpm_manufacturer',\n        1: 'platform_manufacturer',\n        2: 'ek_cert_signer',\n    }\n\n\nclass EvaluationAssuranceLevel(Enumerated):\n    _map = {\n        1: 'level1',\n        2: 'level2',\n        3: 'level3',\n        4: 'level4',\n        5: 'level5',\n        6: 'level6',\n        7: 'level7',\n    }\n\n\nclass EvaluationStatus(Enumerated):\n    _map = {\n        0: 'designed_to_meet',\n        1: 'evaluation_in_progress',\n        2: 'evaluation_completed',\n    }\n\n\nclass StrengthOfFunction(Enumerated):\n    _map = {\n        0: 'basic',\n        1: 'medium',\n        2: 'high',\n    }\n\n\nclass URIReference(Sequence):\n    _fields = [\n        ('uniform_resource_identifier', IA5String),\n        ('hash_algorithm', DigestAlgorithm, {'optional': True}),\n        ('hash_value', BitString, {'optional': True}),\n    ]\n\n\nclass CommonCriteriaMeasures(Sequence):\n    _fields = [\n        ('version', IA5String),\n        ('assurance_level', EvaluationAssuranceLevel),\n        ('evaluation_status', EvaluationStatus),\n        ('plus', Boolean, {'default': False}),\n        ('strengh_of_function', StrengthOfFunction, {'implicit': 0, 'optional': True}),\n        ('profile_oid', ObjectIdentifier, {'implicit': 1, 'optional': True}),\n        ('profile_url', URIReference, {'implicit': 2, 'optional': True}),\n        ('target_oid', ObjectIdentifier, {'implicit': 3, 'optional': True}),\n        ('target_uri', URIReference, {'implicit': 4, 'optional': True}),\n    ]\n\n\nclass SecurityLevel(Enumerated):\n    _map = {\n        1: 'level1',\n        2: 'level2',\n        3: 'level3',\n        4: 'level4',\n    }\n\n\nclass FIPSLevel(Sequence):\n    _fields = [\n        ('version', IA5String),\n        ('level', SecurityLevel),\n        ('plus', Boolean, {'default': False}),\n    ]\n\n\nclass TPMSecurityAssertions(Sequence):\n    _fields = [\n        ('version', Version, {'default': 'v1'}),\n        ('field_upgradable', Boolean, {'default': False}),\n        ('ek_generation_type', EKGenerationType, {'implicit': 0, 'optional': True}),\n        ('ek_generation_location', EKGenerationLocation, {'implicit': 1, 'optional': True}),\n        ('ek_certificate_generation_location', EKCertificateGenerationLocation, {'implicit': 2, 'optional': True}),\n        ('cc_info', CommonCriteriaMeasures, {'implicit': 3, 'optional': True}),\n        ('fips_level', FIPSLevel, {'implicit': 4, 'optional': True}),\n        ('iso_9000_certified', Boolean, {'implicit': 5, 'default': False}),\n        ('iso_9000_uri', IA5String, {'optional': True}),\n    ]\n\n\nclass SetOfTPMSecurityAssertions(SetOf):\n    _child_spec = TPMSecurityAssertions\n\n\nclass SubjectDirectoryAttributeId(ObjectIdentifier):\n    _map = {\n        # https://tools.ietf.org/html/rfc2256#page-11\n        '2.5.4.52': 'supported_algorithms',\n        # https://www.trustedcomputinggroup.org/wp-content/uploads/Credential_Profile_EK_V2.0_R14_published.pdf\n        '2.23.133.2.16': 'tpm_specification',\n        '2.23.133.2.17': 'tcg_platform_specification',\n        '2.23.133.2.18': 'tpm_security_assertions',\n        # https://tools.ietf.org/html/rfc3739#page-18\n        '1.3.6.1.5.5.7.9.1': 'pda_date_of_birth',\n        '1.3.6.1.5.5.7.9.2': 'pda_place_of_birth',\n        '1.3.6.1.5.5.7.9.3': 'pda_gender',\n        '1.3.6.1.5.5.7.9.4': 'pda_country_of_citizenship',\n        '1.3.6.1.5.5.7.9.5': 'pda_country_of_residence',\n        # https://holtstrom.com/michael/tools/asn1decoder.php\n        '1.2.840.113533.7.68.29': 'entrust_user_role',\n    }\n\n\nclass SetOfGeneralizedTime(SetOf):\n    _child_spec = GeneralizedTime\n\n\nclass SetOfDirectoryString(SetOf):\n    _child_spec = DirectoryString\n\n\nclass SetOfPrintableString(SetOf):\n    _child_spec = PrintableString\n\n\nclass SupportedAlgorithm(Sequence):\n    _fields = [\n        ('algorithm_identifier', AnyAlgorithmIdentifier),\n        ('intended_usage', KeyUsage, {'explicit': 0, 'optional': True}),\n        ('intended_certificate_policies', CertificatePolicies, {'explicit': 1, 'optional': True}),\n    ]\n\n\nclass SetOfSupportedAlgorithm(SetOf):\n    _child_spec = SupportedAlgorithm\n\n\nclass SubjectDirectoryAttribute(Sequence):\n    _fields = [\n        ('type', SubjectDirectoryAttributeId),\n        ('values', Any),\n    ]\n\n    _oid_pair = ('type', 'values')\n    _oid_specs = {\n        'supported_algorithms': SetOfSupportedAlgorithm,\n        'tpm_specification': SetOfTPMSpecification,\n        'tcg_platform_specification': SetOfTCGPlatformSpecification,\n        'tpm_security_assertions': SetOfTPMSecurityAssertions,\n        'pda_date_of_birth': SetOfGeneralizedTime,\n        'pda_place_of_birth': SetOfDirectoryString,\n        'pda_gender': SetOfPrintableString,\n        'pda_country_of_citizenship': SetOfPrintableString,\n        'pda_country_of_residence': SetOfPrintableString,\n    }\n\n    def _values_spec(self):\n        type_ = self['type'].native\n        if type_ in self._oid_specs:\n            return self._oid_specs[type_]\n        return SetOf\n\n    _spec_callbacks = {\n        'values': _values_spec\n    }\n\n\nclass SubjectDirectoryAttributes(SequenceOf):\n    _child_spec = SubjectDirectoryAttribute\n\n\nclass ExtensionId(ObjectIdentifier):\n    _map = {\n        '2.5.29.9': 'subject_directory_attributes',\n        '2.5.29.14': 'key_identifier',\n        '2.5.29.15': 'key_usage',\n        '2.5.29.16': 'private_key_usage_period',\n        '2.5.29.17': 'subject_alt_name',\n        '2.5.29.18': 'issuer_alt_name',\n        '2.5.29.19': 'basic_constraints',\n        '2.5.29.30': 'name_constraints',\n        '2.5.29.31': 'crl_distribution_points',\n        '2.5.29.32': 'certificate_policies',\n        '2.5.29.33': 'policy_mappings',\n        '2.5.29.35': 'authority_key_identifier',\n        '2.5.29.36': 'policy_constraints',\n        '2.5.29.37': 'extended_key_usage',\n        '2.5.29.46': 'freshest_crl',\n        '2.5.29.54': 'inhibit_any_policy',\n        '1.3.6.1.5.5.7.1.1': 'authority_information_access',\n        '1.3.6.1.5.5.7.1.11': 'subject_information_access',\n        # https://tools.ietf.org/html/rfc7633\n        '1.3.6.1.5.5.7.1.24': 'tls_feature',\n        '1.3.6.1.5.5.7.48.1.5': 'ocsp_no_check',\n        '1.2.840.113533.7.65.0': 'entrust_version_extension',\n        '2.16.840.1.113730.1.1': 'netscape_certificate_type',\n        # https://tools.ietf.org/html/rfc6962.html#page-14\n        '1.3.6.1.4.1.11129.2.4.2': 'signed_certificate_timestamp_list',\n        # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-wcce/3aec3e50-511a-42f9-a5d5-240af503e470\n        '1.3.6.1.4.1.311.20.2': 'microsoft_enroll_certtype',\n    }\n\n\nclass Extension(Sequence):\n    _fields = [\n        ('extn_id', ExtensionId),\n        ('critical', Boolean, {'default': False}),\n        ('extn_value', ParsableOctetString),\n    ]\n\n    _oid_pair = ('extn_id', 'extn_value')\n    _oid_specs = {\n        'subject_directory_attributes': SubjectDirectoryAttributes,\n        'key_identifier': OctetString,\n        'key_usage': KeyUsage,\n        'private_key_usage_period': PrivateKeyUsagePeriod,\n        'subject_alt_name': GeneralNames,\n        'issuer_alt_name': GeneralNames,\n        'basic_constraints': BasicConstraints,\n        'name_constraints': NameConstraints,\n        'crl_distribution_points': CRLDistributionPoints,\n        'certificate_policies': CertificatePolicies,\n        'policy_mappings': PolicyMappings,\n        'authority_key_identifier': AuthorityKeyIdentifier,\n        'policy_constraints': PolicyConstraints,\n        'extended_key_usage': ExtKeyUsageSyntax,\n        'freshest_crl': CRLDistributionPoints,\n        'inhibit_any_policy': Integer,\n        'authority_information_access': AuthorityInfoAccessSyntax,\n        'subject_information_access': SubjectInfoAccessSyntax,\n        'tls_feature': Features,\n        'ocsp_no_check': Null,\n        'entrust_version_extension': EntrustVersionInfo,\n        'netscape_certificate_type': NetscapeCertificateType,\n        'signed_certificate_timestamp_list': OctetString,\n        # Not UTF8String as Microsofts docs claim, see:\n        # https://www.alvestrand.no/objectid/1.3.6.1.4.1.311.20.2.html\n        'microsoft_enroll_certtype': BMPString,\n    }\n\n\nclass Extensions(SequenceOf):\n    _child_spec = Extension\n\n\nclass TbsCertificate(Sequence):\n    _fields = [\n        ('version', Version, {'explicit': 0, 'default': 'v1'}),\n        ('serial_number', Integer),\n        ('signature', SignedDigestAlgorithm),\n        ('issuer', Name),\n        ('validity', Validity),\n        ('subject', Name),\n        ('subject_public_key_info', PublicKeyInfo),\n        ('issuer_unique_id', OctetBitString, {'implicit': 1, 'optional': True}),\n        ('subject_unique_id', OctetBitString, {'implicit': 2, 'optional': True}),\n        ('extensions', Extensions, {'explicit': 3, 'optional': True}),\n    ]\n\n\nclass Certificate(Sequence):\n    _fields = [\n        ('tbs_certificate', TbsCertificate),\n        ('signature_algorithm', SignedDigestAlgorithm),\n        ('signature_value', OctetBitString),\n    ]\n\n    _processed_extensions = False\n    _critical_extensions = None\n    _subject_directory_attributes_value = None\n    _key_identifier_value = None\n    _key_usage_value = None\n    _subject_alt_name_value = None\n    _issuer_alt_name_value = None\n    _basic_constraints_value = None\n    _name_constraints_value = None\n    _crl_distribution_points_value = None\n    _certificate_policies_value = None\n    _policy_mappings_value = None\n    _authority_key_identifier_value = None\n    _policy_constraints_value = None\n    _freshest_crl_value = None\n    _inhibit_any_policy_value = None\n    _extended_key_usage_value = None\n    _authority_information_access_value = None\n    _subject_information_access_value = None\n    _private_key_usage_period_value = None\n    _tls_feature_value = None\n    _ocsp_no_check_value = None\n    _issuer_serial = None\n    _authority_issuer_serial = False\n    _crl_distribution_points = None\n    _delta_crl_distribution_points = None\n    _valid_domains = None\n    _valid_ips = None\n    _self_issued = None\n    _self_signed = None\n    _sha1 = None\n    _sha256 = None\n\n    def _set_extensions(self):\n        \"\"\"\n        Sets common named extensions to private attributes and creates a list\n        of critical extensions\n        \"\"\"\n\n        self._critical_extensions = set()\n\n        for extension in self['tbs_certificate']['extensions']:\n            name = extension['extn_id'].native\n            attribute_name = '_%s_value' % name\n            if hasattr(self, attribute_name):\n                setattr(self, attribute_name, extension['extn_value'].parsed)\n            if extension['critical'].native:\n                self._critical_extensions.add(name)\n\n        self._processed_extensions = True\n\n    @property\n    def critical_extensions(self):\n        \"\"\"\n        Returns a set of the names (or OID if not a known extension) of the\n        extensions marked as critical\n\n        :return:\n            A set of unicode strings\n        \"\"\"\n\n        if not self._processed_extensions:\n            self._set_extensions()\n        return self._critical_extensions\n\n    @property\n    def private_key_usage_period_value(self):\n        \"\"\"\n        This extension is used to constrain the period over which the subject\n        private key may be used\n\n        :return:\n            None or a PrivateKeyUsagePeriod object\n        \"\"\"\n\n        if not self._processed_extensions:\n            self._set_extensions()\n        return self._private_key_usage_period_value\n\n    @property\n    def subject_directory_attributes_value(self):\n        \"\"\"\n        This extension is used to contain additional identification attributes\n        about the subject.\n\n        :return:\n            None or a SubjectDirectoryAttributes object\n        \"\"\"\n\n        if not self._processed_extensions:\n            self._set_extensions()\n        return self._subject_directory_attributes_value\n\n    @property\n    def key_identifier_value(self):\n        \"\"\"\n        This extension is used to help in creating certificate validation paths.\n        It contains an identifier that should generally, but is not guaranteed\n        to, be unique.\n\n        :return:\n            None or an OctetString object\n        \"\"\"\n\n        if not self._processed_extensions:\n            self._set_extensions()\n        return self._key_identifier_value\n\n    @property\n    def key_usage_value(self):\n        \"\"\"\n        This extension is used to define the purpose of the public key\n        contained within the certificate.\n\n        :return:\n            None or a KeyUsage\n        \"\"\"\n\n        if not self._processed_extensions:\n            self._set_extensions()\n        return self._key_usage_value\n\n    @property\n    def subject_alt_name_value(self):\n        \"\"\"\n        This extension allows for additional names to be associate with the\n        subject of the certificate. While it may contain a whole host of\n        possible names, it is usually used to allow certificates to be used\n        with multiple different domain names.\n\n        :return:\n            None or a GeneralNames object\n        \"\"\"\n\n        if not self._processed_extensions:\n            self._set_extensions()\n        return self._subject_alt_name_value\n\n    @property\n    def issuer_alt_name_value(self):\n        \"\"\"\n        This extension allows associating one or more alternative names with\n        the issuer of the certificate.\n\n        :return:\n            None or an x509.GeneralNames object\n        \"\"\"\n\n        if not self._processed_extensions:\n            self._set_extensions()\n        return self._issuer_alt_name_value\n\n    @property\n    def basic_constraints_value(self):\n        \"\"\"\n        This extension is used to determine if the subject of the certificate\n        is a CA, and if so, what the maximum number of intermediate CA certs\n        after this are, before an end-entity certificate is found.\n\n        :return:\n            None or a BasicConstraints object\n        \"\"\"\n\n        if not self._processed_extensions:\n            self._set_extensions()\n        return self._basic_constraints_value\n\n    @property\n    def name_constraints_value(self):\n        \"\"\"\n        This extension is used in CA certificates, and is used to limit the\n        possible names of certificates issued.\n\n        :return:\n            None or a NameConstraints object\n        \"\"\"\n\n        if not self._processed_extensions:\n            self._set_extensions()\n        return self._name_constraints_value\n\n    @property\n    def crl_distribution_points_value(self):\n        \"\"\"\n        This extension is used to help in locating the CRL for this certificate.\n\n        :return:\n            None or a CRLDistributionPoints object\n            extension\n        \"\"\"\n\n        if not self._processed_extensions:\n            self._set_extensions()\n        return self._crl_distribution_points_value\n\n    @property\n    def certificate_policies_value(self):\n        \"\"\"\n        This extension defines policies in CA certificates under which\n        certificates may be issued. In end-entity certificates, the inclusion\n        of a policy indicates the issuance of the certificate follows the\n        policy.\n\n        :return:\n            None or a CertificatePolicies object\n        \"\"\"\n\n        if not self._processed_extensions:\n            self._set_extensions()\n        return self._certificate_policies_value\n\n    @property\n    def policy_mappings_value(self):\n        \"\"\"\n        This extension allows mapping policy OIDs to other OIDs. This is used\n        to allow different policies to be treated as equivalent in the process\n        of validation.\n\n        :return:\n            None or a PolicyMappings object\n        \"\"\"\n\n        if not self._processed_extensions:\n            self._set_extensions()\n        return self._policy_mappings_value\n\n    @property\n    def authority_key_identifier_value(self):\n        \"\"\"\n        This extension helps in identifying the public key with which to\n        validate the authenticity of the certificate.\n\n        :return:\n            None or an AuthorityKeyIdentifier object\n        \"\"\"\n\n        if not self._processed_extensions:\n            self._set_extensions()\n        return self._authority_key_identifier_value\n\n    @property\n    def policy_constraints_value(self):\n        \"\"\"\n        This extension is used to control if policy mapping is allowed and\n        when policies are required.\n\n        :return:\n            None or a PolicyConstraints object\n        \"\"\"\n\n        if not self._processed_extensions:\n            self._set_extensions()\n        return self._policy_constraints_value\n\n    @property\n    def freshest_crl_value(self):\n        \"\"\"\n        This extension is used to help locate any available delta CRLs\n\n        :return:\n            None or an CRLDistributionPoints object\n        \"\"\"\n\n        if not self._processed_extensions:\n            self._set_extensions()\n        return self._freshest_crl_value\n\n    @property\n    def inhibit_any_policy_value(self):\n        \"\"\"\n        This extension is used to prevent mapping of the any policy to\n        specific requirements\n\n        :return:\n            None or a Integer object\n        \"\"\"\n\n        if not self._processed_extensions:\n            self._set_extensions()\n        return self._inhibit_any_policy_value\n\n    @property\n    def extended_key_usage_value(self):\n        \"\"\"\n        This extension is used to define additional purposes for the public key\n        beyond what is contained in the basic constraints.\n\n        :return:\n            None or an ExtKeyUsageSyntax object\n        \"\"\"\n\n        if not self._processed_extensions:\n            self._set_extensions()\n        return self._extended_key_usage_value\n\n    @property\n    def authority_information_access_value(self):\n        \"\"\"\n        This extension is used to locate the CA certificate used to sign this\n        certificate, or the OCSP responder for this certificate.\n\n        :return:\n            None or an AuthorityInfoAccessSyntax object\n        \"\"\"\n\n        if not self._processed_extensions:\n            self._set_extensions()\n        return self._authority_information_access_value\n\n    @property\n    def subject_information_access_value(self):\n        \"\"\"\n        This extension is used to access information about the subject of this\n        certificate.\n\n        :return:\n            None or a SubjectInfoAccessSyntax object\n        \"\"\"\n\n        if not self._processed_extensions:\n            self._set_extensions()\n        return self._subject_information_access_value\n\n    @property\n    def tls_feature_value(self):\n        \"\"\"\n        This extension is used to list the TLS features a server must respond\n        with if a client initiates a request supporting them.\n\n        :return:\n            None or a Features object\n        \"\"\"\n\n        if not self._processed_extensions:\n            self._set_extensions()\n        return self._tls_feature_value\n\n    @property\n    def ocsp_no_check_value(self):\n        \"\"\"\n        This extension is used on certificates of OCSP responders, indicating\n        that revocation information for the certificate should never need to\n        be verified, thus preventing possible loops in path validation.\n\n        :return:\n            None or a Null object (if present)\n        \"\"\"\n\n        if not self._processed_extensions:\n            self._set_extensions()\n        return self._ocsp_no_check_value\n\n    @property\n    def signature(self):\n        \"\"\"\n        :return:\n            A byte string of the signature\n        \"\"\"\n\n        return self['signature_value'].native\n\n    @property\n    def signature_algo(self):\n        \"\"\"\n        :return:\n            A unicode string of \"rsassa_pkcs1v15\", \"rsassa_pss\", \"dsa\", \"ecdsa\"\n        \"\"\"\n\n        return self['signature_algorithm'].signature_algo\n\n    @property\n    def hash_algo(self):\n        \"\"\"\n        :return:\n            A unicode string of \"md2\", \"md5\", \"sha1\", \"sha224\", \"sha256\",\n            \"sha384\", \"sha512\", \"sha512_224\", \"sha512_256\"\n        \"\"\"\n\n        return self['signature_algorithm'].hash_algo\n\n    @property\n    def public_key(self):\n        \"\"\"\n        :return:\n            The PublicKeyInfo object for this certificate\n        \"\"\"\n\n        return self['tbs_certificate']['subject_public_key_info']\n\n    @property\n    def subject(self):\n        \"\"\"\n        :return:\n            The Name object for the subject of this certificate\n        \"\"\"\n\n        return self['tbs_certificate']['subject']\n\n    @property\n    def issuer(self):\n        \"\"\"\n        :return:\n            The Name object for the issuer of this certificate\n        \"\"\"\n\n        return self['tbs_certificate']['issuer']\n\n    @property\n    def serial_number(self):\n        \"\"\"\n        :return:\n            An integer of the certificate's serial number\n        \"\"\"\n\n        return self['tbs_certificate']['serial_number'].native\n\n    @property\n    def key_identifier(self):\n        \"\"\"\n        :return:\n            None or a byte string of the certificate's key identifier from the\n            key identifier extension\n        \"\"\"\n\n        if not self.key_identifier_value:\n            return None\n\n        return self.key_identifier_value.native\n\n    @property\n    def issuer_serial(self):\n        \"\"\"\n        :return:\n            A byte string of the SHA-256 hash of the issuer concatenated with\n            the ascii character \":\", concatenated with the serial number as\n            an ascii string\n        \"\"\"\n\n        if self._issuer_serial is None:\n            self._issuer_serial = self.issuer.sha256 + b':' + str_cls(self.serial_number).encode('ascii')\n        return self._issuer_serial\n\n    @property\n    def not_valid_after(self):\n        \"\"\"\n        :return:\n            A datetime of latest time when the certificate is still valid\n        \"\"\"\n        return self['tbs_certificate']['validity']['not_after'].native\n\n    @property\n    def not_valid_before(self):\n        \"\"\"\n        :return:\n            A datetime of the earliest time when the certificate is valid\n        \"\"\"\n        return self['tbs_certificate']['validity']['not_before'].native\n\n    @property\n    def authority_key_identifier(self):\n        \"\"\"\n        :return:\n            None or a byte string of the key_identifier from the authority key\n            identifier extension\n        \"\"\"\n\n        if not self.authority_key_identifier_value:\n            return None\n\n        return self.authority_key_identifier_value['key_identifier'].native\n\n    @property\n    def authority_issuer_serial(self):\n        \"\"\"\n        :return:\n            None or a byte string of the SHA-256 hash of the isser from the\n            authority key identifier extension concatenated with the ascii\n            character \":\", concatenated with the serial number from the\n            authority key identifier extension as an ascii string\n        \"\"\"\n\n        if self._authority_issuer_serial is False:\n            akiv = self.authority_key_identifier_value\n            if akiv and akiv['authority_cert_issuer'].native:\n                issuer = self.authority_key_identifier_value['authority_cert_issuer'][0].chosen\n                # We untag the element since it is tagged via being a choice from GeneralName\n                issuer = issuer.untag()\n                authority_serial = self.authority_key_identifier_value['authority_cert_serial_number'].native\n                self._authority_issuer_serial = issuer.sha256 + b':' + str_cls(authority_serial).encode('ascii')\n            else:\n                self._authority_issuer_serial = None\n        return self._authority_issuer_serial\n\n    @property\n    def crl_distribution_points(self):\n        \"\"\"\n        Returns complete CRL URLs - does not include delta CRLs\n\n        :return:\n            A list of zero or more DistributionPoint objects\n        \"\"\"\n\n        if self._crl_distribution_points is None:\n            self._crl_distribution_points = self._get_http_crl_distribution_points(self.crl_distribution_points_value)\n        return self._crl_distribution_points\n\n    @property\n    def delta_crl_distribution_points(self):\n        \"\"\"\n        Returns delta CRL URLs - does not include complete CRLs\n\n        :return:\n            A list of zero or more DistributionPoint objects\n        \"\"\"\n\n        if self._delta_crl_distribution_points is None:\n            self._delta_crl_distribution_points = self._get_http_crl_distribution_points(self.freshest_crl_value)\n        return self._delta_crl_distribution_points\n\n    def _get_http_crl_distribution_points(self, crl_distribution_points):\n        \"\"\"\n        Fetches the DistributionPoint object for non-relative, HTTP CRLs\n        referenced by the certificate\n\n        :param crl_distribution_points:\n            A CRLDistributionPoints object to grab the DistributionPoints from\n\n        :return:\n            A list of zero or more DistributionPoint objects\n        \"\"\"\n\n        output = []\n\n        if crl_distribution_points is None:\n            return []\n\n        for distribution_point in crl_distribution_points:\n            distribution_point_name = distribution_point['distribution_point']\n            if distribution_point_name is VOID:\n                continue\n            # RFC 5280 indicates conforming CA should not use the relative form\n            if distribution_point_name.name == 'name_relative_to_crl_issuer':\n                continue\n            # This library is currently only concerned with HTTP-based CRLs\n            for general_name in distribution_point_name.chosen:\n                if general_name.name == 'uniform_resource_identifier':\n                    output.append(distribution_point)\n\n        return output\n\n    @property\n    def ocsp_urls(self):\n        \"\"\"\n        :return:\n            A list of zero or more unicode strings of the OCSP URLs for this\n            cert\n        \"\"\"\n\n        if not self.authority_information_access_value:\n            return []\n\n        output = []\n        for entry in self.authority_information_access_value:\n            if entry['access_method'].native == 'ocsp':\n                location = entry['access_location']\n                if location.name != 'uniform_resource_identifier':\n                    continue\n                url = location.native\n                if url.lower().startswith(('http://', 'https://', 'ldap://', 'ldaps://')):\n                    output.append(url)\n        return output\n\n    @property\n    def valid_domains(self):\n        \"\"\"\n        :return:\n            A list of unicode strings of valid domain names for the certificate.\n            Wildcard certificates will have a domain in the form: *.example.com\n        \"\"\"\n\n        if self._valid_domains is None:\n            self._valid_domains = []\n\n            # For the subject alt name extension, we can look at the name of\n            # the choice selected since it distinguishes between domain names,\n            # email addresses, IPs, etc\n            if self.subject_alt_name_value:\n                for general_name in self.subject_alt_name_value:\n                    if general_name.name == 'dns_name' and general_name.native not in self._valid_domains:\n                        self._valid_domains.append(general_name.native)\n\n            # If there was no subject alt name extension, and the common name\n            # in the subject looks like a domain, that is considered the valid\n            # list. This is done because according to\n            # https://tools.ietf.org/html/rfc6125#section-6.4.4, the common\n            # name should not be used if the subject alt name is present.\n            else:\n                pattern = re.compile('^(\\\\*\\\\.)?(?:[a-zA-Z0-9](?:[a-zA-Z0-9\\\\-]*[a-zA-Z0-9])?\\\\.)+[a-zA-Z]{2,}$')\n                for rdn in self.subject.chosen:\n                    for name_type_value in rdn:\n                        if name_type_value['type'].native == 'common_name':\n                            value = name_type_value['value'].native\n                            if pattern.match(value):\n                                self._valid_domains.append(value)\n\n        return self._valid_domains\n\n    @property\n    def valid_ips(self):\n        \"\"\"\n        :return:\n            A list of unicode strings of valid IP addresses for the certificate\n        \"\"\"\n\n        if self._valid_ips is None:\n            self._valid_ips = []\n\n            if self.subject_alt_name_value:\n                for general_name in self.subject_alt_name_value:\n                    if general_name.name == 'ip_address':\n                        self._valid_ips.append(general_name.native)\n\n        return self._valid_ips\n\n    @property\n    def ca(self):\n        \"\"\"\n        :return;\n            A boolean - if the certificate is marked as a CA\n        \"\"\"\n\n        return self.basic_constraints_value and self.basic_constraints_value['ca'].native\n\n    @property\n    def max_path_length(self):\n        \"\"\"\n        :return;\n            None or an integer of the maximum path length\n        \"\"\"\n\n        if not self.ca:\n            return None\n        return self.basic_constraints_value['path_len_constraint'].native\n\n    @property\n    def self_issued(self):\n        \"\"\"\n        :return:\n            A boolean - if the certificate is self-issued, as defined by RFC\n            5280\n        \"\"\"\n\n        if self._self_issued is None:\n            self._self_issued = self.subject == self.issuer\n        return self._self_issued\n\n    @property\n    def self_signed(self):\n        \"\"\"\n        :return:\n            A unicode string of \"no\" or \"maybe\". The \"maybe\" result will\n            be returned if the certificate issuer and subject are the same.\n            If a key identifier and authority key identifier are present,\n            they will need to match otherwise \"no\" will be returned.\n\n            To verify is a certificate is truly self-signed, the signature\n            will need to be verified. See the certvalidator package for\n            one possible solution.\n        \"\"\"\n\n        if self._self_signed is None:\n            self._self_signed = 'no'\n            if self.self_issued:\n                if self.key_identifier:\n                    if not self.authority_key_identifier:\n                        self._self_signed = 'maybe'\n                    elif self.authority_key_identifier == self.key_identifier:\n                        self._self_signed = 'maybe'\n                else:\n                    self._self_signed = 'maybe'\n        return self._self_signed\n\n    @property\n    def sha1(self):\n        \"\"\"\n        :return:\n            The SHA-1 hash of the DER-encoded bytes of this complete certificate\n        \"\"\"\n\n        if self._sha1 is None:\n            self._sha1 = hashlib.sha1(self.dump()).digest()\n        return self._sha1\n\n    @property\n    def sha1_fingerprint(self):\n        \"\"\"\n        :return:\n            A unicode string of the SHA-1 hash, formatted using hex encoding\n            with a space between each pair of characters, all uppercase\n        \"\"\"\n\n        return ' '.join('%02X' % c for c in bytes_to_list(self.sha1))\n\n    @property\n    def sha256(self):\n        \"\"\"\n        :return:\n            The SHA-256 hash of the DER-encoded bytes of this complete\n            certificate\n        \"\"\"\n\n        if self._sha256 is None:\n            self._sha256 = hashlib.sha256(self.dump()).digest()\n        return self._sha256\n\n    @property\n    def sha256_fingerprint(self):\n        \"\"\"\n        :return:\n            A unicode string of the SHA-256 hash, formatted using hex encoding\n            with a space between each pair of characters, all uppercase\n        \"\"\"\n\n        return ' '.join('%02X' % c for c in bytes_to_list(self.sha256))\n\n    def is_valid_domain_ip(self, domain_ip):\n        \"\"\"\n        Check if a domain name or IP address is valid according to the\n        certificate\n\n        :param domain_ip:\n            A unicode string of a domain name or IP address\n\n        :return:\n            A boolean - if the domain or IP is valid for the certificate\n        \"\"\"\n\n        if not isinstance(domain_ip, str_cls):\n            raise TypeError(unwrap(\n                '''\n                domain_ip must be a unicode string, not %s\n                ''',\n                type_name(domain_ip)\n            ))\n\n        encoded_domain_ip = domain_ip.encode('idna').decode('ascii').lower()\n\n        is_ipv6 = encoded_domain_ip.find(':') != -1\n        is_ipv4 = not is_ipv6 and re.match('^\\\\d+\\\\.\\\\d+\\\\.\\\\d+\\\\.\\\\d+$', encoded_domain_ip)\n        is_domain = not is_ipv6 and not is_ipv4\n\n        # Handle domain name checks\n        if is_domain:\n            if not self.valid_domains:\n                return False\n\n            domain_labels = encoded_domain_ip.split('.')\n\n            for valid_domain in self.valid_domains:\n                encoded_valid_domain = valid_domain.encode('idna').decode('ascii').lower()\n                valid_domain_labels = encoded_valid_domain.split('.')\n\n                # The domain must be equal in label length to match\n                if len(valid_domain_labels) != len(domain_labels):\n                    continue\n\n                if valid_domain_labels == domain_labels:\n                    return True\n\n                is_wildcard = self._is_wildcard_domain(encoded_valid_domain)\n                if is_wildcard and self._is_wildcard_match(domain_labels, valid_domain_labels):\n                    return True\n\n            return False\n\n        # Handle IP address checks\n        if not self.valid_ips:\n            return False\n\n        family = socket.AF_INET if is_ipv4 else socket.AF_INET6\n        normalized_ip = inet_pton(family, encoded_domain_ip)\n\n        for valid_ip in self.valid_ips:\n            valid_family = socket.AF_INET if valid_ip.find('.') != -1 else socket.AF_INET6\n            normalized_valid_ip = inet_pton(valid_family, valid_ip)\n\n            if normalized_valid_ip == normalized_ip:\n                return True\n\n        return False\n\n    def _is_wildcard_domain(self, domain):\n        \"\"\"\n        Checks if a domain is a valid wildcard according to\n        https://tools.ietf.org/html/rfc6125#section-6.4.3\n\n        :param domain:\n            A unicode string of the domain name, where any U-labels from an IDN\n            have been converted to A-labels\n\n        :return:\n            A boolean - if the domain is a valid wildcard domain\n        \"\"\"\n\n        # The * character must be present for a wildcard match, and if there is\n        # most than one, it is an invalid wildcard specification\n        if domain.count('*') != 1:\n            return False\n\n        labels = domain.lower().split('.')\n\n        if not labels:\n            return False\n\n        # Wildcards may only appear in the left-most label\n        if labels[0].find('*') == -1:\n            return False\n\n        # Wildcards may not be embedded in an A-label from an IDN\n        if labels[0][0:4] == 'xn--':\n            return False\n\n        return True\n\n    def _is_wildcard_match(self, domain_labels, valid_domain_labels):\n        \"\"\"\n        Determines if the labels in a domain are a match for labels from a\n        wildcard valid domain name\n\n        :param domain_labels:\n            A list of unicode strings, with A-label form for IDNs, of the labels\n            in the domain name to check\n\n        :param valid_domain_labels:\n            A list of unicode strings, with A-label form for IDNs, of the labels\n            in a wildcard domain pattern\n\n        :return:\n            A boolean - if the domain matches the valid domain\n        \"\"\"\n\n        first_domain_label = domain_labels[0]\n        other_domain_labels = domain_labels[1:]\n\n        wildcard_label = valid_domain_labels[0]\n        other_valid_domain_labels = valid_domain_labels[1:]\n\n        # The wildcard is only allowed in the first label, so if\n        # The subsequent labels are not equal, there is no match\n        if other_domain_labels != other_valid_domain_labels:\n            return False\n\n        if wildcard_label == '*':\n            return True\n\n        wildcard_regex = re.compile('^' + wildcard_label.replace('*', '.*') + '$')\n        if wildcard_regex.match(first_domain_label):\n            return True\n\n        return False\n\n\n# The structures are taken from the OpenSSL source file x_x509a.c, and specify\n# extra information that is added to X.509 certificates to store trust\n# information about the certificate.\n\nclass KeyPurposeIdentifiers(SequenceOf):\n    _child_spec = KeyPurposeId\n\n\nclass SequenceOfAlgorithmIdentifiers(SequenceOf):\n    _child_spec = AlgorithmIdentifier\n\n\nclass CertificateAux(Sequence):\n    _fields = [\n        ('trust', KeyPurposeIdentifiers, {'optional': True}),\n        ('reject', KeyPurposeIdentifiers, {'implicit': 0, 'optional': True}),\n        ('alias', UTF8String, {'optional': True}),\n        ('keyid', OctetString, {'optional': True}),\n        ('other', SequenceOfAlgorithmIdentifiers, {'implicit': 1, 'optional': True}),\n    ]\n\n\nclass TrustedCertificate(Concat):\n    _child_specs = [Certificate, CertificateAux]\n"
  },
  {
    "path": "code/default/lib/noarch/dnslib/__init__.py",
    "content": "# -*- coding: utf-8 -*-\n\n\"\"\"\ndnslib\n------\n\nA library to encode/decode DNS wire-format packets supporting both\nPython 2.7 and Python 3.2+.\n\nThe library provides:\n\n * Support for encoding/decoding DNS packets between wire format,\n   python objects, and Zone/DiG textual representation (dnslib.dns)\n\n * A server framework allowing the simple creation of custom DNS\n   resolvers (dnslib.server) and a number of example servers\n   created using this frameowork\n\n * A number of utilities for testing (dnslib.client, dnslib.proxy,\n   dnslib.intercept)\n\nPython 3 support was added in Version 0.9.0 which represented a fairly\nmajor update to the library - the key changes include:\n\n * Python 2.7/3.2+ support (the last version supporting Python 2.6\n   or earlier was version 0.8.3)\n\n * The 'Bimap' interface was changed significantly to explicitly\n   split forward (value->text) lookups via __getitem__ and\n   reverse (text->value) lookups via __getattr__. Applications\n   using the old interface will need to be updated.\n\n * Hostnames are now returned with a trailing dot by default (in\n   line with RFC)\n\n * Most object attributes are now typed in line with the record\n   definitions to make it harder to generate invalid packets\n\n * Support for encoding/decoding resource records in 'Zone' (BIND)\n   file format\n\n * Support for encoding/decoding backets in 'DiG' format\n\n * Server framework allowing (in most cases) custom resolvers to\n   be created by just subclassing the DNSResolver class and\n   overringing the 'resolve' method\n\n * A lot of fixes to error detection/handling which should make\n   the library much more robust to invalid/unsupported data. The\n   library should now either return a valid DNSRecord instance\n   when parsing a packet or raise DNSError (tested via fuzzing)\n\n * Improved utilities (dnslib.client, dnslib.proxy, dnslib.intercept)\n\n * Improvements to encoding/decoding tests including the ability\n   to generate test data automatically in test_decode.py (comparing\n   outputs against DiG)\n\n * Ability to compare and diff DNSRecords\n\nThis is a large release and despite the testing there therefore are likely\nto be some bugs. Once the 0.9 release is sufficiently stable I would expect\nto release as 1.0.0 (and stabilise th api)\n\nThe key DNS packet handling classes are in dnslib.dns and map to the\nstandard DNS packet sections:\n\n * DNSRecord - container for DNS packet. Contains:\n    - DNSHeader\n    - Question section containing zero or more DNSQuestion objects\n    - Answer section containing zero or more RR objects\n    - Authority section containing zero or more RR objects\n    - Additional section containing zero or more RR objects\n * DNS RRs (resource records) contain an RR header and an RD object)\n * Specific RD types are implemented as subclasses of RD\n * DNS labels are represented by a DNSLabel class - in most cases\n   this handles conversion to/from textual representation however\n   does support arbitatry labels via a tuple of bytes objects)\n\nVersion 0.9 of the library was a major rewrite to support Python 3.2+\n(retaining support for Python 2.7+). As part of the Py3 changes a\nnumber of other significant changes were intrtoduced:\n\n- Much better error handling (packet decoding errors should be\n  caught and DNSError raised)\n\nUsage:\n------\n\nTo decode a DNS packet:\n\n    >>> packet = binascii.unhexlify(b'd5ad818000010005000000000377777706676f6f676c6503636f6d0000010001c00c0005000100000005000803777777016cc010c02c0001000100000005000442f95b68c02c0001000100000005000442f95b63c02c0001000100000005000442f95b67c02c0001000100000005000442f95b93')\n    >>> d = DNSRecord.parse(packet)\n    >>> d\n    <DNS Header: id=0xd5ad type=RESPONSE opcode=QUERY flags=RD,RA rcode='NOERROR' q=1 a=5 ns=0 ar=0>\n    <DNS Question: 'www.google.com.' qtype=A qclass=IN>\n    <DNS RR: 'www.google.com.' rtype=CNAME rclass=IN ttl=5 rdata='www.l.google.com.'>\n    <DNS RR: 'www.l.google.com.' rtype=A rclass=IN ttl=5 rdata='66.249.91.104'>\n    <DNS RR: 'www.l.google.com.' rtype=A rclass=IN ttl=5 rdata='66.249.91.99'>\n    <DNS RR: 'www.l.google.com.' rtype=A rclass=IN ttl=5 rdata='66.249.91.103'>\n    <DNS RR: 'www.l.google.com.' rtype=A rclass=IN ttl=5 rdata='66.249.91.147'>\n\nThe default text representation of the DNSRecord is in zone file format:\n\n    >>> print(d)\n    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 54701\n    ;; flags: qr rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 0\n    ;; QUESTION SECTION:\n    ;www.google.com.                IN      A\n    ;; ANSWER SECTION:\n    www.google.com.         5       IN      CNAME   www.l.google.com.\n    www.l.google.com.       5       IN      A       66.249.91.104\n    www.l.google.com.       5       IN      A       66.249.91.99\n    www.l.google.com.       5       IN      A       66.249.91.103\n    www.l.google.com.       5       IN      A       66.249.91.147\n\nTo create a DNS Request Packet:\n\n    >>> d = DNSRecord.question(\"google.com\")\n\n(This is equivalent to: d = DNSRecord(q=DNSQuestion(\"google.com\") )\n\n    >>> d\n    <DNS Header: id=... type=QUERY opcode=QUERY flags=RD rcode='NOERROR' q=1 a=0 ns=0 ar=0>\n    <DNS Question: 'google.com.' qtype=A qclass=IN>\n\n    >>> str(DNSRecord.parse(d.pack())) == str(d)\n    True\n\n    >>> print(d)\n    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...\n    ;; flags: rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0\n    ;; QUESTION SECTION:\n    ;google.com.                    IN      A\n\n    >>> d = DNSRecord.question(\"google.com\",\"MX\")\n\n(This is equivalent to: d = DNSRecord(q=DNSQuestion(\"google.com\",QTYPE.MX) )\n\n    >>> str(DNSRecord.parse(d.pack())) == str(d)\n    True\n\n    >>> print(d)\n    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...\n    ;; flags: rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0\n    ;; QUESTION SECTION:\n    ;google.com.                    IN      MX\n\nTo create a DNS Response Packet:\n\n    >>> d = DNSRecord(DNSHeader(qr=1,aa=1,ra=1),\n    ...               q=DNSQuestion(\"abc.com\"),\n    ...               a=RR(\"abc.com\",rdata=A(\"1.2.3.4\")))\n    >>> d\n    <DNS Header: id=... type=RESPONSE opcode=QUERY flags=AA,RD,RA rcode='NOERROR' q=1 a=1 ns=0 ar=0>\n    <DNS Question: 'abc.com.' qtype=A qclass=IN>\n    <DNS RR: 'abc.com.' rtype=A rclass=IN ttl=0 rdata='1.2.3.4'>\n    >>> str(DNSRecord.parse(d.pack())) == str(d)\n    True\n\n    >>> print(d)\n    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...\n    ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0\n    ;; QUESTION SECTION:\n    ;abc.com.                       IN      A\n    ;; ANSWER SECTION:\n    abc.com.                0       IN      A       1.2.3.4\n\nIt is also possible to create RRs from a string in zone file format\n\n    >>> RR.fromZone(\"abc.com IN A 1.2.3.4\")\n    [<DNS RR: 'abc.com.' rtype=A rclass=IN ttl=0 rdata='1.2.3.4'>]\n\n(Note: this produces a list of RRs which should be unpacked if being\n    passed to add_answer/add_auth/add_ar etc)\n\n    >>> q = DNSRecord.question(\"abc.com\")\n    >>> a = q.reply()\n    >>> a.add_answer(*RR.fromZone(\"abc.com 60 A 1.2.3.4\"))\n    >>> print(a)\n    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...\n    ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0\n    ;; QUESTION SECTION:\n    ;abc.com.                       IN      A\n    ;; ANSWER SECTION:\n    abc.com.                60      IN      A       1.2.3.4\n\nThe zone file can contain multiple entries and supports most of the normal\nformat defined in RFC1035 (specifically not $INCLUDE)\n\n    >>> z = '''\n    ...         $TTL 300\n    ...         $ORIGIN abc.com\n    ...\n    ...         @       IN      MX      10  mail.abc.com.\n    ...         www     IN      A       1.2.3.4\n    ...                 IN      TXT     \"Some Text\"\n    ...         mail    IN      CNAME   www.abc.com.\n    ... '''\n    >>> for rr in RR.fromZone(textwrap.dedent(z)):\n    ...     print(rr)\n    abc.com.                300     IN      MX      10 mail.abc.com.\n    www.abc.com.            300     IN      A       1.2.3.4\n    www.abc.com.            300     IN      TXT     \"Some Text\"\n    mail.abc.com.           300     IN      CNAME   www.abc.com.\n\nTo create a skeleton reply to a DNS query:\n\n    >>> q = DNSRecord(q=DNSQuestion(\"abc.com\",QTYPE.ANY))\n    >>> a = q.reply()\n    >>> a.add_answer(RR(\"abc.com\",QTYPE.A,rdata=A(\"1.2.3.4\"),ttl=60))\n    >>> str(DNSRecord.parse(a.pack())) == str(a)\n    True\n    >>> print(a)\n    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...\n    ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0\n    ;; QUESTION SECTION:\n    ;abc.com.                       IN      ANY\n    ;; ANSWER SECTION:\n    abc.com.                60      IN      A       1.2.3.4\n\nAdd additional RRs:\n\n    >>> a.add_answer(RR(\"xxx.abc.com\",QTYPE.A,rdata=A(\"1.2.3.4\")))\n    >>> a.add_answer(RR(\"xxx.abc.com\",QTYPE.AAAA,rdata=AAAA(\"1234:5678::1\")))\n    >>> str(DNSRecord.parse(a.pack())) == str(a)\n    True\n    >>> print(a)\n    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...\n    ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0\n    ;; QUESTION SECTION:\n    ;abc.com.                       IN      ANY\n    ;; ANSWER SECTION:\n    abc.com.                60      IN      A       1.2.3.4\n    xxx.abc.com.            0       IN      A       1.2.3.4\n    xxx.abc.com.            0       IN      AAAA    1234:5678::1\n\n\nIt is also possible to create a reply from a string in zone file format:\n\n    >>> q = DNSRecord(q=DNSQuestion(\"abc.com\",QTYPE.ANY))\n    >>> a = q.replyZone(\"abc.com 60 IN CNAME xxx.abc.com\")\n    >>> print(a)\n    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...\n    ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0\n    ;; QUESTION SECTION:\n    ;abc.com.                       IN      ANY\n    ;; ANSWER SECTION:\n    abc.com.                60      IN      CNAME   xxx.abc.com.\n\n    >>> str(DNSRecord.parse(a.pack())) == str(a)\n    True\n\n    >>> q = DNSRecord(q=DNSQuestion(\"abc.com\",QTYPE.ANY))\n    >>> a = q.replyZone(textwrap.dedent(z))\n    >>> print(a)\n    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...\n    ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 0\n    ;; QUESTION SECTION:\n    ;abc.com.                       IN      ANY\n    ;; ANSWER SECTION:\n    abc.com.                300     IN      MX      10 mail.abc.com.\n    www.abc.com.            300     IN      A       1.2.3.4\n    www.abc.com.            300     IN      TXT     \"Some Text\"\n    mail.abc.com.           300     IN      CNAME   www.abc.com.\n\n\nThe library also includes a simple framework for generating custom DNS\nresolvers in dnslib.server (see module docs). In post cases this just\nrequires implementing a custom 'resolve' method which receives a question\nobject and returns a response.\n\nA number of sample resolvers are provided as examples (see CLI --help):\n\n * dnslib.fixedresolver    - Respond to all requests with fixed response\n * dnslib.zoneresolver     - Respond from Zone file\n * dnslib.shellresolver    - Call shell script to generate response\n\nThe library includes a number of client utilities:\n\n * DiG like client library\n\n        # python -m dnslib.client --help\n\n * DNS Proxy Server\n\n        # python -m dnslib.proxy --help\n\n * Intercepting DNS Proxy Server (replace proxy responses for specified domains)\n\n        # python -m dnslib.intercept --help\n\n\nChangelog:\n----------\n\n *   0.1     2010-09-19  Initial Release\n *   0.2     2010-09-22  Minor fixes\n *   0.3     2010-10-02  Add DNSLabel class to support arbitrary labels (embedded '.')\n *   0.4     2012-02-26  Merge with dbslib-circuits\n *   0.5     2012-09-13  Add support for RFC2136 DDNS updates\n                         Patch provided by Wesley Shields <wxs@FreeBSD.org> - thanks\n *   0.6     2012-10-20  Basic AAAA support\n *   0.7     2012-10-20  Add initial EDNS0 support (untested)\n *   0.8     2012-11-04  Add support for NAPTR, Authority RR and additional RR\n                         Patch provided by Stefan Andersson (https://bitbucket.org/norox) - thanks\n *   0.8.1   2012-11-05  Added NAPTR test case and fixed logic error\n                         Patch provided by Stefan Andersson (https://bitbucket.org/norox) - thanks\n *   0.8.2   2012-11-11  Patch to fix IPv6 formatting\n                         Patch provided by Torbjörn Lönnemark (https://bitbucket.org/tobbezz) - thanks\n *   0.8.3   2013-04-27  Don't parse rdata if rdlength is 0\n                         Patch provided by Wesley Shields <wxs@FreeBSD.org> - thanks\n *   0.9.0   2014-05-05  Major update including Py3 support (see docs)\n *   0.9.1   2014-05-05  Minor fixes\n *   0.9.2   2014-08-26  Fix Bimap handling of unknown mappings to avoid exception in printing\n                         Add typed attributes to classes\n                         Misc fixes from James Mills - thanks\n *   0.9.3   2014-08-26  Workaround for argparse bug which raises AssertionError is [] is\n                         present in option text (really?)\n\nLicense:\n--------\n\nBSD\n\nAuthor:\n-------\n\n *   Paul Chakravarti (paul.chakravarti@gmail.com)\n\nMaster Repository/Issues:\n-------------------------\n\n *   https://bitbucket.org/paulc/dnslib\n    (Cloned on GitHub: https://github.com/paulchakravarti/dnslib)\n\"\"\"\n\nfrom dnslib.dns import *\n\nversion = \"0.9.3\"\n\nif __name__ == '__main__':\n    import doctest,textwrap\n    doctest.testmod(optionflags=doctest.ELLIPSIS)\n\n"
  },
  {
    "path": "code/default/lib/noarch/dnslib/bimap.py",
    "content": "# -*- coding: utf-8 -*-\n\n\"\"\"\n    Bimap - bidirectional mapping between code/value\n\"\"\"\n\nclass BimapError(Exception):\n    pass\n\nclass Bimap(object):\n\n    \"\"\"\n        Bi-directional mapping between code/value.\n\n        Initialised using:\n\n            name:   Used for exceptions\n            dict:   Dict mapping from value (numeric) to code (text)\n            error:  Error type to raise if key not found\n\n        The class provides:\n\n            * A 'forward' map (code->text) which is accessed through\n              __getitem__ (bimap[code])\n            * A 'reverse' map (code>value) which is accessed through\n              __getattr__ (bimap.text)\n            * A 'get' method which does a forward lookup (code->text)\n              and returns a textual version of code if there is no\n              explicit mapping (or default provided)\n\n        >>> class TestError(Exception):\n        ...     pass\n\n        >>> TEST = Bimap('TEST',{1:'A', 2:'B', 3:'C'},TestError)\n        >>> TEST[1]\n        'A'\n        >>> TEST.A\n        1\n        >>> TEST.X\n        Traceback (most recent call last):\n        ...\n        TestError: TEST: Invalid reverse lookup: [X]\n        >>> TEST[99]\n        Traceback (most recent call last):\n        ...\n        TestError: TEST: Invalid forward lookup: [99]\n        >>> TEST.get(99)\n        '99'\n\n    \"\"\"\n\n    def __init__(self,name,forward,error=KeyError):\n        self.name = name\n        self.error = error\n        self.forward = forward.copy()\n        self.reverse = dict([(v,k) for (k,v) in list(forward.items())])\n\n    def get(self,k,default=None):\n        try:\n            return self.forward[k]\n        except KeyError as e:\n            return default or str(k)\n\n    def __getitem__(self,k):\n        try:\n            return self.forward[k]\n        except KeyError as e:\n            raise self.error(\"%s: Invalid forward lookup: [%s]\" % (self.name,k))\n\n    def __getattr__(self,k):\n        try:\n            return self.reverse[k]\n        except KeyError as e:\n            raise self.error(\"%s: Invalid reverse lookup: [%s]\" % (self.name,k))\n\nif __name__ == '__main__':\n    import doctest\n    doctest.testmod()\n"
  },
  {
    "path": "code/default/lib/noarch/dnslib/bit.py",
    "content": "# -*- coding: utf-8 -*-\n\n\"\"\"\n    Some basic bit mainpulation utilities\n\"\"\"\n\n\nFILTER = bytearray([ (i < 32 or i > 127) and 46 or i for i in range(256) ])\n\ndef hexdump(src, length=16, prefix=''):\n    \"\"\"\n    Print hexdump of string\n\n    >>> print(hexdump(b\"abcd\" * 4))\n    0000  61 62 63 64 61 62 63 64  61 62 63 64 61 62 63 64  abcdabcd abcdabcd\n\n    >>> print(hexdump(bytearray(range(48))))\n    0000  00 01 02 03 04 05 06 07  08 09 0a 0b 0c 0d 0e 0f  ........ ........\n    0010  10 11 12 13 14 15 16 17  18 19 1a 1b 1c 1d 1e 1f  ........ ........\n    0020  20 21 22 23 24 25 26 27  28 29 2a 2b 2c 2d 2e 2f   !\"#$%&' ()*+,-./\n\n    \"\"\"\n    n = 0\n    left = length // 2\n    right = length - left\n    result= []\n    src = bytearray(src)\n    while src:\n        s,src = src[:length],src[length:]\n        l,r = s[:left],s[left:]\n        hexa = \"%-*s\" % (left*3,' '.join([\"%02x\"%x for x in l]))\n        hexb = \"%-*s\" % (right*3,' '.join([\"%02x\"%x for x in r]))\n        lf = l.translate(FILTER)\n        rf = r.translate(FILTER)\n        result.append(\"%s%04x  %s %s %s %s\" % (prefix, n, hexa, hexb,\n                                               lf.decode(), rf.decode()))\n        n += length\n    return \"\\n\".join(result)\n\ndef get_bits(data,offset,bits=1):\n    \"\"\"\n        Get specified bits from integer\n\n        >>> bin(get_bits(0b0011100,2))\n        '0b1'\n        >>> bin(get_bits(0b0011100,0,4))\n        '0b1100'\n\n    \"\"\"\n    mask = ((1 << bits) - 1) << offset\n    return (data & mask) >> offset\n\ndef set_bits(data,value,offset,bits=1):\n    \"\"\"\n        Set specified bits in integer\n\n        >>> bin(set_bits(0,0b1010,0,4))\n        '0b1010'\n        >>> bin(set_bits(0,0b1010,3,4))\n        '0b1010000'\n    \"\"\"\n    mask = ((1 << bits) - 1) << offset\n    clear = 0xffff ^ mask\n    data = (data & clear) | ((value << offset) & mask)\n    return data\n\ndef binary(n,count=16,reverse=False):\n    \"\"\"\n        Display n in binary (only difference from built-in `bin` is\n        that this function returns a fixed width string and can\n        optionally be reversed\n\n        >>> binary(6789)\n        '0001101010000101'\n        >>> binary(6789,8)\n        '10000101'\n        >>> binary(6789,reverse=True)\n        '1010000101011000'\n\n    \"\"\"\n    bits = [str((n >> y) & 1) for y in range(count-1, -1, -1)]\n    if reverse:\n        bits.reverse()\n    return \"\".join(bits)\n\nif __name__ == '__main__':\n    import doctest\n    doctest.testmod()\n\n"
  },
  {
    "path": "code/default/lib/noarch/dnslib/buffer.py",
    "content": "# -*- coding: utf-8 -*-\n\n\"\"\"\n    Buffer - simple data buffer\n\"\"\"\n\nimport binascii,struct\n\nclass BufferError(Exception):\n    pass\n\nclass Buffer(object):\n\n    \"\"\"\n    A simple data buffer - supports packing/unpacking in struct format\n\n    # Needed for Python 2/3 doctest compatibility\n    >>> def p(s):\n    ...     if not isinstance(s,str):\n    ...         return s.decode()\n    ...     return s\n\n    >>> b = Buffer()\n    >>> b.pack(\"!BHI\",1,2,3)\n    >>> b.offset\n    7\n    >>> b.append(b\"0123456789\")\n    >>> b.offset\n    17\n    >>> p(b.hex())\n    '0100020000000330313233343536373839'\n    >>> b.offset = 0\n    >>> b.unpack(\"!BHI\")\n    (1, 2, 3)\n    >>> bytearray(b.get(5))\n    bytearray(b'01234')\n    >>> bytearray(b.get(5))\n    bytearray(b'56789')\n    >>> b.update(7,\"2s\",b\"xx\")\n    >>> b.offset = 7\n    >>> bytearray(b.get(5))\n    bytearray(b'xx234')\n    \"\"\"\n\n    def __init__(self,data=b''):\n        \"\"\"\n            Initialise Buffer from data\n        \"\"\"\n        self.data = bytearray(data)\n        self.offset = 0\n\n    def remaining(self):\n        \"\"\"\n            Return bytes remaining\n        \"\"\"\n        return len(self.data) - self.offset\n\n    def get(self,length):\n        \"\"\"\n            Gen len bytes at current offset (& increment offset)\n        \"\"\"\n        if length > self.remaining():\n            raise BufferError(\"Not enough bytes [offset=%d,remaining=%d,requested=%d]\" %\n                    (self.offset,self.remaining(),length))\n        start = self.offset\n        end = self.offset + length\n        self.offset += length\n        return bytes(self.data[start:end])\n\n    def hex(self):\n        \"\"\"\n            Return data as hex string\n        \"\"\"\n        return binascii.hexlify(self.data)\n\n    def pack(self,fmt,*args):\n        \"\"\"\n            Pack data at end of data according to fmt (from struct) & increment\n            offset\n        \"\"\"\n        self.offset += struct.calcsize(fmt)\n        self.data += struct.pack(fmt,*args)\n\n    def append(self,s):\n        \"\"\"\n            Append s to end of data & increment offset\n        \"\"\"\n        self.offset += len(s)\n        self.data += s\n\n    def update(self,ptr,fmt,*args):\n        \"\"\"\n            Modify data at offset `ptr`\n        \"\"\"\n        s = struct.pack(fmt,*args)\n        self.data[ptr:ptr+len(s)] = s\n\n    def unpack(self,fmt):\n        \"\"\"\n            Unpack data at current offset according to fmt (from struct)\n        \"\"\"\n        try:\n            data = self.get(struct.calcsize(fmt))\n            return struct.unpack(fmt,data)\n        except struct.error as e:\n            raise BufferError(\"Error unpacking struct '%s' <%s>\" %\n                    (fmt,binascii.hexlify(data).decode()))\n\n    def __len__(self):\n        return len(self.data)\n\nif __name__ == '__main__':\n    import doctest\n    doctest.testmod()\n"
  },
  {
    "path": "code/default/lib/noarch/dnslib/client.py",
    "content": "# -*- coding: utf-8 -*-\n\n\"\"\"\n    DNS Client - DiG-like CLI utility.\n\n    Mostly useful for testing. Can optionally compare results from two\n    nameservers (--diff) or compare results against DiG (--dig).\n\n    Usage: python -m dnslib.client [options|--help]\n\n    See --help for usage.\n\"\"\"\n\n\n\ntry:\n    from subprocess import getoutput\nexcept ImportError:\n    from subprocess import getoutput\n\nimport binascii,code,pprint\n\nfrom dnslib.dns import DNSRecord,DNSHeader,DNSQuestion,QTYPE\nfrom dnslib.digparser import DigParser\n\nif __name__ == '__main__':\n\n    import argparse,sys,time\n\n    p = argparse.ArgumentParser(description=\"DNS Client\")\n    p.add_argument(\"--server\",\"-s\",default=\"8.8.8.8\",\n                    metavar=\"<address:port>\",\n                    help=\"Server address:port (default:8.8.8.8:53) (port is optional)\")\n    p.add_argument(\"--query\",action='store_true',default=False,\n                    help=\"Show query (default: False)\")\n    p.add_argument(\"--hex\",action='store_true',default=False,\n                    help=\"Dump packet in hex (default: False)\")\n    p.add_argument(\"--tcp\",action='store_true',default=False,\n                    help=\"Use TCP (default: UDP)\")\n    p.add_argument(\"--noretry\",action='store_true',default=False,\n                    help=\"Don't retry query using TCP if truncated (default: false)\")\n    p.add_argument(\"--diff\",default=\"\",\n                    help=\"Compare response from alternate nameserver (format: address:port / default: false)\")\n    p.add_argument(\"--dig\",action='store_true',default=False,\n                    help=\"Compare result with DiG - if ---diff also specified use alternative nameserver for DiG request (default: false)\")\n    p.add_argument(\"--short\",action='store_true',default=False,\n                    help=\"Short output - rdata only (default: false)\")\n    p.add_argument(\"--debug\",action='store_true',default=False,\n                    help=\"Drop into CLI after request (default: false)\")\n    p.add_argument(\"domain\",metavar=\"<domain>\",\n                    help=\"Query domain\")\n    p.add_argument(\"qtype\",metavar=\"<type>\",default=\"A\",nargs=\"?\",\n                    help=\"Query type (default: A)\")\n    args = p.parse_args()\n\n    # Construct request\n    q = DNSRecord(q=DNSQuestion(args.domain,getattr(QTYPE,args.qtype)))\n\n    address,_,port = args.server.partition(':')\n    port = int(port or 53)\n\n    if args.query:\n        print(\";; Sending%s:\" % (\" (TCP)\" if args.tcp else \"\"))\n        if args.hex:\n            print(\";; QUERY:\",binascii.hexlify(q.pack()).decode())\n        print(q)\n        print()\n\n    a_pkt = q.send(address,port,tcp=args.tcp)\n    a = DNSRecord.parse(a_pkt)\n\n    if a.header.tc and args.noretry == False:\n        # Truncated - retry in TCP mode\n        a_pkt = q.send(address,port,tcp=True)\n        a = DNSRecord.parse(a_pkt)\n\n    if args.dig or args.diff:\n        if args.diff:\n            address,_,port = args.diff.partition(':')\n            port = int(port or 53)\n\n        if args.dig:\n            dig = getoutput(\"dig +qr -p %d %s %s @%s\" % (\n                                port, args.domain, args.qtype, address))\n            dig_reply = list(iter(DigParser(dig)))\n            # DiG might have retried in TCP mode so get last q/a\n            q_diff = dig_reply[-2]\n            a_diff = dig_reply[-1]\n        else:\n            q_diff = DNSRecord(header=DNSHeader(id=q.header.id),\n                               q=DNSQuestion(args.domain,\n                                             getattr(QTYPE,args.qtype)))\n            q_diff = q\n            diff = q_diff.send(address,port,tcp=args.tcp)\n            a_diff = DNSRecord.parse(diff)\n            if a_diff.header.tc and args.noretry == False:\n                diff = q_diff.send(address,port,tcp=True)\n                a_diff = DNSRecord.parse(diff)\n\n    if args.short:\n        print(a.short())\n    else:\n        print(\";; Got answer:\")\n        if args.hex:\n            print(\";; RESPONSE:\",binascii.hexlify(a_pkt).decode())\n            if args.diff and not args.dig:\n                print(\";; DIFF    :\",binascii.hexlify(diff).decode())\n        print(a)\n        print()\n\n        if args.dig or args.diff:\n            if q != q_diff:\n                print(\";;; ERROR: Diff Question differs\")\n                for (d1,d2) in q.diff(q_diff):\n                    if d1:\n                        print(\";; - %s\" % d1)\n                    if d2:\n                        print(\";; + %s\" % d2)\n            if a != a_diff:\n                print(\";;; ERROR: Diff Response differs\")\n                for (d1,d2) in a.diff(a_diff):\n                    if d1:\n                        print(\";; - %s\" % d1)\n                    if d2:\n                        print(\";; + %s\" % d2)\n\n    if args.debug:\n        code.interact(local=locals())\n\n"
  },
  {
    "path": "code/default/lib/noarch/dnslib/dns.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\n    DNS - main dnslib module\n\n    Contains core DNS packet handling code\n\"\"\"\n\n\nimport sys\nimport base64,binascii,collections,copy,os.path,random,socket,\\\n       string,struct,textwrap,time\n\nfrom itertools import chain\n\ntry:\n    from itertools import zip_longest\nexcept ImportError:\n    if sys.version_info[0] == 2:\n        from itertools import izip_longest as zip_longest\n    else:\n        from itertools import zip_longest as zip_longest\n\nfrom dnslib.bit import get_bits,set_bits\nfrom dnslib.bimap import Bimap,BimapError\nfrom dnslib.buffer import Buffer,BufferError\nfrom dnslib.label import DNSLabel,DNSLabelError,DNSBuffer\nfrom dnslib.lex import WordLexer\nfrom dnslib.ranges import B,H,I,IP4,IP6,ntuple_range\n\nclass DNSError(Exception):\n    pass\n\n# DNS codes\n\nQTYPE =  Bimap('QTYPE',\n                {1:'A', 2:'NS', 5:'CNAME', 6:'SOA', 12:'PTR', 15:'MX',\n                 16:'TXT', 17:'RP', 18:'AFSDB', 24:'SIG', 25:'KEY', 28:'AAAA',\n                 29:'LOC', 33:'SRV', 35:'NAPTR', 36:'KX', 37:'CERT', 39:'DNAME',\n                 41:'OPT', 42:'APL', 43:'DS', 44:'SSHFP', 45:'IPSECKEY',\n                 46:'RRSIG', 47:'NSEC', 48:'DNSKEY', 49:'DHCID', 50:'NSEC3',\n                 51:'NSEC3PARAM', 52:'TLSA', 55:'HIP', 99:'SPF', 249:'TKEY',\n                 250:'TSIG', 251:'IXFR', 252:'AXFR', 255:'ANY', 257:'TYPE257',\n                 32768:'TA', 32769:'DLV'},\n                DNSError)\nCLASS =  Bimap('CLASS',\n                {1:'IN', 2:'CS', 3:'CH', 4:'Hesiod', 254:'None', 255:'*'},\n                DNSError)\nQR =     Bimap('QR',\n                {0:'QUERY', 1:'RESPONSE'},\n                DNSError)\nRCODE =  Bimap('RCODE',\n                {0:'NOERROR', 1:'FORMERR', 2:'SERVFAIL', 3:'NXDOMAIN',\n                 4:'NOTIMP', 5:'REFUSED', 6:'YXDOMAIN', 7:'YXRRSET',\n                 8:'NXRRSET', 9:'NOTAUTH', 10:'NOTZONE'},\n                DNSError)\nOPCODE = Bimap('OPCODE',{0:'QUERY', 1:'IQUERY', 2:'STATUS', 5:'UPDATE'},\n                DNSError)\n\ndef label(label,origin=None):\n    if label.endswith(\".\"):\n        return DNSLabel(label)\n    else:\n        return (origin if isinstance(origin,DNSLabel)\n                       else DNSLabel(origin)).add(label)\n\nclass DNSRecord(object):\n\n    \"\"\"\n        Main DNS class - corresponds to DNS packet & comprises DNSHeader,\n        DNSQuestion and RR sections (answer,ns,ar)\n\n        >>> d = DNSRecord()\n        >>> d.add_question(DNSQuestion(\"abc.com\")) # Or DNSRecord.question(\"abc.com\")\n        >>> d.add_answer(RR(\"abc.com\",QTYPE.CNAME,ttl=60,rdata=CNAME(\"ns.abc.com\")))\n        >>> d.add_auth(RR(\"abc.com\",QTYPE.SOA,ttl=60,rdata=SOA(\"ns.abc.com\",\"admin.abc.com\",(20140101,3600,3600,3600,3600))))\n        >>> d.add_ar(RR(\"ns.abc.com\",ttl=60,rdata=A(\"1.2.3.4\")))\n        >>> print(d)\n        ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...\n        ;; flags: rd; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1\n        ;; QUESTION SECTION:\n        ;abc.com.                       IN      A\n        ;; ANSWER SECTION:\n        abc.com.                60      IN      CNAME   ns.abc.com.\n        ;; AUTHORITY SECTION:\n        abc.com.                60      IN      SOA     ns.abc.com. admin.abc.com. 20140101 3600 3600 3600 3600\n        ;; ADDITIONAL SECTION:\n        ns.abc.com.             60      IN      A       1.2.3.4\n        >>> str(d) == str(DNSRecord.parse(d.pack()))\n        True\n    \"\"\"\n\n    @classmethod\n    def parse(cls,packet):\n        \"\"\"\n            Parse DNS packet data and return DNSRecord instance\n            Recursively parses sections (calling appropriate parse method)\n        \"\"\"\n        buffer = DNSBuffer(packet)\n        try:\n            header = DNSHeader.parse(buffer)\n            questions = []\n            rr = []\n            auth = []\n            ar = []\n            for i in range(header.q):\n                questions.append(DNSQuestion.parse(buffer))\n            for i in range(header.a):\n                rr.append(RR.parse(buffer))\n            for i in range(header.auth):\n                auth.append(RR.parse(buffer))\n            for i in range(header.ar):\n                ar.append(RR.parse(buffer))\n            return cls(header,questions,rr,auth=auth,ar=ar)\n        except DNSError:\n            raise\n        except (BufferError,BimapError) as e:\n            raise DNSError(\"Error unpacking DNSRecord [offset=%d]: %s\" % (\n                                    buffer.offset,e))\n\n    @classmethod\n    def question(cls,qname,qtype=\"A\",qclass=\"IN\"):\n        \"\"\"\n            Shortcut to create question\n\n            >>> q = DNSRecord.question(\"www.google.com\")\n            >>> print(q)\n            ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...\n            ;; flags: rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0\n            ;; QUESTION SECTION:\n            ;www.google.com.                IN      A\n\n            >>> q = DNSRecord.question(\"www.google.com\",\"NS\")\n            >>> print(q)\n            ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...\n            ;; flags: rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0\n            ;; QUESTION SECTION:\n            ;www.google.com.                IN      NS\n        \"\"\"\n        return DNSRecord(q=DNSQuestion(qname,getattr(QTYPE,qtype),\n                                             getattr(CLASS,qclass)))\n\n\n    def __init__(self,header=None,questions=None,\n                      rr=None,q=None,a=None,auth=None,ar=None):\n        \"\"\"\n            Create new DNSRecord\n        \"\"\"\n        self.header = header or DNSHeader()\n        self.questions = questions or []\n        self.rr = rr or []\n        self.auth = auth or []\n        self.ar = ar or []\n        # Shortcuts to add a single Question/Answer\n        if q:\n            self.questions.append(q)\n        if a:\n            self.rr.append(a)\n        self.set_header_qa()\n\n    def reply(self,ra=1,aa=1):\n        \"\"\"\n            Create skeleton reply packet\n\n            >>> q = DNSRecord.question(\"abc.com\")\n            >>> a = q.reply()\n            >>> a.add_answer(RR(\"abc.com\",QTYPE.A,rdata=A(\"1.2.3.4\"),ttl=60))\n            >>> print(a)\n            ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...\n            ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0\n            ;; QUESTION SECTION:\n            ;abc.com.                       IN      A\n            ;; ANSWER SECTION:\n            abc.com.                60      IN      A       1.2.3.4\n        \"\"\"\n        return DNSRecord(DNSHeader(id=self.header.id,\n                                   bitmap=self.header.bitmap,\n                                   qr=1,ra=ra,aa=aa),\n                         q=self.q)\n\n    def replyZone(self,zone,ra=1,aa=1):\n        \"\"\"\n            Create reply with response data in zone-file format\n            >>> q = DNSRecord.question(\"abc.com\")\n            >>> a = q.replyZone(\"abc.com 60 A 1.2.3.4\")\n            >>> print(a)\n            ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...\n            ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0\n            ;; QUESTION SECTION:\n            ;abc.com.                       IN      A\n            ;; ANSWER SECTION:\n            abc.com.                60      IN      A       1.2.3.4\n        \"\"\"\n        return DNSRecord(DNSHeader(id=self.header.id,\n                                   bitmap=self.header.bitmap,\n                                   qr=1,ra=ra,aa=aa),\n                         q=self.q,\n                         rr=RR.fromZone(zone))\n\n    def add_question(self,*q):\n        \"\"\"\n            Add question(s)\n\n            >>> q = DNSRecord()\n            >>> q.add_question(DNSQuestion(\"abc.com\"),\n            ...                DNSQuestion(\"abc.com\",QTYPE.MX))\n            >>> print(q)\n            ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...\n            ;; flags: rd; QUERY: 2, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0\n            ;; QUESTION SECTION:\n            ;abc.com.                       IN      A\n            ;abc.com.                       IN      MX\n        \"\"\"\n        self.questions.extend(q)\n        self.set_header_qa()\n\n    def add_answer(self,*rr):\n        \"\"\"\n            Add answer(s)\n\n            >>> q = DNSRecord.question(\"abc.com\")\n            >>> a = q.reply()\n            >>> a.add_answer(*RR.fromZone(\"abc.com A 1.2.3.4\"))\n            >>> print(a)\n            ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...\n            ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0\n            ;; QUESTION SECTION:\n            ;abc.com.                       IN      A\n            ;; ANSWER SECTION:\n            abc.com.                0       IN      A       1.2.3.4\n        \"\"\"\n        self.rr.extend(rr)\n        self.set_header_qa()\n\n    def add_auth(self,*auth):\n        \"\"\"\n            Add authority records\n\n            >>> q = DNSRecord.question(\"abc.com\")\n            >>> a = q.reply()\n            >>> a.add_answer(*RR.fromZone(\"abc.com 60 A 1.2.3.4\"))\n            >>> a.add_auth(*RR.fromZone(\"abc.com 3600 NS nsa.abc.com\"))\n            >>> print(a)\n            ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...\n            ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 0\n            ;; QUESTION SECTION:\n            ;abc.com.                       IN      A\n            ;; ANSWER SECTION:\n            abc.com.                60      IN      A       1.2.3.4\n            ;; AUTHORITY SECTION:\n            abc.com.                3600    IN      NS      nsa.abc.com.\n        \"\"\"\n        self.auth.extend(auth)\n        self.set_header_qa()\n\n    def add_ar(self,*ar):\n        \"\"\"\n            Add additional records\n\n            >>> q = DNSRecord.question(\"abc.com\")\n            >>> a = q.reply()\n            >>> a.add_answer(*RR.fromZone(\"abc.com 60 CNAME x.abc.com\"))\n            >>> a.add_ar(*RR.fromZone(\"x.abc.com 3600 A 1.2.3.4\"))\n            >>> print(a)\n            ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...\n            ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1\n            ;; QUESTION SECTION:\n            ;abc.com.                       IN      A\n            ;; ANSWER SECTION:\n            abc.com.                60      IN      CNAME   x.abc.com.\n            ;; ADDITIONAL SECTION:\n            x.abc.com.              3600    IN      A       1.2.3.4\n        \"\"\"\n        self.ar.extend(ar)\n        self.set_header_qa()\n\n    def set_header_qa(self):\n        \"\"\"\n            Reset header q/a/auth/ar counts to match numver of records\n            (normally done transparently)\n        \"\"\"\n        self.header.q = len(self.questions)\n        self.header.a = len(self.rr)\n        self.header.auth = len(self.auth)\n        self.header.ar = len(self.ar)\n\n    # Shortcut to get first question\n    def get_q(self):\n        return self.questions[0] if self.questions else DNSQuestion()\n    q = property(get_q)\n\n    # Shortcut to get first answer\n    def get_a(self):\n        return self.rr[0] if self.rr else RR()\n    a = property(get_a)\n\n    def pack(self):\n        \"\"\"\n            Pack record into binary packet\n            (recursively packs each section into buffer)\n\n            >>> q = DNSRecord.question(\"abc.com\")\n            >>> q.header.id = 1234\n            >>> a = q.replyZone(\"abc.com A 1.2.3.4\")\n            >>> a.header.aa = 0\n            >>> pkt = a.pack()\n            >>> print(DNSRecord.parse(pkt))\n            ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1234\n            ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0\n            ;; QUESTION SECTION:\n            ;abc.com.                       IN      A\n            ;; ANSWER SECTION:\n            abc.com.                0       IN      A       1.2.3.4\n        \"\"\"\n        self.set_header_qa()\n        buffer = DNSBuffer()\n        self.header.pack(buffer)\n        for q in self.questions:\n            q.pack(buffer)\n        for rr in self.rr:\n            rr.pack(buffer)\n        for auth in self.auth:\n            auth.pack(buffer)\n        for ar in self.ar:\n            ar.pack(buffer)\n        return buffer.data\n\n    def truncate(self):\n        \"\"\"\n            Return truncated copy of DNSRecord (with TC flag set)\n            (removes all Questions & RRs and just returns header)\n\n            >>> q = DNSRecord.question(\"abc.com\")\n            >>> a = q.reply()\n            >>> a.add_answer(*RR.fromZone('abc.com IN TXT %s' % ('x' * 255)))\n            >>> a.add_answer(*RR.fromZone('abc.com IN TXT %s' % ('x' * 255)))\n            >>> a.add_answer(*RR.fromZone('abc.com IN TXT %s' % ('x' * 255)))\n            >>> len(a.pack())\n            829\n            >>> t = a.truncate()\n            >>> print(t)\n            ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...\n            ;; flags: qr aa tc rd ra; QUERY: 0, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0\n\n        \"\"\"\n        return DNSRecord(DNSHeader(id=self.header.id,\n                                   bitmap=self.header.bitmap,\n                                   tc=1))\n\n    def send(self,dest,port=53,tcp=False,timeout=None):\n        \"\"\"\n            Send packet to nameserver and return response\n        \"\"\"\n        data = self.pack()\n        if tcp:\n            if len(data) > 65535:\n                raise ValueError(\"Packet length too long: %d\" % len(data))\n            data = struct.pack(\"!H\",len(data)) + data\n            sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)\n            if timeout is not None:\n                sock.settimeout(timeout)\n            sock.connect((dest,port))\n            sock.sendall(data)\n            response = sock.recv(8192)\n            length = struct.unpack(\"!H\",bytes(response[:2]))[0]\n            while len(response) - 2 < length:\n                response += sock.recv(8192)\n            sock.close()\n            response = response[2:]\n        else:\n            sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)\n            if timeout is not None:\n                sock.settimeout(timeout)\n            sock.sendto(self.pack(),(dest,port))\n            response,server = sock.recvfrom(8192)\n            sock.close()\n        return response\n\n    def format(self,prefix=\"\",sort=False):\n        \"\"\"\n            Formatted 'repr'-style representation of record\n            (optionally with prefix and/or sorted RRs)\n        \"\"\"\n        s = sorted if sort else lambda x:x\n        sections = [ repr(self.header) ]\n        sections.extend(s([repr(q) for q in self.questions]))\n        sections.extend(s([repr(rr) for rr in self.rr]))\n        sections.extend(s([repr(rr) for rr in self.auth]))\n        sections.extend(s([repr(rr) for rr in self.ar]))\n        return prefix + (\"\\n\" + prefix).join(sections)\n\n    def toZone(self,prefix=\"\"):\n        \"\"\"\n            Formatted 'DiG' (zone) style output\n            (with optional prefix)\n        \"\"\"\n        z = self.header.toZone().split(\"\\n\")\n        if self.questions:\n            z.append(\";; QUESTION SECTION:\")\n            [ z.extend(q.toZone().split(\"\\n\")) for q in self.questions ]\n        if self.rr:\n            z.append(\";; ANSWER SECTION:\")\n            [ z.extend(rr.toZone().split(\"\\n\")) for rr in self.rr ]\n        if self.auth:\n            z.append(\";; AUTHORITY SECTION:\")\n            [ z.extend(rr.toZone().split(\"\\n\")) for rr in self.auth ]\n        if self.ar:\n            z.append(\";; ADDITIONAL SECTION:\")\n            [ z.extend(rr.toZone().split(\"\\n\")) for rr in self.ar ]\n        return prefix + (\"\\n\" + prefix).join(z)\n\n    def short(self):\n        \"\"\"\n            Just return RDATA\n        \"\"\"\n        return \"\\n\".join([rr.rdata.toZone() for rr in self.rr])\n\n    def __eq__(self,other):\n        \"\"\"\n            Test for equality by diffing records\n        \"\"\"\n        if type(other) != type(self):\n            return False\n        else:\n            return self.diff(other) == []\n\n    def __ne__(self,other):\n        return not(self.__eq__(other))\n\n    def diff(self,other):\n        \"\"\"\n            Diff records - recursively diff sections (sorting RRs)\n        \"\"\"\n        err = []\n        if self.header != other.header:\n            err.append((self.header,other.header))\n        for section in ('questions','rr','auth','ar'):\n            if section == 'questions':\n                k = lambda x:tuple(map(str,(x.qname,x.qtype)))\n            else:\n                k = lambda x:tuple(map(str,(x.rname,x.rtype,x.rdata)))\n            a = dict([(k(rr),rr) for rr in getattr(self,section)])\n            b = dict([(k(rr),rr) for rr in getattr(other,section)])\n            sa = set(a)\n            sb = set(b)\n            for e in sorted(sa.intersection(sb)):\n                if a[e] != b[e]:\n                    err.append((a[e],b[e]))\n            for e in sorted(sa.difference(sb)):\n                err.append((a[e],None))\n            for e in sorted(sb.difference(sa)):\n                err.append((None,b[e]))\n        return err\n\n    def __repr__(self):\n        return self.format()\n\n    def __str__(self):\n        return self.toZone()\n\nclass DNSHeader(object):\n\n    \"\"\"\n        DNSHeader section\n    \"\"\"\n\n    # Ensure attribute values match packet\n    id = H('id')\n    bitmap = H('bitmap')\n    q = H('q')\n    a = H('a')\n    auth = H('auth')\n    ar = H('ar')\n\n    @classmethod\n    def parse(cls,buffer):\n        \"\"\"\n            Implements parse interface\n        \"\"\"\n        try:\n            (id,bitmap,q,a,auth,ar) = buffer.unpack(\"!HHHHHH\")\n            return cls(id,bitmap,q,a,auth,ar)\n        except (BufferError,BimapError) as e:\n            raise DNSError(\"Error unpacking DNSHeader [offset=%d]: %s\" % (\n                                buffer.offset,e))\n\n    def __init__(self,id=None,bitmap=None,q=0,a=0,auth=0,ar=0,**args):\n        if id is None:\n            self.id = random.randint(0,65535)\n        else:\n            self.id = id\n        if bitmap is None:\n            self.bitmap = 0\n            self.rd = 1\n        else:\n            self.bitmap = bitmap\n        self.q = q\n        self.a = a\n        self.auth = auth\n        self.ar = ar\n        for k,v in list(args.items()):\n            if k.lower() == \"qr\":\n                self.qr = v\n            elif k.lower() == \"opcode\":\n                self.opcode = v\n            elif k.lower() == \"aa\":\n                self.aa = v\n            elif k.lower() == \"tc\":\n                self.tc = v\n            elif k.lower() == \"rd\":\n                self.rd = v\n            elif k.lower() == \"ra\":\n                self.ra = v\n            elif k.lower() == \"rcode\":\n                self.rcode = v\n\n    # Accessors for header properties (automatically pack/unpack\n    # into bitmap)\n    def get_qr(self):\n        return get_bits(self.bitmap,15)\n\n    def set_qr(self,val):\n        self.bitmap = set_bits(self.bitmap,val,15)\n\n    qr = property(get_qr,set_qr)\n\n    def get_opcode(self):\n        return get_bits(self.bitmap,11,4)\n\n    def set_opcode(self,val):\n        self.bitmap = set_bits(self.bitmap,val,11,4)\n\n    opcode = property(get_opcode,set_opcode)\n\n    def get_aa(self):\n        return get_bits(self.bitmap,10)\n\n    def set_aa(self,val):\n        self.bitmap = set_bits(self.bitmap,val,10)\n\n    aa = property(get_aa,set_aa)\n\n    def get_tc(self):\n        return get_bits(self.bitmap,9)\n\n    def set_tc(self,val):\n        self.bitmap = set_bits(self.bitmap,val,9)\n\n    tc = property(get_tc,set_tc)\n\n    def get_rd(self):\n        return get_bits(self.bitmap,8)\n\n    def set_rd(self,val):\n        self.bitmap = set_bits(self.bitmap,val,8)\n\n    rd = property(get_rd,set_rd)\n\n    def get_ra(self):\n        return get_bits(self.bitmap,7)\n\n    def set_ra(self,val):\n        self.bitmap = set_bits(self.bitmap,val,7)\n\n    ra = property(get_ra,set_ra)\n\n    def get_rcode(self):\n        return get_bits(self.bitmap,0,4)\n\n    def set_rcode(self,val):\n        self.bitmap = set_bits(self.bitmap,val,0,4)\n\n    rcode = property(get_rcode,set_rcode)\n\n    def pack(self,buffer):\n        buffer.pack(\"!HHHHHH\",self.id,self.bitmap,\n                              self.q,self.a,self.auth,self.ar)\n\n    def __repr__(self):\n        f = [ self.aa and 'AA',\n              self.tc and 'TC',\n              self.rd and 'RD',\n              self.ra and 'RA' ]\n        if OPCODE.get(self.opcode) == 'UPDATE':\n            f1='zo'\n            f2='pr'\n            f3='up'\n            f4='ad'\n        else:\n            f1='q'\n            f2='a'\n            f3='ns'\n            f4='ar'\n        return \"<DNS Header: id=0x%x type=%s opcode=%s flags=%s \" \\\n                            \"rcode='%s' %s=%d %s=%d %s=%d %s=%d>\" % (\n                    self.id,\n                    QR.get(self.qr),\n                    OPCODE.get(self.opcode),\n                    \",\".join([_f for _f in f if _f]),\n                    RCODE.get(self.rcode),\n                    f1, self.q, f2, self.a, f3, self.auth, f4, self.ar )\n\n    def toZone(self):\n        f = [ self.qr and 'qr',\n              self.aa and 'aa',\n              self.tc and 'tc',\n              self.rd and 'rd',\n              self.ra and 'ra' ]\n        z1 = ';; ->>HEADER<<- opcode: %s, status: %s, id: %d' % (\n                    OPCODE.get(self.opcode),RCODE.get(self.rcode),self.id)\n        z2 = ';; flags: %s; QUERY: %d, ANSWER: %d, AUTHORITY: %d, ADDITIONAL: %d' % (\n                      \" \".join([_f for _f in f if _f]),\n                      self.q,self.a,self.auth,self.ar)\n        return z1 + \"\\n\" + z2\n\n    def __str__(self):\n        return self.toZone()\n\n    def __ne__(self,other):\n        return not(self.__eq__(other))\n\n    def __eq__(self,other):\n        if type(other) != type(self):\n            return False\n        else:\n            # Ignore id\n            attrs = ('qr','aa','tc','rd','ra','opcode','rcode')\n            return all([getattr(self,x) == getattr(other,x) for x in attrs])\n\nclass DNSQuestion(object):\n\n    \"\"\"\n        DNSQuestion section\n    \"\"\"\n\n    @classmethod\n    def parse(cls,buffer):\n        try:\n            qname = buffer.decode_name()\n            qtype,qclass = buffer.unpack(\"!HH\")\n            return cls(qname,qtype,qclass)\n        except (BufferError,BimapError) as e:\n            raise DNSError(\"Error unpacking DNSQuestion [offset=%d]: %s\" % (\n                                buffer.offset,e))\n\n    def __init__(self,qname=None,qtype=1,qclass=1):\n        self.qname = qname\n        self.qtype = qtype\n        self.qclass = qclass\n\n    def set_qname(self,qname):\n        if isinstance(qname,DNSLabel):\n            self._qname = qname\n        else:\n            self._qname = DNSLabel(qname)\n\n    def get_qname(self):\n        return self._qname\n\n    qname = property(get_qname,set_qname)\n\n    def pack(self,buffer):\n        buffer.encode_name(self.qname)\n        buffer.pack(\"!HH\",self.qtype,self.qclass)\n\n    def toZone(self):\n       return ';%-30s %-7s %s' % (self.qname,CLASS.get(self.qclass),\n                                             QTYPE.get(self.qtype))\n\n    def __repr__(self):\n        return \"<DNS Question: '%s' qtype=%s qclass=%s>\" % (\n                    self.qname, QTYPE.get(self.qtype), CLASS.get(self.qclass))\n\n    def __str__(self):\n        return self.toZone()\n\n    def __ne__(self,other):\n        return not(self.__eq__(other))\n\n    def __eq__(self,other):\n        if type(other) != type(self):\n            return False\n        else:\n            # List of attributes to compare when diffing\n            attrs = ('qname','qtype','qclass')\n            return all([getattr(self,x) == getattr(other,x) for x in attrs])\n\nclass EDNSOption(object):\n\n    \"\"\"\n        EDNSOption pseudo-section\n\n        Very rudimentary support for EDNS0 options however this has not been\n        tested due to a lack of data (anyone wanting to improve support or\n        provide test data please raise an issue)\n\n    \"\"\"\n    def __init__(self,code,data):\n        self.code = code\n        self.data = data\n\n    def pack(self,buffer):\n        buffer.pack(\"!HH\",self.code,len(self.data))\n        buffer.append(self.data)\n\n    def __repr__(self):\n        return \"<EDNS Option: Code=%d Data='%s'>\" % (\n                    self.code,binascii.hexlify(self.data).decode())\n\n    def toZone(self):\n        return \";EDNS: code: %s; data: %s\" % (\n                    self.code,binascii.hexlify(self.data).decode())\n\n    def __str__(self):\n        return self.toZone()\n\n    def __ne__(self,other):\n        return not(self.__eq__(other))\n\n    def __eq__(self,other):\n        if type(other) != type(self):\n            return False\n        else:\n            # List of attributes to compare when diffing\n            attrs = ('code','data')\n            return all([getattr(self,x) == getattr(other,x) for x in attrs])\n\nclass RR(object):\n\n    \"\"\"\n        DNS Resource Record\n        Contains RR header and RD (resource data) instance\n    \"\"\"\n\n    rtype = H('rtype')\n    rclass = H('rclass')\n    ttl = I('ttl')\n    rdlength = H('rdlength')\n\n    @classmethod\n    def parse(cls,buffer):\n        try:\n            rname = buffer.decode_name()\n            rtype,rclass,ttl,rdlength = buffer.unpack(\"!HHIH\")\n            if rtype == QTYPE.OPT:\n                options = []\n                option_buffer = Buffer(buffer.get(rdlength))\n                while option_buffer.remaining() > 4:\n                    code,length = option_buffer.unpack(\"!HH\")\n                    data = option_buffer.get(length)\n                    options.append(EDNSOption(code,data))\n                rdata = options\n            else:\n                if rdlength:\n                    rdata = RDMAP.get(QTYPE.get(rtype),RD).parse(\n                                            buffer,rdlength)\n                else:\n                    rdata = ''\n            return cls(rname,rtype,rclass,ttl,rdata)\n        except (BufferError,BimapError) as e:\n            raise DNSError(\"Error unpacking RR [offset=%d]: %s\" % (\n                                buffer.offset,e))\n\n    @classmethod\n    def fromZone(cls,zone,origin=\"\",ttl=0):\n        \"\"\"\n            Parse RR data from zone file and return list of RRs\n        \"\"\"\n        return list(ZoneParser(zone,origin=origin,ttl=ttl))\n\n    def __init__(self,rname=None,rtype=1,rclass=1,ttl=0,rdata=None):\n        self.rname = rname\n        self.rtype = rtype\n        self.rclass = rclass\n        self.ttl = ttl\n        self.rdata = rdata\n        # TODO Add property getters/setters\n        if self.rtype == QTYPE.OPT:\n            self.edns_len = self.rclass\n            self.edns_do = get_bits(self.ttl,15)\n            self.edns_ver = get_bits(self.ttl,16,8)\n            self.edns_rcode = get_bits(self.ttl,24,8)\n\n    def set_rname(self,rname):\n        if isinstance(rname,DNSLabel):\n            self._rname = rname\n        else:\n            self._rname = DNSLabel(rname)\n\n    def get_rname(self):\n        return self._rname\n\n    rname = property(get_rname,set_rname)\n\n    def pack(self,buffer):\n        buffer.encode_name(self.rname)\n        buffer.pack(\"!HHI\",self.rtype,self.rclass,self.ttl)\n        rdlength_ptr = buffer.offset\n        buffer.pack(\"!H\",0)\n        start = buffer.offset\n        if self.rtype == QTYPE.OPT:\n            for opt in self.rdata:\n                opt.pack(buffer)\n        else:\n            self.rdata.pack(buffer)\n        end = buffer.offset\n        buffer.update(rdlength_ptr,\"!H\",end-start)\n\n    def __repr__(self):\n        if self.rtype == QTYPE.OPT:\n            s = [\"<DNS OPT: edns_ver=%d do=%d ext_rcode=%d udp_len=%d>\" % (\n                        self.edns_ver,self.edns_do,self.edns_rcode,self.edns_len)]\n            s.extend([repr(opt) for opt in self.rdata])\n            return \"\\n\".join(s)\n        else:\n            return \"<DNS RR: '%s' rtype=%s rclass=%s ttl=%d rdata='%s'>\" % (\n                    self.rname, QTYPE.get(self.rtype), CLASS.get(self.rclass),\n                    self.ttl, self.rdata)\n\n    def toZone(self):\n        if self.rtype == QTYPE.OPT:\n            edns = [ \";OPT PSEUDOSECTION\",\n                     \";EDNS: version: %d, flags: %s; udp: %d\" % (\n                             self.edns_ver,\n                             \"do\" if self.edns_do else \"\",\n                             self.edns_len)\n                    ]\n            edns.extend([str(opt) for opt in self.rdata])\n            return \"\\n\".join(edns)\n        else:\n            return '%-23s %-7s %-7s %-7s %s' % (self.rname,self.ttl,\n                                                CLASS.get(self.rclass),\n                                                QTYPE.get(self.rtype),\n                                                self.rdata.toZone())\n\n    def __str__(self):\n        return self.toZone()\n\n    def __ne__(self,other):\n        return not(self.__eq__(other))\n\n    def __eq__(self,other):\n        if type(other) != type(self):\n            return False\n        else:\n            # List of attributes to compare when diffing (ignore ttl)\n            attrs = ('rname','rclass','rtype','rdata')\n            return all([getattr(self,x) == getattr(other,x) for x in attrs])\n\n\nclass RD(object):\n    \"\"\"\n        Base RD object - also used as placeholder for unknown RD types\n\n        To create a new RD type subclass this and add to RDMAP (below)\n\n        Subclass should implement (as a mininum):\n\n            parse (parse from packet data)\n            __init__ (create class)\n            __repr__ (return in zone format)\n            fromZone (create from zone format)\n\n            (toZone uses __repr__ by default)\n\n        Unknown rdata types default to RD and store rdata as a binary\n        blob (this allows round-trip encoding/decoding)\n    \"\"\"\n\n    @classmethod\n    def parse(cls,buffer,length):\n        \"\"\"\n            Unpack from buffer\n        \"\"\"\n        try:\n            data = buffer.get(length)\n            return cls(data)\n        except (BufferError,BimapError) as e:\n            raise DNSError(\"Error unpacking RD [offset=%d]: %s\" %\n                                    (buffer.offset,e))\n\n    @classmethod\n    def fromZone(cls,rd,origin=None):\n        \"\"\"\n            Create new record from zone format data\n            RD is a list of strings parsed from DiG output\n        \"\"\"\n        # Unknown rata - assume hexdump in zone format\n        # (DiG prepends \"\\\\# <len>\" to the hexdump so get last item)\n        return cls(binascii.unhexlify(rd[-1].encode('ascii')))\n\n    def __init__(self,data=b\"\"):\n        # Assume raw bytes\n        self.data = bytes(data)\n\n    def pack(self,buffer):\n        \"\"\"\n            Pack record into buffer\n        \"\"\"\n        buffer.append(self.data)\n\n    def __repr__(self):\n        \"\"\"\n            Default 'repr' format should be equivalent to RD zone format\n        \"\"\"\n        # For unknown rdata just default to hex\n        return binascii.hexlify(self.data).decode()\n\n    def toZone(self):\n        return repr(self)\n\n    # Comparison operations - in most cases only need to override 'attrs'\n    # in subclass (__eq__ will automatically compare defined atttrs)\n\n    # Attributes for comparison\n    attrs = ('data',)\n\n    def __eq__(self,other):\n        if type(other) != type(self):\n            return False\n        else:\n            return all([getattr(self,x) == getattr(other,x) for x in self.attrs])\n\n    def __ne__(self,other):\n        return not(self.__eq__(other))\n\nclass TXT(RD):\n\n    @classmethod\n    def parse(cls,buffer,length):\n        try:\n            (txtlength,) = buffer.unpack(\"!B\")\n            # First byte is TXT length (not in RFC?)\n            if txtlength < length:\n                data = buffer.get(txtlength)\n            else:\n                raise DNSError(\"Invalid TXT record: len(%d) > RD len(%d)\" %\n                                        (txtlength,length))\n            return cls(data)\n        except (BufferError,BimapError) as e:\n            raise DNSError(\"Error unpacking TXT [offset=%d]: %s\" %\n                                        (buffer.offset,e))\n\n    @classmethod\n    def fromZone(cls,rd,origin=None):\n        return cls(rd[0].encode())\n\n    def pack(self,buffer):\n        if len(self.data) > 255:\n            raise DNSError(\"TXT record too long: %s\" % self.data)\n        buffer.pack(\"!B\",len(self.data))\n        buffer.append(self.data)\n\n    def toZone(self):\n        return '\"%s\"' % repr(self)\n\n    def __repr__(self):\n        # Pyyhon 2/3 hack\n        # FIXME UnicodeDecodeError: 'utf-8' codec can't decode byte 0xfc in position 1\n        return self.data if isinstance(self.data,str) else self.data.decode(errors='replace')\n\nclass A(RD):\n\n    data = IP4('data')\n\n    @classmethod\n    def parse(cls,buffer,length):\n        try:\n            data = buffer.unpack(\"!BBBB\")\n            return cls(data)\n        except (BufferError,BimapError) as e:\n            raise DNSError(\"Error unpacking A [offset=%d]: %s\" %\n                                (buffer.offset,e))\n\n    @classmethod\n    def fromZone(cls,rd,origin=None):\n        return cls(rd[0])\n\n    def __init__(self,data):\n        if type(data) in (tuple,list):\n            self.data = tuple(data)\n        else:\n            if isinstance(data, bytes):\n                data = data.decode('utf-8')\n            self.data = tuple(map(int,data.rstrip(\".\").split(\".\")))\n\n    def pack(self,buffer):\n        buffer.pack(\"!BBBB\", *self.data)\n\n    def __repr__(self):\n        return \"%d.%d.%d.%d\" % self.data\n\ndef _parse_ipv6(a):\n    \"\"\"\n        Parse IPv6 address. Ideally we would use the ipaddress module in\n        Python3.3 but can't rely on having this.\n\n        Does not handle dotted-quad addresses or subnet prefix\n\n        >>> _parse_ipv6(\"::\") == (0,) * 16\n        True\n        >>> _parse_ipv6(\"1234:5678::abcd:0:ff00\")\n        (18, 52, 86, 120, 0, 0, 0, 0, 0, 0, 171, 205, 0, 0, 255, 0)\n\n    \"\"\"\n\n    if isinstance(a, bytes):\n        a = a.decode('utf-8')\n    l,_,r = a.partition(\"::\")\n    l_groups = list(chain(*[divmod(int(x,16),256) for x in l.split(\":\") if x]))\n    r_groups = list(chain(*[divmod(int(x,16),256) for x in r.split(\":\") if x]))\n    zeros = [0] * (16 - len(l_groups) - len(r_groups))\n    return tuple(l_groups + zeros + r_groups)\n\ndef _format_ipv6(a):\n    \"\"\"\n        Format IPv6 address (from tuple of 16 bytes) compressing sequence of\n        zero bytes to '::'. Ideally we would use the ipaddress module in\n        Python3.3 but can't rely on having this.\n\n        >>> _format_ipv6([0]*16)\n        '::'\n        >>> _format_ipv6(_parse_ipv6(\"::0012:5678\"))\n        '::12:5678'\n        >>> _format_ipv6(_parse_ipv6(\"1234:0:5678::ff:0:1\"))\n        '1234:0:5678::ff:0:1'\n    \"\"\"\n    left = []\n    right = []\n    current = 'left'\n    for i in range(0,16,2):\n        group = (a[i] << 8) + a[i+1]\n        if current == 'left':\n            if group == 0 and i < 14:\n                if (a[i+2] << 8) + a[i+3] == 0:\n                    current = 'right'\n                else:\n                    left.append(\"0\")\n            else:\n                left.append(\"%x\" % group)\n        else:\n            if group == 0 and len(right) == 0:\n                pass\n            else:\n                right.append(\"%x\" % group)\n    if len(left) < 8:\n        return \":\".join(left) + \"::\" + \":\".join(right)\n    else:\n        return \":\".join(left)\n\nclass AAAA(RD):\n\n    \"\"\"\n        Basic support for AAAA record - accepts IPv6 address data as either\n        a tuple of 16 bytes or in text format\n    \"\"\"\n\n    data = IP6('data')\n\n    @classmethod\n    def parse(cls,buffer,length):\n        try:\n            data = buffer.unpack(\"!16B\")\n            return cls(data)\n        except (BufferError,BimapError) as e:\n            raise DNSError(\"Error unpacking AAAA [offset=%d]: %s\" %\n                                        (buffer.offset,e))\n\n    @classmethod\n    def fromZone(cls,rd,origin=None):\n        return cls(rd[0])\n\n    def __init__(self,data):\n        if type(data) in (tuple,list):\n            self.data = tuple(data)\n        else:\n            self.data = _parse_ipv6(data)\n\n    def pack(self,buffer):\n        buffer.pack(\"!16B\",*self.data)\n\n    def __repr__(self):\n        return _format_ipv6(self.data)\n\nclass MX(RD):\n\n    preference = H('preference')\n\n    @classmethod\n    def parse(cls,buffer,length):\n        try:\n            (preference,) = buffer.unpack(\"!H\")\n            mx = buffer.decode_name()\n            return cls(mx,preference)\n        except (BufferError,BimapError) as e:\n            raise DNSError(\"Error unpacking MX [offset=%d]: %s\" %\n                                        (buffer.offset,e))\n\n    @classmethod\n    def fromZone(cls,rd,origin=None):\n        return cls(label(rd[1],origin),int(rd[0]))\n\n    def __init__(self,label=None,preference=10):\n        self.label = label\n        self.preference = preference\n\n    def set_label(self,label):\n        if isinstance(label,DNSLabel):\n            self._label = label\n        else:\n            self._label = DNSLabel(label)\n\n    def get_label(self):\n        return self._label\n\n    label = property(get_label,set_label)\n\n    def pack(self,buffer):\n        buffer.pack(\"!H\",self.preference)\n        buffer.encode_name(self.label)\n\n    def __repr__(self):\n        return \"%d %s\" % (self.preference,self.label)\n\n    attrs = ('preference','label')\n\nclass CNAME(RD):\n\n    @classmethod\n    def parse(cls,buffer,length):\n        try:\n            label = buffer.decode_name()\n            return cls(label)\n        except (BufferError,BimapError) as e:\n            raise DNSError(\"Error unpacking CNAME [offset=%d]: %s\" %\n                                        (buffer.offset,e))\n\n    @classmethod\n    def fromZone(cls,rd,origin=None):\n        return cls(label(rd[0],origin))\n\n    def __init__(self,label=None):\n        self.label = label\n\n    def set_label(self,label):\n        if isinstance(label,DNSLabel):\n            self._label = label\n        else:\n            self._label = DNSLabel(label)\n\n    def get_label(self):\n        return self._label\n\n    label = property(get_label,set_label)\n\n    def pack(self,buffer):\n        buffer.encode_name(self.label)\n\n    def __repr__(self):\n        return \"%s\" % (self.label)\n\n    attrs = ('label',)\n\nclass PTR(CNAME):\n    pass\n\nclass NS(CNAME):\n    pass\n\nclass SOA(RD):\n\n    times = ntuple_range('times',5,0,4294967295)\n    @classmethod\n    def parse(cls,buffer,length):\n        try:\n            mname = buffer.decode_name()\n            rname = buffer.decode_name()\n            times = buffer.unpack(\"!IIIII\")\n            return cls(mname,rname,times)\n        except (BufferError,BimapError) as e:\n            raise DNSError(\"Error unpacking SOA [offset=%d]: %s\" %\n                                        (buffer.offset,e))\n\n    @classmethod\n    def fromZone(cls,rd,origin=None):\n        return cls(label(rd[0],origin),label(rd[1],origin),[int(t) for t in rd[2:]])\n\n    def __init__(self,mname=None,rname=None,times=None):\n        self.mname = mname\n        self.rname = rname\n        self.times = tuple(times) if times else (0,0,0,0,0)\n\n    def set_mname(self,mname):\n        if isinstance(mname,DNSLabel):\n            self._mname = mname\n        else:\n            self._mname = DNSLabel(mname)\n\n    def get_mname(self):\n        return self._mname\n\n    mname = property(get_mname,set_mname)\n\n    def set_rname(self,rname):\n        if isinstance(rname,DNSLabel):\n            self._rname = rname\n        else:\n            self._rname = DNSLabel(rname)\n\n    def get_rname(self):\n        return self._rname\n\n    rname = property(get_rname,set_rname)\n\n    def pack(self,buffer):\n        buffer.encode_name(self.mname)\n        buffer.encode_name(self.rname)\n        buffer.pack(\"!IIIII\", *self.times)\n\n    def __repr__(self):\n        return \"%s %s %s\" % (self.mname,self.rname,\n                             \" \".join(map(str,self.times)))\n\n    attrs = ('mname','rname','times')\n\nclass SRV(RD):\n\n    priority = H('priority')\n    weight = H('weight')\n    port = H('port')\n\n    @classmethod\n    def parse(cls,buffer,length):\n        try:\n            priority,weight,port = buffer.unpack(\"!HHH\")\n            target = buffer.decode_name()\n            return cls(priority,weight,port,target)\n        except (BufferError,BimapError) as e:\n            raise DNSError(\"Error unpacking SRV [offset=%d]: %s\" %\n                                        (buffer.offset,e))\n\n    @classmethod\n    def fromZone(cls,rd,origin=None):\n        return cls(int(rd[0]),int(rd[1]),int(rd[2]),rd[3])\n\n    def __init__(self,priority=0,weight=0,port=0,target=None):\n        self.priority = priority\n        self.weight = weight\n        self.port = port\n        self.target = target\n\n    def set_target(self,target):\n        if isinstance(target,DNSLabel):\n            self._target = target\n        else:\n            self._target = DNSLabel(target)\n\n    def get_target(self):\n        return self._target\n\n    target = property(get_target,set_target)\n\n    def pack(self,buffer):\n        buffer.pack(\"!HHH\",self.priority,self.weight,self.port)\n        buffer.encode_name(self.target)\n\n    def __repr__(self):\n        return \"%d %d %d %s\" % (self.priority,self.weight,self.port,self.target)\n\n    attrs = ('priority','weight','port','target')\n\nclass NAPTR(RD):\n\n    order = H('order')\n    preference = H('preference')\n\n    @classmethod\n    def parse(cls, buffer, length):\n        try:\n            order, preference = buffer.unpack('!HH')\n            (length,) = buffer.unpack('!B')\n            flags = buffer.get(length)\n            (length,) = buffer.unpack('!B')\n            service = buffer.get(length)\n            (length,) = buffer.unpack('!B')\n            regexp = buffer.get(length)\n            replacement = buffer.decode_name()\n            return cls(order, preference, flags, service, regexp, replacement)\n        except (BufferError,BimapError) as e:\n            raise DNSError(\"Error unpacking NAPTR [offset=%d]: %s\" %\n                                    (buffer.offset,e))\n\n    @classmethod\n    def fromZone(cls,rd,origin=None):\n        encode = lambda s : s.encode()\n        _label = lambda s : label(s,origin)\n        m = (int,int,encode,encode,encode,_label)\n        return cls(*[ f(v) for f,v in zip(m,rd)])\n\n    def __init__(self,order,preference,flags,service,regexp,replacement=None):\n        self.order = order\n        self.preference = preference\n        self.flags = flags\n        self.service = service\n        self.regexp = regexp\n        self.replacement = replacement\n\n    def set_replacement(self,replacement):\n        if isinstance(replacement,DNSLabel):\n            self._replacement = replacement\n        else:\n            self._replacement = DNSLabel(replacement)\n\n    def get_replacement(self):\n        return self._replacement\n\n    replacement = property(get_replacement,set_replacement)\n\n    def pack(self, buffer):\n        buffer.pack('!HH', self.order, self.preference)\n        buffer.pack('!B', len(self.flags))\n        buffer.append(self.flags)\n        buffer.pack('!B', len(self.service))\n        buffer.append(self.service)\n        buffer.pack('!B', len(self.regexp))\n        buffer.append(self.regexp)\n        buffer.encode_name(self.replacement)\n\n    def __repr__(self):\n        return '%d %d \"%s\" \"%s\" \"%s\" %s' %(\n            self.order,self.preference,self.flags.decode(),\n            self.service.decode(),\n            self.regexp.decode().replace('\\\\','\\\\\\\\'),\n            self.replacement or '.'\n        )\n\n    attrs = ('order','preference','flags','service','regexp','replacement')\n\nclass DNSKEY(RD):\n\n    flags = H('flags')\n    protocol = B('protocol')\n    algorithm = B('algorithm')\n\n    @classmethod\n    def parse(cls,buffer,length):\n        try:\n            (flags,protocol,algorithm) = buffer.unpack(\"!HBB\")\n            key = buffer.get(length - 4)\n            return cls(flags,protocol,algorithm,key)\n        except (BufferError,BimapError) as e:\n            raise DNSError(\"Error unpacking DNSKEY [offset=%d]: %s\" %\n                                        (buffer.offset,e))\n\n    @classmethod\n    def fromZone(cls,rd,origin=None):\n        return cls(int(rd[0]),int(rd[1]),int(rd[2]),\n                   base64.b64decode((\"\".join(rd[3:])).encode('ascii')))\n\n    def __init__(self,flags,protocol,algorithm,key):\n        self.flags = flags\n        self.protocol = protocol\n        self.algorithm = algorithm\n        self.key = key\n\n    def pack(self,buffer):\n        buffer.pack(\"!HBB\",self.flags,self.protocol,self.algorithm)\n        buffer.append(self.key)\n\n    def __repr__(self):\n        return \"%d %d %d %s\" % (self.flags,self.protocol,self.algorithm,\n                                base64.b64encode(self.key).decode())\n\n    attrs = ('flags','protocol','algorithm','key')\n\nclass RRSIG(RD):\n\n    covered = H('covered')\n    algorithm = B('algorithm')\n    labels = B('labels')\n    orig_ttl = I('orig_ttl')\n    sig_exp = I('sig_exp')\n    sig_inc = I('sig_inc')\n    key_tag = H('key_tag')\n\n    @classmethod\n    def parse(cls,buffer,length):\n        try:\n            start = buffer.offset\n            (covered,algorithm,labels,\n                orig_ttl,sig_exp,sig_inc,key_tag) = buffer.unpack(\"!HBBIIIH\")\n            name = buffer.decode_name()\n            sig = buffer.get(length - (buffer.offset - start))\n            return cls(covered,algorithm,labels,orig_ttl,sig_exp,sig_inc,key_tag,\n                            name,sig)\n        except (BufferError,BimapError) as e:\n            raise DNSError(\"Error unpacking DNSKEY [offset=%d]: %s\" %\n                                        (buffer.offset,e))\n\n    @classmethod\n    def fromZone(cls,rd,origin=None):\n        return cls(getattr(QTYPE,rd[0]),int(rd[1]),int(rd[2]),int(rd[3]),\n                        int(time.mktime(time.strptime(rd[4]+'GMT',\"%Y%m%d%H%M%S%Z\"))),\n                        int(time.mktime(time.strptime(rd[5]+'GMT',\"%Y%m%d%H%M%S%Z\"))),\n                        int(rd[6]),rd[7],\n                        base64.b64decode((\"\".join(rd[8:])).encode('ascii')))\n\n    def __init__(self,covered,algorithm,labels,orig_ttl,\n                      sig_exp,sig_inc,key_tag,name,sig):\n        self.covered = covered\n        self.algorithm = algorithm\n        self.labels = labels\n        self.orig_ttl = orig_ttl\n        self.sig_exp = sig_exp\n        self.sig_inc = sig_inc\n        self.key_tag = key_tag\n        self.name = DNSLabel(name)\n        self.sig = sig\n\n    def pack(self,buffer):\n        buffer.pack(\"!HBBIIIH\",self.covered,self.algorithm,self.labels,\n                               self.orig_ttl,self.sig_exp,self.sig_inc,\n                               self.key_tag)\n        buffer.encode_name_nocompress(self.name)\n        buffer.append(self.sig)\n\n    def __repr__(self):\n        return \"%s %d %d %d %s %s %d %s %s\" % (\n                        QTYPE.get(self.covered),\n                        self.algorithm,\n                        self.labels,\n                        self.orig_ttl,\n                        time.strftime(\"%Y%m%d%H%M%S\",time.gmtime(self.sig_exp)),\n                        time.strftime(\"%Y%m%d%H%M%S\",time.gmtime(self.sig_inc)),\n                        self.key_tag,\n                        self.name,\n                        base64.b64encode(self.sig).decode())\n\n    attrs = ('covered','algorithm','labels','orig_ttl','sig_exp','sig_inc',\n             'key_tag','name','sig')\n\n# Map from RD type to class (used to pack/unpack records)\n# If you add a new RD class you must add to RDMAP\n\nRDMAP = { 'CNAME':CNAME, 'A':A, 'AAAA':AAAA, 'TXT':TXT, 'MX':MX,\n          'PTR':PTR, 'SOA':SOA, 'NS':NS, 'NAPTR': NAPTR, 'SRV':SRV,\n          'DNSKEY':DNSKEY, 'RRSIG':RRSIG,\n        }\n\n##\n## Zone parser\n## TODO  - ideally this would be in a separate file but have to deal\n##         with circular dependencies\n##\n\nsecs = {'s':1,'m':60,'h':3600,'d':86400,'w':604800}\n\ndef parse_time(s):\n    \"\"\"\n        Parse time spec with optional s/m/h/d/w suffix\n    \"\"\"\n    if s[-1].lower() in secs:\n        return int(s[:-1]) * secs[s[-1].lower()]\n    else:\n        return int(s)\n\nclass ZoneParser:\n\n    \"\"\"\n        Zone file parser\n\n        >>> z = ZoneParser(\"www.example.com. 60 IN A 1.2.3.4\")\n        >>> list(z.parse())\n        [<DNS RR: 'www.example.com.' rtype=A rclass=IN ttl=60 rdata='1.2.3.4'>]\n    \"\"\"\n\n    def __init__(self,zone,origin=\"\",ttl=0):\n        self.l = WordLexer(zone)\n        self.l.commentchars = ';'\n        self.l.nltok = ('NL',None)\n        self.l.spacetok = ('SPACE',None)\n        self.i = iter(self.l)\n        if type(origin) is DNSLabel:\n            self.origin = origin\n        else:\n            self.origin= DNSLabel(origin)\n        self.ttl = ttl\n        self.label = DNSLabel(\"\")\n        self.prev = None\n\n    def expect(self,expect):\n        t,val = next(self.i)\n        if t != expect:\n            raise ValueError(\"Invalid Token: %s (expecting: %s)\" % (t,expect))\n        return val\n\n    def parse_label(self,label):\n        if label.endswith(\".\"):\n            self.label = DNSLabel(label)\n        elif label == \"@\":\n            self.label = self.origin\n        elif label == '':\n            pass\n        else:\n            self.label = self.origin.add(label)\n        return self.label\n\n    def parse_rr(self,rr):\n        label = self.parse_label(rr.pop(0))\n        ttl = int(rr.pop(0)) if rr[0].isdigit() else self.ttl\n        rclass = rr.pop(0) if rr[0] in ('IN','CH','HS') else 'IN'\n        rtype = rr.pop(0)\n        rdata = rr\n        rd = RDMAP.get(rtype,RD)\n        return RR(rname=label,\n                         ttl=ttl,\n                         rclass=getattr(CLASS,rclass),\n                         rtype=getattr(QTYPE,rtype),\n                         rdata=rd.fromZone(rdata,self.origin))\n\n    def __iter__(self):\n        return self.parse()\n\n    def parse(self):\n        rr = []\n        paren = False\n        try:\n            while True:\n                tok,val = next(self.i)\n                if tok == 'NL':\n                    if not paren and rr:\n                        self.prev = tok\n                        yield self.parse_rr(rr)\n                        rr = []\n                elif tok == 'SPACE' and self.prev == 'NL' and not paren:\n                    rr.append('')\n                elif tok == 'ATOM':\n                    if val == '(':\n                        paren = True\n                    elif val == ')':\n                        paren = False\n                    elif val == '$ORIGIN':\n                        self.expect('SPACE')\n                        origin = self.expect('ATOM')\n                        self.origin = self.label = DNSLabel(origin)\n                    elif val == '$TTL':\n                        self.expect('SPACE')\n                        ttl = self.expect('ATOM')\n                        self.ttl = parse_time(ttl)\n                    else:\n                        rr.append(val)\n                self.prev = tok\n        except StopIteration:\n            if rr:\n                yield self.parse_rr(rr)\n\nif __name__ == '__main__':\n    import doctest\n    doctest.testmod(optionflags=doctest.ELLIPSIS)\n"
  },
  {
    "path": "code/default/lib/noarch/dnslib/fixedresolver.py",
    "content": "# -*- coding: utf-8 -*-\n\n\"\"\"\n    FixedResolver - example resolver which responds with fixed response\n                    to all requests\n\"\"\"\n\n\n\nimport copy\n\nfrom dnslib import RR\nfrom dnslib.server import DNSServer,DNSHandler,BaseResolver,DNSLogger\n\nclass FixedResolver(BaseResolver):\n    \"\"\"\n        Respond with fixed response to all requests\n    \"\"\"\n    def __init__(self,zone):\n        # Parse RRs\n        self.rrs = RR.fromZone(zone)\n\n    def resolve(self,request,handler):\n        reply = request.reply()\n        qname = request.q.qname\n        # Replace labels with request label\n        for rr in self.rrs:\n            a = copy.copy(rr)\n            a.rname = qname\n            reply.add_answer(a)\n        return reply\n\nif __name__ == '__main__':\n\n    import argparse,sys,time\n\n    p = argparse.ArgumentParser(description=\"Fixed DNS Resolver\")\n    p.add_argument(\"--response\",\"-r\",default=\". 60 IN A 127.0.0.1\",\n                    metavar=\"<response>\",\n                    help=\"DNS response (zone format) (default: 127.0.0.1)\")\n    p.add_argument(\"--zonefile\",\"-f\",\n                    metavar=\"<zonefile>\",\n                    help=\"DNS response (zone file, '-' for stdin)\")\n    p.add_argument(\"--port\",\"-p\",type=int,default=53,\n                    metavar=\"<port>\",\n                    help=\"Server port (default:53)\")\n    p.add_argument(\"--address\",\"-a\",default=\"\",\n                    metavar=\"<address>\",\n                    help=\"Listen address (default:all)\")\n    p.add_argument(\"--udplen\",\"-u\",type=int,default=0,\n                    metavar=\"<udplen>\",\n                    help=\"Max UDP packet length (default:0)\")\n    p.add_argument(\"--tcp\",action='store_true',default=False,\n                    help=\"TCP server (default: UDP only)\")\n    p.add_argument(\"--log\",default=\"request,reply,truncated,error\",\n                    help=\"Log hooks to enable (default: +request,+reply,+truncated,+error,-recv,-send,-data)\")\n    p.add_argument(\"--log-prefix\",action='store_true',default=False,\n                    help=\"Log prefix (timestamp/handler/resolver) (default: False)\")\n    args = p.parse_args()\n\n    if args.zonefile:\n        if args.zonefile == '-':\n            args.response = sys.stdin\n        else:\n            args.response = open(args.zonefile)\n\n    resolver = FixedResolver(args.response)\n    logger = DNSLogger(args.log,args.log_prefix)\n\n    print(\"Starting Fixed Resolver (%s:%d) [%s]\" % (\n                        args.address or \"*\",\n                        args.port,\n                        \"UDP/TCP\" if args.tcp else \"UDP\"))\n\n    # for rr in resolver.rrs:\n    #     print(\"    | \",rr.toZone().strip(),sep=\"\")\n    print()\n\n    if args.udplen:\n        DNSHandler.udplen = args.udplen\n\n    udp_server = DNSServer(resolver,\n                           port=args.port,\n                           address=args.address,\n                           logger=logger)\n    udp_server.start_thread()\n\n    if args.tcp:\n        tcp_server = DNSServer(resolver,\n                               port=args.port,\n                               address=args.address,\n                               tcp=True,\n                               logger=logger)\n        tcp_server.start_thread()\n\n    while udp_server.isAlive():\n        time.sleep(1)\n\n"
  },
  {
    "path": "code/default/lib/noarch/dnslib/intercept.py",
    "content": "# -*- coding: utf-8 -*-\n\n\"\"\"\n    InterceptResolver - proxy requests to upstream server\n                        (optionally intercepting)\n\n\"\"\"\n\n\nimport binascii,copy,socket,struct,sys\n\nfrom dnslib import DNSRecord,RR,QTYPE,RCODE,parse_time\nfrom dnslib.server import DNSServer,DNSHandler,BaseResolver,DNSLogger\nfrom dnslib.label import DNSLabel\n\nclass InterceptResolver(BaseResolver):\n\n    \"\"\"\n        Intercepting resolver\n\n        Proxy requests to upstream server optionally intercepting requests\n        matching local records\n    \"\"\"\n\n    def __init__(self,address,port,ttl,intercept,skip,nxdomain):\n        \"\"\"\n            address/port    - upstream server\n            ttl             - default ttl for intercept records\n            intercept       - list of wildcard RRs to respond to (zone format)\n            skip            - list of wildcard labels to skip\n            nxdomain        - list of wildcard labels to retudn NXDOMAIN\n        \"\"\"\n        self.address = address\n        self.port = port\n        self.ttl = parse_time(ttl)\n        self.skip = skip\n        self.nxdomain = nxdomain\n        self.zone = []\n        for i in intercept:\n            if i == '-':\n                i = sys.stdin.read()\n            for rr in RR.fromZone(i,ttl=self.ttl):\n                self.zone.append((rr.rname,QTYPE[rr.rtype],rr))\n\n    def resolve(self,request,handler):\n        reply = request.reply()\n        qname = request.q.qname\n        qtype = QTYPE[request.q.qtype]\n        # Try to resolve locally unless on skip list\n        if not any([qname.matchGlob(s) for s in self.skip]):\n            for name,rtype,rr in self.zone:\n                if qname.matchGlob(name) and (qtype in (rtype,'ANY','CNAME')):\n                    a = copy.copy(rr)\n                    a.rname = qname\n                    reply.add_answer(a)\n        # Check for NXDOMAIN\n        if any([qname.matchGlob(s) for s in self.nxdomain]):\n            reply.header.rcode = getattr(RCODE,'NXDOMAIN')\n            return reply\n        # Otherwise proxy\n        if not reply.rr:\n            if handler.protocol == 'udp':\n                proxy_r = request.send(self.address,self.port)\n            else:\n                proxy_r = request.send(self.address,self.port,tcp=True)\n            reply = DNSRecord.parse(proxy_r)\n        return reply\n\nif __name__ == '__main__':\n\n    import argparse,sys,time\n\n    p = argparse.ArgumentParser(description=\"DNS Intercept Proxy\")\n    p.add_argument(\"--port\",\"-p\",type=int,default=53,\n                    metavar=\"<port>\",\n                    help=\"Local proxy port (default:53)\")\n    p.add_argument(\"--address\",\"-a\",default=\"\",\n                    metavar=\"<address>\",\n                    help=\"Local proxy listen address (default:all)\")\n    p.add_argument(\"--upstream\",\"-u\",default=\"8.8.8.8:53\",\n            metavar=\"<dns server:port>\",\n                    help=\"Upstream DNS server:port (default:8.8.8.8:53)\")\n    p.add_argument(\"--tcp\",action='store_true',default=False,\n                    help=\"TCP proxy (default: UDP only)\")\n    p.add_argument(\"--intercept\",\"-i\",action=\"append\",\n                    metavar=\"<zone record>\",\n                    help=\"Intercept requests matching zone record (glob) ('-' for stdin)\")\n    p.add_argument(\"--skip\",\"-s\",action=\"append\",\n                    metavar=\"<label>\",\n                    help=\"Don't intercept matching label (glob)\")\n    p.add_argument(\"--nxdomain\",\"-x\",action=\"append\",\n                    metavar=\"<label>\",\n                    help=\"Return NXDOMAIN (glob)\")\n    p.add_argument(\"--ttl\",\"-t\",default=\"60s\",\n                    metavar=\"<ttl>\",\n                    help=\"Intercept TTL (default: 60s)\")\n    p.add_argument(\"--log\",default=\"request,reply,truncated,error\",\n                    help=\"Log hooks to enable (default: +request,+reply,+truncated,+error,-recv,-send,-data)\")\n    p.add_argument(\"--log-prefix\",action='store_true',default=False,\n                    help=\"Log prefix (timestamp/handler/resolver) (default: False)\")\n    args = p.parse_args()\n\n    args.dns,_,args.dns_port = args.upstream.partition(':')\n    args.dns_port = int(args.dns_port or 53)\n\n    resolver = InterceptResolver(args.dns,\n                                 args.dns_port,\n                                 args.ttl,\n                                 args.intercept or [],\n                                 args.skip or [],\n                                 args.nxdomain or [])\n    logger = DNSLogger(args.log,args.log_prefix)\n\n    print(\"Starting Intercept Proxy (%s:%d -> %s:%d) [%s]\" % (\n                        args.address or \"*\",args.port,\n                        args.dns,args.dns_port,\n                        \"UDP/TCP\" if args.tcp else \"UDP\"))\n\n    # for rr in resolver.zone:\n    #     print(\"    | \",rr[2].toZone(),sep=\"\")\n    if resolver.nxdomain:\n        print(\"    NXDOMAIN:\",\", \".join(resolver.nxdomain))\n    if resolver.skip:\n        print(\"    Skipping:\",\", \".join(resolver.skip))\n    print()\n\n\n    DNSHandler.log = {\n        'log_request',      # DNS Request\n        'log_reply',        # DNS Response\n        'log_truncated',    # Truncated\n        'log_error',        # Decoding error\n    }\n\n    udp_server = DNSServer(resolver,\n                           port=args.port,\n                           address=args.address,\n                           logger=logger)\n    udp_server.start_thread()\n\n    if args.tcp:\n        tcp_server = DNSServer(resolver,\n                               port=args.port,\n                               address=args.address,\n                               tcp=True,\n                               logger=logger)\n        tcp_server.start_thread()\n\n    while udp_server.isAlive():\n        time.sleep(1)\n\n"
  },
  {
    "path": "code/default/lib/noarch/dnslib/label.py",
    "content": "# -*- coding: utf-8 -*-\n\n\"\"\"\n    DNSLabel/DNSBuffer - DNS label handling & encoding/decoding\n\"\"\"\n\n\n\nimport fnmatch\n\nfrom dnslib.bit import get_bits,set_bits\nfrom dnslib.buffer import Buffer, BufferError\n\nclass DNSLabelError(Exception):\n    pass\n\nclass DNSLabel(object):\n\n    \"\"\"\n    Container for DNS label\n\n    Supports IDNA encoding for unicode domain names\n\n    >>> l1 = DNSLabel(\"aaa.bbb.ccc.\")\n    >>> l2 = DNSLabel([b\"aaa\",b\"bbb\",b\"ccc\"])\n    >>> l1 == l2\n    True\n    >>> l3 = DNSLabel(\"AAA.BBB.CCC\")\n    >>> l1 == l3\n    True\n    >>> l1 == 'AAA.BBB.CCC'\n    True\n    >>> x = { l1 : 1 }\n    >>> x[l1]\n    1\n    >>> l1\n    <DNSLabel: 'aaa.bbb.ccc.'>\n    >>> str(l1)\n    'aaa.bbb.ccc.'\n    >>> l3 = l1.add(\"xxx.yyy\")\n    >>> l3\n    <DNSLabel: 'xxx.yyy.aaa.bbb.ccc.'>\n    >>> l3.matchSuffix(l1)\n    True\n    >>> l3.matchSuffix(\"xxx.yyy.\")\n    False\n    >>> l3.stripSuffix(\"bbb.ccc.\")\n    <DNSLabel: 'xxx.yyy.aaa.'>\n    >>> l3.matchGlob(\"*.[abc]aa.BBB.ccc\")\n    True\n    >>> l3.matchGlob(\"*.[abc]xx.bbb.ccc\")\n    False\n\n    # Too hard to get unicode doctests to work on Python 3.2\n    # (works on 3.3)\n    # >>> u1 = DNSLabel(u'\\\\u2295.com')\n    # >>> u1.__str__() == u'\\\\u2295.com.'\n    # True\n    # >>> u1.label == ( b\"xn--keh\", b\"com\" )\n    # True\n\n    \"\"\"\n    def __init__(self,label):\n        \"\"\"\n            Create DNS label instance\n\n            Label can be specified as:\n            - a list/tuple of byte strings\n            - a byte string (split into components separated by b'.')\n            - a unicode string which will be encoded according to RFC3490/IDNA\n        \"\"\"\n        if type(label) == DNSLabel:\n            self.label = label.label\n        elif type(label) in (list,tuple):\n            self.label = tuple(label)\n        else:\n            if not label or label in (b'.','.'):\n                self.label = ()\n            elif type(label) is not bytes:\n                self.label = tuple(label.encode(\"idna\").\\\n                                rstrip(b\".\").split(b\".\"))\n            else:\n                self.label = tuple(label.rstrip(b\".\").split(b\".\"))\n\n    def add(self,name):\n        \"\"\"\n            Prepend name to label\n        \"\"\"\n        new = DNSLabel(name)\n        if self.label:\n            new.label += self.label\n        return new\n\n    def matchGlob(self,pattern):\n        if type(pattern) != DNSLabel:\n            pattern = DNSLabel(pattern)\n        return fnmatch.fnmatch(str(self).lower(),str(pattern).lower())\n\n    def matchSuffix(self,suffix):\n        \"\"\"\n            Return True if label suffix matches\n        \"\"\"\n        suffix = DNSLabel(suffix)\n        return self.label[-len(suffix.label):] == suffix.label\n\n    def stripSuffix(self,suffix):\n        \"\"\"\n            Strip suffix from label\n        \"\"\"\n        suffix = DNSLabel(suffix)\n        if self.label[-len(suffix.label):] == suffix.label:\n            return DNSLabel(self.label[:-len(suffix.label)])\n        else:\n            return self\n\n    def idna(self):\n        return \".\".join([ s.decode(\"idna\") for s in self.label ]) + \".\"\n\n    def __str__(self):\n        return \".\".join([ s.decode() for s in self.label ]) + \".\"\n\n    def __repr__(self):\n        return \"<DNSLabel: '%s'>\" % str(self)\n\n    def __hash__(self):\n        return hash(self.label)\n\n    def __ne__(self,other):\n        return not self == other\n\n    def __eq__(self,other):\n        if type(other) != DNSLabel:\n            return self.__eq__(DNSLabel(other))\n        else:\n            return [ l.lower() for l in self.label ] == \\\n                   [ l.lower() for l in other.label ]\n\n    def __len__(self):\n        return len(b'.'.join(self.label))\n\nclass DNSBuffer(Buffer):\n\n    \"\"\"\n    Extends Buffer to provide DNS name encoding/decoding (with caching)\n\n    # Needed for Python 2/3 doctest compatibility\n    >>> def p(s):\n    ...     if not isinstance(s,str):\n    ...         return s.decode()\n    ...     return s\n\n    >>> b = DNSBuffer()\n    >>> b.encode_name(b'aaa.bbb.ccc.')\n    >>> len(b)\n    13\n    >>> b.encode_name(b'aaa.bbb.ccc.')\n    >>> len(b)\n    15\n    >>> b.encode_name(b'xxx.yyy.zzz')\n    >>> len(b)\n    28\n    >>> b.encode_name(b'zzz.xxx.bbb.ccc.')\n    >>> len(b)\n    38\n    >>> b.encode_name(b'aaa.xxx.bbb.ccc')\n    >>> len(b)\n    44\n    >>> b.offset = 0\n    >>> print(b.decode_name())\n    aaa.bbb.ccc.\n    >>> print(b.decode_name())\n    aaa.bbb.ccc.\n    >>> print(b.decode_name())\n    xxx.yyy.zzz.\n    >>> print(b.decode_name())\n    zzz.xxx.bbb.ccc.\n    >>> print(b.decode_name())\n    aaa.xxx.bbb.ccc.\n\n    >>> b = DNSBuffer()\n    >>> b.encode_name([b'a.aa',b'b.bb',b'c.cc'])\n    >>> b.offset = 0\n    >>> len(b.decode_name().label)\n    3\n\n    >>> b = DNSBuffer()\n    >>> b.encode_name_nocompress(b'aaa.bbb.ccc.')\n    >>> len(b)\n    13\n    >>> b.encode_name_nocompress(b'aaa.bbb.ccc.')\n    >>> len(b)\n    26\n    >>> b.offset = 0\n    >>> print(b.decode_name())\n    aaa.bbb.ccc.\n    >>> print(b.decode_name())\n    aaa.bbb.ccc.\n    \"\"\"\n\n    def __init__(self,data=b''):\n        \"\"\"\n            Add 'names' dict to cache stored labels\n        \"\"\"\n        super(DNSBuffer,self).__init__(data)\n        self.names = {}\n\n    def decode_name(self,last=-1):\n        \"\"\"\n            Decode label at current offset in buffer (following pointers\n            to cached elements where necessary)\n        \"\"\"\n        label = []\n        done = False\n        while not done:\n            (length,) = self.unpack(\"!B\")\n            if get_bits(length,6,2) == 3:\n                # Pointer\n                self.offset -= 1\n                pointer = get_bits(self.unpack(\"!H\")[0],0,14)\n                save = self.offset\n                if last == save:\n                    raise BufferError(\"Recursive pointer in DNSLabel [offset=%d,pointer=%d,length=%d]\" %\n                            (self.offset,pointer,len(self.data)))\n                if pointer < self.offset:\n                    self.offset = pointer\n                else:\n                    # Pointer can't point forwards\n                    raise BufferError(\"Invalid pointer in DNSLabel [offset=%d,pointer=%d,length=%d]\" %\n                            (self.offset,pointer,len(self.data)))\n                label.extend(self.decode_name(save).label)\n                self.offset = save\n                done = True\n            else:\n                if length > 0:\n                    l = self.get(length)\n                    try:\n                        l.decode()\n                    except UnicodeDecodeError:\n                        raise BufferError(\"Invalid label <%s>\" % l)\n                    label.append(l)\n                else:\n                    done = True\n        return DNSLabel(label)\n\n    def encode_name(self,name):\n        \"\"\"\n            Encode label and store at end of buffer (compressing\n            cached elements where needed) and store elements\n            in 'names' dict\n        \"\"\"\n        if not isinstance(name,DNSLabel):\n            name = DNSLabel(name)\n        if len(name) > 253:\n            raise DNSLabelError(\"Domain label too long: %r\" % name)\n        name = list(name.label)\n        while name:\n            if tuple(name) in self.names:\n                # Cached - set pointer\n                pointer = self.names[tuple(name)]\n                pointer = set_bits(pointer,3,14,2)\n                self.pack(\"!H\",pointer)\n                return\n            else:\n                self.names[tuple(name)] = self.offset\n                element = name.pop(0)\n                if len(element) > 256:\n                    raise DNSLabelError(\"Label component too long: %r\" % element)\n                self.pack(\"!B\",len(element))\n                self.append(element)\n        self.append(b'\\x00')\n\n    def encode_name_nocompress(self,name):\n        \"\"\"\n            Encode and store label with no compression\n            (needed for RRSIG)\n        \"\"\"\n        if not isinstance(name,DNSLabel):\n            name = DNSLabel(name)\n        if len(name) > 253:\n            raise DNSLabelError(\"Domain label too long: %r\" % name)\n        name = list(name.label)\n        while name:\n            element = name.pop(0)\n            if len(element) > 63:\n                raise DNSLabelError(\"Label component too long: %r\" % element)\n            self.pack(\"!B\",len(element))\n            self.append(element)\n        self.append(b'\\x00')\n\nif __name__ == '__main__':\n    import doctest\n    doctest.testmod()\n"
  },
  {
    "path": "code/default/lib/noarch/dnslib/lex.py",
    "content": "# -*- coding: utf-8 -*-\n\n\n\nimport collections,string\n\ntry:\n    from io import StringIO\nexcept ImportError:\n    from io import StringIO\n\nclass Lexer(object):\n\n    \"\"\"\n        Simple Lexer base class. Provides basic lexer framework and\n        helper functionality (read/peek/pushback etc)\n\n        Each state is implemented using a method (lexXXXX) which should\n        match a single token and return a (token,lexYYYY) tuple, with lexYYYY\n        representing the next state. If token is None this is not emitted\n        and if lexYYYY is None or the lexer reaches the end of the\n        input stream the lexer exits.\n\n        The 'parse' method returns a generator that will return tokens\n        (the class also acts as an iterator)\n\n        The default start state is 'lexStart'\n\n        Input can either be a string/bytes or file object.\n\n        The approach is based loosely on Rob Pike's Go lexer presentation\n        (using generators rather than channels).\n\n        >>> p = Lexer(\"a bcd efgh\")\n        >>> p.read()\n        'a'\n        >>> p.read()\n        ' '\n        >>> p.peek(3)\n        'bcd'\n        >>> p.read(5)\n        'bcd e'\n        >>> p.pushback('e')\n        >>> p.read(4)\n        'efgh'\n    \"\"\"\n\n    escape_chars = '\\\\'\n    escape = {'n':'\\n','t':'\\t','r':'\\r'}\n\n    def __init__(self,f,debug=False):\n        if hasattr(f,'read'):\n            self.f = f\n        elif type(f) == str:\n            self.f = StringIO(f)\n        elif type(f) == bytes:\n            self.f = StringIO(f.decode())\n        else:\n            raise ValueError(\"Invalid input\")\n        self.debug = debug\n        self.q = collections.deque()\n        self.state = self.lexStart\n        self.escaped = False\n        self.eof = False\n\n    def __iter__(self):\n        return self.parse()\n\n    def next_token(self):\n        if self.debug:\n            print(\"STATE\",self.state)\n        (tok,self.state) = self.state()\n        return tok\n\n    def parse(self):\n        while self.state is not None and not self.eof:\n            tok = self.next_token()\n            if tok:\n                yield tok\n\n    def read(self,n=1):\n        s = \"\"\n        while self.q and n > 0:\n            s += self.q.popleft()\n            n -= 1\n        s += self.f.read(n)\n        if s == '':\n            self.eof = True\n        if self.debug:\n            print(\"Read: >%s<\" % repr(s))\n        return s\n\n    def peek(self,n=1):\n        s = \"\"\n        i = 0\n        while len(self.q) > i and n > 0:\n            s += self.q[i]\n            i += 1\n            n -= 1\n        r = self.f.read(n)\n        if n > 0 and r == '':\n            self.eof = True\n        self.q.extend(r)\n        if self.debug:\n            print(\"Peek : >%s<\" % repr(s + r))\n        return s + r\n\n    def pushback(self,s):\n        p = collections.deque(s)\n        p.extend(self.q)\n        self.q = p\n\n    def readescaped(self):\n        c = self.read(1)\n        if c in self.escape_chars:\n            self.escaped = True\n            n = self.peek(3)\n            if n.isdigit():\n                n = self.read(3)\n                if self.debug:\n                    print(\"Escape: >%s<\" % n)\n                return chr(int(n,8))\n            elif n[0] in 'x':\n                x = self.read(3)\n                if self.debug:\n                    print(\"Escape: >%s<\" % x)\n                return chr(int(x[1:],16))\n            else:\n                c = self.read(1)\n                if self.debug:\n                    print(\"Escape: >%s<\" % c)\n                return self.escape.get(c,c)\n        else:\n            self.escaped = False\n            return c\n\n    def lexStart(self):\n        return (None,None)\n\nclass WordLexer(Lexer):\n    \"\"\"\n        Example lexer which will split input stream into words (respecting\n        quotes)\n\n        To emit SPACE tokens: self.spacetok = ('SPACE',None)\n        To emit NL tokens: self.nltok = ('NL',None)\n\n        >>> l = WordLexer(r'abc \"def\\100\\x3d\\. ghi\" jkl')\n        >>> list(l)\n        [('ATOM', 'abc'), ('ATOM', 'def@=. ghi'), ('ATOM', 'jkl')]\n        >>> l = WordLexer(r\"1 '2 3 4' 5\")\n        >>> list(l)\n        [('ATOM', '1'), ('ATOM', '2 3 4'), ('ATOM', '5')]\n        >>> l = WordLexer(\"abc# a comment\")\n        >>> list(l)\n        [('ATOM', 'abc'), ('COMMENT', 'a comment')]\n    \"\"\"\n\n    wordchars = set(string.ascii_letters) | set(string.digits) | \\\n                set(string.punctuation)\n    quotechars = set('\"\\'')\n    commentchars = set('#')\n    spacechars = set(' \\t\\x0b\\x0c')\n    nlchars = set('\\r\\n')\n    spacetok = None\n    nltok = None\n\n    def lexStart(self):\n        return (None,self.lexSpace)\n\n    def lexSpace(self):\n        s = []\n        if self.spacetok:\n            tok = lambda n : (self.spacetok,n) if s else (None,n)\n        else:\n            tok = lambda n : (None,n)\n        while not self.eof:\n            c = self.peek()\n            if c in self.spacechars:\n                s.append(self.read())\n            elif c in self.nlchars:\n                return tok(self.lexNL)\n            elif c in self.commentchars:\n                return tok(self.lexComment)\n            elif c in self.quotechars:\n                return tok(self.lexQuote)\n            elif c in self.wordchars:\n                return tok(self.lexWord)\n                return (self.spacetok,self.lexWord)\n            elif c:\n                raise ValueError(\"Invalid input [%d]: %s\" % (\n                                        self.f.tell(),c))\n        return (None,None)\n\n    def lexNL(self):\n        while True:\n            c = self.read()\n            if c not in self.nlchars:\n                self.pushback(c)\n                return (self.nltok,self.lexSpace)\n\n    def lexComment(self):\n        s = []\n        tok = lambda n : (('COMMENT',''.join(s)),n) if s else (None,n)\n        start = False\n        _ = self.read()\n        while not self.eof:\n            c = self.read()\n            if c == '\\n':\n                self.pushback(c)\n                return tok(self.lexNL)\n            elif start or c not in string.whitespace:\n                start = True\n                s.append(c)\n        return tok(None)\n\n    def lexWord(self):\n        s = []\n        tok = lambda n : (('ATOM',''.join(s)),n) if s else (None,n)\n        while not self.eof:\n            c = self.peek()\n            if c == '\"':\n                return tok(self.lexQuote)\n            elif c in self.commentchars:\n                return tok(self.lexComment)\n            elif c.isspace():\n                return tok(self.lexSpace)\n            elif c in self.wordchars:\n                s.append(self.read())\n            elif c:\n                raise ValueError('Invalid input [%d]: %s' % (\n                                    self.f.tell(),c))\n        return tok(None)\n\n    def lexQuote(self):\n        s = []\n        tok = lambda n : (('ATOM',''.join(s)),n)\n        q = self.read(1)\n        while not self.eof:\n            c = self.readescaped()\n            if c == q and not self.escaped:\n                break\n            else:\n                s.append(c)\n        return tok(self.lexSpace)\n\nclass RandomLexer(Lexer):\n\n    \"\"\"\n        Test lexing from infinite stream.\n\n        Extract strings of letters/numbers from /dev/urandom\n\n        >>> import itertools,sys\n        >>> if sys.version[0] == '2':\n        ...     f = open(\"/dev/urandom\")\n        ... else:\n        ...     f = open(\"/dev/urandom\",encoding=\"ascii\",errors=\"replace\")\n        >>> r = RandomLexer(f)\n        >>> i = iter(r)\n        >>> len(list(itertools.islice(i,10)))\n        10\n    \"\"\"\n\n    minalpha = 4\n    mindigits = 3\n\n    def lexStart(self):\n        return (None,self.lexRandom)\n\n    def lexRandom(self):\n        n = 0\n        c = self.peek(1)\n        while not self.eof:\n            if c.isalpha():\n                return (None,self.lexAlpha)\n            elif c.isdigit():\n                return (None,self.lexDigits)\n            else:\n                n += 1\n                _ = self.read(1)\n                c = self.peek(1)\n        return (None,None)\n\n    def lexDigits(self):\n        s = []\n        c = self.read(1)\n        while c.isdigit():\n            s.append(c)\n            c = self.read(1)\n        self.pushback(c)\n        if len(s) >= self.mindigits:\n            return (('NUMBER',\"\".join(s)),self.lexRandom)\n        else:\n            return (None,self.lexRandom)\n\n    def lexAlpha(self):\n        s = []\n        c = self.read(1)\n        while c.isalpha():\n            s.append(c)\n            c = self.read(1)\n        self.pushback(c)\n        if len(s) >= self.minalpha:\n            return (('STRING',\"\".join(s)),self.lexRandom)\n        else:\n            return (None,self.lexRandom)\n\nif __name__ == '__main__':\n\n    import argparse,doctest,sys\n\n    p = argparse.ArgumentParser(description=\"Lex Tester\")\n    p.add_argument(\"--lex\",\"-l\",action='store_true',default=False,\n                    help=\"Lex input (stdin)\")\n    p.add_argument(\"--nl\",action='store_true',default=False,\n                    help=\"Output NL tokens\")\n    p.add_argument(\"--space\",action='store_true',default=False,\n                    help=\"Output Whitespace tokens\")\n    p.add_argument(\"--wordchars\",help=\"Wordchars\")\n    p.add_argument(\"--quotechars\",help=\"Quotechars\")\n    p.add_argument(\"--commentchars\",help=\"Commentchars\")\n    p.add_argument(\"--spacechars\",help=\"Spacechars\")\n    p.add_argument(\"--nlchars\",help=\"NLchars\")\n\n    args = p.parse_args()\n\n    if args.lex:\n        l = WordLexer(sys.stdin)\n        if args.wordchars:\n            l.wordchars = set(args.wordchars)\n        if args.quotechars:\n            l.quotechars = set(args.quotechars)\n        if args.commentchars:\n            l.commentchars = set(args.commentchars)\n        if args.spacechars:\n            l.spacechars = set(args.spacechars)\n        if args.nlchars:\n            l.nlchars = set(args.nlchars)\n        if args.space:\n            l.spacetok = ('SPACE',)\n        if args.nl:\n            l.nltok = ('NL',)\n\n        for tok in l:\n            print(tok)\n    else:\n        try:\n            # Test if we have /dev/urandom\n            open(\"/dev/urandom\")\n            doctest.testmod()\n        except IOError:\n            # Don't run stream test\n            doctest.run_docstring_examples(Lexer, globals())\n            doctest.run_docstring_examples(WordLexer, globals())\n\n"
  },
  {
    "path": "code/default/lib/noarch/dnslib/proxy.py",
    "content": "# -*- coding: utf-8 -*-\n\n\n\nimport binascii,socket,struct\n\nfrom dnslib import DNSRecord\nfrom dnslib.server import DNSServer,DNSHandler,BaseResolver,DNSLogger\n\nclass ProxyResolver(BaseResolver):\n    \"\"\"\n        Proxy resolver - passes all requests to upstream DNS server and\n        returns response\n\n        Note that the request/response will be each be decoded/re-encoded\n        twice:\n\n        a) Request packet received by DNSHandler and parsed into DNSRecord\n        b) DNSRecord passed to ProxyResolver, serialised back into packet\n           and sent to upstream DNS server\n        c) Upstream DNS server returns response packet which is parsed into\n           DNSRecord\n        d) ProxyResolver returns DNSRecord to DNSHandler which re-serialises\n           this into packet and returns to client\n\n        In practice this is actually fairly useful for testing but for a\n        'real' transparent proxy option the DNSHandler logic needs to be\n        modified (see PassthroughDNSHandler)\n\n    \"\"\"\n\n    def __init__(self,address,port):\n        self.address = address\n        self.port = port\n\n    def resolve(self,request,handler):\n        if handler.protocol == 'udp':\n            proxy_r = request.send(self.address,self.port)\n        else:\n            proxy_r = request.send(self.address,self.port,tcp=True)\n        reply = DNSRecord.parse(proxy_r)\n        return reply\n\nclass PassthroughDNSHandler(DNSHandler):\n    \"\"\"\n        Modify DNSHandler logic (get_reply method) to send directly to\n        upstream DNS server rather then decoding/encoding packet and\n        passing to Resolver (The request/response packets are still\n        parsed and logged but this is not inline)\n    \"\"\"\n    def get_reply(self,data):\n        host,port = self.server.resolver.address,self.server.resolver.port\n\n        request = DNSRecord.parse(data)\n        self.log_request(request)\n\n        if self.protocol == 'tcp':\n            data = struct.pack(\"!H\",len(data)) + data\n            response = send_tcp(data,host,port)\n            response = response[2:]\n        else:\n            response = send_udp(data,host,port)\n\n        reply = DNSRecord.parse(response)\n        self.log_reply(reply)\n\n        return response\n\ndef send_tcp(data,host,port):\n    \"\"\"\n        Helper function to send/receive DNS TCP request\n        (in/out packets will have prepended TCP length header)\n    \"\"\"\n    sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)\n    sock.connect((host,port))\n    sock.sendall(data)\n    response = sock.recv(8192)\n    length = struct.unpack(\"!H\",bytes(response[:2]))[0]\n    while len(response) - 2 < length:\n        response += sock.recv(8192)\n    sock.close()\n    return response\n\ndef send_udp(data,host,port):\n    \"\"\"\n        Helper function to send/receive DNS UDP request\n    \"\"\"\n    sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)\n    sock.sendto(data,(host,port))\n    response,server = sock.recvfrom(8192)\n    sock.close()\n    return response\n\nif __name__ == '__main__':\n\n    import argparse,sys,time\n\n    p = argparse.ArgumentParser(description=\"DNS Proxy\")\n    p.add_argument(\"--port\",\"-p\",type=int,default=53,\n                    metavar=\"<port>\",\n                    help=\"Local proxy port (default:53)\")\n    p.add_argument(\"--address\",\"-a\",default=\"\",\n                    metavar=\"<address>\",\n                    help=\"Local proxy listen address (default:all)\")\n    p.add_argument(\"--upstream\",\"-u\",default=\"8.8.8.8:53\",\n            metavar=\"<dns server:port>\",\n                    help=\"Upstream DNS server:port (default:8.8.8.8:53)\")\n    p.add_argument(\"--tcp\",action='store_true',default=False,\n                    help=\"TCP proxy (default: UDP only)\")\n    p.add_argument(\"--passthrough\",action='store_true',default=False,\n                    help=\"Dont decode/re-encode request/response (default: off)\")\n    p.add_argument(\"--log\",default=\"request,reply,truncated,error\",\n                    help=\"Log hooks to enable (default: +request,+reply,+truncated,+error,-recv,-send,-data)\")\n    p.add_argument(\"--log-prefix\",action='store_true',default=False,\n                    help=\"Log prefix (timestamp/handler/resolver) (default: False)\")\n    args = p.parse_args()\n\n    args.dns,_,args.dns_port = args.upstream.partition(':')\n    args.dns_port = int(args.dns_port or 53)\n\n    print(\"Starting Proxy Resolver (%s:%d -> %s:%d) [%s]\" % (\n                        args.address or \"*\",args.port,\n                        args.dns,args.dns_port,\n                        \"UDP/TCP\" if args.tcp else \"UDP\"))\n\n    resolver = ProxyResolver(args.dns,args.dns_port)\n    handler = PassthroughDNSHandler if args.passthrough else DNSHandler\n    logger = DNSLogger(args.log,args.log_prefix)\n    udp_server = DNSServer(resolver,\n                           port=args.port,\n                           address=args.address,\n                           logger=logger,\n                           handler=handler)\n    udp_server.start_thread()\n\n    if args.tcp:\n        tcp_server = DNSServer(resolver,\n                               port=args.port,\n                               address=args.address,\n                               tcp=True,\n                               logger=logger,\n                               handler=handler)\n        tcp_server.start_thread()\n\n    while udp_server.isAlive():\n        time.sleep(1)\n\n"
  },
  {
    "path": "code/default/lib/noarch/dnslib/ranges.py",
    "content": "# -*- coding: utf-8 -*-\n\n\"\"\"\n    Wrapper around property builtin to restrict attribute to defined\n    integer value range (throws ValueError).\n\n    Intended to ensure that values packed with struct are in the\n    correct range\n\n    >>> class T(object):\n    ...     a = range_property('a',-100,100)\n    ...     b = B('b')\n    ...     c = H('c')\n    ...     d = I('d')\n    >>> t = T()\n    >>> for i in [0,100,-100]:\n    ...     t.a = i\n    ...     assert t.a == i\n    >>> t.a = 101\n    Traceback (most recent call last):\n    ...\n    ValueError: Attribute 'a' must be between -100-100 [101]\n    >>> t.a = -101\n    Traceback (most recent call last):\n    ...\n    ValueError: Attribute 'a' must be between -100-100 [-101]\n    >>> t.a = 'blah'\n    Traceback (most recent call last):\n    ...\n    ValueError: Attribute 'a' must be between -100-100 [blah]\n\n\"\"\"\n\nimport sys\nif sys.version < '3':\n    int_types = (int, int,)\nelse:\n    int_types = (int,)\n\ndef range_property(attr,min,max):\n    def getter(obj):\n        return getattr(obj,\"_%s\" % attr)\n    def setter(obj,val):\n        if isinstance(val,int_types) and min <= val <= max:\n            setattr(obj,\"_%s\" % attr,val)\n        else:\n            raise ValueError(\"Attribute '%s' must be between %d-%d [%s]\" %\n                                        (attr,min,max,val))\n    return property(getter,setter)\n\ndef B(attr):\n    \"\"\"\n        Unsigned Byte\n    \"\"\"\n    return range_property(attr,0,255)\n\ndef H(attr):\n    \"\"\"\n        Unsigned Short\n    \"\"\"\n    return range_property(attr,0,65535)\n\ndef I(attr):\n    \"\"\"\n        Unsigned Long\n    \"\"\"\n    return range_property(attr,0,4294967295)\n\ndef ntuple_range(attr,n,min,max):\n    f = lambda x : isinstance(x,int_types) and min <= x <= max\n    def getter(obj):\n        return getattr(obj,\"_%s\" % attr)\n    def setter(obj,val):\n        if len(val) != n:\n            raise ValueError(\"Attribute '%s' must be tuple with %d elements [%s]\" %\n                                        (attr,n,val))\n        if all(map(f,val)):\n            setattr(obj,\"_%s\" % attr,val)\n        else:\n            raise ValueError(\"Attribute '%s' elements must be between %d-%d [%s]\" %\n                                        (attr,min,max,val))\n    return property(getter,setter)\n\ndef IP4(attr):\n    return ntuple_range(attr,4,0,255)\n\ndef IP6(attr):\n    return ntuple_range(attr,16,0,255)\n\nif __name__ == '__main__':\n    import doctest\n    doctest.testmod()\n\n"
  },
  {
    "path": "code/default/lib/noarch/dnslib/server.py",
    "content": "# -*- coding: utf-8 -*-\n\n\"\"\"\n    DNS server framework - intended to simplify creation of custom resolvers.\n\n    Comprises the following components:\n\n        DNSServer   - socketserver wrapper (in most cases you should just\n                      need to pass this an appropriate resolver instance\n                      and start in either foreground/background)\n\n        DNSHandler  - handler instantiated by DNSServer to handle requests\n                      The 'handle' method deals with the sending/receiving\n                      packets (handling TCP length prefix) and delegates\n                      the protocol handling to 'get_reply'. This decodes\n                      packet, hands off a DNSRecord to the Resolver instance,\n                      and encodes the returned DNSRecord.\n\n                      In most cases you dont need to change DNSHandler unless\n                      you need to get hold of the raw protocol data in the\n                      Resolver\n\n        DNSLogger   - The class provides a default set of logging functions for\n                      the various stages of the request handled by a DNSServer\n                      instance which are enabled/disabled by flags in the 'log'\n                      class variable.\n\n        Resolver    - Instance implementing a 'resolve' method that receives\n                      the decodes request packet and returns a response.\n\n                      To implement a custom resolver in most cases all you need\n                      is to implement this interface.\n\n                      Note that there is only a single instance of the Resolver\n                      so need to be careful about thread-safety and blocking\n\n        The following examples use the server framework:\n\n            fixedresolver.py    - Simple resolver which will respond to all\n                                  requests with a fixed response\n            zoneresolver.py     - Resolver which will take a standard zone\n                                  file input\n            shellresolver.py    - Example of a dynamic resolver\n            proxy.py            - DNS proxy\n            intercept.py        - Intercepting DNS proxy\n\n        >>> resolver = BaseResolver()\n        >>> logger = DNSLogger(prefix=False)\n        >>> server = DNSServer(resolver,port=8053,address=\"localhost\",logger=logger)\n        >>> server.start_thread()\n        >>> q = DNSRecord.question(\"abc.def\")\n        >>> a = q.send(\"localhost\",8053)\n        Request: [...] (udp) / 'abc.def.' (A)\n        Reply: [...] (udp) / 'abc.def.' (A) / RRs:\n        >>> print(DNSRecord.parse(a))\n        ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: ...\n        ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0\n        ;; QUESTION SECTION:\n        ;abc.def.                       IN      A\n        >>> server.stop()\n\n        >>> class TestResolver:\n        ...     def resolve(self,request,handler):\n        ...         reply = request.reply()\n        ...         reply.add_answer(*RR.fromZone(\"abc.def. 60 A 1.2.3.4\"))\n        ...         return reply\n        >>> resolver = TestResolver()\n        >>> server = DNSServer(resolver,port=8053,address=\"localhost\",logger=logger,tcp=True)\n        >>> server.start_thread()\n        >>> a = q.send(\"localhost\",8053,tcp=True)\n        Request: [...] (tcp) / 'abc.def.' (A)\n        Reply: [...] (tcp) / 'abc.def.' (A) / RRs: A\n        >>> print(DNSRecord.parse(a))\n        ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...\n        ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0\n        ;; QUESTION SECTION:\n        ;abc.def.                       IN      A\n        ;; ANSWER SECTION:\n        abc.def.                60      IN      A       1.2.3.4\n        >>> server.stop()\n\n\n\"\"\"\n\n\nimport binascii,socket,struct,threading,time\n\ntry:\n    import socketserver\nexcept ImportError:\n    import socketserver as socketserver\n\nfrom dnslib import DNSRecord,DNSError,QTYPE,RCODE,RR\n\nclass BaseResolver(object):\n    \"\"\"\n        Base resolver implementation. Provides 'resolve' method which is\n        called by DNSHandler with the decode request (DNSRecord instance)\n        and returns a DNSRecord instance as reply.\n\n        In most cases you should be able to create a custom resolver by\n        just replacing the resolve method with appropriate resolver code for\n        application (see fixedresolver/zoneresolver/shellresolver for\n        examples)\n\n        Note that a single instance is used by all DNSHandler instances so\n        need to consider blocking & thread safety.\n    \"\"\"\n    def resolve(self,request,handler):\n        \"\"\"\n            Example resolver - respond to all requests with NXDOMAIN\n        \"\"\"\n        reply = request.reply()\n        reply.header.rcode = getattr(RCODE,'NXDOMAIN')\n        return reply\n\nclass DNSHandler(socketserver.BaseRequestHandler):\n    \"\"\"\n        Handler for socketserver. Transparently handles both TCP/UDP requests\n        (TCP requests have length prepended) and hands off lookup to resolver\n        instance specified in <SocketServer>.resolver\n    \"\"\"\n\n    udplen = 0                  # Max udp packet length (0 = ignore)\n\n    def handle(self):\n        if self.server.socket_type == socket.SOCK_STREAM:\n            self.protocol = 'tcp'\n            data = self.request.recv(8192)\n            length = struct.unpack(\"!H\",bytes(data[:2]))[0]\n            while len(data) - 2 < length:\n                data += self.request.recv(8192)\n            data = data[2:]\n        else:\n            self.protocol = 'udp'\n            data,connection = self.request\n\n        self.server.logger.log_recv(self,data)\n\n        try:\n            rdata = self.get_reply(data)\n            self.server.logger.log_send(self,rdata)\n\n            if self.protocol == 'tcp':\n                rdata = struct.pack(\"!H\",len(rdata)) + rdata\n                self.request.sendall(rdata)\n            else:\n                connection.sendto(rdata,self.client_address)\n\n        except DNSError as e:\n            self.server.logger.log_error(self,e)\n\n    def get_reply(self,data):\n        request = DNSRecord.parse(data)\n        self.server.logger.log_request(self,request)\n\n        resolver = self.server.resolver\n        reply = resolver.resolve(request,self)\n        self.server.logger.log_reply(self,reply)\n\n        if self.protocol == 'udp':\n            rdata = reply.pack()\n            if self.udplen and len(rdata) > self.udplen:\n                truncated_reply = reply.truncate()\n                rdata = truncated_reply.pack()\n                self.server.logger.log_truncated(self,truncated_reply)\n        else:\n            rdata = reply.pack()\n\n        return rdata\n\nclass DNSLogger:\n\n    \"\"\"\n        The class provides a default set of logging functions for the various\n        stages of the request handled by a DNSServer instance which are\n        enabled/disabled by flags in the 'log' class variable.\n\n        To customise logging create an object which implements the DNSLogger\n        interface and pass instance to DNSServer.\n\n        The methods which the logger instance must implement are:\n\n            log_recv          - Raw packet received\n            log_send          - Raw packet sent\n            log_request       - DNS Request\n            log_reply         - DNS Response\n            log_truncated     - Truncated\n            log_error         - Decoding error\n            log_data          - Dump full request/response\n    \"\"\"\n\n    def __init__(self,log=\"\",prefix=True):\n        \"\"\"\n            Selectively enable log hooks depending on log argument\n            (comma separated list of hooks to enable/disable)\n\n            - If empty enable default log hooks\n            - If entry starts with '+' (eg. +send,+recv) enable hook\n            - If entry starts with '-' (eg. -data) disable hook\n            - If entry doesn't start with +/- replace defaults\n\n            Prefix argument enables/disables log prefix\n        \"\"\"\n        default = [\"request\",\"reply\",\"truncated\",\"error\"]\n        log = log.split(\",\") if log else []\n        enabled = set([ s for s in log if s[0] not in '+-'] or default)\n        [ enabled.add(l[1:]) for l in log if l.startswith('+') ]\n        [ enabled.discard(l[1:]) for l in log if l.startswith('-') ]\n        for l in ['log_recv','log_send','log_request','log_reply',\n                  'log_truncated','log_error','log_data']:\n            if l[4:] not in enabled:\n                setattr(self,l,self.log_pass)\n        self.prefix = prefix\n\n    def log_pass(self,*args):\n        pass\n\n    def log_prefix(self,handler):\n        if self.prefix:\n            return \"%s [%s:%s] \" % (time.strftime(\"%Y-%M-%d %X\"),\n                               handler.__class__.__name__,\n                               handler.server.resolver.__class__.__name__)\n        else:\n            return \"\"\n\n    def log_recv(self,handler,data):\n        print(\"%sReceived: [%s:%d] (%s) <%d> : %s\" % (\n                    self.log_prefix(handler),\n                    handler.client_address[0],\n                    handler.client_address[1],\n                    handler.protocol,\n                    len(data),\n                    binascii.hexlify(data)))\n\n    def log_send(self,handler,data):\n        print(\"%sSent: [%s:%d] (%s) <%d> : %s\" % (\n                    self.log_prefix(handler),\n                    handler.client_address[0],\n                    handler.client_address[1],\n                    handler.protocol,\n                    len(data),\n                    binascii.hexlify(data)))\n\n    def log_request(self,handler,request):\n        print(\"%sRequest: [%s:%d] (%s) / '%s' (%s)\" % (\n                    self.log_prefix(handler),\n                    handler.client_address[0],\n                    handler.client_address[1],\n                    handler.protocol,\n                    request.q.qname,\n                    QTYPE[request.q.qtype]))\n        self.log_data(request)\n\n    def log_reply(self,handler,reply):\n        print(\"%sReply: [%s:%d] (%s) / '%s' (%s) / RRs: %s\" % (\n                    self.log_prefix(handler),\n                    handler.client_address[0],\n                    handler.client_address[1],\n                    handler.protocol,\n                    reply.q.qname,\n                    QTYPE[reply.q.qtype],\n                    \",\".join([QTYPE[a.rtype] for a in reply.rr])))\n        self.log_data(reply)\n\n    def log_truncated(self,handler,reply):\n        print(\"%sTruncated Reply: [%s:%d] (%s) / '%s' (%s) / RRs: %s\" % (\n                    self.log_prefix(handler),\n                    handler.client_address[0],\n                    handler.client_address[1],\n                    handler.protocol,\n                    reply.q.qname,\n                    QTYPE[reply.q.qtype],\n                    \",\".join([QTYPE[a.rtype] for a in reply.rr])))\n        self.log_data(reply)\n\n    def log_error(self,handler,e):\n        print(\"%sInvalid Request: [%s:%d] (%s) :: %s\" % (\n                    self.log_prefix(handler),\n                    handler.client_address[0],\n                    handler.client_address[1],\n                    handler.protocol,\n                    e))\n\n    def log_data(self,dnsobj):\n        # print(\"\\n\",dnsobj.toZone(\"    \"),\"\\n\",sep=\"\")\n        pass\n\nclass UDPServer(socketserver.UDPServer):\n    allow_reuse_address = True\n\nclass TCPServer(socketserver.TCPServer):\n    allow_reuse_address = True\n\nclass DNSServer(object):\n\n    \"\"\"\n        Convenience wrapper for socketserver instance allowing\n        either UDP/TCP server to be started in blocking more\n        or as a background thread.\n\n        Processing is delegated to custom resolver (instance) and\n        optionally custom logger (instance), handler (class), and\n        server (class)\n\n        In most cases only a custom resolver instance is required\n        (and possibly logger)\n    \"\"\"\n    def __init__(self,resolver,\n                      address=\"\",\n                      port=53,\n                      tcp=False,\n                      logger=None,\n                      handler=DNSHandler,\n                      server=None):\n        \"\"\"\n            resolver:   resolver instance\n            address:    listen address (default: \"\")\n            port:       listen port (default: 53)\n            tcp:        UDP (false) / TCP (true) (default: False)\n            logger:     logger instance (default: DNSLogger)\n            handler:    handler class (default: DNSHandler)\n            server:     socketserver class (default: UDPServer/TCPServer)\n        \"\"\"\n        if not server:\n            if tcp:\n                server = TCPServer\n            else:\n                server = UDPServer\n        self.server = server((address,port),handler)\n        self.server.resolver = resolver\n        self.server.logger = logger or DNSLogger()\n\n    def start(self):\n        self.server.serve_forever()\n\n    def start_thread(self):\n        self.thread = threading.Thread(target=self.server.serve_forever, name=\"dns_server\")\n        self.thread.daemon = True\n        self.thread.start()\n\n    def stop(self):\n        self.server.shutdown()\n\n    def isAlive(self):\n        return self.thread.isAlive()\n\nif __name__ == \"__main__\":\n    import doctest\n    doctest.testmod(optionflags=doctest.ELLIPSIS)\n"
  },
  {
    "path": "code/default/lib/noarch/dnslib/shellresolver.py",
    "content": "# -*- coding: utf-8 -*-\n\n\n\ntry:\n    from subprocess import getoutput\nexcept ImportError:\n    from subprocess import getoutput\n\nfrom dnslib import RR,QTYPE,RCODE,TXT,parse_time\nfrom dnslib.label import DNSLabel\nfrom dnslib.server import DNSServer,DNSHandler,BaseResolver,DNSLogger\n\nclass ShellResolver(BaseResolver):\n    \"\"\"\n        Example dynamic resolver.\n        Maps DNS labels to shell commands and returns result as TXT record\n        (Note: No context is passed to the shell command)\n\n        Shell commands are passed in a a list in <label>:<cmd> format - eg:\n\n            [ 'uptime.abc.com.:uptime', 'ls:ls' ]\n\n        Would respond to requests to 'uptime.abc.com.' with the output\n        of the 'uptime' command.\n\n        For non-absolute labels the 'origin' parameter is prepended\n\n    \"\"\"\n    def __init__(self,routes,origin,ttl):\n        self.origin = DNSLabel(origin)\n        self.ttl = parse_time(ttl)\n        self.routes = {}\n        for r in routes:\n            route,_,cmd = r.partition(\":\")\n            if route.endswith('.'):\n                route = DNSLabel(route)\n            else:\n                route = self.origin.add(route)\n            self.routes[route] = cmd\n\n    def resolve(self,request,handler):\n        reply = request.reply()\n        qname = request.q.qname\n        cmd = self.routes.get(qname)\n        if cmd:\n            output = getoutput(cmd).encode()\n            reply.add_answer(RR(qname,QTYPE.TXT,ttl=self.ttl,\n                                rdata=TXT(output[:254])))\n        else:\n            reply.header.rcode = RCODE.NXDOMAIN\n        return reply\n\nif __name__ == '__main__':\n\n    import argparse,sys,time\n\n    p = argparse.ArgumentParser(description=\"Shell DNS Resolver\")\n    p.add_argument(\"--map\",\"-m\",action=\"append\",required=True,\n                    metavar=\"<label>:<shell command>\",\n                    help=\"Map label to shell command (multiple supported)\")\n    p.add_argument(\"--origin\",\"-o\",default=\".\",\n                    metavar=\"<origin>\",\n                    help=\"Origin domain label (default: .)\")\n    p.add_argument(\"--ttl\",\"-t\",default=\"60s\",\n                    metavar=\"<ttl>\",\n                    help=\"Response TTL (default: 60s)\")\n    p.add_argument(\"--port\",\"-p\",type=int,default=53,\n                    metavar=\"<port>\",\n                    help=\"Server port (default:53)\")\n    p.add_argument(\"--address\",\"-a\",default=\"\",\n                    metavar=\"<address>\",\n                    help=\"Listen address (default:all)\")\n    p.add_argument(\"--udplen\",\"-u\",type=int,default=0,\n                    metavar=\"<udplen>\",\n                    help=\"Max UDP packet length (default:0)\")\n    p.add_argument(\"--tcp\",action='store_true',default=False,\n                    help=\"TCP server (default: UDP only)\")\n    p.add_argument(\"--log\",default=\"request,reply,truncated,error\",\n                    help=\"Log hooks to enable (default: +request,+reply,+truncated,+error,-recv,-send,-data)\")\n    p.add_argument(\"--log-prefix\",action='store_true',default=False,\n                    help=\"Log prefix (timestamp/handler/resolver) (default: False)\")\n    args = p.parse_args()\n\n    resolver = ShellResolver(args.map,args.origin,args.ttl)\n    logger = DNSLogger(args.log,args.log_prefix)\n\n    print(\"Starting Shell Resolver (%s:%d) [%s]\" % (\n                        args.address or \"*\",\n                        args.port,\n                        \"UDP/TCP\" if args.tcp else \"UDP\"))\n\n    for route,cmd in list(resolver.routes.items()):\n        print(\"    | \",route,\"-->\",cmd)\n    print()\n\n    if args.udplen:\n        DNSHandler.udplen = args.udplen\n\n    udp_server = DNSServer(resolver,\n                           port=args.port,\n                           address=args.address,\n                           logger=logger)\n    udp_server.start_thread()\n\n    if args.tcp:\n        tcp_server = DNSServer(resolver,\n                               port=args.port,\n                               address=args.address,\n                               tcp=True,\n                               logger=logger)\n        tcp_server.start_thread()\n\n    while udp_server.isAlive():\n        time.sleep(1)\n\n"
  },
  {
    "path": "code/default/lib/noarch/dnslib/zoneresolver.py",
    "content": "# -*- coding: utf-8 -*-\n\n\n\nimport copy\n\nfrom dnslib import RR,QTYPE,RCODE\nfrom dnslib.server import DNSServer,DNSHandler,BaseResolver,DNSLogger\n\nclass ZoneResolver(BaseResolver):\n    \"\"\"\n        Simple fixed zone file resolver.\n    \"\"\"\n\n    def __init__(self,zone,glob=False):\n        \"\"\"\n            Initialise resolver from zone file.\n            Stores RRs as a list of (label,type,rr) tuples\n            If 'glob' is True use glob match against zone file\n        \"\"\"\n        self.zone = [(rr.rname,QTYPE[rr.rtype],rr) for rr in RR.fromZone(zone)]\n        self.glob = glob\n        self.eq = 'matchGlob' if glob else '__eq__'\n\n    def resolve(self,request,handler):\n        \"\"\"\n            Respond to DNS request - parameters are request packet & handler.\n            Method is expected to return DNS response\n        \"\"\"\n        reply = request.reply()\n        qname = request.q.qname\n        qtype = QTYPE[request.q.qtype]\n        for name,rtype,rr in self.zone:\n            # Check if label & type match\n            if getattr(qname,self.eq)(name) and (qtype == rtype or\n                                                 qtype == 'ANY' or\n                                                 rtype == 'CNAME'):\n                # If we have a glob match fix reply label\n                if self.glob:\n                    a = copy.copy(rr)\n                    a.rname = qname\n                    reply.add_answer(a)\n                else:\n                    reply.add_answer(rr)\n                # Check for A/AAAA records associated with reply and\n                # add in additional section\n                if rtype in ['CNAME','NS','MX','PTR']:\n                    for a_name,a_rtype,a_rr in self.zone:\n                        if a_name == rr.rdata.label and a_rtype in ['A','AAAA']:\n                            reply.add_ar(a_rr)\n        if not reply.rr:\n            reply.header.rcode = RCODE.NXDOMAIN\n        return reply\n\nif __name__ == '__main__':\n\n    import argparse,sys,time\n\n    p = argparse.ArgumentParser(description=\"Zone DNS Resolver\")\n    p.add_argument(\"--zone\",\"-z\",required=True,\n                        metavar=\"<zone-file>\",\n                        help=\"Zone file ('-' for stdin)\")\n    p.add_argument(\"--port\",\"-p\",type=int,default=53,\n                        metavar=\"<port>\",\n                        help=\"Server port (default:53)\")\n    p.add_argument(\"--address\",\"-a\",default=\"\",\n                        metavar=\"<address>\",\n                        help=\"Listen address (default:all)\")\n    p.add_argument(\"--glob\",action='store_true',default=False,\n                        help=\"Glob match against zone file (default: false)\")\n    p.add_argument(\"--udplen\",\"-u\",type=int,default=0,\n                    metavar=\"<udplen>\",\n                    help=\"Max UDP packet length (default:0)\")\n    p.add_argument(\"--tcp\",action='store_true',default=False,\n                        help=\"TCP server (default: UDP only)\")\n    p.add_argument(\"--log\",default=\"request,reply,truncated,error\",\n                    help=\"Log hooks to enable (default: +request,+reply,+truncated,+error,-recv,-send,-data)\")\n    p.add_argument(\"--log-prefix\",action='store_true',default=False,\n                    help=\"Log prefix (timestamp/handler/resolver) (default: False)\")\n    args = p.parse_args()\n\n    if args.zone == '-':\n        args.zone = sys.stdin\n    else:\n        args.zone = open(args.zone)\n\n    resolver = ZoneResolver(args.zone,args.glob)\n    logger = DNSLogger(args.log,args.log_prefix)\n\n    print(\"Starting Zone Resolver (%s:%d) [%s]\" % (\n                        args.address or \"*\",\n                        args.port,\n                        \"UDP/TCP\" if args.tcp else \"UDP\"))\n\n    # for rr in resolver.zone:\n    #     print(\"    | \",rr[2].toZone(),sep=\"\")\n    print()\n\n    if args.udplen:\n        DNSHandler.udplen = args.udplen\n\n    udp_server = DNSServer(resolver,\n                           port=args.port,\n                           address=args.address,\n                           logger=logger)\n    udp_server.start_thread()\n\n    if args.tcp:\n        tcp_server = DNSServer(resolver,\n                               port=args.port,\n                               address=args.address,\n                               tcp=True,\n                               logger=logger)\n        tcp_server.start_thread()\n\n    while udp_server.isAlive():\n        time.sleep(1)\n\n"
  },
  {
    "path": "code/default/lib/noarch/ecdsa/__init__.py",
    "content": "# while we don't use six in this file, we did bundle it for a long time, so\n# keep as part of module in a virtual way (through __all__)\nimport six\nfrom .keys import (\n    SigningKey,\n    VerifyingKey,\n    BadSignatureError,\n    BadDigestError,\n    MalformedPointError,\n)\nfrom .curves import (\n    NIST192p,\n    NIST224p,\n    NIST256p,\n    NIST384p,\n    NIST521p,\n    SECP256k1,\n    BRAINPOOLP160r1,\n    BRAINPOOLP192r1,\n    BRAINPOOLP224r1,\n    BRAINPOOLP256r1,\n    BRAINPOOLP320r1,\n    BRAINPOOLP384r1,\n    BRAINPOOLP512r1,\n    SECP112r1,\n    SECP112r2,\n    SECP128r1,\n    SECP160r1,\n    Ed25519,\n    Ed448,\n)\nfrom .ecdh import (\n    ECDH,\n    NoKeyError,\n    NoCurveError,\n    InvalidCurveError,\n    InvalidSharedSecretError,\n)\nfrom .der import UnexpectedDER\nfrom . import _version\n\n# This code comes from http://github.com/tlsfuzzer/python-ecdsa\n__all__ = [\n    \"curves\",\n    \"der\",\n    \"ecdsa\",\n    \"ellipticcurve\",\n    \"keys\",\n    \"numbertheory\",\n    \"test_pyecdsa\",\n    \"util\",\n    \"six\",\n]\n\n_hush_pyflakes = [\n    SigningKey,\n    VerifyingKey,\n    BadSignatureError,\n    BadDigestError,\n    MalformedPointError,\n    UnexpectedDER,\n    InvalidCurveError,\n    NoKeyError,\n    InvalidSharedSecretError,\n    ECDH,\n    NoCurveError,\n    NIST192p,\n    NIST224p,\n    NIST256p,\n    NIST384p,\n    NIST521p,\n    SECP256k1,\n    BRAINPOOLP160r1,\n    BRAINPOOLP192r1,\n    BRAINPOOLP224r1,\n    BRAINPOOLP256r1,\n    BRAINPOOLP320r1,\n    BRAINPOOLP384r1,\n    BRAINPOOLP512r1,\n    SECP112r1,\n    SECP112r2,\n    SECP128r1,\n    SECP160r1,\n    Ed25519,\n    Ed448,\n    six.b(\"\"),\n]\ndel _hush_pyflakes\n\n__version__ = _version.get_versions()[\"version\"]\n"
  },
  {
    "path": "code/default/lib/noarch/ecdsa/_compat.py",
    "content": "\"\"\"\nCommon functions for providing cross-python version compatibility.\n\"\"\"\nimport sys\nimport re\nimport binascii\nfrom six import integer_types\n\n\ndef str_idx_as_int(string, index):\n    \"\"\"Take index'th byte from string, return as integer\"\"\"\n    val = string[index]\n    if isinstance(val, integer_types):\n        return val\n    return ord(val)\n\n\nif sys.version_info < (3, 0):  # pragma: no branch\n    import platform\n\n    def normalise_bytes(buffer_object):\n        \"\"\"Cast the input into array of bytes.\"\"\"\n        # flake8 runs on py3 where `buffer` indeed doesn't exist...\n        return buffer(buffer_object)  # noqa: F821\n\n    def hmac_compat(ret):\n        return ret\n\n    if (\n        sys.version_info < (2, 7)\n        or sys.version_info < (2, 7, 4)\n        or platform.system() == \"Java\"\n    ):  # pragma: no branch\n\n        def remove_whitespace(text):\n            \"\"\"Removes all whitespace from passed in string\"\"\"\n            return re.sub(r\"\\s+\", \"\", text)\n\n        def compat26_str(val):\n            return str(val)\n\n        def bit_length(val):\n            if val == 0:\n                return 0\n            return len(bin(val)) - 2\n\n    else:\n\n        def remove_whitespace(text):\n            \"\"\"Removes all whitespace from passed in string\"\"\"\n            return re.sub(r\"\\s+\", \"\", text, flags=re.UNICODE)\n\n        def compat26_str(val):\n            return val\n\n        def bit_length(val):\n            \"\"\"Return number of bits necessary to represent an integer.\"\"\"\n            return val.bit_length()\n\n    def b2a_hex(val):\n        return binascii.b2a_hex(compat26_str(val))\n\n    def a2b_hex(val):\n        try:\n            return bytearray(binascii.a2b_hex(val))\n        except Exception as e:\n            raise ValueError(\"base16 error: %s\" % e)\n\n    def bytes_to_int(val, byteorder):\n        \"\"\"Convert bytes to an int.\"\"\"\n        if not val:\n            return 0\n        if byteorder == \"big\":\n            return int(b2a_hex(val), 16)\n        if byteorder == \"little\":\n            return int(b2a_hex(val[::-1]), 16)\n        raise ValueError(\"Only 'big' and 'little' endian supported\")\n\n    def int_to_bytes(val, length=None, byteorder=\"big\"):\n        \"\"\"Return number converted to bytes\"\"\"\n        if length is None:\n            length = byte_length(val)\n        if byteorder == \"big\":\n            return bytearray(\n                (val >> i) & 0xFF for i in reversed(range(0, length * 8, 8))\n            )\n        if byteorder == \"little\":\n            return bytearray(\n                (val >> i) & 0xFF for i in range(0, length * 8, 8)\n            )\n        raise ValueError(\"Only 'big' or 'little' endian supported\")\n\nelse:\n    if sys.version_info < (3, 4):  # pragma: no branch\n        # on python 3.3 hmac.hmac.update() accepts only bytes, on newer\n        # versions it does accept memoryview() also\n        def hmac_compat(data):\n            if not isinstance(data, bytes):  # pragma: no branch\n                return bytes(data)\n            return data\n\n        def normalise_bytes(buffer_object):\n            \"\"\"Cast the input into array of bytes.\"\"\"\n            if not buffer_object:\n                return b\"\"\n            return memoryview(buffer_object).cast(\"B\")\n\n    else:\n\n        def hmac_compat(data):\n            return data\n\n        def normalise_bytes(buffer_object):\n            \"\"\"Cast the input into array of bytes.\"\"\"\n            return memoryview(buffer_object).cast(\"B\")\n\n    def compat26_str(val):\n        return val\n\n    def remove_whitespace(text):\n        \"\"\"Removes all whitespace from passed in string\"\"\"\n        return re.sub(r\"\\s+\", \"\", text, flags=re.UNICODE)\n\n    def a2b_hex(val):\n        try:\n            return bytearray(binascii.a2b_hex(bytearray(val, \"ascii\")))\n        except Exception as e:\n            raise ValueError(\"base16 error: %s\" % e)\n\n    # pylint: disable=invalid-name\n    # pylint is stupid here and doesn't notice it's a function, not\n    # constant\n    bytes_to_int = int.from_bytes\n    # pylint: enable=invalid-name\n\n    def bit_length(val):\n        \"\"\"Return number of bits necessary to represent an integer.\"\"\"\n        return val.bit_length()\n\n    def int_to_bytes(val, length=None, byteorder=\"big\"):\n        \"\"\"Convert integer to bytes.\"\"\"\n        if length is None:\n            length = byte_length(val)\n        # for gmpy we need to convert back to native int\n        if type(val) != int:\n            val = int(val)\n        return bytearray(val.to_bytes(length=length, byteorder=byteorder))\n\n\ndef byte_length(val):\n    \"\"\"Return number of bytes necessary to represent an integer.\"\"\"\n    length = bit_length(val)\n    return (length + 7) // 8\n"
  },
  {
    "path": "code/default/lib/noarch/ecdsa/_rwlock.py",
    "content": "# Copyright Mateusz Kobos, (c) 2011\n# https://code.activestate.com/recipes/577803-reader-writer-lock-with-priority-for-writers/\n# released under the MIT licence\n\nimport threading\n\n\n__author__ = \"Mateusz Kobos\"\n\n\nclass RWLock:\n    \"\"\"\n    Read-Write locking primitive\n\n    Synchronization object used in a solution of so-called second\n    readers-writers problem. In this problem, many readers can simultaneously\n    access a share, and a writer has an exclusive access to this share.\n    Additionally, the following constraints should be met:\n    1) no reader should be kept waiting if the share is currently opened for\n       reading unless a writer is also waiting for the share,\n    2) no writer should be kept waiting for the share longer than absolutely\n       necessary.\n\n    The implementation is based on [1, secs. 4.2.2, 4.2.6, 4.2.7]\n    with a modification -- adding an additional lock (C{self.__readers_queue})\n    -- in accordance with [2].\n\n    Sources:\n    [1] A.B. Downey: \"The little book of semaphores\", Version 2.1.5, 2008\n    [2] P.J. Courtois, F. Heymans, D.L. Parnas:\n        \"Concurrent Control with 'Readers' and 'Writers'\",\n        Communications of the ACM, 1971 (via [3])\n    [3] http://en.wikipedia.org/wiki/Readers-writers_problem\n    \"\"\"\n\n    def __init__(self):\n        \"\"\"\n        A lock giving an even higher priority to the writer in certain\n        cases (see [2] for a discussion).\n        \"\"\"\n        self.__read_switch = _LightSwitch()\n        self.__write_switch = _LightSwitch()\n        self.__no_readers = threading.Lock()\n        self.__no_writers = threading.Lock()\n        self.__readers_queue = threading.Lock()\n\n    def reader_acquire(self):\n        self.__readers_queue.acquire()\n        self.__no_readers.acquire()\n        self.__read_switch.acquire(self.__no_writers)\n        self.__no_readers.release()\n        self.__readers_queue.release()\n\n    def reader_release(self):\n        self.__read_switch.release(self.__no_writers)\n\n    def writer_acquire(self):\n        self.__write_switch.acquire(self.__no_readers)\n        self.__no_writers.acquire()\n\n    def writer_release(self):\n        self.__no_writers.release()\n        self.__write_switch.release(self.__no_readers)\n\n\nclass _LightSwitch:\n    \"\"\"An auxiliary \"light switch\"-like object. The first thread turns on the\n    \"switch\", the last one turns it off (see [1, sec. 4.2.2] for details).\"\"\"\n\n    def __init__(self):\n        self.__counter = 0\n        self.__mutex = threading.Lock()\n\n    def acquire(self, lock):\n        self.__mutex.acquire()\n        self.__counter += 1\n        if self.__counter == 1:\n            lock.acquire()\n        self.__mutex.release()\n\n    def release(self, lock):\n        self.__mutex.acquire()\n        self.__counter -= 1\n        if self.__counter == 0:\n            lock.release()\n        self.__mutex.release()\n"
  },
  {
    "path": "code/default/lib/noarch/ecdsa/_sha3.py",
    "content": "\"\"\"\nImplementation of the SHAKE-256 algorithm for Ed448\n\"\"\"\n\ntry:\n    import hashlib\n\n    hashlib.new(\"shake256\").digest(64)\n\n    def shake_256(msg, outlen):\n        return hashlib.new(\"shake256\", msg).digest(outlen)\n\nexcept (TypeError, ValueError):\n\n    from ._compat import bytes_to_int, int_to_bytes\n\n    # From little endian.\n    def _from_le(s):\n        return bytes_to_int(s, byteorder=\"little\")\n\n    # Rotate a word x by b places to the left.\n    def _rol(x, b):\n        return ((x << b) | (x >> (64 - b))) & (2**64 - 1)\n\n    # Do the SHA-3 state transform on state s.\n    def _sha3_transform(s):\n        ROTATIONS = [\n            0,\n            1,\n            62,\n            28,\n            27,\n            36,\n            44,\n            6,\n            55,\n            20,\n            3,\n            10,\n            43,\n            25,\n            39,\n            41,\n            45,\n            15,\n            21,\n            8,\n            18,\n            2,\n            61,\n            56,\n            14,\n        ]\n        PERMUTATION = [\n            1,\n            6,\n            9,\n            22,\n            14,\n            20,\n            2,\n            12,\n            13,\n            19,\n            23,\n            15,\n            4,\n            24,\n            21,\n            8,\n            16,\n            5,\n            3,\n            18,\n            17,\n            11,\n            7,\n            10,\n        ]\n        RC = [\n            0x0000000000000001,\n            0x0000000000008082,\n            0x800000000000808A,\n            0x8000000080008000,\n            0x000000000000808B,\n            0x0000000080000001,\n            0x8000000080008081,\n            0x8000000000008009,\n            0x000000000000008A,\n            0x0000000000000088,\n            0x0000000080008009,\n            0x000000008000000A,\n            0x000000008000808B,\n            0x800000000000008B,\n            0x8000000000008089,\n            0x8000000000008003,\n            0x8000000000008002,\n            0x8000000000000080,\n            0x000000000000800A,\n            0x800000008000000A,\n            0x8000000080008081,\n            0x8000000000008080,\n            0x0000000080000001,\n            0x8000000080008008,\n        ]\n\n        for rnd in range(0, 24):\n            # AddColumnParity (Theta)\n            c = [0] * 5\n            d = [0] * 5\n            for i in range(0, 25):\n                c[i % 5] ^= s[i]\n            for i in range(0, 5):\n                d[i] = c[(i + 4) % 5] ^ _rol(c[(i + 1) % 5], 1)\n            for i in range(0, 25):\n                s[i] ^= d[i % 5]\n            # RotateWords (Rho)\n            for i in range(0, 25):\n                s[i] = _rol(s[i], ROTATIONS[i])\n            # PermuteWords (Pi)\n            t = s[PERMUTATION[0]]\n            for i in range(0, len(PERMUTATION) - 1):\n                s[PERMUTATION[i]] = s[PERMUTATION[i + 1]]\n            s[PERMUTATION[-1]] = t\n            # NonlinearMixRows (Chi)\n            for i in range(0, 25, 5):\n                t = [\n                    s[i],\n                    s[i + 1],\n                    s[i + 2],\n                    s[i + 3],\n                    s[i + 4],\n                    s[i],\n                    s[i + 1],\n                ]\n                for j in range(0, 5):\n                    s[i + j] = t[j] ^ ((~t[j + 1]) & (t[j + 2]))\n            # AddRoundConstant (Iota)\n            s[0] ^= RC[rnd]\n\n    # Reinterpret octet array b to word array and XOR it to state s.\n    def _reinterpret_to_words_and_xor(s, b):\n        for j in range(0, len(b) // 8):\n            s[j] ^= _from_le(b[8 * j : 8 * j + 8])\n\n    # Reinterpret word array w to octet array and return it.\n    def _reinterpret_to_octets(w):\n        mp = bytearray()\n        for j in range(0, len(w)):\n            mp += int_to_bytes(w[j], 8, byteorder=\"little\")\n        return mp\n\n    def _sha3_raw(msg, r_w, o_p, e_b):\n        \"\"\"Semi-generic SHA-3 implementation\"\"\"\n        r_b = 8 * r_w\n        s = [0] * 25\n        # Handle whole blocks.\n        idx = 0\n        blocks = len(msg) // r_b\n        for i in range(0, blocks):\n            _reinterpret_to_words_and_xor(s, msg[idx : idx + r_b])\n            idx += r_b\n            _sha3_transform(s)\n        # Handle last block padding.\n        m = bytearray(msg[idx:])\n        m.append(o_p)\n        while len(m) < r_b:\n            m.append(0)\n        m[len(m) - 1] |= 128\n        # Handle padded last block.\n        _reinterpret_to_words_and_xor(s, m)\n        _sha3_transform(s)\n        # Output.\n        out = bytearray()\n        while len(out) < e_b:\n            out += _reinterpret_to_octets(s[:r_w])\n            _sha3_transform(s)\n        return out[:e_b]\n\n    def shake_256(msg, outlen):\n        return _sha3_raw(msg, 17, 31, outlen)\n"
  },
  {
    "path": "code/default/lib/noarch/ecdsa/_version.py",
    "content": "\n# This file was generated by 'versioneer.py' (0.21) from\n# revision-control system data, or from the parent directory name of an\n# unpacked source archive. Distribution tarballs contain a pre-generated copy\n# of this file.\n\nimport json\n\nversion_json = '''\n{\n \"date\": \"2022-07-09T14:49:17+0200\",\n \"dirty\": false,\n \"error\": null,\n \"full-revisionid\": \"341e0d8be9fedf66fbc9a95630b4ed2138343380\",\n \"version\": \"0.18.0\"\n}\n'''  # END VERSION_JSON\n\n\ndef get_versions():\n    return json.loads(version_json)\n"
  },
  {
    "path": "code/default/lib/noarch/ecdsa/curves.py",
    "content": "from __future__ import division\n\nfrom six import PY2\nfrom . import der, ecdsa, ellipticcurve, eddsa\nfrom .util import orderlen, number_to_string, string_to_number\nfrom ._compat import normalise_bytes, bit_length\n\n\n# orderlen was defined in this module previously, so keep it in __all__,\n# will need to mark it as deprecated later\n__all__ = [\n    \"UnknownCurveError\",\n    \"orderlen\",\n    \"Curve\",\n    \"SECP112r1\",\n    \"SECP112r2\",\n    \"SECP128r1\",\n    \"SECP160r1\",\n    \"NIST192p\",\n    \"NIST224p\",\n    \"NIST256p\",\n    \"NIST384p\",\n    \"NIST521p\",\n    \"curves\",\n    \"find_curve\",\n    \"curve_by_name\",\n    \"SECP256k1\",\n    \"BRAINPOOLP160r1\",\n    \"BRAINPOOLP192r1\",\n    \"BRAINPOOLP224r1\",\n    \"BRAINPOOLP256r1\",\n    \"BRAINPOOLP320r1\",\n    \"BRAINPOOLP384r1\",\n    \"BRAINPOOLP512r1\",\n    \"PRIME_FIELD_OID\",\n    \"CHARACTERISTIC_TWO_FIELD_OID\",\n    \"Ed25519\",\n    \"Ed448\",\n]\n\n\nPRIME_FIELD_OID = (1, 2, 840, 10045, 1, 1)\nCHARACTERISTIC_TWO_FIELD_OID = (1, 2, 840, 10045, 1, 2)\n\n\nclass UnknownCurveError(Exception):\n    pass\n\n\nclass Curve:\n    def __init__(self, name, curve, generator, oid, openssl_name=None):\n        self.name = name\n        self.openssl_name = openssl_name  # maybe None\n        self.curve = curve\n        self.generator = generator\n        self.order = generator.order()\n        if isinstance(curve, ellipticcurve.CurveEdTw):\n            # EdDSA keys are special in that both private and public\n            # are the same size (as it's defined only with compressed points)\n\n            # +1 for the sign bit and then round up\n            self.baselen = (bit_length(curve.p()) + 1 + 7) // 8\n            self.verifying_key_length = self.baselen\n        else:\n            self.baselen = orderlen(self.order)\n            self.verifying_key_length = 2 * orderlen(curve.p())\n        self.signature_length = 2 * self.baselen\n        self.oid = oid\n        if oid:\n            self.encoded_oid = der.encode_oid(*oid)\n\n    def __eq__(self, other):\n        if isinstance(other, Curve):\n            return (\n                self.curve == other.curve and self.generator == other.generator\n            )\n        return NotImplemented\n\n    def __ne__(self, other):\n        return not self == other\n\n    def __repr__(self):\n        return self.name\n\n    def to_der(self, encoding=None, point_encoding=\"uncompressed\"):\n        \"\"\"Serialise the curve parameters to binary string.\n\n        :param str encoding: the format to save the curve parameters in.\n            Default is ``named_curve``, with fallback being the ``explicit``\n            if the OID is not set for the curve.\n        :param str point_encoding: the point encoding of the generator when\n            explicit curve encoding is used. Ignored for ``named_curve``\n            format.\n\n        :return: DER encoded ECParameters structure\n        :rtype: bytes\n        \"\"\"\n        if encoding is None:\n            if self.oid:\n                encoding = \"named_curve\"\n            else:\n                encoding = \"explicit\"\n\n        if encoding not in (\"named_curve\", \"explicit\"):\n            raise ValueError(\n                \"Only 'named_curve' and 'explicit' encodings supported\"\n            )\n\n        if encoding == \"named_curve\":\n            if not self.oid:\n                raise UnknownCurveError(\n                    \"Can't encode curve using named_curve encoding without \"\n                    \"associated curve OID\"\n                )\n            return der.encode_oid(*self.oid)\n        elif isinstance(self.curve, ellipticcurve.CurveEdTw):\n            assert encoding == \"explicit\"\n            raise UnknownCurveError(\n                \"Twisted Edwards curves don't support explicit encoding\"\n            )\n\n        # encode the ECParameters sequence\n        curve_p = self.curve.p()\n        version = der.encode_integer(1)\n        field_id = der.encode_sequence(\n            der.encode_oid(*PRIME_FIELD_OID), der.encode_integer(curve_p)\n        )\n        curve = der.encode_sequence(\n            der.encode_octet_string(\n                number_to_string(self.curve.a() % curve_p, curve_p)\n            ),\n            der.encode_octet_string(\n                number_to_string(self.curve.b() % curve_p, curve_p)\n            ),\n        )\n        base = der.encode_octet_string(self.generator.to_bytes(point_encoding))\n        order = der.encode_integer(self.generator.order())\n        seq_elements = [version, field_id, curve, base, order]\n        if self.curve.cofactor():\n            cofactor = der.encode_integer(self.curve.cofactor())\n            seq_elements.append(cofactor)\n\n        return der.encode_sequence(*seq_elements)\n\n    def to_pem(self, encoding=None, point_encoding=\"uncompressed\"):\n        \"\"\"\n        Serialise the curve parameters to the :term:`PEM` format.\n\n        :param str encoding: the format to save the curve parameters in.\n            Default is ``named_curve``, with fallback being the ``explicit``\n            if the OID is not set for the curve.\n        :param str point_encoding: the point encoding of the generator when\n            explicit curve encoding is used. Ignored for ``named_curve``\n            format.\n\n        :return: PEM encoded ECParameters structure\n        :rtype: str\n        \"\"\"\n        return der.topem(\n            self.to_der(encoding, point_encoding), \"EC PARAMETERS\"\n        )\n\n    @staticmethod\n    def from_der(data, valid_encodings=None):\n        \"\"\"Decode the curve parameters from DER file.\n\n        :param data: the binary string to decode the parameters from\n        :type data: :term:`bytes-like object`\n        :param valid_encodings: set of names of allowed encodings, by default\n            all (set by passing ``None``), supported ones are ``named_curve``\n            and ``explicit``\n        :type valid_encodings: :term:`set-like object`\n        \"\"\"\n        if not valid_encodings:\n            valid_encodings = set((\"named_curve\", \"explicit\"))\n        if not all(i in [\"named_curve\", \"explicit\"] for i in valid_encodings):\n            raise ValueError(\n                \"Only named_curve and explicit encodings supported\"\n            )\n        data = normalise_bytes(data)\n        if not der.is_sequence(data):\n            if \"named_curve\" not in valid_encodings:\n                raise der.UnexpectedDER(\n                    \"named_curve curve parameters not allowed\"\n                )\n            oid, empty = der.remove_object(data)\n            if empty:\n                raise der.UnexpectedDER(\"Unexpected data after OID\")\n            return find_curve(oid)\n\n        if \"explicit\" not in valid_encodings:\n            raise der.UnexpectedDER(\"explicit curve parameters not allowed\")\n\n        seq, empty = der.remove_sequence(data)\n        if empty:\n            raise der.UnexpectedDER(\n                \"Unexpected data after ECParameters structure\"\n            )\n        # decode the ECParameters sequence\n        version, rest = der.remove_integer(seq)\n        if version != 1:\n            raise der.UnexpectedDER(\"Unknown parameter encoding format\")\n        field_id, rest = der.remove_sequence(rest)\n        curve, rest = der.remove_sequence(rest)\n        base_bytes, rest = der.remove_octet_string(rest)\n        order, rest = der.remove_integer(rest)\n        cofactor = None\n        if rest:\n            # the ASN.1 specification of ECParameters allows for future\n            # extensions of the sequence, so ignore the remaining bytes\n            cofactor, _ = der.remove_integer(rest)\n\n        # decode the ECParameters.fieldID sequence\n        field_type, rest = der.remove_object(field_id)\n        if field_type == CHARACTERISTIC_TWO_FIELD_OID:\n            raise UnknownCurveError(\"Characteristic 2 curves unsupported\")\n        if field_type != PRIME_FIELD_OID:\n            raise UnknownCurveError(\n                \"Unknown field type: {0}\".format(field_type)\n            )\n        prime, empty = der.remove_integer(rest)\n        if empty:\n            raise der.UnexpectedDER(\n                \"Unexpected data after ECParameters.fieldID.Prime-p element\"\n            )\n\n        # decode the ECParameters.curve sequence\n        curve_a_bytes, rest = der.remove_octet_string(curve)\n        curve_b_bytes, rest = der.remove_octet_string(rest)\n        # seed can be defined here, but we don't parse it, so ignore `rest`\n\n        curve_a = string_to_number(curve_a_bytes)\n        curve_b = string_to_number(curve_b_bytes)\n\n        curve_fp = ellipticcurve.CurveFp(prime, curve_a, curve_b, cofactor)\n\n        # decode the ECParameters.base point\n\n        base = ellipticcurve.PointJacobi.from_bytes(\n            curve_fp,\n            base_bytes,\n            valid_encodings=(\"uncompressed\", \"compressed\", \"hybrid\"),\n            order=order,\n            generator=True,\n        )\n        tmp_curve = Curve(\"unknown\", curve_fp, base, None)\n\n        # if the curve matches one of the well-known ones, use the well-known\n        # one in preference, as it will have the OID and name associated\n        for i in curves:\n            if tmp_curve == i:\n                return i\n        return tmp_curve\n\n    @classmethod\n    def from_pem(cls, string, valid_encodings=None):\n        \"\"\"Decode the curve parameters from PEM file.\n\n        :param str string: the text string to decode the parameters from\n        :param valid_encodings: set of names of allowed encodings, by default\n            all (set by passing ``None``), supported ones are ``named_curve``\n            and ``explicit``\n        :type valid_encodings: :term:`set-like object`\n        \"\"\"\n        if not PY2 and isinstance(string, str):  # pragma: no branch\n            string = string.encode()\n\n        ec_param_index = string.find(b\"-----BEGIN EC PARAMETERS-----\")\n        if ec_param_index == -1:\n            raise der.UnexpectedDER(\"EC PARAMETERS PEM header not found\")\n\n        return cls.from_der(\n            der.unpem(string[ec_param_index:]), valid_encodings\n        )\n\n\n# the SEC curves\nSECP112r1 = Curve(\n    \"SECP112r1\",\n    ecdsa.curve_112r1,\n    ecdsa.generator_112r1,\n    (1, 3, 132, 0, 6),\n    \"secp112r1\",\n)\n\n\nSECP112r2 = Curve(\n    \"SECP112r2\",\n    ecdsa.curve_112r2,\n    ecdsa.generator_112r2,\n    (1, 3, 132, 0, 7),\n    \"secp112r2\",\n)\n\n\nSECP128r1 = Curve(\n    \"SECP128r1\",\n    ecdsa.curve_128r1,\n    ecdsa.generator_128r1,\n    (1, 3, 132, 0, 28),\n    \"secp128r1\",\n)\n\n\nSECP160r1 = Curve(\n    \"SECP160r1\",\n    ecdsa.curve_160r1,\n    ecdsa.generator_160r1,\n    (1, 3, 132, 0, 8),\n    \"secp160r1\",\n)\n\n\n# the NIST curves\nNIST192p = Curve(\n    \"NIST192p\",\n    ecdsa.curve_192,\n    ecdsa.generator_192,\n    (1, 2, 840, 10045, 3, 1, 1),\n    \"prime192v1\",\n)\n\n\nNIST224p = Curve(\n    \"NIST224p\",\n    ecdsa.curve_224,\n    ecdsa.generator_224,\n    (1, 3, 132, 0, 33),\n    \"secp224r1\",\n)\n\n\nNIST256p = Curve(\n    \"NIST256p\",\n    ecdsa.curve_256,\n    ecdsa.generator_256,\n    (1, 2, 840, 10045, 3, 1, 7),\n    \"prime256v1\",\n)\n\n\nNIST384p = Curve(\n    \"NIST384p\",\n    ecdsa.curve_384,\n    ecdsa.generator_384,\n    (1, 3, 132, 0, 34),\n    \"secp384r1\",\n)\n\n\nNIST521p = Curve(\n    \"NIST521p\",\n    ecdsa.curve_521,\n    ecdsa.generator_521,\n    (1, 3, 132, 0, 35),\n    \"secp521r1\",\n)\n\n\nSECP256k1 = Curve(\n    \"SECP256k1\",\n    ecdsa.curve_secp256k1,\n    ecdsa.generator_secp256k1,\n    (1, 3, 132, 0, 10),\n    \"secp256k1\",\n)\n\n\nBRAINPOOLP160r1 = Curve(\n    \"BRAINPOOLP160r1\",\n    ecdsa.curve_brainpoolp160r1,\n    ecdsa.generator_brainpoolp160r1,\n    (1, 3, 36, 3, 3, 2, 8, 1, 1, 1),\n    \"brainpoolP160r1\",\n)\n\n\nBRAINPOOLP192r1 = Curve(\n    \"BRAINPOOLP192r1\",\n    ecdsa.curve_brainpoolp192r1,\n    ecdsa.generator_brainpoolp192r1,\n    (1, 3, 36, 3, 3, 2, 8, 1, 1, 3),\n    \"brainpoolP192r1\",\n)\n\n\nBRAINPOOLP224r1 = Curve(\n    \"BRAINPOOLP224r1\",\n    ecdsa.curve_brainpoolp224r1,\n    ecdsa.generator_brainpoolp224r1,\n    (1, 3, 36, 3, 3, 2, 8, 1, 1, 5),\n    \"brainpoolP224r1\",\n)\n\n\nBRAINPOOLP256r1 = Curve(\n    \"BRAINPOOLP256r1\",\n    ecdsa.curve_brainpoolp256r1,\n    ecdsa.generator_brainpoolp256r1,\n    (1, 3, 36, 3, 3, 2, 8, 1, 1, 7),\n    \"brainpoolP256r1\",\n)\n\n\nBRAINPOOLP320r1 = Curve(\n    \"BRAINPOOLP320r1\",\n    ecdsa.curve_brainpoolp320r1,\n    ecdsa.generator_brainpoolp320r1,\n    (1, 3, 36, 3, 3, 2, 8, 1, 1, 9),\n    \"brainpoolP320r1\",\n)\n\n\nBRAINPOOLP384r1 = Curve(\n    \"BRAINPOOLP384r1\",\n    ecdsa.curve_brainpoolp384r1,\n    ecdsa.generator_brainpoolp384r1,\n    (1, 3, 36, 3, 3, 2, 8, 1, 1, 11),\n    \"brainpoolP384r1\",\n)\n\n\nBRAINPOOLP512r1 = Curve(\n    \"BRAINPOOLP512r1\",\n    ecdsa.curve_brainpoolp512r1,\n    ecdsa.generator_brainpoolp512r1,\n    (1, 3, 36, 3, 3, 2, 8, 1, 1, 13),\n    \"brainpoolP512r1\",\n)\n\n\nEd25519 = Curve(\n    \"Ed25519\",\n    eddsa.curve_ed25519,\n    eddsa.generator_ed25519,\n    (1, 3, 101, 112),\n)\n\n\nEd448 = Curve(\n    \"Ed448\",\n    eddsa.curve_ed448,\n    eddsa.generator_ed448,\n    (1, 3, 101, 113),\n)\n\n\n# no order in particular, but keep previously added curves first\ncurves = [\n    NIST192p,\n    NIST224p,\n    NIST256p,\n    NIST384p,\n    NIST521p,\n    SECP256k1,\n    BRAINPOOLP160r1,\n    BRAINPOOLP192r1,\n    BRAINPOOLP224r1,\n    BRAINPOOLP256r1,\n    BRAINPOOLP320r1,\n    BRAINPOOLP384r1,\n    BRAINPOOLP512r1,\n    SECP112r1,\n    SECP112r2,\n    SECP128r1,\n    SECP160r1,\n    Ed25519,\n    Ed448,\n]\n\n\ndef find_curve(oid_curve):\n    \"\"\"Select a curve based on its OID\n\n    :param tuple[int,...] oid_curve: ASN.1 Object Identifier of the\n        curve to return, like ``(1, 2, 840, 10045, 3, 1, 7)`` for ``NIST256p``.\n\n    :raises UnknownCurveError: When the oid doesn't match any of the supported\n        curves\n\n    :rtype: ~ecdsa.curves.Curve\n    \"\"\"\n    for c in curves:\n        if c.oid == oid_curve:\n            return c\n    raise UnknownCurveError(\n        \"I don't know about the curve with oid %s.\"\n        \"I only know about these: %s\" % (oid_curve, [c.name for c in curves])\n    )\n\n\ndef curve_by_name(name):\n    \"\"\"Select a curve based on its name.\n\n    Returns a :py:class:`~ecdsa.curves.Curve` object with a ``name`` name.\n    Note that ``name`` is case-sensitve.\n\n    :param str name: Name of the curve to return, like ``NIST256p`` or\n        ``prime256v1``\n\n    :raises UnknownCurveError: When the name doesn't match any of the supported\n        curves\n\n    :rtype: ~ecdsa.curves.Curve\n    \"\"\"\n    for c in curves:\n        if name == c.name or (c.openssl_name and name == c.openssl_name):\n            return c\n    raise UnknownCurveError(\n        \"Curve with name {0!r} unknown, only curves supported: {1}\".format(\n            name, [c.name for c in curves]\n        )\n    )\n"
  },
  {
    "path": "code/default/lib/noarch/ecdsa/der.py",
    "content": "from __future__ import division\n\nimport binascii\nimport base64\nimport warnings\nfrom itertools import chain\nfrom six import int2byte, b, text_type\nfrom ._compat import str_idx_as_int\n\n\nclass UnexpectedDER(Exception):\n    pass\n\n\ndef encode_constructed(tag, value):\n    return int2byte(0xA0 + tag) + encode_length(len(value)) + value\n\n\ndef encode_integer(r):\n    assert r >= 0  # can't support negative numbers yet\n    h = (\"%x\" % r).encode()\n    if len(h) % 2:\n        h = b(\"0\") + h\n    s = binascii.unhexlify(h)\n    num = str_idx_as_int(s, 0)\n    if num <= 0x7F:\n        return b(\"\\x02\") + encode_length(len(s)) + s\n    else:\n        # DER integers are two's complement, so if the first byte is\n        # 0x80-0xff then we need an extra 0x00 byte to prevent it from\n        # looking negative.\n        return b(\"\\x02\") + encode_length(len(s) + 1) + b(\"\\x00\") + s\n\n\n# sentry object to check if an argument was specified (used to detect\n# deprecated calling convention)\n_sentry = object()\n\n\ndef encode_bitstring(s, unused=_sentry):\n    \"\"\"\n    Encode a binary string as a BIT STRING using :term:`DER` encoding.\n\n    Note, because there is no native Python object that can encode an actual\n    bit string, this function only accepts byte strings as the `s` argument.\n    The byte string is the actual bit string that will be encoded, padded\n    on the right (least significant bits, looking from big endian perspective)\n    to the first full byte. If the bit string has a bit length that is multiple\n    of 8, then the padding should not be included. For correct DER encoding\n    the padding bits MUST be set to 0.\n\n    Number of bits of padding need to be provided as the `unused` parameter.\n    In case they are specified as None, it means the number of unused bits\n    is already encoded in the string as the first byte.\n\n    The deprecated call convention specifies just the `s` parameters and\n    encodes the number of unused bits as first parameter (same convention\n    as with None).\n\n    Empty string must be encoded with `unused` specified as 0.\n\n    Future version of python-ecdsa will make specifying the `unused` argument\n    mandatory.\n\n    :param s: bytes to encode\n    :type s: bytes like object\n    :param unused: number of bits at the end of `s` that are unused, must be\n        between 0 and 7 (inclusive)\n    :type unused: int or None\n\n    :raises ValueError: when `unused` is too large or too small\n\n    :return: `s` encoded using DER\n    :rtype: bytes\n    \"\"\"\n    encoded_unused = b\"\"\n    len_extra = 0\n    if unused is _sentry:\n        warnings.warn(\n            \"Legacy call convention used, unused= needs to be specified\",\n            DeprecationWarning,\n        )\n    elif unused is not None:\n        if not 0 <= unused <= 7:\n            raise ValueError(\"unused must be integer between 0 and 7\")\n        if unused:\n            if not s:\n                raise ValueError(\"unused is non-zero but s is empty\")\n            last = str_idx_as_int(s, -1)\n            if last & (2**unused - 1):\n                raise ValueError(\"unused bits must be zeros in DER\")\n        encoded_unused = int2byte(unused)\n        len_extra = 1\n    return b(\"\\x03\") + encode_length(len(s) + len_extra) + encoded_unused + s\n\n\ndef encode_octet_string(s):\n    return b(\"\\x04\") + encode_length(len(s)) + s\n\n\ndef encode_oid(first, second, *pieces):\n    assert 0 <= first < 2 and 0 <= second <= 39 or first == 2 and 0 <= second\n    body = b\"\".join(\n        chain(\n            [encode_number(40 * first + second)],\n            (encode_number(p) for p in pieces),\n        )\n    )\n    return b\"\\x06\" + encode_length(len(body)) + body\n\n\ndef encode_sequence(*encoded_pieces):\n    total_len = sum([len(p) for p in encoded_pieces])\n    return b(\"\\x30\") + encode_length(total_len) + b(\"\").join(encoded_pieces)\n\n\ndef encode_number(n):\n    b128_digits = []\n    while n:\n        b128_digits.insert(0, (n & 0x7F) | 0x80)\n        n = n >> 7\n    if not b128_digits:\n        b128_digits.append(0)\n    b128_digits[-1] &= 0x7F\n    return b(\"\").join([int2byte(d) for d in b128_digits])\n\n\ndef is_sequence(string):\n    return string and string[:1] == b\"\\x30\"\n\n\ndef remove_constructed(string):\n    s0 = str_idx_as_int(string, 0)\n    if (s0 & 0xE0) != 0xA0:\n        raise UnexpectedDER(\n            \"wanted type 'constructed tag' (0xa0-0xbf), got 0x%02x\" % s0\n        )\n    tag = s0 & 0x1F\n    length, llen = read_length(string[1:])\n    body = string[1 + llen : 1 + llen + length]\n    rest = string[1 + llen + length :]\n    return tag, body, rest\n\n\ndef remove_sequence(string):\n    if not string:\n        raise UnexpectedDER(\"Empty string does not encode a sequence\")\n    if string[:1] != b\"\\x30\":\n        n = str_idx_as_int(string, 0)\n        raise UnexpectedDER(\"wanted type 'sequence' (0x30), got 0x%02x\" % n)\n    length, lengthlength = read_length(string[1:])\n    if length > len(string) - 1 - lengthlength:\n        raise UnexpectedDER(\"Length longer than the provided buffer\")\n    endseq = 1 + lengthlength + length\n    return string[1 + lengthlength : endseq], string[endseq:]\n\n\ndef remove_octet_string(string):\n    if string[:1] != b\"\\x04\":\n        n = str_idx_as_int(string, 0)\n        raise UnexpectedDER(\"wanted type 'octetstring' (0x04), got 0x%02x\" % n)\n    length, llen = read_length(string[1:])\n    body = string[1 + llen : 1 + llen + length]\n    rest = string[1 + llen + length :]\n    return body, rest\n\n\ndef remove_object(string):\n    if not string:\n        raise UnexpectedDER(\n            \"Empty string does not encode an object identifier\"\n        )\n    if string[:1] != b\"\\x06\":\n        n = str_idx_as_int(string, 0)\n        raise UnexpectedDER(\"wanted type 'object' (0x06), got 0x%02x\" % n)\n    length, lengthlength = read_length(string[1:])\n    body = string[1 + lengthlength : 1 + lengthlength + length]\n    rest = string[1 + lengthlength + length :]\n    if not body:\n        raise UnexpectedDER(\"Empty object identifier\")\n    if len(body) != length:\n        raise UnexpectedDER(\n            \"Length of object identifier longer than the provided buffer\"\n        )\n    numbers = []\n    while body:\n        n, ll = read_number(body)\n        numbers.append(n)\n        body = body[ll:]\n    n0 = numbers.pop(0)\n    if n0 < 80:\n        first = n0 // 40\n    else:\n        first = 2\n    second = n0 - (40 * first)\n    numbers.insert(0, first)\n    numbers.insert(1, second)\n    return tuple(numbers), rest\n\n\ndef remove_integer(string):\n    if not string:\n        raise UnexpectedDER(\n            \"Empty string is an invalid encoding of an integer\"\n        )\n    if string[:1] != b\"\\x02\":\n        n = str_idx_as_int(string, 0)\n        raise UnexpectedDER(\"wanted type 'integer' (0x02), got 0x%02x\" % n)\n    length, llen = read_length(string[1:])\n    if length > len(string) - 1 - llen:\n        raise UnexpectedDER(\"Length longer than provided buffer\")\n    if length == 0:\n        raise UnexpectedDER(\"0-byte long encoding of integer\")\n    numberbytes = string[1 + llen : 1 + llen + length]\n    rest = string[1 + llen + length :]\n    msb = str_idx_as_int(numberbytes, 0)\n    if not msb < 0x80:\n        raise UnexpectedDER(\"Negative integers are not supported\")\n    # check if the encoding is the minimal one (DER requirement)\n    if length > 1 and not msb:\n        # leading zero byte is allowed if the integer would have been\n        # considered a negative number otherwise\n        smsb = str_idx_as_int(numberbytes, 1)\n        if smsb < 0x80:\n            raise UnexpectedDER(\n                \"Invalid encoding of integer, unnecessary \"\n                \"zero padding bytes\"\n            )\n    return int(binascii.hexlify(numberbytes), 16), rest\n\n\ndef read_number(string):\n    number = 0\n    llen = 0\n    if str_idx_as_int(string, 0) == 0x80:\n        raise UnexpectedDER(\"Non minimal encoding of OID subidentifier\")\n    # base-128 big endian, with most significant bit set in all but the last\n    # byte\n    while True:\n        if llen >= len(string):\n            raise UnexpectedDER(\"ran out of length bytes\")\n        number = number << 7\n        d = str_idx_as_int(string, llen)\n        number += d & 0x7F\n        llen += 1\n        if not d & 0x80:\n            break\n    return number, llen\n\n\ndef encode_length(l):\n    assert l >= 0\n    if l < 0x80:\n        return int2byte(l)\n    s = (\"%x\" % l).encode()\n    if len(s) % 2:\n        s = b(\"0\") + s\n    s = binascii.unhexlify(s)\n    llen = len(s)\n    return int2byte(0x80 | llen) + s\n\n\ndef read_length(string):\n    if not string:\n        raise UnexpectedDER(\"Empty string can't encode valid length value\")\n    num = str_idx_as_int(string, 0)\n    if not (num & 0x80):\n        # short form\n        return (num & 0x7F), 1\n    # else long-form: b0&0x7f is number of additional base256 length bytes,\n    # big-endian\n    llen = num & 0x7F\n    if not llen:\n        raise UnexpectedDER(\"Invalid length encoding, length of length is 0\")\n    if llen > len(string) - 1:\n        raise UnexpectedDER(\"Length of length longer than provided buffer\")\n    # verify that the encoding is minimal possible (DER requirement)\n    msb = str_idx_as_int(string, 1)\n    if not msb or llen == 1 and msb < 0x80:\n        raise UnexpectedDER(\"Not minimal encoding of length\")\n    return int(binascii.hexlify(string[1 : 1 + llen]), 16), 1 + llen\n\n\ndef remove_bitstring(string, expect_unused=_sentry):\n    \"\"\"\n    Remove a BIT STRING object from `string` following :term:`DER`.\n\n    The `expect_unused` can be used to specify if the bit string should\n    have the amount of unused bits decoded or not. If it's an integer, any\n    read BIT STRING that has number of unused bits different from specified\n    value will cause UnexpectedDER exception to be raised (this is especially\n    useful when decoding BIT STRINGS that have DER encoded object in them;\n    DER encoding is byte oriented, so the unused bits will always equal 0).\n\n    If the `expect_unused` is specified as None, the first element returned\n    will be a tuple, with the first value being the extracted bit string\n    while the second value will be the decoded number of unused bits.\n\n    If the `expect_unused` is unspecified, the decoding of byte with\n    number of unused bits will not be attempted and the bit string will be\n    returned as-is, the callee will be required to decode it and verify its\n    correctness.\n\n    Future version of python will require the `expected_unused` parameter\n    to be specified.\n\n    :param string: string of bytes to extract the BIT STRING from\n    :type string: bytes like object\n    :param expect_unused: number of bits that should be unused in the BIT\n        STRING, or None, to return it to caller\n    :type expect_unused: int or None\n\n    :raises UnexpectedDER: when the encoding does not follow DER.\n\n    :return: a tuple with first element being the extracted bit string and\n        the second being the remaining bytes in the string (if any); if the\n        `expect_unused` is specified as None, the first element of the returned\n        tuple will be a tuple itself, with first element being the bit string\n        as bytes and the second element being the number of unused bits at the\n        end of the byte array as an integer\n    :rtype: tuple\n    \"\"\"\n    if not string:\n        raise UnexpectedDER(\"Empty string does not encode a bitstring\")\n    if expect_unused is _sentry:\n        warnings.warn(\n            \"Legacy call convention used, expect_unused= needs to be\"\n            \" specified\",\n            DeprecationWarning,\n        )\n    num = str_idx_as_int(string, 0)\n    if string[:1] != b\"\\x03\":\n        raise UnexpectedDER(\"wanted bitstring (0x03), got 0x%02x\" % num)\n    length, llen = read_length(string[1:])\n    if not length:\n        raise UnexpectedDER(\"Invalid length of bit string, can't be 0\")\n    body = string[1 + llen : 1 + llen + length]\n    rest = string[1 + llen + length :]\n    if expect_unused is not _sentry:\n        unused = str_idx_as_int(body, 0)\n        if not 0 <= unused <= 7:\n            raise UnexpectedDER(\"Invalid encoding of unused bits\")\n        if expect_unused is not None and expect_unused != unused:\n            raise UnexpectedDER(\"Unexpected number of unused bits\")\n        body = body[1:]\n        if unused:\n            if not body:\n                raise UnexpectedDER(\"Invalid encoding of empty bit string\")\n            last = str_idx_as_int(body, -1)\n            # verify that all the unused bits are set to zero (DER requirement)\n            if last & (2**unused - 1):\n                raise UnexpectedDER(\"Non zero padding bits in bit string\")\n        if expect_unused is None:\n            body = (body, unused)\n    return body, rest\n\n\n# SEQUENCE([1, STRING(secexp), cont[0], OBJECT(curvename), cont[1], BINTSTRING)\n\n\n# signatures: (from RFC3279)\n#  ansi-X9-62  OBJECT IDENTIFIER ::= {\n#       iso(1) member-body(2) us(840) 10045 }\n#\n#  id-ecSigType OBJECT IDENTIFIER  ::=  {\n#       ansi-X9-62 signatures(4) }\n#  ecdsa-with-SHA1  OBJECT IDENTIFIER ::= {\n#       id-ecSigType 1 }\n# so 1,2,840,10045,4,1\n# so 0x42, .. ..\n\n#  Ecdsa-Sig-Value  ::=  SEQUENCE  {\n#       r     INTEGER,\n#       s     INTEGER  }\n\n# id-public-key-type OBJECT IDENTIFIER  ::= { ansi-X9.62 2 }\n#\n# id-ecPublicKey OBJECT IDENTIFIER ::= { id-publicKeyType 1 }\n\n# I think the secp224r1 identifier is (t=06,l=05,v=2b81040021)\n#  secp224r1 OBJECT IDENTIFIER ::= {\n#  iso(1) identified-organization(3) certicom(132) curve(0) 33 }\n# and the secp384r1 is (t=06,l=05,v=2b81040022)\n#  secp384r1 OBJECT IDENTIFIER ::= {\n#  iso(1) identified-organization(3) certicom(132) curve(0) 34 }\n\n\ndef unpem(pem):\n    if isinstance(pem, text_type):  # pragma: no branch\n        pem = pem.encode()\n\n    d = b(\"\").join(\n        [\n            l.strip()\n            for l in pem.split(b(\"\\n\"))\n            if l and not l.startswith(b(\"-----\"))\n        ]\n    )\n    return base64.b64decode(d)\n\n\ndef topem(der, name):\n    b64 = base64.b64encode(der)\n    lines = [(\"-----BEGIN %s-----\\n\" % name).encode()]\n    lines.extend(\n        [b64[start : start + 64] + b(\"\\n\") for start in range(0, len(b64), 64)]\n    )\n    lines.append((\"-----END %s-----\\n\" % name).encode())\n    return b(\"\").join(lines)\n"
  },
  {
    "path": "code/default/lib/noarch/ecdsa/ecdh.py",
    "content": "\"\"\"\nClass for performing Elliptic-curve Diffie-Hellman (ECDH) operations.\n\"\"\"\n\nfrom .util import number_to_string\nfrom .ellipticcurve import INFINITY\nfrom .keys import SigningKey, VerifyingKey\n\n\n__all__ = [\n    \"ECDH\",\n    \"NoKeyError\",\n    \"NoCurveError\",\n    \"InvalidCurveError\",\n    \"InvalidSharedSecretError\",\n]\n\n\nclass NoKeyError(Exception):\n    \"\"\"ECDH. Key not found but it is needed for operation.\"\"\"\n\n    pass\n\n\nclass NoCurveError(Exception):\n    \"\"\"ECDH. Curve not set but it is needed for operation.\"\"\"\n\n    pass\n\n\nclass InvalidCurveError(Exception):\n    \"\"\"\n    ECDH. Raised in case the public and private keys use different curves.\n    \"\"\"\n\n    pass\n\n\nclass InvalidSharedSecretError(Exception):\n    \"\"\"ECDH. Raised in case the shared secret we obtained is an INFINITY.\"\"\"\n\n    pass\n\n\nclass ECDH(object):\n    \"\"\"\n    Elliptic-curve Diffie-Hellman (ECDH). A key agreement protocol.\n\n    Allows two parties, each having an elliptic-curve public-private key\n    pair, to establish a shared secret over an insecure channel\n    \"\"\"\n\n    def __init__(self, curve=None, private_key=None, public_key=None):\n        \"\"\"\n        ECDH init.\n\n        Call can be initialised without parameters, then the first operation\n        (loading either key) will set the used curve.\n        All parameters must be ultimately set before shared secret\n        calculation will be allowed.\n\n        :param curve: curve for operations\n        :type curve: Curve\n        :param private_key: `my` private key for ECDH\n        :type private_key: SigningKey\n        :param public_key:  `their` public key for ECDH\n        :type public_key: VerifyingKey\n        \"\"\"\n        self.curve = curve\n        self.private_key = None\n        self.public_key = None\n        if private_key:\n            self.load_private_key(private_key)\n        if public_key:\n            self.load_received_public_key(public_key)\n\n    def _get_shared_secret(self, remote_public_key):\n        if not self.private_key:\n            raise NoKeyError(\n                \"Private key needs to be set to create shared secret\"\n            )\n        if not self.public_key:\n            raise NoKeyError(\n                \"Public key needs to be set to create shared secret\"\n            )\n        if not (\n            self.private_key.curve == self.curve == remote_public_key.curve\n        ):\n            raise InvalidCurveError(\n                \"Curves for public key and private key is not equal.\"\n            )\n\n        # shared secret = PUBKEYtheirs * PRIVATEKEYours\n        result = (\n            remote_public_key.pubkey.point\n            * self.private_key.privkey.secret_multiplier\n        )\n        if result == INFINITY:\n            raise InvalidSharedSecretError(\"Invalid shared secret (INFINITY).\")\n\n        return result.x()\n\n    def set_curve(self, key_curve):\n        \"\"\"\n        Set the working curve for ecdh operations.\n\n        :param key_curve: curve from `curves` module\n        :type key_curve: Curve\n        \"\"\"\n        self.curve = key_curve\n\n    def generate_private_key(self):\n        \"\"\"\n        Generate local private key for ecdh operation with curve that was set.\n\n        :raises NoCurveError: Curve must be set before key generation.\n\n        :return: public (verifying) key from this private key.\n        :rtype: VerifyingKey\n        \"\"\"\n        if not self.curve:\n            raise NoCurveError(\"Curve must be set prior to key generation.\")\n        return self.load_private_key(SigningKey.generate(curve=self.curve))\n\n    def load_private_key(self, private_key):\n        \"\"\"\n        Load private key from SigningKey (keys.py) object.\n\n        Needs to have the same curve as was set with set_curve method.\n        If curve is not set - it sets from this SigningKey\n\n        :param private_key: Initialised SigningKey class\n        :type private_key: SigningKey\n\n        :raises InvalidCurveError: private_key curve not the same as self.curve\n\n        :return: public (verifying) key from this private key.\n        :rtype: VerifyingKey\n        \"\"\"\n        if not self.curve:\n            self.curve = private_key.curve\n        if self.curve != private_key.curve:\n            raise InvalidCurveError(\"Curve mismatch.\")\n        self.private_key = private_key\n        return self.private_key.get_verifying_key()\n\n    def load_private_key_bytes(self, private_key):\n        \"\"\"\n        Load private key from byte string.\n\n        Uses current curve and checks if the provided key matches\n        the curve of ECDH key agreement.\n        Key loads via from_string method of SigningKey class\n\n        :param private_key: private key in bytes string format\n        :type private_key: :term:`bytes-like object`\n\n        :raises NoCurveError: Curve must be set before loading.\n\n        :return: public (verifying) key from this private key.\n        :rtype: VerifyingKey\n        \"\"\"\n        if not self.curve:\n            raise NoCurveError(\"Curve must be set prior to key load.\")\n        return self.load_private_key(\n            SigningKey.from_string(private_key, curve=self.curve)\n        )\n\n    def load_private_key_der(self, private_key_der):\n        \"\"\"\n        Load private key from DER byte string.\n\n        Compares the curve of the DER-encoded key with the ECDH set curve,\n        uses the former if unset.\n\n        Note, the only DER format supported is the RFC5915\n        Look at keys.py:SigningKey.from_der()\n\n        :param private_key_der: string with the DER encoding of private ECDSA\n            key\n        :type private_key_der: string\n\n        :raises InvalidCurveError: private_key curve not the same as self.curve\n\n        :return: public (verifying) key from this private key.\n        :rtype: VerifyingKey\n        \"\"\"\n        return self.load_private_key(SigningKey.from_der(private_key_der))\n\n    def load_private_key_pem(self, private_key_pem):\n        \"\"\"\n        Load private key from PEM string.\n\n        Compares the curve of the DER-encoded key with the ECDH set curve,\n        uses the former if unset.\n\n        Note, the only PEM format supported is the RFC5915\n        Look at keys.py:SigningKey.from_pem()\n        it needs to have `EC PRIVATE KEY` section\n\n        :param private_key_pem: string with PEM-encoded private ECDSA key\n        :type private_key_pem: string\n\n        :raises InvalidCurveError: private_key curve not the same as self.curve\n\n        :return: public (verifying) key from this private key.\n        :rtype: VerifyingKey\n        \"\"\"\n        return self.load_private_key(SigningKey.from_pem(private_key_pem))\n\n    def get_public_key(self):\n        \"\"\"\n        Provides a public key that matches the local private key.\n\n        Needs to be sent to the remote party.\n\n        :return: public (verifying) key from local private key.\n        :rtype: VerifyingKey\n        \"\"\"\n        return self.private_key.get_verifying_key()\n\n    def load_received_public_key(self, public_key):\n        \"\"\"\n        Load public key from VerifyingKey (keys.py) object.\n\n        Needs to have the same curve as set as current for ecdh operation.\n        If curve is not set - it sets it from VerifyingKey.\n\n        :param public_key: Initialised VerifyingKey class\n        :type public_key: VerifyingKey\n\n        :raises InvalidCurveError: public_key curve not the same as self.curve\n        \"\"\"\n        if not self.curve:\n            self.curve = public_key.curve\n        if self.curve != public_key.curve:\n            raise InvalidCurveError(\"Curve mismatch.\")\n        self.public_key = public_key\n\n    def load_received_public_key_bytes(\n        self, public_key_str, valid_encodings=None\n    ):\n        \"\"\"\n        Load public key from byte string.\n\n        Uses current curve and checks if key length corresponds to\n        the current curve.\n        Key loads via from_string method of VerifyingKey class\n\n        :param public_key_str: public key in bytes string format\n        :type public_key_str: :term:`bytes-like object`\n        :param valid_encodings: list of acceptable point encoding formats,\n            supported ones are: :term:`uncompressed`, :term:`compressed`,\n            :term:`hybrid`, and :term:`raw encoding` (specified with ``raw``\n            name). All formats by default (specified with ``None``).\n        :type valid_encodings: :term:`set-like object`\n        \"\"\"\n        return self.load_received_public_key(\n            VerifyingKey.from_string(\n                public_key_str, self.curve, valid_encodings\n            )\n        )\n\n    def load_received_public_key_der(self, public_key_der):\n        \"\"\"\n        Load public key from DER byte string.\n\n        Compares the curve of the DER-encoded key with the ECDH set curve,\n        uses the former if unset.\n\n        Note, the only DER format supported is the RFC5912\n        Look at keys.py:VerifyingKey.from_der()\n\n        :param public_key_der: string with the DER encoding of public ECDSA key\n        :type public_key_der: string\n\n        :raises InvalidCurveError: public_key curve not the same as self.curve\n        \"\"\"\n        return self.load_received_public_key(\n            VerifyingKey.from_der(public_key_der)\n        )\n\n    def load_received_public_key_pem(self, public_key_pem):\n        \"\"\"\n        Load public key from PEM string.\n\n        Compares the curve of the PEM-encoded key with the ECDH set curve,\n        uses the former if unset.\n\n        Note, the only PEM format supported is the RFC5912\n        Look at keys.py:VerifyingKey.from_pem()\n\n        :param public_key_pem: string with PEM-encoded public ECDSA key\n        :type public_key_pem: string\n\n        :raises InvalidCurveError: public_key curve not the same as self.curve\n        \"\"\"\n        return self.load_received_public_key(\n            VerifyingKey.from_pem(public_key_pem)\n        )\n\n    def generate_sharedsecret_bytes(self):\n        \"\"\"\n        Generate shared secret from local private key and remote public key.\n\n        The objects needs to have both private key and received public key\n        before generation is allowed.\n\n        :raises InvalidCurveError: public_key curve not the same as self.curve\n        :raises NoKeyError: public_key or private_key is not set\n\n        :return: shared secret\n        :rtype: bytes\n        \"\"\"\n        return number_to_string(\n            self.generate_sharedsecret(), self.private_key.curve.curve.p()\n        )\n\n    def generate_sharedsecret(self):\n        \"\"\"\n        Generate shared secret from local private key and remote public key.\n\n        The objects needs to have both private key and received public key\n        before generation is allowed.\n\n        It's the same for local and remote party,\n        shared secret(local private key, remote public key) ==\n        shared secret(local public key, remote private key)\n\n        :raises InvalidCurveError: public_key curve not the same as self.curve\n        :raises NoKeyError: public_key or private_key is not set\n\n        :return: shared secret\n        :rtype: int\n        \"\"\"\n        return self._get_shared_secret(self.public_key)\n"
  },
  {
    "path": "code/default/lib/noarch/ecdsa/ecdsa.py",
    "content": "#! /usr/bin/env python\n\n\"\"\"\nLow level implementation of Elliptic-Curve Digital Signatures.\n\n.. note ::\n    You're most likely looking for the :py:class:`~ecdsa.keys` module.\n    This is a low-level implementation of the ECDSA that operates on\n    integers, not byte strings.\n\nNOTE: This a low level implementation of ECDSA, for normal applications\nyou should be looking at the keys.py module.\n\nClasses and methods for elliptic-curve signatures:\nprivate keys, public keys, signatures,\nand definitions of prime-modulus curves.\n\nExample:\n\n.. code-block:: python\n\n   # (In real-life applications, you would probably want to\n   # protect against defects in SystemRandom.)\n   from random import SystemRandom\n   randrange = SystemRandom().randrange\n\n   # Generate a public/private key pair using the NIST Curve P-192:\n\n   g = generator_192\n   n = g.order()\n   secret = randrange( 1, n )\n   pubkey = Public_key( g, g * secret )\n   privkey = Private_key( pubkey, secret )\n\n   # Signing a hash value:\n\n   hash = randrange( 1, n )\n   signature = privkey.sign( hash, randrange( 1, n ) )\n\n   # Verifying a signature for a hash value:\n\n   if pubkey.verifies( hash, signature ):\n     print_(\"Demo verification succeeded.\")\n   else:\n     print_(\"*** Demo verification failed.\")\n\n   # Verification fails if the hash value is modified:\n\n   if pubkey.verifies( hash-1, signature ):\n     print_(\"**** Demo verification failed to reject tampered hash.\")\n   else:\n     print_(\"Demo verification correctly rejected tampered hash.\")\n\nRevision history:\n      2005.12.31 - Initial version.\n\n      2008.11.25 - Substantial revisions introducing new classes.\n\n      2009.05.16 - Warn against using random.randrange in real applications.\n\n      2009.05.17 - Use random.SystemRandom by default.\n\nOriginally written in 2005 by Peter Pearson and placed in the public domain,\nmodified as part of the python-ecdsa package.\n\"\"\"\n\nfrom six import int2byte, b\nfrom . import ellipticcurve\nfrom . import numbertheory\nfrom .util import bit_length\nfrom ._compat import remove_whitespace\n\n\nclass RSZeroError(RuntimeError):\n    pass\n\n\nclass InvalidPointError(RuntimeError):\n    pass\n\n\nclass Signature(object):\n    \"\"\"\n    ECDSA signature.\n\n    :ivar int r: the ``r`` element of the ECDSA signature\n    :ivar int s: the ``s`` element of the ECDSA signature\n    \"\"\"\n\n    def __init__(self, r, s):\n        self.r = r\n        self.s = s\n\n    def recover_public_keys(self, hash, generator):\n        \"\"\"\n        Returns two public keys for which the signature is valid\n\n        :param int hash: signed hash\n        :param AbstractPoint generator: is the generator used in creation\n            of the signature\n        :rtype: tuple(Public_key, Public_key)\n        :return: a pair of public keys that can validate the signature\n        \"\"\"\n        curve = generator.curve()\n        n = generator.order()\n        r = self.r\n        s = self.s\n        e = hash\n        x = r\n\n        # Compute the curve point with x as x-coordinate\n        alpha = (\n            pow(x, 3, curve.p()) + (curve.a() * x) + curve.b()\n        ) % curve.p()\n        beta = numbertheory.square_root_mod_prime(alpha, curve.p())\n        y = beta if beta % 2 == 0 else curve.p() - beta\n\n        # Compute the public key\n        R1 = ellipticcurve.PointJacobi(curve, x, y, 1, n)\n        Q1 = numbertheory.inverse_mod(r, n) * (s * R1 + (-e % n) * generator)\n        Pk1 = Public_key(generator, Q1)\n\n        # And the second solution\n        R2 = ellipticcurve.PointJacobi(curve, x, -y, 1, n)\n        Q2 = numbertheory.inverse_mod(r, n) * (s * R2 + (-e % n) * generator)\n        Pk2 = Public_key(generator, Q2)\n\n        return [Pk1, Pk2]\n\n\nclass Public_key(object):\n    \"\"\"Public key for ECDSA.\"\"\"\n\n    def __init__(self, generator, point, verify=True):\n        \"\"\"Low level ECDSA public key object.\n\n        :param generator: the Point that generates the group (the base point)\n        :param point: the Point that defines the public key\n        :param bool verify: if True check if point is valid point on curve\n\n        :raises InvalidPointError: if the point parameters are invalid or\n            point does not lay on the curve\n        \"\"\"\n\n        self.curve = generator.curve()\n        self.generator = generator\n        self.point = point\n        n = generator.order()\n        p = self.curve.p()\n        if not (0 <= point.x() < p) or not (0 <= point.y() < p):\n            raise InvalidPointError(\n                \"The public point has x or y out of range.\"\n            )\n        if verify and not self.curve.contains_point(point.x(), point.y()):\n            raise InvalidPointError(\"Point does not lay on the curve\")\n        if not n:\n            raise InvalidPointError(\"Generator point must have order.\")\n        # for curve parameters with base point with cofactor 1, all points\n        # that are on the curve are scalar multiples of the base point, so\n        # verifying that is not necessary. See Section 3.2.2.1 of SEC 1 v2\n        if (\n            verify\n            and self.curve.cofactor() != 1\n            and not n * point == ellipticcurve.INFINITY\n        ):\n            raise InvalidPointError(\"Generator point order is bad.\")\n\n    def __eq__(self, other):\n        \"\"\"Return True if the keys are identical, False otherwise.\n\n        Note: for comparison, only placement on the same curve and point\n        equality is considered, use of the same generator point is not\n        considered.\n        \"\"\"\n        if isinstance(other, Public_key):\n            return self.curve == other.curve and self.point == other.point\n        return NotImplemented\n\n    def __ne__(self, other):\n        \"\"\"Return False if the keys are identical, True otherwise.\"\"\"\n        return not self == other\n\n    def verifies(self, hash, signature):\n        \"\"\"Verify that signature is a valid signature of hash.\n        Return True if the signature is valid.\n        \"\"\"\n\n        # From X9.62 J.3.1.\n\n        G = self.generator\n        n = G.order()\n        r = signature.r\n        s = signature.s\n        if r < 1 or r > n - 1:\n            return False\n        if s < 1 or s > n - 1:\n            return False\n        c = numbertheory.inverse_mod(s, n)\n        u1 = (hash * c) % n\n        u2 = (r * c) % n\n        if hasattr(G, \"mul_add\"):\n            xy = G.mul_add(u1, self.point, u2)\n        else:\n            xy = u1 * G + u2 * self.point\n        v = xy.x() % n\n        return v == r\n\n\nclass Private_key(object):\n    \"\"\"Private key for ECDSA.\"\"\"\n\n    def __init__(self, public_key, secret_multiplier):\n        \"\"\"public_key is of class Public_key;\n        secret_multiplier is a large integer.\n        \"\"\"\n\n        self.public_key = public_key\n        self.secret_multiplier = secret_multiplier\n\n    def __eq__(self, other):\n        \"\"\"Return True if the points are identical, False otherwise.\"\"\"\n        if isinstance(other, Private_key):\n            return (\n                self.public_key == other.public_key\n                and self.secret_multiplier == other.secret_multiplier\n            )\n        return NotImplemented\n\n    def __ne__(self, other):\n        \"\"\"Return False if the points are identical, True otherwise.\"\"\"\n        return not self == other\n\n    def sign(self, hash, random_k):\n        \"\"\"Return a signature for the provided hash, using the provided\n        random nonce.  It is absolutely vital that random_k be an unpredictable\n        number in the range [1, self.public_key.point.order()-1].  If\n        an attacker can guess random_k, he can compute our private key from a\n        single signature.  Also, if an attacker knows a few high-order\n        bits (or a few low-order bits) of random_k, he can compute our private\n        key from many signatures.  The generation of nonces with adequate\n        cryptographic strength is very difficult and far beyond the scope\n        of this comment.\n\n        May raise RuntimeError, in which case retrying with a new\n        random value k is in order.\n        \"\"\"\n\n        G = self.public_key.generator\n        n = G.order()\n        k = random_k % n\n        # Fix the bit-length of the random nonce,\n        # so that it doesn't leak via timing.\n        # This does not change that ks = k mod n\n        ks = k + n\n        kt = ks + n\n        if bit_length(ks) == bit_length(n):\n            p1 = kt * G\n        else:\n            p1 = ks * G\n        r = p1.x() % n\n        if r == 0:\n            raise RSZeroError(\"amazingly unlucky random number r\")\n        s = (\n            numbertheory.inverse_mod(k, n)\n            * (hash + (self.secret_multiplier * r) % n)\n        ) % n\n        if s == 0:\n            raise RSZeroError(\"amazingly unlucky random number s\")\n        return Signature(r, s)\n\n\ndef int_to_string(x):\n    \"\"\"Convert integer x into a string of bytes, as per X9.62.\"\"\"\n    assert x >= 0\n    if x == 0:\n        return b(\"\\0\")\n    result = []\n    while x:\n        ordinal = x & 0xFF\n        result.append(int2byte(ordinal))\n        x >>= 8\n\n    result.reverse()\n    return b(\"\").join(result)\n\n\ndef string_to_int(s):\n    \"\"\"Convert a string of bytes into an integer, as per X9.62.\"\"\"\n    result = 0\n    for c in s:\n        if not isinstance(c, int):\n            c = ord(c)\n        result = 256 * result + c\n    return result\n\n\ndef digest_integer(m):\n    \"\"\"Convert an integer into a string of bytes, compute\n    its SHA-1 hash, and convert the result to an integer.\"\"\"\n    #\n    # I don't expect this function to be used much. I wrote\n    # it in order to be able to duplicate the examples\n    # in ECDSAVS.\n    #\n    from hashlib import sha1\n\n    return string_to_int(sha1(int_to_string(m)).digest())\n\n\ndef point_is_valid(generator, x, y):\n    \"\"\"Is (x,y) a valid public key based on the specified generator?\"\"\"\n\n    # These are the tests specified in X9.62.\n\n    n = generator.order()\n    curve = generator.curve()\n    p = curve.p()\n    if not (0 <= x < p) or not (0 <= y < p):\n        return False\n    if not curve.contains_point(x, y):\n        return False\n    if (\n        curve.cofactor() != 1\n        and not n * ellipticcurve.PointJacobi(curve, x, y, 1)\n        == ellipticcurve.INFINITY\n    ):\n        return False\n    return True\n\n\n# secp112r1 curve\n_p = int(remove_whitespace(\"DB7C 2ABF62E3 5E668076 BEAD208B\"), 16)\n# s = 00F50B02 8E4D696E 67687561 51752904 72783FB1\n_a = int(remove_whitespace(\"DB7C 2ABF62E3 5E668076 BEAD2088\"), 16)\n_b = int(remove_whitespace(\"659E F8BA0439 16EEDE89 11702B22\"), 16)\n_Gx = int(remove_whitespace(\"09487239 995A5EE7 6B55F9C2 F098\"), 16)\n_Gy = int(remove_whitespace(\"A89C E5AF8724 C0A23E0E 0FF77500\"), 16)\n_r = int(remove_whitespace(\"DB7C 2ABF62E3 5E7628DF AC6561C5\"), 16)\n_h = 1\ncurve_112r1 = ellipticcurve.CurveFp(_p, _a, _b, _h)\ngenerator_112r1 = ellipticcurve.PointJacobi(\n    curve_112r1, _Gx, _Gy, 1, _r, generator=True\n)\n\n\n# secp112r2 curve\n_p = int(remove_whitespace(\"DB7C 2ABF62E3 5E668076 BEAD208B\"), 16)\n# s = 022757A1 114D69E 67687561 51755316 C05E0BD4\n_a = int(remove_whitespace(\"6127 C24C05F3 8A0AAAF6 5C0EF02C\"), 16)\n_b = int(remove_whitespace(\"51DE F1815DB5 ED74FCC3 4C85D709\"), 16)\n_Gx = int(remove_whitespace(\"4BA30AB5 E892B4E1 649DD092 8643\"), 16)\n_Gy = int(remove_whitespace(\"ADCD 46F5882E 3747DEF3 6E956E97\"), 16)\n_r = int(remove_whitespace(\"36DF 0AAFD8B8 D7597CA1 0520D04B\"), 16)\n_h = 4\ncurve_112r2 = ellipticcurve.CurveFp(_p, _a, _b, _h)\ngenerator_112r2 = ellipticcurve.PointJacobi(\n    curve_112r2, _Gx, _Gy, 1, _r, generator=True\n)\n\n\n# secp128r1 curve\n_p = int(remove_whitespace(\"FFFFFFFD FFFFFFFF FFFFFFFF FFFFFFFF\"), 16)\n# S = 000E0D4D 69E6768 75615175 0CC03A44 73D03679\n# a and b are mod p, so a is equal to p-3, or simply -3\n# _a = -3\n_b = int(remove_whitespace(\"E87579C1 1079F43D D824993C 2CEE5ED3\"), 16)\n_Gx = int(remove_whitespace(\"161FF752 8B899B2D 0C28607C A52C5B86\"), 16)\n_Gy = int(remove_whitespace(\"CF5AC839 5BAFEB13 C02DA292 DDED7A83\"), 16)\n_r = int(remove_whitespace(\"FFFFFFFE 00000000 75A30D1B 9038A115\"), 16)\n_h = 1\ncurve_128r1 = ellipticcurve.CurveFp(_p, -3, _b, _h)\ngenerator_128r1 = ellipticcurve.PointJacobi(\n    curve_128r1, _Gx, _Gy, 1, _r, generator=True\n)\n\n\n# secp160r1\n_p = int(remove_whitespace(\"FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 7FFFFFFF\"), 16)\n# S = 1053CDE4 2C14D696 E6768756 1517533B F3F83345\n# a and b are mod p, so a is equal to p-3, or simply -3\n# _a = -3\n_b = int(remove_whitespace(\"1C97BEFC 54BD7A8B 65ACF89F 81D4D4AD C565FA45\"), 16)\n_Gx = int(\n    remove_whitespace(\"4A96B568 8EF57328 46646989 68C38BB9 13CBFC82\"),\n    16,\n)\n_Gy = int(\n    remove_whitespace(\"23A62855 3168947D 59DCC912 04235137 7AC5FB32\"),\n    16,\n)\n_r = int(\n    remove_whitespace(\"01 00000000 00000000 0001F4C8 F927AED3 CA752257\"),\n    16,\n)\n_h = 1\ncurve_160r1 = ellipticcurve.CurveFp(_p, -3, _b, _h)\ngenerator_160r1 = ellipticcurve.PointJacobi(\n    curve_160r1, _Gx, _Gy, 1, _r, generator=True\n)\n\n\n# NIST Curve P-192:\n_p = 6277101735386680763835789423207666416083908700390324961279\n_r = 6277101735386680763835789423176059013767194773182842284081\n# s = 0x3045ae6fc8422f64ed579528d38120eae12196d5L\n# c = 0x3099d2bbbfcb2538542dcd5fb078b6ef5f3d6fe2c745de65L\n_b = int(\n    remove_whitespace(\n        \"\"\"\n    64210519 E59C80E7 0FA7E9AB 72243049 FEB8DEEC C146B9B1\"\"\"\n    ),\n    16,\n)\n_Gx = int(\n    remove_whitespace(\n        \"\"\"\n    188DA80E B03090F6 7CBF20EB 43A18800 F4FF0AFD 82FF1012\"\"\"\n    ),\n    16,\n)\n_Gy = int(\n    remove_whitespace(\n        \"\"\"\n    07192B95 FFC8DA78 631011ED 6B24CDD5 73F977A1 1E794811\"\"\"\n    ),\n    16,\n)\n\ncurve_192 = ellipticcurve.CurveFp(_p, -3, _b, 1)\ngenerator_192 = ellipticcurve.PointJacobi(\n    curve_192, _Gx, _Gy, 1, _r, generator=True\n)\n\n\n# NIST Curve P-224:\n_p = int(\n    remove_whitespace(\n        \"\"\"\n    2695994666715063979466701508701963067355791626002630814351\n    0066298881\"\"\"\n    )\n)\n_r = int(\n    remove_whitespace(\n        \"\"\"\n    2695994666715063979466701508701962594045780771442439172168\n    2722368061\"\"\"\n    )\n)\n# s = 0xbd71344799d5c7fcdc45b59fa3b9ab8f6a948bc5L\n# c = 0x5b056c7e11dd68f40469ee7f3c7a7d74f7d121116506d031218291fbL\n_b = int(\n    remove_whitespace(\n        \"\"\"\n    B4050A85 0C04B3AB F5413256 5044B0B7 D7BFD8BA 270B3943\n    2355FFB4\"\"\"\n    ),\n    16,\n)\n_Gx = int(\n    remove_whitespace(\n        \"\"\"\n    B70E0CBD 6BB4BF7F 321390B9 4A03C1D3 56C21122 343280D6\n    115C1D21\"\"\"\n    ),\n    16,\n)\n_Gy = int(\n    remove_whitespace(\n        \"\"\"\n    BD376388 B5F723FB 4C22DFE6 CD4375A0 5A074764 44D58199\n    85007E34\"\"\"\n    ),\n    16,\n)\n\ncurve_224 = ellipticcurve.CurveFp(_p, -3, _b, 1)\ngenerator_224 = ellipticcurve.PointJacobi(\n    curve_224, _Gx, _Gy, 1, _r, generator=True\n)\n\n# NIST Curve P-256:\n_p = int(\n    remove_whitespace(\n        \"\"\"\n    1157920892103562487626974469494075735300861434152903141955\n    33631308867097853951\"\"\"\n    )\n)\n_r = int(\n    remove_whitespace(\n        \"\"\"\n    115792089210356248762697446949407573529996955224135760342\n    422259061068512044369\"\"\"\n    )\n)\n# s = 0xc49d360886e704936a6678e1139d26b7819f7e90L\n# c = 0x7efba1662985be9403cb055c75d4f7e0ce8d84a9c5114abcaf3177680104fa0dL\n_b = int(\n    remove_whitespace(\n        \"\"\"\n    5AC635D8 AA3A93E7 B3EBBD55 769886BC 651D06B0 CC53B0F6\n    3BCE3C3E 27D2604B\"\"\"\n    ),\n    16,\n)\n_Gx = int(\n    remove_whitespace(\n        \"\"\"\n    6B17D1F2 E12C4247 F8BCE6E5 63A440F2 77037D81 2DEB33A0\n    F4A13945 D898C296\"\"\"\n    ),\n    16,\n)\n_Gy = int(\n    remove_whitespace(\n        \"\"\"\n    4FE342E2 FE1A7F9B 8EE7EB4A 7C0F9E16 2BCE3357 6B315ECE\n    CBB64068 37BF51F5\"\"\"\n    ),\n    16,\n)\n\ncurve_256 = ellipticcurve.CurveFp(_p, -3, _b, 1)\ngenerator_256 = ellipticcurve.PointJacobi(\n    curve_256, _Gx, _Gy, 1, _r, generator=True\n)\n\n# NIST Curve P-384:\n_p = int(\n    remove_whitespace(\n        \"\"\"\n    3940200619639447921227904010014361380507973927046544666794\n    8293404245721771496870329047266088258938001861606973112319\"\"\"\n    )\n)\n_r = int(\n    remove_whitespace(\n        \"\"\"\n    3940200619639447921227904010014361380507973927046544666794\n    6905279627659399113263569398956308152294913554433653942643\"\"\"\n    )\n)\n# s = 0xa335926aa319a27a1d00896a6773a4827acdac73L\n# c = int(remove_whitespace(\n#    \"\"\"\n#    79d1e655 f868f02f ff48dcde e14151dd b80643c1 406d0ca1\n#    0dfe6fc5 2009540a 495e8042 ea5f744f 6e184667 cc722483\"\"\"\n# ), 16)\n_b = int(\n    remove_whitespace(\n        \"\"\"\n    B3312FA7 E23EE7E4 988E056B E3F82D19 181D9C6E FE814112\n    0314088F 5013875A C656398D 8A2ED19D 2A85C8ED D3EC2AEF\"\"\"\n    ),\n    16,\n)\n_Gx = int(\n    remove_whitespace(\n        \"\"\"\n    AA87CA22 BE8B0537 8EB1C71E F320AD74 6E1D3B62 8BA79B98\n    59F741E0 82542A38 5502F25D BF55296C 3A545E38 72760AB7\"\"\"\n    ),\n    16,\n)\n_Gy = int(\n    remove_whitespace(\n        \"\"\"\n    3617DE4A 96262C6F 5D9E98BF 9292DC29 F8F41DBD 289A147C\n    E9DA3113 B5F0B8C0 0A60B1CE 1D7E819D 7A431D7C 90EA0E5F\"\"\"\n    ),\n    16,\n)\n\ncurve_384 = ellipticcurve.CurveFp(_p, -3, _b, 1)\ngenerator_384 = ellipticcurve.PointJacobi(\n    curve_384, _Gx, _Gy, 1, _r, generator=True\n)\n\n# NIST Curve P-521:\n_p = int(\n    \"686479766013060971498190079908139321726943530014330540939\"\n    \"446345918554318339765605212255964066145455497729631139148\"\n    \"0858037121987999716643812574028291115057151\"\n)\n_r = int(\n    \"686479766013060971498190079908139321726943530014330540939\"\n    \"446345918554318339765539424505774633321719753296399637136\"\n    \"3321113864768612440380340372808892707005449\"\n)\n# s = 0xd09e8800291cb85396cc6717393284aaa0da64baL\n# c = int(remove_whitespace(\n#    \"\"\"\n#         0b4 8bfa5f42 0a349495 39d2bdfc 264eeeeb 077688e4\n#    4fbf0ad8 f6d0edb3 7bd6b533 28100051 8e19f1b9 ffbe0fe9\n#    ed8a3c22 00b8f875 e523868c 70c1e5bf 55bad637\"\"\"\n# ), 16)\n_b = int(\n    remove_whitespace(\n        \"\"\"\n         051 953EB961 8E1C9A1F 929A21A0 B68540EE A2DA725B\n    99B315F3 B8B48991 8EF109E1 56193951 EC7E937B 1652C0BD\n    3BB1BF07 3573DF88 3D2C34F1 EF451FD4 6B503F00\"\"\"\n    ),\n    16,\n)\n_Gx = int(\n    remove_whitespace(\n        \"\"\"\n          C6 858E06B7 0404E9CD 9E3ECB66 2395B442 9C648139\n    053FB521 F828AF60 6B4D3DBA A14B5E77 EFE75928 FE1DC127\n    A2FFA8DE 3348B3C1 856A429B F97E7E31 C2E5BD66\"\"\"\n    ),\n    16,\n)\n_Gy = int(\n    remove_whitespace(\n        \"\"\"\n         118 39296A78 9A3BC004 5C8A5FB4 2C7D1BD9 98F54449\n    579B4468 17AFBD17 273E662C 97EE7299 5EF42640 C550B901\n    3FAD0761 353C7086 A272C240 88BE9476 9FD16650\"\"\"\n    ),\n    16,\n)\n\ncurve_521 = ellipticcurve.CurveFp(_p, -3, _b, 1)\ngenerator_521 = ellipticcurve.PointJacobi(\n    curve_521, _Gx, _Gy, 1, _r, generator=True\n)\n\n# Certicom secp256-k1\n_a = 0x0000000000000000000000000000000000000000000000000000000000000000\n_b = 0x0000000000000000000000000000000000000000000000000000000000000007\n_p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F\n_Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798\n_Gy = 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8\n_r = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141\n\ncurve_secp256k1 = ellipticcurve.CurveFp(_p, _a, _b, 1)\ngenerator_secp256k1 = ellipticcurve.PointJacobi(\n    curve_secp256k1, _Gx, _Gy, 1, _r, generator=True\n)\n\n# Brainpool P-160-r1\n_a = 0x340E7BE2A280EB74E2BE61BADA745D97E8F7C300\n_b = 0x1E589A8595423412134FAA2DBDEC95C8D8675E58\n_p = 0xE95E4A5F737059DC60DFC7AD95B3D8139515620F\n_Gx = 0xBED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3\n_Gy = 0x1667CB477A1A8EC338F94741669C976316DA6321\n_q = 0xE95E4A5F737059DC60DF5991D45029409E60FC09\n\ncurve_brainpoolp160r1 = ellipticcurve.CurveFp(_p, _a, _b, 1)\ngenerator_brainpoolp160r1 = ellipticcurve.PointJacobi(\n    curve_brainpoolp160r1, _Gx, _Gy, 1, _q, generator=True\n)\n\n# Brainpool P-192-r1\n_a = 0x6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF\n_b = 0x469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9\n_p = 0xC302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297\n_Gx = 0xC0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6\n_Gy = 0x14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F\n_q = 0xC302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1\n\ncurve_brainpoolp192r1 = ellipticcurve.CurveFp(_p, _a, _b, 1)\ngenerator_brainpoolp192r1 = ellipticcurve.PointJacobi(\n    curve_brainpoolp192r1, _Gx, _Gy, 1, _q, generator=True\n)\n\n# Brainpool P-224-r1\n_a = 0x68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43\n_b = 0x2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B\n_p = 0xD7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF\n_Gx = 0x0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D\n_Gy = 0x58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD\n_q = 0xD7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F\n\ncurve_brainpoolp224r1 = ellipticcurve.CurveFp(_p, _a, _b, 1)\ngenerator_brainpoolp224r1 = ellipticcurve.PointJacobi(\n    curve_brainpoolp224r1, _Gx, _Gy, 1, _q, generator=True\n)\n\n# Brainpool P-256-r1\n_a = 0x7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9\n_b = 0x26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6\n_p = 0xA9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377\n_Gx = 0x8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262\n_Gy = 0x547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997\n_q = 0xA9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7\n\ncurve_brainpoolp256r1 = ellipticcurve.CurveFp(_p, _a, _b, 1)\ngenerator_brainpoolp256r1 = ellipticcurve.PointJacobi(\n    curve_brainpoolp256r1, _Gx, _Gy, 1, _q, generator=True\n)\n\n# Brainpool P-320-r1\n_a = int(\n    remove_whitespace(\n        \"\"\"\n    3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9\n    F492F375A97D860EB4\"\"\"\n    ),\n    16,\n)\n_b = int(\n    remove_whitespace(\n        \"\"\"\n    520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539\n    816F5EB4AC8FB1F1A6\"\"\"\n    ),\n    16,\n)\n_p = int(\n    remove_whitespace(\n        \"\"\"\n    D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC\n    28FCD412B1F1B32E27\"\"\"\n    ),\n    16,\n)\n_Gx = int(\n    remove_whitespace(\n        \"\"\"\n    43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599\n    C710AF8D0D39E20611\"\"\"\n    ),\n    16,\n)\n_Gy = int(\n    remove_whitespace(\n        \"\"\"\n    14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6A\n    C7D35245D1692E8EE1\"\"\"\n    ),\n    16,\n)\n_q = int(\n    remove_whitespace(\n        \"\"\"\n    D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658\n    E98691555B44C59311\"\"\"\n    ),\n    16,\n)\n\ncurve_brainpoolp320r1 = ellipticcurve.CurveFp(_p, _a, _b, 1)\ngenerator_brainpoolp320r1 = ellipticcurve.PointJacobi(\n    curve_brainpoolp320r1, _Gx, _Gy, 1, _q, generator=True\n)\n\n# Brainpool P-384-r1\n_a = int(\n    remove_whitespace(\n        \"\"\"\n    7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F9\n    0F8AA5814A503AD4EB04A8C7DD22CE2826\"\"\"\n    ),\n    16,\n)\n_b = int(\n    remove_whitespace(\n        \"\"\"\n    04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62\n    D57CB4390295DBC9943AB78696FA504C11\"\"\"\n    ),\n    16,\n)\n_p = int(\n    remove_whitespace(\n        \"\"\"\n    8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB711\n    23ACD3A729901D1A71874700133107EC53\"\"\"\n    ),\n    16,\n)\n_Gx = int(\n    remove_whitespace(\n        \"\"\"\n    1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10\n    E8E826E03436D646AAEF87B2E247D4AF1E\"\"\"\n    ),\n    16,\n)\n_Gy = int(\n    remove_whitespace(\n        \"\"\"\n    8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF991292\n    80E4646217791811142820341263C5315\"\"\"\n    ),\n    16,\n)\n_q = int(\n    remove_whitespace(\n        \"\"\"\n    8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425\n    A7CF3AB6AF6B7FC3103B883202E9046565\"\"\"\n    ),\n    16,\n)\n\ncurve_brainpoolp384r1 = ellipticcurve.CurveFp(_p, _a, _b, 1)\ngenerator_brainpoolp384r1 = ellipticcurve.PointJacobi(\n    curve_brainpoolp384r1, _Gx, _Gy, 1, _q, generator=True\n)\n\n# Brainpool P-512-r1\n_a = int(\n    remove_whitespace(\n        \"\"\"\n    7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863\n    BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA\"\"\"\n    ),\n    16,\n)\n_b = int(\n    remove_whitespace(\n        \"\"\"\n    3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117\n    A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723\"\"\"\n    ),\n    16,\n)\n_p = int(\n    remove_whitespace(\n        \"\"\"\n    AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308\n    717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3\"\"\"\n    ),\n    16,\n)\n_Gx = int(\n    remove_whitespace(\n        \"\"\"\n    81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D009\n    8EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822\"\"\"\n    ),\n    16,\n)\n_Gy = int(\n    remove_whitespace(\n        \"\"\"\n    7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F81\n    11B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892\"\"\"\n    ),\n    16,\n)\n_q = int(\n    remove_whitespace(\n        \"\"\"\n    AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308\n    70553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069\"\"\"\n    ),\n    16,\n)\n\ncurve_brainpoolp512r1 = ellipticcurve.CurveFp(_p, _a, _b, 1)\ngenerator_brainpoolp512r1 = ellipticcurve.PointJacobi(\n    curve_brainpoolp512r1, _Gx, _Gy, 1, _q, generator=True\n)\n"
  },
  {
    "path": "code/default/lib/noarch/ecdsa/eddsa.py",
    "content": "\"\"\"Implementation of Edwards Digital Signature Algorithm.\"\"\"\n\nimport hashlib\nfrom ._sha3 import shake_256\nfrom . import ellipticcurve\nfrom ._compat import (\n    remove_whitespace,\n    bit_length,\n    bytes_to_int,\n    int_to_bytes,\n    compat26_str,\n)\n\n# edwards25519, defined in RFC7748\n_p = 2**255 - 19\n_a = -1\n_d = int(\n    remove_whitespace(\n        \"370957059346694393431380835087545651895421138798432190163887855330\"\n        \"85940283555\"\n    )\n)\n_h = 8\n\n_Gx = int(\n    remove_whitespace(\n        \"151122213495354007725011514095885315114540126930418572060461132\"\n        \"83949847762202\"\n    )\n)\n_Gy = int(\n    remove_whitespace(\n        \"463168356949264781694283940034751631413079938662562256157830336\"\n        \"03165251855960\"\n    )\n)\n_r = 2**252 + 0x14DEF9DEA2F79CD65812631A5CF5D3ED\n\n\ndef _sha512(data):\n    return hashlib.new(\"sha512\", compat26_str(data)).digest()\n\n\ncurve_ed25519 = ellipticcurve.CurveEdTw(_p, _a, _d, _h, _sha512)\ngenerator_ed25519 = ellipticcurve.PointEdwards(\n    curve_ed25519, _Gx, _Gy, 1, _Gx * _Gy % _p, _r, generator=True\n)\n\n\n# edwards448, defined in RFC7748\n_p = 2**448 - 2**224 - 1\n_a = 1\n_d = -39081 % _p\n_h = 4\n\n_Gx = int(\n    remove_whitespace(\n        \"224580040295924300187604334099896036246789641632564134246125461\"\n        \"686950415467406032909029192869357953282578032075146446173674602635\"\n        \"247710\"\n    )\n)\n_Gy = int(\n    remove_whitespace(\n        \"298819210078481492676017930443930673437544040154080242095928241\"\n        \"372331506189835876003536878655418784733982303233503462500531545062\"\n        \"832660\"\n    )\n)\n_r = 2**446 - 0x8335DC163BB124B65129C96FDE933D8D723A70AADC873D6D54A7BB0D\n\n\ndef _shake256(data):\n    return shake_256(data, 114)\n\n\ncurve_ed448 = ellipticcurve.CurveEdTw(_p, _a, _d, _h, _shake256)\ngenerator_ed448 = ellipticcurve.PointEdwards(\n    curve_ed448, _Gx, _Gy, 1, _Gx * _Gy % _p, _r, generator=True\n)\n\n\nclass PublicKey(object):\n    \"\"\"Public key for the Edwards Digital Signature Algorithm.\"\"\"\n\n    def __init__(self, generator, public_key, public_point=None):\n        self.generator = generator\n        self.curve = generator.curve()\n        self.__encoded = public_key\n        # plus one for the sign bit and round up\n        self.baselen = (bit_length(self.curve.p()) + 1 + 7) // 8\n        if len(public_key) != self.baselen:\n            raise ValueError(\n                \"Incorrect size of the public key, expected: {0} bytes\".format(\n                    self.baselen\n                )\n            )\n        if public_point:\n            self.__point = public_point\n        else:\n            self.__point = ellipticcurve.PointEdwards.from_bytes(\n                self.curve, public_key\n            )\n\n    def __eq__(self, other):\n        if isinstance(other, PublicKey):\n            return (\n                self.curve == other.curve and self.__encoded == other.__encoded\n            )\n        return NotImplemented\n\n    def __ne__(self, other):\n        return not self == other\n\n    @property\n    def point(self):\n        return self.__point\n\n    @point.setter\n    def point(self, other):\n        if self.__point != other:\n            raise ValueError(\"Can't change the coordinates of the point\")\n        self.__point = other\n\n    def public_point(self):\n        return self.__point\n\n    def public_key(self):\n        return self.__encoded\n\n    def verify(self, data, signature):\n        \"\"\"Verify a Pure EdDSA signature over data.\"\"\"\n        data = compat26_str(data)\n        if len(signature) != 2 * self.baselen:\n            raise ValueError(\n                \"Invalid signature length, expected: {0} bytes\".format(\n                    2 * self.baselen\n                )\n            )\n        R = ellipticcurve.PointEdwards.from_bytes(\n            self.curve, signature[: self.baselen]\n        )\n        S = bytes_to_int(signature[self.baselen :], \"little\")\n        if S >= self.generator.order():\n            raise ValueError(\"Invalid signature\")\n\n        dom = bytearray()\n        if self.curve == curve_ed448:\n            dom = bytearray(b\"SigEd448\" + b\"\\x00\\x00\")\n\n        k = bytes_to_int(\n            self.curve.hash_func(dom + R.to_bytes() + self.__encoded + data),\n            \"little\",\n        )\n\n        if self.generator * S != self.__point * k + R:\n            raise ValueError(\"Invalid signature\")\n\n        return True\n\n\nclass PrivateKey(object):\n    \"\"\"Private key for the Edwards Digital Signature Algorithm.\"\"\"\n\n    def __init__(self, generator, private_key):\n        self.generator = generator\n        self.curve = generator.curve()\n        # plus one for the sign bit and round up\n        self.baselen = (bit_length(self.curve.p()) + 1 + 7) // 8\n        if len(private_key) != self.baselen:\n            raise ValueError(\n                \"Incorrect size of private key, expected: {0} bytes\".format(\n                    self.baselen\n                )\n            )\n        self.__private_key = bytes(private_key)\n        self.__h = bytearray(self.curve.hash_func(private_key))\n        self.__public_key = None\n\n        a = self.__h[: self.baselen]\n        a = self._key_prune(a)\n        scalar = bytes_to_int(a, \"little\")\n        self.__s = scalar\n\n    @property\n    def private_key(self):\n        return self.__private_key\n\n    def __eq__(self, other):\n        if isinstance(other, PrivateKey):\n            return (\n                self.curve == other.curve\n                and self.__private_key == other.__private_key\n            )\n        return NotImplemented\n\n    def __ne__(self, other):\n        return not self == other\n\n    def _key_prune(self, key):\n        # make sure the key is not in a small subgroup\n        h = self.curve.cofactor()\n        if h == 4:\n            h_log = 2\n        elif h == 8:\n            h_log = 3\n        else:\n            raise ValueError(\"Only cofactor 4 and 8 curves supported\")\n        key[0] &= ~((1 << h_log) - 1)\n\n        # ensure the highest bit is set but no higher\n        l = bit_length(self.curve.p())\n        if l % 8 == 0:\n            key[-1] = 0\n            key[-2] |= 0x80\n        else:\n            key[-1] = key[-1] & (1 << (l % 8)) - 1 | 1 << (l % 8) - 1\n        return key\n\n    def public_key(self):\n        \"\"\"Generate the public key based on the included private key\"\"\"\n        if self.__public_key:\n            return self.__public_key\n\n        public_point = self.generator * self.__s\n\n        self.__public_key = PublicKey(\n            self.generator, public_point.to_bytes(), public_point\n        )\n\n        return self.__public_key\n\n    def sign(self, data):\n        \"\"\"Perform a Pure EdDSA signature over data.\"\"\"\n        data = compat26_str(data)\n        A = self.public_key().public_key()\n\n        prefix = self.__h[self.baselen :]\n\n        dom = bytearray()\n        if self.curve == curve_ed448:\n            dom = bytearray(b\"SigEd448\" + b\"\\x00\\x00\")\n\n        r = bytes_to_int(self.curve.hash_func(dom + prefix + data), \"little\")\n        R = (self.generator * r).to_bytes()\n\n        k = bytes_to_int(self.curve.hash_func(dom + R + A + data), \"little\")\n        k %= self.generator.order()\n\n        S = (r + k * self.__s) % self.generator.order()\n\n        return R + int_to_bytes(S, self.baselen, \"little\")\n"
  },
  {
    "path": "code/default/lib/noarch/ecdsa/ellipticcurve.py",
    "content": "#! /usr/bin/env python\n# -*- coding: utf-8 -*-\n#\n# Implementation of elliptic curves, for cryptographic applications.\n#\n# This module doesn't provide any way to choose a random elliptic\n# curve, nor to verify that an elliptic curve was chosen randomly,\n# because one can simply use NIST's standard curves.\n#\n# Notes from X9.62-1998 (draft):\n#   Nomenclature:\n#     - Q is a public key.\n#     The \"Elliptic Curve Domain Parameters\" include:\n#     - q is the \"field size\", which in our case equals p.\n#     - p is a big prime.\n#     - G is a point of prime order (5.1.1.1).\n#     - n is the order of G (5.1.1.1).\n#   Public-key validation (5.2.2):\n#     - Verify that Q is not the point at infinity.\n#     - Verify that X_Q and Y_Q are in [0,p-1].\n#     - Verify that Q is on the curve.\n#     - Verify that nQ is the point at infinity.\n#   Signature generation (5.3):\n#     - Pick random k from [1,n-1].\n#   Signature checking (5.4.2):\n#     - Verify that r and s are in [1,n-1].\n#\n# Revision history:\n#    2005.12.31 - Initial version.\n#    2008.11.25 - Change CurveFp.is_on to contains_point.\n#\n# Written in 2005 by Peter Pearson and placed in the public domain.\n# Modified extensively as part of python-ecdsa.\n\nfrom __future__ import division\n\ntry:\n    from gmpy2 import mpz\n\n    GMPY = True\nexcept ImportError:  # pragma: no branch\n    try:\n        from gmpy import mpz\n\n        GMPY = True\n    except ImportError:\n        GMPY = False\n\n\nfrom six import python_2_unicode_compatible\nfrom . import numbertheory\nfrom ._compat import normalise_bytes, int_to_bytes, bit_length, bytes_to_int\nfrom .errors import MalformedPointError\nfrom .util import orderlen, string_to_number, number_to_string\n\n\n@python_2_unicode_compatible\nclass CurveFp(object):\n    \"\"\"\n    :term:`Short Weierstrass Elliptic Curve <short Weierstrass curve>` over a\n    prime field.\n    \"\"\"\n\n    if GMPY:  # pragma: no branch\n\n        def __init__(self, p, a, b, h=None):\n            \"\"\"\n            The curve of points satisfying y^2 = x^3 + a*x + b (mod p).\n\n            h is an integer that is the cofactor of the elliptic curve domain\n            parameters; it is the number of points satisfying the elliptic\n            curve equation divided by the order of the base point. It is used\n            for selection of efficient algorithm for public point verification.\n            \"\"\"\n            self.__p = mpz(p)\n            self.__a = mpz(a)\n            self.__b = mpz(b)\n            # h is not used in calculations and it can be None, so don't use\n            # gmpy with it\n            self.__h = h\n\n    else:  # pragma: no branch\n\n        def __init__(self, p, a, b, h=None):\n            \"\"\"\n            The curve of points satisfying y^2 = x^3 + a*x + b (mod p).\n\n            h is an integer that is the cofactor of the elliptic curve domain\n            parameters; it is the number of points satisfying the elliptic\n            curve equation divided by the order of the base point. It is used\n            for selection of efficient algorithm for public point verification.\n            \"\"\"\n            self.__p = p\n            self.__a = a\n            self.__b = b\n            self.__h = h\n\n    def __eq__(self, other):\n        \"\"\"Return True if other is an identical curve, False otherwise.\n\n        Note: the value of the cofactor of the curve is not taken into account\n        when comparing curves, as it's derived from the base point and\n        intrinsic curve characteristic (but it's complex to compute),\n        only the prime and curve parameters are considered.\n        \"\"\"\n        if isinstance(other, CurveFp):\n            p = self.__p\n            return (\n                self.__p == other.__p\n                and self.__a % p == other.__a % p\n                and self.__b % p == other.__b % p\n            )\n        return NotImplemented\n\n    def __ne__(self, other):\n        \"\"\"Return False if other is an identical curve, True otherwise.\"\"\"\n        return not self == other\n\n    def __hash__(self):\n        return hash((self.__p, self.__a, self.__b))\n\n    def p(self):\n        return self.__p\n\n    def a(self):\n        return self.__a\n\n    def b(self):\n        return self.__b\n\n    def cofactor(self):\n        return self.__h\n\n    def contains_point(self, x, y):\n        \"\"\"Is the point (x,y) on this curve?\"\"\"\n        return (y * y - ((x * x + self.__a) * x + self.__b)) % self.__p == 0\n\n    def __str__(self):\n        return \"CurveFp(p=%d, a=%d, b=%d, h=%d)\" % (\n            self.__p,\n            self.__a,\n            self.__b,\n            self.__h,\n        )\n\n\nclass CurveEdTw(object):\n    \"\"\"Parameters for a Twisted Edwards Elliptic Curve\"\"\"\n\n    if GMPY:  # pragma: no branch\n\n        def __init__(self, p, a, d, h=None, hash_func=None):\n            \"\"\"\n            The curve of points satisfying a*x^2 + y^2 = 1 + d*x^2*y^2 (mod p).\n\n            h is the cofactor of the curve.\n            hash_func is the hash function associated with the curve\n             (like SHA-512 for Ed25519)\n            \"\"\"\n            self.__p = mpz(p)\n            self.__a = mpz(a)\n            self.__d = mpz(d)\n            self.__h = h\n            self.__hash_func = hash_func\n\n    else:\n\n        def __init__(self, p, a, d, h=None, hash_func=None):\n            \"\"\"\n            The curve of points satisfying a*x^2 + y^2 = 1 + d*x^2*y^2 (mod p).\n\n            h is the cofactor of the curve.\n            hash_func is the hash function associated with the curve\n             (like SHA-512 for Ed25519)\n            \"\"\"\n            self.__p = p\n            self.__a = a\n            self.__d = d\n            self.__h = h\n            self.__hash_func = hash_func\n\n    def __eq__(self, other):\n        \"\"\"Returns True if other is an identical curve.\"\"\"\n        if isinstance(other, CurveEdTw):\n            p = self.__p\n            return (\n                self.__p == other.__p\n                and self.__a % p == other.__a % p\n                and self.__d % p == other.__d % p\n            )\n        return NotImplemented\n\n    def __ne__(self, other):\n        \"\"\"Return False if the other is an identical curve, True otherwise.\"\"\"\n        return not self == other\n\n    def __hash__(self):\n        return hash((self.__p, self.__a, self.__d))\n\n    def contains_point(self, x, y):\n        \"\"\"Is the point (x, y) on this curve?\"\"\"\n        return (\n            self.__a * x * x + y * y - 1 - self.__d * x * x * y * y\n        ) % self.__p == 0\n\n    def p(self):\n        return self.__p\n\n    def a(self):\n        return self.__a\n\n    def d(self):\n        return self.__d\n\n    def hash_func(self, data):\n        return self.__hash_func(data)\n\n    def cofactor(self):\n        return self.__h\n\n    def __str__(self):\n        return \"CurveEdTw(p={0}, a={1}, d={2}, h={3})\".format(\n            self.__p,\n            self.__a,\n            self.__d,\n            self.__h,\n        )\n\n\nclass AbstractPoint(object):\n    \"\"\"Class for common methods of elliptic curve points.\"\"\"\n\n    @staticmethod\n    def _from_raw_encoding(data, raw_encoding_length):\n        \"\"\"\n        Decode public point from :term:`raw encoding`.\n\n        :term:`raw encoding` is the same as the :term:`uncompressed` encoding,\n        but without the 0x04 byte at the beginning.\n        \"\"\"\n        # real assert, from_bytes() should not call us with different length\n        assert len(data) == raw_encoding_length\n        xs = data[: raw_encoding_length // 2]\n        ys = data[raw_encoding_length // 2 :]\n        # real assert, raw_encoding_length is calculated by multiplying an\n        # integer by two so it will always be even\n        assert len(xs) == raw_encoding_length // 2\n        assert len(ys) == raw_encoding_length // 2\n        coord_x = string_to_number(xs)\n        coord_y = string_to_number(ys)\n\n        return coord_x, coord_y\n\n    @staticmethod\n    def _from_compressed(data, curve):\n        \"\"\"Decode public point from compressed encoding.\"\"\"\n        if data[:1] not in (b\"\\x02\", b\"\\x03\"):\n            raise MalformedPointError(\"Malformed compressed point encoding\")\n\n        is_even = data[:1] == b\"\\x02\"\n        x = string_to_number(data[1:])\n        p = curve.p()\n        alpha = (pow(x, 3, p) + (curve.a() * x) + curve.b()) % p\n        try:\n            beta = numbertheory.square_root_mod_prime(alpha, p)\n        except numbertheory.Error as e:\n            raise MalformedPointError(\n                \"Encoding does not correspond to a point on curve\", e\n            )\n        if is_even == bool(beta & 1):\n            y = p - beta\n        else:\n            y = beta\n        return x, y\n\n    @classmethod\n    def _from_hybrid(cls, data, raw_encoding_length, validate_encoding):\n        \"\"\"Decode public point from hybrid encoding.\"\"\"\n        # real assert, from_bytes() should not call us with different types\n        assert data[:1] in (b\"\\x06\", b\"\\x07\")\n\n        # primarily use the uncompressed as it's easiest to handle\n        x, y = cls._from_raw_encoding(data[1:], raw_encoding_length)\n\n        # but validate if it's self-consistent if we're asked to do that\n        if validate_encoding and (\n            y & 1\n            and data[:1] != b\"\\x07\"\n            or (not y & 1)\n            and data[:1] != b\"\\x06\"\n        ):\n            raise MalformedPointError(\"Inconsistent hybrid point encoding\")\n\n        return x, y\n\n    @classmethod\n    def _from_edwards(cls, curve, data):\n        \"\"\"Decode a point on an Edwards curve.\"\"\"\n        data = bytearray(data)\n        p = curve.p()\n        # add 1 for the sign bit and then round up\n        exp_len = (bit_length(p) + 1 + 7) // 8\n        if len(data) != exp_len:\n            raise MalformedPointError(\"Point length doesn't match the curve.\")\n        x_0 = (data[-1] & 0x80) >> 7\n\n        data[-1] &= 0x80 - 1\n\n        y = bytes_to_int(data, \"little\")\n        if GMPY:\n            y = mpz(y)\n\n        x2 = (\n            (y * y - 1)\n            * numbertheory.inverse_mod(curve.d() * y * y - curve.a(), p)\n            % p\n        )\n\n        try:\n            x = numbertheory.square_root_mod_prime(x2, p)\n        except numbertheory.Error as e:\n            raise MalformedPointError(\n                \"Encoding does not correspond to a point on curve\", e\n            )\n\n        if x % 2 != x_0:\n            x = -x % p\n\n        return x, y\n\n    @classmethod\n    def from_bytes(\n        cls, curve, data, validate_encoding=True, valid_encodings=None\n    ):\n        \"\"\"\n        Initialise the object from byte encoding of a point.\n\n        The method does accept and automatically detect the type of point\n        encoding used. It supports the :term:`raw encoding`,\n        :term:`uncompressed`, :term:`compressed`, and :term:`hybrid` encodings.\n\n        Note: generally you will want to call the ``from_bytes()`` method of\n        either a child class, PointJacobi or Point.\n\n        :param data: single point encoding of the public key\n        :type data: :term:`bytes-like object`\n        :param curve: the curve on which the public key is expected to lay\n        :type curve: ~ecdsa.ellipticcurve.CurveFp\n        :param validate_encoding: whether to verify that the encoding of the\n            point is self-consistent, defaults to True, has effect only\n            on ``hybrid`` encoding\n        :type validate_encoding: bool\n        :param valid_encodings: list of acceptable point encoding formats,\n            supported ones are: :term:`uncompressed`, :term:`compressed`,\n            :term:`hybrid`, and :term:`raw encoding` (specified with ``raw``\n            name). All formats by default (specified with ``None``).\n        :type valid_encodings: :term:`set-like object`\n\n        :raises `~ecdsa.errors.MalformedPointError`: if the public point does\n            not lay on the curve or the encoding is invalid\n\n        :return: x and y coordinates of the encoded point\n        :rtype: tuple(int, int)\n        \"\"\"\n        if not valid_encodings:\n            valid_encodings = set(\n                [\"uncompressed\", \"compressed\", \"hybrid\", \"raw\"]\n            )\n        if not all(\n            i in set((\"uncompressed\", \"compressed\", \"hybrid\", \"raw\"))\n            for i in valid_encodings\n        ):\n            raise ValueError(\n                \"Only uncompressed, compressed, hybrid or raw encoding \"\n                \"supported.\"\n            )\n        data = normalise_bytes(data)\n\n        if isinstance(curve, CurveEdTw):\n            return cls._from_edwards(curve, data)\n\n        key_len = len(data)\n        raw_encoding_length = 2 * orderlen(curve.p())\n        if key_len == raw_encoding_length and \"raw\" in valid_encodings:\n            coord_x, coord_y = cls._from_raw_encoding(\n                data, raw_encoding_length\n            )\n        elif key_len == raw_encoding_length + 1 and (\n            \"hybrid\" in valid_encodings or \"uncompressed\" in valid_encodings\n        ):\n            if data[:1] in (b\"\\x06\", b\"\\x07\") and \"hybrid\" in valid_encodings:\n                coord_x, coord_y = cls._from_hybrid(\n                    data, raw_encoding_length, validate_encoding\n                )\n            elif data[:1] == b\"\\x04\" and \"uncompressed\" in valid_encodings:\n                coord_x, coord_y = cls._from_raw_encoding(\n                    data[1:], raw_encoding_length\n                )\n            else:\n                raise MalformedPointError(\n                    \"Invalid X9.62 encoding of the public point\"\n                )\n        elif (\n            key_len == raw_encoding_length // 2 + 1\n            and \"compressed\" in valid_encodings\n        ):\n            coord_x, coord_y = cls._from_compressed(data, curve)\n        else:\n            raise MalformedPointError(\n                \"Length of string does not match lengths of \"\n                \"any of the enabled ({0}) encodings of the \"\n                \"curve.\".format(\", \".join(valid_encodings))\n            )\n        return coord_x, coord_y\n\n    def _raw_encode(self):\n        \"\"\"Convert the point to the :term:`raw encoding`.\"\"\"\n        prime = self.curve().p()\n        x_str = number_to_string(self.x(), prime)\n        y_str = number_to_string(self.y(), prime)\n        return x_str + y_str\n\n    def _compressed_encode(self):\n        \"\"\"Encode the point into the compressed form.\"\"\"\n        prime = self.curve().p()\n        x_str = number_to_string(self.x(), prime)\n        if self.y() & 1:\n            return b\"\\x03\" + x_str\n        return b\"\\x02\" + x_str\n\n    def _hybrid_encode(self):\n        \"\"\"Encode the point into the hybrid form.\"\"\"\n        raw_enc = self._raw_encode()\n        if self.y() & 1:\n            return b\"\\x07\" + raw_enc\n        return b\"\\x06\" + raw_enc\n\n    def _edwards_encode(self):\n        \"\"\"Encode the point according to RFC8032 encoding.\"\"\"\n        self.scale()\n        x, y, p = self.x(), self.y(), self.curve().p()\n\n        # add 1 for the sign bit and then round up\n        enc_len = (bit_length(p) + 1 + 7) // 8\n        y_str = int_to_bytes(y, enc_len, \"little\")\n        if x % 2:\n            y_str[-1] |= 0x80\n        return y_str\n\n    def to_bytes(self, encoding=\"raw\"):\n        \"\"\"\n        Convert the point to a byte string.\n\n        The method by default uses the :term:`raw encoding` (specified\n        by `encoding=\"raw\"`. It can also output points in :term:`uncompressed`,\n        :term:`compressed`, and :term:`hybrid` formats.\n\n        For points on Edwards curves `encoding` is ignored and only the\n        encoding defined in RFC 8032 is supported.\n\n        :return: :term:`raw encoding` of a public on the curve\n        :rtype: bytes\n        \"\"\"\n        assert encoding in (\"raw\", \"uncompressed\", \"compressed\", \"hybrid\")\n        curve = self.curve()\n        if isinstance(curve, CurveEdTw):\n            return self._edwards_encode()\n        elif encoding == \"raw\":\n            return self._raw_encode()\n        elif encoding == \"uncompressed\":\n            return b\"\\x04\" + self._raw_encode()\n        elif encoding == \"hybrid\":\n            return self._hybrid_encode()\n        else:\n            return self._compressed_encode()\n\n    @staticmethod\n    def _naf(mult):\n        \"\"\"Calculate non-adjacent form of number.\"\"\"\n        ret = []\n        while mult:\n            if mult % 2:\n                nd = mult % 4\n                if nd >= 2:\n                    nd -= 4\n                ret.append(nd)\n                mult -= nd\n            else:\n                ret.append(0)\n            mult //= 2\n        return ret\n\n\nclass PointJacobi(AbstractPoint):\n    \"\"\"\n    Point on a short Weierstrass elliptic curve. Uses Jacobi coordinates.\n\n    In Jacobian coordinates, there are three parameters, X, Y and Z.\n    They correspond to affine parameters 'x' and 'y' like so:\n\n    x = X / Z²\n    y = Y / Z³\n    \"\"\"\n\n    def __init__(self, curve, x, y, z, order=None, generator=False):\n        \"\"\"\n        Initialise a point that uses Jacobi representation internally.\n\n        :param CurveFp curve: curve on which the point resides\n        :param int x: the X parameter of Jacobi representation (equal to x when\n          converting from affine coordinates\n        :param int y: the Y parameter of Jacobi representation (equal to y when\n          converting from affine coordinates\n        :param int z: the Z parameter of Jacobi representation (equal to 1 when\n          converting from affine coordinates\n        :param int order: the point order, must be non zero when using\n          generator=True\n        :param bool generator: the point provided is a curve generator, as\n          such, it will be commonly used with scalar multiplication. This will\n          cause to precompute multiplication table generation for it\n        \"\"\"\n        super(PointJacobi, self).__init__()\n        self.__curve = curve\n        if GMPY:  # pragma: no branch\n            self.__coords = (mpz(x), mpz(y), mpz(z))\n            self.__order = order and mpz(order)\n        else:  # pragma: no branch\n            self.__coords = (x, y, z)\n            self.__order = order\n        self.__generator = generator\n        self.__precompute = []\n\n    @classmethod\n    def from_bytes(\n        cls,\n        curve,\n        data,\n        validate_encoding=True,\n        valid_encodings=None,\n        order=None,\n        generator=False,\n    ):\n        \"\"\"\n        Initialise the object from byte encoding of a point.\n\n        The method does accept and automatically detect the type of point\n        encoding used. It supports the :term:`raw encoding`,\n        :term:`uncompressed`, :term:`compressed`, and :term:`hybrid` encodings.\n\n        :param data: single point encoding of the public key\n        :type data: :term:`bytes-like object`\n        :param curve: the curve on which the public key is expected to lay\n        :type curve: ~ecdsa.ellipticcurve.CurveFp\n        :param validate_encoding: whether to verify that the encoding of the\n            point is self-consistent, defaults to True, has effect only\n            on ``hybrid`` encoding\n        :type validate_encoding: bool\n        :param valid_encodings: list of acceptable point encoding formats,\n            supported ones are: :term:`uncompressed`, :term:`compressed`,\n            :term:`hybrid`, and :term:`raw encoding` (specified with ``raw``\n            name). All formats by default (specified with ``None``).\n        :type valid_encodings: :term:`set-like object`\n        :param int order: the point order, must be non zero when using\n            generator=True\n        :param bool generator: the point provided is a curve generator, as\n            such, it will be commonly used with scalar multiplication. This\n            will cause to precompute multiplication table generation for it\n\n        :raises `~ecdsa.errors.MalformedPointError`: if the public point does\n            not lay on the curve or the encoding is invalid\n\n        :return: Point on curve\n        :rtype: PointJacobi\n        \"\"\"\n        coord_x, coord_y = super(PointJacobi, cls).from_bytes(\n            curve, data, validate_encoding, valid_encodings\n        )\n        return PointJacobi(curve, coord_x, coord_y, 1, order, generator)\n\n    def _maybe_precompute(self):\n        if not self.__generator or self.__precompute:\n            return\n\n        # since this code will execute just once, and it's fully deterministic,\n        # depend on atomicity of the last assignment to switch from empty\n        # self.__precompute to filled one and just ignore the unlikely\n        # situation when two threads execute it at the same time (as it won't\n        # lead to inconsistent __precompute)\n        order = self.__order\n        assert order\n        precompute = []\n        i = 1\n        order *= 2\n        coord_x, coord_y, coord_z = self.__coords\n        doubler = PointJacobi(self.__curve, coord_x, coord_y, coord_z, order)\n        order *= 2\n        precompute.append((doubler.x(), doubler.y()))\n\n        while i < order:\n            i *= 2\n            doubler = doubler.double().scale()\n            precompute.append((doubler.x(), doubler.y()))\n\n        self.__precompute = precompute\n\n    def __getstate__(self):\n        # while this code can execute at the same time as _maybe_precompute()\n        # is updating the __precompute or scale() is updating the __coords,\n        # there is no requirement for consistency between __coords and\n        # __precompute\n        state = self.__dict__.copy()\n        return state\n\n    def __setstate__(self, state):\n        self.__dict__.update(state)\n\n    def __eq__(self, other):\n        \"\"\"Compare for equality two points with each-other.\n\n        Note: only points that lay on the same curve can be equal.\n        \"\"\"\n        x1, y1, z1 = self.__coords\n        if other is INFINITY:\n            return not y1 or not z1\n        if isinstance(other, Point):\n            x2, y2, z2 = other.x(), other.y(), 1\n        elif isinstance(other, PointJacobi):\n            x2, y2, z2 = other.__coords\n        else:\n            return NotImplemented\n        if self.__curve != other.curve():\n            return False\n        p = self.__curve.p()\n\n        zz1 = z1 * z1 % p\n        zz2 = z2 * z2 % p\n\n        # compare the fractions by bringing them to the same denominator\n        # depend on short-circuit to save 4 multiplications in case of\n        # inequality\n        return (x1 * zz2 - x2 * zz1) % p == 0 and (\n            y1 * zz2 * z2 - y2 * zz1 * z1\n        ) % p == 0\n\n    def __ne__(self, other):\n        \"\"\"Compare for inequality two points with each-other.\"\"\"\n        return not self == other\n\n    def order(self):\n        \"\"\"Return the order of the point.\n\n        None if it is undefined.\n        \"\"\"\n        return self.__order\n\n    def curve(self):\n        \"\"\"Return curve over which the point is defined.\"\"\"\n        return self.__curve\n\n    def x(self):\n        \"\"\"\n        Return affine x coordinate.\n\n        This method should be used only when the 'y' coordinate is not needed.\n        It's computationally more efficient to use `to_affine()` and then\n        call x() and y() on the returned instance. Or call `scale()`\n        and then x() and y() on the returned instance.\n        \"\"\"\n        x, _, z = self.__coords\n        if z == 1:\n            return x\n        p = self.__curve.p()\n        z = numbertheory.inverse_mod(z, p)\n        return x * z**2 % p\n\n    def y(self):\n        \"\"\"\n        Return affine y coordinate.\n\n        This method should be used only when the 'x' coordinate is not needed.\n        It's computationally more efficient to use `to_affine()` and then\n        call x() and y() on the returned instance. Or call `scale()`\n        and then x() and y() on the returned instance.\n        \"\"\"\n        _, y, z = self.__coords\n        if z == 1:\n            return y\n        p = self.__curve.p()\n        z = numbertheory.inverse_mod(z, p)\n        return y * z**3 % p\n\n    def scale(self):\n        \"\"\"\n        Return point scaled so that z == 1.\n\n        Modifies point in place, returns self.\n        \"\"\"\n        x, y, z = self.__coords\n        if z == 1:\n            return self\n\n        # scaling is deterministic, so even if two threads execute the below\n        # code at the same time, they will set __coords to the same value\n        p = self.__curve.p()\n        z_inv = numbertheory.inverse_mod(z, p)\n        zz_inv = z_inv * z_inv % p\n        x = x * zz_inv % p\n        y = y * zz_inv * z_inv % p\n        self.__coords = (x, y, 1)\n        return self\n\n    def to_affine(self):\n        \"\"\"Return point in affine form.\"\"\"\n        _, y, z = self.__coords\n        if not y or not z:\n            return INFINITY\n        self.scale()\n        x, y, z = self.__coords\n        return Point(self.__curve, x, y, self.__order)\n\n    @staticmethod\n    def from_affine(point, generator=False):\n        \"\"\"Create from an affine point.\n\n        :param bool generator: set to True to make the point to precalculate\n          multiplication table - useful for public point when verifying many\n          signatures (around 100 or so) or for generator points of a curve.\n        \"\"\"\n        return PointJacobi(\n            point.curve(), point.x(), point.y(), 1, point.order(), generator\n        )\n\n    # please note that all the methods that use the equations from\n    # hyperelliptic\n    # are formatted in a way to maximise performance.\n    # Things that make code faster: multiplying instead of taking to the power\n    # (`xx = x * x; xxxx = xx * xx % p` is faster than `xxxx = x**4 % p` and\n    # `pow(x, 4, p)`),\n    # multiple assignments at the same time (`x1, x2 = self.x1, self.x2` is\n    # faster than `x1 = self.x1; x2 = self.x2`),\n    # similarly, sometimes the `% p` is skipped if it makes the calculation\n    # faster and the result of calculation is later reduced modulo `p`\n\n    def _double_with_z_1(self, X1, Y1, p, a):\n        \"\"\"Add a point to itself with z == 1.\"\"\"\n        # after:\n        # http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-mdbl-2007-bl\n        XX, YY = X1 * X1 % p, Y1 * Y1 % p\n        if not YY:\n            return 0, 0, 1\n        YYYY = YY * YY % p\n        S = 2 * ((X1 + YY) ** 2 - XX - YYYY) % p\n        M = 3 * XX + a\n        T = (M * M - 2 * S) % p\n        # X3 = T\n        Y3 = (M * (S - T) - 8 * YYYY) % p\n        Z3 = 2 * Y1 % p\n        return T, Y3, Z3\n\n    def _double(self, X1, Y1, Z1, p, a):\n        \"\"\"Add a point to itself, arbitrary z.\"\"\"\n        if Z1 == 1:\n            return self._double_with_z_1(X1, Y1, p, a)\n        if not Y1 or not Z1:\n            return 0, 0, 1\n        # after:\n        # http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-2007-bl\n        XX, YY = X1 * X1 % p, Y1 * Y1 % p\n        if not YY:\n            return 0, 0, 1\n        YYYY = YY * YY % p\n        ZZ = Z1 * Z1 % p\n        S = 2 * ((X1 + YY) ** 2 - XX - YYYY) % p\n        M = (3 * XX + a * ZZ * ZZ) % p\n        T = (M * M - 2 * S) % p\n        # X3 = T\n        Y3 = (M * (S - T) - 8 * YYYY) % p\n        Z3 = ((Y1 + Z1) ** 2 - YY - ZZ) % p\n\n        return T, Y3, Z3\n\n    def double(self):\n        \"\"\"Add a point to itself.\"\"\"\n        X1, Y1, Z1 = self.__coords\n\n        if not Y1:\n            return INFINITY\n\n        p, a = self.__curve.p(), self.__curve.a()\n\n        X3, Y3, Z3 = self._double(X1, Y1, Z1, p, a)\n\n        if not Y3 or not Z3:\n            return INFINITY\n        return PointJacobi(self.__curve, X3, Y3, Z3, self.__order)\n\n    def _add_with_z_1(self, X1, Y1, X2, Y2, p):\n        \"\"\"add points when both Z1 and Z2 equal 1\"\"\"\n        # after:\n        # http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#addition-mmadd-2007-bl\n        H = X2 - X1\n        HH = H * H\n        I = 4 * HH % p\n        J = H * I\n        r = 2 * (Y2 - Y1)\n        if not H and not r:\n            return self._double_with_z_1(X1, Y1, p, self.__curve.a())\n        V = X1 * I\n        X3 = (r**2 - J - 2 * V) % p\n        Y3 = (r * (V - X3) - 2 * Y1 * J) % p\n        Z3 = 2 * H % p\n        return X3, Y3, Z3\n\n    def _add_with_z_eq(self, X1, Y1, Z1, X2, Y2, p):\n        \"\"\"add points when Z1 == Z2\"\"\"\n        # after:\n        # http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#addition-zadd-2007-m\n        A = (X2 - X1) ** 2 % p\n        B = X1 * A % p\n        C = X2 * A\n        D = (Y2 - Y1) ** 2 % p\n        if not A and not D:\n            return self._double(X1, Y1, Z1, p, self.__curve.a())\n        X3 = (D - B - C) % p\n        Y3 = ((Y2 - Y1) * (B - X3) - Y1 * (C - B)) % p\n        Z3 = Z1 * (X2 - X1) % p\n        return X3, Y3, Z3\n\n    def _add_with_z2_1(self, X1, Y1, Z1, X2, Y2, p):\n        \"\"\"add points when Z2 == 1\"\"\"\n        # after:\n        # http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#addition-madd-2007-bl\n        Z1Z1 = Z1 * Z1 % p\n        U2, S2 = X2 * Z1Z1 % p, Y2 * Z1 * Z1Z1 % p\n        H = (U2 - X1) % p\n        HH = H * H % p\n        I = 4 * HH % p\n        J = H * I\n        r = 2 * (S2 - Y1) % p\n        if not r and not H:\n            return self._double_with_z_1(X2, Y2, p, self.__curve.a())\n        V = X1 * I\n        X3 = (r * r - J - 2 * V) % p\n        Y3 = (r * (V - X3) - 2 * Y1 * J) % p\n        Z3 = ((Z1 + H) ** 2 - Z1Z1 - HH) % p\n        return X3, Y3, Z3\n\n    def _add_with_z_ne(self, X1, Y1, Z1, X2, Y2, Z2, p):\n        \"\"\"add points with arbitrary z\"\"\"\n        # after:\n        # http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#addition-add-2007-bl\n        Z1Z1 = Z1 * Z1 % p\n        Z2Z2 = Z2 * Z2 % p\n        U1 = X1 * Z2Z2 % p\n        U2 = X2 * Z1Z1 % p\n        S1 = Y1 * Z2 * Z2Z2 % p\n        S2 = Y2 * Z1 * Z1Z1 % p\n        H = U2 - U1\n        I = 4 * H * H % p\n        J = H * I % p\n        r = 2 * (S2 - S1) % p\n        if not H and not r:\n            return self._double(X1, Y1, Z1, p, self.__curve.a())\n        V = U1 * I\n        X3 = (r * r - J - 2 * V) % p\n        Y3 = (r * (V - X3) - 2 * S1 * J) % p\n        Z3 = ((Z1 + Z2) ** 2 - Z1Z1 - Z2Z2) * H % p\n\n        return X3, Y3, Z3\n\n    def __radd__(self, other):\n        \"\"\"Add other to self.\"\"\"\n        return self + other\n\n    def _add(self, X1, Y1, Z1, X2, Y2, Z2, p):\n        \"\"\"add two points, select fastest method.\"\"\"\n        if not Y1 or not Z1:\n            return X2, Y2, Z2\n        if not Y2 or not Z2:\n            return X1, Y1, Z1\n        if Z1 == Z2:\n            if Z1 == 1:\n                return self._add_with_z_1(X1, Y1, X2, Y2, p)\n            return self._add_with_z_eq(X1, Y1, Z1, X2, Y2, p)\n        if Z1 == 1:\n            return self._add_with_z2_1(X2, Y2, Z2, X1, Y1, p)\n        if Z2 == 1:\n            return self._add_with_z2_1(X1, Y1, Z1, X2, Y2, p)\n        return self._add_with_z_ne(X1, Y1, Z1, X2, Y2, Z2, p)\n\n    def __add__(self, other):\n        \"\"\"Add two points on elliptic curve.\"\"\"\n        if self == INFINITY:\n            return other\n        if other == INFINITY:\n            return self\n        if isinstance(other, Point):\n            other = PointJacobi.from_affine(other)\n        if self.__curve != other.__curve:\n            raise ValueError(\"The other point is on different curve\")\n\n        p = self.__curve.p()\n        X1, Y1, Z1 = self.__coords\n        X2, Y2, Z2 = other.__coords\n\n        X3, Y3, Z3 = self._add(X1, Y1, Z1, X2, Y2, Z2, p)\n\n        if not Y3 or not Z3:\n            return INFINITY\n        return PointJacobi(self.__curve, X3, Y3, Z3, self.__order)\n\n    def __rmul__(self, other):\n        \"\"\"Multiply point by an integer.\"\"\"\n        return self * other\n\n    def _mul_precompute(self, other):\n        \"\"\"Multiply point by integer with precomputation table.\"\"\"\n        X3, Y3, Z3, p = 0, 0, 1, self.__curve.p()\n        _add = self._add\n        for X2, Y2 in self.__precompute:\n            if other % 2:\n                if other % 4 >= 2:\n                    other = (other + 1) // 2\n                    X3, Y3, Z3 = _add(X3, Y3, Z3, X2, -Y2, 1, p)\n                else:\n                    other = (other - 1) // 2\n                    X3, Y3, Z3 = _add(X3, Y3, Z3, X2, Y2, 1, p)\n            else:\n                other //= 2\n\n        if not Y3 or not Z3:\n            return INFINITY\n        return PointJacobi(self.__curve, X3, Y3, Z3, self.__order)\n\n    def __mul__(self, other):\n        \"\"\"Multiply point by an integer.\"\"\"\n        if not self.__coords[1] or not other:\n            return INFINITY\n        if other == 1:\n            return self\n        if self.__order:\n            # order*2 as a protection for Minerva\n            other = other % (self.__order * 2)\n        self._maybe_precompute()\n        if self.__precompute:\n            return self._mul_precompute(other)\n\n        self = self.scale()\n        X2, Y2, _ = self.__coords\n        X3, Y3, Z3 = 0, 0, 1\n        p, a = self.__curve.p(), self.__curve.a()\n        _double = self._double\n        _add = self._add\n        # since adding points when at least one of them is scaled\n        # is quicker, reverse the NAF order\n        for i in reversed(self._naf(other)):\n            X3, Y3, Z3 = _double(X3, Y3, Z3, p, a)\n            if i < 0:\n                X3, Y3, Z3 = _add(X3, Y3, Z3, X2, -Y2, 1, p)\n            elif i > 0:\n                X3, Y3, Z3 = _add(X3, Y3, Z3, X2, Y2, 1, p)\n\n        if not Y3 or not Z3:\n            return INFINITY\n\n        return PointJacobi(self.__curve, X3, Y3, Z3, self.__order)\n\n    def mul_add(self, self_mul, other, other_mul):\n        \"\"\"\n        Do two multiplications at the same time, add results.\n\n        calculates self*self_mul + other*other_mul\n        \"\"\"\n        if other == INFINITY or other_mul == 0:\n            return self * self_mul\n        if self_mul == 0:\n            return other * other_mul\n        if not isinstance(other, PointJacobi):\n            other = PointJacobi.from_affine(other)\n        # when the points have precomputed answers, then multiplying them alone\n        # is faster (as it uses NAF and no point doublings)\n        self._maybe_precompute()\n        other._maybe_precompute()\n        if self.__precompute and other.__precompute:\n            return self * self_mul + other * other_mul\n\n        if self.__order:\n            self_mul = self_mul % self.__order\n            other_mul = other_mul % self.__order\n\n        # (X3, Y3, Z3) is the accumulator\n        X3, Y3, Z3 = 0, 0, 1\n        p, a = self.__curve.p(), self.__curve.a()\n\n        # as we have 6 unique points to work with, we can't scale all of them,\n        # but do scale the ones that are used most often\n        self.scale()\n        X1, Y1, Z1 = self.__coords\n        other.scale()\n        X2, Y2, Z2 = other.__coords\n\n        _double = self._double\n        _add = self._add\n\n        # with NAF we have 3 options: no add, subtract, add\n        # so with 2 points, we have 9 combinations:\n        # 0, -A, +A, -B, -A-B, +A-B, +B, -A+B, +A+B\n        # so we need 4 combined points:\n        mAmB_X, mAmB_Y, mAmB_Z = _add(X1, -Y1, Z1, X2, -Y2, Z2, p)\n        pAmB_X, pAmB_Y, pAmB_Z = _add(X1, Y1, Z1, X2, -Y2, Z2, p)\n        mApB_X, mApB_Y, mApB_Z = _add(X1, -Y1, Z1, X2, Y2, Z2, p)\n        pApB_X, pApB_Y, pApB_Z = _add(X1, Y1, Z1, X2, Y2, Z2, p)\n        # when the self and other sum to infinity, we need to add them\n        # one by one to get correct result but as that's very unlikely to\n        # happen in regular operation, we don't need to optimise this case\n        if not pApB_Y or not pApB_Z:\n            return self * self_mul + other * other_mul\n\n        # gmp object creation has cumulatively higher overhead than the\n        # speedup we get from calculating the NAF using gmp so ensure use\n        # of int()\n        self_naf = list(reversed(self._naf(int(self_mul))))\n        other_naf = list(reversed(self._naf(int(other_mul))))\n        # ensure that the lists are the same length (zip() will truncate\n        # longer one otherwise)\n        if len(self_naf) < len(other_naf):\n            self_naf = [0] * (len(other_naf) - len(self_naf)) + self_naf\n        elif len(self_naf) > len(other_naf):\n            other_naf = [0] * (len(self_naf) - len(other_naf)) + other_naf\n\n        for A, B in zip(self_naf, other_naf):\n            X3, Y3, Z3 = _double(X3, Y3, Z3, p, a)\n\n            # conditions ordered from most to least likely\n            if A == 0:\n                if B == 0:\n                    pass\n                elif B < 0:\n                    X3, Y3, Z3 = _add(X3, Y3, Z3, X2, -Y2, Z2, p)\n                else:\n                    assert B > 0\n                    X3, Y3, Z3 = _add(X3, Y3, Z3, X2, Y2, Z2, p)\n            elif A < 0:\n                if B == 0:\n                    X3, Y3, Z3 = _add(X3, Y3, Z3, X1, -Y1, Z1, p)\n                elif B < 0:\n                    X3, Y3, Z3 = _add(X3, Y3, Z3, mAmB_X, mAmB_Y, mAmB_Z, p)\n                else:\n                    assert B > 0\n                    X3, Y3, Z3 = _add(X3, Y3, Z3, mApB_X, mApB_Y, mApB_Z, p)\n            else:\n                assert A > 0\n                if B == 0:\n                    X3, Y3, Z3 = _add(X3, Y3, Z3, X1, Y1, Z1, p)\n                elif B < 0:\n                    X3, Y3, Z3 = _add(X3, Y3, Z3, pAmB_X, pAmB_Y, pAmB_Z, p)\n                else:\n                    assert B > 0\n                    X3, Y3, Z3 = _add(X3, Y3, Z3, pApB_X, pApB_Y, pApB_Z, p)\n\n        if not Y3 or not Z3:\n            return INFINITY\n\n        return PointJacobi(self.__curve, X3, Y3, Z3, self.__order)\n\n    def __neg__(self):\n        \"\"\"Return negated point.\"\"\"\n        x, y, z = self.__coords\n        return PointJacobi(self.__curve, x, -y, z, self.__order)\n\n\nclass Point(AbstractPoint):\n    \"\"\"A point on a short Weierstrass elliptic curve. Altering x and y is\n    forbidden, but they can be read by the x() and y() methods.\"\"\"\n\n    def __init__(self, curve, x, y, order=None):\n        \"\"\"curve, x, y, order; order (optional) is the order of this point.\"\"\"\n        super(Point, self).__init__()\n        self.__curve = curve\n        if GMPY:\n            self.__x = x and mpz(x)\n            self.__y = y and mpz(y)\n            self.__order = order and mpz(order)\n        else:\n            self.__x = x\n            self.__y = y\n            self.__order = order\n        # self.curve is allowed to be None only for INFINITY:\n        if self.__curve:\n            assert self.__curve.contains_point(x, y)\n        # for curves with cofactor 1, all points that are on the curve are\n        # scalar multiples of the base point, so performing multiplication is\n        # not necessary to verify that. See Section 3.2.2.1 of SEC 1 v2\n        if curve and curve.cofactor() != 1 and order:\n            assert self * order == INFINITY\n\n    @classmethod\n    def from_bytes(\n        cls,\n        curve,\n        data,\n        validate_encoding=True,\n        valid_encodings=None,\n        order=None,\n    ):\n        \"\"\"\n        Initialise the object from byte encoding of a point.\n\n        The method does accept and automatically detect the type of point\n        encoding used. It supports the :term:`raw encoding`,\n        :term:`uncompressed`, :term:`compressed`, and :term:`hybrid` encodings.\n\n        :param data: single point encoding of the public key\n        :type data: :term:`bytes-like object`\n        :param curve: the curve on which the public key is expected to lay\n        :type curve: ~ecdsa.ellipticcurve.CurveFp\n        :param validate_encoding: whether to verify that the encoding of the\n            point is self-consistent, defaults to True, has effect only\n            on ``hybrid`` encoding\n        :type validate_encoding: bool\n        :param valid_encodings: list of acceptable point encoding formats,\n            supported ones are: :term:`uncompressed`, :term:`compressed`,\n            :term:`hybrid`, and :term:`raw encoding` (specified with ``raw``\n            name). All formats by default (specified with ``None``).\n        :type valid_encodings: :term:`set-like object`\n        :param int order: the point order, must be non zero when using\n            generator=True\n\n        :raises `~ecdsa.errors.MalformedPointError`: if the public point does\n            not lay on the curve or the encoding is invalid\n\n        :return: Point on curve\n        :rtype: Point\n        \"\"\"\n        coord_x, coord_y = super(Point, cls).from_bytes(\n            curve, data, validate_encoding, valid_encodings\n        )\n        return Point(curve, coord_x, coord_y, order)\n\n    def __eq__(self, other):\n        \"\"\"Return True if the points are identical, False otherwise.\n\n        Note: only points that lay on the same curve can be equal.\n        \"\"\"\n        if isinstance(other, Point):\n            return (\n                self.__curve == other.__curve\n                and self.__x == other.__x\n                and self.__y == other.__y\n            )\n        return NotImplemented\n\n    def __ne__(self, other):\n        \"\"\"Returns False if points are identical, True otherwise.\"\"\"\n        return not self == other\n\n    def __neg__(self):\n        return Point(self.__curve, self.__x, self.__curve.p() - self.__y)\n\n    def __add__(self, other):\n        \"\"\"Add one point to another point.\"\"\"\n\n        # X9.62 B.3:\n\n        if not isinstance(other, Point):\n            return NotImplemented\n        if other == INFINITY:\n            return self\n        if self == INFINITY:\n            return other\n        assert self.__curve == other.__curve\n        if self.__x == other.__x:\n            if (self.__y + other.__y) % self.__curve.p() == 0:\n                return INFINITY\n            else:\n                return self.double()\n\n        p = self.__curve.p()\n\n        l = (\n            (other.__y - self.__y)\n            * numbertheory.inverse_mod(other.__x - self.__x, p)\n        ) % p\n\n        x3 = (l * l - self.__x - other.__x) % p\n        y3 = (l * (self.__x - x3) - self.__y) % p\n\n        return Point(self.__curve, x3, y3)\n\n    def __mul__(self, other):\n        \"\"\"Multiply a point by an integer.\"\"\"\n\n        def leftmost_bit(x):\n            assert x > 0\n            result = 1\n            while result <= x:\n                result = 2 * result\n            return result // 2\n\n        e = other\n        if e == 0 or (self.__order and e % self.__order == 0):\n            return INFINITY\n        if self == INFINITY:\n            return INFINITY\n        if e < 0:\n            return (-self) * (-e)\n\n        # From X9.62 D.3.2:\n\n        e3 = 3 * e\n        negative_self = Point(self.__curve, self.__x, -self.__y, self.__order)\n        i = leftmost_bit(e3) // 2\n        result = self\n        # print_(\"Multiplying %s by %d (e3 = %d):\" % (self, other, e3))\n        while i > 1:\n            result = result.double()\n            if (e3 & i) != 0 and (e & i) == 0:\n                result = result + self\n            if (e3 & i) == 0 and (e & i) != 0:\n                result = result + negative_self\n            # print_(\". . . i = %d, result = %s\" % ( i, result ))\n            i = i // 2\n\n        return result\n\n    def __rmul__(self, other):\n        \"\"\"Multiply a point by an integer.\"\"\"\n\n        return self * other\n\n    def __str__(self):\n        if self == INFINITY:\n            return \"infinity\"\n        return \"(%d,%d)\" % (self.__x, self.__y)\n\n    def double(self):\n        \"\"\"Return a new point that is twice the old.\"\"\"\n\n        if self == INFINITY:\n            return INFINITY\n\n        # X9.62 B.3:\n\n        p = self.__curve.p()\n        a = self.__curve.a()\n\n        l = (\n            (3 * self.__x * self.__x + a)\n            * numbertheory.inverse_mod(2 * self.__y, p)\n        ) % p\n\n        x3 = (l * l - 2 * self.__x) % p\n        y3 = (l * (self.__x - x3) - self.__y) % p\n\n        return Point(self.__curve, x3, y3)\n\n    def x(self):\n        return self.__x\n\n    def y(self):\n        return self.__y\n\n    def curve(self):\n        return self.__curve\n\n    def order(self):\n        return self.__order\n\n\nclass PointEdwards(AbstractPoint):\n    \"\"\"Point on Twisted Edwards curve.\n\n    Internally represents the coordinates on the curve using four parameters,\n    X, Y, Z, T. They correspond to affine parameters 'x' and 'y' like so:\n\n    x = X / Z\n    y = Y / Z\n    x*y = T / Z\n    \"\"\"\n\n    def __init__(self, curve, x, y, z, t, order=None, generator=False):\n        \"\"\"\n        Initialise a point that uses the extended coordinates internally.\n        \"\"\"\n        super(PointEdwards, self).__init__()\n        self.__curve = curve\n        if GMPY:  # pragma: no branch\n            self.__coords = (mpz(x), mpz(y), mpz(z), mpz(t))\n            self.__order = order and mpz(order)\n        else:  # pragma: no branch\n            self.__coords = (x, y, z, t)\n            self.__order = order\n        self.__generator = generator\n        self.__precompute = []\n\n    @classmethod\n    def from_bytes(\n        cls,\n        curve,\n        data,\n        validate_encoding=None,\n        valid_encodings=None,\n        order=None,\n        generator=False,\n    ):\n        \"\"\"\n        Initialise the object from byte encoding of a point.\n\n        `validate_encoding` and `valid_encodings` are provided for\n        compatibility with Weierstrass curves, they are ignored for Edwards\n        points.\n\n        :param data: single point encoding of the public key\n        :type data: :term:`bytes-like object`\n        :param curve: the curve on which the public key is expected to lay\n        :type curve: ecdsa.ellipticcurve.CurveEdTw\n        :param None validate_encoding: Ignored, encoding is always validated\n        :param None valid_encodings: Ignored, there is just one encoding\n            supported\n        :param int order: the point order, must be non zero when using\n            generator=True\n        :param bool generator: Flag to mark the point as a curve generator,\n            this will cause the library to pre-compute some values to\n            make repeated usages of the point much faster\n\n        :raises `~ecdsa.errors.MalformedPointError`: if the public point does\n            not lay on the curve or the encoding is invalid\n\n        :return: Initialised point on an Edwards curve\n        :rtype: PointEdwards\n        \"\"\"\n        coord_x, coord_y = super(PointEdwards, cls).from_bytes(\n            curve, data, validate_encoding, valid_encodings\n        )\n        return PointEdwards(\n            curve, coord_x, coord_y, 1, coord_x * coord_y, order, generator\n        )\n\n    def _maybe_precompute(self):\n        if not self.__generator or self.__precompute:\n            return self.__precompute\n\n        # since this code will execute just once, and it's fully deterministic,\n        # depend on atomicity of the last assignment to switch from empty\n        # self.__precompute to filled one and just ignore the unlikely\n        # situation when two threads execute it at the same time (as it won't\n        # lead to inconsistent __precompute)\n        order = self.__order\n        assert order\n        precompute = []\n        i = 1\n        order *= 2\n        coord_x, coord_y, coord_z, coord_t = self.__coords\n        prime = self.__curve.p()\n\n        doubler = PointEdwards(\n            self.__curve, coord_x, coord_y, coord_z, coord_t, order\n        )\n        # for \"protection\" against Minerva we need 1 or 2 more bits depending\n        # on order bit size, but it's easier to just calculate one\n        # point more always\n        order *= 4\n\n        while i < order:\n            doubler = doubler.scale()\n            coord_x, coord_y = doubler.x(), doubler.y()\n            coord_t = coord_x * coord_y % prime\n            precompute.append((coord_x, coord_y, coord_t))\n\n            i *= 2\n            doubler = doubler.double()\n\n        self.__precompute = precompute\n        return self.__precompute\n\n    def x(self):\n        \"\"\"Return affine x coordinate.\"\"\"\n        X1, _, Z1, _ = self.__coords\n        if Z1 == 1:\n            return X1\n        p = self.__curve.p()\n        z_inv = numbertheory.inverse_mod(Z1, p)\n        return X1 * z_inv % p\n\n    def y(self):\n        \"\"\"Return affine y coordinate.\"\"\"\n        _, Y1, Z1, _ = self.__coords\n        if Z1 == 1:\n            return Y1\n        p = self.__curve.p()\n        z_inv = numbertheory.inverse_mod(Z1, p)\n        return Y1 * z_inv % p\n\n    def curve(self):\n        \"\"\"Return the curve of the point.\"\"\"\n        return self.__curve\n\n    def order(self):\n        return self.__order\n\n    def scale(self):\n        \"\"\"\n        Return point scaled so that z == 1.\n\n        Modifies point in place, returns self.\n        \"\"\"\n        X1, Y1, Z1, _ = self.__coords\n        if Z1 == 1:\n            return self\n\n        p = self.__curve.p()\n        z_inv = numbertheory.inverse_mod(Z1, p)\n        x = X1 * z_inv % p\n        y = Y1 * z_inv % p\n        t = x * y % p\n        self.__coords = (x, y, 1, t)\n        return self\n\n    def __eq__(self, other):\n        \"\"\"Compare for equality two points with each-other.\n\n        Note: only points on the same curve can be equal.\n        \"\"\"\n        x1, y1, z1, t1 = self.__coords\n        if other is INFINITY:\n            return not x1 or not t1\n        if isinstance(other, PointEdwards):\n            x2, y2, z2, t2 = other.__coords\n        else:\n            return NotImplemented\n        if self.__curve != other.curve():\n            return False\n        p = self.__curve.p()\n\n        # cross multiply to eliminate divisions\n        xn1 = x1 * z2 % p\n        xn2 = x2 * z1 % p\n        yn1 = y1 * z2 % p\n        yn2 = y2 * z1 % p\n        return xn1 == xn2 and yn1 == yn2\n\n    def __ne__(self, other):\n        \"\"\"Compare for inequality two points with each-other.\"\"\"\n        return not self == other\n\n    def _add(self, X1, Y1, Z1, T1, X2, Y2, Z2, T2, p, a):\n        \"\"\"add two points, assume sane parameters.\"\"\"\n        # after add-2008-hwcd-2\n        # from https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html\n        # NOTE: there are more efficient formulas for Z1 or Z2 == 1\n        A = X1 * X2 % p\n        B = Y1 * Y2 % p\n        C = Z1 * T2 % p\n        D = T1 * Z2 % p\n        E = D + C\n        F = ((X1 - Y1) * (X2 + Y2) + B - A) % p\n        G = B + a * A\n        H = D - C\n        if not H:\n            return self._double(X1, Y1, Z1, T1, p, a)\n        X3 = E * F % p\n        Y3 = G * H % p\n        T3 = E * H % p\n        Z3 = F * G % p\n\n        return X3, Y3, Z3, T3\n\n    def __add__(self, other):\n        \"\"\"Add point to another.\"\"\"\n        if other == INFINITY:\n            return self\n        if (\n            not isinstance(other, PointEdwards)\n            or self.__curve != other.__curve\n        ):\n            raise ValueError(\"The other point is on a different curve.\")\n\n        p, a = self.__curve.p(), self.__curve.a()\n        X1, Y1, Z1, T1 = self.__coords\n        X2, Y2, Z2, T2 = other.__coords\n\n        X3, Y3, Z3, T3 = self._add(X1, Y1, Z1, T1, X2, Y2, Z2, T2, p, a)\n\n        if not X3 or not T3:\n            return INFINITY\n        return PointEdwards(self.__curve, X3, Y3, Z3, T3, self.__order)\n\n    def __radd__(self, other):\n        \"\"\"Add other to self.\"\"\"\n        return self + other\n\n    def _double(self, X1, Y1, Z1, T1, p, a):\n        \"\"\"Double the point, assume sane parameters.\"\"\"\n        # after \"dbl-2008-hwcd\"\n        # from https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html\n        # NOTE: there are more efficient formulas for Z1 == 1\n        A = X1 * X1 % p\n        B = Y1 * Y1 % p\n        C = 2 * Z1 * Z1 % p\n        D = a * A % p\n        E = ((X1 + Y1) * (X1 + Y1) - A - B) % p\n        G = D + B\n        F = G - C\n        H = D - B\n        X3 = E * F % p\n        Y3 = G * H % p\n        T3 = E * H % p\n        Z3 = F * G % p\n\n        return X3, Y3, Z3, T3\n\n    def double(self):\n        \"\"\"Return point added to itself.\"\"\"\n        X1, Y1, Z1, T1 = self.__coords\n\n        if not X1 or not T1:\n            return INFINITY\n\n        p, a = self.__curve.p(), self.__curve.a()\n\n        X3, Y3, Z3, T3 = self._double(X1, Y1, Z1, T1, p, a)\n\n        if not X3 or not T3:\n            return INFINITY\n        return PointEdwards(self.__curve, X3, Y3, Z3, T3, self.__order)\n\n    def __rmul__(self, other):\n        \"\"\"Multiply point by an integer.\"\"\"\n        return self * other\n\n    def _mul_precompute(self, other):\n        \"\"\"Multiply point by integer with precomputation table.\"\"\"\n        X3, Y3, Z3, T3, p, a = 0, 1, 1, 0, self.__curve.p(), self.__curve.a()\n        _add = self._add\n        for X2, Y2, T2 in self.__precompute:\n            rem = other % 4\n            if rem == 0 or rem == 2:\n                other //= 2\n            elif rem == 3:\n                other = (other + 1) // 2\n                X3, Y3, Z3, T3 = _add(X3, Y3, Z3, T3, -X2, Y2, 1, -T2, p, a)\n            else:\n                assert rem == 1\n                other = (other - 1) // 2\n                X3, Y3, Z3, T3 = _add(X3, Y3, Z3, T3, X2, Y2, 1, T2, p, a)\n\n        if not X3 or not T3:\n            return INFINITY\n\n        return PointEdwards(self.__curve, X3, Y3, Z3, T3, self.__order)\n\n    def __mul__(self, other):\n        \"\"\"Multiply point by an integer.\"\"\"\n        X2, Y2, Z2, T2 = self.__coords\n        if not X2 or not T2 or not other:\n            return INFINITY\n        if other == 1:\n            return self\n        if self.__order:\n            # order*2 as a \"protection\" for Minerva\n            other = other % (self.__order * 2)\n        if self._maybe_precompute():\n            return self._mul_precompute(other)\n\n        X3, Y3, Z3, T3 = 0, 1, 1, 0  # INFINITY in extended coordinates\n        p, a = self.__curve.p(), self.__curve.a()\n        _double = self._double\n        _add = self._add\n\n        for i in reversed(self._naf(other)):\n            X3, Y3, Z3, T3 = _double(X3, Y3, Z3, T3, p, a)\n            if i < 0:\n                X3, Y3, Z3, T3 = _add(X3, Y3, Z3, T3, -X2, Y2, Z2, -T2, p, a)\n            elif i > 0:\n                X3, Y3, Z3, T3 = _add(X3, Y3, Z3, T3, X2, Y2, Z2, T2, p, a)\n\n        if not X3 or not T3:\n            return INFINITY\n\n        return PointEdwards(self.__curve, X3, Y3, Z3, T3, self.__order)\n\n\n# This one point is the Point At Infinity for all purposes:\nINFINITY = Point(None, None, None)\n"
  },
  {
    "path": "code/default/lib/noarch/ecdsa/errors.py",
    "content": "class MalformedPointError(AssertionError):\n    \"\"\"Raised in case the encoding of private or public key is malformed.\"\"\"\n\n    pass\n"
  },
  {
    "path": "code/default/lib/noarch/ecdsa/keys.py",
    "content": "\"\"\"\nPrimary classes for performing signing and verification operations.\n\"\"\"\n\nimport binascii\nfrom hashlib import sha1\nimport os\nfrom six import PY2, b\nfrom . import ecdsa, eddsa\nfrom . import der\nfrom . import rfc6979\nfrom . import ellipticcurve\nfrom .curves import NIST192p, Curve, Ed25519, Ed448\nfrom .ecdsa import RSZeroError\nfrom .util import string_to_number, number_to_string, randrange\nfrom .util import sigencode_string, sigdecode_string, bit_length\nfrom .util import (\n    oid_ecPublicKey,\n    encoded_oid_ecPublicKey,\n    oid_ecDH,\n    oid_ecMQV,\n    MalformedSignature,\n)\nfrom ._compat import normalise_bytes\nfrom .errors import MalformedPointError\nfrom .ellipticcurve import PointJacobi, CurveEdTw\n\n\n__all__ = [\n    \"BadSignatureError\",\n    \"BadDigestError\",\n    \"VerifyingKey\",\n    \"SigningKey\",\n    \"MalformedPointError\",\n]\n\n\nclass BadSignatureError(Exception):\n    \"\"\"\n    Raised when verification of signature failed.\n\n    Will be raised irrespective of reason of the failure:\n\n    * the calculated or provided hash does not match the signature\n    * the signature does not match the curve/public key\n    * the encoding of the signature is malformed\n    * the size of the signature does not match the curve of the VerifyingKey\n    \"\"\"\n\n    pass\n\n\nclass BadDigestError(Exception):\n    \"\"\"Raised in case the selected hash is too large for the curve.\"\"\"\n\n    pass\n\n\ndef _truncate_and_convert_digest(digest, curve, allow_truncate):\n    \"\"\"Truncates and converts digest to an integer.\"\"\"\n    if not allow_truncate:\n        if len(digest) > curve.baselen:\n            raise BadDigestError(\n                \"this curve ({0}) is too short \"\n                \"for the length of your digest ({1})\".format(\n                    curve.name, 8 * len(digest)\n                )\n            )\n    else:\n        digest = digest[: curve.baselen]\n    number = string_to_number(digest)\n    if allow_truncate:\n        max_length = bit_length(curve.order)\n        # we don't use bit_length(number) as that truncates leading zeros\n        length = len(digest) * 8\n\n        # See NIST FIPS 186-4:\n        #\n        # When the length of the output of the hash function is greater\n        # than N (i.e., the bit length of q), then the leftmost N bits of\n        # the hash function output block shall be used in any calculation\n        # using the hash function output during the generation or\n        # verification of a digital signature.\n        #\n        # as such, we need to shift-out the low-order bits:\n        number >>= max(0, length - max_length)\n\n    return number\n\n\nclass VerifyingKey(object):\n    \"\"\"\n    Class for handling keys that can verify signatures (public keys).\n\n    :ivar `~ecdsa.curves.Curve` ~.curve: The Curve over which all the\n        cryptographic operations will take place\n    :ivar default_hashfunc: the function that will be used for hashing the\n        data. Should implement the same API as hashlib.sha1\n    :vartype default_hashfunc: callable\n    :ivar pubkey: the actual public key\n    :vartype pubkey: ~ecdsa.ecdsa.Public_key\n    \"\"\"\n\n    def __init__(self, _error__please_use_generate=None):\n        \"\"\"Unsupported, please use one of the classmethods to initialise.\"\"\"\n        if not _error__please_use_generate:\n            raise TypeError(\n                \"Please use VerifyingKey.generate() to construct me\"\n            )\n        self.curve = None\n        self.default_hashfunc = None\n        self.pubkey = None\n\n    def __repr__(self):\n        pub_key = self.to_string(\"compressed\")\n        if self.default_hashfunc:\n            hash_name = self.default_hashfunc().name\n        else:\n            hash_name = \"None\"\n        return \"VerifyingKey.from_string({0!r}, {1!r}, {2})\".format(\n            pub_key, self.curve, hash_name\n        )\n\n    def __eq__(self, other):\n        \"\"\"Return True if the points are identical, False otherwise.\"\"\"\n        if isinstance(other, VerifyingKey):\n            return self.curve == other.curve and self.pubkey == other.pubkey\n        return NotImplemented\n\n    def __ne__(self, other):\n        \"\"\"Return False if the points are identical, True otherwise.\"\"\"\n        return not self == other\n\n    @classmethod\n    def from_public_point(\n        cls, point, curve=NIST192p, hashfunc=sha1, validate_point=True\n    ):\n        \"\"\"\n        Initialise the object from a Point object.\n\n        This is a low-level method, generally you will not want to use it.\n\n        :param point: The point to wrap around, the actual public key\n        :type point: ~ecdsa.ellipticcurve.AbstractPoint\n        :param curve: The curve on which the point needs to reside, defaults\n            to NIST192p\n        :type curve: ~ecdsa.curves.Curve\n        :param hashfunc: The default hash function that will be used for\n            verification, needs to implement the same interface\n            as :py:class:`hashlib.sha1`\n        :type hashfunc: callable\n        :type bool validate_point: whether to check if the point lays on curve\n            should always be used if the public point is not a result\n            of our own calculation\n\n        :raises MalformedPointError: if the public point does not lay on the\n            curve\n\n        :return: Initialised VerifyingKey object\n        :rtype: VerifyingKey\n        \"\"\"\n        self = cls(_error__please_use_generate=True)\n        if isinstance(curve.curve, CurveEdTw):\n            raise ValueError(\"Method incompatible with Edwards curves\")\n        if not isinstance(point, ellipticcurve.PointJacobi):\n            point = ellipticcurve.PointJacobi.from_affine(point)\n        self.curve = curve\n        self.default_hashfunc = hashfunc\n        try:\n            self.pubkey = ecdsa.Public_key(\n                curve.generator, point, validate_point\n            )\n        except ecdsa.InvalidPointError:\n            raise MalformedPointError(\"Point does not lay on the curve\")\n        self.pubkey.order = curve.order\n        return self\n\n    def precompute(self, lazy=False):\n        \"\"\"\n        Precompute multiplication tables for faster signature verification.\n\n        Calling this method will cause the library to precompute the\n        scalar multiplication tables, used in signature verification.\n        While it's an expensive operation (comparable to performing\n        as many signatures as the bit size of the curve, i.e. 256 for NIST256p)\n        it speeds up verification 2 times. You should call this method\n        if you expect to verify hundreds of signatures (or more) using the same\n        VerifyingKey object.\n\n        Note: You should call this method only once, this method generates a\n        new precomputation table every time it's called.\n\n        :param bool lazy: whether to calculate the precomputation table now\n           (if set to False) or if it should be delayed to the time of first\n           use (when set to True)\n        \"\"\"\n        if isinstance(self.curve.curve, CurveEdTw):\n            pt = self.pubkey.point\n            self.pubkey.point = ellipticcurve.PointEdwards(\n                pt.curve(),\n                pt.x(),\n                pt.y(),\n                1,\n                pt.x() * pt.y(),\n                self.curve.order,\n                generator=True,\n            )\n        else:\n            self.pubkey.point = ellipticcurve.PointJacobi.from_affine(\n                self.pubkey.point, True\n            )\n        # as precomputation in now delayed to the time of first use of the\n        # point and we were asked specifically to precompute now, make\n        # sure the precomputation is performed now to preserve the behaviour\n        if not lazy:\n            self.pubkey.point * 2\n\n    @classmethod\n    def from_string(\n        cls,\n        string,\n        curve=NIST192p,\n        hashfunc=sha1,\n        validate_point=True,\n        valid_encodings=None,\n    ):\n        \"\"\"\n        Initialise the object from byte encoding of public key.\n\n        The method does accept and automatically detect the type of point\n        encoding used. It supports the :term:`raw encoding`,\n        :term:`uncompressed`, :term:`compressed`, and :term:`hybrid` encodings.\n        It also works with the native encoding of Ed25519 and Ed448 public\n        keys (technically those are compressed, but encoded differently than\n        in other signature systems).\n\n        Note, while the method is named \"from_string\" it's a misnomer from\n        Python 2 days when there were no binary strings. In Python 3 the\n        input needs to be a bytes-like object.\n\n        :param string: single point encoding of the public key\n        :type string: :term:`bytes-like object`\n        :param curve: the curve on which the public key is expected to lay\n        :type curve: ~ecdsa.curves.Curve\n        :param hashfunc: The default hash function that will be used for\n            verification, needs to implement the same interface as\n            hashlib.sha1. Ignored for EdDSA.\n        :type hashfunc: callable\n        :param validate_point: whether to verify that the point lays on the\n            provided curve or not, defaults to True. Ignored for EdDSA.\n        :type validate_point: bool\n        :param valid_encodings: list of acceptable point encoding formats,\n            supported ones are: :term:`uncompressed`, :term:`compressed`,\n            :term:`hybrid`, and :term:`raw encoding` (specified with ``raw``\n            name). All formats by default (specified with ``None``).\n            Ignored for EdDSA.\n        :type valid_encodings: :term:`set-like object`\n\n        :raises MalformedPointError: if the public point does not lay on the\n            curve or the encoding is invalid\n\n        :return: Initialised VerifyingKey object\n        :rtype: VerifyingKey\n        \"\"\"\n        if isinstance(curve.curve, CurveEdTw):\n            self = cls(_error__please_use_generate=True)\n            self.curve = curve\n            self.default_hashfunc = None  # ignored for EdDSA\n            try:\n                self.pubkey = eddsa.PublicKey(curve.generator, string)\n            except ValueError:\n                raise MalformedPointError(\"Malformed point for the curve\")\n            return self\n\n        point = PointJacobi.from_bytes(\n            curve.curve,\n            string,\n            validate_encoding=validate_point,\n            valid_encodings=valid_encodings,\n        )\n        return cls.from_public_point(point, curve, hashfunc, validate_point)\n\n    @classmethod\n    def from_pem(\n        cls,\n        string,\n        hashfunc=sha1,\n        valid_encodings=None,\n        valid_curve_encodings=None,\n    ):\n        \"\"\"\n        Initialise from public key stored in :term:`PEM` format.\n\n        The PEM header of the key should be ``BEGIN PUBLIC KEY``.\n\n        See the :func:`~VerifyingKey.from_der()` method for details of the\n        format supported.\n\n        Note: only a single PEM object decoding is supported in provided\n        string.\n\n        :param string: text with PEM-encoded public ECDSA key\n        :type string: str\n        :param valid_encodings: list of allowed point encodings.\n            By default :term:`uncompressed`, :term:`compressed`, and\n            :term:`hybrid`. To read malformed files, include\n            :term:`raw encoding` with ``raw`` in the list.\n        :type valid_encodings: :term:`set-like object`\n        :param valid_curve_encodings: list of allowed encoding formats\n            for curve parameters. By default (``None``) all are supported:\n            ``named_curve`` and ``explicit``.\n        :type valid_curve_encodings: :term:`set-like object`\n\n\n        :return: Initialised VerifyingKey object\n        :rtype: VerifyingKey\n        \"\"\"\n        return cls.from_der(\n            der.unpem(string),\n            hashfunc=hashfunc,\n            valid_encodings=valid_encodings,\n            valid_curve_encodings=valid_curve_encodings,\n        )\n\n    @classmethod\n    def from_der(\n        cls,\n        string,\n        hashfunc=sha1,\n        valid_encodings=None,\n        valid_curve_encodings=None,\n    ):\n        \"\"\"\n        Initialise the key stored in :term:`DER` format.\n\n        The expected format of the key is the SubjectPublicKeyInfo structure\n        from RFC5912 (for RSA keys, it's known as the PKCS#1 format)::\n\n           SubjectPublicKeyInfo {PUBLIC-KEY: IOSet} ::= SEQUENCE {\n               algorithm        AlgorithmIdentifier {PUBLIC-KEY, {IOSet}},\n               subjectPublicKey BIT STRING\n           }\n\n        Note: only public EC keys are supported by this method. The\n        SubjectPublicKeyInfo.algorithm.algorithm field must specify\n        id-ecPublicKey (see RFC3279).\n\n        Only the named curve encoding is supported, thus the\n        SubjectPublicKeyInfo.algorithm.parameters field needs to be an\n        object identifier. A sequence in that field indicates an explicit\n        parameter curve encoding, this format is not supported. A NULL object\n        in that field indicates an \"implicitlyCA\" encoding, where the curve\n        parameters come from CA certificate, those, again, are not supported.\n\n        :param string: binary string with the DER encoding of public ECDSA key\n        :type string: bytes-like object\n        :param valid_encodings: list of allowed point encodings.\n            By default :term:`uncompressed`, :term:`compressed`, and\n            :term:`hybrid`. To read malformed files, include\n            :term:`raw encoding` with ``raw`` in the list.\n        :type valid_encodings: :term:`set-like object`\n        :param valid_curve_encodings: list of allowed encoding formats\n            for curve parameters. By default (``None``) all are supported:\n            ``named_curve`` and ``explicit``.\n        :type valid_curve_encodings: :term:`set-like object`\n\n        :return: Initialised VerifyingKey object\n        :rtype: VerifyingKey\n        \"\"\"\n        if valid_encodings is None:\n            valid_encodings = set([\"uncompressed\", \"compressed\", \"hybrid\"])\n        string = normalise_bytes(string)\n        # [[oid_ecPublicKey,oid_curve], point_str_bitstring]\n        s1, empty = der.remove_sequence(string)\n        if empty != b\"\":\n            raise der.UnexpectedDER(\n                \"trailing junk after DER pubkey: %s\" % binascii.hexlify(empty)\n            )\n        s2, point_str_bitstring = der.remove_sequence(s1)\n        # s2 = oid_ecPublicKey,oid_curve\n        oid_pk, rest = der.remove_object(s2)\n        if oid_pk in (Ed25519.oid, Ed448.oid):\n            if oid_pk == Ed25519.oid:\n                curve = Ed25519\n            else:\n                assert oid_pk == Ed448.oid\n                curve = Ed448\n            point_str, empty = der.remove_bitstring(point_str_bitstring, 0)\n            if empty:\n                raise der.UnexpectedDER(\"trailing junk after public key\")\n            return cls.from_string(point_str, curve, None)\n        if not oid_pk == oid_ecPublicKey:\n            raise der.UnexpectedDER(\n                \"Unexpected object identifier in DER \"\n                \"encoding: {0!r}\".format(oid_pk)\n            )\n        curve = Curve.from_der(rest, valid_curve_encodings)\n        point_str, empty = der.remove_bitstring(point_str_bitstring, 0)\n        if empty != b\"\":\n            raise der.UnexpectedDER(\n                \"trailing junk after pubkey pointstring: %s\"\n                % binascii.hexlify(empty)\n            )\n        # raw encoding of point is invalid in DER files\n        if len(point_str) == curve.verifying_key_length:\n            raise der.UnexpectedDER(\"Malformed encoding of public point\")\n        return cls.from_string(\n            point_str,\n            curve,\n            hashfunc=hashfunc,\n            valid_encodings=valid_encodings,\n        )\n\n    @classmethod\n    def from_public_key_recovery(\n        cls,\n        signature,\n        data,\n        curve,\n        hashfunc=sha1,\n        sigdecode=sigdecode_string,\n        allow_truncate=True,\n    ):\n        \"\"\"\n        Return keys that can be used as verifiers of the provided signature.\n\n        Tries to recover the public key that can be used to verify the\n        signature, usually returns two keys like that.\n\n        :param signature: the byte string with the encoded signature\n        :type signature: bytes-like object\n        :param data: the data to be hashed for signature verification\n        :type data: bytes-like object\n        :param curve: the curve over which the signature was performed\n        :type curve: ~ecdsa.curves.Curve\n        :param hashfunc: The default hash function that will be used for\n            verification, needs to implement the same interface as hashlib.sha1\n        :type hashfunc: callable\n        :param sigdecode: Callable to define the way the signature needs to\n            be decoded to an object, needs to handle `signature` as the\n            first parameter, the curve order (an int) as the second and return\n            a tuple with two integers, \"r\" as the first one and \"s\" as the\n            second one. See :func:`ecdsa.util.sigdecode_string` and\n            :func:`ecdsa.util.sigdecode_der` for examples.\n        :param bool allow_truncate: if True, the provided hashfunc can generate\n            values larger than the bit size of the order of the curve, the\n            extra bits (at the end of the digest) will be truncated.\n        :type sigdecode: callable\n\n        :return: Initialised VerifyingKey objects\n        :rtype: list of VerifyingKey\n        \"\"\"\n        if isinstance(curve.curve, CurveEdTw):\n            raise ValueError(\"Method unsupported for Edwards curves\")\n        data = normalise_bytes(data)\n        digest = hashfunc(data).digest()\n        return cls.from_public_key_recovery_with_digest(\n            signature,\n            digest,\n            curve,\n            hashfunc=hashfunc,\n            sigdecode=sigdecode,\n            allow_truncate=allow_truncate,\n        )\n\n    @classmethod\n    def from_public_key_recovery_with_digest(\n        cls,\n        signature,\n        digest,\n        curve,\n        hashfunc=sha1,\n        sigdecode=sigdecode_string,\n        allow_truncate=False,\n    ):\n        \"\"\"\n        Return keys that can be used as verifiers of the provided signature.\n\n        Tries to recover the public key that can be used to verify the\n        signature, usually returns two keys like that.\n\n        :param signature: the byte string with the encoded signature\n        :type signature: bytes-like object\n        :param digest: the hash value of the message signed by the signature\n        :type digest: bytes-like object\n        :param curve: the curve over which the signature was performed\n        :type curve: ~ecdsa.curves.Curve\n        :param hashfunc: The default hash function that will be used for\n            verification, needs to implement the same interface as hashlib.sha1\n        :type hashfunc: callable\n        :param sigdecode: Callable to define the way the signature needs to\n            be decoded to an object, needs to handle `signature` as the\n            first parameter, the curve order (an int) as the second and return\n            a tuple with two integers, \"r\" as the first one and \"s\" as the\n            second one. See :func:`ecdsa.util.sigdecode_string` and\n            :func:`ecdsa.util.sigdecode_der` for examples.\n        :type sigdecode: callable\n        :param bool allow_truncate: if True, the provided hashfunc can generate\n            values larger than the bit size of the order of the curve (and\n            the length of provided `digest`), the extra bits (at the end of the\n            digest) will be truncated.\n\n        :return: Initialised VerifyingKey object\n        :rtype: VerifyingKey\n        \"\"\"\n        if isinstance(curve.curve, CurveEdTw):\n            raise ValueError(\"Method unsupported for Edwards curves\")\n        generator = curve.generator\n        r, s = sigdecode(signature, generator.order())\n        sig = ecdsa.Signature(r, s)\n\n        digest = normalise_bytes(digest)\n        digest_as_number = _truncate_and_convert_digest(\n            digest, curve, allow_truncate\n        )\n        pks = sig.recover_public_keys(digest_as_number, generator)\n\n        # Transforms the ecdsa.Public_key object into a VerifyingKey\n        verifying_keys = [\n            cls.from_public_point(pk.point, curve, hashfunc) for pk in pks\n        ]\n        return verifying_keys\n\n    def to_string(self, encoding=\"raw\"):\n        \"\"\"\n        Convert the public key to a byte string.\n\n        The method by default uses the :term:`raw encoding` (specified\n        by `encoding=\"raw\"`. It can also output keys in :term:`uncompressed`,\n        :term:`compressed` and :term:`hybrid` formats.\n\n        Remember that the curve identification is not part of the encoding\n        so to decode the point using :func:`~VerifyingKey.from_string`, curve\n        needs to be specified.\n\n        Note: while the method is called \"to_string\", it's a misnomer from\n        Python 2 days when character strings and byte strings shared type.\n        On Python 3 the returned type will be `bytes`.\n\n        :return: :term:`raw encoding` of the public key (public point) on the\n            curve\n        :rtype: bytes\n        \"\"\"\n        assert encoding in (\"raw\", \"uncompressed\", \"compressed\", \"hybrid\")\n        return self.pubkey.point.to_bytes(encoding)\n\n    def to_pem(\n        self, point_encoding=\"uncompressed\", curve_parameters_encoding=None\n    ):\n        \"\"\"\n        Convert the public key to the :term:`PEM` format.\n\n        The PEM header of the key will be ``BEGIN PUBLIC KEY``.\n\n        The format of the key is described in the\n        :func:`~VerifyingKey.from_der()` method.\n        This method supports only \"named curve\" encoding of keys.\n\n        :param str point_encoding: specification of the encoding format\n            of public keys. \"uncompressed\" is most portable, \"compressed\" is\n            smallest. \"hybrid\" is uncommon and unsupported by most\n            implementations, it is as big as \"uncompressed\".\n        :param str curve_parameters_encoding: the encoding for curve parameters\n            to use, by default tries to use ``named_curve`` encoding,\n            if that is not possible, falls back to ``explicit`` encoding.\n\n        :return: portable encoding of the public key\n        :rtype: bytes\n\n        .. warning:: The PEM is encoded to US-ASCII, it needs to be\n            re-encoded if the system is incompatible (e.g. uses UTF-16)\n        \"\"\"\n        return der.topem(\n            self.to_der(point_encoding, curve_parameters_encoding),\n            \"PUBLIC KEY\",\n        )\n\n    def to_der(\n        self, point_encoding=\"uncompressed\", curve_parameters_encoding=None\n    ):\n        \"\"\"\n        Convert the public key to the :term:`DER` format.\n\n        The format of the key is described in the\n        :func:`~VerifyingKey.from_der()` method.\n        This method supports only \"named curve\" encoding of keys.\n\n        :param str point_encoding: specification of the encoding format\n            of public keys. \"uncompressed\" is most portable, \"compressed\" is\n            smallest. \"hybrid\" is uncommon and unsupported by most\n            implementations, it is as big as \"uncompressed\".\n        :param str curve_parameters_encoding: the encoding for curve parameters\n            to use, by default tries to use ``named_curve`` encoding,\n            if that is not possible, falls back to ``explicit`` encoding.\n\n        :return: DER encoding of the public key\n        :rtype: bytes\n        \"\"\"\n        if point_encoding == \"raw\":\n            raise ValueError(\"raw point_encoding not allowed in DER\")\n        point_str = self.to_string(point_encoding)\n        if isinstance(self.curve.curve, CurveEdTw):\n            return der.encode_sequence(\n                der.encode_sequence(der.encode_oid(*self.curve.oid)),\n                der.encode_bitstring(bytes(point_str), 0),\n            )\n        return der.encode_sequence(\n            der.encode_sequence(\n                encoded_oid_ecPublicKey,\n                self.curve.to_der(curve_parameters_encoding, point_encoding),\n            ),\n            # 0 is the number of unused bits in the\n            # bit string\n            der.encode_bitstring(point_str, 0),\n        )\n\n    def verify(\n        self,\n        signature,\n        data,\n        hashfunc=None,\n        sigdecode=sigdecode_string,\n        allow_truncate=True,\n    ):\n        \"\"\"\n        Verify a signature made over provided data.\n\n        Will hash `data` to verify the signature.\n\n        By default expects signature in :term:`raw encoding`. Can also be used\n        to verify signatures in ASN.1 DER encoding by using\n        :func:`ecdsa.util.sigdecode_der`\n        as the `sigdecode` parameter.\n\n        :param signature: encoding of the signature\n        :type signature: sigdecode method dependent\n        :param data: data signed by the `signature`, will be hashed using\n            `hashfunc`, if specified, or default hash function\n        :type data: :term:`bytes-like object`\n        :param hashfunc: The default hash function that will be used for\n            verification, needs to implement the same interface as hashlib.sha1\n        :type hashfunc: callable\n        :param sigdecode: Callable to define the way the signature needs to\n            be decoded to an object, needs to handle `signature` as the\n            first parameter, the curve order (an int) as the second and return\n            a tuple with two integers, \"r\" as the first one and \"s\" as the\n            second one. See :func:`ecdsa.util.sigdecode_string` and\n            :func:`ecdsa.util.sigdecode_der` for examples.\n        :type sigdecode: callable\n        :param bool allow_truncate: if True, the provided digest can have\n            bigger bit-size than the order of the curve, the extra bits (at\n            the end of the digest) will be truncated. Use it when verifying\n            SHA-384 output using NIST256p or in similar situations. Defaults to\n            True.\n\n        :raises BadSignatureError: if the signature is invalid or malformed\n\n        :return: True if the verification was successful\n        :rtype: bool\n        \"\"\"\n        # signature doesn't have to be a bytes-like-object so don't normalise\n        # it, the decoders will do that\n        data = normalise_bytes(data)\n        if isinstance(self.curve.curve, CurveEdTw):\n            signature = normalise_bytes(signature)\n            try:\n                return self.pubkey.verify(data, signature)\n            except (ValueError, MalformedPointError) as e:\n                raise BadSignatureError(\"Signature verification failed\", e)\n\n        hashfunc = hashfunc or self.default_hashfunc\n        digest = hashfunc(data).digest()\n        return self.verify_digest(signature, digest, sigdecode, allow_truncate)\n\n    def verify_digest(\n        self,\n        signature,\n        digest,\n        sigdecode=sigdecode_string,\n        allow_truncate=False,\n    ):\n        \"\"\"\n        Verify a signature made over provided hash value.\n\n        By default expects signature in :term:`raw encoding`. Can also be used\n        to verify signatures in ASN.1 DER encoding by using\n        :func:`ecdsa.util.sigdecode_der`\n        as the `sigdecode` parameter.\n\n        :param signature: encoding of the signature\n        :type signature: sigdecode method dependent\n        :param digest: raw hash value that the signature authenticates.\n        :type digest: :term:`bytes-like object`\n        :param sigdecode: Callable to define the way the signature needs to\n            be decoded to an object, needs to handle `signature` as the\n            first parameter, the curve order (an int) as the second and return\n            a tuple with two integers, \"r\" as the first one and \"s\" as the\n            second one. See :func:`ecdsa.util.sigdecode_string` and\n            :func:`ecdsa.util.sigdecode_der` for examples.\n        :type sigdecode: callable\n        :param bool allow_truncate: if True, the provided digest can have\n            bigger bit-size than the order of the curve, the extra bits (at\n            the end of the digest) will be truncated. Use it when verifying\n            SHA-384 output using NIST256p or in similar situations.\n\n        :raises BadSignatureError: if the signature is invalid or malformed\n        :raises BadDigestError: if the provided digest is too big for the curve\n            associated with this VerifyingKey and allow_truncate was not set\n\n        :return: True if the verification was successful\n        :rtype: bool\n        \"\"\"\n        # signature doesn't have to be a bytes-like-object so don't normalise\n        # it, the decoders will do that\n        digest = normalise_bytes(digest)\n        number = _truncate_and_convert_digest(\n            digest,\n            self.curve,\n            allow_truncate,\n        )\n\n        try:\n            r, s = sigdecode(signature, self.pubkey.order)\n        except (der.UnexpectedDER, MalformedSignature) as e:\n            raise BadSignatureError(\"Malformed formatting of signature\", e)\n        sig = ecdsa.Signature(r, s)\n        if self.pubkey.verifies(number, sig):\n            return True\n        raise BadSignatureError(\"Signature verification failed\")\n\n\nclass SigningKey(object):\n    \"\"\"\n    Class for handling keys that can create signatures (private keys).\n\n    :ivar `~ecdsa.curves.Curve` curve: The Curve over which all the\n        cryptographic operations will take place\n    :ivar default_hashfunc: the function that will be used for hashing the\n        data. Should implement the same API as :py:class:`hashlib.sha1`\n    :ivar int baselen: the length of a :term:`raw encoding` of private key\n    :ivar `~ecdsa.keys.VerifyingKey` verifying_key: the public key\n        associated with this private key\n    :ivar `~ecdsa.ecdsa.Private_key` privkey: the actual private key\n    \"\"\"\n\n    def __init__(self, _error__please_use_generate=None):\n        \"\"\"Unsupported, please use one of the classmethods to initialise.\"\"\"\n        if not _error__please_use_generate:\n            raise TypeError(\"Please use SigningKey.generate() to construct me\")\n        self.curve = None\n        self.default_hashfunc = None\n        self.baselen = None\n        self.verifying_key = None\n        self.privkey = None\n\n    def __eq__(self, other):\n        \"\"\"Return True if the points are identical, False otherwise.\"\"\"\n        if isinstance(other, SigningKey):\n            return (\n                self.curve == other.curve\n                and self.verifying_key == other.verifying_key\n                and self.privkey == other.privkey\n            )\n        return NotImplemented\n\n    def __ne__(self, other):\n        \"\"\"Return False if the points are identical, True otherwise.\"\"\"\n        return not self == other\n\n    @classmethod\n    def _twisted_edwards_keygen(cls, curve, entropy):\n        \"\"\"Generate a private key on a Twisted Edwards curve.\"\"\"\n        if not entropy:\n            entropy = os.urandom\n        random = entropy(curve.baselen)\n        private_key = eddsa.PrivateKey(curve.generator, random)\n        public_key = private_key.public_key()\n\n        verifying_key = VerifyingKey.from_string(\n            public_key.public_key(), curve\n        )\n\n        self = cls(_error__please_use_generate=True)\n        self.curve = curve\n        self.default_hashfunc = None\n        self.baselen = curve.baselen\n        self.privkey = private_key\n        self.verifying_key = verifying_key\n        return self\n\n    @classmethod\n    def _weierstrass_keygen(cls, curve, entropy, hashfunc):\n        \"\"\"Generate a private key on a Weierstrass curve.\"\"\"\n        secexp = randrange(curve.order, entropy)\n        return cls.from_secret_exponent(secexp, curve, hashfunc)\n\n    @classmethod\n    def generate(cls, curve=NIST192p, entropy=None, hashfunc=sha1):\n        \"\"\"\n        Generate a random private key.\n\n        :param curve: The curve on which the point needs to reside, defaults\n            to NIST192p\n        :type curve: ~ecdsa.curves.Curve\n        :param entropy: Source of randomness for generating the private keys,\n            should provide cryptographically secure random numbers if the keys\n            need to be secure. Uses os.urandom() by default.\n        :type entropy: callable\n        :param hashfunc: The default hash function that will be used for\n            signing, needs to implement the same interface\n            as hashlib.sha1\n        :type hashfunc: callable\n\n        :return: Initialised SigningKey object\n        :rtype: SigningKey\n        \"\"\"\n        if isinstance(curve.curve, CurveEdTw):\n            return cls._twisted_edwards_keygen(curve, entropy)\n        return cls._weierstrass_keygen(curve, entropy, hashfunc)\n\n    @classmethod\n    def from_secret_exponent(cls, secexp, curve=NIST192p, hashfunc=sha1):\n        \"\"\"\n        Create a private key from a random integer.\n\n        Note: it's a low level method, it's recommended to use the\n        :func:`~SigningKey.generate` method to create private keys.\n\n        :param int secexp: secret multiplier (the actual private key in ECDSA).\n            Needs to be an integer between 1 and the curve order.\n        :param curve: The curve on which the point needs to reside\n        :type curve: ~ecdsa.curves.Curve\n        :param hashfunc: The default hash function that will be used for\n            signing, needs to implement the same interface\n            as hashlib.sha1\n        :type hashfunc: callable\n\n        :raises MalformedPointError: when the provided secexp is too large\n            or too small for the curve selected\n        :raises RuntimeError: if the generation of public key from private\n            key failed\n\n        :return: Initialised SigningKey object\n        :rtype: SigningKey\n        \"\"\"\n        if isinstance(curve.curve, CurveEdTw):\n            raise ValueError(\n                \"Edwards keys don't support setting the secret scalar \"\n                \"(exponent) directly\"\n            )\n        self = cls(_error__please_use_generate=True)\n        self.curve = curve\n        self.default_hashfunc = hashfunc\n        self.baselen = curve.baselen\n        n = curve.order\n        if not 1 <= secexp < n:\n            raise MalformedPointError(\n                \"Invalid value for secexp, expected integer \"\n                \"between 1 and {0}\".format(n)\n            )\n        pubkey_point = curve.generator * secexp\n        if hasattr(pubkey_point, \"scale\"):\n            pubkey_point = pubkey_point.scale()\n        self.verifying_key = VerifyingKey.from_public_point(\n            pubkey_point, curve, hashfunc, False\n        )\n        pubkey = self.verifying_key.pubkey\n        self.privkey = ecdsa.Private_key(pubkey, secexp)\n        self.privkey.order = n\n        return self\n\n    @classmethod\n    def from_string(cls, string, curve=NIST192p, hashfunc=sha1):\n        \"\"\"\n        Decode the private key from :term:`raw encoding`.\n\n        Note: the name of this method is a misnomer coming from days of\n        Python 2, when binary strings and character strings shared a type.\n        In Python 3, the expected type is `bytes`.\n\n        :param string: the raw encoding of the private key\n        :type string: :term:`bytes-like object`\n        :param curve: The curve on which the point needs to reside\n        :type curve: ~ecdsa.curves.Curve\n        :param hashfunc: The default hash function that will be used for\n            signing, needs to implement the same interface\n            as hashlib.sha1\n        :type hashfunc: callable\n\n        :raises MalformedPointError: if the length of encoding doesn't match\n            the provided curve or the encoded values is too large\n        :raises RuntimeError: if the generation of public key from private\n            key failed\n\n        :return: Initialised SigningKey object\n        :rtype: SigningKey\n        \"\"\"\n        string = normalise_bytes(string)\n\n        if len(string) != curve.baselen:\n            raise MalformedPointError(\n                \"Invalid length of private key, received {0}, \"\n                \"expected {1}\".format(len(string), curve.baselen)\n            )\n        if isinstance(curve.curve, CurveEdTw):\n            self = cls(_error__please_use_generate=True)\n            self.curve = curve\n            self.default_hashfunc = None  # Ignored for EdDSA\n            self.baselen = curve.baselen\n            self.privkey = eddsa.PrivateKey(curve.generator, string)\n            self.verifying_key = VerifyingKey.from_string(\n                self.privkey.public_key().public_key(), curve\n            )\n            return self\n        secexp = string_to_number(string)\n        return cls.from_secret_exponent(secexp, curve, hashfunc)\n\n    @classmethod\n    def from_pem(cls, string, hashfunc=sha1, valid_curve_encodings=None):\n        \"\"\"\n        Initialise from key stored in :term:`PEM` format.\n\n        The PEM formats supported are the un-encrypted RFC5915\n        (the ssleay format) supported by OpenSSL, and the more common\n        un-encrypted RFC5958 (the PKCS #8 format).\n\n        The legacy format files have the header with the string\n        ``BEGIN EC PRIVATE KEY``.\n        PKCS#8 files have the header ``BEGIN PRIVATE KEY``.\n        Encrypted files (ones that include the string\n        ``Proc-Type: 4,ENCRYPTED``\n        right after the PEM header) are not supported.\n\n        See :func:`~SigningKey.from_der` for ASN.1 syntax of the objects in\n        this files.\n\n        :param string: text with PEM-encoded private ECDSA key\n        :type string: str\n        :param valid_curve_encodings: list of allowed encoding formats\n            for curve parameters. By default (``None``) all are supported:\n            ``named_curve`` and ``explicit``.\n        :type valid_curve_encodings: :term:`set-like object`\n\n\n        :raises MalformedPointError: if the length of encoding doesn't match\n            the provided curve or the encoded values is too large\n        :raises RuntimeError: if the generation of public key from private\n            key failed\n        :raises UnexpectedDER: if the encoding of the PEM file is incorrect\n\n        :return: Initialised SigningKey object\n        :rtype: SigningKey\n        \"\"\"\n        if not PY2 and isinstance(string, str):  # pragma: no branch\n            string = string.encode()\n\n        # The privkey pem may have multiple sections, commonly it also has\n        # \"EC PARAMETERS\", we need just \"EC PRIVATE KEY\". PKCS#8 should not\n        # have the \"EC PARAMETERS\" section; it's just \"PRIVATE KEY\".\n        private_key_index = string.find(b\"-----BEGIN EC PRIVATE KEY-----\")\n        if private_key_index == -1:\n            private_key_index = string.index(b\"-----BEGIN PRIVATE KEY-----\")\n\n        return cls.from_der(\n            der.unpem(string[private_key_index:]),\n            hashfunc,\n            valid_curve_encodings,\n        )\n\n    @classmethod\n    def from_der(cls, string, hashfunc=sha1, valid_curve_encodings=None):\n        \"\"\"\n        Initialise from key stored in :term:`DER` format.\n\n        The DER formats supported are the un-encrypted RFC5915\n        (the ssleay format) supported by OpenSSL, and the more common\n        un-encrypted RFC5958 (the PKCS #8 format).\n\n        Both formats contain an ASN.1 object following the syntax specified\n        in RFC5915::\n\n            ECPrivateKey ::= SEQUENCE {\n              version        INTEGER { ecPrivkeyVer1(1) }} (ecPrivkeyVer1),\n              privateKey     OCTET STRING,\n              parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,\n              publicKey  [1] BIT STRING OPTIONAL\n            }\n\n        `publicKey` field is ignored completely (errors, if any, in it will\n        be undetected).\n\n        Two formats are supported for the `parameters` field: the named\n        curve and the explicit encoding of curve parameters.\n        In the legacy ssleay format, this implementation requires the optional\n        `parameters` field to get the curve name. In PKCS #8 format, the curve\n        is part of the PrivateKeyAlgorithmIdentifier.\n\n        The PKCS #8 format includes an ECPrivateKey object as the `privateKey`\n        field within a larger structure::\n\n            OneAsymmetricKey ::= SEQUENCE {\n                version                   Version,\n                privateKeyAlgorithm       PrivateKeyAlgorithmIdentifier,\n                privateKey                PrivateKey,\n                attributes            [0] Attributes OPTIONAL,\n                ...,\n                [[2: publicKey        [1] PublicKey OPTIONAL ]],\n                ...\n            }\n\n        The `attributes` and `publicKey` fields are completely ignored; errors\n        in them will not be detected.\n\n        :param string: binary string with DER-encoded private ECDSA key\n        :type string: :term:`bytes-like object`\n        :param valid_curve_encodings: list of allowed encoding formats\n            for curve parameters. By default (``None``) all are supported:\n            ``named_curve`` and ``explicit``.\n            Ignored for EdDSA.\n        :type valid_curve_encodings: :term:`set-like object`\n\n        :raises MalformedPointError: if the length of encoding doesn't match\n            the provided curve or the encoded values is too large\n        :raises RuntimeError: if the generation of public key from private\n            key failed\n        :raises UnexpectedDER: if the encoding of the DER file is incorrect\n\n        :return: Initialised SigningKey object\n        :rtype: SigningKey\n        \"\"\"\n        s = normalise_bytes(string)\n        curve = None\n\n        s, empty = der.remove_sequence(s)\n        if empty != b(\"\"):\n            raise der.UnexpectedDER(\n                \"trailing junk after DER privkey: %s\" % binascii.hexlify(empty)\n            )\n\n        version, s = der.remove_integer(s)\n\n        # At this point, PKCS #8 has a sequence containing the algorithm\n        # identifier and the curve identifier. The ssleay format instead has\n        # an octet string containing the key data, so this is how we can\n        # distinguish the two formats.\n        if der.is_sequence(s):\n            if version not in (0, 1):\n                raise der.UnexpectedDER(\n                    \"expected version '0' or '1' at start of privkey, got %d\"\n                    % version\n                )\n\n            sequence, s = der.remove_sequence(s)\n            algorithm_oid, algorithm_identifier = der.remove_object(sequence)\n\n            if algorithm_oid in (Ed25519.oid, Ed448.oid):\n                if algorithm_identifier:\n                    raise der.UnexpectedDER(\n                        \"Non NULL parameters for a EdDSA key\"\n                    )\n                key_str_der, s = der.remove_octet_string(s)\n\n                # As RFC5958 describe, there are may be optional Attributes\n                # and Publickey. Don't raise error if something after\n                # Privatekey\n\n                # TODO parse attributes or validate publickey\n                # if s:\n                #     raise der.UnexpectedDER(\n                #         \"trailing junk inside the privateKey\"\n                #     )\n                key_str, s = der.remove_octet_string(key_str_der)\n                if s:\n                    raise der.UnexpectedDER(\n                        \"trailing junk after the encoded private key\"\n                    )\n\n                if algorithm_oid == Ed25519.oid:\n                    curve = Ed25519\n                else:\n                    assert algorithm_oid == Ed448.oid\n                    curve = Ed448\n\n                return cls.from_string(key_str, curve, None)\n\n            if algorithm_oid not in (oid_ecPublicKey, oid_ecDH, oid_ecMQV):\n                raise der.UnexpectedDER(\n                    \"unexpected algorithm identifier '%s'\" % (algorithm_oid,)\n                )\n\n            curve = Curve.from_der(algorithm_identifier, valid_curve_encodings)\n\n            if empty != b\"\":\n                raise der.UnexpectedDER(\n                    \"unexpected data after algorithm identifier: %s\"\n                    % binascii.hexlify(empty)\n                )\n\n            # Up next is an octet string containing an ECPrivateKey. Ignore\n            # the optional \"attributes\" and \"publicKey\" fields that come after.\n            s, _ = der.remove_octet_string(s)\n\n            # Unpack the ECPrivateKey to get to the key data octet string,\n            # and rejoin the ssleay parsing path.\n            s, empty = der.remove_sequence(s)\n            if empty != b(\"\"):\n                raise der.UnexpectedDER(\n                    \"trailing junk after DER privkey: %s\"\n                    % binascii.hexlify(empty)\n                )\n\n            version, s = der.remove_integer(s)\n\n        # The version of the ECPrivateKey must be 1.\n        if version != 1:\n            raise der.UnexpectedDER(\n                \"expected version '1' at start of DER privkey, got %d\"\n                % version\n            )\n\n        privkey_str, s = der.remove_octet_string(s)\n\n        if not curve:\n            tag, curve_oid_str, s = der.remove_constructed(s)\n            if tag != 0:\n                raise der.UnexpectedDER(\n                    \"expected tag 0 in DER privkey, got %d\" % tag\n                )\n            curve = Curve.from_der(curve_oid_str, valid_curve_encodings)\n\n        # we don't actually care about the following fields\n        #\n        # tag, pubkey_bitstring, s = der.remove_constructed(s)\n        # if tag != 1:\n        #     raise der.UnexpectedDER(\"expected tag 1 in DER privkey, got %d\"\n        #                             % tag)\n        # pubkey_str = der.remove_bitstring(pubkey_bitstring, 0)\n        # if empty != \"\":\n        #     raise der.UnexpectedDER(\"trailing junk after DER privkey \"\n        #                             \"pubkeystr: %s\"\n        #                             % binascii.hexlify(empty))\n\n        # our from_string method likes fixed-length privkey strings\n        if len(privkey_str) < curve.baselen:\n            privkey_str = (\n                b(\"\\x00\") * (curve.baselen - len(privkey_str)) + privkey_str\n            )\n        return cls.from_string(privkey_str, curve, hashfunc)\n\n    def to_string(self):\n        \"\"\"\n        Convert the private key to :term:`raw encoding`.\n\n        Note: while the method is named \"to_string\", its name comes from\n        Python 2 days, when binary and character strings used the same type.\n        The type used in Python 3 is `bytes`.\n\n        :return: raw encoding of private key\n        :rtype: bytes\n        \"\"\"\n        if isinstance(self.curve.curve, CurveEdTw):\n            return bytes(self.privkey.private_key)\n        secexp = self.privkey.secret_multiplier\n        s = number_to_string(secexp, self.privkey.order)\n        return s\n\n    def to_pem(\n        self,\n        point_encoding=\"uncompressed\",\n        format=\"ssleay\",\n        curve_parameters_encoding=None,\n    ):\n        \"\"\"\n        Convert the private key to the :term:`PEM` format.\n\n        See :func:`~SigningKey.from_pem` method for format description.\n\n        Only the named curve format is supported.\n        The public key will be included in generated string.\n\n        The PEM header will specify ``BEGIN EC PRIVATE KEY`` or\n        ``BEGIN PRIVATE KEY``, depending on the desired format.\n\n        :param str point_encoding: format to use for encoding public point\n        :param str format: either ``ssleay`` (default) or ``pkcs8``\n        :param str curve_parameters_encoding: format of encoded curve\n            parameters, default depends on the curve, if the curve has\n            an associated OID, ``named_curve`` format will be used,\n            if no OID is associated with the curve, the fallback of\n            ``explicit`` parameters will be used.\n\n        :return: PEM encoded private key\n        :rtype: bytes\n\n        .. warning:: The PEM is encoded to US-ASCII, it needs to be\n            re-encoded if the system is incompatible (e.g. uses UTF-16)\n        \"\"\"\n        # TODO: \"BEGIN ECPARAMETERS\"\n        assert format in (\"ssleay\", \"pkcs8\")\n        header = \"EC PRIVATE KEY\" if format == \"ssleay\" else \"PRIVATE KEY\"\n        return der.topem(\n            self.to_der(point_encoding, format, curve_parameters_encoding),\n            header,\n        )\n\n    def _encode_eddsa(self):\n        \"\"\"Create a PKCS#8 encoding of EdDSA keys.\"\"\"\n        ec_private_key = der.encode_octet_string(self.to_string())\n        return der.encode_sequence(\n            der.encode_integer(0),\n            der.encode_sequence(der.encode_oid(*self.curve.oid)),\n            der.encode_octet_string(ec_private_key),\n        )\n\n    def to_der(\n        self,\n        point_encoding=\"uncompressed\",\n        format=\"ssleay\",\n        curve_parameters_encoding=None,\n    ):\n        \"\"\"\n        Convert the private key to the :term:`DER` format.\n\n        See :func:`~SigningKey.from_der` method for format specification.\n\n        Only the named curve format is supported.\n        The public key will be included in the generated string.\n\n        :param str point_encoding: format to use for encoding public point\n            Ignored for EdDSA\n        :param str format: either ``ssleay`` (default) or ``pkcs8``.\n            EdDSA keys require ``pkcs8``.\n        :param str curve_parameters_encoding: format of encoded curve\n            parameters, default depends on the curve, if the curve has\n            an associated OID, ``named_curve`` format will be used,\n            if no OID is associated with the curve, the fallback of\n            ``explicit`` parameters will be used.\n            Ignored for EdDSA.\n\n        :return: DER encoded private key\n        :rtype: bytes\n        \"\"\"\n        # SEQ([int(1), octetstring(privkey),cont[0], oid(secp224r1),\n        #      cont[1],bitstring])\n        if point_encoding == \"raw\":\n            raise ValueError(\"raw encoding not allowed in DER\")\n        assert format in (\"ssleay\", \"pkcs8\")\n        if isinstance(self.curve.curve, CurveEdTw):\n            if format != \"pkcs8\":\n                raise ValueError(\"Only PKCS#8 format supported for EdDSA keys\")\n            return self._encode_eddsa()\n        encoded_vk = self.get_verifying_key().to_string(point_encoding)\n        priv_key_elems = [\n            der.encode_integer(1),\n            der.encode_octet_string(self.to_string()),\n        ]\n        if format == \"ssleay\":\n            priv_key_elems.append(\n                der.encode_constructed(\n                    0, self.curve.to_der(curve_parameters_encoding)\n                )\n            )\n        # the 0 in encode_bitstring specifies the number of unused bits\n        # in the `encoded_vk` string\n        priv_key_elems.append(\n            der.encode_constructed(1, der.encode_bitstring(encoded_vk, 0))\n        )\n        ec_private_key = der.encode_sequence(*priv_key_elems)\n\n        if format == \"ssleay\":\n            return ec_private_key\n        else:\n            return der.encode_sequence(\n                # version = 1 means the public key is not present in the\n                # top-level structure.\n                der.encode_integer(1),\n                der.encode_sequence(\n                    der.encode_oid(*oid_ecPublicKey),\n                    self.curve.to_der(curve_parameters_encoding),\n                ),\n                der.encode_octet_string(ec_private_key),\n            )\n\n    def get_verifying_key(self):\n        \"\"\"\n        Return the VerifyingKey associated with this private key.\n\n        Equivalent to reading the `verifying_key` field of an instance.\n\n        :return: a public key that can be used to verify the signatures made\n            with this SigningKey\n        :rtype: VerifyingKey\n        \"\"\"\n        return self.verifying_key\n\n    def sign_deterministic(\n        self,\n        data,\n        hashfunc=None,\n        sigencode=sigencode_string,\n        extra_entropy=b\"\",\n    ):\n        \"\"\"\n        Create signature over data.\n\n        For Weierstrass curves it uses the deterministic RFC6979 algorithm.\n        For Edwards curves it uses the standard EdDSA algorithm.\n\n        For ECDSA the data will be hashed using the `hashfunc` function before\n        signing.\n        For EdDSA the data will be hashed with the hash associated with the\n        curve (SHA-512 for Ed25519 and SHAKE-256 for Ed448).\n\n        This is the recommended method for performing signatures when hashing\n        of data is necessary.\n\n        :param data: data to be hashed and computed signature over\n        :type data: :term:`bytes-like object`\n        :param hashfunc: hash function to use for computing the signature,\n            if unspecified, the default hash function selected during\n            object initialisation will be used (see\n            `VerifyingKey.default_hashfunc`). The object needs to implement\n            the same interface as hashlib.sha1.\n            Ignored with EdDSA.\n        :type hashfunc: callable\n        :param sigencode: function used to encode the signature.\n            The function needs to accept three parameters: the two integers\n            that are the signature and the order of the curve over which the\n            signature was computed. It needs to return an encoded signature.\n            See `ecdsa.util.sigencode_string` and `ecdsa.util.sigencode_der`\n            as examples of such functions.\n            Ignored with EdDSA.\n        :type sigencode: callable\n        :param extra_entropy: additional data that will be fed into the random\n            number generator used in the RFC6979 process. Entirely optional.\n            Ignored with EdDSA.\n        :type extra_entropy: :term:`bytes-like object`\n\n        :return: encoded signature over `data`\n        :rtype: bytes or sigencode function dependent type\n        \"\"\"\n        hashfunc = hashfunc or self.default_hashfunc\n        data = normalise_bytes(data)\n\n        if isinstance(self.curve.curve, CurveEdTw):\n            return self.privkey.sign(data)\n\n        extra_entropy = normalise_bytes(extra_entropy)\n        digest = hashfunc(data).digest()\n\n        return self.sign_digest_deterministic(\n            digest,\n            hashfunc=hashfunc,\n            sigencode=sigencode,\n            extra_entropy=extra_entropy,\n            allow_truncate=True,\n        )\n\n    def sign_digest_deterministic(\n        self,\n        digest,\n        hashfunc=None,\n        sigencode=sigencode_string,\n        extra_entropy=b\"\",\n        allow_truncate=False,\n    ):\n        \"\"\"\n        Create signature for digest using the deterministic RFC6979 algorithm.\n\n        `digest` should be the output of cryptographically secure hash function\n        like SHA256 or SHA-3-256.\n\n        This is the recommended method for performing signatures when no\n        hashing of data is necessary.\n\n        :param digest: hash of data that will be signed\n        :type digest: :term:`bytes-like object`\n        :param hashfunc: hash function to use for computing the random \"k\"\n            value from RFC6979 process,\n            if unspecified, the default hash function selected during\n            object initialisation will be used (see\n            :attr:`.VerifyingKey.default_hashfunc`). The object needs to\n            implement\n            the same interface as :func:`~hashlib.sha1` from :py:mod:`hashlib`.\n        :type hashfunc: callable\n        :param sigencode: function used to encode the signature.\n            The function needs to accept three parameters: the two integers\n            that are the signature and the order of the curve over which the\n            signature was computed. It needs to return an encoded signature.\n            See :func:`~ecdsa.util.sigencode_string` and\n            :func:`~ecdsa.util.sigencode_der`\n            as examples of such functions.\n        :type sigencode: callable\n        :param extra_entropy: additional data that will be fed into the random\n            number generator used in the RFC6979 process. Entirely optional.\n        :type extra_entropy: :term:`bytes-like object`\n        :param bool allow_truncate: if True, the provided digest can have\n            bigger bit-size than the order of the curve, the extra bits (at\n            the end of the digest) will be truncated. Use it when signing\n            SHA-384 output using NIST256p or in similar situations.\n\n        :return: encoded signature for the `digest` hash\n        :rtype: bytes or sigencode function dependent type\n        \"\"\"\n        if isinstance(self.curve.curve, CurveEdTw):\n            raise ValueError(\"Method unsupported for Edwards curves\")\n        secexp = self.privkey.secret_multiplier\n        hashfunc = hashfunc or self.default_hashfunc\n        digest = normalise_bytes(digest)\n        extra_entropy = normalise_bytes(extra_entropy)\n\n        def simple_r_s(r, s, order):\n            return r, s, order\n\n        retry_gen = 0\n        while True:\n            k = rfc6979.generate_k(\n                self.curve.generator.order(),\n                secexp,\n                hashfunc,\n                digest,\n                retry_gen=retry_gen,\n                extra_entropy=extra_entropy,\n            )\n            try:\n                r, s, order = self.sign_digest(\n                    digest,\n                    sigencode=simple_r_s,\n                    k=k,\n                    allow_truncate=allow_truncate,\n                )\n                break\n            except RSZeroError:\n                retry_gen += 1\n\n        return sigencode(r, s, order)\n\n    def sign(\n        self,\n        data,\n        entropy=None,\n        hashfunc=None,\n        sigencode=sigencode_string,\n        k=None,\n        allow_truncate=True,\n    ):\n        \"\"\"\n        Create signature over data.\n\n        Uses the probabilistic ECDSA algorithm for Weierstrass curves\n        (NIST256p, etc.) and the deterministic EdDSA algorithm for the\n        Edwards curves (Ed25519, Ed448).\n\n        This method uses the standard ECDSA algorithm that requires a\n        cryptographically secure random number generator.\n\n        It's recommended to use the :func:`~SigningKey.sign_deterministic`\n        method instead of this one.\n\n        :param data: data that will be hashed for signing\n        :type data: :term:`bytes-like object`\n        :param callable entropy: randomness source, :func:`os.urandom` by\n            default. Ignored with EdDSA.\n        :param hashfunc: hash function to use for hashing the provided\n            ``data``.\n            If unspecified the default hash function selected during\n            object initialisation will be used (see\n            :attr:`.VerifyingKey.default_hashfunc`).\n            Should behave like :func:`~hashlib.sha1` from :py:mod:`hashlib`.\n            The output length of the\n            hash (in bytes) must not be longer than the length of the curve\n            order (rounded up to the nearest byte), so using SHA256 with\n            NIST256p is ok, but SHA256 with NIST192p is not. (In the 2**-96ish\n            unlikely event of a hash output larger than the curve order, the\n            hash will effectively be wrapped mod n).\n            If you want to explicitly allow use of large hashes with small\n            curves set the ``allow_truncate`` to ``True``.\n            Use ``hashfunc=hashlib.sha1`` to match openssl's\n            ``-ecdsa-with-SHA1`` mode,\n            or ``hashfunc=hashlib.sha256`` for openssl-1.0.0's\n            ``-ecdsa-with-SHA256``.\n            Ignored for EdDSA\n        :type hashfunc: callable\n        :param sigencode: function used to encode the signature.\n            The function needs to accept three parameters: the two integers\n            that are the signature and the order of the curve over which the\n            signature was computed. It needs to return an encoded signature.\n            See :func:`~ecdsa.util.sigencode_string` and\n            :func:`~ecdsa.util.sigencode_der`\n            as examples of such functions.\n            Ignored for EdDSA\n        :type sigencode: callable\n        :param int k: a pre-selected nonce for calculating the signature.\n            In typical use cases, it should be set to None (the default) to\n            allow its generation from an entropy source.\n            Ignored for EdDSA.\n        :param bool allow_truncate: if ``True``, the provided digest can have\n            bigger bit-size than the order of the curve, the extra bits (at\n            the end of the digest) will be truncated. Use it when signing\n            SHA-384 output using NIST256p or in similar situations. True by\n            default.\n            Ignored for EdDSA.\n\n        :raises RSZeroError: in the unlikely event when *r* parameter or\n            *s* parameter of the created signature is equal 0, as that would\n            leak the key. Caller should try a better entropy source, retry with\n            different ``k``, or use the\n            :func:`~SigningKey.sign_deterministic` in such case.\n\n        :return: encoded signature of the hash of `data`\n        :rtype: bytes or sigencode function dependent type\n        \"\"\"\n        hashfunc = hashfunc or self.default_hashfunc\n        data = normalise_bytes(data)\n        if isinstance(self.curve.curve, CurveEdTw):\n            return self.sign_deterministic(data)\n        h = hashfunc(data).digest()\n        return self.sign_digest(h, entropy, sigencode, k, allow_truncate)\n\n    def sign_digest(\n        self,\n        digest,\n        entropy=None,\n        sigencode=sigencode_string,\n        k=None,\n        allow_truncate=False,\n    ):\n        \"\"\"\n        Create signature over digest using the probabilistic ECDSA algorithm.\n\n        This method uses the standard ECDSA algorithm that requires a\n        cryptographically secure random number generator.\n\n        This method does not hash the input.\n\n        It's recommended to use the\n        :func:`~SigningKey.sign_digest_deterministic` method\n        instead of this one.\n\n        :param digest: hash value that will be signed\n        :type digest: :term:`bytes-like object`\n        :param callable entropy: randomness source, os.urandom by default\n        :param sigencode: function used to encode the signature.\n            The function needs to accept three parameters: the two integers\n            that are the signature and the order of the curve over which the\n            signature was computed. It needs to return an encoded signature.\n            See `ecdsa.util.sigencode_string` and `ecdsa.util.sigencode_der`\n            as examples of such functions.\n        :type sigencode: callable\n        :param int k: a pre-selected nonce for calculating the signature.\n            In typical use cases, it should be set to None (the default) to\n            allow its generation from an entropy source.\n        :param bool allow_truncate: if True, the provided digest can have\n            bigger bit-size than the order of the curve, the extra bits (at\n            the end of the digest) will be truncated. Use it when signing\n            SHA-384 output using NIST256p or in similar situations.\n\n        :raises RSZeroError: in the unlikely event when \"r\" parameter or\n            \"s\" parameter of the created signature is equal 0, as that would\n            leak the key. Caller should try a better entropy source, retry with\n            different 'k', or use the\n            :func:`~SigningKey.sign_digest_deterministic` in such case.\n\n        :return: encoded signature for the `digest` hash\n        :rtype: bytes or sigencode function dependent type\n        \"\"\"\n        if isinstance(self.curve.curve, CurveEdTw):\n            raise ValueError(\"Method unsupported for Edwards curves\")\n        digest = normalise_bytes(digest)\n        number = _truncate_and_convert_digest(\n            digest,\n            self.curve,\n            allow_truncate,\n        )\n        r, s = self.sign_number(number, entropy, k)\n        return sigencode(r, s, self.privkey.order)\n\n    def sign_number(self, number, entropy=None, k=None):\n        \"\"\"\n        Sign an integer directly.\n\n        Note, this is a low level method, usually you will want to use\n        :func:`~SigningKey.sign_deterministic` or\n        :func:`~SigningKey.sign_digest_deterministic`.\n\n        :param int number: number to sign using the probabilistic ECDSA\n            algorithm.\n        :param callable entropy: entropy source, os.urandom by default\n        :param int k: pre-selected nonce for signature operation. If unset\n            it will be selected at random using the entropy source.\n\n        :raises RSZeroError: in the unlikely event when \"r\" parameter or\n            \"s\" parameter of the created signature is equal 0, as that would\n            leak the key. Caller should try a better entropy source, retry with\n            different 'k', or use the\n            :func:`~SigningKey.sign_digest_deterministic` in such case.\n\n        :return: the \"r\" and \"s\" parameters of the signature\n        :rtype: tuple of ints\n        \"\"\"\n        if isinstance(self.curve.curve, CurveEdTw):\n            raise ValueError(\"Method unsupported for Edwards curves\")\n        order = self.privkey.order\n\n        if k is not None:\n            _k = k\n        else:\n            _k = randrange(order, entropy)\n\n        assert 1 <= _k < order\n        sig = self.privkey.sign(number, _k)\n        return sig.r, sig.s\n"
  },
  {
    "path": "code/default/lib/noarch/ecdsa/numbertheory.py",
    "content": "#! /usr/bin/env python\n#\n# Provide some simple capabilities from number theory.\n#\n# Version of 2008.11.14.\n#\n# Written in 2005 and 2006 by Peter Pearson and placed in the public domain.\n# Revision history:\n#   2008.11.14: Use pow(base, exponent, modulus) for modular_exp.\n#               Make gcd and lcm accept arbitrarily many arguments.\n\nfrom __future__ import division\n\nimport sys\nfrom six import integer_types, PY2\nfrom six.moves import reduce\n\ntry:\n    xrange\nexcept NameError:\n    xrange = range\ntry:\n    from gmpy2 import powmod\n\n    GMPY2 = True\n    GMPY = False\nexcept ImportError:\n    GMPY2 = False\n    try:\n        from gmpy import mpz\n\n        GMPY = True\n    except ImportError:\n        GMPY = False\n\nimport math\nimport warnings\n\n\nclass Error(Exception):\n    \"\"\"Base class for exceptions in this module.\"\"\"\n\n    pass\n\n\nclass JacobiError(Error):\n    pass\n\n\nclass SquareRootError(Error):\n    pass\n\n\nclass NegativeExponentError(Error):\n    pass\n\n\ndef modular_exp(base, exponent, modulus):  # pragma: no cover\n    \"\"\"Raise base to exponent, reducing by modulus\"\"\"\n    # deprecated in 0.14\n    warnings.warn(\n        \"Function is unused in library code. If you use this code, \"\n        \"change to pow() builtin.\",\n        DeprecationWarning,\n    )\n    if exponent < 0:\n        raise NegativeExponentError(\n            \"Negative exponents (%d) not allowed\" % exponent\n        )\n    return pow(base, exponent, modulus)\n\n\ndef polynomial_reduce_mod(poly, polymod, p):\n    \"\"\"Reduce poly by polymod, integer arithmetic modulo p.\n\n    Polynomials are represented as lists of coefficients\n    of increasing powers of x.\"\"\"\n\n    # This module has been tested only by extensive use\n    # in calculating modular square roots.\n\n    # Just to make this easy, require a monic polynomial:\n    assert polymod[-1] == 1\n\n    assert len(polymod) > 1\n\n    while len(poly) >= len(polymod):\n        if poly[-1] != 0:\n            for i in xrange(2, len(polymod) + 1):\n                poly[-i] = (poly[-i] - poly[-1] * polymod[-i]) % p\n        poly = poly[0:-1]\n\n    return poly\n\n\ndef polynomial_multiply_mod(m1, m2, polymod, p):\n    \"\"\"Polynomial multiplication modulo a polynomial over ints mod p.\n\n    Polynomials are represented as lists of coefficients\n    of increasing powers of x.\"\"\"\n\n    # This is just a seat-of-the-pants implementation.\n\n    # This module has been tested only by extensive use\n    # in calculating modular square roots.\n\n    # Initialize the product to zero:\n\n    prod = (len(m1) + len(m2) - 1) * [0]\n\n    # Add together all the cross-terms:\n\n    for i in xrange(len(m1)):\n        for j in xrange(len(m2)):\n            prod[i + j] = (prod[i + j] + m1[i] * m2[j]) % p\n\n    return polynomial_reduce_mod(prod, polymod, p)\n\n\ndef polynomial_exp_mod(base, exponent, polymod, p):\n    \"\"\"Polynomial exponentiation modulo a polynomial over ints mod p.\n\n    Polynomials are represented as lists of coefficients\n    of increasing powers of x.\"\"\"\n\n    # Based on the Handbook of Applied Cryptography, algorithm 2.227.\n\n    # This module has been tested only by extensive use\n    # in calculating modular square roots.\n\n    assert exponent < p\n\n    if exponent == 0:\n        return [1]\n\n    G = base\n    k = exponent\n    if k % 2 == 1:\n        s = G\n    else:\n        s = [1]\n\n    while k > 1:\n        k = k // 2\n        G = polynomial_multiply_mod(G, G, polymod, p)\n        if k % 2 == 1:\n            s = polynomial_multiply_mod(G, s, polymod, p)\n\n    return s\n\n\ndef jacobi(a, n):\n    \"\"\"Jacobi symbol\"\"\"\n\n    # Based on the Handbook of Applied Cryptography (HAC), algorithm 2.149.\n\n    # This function has been tested by comparison with a small\n    # table printed in HAC, and by extensive use in calculating\n    # modular square roots.\n\n    if not n >= 3:\n        raise JacobiError(\"n must be larger than 2\")\n    if not n % 2 == 1:\n        raise JacobiError(\"n must be odd\")\n    a = a % n\n    if a == 0:\n        return 0\n    if a == 1:\n        return 1\n    a1, e = a, 0\n    while a1 % 2 == 0:\n        a1, e = a1 // 2, e + 1\n    if e % 2 == 0 or n % 8 == 1 or n % 8 == 7:\n        s = 1\n    else:\n        s = -1\n    if a1 == 1:\n        return s\n    if n % 4 == 3 and a1 % 4 == 3:\n        s = -s\n    return s * jacobi(n % a1, a1)\n\n\ndef square_root_mod_prime(a, p):\n    \"\"\"Modular square root of a, mod p, p prime.\"\"\"\n\n    # Based on the Handbook of Applied Cryptography, algorithms 3.34 to 3.39.\n\n    # This module has been tested for all values in [0,p-1] for\n    # every prime p from 3 to 1229.\n\n    assert 0 <= a < p\n    assert 1 < p\n\n    if a == 0:\n        return 0\n    if p == 2:\n        return a\n\n    jac = jacobi(a, p)\n    if jac == -1:\n        raise SquareRootError(\"%d has no square root modulo %d\" % (a, p))\n\n    if p % 4 == 3:\n        return pow(a, (p + 1) // 4, p)\n\n    if p % 8 == 5:\n        d = pow(a, (p - 1) // 4, p)\n        if d == 1:\n            return pow(a, (p + 3) // 8, p)\n        assert d == p - 1\n        return (2 * a * pow(4 * a, (p - 5) // 8, p)) % p\n\n    if PY2:\n        # xrange on python2 can take integers representable as C long only\n        range_top = min(0x7FFFFFFF, p)\n    else:\n        range_top = p\n    for b in xrange(2, range_top):\n        if jacobi(b * b - 4 * a, p) == -1:\n            f = (a, -b, 1)\n            ff = polynomial_exp_mod((0, 1), (p + 1) // 2, f, p)\n            if ff[1]:\n                raise SquareRootError(\"p is not prime\")\n            return ff[0]\n    raise RuntimeError(\"No b found.\")\n\n\n# because all the inverse_mod code is arch/environment specific, and coveralls\n# expects it to execute equal number of times, we need to waive it by\n# adding the \"no branch\" pragma to all branches\nif GMPY2:  # pragma: no branch\n\n    def inverse_mod(a, m):\n        \"\"\"Inverse of a mod m.\"\"\"\n        if a == 0:  # pragma: no branch\n            return 0\n        return powmod(a, -1, m)\n\nelif GMPY:  # pragma: no branch\n\n    def inverse_mod(a, m):\n        \"\"\"Inverse of a mod m.\"\"\"\n        # while libgmp does support inverses modulo, it is accessible\n        # only using the native `pow()` function, and `pow()` in gmpy sanity\n        # checks the parameters before passing them on to underlying\n        # implementation\n        if a == 0:  # pragma: no branch\n            return 0\n        a = mpz(a)\n        m = mpz(m)\n\n        lm, hm = mpz(1), mpz(0)\n        low, high = a % m, m\n        while low > 1:  # pragma: no branch\n            r = high // low\n            lm, low, hm, high = hm - lm * r, high - low * r, lm, low\n\n        return lm % m\n\nelif sys.version_info >= (3, 8):  # pragma: no branch\n\n    def inverse_mod(a, m):\n        \"\"\"Inverse of a mod m.\"\"\"\n        if a == 0:  # pragma: no branch\n            return 0\n        return pow(a, -1, m)\n\nelse:  # pragma: no branch\n\n    def inverse_mod(a, m):\n        \"\"\"Inverse of a mod m.\"\"\"\n\n        if a == 0:  # pragma: no branch\n            return 0\n\n        lm, hm = 1, 0\n        low, high = a % m, m\n        while low > 1:  # pragma: no branch\n            r = high // low\n            lm, low, hm, high = hm - lm * r, high - low * r, lm, low\n\n        return lm % m\n\n\ntry:\n    gcd2 = math.gcd\nexcept AttributeError:\n\n    def gcd2(a, b):\n        \"\"\"Greatest common divisor using Euclid's algorithm.\"\"\"\n        while a:\n            a, b = b % a, a\n        return b\n\n\ndef gcd(*a):\n    \"\"\"Greatest common divisor.\n\n    Usage: gcd([ 2, 4, 6 ])\n    or:    gcd(2, 4, 6)\n    \"\"\"\n\n    if len(a) > 1:\n        return reduce(gcd2, a)\n    if hasattr(a[0], \"__iter__\"):\n        return reduce(gcd2, a[0])\n    return a[0]\n\n\ndef lcm2(a, b):\n    \"\"\"Least common multiple of two integers.\"\"\"\n\n    return (a * b) // gcd(a, b)\n\n\ndef lcm(*a):\n    \"\"\"Least common multiple.\n\n    Usage: lcm([ 3, 4, 5 ])\n    or:    lcm(3, 4, 5)\n    \"\"\"\n\n    if len(a) > 1:\n        return reduce(lcm2, a)\n    if hasattr(a[0], \"__iter__\"):\n        return reduce(lcm2, a[0])\n    return a[0]\n\n\ndef factorization(n):\n    \"\"\"Decompose n into a list of (prime,exponent) pairs.\"\"\"\n\n    assert isinstance(n, integer_types)\n\n    if n < 2:\n        return []\n\n    result = []\n\n    # Test the small primes:\n\n    for d in smallprimes:\n        if d > n:\n            break\n        q, r = divmod(n, d)\n        if r == 0:\n            count = 1\n            while d <= n:\n                n = q\n                q, r = divmod(n, d)\n                if r != 0:\n                    break\n                count = count + 1\n            result.append((d, count))\n\n    # If n is still greater than the last of our small primes,\n    # it may require further work:\n\n    if n > smallprimes[-1]:\n        if is_prime(n):  # If what's left is prime, it's easy:\n            result.append((n, 1))\n        else:  # Ugh. Search stupidly for a divisor:\n            d = smallprimes[-1]\n            while 1:\n                d = d + 2  # Try the next divisor.\n                q, r = divmod(n, d)\n                if q < d:  # n < d*d means we're done, n = 1 or prime.\n                    break\n                if r == 0:  # d divides n. How many times?\n                    count = 1\n                    n = q\n                    while d <= n:  # As long as d might still divide n,\n                        q, r = divmod(n, d)  # see if it does.\n                        if r != 0:\n                            break\n                        n = q  # It does. Reduce n, increase count.\n                        count = count + 1\n                    result.append((d, count))\n            if n > 1:\n                result.append((n, 1))\n\n    return result\n\n\ndef phi(n):  # pragma: no cover\n    \"\"\"Return the Euler totient function of n.\"\"\"\n    # deprecated in 0.14\n    warnings.warn(\n        \"Function is unused by library code. If you use this code, \"\n        \"please open an issue in \"\n        \"https://github.com/tlsfuzzer/python-ecdsa\",\n        DeprecationWarning,\n    )\n\n    assert isinstance(n, integer_types)\n\n    if n < 3:\n        return 1\n\n    result = 1\n    ff = factorization(n)\n    for f in ff:\n        e = f[1]\n        if e > 1:\n            result = result * f[0] ** (e - 1) * (f[0] - 1)\n        else:\n            result = result * (f[0] - 1)\n    return result\n\n\ndef carmichael(n):  # pragma: no cover\n    \"\"\"Return Carmichael function of n.\n\n    Carmichael(n) is the smallest integer x such that\n    m**x = 1 mod n for all m relatively prime to n.\n    \"\"\"\n    # deprecated in 0.14\n    warnings.warn(\n        \"Function is unused by library code. If you use this code, \"\n        \"please open an issue in \"\n        \"https://github.com/tlsfuzzer/python-ecdsa\",\n        DeprecationWarning,\n    )\n\n    return carmichael_of_factorized(factorization(n))\n\n\ndef carmichael_of_factorized(f_list):  # pragma: no cover\n    \"\"\"Return the Carmichael function of a number that is\n    represented as a list of (prime,exponent) pairs.\n    \"\"\"\n    # deprecated in 0.14\n    warnings.warn(\n        \"Function is unused by library code. If you use this code, \"\n        \"please open an issue in \"\n        \"https://github.com/tlsfuzzer/python-ecdsa\",\n        DeprecationWarning,\n    )\n\n    if len(f_list) < 1:\n        return 1\n\n    result = carmichael_of_ppower(f_list[0])\n    for i in xrange(1, len(f_list)):\n        result = lcm(result, carmichael_of_ppower(f_list[i]))\n\n    return result\n\n\ndef carmichael_of_ppower(pp):  # pragma: no cover\n    \"\"\"Carmichael function of the given power of the given prime.\"\"\"\n    # deprecated in 0.14\n    warnings.warn(\n        \"Function is unused by library code. If you use this code, \"\n        \"please open an issue in \"\n        \"https://github.com/tlsfuzzer/python-ecdsa\",\n        DeprecationWarning,\n    )\n\n    p, a = pp\n    if p == 2 and a > 2:\n        return 2 ** (a - 2)\n    else:\n        return (p - 1) * p ** (a - 1)\n\n\ndef order_mod(x, m):  # pragma: no cover\n    \"\"\"Return the order of x in the multiplicative group mod m.\"\"\"\n    # deprecated in 0.14\n    warnings.warn(\n        \"Function is unused by library code. If you use this code, \"\n        \"please open an issue in \"\n        \"https://github.com/tlsfuzzer/python-ecdsa\",\n        DeprecationWarning,\n    )\n\n    # Warning: this implementation is not very clever, and will\n    # take a long time if m is very large.\n\n    if m <= 1:\n        return 0\n\n    assert gcd(x, m) == 1\n\n    z = x\n    result = 1\n    while z != 1:\n        z = (z * x) % m\n        result = result + 1\n    return result\n\n\ndef largest_factor_relatively_prime(a, b):  # pragma: no cover\n    \"\"\"Return the largest factor of a relatively prime to b.\"\"\"\n    # deprecated in 0.14\n    warnings.warn(\n        \"Function is unused by library code. If you use this code, \"\n        \"please open an issue in \"\n        \"https://github.com/tlsfuzzer/python-ecdsa\",\n        DeprecationWarning,\n    )\n\n    while 1:\n        d = gcd(a, b)\n        if d <= 1:\n            break\n        b = d\n        while 1:\n            q, r = divmod(a, d)\n            if r > 0:\n                break\n            a = q\n    return a\n\n\ndef kinda_order_mod(x, m):  # pragma: no cover\n    \"\"\"Return the order of x in the multiplicative group mod m',\n    where m' is the largest factor of m relatively prime to x.\n    \"\"\"\n    # deprecated in 0.14\n    warnings.warn(\n        \"Function is unused by library code. If you use this code, \"\n        \"please open an issue in \"\n        \"https://github.com/tlsfuzzer/python-ecdsa\",\n        DeprecationWarning,\n    )\n\n    return order_mod(x, largest_factor_relatively_prime(m, x))\n\n\ndef is_prime(n):\n    \"\"\"Return True if x is prime, False otherwise.\n\n    We use the Miller-Rabin test, as given in Menezes et al. p. 138.\n    This test is not exact: there are composite values n for which\n    it returns True.\n\n    In testing the odd numbers from 10000001 to 19999999,\n    about 66 composites got past the first test,\n    5 got past the second test, and none got past the third.\n    Since factors of 2, 3, 5, 7, and 11 were detected during\n    preliminary screening, the number of numbers tested by\n    Miller-Rabin was (19999999 - 10000001)*(2/3)*(4/5)*(6/7)\n    = 4.57 million.\n    \"\"\"\n\n    # (This is used to study the risk of false positives:)\n    global miller_rabin_test_count\n\n    miller_rabin_test_count = 0\n\n    if n <= smallprimes[-1]:\n        if n in smallprimes:\n            return True\n        else:\n            return False\n\n    if gcd(n, 2 * 3 * 5 * 7 * 11) != 1:\n        return False\n\n    # Choose a number of iterations sufficient to reduce the\n    # probability of accepting a composite below 2**-80\n    # (from Menezes et al. Table 4.4):\n\n    t = 40\n    n_bits = 1 + int(math.log(n, 2))\n    for k, tt in (\n        (100, 27),\n        (150, 18),\n        (200, 15),\n        (250, 12),\n        (300, 9),\n        (350, 8),\n        (400, 7),\n        (450, 6),\n        (550, 5),\n        (650, 4),\n        (850, 3),\n        (1300, 2),\n    ):\n        if n_bits < k:\n            break\n        t = tt\n\n    # Run the test t times:\n\n    s = 0\n    r = n - 1\n    while (r % 2) == 0:\n        s = s + 1\n        r = r // 2\n    for i in xrange(t):\n        a = smallprimes[i]\n        y = pow(a, r, n)\n        if y != 1 and y != n - 1:\n            j = 1\n            while j <= s - 1 and y != n - 1:\n                y = pow(y, 2, n)\n                if y == 1:\n                    miller_rabin_test_count = i + 1\n                    return False\n                j = j + 1\n            if y != n - 1:\n                miller_rabin_test_count = i + 1\n                return False\n    return True\n\n\ndef next_prime(starting_value):\n    \"\"\"Return the smallest prime larger than the starting value.\"\"\"\n\n    if starting_value < 2:\n        return 2\n    result = (starting_value + 1) | 1\n    while not is_prime(result):\n        result = result + 2\n    return result\n\n\nsmallprimes = [\n    2,\n    3,\n    5,\n    7,\n    11,\n    13,\n    17,\n    19,\n    23,\n    29,\n    31,\n    37,\n    41,\n    43,\n    47,\n    53,\n    59,\n    61,\n    67,\n    71,\n    73,\n    79,\n    83,\n    89,\n    97,\n    101,\n    103,\n    107,\n    109,\n    113,\n    127,\n    131,\n    137,\n    139,\n    149,\n    151,\n    157,\n    163,\n    167,\n    173,\n    179,\n    181,\n    191,\n    193,\n    197,\n    199,\n    211,\n    223,\n    227,\n    229,\n    233,\n    239,\n    241,\n    251,\n    257,\n    263,\n    269,\n    271,\n    277,\n    281,\n    283,\n    293,\n    307,\n    311,\n    313,\n    317,\n    331,\n    337,\n    347,\n    349,\n    353,\n    359,\n    367,\n    373,\n    379,\n    383,\n    389,\n    397,\n    401,\n    409,\n    419,\n    421,\n    431,\n    433,\n    439,\n    443,\n    449,\n    457,\n    461,\n    463,\n    467,\n    479,\n    487,\n    491,\n    499,\n    503,\n    509,\n    521,\n    523,\n    541,\n    547,\n    557,\n    563,\n    569,\n    571,\n    577,\n    587,\n    593,\n    599,\n    601,\n    607,\n    613,\n    617,\n    619,\n    631,\n    641,\n    643,\n    647,\n    653,\n    659,\n    661,\n    673,\n    677,\n    683,\n    691,\n    701,\n    709,\n    719,\n    727,\n    733,\n    739,\n    743,\n    751,\n    757,\n    761,\n    769,\n    773,\n    787,\n    797,\n    809,\n    811,\n    821,\n    823,\n    827,\n    829,\n    839,\n    853,\n    857,\n    859,\n    863,\n    877,\n    881,\n    883,\n    887,\n    907,\n    911,\n    919,\n    929,\n    937,\n    941,\n    947,\n    953,\n    967,\n    971,\n    977,\n    983,\n    991,\n    997,\n    1009,\n    1013,\n    1019,\n    1021,\n    1031,\n    1033,\n    1039,\n    1049,\n    1051,\n    1061,\n    1063,\n    1069,\n    1087,\n    1091,\n    1093,\n    1097,\n    1103,\n    1109,\n    1117,\n    1123,\n    1129,\n    1151,\n    1153,\n    1163,\n    1171,\n    1181,\n    1187,\n    1193,\n    1201,\n    1213,\n    1217,\n    1223,\n    1229,\n]\n\nmiller_rabin_test_count = 0\n"
  },
  {
    "path": "code/default/lib/noarch/ecdsa/rfc6979.py",
    "content": "\"\"\"\nRFC 6979:\n    Deterministic Usage of the Digital Signature Algorithm (DSA) and\n    Elliptic Curve Digital Signature Algorithm (ECDSA)\n\n    http://tools.ietf.org/html/rfc6979\n\nMany thanks to Coda Hale for his implementation in Go language:\n    https://github.com/codahale/rfc6979\n\"\"\"\n\nimport hmac\nfrom binascii import hexlify\nfrom .util import number_to_string, number_to_string_crop, bit_length\nfrom ._compat import hmac_compat\n\n\n# bit_length was defined in this module previously so keep it for backwards\n# compatibility, will need to deprecate and remove it later\n__all__ = [\"bit_length\", \"bits2int\", \"bits2octets\", \"generate_k\"]\n\n\ndef bits2int(data, qlen):\n    x = int(hexlify(data), 16)\n    l = len(data) * 8\n\n    if l > qlen:\n        return x >> (l - qlen)\n    return x\n\n\ndef bits2octets(data, order):\n    z1 = bits2int(data, bit_length(order))\n    z2 = z1 - order\n\n    if z2 < 0:\n        z2 = z1\n\n    return number_to_string_crop(z2, order)\n\n\n# https://tools.ietf.org/html/rfc6979#section-3.2\ndef generate_k(order, secexp, hash_func, data, retry_gen=0, extra_entropy=b\"\"):\n    \"\"\"\n    Generate the ``k`` value - the nonce for DSA.\n\n    :param int order: order of the DSA generator used in the signature\n    :param int secexp: secure exponent (private key) in numeric form\n    :param hash_func: reference to the same hash function used for generating\n        hash, like :py:class:`hashlib.sha1`\n    :param bytes data: hash in binary form of the signing data\n    :param int retry_gen: how many good 'k' values to skip before returning\n    :param bytes extra_entropy: additional added data in binary form as per\n        section-3.6 of rfc6979\n    :rtype: int\n    \"\"\"\n\n    qlen = bit_length(order)\n    holen = hash_func().digest_size\n    rolen = (qlen + 7) // 8\n    bx = (\n        hmac_compat(number_to_string(secexp, order)),\n        hmac_compat(bits2octets(data, order)),\n        hmac_compat(extra_entropy),\n    )\n\n    # Step B\n    v = b\"\\x01\" * holen\n\n    # Step C\n    k = b\"\\x00\" * holen\n\n    # Step D\n\n    k = hmac.new(k, digestmod=hash_func)\n    k.update(v + b\"\\x00\")\n    for i in bx:\n        k.update(i)\n    k = k.digest()\n\n    # Step E\n    v = hmac.new(k, v, hash_func).digest()\n\n    # Step F\n    k = hmac.new(k, digestmod=hash_func)\n    k.update(v + b\"\\x01\")\n    for i in bx:\n        k.update(i)\n    k = k.digest()\n\n    # Step G\n    v = hmac.new(k, v, hash_func).digest()\n\n    # Step H\n    while True:\n        # Step H1\n        t = b\"\"\n\n        # Step H2\n        while len(t) < rolen:\n            v = hmac.new(k, v, hash_func).digest()\n            t += v\n\n        # Step H3\n        secret = bits2int(t, qlen)\n\n        if 1 <= secret < order:\n            if retry_gen <= 0:\n                return secret\n            retry_gen -= 1\n\n        k = hmac.new(k, v + b\"\\x00\", hash_func).digest()\n        v = hmac.new(k, v, hash_func).digest()\n"
  },
  {
    "path": "code/default/lib/noarch/ecdsa/util.py",
    "content": "from __future__ import division\n\nimport os\nimport math\nimport binascii\nimport sys\nfrom hashlib import sha256\nfrom six import PY2, int2byte, b, next\nfrom . import der\nfrom ._compat import normalise_bytes\n\n# RFC5480:\n#   The \"unrestricted\" algorithm identifier is:\n#     id-ecPublicKey OBJECT IDENTIFIER ::= {\n#       iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 }\n\noid_ecPublicKey = (1, 2, 840, 10045, 2, 1)\nencoded_oid_ecPublicKey = der.encode_oid(*oid_ecPublicKey)\n\n# RFC5480:\n# The ECDH algorithm uses the following object identifier:\n#      id-ecDH OBJECT IDENTIFIER ::= {\n#        iso(1) identified-organization(3) certicom(132) schemes(1)\n#        ecdh(12) }\n\noid_ecDH = (1, 3, 132, 1, 12)\n\n# RFC5480:\n# The ECMQV algorithm uses the following object identifier:\n#      id-ecMQV OBJECT IDENTIFIER ::= {\n#        iso(1) identified-organization(3) certicom(132) schemes(1)\n#        ecmqv(13) }\n\noid_ecMQV = (1, 3, 132, 1, 13)\n\nif sys.version_info >= (3,):  # pragma: no branch\n\n    def entropy_to_bits(ent_256):\n        \"\"\"Convert a bytestring to string of 0's and 1's\"\"\"\n        return bin(int.from_bytes(ent_256, \"big\"))[2:].zfill(len(ent_256) * 8)\n\nelse:\n\n    def entropy_to_bits(ent_256):\n        \"\"\"Convert a bytestring to string of 0's and 1's\"\"\"\n        return \"\".join(bin(ord(x))[2:].zfill(8) for x in ent_256)\n\n\nif sys.version_info < (2, 7):  # pragma: no branch\n    # Can't add a method to a built-in type so we are stuck with this\n    def bit_length(x):\n        return len(bin(x)) - 2\n\nelse:\n\n    def bit_length(x):\n        return x.bit_length() or 1\n\n\ndef orderlen(order):\n    return (1 + len(\"%x\" % order)) // 2  # bytes\n\n\ndef randrange(order, entropy=None):\n    \"\"\"Return a random integer k such that 1 <= k < order, uniformly\n    distributed across that range. Worst case should be a mean of 2 loops at\n    (2**k)+2.\n\n    Note that this function is not declared to be forwards-compatible: we may\n    change the behavior in future releases. The entropy= argument (which\n    should get a callable that behaves like os.urandom) can be used to\n    achieve stability within a given release (for repeatable unit tests), but\n    should not be used as a long-term-compatible key generation algorithm.\n    \"\"\"\n    assert order > 1\n    if entropy is None:\n        entropy = os.urandom\n    upper_2 = bit_length(order - 2)\n    upper_256 = upper_2 // 8 + 1\n    while True:  # I don't think this needs a counter with bit-wise randrange\n        ent_256 = entropy(upper_256)\n        ent_2 = entropy_to_bits(ent_256)\n        rand_num = int(ent_2[:upper_2], base=2) + 1\n        if 0 < rand_num < order:\n            return rand_num\n\n\nclass PRNG:\n    # this returns a callable which, when invoked with an integer N, will\n    # return N pseudorandom bytes. Note: this is a short-term PRNG, meant\n    # primarily for the needs of randrange_from_seed__trytryagain(), which\n    # only needs to run it a few times per seed. It does not provide\n    # protection against state compromise (forward security).\n    def __init__(self, seed):\n        self.generator = self.block_generator(seed)\n\n    def __call__(self, numbytes):\n        a = [next(self.generator) for i in range(numbytes)]\n\n        if PY2:  # pragma: no branch\n            return \"\".join(a)\n        else:\n            return bytes(a)\n\n    def block_generator(self, seed):\n        counter = 0\n        while True:\n            for byte in sha256(\n                (\"prng-%d-%s\" % (counter, seed)).encode()\n            ).digest():\n                yield byte\n            counter += 1\n\n\ndef randrange_from_seed__overshoot_modulo(seed, order):\n    # hash the data, then turn the digest into a number in [1,order).\n    #\n    # We use David-Sarah Hopwood's suggestion: turn it into a number that's\n    # sufficiently larger than the group order, then modulo it down to fit.\n    # This should give adequate (but not perfect) uniformity, and simple\n    # code. There are other choices: try-try-again is the main one.\n    base = PRNG(seed)(2 * orderlen(order))\n    number = (int(binascii.hexlify(base), 16) % (order - 1)) + 1\n    assert 1 <= number < order, (1, number, order)\n    return number\n\n\ndef lsb_of_ones(numbits):\n    return (1 << numbits) - 1\n\n\ndef bits_and_bytes(order):\n    bits = int(math.log(order - 1, 2) + 1)\n    bytes = bits // 8\n    extrabits = bits % 8\n    return bits, bytes, extrabits\n\n\n# the following randrange_from_seed__METHOD() functions take an\n# arbitrarily-sized secret seed and turn it into a number that obeys the same\n# range limits as randrange() above. They are meant for deriving consistent\n# signing keys from a secret rather than generating them randomly, for\n# example a protocol in which three signing keys are derived from a master\n# secret. You should use a uniformly-distributed unguessable seed with about\n# curve.baselen bytes of entropy. To use one, do this:\n#   seed = os.urandom(curve.baselen) # or other starting point\n#   secexp = ecdsa.util.randrange_from_seed__trytryagain(sed, curve.order)\n#   sk = SigningKey.from_secret_exponent(secexp, curve)\n\n\ndef randrange_from_seed__truncate_bytes(seed, order, hashmod=sha256):\n    # hash the seed, then turn the digest into a number in [1,order), but\n    # don't worry about trying to uniformly fill the range. This will lose,\n    # on average, four bits of entropy.\n    bits, _bytes, extrabits = bits_and_bytes(order)\n    if extrabits:\n        _bytes += 1\n    base = hashmod(seed).digest()[:_bytes]\n    base = \"\\x00\" * (_bytes - len(base)) + base\n    number = 1 + int(binascii.hexlify(base), 16)\n    assert 1 <= number < order\n    return number\n\n\ndef randrange_from_seed__truncate_bits(seed, order, hashmod=sha256):\n    # like string_to_randrange_truncate_bytes, but only lose an average of\n    # half a bit\n    bits = int(math.log(order - 1, 2) + 1)\n    maxbytes = (bits + 7) // 8\n    base = hashmod(seed).digest()[:maxbytes]\n    base = \"\\x00\" * (maxbytes - len(base)) + base\n    topbits = 8 * maxbytes - bits\n    if topbits:\n        base = int2byte(ord(base[0]) & lsb_of_ones(topbits)) + base[1:]\n    number = 1 + int(binascii.hexlify(base), 16)\n    assert 1 <= number < order\n    return number\n\n\ndef randrange_from_seed__trytryagain(seed, order):\n    # figure out exactly how many bits we need (rounded up to the nearest\n    # bit), so we can reduce the chance of looping to less than 0.5 . This is\n    # specified to feed from a byte-oriented PRNG, and discards the\n    # high-order bits of the first byte as necessary to get the right number\n    # of bits. The average number of loops will range from 1.0 (when\n    # order=2**k-1) to 2.0 (when order=2**k+1).\n    assert order > 1\n    bits, bytes, extrabits = bits_and_bytes(order)\n    generate = PRNG(seed)\n    while True:\n        extrabyte = b(\"\")\n        if extrabits:\n            extrabyte = int2byte(ord(generate(1)) & lsb_of_ones(extrabits))\n        guess = string_to_number(extrabyte + generate(bytes)) + 1\n        if 1 <= guess < order:\n            return guess\n\n\ndef number_to_string(num, order):\n    l = orderlen(order)\n    fmt_str = \"%0\" + str(2 * l) + \"x\"\n    string = binascii.unhexlify((fmt_str % num).encode())\n    assert len(string) == l, (len(string), l)\n    return string\n\n\ndef number_to_string_crop(num, order):\n    l = orderlen(order)\n    fmt_str = \"%0\" + str(2 * l) + \"x\"\n    string = binascii.unhexlify((fmt_str % num).encode())\n    return string[:l]\n\n\ndef string_to_number(string):\n    return int(binascii.hexlify(string), 16)\n\n\ndef string_to_number_fixedlen(string, order):\n    l = orderlen(order)\n    assert len(string) == l, (len(string), l)\n    return int(binascii.hexlify(string), 16)\n\n\n# these methods are useful for the sigencode= argument to SK.sign() and the\n# sigdecode= argument to VK.verify(), and control how the signature is packed\n# or unpacked.\n\n\ndef sigencode_strings(r, s, order):\n    r_str = number_to_string(r, order)\n    s_str = number_to_string(s, order)\n    return (r_str, s_str)\n\n\ndef sigencode_string(r, s, order):\n    \"\"\"\n    Encode the signature to raw format (:term:`raw encoding`)\n\n    It's expected that this function will be used as a `sigencode=` parameter\n    in :func:`ecdsa.keys.SigningKey.sign` method.\n\n    :param int r: first parameter of the signature\n    :param int s: second parameter of the signature\n    :param int order: the order of the curve over which the signature was\n        computed\n\n    :return: raw encoding of ECDSA signature\n    :rtype: bytes\n    \"\"\"\n    # for any given curve, the size of the signature numbers is\n    # fixed, so just use simple concatenation\n    r_str, s_str = sigencode_strings(r, s, order)\n    return r_str + s_str\n\n\ndef sigencode_der(r, s, order):\n    \"\"\"\n    Encode the signature into the ECDSA-Sig-Value structure using :term:`DER`.\n\n    Encodes the signature to the following :term:`ASN.1` structure::\n\n        Ecdsa-Sig-Value ::= SEQUENCE {\n            r       INTEGER,\n            s       INTEGER\n        }\n\n    It's expected that this function will be used as a `sigencode=` parameter\n    in :func:`ecdsa.keys.SigningKey.sign` method.\n\n    :param int r: first parameter of the signature\n    :param int s: second parameter of the signature\n    :param int order: the order of the curve over which the signature was\n        computed\n\n    :return: DER encoding of ECDSA signature\n    :rtype: bytes\n    \"\"\"\n    return der.encode_sequence(der.encode_integer(r), der.encode_integer(s))\n\n\n# canonical versions of sigencode methods\n# these enforce low S values, by negating the value (modulo the order) if\n# above order/2 see CECKey::Sign()\n# https://github.com/bitcoin/bitcoin/blob/master/src/key.cpp#L214\ndef sigencode_strings_canonize(r, s, order):\n    if s > order / 2:\n        s = order - s\n    return sigencode_strings(r, s, order)\n\n\ndef sigencode_string_canonize(r, s, order):\n    if s > order / 2:\n        s = order - s\n    return sigencode_string(r, s, order)\n\n\ndef sigencode_der_canonize(r, s, order):\n    if s > order / 2:\n        s = order - s\n    return sigencode_der(r, s, order)\n\n\nclass MalformedSignature(Exception):\n    \"\"\"\n    Raised by decoding functions when the signature is malformed.\n\n    Malformed in this context means that the relevant strings or integers\n    do not match what a signature over provided curve would create. Either\n    because the byte strings have incorrect lengths or because the encoded\n    values are too large.\n    \"\"\"\n\n    pass\n\n\ndef sigdecode_string(signature, order):\n    \"\"\"\n    Decoder for :term:`raw encoding`  of ECDSA signatures.\n\n    raw encoding is a simple concatenation of the two integers that comprise\n    the signature, with each encoded using the same amount of bytes depending\n    on curve size/order.\n\n    It's expected that this function will be used as the `sigdecode=`\n    parameter to the :func:`ecdsa.keys.VerifyingKey.verify` method.\n\n    :param signature: encoded signature\n    :type signature: bytes like object\n    :param order: order of the curve over which the signature was computed\n    :type order: int\n\n    :raises MalformedSignature: when the encoding of the signature is invalid\n\n    :return: tuple with decoded 'r' and 's' values of signature\n    :rtype: tuple of ints\n    \"\"\"\n    signature = normalise_bytes(signature)\n    l = orderlen(order)\n    if not len(signature) == 2 * l:\n        raise MalformedSignature(\n            \"Invalid length of signature, expected {0} bytes long, \"\n            \"provided string is {1} bytes long\".format(2 * l, len(signature))\n        )\n    r = string_to_number_fixedlen(signature[:l], order)\n    s = string_to_number_fixedlen(signature[l:], order)\n    return r, s\n\n\ndef sigdecode_strings(rs_strings, order):\n    \"\"\"\n    Decode the signature from two strings.\n\n    First string needs to be a big endian encoding of 'r', second needs to\n    be a big endian encoding of the 's' parameter of an ECDSA signature.\n\n    It's expected that this function will be used as the `sigdecode=`\n    parameter to the :func:`ecdsa.keys.VerifyingKey.verify` method.\n\n    :param list rs_strings: list of two bytes-like objects, each encoding one\n        parameter of signature\n    :param int order: order of the curve over which the signature was computed\n\n    :raises MalformedSignature: when the encoding of the signature is invalid\n\n    :return: tuple with decoded 'r' and 's' values of signature\n    :rtype: tuple of ints\n    \"\"\"\n    if not len(rs_strings) == 2:\n        raise MalformedSignature(\n            \"Invalid number of strings provided: {0}, expected 2\".format(\n                len(rs_strings)\n            )\n        )\n    (r_str, s_str) = rs_strings\n    r_str = normalise_bytes(r_str)\n    s_str = normalise_bytes(s_str)\n    l = orderlen(order)\n    if not len(r_str) == l:\n        raise MalformedSignature(\n            \"Invalid length of first string ('r' parameter), \"\n            \"expected {0} bytes long, provided string is {1} \"\n            \"bytes long\".format(l, len(r_str))\n        )\n    if not len(s_str) == l:\n        raise MalformedSignature(\n            \"Invalid length of second string ('s' parameter), \"\n            \"expected {0} bytes long, provided string is {1} \"\n            \"bytes long\".format(l, len(s_str))\n        )\n    r = string_to_number_fixedlen(r_str, order)\n    s = string_to_number_fixedlen(s_str, order)\n    return r, s\n\n\ndef sigdecode_der(sig_der, order):\n    \"\"\"\n    Decoder for DER format of ECDSA signatures.\n\n    DER format of signature is one that uses the :term:`ASN.1` :term:`DER`\n    rules to encode it as a sequence of two integers::\n\n        Ecdsa-Sig-Value ::= SEQUENCE {\n            r       INTEGER,\n            s       INTEGER\n        }\n\n    It's expected that this function will be used as as the `sigdecode=`\n    parameter to the :func:`ecdsa.keys.VerifyingKey.verify` method.\n\n    :param sig_der: encoded signature\n    :type sig_der: bytes like object\n    :param order: order of the curve over which the signature was computed\n    :type order: int\n\n    :raises UnexpectedDER: when the encoding of signature is invalid\n\n    :return: tuple with decoded 'r' and 's' values of signature\n    :rtype: tuple of ints\n    \"\"\"\n    sig_der = normalise_bytes(sig_der)\n    # return der.encode_sequence(der.encode_integer(r), der.encode_integer(s))\n    rs_strings, empty = der.remove_sequence(sig_der)\n    if empty != b\"\":\n        raise der.UnexpectedDER(\n            \"trailing junk after DER sig: %s\" % binascii.hexlify(empty)\n        )\n    r, rest = der.remove_integer(rs_strings)\n    s, empty = der.remove_integer(rest)\n    if empty != b\"\":\n        raise der.UnexpectedDER(\n            \"trailing junk after DER numbers: %s\" % binascii.hexlify(empty)\n        )\n    return r, s\n"
  },
  {
    "path": "code/default/lib/noarch/encrypt.py",
    "content": "#!/usr/bin/env python\n\n# Copyright (c) 2014 clowwindy\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in\n# all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n# SOFTWARE.\n\n\n\nimport os\nimport sys\nimport hashlib\nimport logging as xlog\n\n\nfrom scrypto import m2, rc4_md5, salsa20_ctr, ctypes_openssl, table\n\n\nmethod_supported = {}\nmethod_supported.update(rc4_md5.ciphers)\nmethod_supported.update(salsa20_ctr.ciphers)\nmethod_supported.update(ctypes_openssl.ciphers)\n# let M2Crypto override ctypes_openssl\nmethod_supported.update(m2.ciphers)\nmethod_supported.update(table.ciphers)\n\n\ndef random_string(length):\n    try:\n        import M2Crypto.Rand\n        return M2Crypto.Rand.rand_bytes(length)\n    except ImportError:\n        return os.urandom(length)\n\n\ncached_keys = {}\n\n\ndef try_cipher(key, method=None):\n    Encryptor(key, method)\n\n\ndef EVP_BytesToKey(password, key_len, iv_len):\n    # equivalent to OpenSSL's EVP_BytesToKey() with count 1\n    # so that we make the same key and iv as nodejs version\n    if hasattr(password, 'encode'):\n        password = password.encode('utf-8')\n    r = cached_keys.get(password, None)\n    if r:\n        return r\n    m = []\n    i = 0\n    while len(b''.join(m)) < (key_len + iv_len):\n        md5 = hashlib.md5()\n        data = password\n        if i > 0:\n            data = m[i - 1] + password\n        md5.update(data)\n        m.append(md5.digest())\n        i += 1\n    ms = b''.join(m)\n    key = ms[:key_len]\n    iv = ms[key_len:key_len + iv_len]\n    cached_keys[password] = (key, iv)\n    return key, iv\n\n\nclass Encryptor(object):\n    def __init__(self, key, method):\n        self.key = key\n        self.method = method\n        self.iv = None\n        self.iv_sent = False\n        self.cipher_iv = b''\n        self.decipher = None\n        method = method.lower()\n        self._method_info = self.get_method_info(method)\n        if self._method_info:\n            self.cipher = self.get_cipher(key, method, 1,\n                                          random_string(self._method_info[1]))\n        else:\n            xlog.error('method %s not supported' % method)\n            sys.exit(1)\n\n    def get_method_info(self, method):\n        method = method.lower()\n        m = method_supported.get(method)\n        return m\n\n    def iv_len(self):\n        return len(self.cipher_iv)\n\n    def get_cipher(self, password, method, op, iv):\n        if hasattr(password, 'encode'):\n            password = password.encode('utf-8')\n        m = self._method_info\n        if m[0] > 0:\n            key, iv_ = EVP_BytesToKey(password, m[0], m[1])\n        else:\n            # key_length == 0 indicates we should use the key directly\n            key, iv = password, b''\n\n        iv = iv[:m[1]]\n        if op == 1:\n            # this iv is for cipher not decipher\n            self.cipher_iv = iv[:m[1]]\n        return m[2](method, key, iv, op)\n\n    def encrypt(self, buf):\n        if len(buf) == 0:\n            return buf\n\n        if not self.iv_sent:\n            head = self.cipher_iv\n            self.iv_sent = True\n        else:\n            head = \"\"\n        return head + self.cipher.update(buf)\n\n    def decrypt(self, buf):\n        if len(buf) == 0:\n            return buf\n        if self.decipher is None:\n            decipher_iv_len = self._method_info[1]\n            decipher_iv = buf[:decipher_iv_len]\n            self.decipher = self.get_cipher(self.key, self.method, 0,\n                                            iv=decipher_iv)\n            buf = buf[decipher_iv_len:]\n            if len(buf) == 0:\n                return buf\n        return self.decipher.update(buf)\n\ndef encrypt_all(password, method, op, data):\n    result = []\n    method = method.lower()\n    (key_len, iv_len, m) = method_supported[method]\n    if key_len > 0:\n        key, _ = EVP_BytesToKey(password, key_len, iv_len)\n    else:\n        key = password\n    if op:\n        iv = random_string(iv_len)\n        result.append(iv)\n    else:\n        iv = data[:iv_len]\n        data = data[iv_len:]\n    cipher = m(method, key, iv, op)\n    result.append(cipher.update(data))\n    return b''.join(result)\n\n\ntry:\n    from Crypto.Cipher.ARC4 import new as RC4Cipher\nexcept:\n    xlog.warn('Load Crypto.Cipher.ARC4 Failed, Use Pure Python Instead.')\n    class RC4Cipher(object):\n        def __init__(self, key):\n            x = 0\n            box = list(range(256))\n            for i, y in enumerate(box):\n                x = (x + y + ord(key[i % len(key)])) & 0xff\n                box[i], box[x] = box[x], y\n            self.__box = box\n            self.__x = 0\n            self.__y = 0\n        def encrypt(self, data):\n            out = []\n            out_append = out.append\n            x = self.__x\n            y = self.__y\n            box = self.__box\n            for char in data:\n                x = (x + 1) & 0xff\n                y = (y + box[x]) & 0xff\n                box[x], box[y] = box[y], box[x]\n                out_append(chr(ord(char) ^ box[(box[x] + box[y]) & 0xff]))\n            self.__x = x\n            self.__y = y\n            return ''.join(out)"
  },
  {
    "path": "code/default/lib/noarch/env_info.py",
    "content": "import os\nimport platform\nimport sys\nfrom pathlib import Path\nimport json\n\nimport utils\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\ndefault_path = os.path.abspath(os.path.join(current_path, os.path.pardir, os.path.pardir))\ndata_path = os.path.abspath(os.path.join(default_path, os.path.pardir, os.path.pardir, 'data'))\n\n\ndef win32_version():\n    import ctypes\n    class OSVERSIONINFOEXW(ctypes.Structure):\n        _fields_ = [('dwOSVersionInfoSize', ctypes.c_ulong),\n                    ('dwMajorVersion', ctypes.c_ulong),\n                    ('dwMinorVersion', ctypes.c_ulong),\n                    ('dwBuildNumber', ctypes.c_ulong),\n                    ('dwPlatformId', ctypes.c_ulong),\n                    ('szCSDVersion', ctypes.c_wchar * 128),\n                    ('wServicePackMajor', ctypes.c_ushort),\n                    ('wServicePackMinor', ctypes.c_ushort),\n                    ('wSuiteMask', ctypes.c_ushort),\n                    ('wProductType', ctypes.c_byte),\n                    ('wReserved', ctypes.c_byte)]\n\n    \"\"\"\n    Get's the OS major and minor versions.  Returns a tuple of\n    (OS_MAJOR, OS_MINOR).\n    \"\"\"\n    os_version = OSVERSIONINFOEXW()\n    os_version.dwOSVersionInfoSize = ctypes.sizeof(os_version)\n    retcode = ctypes.windll.Ntdll.RtlGetVersion(ctypes.byref(os_version))\n    if retcode != 0:\n        raise Exception(\"Failed to get OS version\")\n\n    return os_version.dwMajorVersion\n\n\ndef win32_version_string():\n    import ctypes\n    class OSVERSIONINFOEXW(ctypes.Structure):\n        _fields_ = [('dwOSVersionInfoSize', ctypes.c_ulong),\n                    ('dwMajorVersion', ctypes.c_ulong),\n                    ('dwMinorVersion', ctypes.c_ulong),\n                    ('dwBuildNumber', ctypes.c_ulong),\n                    ('dwPlatformId', ctypes.c_ulong),\n                    ('szCSDVersion', ctypes.c_wchar * 128),\n                    ('wServicePackMajor', ctypes.c_ushort),\n                    ('wServicePackMinor', ctypes.c_ushort),\n                    ('wSuiteMask', ctypes.c_ushort),\n                    ('wProductType', ctypes.c_byte),\n                    ('wReserved', ctypes.c_byte)]\n\n    \"\"\"\n    Get's the OS major and minor versions.  Returns a tuple of\n    (OS_MAJOR, OS_MINOR).\n    \"\"\"\n    os_version = OSVERSIONINFOEXW()\n    os_version.dwOSVersionInfoSize = ctypes.sizeof(os_version)\n    retcode = ctypes.windll.Ntdll.RtlGetVersion(ctypes.byref(os_version))\n    if retcode != 0:\n        raise Exception(\"Failed to get OS version\")\n\n    version_string = \"Version:%d-%d; Build:%d; Platform:%d; CSD:%s; ServicePack:%d-%d; Suite:%d; ProductType:%d\" % (\n        os_version.dwMajorVersion, os_version.dwMinorVersion,\n        os_version.dwBuildNumber,\n        os_version.dwPlatformId,\n        os_version.szCSDVersion,\n        os_version.wServicePackMajor, os_version.wServicePackMinor,\n        os_version.wSuiteMask,\n        os_version.wReserved\n    )\n\n    return version_string\n\n\ndef linux_distribution():\n    try:\n        with open(\"/etc/os-release\", \"br\") as fd:\n            kvs = {}\n            for line in fd.readlines():\n                kv = line.split(b\"=\")\n                if kv[0] == b\"NAME\":\n                    v = kv[1].replace(b\"\\\"\", b\"\")\n                    kvs[kv[0]] = v\n        if b\"PRETTY_NAME\" in kvs:\n            return kvs[b\"PRETTY_NAME\"]\n        elif b\"NAME\" in kvs:\n            return kvs[b\"NAME\"]\n        else:\n            return None\n    except Exception as e:\n        return None\n\n\ndef os_detail():\n    if sys.platform == \"win32\":\n        return win32_version_string()\n    elif sys.platform.startswith(\"linux\"):\n        distribution = linux_distribution()\n        if distribution is None:\n            return \"plat:%s release:%s ver:%s\" % (platform.platform(), platform.release(), platform.version())\n        else:\n            return utils.to_str(distribution)\n    elif sys.platform == \"darwin\":\n        release, versioninfo, machine = platform.mac_ver()\n        return \"Release:%s; Version:%s Machine:%s\" % (release, versioninfo, machine)\n    else:\n        return \"None\"\n\n\ndef get_system_date_path():\n    home = Path.home()\n    if sys.platform == \"win32\":\n        return os.environ.get(\"APPDATA\")\n    elif sys.platform == \"darwin\":\n        return os.path.join(home, \"Library\", \"Application Support\")\n    else:\n        return os.path.join(home, \".local\", \"share\")\n\ndef get_user_data_path():\n    \"\"\"\n    获取用户数据目录路径\n\n    Returns:\n        Path: 用户数据目录的 Path 对象\n\n    Raises:\n        OSError: 当无法确定用户目录时\n    \"\"\"\n    try:\n        home = Path.home()\n    except RuntimeError:\n        raise OSError(\"无法确定用户主目录\")\n\n    if sys.platform == \"win32\":\n        # Windows: %APPDATA%\n        appdata = os.environ.get(\"APPDATA\")\n        if appdata and Path(appdata).exists():\n            return Path(appdata)\n        # Fallback\n        fallback = home / \"AppData\" / \"Roaming\"\n        fallback.mkdir(parents=True, exist_ok=True)\n        return fallback\n\n    elif sys.platform == \"darwin\":\n        # macOS: ~/Library/Application Support\n        app_support = home / \"Library\" / \"Application Support\"\n        app_support.mkdir(parents=True, exist_ok=True)\n        return app_support\n\n    else:\n        # Linux/Unix: 遵循 XDG Base Directory Specification\n        xdg_data_home = os.environ.get(\"XDG_DATA_HOME\")\n        if xdg_data_home:\n            data_dir = Path(xdg_data_home)\n        else:\n            data_dir = home / \".local\" / \"share\"\n\n        data_dir.mkdir(parents=True, exist_ok=True)\n        return data_dir\n\n\ndef is_in_system_application_path(p):\n    if sys.platform == \"win32\":\n        if \"Program Files\" in p:\n            return True\n    elif sys.platform == \"darwin\":\n        if \"Contents\" in p:\n            return True\n    else:\n        return False\n\n\ndef get_app_name():\n    app_info_file = os.path.join(default_path, os.path.pardir, \"app_info.json\")\n    try:\n        with open(app_info_file, \"r\") as fd:\n            dat = json.load(fd)\n        return dat[\"app_name\"]\n    except Exception as e:\n        print(\"get app name fail:%r\", e)\n    return \"Dashboard\"\n\n\ndef use_default_data_path():\n    if os.path.isdir(data_path):\n        return True\n\n    try:\n        os.mkdir(data_path)\n        return True\n    except Exception as e:\n        return False\n\n\napp_name = get_app_name()\n\n# check and update data path\nif not os.path.isdir(data_path) and \\\n        (is_in_system_application_path(data_path) or not use_default_data_path() or app_name not in [\"XX-Net\"]):\n    data_path = os.path.join(get_user_data_path(), app_name)\n    if not os.path.isdir(data_path):\n        os.mkdir(data_path)\n"
  },
  {
    "path": "code/default/lib/noarch/front_base/__init__.py",
    "content": ""
  },
  {
    "path": "code/default/lib/noarch/front_base/boringssl_wrap.py",
    "content": "# this wrap has a close callback.\n# Which is used by  ip manager\n#  ip manager keep a connection number counter for every ip.\n\nimport socket\nimport threading\n\nimport selectors2 as selectors\nimport utils\n\nfrom boringssl import lib as bssl, ffi\n\n\nclass SSLConnection(object):\n    BIO_CLOSE = 1\n\n    def __init__(self, context, sock, ip_str=None, sni=None, on_close=None):\n        self._lock = threading.Lock()\n        self._context = context\n        self._sock = sock\n        self._fileno = self._sock.fileno()\n        # self._context.logger.debug(\"sock %s init fd:%d\", ip_str, self._fileno)\n        self.ip_str = ip_str\n        self.sni = sni\n        self._makefile_refs = 0\n        self._on_close = on_close\n        self.peer_cert = None\n        self.socket_closed = False\n        self.timeout = self._sock.gettimeout() or 0.1\n        self.running = True\n        self._connection = None\n        self.wrap()\n\n        self.select2 = selectors.DefaultSelector()\n        self.select2.register(sock, selectors.EVENT_WRITE)\n\n    def wrap(self):\n        ip, port = utils.get_ip_port(self.ip_str)\n        self.ip = ip\n        if isinstance(ip, str):\n            ip = utils.to_bytes(ip)\n\n        try:\n            self._sock.connect((ip, port))\n        except Exception as e:\n            raise socket.error('conn %s fail, sni:%s, e:%r' % (self.ip_str, self.sni, e))\n\n        self._sock.setblocking(True)\n\n        fn = self._fileno\n        bio = bssl.BSSL_BIO_new_socket(fn, self.BIO_CLOSE)\n\n        self._connection = bssl.BSSL_SSL_new(self._context.ctx)\n\n        if self.sni:\n            bssl.BSSL_SSL_set_tlsext_host_name(self._connection, utils.to_bytes(self.sni))\n\n        bssl.BSSL_SSL_set_bio(self._connection, bio, bio)\n\n        if self._context.support_http2:\n            proto = b\"h2\"\n            setting = b\"h2\"\n            ret = bssl.BSSL_SSL_add_application_settings(self._connection,\n                                                    proto, len(proto),\n                                                    setting, len(setting))\n            if ret != 1:\n                error = bssl.BSSL_SSL_get_error(self._connection, ret)\n                raise socket.error(\"set alpn fail, error:%s\" % error)\n\n        ret = bssl.BSSL_SSL_connect(self._connection)\n        if ret == 1:\n            return\n\n        error = bssl.BSSL_SSL_get_error(self._connection, ret)\n        if error == 1:\n            p = ffi.new(\"char[]\", b\"hello, worldhello, worldhello, worldhello, worldhello, world\")  # p is a 'char *'\n            q = ffi.new(\"char **\", p)  # q is a 'char **'\n            line_no = 0\n            line_no_p = ffi.new(\"int *\", line_no)\n            error = bssl.BSSL_ERR_get_error_line(q, line_no_p)\n            filename = ffi.string(q[0])\n            # self._context.logger.error(\"error:%d file:%s, line:%s\", error, filename, line_no_p[0])\n            raise socket.error(\"SSL_connect fail: %s, file:%s, line:%d, sni:%s\" %\n                               (error, filename, line_no_p[0], self.sni))\n        else:\n            raise socket.error(\"SSL_connect fail: %s, sni:%s\" % (error, self.sni))\n\n    def do_handshake(self):\n        if not self._connection:\n            raise socket.error(\"do_handshake fail: not connected\")\n\n        ret = bssl.BSSL_SSL_do_handshake(self._connection)\n        if ret == 1:\n            return\n\n        error = bssl.BSSL_SSL_get_error(self._connection, ret)\n        raise socket.error(\"do_handshake fail: %s\" % error)\n\n    def is_support_h2(self):\n        if not self._connection:\n            return False\n\n        out_data_pp = ffi.new(\"uint8_t**\", ffi.NULL)\n        out_len_p = ffi.new(\"unsigned*\")\n        bssl.BSSL_SSL_get0_alpn_selected(self._connection, out_data_pp, out_len_p)\n\n        proto_len = out_len_p[0]\n        if proto_len == 0:\n            return False\n\n        if ffi.string(out_data_pp[0])[:proto_len] == b\"h2\":\n            return True\n\n        return False\n\n    def setblocking(self, block):\n        self._context.logger.debug(\"%s setblocking: %d\", self.ip_str, block)\n        self._sock.setblocking(block)\n\n    def __getattr__(self, attr):\n        if attr in ('is_support_h2', \"_on_close\", '_context', '_sock', '_connection', '_makefile_refs',\n                      'sni', 'wrap', 'socket_closed'):\n            return getattr(self, attr)\n\n        elif hasattr(self._connection, attr):\n            return getattr(self._connection, attr)\n\n    def get_cert(self):\n        if self.peer_cert:\n            return self.peer_cert\n\n        def x509_name_to_string(xname):\n            line = bssl.BSSL_X509_NAME_oneline(xname, ffi.NULL, 0)\n            return ffi.string(line)\n\n        with self._lock:\n            if self._connection:\n                try:\n                    cert = bssl.BSSL_SSL_get_peer_certificate(self._connection)\n                    if cert == ffi.NULL:\n                        raise Exception(\"get cert failed\")\n\n                    alt_names_p = bssl.get_alt_names(cert)\n                    if alt_names_p == ffi.NULL:\n                        raise Exception(\"get alt_names failed\")\n\n                    alt_names = utils.to_str(ffi.string(alt_names_p))\n                    bssl.free(alt_names_p)\n\n                    subject = x509_name_to_string(bssl.BSSL_X509_get_subject_name(cert))\n                    issuer = x509_name_to_string(bssl.BSSL_X509_get_issuer_name(cert))\n                    altName = alt_names.split(\";\")\n                except Exception as e:\n                    subject = \"\"\n                    issuer = \"\"\n                    altName = []\n\n        self.peer_cert = {\n            \"cert\": subject,\n            \"issuer_commonname\": issuer,\n            \"commonName\": \"\",\n            \"altName\": altName\n        }\n\n        return self.peer_cert\n\n    def send(self, data, flags=0):\n        with self._lock:\n            if not self._connection:\n                e = socket.error(5)\n                e.errno = 5\n                raise e\n\n            try:\n                while True:\n                    # self._context.logger.debug(\"%s send %d \", self.ip_str, len(data))\n                    ret = bssl.BSSL_SSL_write(self._connection, data, len(data))\n                    if ret <= 0:\n                        errno = bssl.BSSL_SSL_get_error(self._connection, ret)\n                        if errno not in [2, 3, ]:\n                            # self._context.logger.warn(\"send n:%d errno: %d ip:%s\", ret, errno, self.ip_str)\n                            e = socket.error(errno)\n                            e.errno = errno\n                            raise e\n                        else:\n                            # self._context.logger.debug(\"send n:%d errno: %d ip:%s\", ret, errno, self.ip_str)\n                            self.select2.select(timeout=self.timeout)\n                            continue\n                    else:\n                        # self._context.logger.debug(\"send:%d ip:%s\", ret, self.ip_str)\n                        break\n\n                return ret\n            except OSError:\n                self._context.logger.warn(\"ssl send:%r\", e)\n                raise e\n            except Exception as e:\n                self._context.logger.exception(\"ssl send:%r\", e)\n                raise e\n\n    def recv(self, bufsiz, flags=0):\n        with self._lock:\n            if not self._connection:\n                e = socket.error(2)\n                e.errno = 5\n                raise e\n\n            bufsiz = min(16*1024, bufsiz)\n            buf = bytes(bufsiz)\n            # t0 = time.time()\n            n = bssl.BSSL_SSL_read(self._connection, buf, bufsiz)\n            # t2 = time.time()\n            # self._context.logger.debug(\"%s read: %d t:%f\", self.ip_str, n, t2 - t0)\n            if n <= 0:\n                errno = bssl.BSSL_SSL_get_error(self._connection, n)\n                # self._context.logger.warn(\"recv n:%d errno: %d ip:%s\", n, errno, self.ip_str)\n                e = socket.error(errno)\n                e.errno = errno\n                raise e\n\n            dat = bytes(buf[:n])\n            return dat\n\n    def recv_into(self, buf, nbytes=None):\n        if not nbytes:\n            nbytes = len(buf)\n\n        dat = self.recv(nbytes)\n        n = len(dat)\n        buf[:n] = dat\n        return n\n\n    def read(self, bufsiz, flags=0):\n        return self.recv(bufsiz, flags)\n\n    def write(self, buf, flags=0):\n        return self.send(buf, flags)\n\n    def close(self, reason=\"\"):\n        with self._lock:\n            self.running = False\n            if not self.socket_closed:\n                if self._connection:\n                    res = bssl.BSSL_SSL_shutdown(self._connection)\n                    # res == 0: close_notify sent but not recv, means you need to call SSL_shutdown again if you want a full bidirectional shutdown.\n                    # res == 1: success, mean you previously received a close_notify alert from the other peer, and you're totally done\n                    # res == -1: failed\n                    # self._context.logger.debug(\"sock %s SSL_shutdown fd:%d res:%d\", self.ip_str, self._fileno, res)\n\n                    if res < 0:\n                        error = bssl.BSSL_SSL_get_error(self._connection, res)\n                        # self._context.logger.debug(\"sock %s shutdown fd:%d error:%d\", self.ip_str, self._fileno, error)\n                        if error == 1:\n                            p = ffi.new(\"char[]\",\n                                        b\"hello, worldhello, worldhello, worldhello, worldhello, world\")  # p is a 'char *'\n                            q = ffi.new(\"char **\", p)  # q is a 'char **'\n                            line_no = 0\n                            line_no_p = ffi.new(\"int *\", line_no)\n                            error = bssl.BSSL_ERR_get_error_line(q, line_no_p)\n                            filename = ffi.string(q[0])\n                            # self._context.logger.error(\"error:%d file:%s, line:%s\", error, filename, line_no_p[0])\n                            self._context.logger.debug(\"sock %s shutdown error: %s, file:%s, line:%d, sni:%s\" %\n                                               (self.ip_str, error, filename, line_no_p[0], self.sni))\n                        else:\n                            self._context.logger.debug(\"sock %s shutdown error:%s\" % (self.ip_str, error))\n\n                    bssl.BSSL_SSL_free(self._connection)\n                    self._connection = None\n\n                if self._sock:\n                    try:\n                        self._sock.close()\n                        # self._context.logger.debug(\"sock %s sock_close fd:%d\", self.ip_str, self._fileno)\n                    except Exception as e:\n                        # self._context.logger.debug(\"sock %s sock_close fd:%d e:%r\", self.ip_str, self._fileno, e)\n                        pass\n                    self._sock = None\n\n                self.socket_closed = True\n\n                if self._on_close:\n                    self._on_close(self.ip_str, self.sni, reason=reason)\n                    self._on_close = None\n\n    def __del__(self):\n        self.close()\n\n    def settimeout(self, t):\n        if not self.running:\n            return\n\n        if self.timeout != t:\n            # self._context.logger.debug(\"settimeout %d\", t)\n            self._sock.settimeout(t)\n            self.timeout = t\n\n    def makefile(self, mode='r', bufsize=-1):\n        self._makefile_refs += 1\n        return socket._fileobject(self, mode, bufsize, close=True)\n\n    def fileno(self):\n        return self._fileno\n\n\nclass SSLContext(object):\n    def __init__(self, logger, ca_certs=None, cipher_suites=None, support_http2=True, protocol=None):\n        self.logger = logger\n        self.context = self\n\n        method = bssl.BSSL_TLS_method()\n        self.ctx = bssl.BSSL_SSL_CTX_new(method)\n        self.support_http2 = support_http2\n        bssl.BSSL_SSL_CTX_set_grease_enabled(self.ctx, 1)\n\n        cmd = b\"ALL:!aPSK:!ECDSA+SHA1:!3DES\"\n        bssl.BSSL_SSL_CTX_set_cipher_list(self.ctx, cmd)\n\n        if support_http2:\n            alpn = b\"\"\n            for proto in [b\"h2\", b\"http/1.1\"]:\n                proto_len = len(proto)\n                alpn += proto_len.to_bytes(1, 'big') + proto\n            bssl.BSSL_SSL_CTX_set_alpn_protos(self.ctx, alpn, len(alpn))\n        bssl.BSSL_SSL_CTX_enable_ocsp_stapling(self.ctx)\n        bssl.BSSL_SSL_CTX_enable_signed_cert_timestamps(self.ctx)\n\n        # SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PSS_RSAE_SHA256,\n        # SSL_SIGN_RSA_PKCS1_SHA256,       SSL_SIGN_ECDSA_SECP384R1_SHA384,\n        # SSL_SIGN_RSA_PSS_RSAE_SHA384,    SSL_SIGN_RSA_PKCS1_SHA384,\n        # SSL_SIGN_RSA_PSS_RSAE_SHA512,    SSL_SIGN_RSA_PKCS1_SHA512,\n        algs = [0x0403, 0x0804, 0x0401, 0x0503, 0x0805, 0x0501, 0x0806, 0x0601]\n        algs_buf = ffi.new(\"uint16_t[%s]\" % (len(algs)))\n        i = 0\n        for alg in algs:\n            algs_buf[i] = alg\n            i += 1\n        cdata_ptr = ffi.cast(\"uint16_t *\", algs_buf)\n        bssl.BSSL_SSL_CTX_set_verify_algorithm_prefs(self.ctx, cdata_ptr, len(algs))\n\n        bssl.BSSL_SSL_CTX_set_min_proto_version(self.ctx, 0x0303)\n\n        try:\n            bssl.BSSL_SSL_CTX_set_num_tickets(self.ctx, 0)\n            bssl.BSSL_SSL_CTX_set_permute_extensions(self.ctx, 1)\n        except:\n            self.logger.info(\"boringsssl not support permute extension\")\n\n        bssl.SetCompression(self.ctx)\n\n    def supported_protocol(self):\n        return \"TLS 1.3\"\n\n    def support_alpn_npn(self):\n        return \"alpn\"\n\n\nclass SSLCert:\n    def __init__(self, cert):\n        \"\"\"\n            Returns a (common name, [subject alternative names]) tuple.\n        \"\"\"\n        self.x509 = cert\n"
  },
  {
    "path": "code/default/lib/noarch/front_base/check_ip.py",
    "content": "import socket\nimport time\n\nimport hyper\nimport simple_http_client\nimport utils\n\n\nclass CheckIp(object):\n    def __init__(self, logger, config, connect_creator):\n        self.logger = logger\n        self.config = config\n        self.connect_creator = connect_creator\n        self.check_content = utils.to_bytes(self.config.check_ip_content)\n\n    def check_http1(self, ssl_sock, host):\n        self.logger.info(\"ip:%s use http/1.1\", ssl_sock.ip_str)\n\n        try:\n            request_data = 'GET %s HTTP/1.1\\r\\nHost: %s\\r\\nAccept: */*\\r\\n\\r\\n' % (self.config.check_ip_path, host)\n            ssl_sock.send(request_data.encode())\n\n            response = simple_http_client.Response(ssl_sock)\n            response.begin(timeout=5)\n            return response\n        except Exception as e:\n            self.logger.exception(\"check ip %s http1 e:%r\", ssl_sock.ip_str, e)\n            return False\n\n    def check_http2(self, ssl_sock, host, path=None, headers={}):\n        self.logger.debug(\"ip:%s use http/2\", ssl_sock.ip_str)\n        try:\n            conn = hyper.HTTP20Connection(ssl_sock, host=host, ip=ssl_sock.ip_str, port=443)\n            if not path:\n                path = self.config.check_ip_path\n            conn.request('GET', path, headers=headers)\n            response = conn.get_response()\n            return response\n        except Exception as e:\n            self.logger.debug(\"check ip %s http2 get response fail:%r\", ssl_sock.ip_str, e)\n            return False\n\n    def check_ip(self, ip, sni=None, host=None, wait_time=0, path=None, headers={}):\n        try:\n            ssl_sock = self.connect_creator.connect_ssl(ip, sni=sni, host=host)\n        except socket.timeout:\n            self.logger.warn(\"connect timeout\")\n            return False\n        except Exception as e:\n            self.logger.exception(\"check_ip:%s create_ssl except:%r\", ip, e)\n            return False\n\n        ssl_sock.ok = False\n\n        if host:\n            pass\n        elif self.config.check_ip_subdomain:\n            host = self.config.check_ip_subdomain + \".\" + ssl_sock.host\n        elif self.config.check_ip_host:\n            host = self.config.check_ip_host\n        else:\n            host = ssl_sock.host\n        self.logger.info(\"host:%s\", host)\n\n        if wait_time:\n            time.sleep(wait_time)\n        start_time = time.time()\n\n        if not ssl_sock.h2:\n            response = self.check_http1(ssl_sock, host)\n        else:\n            response = self.check_http2(ssl_sock, host, path, headers)\n\n        if not response:\n            return False\n\n        if not self.check_response(response):\n            return False\n\n        time_cost = (time.time() - start_time) * 1000\n        ssl_sock.request_time = time_cost\n        self.logger.info(\"check ok, time:%d\", time_cost)\n        ssl_sock.ok = True\n        ssl_sock.response = response\n        return ssl_sock\n\n    def check_response(self, response):\n        server_type = response.headers.get(b'Server', b\"\")\n        self.logger.debug(\"status:%d\", response.status)\n        self.logger.debug(\"Server type:%s\", server_type)\n\n        if response.status not in self.config.check_ip_accept_status:\n            return False\n\n        content = response.read()\n        response.content = content\n\n        if self.check_content and self.check_content not in content:\n            self.logger.warn(\"app check content:%s\", content)\n            return False\n\n        return True\n"
  },
  {
    "path": "code/default/lib/noarch/front_base/config.py",
    "content": "\nimport xconfig\n\n\nclass ConfigBase(xconfig.Config):\n    def set_default(self):\n        # proxy\n        self.set_var(\"PROXY_ENABLE\", 0)\n        self.set_var(\"PROXY_TYPE\", \"HTTP\")\n        self.set_var(\"PROXY_HOST\", \"\")\n        self.set_var(\"PROXY_PORT\", 0)\n        self.set_var(\"PROXY_USER\", \"\")\n        self.set_var(\"PROXY_PASSWD\", \"\")\n\n        # http_dispatcher\n        self.set_var(\"dispather_min_idle_workers\", 0)\n        self.set_var(\"dispather_worker_idle_time\", 300)\n        self.set_var(\"dispather_work_min_idle_time\", 0)\n        self.set_var(\"dispather_work_max_score\", 1)\n        self.set_var(\"dispather_min_workers\", 0)\n        self.set_var(\"dispather_max_workers\", 60)\n        self.set_var(\"dispather_score_factor\", 1)\n        self.set_var(\"dispather_max_idle_workers\", 30)\n        self.set_var(\"dispather_worker_max_continue_fail\", 8)\n        self.set_var(\"dispather_connect_all_workers_on_startup\", 0)\n        self.set_var(\"dispather_ping_check_speed_interval\", 60 * 5)\n        self.set_var(\"dispather_ping_upload_size\", 1024)\n        self.set_var(\"dispather_ping_rtt_download_size\", 512)\n        self.set_var(\"dispather_ping_speed_download_size\", 1024 * 100)\n\n        self.set_var(\"max_task_num\", 100)\n\n        # http 1.1 worker\n        self.set_var(\"http1_first_ping_wait\", 300)\n        self.set_var(\"http1_ping_interval\", 300)\n        self.set_var(\"http1_idle_time\", 360)\n        self.set_var(\"http1_max_process_tasks\", 99999999)\n        self.set_var(\"http1_trace_size\", 20)\n\n        # http 2 worker\n        self.set_var(\"http2_max_concurrent\", 60)\n        self.set_var(\"http2_target_concurrent\", 6)\n        self.set_var(\"http2_max_timeout_tasks\", 5)\n        self.set_var(\"http2_max_process_tasks\", 900)  # Nginx will GoAway after 1000 tasks.\n        self.set_var(\"http2_timeout_active\", 15)\n        self.set_var(\"http2_status_to_close\", [])\n        self.set_var(\"http2_show_debug\", 0)\n        self.set_var(\"http2_ping_min_interval\", 5)\n        self.set_var(\"http2_idle_ping_min_interval\", 235)\n\n        # worker_base\n        self.set_var(\"show_state_debug\", 0)\n        self.set_var(\"http_query_history_size\", 30)  # for calculating rtt and speed.\n\n        # connect manager\n        self.set_var(\"https_max_connect_thread\", 1)\n        self.set_var(\"max_connect_thread\", 1)\n        self.set_var(\"connect_create_interval\", 0.1)\n        self.set_var(\"ssl_first_use_timeout\", 10)\n        self.set_var(\"connection_pool_min\", 1)\n        self.set_var(\"https_keep_alive\", 15)  # time to pass created link to worker\n        self.set_var(\"https_connection_pool_min\", 1)\n        self.set_var(\"https_connection_pool_max\", 2)\n        self.set_var(\"https_new_connect_num\", 1)\n        self.set_var(\"http1_new_connect_num\", 1)\n        self.set_var(\"connection_max_life\", 999990)\n\n        # check_ip\n        self.set_var(\"check_ip_subdomain\", \"\")\n        self.set_var(\"check_ip_host\", \"\")\n        self.set_var(\"check_ip_path\", \"/\")\n        self.set_var(\"check_ip_accept_status\", [200])\n        self.set_var(\"check_ip_content\", \"OK\")\n\n        # connect_creator\n        self.set_var(\"socket_timeout\", 1)\n        self.set_var(\"connect_receive_buffer\", 1024 * 512)\n        self.set_var(\"connect_send_buffer\", 1024 * 512)\n        self.set_var(\"connect_force_http1\", 0)\n        self.set_var(\"connect_force_http2\", 0)\n        self.set_var(\"check_pkp\", [])\n        self.set_var(\"check_commonname\", \"\")\n        self.set_var(\"check_sni\", 0) # 0, 1, string\n        self.set_var(\"min_intermediate_CA\", 0)\n\n        # ip manager\n        self.set_var(\"check_exist_ip_on_startup\", 0)\n        self.set_var(\"auto_adjust_scan_ip_thread_num\", 1)\n        self.set_var(\"max_scan_ip_thread_num\", 0)\n        self.set_var(\"max_good_ip_num\", 100)\n        self.set_var(\"target_handshake_time\", 300)\n        self.set_var(\"max_links_per_ip\", 1)\n        self.set_var(\"ip_connect_interval\", 0.5)\n        self.set_var(\"record_ip_history\", 0)\n        self.set_var(\"scan_ip_interval\", 1)\n        self.set_var(\"down_fail_connect_interval\", 60)\n        self.set_var(\"active_connect_interval\", 0)\n        self.set_var(\"long_fail_threshold\", 300)\n        self.set_var(\"long_fail_connect_interval\", 180)\n        self.set_var(\"short_fail_connect_interval\", 10)\n        self.set_var(\"shuffle_ip_on_first_load\", 0)\n        self.set_var(\"ip_speed_history_size\", 30)\n        self.set_var(\"ip_initial_rtt\", 0.03)\n        self.set_var(\"ip_initial_speed\", 129000)\n        self.set_var(\"ip_initial_score\", 0.1)\n        self.set_var(\"ip_cal_rtt_max_package_size\", 10000)\n        self.set_var(\"ip_cal_speed_min_package_size\", 100000)\n        self.set_var(\"ip_cal_expect_time_package_size\", 40000)\n        self.set_var(\"ip_speed_save_interval\", 60)\n\n        # ip source\n        self.set_var(\"use_ipv6\", \"auto\") #force_ipv4/force_ipv6\n        self.set_var(\"ipv6_scan_ratio\", 50) # 0 - 100\n\n    def load(self):\n        super(ConfigBase, self).load()\n\n        if self.check_pkp:\n            self.CHECK_PKP = set(self.check_pkp)"
  },
  {
    "path": "code/default/lib/noarch/front_base/connect_creator.py",
    "content": "import socket\nimport struct\nimport time\nimport sys\n\nimport socks\nimport utils\nfrom . import openssl_wrap\nfrom subj_alt_name import SubjectAltName\nfrom pyasn1.codec.der import decoder as der_decoder\n\n\nclass ConnectCreator(object):\n    def __init__(self, logger, config, openssl_context=None, host_manager=None,\n                 timeout=5, debug=False,\n                 check_cert=None):\n        self.logger = logger\n        self.config = config\n        self.openssl_context = openssl_context\n        self.host_manager = host_manager\n        self.timeout = self.config.socket_timeout\n        self.debug = debug or self.config.show_state_debug\n        self.peer_cert = None\n        if check_cert:\n            self.check_cert = check_cert\n        self.update_config()\n\n        self.connect_force_http1 = self.config.connect_force_http1\n        self.connect_force_http2 = self.config.connect_force_http2\n\n    def update_config(self):\n        if int(self.config.PROXY_ENABLE):\n\n            if self.config.PROXY_TYPE == \"HTTP\":\n                proxy_type = socks.HTTP\n            elif self.config.PROXY_TYPE == \"SOCKS4\":\n                proxy_type = socks.SOCKS4\n            elif self.config.PROXY_TYPE == \"SOCKS5\":\n                proxy_type = socks.SOCKS5\n            else:\n                self.logger.error(\"proxy type %s unknown, disable proxy\", self.config.PROXY_TYPE)\n                raise Exception()\n\n            socks.set_default_proxy(proxy_type=proxy_type,\n                                    addr=self.config.PROXY_HOST,\n                                    port=self.config.PROXY_PORT,\n                                    username=self.config.PROXY_USER,\n                                    password=self.config.PROXY_PASSWD)\n\n    def connect_ssl(self, ip_str, sni, host, close_cb=None):\n        ip_str = utils.to_str(ip_str)\n\n        if self.debug:\n            self.logger.debug(\"connect ip:%s sni:%s host:%s\", ip_str, sni, host)\n\n        ip, port = utils.get_ip_port(ip_str)\n        if isinstance(ip, str):\n            ip = utils.to_bytes(ip)\n\n        if openssl_wrap.implementation == \"UTLS\":\n            # currently UTLS will create TLS connection by itself.\n            # So will not support LAN proxy.\n            sock = None\n        else:\n            if int(self.config.PROXY_ENABLE):\n                sock = socks.socksocket(socket.AF_INET if b':' not in ip else socket.AF_INET6)\n            else:\n                sock = socket.socket(socket.AF_INET if b':' not in ip else socket.AF_INET6)\n\n            sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)\n\n            # set struct linger{l_onoff=1,l_linger=0} to avoid 10048 socket error\n            # Close the connection with a TCP RST instead of a TCP FIN.\n            sock.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack('ii', 1, 0))\n\n            # resize socket receive buffer ->64 above to improve browser related application performance\n            sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, self.config.connect_receive_buffer)\n            sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, self.config.connect_send_buffer)\n            sock.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, True)\n            sock.settimeout(self.timeout)\n\n        time_begin = time.time()\n        ssl_sock = openssl_wrap.SSLConnection(self.openssl_context.context, sock,\n                                              ip_str=ip_str,\n                                              sni=sni,\n                                              on_close=close_cb)\n\n        ssl_sock.sni = utils.to_str(sni)\n\n        time_connected = time.time()\n\n        try:\n            ssl_sock.do_handshake()\n        except Exception as e:\n            # self.logger.exception(\"handshake except:%r\", e)\n            raise socket.error('tls handshake fail, sni:%s, top:%s e:%r' % (sni, host, e))\n\n        if ssl_sock.is_support_h2():\n            ssl_sock.h2 = True\n        else:\n            ssl_sock.h2 = False\n\n        time_handshaked = time.time()\n\n        self.check_cert(ssl_sock)\n\n        connect_time = int((time_connected - time_begin) * 1000)\n        handshake_time = int((time_handshaked - time_begin) * 1000)\n        if sock:\n            ssl_sock.fd = sock.fileno()\n        ssl_sock.create_time = time_begin\n        ssl_sock.connect_time = connect_time\n        ssl_sock.handshake_time = handshake_time\n        ssl_sock.last_use_time = time_handshaked\n        ssl_sock.host = host\n        ssl_sock.received_size = 0\n\n        return ssl_sock\n\n    def check_cert(self, ssl_sock):\n        if sys.version_info[0] == 3:\n            try:\n                peer_cert = ssl_sock.get_cert()\n            except Exception as e:\n                self.logger.exception(\"check_cert %r\", e)\n\n            if self.debug:\n                self.logger.debug(\"cert:%r\", peer_cert)\n\n            if self.config.check_commonname:\n                if not peer_cert[\"issuer_commonname\"].startswith(self.config.check_commonname):\n                    raise socket.error(' certificate is issued by %r' % (peer_cert[\"issuer_commonname\"]))\n\n            if isinstance(self.config.check_sni, str):\n                if self.config.check_sni not in peer_cert[\"altName\"]:\n                    raise socket.error(\n                        'check sni fail:%s, alt_names:%s' % (self.config.check_sni, peer_cert[\"altName\"]))\n\n            elif self.config.check_sni:\n                alt_name = peer_cert[\"altName\"]\n                if isinstance(alt_name, str):\n                    if not ssl_sock.sni.endswith(alt_name):\n                        raise socket.error(\n                            'check %s sni:%s fail, alt_names:%s' % (ssl_sock.ip_str, ssl_sock.sni, alt_name))\n                elif isinstance(alt_name, list):\n                    for alt_name_n in alt_name:\n                        if ssl_sock.sni.endswith(alt_name_n):\n                            return\n                    raise socket.error(\n                        'check %s sni:%s fail, alt_names:%s' % (ssl_sock.ip_str, ssl_sock.sni, alt_name))\n\n        else:\n            import OpenSSL\n            cert_chain = ssl_sock.get_peer_cert_chain()\n            if not cert_chain:\n                raise socket.error('certificate is none, sni:%s' % ssl_sock.sni)\n\n            if len(cert_chain) < self.config.min_intermediate_CA:\n                raise socket.error('No intermediate CA was found.')\n\n            if self.config.check_pkp and hasattr(OpenSSL.crypto, \"dump_publickey\"):\n                # old OpenSSL not support this function.\n                pub_key = OpenSSL.crypto.dump_publickey(OpenSSL.crypto.FILETYPE_PEM,\n                                                        cert_chain[1].get_pubkey())\n                if pub_key not in self.config.CHECK_PKP:\n                    # google_ip.report_connect_fail(ip, force_remove=True)\n                    raise socket.error('The intermediate CA is mismatching.')\n            self.get_ssl_cert_domain(ssl_sock)\n            issuer_commonname = next((v for k, v in cert_chain[0].get_issuer().get_components() if k == 'CN'), '')\n            if self.debug:\n                for cert in cert_chain:\n                    for k, v in cert.get_issuer().get_components():\n                        if k != \"CN\":\n                            continue\n                        cn = v\n                        self.logger.debug(\"cn:%s\", cn)\n\n                self.logger.debug(\"issued by:%s\", issuer_commonname)\n                self.logger.debug(\"Common Name:%s\", ssl_sock.domain)\n\n            if self.config.check_commonname and not issuer_commonname.startswith(self.config.check_commonname):\n                raise socket.error(' certificate is issued by %r' % (issuer_commonname))\n\n            cert = ssl_sock.get_peer_certificate()\n            if not cert:\n                raise socket.error('certificate is none')\n\n            if self.config.check_sni:\n                # get_subj_alt_name cost near 100ms. be careful.\n                try:\n                    alt_names = ConnectCreator.get_subj_alt_name(cert)\n                except Exception as e:\n                    # self.logger.warn(\"get_subj_alt_name fail:%r\", e)\n                    alt_names = [\"\"]\n\n                if self.debug:\n                    self.logger.debug('alt names: \"%s\"', '\", \"'.join(alt_names))\n\n                if isinstance(self.config.check_sni, str):\n                    if self.config.check_sni not in alt_names:\n                        raise socket.error('check sni fail, alt_names:%s' % (alt_names))\n                else:\n                    alt_names = tuple(alt_names)\n                    if not ssl_sock.sni.endswith(alt_names):\n                        raise socket.error('check sni:%s fail, alt_names:%s' % (ssl_sock.sni, alt_names))\n\n    def get_ssl_cert_domain(self, ssl_sock):\n        cert = ssl_sock.get_peer_certificate()\n        if not cert:\n            raise Exception(\"no cert\")\n\n        ssl_cert = openssl_wrap.SSLCert(cert)\n        ssl_sock.domain = ssl_cert.cn\n\n    @staticmethod\n    def get_subj_alt_name(peer_cert):\n        '''\n        Copied from ndg.httpsclient.ssl_peer_verification.ServerSSLCertVerification\n        Extract subjectAltName DNS name settings from certificate extensions\n        @param peer_cert: peer certificate in SSL connection.  subjectAltName\n        settings if any will be extracted from this\n        @type peer_cert: OpenSSL.crypto.X509\n        '''\n        # Search through extensions\n        dns_name = []\n        general_names = SubjectAltName()\n        for i in range(peer_cert.get_extension_count()):\n            ext = peer_cert.get_extension(i)\n            ext_name = ext.get_short_name()\n            if ext_name == \"subjectAltName\":\n                # PyOpenSSL returns extension data in ASN.1 encoded form\n                ext_dat = ext.get_data()\n                decoded_dat = der_decoder.decode(ext_dat, asn1Spec=general_names)\n\n                for name in decoded_dat:\n                    if isinstance(name, SubjectAltName):\n                        for entry in range(len(name)):\n                            component = name.getComponentByPosition(entry)\n                            n = str(component.getComponent())\n                            if n.startswith(\"*\"):\n                                continue\n                            dns_name.append(n)\n        return dns_name\n"
  },
  {
    "path": "code/default/lib/noarch/front_base/connect_manager.py",
    "content": "#!/usr/bin/env python\n# coding:utf-8\n\n\n\"\"\"\nThis file manage the ssl connection pool.\nFor faster access the target host,\n\nssl link will save to pool after use.\nand need keep alive every 60 seconds.\n\nWe create multi-thread to try-connect google cloud ip.\n\nwe also keep host connect for direct connect.\nevery ssl connect can't change host after request.\n\"\"\"\n\nimport time\nimport threading\nimport operator\nimport socket\nimport random\nfrom queue import Queue\n\nfrom .openssl_wrap import SSLConnection\n\nclass NoRescourceException(Exception):\n    pass\n\n\nclass ConnectPool():\n    def __init__(self):\n        self.pool_lock = threading.Lock()\n        self.not_empty = threading.Condition(self.pool_lock)\n        self.pool = {}\n\n    def qsize(self):\n        return len(self.pool)\n\n    def put(self, item):\n        handshake_time, sock = item\n        self.not_empty.acquire()\n        try:\n            self.pool[sock] = handshake_time\n            self.not_empty.notify()\n        finally:\n            self.not_empty.release()\n\n    def get(self, block=True, timeout=None):\n        self.not_empty.acquire()\n        try:\n            if not block:\n                if self.qsize() == 0:\n                    return None\n            elif timeout is None:\n                while self.qsize() == 0:\n                    self.not_empty.wait()\n            elif timeout < 0:\n                raise ValueError(\"'timeout' must be a positive number\")\n            else:\n                end_time = time.time() + timeout\n                while not self.qsize():\n                    remaining = end_time - time.time()\n                    if remaining <= 0.0:\n                        return None\n                    self.not_empty.wait(remaining)\n\n            item = self._get()\n            return item\n        finally:\n            self.not_empty.release()\n\n    def get_nowait(self):\n        return self.get(block=False)\n\n    def _get(self):\n        fastest_time = 9999\n        fastest_sock = None\n        for sock in self.pool:\n            hs_time = self.pool[sock]\n            if hs_time < fastest_time or not fastest_sock:\n                fastest_time = hs_time\n                fastest_sock = sock\n\n        self.pool.pop(fastest_sock)\n        return fastest_time, fastest_sock\n\n    def get_slowest(self):\n        self.not_empty.acquire()\n        try:\n            if not self.qsize():\n                raise ValueError(\"no item\")\n\n            slowest_handshake_time = 0\n            slowest_sock = None\n            for sock in self.pool:\n                handshake_time = self.pool[sock]\n                if handshake_time > slowest_handshake_time:\n                    slowest_handshake_time = handshake_time\n                    slowest_sock = sock\n\n            self.pool.pop(slowest_sock)\n            return slowest_handshake_time, slowest_sock\n        finally:\n            self.not_empty.release()\n\n    def get_need_keep_alive(self, maxtime=200):\n        return_list = []\n        self.pool_lock.acquire()\n        try:\n            pool = tuple(self.pool)\n            for sock in pool:\n                inactive_time = time.time() - sock.last_use_time\n                # self.logger.debug(\"inactive_time:%d\", inactive_time * 1000)\n                if inactive_time >= maxtime:\n                    return_list.append(sock)\n\n                    del self.pool[sock]\n\n            return return_list\n        finally:\n            self.pool_lock.release()\n\n    def clear(self):\n        self.pool_lock.acquire()\n        try:\n            for sock in self.pool:\n                sock.close()\n\n            self.pool = {}\n        finally:\n            self.pool_lock.release()\n\n    def to_string(self):\n        out_str = ''\n        self.pool_lock.acquire()\n        try:\n            pool = sorted(list(self.pool.items()), key=operator.itemgetter(1))\n            i = 0\n            for item in pool:\n                sock, t = item\n                out_str += \"%d \\t %s handshake:%d not_active_time:%d \\r\\n\" % (i, sock.ip_str, t, time.time() - sock.last_use_time)\n                i += 1\n        finally:\n            self.pool_lock.release()\n\n        return out_str\n\n\nclass ConnectManager(object):\n    def __init__(self, logger, config, connect_creator, ip_manager, check_local_network):\n        self.class_name = \"ConnectManager\"\n        self.logger = logger\n        self.config = config\n        self.connect_creator = connect_creator\n        self.ip_manager = ip_manager\n        self.check_local_network = check_local_network\n\n        self.thread_num_lock = threading.Lock()\n        self.timeout = 4\n        self.start_connect_time = 0\n        self.thread_num = 0\n        self.running = True\n\n        self._waiting_num_lock = threading.Lock()\n        self._connection_waiting_num = 0\n        self.no_ip_lock = threading.Lock()\n        self.no_ip_time = 0\n\n        # after new created ssl_sock timeout(50 seconds)\n        # call the callback.\n        # This callback will put ssl to worker\n        self.ssl_timeout_cb = None\n        \n        self.new_conn_pool = ConnectPool()\n\n        self.connecting_more_thread = None\n\n        self.keep_alive_th = threading.Thread(target=self.keep_alive_thread,\n                                              name=\"%s_conn_manager_keep_alive\" % self.logger.name)\n        self.keep_alive_th.daemon = True\n        self.keep_alive_th.start()\n\n        if self.config.connection_pool_min:\n            self.keep_conn_th = threading.Thread(target=self.keep_connection_daemon,\n                                                 name=\"%s_conn_manager_keep_conn\" % self.logger.name)\n            self.keep_conn_th.daemon = True\n            self.keep_conn_th.start()\n        else:\n            self.keep_conn_th = None\n\n    def stop(self):\n        self.running = False\n\n    def set_ssl_created_cb(self, cb):\n        self.ssl_timeout_cb = cb\n\n    def keep_alive_thread(self):\n        while self.running:\n            to_keep_live_list = self.new_conn_pool.get_need_keep_alive(maxtime=self.config.https_keep_alive-6)\n\n            for ssl_sock in to_keep_live_list:\n                inactive_time = time.time() - ssl_sock.last_use_time\n                if inactive_time > self.config.https_keep_alive or not self.ssl_timeout_cb:\n                    self.ip_manager.report_connect_closed(ssl_sock.ip_str, ssl_sock.sni, \"alive_timeout\")\n                    ssl_sock.close()\n                else:\n                    # put ssl to worker\n                    try:\n                        self.ssl_timeout_cb(ssl_sock)\n                    except Exception as e:\n                        self.logger.exception(\"ssl_timeout_cb except:%r\", e)\n                        # no appid avaiable\n                        pass\n\n            time.sleep(5)\n\n    def keep_connection_daemon(self):\n        while self.running:\n            if self.new_conn_pool.qsize() >= self.config.https_connection_pool_min:\n                time.sleep(5)\n                continue\n\n            if self.config.show_state_debug:\n                self.logger.debug(\"call _connect_process from keep_connection_daemon\")\n            self._connect_process()\n\n    def _need_more_ip(self):\n        if self._connection_waiting_num:\n            return True\n        else:\n            return False\n\n    def _create_more_connection(self):\n        if self.config.show_state_debug:\n            self.logger.debug(\"_create_more_connection\")\n        if not self.connecting_more_thread:\n            with self.thread_num_lock:\n                self.connecting_more_thread = threading.Thread(target=self._create_more_connection_worker,\n                                                               name=\"%s_conn_manager__create_more_conn\" % self.logger.name)\n                self.connecting_more_thread.start()\n\n    def _create_more_connection_worker(self):\n        if self.config.show_state_debug:\n            self.logger.debug(\"_create_more_connection_worker\")\n        if self.start_connect_time and self.start_connect_time + 30 < time.time():\n            self.start_connect_time = 0\n            self.config.https_max_connect_thread += 1\n            self.logger.warning(\"Connect creating process blocked, max connect thread increase to %d\",\n                                self.config.https_max_connect_thread)\n\n        for i in range(self.thread_num, self.config.https_max_connect_thread):\n            self.thread_num_lock.acquire()\n            self.thread_num += 1\n            self.thread_num_lock.release()\n\n            p = threading.Thread(target=self._connect_thread, name=\"%s_conn_manager__connect_th\" % self.logger.name)\n            p.start()\n            if self.config.connect_create_interval > 0.1:\n                time.sleep(self.config.connect_create_interval)\n\n            if not self._need_more_ip():\n                break\n\n        with self.thread_num_lock:\n            self.connecting_more_thread = None\n\n    def _connect_thread(self, sleep_time=0):\n        if self.config.show_state_debug:\n            self.logger.debug(\"_connect_thread\")\n\n        if sleep_time > 0.1:\n            self.logger.debug(\"_connect_thread sleep %f\", sleep_time)\n            time.sleep(sleep_time)\n\n        try:\n            while self.running and self._need_more_ip() and time.time() - self.no_ip_time > 10:\n                if self.new_conn_pool.qsize() > self.config.https_connection_pool_max:\n                    break\n\n                if self.config.show_state_debug:\n                    self.logger.debug(\"call _connect_process from _connect_thread\")\n                self.start_connect_time = time.time()\n                self._connect_process()\n                self.start_connect_time = 0\n        finally:\n            self.thread_num_lock.acquire()\n            self.thread_num -= 1\n            self.thread_num_lock.release()\n\n    def _connect_process(self):\n        if self.config.show_state_debug:\n            self.logger.debug(\"_connect_process\")\n        try:\n            host_info = self.ip_manager.get_ip_sni_host()\n            if not host_info:\n                self.no_ip_time = time.time()\n                with self.no_ip_lock:\n                    self.logger.warning(\"not enough ip\")\n                    time.sleep(1)\n                return None\n\n            # self.logger.debug(\"create ssl conn %s\", ip_str)\n            ssl_sock = self._create_ssl_connection(host_info)\n            if not ssl_sock:\n                return None\n\n            self.new_conn_pool.put((ssl_sock.handshake_time, ssl_sock))\n\n            if self.config.connect_create_interval > 0.1:\n                sleep = random.uniform(self.config.connect_create_interval, self.config.connect_create_interval*2)\n                time.sleep(sleep)\n\n            return ssl_sock\n        except Exception as e:\n            self.logger.exception(\"connect_process except:%r\", e)\n\n    def _connect_ssl(self, ip_str, sni, host, close_cb, queue):\n        if self.config.show_state_debug:\n            self.logger.debug(\"_connect_ssl\")\n\n        try:\n            ssl_sock = self.connect_creator.connect_ssl(ip_str, sni, host, close_cb=close_cb)\n            queue.put(ssl_sock)\n        except Exception as e:\n            self.logger.warn(\"_connect_ssl %s sni:%s host:%s fail:%r\", ip_str, sni, host, e)\n            queue.put(e)\n\n    def _create_ssl_connection(self, host_info):\n        if self.config.show_state_debug:\n            self.logger.debug(\"_create_ssl_connection\")\n\n        ip_str = host_info[\"ip_str\"]\n        sni = host_info[\"sni\"]\n        host = host_info[\"host\"]\n\n        try:\n            q = Queue()\n            fn_args = (ip_str, sni, host, self.ip_manager.ssl_closed, q)\n            t = threading.Thread(target=self._connect_ssl, args=fn_args, name=\"connect_ssl_%s\" % ip_str)\n            t.start()\n            try:\n                ssl_sock = q.get(timeout=30)\n            except:\n                self.logger.warn(\"connect_ssl_timeout %s\", ip_str)\n                raise socket.error(\"timeout\")\n\n            if not ssl_sock or isinstance(ssl_sock, ValueError) or isinstance(ssl_sock, OSError) or not hasattr(ssl_sock, \"handshake_time\"):\n                raise socket.error(\"timeout\")\n\n            self.ip_manager.update_ip(ip_str, sni, ssl_sock.handshake_time)\n            self.logger.debug(\"create_ssl update ip:%s time:%d h2:%d sni:%s, host:%s\",\n                              ip_str, ssl_sock.handshake_time, ssl_sock.h2, ssl_sock.sni, ssl_sock.host)\n            ssl_sock.host_info = host_info\n\n            return ssl_sock\n        except socket.error as e:\n            if str(e) in [\"no host\", \"timeout\"]:\n                pass\n            elif not self.check_local_network.is_ok(ip_str):\n                self.logger.debug(\"connect %s network fail, %r\", ip_str, e)\n                time.sleep(1)\n            else:\n                self.logger.debug(\"connect %s fail:%r\", ip_str, e)\n            self.ip_manager.report_connect_fail(ip_str, sni, str(e))\n        except NoRescourceException as e:\n            self.logger.warning(\"create ssl for %s except:%r\", ip_str, e)\n            self.ip_manager.report_connect_fail(ip_str, sni, str(e))\n        except Exception as e:\n            self.logger.exception(\"connect except:%r\", e)\n            self.ip_manager.report_connect_fail(ip_str, sni, str(e))\n            if not self.check_local_network.is_ok(ip_str):\n                self.logger.debug(\"connect %s network fail, %r\", ip_str, e)\n                time.sleep(10)\n            else:\n                self.logger.exception(\"connect %s fail:%r\", ip_str, e)\n                time.sleep(1)\n\n    def get_ssl_connection(self, timeout=30):\n        with self._waiting_num_lock:\n            self._connection_waiting_num += 1\n\n        end_time = time.time() + timeout\n        try:\n            while self.running:\n                ret = self.new_conn_pool.get(block=False)\n                if not ret:\n                    self._create_more_connection()\n                    ret = self.new_conn_pool.get(block=True, timeout=1)\n\n                if ret:\n                    handshake_time, ssl_sock = ret\n                    if time.time() - ssl_sock.last_use_time < self.config.https_keep_alive - 1:\n                        if self.config.show_state_debug:\n                            self.logger.debug(\"new_conn_pool.get:%s handshake:%d\", ssl_sock.ip, handshake_time)\n                        return ssl_sock\n                    else:\n                        self.logger.warn(\"new_conn_pool.get:%s handshake:%d timeout.\", ssl_sock.ip, handshake_time)\n                        self.ip_manager.report_connect_closed(ssl_sock.ip_str, ssl_sock.sni, \"get_ssl_timeout\")\n                        ssl_sock.close()\n                else:\n                    if time.time() > end_time:\n                        self.logger.debug(\"get_ssl_connection timeout\")\n                        return None\n\n                self._create_more_connection()\n        finally:\n            with self._waiting_num_lock:\n                self._connection_waiting_num -= 1\n"
  },
  {
    "path": "code/default/lib/noarch/front_base/domain_manager.py",
    "content": "\n\nclass DomainManagerBase(object):\n    def get_host_sni(self):\n        return \"\", \"\""
  },
  {
    "path": "code/default/lib/noarch/front_base/host_manager.py",
    "content": "import random\n\nclass HostManagerBase(object):\n\n    def get_sni_host(self, ip):\n        return None, \"\"\n"
  },
  {
    "path": "code/default/lib/noarch/front_base/http1.py",
    "content": "from queue import Queue\nimport threading\n\nfrom .http_common import *\nimport simple_http_client\nimport utils\n\n\ndef pack_headers(headers):\n    out_list = []\n    for k, v in headers.items():\n        if isinstance(v, int):\n            out_list.append(b'%s: %d\\r\\n' % (utils.to_bytes(k), v))\n        else:\n            out_list.append(b'%s: %s\\r\\n' % (utils.to_bytes(k), utils.to_bytes(v)))\n\n    return b''.join(out_list)\n\n\nclass Http1Worker(HttpWorker):\n    def __init__(self, logger, ip_manager, config, ssl_sock, close_cb, retry_task_cb, idle_cb, log_debug_data):\n        super(Http1Worker, self).__init__(logger, ip_manager, config, ssl_sock,\n                                          close_cb, retry_task_cb, idle_cb, log_debug_data)\n\n        self.version = \"1.1\"\n        self.task = None\n        self.transfered_size = 0\n        self.trace_time = []\n        self.trace_time.append([ssl_sock.create_time, \"connect\"])\n        self.record_active(\"init\")\n\n        self.task_queue = Queue()\n        threading.Thread(target=self.work_loop, name=\"%s_http1_work_loop\" % self.logger.name).start()\n        self.idle_cb()\n\n        if self.config.http1_first_ping_wait or self.config.http1_ping_interval:\n            threading.Thread(target=self.keep_alive_thread, name=\"%s_http1_keep_alive\" % self.logger.name).start()\n\n    def record_active(self, active=\"\"):\n        self.trace_time.append([time.time(), active])\n        if len(self.trace_time) > self.config.http1_trace_size:\n            self.trace_time.pop(0)\n        # self.logger.debug(\"%s stat:%s\", self.ip, active)\n\n    def get_trace(self):\n        out_list = []\n        last_time = self.trace_time[0][0]\n        for t, stat in self.trace_time:\n            time_diff = int((t - last_time) * 1000)\n            last_time = t\n            out_list.append(\" %d:%s\" % (time_diff, stat))\n        out_list.append(\":%d\" % ((time.time() - last_time) * 1000))\n        out_list.append(\" processed:%d\" % self.processed_tasks)\n        out_list.append(\" transfered:%d\" % self.transfered_size)\n        out_list.append(\" sni:%s\" % self.ssl_sock.sni)\n        return \",\".join(out_list)\n\n    def request(self, task):\n        self.accept_task = False\n        self.task = task\n        self.task_queue.put(task)\n\n    def keep_alive_thread(self):\n        while time.time() - self.ssl_sock.create_time < self.config.http1_first_ping_wait:\n            if not self.keep_running:\n                self.close(\"exit\")\n                return\n\n            time.sleep(3)\n\n        if self.config.http1_first_ping_wait and self.processed_tasks == 0:\n            self.task_queue.put(\"ping\")\n\n        if self.config.http1_ping_interval:\n            while self.keep_running:\n                time_to_ping = max(self.config.http1_ping_interval - (time.time() - self.last_recv_time), 3)\n                time.sleep(time_to_ping)\n\n                if not self.request_onway and \\\n                        time.time() - self.last_recv_time > self.config.http1_ping_interval - 3:\n                    self.task_queue.put(\"ping\")\n                    time.sleep(3)\n\n        elif self.config.http1_idle_time:\n            while self.keep_running:\n                time_to_sleep = max(self.config.http1_idle_time - (time.time() - self.last_recv_time), 3)\n                time.sleep(time_to_sleep)\n\n                if not self.request_onway and time.time() - self.last_recv_time > self.config.http1_idle_time:\n                    self.close(\"idle timeout\")\n                    return\n\n    def work_loop(self):\n        while self.keep_running:\n            try:\n                task = self.task_queue.get(block=True)\n            except:\n                task = None\n\n            if not task:\n                # None task means exit\n                self.accept_task = False\n                self.keep_running = False\n                return\n\n            if task == \"ping\":\n                if not self.head_request():\n                    self.ip_manager.recheck_ip(self.ssl_sock.ip_str)\n                    self.close(\"keep alive\")\n                    return\n\n                continue\n\n            # self.logger.debug(\"http1 get task\")\n            time_now = time.time()\n            if time_now - self.last_recv_time > self.config.http1_idle_time:\n                self.logger.warn(\"get task but inactive time:%d\", time_now - self.last_recv_time)\n                self.task = task\n                self.close(\"inactive timeout %d\" % (time_now - self.last_recv_time))\n                return\n\n            self.request_task(task)\n            self.request_onway = False\n            self.last_send_time = time_now\n\n            life_end_reason = self.is_life_end()\n            if life_end_reason:\n                self.close(\"life_end:\" + life_end_reason)\n                return\n\n    def request_task(self, task):\n        timeout = task.timeout\n        self.request_onway = True\n        start_time = time.time()\n\n        self.record_active(\"request\")\n        task.set_state(\"h1_req\")\n\n        task.headers[b'Host'] = self.get_host(task.host)\n\n        request_len = len(task.body)\n        task.headers[b\"Content-Length\"] = request_len\n        request_data = b'%s %s HTTP/1.1\\r\\n' % (task.method, task.path)\n        request_data += pack_headers(task.headers)\n        request_data += b'\\r\\n'\n\n        try:\n            self.ssl_sock.send(request_data)\n            payload_len = len(task.body)\n            start = 0\n            while start < payload_len:\n                send_size = min(payload_len - start, 65535)\n                sended = self.ssl_sock.send(task.body[start:start + send_size])\n                start += sended\n\n            task.set_state(\"h1_req_sent\")\n        except Exception as e:\n            self.logger.warn(\"%s %s h1_request send:%r inactive_time:%d task.timeout:%d\",\n                             self.ip_str, self.ssl_sock.getsockname(),\n                             e, time.time() - self.last_recv_time, task.timeout)\n            self.logger.warn('%s trace:%s', self.ip_str, self.get_trace())\n\n            self.retry_task_cb(task)\n            self.task = None\n            self.close(\"send fail\")\n            return\n\n        try:\n            response = simple_http_client.Response(self.ssl_sock)\n            response.begin(timeout=timeout)\n            task.set_state(\"response_begin\")\n            self.last_recv_time = time.time()\n        except Exception as e:\n            self.logger.warn(\"%s h1_request recv:%r inactive_time:%d task.timeout:%d\",\n                             self.ip_str, e, time.time() - self.last_recv_time, task.timeout)\n            self.logger.warn('%s trace:%s', self.ip_str, self.get_trace())\n\n            self.retry_task_cb(task)\n            self.task = None\n            self.close(\"recv fail\")\n            return\n\n        task.set_state(\"h1_get_head\")\n\n        time_left = timeout - (time.time() - start_time)\n\n        if task.method == b\"HEAD\" or response.status in [204, 304]:\n            response.content_length = 0\n\n        response.ssl_sock = self.ssl_sock\n        response.task = task\n        response.worker = self\n        task.content_length = response.content_length\n        task.responsed = True\n        if task.queue:\n            task.queue.put(response)\n\n        if self.config.http2_show_debug:\n                self.logger.debug(\"got res for %s status:%d\", self.ip_str, response.status)\n\n        try:\n            read_target = int(response.content_length)\n        except:\n            read_target = 0\n\n        data_len = 0\n        while True:\n            try:\n                data = response.read(timeout=time_left)\n                if not data:\n                    break\n            except Exception as e:\n                self.logger.warn(\"read fail, ip:%s, chunk:%d url:%s task.timeout:%d e:%r\",\n                                 self.ip_str, response.chunked, task.url, task.timeout, e)\n                self.logger.warn('%s trace:%s', self.ip_str, self.get_trace())\n                self.close(\"read fail\")\n                return\n\n            task.put_data(data)\n            length = len(data)\n            data_len += length\n            if read_target and data_len >= read_target:\n                break\n\n        if read_target > data_len:\n            self.logger.warn(\"read fail, ip:%s, chunk:%d url:%s task.timeout:%d \",\n                             self.ip_str, response.chunked, task.url, task.timeout)\n            self.ip_manager.recheck_ip(self.ssl_sock.ip_str)\n            self.close(\"down fail\")\n\n        task.finish()\n\n        self.ssl_sock.received_size += data_len\n\n        time_now = time.time()\n        time_cost = (time_now - start_time)\n        xcost = float(response.headers.get(b\"X-Cost\", -1))\n        if isinstance(xcost, list):\n            xcost = float(xcost[0])\n\n        road_time = time_cost - xcost\n        if xcost != -1 and road_time > 0:\n            self.update_speed(road_time, request_len, data_len)\n\n        task.set_state(\"h1_finish[RTT:%d]\" % (road_time * 1000))\n\n        self.transfered_size += len(request_data) + data_len\n        self.task = None\n        self.accept_task = True\n        self.idle_cb()\n        self.processed_tasks += 1\n        self.last_recv_time = time.time()\n        self.record_active(\"Res\")\n\n    def head_request(self):\n        if not self.ssl_sock.host:\n            # self.logger.warn(\"try head but no host set\")\n            return True\n\n        # for keep alive, not work now.\n        self.request_onway = True\n        self.record_active(\"head\")\n        # start_time = time.time()\n        # self.logger.debug(\"head request %s\", self.ip)\n        request_data = b'GET / HTTP/1.1\\r\\nHost: %s\\r\\n\\r\\n' % utils.to_bytes(self.ssl_sock.host)\n\n        try:\n            data = request_data\n            ret = self.ssl_sock.send(data)\n            if ret != len(data):\n                self.logger.warn(\"h1 head send len:%r %d %s\", ret, len(data), self.ip_str)\n                self.logger.warn('%s trace:%s', self.ip_str, self.get_trace())\n                return False\n            response = simple_http_client.Response(self.ssl_sock)\n            response.begin(timeout=5)\n\n            status = response.status\n            if status not in [200, 404]:\n                self.logger.warn(\"%s host:%s head fail status:%d\", self.ip_str, self.ssl_sock.host, status)\n                return False\n\n            content = response.readall(timeout=5)\n            self.record_active(\"head end\")\n            self.last_recv_time = time.time()\n            return True\n        except Exception as e:\n            self.logger.warn(\"h1 %s HEAD keep alive request fail:%r\", self.ssl_sock.ip_str, e)\n            self.logger.warn('%s trace:%s', self.ip_str, self.get_trace())\n            return False\n        finally:\n            self.request_onway = False\n\n    def close(self, reason=\"\"):\n        # Notify loop to exit\n        # This function may be call by outside http2\n        # When gae_proxy found the appid or ip is wrong\n        self.task_queue.put(None)\n\n        if self.task is not None:\n            if self.task.responsed:\n                self.task.finish()\n            else:\n                self.retry_task_cb(self.task)\n            self.task = None\n\n        super(Http1Worker, self).close(reason)\n"
  },
  {
    "path": "code/default/lib/noarch/front_base/http2_connection.py",
    "content": "import time\n\nfrom six.moves import queue\nimport threading\nimport socket\nimport errno\nimport struct\nfrom ssl import SSLError\n\nfrom .http_common import *\n\n\nfrom hyper.common.bufsocket import BufferedSocket\nfrom hyper.common.exceptions import ConnectionResetError\n\nfrom hyper.packages.hyperframe.frame import (\n    FRAMES, DataFrame, HeadersFrame, PushPromiseFrame, RstStreamFrame,\n    SettingsFrame, Frame, WindowUpdateFrame, GoAwayFrame, PingFrame,\n    BlockedFrame, FRAME_MAX_ALLOWED_LEN, FRAME_MAX_LEN\n)\nfrom .http2_stream import Stream\nfrom hyper.http20.window import BaseFlowControlManager\n\nfrom hyper.packages.hpack import Encoder, Decoder\n\n# this is defined in rfc7540\n# default window size 64k\nDEFAULT_WINDOW_SIZE = 65535\n\n# default max frame is 16k, defined in rfc7540\nDEFAULT_MAX_FRAME = FRAME_MAX_LEN\n\n\nclass FlowControlManager(BaseFlowControlManager):\n    \"\"\"\n    ``hyper``'s default flow control manager.\n\n    This implements hyper's flow control algorithms. This algorithm attempts to\n    reduce the number of WINDOWUPDATE frames we send without blocking the remote\n    endpoint behind the flow control window.\n\n    This algorithm will become more complicated over time. In the current form,\n    the algorithm is very simple:\n        - When the flow control window gets less than 3/4 of the maximum size,\n          increment back to the maximum.\n        - Otherwise, if the flow control window gets to less than 1kB, increment\n          back to the maximum.\n    \"\"\"\n    def increase_window_size(self, frame_size):\n        future_window_size = self.window_size - frame_size\n\n        if ((future_window_size < (self.initial_window_size * 3 / 4)) or\n            (future_window_size < 1000)):\n            return self.initial_window_size - future_window_size\n\n        return 0\n\n    def blocked(self):\n        return self.initial_window_size - self.window_size\n\n\nclass RawFrame(object):\n    def __init__(self, dat):\n        self.dat = dat\n\n    def serialize(self):\n        return self.dat\n\n    def __repr__(self):\n        out_str = \"{type}\".format(type=type(self).__name__)\n        return out_str\n\n\nclass Http2Worker(HttpWorker):\n    version = \"2\"\n\n    def __init__(self, logger, ip_manager, config, ssl_sock, close_cb, retry_task_cb, idle_cb, log_debug_data,\n                 stream_class=None):\n        super(Http2Worker, self).__init__(\n            logger, ip_manager, config, ssl_sock, close_cb, retry_task_cb, idle_cb, log_debug_data)\n        self.version = \"2\"\n\n        self.network_buffer_size = 65535\n        if stream_class:\n            self.stream_class = stream_class\n        else:\n            self.stream_class = Stream\n\n        # Google http/2 time out is 4 mins.\n        self.ssl_sock.settimeout(240)\n        self._sock = BufferedSocket(ssl_sock, self.network_buffer_size)\n\n        self.next_stream_id = 1\n        self.streams = {}\n        self.last_ping_time = time.time()\n        self.continue_timeout = 0\n\n        # count ping not ACK\n        # increase when send ping\n        # decrease when recv ping ack\n        # if this in not 0, don't accept request.\n        self.ping_on_way = 0\n        self.accept_task = False\n\n        # request_lock\n        self.request_lock = threading.Lock()\n\n        # all send frame must put to this queue\n        # then send by send_loop\n        # every frame put to this queue must allowed by stream window and connection window\n        # any data frame blocked by connection window should put to self.blocked_send_frames\n        self.send_queue = queue.Queue()\n        self.encoder = Encoder()\n        self.decoder = Decoder()\n\n        # keep blocked data frame in this buffer\n        # which is allowed by stream window but blocked by connection window.\n        # They will be sent when connection window open\n        self.blocked_send_frames = []\n\n        # Values for the settings used on an HTTP/2 connection.\n        # will send to remote using Setting Frame\n        self.local_settings = {\n            SettingsFrame.INITIAL_WINDOW_SIZE: 16 * 1024 * 1024,\n            SettingsFrame.SETTINGS_MAX_FRAME_SIZE: 256 * 1024\n        }\n        self.local_connection_initial_windows = 32 * 1024 * 1024\n        self.local_window_manager = FlowControlManager(self.local_connection_initial_windows)\n\n        # changed by server, with SettingFrame\n        self.remote_settings = {\n            SettingsFrame.INITIAL_WINDOW_SIZE: DEFAULT_WINDOW_SIZE,\n            SettingsFrame.SETTINGS_MAX_FRAME_SIZE: DEFAULT_MAX_FRAME,\n            SettingsFrame.MAX_CONCURRENT_STREAMS: 100\n        }\n\n        #self.remote_window_size = DEFAULT_WINDOW_SIZE\n        self.remote_window_size = 32 * 1024 * 1024\n\n        # send Setting frame before accept task.\n        self._send_preamble()\n\n        threading.Thread(target=self.h2_send_loop, name=\"h2_send_%s\" % self.ip_str).start()\n        threading.Thread(target=self.h2_recv_loop, name=\"h2_recv_%s\" % self.ip_str).start()\n\n    # export api\n    def request(self, task):\n        if not self.keep_running:\n            # race condition\n            self.retry_task_cb(task)\n            return\n\n        if len(self.streams) > self.config.http2_max_concurrent:\n            self.accept_task = False\n\n        task.set_state(\"h2_req\")\n        self.request_task(task)\n\n    def encode_header(self, headers):\n        return self.encoder.encode(headers)\n\n    def request_task(self, task):\n        with self.request_lock:\n            # create stream to process task\n            stream_id = self.next_stream_id\n\n            # http/2 client use odd stream_id\n            self.next_stream_id += 2\n\n            stream = self.stream_class(self.logger, self.config, self, self.ip_str, stream_id, task,\n                            self._send_cb, self._close_stream_cb, self.encode_header, self.decoder,\n                            FlowControlManager(self.local_settings[SettingsFrame.INITIAL_WINDOW_SIZE]),\n                            self.remote_settings[SettingsFrame.INITIAL_WINDOW_SIZE],\n                            self.remote_settings[SettingsFrame.SETTINGS_MAX_FRAME_SIZE])\n            self.streams[stream_id] = stream\n            stream.start_request()\n\n    def h2_send_loop(self):\n        while self.keep_running:\n            frame = self.send_queue.get(True)\n            if not frame:\n                # None frame means exist\n                break\n\n            if self.config.http2_show_debug:\n                self.logger.debug(\"%s Send:%s\", self.ip_str, str(frame))\n            data = frame.serialize()\n            try:\n                self._sock.send(data, flush=False)\n                # don't flush for small package\n                # reduce send api call\n\n                if self.send_queue._qsize():\n                    continue\n\n                # wait for payload frame\n                # time.sleep(0.01)\n                # combine header and payload in one tcp package.\n                if not self.send_queue._qsize():\n                    self._sock.flush()\n\n                self.last_send_time = time.time()\n            except socket.error as e:\n                if e.errno not in (errno.EPIPE, errno.ECONNRESET):\n                    self.logger.warn(\"%s http2 send fail:%r\", self.ip_str, e)\n                else:\n                    self.logger.exception(\"send error:%r\", e)\n\n                self.close(\"send fail:%r\" % e)\n            except Exception as e:\n                self.logger.debug(\"http2 %s send error:%r\", self.ip_str, e)\n                self.close(\"send fail:%r\" % e)\n\n    def h2_recv_loop(self):\n        while self.keep_running:\n            try:\n                self._consume_single_frame()\n            except Exception as e:\n                self.logger.exception(\"recv fail:%r\", e)\n                self.close(\"recv fail:%r\" % e)\n\n    def close(self, reason=\"conn close\"):\n        # Notify loop to exit\n        # This function may be call by out side http2\n        # When gae_proxy found the appid or ip is wrong\n        if reason.startswith(\"GoAway\") or reason in [\"life end\"]:\n            life_time = time.time() - self.ssl_sock.create_time\n            self.logger.debug(\"%s close, reason: %s, life_time:%d trace:%s\",\n                              self.ip_str, reason, life_time, self.get_trace())\n        else:\n            self.logger.warn(\"%s close, reason: %s, trace:%s\", self.ip_str, reason, self.get_trace())\n        self.send_queue.put(None)\n\n        for stream in list(self.streams.values()):\n            if stream.task.responsed or stream.task.start_time + stream.task.timeout < time.time():\n                # response have sent to client, or timeout\n                # can't retry\n                stream.close(reason=reason)\n            else:\n                self.retry_task_cb(stream.task)\n        self.streams = {}\n        super(Http2Worker, self).close(reason)\n\n    def send_ping(self):\n        p = PingFrame(0)\n        p.opaque_data = struct.pack(\"!d\", time.time())\n        #self.send_queue.put(p)\n        self._send_cb(p)\n        self.last_ping_time = time.time()\n        self.ping_on_way += 1\n\n    def _send_preamble(self):\n        self.send_queue.put(RawFrame(b'PRI * HTTP/2.0\\r\\n\\r\\nSM\\r\\n\\r\\n'))\n\n        f = SettingsFrame(0)\n        f.settings[SettingsFrame.ENABLE_PUSH] = 0\n        f.settings[SettingsFrame.INITIAL_WINDOW_SIZE] = self.local_settings[SettingsFrame.INITIAL_WINDOW_SIZE]\n        f.settings[SettingsFrame.SETTINGS_MAX_FRAME_SIZE] = self.local_settings[SettingsFrame.SETTINGS_MAX_FRAME_SIZE]\n        self._send_cb(f)\n\n        # update local connection windows size\n        f = WindowUpdateFrame(0)\n        f.window_increment = self.local_connection_initial_windows - DEFAULT_WINDOW_SIZE\n        self._send_cb(f)\n\n    def increase_remote_window_size(self, inc_size):\n        # check and send blocked frames if window allow\n        self.remote_window_size += inc_size\n        #self.logger.debug(\"%s increase send win:%d result:%d\", self.ip, inc_size, self.remote_window_size)\n        while len(self.blocked_send_frames):\n            frame = self.blocked_send_frames[0]\n            if len(frame.data) > self.remote_window_size:\n                return\n\n            self.remote_window_size -= len(frame.data)\n            self.send_queue.put(frame)\n            self.blocked_send_frames.pop(0)\n\n        if self.keep_running and \\\n                self.accept_task == False and \\\n                len(self.streams) < self.config.http2_max_concurrent and \\\n                self.remote_window_size > 10000:\n            self.accept_task = True\n            self.idle_cb()\n\n    def _send_cb(self, frame):\n        # can be called by stream\n        # put to send_blocked if connection window not allow,\n        if frame.type in [HeadersFrame.type, DataFrame.type]:\n            if len(frame.data) > self.remote_window_size:\n                self.blocked_send_frames.append(frame)\n                self.accept_task = False\n                return\n            else:\n                self.remote_window_size -= len(frame.data)\n                self.send_queue.put(frame)\n        else:\n            self.send_queue.put(frame)\n\n    def _close_stream_cb(self, stream_id, reason):\n        # call by stream to remove from streams list\n        # self.logger.debug(\"%s close stream:%d %s\", self.ssl_sock.ip, stream_id, reason)\n        try:\n            del self.streams[stream_id]\n        except KeyError:\n            pass\n\n        self.processed_tasks += 1\n\n        if len(self.streams) == 0 and self.is_life_end():\n            self.close(\"life end\")\n            return\n\n        if self.keep_running and \\\n                len(self.streams) < self.config.http2_max_concurrent and \\\n                self.remote_window_size > 10000:\n            self.accept_task = True\n            self.idle_cb()\n\n    def _consume_single_frame(self):\n        try:\n            header = self._sock.recv(9)\n        except SSLError as e:\n            self.close(\"recv.ssl error:%r\" % e)\n            return\n        except socket.timeout as e:\n            self.logger.debug(\"%s _consume_single_frame:%r, inactive time:%d\", self.ip_str, e,\n                                  time.time() - self.last_recv_time)\n            self.close(\"recv.timeout:%r\" % e)\n            return\n        except ConnectionResetError as e:\n            self.logger.debug(\"%s _consume_single_frame:%r, inactive time:%d\", self.ip_str, e,\n                                  time.time() - self.last_recv_time)\n            self.close(\"ConnectionReset:%r\" % e)\n            return\n        except Exception as e:\n            if self.keep_running:\n                self.logger.warn(\"%s _consume_single_frame:%r, inactive time:%d\", self.ip_str, e, time.time() - self.last_recv_time)\n            self.close(\"ConnectionReset:%r\" % e)\n            return\n        self.last_recv_time = time.time()\n\n        # Parse the header. We can use the returned memoryview directly here.\n        frame, length = Frame.parse_frame_header(header)\n        #self.logger.debug(\"h2 %s recv %s\", self.ip_str, frame)\n\n        if length > FRAME_MAX_ALLOWED_LEN:\n            self.logger.error(\"%s Frame size exceeded on stream %d (received: %d, max: %d)\",\n                              self.ip_str, frame.stream_id, length, FRAME_MAX_LEN)\n            # self._send_rst_frame(frame.stream_id, 6) # 6 = FRAME_SIZE_ERROR\n\n        try:\n            data = self._recv_payload(length)\n        except Exception as e:\n            self.close(\"ConnectionReset:%r\" % e)\n            return\n\n        self._consume_frame_payload(frame, data)\n\n    def _recv_payload(self, length):\n        if not length:\n            return memoryview(b'')\n\n        buffer = bytearray(length)\n        buffer_view = memoryview(buffer)\n        index = 0\n        data_length = -1\n\n        # _sock.recv(length) might not read out all data if the given length\n        # is very large. So it should be to retrieve from socket repeatedly.\n        while length and data_length:\n            data = self._sock.recv(length)\n            self.last_recv_time = time.time()\n            data_length = len(data)\n            end = index + data_length\n            buffer_view[index:end] = data[:]\n            length -= data_length\n            index = end\n\n        return buffer_view[:end]\n\n    def _consume_frame_payload(self, frame, data):\n        frame.parse_body(data)\n\n        if self.config.http2_show_debug:\n            self.logger.debug(\"h2 %s Recv:%s\", self.ip_str, str(frame))\n\n        # Maintain our flow control window. We do this by delegating to the\n        # chosen WindowManager.\n        if frame.type == DataFrame.type:\n\n            size = frame.flow_controlled_length\n            increment = self.local_window_manager._handle_frame(size)\n\n            if increment < 0:\n                self.logger.warn(\"increment:%d\", increment)\n            elif increment:\n                #self.logger.debug(\"%s frame size:%d increase win:%d\", self.ip, size, increment)\n                w = WindowUpdateFrame(0)\n                w.window_increment = increment\n                self._send_cb(w)\n\n        elif frame.type == PushPromiseFrame.type:\n            self.logger.error(\"%s receive push frame\", self.ip_str, )\n\n        # Work out to whom this frame should go.\n        if frame.stream_id != 0:\n            try:\n                stream = self.streams[frame.stream_id]\n                stream.receive_frame(frame)\n            except KeyError as e:\n                if frame.type not in [WindowUpdateFrame.type]:\n                    self.logger.warn(\"%s Unexpected stream identifier %d, frame.type:%s e:%r\",\n                                          self.ip_str, frame.stream_id, frame, e)\n        else:\n            self.receive_frame(frame)\n\n    def receive_frame(self, frame):\n        #self.logger.debug(\"h2conn recv:%s\", frame)\n        if frame.type == WindowUpdateFrame.type:\n            # self.logger.debug(\"WindowUpdateFrame %d\", frame.window_increment)\n            self.increase_remote_window_size(frame.window_increment)\n\n        elif frame.type == PingFrame.type:\n            if b'ACK' in frame.flags:\n                ping_time = struct.unpack(\"!d\", frame.opaque_data)[0]\n                time_now = time.time()\n                rtt = (time_now - ping_time) * 1000\n                if rtt < 0:\n                    self.logger.error(\"rtt:%f ping_time:%f now:%f\", rtt, ping_time, time_now)\n                self.ping_on_way -= 1\n                #self.logger.debug(\"RTT:%d, on_way:%d\", self.rtt, self.ping_on_way)\n                if self.keep_running and self.ping_on_way == 0:\n                    self.accept_task = True\n            else:\n                # The spec requires us to reply with PING+ACK and identical data.\n                p = PingFrame(0)\n                p.flags.add(b'ACK')\n                p.opaque_data = frame.opaque_data\n                self._send_cb(p)\n\n        elif frame.type == SettingsFrame.type:\n            if b'ACK' not in frame.flags:\n                # send ACK as soon as possible\n                f = SettingsFrame(0)\n                f.flags.add(b'ACK')\n                self._send_cb(f)\n\n                # this may trigger send DataFrame blocked by remote window\n                self._update_settings(frame)\n            else:\n                self.accept_task = True\n                self.idle_cb()\n\n        elif frame.type == GoAwayFrame.type:\n            # If we get GoAway with error code zero, we are doing a graceful\n            # shutdown and all is well. Otherwise, throw an exception.\n\n            # If an error occured, try to read the error description from\n            # code registry otherwise use the frame's additional data.\n            error_string = frame._extra_info()\n            time_cost = time.time() - self.last_recv_time\n            # if frame.additional_data != b\"session_timed_out\":\n            #     self.logger.warn(\"goaway:%s, t:%d\", error_string, time_cost)\n\n            self.close(\"GoAway:%s inactive time:%d\" % (error_string, time_cost))\n\n        elif frame.type == BlockedFrame.type:\n            self.logger.warn(\"%s get BlockedFrame\", self.ip_str)\n        elif frame.type in FRAMES:\n            # This frame isn't valid at this point.\n            #raise ValueError(\"Unexpected frame %s.\" % frame)\n            self.logger.error(\"%s Unexpected frame %s.\", self.ip_str, frame)\n        else:  # pragma: no cover\n            # Unexpected frames belong to extensions. Just drop it on the\n            # floor, but log so that users know that something happened.\n            self.logger.error(\"%s Received unknown frame, type %d\", self.ip_str, frame.type)\n\n    def _update_settings(self, frame):\n        if SettingsFrame.HEADER_TABLE_SIZE in frame.settings:\n            new_size = frame.settings[SettingsFrame.HEADER_TABLE_SIZE]\n\n            self.remote_settings[SettingsFrame.HEADER_TABLE_SIZE] = new_size\n            #self.encoder.header_table_size = new_size\n\n        if SettingsFrame.INITIAL_WINDOW_SIZE in frame.settings:\n            newsize = frame.settings[SettingsFrame.INITIAL_WINDOW_SIZE]\n            oldsize = self.remote_settings[SettingsFrame.INITIAL_WINDOW_SIZE]\n            delta = newsize - oldsize\n\n            for stream in list(self.streams.values()):\n                stream.remote_window_size += delta\n\n            self.remote_settings[SettingsFrame.INITIAL_WINDOW_SIZE] = newsize\n\n        if SettingsFrame.SETTINGS_MAX_FRAME_SIZE in frame.settings:\n            new_size = frame.settings[SettingsFrame.SETTINGS_MAX_FRAME_SIZE]\n            if not (FRAME_MAX_LEN <= new_size <= FRAME_MAX_ALLOWED_LEN):\n                self.logger.error(\"%s Frame size %d is outside of allowed range\", self.ip_str, new_size)\n\n                # Tear the connection down with error code PROTOCOL_ERROR\n                self.close(\"bad max frame size\")\n                #error_string = (\"Advertised frame size %d is outside of range\" % (new_size))\n                #raise ConnectionError(error_string)\n                return\n\n            self.remote_settings[SettingsFrame.SETTINGS_MAX_FRAME_SIZE] = new_size\n\n            for stream in list(self.streams.values()):\n                stream.max_frame_size += new_size\n\n    def get_trace(self):\n        now = time.time()\n        out_list = [\n            \" continue_timeout:%d\" % self.continue_timeout, \" processed:%d\" % self.processed_tasks,\n            \" inactive:%d, %d\" % (now - self.last_send_time, now - self.last_recv_time),\n            \" h2.stream_num:%d\" % len(self.streams),\n            \" sni:%s, host:%s\" % (self.ssl_sock.sni, self.ssl_sock.host)\n        ]\n        return \",\".join(out_list)\n"
  },
  {
    "path": "code/default/lib/noarch/front_base/http2_stream.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nport from hyper/http20/stream for async\nremove push support\nincrease init window size to improve performance\n~~~~~~~~~~~~~~~~~~~\n\nObjects that make up the stream-level abstraction of hyper's HTTP/2 support.\n\n\nConceptually, a single HTTP/2 connection is made up of many streams: each\nstream is an independent, bi-directional sequence of HTTP headers and data.\nEach stream is identified by a monotonically increasing integer, assigned to\nthe stream by the endpoint that initiated the stream.\n\"\"\"\n\n\nimport threading\nimport time\n\nfrom hyper.common.headers import HTTPHeaderMap\nfrom hyper.packages.hyperframe.frame import (\n    FRAME_MAX_LEN, FRAMES, HeadersFrame, DataFrame, PushPromiseFrame,\n    WindowUpdateFrame, ContinuationFrame, BlockedFrame, RstStreamFrame\n)\nfrom hyper.http20.exceptions import ProtocolError, StreamResetError\nfrom hyper.http20.util import h2_safe_headers\nfrom hyper.http20.response import strip_headers\nfrom hyper.common.util import to_host_port_tuple, to_native_string, to_bytestring\nimport simple_http_client\n\nfrom .http_common import *\nfrom utils import to_bytes\n\n# Define a set of states for a HTTP/2 stream.\nSTATE_IDLE               = 0\nSTATE_OPEN               = 1\nSTATE_HALF_CLOSED_LOCAL  = 2\nSTATE_HALF_CLOSED_REMOTE = 3\nSTATE_CLOSED             = 4\n\n\nclass Stream(object):\n    \"\"\"\n    A single HTTP/2 stream.\n\n    A stream is an independent, bi-directional sequence of HTTP headers and\n    data. Each stream is identified by a single integer. From a HTTP\n    perspective, a stream _approximately_ matches a single request-response\n    pair.\n    \"\"\"\n    def __init__(self,\n                 logger,\n                 config,\n                 connection,\n                 ip_str,\n                 stream_id,\n                 task,\n                 send_cb,\n                 close_cb,\n                 encoder,\n                 decoder,\n                 receive_window_manager,\n                 remote_window_size,\n                 max_frame_size):\n\n        self.logger = logger\n        self.config = config\n        self.connection = connection\n        self.ip_str = ip_str\n        self.stream_id = stream_id\n        self.task = task\n        self.state = STATE_IDLE\n        self.get_head_time = None\n        self.start_connection_point = self.connection._sock.bytes_received\n        self.get_head_stream_num = 0\n\n        # There are two flow control windows: one for data we're sending,\n        # one for data being sent to us.\n        self.receive_window_manager = receive_window_manager\n        self.remote_window_size = remote_window_size\n        self.max_frame_size = max_frame_size\n\n        # This is the callback handed to the stream by its parent connection.\n        # It is called when the stream wants to send data. It expects to\n        # receive a list of frames that will be automatically serialized.\n        self._send_cb = send_cb\n\n        # This is the callback to be called when the stream is closed.\n        self._close_cb = close_cb\n\n        # A reference to the header encoder and decoder objects belonging to\n        # the parent connection.\n        self._encoder = encoder\n        self._decoder = decoder\n\n        self.request_headers = HTTPHeaderMap()\n\n        # Convert the body to bytes if needed.\n        self.request_body = to_bytestring(self.task.body)\n\n        # request body not send blocked by send window\n        # the left body will send when send window opened.\n        self.request_body_left = len(self.request_body)\n        self.request_body_sended = False\n\n        # data list before decode\n        self.response_header_datas = []\n\n        # Set to a key-value set of the response headers once their\n        # HEADERS..CONTINUATION frame sequence finishes.\n        self.response_headers = None\n\n        # Unconsumed response data chunks\n        self.response_body = []\n        self.response_body_len = 0\n        self.start_time = time.time()\n\n    def start_request(self):\n        \"\"\"\n        Open the stream. Does this by encoding and sending the headers: no more\n        calls to ``add_header`` are allowed after this method is called.\n        The `end` flag controls whether this will be the end of the stream, or\n        whether data will follow.\n        \"\"\"\n        # Strip any headers invalid in H2.\n        #headers = h2_safe_headers(self.request_headers)\n\n        host = self.connection.get_host(self.task.host)\n\n        self.add_header(\":method\", self.task.method)\n        self.add_header(\":scheme\", \"https\")\n        self.add_header(\":authority\", host)\n        self.add_header(\":path\", self.task.path)\n\n        default_headers = (':method', ':scheme', ':authority', ':path')\n        #headers = h2_safe_headers(self.task.headers)\n        for name, value in list(self.task.headers.items()):\n            is_default = to_native_string(name) in default_headers\n            self.add_header(name, value, replace=is_default)\n\n        # Encode the headers.\n        encoded_headers = self._encoder(self.request_headers)\n\n        # It's possible that there is a substantial amount of data here. The\n        # data needs to go into one HEADERS frame, followed by a number of\n        # CONTINUATION frames. For now, for ease of implementation, let's just\n        # assume that's never going to happen (16kB of headers is lots!).\n        # Additionally, since this is so unlikely, there's no point writing a\n        # test for this: it's just so simple.\n        if len(encoded_headers) > FRAME_MAX_LEN:  # pragma: no cover\n            raise ValueError(\"Header block too large.\")\n\n        header_frame = HeadersFrame(self.stream_id)\n        header_frame.data = encoded_headers\n\n        # If no data has been provided, this is the end of the stream. Either\n        # way, due to the restriction above it's definitely the end of the\n        # headers.\n        header_frame.flags.add('END_HEADERS')\n        if self.request_body_left == 0:\n            header_frame.flags.add('END_STREAM')\n\n        # Send the header frame.\n        self.task.set_state(\"start send header\")\n        self._send_cb(header_frame)\n\n        # Transition the stream state appropriately.\n        self.state = STATE_OPEN\n\n        self.task.set_state(\"start send left body\")\n        if self.request_body_left > 0:\n            self.send_left_body()\n\n    def add_header(self, name, value, replace=False):\n        \"\"\"\n        Adds a single HTTP header to the headers to be sent on the request.\n        \"\"\"\n        value = to_bytes(value)\n        if not replace:\n            self.request_headers[name] = value\n        else:\n            self.request_headers.replace(name, value)\n\n    def send_left_body(self):\n        while self.remote_window_size and not self.request_body_sended:\n            send_size = min(self.remote_window_size, self.request_body_left, self.max_frame_size)\n\n            f = DataFrame(self.stream_id)\n            data_start = len(self.request_body) - self.request_body_left\n            f.data = self.request_body[data_start:data_start+send_size]\n\n            self.remote_window_size -= send_size\n            self.request_body_left -= send_size\n\n            # If the length of the data is less than MAX_CHUNK, we're probably\n            # at the end of the file. If this is the end of the data, mark it\n            # as END_STREAM.\n            if self.request_body_left == 0:\n                f.flags.add('END_STREAM')\n\n            # Send the frame and decrement the flow control window.\n            self._send_cb(f)\n\n            # If no more data is to be sent on this stream, transition our state.\n            if self.request_body_left == 0:\n                self.request_body_sended = True\n                self._close_local()\n                self.task.set_state(\"end send left body\")\n\n    def receive_frame(self, frame):\n        \"\"\"\n        Handle a frame received on this stream.\n        called by connection.\n        \"\"\"\n        # self.logger.debug(\"stream %d recved frame %r\", self.stream_id, frame)\n        if frame.type == WindowUpdateFrame.type:\n            self.remote_window_size += frame.window_increment\n            self.send_left_body()\n        elif frame.type == HeadersFrame.type:\n            # Begin the header block for the response headers.\n            #self.response_header_datas = [frame.data]\n            self.response_header_datas.append(frame.data)\n        elif frame.type == PushPromiseFrame.type:\n            self.logger.error(\"%s receive PushPromiseFrame:%d\", self.ip_str, frame.stream_id)\n        elif frame.type == ContinuationFrame.type:\n            # Continue a header block begun with either HEADERS or PUSH_PROMISE.\n            self.response_header_datas.append(frame.data)\n        elif frame.type == DataFrame.type:\n            # Append the data to the buffer.\n            if not self.task.finished:\n                self.task.put_data(frame.data)\n\n            if b'END_STREAM' not in frame.flags:\n                # Increase the window size. Only do this if the data frame contains\n                # actual data.\n                # don't do it if stream is closed.\n                size = frame.flow_controlled_length\n                increment = self.receive_window_manager._handle_frame(size)\n                #if increment:\n                #    self.logger.debug(\"stream:%d frame size:%d increase win:%d\", self.stream_id, size, increment)\n\n                #content_len = int(self.request_headers.get(\"Content-Length\")[0])\n                #self.logger.debug(\"%s get:%d s:%d\", self.ip, self.response_body_len, size)\n\n                if increment and not self._remote_closed:\n                    w = WindowUpdateFrame(self.stream_id)\n                    w.window_increment = increment\n                    self._send_cb(w)\n        elif frame.type == BlockedFrame.type:\n            # If we've been blocked we may want to fixup the window.\n            increment = self.receive_window_manager._blocked()\n            if increment:\n                w = WindowUpdateFrame(self.stream_id)\n                w.window_increment = increment\n                self._send_cb(w)\n        elif frame.type == RstStreamFrame.type:\n            # Rest Frame send from server is not define in RFC\n            inactive_time = time.time() - self.connection.last_recv_time\n            self.logger.debug(\"%s Stream %d Rest by server, inactive:%d. error code:%d\",\n                       self.ip_str, self.stream_id, inactive_time, frame.error_code)\n            self.connection.close(\"RESET\")\n        elif frame.type in FRAMES:\n            # This frame isn't valid at this point.\n            # Raise ValueError(\"Unexpected frame %s.\" % frame)\n            self.logger.error(\"%s Unexpected frame %s.\", self.ip_str, frame)\n        else:  # pragma: no cover\n            # Unknown frames belong to extensions. Just drop it on the\n            # floor, but log so that users know that something happened.\n            self.logger.error(\"%s Received unknown frame, type %d\", self.ip_str, frame.type)\n            pass\n\n        if b'END_HEADERS' in frame.flags:\n            if self.response_headers is not None:\n                raise ProtocolError(\"Too many header blocks.\")\n\n            # Begin by decoding the header block. If this fails, we need to\n            # tear down the entire connection.\n            if len(self.response_header_datas) == 1:\n                header_data = self.response_header_datas[0]\n            else:\n                header_data = b''.join(self.response_header_datas)\n\n            try:\n                headers = self._decoder.decode(header_data)\n            except Exception as e:\n                self.logger.exception(\"decode h2 header %s fail:%r\", header_data, e)\n                raise e\n\n            self.response_headers = HTTPHeaderMap(headers)\n\n            # We've handled the headers, zero them out.\n            self.response_header_datas = None\n\n            self.get_head_time = time.time()\n            self.get_head_stream_num = len(self.connection.streams)\n\n            length = self.response_headers.get(\"Content-Length\", None)\n            if isinstance(length, list):\n                length = int(length[0])\n            if not self.task.finished:\n                self.task.content_length = length\n                self.task.set_state(\"h2_get_head\")\n                self.send_response()\n\n        if b'END_STREAM' in frame.flags:\n            xcost = self.response_headers.get(\"X-Cost\", -1)\n            if isinstance(xcost, list):\n                xcost = float(xcost[0])\n\n            time_now = time.time()\n            whole_cost = time_now - self.start_time\n            rtt = whole_cost - xcost\n            bytes_received = self.connection._sock.bytes_received - self.start_connection_point\n            if self.config.http2_show_debug:\n                self.logger.debug(\"%s stream:%d END_STREAM %s%s\", self.connection.ssl_sock.ip_str,\n                                  self.stream_id, self.task.host, self.task.path)\n\n            if b\"ping\" in self.task.path and self.config.http2_show_debug:\n                self.logger.debug(\"got pong for %s\", self.connection.ip_str)\n\n            if rtt > 0 and not self.task.finished and xcost >= 0.0:\n                self.connection.update_speed(rtt, len(self.request_body), bytes_received)\n                self.task.set_state(\"h2_finish[RTT:%d]\" % (rtt * 1000))\n                if self.config.http2_show_debug:\n                    self.logger.debug(\"%s rtt:%f send_len:%d recv_len:%d \"\n                                      \"whole_Cost:%f xcost:%f\",\n                                      self.connection.ssl_sock.ip_str, rtt * 1000,\n                                      len(self.request_body), bytes_received,\n                                      whole_cost, xcost)\n\n            self._close_remote()\n\n            self.close(\"end stream\")\n            if not self.task.finished:\n                self.connection.continue_timeout = 0\n\n    def send_response(self):\n        if self.task.responsed:\n            self.logger.error(\"http2_stream send_response but responsed.%s\", self.task.url)\n            self.close(\"h2 stream send_response but sended.\")\n            return\n\n        self.task.responsed = True\n        status = int(self.response_headers[b':status'][0])\n        strip_headers(self.response_headers)\n        response = simple_http_client.BaseResponse(status=status, headers=self.response_headers)\n        response.ssl_sock = self.connection.ssl_sock\n        response.worker = self.connection\n        response.task = self.task\n\n        if self.task.queue:\n            self.task.queue.put(response)\n        else:\n            if self.config.http2_show_debug:\n                self.logger.debug(\"got pong for %s status:%d\", self.connection.ip_str, status)\n\n        if status in self.config.http2_status_to_close:\n            self.connection.close(\"status %d\" % status)\n\n    def close(self, reason=\"close\"):\n        if not self.task.responsed:\n            # self.task.set_state(\"stream close: %s, call retry\" % reason)\n            if self.task.start_time + self.task.timeout > time.time():\n                self.connection.retry_task_cb(self.task, reason)\n        else:\n            # self.task.set_state(\"stream close: %s, finished\" % reason)\n            self.task.finish()\n            # empty block means fail or closed.\n\n        self._close_remote()\n        # self.task.set_state(\"stream close: %s, closed remote\" % reason)\n\n        self._close_cb(self.stream_id, reason)\n        # self.task.set_state(\"stream close: %s, called close_cb\" % reason)\n\n    @property\n    def _local_closed(self):\n        return self.state in (STATE_CLOSED, STATE_HALF_CLOSED_LOCAL)\n\n    @property\n    def _remote_closed(self):\n        return self.state in (STATE_CLOSED, STATE_HALF_CLOSED_REMOTE)\n\n    @property\n    def _local_open(self):\n        return self.state in (STATE_OPEN, STATE_HALF_CLOSED_REMOTE)\n\n    def _close_local(self):\n        self.state = (\n            STATE_HALF_CLOSED_LOCAL if self.state == STATE_OPEN\n            else STATE_CLOSED\n        )\n\n    def _close_remote(self):\n        self.state = (\n            STATE_HALF_CLOSED_REMOTE if self.state == STATE_OPEN\n            else STATE_CLOSED\n        )\n\n    def check_timeout(self, now):\n        if time.time() - self.start_time < self.task.timeout:\n            return\n\n        if self._remote_closed:\n            return\n\n        self.logger.warn(\"h2 timeout %s task_trace:%s worker_trace:%s\",\n                  self.connection.ssl_sock.ip_str,\n                  self.task.get_trace(),\n                  self.connection.get_trace())\n        self.task.set_state(\"timeout\")\n\n        if self.task.responsed:\n            self.task.finish()\n        else:\n            self.task.response_fail(\"timeout\")\n\n        self.connection.continue_timeout += 1\n        #if self.connection.continue_timeout >= self.connection.config.http2_max_timeout_tasks and \\\n        #        time.time() - self.connection.last_redv_time > self.connection.config.http2_timeout_active:\n        #    self.connection.close(\"down fail\")"
  },
  {
    "path": "code/default/lib/noarch/front_base/http_common.py",
    "content": "import threading\nimport time\nimport random\n\nfrom queue import Queue\nimport simple_http_client\n\nimport utils\n\n\nclass Task(object):\n    def __init__(self, logger, config, method, host, path, headers, body, queue, url, timeout):\n        self.logger = logger\n        self.config = config\n        self.method = method\n        self.host = host\n        self.path = path\n        self.headers = headers\n        self.body = body\n        self.queue = queue\n        self.url = url\n        self.timeout = timeout\n        self.start_time = time.time()\n        if path == b'/':\n            path = headers.get(b\"X-Path\", b\"/\")\n        self.unique_id = \"%s%s:%f\" % (url, path, self.start_time)\n        self.trace_time = []\n        self.body_queue = Queue()\n        self.body_len = 0\n        self.body_readed = 0\n        self.content_length = None\n        self.worker = None\n        self.read_buffers = []\n        self.read_buffer_len = 0\n\n        self.responsed = False\n        self.finished = False\n        self.retry_count = 0\n\n    def to_string(self):\n        out_str = \" Task:%s\\r\\n\" % self.url\n        out_str += \"   responsed:%d\" % self.responsed\n        out_str += \"   retry_count:%d\" % self.retry_count\n        out_str += \"   start_time:%d\" % (time.time() - self.start_time)\n        out_str += \"   body_readed:%d\\r\\n\" % self.body_readed\n        out_str += \"   Trace:%s\" % self.get_trace()\n        out_str += \"\\r\\n\"\n        return out_str\n\n    def put_data(self, data):\n        # hyper H2\n        if isinstance(data, memoryview):\n            data = data.tobytes()\n        self.body_queue.put(data)\n        self.body_len += len(data)\n\n    def read(self, size=None):\n        # fail or cloe if return \"\"\n        if self.body_readed == self.content_length:\n            return b''\n\n        if size:\n            while self.read_buffer_len < size:\n                try:\n                    data = self.body_queue.get(timeout=self.timeout)\n                except:\n                    data = None\n\n                if not data:\n                    return b''\n\n                self.read_buffers.append(data)\n                self.read_buffer_len += len(data)\n\n            if len(self.read_buffers[0]) == size:\n                data = self.read_buffers[0]\n                self.read_buffers.pop(0)\n                self.read_buffer_len -= size\n            elif len(self.read_buffers[0]) > size:\n                data = self.read_buffers[0][:size]\n                self.read_buffers[0] = self.read_buffers[0][size:]\n                self.read_buffer_len -= size\n            else:\n                buff = bytearray(self.read_buffer_len)\n                buff_view = memoryview(buff)\n                p = 0\n                for data in self.read_buffers:\n                    buff_view[p:p + len(data)] = data\n                    p += len(data)\n\n                if self.read_buffer_len == size:\n                    self.read_buffers = []\n                    self.read_buffer_len = 0\n                    data = buff_view.tobytes()\n                else:\n                    data = buff_view[:size].tobytes()\n\n                    self.read_buffers = [buff_view[size:].tobytes()]\n                    self.read_buffer_len -= size\n\n        else:\n            if self.read_buffers:\n                data = self.read_buffers.pop(0)\n                self.read_buffer_len -= len(data)\n            else:\n                try:\n                    data = self.body_queue.get(timeout=self.timeout)\n                except:\n                    data = None\n\n                if not data:\n                    return b''\n\n        self.body_readed += len(data)\n        return data\n\n    def read_all(self):\n        if self.content_length:\n            left_body = int(self.content_length) - self.body_readed\n\n            buff = bytearray(left_body)\n            buff_view = memoryview(buff)\n            p = 0\n            for data in self.read_buffers:\n                buff_view[p:p + len(data)] = data\n                p += len(data)\n\n            self.read_buffers = []\n            self.read_buffer_len = 0\n\n            while p < left_body:\n                data = self.read()\n                if not data:\n                    break\n\n                buff_view[p:p + len(data)] = data[0:len(data)]\n                p += len(data)\n\n            self.body_readed += p\n            return buff_view[:p].tobytes()\n        else:\n            out = list()\n            while True:\n                data = self.read()\n                if not data:\n                    break\n                out.append(data)\n            return b\"\".join(out)\n\n    def set_state(self, stat):\n        # for debug trace\n        time_now = time.time()\n        self.trace_time.append((time_now, stat))\n        if self.config.show_state_debug:\n            self.logger.debug(\"%s stat:%s\", self.unique_id, stat)\n        return time_now\n\n    def get_trace(self):\n        out_list = []\n        last_time = self.start_time\n        for t, stat in self.trace_time:\n            time_diff = int((t - last_time) * 1000)\n            if time_diff == 0 and \"get_worker\" not in stat:\n                continue\n\n            last_time = t\n            out_list.append(\"%d:%s\" % (time_diff, stat))\n        out_list.append(\":%d\" % ((time.time() - last_time) * 1000))\n        return \",\".join(out_list)\n\n    def response_fail(self, reason=\"\"):\n        if self.responsed:\n            self.logger.error(\"http_common responsed_fail but responed.%s\", self.url)\n            self.put_data(\"\")\n            return\n\n        self.responsed = True\n        err_text = \"response_fail:%s\" % reason\n        self.logger.warn(\"%s %s\", self.url, err_text)\n        res = simple_http_client.BaseResponse(body=err_text)\n        res.task = self\n        res.worker = self.worker\n        if self.queue:\n            self.queue.put(res)\n        self.finish()\n\n    def finish(self):\n        if self.finished:\n            return\n\n        self.put_data(\"\")\n        self.finished = True\n\n\nclass HttpWorker(object):\n    max_payload = 32 * 1024\n\n    def __init__(self, logger, ip_manager, config, ssl_sock, close_cb, retry_task_cb, idle_cb, log_debug_data):\n        self.logger = logger\n        self.ip_manager = ip_manager\n        self.config = config\n        self.ssl_sock = ssl_sock\n        self.handshake = ssl_sock.handshake_time * 0.001  # client to front\n        self.adjust = float(ssl_sock.host_info.get(\"adjust\", 0))\n        self.ip_str = utils.to_str(ssl_sock.ip_str)\n        self.close_cb = close_cb\n        self.retry_task_cb = retry_task_cb\n        self.idle_cb = idle_cb\n        self.log_debug_data = log_debug_data\n\n        self.version = \"0\"\n        self._lock = threading.Lock()\n        self.request_onway = False\n        self.accept_task = True\n        self.keep_running = True\n        self.processed_tasks = 0\n        self.score = 0\n        self.continue_fail_tasks = 0\n        self.streams = {}\n\n        self.last_request_time = self.ssl_sock.create_time\n        self.last_recv_time = self.ssl_sock.create_time\n        self.last_send_time = self.ssl_sock.create_time\n        self.life_end_time = self.ssl_sock.create_time + \\\n                             random.randint(self.config.connection_max_life, int(self.config.connection_max_life * 1.5))\n        # self.logger.debug(\"worker.init %s %s\", self.ip_str, self.ssl_sock.getsockname())\n\n        speed, rtt = self.ip_manager.get_speed(self.ip_str)\n        self.calculate_score(rtt, speed)\n\n    def __str__(self):\n        o = \"\"\n        o += \" ip_str: %s\\r\\n\" % (self.ip_str)\n        o += \" running: %s\\r\\n\" % (self.keep_running)\n        o += \" processed_tasks: %d\\r\\n\" % (self.processed_tasks)\n        o += \" continue_fail_tasks: %s\\r\\n\" % (self.continue_fail_tasks)\n        o += \" handshake: %f \\r\\n\" % self.handshake\n        o += \" adjust: %f \\r\\n\" % self.adjust\n        if self.version != \"1.1\":\n            o += \"streams: %d\\r\\n\" % len(self.streams)\n        speed, min_rtt = self.ip_manager.get_speed(self.ip_str)\n        o += \" speed: %f\\r\\n\" % (speed)\n        o += \" min_rtt: %f\\r\\n\" % (min_rtt)\n        o += \" score: %f\\r\\n\" % (self.get_score())\n        o += \" last_recv_time: %f\\r\\n\" % (time.time() - self.last_recv_time)\n        o += \" last_request_time: %f\\r\\n\" % (time.time() - self.last_request_time)\n        return o\n\n    def update_speed(self, timecost, sent, received):\n        mean_rtt, speed = self.ip_manager.report_traffic_timecost(self.ip_str, timecost, sent + received)\n        self.calculate_score(mean_rtt, speed)\n\n        self.log_debug_data(timecost, sent, received)\n\n    def calculate_score(self, rtt, speed):\n        mean_traffic_size = self.config.ip_cal_expect_time_package_size\n        # calculate score\n        # the meaning of the score is the expected timecost\n        if self.version == \"1.1\":\n            score = rtt + (mean_traffic_size / speed)\n        else:\n            response_body_len = mean_traffic_size\n            for _, stream in self.streams.items():\n                if stream.response_body_len == 0:\n                    response_body_len += mean_traffic_size\n                else:\n                    response_body_len += stream.response_body_len - stream.task.body_len\n            score = rtt + (response_body_len / speed)\n\n        if self.config.show_state_debug:\n            self.logger.debug(\"cal score %s, speed:%f rtt:%d stream_num:%d score:%f\", self.ip_str,\n                              speed, rtt * 1000, len(self.streams), score * 1000)\n\n        self.score = score + self.adjust\n\n        if self.version == \"1.1\":\n            self.ip_manager.update_score(self.ip_str, self.score)\n\n    def get_score(self):\n        # The smaller, the better\n        if self.version == \"1.1\":\n            return self.ip_manager.get_score(self.ip_str)\n        else:\n            return self.score\n\n    def close(self, reason):\n        with self._lock:\n            if not self.keep_running:\n                # self.logger.warn(\"worker %s already closed %s\", self.ip_str, reason)\n                return\n\n            # self.logger.debug(\"worker.close %s reason:%s\", self.ip_str, reason)\n            self.accept_task = False\n            self.keep_running = False\n            self.ssl_sock.close(reason)\n            if reason not in [\"idle timeout\", \"life end\"]:\n                now = time.time()\n                inactive_time = now - self.last_recv_time\n                if inactive_time < self.config.http2_ping_min_interval:\n                    self.logger.debug(\"%s worker close:%s inactive:%d\", self.ip_str, reason, inactive_time)\n            self.ip_manager.report_connect_closed(self.ssl_sock.ip_str, self.ssl_sock.sni, reason)\n            self.close_cb(self)\n\n    def __del__(self):\n        # self.logger.debug(\"__del__ %s\", self.ip_str)\n        self.close(\"__del__\")\n\n    def get_host(self, task_host):\n        if task_host:\n            return task_host\n        else:\n            return self.ssl_sock.host\n\n    def is_life_end(self):\n        now = time.time()\n        if now > self.life_end_time:\n            return \"life_end_time\"\n        elif now - self.last_recv_time > 230:\n            return \"last_recv_time\"\n        elif self.continue_fail_tasks > self.config.dispather_worker_max_continue_fail:\n            return \"continue_fail\"\n        elif self.processed_tasks > self.config.http2_max_process_tasks:\n            return \"processed_tasks\"\n        elif self.version == \"1.1\":\n            if self.processed_tasks > self.config.http1_max_process_tasks:\n                return \"http1 max_process_tasks\"\n            elif now - self.last_recv_time > self.config.http1_idle_time:\n                return \"http1 last_recv_time\"\n            else:\n                return False\n        else:\n            return False\n"
  },
  {
    "path": "code/default/lib/noarch/front_base/http_dispatcher.py",
    "content": "#!/usr/bin/env python\n# coding:utf-8\n\n\n\"\"\"\nThis file manage the ssl connection dispatcher\nInclude http/1.1 and http/2 workers.\n\ncreate ssl socket, then run worker on ssl.\nif ssl suppport http/2, run http/2 worker.\n\nprovide simple https request block api.\n caller don't need to known ip/ssl/http2/appid.\n\nperformance:\n get the fastest worker to process the request.\n sorted by rtt and pipeline task on load.\n\"\"\"\nfrom six.moves import queue\nimport random\nimport operator\nimport threading\nimport time\nimport traceback\n\nfrom utils import SimpleCondition\nfrom queue import Queue\nimport utils\n\nfrom . import http_common\nfrom .http1 import Http1Worker\nfrom .http2_connection import Http2Worker, Stream\n\n\nclass HttpsDispatcher(object):\n    idle_time = 2 * 60\n\n    base_headers = {\n        \"User-Agent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.67 Safari/537.36\",\n        \"Accept\": \"*/*\",\n        \"Accept-Language\": \"en-US,en;q=0.5\",\n        \"Connection\": \"keep-alive\",\n        \"Sec-Fetch-Dest\": \"empty\",\n        \"Sec-Fetch-Mode\": \"no-cors\",\n        \"Sec-Fetch-Site\": \"same-origin\",\n    }\n\n    def __init__(self, logger, config, ip_manager, connection_manager,\n                 http1worker=Http1Worker,\n                 http2worker=Http2Worker,\n                 http2stream_class=None):\n        self.logger = logger\n        self.config = config\n        self.ip_manager = ip_manager\n        self.connection_manager = connection_manager\n        self.connection_manager.set_ssl_created_cb(self.on_ssl_created_cb)\n\n        self.http1worker = http1worker\n        self.http2worker = http2worker\n        if http2stream_class:\n            self.http2stream_class = http2stream_class\n        else:\n            self.http2stream_class = Stream\n\n        self.request_queue = Queue()\n        self.workers = []\n        self.working_tasks = {}\n        self.account = \"\"\n        self.last_host = None\n        self.session_host = None\n        self.h1_num = 0\n        self.h2_num = 0\n        self.last_request_time = time.time()\n        self.last_get_score_time = 0\n        self.task_count_lock = threading.Lock()\n        self.task_count = 0\n        self.running = True\n\n        self.connect_all_workers = False\n\n        # for statistic\n        self.success_num = 0\n        self.fail_num = 0\n        self.continue_fail_num = 0\n        self.last_fail_time = 0\n        self.rtts = []\n        self.last_sent = self.total_sent = 0\n        self.last_received = self.total_received = 0\n        self.second_stats = queue.deque()\n        self.last_statistic_time = time.time()\n        self.second_stat = {\n            \"rtt\": 0,\n            \"sent\": 0,\n            \"received\": 0\n        }\n        self.minute_stat = {\n            \"rtt\": 0,\n            \"sent\": 0,\n            \"received\": 0\n        }\n        self.ping_speed_ip_str_last_active = {}  # ip_str => last_active\n\n        self.trigger_create_worker_cv = SimpleCondition()\n        self.wait_a_worker_cv = SimpleCondition()\n\n        threading.Thread(target=self.dispatcher, name=\"%s_dispatcher\" % self.logger.name).start()\n        threading.Thread(target=self.create_worker_thread, name=\"%s_create_worker_thread\" % self.logger.name).start()\n        threading.Thread(target=self.connection_checker, name=\"%s_connection_checker\" % self.logger.name).start()\n\n        if self.config.dispather_connect_all_workers_on_startup:\n            self.start_connect_all_ips()\n\n    def stop(self):\n        self.running = False\n        self.request_queue.put(None)\n        self.close_all_worker(\"stop\")\n\n    def _debug_log(self, fmt, *args, **kwargs):\n        if not self.config.show_state_debug:\n            return\n        self.logger.debug(fmt, *args, **kwargs)\n\n    def on_ssl_created_cb(self, ssl_sock, remove_slowest_worker=True):\n        self._debug_log(\"on_ssl_created_cb %s\", ssl_sock.ip_str)\n\n        if not self.running:\n            self.logger.info(\"on_ssl_created_cb %s but stopped\", ssl_sock.ip_str)\n            ssl_sock.close()\n            return\n\n        if not ssl_sock:\n            raise Exception(\"on_ssl_created_cb ssl_sock None\")\n\n        if ssl_sock.h2:\n            worker = self.http2worker(\n                self.logger, self.ip_manager, self.config, ssl_sock,\n                self.close_cb, self.retry_task_cb, self._on_worker_idle_cb, self.log_debug_data,\n                stream_class=self.http2stream_class)\n            self.h2_num += 1\n        else:\n            worker = self.http1worker(\n                self.logger, self.ip_manager, self.config, ssl_sock,\n                self.close_cb, self.retry_task_cb, self._on_worker_idle_cb, self.log_debug_data)\n            self.h1_num += 1\n\n        self.workers.append(worker)\n\n        if time.time() - self.ping_speed_ip_str_last_active.get(worker.ip_str, 0) > self.config.dispather_ping_check_speed_interval:\n            self.ping_speed(worker, self.config.dispather_ping_rtt_download_size)\n            self.ping_speed(worker, self.config.dispather_ping_speed_download_size)\n            self.ping_speed_ip_str_last_active[worker.ip_str] = time.time()\n        elif remove_slowest_worker:\n            self._remove_slowest_worker()\n\n    def ping_speed(self, worker, size):\n        if not self.session_host:\n            return\n\n        method = b\"POST\"\n        path = b\"/ping?content_length=%d\" % size\n        body = utils.to_bytes(utils.generate_random_lowercase(self.config.dispather_ping_upload_size))\n        headers = {\n            b\"Padding\": utils.to_str(utils.generate_random_lowercase(random.randint(32, 128))),\n            b\"Xx-Account\": self.account,\n            b\"X-Host\": self.session_host,\n            b\"X-Path\": path\n        }\n\n        task = http_common.Task(self.logger, self.config, method, self.session_host, path,\n                                headers, body, None, \"/ping\", 5)\n        task.set_state(\"start_ping_request(%s)\" % worker.ip_str)\n        # self.logger.debug(\"send ping for %s\", worker.ip_str)\n\n        worker.request(task)\n\n    def _on_worker_idle_cb(self):\n        self.wait_a_worker_cv.notify()\n\n    def create_worker_thread(self):\n        self.logger.info(\"%s create_worker_thread start\", self.logger.name)\n        while self.running:\n            if not self.connect_all_workers or (len(self.workers) > self.config.dispather_max_workers):\n                self.trigger_create_worker_cv.wait()\n                self._debug_log(\"got a trigger_create_worker_cv notify\")\n\n            try:\n                ssl_sock = self.connection_manager.get_ssl_connection(timeout=60)\n            except Exception as e:\n                self._debug_log(\"create_worker_thread get_ssl_connection fail:%r\", e)\n                ssl_sock = None\n\n            if not ssl_sock:\n                self._debug_log(\"create_worker_thread get ssl_sock fail\")\n                self.connect_all_workers = False\n                continue\n\n            try:\n                self.on_ssl_created_cb(ssl_sock, remove_slowest_worker=False)\n            except Exception as e:\n                self.logger.exception(\"on_ssl_created_cb %s except:%r\", ssl_sock.ip, e)\n                time.sleep(10)\n\n            if self.connect_all_workers and len(self.workers) >= self.config.dispather_min_workers:\n                self.connect_all_workers = False\n\n        self.logger.info(\"%s create_worker_thread exit\", self.logger.name)\n\n    def start_connect_all_ips(self):\n        # trigger to connect all ips\n        # used in tls relay.\n        self.connect_all_workers = True\n        self.trigger_create_worker_cv.notify()\n\n    def _remove_life_end_workers(self):\n        to_close = []\n        for worker in self.workers:\n            if not worker.is_life_end():\n                continue\n\n            if worker.version == \"1.1\" and not worker.request_onway:\n                to_close.append(worker)\n                continue\n\n            now = time.time()\n            task_finished = True\n            for stream_id, stream in worker.streams.items():\n                if stream.task.start_time + stream.task.timeout > now:\n                    task_finished = False\n                    break\n\n            if task_finished:\n                to_close.append(worker)\n\n        for worker in to_close:\n            reason = worker.is_life_end()\n            worker.close(\"life end:\" + reason)\n            if worker in self.workers:\n                try:\n                    self.workers.remove(worker)\n                except:\n                    pass\n\n    def get_worker(self, nowait=False):\n        # self._debug_log(\"start get_worker\")\n\n        while self.running:\n            top_score = 99999999\n            best_score = 99999999\n            best_worker = None\n            good_worker = 0\n            idle_num = 0\n            now = time.time()\n\n            self._remove_life_end_workers()\n\n            for worker in self.workers:\n                score = worker.get_score()\n                if top_score > score:\n                    top_score = score\n\n                if worker.is_life_end():\n                    self._debug_log(\"life end worker: %s\", worker.ip_str)\n                    # self.close_cb(worker)\n                    continue\n\n                good_worker += 1\n\n                if not worker.accept_task:\n                    continue\n\n                if worker.version == \"1.1\":\n                    idle_num += 1\n                else:\n                    if len(worker.streams) == 0:\n                        idle_num += 1\n\n                if best_score > score:\n                    best_score = score\n                    best_worker = worker\n\n            if good_worker < self.config.dispather_max_workers and \\\n                    (best_worker is None or\n                    idle_num < self.config.dispather_min_idle_workers or\n                    len(self.workers) < self.config.dispather_min_workers or\n                    abs(now - best_worker.last_recv_time) < self.config.dispather_work_min_idle_time or\n                    best_score > self.config.dispather_work_max_score or\n                     (best_worker.version == \"2\" and len(best_worker.streams) >= self.config.http2_target_concurrent) or\n                     (best_score > top_score and best_worker.version == \"1.1\")):\n                self._debug_log(\"trigger get more worker\")\n                self.trigger_create_worker_cv.notify()\n\n            if nowait or best_worker:\n                return best_worker\n\n            self._debug_log(\"wait a new worker\")\n            self.wait_a_worker_cv.wait(1)\n\n    def _remove_slowest_worker(self):\n        # close slowest worker,\n        # give chance for better worker\n        while True:\n            slowest_score = 9999\n            slowest_worker = None\n            idle_num = 0\n            for worker in self.workers:\n                if not worker.accept_task:\n                    continue\n\n                if worker.version == \"2\" and len(worker.streams) > 0:\n                    continue\n\n                score = worker.get_score()\n                if score < 1000:\n                    idle_num += 1\n\n                if score > slowest_score:\n                    slowest_score = score\n                    slowest_worker = worker\n\n            if idle_num < self.config.dispather_max_idle_workers or \\\n                    idle_num < int(len(self.workers) * 0.3) or \\\n                    len(self.workers) < self.config.dispather_min_workers:\n                return\n\n            if slowest_worker is None:\n                return\n\n            self.logger.debug(\"remove_slowest_worker remove %s\", slowest_worker.ip_str)\n            self.close_cb(slowest_worker)\n\n    def request(self, method, host, path, headers, body, url=b\"\", timeout=60):\n        method = utils.to_bytes(method)\n        host = utils.to_bytes(host)\n        path = utils.to_bytes(path)\n        headers = utils.to_bytes(headers)\n        body = utils.to_bytes(body)\n\n        if self.task_count > self.config.max_task_num:\n            self.logger.warn(\"task num exceed\")\n            time.sleep(1)\n            return None\n\n        with self.task_count_lock:\n            self.task_count += 1\n\n        self.last_host = host\n\n        try:\n            if not url:\n                url = b\"%s %s%s\" % (method, host, path)\n\n            self._debug_log(\"task start request %s\" % url)\n\n            self.last_request_time = time.time()\n            q = Queue()\n            task = http_common.Task(self.logger, self.config, method, host, path, headers, body, q, url, timeout)\n            task.set_state(\"start_request\")\n            self.request_queue.put(task)\n\n            try:\n                response = q.get(timeout=timeout)\n            except:\n                response = None\n\n            if response and response.status == 200:\n                self.success_num += 1\n                self.continue_fail_num = 0\n                task.worker.continue_fail_tasks = 0\n            else:\n                if not response:\n                    self.logger.warn(\"task %s %s %s timeout\", method, host, path)\n                else:\n                    self.logger.warn(\"task %s %s %s status:%d\", method, host, path, response.status)\n\n                self.fail_num += 1\n                self.continue_fail_num += 1\n                self.last_fail_time = time.time()\n                if task.worker:\n                    task.worker.continue_fail_tasks += 1\n                    if task.worker.continue_fail_tasks > self.config.dispather_worker_max_continue_fail:\n                        self.trigger_create_worker_cv.notify()\n                else:\n                    self.trigger_create_worker_cv.notify()\n\n            task.set_state(\"get_response\")\n            return response\n        except Exception as e:\n            self.logger.exception(\"http_dispatcher:request:%r\", e)\n        finally:\n            with self.task_count_lock:\n                self.task_count -= 1\n\n    def set_session_host(self, host):\n        self.session_host = host\n\n    def retry_task_cb(self, task, reason=\"\"):\n        self.fail_num += 1\n        self.continue_fail_num += 1\n        self.last_fail_time = time.time()\n        self.logger.warn(\"retry_task_cb: %s, trace:%s\", task.url, task.get_trace())\n\n        if task.responsed:\n            self.logger.warn(\"retry but responses. %s\", task.url)\n            # st = traceback.extract_stack()\n            # stl = traceback.format_list(st)\n            # self.logger.warn(\"stack:%r\", repr(stl))\n            task.finish()\n            return\n\n        if task.retry_count > 10:\n            task.response_fail(\"retry time exceed 10\")\n            return\n\n        if time.time() - task.start_time > task.timeout:\n            task.response_fail(\"retry timeout:%d\" % (time.time() - task.start_time))\n            return\n\n        if not self.running:\n            task.response_fail(\"retry but stopped.\")\n            return\n\n        task.set_state(\"retry(%s)\" % reason)\n        task.retry_count += 1\n        self.request_queue.put(task)\n\n    def dispatcher(self):\n        while self.running:\n            start_time = time.time()\n            try:\n                task = self.request_queue.get()\n            except:\n                task = None\n\n            if task is None:\n                # exit\n                break\n\n            get_time = time.time()\n            get_cost = get_time - start_time\n\n            task.set_state(\"get_task(%d)\" % get_cost)\n            try:\n                worker = self.get_worker()\n            except Exception as e:\n                self.logger.warn(\"get worker fail:%r\", e)\n                task.response_fail(reason=\"get worker fail:%r\" % e)\n                continue\n\n            if worker is None:\n                # can send because exit.\n                self.logger.warn(\"http_dispatcher get None worker\")\n                task.response_fail(\"get worker fail.\")\n                continue\n\n            get_worker_time = time.time()\n            get_cost = get_worker_time - get_time\n            self.ping_speed_ip_str_last_active[worker.ip_str] = get_worker_time\n            task.set_state(\"get_worker(%d):%s, score:%f\" % (get_cost, worker.ip_str, worker.get_score()))\n            task.worker = worker\n            task.predict_rtt = worker.get_score()\n            worker.last_request_time = get_worker_time\n            try:\n                worker.request(task)\n            except Exception as e:\n                self.logger.exception(\"dispatch request:%r\", e)\n\n        # wait up threads to exit.\n        self.wait_a_worker_cv.notify()\n        self.trigger_create_worker_cv.notify()\n\n    def connection_checker(self):\n        while self.running:\n            now = time.time()\n            try:\n                for worker in list(self.workers):\n                    if not worker.keep_running:\n                        continue\n\n                    if worker.is_life_end():\n                        worker.close(\"life end\")\n                        continue\n\n                    if now - worker.last_request_time > self.config.dispather_worker_idle_time and \\\n                            len(self.workers) > self.config.dispather_min_workers:\n                        worker.close(\"idle too long\")\n                        continue\n\n                    last_active_time = self.ping_speed_ip_str_last_active.get(worker.ip_str, 0)\n                    if now - last_active_time > self.config.dispather_ping_check_speed_interval and \\\n                        self.last_get_score_time > last_active_time:\n\n                        self.ping_speed(worker, self.config.dispather_ping_rtt_download_size)\n                        self.ping_speed(worker, self.config.dispather_ping_speed_download_size)\n                        self.ping_speed_ip_str_last_active[worker.ip_str] = time.time()\n                        continue\n\n                    if worker.version == \"2\":\n                        if len(worker.streams):\n                            continue\n\n                        if now - worker.last_send_time > self.config.http2_idle_ping_min_interval:\n                            worker.send_ping()\n\n            except Exception as e:\n                self.logger.exception(\"check worker except:%r\", e)\n\n            time.sleep(5)\n\n    def is_idle(self):\n        return time.time() - self.last_request_time > self.idle_time\n\n    def close_cb(self, worker):\n        try:\n            self.workers.remove(worker)\n            if worker.version == \"2\":\n                self.h2_num -= 1\n            else:\n                self.h1_num -= 1\n        except:\n            pass\n\n    def close_all_worker(self, reason=\"close all worker\"):\n        for w in list(self.workers):\n            if w.accept_task:\n                w.close(reason)\n\n        self.workers = []\n        self.h1_num = 0\n        self.h2_num = 0\n\n    def log_debug_data(self, rtt, sent, received):\n        self.rtts.append(rtt)\n        if len(self.rtts) > 30:\n            self.rtts.pop(0)\n        self.total_sent += sent\n        self.total_received += received\n\n    def statistic(self):\n        now = time.time()\n        if now > self.last_statistic_time + 60:\n            rtt = 0\n            sent = 0\n            received = 0\n            for stat in self.second_stats:\n                rtt = max(rtt, stat[\"rtt\"])\n                sent += stat[\"sent\"]\n                received += stat[\"received\"]\n            self.minute_stat = {\n                \"rtt\": rtt,\n                \"sent\": sent,\n                \"received\": received\n            }\n            self.second_stats = queue.deque()\n            self.last_statistic_time = now\n\n        if len(self.rtts):\n            rtt = max(self.rtts)\n        else:\n            rtt = 0\n\n        self.second_stat = {\n            \"rtt\": rtt,\n            \"sent\": self.total_sent - self.last_sent,\n            \"received\": self.total_received - self.last_received\n        }\n        self.last_sent = self.total_sent\n        self.last_received = self.total_received\n        self.second_stats.append(self.second_stat)\n\n    def worker_num(self):\n        return len(self.workers)\n\n    def get_score(self):\n        if self.task_count >= self.config.max_task_num:\n            return None\n\n        now = time.time()\n        self.last_get_score_time = now\n        if now - self.last_fail_time < 10 and self.continue_fail_num > 10:\n            return None\n\n        worker = self.get_worker(nowait=True)\n        if not worker:\n            self.start_connect_all_ips()\n            return None\n\n        return worker.get_score() * self.config.dispather_score_factor\n\n    def to_string(self):\n        out_str = 'thread num:%d\\r\\n' % threading.active_count()\n        out_str += \"\\r\\n working_tasks:\\r\\n\"\n        for unique_id in self.working_tasks:\n            task = self.working_tasks[unique_id]\n            out_str += task.to_string()\n\n        return out_str\n"
  },
  {
    "path": "code/default/lib/noarch/front_base/ip_manager.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\nimport json\nfrom six.moves import queue\nimport operator\nimport os\nimport threading\nimport time\nimport random\n\nimport six\n\nimport utils\n\n\nclass IpManagerBase():\n    def __init__(self, config, ip_source, logger, speed_fn=None):\n        self.scan_thread_lock = threading.Lock()\n        self.ip_lock = threading.Lock()\n\n        self.config = config\n        self.ip_source = ip_source\n        self.logger = logger\n        self.ips = []\n\n        self.ip_str_states = {}  # will not save state to disk\n\n        self.speed_fn = speed_fn\n        self.ip_str_info = self.load_ip_str_info()  # will save info to disk.\n        self.ip_str_info_last_save_time = time.time()\n        self.default_info = {\n                \"score\": self.config.ip_initial_score,\n                \"rtt\": self.config.ip_initial_rtt,\n                \"speed\": self.config.ip_initial_speed\n            }\n\n    def __str__(self):\n        o = \"\"\n        o += \" ip_str_info: \\r\\n%s\\r\\n\" % json.dumps(self.ip_str_info, indent=2)\n        o += \" ip_str_states: \\r\\n%s\\r\\n\" % json.dumps(self.ip_str_states, indent=2)\n        return o\n\n    def load_ip_str_info(self):\n        if not self.speed_fn or not os.path.isfile(self.speed_fn):\n            return {}\n\n        try:\n            with open(self.speed_fn, \"r\") as fd:\n                ip_str_info = json.load(fd)\n\n            for ip_str, info in ip_str_info.items():\n                if \"rtt\" not in info:\n                    return {}\n            return ip_str_info\n        except Exception as e:\n            self.logger.exception(\"load speed info %s failed:%r\", self.speed_fn, e)\n            return {}\n\n    def save_ip_str_info(self):\n        if not self.speed_fn:\n            return\n\n        try:\n            with open(self.speed_fn, \"w\") as fd:\n                json.dump(self.ip_str_info, fd, indent=2)\n        except Exception as e:\n            self.logger.exception(\"save speed info %s fail:%r\", self.speed_fn, e)\n\n    def _get_state(self, ip_str):\n        state = self.ip_str_states.setdefault(ip_str, {\n            \"traffic_cost_history\":[],\n            \"traffic_history\":[],\n            \"speed_history\": [],\n            \"score_history\": [],\n            \"rtt_history\": [],\n            \"last_use\": time.time()\n        })\n        return state\n\n    def _get_info(self, ip_str):\n        if ip_str not in self.ip_str_info:\n            self.ip_str_info[ip_str] = dict(self.default_info)\n        return self.ip_str_info[ip_str]\n\n    def report_traffic_timecost(self, ip_str, timecost, traffic):\n        state = self._get_state(ip_str)\n        state[\"last_use\"] = time.time()\n\n        if traffic < self.config.ip_cal_rtt_max_package_size:\n            state[\"rtt_history\"].append(timecost)\n            if len(state[\"rtt_history\"]) > self.config.http_query_history_size:\n                state[\"rtt_history\"].pop(0)\n                # self.logger.debug(\"update speed %s %d\", ip_str, ip_info[\"speed\"])\n\n        info = self._get_info(ip_str)\n        if len(state[\"rtt_history\"]):\n            min_rtt = min(state[\"rtt_history\"])\n            mean_rtt = sum(state[\"rtt_history\"]) / len(state[\"rtt_history\"])\n        else:\n            min_rtt = min(info[\"rtt\"], timecost)\n            mean_rtt = min_rtt\n\n        info[\"rtt\"] = min_rtt\n\n        if traffic > self.config.ip_cal_speed_min_package_size:\n            traffic_cost = timecost - min_rtt\n            state[\"traffic_cost_history\"].append(traffic_cost)\n            if len(state[\"traffic_cost_history\"]) > self.config.http_query_history_size:\n                state[\"traffic_cost_history\"].pop(0)\n\n            state[\"traffic_history\"].append(traffic)\n            if len(state[\"traffic_history\"]) > self.config.http_query_history_size:\n                state[\"traffic_history\"].pop(0)\n\n        last_speed = info[\"speed\"]\n        virtual_traffic_cost = self.config.ip_cal_expect_time_package_size / last_speed\n        all_traffic = sum(state[\"traffic_history\"]) + self.config.ip_cal_expect_time_package_size\n        all_traffic_cost = sum(state[\"traffic_cost_history\"]) + virtual_traffic_cost\n        speed = all_traffic / all_traffic_cost\n        info[\"speed\"] = speed\n\n        state[\"speed_history\"].append(speed)\n        if len(state[\"speed_history\"]) > self.config.http_query_history_size:\n            state[\"speed_history\"].pop(0)\n\n        if time.time() - self.ip_str_info_last_save_time > self.config.ip_speed_save_interval:\n            self.save_ip_str_info()\n            self.ip_str_info_last_save_time = time.time()\n\n        if self.config.show_state_debug:\n            self.logger.debug(\"report_traffic_timecost %s cost:%f traffic:%d mean_rtt:%f speed:%d\", ip_str, timecost, traffic, mean_rtt, speed)\n\n        return mean_rtt, speed\n\n    def update_score(self, ip_str, score):\n        state = self._get_state(ip_str)\n\n        info = self._get_info(ip_str)\n        info[\"score\"] = score\n\n        state[\"score_history\"].append(score)\n        if len(state[\"score_history\"]) > self.config.http_query_history_size:\n            state[\"score_history\"].pop(0)\n\n    def get_score(self, ip_str):\n        info = self._get_info(ip_str)\n        return info[\"score\"]\n\n    def get_speed(self, ip_str):\n        info = self._get_info(ip_str)\n        return info[\"speed\"], info[\"rtt\"]\n\n    def load_config(self):\n        pass\n\n    def set_ips(self, ips):\n        self.ips = ips\n\n    def get_ip(self):\n        if not self.ips:\n            return \"\"\n        return random.choice(self.ips)\n\n    def update_ip(self, ip_str, sni, handshake_time):\n        pass\n\n    def report_connect_fail(self, ip_str, sni=None, reason=\"\", force_remove=True):\n        # Report a connection failed.\n        pass\n\n    def report_connect_closed(self, ip_str, sni=None, reason=\"\"):\n        # report on connection timeout of keep alive, or http close(life end/idle timeout)\n        # Reason: alive_timeout, get_ssl_timeout, %from worker.close(reason):\n        #   HTTP1: __del__, read fail, down fail, send fail, recv fail, life_end:xxx, inactive timeout, keep alive,\n        #    idle timeout, exit\n        #   HTTP2: status, RESET, bad max frame size, GoAway, ConnectionReset, recv.timeout, recv.error, life end,\n        #    recv fail, send fail\n        pass\n\n    def ssl_closed(self, ip_str, sni=None, reason=\"\"):\n        if self.config.show_state_debug:\n            self.logger.debug(\"ip_str:%s sni:%s ssl_closed:%s\", ip_str, sni, reason)\n\n    def recheck_ip(self, ip_str):\n        pass\n\n\n######################################\n# about ip connect time and handshake time\n# handshake time is double of connect time in common case.\n# after connect and handshaked, http get time is like connect time\n#\n# connect time is zero if you use socks proxy.\n#\n# most case, connect time is 300ms - 600ms.\n# good case is 60ms\n# bad case is 1300ms and more.\n\nclass IpManager(IpManagerBase):\n    # Functions:\n    # 1. Scan ip in back ground\n    # 2. sort ip by RTT and fail times\n    #     RTT + fail_times * 1000\n    # 3. count ip connection number\n    #    keep max one link every ip.\n    #    more link may be block by GFW if large traffic on some ip.\n    # 4. scan all exist ip\n    #    stop scan ip thread then start 10 threads to scan all exist ip.\n    #    called by web_control.\n\n    def __init__(self, logger, config, ip_source, host_manager, check_local_network, check_ip,\n                 default_ip_list_fn, ip_list_fn, scan_ip_log=None):\n        super().__init__(config, ip_source, logger)\n        self.host_manager = host_manager\n        self.check_local_network = check_local_network\n        self.check_ip = check_ip\n        self.scan_ip_log = scan_ip_log\n\n        self.default_ip_list_fn = default_ip_list_fn\n        self.ip_list_fn = ip_list_fn\n\n        self.scan_thread_lock = threading.Lock()\n        self.ip_lock = threading.Lock()\n        self.reset()\n\n        self.check_ip_thread = threading.Thread(target=self.check_ip_process, name=\"%s_ip_manager_check_ip\" % self.logger.name)\n        self.check_ip_thread.daemon = True\n        self.check_ip_thread.start()\n\n        if config.check_exist_ip_on_startup:\n            self.scan_all_exist_ip()\n\n    def reset(self):\n        self.ip_lock.acquire()\n        self.ip_pointer = 0\n        self.ip_pointer_reset_time = 0\n        self.scan_thread_count = 0\n        self.scan_fail_count = 0\n        self.scan_recheck_interval = 3\n        self.iplist_need_save = False\n        self.iplist_saved_time = 0\n        self.last_sort_time = 0  # keep status for avoid wast too many cpu\n        self.good_ip_num = 0  # only success ip num\n        self.good_ipv4_num = 0\n        self.good_ipv6_num = 0\n        self.running = True\n\n        # ip_str => {\n        # 'handshake_time'=>?ms,\n        # 'links' => current link number, limit max to 1\n        # 'fail_times' => N   continue timeout num, if connect success, reset to 0\n        # 'fail_time' => time.time(),  last fail time, next time retry will need more time.\n        # 'transfered_data' => X bytes\n        # 'down_fail' => times of fails when download content data\n        # 'down_fail_time'\n        # 'data_active' => transfered_data - n second, for select\n        # 'get_time' => ip used time.\n        # 'last_active' => ip close time.\n        # 'success_time' => last connect success time.\n        # 'domain'=>CN,\n        # 'server'=>gws/gvs?,\n        # history=>[[time,status], []]\n        # }\n\n        # ip_str can be ip or ip:port stirng.\n\n        self.ip_dict = {}\n\n        # gererate from ip_dict, sort by handshake_time, when get_batch_ip\n        self.ip_list = []\n        self.to_check_ip_queue = queue.Queue()\n        self.scan_exist_ip_queue = queue.Queue()\n        self.ip_lock.release()\n\n        self.load_config()\n        self.load_ip()\n\n        # if check_local_network.network_stat == \"OK\" and not config.USE_IPV6:\n        #    self.start_scan_all_exist_ip()\n        self.search_more_ip()\n\n    def is_ip_enough(self):\n        if len(self.ip_list) >= self.max_good_ip_num:\n            return True\n        else:\n            return False\n\n    def load_config(self):\n        self.scan_ip_thread_num = self.config.max_scan_ip_thread_num\n        self.max_links_per_ip = self.config.max_links_per_ip\n        self.max_good_ip_num = self.config.max_good_ip_num  # 3000  # stop scan ip when enough\n        self.auto_adjust_scan_ip_pointer = int(30 + self.max_good_ip_num * 0.1)\n        self.ip_connect_interval = self.config.ip_connect_interval  # 5,10\n        self.record_ip_history = self.config.record_ip_history\n\n    def load_ip(self):\n        for file_path in [self.ip_list_fn, self.default_ip_list_fn]:\n            if not file_path or not os.path.isfile(file_path):\n                continue\n\n            with open(file_path, \"r\") as fd:\n                lines = fd.readlines()\n\n            if not lines:\n                continue\n\n            for line in lines:\n                try:\n                    if line.startswith(\"#\"):\n                        continue\n\n                    str_l = line.split(' ')\n\n                    if len(str_l) < 4:\n                        self.logger.warning(\"line err: %s\", line)\n                        continue\n                    ip_str = str_l[0]\n                    domain = str_l[1]\n                    server = str_l[2]\n                    if file_path == self.default_ip_list_fn and self.config.shuffle_ip_on_first_load:\n                        handshake_time = random.randint(500, 800)\n                    else:\n                        handshake_time = int(str_l[3])\n                    if len(str_l) > 4:\n                        fail_times = int(str_l[4])\n                    else:\n                        fail_times = 0\n\n                    if len(str_l) > 5:\n                        down_fail = int(str_l[5])\n                    else:\n                        down_fail = 0\n\n                    # self.logger.info(\"load ip: %s time:%d domain:%s server:%s\", ip, handshake_time, domain, server)\n                    self.add_ip(ip_str, handshake_time, domain, server, fail_times, down_fail, False)\n                except Exception as e:\n                    self.logger.exception(\"load_ip line:%s err:%s\", line, e)\n\n            self.logger.info(\"load ip_list %s num:%d, target num:%d\", file_path, len(self.ip_dict), len(self.ip_list))\n            if file_path == self.default_ip_list_fn and self.config.shuffle_ip_on_first_load:\n                # self.logger.debug(\"first load, shuffle all ip\")\n                random.shuffle(self.ip_list)\n                # self.logger.debug(\"ip:%s\",self.ip_list)\n            else:\n                self.try_sort_ip(force=True)\n\n            return\n\n    def save(self, force=False):\n        if not force:\n            if not self.iplist_need_save:\n                return\n            if time.time() - self.iplist_saved_time < 10:\n                return\n\n        self.iplist_saved_time = time.time()\n\n        try:\n            self.ip_lock.acquire()\n            ip_dict = sorted(list(self.ip_dict.items()),\n                             key=lambda x: (x[1]['handshake_time'] + x[1]['fail_times'] * 1000))\n            with open(self.ip_list_fn, \"w\") as fd:\n                for ip_str, property in ip_dict:\n                    fd.write(\"%s %s %s %d %d %d\\n\" %\n                             (ip_str, property['domain'],\n                              property['server'],\n                              property['handshake_time'],\n                              property['fail_times'],\n                              property['down_fail']))\n                fd.flush()\n\n            self.iplist_need_save = False\n        except Exception as e:\n            self.logger.error(\"save %s fail %s\", self.ip_list_fn, e)\n        finally:\n            self.ip_lock.release()\n\n    def _ip_rate(self, ip_info):\n        return ip_info['handshake_time'] + \\\n               (ip_info['fail_times'] * 500) + \\\n               (ip_info['down_fail'] * 500)\n\n    def _add_ip_num(self, ip_str, num):\n        if \".\" in ip_str:\n            self.good_ipv4_num += num\n        else:\n            self.good_ipv6_num += num\n        self.good_ip_num += num\n\n    def try_sort_ip(self, force=False):\n        if time.time() - self.last_sort_time < 10 and not force:\n            return\n\n        self.ip_lock.acquire()\n        self.last_sort_time = time.time()\n        try:\n            self.good_ip_num = 0\n            self.good_ipv4_num = 0\n            self.good_ipv6_num = 0\n            ip_rate = {}\n            for ip_str in self.ip_dict:\n                if \".\" in ip_str and self.config.use_ipv6 == \"force_ipv6\":\n                    continue\n\n                if not \".\" in ip_str and self.config.use_ipv6 == \"force_ipv4\":\n                    continue\n\n                if 'gws' not in self.ip_dict[ip_str]['server']:\n                    continue\n                ip_rate[ip_str] = self._ip_rate(self.ip_dict[ip_str])\n                if self.ip_dict[ip_str]['fail_times'] == 0:\n                    self._add_ip_num(ip_str, 1)\n\n            ip_time = sorted(list(ip_rate.items()), key=operator.itemgetter(1))\n            self.ip_list = [ip_str for ip_str, rate in ip_time]\n\n        except Exception as e:\n            self.logger.error(\"try_sort_ip_by_handshake_time:%s\", e)\n        finally:\n            self.ip_lock.release()\n\n        time_cost = ((time.time() - self.last_sort_time) * 1000)\n        if time_cost > 30:\n            self.logger.debug(\"sort ip time:%dms\", time_cost)  # 5ms for 1000 ip. 70~150ms for 30000 ip.\n\n        self.adjust_scan_thread_num()\n\n    def adjust_scan_thread_num(self):\n        ip_num = len(self.ip_list)\n        min_scan_ip_thread_num = 1 if self.config.max_scan_ip_thread_num else 0\n\n        if not self.config.auto_adjust_scan_ip_thread_num:\n            scan_ip_thread_num = self.config.max_scan_ip_thread_num\n        elif ip_num < self.max_good_ip_num:\n            scan_ip_thread_num = int(self.config.max_scan_ip_thread_num * (1.5 - ip_num / self.max_good_ip_num))\n        else:\n            try:\n                if ip_num > self.auto_adjust_scan_ip_pointer:\n                    last_ip = self.ip_list[self.auto_adjust_scan_ip_pointer]\n                else:\n                    last_ip = self.ip_list[-1]\n\n                last_ip_handshake_time = self._ip_rate(self.ip_dict[last_ip])\n                scan_ip_thread_num = int((last_ip_handshake_time - self.config.target_handshake_time) / 2 * \\\n                                         self.config.max_scan_ip_thread_num / 50 * \\\n                                         self.max_good_ip_num / max(self.good_ip_num, 1))\n            except Exception as e:\n                self.logger.warn(\"adjust_scan_thread_num fail:%r\", e)\n                return\n\n        if scan_ip_thread_num > self.config.max_scan_ip_thread_num:\n            scan_ip_thread_num = self.config.max_scan_ip_thread_num\n        elif scan_ip_thread_num < min_scan_ip_thread_num:\n            scan_ip_thread_num = min_scan_ip_thread_num\n\n        if scan_ip_thread_num > self.config.max_scan_ip_thread_num:\n            return\n\n        if scan_ip_thread_num != self.scan_ip_thread_num:\n            self.logger.info(\"Adjust scan thread num from %d to %d\", self.scan_ip_thread_num, scan_ip_thread_num)\n            self.scan_ip_thread_num = scan_ip_thread_num\n            self.search_more_ip()\n\n    def ip_quality(self, num=10):\n        try:\n            iplist_length = len(self.ip_list)\n            ip_th = min(num, iplist_length)\n            for i in range(ip_th, 0, -1):\n                last_ip = self.ip_list[i]\n                if self.ip_dict[last_ip]['fail_times'] > 0:\n                    continue\n                handshake_time = self.ip_dict[last_ip]['handshake_time']\n                return handshake_time\n\n            return 9999\n        except:\n            return 9999\n\n    def append_ip_history(self, ip_str, info):\n        if self.record_ip_history:\n            self.ip_dict[ip_str]['history'].append([time.time(), info])\n\n    # algorithm to get ip:\n    # scan start from fastest ip\n    # always use the fastest ip.\n    # if the ip is used in 5 seconds, try next ip;\n    # if the ip is fail in 60 seconds, try next ip;\n    # reset pointer to front every 3 seconds\n    def get_ip_sni_host(self, to_recheck=False):\n        if not to_recheck:\n            self.try_sort_ip()\n\n        self.ip_lock.acquire()\n        try:\n            ip_num = len(self.ip_list)\n            if ip_num == 0:\n                # self.logger.warning(\"no ip\")\n                time.sleep(5)\n                return None\n\n            ip_connect_interval = ip_num * self.scan_recheck_interval + 200 if to_recheck else self.ip_connect_interval\n\n            for i in range(ip_num):\n                time_now = time.time()\n                if self.ip_pointer >= ip_num:\n                    if time_now - self.ip_pointer_reset_time < 1:\n                        time.sleep(1)\n                        continue\n                    else:\n                        self.ip_pointer = 0\n                        self.ip_pointer_reset_time = time_now\n                elif self.ip_pointer > 0 and time_now - self.ip_pointer_reset_time > 3:\n                    self.ip_pointer = 0\n                    self.ip_pointer_reset_time = time_now\n\n                ip_str = self.ip_list[self.ip_pointer]\n                if \".\" in ip_str and self.config.use_ipv6 == \"force_ipv6\":\n                    continue\n\n                if not \".\" in ip_str and self.config.use_ipv6 == \"force_ipv4\":\n                    continue\n\n                get_time = self.ip_dict[ip_str][\"get_time\"]\n                if time_now - get_time < ip_connect_interval:\n                    self.ip_pointer += 1\n                    continue\n\n                if not to_recheck:\n                    if time_now - self.ip_dict[ip_str]['success_time'] > self.config.long_fail_threshold:  # 5 min\n                        fail_connect_interval = self.config.long_fail_connect_interval  # 180\n                    else:\n                        fail_connect_interval = self.config.short_fail_connect_interval  # 10\n                    fail_time = self.ip_dict[ip_str][\"fail_time\"]\n                    if time_now - fail_time < fail_connect_interval:\n                        self.ip_pointer += 1\n                        continue\n\n                    down_fail_time = self.ip_dict[ip_str][\"down_fail_time\"]\n                    if time_now - down_fail_time < self.config.down_fail_connect_interval:\n                        self.ip_pointer += 1\n                        continue\n\n                    last_active = self.ip_dict[ip_str][\"last_active\"]\n                    if time_now - last_active < self.config.active_connect_interval:\n                        self.ip_pointer += 1\n                        continue\n\n                if self.ip_dict[ip_str]['links'] >= self.max_links_per_ip:\n                    self.ip_pointer += 1\n                    continue\n\n                # self.logger.debug(\"get ip:%s t:%d\", ip, self.ip_dict[ip_str][\"handshake_time\"])\n                self.append_ip_history(ip_str, \"get\")\n                self.ip_dict[ip_str]['get_time'] = time_now\n                if not to_recheck:\n                    self.ip_dict[ip_str]['links'] += 1\n                self.ip_pointer += 1\n\n                sni, host = self.host_manager.get_sni_host(ip_str)\n                return {\n                    \"ip_str\": ip_str,\n                    \"sni\": sni,\n                    \"host\": host,\n                }\n        except Exception as e:\n            self.logger.exception(\"get_ip fail:%r\", e)\n        finally:\n            self.ip_lock.release()\n\n        return None\n\n    def add_ip(self, ip_str, handshake_time=100, domain=None, server='gws', fail_times=0, down_fail=0,\n               scan_result=True):\n        if not isinstance(ip_str, six.string_types):\n            self.logger.error(\"add_ip input [%s] %s\", type(ip_str), ip_str)\n            return\n\n        time_now = time.time()\n        if scan_result:\n            self.check_local_network.report_ok(ip_str)\n            success_time = time_now\n        else:\n            success_time = 0\n\n        ip_str = str(ip_str)\n\n        handshake_time = int(handshake_time)\n\n        self.ip_lock.acquire()\n        try:\n            if ip_str in self.ip_dict:\n                self.ip_dict[ip_str]['success_time'] = success_time\n                self.ip_dict[ip_str]['handshake_time'] = handshake_time\n                self.ip_dict[ip_str]['fail_times'] = fail_times\n                if self.ip_dict[ip_str]['fail_time'] > 0:\n                    self.ip_dict[ip_str]['fail_time'] = 0\n                    self._add_ip_num(ip_str, 1)\n                self.append_ip_history(ip_str, handshake_time)\n                return False\n\n            self.iplist_need_save = True\n            self._add_ip_num(ip_str, 1)\n\n            self.ip_dict[ip_str] = {'handshake_time': handshake_time,\n                                    \"fail_times\": fail_times,\n                                    \"transfered_data\": 0,\n                                    'data_active': 0,\n                                    'domain': domain,\n                                    'server': server,\n                                    \"history\": [[time_now, handshake_time]],\n                                    \"fail_time\": 0,\n                                    \"success_time\": success_time,\n                                    \"get_time\": 0,\n                                    \"links\": 0,\n                                    \"down_fail\": down_fail,\n                                    \"down_fail_time\": 0,\n                                    \"last_active\": 0,\n                                    }\n\n            if 'gws' not in server:\n                return\n\n            self.ip_list.append(ip_str)\n        except Exception as e:\n            self.logger.exception(\"add_ip err:%s\", e)\n        finally:\n            self.ip_lock.release()\n\n        return True\n\n    def update_ip(self, ip_str, sni, handshake_time):\n        if not isinstance(ip_str, str):\n            self.logger.error(\"update_ip input error:%s %s\", ip_str, sni)\n            return\n\n        handshake_time = int(handshake_time)\n        if handshake_time < 5:  # that's impossible\n            self.logger.warn(\"%s handshake:%d impossible\", ip_str, 1000 * handshake_time)\n            return\n\n        time_now = time.time()\n        self.check_local_network.report_ok(ip_str)\n\n        self.ip_lock.acquire()\n        try:\n            if ip_str in self.ip_dict:\n\n                # Case: some good ip, average handshake time is 300ms\n                # some times ip package lost cause handshake time become 2000ms\n                # this ip will not return back to good ip front until all become bad\n                # There for, prevent handshake time increase too quickly.\n                org_time = self.ip_dict[ip_str]['handshake_time']\n                if handshake_time - org_time > 500:\n                    self.ip_dict[ip_str]['handshake_time'] = org_time + 500\n                else:\n                    self.ip_dict[ip_str]['handshake_time'] = handshake_time\n\n                self.ip_dict[ip_str]['success_time'] = time_now\n                if self.ip_dict[ip_str]['fail_times'] > 0:\n                    self._add_ip_num(ip_str, 1)\n                self.ip_dict[ip_str]['fail_times'] = 0\n                self.append_ip_history(ip_str, handshake_time)\n                self.ip_dict[ip_str][\"fail_time\"] = 0\n\n                self.iplist_need_save = True\n\n            # self.logger.debug(\"update ip:%s not exist\", ip)\n        except Exception as e:\n            self.logger.error(\"update_ip err:%s\", e)\n        finally:\n            self.ip_lock.release()\n\n        self.save()\n\n    def report_connect_fail(self, ip_str, sni=None, reason=\"\", force_remove=False):\n        self.ip_lock.acquire()\n        try:\n            time_now = time.time()\n            ip, _ = utils.get_ip_port(ip_str)\n            ip = utils.to_str(ip)\n            if not ip in self.ip_dict:\n                self.logger.debug(\"report_connect_fail %s not exist\", ip)\n                return\n\n            if force_remove:\n                if self.ip_dict[ip]['fail_times'] == 0:\n                    self._add_ip_num(ip, -1)\n                del self.ip_dict[ip]\n\n                if ip in self.ip_list:\n                    self.ip_list.remove(ip)\n\n                self.logger.info(\"remove ip:%s left amount:%d target_num:%d\", ip, len(self.ip_dict),\n                                 len(self.ip_list))\n                return\n\n            if self.ip_dict[ip]['links'] > 0:\n                self.ip_dict[ip]['links'] -= 1\n\n            self.check_local_network.report_fail(ip)\n            # ignore if system network is disconnected.\n            if not self.check_local_network.is_ok(ip):\n                self.logger.debug(\"report_connect_fail network fail\")\n                return\n\n            fail_time = self.ip_dict[ip][\"fail_time\"]\n            if time_now - fail_time < 1:\n                self.logger.debug(\"fail time too near %s\", ip)\n                return\n\n            if self.ip_dict[ip]['fail_times'] == 0:\n                self._add_ip_num(ip, -1)\n            self.ip_dict[ip]['fail_times'] += 1\n            self.append_ip_history(ip, \"fail\")\n            self.ip_dict[ip][\"fail_time\"] = time_now\n\n            # self.to_check_ip_queue.put((ip, time_now + 10))\n            self.logger.debug(\"report_connect_fail:%s\", ip)\n\n        except Exception as e:\n            self.logger.exception(\"report_connect_fail %s err:%s\", ip_str, e)\n        finally:\n            self.iplist_need_save = True\n            self.ip_lock.release()\n\n        if not self.is_ip_enough():\n            self.search_more_ip()\n\n    def report_connect_closed(self, ip_str, sni=None, reason=\"\"):\n        # if reason not in [\"idle timeout\"]:\n        # self.logger.debug(\"%s close:%s\", ip, reason)\n        self.ip_lock.acquire()\n        try:\n            ip, _ = utils.get_ip_port(ip_str)\n            ip = utils.to_str(ip)\n            if ip not in self.ip_dict:\n                self.logger.debug(\"report_connect_closed %s not exist\", ip)\n                return\n\n            time_now = time.time()\n\n            if reason not in [\"down fail\", ] and not reason.startswith(\"status \"):\n                self.ip_dict[ip][\"last_active\"] = time_now\n                return\n\n            if self.ip_dict[ip]['down_fail'] == 0:\n                self._add_ip_num(ip, -1)\n\n            self.ip_dict[ip]['down_fail'] += 1\n            self.append_ip_history(ip, reason)\n            self.ip_dict[ip][\"down_fail_time\"] = time_now\n            self.logger.debug(\"report_connect_closed %s, reason:%s\", ip, reason)\n        except Exception as e:\n            self.logger.error(\"report_connect_closed %s err:%s\", ip_str, e)\n        finally:\n            self.ip_lock.release()\n\n    def ssl_closed(self, ip_str, sni=None, reason=\"\"):\n        self.logger.debug(\"%s ssl_closed:%s\", ip_str, reason)\n        self.ip_lock.acquire()\n        try:\n            ip, _ = utils.get_ip_port(ip_str)\n            ip = utils.to_str(ip)\n            if ip not in self.ip_dict:\n                self.logger.debug(\"ssl_closed %s not exist\", ip)\n                return\n\n            self.append_ip_history(ip, \"C[%s]\" % reason)\n            # self.logger.debug(\"ssl_closed %s\", ip)\n        except Exception as e:\n            self.logger.error(\"ssl_closed %s err:%s\", ip_str, e)\n        finally:\n            self.ip_lock.release()\n\n    def check_ip_process(self):\n        while self.running:\n            try:\n                ip_str, test_time = self.to_check_ip_queue.get()\n            except Exception as e:\n                continue\n\n            time_wait = test_time - time.time()\n            if time_wait > 0:\n                time.sleep(time_wait)\n\n            if not self.check_local_network.is_ok(ip_str):\n                try:\n                    if self.ip_dict[ip_str]['fail_times']:\n                        self.ip_dict[ip_str]['fail_times'] = 0\n                        self._add_ip_num(ip_str, 1)\n                except:\n                    pass\n                continue\n\n            result = self.check_ip(ip_str)\n            if result and result.ok:\n                self.add_ip(ip_str, result.request_time, result.domain)\n                self.logger.debug(\"restore ip:%s\", ip_str)\n                continue\n\n            self.logger.debug(\"ip:%s real fail\", ip_str)\n\n    def remove_slowest_ip(self):\n        if len(self.ip_list) <= self.max_good_ip_num:\n            return\n\n        self.try_sort_ip(force=True)\n\n        self.ip_lock.acquire()\n        try:\n            ip_num = len(self.ip_list)\n            while ip_num > self.max_good_ip_num:\n\n                ip_str = self.ip_list[ip_num - 1]\n\n                property = self.ip_dict[ip_str]\n                fails = property['fail_times']\n                handshake_time = property['handshake_time']\n                self.logger.info(\"remove_slowest_ip:%s handshake_time:%d, fails:%d\", ip_str, handshake_time, fails)\n\n                if fails == 0:\n                    self._add_ip_num(ip_str, -1)\n                del self.ip_dict[ip_str]\n\n                if ip_str in self.ip_list:\n                    self.ip_list.remove(ip_str)\n\n                ip_num -= 1\n\n        except Exception as e:\n            self.logger.exception(\"remove_slowest_ip err:%s\", e)\n        finally:\n            self.ip_lock.release()\n\n    def recheck_ip(self, ip_str, first_report=True):\n        # recheck ip if not work.\n        # can block.\n        if not self.check_local_network.is_ok(ip_str):\n            self.logger.debug(\"recheck_ip:%s network is fail\", ip_str)\n            return\n\n        if first_report:\n            self.report_connect_fail(ip_str)\n\n        result = self.check_ip(ip_str)\n\n        if ip_str not in self.ip_dict:\n            # may deleted by other thread\n            return\n\n        if not result:\n            if first_report:\n                if self.ip_dict[ip_str]['fail_times'] <= 2:\n                    # connect max fail 3 times.\n                    # do nothing\n                    return\n                else:\n                    time.sleep(5)\n                    self.recheck_ip(ip_str)\n                    return\n\n        if not result or not result.ok:\n            self.report_connect_fail(ip_str, force_remove=True)\n            self.logger.debug(\"recheck_ip:%s real fail, removed.\", ip_str)\n        else:\n            self.add_ip(ip_str, result.request_time, result.domain)\n            self.logger.debug(\"recheck_ip:%s restore ok\", ip_str)\n\n    def scan_ip_worker(self):\n        recheck_ip = False\n        while self.scan_thread_count <= self.scan_ip_thread_num and self.running:\n            time.sleep(self.config.scan_ip_interval)\n            try:\n                # work for idle and too many scan failures\n                if (recheck_ip or\n                    self.scan_ip_thread_num == 1 and\n                    self.config.max_scan_ip_thread_num > 1) and \\\n                        self.check_local_network.is_ok():\n                    if self.good_ip_num >= self.max_good_ip_num * 0.6 and \\\n                            len(self.ip_list) >= self.max_good_ip_num * 0.9:\n                        host_info = self.get_ip_sni_host()\n                        ip_str = host_info[\"ip_str\"]\n                        if ip_str and self.check_local_network.is_ok(ip_str):\n                            self.recheck_ip(ip_str, first_report=False)\n                            time.sleep(self.scan_recheck_interval)\n                            continue\n                    else:\n                        self.adjust_scan_thread_num()\n            except Exception as e:\n                self.logger.exception(\"scan_ip_worker recheck ip except:%r\", e)\n            finally:\n                recheck_ip = False\n\n            try:\n                ip_str = self.ip_source.get_ip()\n                # self.logger.debug(\"check ip:%s\", ip)\n\n                if not ip_str or ip_str in self.ip_dict:\n                    time.sleep(5)\n                    continue\n\n                if not self.check_local_network.is_ok(ip_str):\n                    # self.logger.debug(\"scan_ip:%s network is fail\", ip)\n                    time.sleep(5)\n                result = self.check_ip(ip_str)\n\n                self.scan_thread_lock.acquire()\n                if result:\n                    self.scan_fail_count = 0\n                else:\n                    self.scan_fail_count += 1\n                    if self.scan_thread_count and self.scan_fail_count / self.scan_thread_count > 3:\n                        self.scan_fail_count = 0\n                        self.check_local_network.report_fail(ip_str)\n                        recheck_ip = True\n                self.scan_thread_lock.release()\n\n                if not result or not result.ok:\n                    continue\n\n                if self.add_ip(ip_str, result.request_time, result.domain):\n                    # self.logger.info(\"add  %s  CN:%s  type:%s  time:%d  target:%d \", ip,\n                    #     result.domain, result.server_type, result.handshake_time, len(self.ip_list))\n                    self.logger.info(\"scan_ip add ip:%s time:%d h2:%d\", ip_str, result.request_time, result.h2)\n                    if self.scan_ip_log:\n                        self.scan_ip_log.info(\"Add %s time:%d CN:%s \", ip_str, result.request_time, result.domain)\n                    self.remove_slowest_ip()\n                    self.save()\n            except Exception as e:\n                self.logger.exception(\"scan_ip_worker except:%r\", e)\n\n        self.scan_thread_lock.acquire()\n        self.scan_thread_count -= 1\n        self.scan_thread_lock.release()\n        # self.logger.info(\"scan_ip_worker exit\")\n\n    def search_more_ip(self):\n        if not self.ip_source:\n            return\n\n        if self.scan_ip_thread_num > self.config.max_scan_ip_thread_num:\n            self.scan_ip_thread_num = self.config.max_scan_ip_thread_num\n\n        new_thread_num = self.scan_ip_thread_num - self.scan_thread_count\n        if new_thread_num < 1:\n            return\n\n        for i in range(0, new_thread_num):\n            self.scan_thread_lock.acquire()\n            self.scan_thread_count += 1\n            self.scan_thread_lock.release()\n\n            p = threading.Thread(target=self.scan_ip_worker, name=\"%s_ip_manager_scan_ip\" % self.logger.name)\n            p.start()\n\n    def scan_all_exist_ip(self):\n        # stop all scan ip threads\n        self.scan_ip_thread_num = 0\n\n        for ip_str in self.ip_dict:\n            self.scan_exist_ip_queue.put(ip_str)\n        self.logger.debug(\"start scan all exist ip, num:%d\", self.scan_exist_ip_queue.qsize())\n\n        self.keep_scan_all_exist_ip = True\n        scan_threads = []\n        for i in range(0, 50):\n            th = threading.Thread(target=self.scan_exist_ip_worker,\n                                  name=\"%s_ip_manager_scan_exist_ip\" % self.logger.name)\n            th.start()\n            scan_threads.append(th)\n\n        for th in scan_threads:\n            th.join()\n\n        self.try_sort_ip()\n        self.logger.debug(\"finished scan all exist ip\")\n        self.save(force=True)\n\n        self.adjust_scan_thread_num()\n        self.scan_all_ip_thread = None\n\n    def start_scan_all_exist_ip(self):\n        if hasattr(self, \"scan_all_ip_thread\") and self.scan_all_ip_thread:\n            self.logger.warn(\"scan all exist ip is running\")\n            return\n\n        self.scan_all_ip_thread = threading.Thread(target=self.scan_all_exist_ip,\n                                                   name=\"%s_ip_manager_scan_all_exist_ip\" % self.logger.name)\n        self.scan_all_ip_thread.start()\n\n    def stop_scan_all_exist_ip(self):\n        self.keep_scan_all_exist_ip = False\n        self.scan_exist_ip_queue = queue.Queue()\n\n    def scan_exist_ip_worker(self):\n        while self.running and self.keep_scan_all_exist_ip:\n            try:\n                ip_str = self.scan_exist_ip_queue.get_nowait()\n            except:\n                break\n\n            result = self.check_ip(ip_str)\n            if not result:\n                self.ip_lock.acquire()\n                try:\n                    if ip_str not in self.ip_dict:\n                        continue\n\n                    if self.ip_dict[ip_str]['fail_times'] == 0:\n                        self._add_ip_num(ip_str, -1)\n                    self.ip_dict[ip_str]['fail_times'] += 1\n                    self.ip_dict[ip_str][\"fail_time\"] = time.time()\n                finally:\n                    self.ip_lock.release()\n            elif result.ok:\n                self.add_ip(ip_str, result.request_time, result.domain)\n            else:\n                self.report_connect_fail(ip_str, force_remove=True)\n\n    def clean_failed_ips(self):\n        to_remove = []\n        for ip_str in self.ip_dict:\n            dat = self.ip_dict[ip_str]\n            if dat[\"fail_times\"] > 0:\n                to_remove.append(ip_str)\n                self.logger.debug(\"ip_manager remove continue fail ip:%s\", ip_str)\n\n        for ip_str in to_remove:\n            del self.ip_dict[ip_str]\n\n        self.try_sort_ip(True)\n\n    def update_ips(self, ips, sni):\n        for ip_str in ips:\n            if ip_str not in self.ip_dict:\n                self.add_ip(ip_str, scan_result=False)\n\n        for ip_str in list(self.ip_dict.keys()):\n            if ip_str not in ips:\n                del self.ip_dict[ip_str]\n\n        self.try_sort_ip(True)\n\n    def stop(self):\n        self.running = False\n"
  },
  {
    "path": "code/default/lib/noarch/front_base/ip_source.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\nimport random\nimport time\nimport os\nimport threading\nimport struct\n\nimport utils\nfrom . import random_get_slice\n\nrandom.seed(time.time()* 1000000)\n\n\nclass IpSimpleSource(object):\n    def __init__(self, ips=[]):\n        self.ips = ips\n\n    def set_ips(self, ips):\n        self.ips = ips\n\n    def get_ip(self):\n        if not self.ips:\n            return \"\"\n        else:\n            return random.choice(self.ips)\n\n\nclass Ipv4RangeSource(object):\n    def __init__(self, logger, config, default_range_fn, user_range_fn):\n        self.logger = logger\n        self.config = config\n\n        self.default_range_file = default_range_fn\n        self.user_range_fn = user_range_fn\n        self.load_ip_range()\n\n    def load_range_content(self, default=False):\n        if not default and os.path.isfile(self.user_range_fn):\n            fd = open(self.user_range_fn, \"r\")\n            if fd:\n                content = fd.read()\n                fd.close()\n                if len(content) > 10:\n                    self.logger.info(\"load ip range file:%s\", self.user_range_fn)\n                    return content\n\n        self.logger.info(\"load ip range file:%s\", self.default_range_file)\n        fd = open(self.default_range_file, \"r\")\n        if not fd:\n            self.logger.error(\"load ip range %s fail\", self.default_range_file)\n            return\n\n        content = fd.read()\n        fd.close()\n        return content\n\n    def update_range_content(self, content):\n        with open(self.user_range_fn, \"w\") as fd:\n            fd.write(content)\n\n    def remove_user_range(self):\n        try:\n            os.remove(self.user_range_fn)\n        except:\n            pass\n\n    def load_ip_range(self):\n        self.ip_range_map = {}\n        self.ip_range_list = []\n        self.ip_range_index = []\n        self.candidate_amount_ip = 0\n\n        content = self.load_range_content()\n        lines = content.splitlines()\n        for line in lines:\n            if len(line) == 0 or line[0] == '#':\n                continue\n\n            try:\n                begin, end = utils.split_ip(line)\n                nbegin = utils.ip_string_to_num(begin)\n                nend = utils.ip_string_to_num(end)\n                if not nbegin or not nend or nend < nbegin:\n                    self.logger.warn(\"load ip range:%s fail\", line)\n                    continue\n            except Exception as e:\n                self.logger.exception(\"load ip range:%s fail:%r\", line, e)\n                continue\n\n            self.ip_range_map[self.candidate_amount_ip] = [nbegin, nend]\n            self.ip_range_list.append( [nbegin, nend] )\n            self.ip_range_index.append(self.candidate_amount_ip)\n            num = nend - nbegin\n            self.candidate_amount_ip += num\n            # print utils.ip_num_to_string(nbegin), utils.ip_num_to_string(nend), num\n\n        self.ip_range_index.sort()\n        #print \"amount ip num:\", self.candidate_amount_ip\n\n    def get_ip(self):\n        while True:\n            index = random.randint(0, len(self.ip_range_list) - 1)\n            ip_range = self.ip_range_list[index]\n            #self.logger.debug(\"random.randint %d - %d\", ip_range[0], ip_range[1])\n            if ip_range[1] == ip_range[0]:\n                return utils.ip_num_to_string(ip_range[1])\n\n            try:\n                id_2 = random.randint(0, ip_range[1] - ip_range[0])\n            except Exception as e:\n                self.logger.exception(\"random.randint:%r %d - %d, %d\", e, ip_range[0], ip_range[1], ip_range[1] - ip_range[0])\n                return\n\n            ip = ip_range[0] + id_2\n            add_last_byte = ip % 256\n            if add_last_byte == 0 or add_last_byte == 255:\n                continue\n\n            return utils.ip_num_to_string(ip)\n\n\nclass Ipv4PoolSource(object):\n    def __init__(self, logger, source_txt_fn, dest_bin_fn):\n        self.logger = logger\n        self.source_txt_fn = source_txt_fn\n        self.dest_bin_fn = dest_bin_fn\n\n        self.bin_fd = None\n        threading.Thread(target=self.init, name=\"%s_ipv4PoolSource_init\" % self.logger.name).start()\n\n    def init(self):\n        if not self.check_bin():\n            self.generate_bin()\n        self.bin_fd = open(self.dest_bin_fn, \"rb\")\n        self.bin_size = os.path.getsize(self.dest_bin_fn)\n\n    def check_bin(self):\n        if not os.path.isfile(self.dest_bin_fn):\n            return False\n\n        if os.path.getmtime(self.dest_bin_fn) < os.path.getmtime(self.source_txt_fn):\n            return False\n\n        return True\n\n    def generate_bin(self):\n        self.logger.info(\"generating binary ip pool file.\")\n        rfd = open(self.source_txt_fn, \"rt\")\n        wfd = open(self.dest_bin_fn, \"wb\")\n        num = 0\n        for line in rfd.readlines():\n            ip = line\n            try:\n                ip_num = utils.ip_string_to_num(ip)\n            except Exception as e:\n                self.logger.warn(\"ip %s not valid in %s\", ip, self.source_txt_fn)\n                continue\n            ip_bin = struct.pack(\"<I\", ip_num)\n            wfd.write(ip_bin)\n            num += 1\n\n        rfd.close()\n        wfd.close()\n        self.logger.info(\"finished generate binary ip pool file, num:%d\", num)\n\n    def get_ip(self):\n        while self.bin_fd is None:\n            time.sleep(1)\n\n        for _ in range(5):\n            position = random.randint(0, self.bin_size/4) * 4\n            self.bin_fd.seek(position)\n            ip_bin = self.bin_fd.read(4)\n            if ip_bin is None:\n                self.logger.warn(\"ip_pool.random_get_ip position:%d get None\", position)\n            elif len(ip_bin) != 4:\n                self.logger.warn(\"ip_pool.random_get_ip position:%d len:%d\", position, len(ip_bin))\n            else:\n                ip_num = struct.unpack(\"<I\", ip_bin)[0]\n                ip = utils.ip_num_to_string(ip_num)\n                return ip\n        time.sleep(3)\n        raise Exception(\"get ip fail.\")\n\n\nclass Ipv6PoolSource(object):\n    def __init__(self, logger, config, list_fn):\n        self.logger = logger\n        self.config = config\n        self.list_fn = list_fn\n\n        self.source = random_get_slice.RandomGetSlice(list_fn, 200)\n\n    def get_ip(self):\n        line = self.source.get()\n        lp = line.split()\n        ip = lp[0]\n        return ip\n\n\nclass IpCombineSource(object):\n    def __init__(self, logger, config, ipv4_source, ipv6_source):\n        self.logger = logger\n        self.config = config\n        self.ipv4_source = ipv4_source\n        self.ipv6_source = ipv6_source\n\n    def get_ip(self, use_ipv6=None):\n        if use_ipv6 is None:\n            use_ipv6 = self.config.use_ipv6\n\n        if use_ipv6 == \"force_ipv4\":\n            return self.ipv4_source.get_ip()\n        elif use_ipv6 == \"force_ipv6\":\n            return self.ipv6_source.get_ip()\n        else:\n            if use_ipv6 != \"auto\":\n                self.logger.warn(\"IpRange get_ip but use_ip is %s\", use_ipv6)\n\n            ran = random.randint(0, 100)\n            if ran < self.config.ipv6_scan_ratio:\n                return self.ipv6_source.get_ip()\n            else:\n                return self.ipv4_source.get_ip()\n"
  },
  {
    "path": "code/default/lib/noarch/front_base/openssl_wrap.py",
    "content": "\n# this wrap has a close callback.\n# Which is used by  ip manager\n#  ip manager keep a connection number counter for every ip.\n\n# the wrap SSL implementation, python 2.7 will use pyOpenSSL, python 3.x will use build in ssl.\n# This can also be used to store some attribute like ip_str/appid\n\nimport sys\n\nerror_str = \"\"\nimplementation = None\n\ndef init():\n    global implementation\n    try:\n        from .boringssl_wrap import SSLConnection, SSLContext, SSLCert\n        implementation = \"BoringSSL\"\n        return SSLConnection, SSLContext, SSLCert\n    except Exception as e:\n        error_str = \"import boringssl except: %r;\" % e\n\n    if sys.version_info[0] == 3:\n        from .ssl_wrap import SSLConnection, SSLContext, SSLCert\n\n        implementation = \"ssl, \" + error_str\n    else:\n        from .pyopenssl_wrap import SSLConnection, SSLContext, SSLCert\n        implementation = \"OpenSSL, \" + error_str\n\n    return SSLConnection, SSLContext, SSLCert\n\n\nSSLConnection, SSLContext, SSLCert = init()\n"
  },
  {
    "path": "code/default/lib/noarch/front_base/pyopenssl_wrap.py",
    "content": "\n# this wrap has a close callback.\n# Which is used by  ip manager\n#  ip manager keep a connection number counter for every ip.\n\n# the wrap SSL implementation, python 2.7 will use pyOpenSSL, python 3.x will use build in ssl.\n# This can also be used to store some attribute like ip_str/appid\n\nimport os\nimport sys\nimport datetime\nimport socket\nimport ssl\nimport OpenSSL\nimport time\nimport select\nimport errno\n\nimport utils\n\n\nclass SSLConnection(object):\n    def __init__(self, context, sock, ip_str=None, sni=None, on_close=None):\n        self._context = context\n        self._sock = sock\n        self.ip_str = ip_str\n        self.sni = sni\n        self._makefile_refs = 0\n        self._on_close = on_close\n        self.peer_cert = None\n        self.socket_closed = False\n        self.timeout = self._sock.gettimeout() or 0.1\n        self.running = True\n        self._connection = None\n        self.wrap()\n\n    def wrap(self):\n        ip, port = utils.get_ip_port(self.ip_str)\n        if isinstance(ip, str):\n            ip = utils.to_bytes(ip)\n\n        ip_port = (utils.to_str(ip), port)\n\n        if sys.version_info[0] == 3:\n            try:\n                self._sock.connect((ip, port))\n            except Exception as e:\n                raise socket.error('conn %s fail, sni:%s, e:%r' % (self.ip_str, self.sni, e))\n\n            self._connection = self._context.wrap_socket(self._sock, server_hostname=self.sni,\n                                                         do_handshake_on_connect=False)\n        else:\n            self._connection = OpenSSL.SSL.Connection(self._context, self._sock)\n            self._connection.set_connect_state()\n            if self.sni:\n                try:\n                    self._connection.set_tlsext_host_name(self.sni)\n                except:\n                    pass\n            self._connection.connect(ip_port)\n\n    def is_support_h2(self):\n        if sys.version_info[0] == 3:\n            return self._connection.selected_alpn_protocol() == \"h2\" or self._connection.selected_npn_protocol() == \"h2\"\n        else:\n            return self._connection.get_alpn_proto_negotiated()\n\n    def __getattr__(self, attr):\n        if attr == \"socket_closed\":\n            # work around in case close before finished init.\n            return True\n\n        elif attr in ('is_support_h2', \"_on_close\", '_context', '_sock', '_connection', '_makefile_refs',\n                      'sni', 'wrap', 'socket_closed'):\n            return getattr(self, attr)\n\n        elif hasattr(self._connection, attr):\n            return getattr(self._connection, attr)\n\n    def __del__(self):\n        if not self.socket_closed and self._connection:\n            self._connection.close()\n            self.socket_closed = True\n\n        if self._on_close:\n            self._on_close(self.ip_str, self.sni)\n            self._on_close = None\n\n    def set_tlsext_host_name(self, hostname):\n        self._connection.server_hostname = utils.to_str(hostname)\n\n    def get_cert(self):\n        # py3 only\n        if self.peer_cert:\n            return self.peer_cert\n\n        cert = self._connection.getpeercert()\n        # For debug:\n        #cert = self._connection.getpeercert(True)\n        #from asn1crypto.x509 import Certificate\n        #cert = Certificate.load(cert)\n\n        self.peer_cert = {\n            \"cert\": cert,\n            \"issuer_commonname\": \"\",\n            \"commonName\": \"\",\n            \"altName\": []\n        }\n        for kv in cert[\"issuer\"]:\n            k, v = kv[0]\n            if k == 'commonName':\n                self.peer_cert[\"issuer_commonname\"] = v\n\n        for kv in cert[\"subject\"]:\n            k, v = kv[0]\n            if k == 'commonName':\n                self.peer_cert[\"commonName\"] = v\n\n        for k, v in cert[\"subjectAltName\"]:\n            self.peer_cert[\"altName\"].append(v)\n        self.peer_cert[\"altName\"] = tuple(self.peer_cert[\"altName\"])\n\n        return self.peer_cert\n\n    def __iowait(self, io_func, *args, **kwargs):\n        fd = self._sock.fileno()\n        time_start = time.time()\n        while self.running:\n            time_now = time.time()\n            wait_timeout = max(0.1, self.timeout - (time_now - time_start))\n            wait_timeout = min(wait_timeout, 10)\n            # in case socket was blocked by FW\n            # recv is called before send request, which timeout is 240\n            # then send request is called and timeout change to 100\n\n            try:\n                return io_func(*args, **kwargs)\n            except (OpenSSL.SSL.WantReadError, OpenSSL.SSL.WantX509LookupError) as e:\n                sys.exc_clear()\n                _, _, errors = select.select([fd], [], [fd], wait_timeout)\n                if errors:\n                    raise e\n                if time_now - time_start > self.timeout:\n                    break\n            except OpenSSL.SSL.WantWriteError as e:\n                sys.exc_clear()\n                _, _, errors = select.select([], [fd], [fd], wait_timeout)\n                if errors:\n                    raise e\n                time_now = time.time()\n                if time_now - time_start > self.timeout:\n                    break\n            except OpenSSL.SSL.SysCallError as e:\n                if e[0] == 10035 and 'WSAEWOULDBLOCK' in e[1]:\n                    sys.exc_clear()\n                    if io_func == self._connection.send:\n                        _, _, errors = select.select([], [fd], [fd], wait_timeout)\n                    else:\n                        _, _, errors = select.select([fd], [], [fd], wait_timeout)\n\n                    if errors:\n                        raise e\n                    time_now = time.time()\n                    if time_now - time_start > self.timeout:\n                        break\n                else:\n                    raise e\n            except Exception as e:\n                #self.logger.exception(\"e:%r\", e)\n                raise e\n\n        return 0\n\n    def accept(self):\n        sock, addr = self._sock.accept()\n        client = OpenSSL.SSL.Connection(sock._context, sock)\n        return client, addr\n\n    def do_handshake(self):\n        self.__iowait(self._connection.do_handshake)\n\n    def connect(self, *args, **kwargs):\n        return self.__iowait(self._connection.connect, *args, **kwargs)\n\n    def __send(self, data, flags=0):\n        try:\n            return self.__iowait(self._connection.send, data, flags)\n        except OpenSSL.SSL.SysCallError as e:\n            if e[0] == -1 and not data:\n                # errors when writing empty strings are expected and can be ignored\n                return 0\n            raise\n        except Exception as e:\n            #self.logger.exception(\"ssl send:%r\", e)\n            raise\n\n    def __send_memoryview(self, data, flags=0):\n        if hasattr(data, 'tobytes'):\n            data = data.tobytes()\n        return self.__send(data, flags)\n\n    send = __send if sys.version_info >= (2, 7, 5) else __send_memoryview\n\n    def recv(self, bufsiz, flags=0):\n        pending = self._connection.pending()\n        if pending:\n            return self._connection.recv(min(pending, bufsiz))\n\n        try:\n            return self.__iowait(self._connection.recv, bufsiz, flags)\n        except OpenSSL.SSL.ZeroReturnError:\n            return ''\n        except OpenSSL.SSL.SysCallError as e:\n            if e[0] == -1 and 'Unexpected EOF' in e[1]:\n                # remote closed\n                #raise e\n                return \"\"\n            elif e[0] == 10053 or e[0] == 10054 or e[0] == 10038:\n                return \"\"\n            raise\n\n    def recv_into(self, buf, nbytes=None):\n        pending = self._connection.pending()\n        if pending:\n            ret = self._connection.recv_into(buf, nbytes)\n            if not ret:\n                # self.logger.debug(\"recv_into 0\")\n                pass\n            return ret\n\n        while self.running:\n            try:\n                ret = self.__iowait(self._connection.recv_into, buf, nbytes)\n                if not ret:\n                    # self.logger.debug(\"recv_into 0\")\n                    pass\n                return ret\n            except OpenSSL.SSL.ZeroReturnError as e:\n                raise e\n            except OpenSSL.SSL.SysCallError as e:\n                if sys.version_info[0] == 2:\n                    if e[0] == -1 and 'Unexpected EOF' in e[1]:\n                        # errors when reading empty strings are expected and can be ignored\n                        return 0\n                    elif e[0] == 11 and e[1] == 'EAGAIN':\n                        continue\n                raise\n            except Exception as e:\n                if sys.version_info[0] == 2 and e == errno.EAGAIN:\n                    continue\n                # logging.exception(\"recv %r\", e)\n                raise e\n\n    def read(self, bufsiz, flags=0):\n        return self.recv(bufsiz, flags)\n\n    def write(self, buf, flags=0):\n        return self.sendall(buf, flags)\n\n    def close(self, reason=\"\"):\n        if self._makefile_refs < 1:\n            self.running = False\n            if not self.socket_closed:\n                socket.socket.close(self._sock)\n                self.socket_closed = True\n                if self._on_close:\n                    self._on_close(self.ip_str, self.sni, reason=reason)\n                    self._on_close = None\n        else:\n            self._makefile_refs -= 1\n\n    def settimeout(self, t):\n        if not self.running:\n            return\n\n        if self.timeout != t:\n            if sys.version_info[0] == 3:\n                self._connection.settimeout(t)\n            else:\n                self._sock.settimeout(t)\n            self.timeout = t\n\n    def makefile(self, mode='r', bufsize=-1):\n        self._makefile_refs += 1\n        return socket._fileobject(self, mode, bufsize, close=True)\n\n\nclass SSLContext(object):\n    def __init__(self, logger, ca_certs=None, cipher_suites=None, support_http2=True, protocol=None):\n        self.logger = logger\n\n        if sys.version_info[0] == 3:\n            if protocol == \"TLSv1_2\":\n                ssl_version = ssl.PROTOCOL_TLSv1_2\n\n            elif hasattr(ssl, \"PROTOCOL_TLS\"):\n                ssl_version = ssl.PROTOCOL_TLS\n            elif hasattr(ssl, \"PROTOCOL_TLSv1_2\"):\n                ssl_version = ssl.PROTOCOL_TLSv1_2\n            elif hasattr(ssl, \"PROTOCOL_TLSv1_1\"):\n                ssl_version = ssl.PROTOCOL_TLSv1_1\n            elif hasattr(ssl, \"PROTOCOL_TLSv1\"):\n                ssl_version = ssl.PROTOCOL_TLSv1\n            elif hasattr(ssl, \"PROTOCOL_SSLv3\"):\n                ssl_version = ssl.PROTOCOL_SSLv3\n            elif hasattr(ssl, \"PROTOCOL_SSLv2\"):\n                ssl_version = ssl.PROTOCOL_SSLv2\n            else:\n                ssl_version = ssl.PROTOCOL_SSLv23\n\n            self.logger.info(\"SSL use version:%s\", self.supported_protocol())\n            self.context = ssl.SSLContext(protocol=ssl_version)\n\n            self.set_ca(ca_certs)\n\n            if cipher_suites:\n                self.context.set_ciphers(':'.join(cipher_suites))\n\n            self.support_alpn_npn = None\n            if support_http2:\n                try:\n                    self.context.set_alpn_protocols(['h2', 'http/1.1'])\n                    self.logger.info(\"OpenSSL support alpn\")\n                    self.support_alpn_npn = \"alpn\"\n                    return\n                except Exception as e:\n                    self.logger.exception(\"set_alpn_protos:%r\", e)\n                    pass\n\n                try:\n                    self.context.set_npn_protocols(['h2', 'http/1.1'])\n                    self.logger.info(\"OpenSSL support npn\")\n                    self.support_alpn_npn = \"npn\"\n                except Exception as e:\n                    # xlog.exception(\"set_npn_select_callback:%r\", e)\n                    self.logger.info(\"OpenSSL dont't support npn/alpn, no HTTP/2 supported.\")\n                    pass\n        else:\n            self.ssl_version = self.supported_protocol()\n\n            protocol_version = getattr(OpenSSL.SSL, '%s_METHOD' % self.ssl_version)\n            self.context = OpenSSL.SSL.Context(protocol_version)\n\n            self.set_ca(ca_certs)\n\n            if cipher_suites:\n                self.context.set_cipher_list(':'.join(cipher_suites))\n\n            self.support_alpn_npn = None\n            if support_http2:\n                try:\n                    self.context.set_alpn_protos([b'h2', b'http/1.1'])\n                    self.logger.info(\"OpenSSL support alpn\")\n                    self.support_alpn_npn = \"alpn\"\n                    return\n                except Exception as e:\n                    # self.logger.exception(\"set_alpn_protos:%r\", e)\n                    pass\n\n                try:\n                    self.context.set_npn_select_callback(SSLContext.npn_select_callback)\n                    self.logger.info(\"OpenSSL support npn\")\n                    self.support_alpn_npn = \"npn\"\n                except Exception as e:\n                    #xlog.exception(\"set_npn_select_callback:%r\", e)\n                    self.logger.info(\"OpenSSL dont't support npn/alpn, no HTTP/2 supported.\")\n                    pass\n\n    @staticmethod\n    def npn_select_callback(conn, protocols):\n        # self.logger.debug(\"npn protocl:%s\", \";\".join(protocols))\n        if b\"h2\" in protocols:\n            conn.protos = \"h2\"\n            return b\"h2\"\n        else:\n            return b\"http/1.1\"\n\n    @staticmethod\n    def supported_protocol():\n        if sys.version_info[0] == 3:\n            if hasattr(ssl, \"HAS_TLSv1_3\") and ssl.HAS_TLSv1_3:\n                ssl_version = \"TLSv1_3\"\n            elif hasattr(ssl, \"HAS_TLSv1_2\") and ssl.HAS_TLSv1_2:\n                ssl_version = \"TLSv1_2\"\n            elif hasattr(ssl, \"HAS_TLSv1_1\") and ssl.HAS_TLSv1_1:\n                ssl_version = \"TLSv1_1\"\n            elif hasattr(ssl, \"HAS_SSLv3\") and ssl.HAS_SSLv3:\n                ssl_version = \"SSLv3\"\n            elif hasattr(ssl, \"HAS_SSLv2\") and ssl.HAS_SSLv2:\n                ssl_version = \"SSLv2\"\n            else:\n                ssl_version = \"SSLv1\"\n        else:\n            if hasattr(OpenSSL.SSL, \"TLSv1_2_METHOD\"):\n                ssl_version = \"TLSv1_2\"\n            elif hasattr(OpenSSL.SSL, \"TLSv1_1_METHOD\"):\n                ssl_version = \"TLSv1_1\"\n            elif hasattr(OpenSSL.SSL, \"TLSv1_METHOD\"):\n                ssl_version = \"TLSv1\"\n            else:\n                ssl_version = \"SSLv23\"\n\n            if sys.platform == \"darwin\":\n                # MacOS pyOpenSSL has TLSv1_2_METHOD attr but can use.\n                # There for we hard code here.\n                # may be try/cache is a better solution.\n                ssl_version = \"TLSv1\"\n\n            # freenas openssl support fix from twitter user \"himanzero\"\n            # https://twitter.com/himanzero/status/645231724318748672\n            if sys.platform == \"freebsd9\":\n                ssl_version = \"TLSv1\"\n\n        return ssl_version\n\n    def set_ca(self, ca_certs):\n        if sys.version_info[0] == 3:\n            try:\n                if ca_certs:\n                    self.context.load_verify_locations(cafile=os.path.abspath(ca_certs))\n                    self.context.verify_mode = ssl.CERT_REQUIRED\n                else:\n                    self.context.verify_mode = ssl.CERT_NONE\n            except Exception as e:\n                self.logger.debug(\"set_ca fail:%r\", e)\n        else:\n            if ca_certs:\n                self.context.load_verify_locations(os.path.abspath(ca_certs))\n                self.context.set_verify(OpenSSL.SSL.VERIFY_PEER, lambda c, x, e, d, ok: ok)\n            else:\n                self.context.set_verify(OpenSSL.SSL.VERIFY_NONE, lambda c, x, e, d, ok: ok)\n\n\nfrom pyasn1.codec.der.decoder import decode\nfrom pyasn1.error import PyAsn1Error\nfrom pyasn1.type import univ, constraint, char, namedtype, tag\n\n\nclass _GeneralName(univ.Choice):\n    # We are only interested in dNSNames. We use a default handler to ignore\n    # other types.\n    componentType = namedtype.NamedTypes(\n        namedtype.NamedType('dNSName', char.IA5String().subtype(\n                implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2)\n            )\n        ),\n    )\n\n\nclass _GeneralNames(univ.SequenceOf):\n    componentType = _GeneralName()\n    sizeSpec = univ.SequenceOf.sizeSpec + constraint.ValueSizeConstraint(1, 1024)\n\n\nclass SSLCert:\n    def __init__(self, cert):\n        \"\"\"\n            Returns a (common name, [subject alternative names]) tuple.\n        \"\"\"\n        self.x509 = cert\n\n    @classmethod\n    def from_pem(klass, txt):\n        x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, txt)\n        return klass(x509)\n\n    @classmethod\n    def from_der(klass, der):\n        pem = ssl.DER_cert_to_PEM_cert(der)\n        return klass.from_pem(pem)\n\n    def to_pem(self):\n        return OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, self.x509)\n\n    def digest(self, name):\n        return self.x509.digest(name)\n\n    @property\n    def issuer(self):\n        return self.x509.get_issuer().get_components()\n\n    @property\n    def notbefore(self):\n        t = self.x509.get_notBefore()\n        return datetime.datetime.strptime(t, \"%Y%m%d%H%M%SZ\")\n\n    @property\n    def notafter(self):\n        t = self.x509.get_notAfter()\n        return datetime.datetime.strptime(t, \"%Y%m%d%H%M%SZ\")\n\n    @property\n    def has_expired(self):\n        return self.x509.has_expired()\n\n    @property\n    def subject(self):\n        return self.x509.get_subject().get_components()\n\n    @property\n    def serial(self):\n        return self.x509.get_serial_number()\n\n    @property\n    def keyinfo(self):\n        pk = self.x509.get_pubkey()\n        types = {\n            OpenSSL.crypto.TYPE_RSA: \"RSA\",\n            OpenSSL.crypto.TYPE_DSA: \"DSA\",\n        }\n        return (\n            types.get(pk.type(), \"UNKNOWN\"),\n            pk.bits()\n        )\n\n    @property\n    def cn(self):\n        c = None\n        for i in self.subject:\n            if i[0] == \"CN\":\n                c = i[1]\n        return c\n\n    @property\n    def altnames(self):\n        altnames = []\n        for i in range(self.x509.get_extension_count()):\n            ext = self.x509.get_extension(i)\n            if ext.get_short_name() == \"subjectAltName\":\n                try:\n                    dec = decode(ext.get_data(), asn1Spec=_GeneralNames())\n                except PyAsn1Error:\n                    continue\n                for i in dec[0]:\n                    altnames.append(i[0].asOctets())\n        return altnames\n"
  },
  {
    "path": "code/default/lib/noarch/front_base/random_get_slice.py",
    "content": "import os\nimport random\nimport threading\n\n\nclass RandomGetSlice(object):\n    def __init__(self, fn, line_max_size=80, spliter='\\n'):\n        self.fn = fn\n        self.line_max_size = line_max_size\n        self.spliter = spliter\n\n        self.lock = threading.Lock()\n        self.fd = open(fn, \"r\")\n        self.fsize = os.path.getsize(fn)\n\n    def get(self):\n        with self.lock:\n            position = random.randint(0, self.fsize - (self.line_max_size*2))\n            try:\n                self.fd.seek(position)\n                slice = self.fd.read(self.line_max_size * 2)\n            except Exception as e:\n                # xlog.warn(\"RandomGetSlice.get fail, fn:%s e:%r\", self.fn, e)\n                self.fd.close()\n                self.fd = open(self.fn, \"r\")\n                self.fd.seek(position)\n                slice = self.fd.read(self.line_max_size * 2)\n\n            if slice is None:\n                raise Exception(\"random read line fail:%s\" % slice)\n\n            ns = slice.split(self.spliter)\n            if len(ns) < 3:\n                raise Exception(\"random read line fail:%s\" % slice)\n\n            line = ns[1]\n            return line\n"
  },
  {
    "path": "code/default/lib/noarch/front_base/ssl_wrap.py",
    "content": "\n# this wrap has a close callback.\n# Which is used by  ip manager\n#  ip manager keep a connection number counter for every ip.\n\n# the wrap SSL implementation, python 2.7 will use pyOpenSSL, python 3.x will use build in ssl.\n# This can also be used to store some attribute like ip_str/appid\n\nimport os\nimport sys\nimport datetime\nimport socket\nimport ssl\nimport time\nimport select\nimport errno\n\nimport utils\n\n\nclass SSLConnection(object):\n    def __init__(self, context, sock, ip_str=None, sni=None, on_close=None):\n        self._context = context\n        self._sock = sock\n        self.ip_str = ip_str\n        self.sni = sni\n        self._makefile_refs = 0\n        self._on_close = on_close\n        self.peer_cert = None\n        self.socket_closed = False\n        self.timeout = self._sock.gettimeout() or 0.1\n        self.running = True\n        self._connection = None\n        self.wrap()\n\n    def wrap(self):\n        ip, port = utils.get_ip_port(self.ip_str)\n        if isinstance(ip, str):\n            ip = utils.to_bytes(ip)\n\n        try:\n            self._sock.connect((ip, port))\n        except Exception as e:\n            raise socket.error('conn %s fail, sni:%s, e:%r' % (self.ip_str, self.sni, e))\n\n        self._connection = self._context.wrap_socket(self._sock, server_hostname=self.sni,\n                                                     do_handshake_on_connect=False)\n\n    def is_support_h2(self):\n        if sys.version_info[0] == 3:\n            return self._connection.selected_alpn_protocol() == \"h2\" or self._connection.selected_npn_protocol() == \"h2\"\n        else:\n            return self._connection.get_alpn_proto_negotiated()\n\n    def __getattr__(self, attr):\n        if attr == \"socket_closed\":\n            # work around in case close before finished init.\n            return True\n\n        elif attr in ('is_support_h2', \"_on_close\", '_context', '_sock', '_connection', '_makefile_refs',\n                      'sni', 'wrap', 'socket_closed'):\n            return getattr(self, attr)\n\n        elif hasattr(self._connection, attr):\n            return getattr(self._connection, attr)\n\n    def __del__(self):\n        if not self.socket_closed and self._connection:\n            self._connection.close()\n            self.socket_closed = True\n            if self._on_close:\n                self._on_close(self.ip_str, self.sni)\n\n    def set_tlsext_host_name(self, hostname):\n        self._connection.server_hostname = utils.to_str(hostname)\n\n    def get_cert(self):\n        # py3 only\n        if self.peer_cert:\n            return self.peer_cert\n\n        cert = self._connection.getpeercert()\n        # For debug:\n        #cert = self._connection.getpeercert(True)\n        #from asn1crypto.x509 import Certificate\n        #cert = Certificate.load(cert)\n\n        self.peer_cert = {\n            \"cert\": cert,\n            \"issuer_commonname\": \"\",\n            \"commonName\": \"\",\n            \"altName\": []\n        }\n        for kv in cert.get(\"issuer\", {}):\n            k, v = kv[0]\n            if k == 'commonName':\n                self.peer_cert[\"issuer_commonname\"] = v\n\n        for kv in cert.get(\"subject\", {}):\n            k, v = kv[0]\n            if k == 'commonName':\n                self.peer_cert[\"commonName\"] = v\n\n        for k, v in cert.get(\"subjectAltName\", {}):\n            self.peer_cert[\"altName\"].append(v)\n        self.peer_cert[\"altName\"] = tuple(self.peer_cert[\"altName\"])\n\n        return self.peer_cert\n\n    def __iowait(self, io_func, *args, **kwargs):\n        fd = self._sock.fileno()\n        time_start = time.time()\n        while self.running:\n            time_now = time.time()\n            wait_timeout = max(0.1, self.timeout - (time_now - time_start))\n            wait_timeout = min(wait_timeout, 10)\n            # in case socket was blocked by FW\n            # recv is called before send request, which timeout is 240\n            # then send request is called and timeout change to 100\n\n            try:\n                return io_func(*args, **kwargs)\n            except Exception as e:\n                #self.logger.exception(\"e:%r\", e)\n                raise e\n\n        return 0\n\n    def accept(self):\n        sock, addr = self._sock.accept()\n        client = OpenSSL.SSL.Connection(sock._context, sock)\n        return client, addr\n\n    def do_handshake(self):\n        self.__iowait(self._connection.do_handshake)\n\n    def connect(self, *args, **kwargs):\n        return self.__iowait(self._connection.connect, *args, **kwargs)\n\n    def __send(self, data, flags=0):\n        try:\n            return self.__iowait(self._connection.send, data, flags)\n        except Exception as e:\n            #self.logger.exception(\"ssl send:%r\", e)\n            raise\n\n    def __send_memoryview(self, data, flags=0):\n        if hasattr(data, 'tobytes'):\n            data = data.tobytes()\n        return self.__send(data, flags)\n\n    send = __send if sys.version_info >= (2, 7, 5) else __send_memoryview\n\n    def recv(self, bufsiz, flags=0):\n        pending = self._connection.pending()\n        if pending:\n            return self._connection.recv(min(pending, bufsiz))\n\n        try:\n            return self.__iowait(self._connection.recv, bufsiz, flags)\n        except Exception:\n            return ''\n\n    def recv_into(self, buf, nbytes=None):\n        pending = self._connection.pending()\n        if pending:\n            ret = self._connection.recv_into(buf, nbytes)\n            if not ret:\n                # self.logger.debug(\"recv_into 0\")\n                pass\n            return ret\n\n        while self.running:\n            try:\n                ret = self.__iowait(self._connection.recv_into, buf, nbytes)\n                if not ret:\n                    # self.logger.debug(\"recv_into 0\")\n                    pass\n                return ret\n            except Exception as e:\n                if sys.version_info[0] == 2 and e == errno.EAGAIN:\n                    continue\n                # logging.exception(\"recv %r\", e)\n                raise e\n\n    def read(self, bufsiz, flags=0):\n        return self.recv(bufsiz, flags)\n\n    def write(self, buf, flags=0):\n        return self.sendall(buf, flags)\n\n    def close(self, reason=\"\"):\n        if self._makefile_refs < 1:\n            self.running = False\n            if not self.socket_closed:\n                socket.socket.close(self._sock)\n                self.socket_closed = True\n                if self._on_close:\n                    self._on_close(self.ip_str, self.sni, reason=reason)\n        else:\n            self._makefile_refs -= 1\n\n    def settimeout(self, t):\n        if not self.running:\n            return\n\n        if self.timeout != t:\n            if sys.version_info[0] == 3:\n                self._connection.settimeout(t)\n            else:\n                self._sock.settimeout(t)\n            self.timeout = t\n\n    def makefile(self, mode='r', bufsize=-1):\n        self._makefile_refs += 1\n        return socket._fileobject(self, mode, bufsize, close=True)\n\n\nclass SSLContext(object):\n    def __init__(self, logger, ca_certs=None, cipher_suites=None, support_http2=True, protocol=None):\n        self.logger = logger\n\n        if protocol == \"TLSv1_2\":\n            ssl_version = ssl.PROTOCOL_TLSv1_2\n\n        elif hasattr(ssl, \"PROTOCOL_TLS\"):\n            ssl_version = ssl.PROTOCOL_TLS\n        elif hasattr(ssl, \"PROTOCOL_TLSv1_2\"):\n            ssl_version = ssl.PROTOCOL_TLSv1_2\n        elif hasattr(ssl, \"PROTOCOL_TLSv1_1\"):\n            ssl_version = ssl.PROTOCOL_TLSv1_1\n        elif hasattr(ssl, \"PROTOCOL_TLSv1\"):\n            ssl_version = ssl.PROTOCOL_TLSv1\n        elif hasattr(ssl, \"PROTOCOL_SSLv3\"):\n            ssl_version = ssl.PROTOCOL_SSLv3\n        elif hasattr(ssl, \"PROTOCOL_SSLv2\"):\n            ssl_version = ssl.PROTOCOL_SSLv2\n        else:\n            ssl_version = ssl.PROTOCOL_SSLv23\n\n        self.logger.info(\"SSL use version:%s\", self.supported_protocol())\n        self.context = ssl.SSLContext(protocol=ssl_version)\n\n        self.set_ca(ca_certs)\n\n        if cipher_suites:\n            self.context.set_ciphers(':'.join(cipher_suites))\n\n        self.support_alpn_npn = None\n        if support_http2:\n            try:\n                self.context.set_alpn_protocols(['h2', 'http/1.1'])\n                self.logger.info(\"OpenSSL support alpn\")\n                self.support_alpn_npn = \"alpn\"\n                return\n            except Exception as e:\n                self.logger.exception(\"set_alpn_protos:%r\", e)\n                pass\n\n            try:\n                self.context.set_npn_protocols(['h2', 'http/1.1'])\n                self.logger.info(\"OpenSSL support npn\")\n                self.support_alpn_npn = \"npn\"\n            except Exception as e:\n                # xlog.exception(\"set_npn_select_callback:%r\", e)\n                self.logger.info(\"OpenSSL dont't support npn/alpn, no HTTP/2 supported.\")\n                pass\n\n    @staticmethod\n    def npn_select_callback(conn, protocols):\n        # self.logger.debug(\"npn protocl:%s\", \";\".join(protocols))\n        if b\"h2\" in protocols:\n            conn.protos = \"h2\"\n            return b\"h2\"\n        else:\n            return b\"http/1.1\"\n\n    @staticmethod\n    def supported_protocol():\n        if hasattr(ssl, \"HAS_TLSv1_3\") and ssl.HAS_TLSv1_3:\n            ssl_version = \"TLSv1_3\"\n        elif hasattr(ssl, \"HAS_TLSv1_2\") and ssl.HAS_TLSv1_2:\n            ssl_version = \"TLSv1_2\"\n        elif hasattr(ssl, \"HAS_TLSv1_1\") and ssl.HAS_TLSv1_1:\n            ssl_version = \"TLSv1_1\"\n        elif hasattr(ssl, \"HAS_SSLv3\") and ssl.HAS_SSLv3:\n            ssl_version = \"SSLv3\"\n        elif hasattr(ssl, \"HAS_SSLv2\") and ssl.HAS_SSLv2:\n            ssl_version = \"SSLv2\"\n        else:\n            ssl_version = \"SSLv1\"\n\n        return ssl_version\n\n    def set_ca(self, ca_certs):\n        if sys.version_info[0] == 3:\n            try:\n                if ca_certs:\n                    self.context.load_verify_locations(cafile=os.path.abspath(ca_certs))\n                    self.context.verify_mode = ssl.CERT_REQUIRED\n                else:\n                    self.context.verify_mode = ssl.CERT_NONE\n            except Exception as e:\n                self.logger.debug(\"set_ca fail:%r\", e)\n        else:\n            if ca_certs:\n                self.context.load_verify_locations(os.path.abspath(ca_certs))\n                self.context.set_verify(OpenSSL.SSL.VERIFY_PEER, lambda c, x, e, d, ok: ok)\n            else:\n                self.context.set_verify(OpenSSL.SSL.VERIFY_NONE, lambda c, x, e, d, ok: ok)\n\n\nfrom pyasn1.codec.der.decoder import decode\nfrom pyasn1.error import PyAsn1Error\nfrom pyasn1.type import univ, constraint, char, namedtype, tag\n\n\nclass _GeneralName(univ.Choice):\n    # We are only interested in dNSNames. We use a default handler to ignore\n    # other types.\n    componentType = namedtype.NamedTypes(\n        namedtype.NamedType('dNSName', char.IA5String().subtype(\n                implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2)\n            )\n        ),\n    )\n\n\nclass _GeneralNames(univ.SequenceOf):\n    componentType = _GeneralName()\n    sizeSpec = univ.SequenceOf.sizeSpec + constraint.ValueSizeConstraint(1, 1024)\n\n\nclass SSLCert:\n    def __init__(self, cert):\n        \"\"\"\n            Returns a (common name, [subject alternative names]) tuple.\n        \"\"\"\n        self.x509 = cert\n\n    # @classmethod\n    # def from_pem(klass, txt):\n    #     x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, txt)\n    #     return klass(x509)\n\n    # @classmethod\n    # def from_der(klass, der):\n    #     pem = ssl.DER_cert_to_PEM_cert(der)\n    #     return klass.from_pem(pem)\n\n    # def to_pem(self):\n    #     return OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, self.x509)\n\n    def digest(self, name):\n        return self.x509.digest(name)\n\n    @property\n    def issuer(self):\n        return self.x509.get_issuer().get_components()\n\n    @property\n    def notbefore(self):\n        t = self.x509.get_notBefore()\n        return datetime.datetime.strptime(t, \"%Y%m%d%H%M%SZ\")\n\n    @property\n    def notafter(self):\n        t = self.x509.get_notAfter()\n        return datetime.datetime.strptime(t, \"%Y%m%d%H%M%SZ\")\n\n    @property\n    def has_expired(self):\n        return self.x509.has_expired()\n\n    @property\n    def subject(self):\n        return self.x509.get_subject().get_components()\n\n    @property\n    def serial(self):\n        return self.x509.get_serial_number()\n\n    # @property\n    # def keyinfo(self):\n    #     pk = self.x509.get_pubkey()\n    #     types = {\n    #         OpenSSL.crypto.TYPE_RSA: \"RSA\",\n    #         OpenSSL.crypto.TYPE_DSA: \"DSA\",\n    #     }\n    #     return (\n    #         types.get(pk.type(), \"UNKNOWN\"),\n    #         pk.bits()\n    #     )\n\n    @property\n    def cn(self):\n        c = None\n        for i in self.subject:\n            if i[0] == \"CN\":\n                c = i[1]\n        return c\n\n    @property\n    def altnames(self):\n        altnames = []\n        for i in range(self.x509.get_extension_count()):\n            ext = self.x509.get_extension(i)\n            if ext.get_short_name() == \"subjectAltName\":\n                try:\n                    dec = decode(ext.get_data(), asn1Spec=_GeneralNames())\n                except PyAsn1Error:\n                    continue\n                for i in dec[0]:\n                    altnames.append(i[0].asOctets())\n        return altnames\n"
  },
  {
    "path": "code/default/lib/noarch/front_base/tlslite_wrap.py",
    "content": "\n# this wrap has a close callback.\n# Which is used by  ip manager\n#  ip manager keep a connection number counter for every ip.\n\n# the wrap SSL implementation, python 2.7 will use pyOpenSSL, python 3.x will use build in ssl.\n# This can also be used to store some attribute like ip_str/appid\n\nimport socket\n\nfrom tlslite.tlsconnection import TLSConnection\nfrom tlslite.handshakesettings import HandshakeSettings\nimport utils\n\n\nclass SSLConnection(object):\n    def __init__(self, context, sock, ip_str=None, sni=None, on_close=None):\n        self._context = context\n        self._sock = sock\n        self.ip_str = utils.to_bytes(ip_str)\n        self.sni = sni\n        self._makefile_refs = 0\n        self._on_close = on_close\n        self.peer_cert = None\n        self.socket_closed = False\n        self.timeout = self._sock.gettimeout() or 0.1\n        self.running = True\n        self._connection = None\n        self.wrap()\n\n    def wrap(self):\n        ip, port = utils.get_ip_port(self.ip_str)\n        if isinstance(ip, str):\n            ip = utils.to_bytes(ip)\n\n        try:\n            self._sock.connect((ip, port))\n        except Exception as e:\n            raise socket.error('conn %s fail, sni:%s, e:%r' % (self.ip_str, self.sni, e))\n\n        self._connection = TLSConnection(self._sock)\n\n    def is_support_h2(self):\n        if self._connection.session.appProto == bytearray(b\"h2\"):\n            return True\n        else:\n            return False\n\n    def setblocking(self, block):\n        self._sock.setblocking(block)\n\n    def __getattr__(self, attr):\n        if attr == \"socket_closed\":\n            # work around in case close before finished init.\n            return True\n\n        elif attr in ('is_support_h2', \"_on_close\", '_context', '_sock', '_connection', '_makefile_refs',\n                      'sni', 'wrap', 'socket_closed'):\n            return getattr(self, attr)\n\n        elif hasattr(self._connection, attr):\n            return getattr(self._connection, attr)\n\n    def __del__(self):\n        if not self.socket_closed and self._connection:\n            self._connection.close()\n            self.socket_closed = True\n            if self._on_close:\n                self._on_close(self.ip_str, self.sni)\n\n    def get_cert(self):\n        if self.peer_cert:\n            return self.peer_cert\n\n        cert = self._connection.session.serverCertChain.x509List[0].bytes\n        cert = bytes(cert)\n\n        from asn1crypto.x509 import Certificate\n        cert = Certificate.load(cert)\n\n        try:\n            altName = cert.subject_alt_name_value.native\n        except:\n            altName = []\n\n        self.peer_cert = {\n            \"cert\": cert,\n            \"issuer_commonname\": cert.issuer.human_friendly,\n            \"commonName\": \"\",\n            \"altName\": altName\n        }\n\n        return self.peer_cert\n\n    def do_handshake(self):\n        cert_chain = None\n        privateKey = None\n        self._connection.handshakeClientCert(cert_chain, privateKey, None,\n            self._context.settings, None, None, None, self.sni, False, self._context.alpn)\n\n    def connect(self, *args, **kwargs):\n        return self._connection.connect(*args, **kwargs)\n\n    def send(self, data, flags=0):\n        try:\n            return self._connection.send(data)\n        except Exception as e:\n            #self.logger.exception(\"ssl send:%r\", e)\n            raise e\n\n    def recv(self, bufsiz, flags=0):\n        return self._connection.recv(bufsiz)\n\n    def recv_into(self, buf, nbytes=None):\n        if not nbytes:\n            nbytes = len(buf)\n\n        data = self._connection.read(nbytes)\n        if not data:\n            return None\n        buf[:len(data)] = data\n        return len(data)\n\n    def read(self, bufsiz, flags=0):\n        return self.recv(bufsiz, flags)\n\n    def write(self, buf, flags=0):\n        return self.sendall(buf, flags)\n\n    def close(self, reason=\"\"):\n        if self._makefile_refs < 1:\n            self.running = False\n            if not self.socket_closed:\n                socket.socket.close(self._sock)\n                self.socket_closed = True\n                if self._on_close:\n                    self._on_close(self.ip_str, self.sni, reason=reason)\n        else:\n            self._makefile_refs -= 1\n\n    def settimeout(self, t):\n        if not self.running:\n            return\n\n        if self.timeout != t:\n            self._sock.settimeout(t)\n            self.timeout = t\n\n    def makefile(self, mode='r', bufsize=-1):\n        self._makefile_refs += 1\n        return socket._fileobject(self, mode, bufsize, close=True)\n\n    def fileno(self):\n        return self._sock.fileno()\n\n\nclass SSLContext(object):\n    def __init__(self, logger, ca_certs=None, cipher_suites=None, support_http2=True, protocol=None):\n        self.logger = logger\n        self.context = self\n\n        self.settings = HandshakeSettings()\n\n        self.support_alpn_npn = None\n        self.alpn = []\n        if support_http2:\n            self.alpn = [\n                bytearray(b\"h2\"),\n            ]\n        self.alpn.append(bytearray(b\"http/1.1\"))\n\n    def supported_protocol(self):\n        return \"TLS 1.3\"\n\n    def support_alpn_npn(self):\n        return \"alpn\"\n\n\nclass SSLCert:\n    def __init__(self, cert):\n        \"\"\"\n            Returns a (common name, [subject alternative names]) tuple.\n        \"\"\"\n        self.x509 = cert\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/__init__.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhyper\n~~~~~~\n\nA module for providing an abstraction layer over the differences between\nHTTP/1.1 and HTTP/2.\n\"\"\"\n__version__ = '0.5.0'\n\nfrom .common.connection import HTTPConnection\nfrom .http20.connection import HTTP20Connection\nfrom .http20.response import HTTP20Response, HTTP20Push\nfrom .http11.connection import HTTP11Connection\nfrom .http11.response import HTTP11Response\n\n# Throw import errors on Python <2.7 and 3.0-3.2.\nimport sys as _sys\nif _sys.version_info < (2,7) or (3,0) <= _sys.version_info < (3,3):\n    raise ImportError(\"hyper only supports Python 2.7 and Python 3.3 or higher.\")\n\n__all__ = [\n    HTTPConnection,\n    HTTP20Response,\n    HTTP20Push,\n    HTTP20Connection,\n    HTTP11Connection,\n    HTTP11Response,\n]\n\n# Set default logging handler.\nimport logging\nlogging.getLogger(__name__).addHandler(logging.NullHandler())\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/certs.pem",
    "content": "\n# Issuer: O=Equifax OU=Equifax Secure Certificate Authority\n# Subject: O=Equifax OU=Equifax Secure Certificate Authority\n# Label: \"Equifax Secure CA\"\n# Serial: 903804111\n# MD5 Fingerprint: 67:cb:9d:c0:13:24:8a:82:9b:b2:17:1e:d1:1b:ec:d4\n# SHA1 Fingerprint: d2:32:09:ad:23:d3:14:23:21:74:e4:0d:7f:9d:62:13:97:86:63:3a\n# SHA256 Fingerprint: 08:29:7a:40:47:db:a2:36:80:c7:31:db:6e:31:76:53:ca:78:48:e1:be:bd:3a:0b:01:79:a7:07:f9:2c:f1:78\n-----BEGIN CERTIFICATE-----\nMIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV\nUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy\ndGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1\nMVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx\ndWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B\nAQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f\nBeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A\ncJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC\nAwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ\nMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm\naWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw\nODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj\nIBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF\nMAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA\nA4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y\n7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh\n1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4\n-----END CERTIFICATE-----\n\n# Issuer: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA\n# Subject: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA\n# Label: \"GlobalSign Root CA\"\n# Serial: 4835703278459707669005204\n# MD5 Fingerprint: 3e:45:52:15:09:51:92:e1:b7:5d:37:9f:b1:87:29:8a\n# SHA1 Fingerprint: b1:bc:96:8b:d4:f4:9d:62:2a:a8:9a:81:f2:15:01:52:a4:1d:82:9c\n# SHA256 Fingerprint: eb:d4:10:40:e4:bb:3e:c7:42:c9:e3:81:d3:1e:f2:a4:1a:48:b6:68:5c:96:e7:ce:f3:c1:df:6c:d4:33:1c:99\n-----BEGIN CERTIFICATE-----\nMIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG\nA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv\nb3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw\nMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i\nYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT\naWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ\njc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp\nxy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp\n1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG\nsnUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ\nU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8\n9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E\nBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B\nAQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz\nyj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE\n38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP\nAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad\nDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME\nHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==\n-----END CERTIFICATE-----\n\n# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2\n# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2\n# Label: \"GlobalSign Root CA - R2\"\n# Serial: 4835703278459682885658125\n# MD5 Fingerprint: 94:14:77:7e:3e:5e:fd:8f:30:bd:41:b0:cf:e7:d0:30\n# SHA1 Fingerprint: 75:e0:ab:b6:13:85:12:27:1c:04:f8:5f:dd:de:38:e4:b7:24:2e:fe\n# SHA256 Fingerprint: ca:42:dd:41:74:5f:d0:b8:1e:b9:02:36:2c:f9:d8:bf:71:9d:a1:bd:1b:1e:fc:94:6f:5b:4c:99:f4:2c:1b:9e\n-----BEGIN CERTIFICATE-----\nMIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G\nA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp\nZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1\nMDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG\nA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI\nhvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL\nv4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8\neoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq\ntTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd\nC9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa\nzq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB\nmTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH\nV2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n\nbG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG\n3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs\nJ0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO\n291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS\not+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd\nAfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7\nTBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==\n-----END CERTIFICATE-----\n\n# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only\n# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only\n# Label: \"Verisign Class 3 Public Primary Certification Authority - G3\"\n# Serial: 206684696279472310254277870180966723415\n# MD5 Fingerprint: cd:68:b6:a7:c7:c4:ce:75:e0:1d:4f:57:44:61:92:09\n# SHA1 Fingerprint: 13:2d:0d:45:53:4b:69:97:cd:b2:d5:c3:39:e2:55:76:60:9b:5c:c6\n# SHA256 Fingerprint: eb:04:cf:5e:b1:f3:9a:fa:76:2f:2b:b1:20:f2:96:cb:a5:20:c1:b9:7d:b1:58:95:65:b8:1c:b9:a1:7b:72:44\n-----BEGIN CERTIFICATE-----\nMIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQsw\nCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl\ncmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu\nLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT\naWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp\ndHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD\nVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT\naWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ\nbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu\nIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg\nLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMu6nFL8eB8aHm8b\nN3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1EUGO+i2t\nKmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGu\nkxUccLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBm\nCC+Vk7+qRy+oRpfwEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJ\nXwzw3sJ2zq/3avL6QaaiMxTJ5Xpj055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWu\nimi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAERSWwauSCPc/L8my/uRan2Te\n2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5fj267Cz3qWhMe\nDGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC\n/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565p\nF4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt\nTxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ==\n-----END CERTIFICATE-----\n\n# Issuer: CN=VeriSign Class 4 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only\n# Subject: CN=VeriSign Class 4 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only\n# Label: \"Verisign Class 4 Public Primary Certification Authority - G3\"\n# Serial: 314531972711909413743075096039378935511\n# MD5 Fingerprint: db:c8:f2:27:2e:b1:ea:6a:29:23:5d:fe:56:3e:33:df\n# SHA1 Fingerprint: c8:ec:8c:87:92:69:cb:4b:ab:39:e9:8d:7e:57:67:f3:14:95:73:9d\n# SHA256 Fingerprint: e3:89:36:0d:0f:db:ae:b3:d2:50:58:4b:47:30:31:4e:22:2f:39:c1:56:a0:20:14:4e:8d:96:05:61:79:15:06\n-----BEGIN CERTIFICATE-----\nMIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQsw\nCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl\ncmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu\nLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT\naWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp\ndHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD\nVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT\naWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ\nbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu\nIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg\nLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK3LpRFpxlmr8Y+1\nGQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaStBO3IFsJ\n+mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0Gbd\nU6LM8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLm\nNxdLMEYH5IBtptiWLugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XY\nufTsgsbSPZUd5cBPhMnZo0QoBmrXRazwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/\nky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAj/ola09b5KROJ1WrIhVZPMq1\nCtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXttmhwwjIDLk5Mq\ng6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm\nfjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c\n2NU8Qh0XwRJdRTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/\nbLvSHgCwIe34QWKCudiyxLtGUPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg==\n-----END CERTIFICATE-----\n\n# Issuer: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited\n# Subject: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited\n# Label: \"Entrust.net Premium 2048 Secure Server CA\"\n# Serial: 946069240\n# MD5 Fingerprint: ee:29:31:bc:32:7e:9a:e6:e8:b5:f7:51:b4:34:71:90\n# SHA1 Fingerprint: 50:30:06:09:1d:97:d4:f5:ae:39:f7:cb:e7:92:7d:7d:65:2d:34:31\n# SHA256 Fingerprint: 6d:c4:71:72:e0:1c:bc:b0:bf:62:58:0d:89:5f:e2:b8:ac:9a:d4:f8:73:80:1e:0c:10:b9:c8:37:d2:1e:b1:77\n-----BEGIN CERTIFICATE-----\nMIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML\nRW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp\nbmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5\nIEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp\nZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3\nMjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3\nLmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp\nYWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG\nA1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq\nK0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe\nsYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX\nMlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT\nXTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/\nHoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH\n4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV\nHQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub\nj1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo\nU8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf\nzX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b\nu/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+\nbYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er\nfF6adulZkMV8gzURZVE=\n-----END CERTIFICATE-----\n\n# Issuer: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust\n# Subject: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust\n# Label: \"Baltimore CyberTrust Root\"\n# Serial: 33554617\n# MD5 Fingerprint: ac:b6:94:a5:9c:17:e0:d7:91:52:9b:b1:97:06:a6:e4\n# SHA1 Fingerprint: d4:de:20:d0:5e:66:fc:53:fe:1a:50:88:2c:78:db:28:52:ca:e4:74\n# SHA256 Fingerprint: 16:af:57:a9:f6:76:b0:ab:12:60:95:aa:5e:ba:de:f2:2a:b3:11:19:d6:44:ac:95:cd:4b:93:db:f3:f2:6a:eb\n-----BEGIN CERTIFICATE-----\nMIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ\nRTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD\nVQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX\nDTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y\nZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy\nVHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr\nmD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr\nIZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK\nmpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu\nXmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy\ndc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye\njl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1\nBE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3\nDQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92\n9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx\njkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0\nEpn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz\nksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS\nR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp\n-----END CERTIFICATE-----\n\n# Issuer: CN=Equifax Secure Global eBusiness CA-1 O=Equifax Secure Inc.\n# Subject: CN=Equifax Secure Global eBusiness CA-1 O=Equifax Secure Inc.\n# Label: \"Equifax Secure Global eBusiness CA\"\n# Serial: 1\n# MD5 Fingerprint: 8f:5d:77:06:27:c4:98:3c:5b:93:78:e7:d7:7d:9b:cc\n# SHA1 Fingerprint: 7e:78:4a:10:1c:82:65:cc:2d:e1:f1:6d:47:b4:40:ca:d9:0a:19:45\n# SHA256 Fingerprint: 5f:0b:62:ea:b5:e3:53:ea:65:21:65:16:58:fb:b6:53:59:f4:43:28:0a:4a:fb:d1:04:d7:7d:10:f9:f0:4c:07\n-----BEGIN CERTIFICATE-----\nMIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEc\nMBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBT\nZWN1cmUgR2xvYmFsIGVCdXNpbmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIw\nMDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0VxdWlmYXggU2Vj\ndXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEdsb2JhbCBlQnVzaW5l\nc3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRVPEnC\nUdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc\n58O/gGzNqfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/\no5brhTMhHD4ePmBudpxnhcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAH\nMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUvqigdHJQa0S3ySPY+6j/s1dr\naGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hsMA0GCSqGSIb3DQEBBAUA\nA4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okENI7SS+RkA\nZ70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv\n8qIYNMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV\n-----END CERTIFICATE-----\n\n# Issuer: CN=AddTrust Class 1 CA Root O=AddTrust AB OU=AddTrust TTP Network\n# Subject: CN=AddTrust Class 1 CA Root O=AddTrust AB OU=AddTrust TTP Network\n# Label: \"AddTrust Low-Value Services Root\"\n# Serial: 1\n# MD5 Fingerprint: 1e:42:95:02:33:92:6b:b9:5f:c0:7f:da:d6:b2:4b:fc\n# SHA1 Fingerprint: cc:ab:0e:a0:4c:23:01:d6:69:7b:dd:37:9f:cd:12:eb:24:e3:94:9d\n# SHA256 Fingerprint: 8c:72:09:27:9a:c0:4e:27:5e:16:d0:7f:d3:b7:75:e8:01:54:b5:96:80:46:e3:1f:52:dd:25:76:63:24:e9:a7\n-----BEGIN CERTIFICATE-----\nMIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEU\nMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3\nb3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMw\nMTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML\nQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYD\nVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUA\nA4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ul\nCDtbKRY654eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6n\ntGO0/7Gcrjyvd7ZWxbWroulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyl\ndI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1Zmne3yzxbrww2ywkEtvrNTVokMsAsJch\nPXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJuiGMx1I4S+6+JNM3GOGvDC\n+Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8wHQYDVR0O\nBBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8E\nBTADAQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBl\nMQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFk\nZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENB\nIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxtZBsfzQ3duQH6lmM0MkhHma6X\n7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0PhiVYrqW9yTkkz\n43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY\neDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJl\npz/+0WatC7xrmYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOA\nWiFeIc9TVPC6b4nbqKqVz4vjccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk=\n-----END CERTIFICATE-----\n\n# Issuer: CN=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network\n# Subject: CN=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network\n# Label: \"AddTrust External Root\"\n# Serial: 1\n# MD5 Fingerprint: 1d:35:54:04:85:78:b0:3f:42:42:4d:bf:20:73:0a:3f\n# SHA1 Fingerprint: 02:fa:f3:e2:91:43:54:68:60:78:57:69:4d:f5:e4:5b:68:85:18:68\n# SHA256 Fingerprint: 68:7f:a4:51:38:22:78:ff:f0:c8:b1:1f:8d:43:d5:76:67:1c:6e:b2:bc:ea:b4:13:fb:83:d9:65:d0:6d:2f:f2\n-----BEGIN CERTIFICATE-----\nMIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU\nMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs\nIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290\nMB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux\nFDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h\nbCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v\ndDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt\nH7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9\nuMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX\nmk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX\na0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN\nE0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0\nWicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD\nVR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0\nJvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU\ncnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx\nIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN\nAQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH\nYINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5\n6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC\nNr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX\nc4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a\nmnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=\n-----END CERTIFICATE-----\n\n# Issuer: CN=AddTrust Public CA Root O=AddTrust AB OU=AddTrust TTP Network\n# Subject: CN=AddTrust Public CA Root O=AddTrust AB OU=AddTrust TTP Network\n# Label: \"AddTrust Public Services Root\"\n# Serial: 1\n# MD5 Fingerprint: c1:62:3e:23:c5:82:73:9c:03:59:4b:2b:e9:77:49:7f\n# SHA1 Fingerprint: 2a:b6:28:48:5e:78:fb:f3:ad:9e:79:10:dd:6b:df:99:72:2c:96:e5\n# SHA256 Fingerprint: 07:91:ca:07:49:b2:07:82:aa:d3:c7:d7:bd:0c:df:c9:48:58:35:84:3e:b2:d7:99:60:09:ce:43:ab:6c:69:27\n-----BEGIN CERTIFICATE-----\nMIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJTRTEU\nMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3\nb3JrMSAwHgYDVQQDExdBZGRUcnVzdCBQdWJsaWMgQ0EgUm9vdDAeFw0wMDA1MzAx\nMDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtB\nZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIDAeBgNV\nBAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOC\nAQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+A3S72mnTRqX4jsIMEZBRpS9mVEBV\n6tsfSlbunyNu9DnLoblv8n75XYcmYZ4c+OLspoH4IcUkzBEMP9smcnrHAZcHF/nX\nGCwwfQ56HmIexkvA/X1id9NEHif2P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnP\ndzRGULD4EfL+OHn3Bzn+UZKXC1sIXzSGAa2Il+tmzV7R/9x98oTaunet3IAIx6eH\n1lWfl2royBFkuucZKT8Rs3iQhCBSWxHveNCD9tVIkNAwHM+A+WD+eeSI8t0A65RF\n62WUaUC6wNW0uLp9BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0GA1UdDgQW\nBBSBPjfYkrAfd59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUw\nAwEB/zCBjgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDEL\nMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRU\ncnVzdCBUVFAgTmV0d29yazEgMB4GA1UEAxMXQWRkVHJ1c3QgUHVibGljIENBIFJv\nb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4JNojVhaTdt02KLmuG7jD8WS6\nIBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL+YPoRNWyQSW/\niHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbjPGsye/Kf8Lb93/Ao\nGEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bYGozH7ZxOmuASu7VqTITh\n4SINhwBk/ox9Yjllpu9CtoAlEmEBqCQTcAARJl/6NVDFSMwGR+gn2HCNX2TmoUQm\nXiLsks3/QppEIW1cxeMiHV9HEufOX1362KqxMy3ZdvJOOjMMK7MtkAY=\n-----END CERTIFICATE-----\n\n# Issuer: CN=AddTrust Qualified CA Root O=AddTrust AB OU=AddTrust TTP Network\n# Subject: CN=AddTrust Qualified CA Root O=AddTrust AB OU=AddTrust TTP Network\n# Label: \"AddTrust Qualified Certificates Root\"\n# Serial: 1\n# MD5 Fingerprint: 27:ec:39:47:cd:da:5a:af:e2:9a:01:65:21:a9:4c:bb\n# SHA1 Fingerprint: 4d:23:78:ec:91:95:39:b5:00:7f:75:8f:03:3b:21:1e:c5:4d:8b:cf\n# SHA256 Fingerprint: 80:95:21:08:05:db:4b:bc:35:5e:44:28:d8:fd:6e:c2:cd:e3:ab:5f:b9:7a:99:42:98:8e:b8:f4:dc:d0:60:16\n-----BEGIN CERTIFICATE-----\nMIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEU\nMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3\nb3JrMSMwIQYDVQQDExpBZGRUcnVzdCBRdWFsaWZpZWQgQ0EgUm9vdDAeFw0wMDA1\nMzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcxCzAJBgNVBAYTAlNFMRQwEgYDVQQK\nEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIzAh\nBgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290MIIBIjANBgkqhkiG9w0B\nAQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoekn0e+EV+vhDTbYjx5eLfpMLXsDBwq\nxBb/4Oxx64r1EW7tTw2R0hIYLUkVAcKkIhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G\n87B4pfYOQnrjfxvM0PC3KP0q6p6zsLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i\n2O+tCBGaKZnhqkRFmhJePp1tUvznoD1oL/BLcHwTOK28FSXx1s6rosAx1i+f4P8U\nWfyEk9mHfExUE+uf0S0R+Bg6Ot4l2ffTQO2kBhLEO+GRwVY18BTcZTYJbqukB8c1\n0cIDMzZbdSZtQvESa0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HUMIHRMB0G\nA1UdDgQWBBQ5lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0T\nAQH/BAUwAwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6Fr\npGkwZzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQL\nExRBZGRUcnVzdCBUVFAgTmV0d29yazEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVhbGlm\naWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBABmrder4i2VhlRO6aQTv\nhsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxGGuoYQ992zPlm\nhpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx95dr6h+sNNVJn0J6X\ndgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKFYqa0p9m9N5xotS1WfbC3\nP6CxB9bpT9zeRXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9Y\niQBCYz95OdBEsIJuQRno3eDBiFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5no\nxqE=\n-----END CERTIFICATE-----\n\n# Issuer: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc.\n# Subject: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc.\n# Label: \"Entrust Root Certification Authority\"\n# Serial: 1164660820\n# MD5 Fingerprint: d6:a5:c3:ed:5d:dd:3e:00:c1:3d:87:92:1f:1d:3f:e4\n# SHA1 Fingerprint: b3:1e:b1:b7:40:e3:6c:84:02:da:dc:37:d4:4d:f5:d4:67:49:52:f9\n# SHA256 Fingerprint: 73:c1:76:43:4f:1b:c6:d5:ad:f4:5b:0e:76:e7:27:28:7c:8d:e5:76:16:c1:e6:e6:14:1a:2b:2c:bc:7d:8e:4c\n-----BEGIN CERTIFICATE-----\nMIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC\nVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0\nLm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW\nKGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl\ncnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw\nNTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw\nNwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy\nZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV\nBAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ\nKoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo\nNu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4\n4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9\nKlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI\nrb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi\n94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB\nsDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi\ngA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo\nkORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE\nvW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA\nA4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t\nO1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua\nAGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP\n9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/\neu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m\n0vdXcDazv/wor3ElhVsT/h5/WrQ8\n-----END CERTIFICATE-----\n\n# Issuer: O=RSA Security Inc OU=RSA Security 2048 V3\n# Subject: O=RSA Security Inc OU=RSA Security 2048 V3\n# Label: \"RSA Security 2048 v3\"\n# Serial: 13297492616345471454730593562152402946\n# MD5 Fingerprint: 77:0d:19:b1:21:fd:00:42:9c:3e:0c:a5:dd:0b:02:8e\n# SHA1 Fingerprint: 25:01:90:19:cf:fb:d9:99:1c:b7:68:25:74:8d:94:5f:30:93:95:42\n# SHA256 Fingerprint: af:8b:67:62:a1:e5:28:22:81:61:a9:5d:5c:55:9e:e2:66:27:8f:75:d7:9e:83:01:89:a5:03:50:6a:bd:6b:4c\n-----BEGIN CERTIFICATE-----\nMIIDYTCCAkmgAwIBAgIQCgEBAQAAAnwAAAAKAAAAAjANBgkqhkiG9w0BAQUFADA6\nMRkwFwYDVQQKExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0EgU2VjdXJp\ndHkgMjA0OCBWMzAeFw0wMTAyMjIyMDM5MjNaFw0yNjAyMjIyMDM5MjNaMDoxGTAX\nBgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAbBgNVBAsTFFJTQSBTZWN1cml0eSAy\nMDQ4IFYzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt49VcdKA3Xtp\neafwGFAyPGJn9gqVB93mG/Oe2dJBVGutn3y+Gc37RqtBaB4Y6lXIL5F4iSj7Jylg\n/9+PjDvJSZu1pJTOAeo+tWN7fyb9Gd3AIb2E0S1PRsNO3Ng3OTsor8udGuorryGl\nwSMiuLgbWhOHV4PR8CDn6E8jQrAApX2J6elhc5SYcSa8LWrg903w8bYqODGBDSnh\nAMFRD0xS+ARaqn1y07iHKrtjEAMqs6FPDVpeRrc9DvV07Jmf+T0kgYim3WBU6JU2\nPcYJk5qjEoAAVZkZR73QpXzDuvsf9/UP+Ky5tfQ3mBMY3oVbtwyCO4dvlTlYMNpu\nAWgXIszACwIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB\nBjAfBgNVHSMEGDAWgBQHw1EwpKrpRa41JPr/JCwz0LGdjDAdBgNVHQ4EFgQUB8NR\nMKSq6UWuNST6/yQsM9CxnYwwDQYJKoZIhvcNAQEFBQADggEBAF8+hnZuuDU8TjYc\nHnmYv/3VEhF5Ug7uMYm83X/50cYVIeiKAVQNOvtUudZj1LGqlk2iQk3UUx+LEN5/\nZb5gEydxiKRz44Rj0aRV4VCT5hsOedBnvEbIvz8XDZXmxpBp3ue0L96VfdASPz0+\nf00/FGj1EVDVwfSQpQgdMWD/YIwjVAqv/qFuxdF6Kmh4zx6CCiC0H63lhbJqaHVO\nrSU3lIW+vaHU6rcMSzyd6BIA8F+sDeGscGNz9395nzIlQnQFgCi/vcEkllgVsRch\n6YlL2weIZ/QVrXA+L02FO8K32/6YaCOJ4XQP3vTFhGMpG8zLB8kApKnXwiJPZ9d3\n7CAFYd4=\n-----END CERTIFICATE-----\n\n# Issuer: CN=GeoTrust Global CA O=GeoTrust Inc.\n# Subject: CN=GeoTrust Global CA O=GeoTrust Inc.\n# Label: \"GeoTrust Global CA\"\n# Serial: 144470\n# MD5 Fingerprint: f7:75:ab:29:fb:51:4e:b7:77:5e:ff:05:3c:99:8e:f5\n# SHA1 Fingerprint: de:28:f4:a4:ff:e5:b9:2f:a3:c5:03:d1:a3:49:a7:f9:96:2a:82:12\n# SHA256 Fingerprint: ff:85:6a:2d:25:1d:cd:88:d3:66:56:f4:50:12:67:98:cf:ab:aa:de:40:79:9c:72:2d:e4:d2:b5:db:36:a7:3a\n-----BEGIN CERTIFICATE-----\nMIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT\nMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i\nYWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG\nEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg\nR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9\n9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq\nfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv\niS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU\n1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+\nbw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW\nMPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA\nephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l\nuMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn\nZ57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS\ntQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF\nPseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un\nhw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV\n5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==\n-----END CERTIFICATE-----\n\n# Issuer: CN=GeoTrust Global CA 2 O=GeoTrust Inc.\n# Subject: CN=GeoTrust Global CA 2 O=GeoTrust Inc.\n# Label: \"GeoTrust Global CA 2\"\n# Serial: 1\n# MD5 Fingerprint: 0e:40:a7:6c:de:03:5d:8f:d1:0f:e4:d1:8d:f9:6c:a9\n# SHA1 Fingerprint: a9:e9:78:08:14:37:58:88:f2:05:19:b0:6d:2b:0d:2b:60:16:90:7d\n# SHA256 Fingerprint: ca:2d:82:a0:86:77:07:2f:8a:b6:76:4f:f0:35:67:6c:fe:3e:5e:32:5e:01:21:72:df:3f:92:09:6d:b7:9b:85\n-----BEGIN CERTIFICATE-----\nMIIDZjCCAk6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJVUzEW\nMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFs\nIENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMTkwMzA0MDUwMDAwWjBEMQswCQYDVQQG\nEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3Qg\nR2xvYmFsIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDvPE1A\nPRDfO1MA4Wf+lGAVPoWI8YkNkMgoI5kF6CsgncbzYEbYwbLVjDHZ3CB5JIG/NTL8\nY2nbsSpr7iFY8gjpeMtvy/wWUsiRxP89c96xPqfCfWbB9X5SJBri1WeR0IIQ13hL\nTytCOb1kLUCgsBDTOEhGiKEMuzozKmKY+wCdE1l/bztyqu6mD4b5BWHqZ38MN5aL\n5mkWRxHCJ1kDs6ZgwiFAVvqgx306E+PsV8ez1q6diYD3Aecs9pYrEw15LNnA5IZ7\nS4wMcoKK+xfNAGw6EzywhIdLFnopsk/bHdQL82Y3vdj2V7teJHq4PIu5+pIaGoSe\n2HSPqht/XvT+RSIhAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE\nFHE4NvICMVNHK266ZUapEBVYIAUJMB8GA1UdIwQYMBaAFHE4NvICMVNHK266ZUap\nEBVYIAUJMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAQEAA/e1K6td\nEPx7srJerJsOflN4WT5CBP51o62sgU7XAotexC3IUnbHLB/8gTKY0UvGkpMzNTEv\n/NgdRN3ggX+d6YvhZJFiCzkIjKx0nVnZellSlxG5FntvRdOW2TF9AjYPnDtuzywN\nA0ZF66D0f0hExghAzN4bcLUprbqLOzRldRtxIR0sFAqwlpW41uryZfspuk/qkZN0\nabby/+Ea0AzRdoXLiiW9l14sbxWZJue2Kf8i7MkCx1YAzUm5s2x7UwQa4qjJqhIF\nI8LO57sEAszAR6LkxCkvW0VXiVHuPOtSCP8HNR6fNWpHSlaY0VqFH4z1Ir+rzoPz\n4iIprn2DQKi6bA==\n-----END CERTIFICATE-----\n\n# Issuer: CN=GeoTrust Universal CA O=GeoTrust Inc.\n# Subject: CN=GeoTrust Universal CA O=GeoTrust Inc.\n# Label: \"GeoTrust Universal CA\"\n# Serial: 1\n# MD5 Fingerprint: 92:65:58:8b:a2:1a:31:72:73:68:5c:b4:a5:7a:07:48\n# SHA1 Fingerprint: e6:21:f3:35:43:79:05:9a:4b:68:30:9d:8a:2f:74:22:15:87:ec:79\n# SHA256 Fingerprint: a0:45:9b:9f:63:b2:25:59:f5:fa:5d:4c:6d:b3:f9:f7:2f:f1:93:42:03:35:78:f0:73:bf:1d:1b:46:cb:b9:12\n-----BEGIN CERTIFICATE-----\nMIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEW\nMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVy\nc2FsIENBMB4XDTA0MDMwNDA1MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UE\nBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xHjAcBgNVBAMTFUdlb1RydXN0\nIFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKYV\nVaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9tJPi8\ncQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTT\nQjOgNB0eRXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFh\nF7em6fgemdtzbvQKoiFs7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2v\nc7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d8Lsrlh/eezJS/R27tQahsiFepdaVaH/w\nmZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7VqnJNk22CDtucvc+081xd\nVHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3CgaRr0BHdCX\nteGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZ\nf9hBZ3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfRe\nBi9Fi1jUIxaS5BZuKGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+\nnhutxx9z3SxPGWX9f5NAEC7S8O08ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB\n/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0XG0D08DYj3rWMB8GA1UdIwQY\nMBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG\n9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc\naanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fX\nIwjhmF7DWgh2qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzyn\nANXH/KttgCJwpQzgXQQpAvvLoJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0z\nuzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsKxr2EoyNB3tZ3b4XUhRxQ4K5RirqN\nPnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxFKyDuSN/n3QmOGKja\nQI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2DFKW\nkoRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9\nER/frslKxfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQt\nDF4JbAiXfKM9fJP/P6EUp8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/Sfuvm\nbJxPgWp6ZKy7PtXny3YuxadIwVyQD8vIP/rmMuGNG2+k5o7Y+SlIis5z/iw=\n-----END CERTIFICATE-----\n\n# Issuer: CN=GeoTrust Universal CA 2 O=GeoTrust Inc.\n# Subject: CN=GeoTrust Universal CA 2 O=GeoTrust Inc.\n# Label: \"GeoTrust Universal CA 2\"\n# Serial: 1\n# MD5 Fingerprint: 34:fc:b8:d0:36:db:9e:14:b3:c2:f2:db:8f:e4:94:c7\n# SHA1 Fingerprint: 37:9a:19:7b:41:85:45:35:0c:a6:03:69:f3:3c:2e:af:47:4f:20:79\n# SHA256 Fingerprint: a0:23:4f:3b:c8:52:7c:a5:62:8e:ec:81:ad:5d:69:89:5d:a5:68:0d:c9:1d:1c:b8:47:7f:33:f8:78:b9:5b:0b\n-----BEGIN CERTIFICATE-----\nMIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEW\nMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVy\nc2FsIENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYD\nVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1\nc3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC\nAQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0DE81\nWzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUG\nFF+3Qs17j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdq\nXbboW0W63MOhBW9Wjo8QJqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxL\nse4YuU6W3Nx2/zu+z18DwPw76L5GG//aQMJS9/7jOvdqdzXQ2o3rXhhqMcceujwb\nKNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2WP0+GfPtDCapkzj4T8Fd\nIgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP20gaXT73\ny/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRt\nhAAnZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgoc\nQIgfksILAAX/8sgCSqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4\nLt1ZrtmhN79UNdxzMk+MBB4zsslG8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNV\nHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAfBgNV\nHSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8EBAMCAYYwDQYJ\nKoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z\ndXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQ\nL1EuxBRa3ugZ4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgr\nFg5fNuH8KrUwJM/gYwx7WBr+mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSo\nag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpqA1Ihn0CoZ1Dy81of398j9tx4TuaY\nT1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpgY+RdM4kX2TGq2tbz\nGDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiPpm8m\n1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJV\nOCiNUW7dFGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH\n6aLcr34YEoP9VhdBLtUpgn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwX\nQMAJKOSLakhT2+zNVVXxxvjpoixMptEmX36vWkzaH6byHCx+rgIW0lbQL1dTR+iS\n-----END CERTIFICATE-----\n\n# Issuer: CN=Visa eCommerce Root O=VISA OU=Visa International Service Association\n# Subject: CN=Visa eCommerce Root O=VISA OU=Visa International Service Association\n# Label: \"Visa eCommerce Root\"\n# Serial: 25952180776285836048024890241505565794\n# MD5 Fingerprint: fc:11:b8:d8:08:93:30:00:6d:23:f9:7e:eb:52:1e:02\n# SHA1 Fingerprint: 70:17:9b:86:8c:00:a4:fa:60:91:52:22:3f:9f:3e:32:bd:e0:05:62\n# SHA256 Fingerprint: 69:fa:c9:bd:55:fb:0a:c7:8d:53:bb:ee:5c:f1:d5:97:98:9f:d0:aa:ab:20:a2:51:51:bd:f1:73:3e:e7:d1:22\n-----BEGIN CERTIFICATE-----\nMIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBr\nMQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRl\ncm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv\nbW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2WhcNMjIwNjI0MDAxNjEyWjBrMQsw\nCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5h\ndGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1l\ncmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h\n2mCxlCfLF9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4E\nlpF7sDPwsRROEW+1QK8bRaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdV\nZqW1LS7YgFmypw23RuwhY/81q6UCzyr0TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq\n299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI/k4+oKsGGelT84ATB+0t\nvz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzsGHxBvfaL\ndXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD\nAgEGMB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUF\nAAOCAQEAX/FBfXxcCLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcR\nzCSs00Rsca4BIGsDoo8Ytyk6feUWYFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3\nLBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pzzkWKsKZJ/0x9nXGIxHYdkFsd\n7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBuYQa7FkKMcPcw\n++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt\n398znM/jra6O1I7mT1GvFpLgXPYHDw==\n-----END CERTIFICATE-----\n\n# Issuer: CN=Certum CA O=Unizeto Sp. z o.o.\n# Subject: CN=Certum CA O=Unizeto Sp. z o.o.\n# Label: \"Certum Root CA\"\n# Serial: 65568\n# MD5 Fingerprint: 2c:8f:9f:66:1d:18:90:b1:47:26:9d:8e:86:82:8c:a9\n# SHA1 Fingerprint: 62:52:dc:40:f7:11:43:a2:2f:de:9e:f7:34:8e:06:42:51:b1:81:18\n# SHA256 Fingerprint: d8:e0:fe:bc:1d:b2:e3:8d:00:94:0f:37:d2:7d:41:34:4d:99:3e:73:4b:99:d5:65:6d:97:78:d4:d8:14:36:24\n-----BEGIN CERTIFICATE-----\nMIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBM\nMRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD\nQTAeFw0wMjA2MTExMDQ2MzlaFw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBM\nMRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD\nQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6xwS7TT3zNJc4YPk/E\njG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdLkKWo\nePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GI\nULdtlkIJ89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapu\nOb7kky/ZR6By6/qmW6/KUz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUg\nAKpoC6EahQGcxEZjgoi2IrHu/qpGWX7PNSzVttpd90gzFFS269lvzs2I1qsb2pY7\nHVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEA\nuI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+GXYkHAQa\nTOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTg\nxSvgGrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1q\nCjqTE5s7FCMTY5w/0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5x\nO/fIR/RpbxXyEV6DHpx8Uq79AtoSqFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs\n6GAqm4VKQPNriiTsBhYscw==\n-----END CERTIFICATE-----\n\n# Issuer: CN=AAA Certificate Services O=Comodo CA Limited\n# Subject: CN=AAA Certificate Services O=Comodo CA Limited\n# Label: \"Comodo AAA Services root\"\n# Serial: 1\n# MD5 Fingerprint: 49:79:04:b0:eb:87:19:ac:47:b0:bc:11:51:9b:74:d0\n# SHA1 Fingerprint: d1:eb:23:a4:6d:17:d6:8f:d9:25:64:c2:f1:f1:60:17:64:d8:e3:49\n# SHA256 Fingerprint: d7:a7:a0:fb:5d:7e:27:31:d7:71:e9:48:4e:bc:de:f7:1d:5f:0c:3e:0a:29:48:78:2b:c8:3e:e0:ea:69:9e:f4\n-----BEGIN CERTIFICATE-----\nMIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb\nMBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow\nGAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj\nYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL\nMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE\nBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM\nGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP\nADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua\nBtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe\n3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4\nYgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR\nrOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm\nez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU\noBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF\nMAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v\nQUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t\nb2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF\nAAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q\nGE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz\nRt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2\nG9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi\nl2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3\nsmPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==\n-----END CERTIFICATE-----\n\n# Issuer: CN=Secure Certificate Services O=Comodo CA Limited\n# Subject: CN=Secure Certificate Services O=Comodo CA Limited\n# Label: \"Comodo Secure Services root\"\n# Serial: 1\n# MD5 Fingerprint: d3:d9:bd:ae:9f:ac:67:24:b3:c8:1b:52:e1:b9:a9:bd\n# SHA1 Fingerprint: 4a:65:d5:f4:1d:ef:39:b8:b8:90:4a:4a:d3:64:81:33:cf:c7:a1:d1\n# SHA256 Fingerprint: bd:81:ce:3b:4f:65:91:d1:1a:67:b5:fc:7a:47:fd:ef:25:52:1b:f9:aa:4e:18:b9:e3:df:2e:34:a7:80:3b:e8\n-----BEGIN CERTIFICATE-----\nMIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEb\nMBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow\nGAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRp\nZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVow\nfjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G\nA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAiBgNV\nBAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEB\nBQADggEPADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPM\ncm3ye5drswfxdySRXyWP9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3S\nHpR7LZQdqnXXs5jLrLxkU0C8j6ysNstcrbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996\nCF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rCoznl2yY4rYsK7hljxxwk\n3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3Vp6ea5EQz\n6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNV\nHQ4EFgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1Ud\nEwEB/wQFMAMBAf8wgYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2Rv\nY2EuY29tL1NlY3VyZUNlcnRpZmljYXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRw\nOi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmww\nDQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm4J4oqF7Tt/Q0\n5qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj\nZ55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtI\ngKvcnDe4IRRLDXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJ\naD61JlfutuC23bkpgHl9j6PwpCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDl\nizeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1HRR3B7Hzs/Sk=\n-----END CERTIFICATE-----\n\n# Issuer: CN=Trusted Certificate Services O=Comodo CA Limited\n# Subject: CN=Trusted Certificate Services O=Comodo CA Limited\n# Label: \"Comodo Trusted Services root\"\n# Serial: 1\n# MD5 Fingerprint: 91:1b:3f:6e:cd:9e:ab:ee:07:fe:1f:71:d2:b3:61:27\n# SHA1 Fingerprint: e1:9f:e3:0e:8b:84:60:9e:80:9b:17:0d:72:a8:c5:ba:6e:14:09:bd\n# SHA256 Fingerprint: 3f:06:e5:56:81:d4:96:f5:be:16:9e:b5:38:9f:9f:2b:8f:f6:1e:17:08:df:68:81:72:48:49:cd:5d:27:cb:69\n-----BEGIN CERTIFICATE-----\nMIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEb\nMBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow\nGAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0\naWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEwMDAwMDBaFw0yODEyMzEyMzU5NTla\nMH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO\nBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUwIwYD\nVQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0B\nAQEFAAOCAQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWW\nfnJSoBVC21ndZHoa0Lh73TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMt\nTGo87IvDktJTdyR0nAducPy9C1t2ul/y/9c3S0pgePfw+spwtOpZqqPOSC+pw7IL\nfhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6juljatEPmsbS9Is6FARW\n1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsSivnkBbA7\nkUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0G\nA1UdDgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYD\nVR0TAQH/BAUwAwEB/zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21v\nZG9jYS5jb20vVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRo\ndHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMu\nY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8NtwuleGFTQQuS9/\nHrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32\npSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxIS\njBc/lDb+XbDABHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+\nxqFx7D+gIIxmOom0jtTYsU0lR+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/Atyjcn\ndBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O9y5Xt5hwXsjEeLBi\n-----END CERTIFICATE-----\n\n# Issuer: CN=QuoVadis Root Certification Authority O=QuoVadis Limited OU=Root Certification Authority\n# Subject: CN=QuoVadis Root Certification Authority O=QuoVadis Limited OU=Root Certification Authority\n# Label: \"QuoVadis Root CA\"\n# Serial: 985026699\n# MD5 Fingerprint: 27:de:36:fe:72:b7:00:03:00:9d:f4:f0:1e:6c:04:24\n# SHA1 Fingerprint: de:3f:40:bd:50:93:d3:9b:6c:60:f6:da:bc:07:62:01:00:89:76:c9\n# SHA256 Fingerprint: a4:5e:de:3b:bb:f0:9c:8a:e1:5c:72:ef:c0:72:68:d6:93:a2:1c:99:6f:d5:1e:67:ca:07:94:60:fd:6d:88:73\n-----BEGIN CERTIFICATE-----\nMIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJC\nTTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0\naWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0\naWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAzMTkxODMzMzNaFw0yMTAzMTcxODMz\nMzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUw\nIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVR\ndW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG\n9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Yp\nli4kVEAkOPcahdxYTMukJ0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2D\nrOpm2RgbaIr1VxqYuvXtdj182d6UajtLF8HVj71lODqV0D1VNk7feVcxKh7YWWVJ\nWCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeLYzcS19Dsw3sgQUSj7cug\nF+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWenAScOospU\nxbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCC\nAk4wPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVv\ndmFkaXNvZmZzaG9yZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREw\nggENMIIBCQYJKwYBBAG+WAABMIH7MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNl\nIG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBh\nc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFy\nZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh\nY3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYI\nKwYBBQUHAgEWFmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3T\nKbkGGew5Oanwl4Rqy+/fMIGuBgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rq\ny+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1p\ndGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYD\nVQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6tlCL\nMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSk\nfnIYj9lofFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf8\n7C9TqnN7Az10buYWnuulLsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1R\ncHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2xgI4JVrmcGmD+XcHXetwReNDWXcG31a0y\nmQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi5upZIof4l/UO/erMkqQW\nxFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi5nrQNiOK\nSnQ2+Q==\n-----END CERTIFICATE-----\n\n# Issuer: CN=QuoVadis Root CA 2 O=QuoVadis Limited\n# Subject: CN=QuoVadis Root CA 2 O=QuoVadis Limited\n# Label: \"QuoVadis Root CA 2\"\n# Serial: 1289\n# MD5 Fingerprint: 5e:39:7b:dd:f8:ba:ec:82:e9:ac:62:ba:0c:54:00:2b\n# SHA1 Fingerprint: ca:3a:fb:cf:12:40:36:4b:44:b2:16:20:88:80:48:39:19:93:7c:f7\n# SHA256 Fingerprint: 85:a0:dd:7d:d7:20:ad:b7:ff:05:f8:3d:54:2b:20:9d:c7:ff:45:28:f7:d6:77:b1:83:89:fe:a5:e5:c4:9e:86\n-----BEGIN CERTIFICATE-----\nMIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x\nGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv\nb3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV\nBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W\nYWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa\nGMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg\nFyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J\nWpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB\nrrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp\n+ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1\nksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i\nUcw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz\nPtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og\n/zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH\noycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI\nyV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud\nEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2\nA8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL\nMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT\nElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f\nBluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn\ng/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl\nfF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K\nWWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha\nB0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc\nhLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR\nTUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD\nmbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z\nohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y\n4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza\n8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u\n-----END CERTIFICATE-----\n\n# Issuer: CN=QuoVadis Root CA 3 O=QuoVadis Limited\n# Subject: CN=QuoVadis Root CA 3 O=QuoVadis Limited\n# Label: \"QuoVadis Root CA 3\"\n# Serial: 1478\n# MD5 Fingerprint: 31:85:3c:62:94:97:63:b9:aa:fd:89:4e:af:6f:e0:cf\n# SHA1 Fingerprint: 1f:49:14:f7:d8:74:95:1d:dd:ae:02:c0:be:fd:3a:2d:82:75:51:85\n# SHA256 Fingerprint: 18:f1:fc:7f:20:5d:f8:ad:dd:eb:7f:e0:07:dd:57:e3:af:37:5a:9c:4d:8d:73:54:6b:f4:f1:fe:d1:e1:8d:35\n-----BEGIN CERTIFICATE-----\nMIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x\nGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv\nb3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV\nBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W\nYWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM\nV0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB\n4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr\nH556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd\n8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv\nvWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT\nmZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe\nbtfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc\nT5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt\nWAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ\nc6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A\n4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD\nVR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG\nCCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0\naXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0\naWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu\ndC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw\nczALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G\nA1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC\nTTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg\nUm9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0\n7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem\nd1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd\n+LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B\n4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN\nt54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x\nDYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57\nk8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s\nzHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j\nWy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT\nmJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK\n4SVhM7JZG+Ju1zdXtg2pEto=\n-----END CERTIFICATE-----\n\n# Issuer: O=SECOM Trust.net OU=Security Communication RootCA1\n# Subject: O=SECOM Trust.net OU=Security Communication RootCA1\n# Label: \"Security Communication Root CA\"\n# Serial: 0\n# MD5 Fingerprint: f1:bc:63:6a:54:e0:b5:27:f5:cd:e7:1a:e3:4d:6e:4a\n# SHA1 Fingerprint: 36:b1:2b:49:f9:81:9e:d7:4c:9e:bc:38:0f:c6:56:8f:5d:ac:b2:f7\n# SHA256 Fingerprint: e7:5e:72:ed:9f:56:0e:ec:6e:b4:80:00:73:a4:3f:c3:ad:19:19:5a:39:22:82:01:78:95:97:4a:99:02:6b:6c\n-----BEGIN CERTIFICATE-----\nMIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY\nMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t\ndW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5\nWjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD\nVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3\nDQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8\n9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ\nDKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9\nMs+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N\nQV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ\nxrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G\nA1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T\nAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG\nkl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr\nUj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5\nBw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU\nJRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot\nRSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw==\n-----END CERTIFICATE-----\n\n# Issuer: CN=Sonera Class2 CA O=Sonera\n# Subject: CN=Sonera Class2 CA O=Sonera\n# Label: \"Sonera Class 2 Root CA\"\n# Serial: 29\n# MD5 Fingerprint: a3:ec:75:0f:2e:88:df:fa:48:01:4e:0b:5c:48:6f:fb\n# SHA1 Fingerprint: 37:f7:6d:e6:07:7c:90:c5:b1:3e:93:1a:b7:41:10:b4:f2:e4:9a:27\n# SHA256 Fingerprint: 79:08:b4:03:14:c1:38:10:0b:51:8d:07:35:80:7f:fb:fc:f8:51:8a:00:95:33:71:05:ba:38:6b:15:3d:d9:27\n-----BEGIN CERTIFICATE-----\nMIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP\nMA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAx\nMDQwNjA3Mjk0MFoXDTIxMDQwNjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNV\nBAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMiBDQTCCASIwDQYJKoZI\nhvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3/Ei9vX+ALTU74W+o\nZ6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybTdXnt\n5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s\n3TmVToMGf+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2Ej\nvOr7nQKV0ba5cTppCD8PtOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu\n8nYybieDwnPz3BjotJPqdURrBGAgcVeHnfO+oJAjPYok4doh28MCAwEAAaMzMDEw\nDwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITTXjwwCwYDVR0PBAQDAgEG\nMA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt0jSv9zil\nzqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/\n3DEIcbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvD\nFNr450kkkdAdavphOe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6\nTk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2\nZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M\n-----END CERTIFICATE-----\n\n# Issuer: CN=Staat der Nederlanden Root CA O=Staat der Nederlanden\n# Subject: CN=Staat der Nederlanden Root CA O=Staat der Nederlanden\n# Label: \"Staat der Nederlanden Root CA\"\n# Serial: 10000010\n# MD5 Fingerprint: 60:84:7c:5a:ce:db:0c:d4:cb:a7:e9:fe:02:c6:a9:c0\n# SHA1 Fingerprint: 10:1d:fa:3f:d5:0b:cb:bb:9b:b5:60:0c:19:55:a4:1a:f4:73:3a:04\n# SHA256 Fingerprint: d4:1d:82:9e:8c:16:59:82:2a:f9:3f:ce:62:bf:fc:de:26:4f:c8:4e:8b:95:0c:5f:f2:75:d0:52:35:46:95:a3\n-----BEGIN CERTIFICATE-----\nMIIDujCCAqKgAwIBAgIEAJiWijANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJO\nTDEeMBwGA1UEChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFh\ndCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQTAeFw0wMjEyMTcwOTIzNDlaFw0xNTEy\nMTYwOTE1MzhaMFUxCzAJBgNVBAYTAk5MMR4wHAYDVQQKExVTdGFhdCBkZXIgTmVk\nZXJsYW5kZW4xJjAkBgNVBAMTHVN0YWF0IGRlciBOZWRlcmxhbmRlbiBSb290IENB\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmNK1URF6gaYUmHFtvszn\nExvWJw56s2oYHLZhWtVhCb/ekBPHZ+7d89rFDBKeNVU+LCeIQGv33N0iYfXCxw71\n9tV2U02PjLwYdjeFnejKScfST5gTCaI+Ioicf9byEGW07l8Y1Rfj+MX94p2i71MO\nhXeiD+EwR+4A5zN9RGcaC1Hoi6CeUJhoNFIfLm0B8mBF8jHrqTFoKbt6QZ7GGX+U\ntFE5A3+y3qcym7RHjm+0Sq7lr7HcsBthvJly3uSJt3omXdozSVtSnA71iq3DuD3o\nBmrC1SoLbHuEvVYFy4ZlkuxEK7COudxwC0barbxjiDn622r+I/q85Ej0ZytqERAh\nSQIDAQABo4GRMIGOMAwGA1UdEwQFMAMBAf8wTwYDVR0gBEgwRjBEBgRVHSAAMDww\nOgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cucGtpb3ZlcmhlaWQubmwvcG9saWNpZXMv\ncm9vdC1wb2xpY3kwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSofeu8Y6R0E3QA\n7Jbg0zTBLL9s+DANBgkqhkiG9w0BAQUFAAOCAQEABYSHVXQ2YcG70dTGFagTtJ+k\n/rvuFbQvBgwp8qiSpGEN/KtcCFtREytNwiphyPgJWPwtArI5fZlmgb9uXJVFIGzm\neafR2Bwp/MIgJ1HI8XxdNGdphREwxgDS1/PTfLbwMVcoEoJz6TMvplW0C5GUR5z6\nu3pCMuiufi3IvKwUv9kP2Vv8wfl6leF9fpb8cbDCTMjfRTTJzg3ynGQI0DvDKcWy\n7ZAEwbEpkcUwb8GpcjPM/l0WFywRaed+/sWDCN+83CI6LiBpIzlWYGeQiy52OfsR\niJf2fL1LuCAWZwWN4jvBcj+UlTfHXbme2JOhF4//DGYVwSR8MnwDHTuhWEUykw==\n-----END CERTIFICATE-----\n\n# Issuer: CN=UTN - DATACorp SGC O=The USERTRUST Network OU=http://www.usertrust.com\n# Subject: CN=UTN - DATACorp SGC O=The USERTRUST Network OU=http://www.usertrust.com\n# Label: \"UTN DATACorp SGC Root CA\"\n# Serial: 91374294542884689855167577680241077609\n# MD5 Fingerprint: b3:a5:3e:77:21:6d:ac:4a:c0:c9:fb:d5:41:3d:ca:06\n# SHA1 Fingerprint: 58:11:9f:0e:12:82:87:ea:50:fd:d9:87:45:6f:4f:78:dc:fa:d6:d4\n# SHA256 Fingerprint: 85:fb:2f:91:dd:12:27:5a:01:45:b6:36:53:4f:84:02:4a:d6:8b:69:b8:ee:88:68:4f:f7:11:37:58:05:b3:48\n-----BEGIN CERTIFICATE-----\nMIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCB\nkzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug\nQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho\ndHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZBgNVBAMTElVUTiAtIERBVEFDb3Jw\nIFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBaMIGTMQswCQYDVQQG\nEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYD\nVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cu\ndXNlcnRydXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjAN\nBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6\nE5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ysraP6LnD43m77VkIVni5c7yPeIbkFdicZ\nD0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlowHDyUwDAXlCCpVZvNvlK\n4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA9P4yPykq\nlXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulW\nbfXv33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQAB\no4GrMIGoMAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRT\nMtGzz3/64PGgXYVOktKeRR20TzA9BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3Js\nLnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dDLmNybDAqBgNVHSUEIzAhBggr\nBgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3DQEBBQUAA4IB\nAQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft\nGzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyj\nj98C5OBxOvG0I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVH\nKWss5nbZqSl9Mt3JNjy9rjXxEZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv\n2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwPDPafepE39peC4N1xaf92P2BNPM/3\nmfnGV/TJVTl4uix5yaaIK/QI\n-----END CERTIFICATE-----\n\n# Issuer: CN=UTN-USERFirst-Hardware O=The USERTRUST Network OU=http://www.usertrust.com\n# Subject: CN=UTN-USERFirst-Hardware O=The USERTRUST Network OU=http://www.usertrust.com\n# Label: \"UTN USERFirst Hardware Root CA\"\n# Serial: 91374294542884704022267039221184531197\n# MD5 Fingerprint: 4c:56:41:e5:0d:bb:2b:e8:ca:a3:ed:18:08:ad:43:39\n# SHA1 Fingerprint: 04:83:ed:33:99:ac:36:08:05:87:22:ed:bc:5e:46:00:e3:be:f9:d7\n# SHA256 Fingerprint: 6e:a5:47:41:d0:04:66:7e:ed:1b:48:16:63:4a:a3:a7:9e:6e:4b:96:95:0f:82:79:da:fc:8d:9b:d8:81:21:37\n-----BEGIN CERTIFICATE-----\nMIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCB\nlzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug\nQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho\ndHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt\nSGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgxOTIyWjCBlzELMAkG\nA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEe\nMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8v\nd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdh\ncmUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn\n0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlIwrthdBKWHTxqctU8EGc6Oe0rE81m65UJ\nM6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFdtqdt++BxF2uiiPsA3/4a\nMXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8i4fDidNd\noI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqI\nDsjfPe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9Ksy\noUhbAgMBAAGjgbkwgbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYD\nVR0OBBYEFKFyXyYbKJhDlV0HN9WFlp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0\ndHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LUhhcmR3YXJlLmNy\nbDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEF\nBQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM\n//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28Gpgoiskli\nCE7/yMgUsogWXecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gE\nCJChicsZUN/KHAG8HQQZexB2lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t\n3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kniCrVWFCVH/A7HFe7fRQ5YiuayZSS\nKqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67nfhmqA==\n-----END CERTIFICATE-----\n\n# Issuer: CN=Chambers of Commerce Root O=AC Camerfirma SA CIF A82743287 OU=http://www.chambersign.org\n# Subject: CN=Chambers of Commerce Root O=AC Camerfirma SA CIF A82743287 OU=http://www.chambersign.org\n# Label: \"Camerfirma Chambers of Commerce Root\"\n# Serial: 0\n# MD5 Fingerprint: b0:01:ee:14:d9:af:29:18:94:76:8e:f1:69:33:2a:84\n# SHA1 Fingerprint: 6e:3a:55:a4:19:0c:19:5c:93:84:3c:c0:db:72:2e:31:30:61:f0:b1\n# SHA256 Fingerprint: 0c:25:8a:12:a5:67:4a:ef:25:f2:8b:a7:dc:fa:ec:ee:a3:48:e5:41:e6:f5:cc:4e:e6:3b:71:b3:61:60:6a:c3\n-----BEGIN CERTIFICATE-----\nMIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEn\nMCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL\nExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMg\nb2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAxNjEzNDNaFw0zNzA5MzAxNjEzNDRa\nMH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZpcm1hIFNBIENJRiBB\nODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3JnMSIw\nIAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0B\nAQEFAAOCAQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtb\nunXF/KGIJPov7coISjlUxFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0d\nBmpAPrMMhe5cG3nCYsS4No41XQEMIwRHNaqbYE6gZj3LJgqcQKH0XZi/caulAGgq\n7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jWDA+wWFjbw2Y3npuRVDM3\n0pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFVd9oKDMyX\nroDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIG\nA1UdEwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5j\naGFtYmVyc2lnbi5vcmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p\n26EpW1eLTXYGduHRooowDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIA\nBzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hhbWJlcnNpZ24ub3JnMCcGA1Ud\nEgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYDVR0gBFEwTzBN\nBgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz\naWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEB\nAAxBl8IahsAifJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZd\np0AJPaxJRUXcLo0waLIJuvvDL8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi\n1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wNUPf6s+xCX6ndbcj0dc97wXImsQEc\nXCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/nADydb47kMgkdTXg0\neDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1erfu\ntGWaIZDgqtCYvDi1czyL+Nw=\n-----END CERTIFICATE-----\n\n# Issuer: CN=Global Chambersign Root O=AC Camerfirma SA CIF A82743287 OU=http://www.chambersign.org\n# Subject: CN=Global Chambersign Root O=AC Camerfirma SA CIF A82743287 OU=http://www.chambersign.org\n# Label: \"Camerfirma Global Chambersign Root\"\n# Serial: 0\n# MD5 Fingerprint: c5:e6:7b:bf:06:d0:4f:43:ed:c4:7a:65:8a:fb:6b:19\n# SHA1 Fingerprint: 33:9b:6b:14:50:24:9b:55:7a:01:87:72:84:d9:e0:2f:c3:d2:d8:e9\n# SHA256 Fingerprint: ef:3c:b4:17:fc:8e:bf:6f:97:87:6c:9e:4e:ce:39:de:1e:a5:fe:64:91:41:d1:02:8b:7d:11:c0:b2:29:8c:ed\n-----BEGIN CERTIFICATE-----\nMIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEn\nMCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL\nExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENo\nYW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYxNDE4WhcNMzcwOTMwMTYxNDE4WjB9\nMQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgy\nNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4G\nA1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUA\nA4IBDQAwggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0\nMi+ITaFgCPS3CU6gSS9J1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/s\nQJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8Oby4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpV\neAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl6DJWk0aJqCWKZQbua795\nB9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c8lCrEqWh\nz0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0T\nAQH/BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1i\nZXJzaWduLm9yZy9jaGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4w\nTcbOX60Qq+UDpfqpFDAOBgNVHQ8BAf8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAH\nMCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBjaGFtYmVyc2lnbi5vcmcwKgYD\nVR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9yZzBbBgNVHSAE\nVDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh\nbWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0B\nAQUFAAOCAQEAPDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUM\nbKGKfKX0j//U2K0X1S0E0T9YgOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXi\nryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJPJ7oKXqJ1/6v/2j1pReQvayZzKWG\nVwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4IBHNfTIzSJRUTN3c\necQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREest2d/\nAYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A==\n-----END CERTIFICATE-----\n\n# Issuer: CN=NetLock Kozjegyzoi (Class A) Tanusitvanykiado O=NetLock Halozatbiztonsagi Kft. OU=Tanusitvanykiadok\n# Subject: CN=NetLock Kozjegyzoi (Class A) Tanusitvanykiado O=NetLock Halozatbiztonsagi Kft. OU=Tanusitvanykiadok\n# Label: \"NetLock Notary (Class A) Root\"\n# Serial: 259\n# MD5 Fingerprint: 86:38:6d:5e:49:63:6c:85:5c:db:6d:dc:94:b7:d0:f7\n# SHA1 Fingerprint: ac:ed:5f:65:53:fd:25:ce:01:5f:1f:7a:48:3b:6a:74:9f:61:78:c6\n# SHA256 Fingerprint: 7f:12:cd:5f:7e:5e:29:0e:c7:d8:51:79:d5:b7:2c:20:a5:be:75:08:ff:db:5b:f8:1a:b9:68:4a:7f:c9:f6:67\n-----BEGIN CERTIFICATE-----\nMIIGfTCCBWWgAwIBAgICAQMwDQYJKoZIhvcNAQEEBQAwga8xCzAJBgNVBAYTAkhV\nMRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMe\nTmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0\ndmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBLb3pqZWd5em9pIChDbGFzcyBB\nKSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNDIzMTQ0N1oXDTE5MDIxOTIzMTQ0\nN1owga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQHEwhC\ndWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQu\nMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBL\nb3pqZWd5em9pIChDbGFzcyBBKSBUYW51c2l0dmFueWtpYWRvMIIBIjANBgkqhkiG\n9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvHSMD7tM9DceqQWC2ObhbHDqeLVu0ThEDaiD\nzl3S1tWBxdRL51uUcCbbO51qTGL3cfNk1mE7PetzozfZz+qMkjvN9wfcZnSX9EUi\n3fRc4L9t875lM+QVOr/bmJBVOMTtplVjC7B4BPTjbsE/jvxReB+SnoPC/tmwqcm8\nWgD/qaiYdPv2LD4VOQ22BFWoDpggQrOxJa1+mm9dU7GrDPzr4PN6s6iz/0b2Y6LY\nOph7tqyF/7AlT3Rj5xMHpQqPBffAZG9+pyeAlt7ULoZgx2srXnN7F+eRP2QM2Esi\nNCubMvJIH5+hCoR64sKtlz2O1cH5VqNQ6ca0+pii7pXmKgOM3wIDAQABo4ICnzCC\nApswDgYDVR0PAQH/BAQDAgAGMBIGA1UdEwEB/wQIMAYBAf8CAQQwEQYJYIZIAYb4\nQgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaCAk1GSUdZRUxFTSEgRXplbiB0\nYW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pvbGdhbHRhdGFz\naSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQu\nIEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtm\nZWxlbG9zc2VnLWJpenRvc2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMg\nZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUgYXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVs\namFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJhc2EgbWVndGFsYWxoYXRv\nIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBhIGh0dHBzOi8vd3d3\nLm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVub3J6\nZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1\nYW5jZSBhbmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3Qg\ndG8gdGhlIE5ldExvY2sgQ1BTIGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRs\nb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBjcHNAbmV0bG9jay5uZXQuMA0G\nCSqGSIb3DQEBBAUAA4IBAQBIJEb3ulZv+sgoA0BO5TE5ayZrU3/b39/zcT0mwBQO\nxmd7I6gMc90Bu8bKbjc5VdXHjFYgDigKDtIqpLBJUsY4B/6+CgmM0ZjPytoUMaFP\n0jn8DxEsQ8Pdq5PHVT5HfBgaANzze9jyf1JsIPQLX2lS9O74silg6+NJMSEN1rUQ\nQeJBCWziGppWS3cC9qCbmieH6FUpccKQn0V4GuEVZD3QDtigdp+uxdAu6tYPVuxk\nf1qbFFgBJ34TUMdrKuZoPL9coAob4Q566eKAw+np9v1sEZ7Q5SgnK1QyQhSCdeZK\n8CtmdWOMovsEPoMOmzbwGOQmIMOM8CgHrTwXZoi1/baI\n-----END CERTIFICATE-----\n\n# Issuer: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com\n# Subject: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com\n# Label: \"XRamp Global CA Root\"\n# Serial: 107108908803651509692980124233745014957\n# MD5 Fingerprint: a1:0b:44:b3:ca:10:d8:00:6e:9d:0f:d8:0f:92:0a:d1\n# SHA1 Fingerprint: b8:01:86:d1:eb:9c:86:a5:41:04:cf:30:54:f3:4c:52:b7:e5:58:c6\n# SHA256 Fingerprint: ce:cd:dc:90:50:99:d8:da:df:c5:b1:d2:09:b7:37:cb:e2:c1:8c:fb:2c:10:c0:ff:0b:cf:0d:32:86:fc:1a:a2\n-----BEGIN CERTIFICATE-----\nMIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB\ngjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk\nMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY\nUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx\nNDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3\ndy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy\ndmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB\ndXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6\n38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP\nKZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q\nDxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4\nqEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa\nJSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi\nPvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P\nBAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs\njVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0\neS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD\nggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR\nvbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt\nqZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa\nIR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy\ni6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ\nO+7ETPTsJ3xCwnR8gooJybQDJbw=\n-----END CERTIFICATE-----\n\n# Issuer: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority\n# Subject: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority\n# Label: \"Go Daddy Class 2 CA\"\n# Serial: 0\n# MD5 Fingerprint: 91:de:06:25:ab:da:fd:32:17:0c:bb:25:17:2a:84:67\n# SHA1 Fingerprint: 27:96:ba:e6:3f:18:01:e2:77:26:1b:a0:d7:77:70:02:8f:20:ee:e4\n# SHA256 Fingerprint: c3:84:6b:f2:4b:9e:93:ca:64:27:4c:0e:c6:7c:1e:cc:5e:02:4f:fc:ac:d2:d7:40:19:35:0e:81:fe:54:6a:e4\n-----BEGIN CERTIFICATE-----\nMIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh\nMB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE\nYWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3\nMDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo\nZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg\nMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN\nADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA\nPVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w\nwdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi\nEqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY\navx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+\nYihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE\nsNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h\n/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5\nIEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj\nYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD\nggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy\nOO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P\nTMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ\nHmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER\ndEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf\nReYNnyicsbkqWletNw+vHX/bvZ8=\n-----END CERTIFICATE-----\n\n# Issuer: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority\n# Subject: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority\n# Label: \"Starfield Class 2 CA\"\n# Serial: 0\n# MD5 Fingerprint: 32:4a:4b:bb:c8:63:69:9b:be:74:9a:c6:dd:1d:46:24\n# SHA1 Fingerprint: ad:7e:1c:28:b0:64:ef:8f:60:03:40:20:14:c3:d0:e3:37:0e:b5:8a\n# SHA256 Fingerprint: 14:65:fa:20:53:97:b8:76:fa:a6:f0:a9:95:8e:55:90:e4:0f:cc:7f:aa:4f:b7:c2:c8:67:75:21:fb:5f:b6:58\n-----BEGIN CERTIFICATE-----\nMIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl\nMCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp\nU3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw\nNjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE\nChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp\nZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3\nDQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf\n8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN\n+lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0\nX9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa\nK4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA\n1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G\nA1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR\nzt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0\nYXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD\nbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w\nDQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3\nL7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D\neruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl\nxy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp\nVSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY\nWQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=\n-----END CERTIFICATE-----\n\n# Issuer: CN=StartCom Certification Authority O=StartCom Ltd. OU=Secure Digital Certificate Signing\n# Subject: CN=StartCom Certification Authority O=StartCom Ltd. OU=Secure Digital Certificate Signing\n# Label: \"StartCom Certification Authority\"\n# Serial: 1\n# MD5 Fingerprint: 22:4d:8f:8a:fc:f7:35:c2:bb:57:34:90:7b:8b:22:16\n# SHA1 Fingerprint: 3e:2b:f7:f2:03:1b:96:f3:8c:e6:c4:d8:a8:5d:3e:2d:58:47:6a:0f\n# SHA256 Fingerprint: c7:66:a9:be:f2:d4:07:1c:86:3a:31:aa:49:20:e8:13:b2:d1:98:60:8c:b7:b7:cf:e2:11:43:b8:36:df:09:ea\n-----BEGIN CERTIFICATE-----\nMIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW\nMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg\nQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh\ndGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM2WhcNMzYwOTE3MTk0NjM2WjB9\nMQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi\nU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh\ncnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA\nA4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk\npMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf\nOQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C\nJi/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT\nKqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi\nHzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM\nAv+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w\n+2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+\nGkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3\nZzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B\n26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID\nAQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE\nFE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9j\nZXJ0LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3Js\nLnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFM\nBgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUHAgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0\nY29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRwOi8vY2VydC5zdGFy\ndGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYgU3Rh\ncnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlh\nYmlsaXR5LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2Yg\ndGhlIFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFp\nbGFibGUgYXQgaHR0cDovL2NlcnQuc3RhcnRjb20ub3JnL3BvbGljeS5wZGYwEQYJ\nYIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNT\nTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOCAgEAFmyZ\n9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8\njhvh3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUW\nFjgKXlf2Ysd6AgXmvB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJz\newT4F+irsfMuXGRuczE6Eri8sxHkfY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1\nny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3fsNrarnDy0RLrHiQi+fHLB5L\nEUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZEoalHmdkrQYu\nL6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq\nyvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuC\nO3NJo2pXh5Tl1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6V\num0ABj6y6koQOdjQK/W/7HW/lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkySh\nNOsF/5oirpt9P/FlUQqmMGqz9IgcgA38corog14=\n-----END CERTIFICATE-----\n\n# Issuer: O=Government Root Certification Authority\n# Subject: O=Government Root Certification Authority\n# Label: \"Taiwan GRCA\"\n# Serial: 42023070807708724159991140556527066870\n# MD5 Fingerprint: 37:85:44:53:32:45:1f:20:f0:f3:95:e1:25:c4:43:4e\n# SHA1 Fingerprint: f4:8b:11:bf:de:ab:be:94:54:20:71:e6:41:de:6b:be:88:2b:40:b9\n# SHA256 Fingerprint: 76:00:29:5e:ef:e8:5b:9e:1f:d6:24:db:76:06:2a:aa:ae:59:81:8a:54:d2:77:4c:d4:c0:b2:c0:11:31:e1:b3\n-----BEGIN CERTIFICATE-----\nMIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/\nMQswCQYDVQQGEwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmlj\nYXRpb24gQXV0aG9yaXR5MB4XDTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1ow\nPzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dvdmVybm1lbnQgUm9vdCBDZXJ0aWZp\nY2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB\nAJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qNw8XR\nIePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1q\ngQdW8or5BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKy\nyhwOeYHWtXBiCAEuTk8O1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAts\nF/tnyMKtsc2AtJfcdgEWFelq16TheEfOhtX7MfP6Mb40qij7cEwdScevLJ1tZqa2\njWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wovJ5pGfaENda1UhhXcSTvx\nls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7Q3hub/FC\nVGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHK\nYS1tB6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoH\nEgKXTiCQ8P8NHuJBO9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThN\nXo+EHWbNxWCWtFJaBYmOlXqYwZE8lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1Ud\nDgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNVHRMEBTADAQH/MDkGBGcqBwAE\nMTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg209yewDL7MTqK\nUWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ\nTulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyf\nqzvS/3WXy6TjZwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaK\nZEk9GhiHkASfQlK3T8v+R0F2Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFE\nJPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlUD7gsL0u8qV1bYH+Mh6XgUmMqvtg7\nhUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6QzDxARvBMB1uUO07+1\nEqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+HbkZ6Mm\nnD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WX\nudpVBrkk7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44Vbnz\nssQwmSNOXfJIoRIM3BKQCZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDe\nLMDDav7v3Aun+kbfYNucpllQdSNpc5Oy+fwC00fmcc4QAu4njIT/rEUNE1yDMuAl\npYYsfPQS\n-----END CERTIFICATE-----\n\n# Issuer: CN=Swisscom Root CA 1 O=Swisscom OU=Digital Certificate Services\n# Subject: CN=Swisscom Root CA 1 O=Swisscom OU=Digital Certificate Services\n# Label: \"Swisscom Root CA 1\"\n# Serial: 122348795730808398873664200247279986742\n# MD5 Fingerprint: f8:38:7c:77:88:df:2c:16:68:2e:c2:e2:52:4b:b8:f9\n# SHA1 Fingerprint: 5f:3a:fc:0a:8b:64:f6:86:67:34:74:df:7e:a9:a2:fe:f9:fa:7a:51\n# SHA256 Fingerprint: 21:db:20:12:36:60:bb:2e:d4:18:20:5d:a1:1e:e7:a8:5a:65:e2:bc:6e:55:b5:af:7e:78:99:c8:a2:66:d9:2e\n-----BEGIN CERTIFICATE-----\nMIIF2TCCA8GgAwIBAgIQXAuFXAvnWUHfV8w/f52oNjANBgkqhkiG9w0BAQUFADBk\nMQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0\nYWwgQ2VydGlmaWNhdGUgU2VydmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3Qg\nQ0EgMTAeFw0wNTA4MTgxMjA2MjBaFw0yNTA4MTgyMjA2MjBaMGQxCzAJBgNVBAYT\nAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZp\nY2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAxMIICIjAN\nBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0LmwqAzZuz8h+BvVM5OAFmUgdbI9\nm2BtRsiMMW8Xw/qabFbtPMWRV8PNq5ZJkCoZSx6jbVfd8StiKHVFXqrWW/oLJdih\nFvkcxC7mlSpnzNApbjyFNDhhSbEAn9Y6cV9Nbc5fuankiX9qUvrKm/LcqfmdmUc/\nTilftKaNXXsLmREDA/7n29uj/x2lzZAeAR81sH8A25Bvxn570e56eqeqDFdvpG3F\nEzuwpdntMhy0XmeLVNxzh+XTF3xmUHJd1BpYwdnP2IkCb6dJtDZd0KTeByy2dbco\nkdaXvij1mB7qWybJvbCXc9qukSbraMH5ORXWZ0sKbU/Lz7DkQnGMU3nn7uHbHaBu\nHYwadzVcFh4rUx80i9Fs/PJnB3r1re3WmquhsUvhzDdf/X/NTa64H5xD+SpYVUNF\nvJbNcA78yeNmuk6NO4HLFWR7uZToXTNShXEuT46iBhFRyePLoW4xCGQMwtI89Tbo\n19AOeCMgkckkKmUpWyL3Ic6DXqTz3kvTaI9GdVyDCW4pa8RwjPWd1yAv/0bSKzjC\nL3UcPX7ape8eYIVpQtPM+GP+HkM5haa2Y0EQs3MevNP6yn0WR+Kn1dCjigoIlmJW\nbjTb2QK5MHXjBNLnj8KwEUAKrNVxAmKLMb7dxiNYMUJDLXT5xp6mig/p/r+D5kNX\nJLrvRjSq1xIBOO0CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0hBBYw\nFDASBgdghXQBUwABBgdghXQBUwABMBIGA1UdEwEB/wQIMAYBAf8CAQcwHwYDVR0j\nBBgwFoAUAyUv3m+CATpcLNwroWm1Z9SM0/0wHQYDVR0OBBYEFAMlL95vggE6XCzc\nK6FptWfUjNP9MA0GCSqGSIb3DQEBBQUAA4ICAQA1EMvspgQNDQ/NwNurqPKIlwzf\nky9NfEBWMXrrpA9gzXrzvsMnjgM+pN0S734edAY8PzHyHHuRMSG08NBsl9Tpl7Ik\nVh5WwzW9iAUPWxAaZOHHgjD5Mq2eUCzneAXQMbFamIp1TpBcahQq4FJHgmDmHtqB\nsfsUC1rxn9KVuj7QG9YVHaO+htXbD8BJZLsuUBlL0iT43R4HVtA4oJVwIHaM190e\n3p9xxCPvgxNcoyQVTSlAPGrEqdi3pkSlDfTgnXceQHAm/NrZNuR55LU/vJtlvrsR\nls/bxig5OgjOR1tTWsWZ/l2p3e9M1MalrQLmjAcSHm8D0W+go/MpvRLHUKKwf4ip\nmXeascClOS5cfGniLLDqN2qk4Vrh9VDlg++luyqI54zb/W1elxmofmZ1a3Hqv7HH\nb6D0jqTsNFFbjCYDcKF31QESVwA12yPeDooomf2xEG9L/zgtYE4snOtnta1J7ksf\nrK/7DZBaZmBwXarNeNQk7shBoJMBkpxqnvy5JMWzFYJ+vq6VK+uxwNrjAWALXmms\nhFZhvnEX/h0TD/7Gh0Xp/jKgGg0TpJRVcaUWi7rKibCyx/yP2FS1k2Kdzs9Z+z0Y\nzirLNRWCXf9UIltxUvu3yf5gmwBBZPCqKuy2QkPOiWaByIufOVQDJdMWNY6E0F/6\nMBr1mmz0DlP5OlvRHA==\n-----END CERTIFICATE-----\n\n# Issuer: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com\n# Subject: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com\n# Label: \"DigiCert Assured ID Root CA\"\n# Serial: 17154717934120587862167794914071425081\n# MD5 Fingerprint: 87:ce:0b:7b:2a:0e:49:00:e1:58:71:9b:37:a8:93:72\n# SHA1 Fingerprint: 05:63:b8:63:0d:62:d7:5a:bb:c8:ab:1e:4b:df:b5:a8:99:b2:4d:43\n# SHA256 Fingerprint: 3e:90:99:b5:01:5e:8f:48:6c:00:bc:ea:9d:11:1e:e7:21:fa:ba:35:5a:89:bc:f1:df:69:56:1e:3d:c6:32:5c\n-----BEGIN CERTIFICATE-----\nMIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl\nMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\nd3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv\nb3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG\nEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl\ncnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi\nMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c\nJpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP\nmDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+\nwRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4\nVYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/\nAUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB\nAAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW\nBBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun\npyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC\ndWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf\nfwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm\nNW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx\nH2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe\n+o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==\n-----END CERTIFICATE-----\n\n# Issuer: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com\n# Subject: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com\n# Label: \"DigiCert Global Root CA\"\n# Serial: 10944719598952040374951832963794454346\n# MD5 Fingerprint: 79:e4:a9:84:0d:7d:3a:96:d7:c0:4f:e2:43:4c:89:2e\n# SHA1 Fingerprint: a8:98:5d:3a:65:e5:e5:c4:b2:d7:d6:6d:40:c6:dd:2f:b1:9c:54:36\n# SHA256 Fingerprint: 43:48:a0:e9:44:4c:78:cb:26:5e:05:8d:5e:89:44:b4:d8:4f:96:62:bd:26:db:25:7f:89:34:a4:43:c7:01:61\n-----BEGIN CERTIFICATE-----\nMIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh\nMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\nd3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD\nQTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT\nMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j\nb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG\n9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB\nCSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97\nnh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt\n43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P\nT19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4\ngdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO\nBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR\nTLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw\nDQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr\nhMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg\n06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF\nPnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls\nYSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk\nCAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=\n-----END CERTIFICATE-----\n\n# Issuer: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com\n# Subject: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com\n# Label: \"DigiCert High Assurance EV Root CA\"\n# Serial: 3553400076410547919724730734378100087\n# MD5 Fingerprint: d4:74:de:57:5c:39:b2:d3:9c:85:83:c5:c0:65:49:8a\n# SHA1 Fingerprint: 5f:b7:ee:06:33:e2:59:db:ad:0c:4c:9a:e6:d3:8f:1a:61:c7:dc:25\n# SHA256 Fingerprint: 74:31:e5:f4:c3:c1:ce:46:90:77:4f:0b:61:e0:54:40:88:3b:a9:a0:1e:d0:0b:a6:ab:d7:80:6e:d3:b1:18:cf\n-----BEGIN CERTIFICATE-----\nMIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs\nMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\nd3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j\nZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL\nMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3\nLmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug\nRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm\n+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW\nPNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM\nxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB\nIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3\nhzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg\nEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF\nMAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA\nFLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec\nnzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z\neM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF\nhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2\nYzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe\nvEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep\n+OkuE6N36B9K\n-----END CERTIFICATE-----\n\n# Issuer: CN=Class 2 Primary CA O=Certplus\n# Subject: CN=Class 2 Primary CA O=Certplus\n# Label: \"Certplus Class 2 Primary CA\"\n# Serial: 177770208045934040241468760488327595043\n# MD5 Fingerprint: 88:2c:8c:52:b8:a2:3c:f3:f7:bb:03:ea:ae:ac:42:0b\n# SHA1 Fingerprint: 74:20:74:41:72:9c:dd:92:ec:79:31:d8:23:10:8d:c2:81:92:e2:bb\n# SHA256 Fingerprint: 0f:99:3c:8a:ef:97:ba:af:56:87:14:0e:d5:9a:d1:82:1b:b4:af:ac:f0:aa:9a:58:b5:d5:7a:33:8a:3a:fb:cb\n-----BEGIN CERTIFICATE-----\nMIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAw\nPTELMAkGA1UEBhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFz\ncyAyIFByaW1hcnkgQ0EwHhcNOTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9\nMQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2VydHBsdXMxGzAZBgNVBAMTEkNsYXNz\nIDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANxQ\nltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR5aiR\nVhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyL\nkcAbmXuZVg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCd\nEgETjdyAYveVqUSISnFOYFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yas\nH7WLO7dDWWuwJKZtkIvEcupdM5i3y95ee++U8Rs+yskhwcWYAqqi9lt3m/V+llU0\nHGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRMECDAGAQH/AgEKMAsGA1Ud\nDwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJYIZIAYb4\nQgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMu\nY29tL0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/\nAN9WM2K191EBkOvDP9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8\nyfFC82x/xXp8HVGIutIKPidd3i1RTtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMR\nFcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+7UCmnYR0ObncHoUW2ikbhiMA\nybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW//1IMwrh3KWB\nkJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7\nl7+ijrRU\n-----END CERTIFICATE-----\n\n# Issuer: CN=DST Root CA X3 O=Digital Signature Trust Co.\n# Subject: CN=DST Root CA X3 O=Digital Signature Trust Co.\n# Label: \"DST Root CA X3\"\n# Serial: 91299735575339953335919266965803778155\n# MD5 Fingerprint: 41:03:52:dc:0f:f7:50:1b:16:f0:02:8e:ba:6f:45:c5\n# SHA1 Fingerprint: da:c9:02:4f:54:d8:f6:df:94:93:5f:b1:73:26:38:ca:6a:d7:7c:13\n# SHA256 Fingerprint: 06:87:26:03:31:a7:24:03:d9:09:f1:05:e6:9b:cf:0d:32:e1:bd:24:93:ff:c6:d9:20:6d:11:bc:d6:77:07:39\n-----BEGIN CERTIFICATE-----\nMIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/\nMSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT\nDkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow\nPzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD\nEw5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\nAN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O\nrz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq\nOLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b\nxiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw\n7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD\naeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV\nHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG\nSIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69\nikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr\nAvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz\nR8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5\nJDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo\nOb8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ\n-----END CERTIFICATE-----\n\n# Issuer: CN=DST ACES CA X6 O=Digital Signature Trust OU=DST ACES\n# Subject: CN=DST ACES CA X6 O=Digital Signature Trust OU=DST ACES\n# Label: \"DST ACES CA X6\"\n# Serial: 17771143917277623872238992636097467865\n# MD5 Fingerprint: 21:d8:4c:82:2b:99:09:33:a2:eb:14:24:8d:8e:5f:e8\n# SHA1 Fingerprint: 40:54:da:6f:1c:3f:40:74:ac:ed:0f:ec:cd:db:79:d1:53:fb:90:1d\n# SHA256 Fingerprint: 76:7c:95:5a:76:41:2c:89:af:68:8e:90:a1:c7:0f:55:6c:fd:6b:60:25:db:ea:10:41:6d:7e:b6:83:1f:8c:40\n-----BEGIN CERTIFICATE-----\nMIIECTCCAvGgAwIBAgIQDV6ZCtadt3js2AdWO4YV2TANBgkqhkiG9w0BAQUFADBb\nMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3Qx\nETAPBgNVBAsTCERTVCBBQ0VTMRcwFQYDVQQDEw5EU1QgQUNFUyBDQSBYNjAeFw0w\nMzExMjAyMTE5NThaFw0xNzExMjAyMTE5NThaMFsxCzAJBgNVBAYTAlVTMSAwHgYD\nVQQKExdEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdDERMA8GA1UECxMIRFNUIEFDRVMx\nFzAVBgNVBAMTDkRTVCBBQ0VTIENBIFg2MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\nMIIBCgKCAQEAuT31LMmU3HWKlV1j6IR3dma5WZFcRt2SPp/5DgO0PWGSvSMmtWPu\nktKe1jzIDZBfZIGxqAgNTNj50wUoUrQBJcWVHAx+PhCEdc/BGZFjz+iokYi5Q1K7\ngLFViYsx+tC3dr5BPTCapCIlF3PoHuLTrCq9Wzgh1SpL11V94zpVvddtawJXa+ZH\nfAjIgrrep4c9oW24MFbCswKBXy314powGCi4ZtPLAZZv6opFVdbgnf9nKxcCpk4a\nahELfrd755jWjHZvwTvbUJN+5dCOHze4vbrGn2zpfDPyMjwmR/onJALJfh1biEIT\najV8fTXpLmaRcpPVMibEdPVTo7NdmvYJywIDAQABo4HIMIHFMA8GA1UdEwEB/wQF\nMAMBAf8wDgYDVR0PAQH/BAQDAgHGMB8GA1UdEQQYMBaBFHBraS1vcHNAdHJ1c3Rk\nc3QuY29tMGIGA1UdIARbMFkwVwYKYIZIAWUDAgEBATBJMEcGCCsGAQUFBwIBFjto\ndHRwOi8vd3d3LnRydXN0ZHN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0FDRVMt\naW5kZXguaHRtbDAdBgNVHQ4EFgQUCXIGThhDD+XWzMNqizF7eI+og7gwDQYJKoZI\nhvcNAQEFBQADggEBAKPYjtay284F5zLNAdMEA+V25FYrnJmQ6AgwbN99Pe7lv7Uk\nQIRJ4dEorsTCOlMwiPH1d25Ryvr/ma8kXxug/fKshMrfqfBfBC6tFr8hlxCBPeP/\nh40y3JTlR4peahPJlJU90u7INJXQgNStMgiAVDzgvVJT11J8smk/f3rPanTK+gQq\nnExaBqXpIK1FZg9p8d2/6eMyi/rgwYZNcjwu2JN4Cir42NInPRmJX1p7ijvMDNpR\nrscL9yuwNwXsvFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf2\n9w4LTJxoeHtxMcfrHuBnQfO3oKfN5XozNmr6mis=\n-----END CERTIFICATE-----\n\n# Issuer: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı O=(c) 2005 TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş.\n# Subject: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı O=(c) 2005 TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş.\n# Label: \"TURKTRUST Certificate Services Provider Root 1\"\n# Serial: 1\n# MD5 Fingerprint: f1:6a:22:18:c9:cd:df:ce:82:1d:1d:b7:78:5c:a9:a5\n# SHA1 Fingerprint: 79:98:a3:08:e1:4d:65:85:e6:c2:1e:15:3a:71:9f:ba:5a:d3:4a:d9\n# SHA256 Fingerprint: 44:04:e3:3b:5e:14:0d:cf:99:80:51:fd:fc:80:28:c7:c8:16:15:c5:ee:73:7b:11:1b:58:82:33:a9:b5:35:a0\n-----BEGIN CERTIFICATE-----\nMIID+zCCAuOgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBtzE/MD0GA1UEAww2VMOc\nUktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx\nc8SxMQswCQYDVQQGDAJUUjEPMA0GA1UEBwwGQU5LQVJBMVYwVAYDVQQKDE0oYykg\nMjAwNSBUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8\ndmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjAeFw0wNTA1MTMxMDI3MTdaFw0xNTAz\nMjIxMDI3MTdaMIG3MT8wPQYDVQQDDDZUw5xSS1RSVVNUIEVsZWt0cm9uaWsgU2Vy\ndGlmaWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLExCzAJBgNVBAYMAlRSMQ8wDQYD\nVQQHDAZBTktBUkExVjBUBgNVBAoMTShjKSAyMDA1IFTDnFJLVFJVU1QgQmlsZ2kg\nxLBsZXRpxZ9pbSB2ZSBCaWxpxZ9pbSBHw7x2ZW5sacSfaSBIaXptZXRsZXJpIEEu\nxZ4uMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAylIF1mMD2Bxf3dJ7\nXfIMYGFbazt0K3gNfUW9InTojAPBxhEqPZW8qZSwu5GXyGl8hMW0kWxsE2qkVa2k\nheiVfrMArwDCBRj1cJ02i67L5BuBf5OI+2pVu32Fks66WJ/bMsW9Xe8iSi9BB35J\nYbOG7E6mQW6EvAPs9TscyB/C7qju6hJKjRTP8wrgUDn5CDX4EVmt5yLqS8oUBt5C\nurKZ8y1UiBAG6uEaPj1nH/vO+3yC6BFdSsG5FOpU2WabfIl9BJpiyelSPJ6c79L1\nJuTm5Rh8i27fbMx4W09ysstcP4wFjdFMjK2Sx+F4f2VsSQZQLJ4ywtdKxnWKWU51\nb0dewQIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAV\n9VX/N5aAWSGk/KEVTCD21F/aAyT8z5Aa9CEKmu46sWrv7/hg0Uw2ZkUd82YCdAR7\nkjCo3gp2D++Vbr3JN+YaDayJSFvMgzbC9UZcWYJWtNX+I7TYVBxEq8Sn5RTOPEFh\nfEPmzcSBCYsk+1Ql1haolgxnB2+zUEfjHCQo3SqYpGH+2+oSN7wBGjSFvW5P55Fy\nB0SFHljKVETd96y5y4khctuPwGkplyqjrhgjlxxBKot8KsF8kOipKMDTkcatKIdA\naLX/7KfS0zgYnNN9aV3wxqUeJBujR/xpB2jn5Jq07Q+hh4cCzofSSE7hvP/L8XKS\nRGQDJereW26fyfJOrN3H\n-----END CERTIFICATE-----\n\n# Issuer: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı O=TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş. (c) Kasım 2005\n# Subject: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı O=TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş. (c) Kasım 2005\n# Label: \"TURKTRUST Certificate Services Provider Root 2\"\n# Serial: 1\n# MD5 Fingerprint: 37:a5:6e:d4:b1:25:84:97:b7:fd:56:15:7a:f9:a2:00\n# SHA1 Fingerprint: b4:35:d4:e1:11:9d:1c:66:90:a7:49:eb:b3:94:bd:63:7b:a7:82:b7\n# SHA256 Fingerprint: c4:70:cf:54:7e:23:02:b9:77:fb:29:dd:71:a8:9a:7b:6c:1f:60:77:7b:03:29:f5:60:17:f3:28:bf:4f:6b:e6\n-----BEGIN CERTIFICATE-----\nMIIEPDCCAySgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvjE/MD0GA1UEAww2VMOc\nUktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx\nc8SxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xS\nS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kg\nSGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwHhcNMDUxMTA3MTAwNzU3\nWhcNMTUwOTE2MTAwNzU3WjCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBFbGVrdHJv\nbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJU\nUjEPMA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSw\nbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWe\nLiAoYykgS2FzxLFtIDIwMDUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\nAQCpNn7DkUNMwxmYCMjHWHtPFoylzkkBH3MOrHUTpvqeLCDe2JAOCtFp0if7qnef\nJ1Il4std2NiDUBd9irWCPwSOtNXwSadktx4uXyCcUHVPr+G1QRT0mJKIx+XlZEdh\nR3n9wFHxwZnn3M5q+6+1ATDcRhzviuyV79z/rxAc653YsKpqhRgNF8k+v/Gb0AmJ\nQv2gQrSdiVFVKc8bcLyEVK3BEx+Y9C52YItdP5qtygy/p1Zbj3e41Z55SZI/4PGX\nJHpsmxcPbe9TmJEr5A++WXkHeLuXlfSfadRYhwqp48y2WBmfJiGxxFmNskF1wK1p\nzpwACPI2/z7woQ8arBT9pmAPAgMBAAGjQzBBMB0GA1UdDgQWBBTZN7NOBf3Zz58S\nFq62iS/rJTqIHDAPBgNVHQ8BAf8EBQMDBwYAMA8GA1UdEwEB/wQFMAMBAf8wDQYJ\nKoZIhvcNAQEFBQADggEBAHJglrfJ3NgpXiOFX7KzLXb7iNcX/nttRbj2hWyfIvwq\nECLsqrkw9qtY1jkQMZkpAL2JZkH7dN6RwRgLn7Vhy506vvWolKMiVW4XSf/SKfE4\nJl3vpao6+XF75tpYHdN0wgH6PmlYX63LaL4ULptswLbcoCb6dxriJNoaN+BnrdFz\ngw2lGh1uEpJ+hGIAF728JRhX8tepb1mIvDS3LoV4nZbcFMMsilKbloxSZj2GFotH\nuFEJjOp9zYhys2AzsfAKRO8P9Qk3iCQOLGsgOqL6EfJANZxEaGM7rDNvY7wsu/LS\ny3Z9fYjYHcgFHW68lKlmjHdxx/qR+i9Rnuk5UrbnBEI=\n-----END CERTIFICATE-----\n\n# Issuer: CN=SwissSign Gold CA - G2 O=SwissSign AG\n# Subject: CN=SwissSign Gold CA - G2 O=SwissSign AG\n# Label: \"SwissSign Gold CA - G2\"\n# Serial: 13492815561806991280\n# MD5 Fingerprint: 24:77:d9:a8:91:d1:3b:fa:88:2d:c2:ff:f8:cd:33:93\n# SHA1 Fingerprint: d8:c5:38:8a:b7:30:1b:1b:6e:d4:7a:e6:45:25:3a:6f:9f:1a:27:61\n# SHA256 Fingerprint: 62:dd:0b:e9:b9:f5:0a:16:3e:a0:f8:e7:5c:05:3b:1e:ca:57:ea:55:c8:68:8f:64:7c:68:81:f2:c8:35:7b:95\n-----BEGIN CERTIFICATE-----\nMIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\nBAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2ln\nbiBHb2xkIENBIC0gRzIwHhcNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBF\nMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZT\nd2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC\nCgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUqt2/8\n76LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+\nbbqBHH5CjCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c\n6bM8K8vzARO/Ws/BtQpgvd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqE\nemA8atufK+ze3gE/bk3lUIbLtK/tREDFylqM2tIrfKjuvqblCqoOpd8FUrdVxyJd\nMmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvRAiTysybUa9oEVeXBCsdt\nMDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuendjIj3o02y\nMszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69y\nFGkOpeUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPi\naG59je883WX0XaxR7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxM\ngI93e2CaHt+28kgeDrpOVG2Y4OGiGqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCB\nqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUWyV7\nlqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64OfPAeGZe6Drn\n8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov\nL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe6\n45R88a7A3hfm5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczO\nUYrHUDFu4Up+GC9pWbY9ZIEr44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5\nO1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOfMke6UiI0HTJ6CVanfCU2qT1L2sCC\nbwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6mGu6uLftIdxf+u+yv\nGPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxpmo/a\n77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCC\nhdiDyyJkvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid3\n92qgQmwLOM7XdVAyksLfKzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEpp\nLd6leNcG2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+w\nZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt\nQc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ\n-----END CERTIFICATE-----\n\n# Issuer: CN=SwissSign Silver CA - G2 O=SwissSign AG\n# Subject: CN=SwissSign Silver CA - G2 O=SwissSign AG\n# Label: \"SwissSign Silver CA - G2\"\n# Serial: 5700383053117599563\n# MD5 Fingerprint: e0:06:a1:c9:7d:cf:c9:fc:0d:c0:56:75:96:d8:62:13\n# SHA1 Fingerprint: 9b:aa:e5:9f:56:ee:21:cb:43:5a:be:25:93:df:a7:f0:40:d1:1d:cb\n# SHA256 Fingerprint: be:6c:4d:a2:bb:b9:ba:59:b6:f3:93:97:68:37:42:46:c3:c0:05:99:3f:a9:8f:02:0d:1d:ed:be:d4:8a:81:d5\n-----BEGIN CERTIFICATE-----\nMIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UE\nBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWdu\nIFNpbHZlciBDQSAtIEcyMB4XDTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0Nlow\nRzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMY\nU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A\nMIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644N0Mv\nFz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7br\nYT7QbNHm+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieF\nnbAVlDLaYQ1HTWBCrpJH6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH\n6ATK72oxh9TAtvmUcXtnZLi2kUpCe2UuMGoM9ZDulebyzYLs2aFK7PayS+VFheZt\neJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5hqAaEuSh6XzjZG6k4sIN/\nc8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5FZGkECwJ\nMoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRH\nHTBsROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTf\njNFusB3hB48IHpmccelM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb6\n5i/4z3GcRm25xBWNOHkDRUjvxF3XCO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOB\nrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU\nF6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRBtjpbO8tFnb0c\nwpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0\ncDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIB\nAHPGgeAn0i0P4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShp\nWJHckRE1qTodvBqlYJ7YH39FkWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9\nxCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L3XWgwF15kIwb4FDm3jH+mHtwX6WQ\n2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx/uNncqCxv1yL5PqZ\nIseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFaDGi8\naRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2X\nem1ZqSqPe97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQR\ndAtq/gsD/KNVV4n+SsuuWxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/\nOMpXEA29MC/HpeZBoNquBYeaoKRlbEwJDIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+\nhAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLy\ntGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u\n-----END CERTIFICATE-----\n\n# Issuer: CN=GeoTrust Primary Certification Authority O=GeoTrust Inc.\n# Subject: CN=GeoTrust Primary Certification Authority O=GeoTrust Inc.\n# Label: \"GeoTrust Primary Certification Authority\"\n# Serial: 32798226551256963324313806436981982369\n# MD5 Fingerprint: 02:26:c3:01:5e:08:30:37:43:a9:d0:7d:cf:37:e6:bf\n# SHA1 Fingerprint: 32:3c:11:8e:1b:f7:b8:b6:52:54:e2:e2:10:0d:d6:02:90:37:f0:96\n# SHA256 Fingerprint: 37:d5:10:06:c5:12:ea:ab:62:64:21:f1:ec:8c:92:01:3f:c5:f8:2a:e9:8e:e5:33:eb:46:19:b8:de:b4:d0:6c\n-----BEGIN CERTIFICATE-----\nMIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBY\nMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo\nR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEx\nMjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQK\nEw1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQcmltYXJ5IENlcnRp\nZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC\nAQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9\nAWbK7hWNb6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjA\nZIVcFU2Ix7e64HXprQU9nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE0\n7e9GceBrAqg1cmuXm2bgyxx5X9gaBGgeRwLmnWDiNpcB3841kt++Z8dtd1k7j53W\nkBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGttm/81w7a4DSwDRp35+MI\nmO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G\nA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJ\nKoZIhvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ1\n6CePbJC/kRYkRj5KTs4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl\n4b7UVXGYNTq+k+qurUKykG/g/CFNNWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6K\noKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHaFloxt/m0cYASSJlyc1pZU8Fj\nUjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG1riR/aYNKxoU\nAT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk=\n-----END CERTIFICATE-----\n\n# Issuer: CN=thawte Primary Root CA O=thawte, Inc. OU=Certification Services Division/(c) 2006 thawte, Inc. - For authorized use only\n# Subject: CN=thawte Primary Root CA O=thawte, Inc. OU=Certification Services Division/(c) 2006 thawte, Inc. - For authorized use only\n# Label: \"thawte Primary Root CA\"\n# Serial: 69529181992039203566298953787712940909\n# MD5 Fingerprint: 8c:ca:dc:0b:22:ce:f5:be:72:ac:41:1a:11:a8:d8:12\n# SHA1 Fingerprint: 91:c6:d6:ee:3e:8a:c8:63:84:e5:48:c2:99:29:5c:75:6c:81:7b:81\n# SHA256 Fingerprint: 8d:72:2f:81:a9:c1:13:c0:79:1d:f1:36:a2:96:6d:b2:6c:95:0a:97:1d:b4:6b:41:99:f4:ea:54:b7:8b:fb:9f\n-----BEGIN CERTIFICATE-----\nMIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB\nqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf\nQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw\nMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV\nBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw\nNzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j\nLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG\nA1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl\nIG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG\nSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs\nW0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta\n3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk\n6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6\nSk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J\nNqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA\nMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP\nr87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU\nDW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz\nYJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX\nxPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2\n/qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/\nLHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7\njVaMaA==\n-----END CERTIFICATE-----\n\n# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G5 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2006 VeriSign, Inc. - For authorized use only\n# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G5 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2006 VeriSign, Inc. - For authorized use only\n# Label: \"VeriSign Class 3 Public Primary Certification Authority - G5\"\n# Serial: 33037644167568058970164719475676101450\n# MD5 Fingerprint: cb:17:e4:31:67:3e:e2:09:fe:45:57:93:f3:0a:fa:1c\n# SHA1 Fingerprint: 4e:b6:d5:78:49:9b:1c:cf:5f:58:1e:ad:56:be:3d:9b:67:44:a5:e5\n# SHA256 Fingerprint: 9a:cf:ab:7e:43:c8:d8:80:d0:6b:26:2a:94:de:ee:e4:b4:65:99:89:c3:d0:ca:f1:9b:af:64:05:e4:1a:b7:df\n-----BEGIN CERTIFICATE-----\nMIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB\nyjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL\nExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp\nU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW\nZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0\naG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL\nMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW\nZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln\nbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp\nU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y\naXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1\nnmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex\nt0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz\nSdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG\nBO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+\nrCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/\nNIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E\nBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH\nBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy\naXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv\nMzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE\np6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y\n5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK\nWE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ\n4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N\nhnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq\n-----END CERTIFICATE-----\n\n# Issuer: CN=SecureTrust CA O=SecureTrust Corporation\n# Subject: CN=SecureTrust CA O=SecureTrust Corporation\n# Label: \"SecureTrust CA\"\n# Serial: 17199774589125277788362757014266862032\n# MD5 Fingerprint: dc:32:c3:a7:6d:25:57:c7:68:09:9d:ea:2d:a9:a2:d1\n# SHA1 Fingerprint: 87:82:c6:c3:04:35:3b:cf:d2:96:92:d2:59:3e:7d:44:d9:34:ff:11\n# SHA256 Fingerprint: f1:c1:b5:0a:e5:a2:0d:d8:03:0e:c9:f6:bc:24:82:3d:d3:67:b5:25:57:59:b4:e7:1b:61:fc:e9:f7:37:5d:73\n-----BEGIN CERTIFICATE-----\nMIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI\nMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x\nFzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz\nMTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv\ncnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN\nAQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz\nZum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO\n0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao\nwW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj\n7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS\n8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT\nBgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB\n/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg\nJYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC\nNxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3\n6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/\n3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm\nD5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS\nCPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR\n3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE=\n-----END CERTIFICATE-----\n\n# Issuer: CN=Secure Global CA O=SecureTrust Corporation\n# Subject: CN=Secure Global CA O=SecureTrust Corporation\n# Label: \"Secure Global CA\"\n# Serial: 9751836167731051554232119481456978597\n# MD5 Fingerprint: cf:f4:27:0d:d4:ed:dc:65:16:49:6d:3d:da:bf:6e:de\n# SHA1 Fingerprint: 3a:44:73:5a:e5:81:90:1f:24:86:61:46:1e:3b:9c:c4:5f:f5:3a:1b\n# SHA256 Fingerprint: 42:00:f5:04:3a:c8:59:0e:bb:52:7d:20:9e:d1:50:30:29:fb:cb:d4:1c:a1:b5:06:ec:27:f1:5a:de:7d:ac:69\n-----BEGIN CERTIFICATE-----\nMIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK\nMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x\nGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx\nMjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg\nQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG\nSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ\niQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa\n/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ\njnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI\nHmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7\nsFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w\ngZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF\nMAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw\nKaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG\nAQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L\nURYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO\nH0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm\nI50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY\niNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc\nf8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW\n-----END CERTIFICATE-----\n\n# Issuer: CN=COMODO Certification Authority O=COMODO CA Limited\n# Subject: CN=COMODO Certification Authority O=COMODO CA Limited\n# Label: \"COMODO Certification Authority\"\n# Serial: 104350513648249232941998508985834464573\n# MD5 Fingerprint: 5c:48:dc:f7:42:72:ec:56:94:6d:1c:cc:71:35:80:75\n# SHA1 Fingerprint: 66:31:bf:9e:f7:4f:9e:b6:c9:d5:a6:0c:ba:6a:be:d1:f7:bd:ef:7b\n# SHA256 Fingerprint: 0c:2c:d6:3d:f7:80:6f:a3:99:ed:e8:09:11:6b:57:5b:f8:79:89:f0:65:18:f9:80:8c:86:05:03:17:8b:af:66\n-----BEGIN CERTIFICATE-----\nMIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB\ngTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G\nA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV\nBAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw\nMDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl\nYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P\nRE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0\naG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3\nUcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI\n2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8\nQ5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp\n+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+\nDT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O\nnKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW\n/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g\nPKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u\nQXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY\nSdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv\nIC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/\nRxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4\nzJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd\nBA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB\nZQ==\n-----END CERTIFICATE-----\n\n# Issuer: CN=Network Solutions Certificate Authority O=Network Solutions L.L.C.\n# Subject: CN=Network Solutions Certificate Authority O=Network Solutions L.L.C.\n# Label: \"Network Solutions Certificate Authority\"\n# Serial: 116697915152937497490437556386812487904\n# MD5 Fingerprint: d3:f3:a6:16:c0:fa:6b:1d:59:b1:2d:96:4d:0e:11:2e\n# SHA1 Fingerprint: 74:f8:a3:c3:ef:e7:b3:90:06:4b:83:90:3c:21:64:60:20:e5:df:ce\n# SHA256 Fingerprint: 15:f0:ba:00:a3:ac:7a:f3:ac:88:4c:07:2b:10:11:a0:77:bd:77:c0:97:f4:01:64:b2:f8:59:8a:bd:83:86:0c\n-----BEGIN CERTIFICATE-----\nMIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBi\nMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu\nMTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3Jp\ndHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMxMjM1OTU5WjBiMQswCQYDVQQGEwJV\nUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydO\nZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG\nSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwz\nc7MEL7xxjOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPP\nOCwGJgl6cvf6UDL4wpPTaaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rl\nmGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXTcrA/vGp97Eh/jcOrqnErU2lBUzS1sLnF\nBgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc/Qzpf14Dl847ABSHJ3A4\nqY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMBAAGjgZcw\ngZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIB\nBjAPBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwu\nbmV0c29sc3NsLmNvbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3Jp\ndHkuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc8\n6fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q4LqILPxFzBiwmZVRDuwduIj/\nh1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/GGUsyfJj4akH\n/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv\nwKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN\npGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey\n-----END CERTIFICATE-----\n\n# Issuer: CN=WellsSecure Public Root Certificate Authority O=Wells Fargo WellsSecure OU=Wells Fargo Bank NA\n# Subject: CN=WellsSecure Public Root Certificate Authority O=Wells Fargo WellsSecure OU=Wells Fargo Bank NA\n# Label: \"WellsSecure Public Root Certificate Authority\"\n# Serial: 1\n# MD5 Fingerprint: 15:ac:a5:c2:92:2d:79:bc:e8:7f:cb:67:ed:02:cf:36\n# SHA1 Fingerprint: e7:b4:f6:9d:61:ec:90:69:db:7e:90:a7:40:1a:3c:f4:7d:4f:e8:ee\n# SHA256 Fingerprint: a7:12:72:ae:aa:a3:cf:e8:72:7f:7f:b3:9f:0f:b3:d1:e5:42:6e:90:60:b0:6e:e6:f1:3e:9a:3c:58:33:cd:43\n-----BEGIN CERTIFICATE-----\nMIIEvTCCA6WgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhTELMAkGA1UEBhMCVVMx\nIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxs\ncyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9v\ndCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDcxMjEzMTcwNzU0WhcNMjIxMjE0\nMDAwNzU0WjCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdl\nbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQD\nDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkw\nggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDub7S9eeKPCCGeOARBJe+r\nWxxTkqxtnt3CxC5FlAM1iGd0V+PfjLindo8796jE2yljDpFoNoqXjopxaAkH5OjU\nDk/41itMpBb570OYj7OeUt9tkTmPOL13i0Nj67eT/DBMHAGTthP796EfvyXhdDcs\nHqRePGj4S78NuR4uNuip5Kf4D8uCdXw1LSLWwr8L87T8bJVhHlfXBIEyg1J55oNj\nz7fLY4sR4r1e6/aN7ZVyKLSsEmLpSjPmgzKuBXWVvYSV2ypcm44uDLiBK0HmOFaf\nSZtsdvqKXfcBeYF8wYNABf5x/Qw/zE5gCQ5lRxAvAcAFP4/4s0HvWkJ+We/Slwxl\nAgMBAAGjggE0MIIBMDAPBgNVHRMBAf8EBTADAQH/MDkGA1UdHwQyMDAwLqAsoCqG\nKGh0dHA6Ly9jcmwucGtpLndlbGxzZmFyZ28uY29tL3dzcHJjYS5jcmwwDgYDVR0P\nAQH/BAQDAgHGMB0GA1UdDgQWBBQmlRkQ2eihl5H/3BnZtQQ+0nMKajCBsgYDVR0j\nBIGqMIGngBQmlRkQ2eihl5H/3BnZtQQ+0nMKaqGBi6SBiDCBhTELMAkGA1UEBhMC\nVVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNX\nZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMg\nUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCAQEwDQYJKoZIhvcNAQEFBQADggEB\nALkVsUSRzCPIK0134/iaeycNzXK7mQDKfGYZUMbVmO2rvwNa5U3lHshPcZeG1eMd\n/ZDJPHV3V3p9+N701NX3leZ0bh08rnyd2wIDBSxxSyU+B+NemvVmFymIGjifz6pB\nA4SXa5M4esowRBskRDPQ5NHcKDj0E0M1NSljqHyita04pO2t/caaH/+Xc/77szWn\nk4bGdpEA5qxRFsQnMlzbc9qlk1eOPm01JghZ1edE13YgY+esE2fDbbFwRnzVlhE9\niW9dqKHrjQrawx0zbKPqZxmamX9LPYNRKh3KL4YMon4QLSvUFpULB6ouFJJJtylv\n2G0xffX8oRAHh84vWdw+WNs=\n-----END CERTIFICATE-----\n\n# Issuer: CN=COMODO ECC Certification Authority O=COMODO CA Limited\n# Subject: CN=COMODO ECC Certification Authority O=COMODO CA Limited\n# Label: \"COMODO ECC Certification Authority\"\n# Serial: 41578283867086692638256921589707938090\n# MD5 Fingerprint: 7c:62:ff:74:9d:31:53:5e:68:4a:d5:78:aa:1e:bf:23\n# SHA1 Fingerprint: 9f:74:4e:9f:2b:4d:ba:ec:0f:31:2c:50:b6:56:3b:8e:2d:93:c3:11\n# SHA256 Fingerprint: 17:93:92:7a:06:14:54:97:89:ad:ce:2f:8f:34:f7:f0:b6:6d:0f:3a:e3:a3:b8:4d:21:ec:15:db:ba:4f:ad:c7\n-----BEGIN CERTIFICATE-----\nMIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL\nMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE\nBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT\nIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw\nMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy\nZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N\nT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv\nbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR\nFtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J\ncfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW\nBBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/\nBAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm\nfQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv\nGDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY=\n-----END CERTIFICATE-----\n\n# Issuer: CN=IGC/A O=PM/SGDN OU=DCSSI\n# Subject: CN=IGC/A O=PM/SGDN OU=DCSSI\n# Label: \"IGC/A\"\n# Serial: 245102874772\n# MD5 Fingerprint: 0c:7f:dd:6a:f4:2a:b9:c8:9b:bd:20:7e:a9:db:5c:37\n# SHA1 Fingerprint: 60:d6:89:74:b5:c2:65:9e:8a:0f:c1:88:7c:88:d2:46:69:1b:18:2c\n# SHA256 Fingerprint: b9:be:a7:86:0a:96:2e:a3:61:1d:ab:97:ab:6d:a3:e2:1c:10:68:b9:7d:55:57:5e:d0:e1:12:79:c1:1c:89:32\n-----BEGIN CERTIFICATE-----\nMIIEAjCCAuqgAwIBAgIFORFFEJQwDQYJKoZIhvcNAQEFBQAwgYUxCzAJBgNVBAYT\nAkZSMQ8wDQYDVQQIEwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQ\nTS9TR0ROMQ4wDAYDVQQLEwVEQ1NTSTEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG\n9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZyMB4XDTAyMTIxMzE0MjkyM1oXDTIw\nMTAxNzE0MjkyMlowgYUxCzAJBgNVBAYTAkZSMQ8wDQYDVQQIEwZGcmFuY2UxDjAM\nBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVEQ1NTSTEO\nMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2\nLmZyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsh/R0GLFMzvABIaI\ns9z4iPf930Pfeo2aSVz2TqrMHLmh6yeJ8kbpO0px1R2OLc/mratjUMdUC24SyZA2\nxtgv2pGqaMVy/hcKshd+ebUyiHDKcMCWSo7kVc0dJ5S/znIq7Fz5cyD+vfcuiWe4\nu0dzEvfRNWk68gq5rv9GQkaiv6GFGvm/5P9JhfejcIYyHF2fYPepraX/z9E0+X1b\nF8bc1g4oa8Ld8fUzaJ1O/Id8NhLWo4DoQw1VYZTqZDdH6nfK0LJYBcNdfrGoRpAx\nVs5wKpayMLh35nnAvSk7/ZR3TL0gzUEl4C7HG7vupARB0l2tEmqKm0f7yd1GQOGd\nPDPQtQIDAQABo3cwdTAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBRjAVBgNV\nHSAEDjAMMAoGCCqBegF5AQEBMB0GA1UdDgQWBBSjBS8YYFDCiQrdKyFP/45OqDAx\nNjAfBgNVHSMEGDAWgBSjBS8YYFDCiQrdKyFP/45OqDAxNjANBgkqhkiG9w0BAQUF\nAAOCAQEABdwm2Pp3FURo/C9mOnTgXeQp/wYHE4RKq89toB9RlPhJy3Q2FLwV3duJ\nL92PoF189RLrn544pEfMs5bZvpwlqwN+Mw+VgQ39FuCIvjfwbF3QMZsyK10XZZOY\nYLxuj7GoPB7ZHPOpJkL5ZB3C55L29B5aqhlSXa/oovdgoPaN8In1buAKBQGVyYsg\nCrpa/JosPL3Dt8ldeCUFP1YUmwza+zpI/pdpXsoQhvdOlgQITeywvl3cO45Pwf2a\nNjSaTFR+FwNIlQgRHAdvhQh+XU3Endv7rs6y0bO4g2wdsrN58dhwmX7wEwLOXt1R\n0982gaEbeC9xs/FZTEYYKKuF0mBWWg==\n-----END CERTIFICATE-----\n\n# Issuer: O=SECOM Trust Systems CO.,LTD. OU=Security Communication EV RootCA1\n# Subject: O=SECOM Trust Systems CO.,LTD. OU=Security Communication EV RootCA1\n# Label: \"Security Communication EV RootCA1\"\n# Serial: 0\n# MD5 Fingerprint: 22:2d:a6:01:ea:7c:0a:f7:f0:6c:56:43:3f:77:76:d3\n# SHA1 Fingerprint: fe:b8:c4:32:dc:f9:76:9a:ce:ae:3d:d8:90:8f:fd:28:86:65:64:7d\n# SHA256 Fingerprint: a2:2d:ba:68:1e:97:37:6e:2d:39:7d:72:8a:ae:3a:9b:62:96:b9:fd:ba:60:bc:2e:11:f6:47:f2:c6:75:fb:37\n-----BEGIN CERTIFICATE-----\nMIIDfTCCAmWgAwIBAgIBADANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJKUDEl\nMCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEqMCgGA1UECxMh\nU2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBFViBSb290Q0ExMB4XDTA3MDYwNjAyMTIz\nMloXDTM3MDYwNjAyMTIzMlowYDELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09N\nIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKjAoBgNVBAsTIVNlY3VyaXR5IENvbW11\nbmljYXRpb24gRVYgUm9vdENBMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\nggEBALx/7FebJOD+nLpCeamIivqA4PUHKUPqjgo0No0c+qe1OXj/l3X3L+SqawSE\nRMqm4miO/VVQYg+kcQ7OBzgtQoVQrTyWb4vVog7P3kmJPdZkLjjlHmy1V4qe70gO\nzXppFodEtZDkBp2uoQSXWHnvIEqCa4wiv+wfD+mEce3xDuS4GBPMVjZd0ZoeUWs5\nbmB2iDQL87PRsJ3KYeJkHcFGB7hj3R4zZbOOCVVSPbW9/wfrrWFVGCypaZhKqkDF\nMxRldAD5kd6vA0jFQFTcD4SQaCDFkpbcLuUCRarAX1T4bepJz11sS6/vmsJWXMY1\nVkJqMF/Cq/biPT+zyRGPMUzXn0kCAwEAAaNCMEAwHQYDVR0OBBYEFDVK9U2vP9eC\nOKyrcWUXdYydVZPmMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0G\nCSqGSIb3DQEBBQUAA4IBAQCoh+ns+EBnXcPBZsdAS5f8hxOQWsTvoMpfi7ent/HW\ntWS3irO4G8za+6xmiEHO6Pzk2x6Ipu0nUBsCMCRGef4Eh3CXQHPRwMFXGZpppSeZ\nq51ihPZRwSzJIxXYKLerJRO1RuGGAv8mjMSIkh1W/hln8lXkgKNrnKt34VFxDSDb\nEJrbvXZ5B3eZKK2aXtqxT0QsNY6llsf9g/BYxnnWmHyojf6GPgcWkuF75x3sM3Z+\nQi5KhfmRiWiEA4Glm5q+4zfFVKtWOxgtQaQM+ELbmaDgcm+7XeEWT1MKZPlO9L9O\nVL14bIjqv5wTJMJwaaJ/D8g8rQjJsJhAoyrniIPtd490\n-----END CERTIFICATE-----\n\n# Issuer: CN=OISTE WISeKey Global Root GA CA O=WISeKey OU=Copyright (c) 2005/OISTE Foundation Endorsed\n# Subject: CN=OISTE WISeKey Global Root GA CA O=WISeKey OU=Copyright (c) 2005/OISTE Foundation Endorsed\n# Label: \"OISTE WISeKey Global Root GA CA\"\n# Serial: 86718877871133159090080555911823548314\n# MD5 Fingerprint: bc:6c:51:33:a7:e9:d3:66:63:54:15:72:1b:21:92:93\n# SHA1 Fingerprint: 59:22:a1:e1:5a:ea:16:35:21:f8:98:39:6a:46:46:b0:44:1b:0f:a9\n# SHA256 Fingerprint: 41:c9:23:86:6a:b4:ca:d6:b7:ad:57:80:81:58:2e:02:07:97:a6:cb:df:4f:ff:78:ce:83:96:b3:89:37:d7:f5\n-----BEGIN CERTIFICATE-----\nMIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCB\nijELMAkGA1UEBhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHly\naWdodCAoYykgMjAwNTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl\nZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQSBDQTAeFw0w\nNTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYDVQQGEwJDSDEQMA4G\nA1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIwIAYD\nVQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBX\nSVNlS2V5IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\nMIIBCgKCAQEAy0+zAJs9Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxR\nVVuuk+g3/ytr6dTqvirdqFEr12bDYVxgAsj1znJ7O7jyTmUIms2kahnBAbtzptf2\nw93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbDd50kc3vkDIzh2TbhmYsF\nmQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ/yxViJGg\n4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t9\n4B3RLoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYw\nDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQw\nEAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOx\nSPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vImMMkQyh2I+3QZH4VFvbBsUfk2\nftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4+vg1YFkCExh8\nvPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa\nhNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZi\nFj4A4xylNoEYokxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ\n/L7fCg0=\n-----END CERTIFICATE-----\n\n# Issuer: CN=Microsec e-Szigno Root CA O=Microsec Ltd. OU=e-Szigno CA\n# Subject: CN=Microsec e-Szigno Root CA O=Microsec Ltd. OU=e-Szigno CA\n# Label: \"Microsec e-Szigno Root CA\"\n# Serial: 272122594155480254301341951808045322001\n# MD5 Fingerprint: f0:96:b6:2f:c5:10:d5:67:8e:83:25:32:e8:5e:2e:e5\n# SHA1 Fingerprint: 23:88:c9:d3:71:cc:9e:96:3d:ff:7d:3c:a7:ce:fc:d6:25:ec:19:0d\n# SHA256 Fingerprint: 32:7a:3d:76:1a:ba:de:a0:34:eb:99:84:06:27:5c:b1:a4:77:6e:fd:ae:2f:df:6d:01:68:ea:1c:4f:55:67:d0\n-----BEGIN CERTIFICATE-----\nMIIHqDCCBpCgAwIBAgIRAMy4579OKRr9otxmpRwsDxEwDQYJKoZIhvcNAQEFBQAw\ncjELMAkGA1UEBhMCSFUxETAPBgNVBAcTCEJ1ZGFwZXN0MRYwFAYDVQQKEw1NaWNy\nb3NlYyBMdGQuMRQwEgYDVQQLEwtlLVN6aWdubyBDQTEiMCAGA1UEAxMZTWljcm9z\nZWMgZS1Temlnbm8gUm9vdCBDQTAeFw0wNTA0MDYxMjI4NDRaFw0xNzA0MDYxMjI4\nNDRaMHIxCzAJBgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVzdDEWMBQGA1UEChMN\nTWljcm9zZWMgTHRkLjEUMBIGA1UECxMLZS1Temlnbm8gQ0ExIjAgBgNVBAMTGU1p\nY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw\nggEKAoIBAQDtyADVgXvNOABHzNuEwSFpLHSQDCHZU4ftPkNEU6+r+ICbPHiN1I2u\nuO/TEdyB5s87lozWbxXGd36hL+BfkrYn13aaHUM86tnsL+4582pnS4uCzyL4ZVX+\nLMsvfUh6PXX5qqAnu3jCBspRwn5mS6/NoqdNAoI/gqyFxuEPkEeZlApxcpMqyabA\nvjxWTHOSJ/FrtfX9/DAFYJLG65Z+AZHCabEeHXtTRbjcQR/Ji3HWVBTji1R4P770\nYjtb9aPs1ZJ04nQw7wHb4dSrmZsqa/i9phyGI0Jf7Enemotb9HI6QMVJPqW+jqpx\n62z69Rrkav17fVVA71hu5tnVvCSrwe+3AgMBAAGjggQ3MIIEMzBnBggrBgEFBQcB\nAQRbMFkwKAYIKwYBBQUHMAGGHGh0dHBzOi8vcmNhLmUtc3ppZ25vLmh1L29jc3Aw\nLQYIKwYBBQUHMAKGIWh0dHA6Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNydDAP\nBgNVHRMBAf8EBTADAQH/MIIBcwYDVR0gBIIBajCCAWYwggFiBgwrBgEEAYGoGAIB\nAQEwggFQMCgGCCsGAQUFBwIBFhxodHRwOi8vd3d3LmUtc3ppZ25vLmh1L1NaU1ov\nMIIBIgYIKwYBBQUHAgIwggEUHoIBEABBACAAdABhAG4A+gBzAO0AdAB2AOEAbgB5\nACAA6QByAHQAZQBsAG0AZQB6AOkAcwDpAGgAZQB6ACAA6QBzACAAZQBsAGYAbwBn\nAGEAZADhAHMA4QBoAG8AegAgAGEAIABTAHoAbwBsAGcA4QBsAHQAYQB0APMAIABT\nAHoAbwBsAGcA4QBsAHQAYQB0AOEAcwBpACAAUwB6AGEAYgDhAGwAeQB6AGEAdABh\nACAAcwB6AGUAcgBpAG4AdAAgAGsAZQBsAGwAIABlAGwAagDhAHIAbgBpADoAIABo\nAHQAdABwADoALwAvAHcAdwB3AC4AZQAtAHMAegBpAGcAbgBvAC4AaAB1AC8AUwBa\nAFMAWgAvMIHIBgNVHR8EgcAwgb0wgbqggbeggbSGIWh0dHA6Ly93d3cuZS1zemln\nbm8uaHUvUm9vdENBLmNybIaBjmxkYXA6Ly9sZGFwLmUtc3ppZ25vLmh1L0NOPU1p\nY3Jvc2VjJTIwZS1Temlnbm8lMjBSb290JTIwQ0EsT1U9ZS1Temlnbm8lMjBDQSxP\nPU1pY3Jvc2VjJTIwTHRkLixMPUJ1ZGFwZXN0LEM9SFU/Y2VydGlmaWNhdGVSZXZv\nY2F0aW9uTGlzdDtiaW5hcnkwDgYDVR0PAQH/BAQDAgEGMIGWBgNVHREEgY4wgYuB\nEGluZm9AZS1zemlnbm8uaHWkdzB1MSMwIQYDVQQDDBpNaWNyb3NlYyBlLVN6aWdu\nw7MgUm9vdCBDQTEWMBQGA1UECwwNZS1TemlnbsOzIEhTWjEWMBQGA1UEChMNTWlj\ncm9zZWMgS2Z0LjERMA8GA1UEBxMIQnVkYXBlc3QxCzAJBgNVBAYTAkhVMIGsBgNV\nHSMEgaQwgaGAFMegSXUWYYTbMUuE0vE3QJDvTtz3oXakdDByMQswCQYDVQQGEwJI\nVTERMA8GA1UEBxMIQnVkYXBlc3QxFjAUBgNVBAoTDU1pY3Jvc2VjIEx0ZC4xFDAS\nBgNVBAsTC2UtU3ppZ25vIENBMSIwIAYDVQQDExlNaWNyb3NlYyBlLVN6aWdubyBS\nb290IENBghEAzLjnv04pGv2i3GalHCwPETAdBgNVHQ4EFgQUx6BJdRZhhNsxS4TS\n8TdAkO9O3PcwDQYJKoZIhvcNAQEFBQADggEBANMTnGZjWS7KXHAM/IO8VbH0jgds\nZifOwTsgqRy7RlRw7lrMoHfqaEQn6/Ip3Xep1fvj1KcExJW4C+FEaGAHQzAxQmHl\n7tnlJNUb3+FKG6qfx1/4ehHqE5MAyopYse7tDk2016g2JnzgOsHVV4Lxdbb9iV/a\n86g4nzUGCM4ilb7N1fy+W955a9x6qWVmvrElWl/tftOsRm1M9DKHtCAE4Gx4sHfR\nhUZLphK3dehKyVZs15KrnfVJONJPU+NVkBHbmJbGSfI+9J8b4PeI3CVimUTYc78/\nMPMMNz7UwiiAc7EBt51alhQBS6kRnSlqLtBdgcDPsiBDxwPgN05dCtxZICU=\n-----END CERTIFICATE-----\n\n# Issuer: CN=Certigna O=Dhimyotis\n# Subject: CN=Certigna O=Dhimyotis\n# Label: \"Certigna\"\n# Serial: 18364802974209362175\n# MD5 Fingerprint: ab:57:a6:5b:7d:42:82:19:b5:d8:58:26:28:5e:fd:ff\n# SHA1 Fingerprint: b1:2e:13:63:45:86:a4:6f:1a:b2:60:68:37:58:2d:c4:ac:fd:94:97\n# SHA256 Fingerprint: e3:b6:a2:db:2e:d7:ce:48:84:2f:7a:c5:32:41:c7:b7:1d:54:14:4b:fb:40:c1:1f:3f:1d:0b:42:f5:ee:a1:2d\n-----BEGIN CERTIFICATE-----\nMIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV\nBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X\nDTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ\nBgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwIQ2VydGlnbmEwggEiMA0GCSqGSIb3\nDQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7qXOEm7RFHYeGifBZ4\nQCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyHGxny\ngQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbw\nzBfsV1/pogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q\n130yGLMLLGq/jj8UEYkgDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2\nJsglrgVKtOdjLPOMFlN+XPsRGgjBRmKfIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkw\nDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQtCRZvgHyUtVF9lo53BEw\nZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJBgNVBAYT\nAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzj\nAQ/JSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG\n9w0BAQUFAAOCAQEAhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8h\nbV6lUmPOEvjvKtpv6zf+EwLHyzs+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFnc\nfca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu\nHWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w\nt0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw\nWyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg==\n-----END CERTIFICATE-----\n\n# Issuer: CN=TC TrustCenter Class 2 CA II O=TC TrustCenter GmbH OU=TC TrustCenter Class 2 CA\n# Subject: CN=TC TrustCenter Class 2 CA II O=TC TrustCenter GmbH OU=TC TrustCenter Class 2 CA\n# Label: \"TC TrustCenter Class 2 CA II\"\n# Serial: 941389028203453866782103406992443\n# MD5 Fingerprint: ce:78:33:5c:59:78:01:6e:18:ea:b9:36:a0:b9:2e:23\n# SHA1 Fingerprint: ae:50:83:ed:7c:f4:5c:bc:8f:61:c6:21:fe:68:5d:79:42:21:15:6e\n# SHA256 Fingerprint: e6:b8:f8:76:64:85:f8:07:ae:7f:8d:ac:16:70:46:1f:07:c0:a1:3e:ef:3a:1f:f7:17:53:8d:7a:ba:d3:91:b4\n-----BEGIN CERTIFICATE-----\nMIIEqjCCA5KgAwIBAgIOLmoAAQACH9dSISwRXDswDQYJKoZIhvcNAQEFBQAwdjEL\nMAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNV\nBAsTGVRDIFRydXN0Q2VudGVyIENsYXNzIDIgQ0ExJTAjBgNVBAMTHFRDIFRydXN0\nQ2VudGVyIENsYXNzIDIgQ0EgSUkwHhcNMDYwMTEyMTQzODQzWhcNMjUxMjMxMjI1\nOTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i\nSDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQTElMCMGA1UEAxMc\nVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQAD\nggEPADCCAQoCggEBAKuAh5uO8MN8h9foJIIRszzdQ2Lu+MNF2ujhoF/RKrLqk2jf\ntMjWQ+nEdVl//OEd+DFwIxuInie5e/060smp6RQvkL4DUsFJzfb95AhmC1eKokKg\nuNV/aVyQMrKXDcpK3EY+AlWJU+MaWss2xgdW94zPEfRMuzBwBJWl9jmM/XOBCH2J\nXjIeIqkiRUuwZi4wzJ9l/fzLganx4Duvo4bRierERXlQXa7pIXSSTYtZgo+U4+lK\n8edJsBTj9WLL1XK9H7nSn6DNqPoByNkN39r8R52zyFTfSUrxIan+GE7uSNQZu+99\n5OKdy1u2bv/jzVrndIIFuoAlOMvkaZ6vQaoahPUCAwEAAaOCATQwggEwMA8GA1Ud\nEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTjq1RMgKHbVkO3\nkUrL84J6E1wIqzCB7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRy\ndXN0Y2VudGVyLmRlL2NybC92Mi90Y19jbGFzc18yX2NhX0lJLmNybIaBn2xkYXA6\nLy93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBUcnVzdENlbnRlciUyMENsYXNz\nJTIwMiUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21iSCxPVT1yb290\nY2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u\nTGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEAjNfffu4bgBCzg/XbEeprS6iS\nGNn3Bzn1LL4GdXpoUxUc6krtXvwjshOg0wn/9vYua0Fxec3ibf2uWWuFHbhOIprt\nZjluS5TmVfwLG4t3wVMTZonZKNaL80VKY7f9ewthXbhtvsPcW3nS7Yblok2+XnR8\nau0WOB9/WIFaGusyiC2y8zl3gK9etmF1KdsjTYjKUCjLhdLTEKJZbtOTVAB6okaV\nhgWcqRmY5TFyDADiZ9lA4CQze28suVyrZZ0srHbqNZn1l7kPJOzHdiEoZa5X6AeI\ndUpWoNIFOqTmjZKILPPy4cHGYdtBxceb9w4aUUXCYWvcZCcXjFq32nQozZfkvQ==\n-----END CERTIFICATE-----\n\n# Issuer: CN=TC TrustCenter Class 3 CA II O=TC TrustCenter GmbH OU=TC TrustCenter Class 3 CA\n# Subject: CN=TC TrustCenter Class 3 CA II O=TC TrustCenter GmbH OU=TC TrustCenter Class 3 CA\n# Label: \"TC TrustCenter Class 3 CA II\"\n# Serial: 1506523511417715638772220530020799\n# MD5 Fingerprint: 56:5f:aa:80:61:12:17:f6:67:21:e6:2b:6d:61:56:8e\n# SHA1 Fingerprint: 80:25:ef:f4:6e:70:c8:d4:72:24:65:84:fe:40:3b:8a:8d:6a:db:f5\n# SHA256 Fingerprint: 8d:a0:84:fc:f9:9c:e0:77:22:f8:9b:32:05:93:98:06:fa:5c:b8:11:e1:c8:13:f6:a1:08:c7:d3:36:b3:40:8e\n-----BEGIN CERTIFICATE-----\nMIIEqjCCA5KgAwIBAgIOSkcAAQAC5aBd1j8AUb8wDQYJKoZIhvcNAQEFBQAwdjEL\nMAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNV\nBAsTGVRDIFRydXN0Q2VudGVyIENsYXNzIDMgQ0ExJTAjBgNVBAMTHFRDIFRydXN0\nQ2VudGVyIENsYXNzIDMgQ0EgSUkwHhcNMDYwMTEyMTQ0MTU3WhcNMjUxMjMxMjI1\nOTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i\nSDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQTElMCMGA1UEAxMc\nVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQAD\nggEPADCCAQoCggEBALTgu1G7OVyLBMVMeRwjhjEQY0NVJz/GRcekPewJDRoeIMJW\nHt4bNwcwIi9v8Qbxq63WyKthoy9DxLCyLfzDlml7forkzMA5EpBCYMnMNWju2l+Q\nVl/NHE1bWEnrDgFPZPosPIlY2C8u4rBo6SI7dYnWRBpl8huXJh0obazovVkdKyT2\n1oQDZogkAHhg8fir/gKya/si+zXmFtGt9i4S5Po1auUZuV3bOx4a+9P/FRQI2Alq\nukWdFHlgfa9Aigdzs5OW03Q0jTo3Kd5c7PXuLjHCINy+8U9/I1LZW+Jk2ZyqBwi1\nRb3R0DHBq1SfqdLDYmAD8bs5SpJKPQq5ncWg/jcCAwEAAaOCATQwggEwMA8GA1Ud\nEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTUovyfs8PYA9NX\nXAek0CSnwPIA1DCB7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRy\ndXN0Y2VudGVyLmRlL2NybC92Mi90Y19jbGFzc18zX2NhX0lJLmNybIaBn2xkYXA6\nLy93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBUcnVzdENlbnRlciUyMENsYXNz\nJTIwMyUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21iSCxPVT1yb290\nY2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u\nTGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEANmDkcPcGIEPZIxpC8vijsrlN\nirTzwppVMXzEO2eatN9NDoqTSheLG43KieHPOh6sHfGcMrSOWXaiQYUlN6AT0PV8\nTtXqluJucsG7Kv5sbviRmEb8yRtXW+rIGjs/sFGYPAfaLFkB2otE6OF0/ado3VS6\ng0bsyEa1+K+XwDsJHI/OcpY9M1ZwvJbL2NV9IJqDnxrcOfHFcqMRA/07QlIp2+gB\n95tejNaNhk4Z+rwcvsUhpYeeeC422wlxo3I0+GzjBgnyXlal092Y+tTmBvTwtiBj\nS+opvaqCZh77gaqnN60TGOaSw4HBM7uIHqHn4rS9MWwOUT1v+5ZWgOI2F9Hc5A==\n-----END CERTIFICATE-----\n\n# Issuer: CN=TC TrustCenter Universal CA I O=TC TrustCenter GmbH OU=TC TrustCenter Universal CA\n# Subject: CN=TC TrustCenter Universal CA I O=TC TrustCenter GmbH OU=TC TrustCenter Universal CA\n# Label: \"TC TrustCenter Universal CA I\"\n# Serial: 601024842042189035295619584734726\n# MD5 Fingerprint: 45:e1:a5:72:c5:a9:36:64:40:9e:f5:e4:58:84:67:8c\n# SHA1 Fingerprint: 6b:2f:34:ad:89:58:be:62:fd:b0:6b:5c:ce:bb:9d:d9:4f:4e:39:f3\n# SHA256 Fingerprint: eb:f3:c0:2a:87:89:b1:fb:7d:51:19:95:d6:63:b7:29:06:d9:13:ce:0d:5e:10:56:8a:8a:77:e2:58:61:67:e7\n-----BEGIN CERTIFICATE-----\nMIID3TCCAsWgAwIBAgIOHaIAAQAC7LdggHiNtgYwDQYJKoZIhvcNAQEFBQAweTEL\nMAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNV\nBAsTG1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQTEmMCQGA1UEAxMdVEMgVHJ1\nc3RDZW50ZXIgVW5pdmVyc2FsIENBIEkwHhcNMDYwMzIyMTU1NDI4WhcNMjUxMjMx\nMjI1OTU5WjB5MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIg\nR21iSDEkMCIGA1UECxMbVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBMSYwJAYD\nVQQDEx1UQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0EgSTCCASIwDQYJKoZIhvcN\nAQEBBQADggEPADCCAQoCggEBAKR3I5ZEr5D0MacQ9CaHnPM42Q9e3s9B6DGtxnSR\nJJZ4Hgmgm5qVSkr1YnwCqMqs+1oEdjneX/H5s7/zA1hV0qq34wQi0fiU2iIIAI3T\nfCZdzHd55yx4Oagmcw6iXSVphU9VDprvxrlE4Vc93x9UIuVvZaozhDrzznq+VZeu\njRIPFDPiUHDDSYcTvFHe15gSWu86gzOSBnWLknwSaHtwag+1m7Z3W0hZneTvWq3z\nwZ7U10VOylY0Ibw+F1tvdwxIAUMpsN0/lm7mlaoMwCC2/T42J5zjXM9OgdwZu5GQ\nfezmlwQek8wiSdeXhrYTCjxDI3d+8NzmzSQfO4ObNDqDNOMCAwEAAaNjMGEwHwYD\nVR0jBBgwFoAUkqR1LKSevoFE63n8isWVpesQdXMwDwYDVR0TAQH/BAUwAwEB/zAO\nBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFJKkdSyknr6BROt5/IrFlaXrEHVzMA0G\nCSqGSIb3DQEBBQUAA4IBAQAo0uCG1eb4e/CX3CJrO5UUVg8RMKWaTzqwOuAGy2X1\n7caXJ/4l8lfmXpWMPmRgFVp/Lw0BxbFg/UU1z/CyvwbZ71q+s2IhtNerNXxTPqYn\n8aEt2hojnczd7Dwtnic0XQ/CNnm8yUpiLe1r2X1BQ3y2qsrtYbE3ghUJGooWMNjs\nydZHcnhLEEYUjl8Or+zHL6sQ17bxbuyGssLoDZJz3KL0Dzq/YSMQiZxIQG5wALPT\nujdEWBF6AmqI8Dc08BnprNRlc/ZpjGSUOnmFKbAWKwyCPwacx/0QK54PLLae4xW/\n2TYcuiUaUj0a7CIMHOCkoj3w6DnPgcB77V0fb8XQC9eY\n-----END CERTIFICATE-----\n\n# Issuer: CN=Deutsche Telekom Root CA 2 O=Deutsche Telekom AG OU=T-TeleSec Trust Center\n# Subject: CN=Deutsche Telekom Root CA 2 O=Deutsche Telekom AG OU=T-TeleSec Trust Center\n# Label: \"Deutsche Telekom Root CA 2\"\n# Serial: 38\n# MD5 Fingerprint: 74:01:4a:91:b1:08:c4:58:ce:47:cd:f0:dd:11:53:08\n# SHA1 Fingerprint: 85:a4:08:c0:9c:19:3e:5d:51:58:7d:cd:d6:13:30:fd:8c:de:37:bf\n# SHA256 Fingerprint: b6:19:1a:50:d0:c3:97:7f:7d:a9:9b:cd:aa:c8:6a:22:7d:ae:b9:67:9e:c7:0b:a3:b0:c9:d9:22:71:c1:70:d3\n-----BEGIN CERTIFICATE-----\nMIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEc\nMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2Vj\nIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENB\nIDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5MjM1OTAwWjBxMQswCQYDVQQGEwJE\nRTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxl\nU2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290\nIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEU\nha88EOQ5bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhC\nQN/Po7qCWWqSG6wcmtoIKyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1Mjwr\nrFDa1sPeg5TKqAyZMg4ISFZbavva4VhYAUlfckE8FQYBjl2tqriTtM2e66foai1S\nNNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aKSe5TBY8ZTNXeWHmb0moc\nQqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTVjlsB9WoH\ntxa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAP\nBgNVHRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOC\nAQEAlGRZrTlk5ynrE/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756Abrsp\ntJh6sTtU6zkXR34ajgv8HzFZMQSyzhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpa\nIzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8rZ7/gFnkm0W09juwzTkZmDLl\n6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4Gdyd1Lx+4ivn+\nxbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU\nCm26OWMohpLzGITY+9HPBVZkVw==\n-----END CERTIFICATE-----\n\n# Issuer: CN=ComSign Secured CA O=ComSign\n# Subject: CN=ComSign Secured CA O=ComSign\n# Label: \"ComSign Secured CA\"\n# Serial: 264725503855295744117309814499492384489\n# MD5 Fingerprint: 40:01:25:06:8d:21:43:6a:0e:43:00:9c:e7:43:f3:d5\n# SHA1 Fingerprint: f9:cd:0e:2c:da:76:24:c1:8f:bd:f0:f0:ab:b6:45:b8:f7:fe:d5:7a\n# SHA256 Fingerprint: 50:79:41:c7:44:60:a0:b4:70:86:22:0d:4e:99:32:57:2a:b5:d1:b5:bb:cb:89:80:ab:1c:b1:76:51:a8:44:d2\n-----BEGIN CERTIFICATE-----\nMIIDqzCCApOgAwIBAgIRAMcoRwmzuGxFjB36JPU2TukwDQYJKoZIhvcNAQEFBQAw\nPDEbMBkGA1UEAxMSQ29tU2lnbiBTZWN1cmVkIENBMRAwDgYDVQQKEwdDb21TaWdu\nMQswCQYDVQQGEwJJTDAeFw0wNDAzMjQxMTM3MjBaFw0yOTAzMTYxNTA0NTZaMDwx\nGzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBDQTEQMA4GA1UEChMHQ29tU2lnbjEL\nMAkGA1UEBhMCSUwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGtWhf\nHZQVw6QIVS3joFd67+l0Kru5fFdJGhFeTymHDEjWaueP1H5XJLkGieQcPOqs49oh\ngHMhCu95mGwfCP+hUH3ymBvJVG8+pSjsIQQPRbsHPaHA+iqYHU4Gk/v1iDurX8sW\nv+bznkqH7Rnqwp9D5PGBpX8QTz7RSmKtUxvLg/8HZaWSLWapW7ha9B20IZFKF3ue\nMv5WJDmyVIRD9YTC2LxBkMyd1mja6YJQqTtoz7VdApRgFrFD2UNd3V2Hbuq7s8lr\n9gOUCXDeFhF6K+h2j0kQmHe5Y1yLM5d19guMsqtb3nQgJT/j8xH5h2iGNXHDHYwt\n6+UarA9z1YJZQIDTAgMBAAGjgacwgaQwDAYDVR0TBAUwAwEB/zBEBgNVHR8EPTA7\nMDmgN6A1hjNodHRwOi8vZmVkaXIuY29tc2lnbi5jby5pbC9jcmwvQ29tU2lnblNl\nY3VyZWRDQS5jcmwwDgYDVR0PAQH/BAQDAgGGMB8GA1UdIwQYMBaAFMFL7XC29z58\nADsAj8c+DkWfHl3sMB0GA1UdDgQWBBTBS+1wtvc+fAA7AI/HPg5Fnx5d7DANBgkq\nhkiG9w0BAQUFAAOCAQEAFs/ukhNQq3sUnjO2QiBq1BW9Cav8cujvR3qQrFHBZE7p\niL1DRYHjZiM/EoZNGeQFsOY3wo3aBijJD4mkU6l1P7CW+6tMM1X5eCZGbxs2mPtC\ndsGCuY7e+0X5YxtiOzkGynd6qDwJz2w2PQ8KRUtpFhpFfTMDZflScZAmlaxMDPWL\nkz/MdXSFmLr/YnpNH4n+rr2UAJm/EaXc4HnFFgt9AmEd6oX5AhVP51qJThRv4zdL\nhfXBPGHg/QVBspJ/wx2g0K5SZGBrGMYmnNj1ZOQ2GmKfig8+/21OGVZOIJFsnzQz\nOjRXUDpvgV4GxvU+fE6OK85lBi5d0ipTdF7Tbieejw==\n-----END CERTIFICATE-----\n\n# Issuer: CN=Cybertrust Global Root O=Cybertrust, Inc\n# Subject: CN=Cybertrust Global Root O=Cybertrust, Inc\n# Label: \"Cybertrust Global Root\"\n# Serial: 4835703278459682877484360\n# MD5 Fingerprint: 72:e4:4a:87:e3:69:40:80:77:ea:bc:e3:f4:ff:f0:e1\n# SHA1 Fingerprint: 5f:43:e5:b1:bf:f8:78:8c:ac:1c:c7:ca:4a:9a:c6:22:2b:cc:34:c6\n# SHA256 Fingerprint: 96:0a:df:00:63:e9:63:56:75:0c:29:65:dd:0a:08:67:da:0b:9c:bd:6e:77:71:4a:ea:fb:23:49:ab:39:3d:a3\n-----BEGIN CERTIFICATE-----\nMIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYG\nA1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2Jh\nbCBSb290MB4XDTA2MTIxNTA4MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UE\nChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBS\nb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+Mi8vRRQZhP/8NN5\n7CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW0ozS\nJ8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2y\nHLtgwEZLAfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iP\nt3sMpTjr3kfb1V05/Iin89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNz\nFtApD0mpSPCzqrdsxacwOUBdrsTiXSZT8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAY\nXSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/\nMB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2MDSgMqAw\nhi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3Js\nMB8GA1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUA\nA4IBAQBW7wojoFROlZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMj\nWqd8BfP9IjsO0QbE2zZMcwSO5bAi5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUx\nXOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2hO0j9n0Hq0V+09+zv+mKts2o\nomcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+TX3EJIrduPuoc\nA06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW\nWL1WMRJOEcgh4LMRkWXbtKaIOM5V\n-----END CERTIFICATE-----\n\n# Issuer: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority\n# Subject: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority\n# Label: \"ePKI Root Certification Authority\"\n# Serial: 28956088682735189655030529057352760477\n# MD5 Fingerprint: 1b:2e:00:ca:26:06:90:3d:ad:fe:6f:15:68:d3:6b:b3\n# SHA1 Fingerprint: 67:65:0d:f1:7e:8e:7e:5b:82:40:a4:f4:56:4b:cf:e2:3d:69:c6:f0\n# SHA256 Fingerprint: c0:a6:f4:dc:63:a2:4b:fd:cf:54:ef:2a:6a:08:2a:0a:72:de:35:80:3e:2f:f5:ff:52:7a:e5:d8:72:06:df:d5\n-----BEGIN CERTIFICATE-----\nMIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe\nMQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0\nZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe\nFw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw\nIQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL\nSSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF\nAAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH\nSyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh\nijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X\nDZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1\nTBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ\nfzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA\nsgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU\nWH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS\nnT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH\ndmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip\nNiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC\nAwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF\nMAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH\nClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB\nuvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl\nPwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP\nJXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/\ngpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2\nj6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6\n5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB\no2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS\n/jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z\nGp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE\nW9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D\nhNQ+IIX3Sj0rnP0qCglN6oH4EZw=\n-----END CERTIFICATE-----\n\n# Issuer: CN=TÜBİTAK UEKAE Kök Sertifika Hizmet Sağlayıcısı - Sürüm 3 O=Türkiye Bilimsel ve Teknolojik Araştırma Kurumu - TÜBİTAK OU=Ulusal Elektronik ve Kriptoloji Araştırma Enstitüsü - UEKAE/Kamu Sertifikasyon Merkezi\n# Subject: CN=TÜBİTAK UEKAE Kök Sertifika Hizmet Sağlayıcısı - Sürüm 3 O=Türkiye Bilimsel ve Teknolojik Araştırma Kurumu - TÜBİTAK OU=Ulusal Elektronik ve Kriptoloji Araştırma Enstitüsü - UEKAE/Kamu Sertifikasyon Merkezi\n# Label: \"T\\xc3\\x9c\\x42\\xC4\\xB0TAK UEKAE K\\xC3\\xB6k Sertifika Hizmet Sa\\xC4\\x9Flay\\xc4\\xb1\\x63\\xc4\\xb1s\\xc4\\xb1 - S\\xC3\\xBCr\\xC3\\xBCm 3\"\n# Serial: 17\n# MD5 Fingerprint: ed:41:f5:8c:50:c5:2b:9c:73:e6:ee:6c:eb:c2:a8:26\n# SHA1 Fingerprint: 1b:4b:39:61:26:27:6b:64:91:a2:68:6d:d7:02:43:21:2d:1f:1d:96\n# SHA256 Fingerprint: e4:c7:34:30:d7:a5:b5:09:25:df:43:37:0a:0d:21:6e:9a:79:b9:d6:db:83:73:a0:c6:9e:b1:cc:31:c7:c5:2a\n-----BEGIN CERTIFICATE-----\nMIIFFzCCA/+gAwIBAgIBETANBgkqhkiG9w0BAQUFADCCASsxCzAJBgNVBAYTAlRS\nMRgwFgYDVQQHDA9HZWJ6ZSAtIEtvY2FlbGkxRzBFBgNVBAoMPlTDvHJraXllIEJp\nbGltc2VsIHZlIFRla25vbG9qaWsgQXJhxZ90xLFybWEgS3VydW11IC0gVMOcQsSw\nVEFLMUgwRgYDVQQLDD9VbHVzYWwgRWxla3Ryb25payB2ZSBLcmlwdG9sb2ppIEFy\nYcWfdMSxcm1hIEVuc3RpdMO8c8O8IC0gVUVLQUUxIzAhBgNVBAsMGkthbXUgU2Vy\ndGlmaWthc3lvbiBNZXJrZXppMUowSAYDVQQDDEFUw5xCxLBUQUsgVUVLQUUgS8O2\nayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSAtIFPDvHLDvG0gMzAe\nFw0wNzA4MjQxMTM3MDdaFw0xNzA4MjExMTM3MDdaMIIBKzELMAkGA1UEBhMCVFIx\nGDAWBgNVBAcMD0dlYnplIC0gS29jYWVsaTFHMEUGA1UECgw+VMO8cmtpeWUgQmls\naW1zZWwgdmUgVGVrbm9sb2ppayBBcmHFn3TEsXJtYSBLdXJ1bXUgLSBUw5xCxLBU\nQUsxSDBGBgNVBAsMP1VsdXNhbCBFbGVrdHJvbmlrIHZlIEtyaXB0b2xvamkgQXJh\nxZ90xLFybWEgRW5zdGl0w7xzw7wgLSBVRUtBRTEjMCEGA1UECwwaS2FtdSBTZXJ0\naWZpa2FzeW9uIE1lcmtlemkxSjBIBgNVBAMMQVTDnELEsFRBSyBVRUtBRSBLw7Zr\nIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIC0gU8O8csO8bSAzMIIB\nIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAim1L/xCIOsP2fpTo6iBkcK4h\ngb46ezzb8R1Sf1n68yJMlaCQvEhOEav7t7WNeoMojCZG2E6VQIdhn8WebYGHV2yK\nO7Rm6sxA/OOqbLLLAdsyv9Lrhc+hDVXDWzhXcLh1xnnRFDDtG1hba+818qEhTsXO\nfJlfbLm4IpNQp81McGq+agV/E5wrHur+R84EpW+sky58K5+eeROR6Oqeyjh1jmKw\nlZMq5d/pXpduIF9fhHpEORlAHLpVK/swsoHvhOPc7Jg4OQOFCKlUAwUp8MmPi+oL\nhmUZEdPpCSPeaJMDyTYcIW7OjGbxmTDY17PDHfiBLqi9ggtm/oLL4eAagsNAgQID\nAQABo0IwQDAdBgNVHQ4EFgQUvYiHyY/2pAoLquvF/pEjnatKijIwDgYDVR0PAQH/\nBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAB18+kmP\nNOm3JpIWmgV050vQbTlswyb2zrgxvMTfvCr4N5EY3ATIZJkrGG2AA1nJrvhY0D7t\nwyOfaTyGOBye79oneNGEN3GKPEs5z35FBtYt2IpNeBLWrcLTy9LQQfMmNkqblWwM\n7uXRQydmwYj3erMgbOqwaSvHIOgMA8RBBZniP+Rr+KCGgceExh/VS4ESshYhLBOh\ngLJeDEoTniDYYkCrkOpkSi+sDQESeUWoL4cZaMjihccwsnX5OD+ywJO0a+IDRM5n\noN+J1q2MdqMTw5RhK2vZbMEHCiIHhWyFJEapvj+LeISCfiQMnf2BN+MlqO02TpUs\nyZyQ2uypQjyttgI=\n-----END CERTIFICATE-----\n\n# Issuer: CN=Buypass Class 2 CA 1 O=Buypass AS-983163327\n# Subject: CN=Buypass Class 2 CA 1 O=Buypass AS-983163327\n# Label: \"Buypass Class 2 CA 1\"\n# Serial: 1\n# MD5 Fingerprint: b8:08:9a:f0:03:cc:1b:0d:c8:6c:0b:76:a1:75:64:23\n# SHA1 Fingerprint: a0:a1:ab:90:c9:fc:84:7b:3b:12:61:e8:97:7d:5f:d3:22:61:d3:cc\n# SHA256 Fingerprint: 0f:4e:9c:dd:26:4b:02:55:50:d1:70:80:63:40:21:4f:e9:44:34:c9:b0:2f:69:7e:c7:10:fc:5f:ea:fb:5e:38\n-----BEGIN CERTIFICATE-----\nMIIDUzCCAjugAwIBAgIBATANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEd\nMBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3Mg\nQ2xhc3MgMiBDQSAxMB4XDTA2MTAxMzEwMjUwOVoXDTE2MTAxMzEwMjUwOVowSzEL\nMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MR0wGwYD\nVQQDDBRCdXlwYXNzIENsYXNzIDIgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEP\nADCCAQoCggEBAIs8B0XY9t/mx8q6jUPFR42wWsE425KEHK8T1A9vNkYgxC7McXA0\nojTTNy7Y3Tp3L8DrKehc0rWpkTSHIln+zNvnma+WwajHQN2lFYxuyHyXA8vmIPLX\nl18xoS830r7uvqmtqEyeIWZDO6i88wmjONVZJMHCR3axiFyCO7srpgTXjAePzdVB\nHfCuuCkslFJgNJQ72uA40Z0zPhX0kzLFANq1KWYOOngPIVJfAuWSeyXTkh4vFZ2B\n5J2O6O+JzhRMVB0cgRJNcKi+EAUXfh/RuFdV7c27UsKwHnjCTTZoy1YmwVLBvXb3\nWNVyfh9EdrsAiR0WnVE1703CVu9r4Iw7DekCAwEAAaNCMEAwDwYDVR0TAQH/BAUw\nAwEB/zAdBgNVHQ4EFgQUP42aWYv8e3uco684sDntkHGA1sgwDgYDVR0PAQH/BAQD\nAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQAVGn4TirnoB6NLJzKyQJHyIdFkhb5jatLP\ngcIV1Xp+DCmsNx4cfHZSldq1fyOhKXdlyTKdqC5Wq2B2zha0jX94wNWZUYN/Xtm+\nDKhQ7SLHrQVMdvvt7h5HZPb3J31cKA9FxVxiXqaakZG3Uxcu3K1gnZZkOb1naLKu\nBctN518fV4bVIJwo+28TOPX2EZL2fZleHwzoq0QkKXJAPTZSr4xYkHPB7GEseaHs\nh7U/2k3ZIQAw3pDaDtMaSKk+hQsUi4y8QZ5q9w5wwDX3OaJdZtB7WZ+oRxKaJyOk\nLY4ng5IgodcVf/EuGO70SH8vf/GhGLWhC5SgYiAynB321O+/TIho\n-----END CERTIFICATE-----\n\n# Issuer: CN=Buypass Class 3 CA 1 O=Buypass AS-983163327\n# Subject: CN=Buypass Class 3 CA 1 O=Buypass AS-983163327\n# Label: \"Buypass Class 3 CA 1\"\n# Serial: 2\n# MD5 Fingerprint: df:3c:73:59:81:e7:39:50:81:04:4c:34:a2:cb:b3:7b\n# SHA1 Fingerprint: 61:57:3a:11:df:0e:d8:7e:d5:92:65:22:ea:d0:56:d7:44:b3:23:71\n# SHA256 Fingerprint: b7:b1:2b:17:1f:82:1d:aa:99:0c:d0:fe:50:87:b1:28:44:8b:a8:e5:18:4f:84:c5:1e:02:b5:c8:fb:96:2b:24\n-----BEGIN CERTIFICATE-----\nMIIDUzCCAjugAwIBAgIBAjANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEd\nMBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3Mg\nQ2xhc3MgMyBDQSAxMB4XDTA1MDUwOTE0MTMwM1oXDTE1MDUwOTE0MTMwM1owSzEL\nMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MR0wGwYD\nVQQDDBRCdXlwYXNzIENsYXNzIDMgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEP\nADCCAQoCggEBAKSO13TZKWTeXx+HgJHqTjnmGcZEC4DVC69TB4sSveZn8AKxifZg\nisRbsELRwCGoy+Gb72RRtqfPFfV0gGgEkKBYouZ0plNTVUhjP5JW3SROjvi6K//z\nNIqeKNc0n6wv1g/xpC+9UrJJhW05NfBEMJNGJPO251P7vGGvqaMU+8IXF4Rs4HyI\n+MkcVyzwPX6UvCWThOiaAJpFBUJXgPROztmuOfbIUxAMZTpHe2DC1vqRycZxbL2R\nhzyRhkmr8w+gbCZ2Xhysm3HljbybIR6c1jh+JIAVMYKWsUnTYjdbiAwKYjT+p0h+\nmbEwi5A3lRyoH6UsjfRVyNvdWQrCrXig9IsCAwEAAaNCMEAwDwYDVR0TAQH/BAUw\nAwEB/zAdBgNVHQ4EFgQUOBTmyPCppAP0Tj4io1vy1uCtQHQwDgYDVR0PAQH/BAQD\nAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQABZ6OMySU9E2NdFm/soT4JXJEVKirZgCFP\nBdy7pYmrEzMqnji3jG8CcmPHc3ceCQa6Oyh7pEfJYWsICCD8igWKH7y6xsL+z27s\nEzNxZy5p+qksP2bAEllNC1QCkoS72xLvg3BweMhT+t/Gxv/ciC8HwEmdMldg0/L2\nmSlf56oBzKwzqBwKu5HEA6BvtjT5htOzdlSY9EqBs1OdTUDs5XcTRa9bqh/YL0yC\ne/4qxFi7T/ye/QNlGioOw6UgFpRreaaiErS7GqQjel/wroQk5PMr+4okoyeYZdow\ndXb8GZHo2+ubPzK/QJcHJrrM85SFSnonk8+QQtS4Wxam58tAA915\n-----END CERTIFICATE-----\n\n# Issuer: CN=EBG Elektronik Sertifika Hizmet Sağlayıcısı O=EBG Bilişim Teknolojileri ve Hizmetleri A.Ş.\n# Subject: CN=EBG Elektronik Sertifika Hizmet Sağlayıcısı O=EBG Bilişim Teknolojileri ve Hizmetleri A.Ş.\n# Label: \"EBG Elektronik Sertifika Hizmet Sa\\xC4\\x9Flay\\xc4\\xb1\\x63\\xc4\\xb1s\\xc4\\xb1\"\n# Serial: 5525761995591021570\n# MD5 Fingerprint: 2c:20:26:9d:cb:1a:4a:00:85:b5:b7:5a:ae:c2:01:37\n# SHA1 Fingerprint: 8c:96:ba:eb:dd:2b:07:07:48:ee:30:32:66:a0:f3:98:6e:7c:ae:58\n# SHA256 Fingerprint: 35:ae:5b:dd:d8:f7:ae:63:5c:ff:ba:56:82:a8:f0:0b:95:f4:84:62:c7:10:8e:e9:a0:e5:29:2b:07:4a:af:b2\n-----BEGIN CERTIFICATE-----\nMIIF5zCCA8+gAwIBAgIITK9zQhyOdAIwDQYJKoZIhvcNAQEFBQAwgYAxODA2BgNV\nBAMML0VCRyBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx\nc8SxMTcwNQYDVQQKDC5FQkcgQmlsacWfaW0gVGVrbm9sb2ppbGVyaSB2ZSBIaXpt\nZXRsZXJpIEEuxZ4uMQswCQYDVQQGEwJUUjAeFw0wNjA4MTcwMDIxMDlaFw0xNjA4\nMTQwMDMxMDlaMIGAMTgwNgYDVQQDDC9FQkcgRWxla3Ryb25payBTZXJ0aWZpa2Eg\nSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTE3MDUGA1UECgwuRUJHIEJpbGnFn2ltIFRl\na25vbG9qaWxlcmkgdmUgSGl6bWV0bGVyaSBBLsWeLjELMAkGA1UEBhMCVFIwggIi\nMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDuoIRh0DpqZhAy2DE4f6en5f2h\n4fuXd7hxlugTlkaDT7byX3JWbhNgpQGR4lvFzVcfd2NR/y8927k/qqk153nQ9dAk\ntiHq6yOU/im/+4mRDGSaBUorzAzu8T2bgmmkTPiab+ci2hC6X5L8GCcKqKpE+i4s\ntPtGmggDg3KriORqcsnlZR9uKg+ds+g75AxuetpX/dfreYteIAbTdgtsApWjluTL\ndlHRKJ2hGvxEok3MenaoDT2/F08iiFD9rrbskFBKW5+VQarKD7JK/oCZTqNGFav4\nc0JqwmZ2sQomFd2TkuzbqV9UIlKRcF0T6kjsbgNs2d1s/OsNA/+mgxKb8amTD8Um\nTDGyY5lhcucqZJnSuOl14nypqZoaqsNW2xCaPINStnuWt6yHd6i58mcLlEOzrz5z\n+kI2sSXFCjEmN1ZnuqMLfdb3ic1nobc6HmZP9qBVFCVMLDMNpkGMvQQxahByCp0O\nLna9XvNRiYuoP1Vzv9s6xiQFlpJIqkuNKgPlV5EQ9GooFW5Hd4RcUXSfGenmHmMW\nOeMRFeNYGkS9y8RsZteEBt8w9DeiQyJ50hBs37vmExH8nYQKE3vwO9D8owrXieqW\nfo1IhR5kX9tUoqzVegJ5a9KK8GfaZXINFHDk6Y54jzJ0fFfy1tb0Nokb+Clsi7n2\nl9GkLqq+CxnCRelwXQIDAJ3Zo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB\n/wQEAwIBBjAdBgNVHQ4EFgQU587GT/wWZ5b6SqMHwQSny2re2kcwHwYDVR0jBBgw\nFoAU587GT/wWZ5b6SqMHwQSny2re2kcwDQYJKoZIhvcNAQEFBQADggIBAJuYml2+\n8ygjdsZs93/mQJ7ANtyVDR2tFcU22NU57/IeIl6zgrRdu0waypIN30ckHrMk2pGI\n6YNw3ZPX6bqz3xZaPt7gyPvT/Wwp+BVGoGgmzJNSroIBk5DKd8pNSe/iWtkqvTDO\nTLKBtjDOWU/aWR1qeqRFsIImgYZ29fUQALjuswnoT4cCB64kXPBfrAowzIpAoHME\nwfuJJPaaHFy3PApnNgUIMbOv2AFoKuB4j3TeuFGkjGwgPaL7s9QJ/XvCgKqTbCmY\nIai7FvOpEl90tYeY8pUm3zTvilORiF0alKM/fCL414i6poyWqD1SNGKfAB5UVUJn\nxk1Gj7sURT0KlhaOEKGXmdXTMIXM3rRyt7yKPBgpaP3ccQfuJDlq+u2lrDgv+R4Q\nDgZxGhBM/nV+/x5XOULK1+EVoVZVWRvRo68R2E7DpSvvkL/A7IITW43WciyTTo9q\nKd+FPNMN4KIYEsxVL0e3p5sC/kH2iExt2qkBR4NkJ2IQgtYSe14DHzSpyZH+r11t\nhie3I6p1GMog57AP14kOpmciY/SDQSsGS7tY1dHXt7kQY9iJSrSq3RZj9W6+YKH4\n7ejWkE8axsWgKdOnIaj1Wjz3x0miIZpKlVIglnKaZsv30oZDfCK+lvm9AahH3eU7\nQPl1K5srRmSGjR70j/sHd9DqSaIcjVIUpgqT\n-----END CERTIFICATE-----\n\n# Issuer: O=certSIGN OU=certSIGN ROOT CA\n# Subject: O=certSIGN OU=certSIGN ROOT CA\n# Label: \"certSIGN ROOT CA\"\n# Serial: 35210227249154\n# MD5 Fingerprint: 18:98:c0:d6:e9:3a:fc:f9:b0:f5:0c:f7:4b:01:44:17\n# SHA1 Fingerprint: fa:b7:ee:36:97:26:62:fb:2d:b0:2a:f6:bf:03:fd:e8:7c:4b:2f:9b\n# SHA256 Fingerprint: ea:a9:62:c4:fa:4a:6b:af:eb:e4:15:19:6d:35:1c:cd:88:8d:4f:53:f3:fa:8a:e6:d7:c4:66:a9:4e:60:42:bb\n-----BEGIN CERTIFICATE-----\nMIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT\nAlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD\nQTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP\nMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC\nASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do\n0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ\nUySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d\nRdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ\nOA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv\nJoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C\nAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O\nBBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ\nLjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY\nMnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ\n44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I\nJd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw\ni/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN\n9u6wWk5JRFRYX0KD\n-----END CERTIFICATE-----\n\n# Issuer: CN=CNNIC ROOT O=CNNIC\n# Subject: CN=CNNIC ROOT O=CNNIC\n# Label: \"CNNIC ROOT\"\n# Serial: 1228079105\n# MD5 Fingerprint: 21:bc:82:ab:49:c4:13:3b:4b:b2:2b:5c:6b:90:9c:19\n# SHA1 Fingerprint: 8b:af:4c:9b:1d:f0:2a:92:f7:da:12:8e:b9:1b:ac:f4:98:60:4b:6f\n# SHA256 Fingerprint: e2:83:93:77:3d:a8:45:a6:79:f2:08:0c:c7:fb:44:a3:b7:a1:c3:79:2c:b7:eb:77:29:fd:cb:6a:8d:99:ae:a7\n-----BEGIN CERTIFICATE-----\nMIIDVTCCAj2gAwIBAgIESTMAATANBgkqhkiG9w0BAQUFADAyMQswCQYDVQQGEwJD\nTjEOMAwGA1UEChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwHhcNMDcwNDE2\nMDcwOTE0WhcNMjcwNDE2MDcwOTE0WjAyMQswCQYDVQQGEwJDTjEOMAwGA1UEChMF\nQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwggEiMA0GCSqGSIb3DQEBAQUAA4IB\nDwAwggEKAoIBAQDTNfc/c3et6FtzF8LRb+1VvG7q6KR5smzDo+/hn7E7SIX1mlwh\nIhAsxYLO2uOabjfhhyzcuQxauohV3/2q2x8x6gHx3zkBwRP9SFIhxFXf2tizVHa6\ndLG3fdfA6PZZxU3Iva0fFNrfWEQlMhkqx35+jq44sDB7R3IJMfAw28Mbdim7aXZO\nV/kbZKKTVrdvmW7bCgScEeOAH8tjlBAKqeFkgjH5jCftppkA9nCTGPihNIaj3XrC\nGHn2emU1z5DrvTOTn1OrczvmmzQgLx3vqR1jGqCA2wMv+SYahtKNu6m+UjqHZ0gN\nv7Sg2Ca+I19zN38m5pIEo3/PIKe38zrKy5nLAgMBAAGjczBxMBEGCWCGSAGG+EIB\nAQQEAwIABzAfBgNVHSMEGDAWgBRl8jGtKvf33VKWCscCwQ7vptU7ETAPBgNVHRMB\nAf8EBTADAQH/MAsGA1UdDwQEAwIB/jAdBgNVHQ4EFgQUZfIxrSr3991SlgrHAsEO\n76bVOxEwDQYJKoZIhvcNAQEFBQADggEBAEs17szkrr/Dbq2flTtLP1se31cpolnK\nOOK5Gv+e5m4y3R6u6jW39ZORTtpC4cMXYFDy0VwmuYK36m3knITnA3kXr5g9lNvH\nugDnuL8BV8F3RTIMO/G0HAiw/VGgod2aHRM2mm23xzy54cXZF/qD1T0VoDy7Hgvi\nyJA/qIYM/PmLXoXLT1tLYhFHxUV8BS9BsZ4QaRuZluBVeftOhpm4lNqGOGqTo+fL\nbuXf6iFViZx9fX+Y9QCJ7uOEwFyWtcVG6kbghVW2G8kS1sHNzYDzAgE8yGnLRUhj\n2JTQ7IUOO04RZfSCjKY9ri4ilAnIXOo8gV0WKgOXFlUJ24pBgp5mmxE=\n-----END CERTIFICATE-----\n\n# Issuer: O=Japanese Government OU=ApplicationCA\n# Subject: O=Japanese Government OU=ApplicationCA\n# Label: \"ApplicationCA - Japanese Government\"\n# Serial: 49\n# MD5 Fingerprint: 7e:23:4e:5b:a7:a5:b4:25:e9:00:07:74:11:62:ae:d6\n# SHA1 Fingerprint: 7f:8a:b0:cf:d0:51:87:6a:66:f3:36:0f:47:c8:8d:8c:d3:35:fc:74\n# SHA256 Fingerprint: 2d:47:43:7d:e1:79:51:21:5a:12:f3:c5:8e:51:c7:29:a5:80:26:ef:1f:cc:0a:5f:b3:d9:dc:01:2f:60:0d:19\n-----BEGIN CERTIFICATE-----\nMIIDoDCCAoigAwIBAgIBMTANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJKUDEc\nMBoGA1UEChMTSmFwYW5lc2UgR292ZXJubWVudDEWMBQGA1UECxMNQXBwbGljYXRp\nb25DQTAeFw0wNzEyMTIxNTAwMDBaFw0xNzEyMTIxNTAwMDBaMEMxCzAJBgNVBAYT\nAkpQMRwwGgYDVQQKExNKYXBhbmVzZSBHb3Zlcm5tZW50MRYwFAYDVQQLEw1BcHBs\naWNhdGlvbkNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp23gdE6H\nj6UG3mii24aZS2QNcfAKBZuOquHMLtJqO8F6tJdhjYq+xpqcBrSGUeQ3DnR4fl+K\nf5Sk10cI/VBaVuRorChzoHvpfxiSQE8tnfWuREhzNgaeZCw7NCPbXCbkcXmP1G55\nIrmTwcrNwVbtiGrXoDkhBFcsovW8R0FPXjQilbUfKW1eSvNNcr5BViCH/OlQR9cw\nFO5cjFW6WY2H/CPek9AEjP3vbb3QesmlOmpyM8ZKDQUXKi17safY1vC+9D/qDiht\nQWEjdnjDuGWk81quzMKq2edY3rZ+nYVunyoKb58DKTCXKB28t89UKU5RMfkntigm\n/qJj5kEW8DOYRwIDAQABo4GeMIGbMB0GA1UdDgQWBBRUWssmP3HMlEYNllPqa0jQ\nk/5CdTAOBgNVHQ8BAf8EBAMCAQYwWQYDVR0RBFIwUKROMEwxCzAJBgNVBAYTAkpQ\nMRgwFgYDVQQKDA/ml6XmnKzlm73mlL/lupwxIzAhBgNVBAsMGuOCouODl+ODquOC\nseODvOOCt+ODp+ODs0NBMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD\nggEBADlqRHZ3ODrso2dGD/mLBqj7apAxzn7s2tGJfHrrLgy9mTLnsCTWw//1sogJ\nhyzjVOGjprIIC8CFqMjSnHH2HZ9g/DgzE+Ge3Atf2hZQKXsvcJEPmbo0NI2VdMV+\neKlmXb3KIXdCEKxmJj3ekav9FfBv7WxfEPjzFvYDio+nEhEMy/0/ecGc/WLuo89U\nDNErXxc+4z6/wCs+CZv+iKZ+tJIX/COUgb1up8WMwusRRdv4QcmWdupwX3kSa+Sj\nB1oF7ydJzyGfikwJcGapJsErEU4z0g781mzSDjJkaP+tBXhfAx2o45CsJOAPQKdL\nrosot4LKGAfmt1t06SAZf7IbiVQ=\n-----END CERTIFICATE-----\n\n# Issuer: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only\n# Subject: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only\n# Label: \"GeoTrust Primary Certification Authority - G3\"\n# Serial: 28809105769928564313984085209975885599\n# MD5 Fingerprint: b5:e8:34:36:c9:10:44:58:48:70:6d:2e:83:d4:b8:05\n# SHA1 Fingerprint: 03:9e:ed:b8:0b:e7:a0:3c:69:53:89:3b:20:d2:d9:32:3a:4c:2a:fd\n# SHA256 Fingerprint: b4:78:b8:12:25:0d:f8:78:63:5c:2a:a7:ec:7d:15:5e:aa:62:5e:e8:29:16:e2:cd:29:43:61:88:6c:d1:fb:d4\n-----BEGIN CERTIFICATE-----\nMIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCB\nmDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT\nMChjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s\neTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv\ncml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIzNTk1OVowgZgxCzAJ\nBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg\nMjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0\nBgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg\nLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz\n+uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5jK/BGvESyiaHAKAxJcCGVn2TAppMSAmUm\nhsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdEc5IiaacDiGydY8hS2pgn\n5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3CIShwiP/W\nJmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exAL\nDmKudlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZC\nhuOl1UcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw\nHQYDVR0OBBYEFMR5yo6hTgMdHNxr2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IB\nAQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9cr5HqQ6XErhK8WTTOd8lNNTB\nzU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbEAp7aDHdlDkQN\nkv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD\nAWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUH\nSJsMC8tJP33st/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2G\nspki4cErx5z481+oghLrGREt\n-----END CERTIFICATE-----\n\n# Issuer: CN=thawte Primary Root CA - G2 O=thawte, Inc. OU=(c) 2007 thawte, Inc. - For authorized use only\n# Subject: CN=thawte Primary Root CA - G2 O=thawte, Inc. OU=(c) 2007 thawte, Inc. - For authorized use only\n# Label: \"thawte Primary Root CA - G2\"\n# Serial: 71758320672825410020661621085256472406\n# MD5 Fingerprint: 74:9d:ea:60:24:c4:fd:22:53:3e:cc:3a:72:d9:29:4f\n# SHA1 Fingerprint: aa:db:bc:22:23:8f:c4:01:a1:27:bb:38:dd:f4:1d:db:08:9e:f0:12\n# SHA256 Fingerprint: a4:31:0d:50:af:18:a6:44:71:90:37:2a:86:af:af:8b:95:1f:fb:43:1d:83:7f:1e:56:88:b4:59:71:ed:15:57\n-----BEGIN CERTIFICATE-----\nMIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDEL\nMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMp\nIDIwMDcgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAi\nBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMjAeFw0wNzExMDUwMDAw\nMDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh\nd3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBGb3Ig\nYXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9v\ndCBDQSAtIEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/\nBebfowJPDQfGAFG6DAJSLSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6\npapu+7qzcMBniKI11KOasf2twu8x+qi58/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8E\nBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUmtgAMADna3+FGO6Lts6K\nDPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUNG4k8VIZ3\nKMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41ox\nXZ3Krr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg==\n-----END CERTIFICATE-----\n\n# Issuer: CN=thawte Primary Root CA - G3 O=thawte, Inc. OU=Certification Services Division/(c) 2008 thawte, Inc. - For authorized use only\n# Subject: CN=thawte Primary Root CA - G3 O=thawte, Inc. OU=Certification Services Division/(c) 2008 thawte, Inc. - For authorized use only\n# Label: \"thawte Primary Root CA - G3\"\n# Serial: 127614157056681299805556476275995414779\n# MD5 Fingerprint: fb:1b:5d:43:8a:94:cd:44:c6:76:f2:43:4b:47:e7:31\n# SHA1 Fingerprint: f1:8b:53:8d:1b:e9:03:b6:a6:f0:56:43:5b:17:15:89:ca:f3:6b:f2\n# SHA256 Fingerprint: 4b:03:f4:58:07:ad:70:f2:1b:fc:2c:ae:71:c9:fd:e4:60:4c:06:4c:f5:ff:b6:86:ba:e5:db:aa:d7:fd:d3:4c\n-----BEGIN CERTIFICATE-----\nMIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCB\nrjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf\nQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw\nMDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNV\nBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0wODA0MDIwMDAwMDBa\nFw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3Rl\nLCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9u\nMTgwNgYDVQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXpl\nZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEcz\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsr8nLPvb2FvdeHsbnndm\ngcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2AtP0LMqmsywCPLLEHd5N/8\nYZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC+BsUa0Lf\nb1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS9\n9irY7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2S\nzhkGcuYMXDhpxwTWvGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUk\nOQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV\nHQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJKoZIhvcNAQELBQADggEBABpA\n2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweKA3rD6z8KLFIW\noCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu\nt8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7c\nKUGRIjxpp7sC8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fM\nm7v/OeZWYdMKp8RcTGB7BXcmer/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZu\nMdRAGmI0Nj81Aa6sY6A=\n-----END CERTIFICATE-----\n\n# Issuer: CN=GeoTrust Primary Certification Authority - G2 O=GeoTrust Inc. OU=(c) 2007 GeoTrust Inc. - For authorized use only\n# Subject: CN=GeoTrust Primary Certification Authority - G2 O=GeoTrust Inc. OU=(c) 2007 GeoTrust Inc. - For authorized use only\n# Label: \"GeoTrust Primary Certification Authority - G2\"\n# Serial: 80682863203381065782177908751794619243\n# MD5 Fingerprint: 01:5e:d8:6b:bd:6f:3d:8e:a1:31:f8:12:e0:98:73:6a\n# SHA1 Fingerprint: 8d:17:84:d5:37:f3:03:7d:ec:70:fe:57:8b:51:9a:99:e6:10:d7:b0\n# SHA256 Fingerprint: 5e:db:7a:c4:3b:82:a0:6a:87:61:e8:d7:be:49:79:eb:f2:61:1f:7d:d7:9b:f9:1c:1c:6b:56:6a:21:9e:d7:66\n-----BEGIN CERTIFICATE-----\nMIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL\nMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj\nKSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2\nMDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0\neSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV\nBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw\nNyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV\nBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH\nMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL\nSo17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal\ntJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO\nBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG\nCCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT\nqQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz\nrD6ogRLQy7rQkgu2npaqBA+K\n-----END CERTIFICATE-----\n\n# Issuer: CN=VeriSign Universal Root Certification Authority O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2008 VeriSign, Inc. - For authorized use only\n# Subject: CN=VeriSign Universal Root Certification Authority O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2008 VeriSign, Inc. - For authorized use only\n# Label: \"VeriSign Universal Root Certification Authority\"\n# Serial: 85209574734084581917763752644031726877\n# MD5 Fingerprint: 8e:ad:b5:01:aa:4d:81:e4:8c:1d:d1:e1:14:00:95:19\n# SHA1 Fingerprint: 36:79:ca:35:66:87:72:30:4d:30:a5:fb:87:3b:0f:a7:7b:b7:0d:54\n# SHA256 Fingerprint: 23:99:56:11:27:a5:71:25:de:8c:ef:ea:61:0d:df:2f:a0:78:b5:c8:06:7f:4e:82:82:90:bf:b8:60:e8:4b:3c\n-----BEGIN CERTIFICATE-----\nMIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCB\nvTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL\nExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJp\nU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MTgwNgYDVQQDEy9W\nZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe\nFw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJVUzEX\nMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0\nIE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9y\nIGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNh\nbCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF\nAAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj1mCOkdeQmIN65lgZOIzF\n9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGPMiJhgsWH\nH26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+H\nLL729fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN\n/BMReYTtXlT2NJ8IAfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPT\nrJ9VAMf2CGqUuV/c4DPxhGD5WycRtPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1Ud\nEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0GCCsGAQUFBwEMBGEwX6FdoFsw\nWTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2Oa8PPgGrUSBgs\nexkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud\nDgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4\nsAPmLGd75JR3Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+\nseQxIcaBlVZaDrHC1LGmWazxY8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz\n4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTxP/jgdFcrGJ2BtMQo2pSXpXDrrB2+\nBxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+PwGZsY6rp2aQW9IHR\nlRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4mJO3\n7M2CYfE45k+XmCpajQ==\n-----END CERTIFICATE-----\n\n# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G4 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2007 VeriSign, Inc. - For authorized use only\n# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G4 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2007 VeriSign, Inc. - For authorized use only\n# Label: \"VeriSign Class 3 Public Primary Certification Authority - G4\"\n# Serial: 63143484348153506665311985501458640051\n# MD5 Fingerprint: 3a:52:e1:e7:fd:6f:3a:e3:6f:f3:6f:99:1b:f9:22:41\n# SHA1 Fingerprint: 22:d5:d8:df:8f:02:31:d1:8d:f7:9d:b7:cf:8a:2d:64:c9:3f:6c:3a\n# SHA256 Fingerprint: 69:dd:d7:ea:90:bb:57:c9:3e:13:5d:c8:5e:a6:fc:d5:48:0b:60:32:39:bd:c4:54:fc:75:8b:2a:26:cf:7f:79\n-----BEGIN CERTIFICATE-----\nMIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjEL\nMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW\nZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2ln\nbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp\nU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y\naXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjELMAkG\nA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJp\nU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwg\nSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2ln\nbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5\nIC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8Utpkmw4tXNherJI9/gHm\nGUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGzrl0Bp3ve\nfLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUw\nAwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJ\naW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYj\naHR0cDovL2xvZ28udmVyaXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMW\nkf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMDA2gAMGUCMGYhDBgmYFo4e1ZC\n4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIxAJw9SDkjOVga\nFRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA==\n-----END CERTIFICATE-----\n\n# Issuer: CN=NetLock Arany (Class Gold) Főtanúsítvány O=NetLock Kft. OU=Tanúsítványkiadók (Certification Services)\n# Subject: CN=NetLock Arany (Class Gold) Főtanúsítvány O=NetLock Kft. OU=Tanúsítványkiadók (Certification Services)\n# Label: \"NetLock Arany (Class Gold) Főtanúsítvány\"\n# Serial: 80544274841616\n# MD5 Fingerprint: c5:a1:b7:ff:73:dd:d6:d7:34:32:18:df:fc:3c:ad:88\n# SHA1 Fingerprint: 06:08:3f:59:3f:15:a1:04:a0:69:a4:6b:a9:03:d0:06:b7:97:09:91\n# SHA256 Fingerprint: 6c:61:da:c3:a2:de:f0:31:50:6b:e0:36:d2:a6:fe:40:19:94:fb:d1:3d:f9:c8:d4:66:59:92:74:c4:46:ec:98\n-----BEGIN CERTIFICATE-----\nMIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG\nEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3\nMDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl\ncnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR\ndGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB\npzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM\nb2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm\naWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz\nIEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\nMIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT\nlF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz\nAZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5\nVA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG\nILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2\nBJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG\nAQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M\nU9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh\nbvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C\n+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC\nbLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F\nuLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2\nXjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E=\n-----END CERTIFICATE-----\n\n# Issuer: CN=Staat der Nederlanden Root CA - G2 O=Staat der Nederlanden\n# Subject: CN=Staat der Nederlanden Root CA - G2 O=Staat der Nederlanden\n# Label: \"Staat der Nederlanden Root CA - G2\"\n# Serial: 10000012\n# MD5 Fingerprint: 7c:a5:0f:f8:5b:9a:7d:6d:30:ae:54:5a:e3:42:a2:8a\n# SHA1 Fingerprint: 59:af:82:79:91:86:c7:b4:75:07:cb:cf:03:57:46:eb:04:dd:b7:16\n# SHA256 Fingerprint: 66:8c:83:94:7d:a6:3b:72:4b:ec:e1:74:3c:31:a0:e6:ae:d0:db:8e:c5:b3:1b:e3:77:bb:78:4f:91:b6:71:6f\n-----BEGIN CERTIFICATE-----\nMIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO\nTDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh\ndCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oX\nDTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl\nciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv\nb3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ5291\nqj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8Sp\nuOUfiUtnvWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPU\nZ5uW6M7XxgpT0GtJlvOjCwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvE\npMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiile7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp\n5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCROME4HYYEhLoaJXhena/M\nUGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpICT0ugpTN\nGmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy\n5V6548r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv\n6q012iDTiIJh8BIitrzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEK\neN5KzlW/HdXZt1bv8Hb/C3m1r737qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6\nB6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMBAAGjgZcwgZQwDwYDVR0TAQH/\nBAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcCARYxaHR0cDov\nL3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV\nHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqG\nSIb3DQEBCwUAA4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLyS\nCZa59sCrI2AGeYwRTlHSeYAz+51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen\n5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwjf/ST7ZwaUb7dRUG/kSS0H4zpX897\nIZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaNkqbG9AclVMwWVxJK\ngnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfkCpYL\n+63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxL\nvJxxcypFURmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkm\nbEgeqmiSBeGCc1qb3AdbCG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvk\nN1trSt8sV4pAWja63XVECDdCcAz+3F4hoKOKwJCcaNpQ5kUQR3i2TtJlycM33+FC\nY7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoVIPVVYpbtbZNQvOSqeK3Z\nywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm66+KAQ==\n-----END CERTIFICATE-----\n\n# Issuer: CN=CA Disig O=Disig a.s.\n# Subject: CN=CA Disig O=Disig a.s.\n# Label: \"CA Disig\"\n# Serial: 1\n# MD5 Fingerprint: 3f:45:96:39:e2:50:87:f7:bb:fe:98:0c:3c:20:98:e6\n# SHA1 Fingerprint: 2a:c8:d5:8b:57:ce:bf:2f:49:af:f2:fc:76:8f:51:14:62:90:7a:41\n# SHA256 Fingerprint: 92:bf:51:19:ab:ec:ca:d0:b1:33:2d:c4:e1:d0:5f:ba:75:b5:67:90:44:ee:0c:a2:6e:93:1f:74:4f:2f:33:cf\n-----BEGIN CERTIFICATE-----\nMIIEDzCCAvegAwIBAgIBATANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJTSzET\nMBEGA1UEBxMKQnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UE\nAxMIQ0EgRGlzaWcwHhcNMDYwMzIyMDEzOTM0WhcNMTYwMzIyMDEzOTM0WjBKMQsw\nCQYDVQQGEwJTSzETMBEGA1UEBxMKQnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcg\nYS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw\nggEKAoIBAQCS9jHBfYj9mQGp2HvycXXxMcbzdWb6UShGhJd4NLxs/LxFWYgmGErE\nNx+hSkS943EE9UQX4j/8SFhvXJ56CbpRNyIjZkMhsDxkovhqFQ4/61HhVKndBpnX\nmjxUizkDPw/Fzsbrg3ICqB9x8y34dQjbYkzo+s7552oftms1grrijxaSfQUMbEYD\nXcDtab86wYqg6I7ZuUUohwjstMoVvoLdtUSLLa2GDGhibYVW8qwUYzrG0ZmsNHhW\nS8+2rT+MitcE5eN4TPWGqvWP+j1scaMtymfraHtuM6kMgiioTGohQBUgDCZbg8Kp\nFhXAJIJdKxatymP2dACw30PEEGBWZ2NFAgMBAAGjgf8wgfwwDwYDVR0TAQH/BAUw\nAwEB/zAdBgNVHQ4EFgQUjbJJaJ1yCCW5wCf1UJNWSEZx+Y8wDgYDVR0PAQH/BAQD\nAgEGMDYGA1UdEQQvMC2BE2Nhb3BlcmF0b3JAZGlzaWcuc2uGFmh0dHA6Ly93d3cu\nZGlzaWcuc2svY2EwZgYDVR0fBF8wXTAtoCugKYYnaHR0cDovL3d3dy5kaXNpZy5z\nay9jYS9jcmwvY2FfZGlzaWcuY3JsMCygKqAohiZodHRwOi8vY2EuZGlzaWcuc2sv\nY2EvY3JsL2NhX2Rpc2lnLmNybDAaBgNVHSAEEzARMA8GDSuBHpGT5goAAAABAQEw\nDQYJKoZIhvcNAQEFBQADggEBAF00dGFMrzvY/59tWDYcPQuBDRIrRhCA/ec8J9B6\nyKm2fnQwM6M6int0wHl5QpNt/7EpFIKrIYwvF/k/Ji/1WcbvgAa3mkkp7M5+cTxq\nEEHA9tOasnxakZzArFvITV734VP/Q3f8nktnbNfzg9Gg4H8l37iYC5oyOGwwoPP/\nCBUz91BKez6jPiCp3C9WgArtQVCwyfTssuMmRAAOb54GvCKWU3BlxFAKRmukLyeB\nEicTXxChds6KezfqwzlhA5WYOudsiCUI/HloDYd9Yvi0X/vF2Ey9WLw/Q1vUHgFN\nPGO+I++MzVpQuGhU+QqZMxEA4Z7CRneC9VkGjCFMhwnN5ag=\n-----END CERTIFICATE-----\n\n# Issuer: CN=Juur-SK O=AS Sertifitseerimiskeskus\n# Subject: CN=Juur-SK O=AS Sertifitseerimiskeskus\n# Label: \"Juur-SK\"\n# Serial: 999181308\n# MD5 Fingerprint: aa:8e:5d:d9:f8:db:0a:58:b7:8d:26:87:6c:82:35:55\n# SHA1 Fingerprint: 40:9d:4b:d9:17:b5:5c:27:b6:9b:64:cb:98:22:44:0d:cd:09:b8:89\n# SHA256 Fingerprint: ec:c3:e9:c3:40:75:03:be:e0:91:aa:95:2f:41:34:8f:f8:8b:aa:86:3b:22:64:be:fa:c8:07:90:15:74:e9:39\n-----BEGIN CERTIFICATE-----\nMIIE5jCCA86gAwIBAgIEO45L/DANBgkqhkiG9w0BAQUFADBdMRgwFgYJKoZIhvcN\nAQkBFglwa2lAc2suZWUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKExlBUyBTZXJ0aWZp\ndHNlZXJpbWlza2Vza3VzMRAwDgYDVQQDEwdKdXVyLVNLMB4XDTAxMDgzMDE0MjMw\nMVoXDTE2MDgyNjE0MjMwMVowXTEYMBYGCSqGSIb3DQEJARYJcGtpQHNrLmVlMQsw\nCQYDVQQGEwJFRTEiMCAGA1UEChMZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1czEQ\nMA4GA1UEAxMHSnV1ci1TSzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\nAIFxNj4zB9bjMI0TfncyRsvPGbJgMUaXhvSYRqTCZUXP00B841oiqBB4M8yIsdOB\nSvZiF3tfTQou0M+LI+5PAk676w7KvRhj6IAcjeEcjT3g/1tf6mTll+g/mX8MCgkz\nABpTpyHhOEvWgxutr2TC+Rx6jGZITWYfGAriPrsfB2WThbkasLnE+w0R9vXW+RvH\nLCu3GFH+4Hv2qEivbDtPL+/40UceJlfwUR0zlv/vWT3aTdEVNMfqPxZIe5EcgEMP\nPbgFPtGzlc3Yyg/CQ2fbt5PgIoIuvvVoKIO5wTtpeyDaTpxt4brNj3pssAki14sL\n2xzVWiZbDcDq5WDQn/413z8CAwEAAaOCAawwggGoMA8GA1UdEwEB/wQFMAMBAf8w\nggEWBgNVHSAEggENMIIBCTCCAQUGCisGAQQBzh8BAQEwgfYwgdAGCCsGAQUFBwIC\nMIHDHoHAAFMAZQBlACAAcwBlAHIAdABpAGYAaQBrAGEAYQB0ACAAbwBuACAAdgDk\nAGwAagBhAHMAdABhAHQAdQBkACAAQQBTAC0AaQBzACAAUwBlAHIAdABpAGYAaQB0\nAHMAZQBlAHIAaQBtAGkAcwBrAGUAcwBrAHUAcwAgAGEAbABhAG0ALQBTAEsAIABz\nAGUAcgB0AGkAZgBpAGsAYQBhAHQAaQBkAGUAIABrAGkAbgBuAGkAdABhAG0AaQBz\nAGUAawBzMCEGCCsGAQUFBwIBFhVodHRwOi8vd3d3LnNrLmVlL2Nwcy8wKwYDVR0f\nBCQwIjAgoB6gHIYaaHR0cDovL3d3dy5zay5lZS9qdXVyL2NybC8wHQYDVR0OBBYE\nFASqekej5ImvGs8KQKcYP2/v6X2+MB8GA1UdIwQYMBaAFASqekej5ImvGs8KQKcY\nP2/v6X2+MA4GA1UdDwEB/wQEAwIB5jANBgkqhkiG9w0BAQUFAAOCAQEAe8EYlFOi\nCfP+JmeaUOTDBS8rNXiRTHyoERF5TElZrMj3hWVcRrs7EKACr81Ptcw2Kuxd/u+g\nkcm2k298gFTsxwhwDY77guwqYHhpNjbRxZyLabVAyJRld/JXIWY7zoVAtjNjGr95\nHvxcHdMdkxuLDF2FvZkwMhgJkVLpfKG6/2SSmuz+Ne6ML678IIbsSt4beDI3poHS\nna9aEhbKmVv8b20OxaAehsmR0FyYgl9jDIpaq9iVpszLita/ZEuOyoqysOkhMp6q\nqIWYNIE5ITuoOlIyPfZrN4YGWhWY3PARZv40ILcD9EEQfTmEeZZyY7aWAuVrua0Z\nTbvGRNs2yyqcjg==\n-----END CERTIFICATE-----\n\n# Issuer: CN=Hongkong Post Root CA 1 O=Hongkong Post\n# Subject: CN=Hongkong Post Root CA 1 O=Hongkong Post\n# Label: \"Hongkong Post Root CA 1\"\n# Serial: 1000\n# MD5 Fingerprint: a8:0d:6f:39:78:b9:43:6d:77:42:6d:98:5a:cc:23:ca\n# SHA1 Fingerprint: d6:da:a8:20:8d:09:d2:15:4d:24:b5:2f:cb:34:6e:b2:58:b2:8a:58\n# SHA256 Fingerprint: f9:e6:7d:33:6c:51:00:2a:c0:54:c6:32:02:2d:66:dd:a2:e7:e3:ff:f1:0a:d0:61:ed:31:d8:bb:b4:10:cf:b2\n-----BEGIN CERTIFICATE-----\nMIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsx\nFjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3Qg\nUm9vdCBDQSAxMB4XDTAzMDUxNTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkG\nA1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdr\nb25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC\nAQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1ApzQ\njVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEn\nPzlTCeqrauh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjh\nZY4bXSNmO7ilMlHIhqqhqZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9\nnnV0ttgCXjqQesBCNnLsak3c78QA3xMYV18meMjWCnl3v/evt3a5pQuEF10Q6m/h\nq5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNVHRMBAf8ECDAGAQH/AgED\nMA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7ih9legYsC\nmEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI3\n7piol7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clB\noiMBdDhViw+5LmeiIAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJs\nEhTkYY2sEJCehFC78JZvRZ+K88psT/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpO\nfMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilTc4afU9hDDl3WY4JxHYB0yvbi\nAmvZWg==\n-----END CERTIFICATE-----\n\n# Issuer: CN=SecureSign RootCA11 O=Japan Certification Services, Inc.\n# Subject: CN=SecureSign RootCA11 O=Japan Certification Services, Inc.\n# Label: \"SecureSign RootCA11\"\n# Serial: 1\n# MD5 Fingerprint: b7:52:74:e2:92:b4:80:93:f2:75:e4:cc:d7:f2:ea:26\n# SHA1 Fingerprint: 3b:c4:9f:48:f8:f3:73:a0:9c:1e:bd:f8:5b:b1:c3:65:c7:d8:11:b3\n# SHA256 Fingerprint: bf:0f:ee:fb:9e:3a:58:1a:d5:f9:e9:db:75:89:98:57:43:d2:61:08:5c:4d:31:4f:6f:5d:72:59:aa:42:16:12\n-----BEGIN CERTIFICATE-----\nMIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDEr\nMCkGA1UEChMiSmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoG\nA1UEAxMTU2VjdXJlU2lnbiBSb290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0\nMDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSswKQYDVQQKEyJKYXBhbiBDZXJ0aWZp\nY2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1cmVTaWduIFJvb3RD\nQTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvLTJsz\ni1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8\nh9uuywGOwvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOV\nMdrAG/LuYpmGYz+/3ZMqg6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9\nUK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rPO7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni\n8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitAbpSACW22s293bzUIUPsC\nh8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZXt94wDgYD\nVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB\nAKChOBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xm\nKbabfSVSSUOrTC4rbnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQ\nX5Ucv+2rIrVls4W6ng+4reV6G4pQOh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWr\nQbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01y8hSyn+B/tlr0/cR7SXf+Of5\npPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061lgeLKBObjBmN\nQSdJQO7e5iNEOdyhIta6A/I=\n-----END CERTIFICATE-----\n\n# Issuer: CN=ACEDICOM Root O=EDICOM OU=PKI\n# Subject: CN=ACEDICOM Root O=EDICOM OU=PKI\n# Label: \"ACEDICOM Root\"\n# Serial: 7029493972724711941\n# MD5 Fingerprint: 42:81:a0:e2:1c:e3:55:10:de:55:89:42:65:96:22:e6\n# SHA1 Fingerprint: e0:b4:32:2e:b2:f6:a5:68:b6:54:53:84:48:18:4a:50:36:87:43:84\n# SHA256 Fingerprint: 03:95:0f:b4:9a:53:1f:3e:19:91:94:23:98:df:a9:e0:ea:32:d7:ba:1c:dd:9b:c8:5d:b5:7e:d9:40:0b:43:4a\n-----BEGIN CERTIFICATE-----\nMIIFtTCCA52gAwIBAgIIYY3HhjsBggUwDQYJKoZIhvcNAQEFBQAwRDEWMBQGA1UE\nAwwNQUNFRElDT00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00x\nCzAJBgNVBAYTAkVTMB4XDTA4MDQxODE2MjQyMloXDTI4MDQxMzE2MjQyMlowRDEW\nMBQGA1UEAwwNQUNFRElDT00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZF\nRElDT00xCzAJBgNVBAYTAkVTMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC\nAgEA/5KV4WgGdrQsyFhIyv2AVClVYyT/kGWbEHV7w2rbYgIB8hiGtXxaOLHkWLn7\n09gtn70yN78sFW2+tfQh0hOR2QetAQXW8713zl9CgQr5auODAKgrLlUTY4HKRxx7\nXBZXehuDYAQ6PmXDzQHe3qTWDLqO3tkE7hdWIpuPY/1NFgu3e3eM+SW10W2ZEi5P\nGrjm6gSSrj0RuVFCPYewMYWveVqc/udOXpJPQ/yrOq2lEiZmueIM15jO1FillUAK\nt0SdE3QrwqXrIhWYENiLxQSfHY9g5QYbm8+5eaA9oiM/Qj9r+hwDezCNzmzAv+Yb\nX79nuIQZ1RXve8uQNjFiybwCq0Zfm/4aaJQ0PZCOrfbkHQl/Sog4P75n/TSW9R28\nMHTLOO7VbKvU/PQAtwBbhTIWdjPp2KOZnQUAqhbm84F9b32qhm2tFXTTxKJxqvQU\nfecyuB+81fFOvW8XAjnXDpVCOscAPukmYxHqC9FK/xidstd7LzrZlvvoHpKuE1XI\n2Sf23EgbsCTBheN3nZqk8wwRHQ3ItBTutYJXCb8gWH8vIiPYcMt5bMlL8qkqyPyH\nK9caUPgn6C9D4zq92Fdx/c6mUlv53U3t5fZvie27k5x2IXXwkkwp9y+cAS7+UEae\nZAwUswdbxcJzbPEHXEUkFDWug/FqTYl6+rPYLWbwNof1K1MCAwEAAaOBqjCBpzAP\nBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKaz4SsrSbbXc6GqlPUB53NlTKxQ\nMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUprPhKytJttdzoaqU9QHnc2VMrFAw\nRAYDVR0gBD0wOzA5BgRVHSAAMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly9hY2VkaWNv\nbS5lZGljb21ncm91cC5jb20vZG9jMA0GCSqGSIb3DQEBBQUAA4ICAQDOLAtSUWIm\nfQwng4/F9tqgaHtPkl7qpHMyEVNEskTLnewPeUKzEKbHDZ3Ltvo/Onzqv4hTGzz3\ngvoFNTPhNahXwOf9jU8/kzJPeGYDdwdY6ZXIfj7QeQCM8htRM5u8lOk6e25SLTKe\nI6RF+7YuE7CLGLHdztUdp0J/Vb77W7tH1PwkzQSulgUV1qzOMPPKC8W64iLgpq0i\n5ALudBF/TP94HTXa5gI06xgSYXcGCRZj6hitoocf8seACQl1ThCojz2GuHURwCRi\nipZ7SkXp7FnFvmuD5uHorLUwHv4FB4D54SMNUI8FmP8sX+g7tq3PgbUhh8oIKiMn\nMCArz+2UW6yyetLHKKGKC5tNSixthT8Jcjxn4tncB7rrZXtaAWPWkFtPF2Y9fwsZ\no5NjEFIqnxQWWOLcpfShFosOkYuByptZ+thrkQdlVV9SH686+5DdaaVbnG0OLLb6\nzqylfDJKZ0DcMDQj3dcEI2bw/FWAp/tmGYI1Z2JwOV5vx+qQQEQIHriy1tvuWacN\nGHk0vFQYXlPKNFHtRQrmjseCNj6nOGOpMCwXEGCSn1WHElkQwg9naRHMTh5+Spqt\nr0CodaxWkHS4oJyleW/c6RrIaQXpuvoDs3zk4E7Czp3otkYNbn5XOmeUwssfnHdK\nZ05phkOTOPu220+DkdRgfks+KzgHVZhepA==\n-----END CERTIFICATE-----\n\n# Issuer: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd.\n# Subject: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd.\n# Label: \"Microsec e-Szigno Root CA 2009\"\n# Serial: 14014712776195784473\n# MD5 Fingerprint: f8:49:f4:03:bc:44:2d:83:be:48:69:7d:29:64:fc:b1\n# SHA1 Fingerprint: 89:df:74:fe:5c:f4:0f:4a:80:f9:e3:37:7d:54:da:91:e1:01:31:8e\n# SHA256 Fingerprint: 3c:5f:81:fe:a5:fa:b8:2c:64:bf:a2:ea:ec:af:cd:e8:e0:77:fc:86:20:a7:ca:e5:37:16:3d:f3:6e:db:f3:78\n-----BEGIN CERTIFICATE-----\nMIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD\nVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0\nZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G\nCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y\nOTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx\nFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp\nZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o\ndTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP\nkd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc\ncbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U\nfIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7\nN4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC\nxkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1\n+rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G\nA1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM\nPcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG\nSIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h\nmLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk\nddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775\ntyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c\n2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t\nHMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW\n-----END CERTIFICATE-----\n\n# Issuer: CN=e-Guven Kok Elektronik Sertifika Hizmet Saglayicisi O=Elektronik Bilgi Guvenligi A.S.\n# Subject: CN=e-Guven Kok Elektronik Sertifika Hizmet Saglayicisi O=Elektronik Bilgi Guvenligi A.S.\n# Label: \"E-Guven Kok Elektronik Sertifika Hizmet Saglayicisi\"\n# Serial: 91184789765598910059173000485363494069\n# MD5 Fingerprint: 3d:41:29:cb:1e:aa:11:74:cd:5d:b0:62:af:b0:43:5b\n# SHA1 Fingerprint: dd:e1:d2:a9:01:80:2e:1d:87:5e:84:b3:80:7e:4b:b1:fd:99:41:34\n# SHA256 Fingerprint: e6:09:07:84:65:a4:19:78:0c:b6:ac:4c:1c:0b:fb:46:53:d9:d9:cc:6e:b3:94:6e:b7:f3:d6:99:97:ba:d5:98\n-----BEGIN CERTIFICATE-----\nMIIDtjCCAp6gAwIBAgIQRJmNPMADJ72cdpW56tustTANBgkqhkiG9w0BAQUFADB1\nMQswCQYDVQQGEwJUUjEoMCYGA1UEChMfRWxla3Ryb25payBCaWxnaSBHdXZlbmxp\nZ2kgQS5TLjE8MDoGA1UEAxMzZS1HdXZlbiBLb2sgRWxla3Ryb25payBTZXJ0aWZp\na2EgSGl6bWV0IFNhZ2xheWljaXNpMB4XDTA3MDEwNDExMzI0OFoXDTE3MDEwNDEx\nMzI0OFowdTELMAkGA1UEBhMCVFIxKDAmBgNVBAoTH0VsZWt0cm9uaWsgQmlsZ2kg\nR3V2ZW5saWdpIEEuUy4xPDA6BgNVBAMTM2UtR3V2ZW4gS29rIEVsZWt0cm9uaWsg\nU2VydGlmaWthIEhpem1ldCBTYWdsYXlpY2lzaTCCASIwDQYJKoZIhvcNAQEBBQAD\nggEPADCCAQoCggEBAMMSIJ6wXgBljU5Gu4Bc6SwGl9XzcslwuedLZYDBS75+PNdU\nMZTe1RK6UxYC6lhj71vY8+0qGqpxSKPcEC1fX+tcS5yWCEIlKBHMilpiAVDV6wlT\nL/jDj/6z/P2douNffb7tC+Bg62nsM+3YjfsSSYMAyYuXjDtzKjKzEve5TfL0TW3H\n5tYmNwjy2f1rXKPlSFxYvEK+A1qBuhw1DADT9SN+cTAIJjjcJRFHLfO6IxClv7wC\n90Nex/6wN1CZew+TzuZDLMN+DfIcQ2Zgy2ExR4ejT669VmxMvLz4Bcpk9Ok0oSy1\nc+HCPujIyTQlCFzz7abHlJ+tiEMl1+E5YP6sOVkCAwEAAaNCMEAwDgYDVR0PAQH/\nBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJ/uRLOU1fqRTy7ZVZoE\nVtstxNulMA0GCSqGSIb3DQEBBQUAA4IBAQB/X7lTW2M9dTLn+sR0GstG30ZpHFLP\nqk/CaOv/gKlR6D1id4k9CnU58W5dF4dvaAXBlGzZXd/aslnLpRCKysw5zZ/rTt5S\n/wzw9JKp8mxTq5vSR6AfdPebmvEvFZ96ZDAYBzwqD2fK/A+JYZ1lpTzlvBNbCNvj\n/+27BrtqBrF6T2XGgv0enIu1De5Iu7i9qgi0+6N8y5/NkHZchpZ4Vwpm+Vganf2X\nKWDeEaaQHBkc7gGWIjQ0LpH5t8Qn0Xvmv/uARFoW5evg1Ao4vOSR49XrXMGs3xtq\nfJ7lddK2l4fbzIcrQzqECK+rPNv3PGYxhrCdU3nt+CPeQuMtgvEP5fqX\n-----END CERTIFICATE-----\n\n# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3\n# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3\n# Label: \"GlobalSign Root CA - R3\"\n# Serial: 4835703278459759426209954\n# MD5 Fingerprint: c5:df:b8:49:ca:05:13:55:ee:2d:ba:1a:c3:3e:b0:28\n# SHA1 Fingerprint: d6:9b:56:11:48:f0:1c:77:c5:45:78:c1:09:26:df:5b:85:69:76:ad\n# SHA256 Fingerprint: cb:b5:22:d7:b7:f1:27:ad:6a:01:13:86:5b:df:1c:d4:10:2e:7d:07:59:af:63:5a:7c:f4:72:0d:c9:63:c5:3b\n-----BEGIN CERTIFICATE-----\nMIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G\nA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp\nZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4\nMTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG\nA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI\nhvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8\nRgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT\ngHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm\nKPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd\nQQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ\nXriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw\nDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o\nLkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU\nRUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp\njjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK\n6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX\nmcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs\nMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH\nWD9f\n-----END CERTIFICATE-----\n\n# Issuer: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068\n# Subject: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068\n# Label: \"Autoridad de Certificacion Firmaprofesional CIF A62634068\"\n# Serial: 6047274297262753887\n# MD5 Fingerprint: 73:3a:74:7a:ec:bb:a3:96:a6:c2:e4:e2:c8:9b:c0:c3\n# SHA1 Fingerprint: ae:c5:fb:3f:c8:e1:bf:c4:e5:4f:03:07:5a:9a:e8:00:b7:f7:b6:fa\n# SHA256 Fingerprint: 04:04:80:28:bf:1f:28:64:d4:8f:9a:d4:d8:32:94:36:6a:82:88:56:55:3f:3b:14:30:3f:90:14:7f:5d:40:ef\n-----BEGIN CERTIFICATE-----\nMIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE\nBhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h\ncHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEy\nMzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg\nQ2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi\nMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9\nthDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM\ncas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG\nL9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i\nNA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h\nX68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b\nm8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy\nZ/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja\nEbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T\nKI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF\n6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh\nOSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD\nVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNHDhpkLzCBpgYD\nVR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp\ncm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBv\nACAAZABlACAAbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBl\nAGwAbwBuAGEAIAAwADgAMAAxADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF\n661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx51tkljYyGOylMnfX40S2wBEqgLk9\nam58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qkR71kMrv2JYSiJ0L1\nILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaPT481\nPyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS\n3a/DTg4fJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5k\nSeTy36LssUzAKh3ntLFlosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF\n3dvd6qJ2gHN99ZwExEWN57kci57q13XRcrHedUTnQn3iV2t93Jm8PYMo6oCTjcVM\nZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoRsaS8I8nkvof/uZS2+F0g\nStRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTDKCOM/icz\nQ0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQB\njLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V\n-----END CERTIFICATE-----\n\n# Issuer: CN=Izenpe.com O=IZENPE S.A.\n# Subject: CN=Izenpe.com O=IZENPE S.A.\n# Label: \"Izenpe.com\"\n# Serial: 917563065490389241595536686991402621\n# MD5 Fingerprint: a6:b0:cd:85:80:da:5c:50:34:a3:39:90:2f:55:67:73\n# SHA1 Fingerprint: 2f:78:3d:25:52:18:a7:4a:65:39:71:b5:2c:a2:9c:45:15:6f:e9:19\n# SHA256 Fingerprint: 25:30:cc:8e:98:32:15:02:ba:d9:6f:9b:1f:ba:1b:09:9e:2d:29:9e:0f:45:48:bb:91:4f:36:3b:c0:d4:53:1f\n-----BEGIN CERTIFICATE-----\nMIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4\nMQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6\nZW5wZS5jb20wHhcNMDcxMjEzMTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYD\nVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5j\nb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ03rKDx6sp4boFmVq\nscIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAKClaO\nxdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6H\nLmYRY2xU+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFX\nuaOKmMPsOzTFlUFpfnXCPCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQD\nyCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxTOTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+\nJrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbKF7jJeodWLBoBHmy+E60Q\nrLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK0GqfvEyN\nBjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8L\nhij+0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIB\nQFqNeb+Lz0vPqhbBleStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+\nHMh3/1uaD7euBUbl8agW7EekFwIDAQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2lu\nZm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+SVpFTlBFIFMuQS4gLSBDSUYg\nQTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBGNjIgUzgxQzBB\nBgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx\nMCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\nAQYwHQYDVR0OBBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUA\nA4ICAQB4pgwWSp9MiDrAyw6lFn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWb\nlaQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbgakEyrkgPH7UIBzg/YsfqikuFgba56\nawmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8qhT/AQKM6WfxZSzwo\nJNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Csg1lw\nLDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCT\nVyvehQP5aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGk\nLhObNA5me0mrZJfQRsN5nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJb\nUjWumDqtujWTI6cfSN01RpiyEGjkpTHCClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/\nQnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZoQ0iy2+tzJOeRf1SktoA+\nnaM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1ZWrOZyGls\nQyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw==\n-----END CERTIFICATE-----\n\n# Issuer: CN=Chambers of Commerce Root - 2008 O=AC Camerfirma S.A.\n# Subject: CN=Chambers of Commerce Root - 2008 O=AC Camerfirma S.A.\n# Label: \"Chambers of Commerce Root - 2008\"\n# Serial: 11806822484801597146\n# MD5 Fingerprint: 5e:80:9e:84:5a:0e:65:0b:17:02:f3:55:18:2a:3e:d7\n# SHA1 Fingerprint: 78:6a:74:ac:76:ab:14:7f:9c:6a:30:50:ba:9e:a8:7e:fe:9a:ce:3c\n# SHA256 Fingerprint: 06:3e:4a:fa:c4:91:df:d3:32:f3:08:9b:85:42:e9:46:17:d8:93:d7:fe:94:4e:10:a7:93:7e:e2:9d:96:93:c0\n-----BEGIN CERTIFICATE-----\nMIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYD\nVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0\nIHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3\nMRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xKTAnBgNVBAMTIENoYW1iZXJz\nIG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEyMjk1MFoXDTM4MDcz\nMTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBj\ndXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIw\nEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEp\nMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0G\nCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW9\n28sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKAXuFixrYp4YFs8r/lfTJq\nVKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorjh40G072Q\nDuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR\n5gN/ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfL\nZEFHcpOrUMPrCXZkNNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05a\nSd+pZgvMPMZ4fKecHePOjlO+Bd5gD2vlGts/4+EhySnB8esHnFIbAURRPHsl18Tl\nUlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331lubKgdaX8ZSD6e2wsWsSaR6s\n+12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ0wlf2eOKNcx5\nWk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj\nya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAx\nhduub+84Mxh2EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNV\nHQ4EFgQU+SSsD7K1+HnA+mCIG8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1\n+HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpN\nYWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29t\nL2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVy\nZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAt\nIDIwMDiCCQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRV\nHSAAMCowKAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20w\nDQYJKoZIhvcNAQEFBQADggIBAJASryI1wqM58C7e6bXpeHxIvj99RZJe6dqxGfwW\nPJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH3qLPaYRgM+gQDROpI9CF\n5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbURWpGqOt1\nglanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaH\nFoI6M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2\npSB7+R5KBWIBpih1YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MD\nxvbxrN8y8NmBGuScvfaAFPDRLLmF9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QG\ntjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcKzBIKinmwPQN/aUv0NCB9szTq\njktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvGnrDQWzilm1De\nfhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg\nOGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZ\nd0jQ\n-----END CERTIFICATE-----\n\n# Issuer: CN=Global Chambersign Root - 2008 O=AC Camerfirma S.A.\n# Subject: CN=Global Chambersign Root - 2008 O=AC Camerfirma S.A.\n# Label: \"Global Chambersign Root - 2008\"\n# Serial: 14541511773111788494\n# MD5 Fingerprint: 9e:80:ff:78:01:0c:2e:c1:36:bd:fe:96:90:6e:08:f3\n# SHA1 Fingerprint: 4a:bd:ee:ec:95:0d:35:9c:89:ae:c7:52:a1:2c:5b:29:f6:d6:aa:0c\n# SHA256 Fingerprint: 13:63:35:43:93:34:a7:69:80:16:a0:d3:24:de:72:28:4e:07:9d:7b:52:20:bb:8f:bd:74:78:16:ee:be:ba:ca\n-----BEGIN CERTIFICATE-----\nMIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYD\nVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0\nIHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3\nMRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD\naGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMxNDBaFw0zODA3MzEx\nMjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3Vy\ncmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAG\nA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAl\nBgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZI\nhvcNAQEBBQADggIPADCCAgoCggIBAMDfVtPkOpt2RbQT2//BthmLN0EYlVJH6xed\nKYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXfXjaOcNFccUMd2drvXNL7\nG706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0ZJJ0YPP2\nzxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4\nddPB/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyG\nHoiMvvKRhI9lNNgATH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2\nId3UwD2ln58fQ1DJu7xsepeY7s2MH/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3V\nyJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfeOx2YItaswTXbo6Al/3K1dh3e\nbeksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSFHTynyQbehP9r\n6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh\nwZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsog\nzCtLkykPAgMBAAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQW\nBBS5CcqcHtvTbDprru1U8VuTBjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDpr\nru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UEBhMCRVUxQzBBBgNVBAcTOk1hZHJp\nZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJmaXJtYS5jb20vYWRk\ncmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJmaXJt\nYSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiC\nCQDJzdPp1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCow\nKAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZI\nhvcNAQEFBQADggIBAICIf3DekijZBZRG/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZ\nUohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6ReAJ3spED8IXDneRRXoz\nX1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/sdZ7LoR/x\nfxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVz\na2Mg9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yyd\nYhz2rXzdpjEetrHHfoUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMd\nSqlapskD7+3056huirRXhOukP9DuqqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9O\nAP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETrP3iZ8ntxPjzxmKfFGBI/5rso\nM0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVqc5iJWzouE4ge\nv8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z\n09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B\n-----END CERTIFICATE-----\n\n# Issuer: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc.\n# Subject: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc.\n# Label: \"Go Daddy Root Certificate Authority - G2\"\n# Serial: 0\n# MD5 Fingerprint: 80:3a:bc:22:c1:e6:fb:8d:9b:3b:27:4a:32:1b:9a:01\n# SHA1 Fingerprint: 47:be:ab:c9:22:ea:e8:0e:78:78:34:62:a7:9f:45:c2:54:fd:e6:8b\n# SHA256 Fingerprint: 45:14:0b:32:47:eb:9c:c8:c5:b4:f0:d7:b5:30:91:f7:32:92:08:9e:6e:5a:63:e2:74:9d:d3:ac:a9:19:8e:da\n-----BEGIN CERTIFICATE-----\nMIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx\nEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT\nEUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp\nZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz\nNTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH\nEwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE\nAxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw\nDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD\nE6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH\n/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy\nDfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh\nGkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR\ntDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA\nAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE\nFDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX\nWWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu\n9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr\ngIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo\n2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO\nLPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI\n4uJEvlz36hz1\n-----END CERTIFICATE-----\n\n# Issuer: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc.\n# Subject: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc.\n# Label: \"Starfield Root Certificate Authority - G2\"\n# Serial: 0\n# MD5 Fingerprint: d6:39:81:c6:52:7e:96:69:fc:fc:ca:66:ed:05:f2:96\n# SHA1 Fingerprint: b5:1c:06:7c:ee:2b:0c:3d:f8:55:ab:2d:92:f4:fe:39:d4:e7:0f:0e\n# SHA256 Fingerprint: 2c:e1:cb:0b:f9:d2:f9:e1:02:99:3f:be:21:51:52:c3:b2:dd:0c:ab:de:1c:68:e5:31:9b:83:91:54:db:b7:f5\n-----BEGIN CERTIFICATE-----\nMIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx\nEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT\nHFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs\nZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw\nMFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6\nb25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj\naG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp\nY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\nggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg\nnLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1\nHOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N\nHwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN\ndloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0\nHZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO\nBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G\nCSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU\nsHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3\n4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg\n8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K\npL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1\nmMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0\n-----END CERTIFICATE-----\n\n# Issuer: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc.\n# Subject: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc.\n# Label: \"Starfield Services Root Certificate Authority - G2\"\n# Serial: 0\n# MD5 Fingerprint: 17:35:74:af:7b:61:1c:eb:f4:f9:3c:e2:ee:40:f9:a2\n# SHA1 Fingerprint: 92:5a:8f:8d:2c:6d:04:e0:66:5f:59:6a:ff:22:d8:63:e8:25:6f:3f\n# SHA256 Fingerprint: 56:8d:69:05:a2:c8:87:08:a4:b3:02:51:90:ed:cf:ed:b1:97:4a:60:6a:13:c6:e5:29:0f:cb:2a:e6:3e:da:b5\n-----BEGIN CERTIFICATE-----\nMIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx\nEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT\nHFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs\nZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5\nMDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD\nVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy\nZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy\ndmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI\nhvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p\nOsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2\n8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K\nTs9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe\nhRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk\n6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw\nDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q\nAdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI\nbw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB\nve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z\nqwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd\niEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn\n0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN\nsSi6\n-----END CERTIFICATE-----\n\n# Issuer: CN=AffirmTrust Commercial O=AffirmTrust\n# Subject: CN=AffirmTrust Commercial O=AffirmTrust\n# Label: \"AffirmTrust Commercial\"\n# Serial: 8608355977964138876\n# MD5 Fingerprint: 82:92:ba:5b:ef:cd:8a:6f:a6:3d:55:f9:84:f6:d6:b7\n# SHA1 Fingerprint: f9:b5:b6:32:45:5f:9c:be:ec:57:5f:80:dc:e9:6e:2c:c7:b2:78:b7\n# SHA256 Fingerprint: 03:76:ab:1d:54:c5:f9:80:3c:e4:b2:e2:01:a0:ee:7e:ef:7b:57:b6:36:e8:a9:3c:9b:8d:48:60:c9:6f:5f:a7\n-----BEGIN CERTIFICATE-----\nMIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE\nBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz\ndCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL\nMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp\ncm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC\nAQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP\nHx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr\nba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL\nMeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1\nyHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr\nVwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/\nnx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ\nKoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG\nXUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj\nvbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt\nZ8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g\nN53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC\nnlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8=\n-----END CERTIFICATE-----\n\n# Issuer: CN=AffirmTrust Networking O=AffirmTrust\n# Subject: CN=AffirmTrust Networking O=AffirmTrust\n# Label: \"AffirmTrust Networking\"\n# Serial: 8957382827206547757\n# MD5 Fingerprint: 42:65:ca:be:01:9a:9a:4c:a9:8c:41:49:cd:c0:d5:7f\n# SHA1 Fingerprint: 29:36:21:02:8b:20:ed:02:f5:66:c5:32:d1:d6:ed:90:9f:45:00:2f\n# SHA256 Fingerprint: 0a:81:ec:5a:92:97:77:f1:45:90:4a:f3:8d:5d:50:9f:66:b5:e2:c5:8f:cd:b5:31:05:8b:0e:17:f3:f0:b4:1b\n-----BEGIN CERTIFICATE-----\nMIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE\nBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz\ndCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL\nMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp\ncm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC\nAQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y\nYJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua\nkCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL\nQESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp\n6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG\nyH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i\nQLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ\nKoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO\ntDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu\nQY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ\nLgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u\nolu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48\nx3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s=\n-----END CERTIFICATE-----\n\n# Issuer: CN=AffirmTrust Premium O=AffirmTrust\n# Subject: CN=AffirmTrust Premium O=AffirmTrust\n# Label: \"AffirmTrust Premium\"\n# Serial: 7893706540734352110\n# MD5 Fingerprint: c4:5d:0e:48:b6:ac:28:30:4e:0a:bc:f9:38:16:87:57\n# SHA1 Fingerprint: d8:a6:33:2c:e0:03:6f:b1:85:f6:63:4f:7d:6a:06:65:26:32:28:27\n# SHA256 Fingerprint: 70:a7:3f:7f:37:6b:60:07:42:48:90:45:34:b1:14:82:d5:bf:0e:69:8e:cc:49:8d:f5:25:77:eb:f2:e9:3b:9a\n-----BEGIN CERTIFICATE-----\nMIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE\nBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz\ndCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG\nA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U\ncnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf\nqV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ\nJG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ\n+jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS\ns8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5\nHMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7\n70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG\nV+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S\nqHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S\n5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia\nC1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX\nOwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE\nFJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/\nBAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2\nKI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg\nNt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B\n8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ\nMKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc\n0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ\nu4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF\nu+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH\nYoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8\nGKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO\nRtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e\nKeC2uAloGRwYQw==\n-----END CERTIFICATE-----\n\n# Issuer: CN=AffirmTrust Premium ECC O=AffirmTrust\n# Subject: CN=AffirmTrust Premium ECC O=AffirmTrust\n# Label: \"AffirmTrust Premium ECC\"\n# Serial: 8401224907861490260\n# MD5 Fingerprint: 64:b0:09:55:cf:b1:d5:99:e2:be:13:ab:a6:5d:ea:4d\n# SHA1 Fingerprint: b8:23:6b:00:2f:1d:16:86:53:01:55:6c:11:a4:37:ca:eb:ff:c3:bb\n# SHA256 Fingerprint: bd:71:fd:f6:da:97:e4:cf:62:d1:64:7a:dd:25:81:b0:7d:79:ad:f8:39:7e:b4:ec:ba:9c:5e:84:88:82:14:23\n-----BEGIN CERTIFICATE-----\nMIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC\nVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ\ncmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ\nBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt\nVHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D\n0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9\nss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G\nA1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G\nA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs\naobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I\nflc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ==\n-----END CERTIFICATE-----\n\n# Issuer: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority\n# Subject: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority\n# Label: \"Certum Trusted Network CA\"\n# Serial: 279744\n# MD5 Fingerprint: d5:e9:81:40:c5:18:69:fc:46:2c:89:75:62:0f:aa:78\n# SHA1 Fingerprint: 07:e0:32:e0:20:b7:2c:3f:19:2f:06:28:a2:59:3a:19:a7:0f:06:9e\n# SHA256 Fingerprint: 5c:58:46:8d:55:f5:8e:49:7e:74:39:82:d2:b5:00:10:b6:d1:65:37:4a:cf:83:a7:d4:a3:2d:b7:68:c4:40:8e\n-----BEGIN CERTIFICATE-----\nMIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM\nMSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D\nZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU\ncnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3\nWjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg\nUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw\nIAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B\nAQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH\nUV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM\nTXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU\nBBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM\nkUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x\nAcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV\nHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV\nHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y\nsHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL\nI9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8\nJ9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY\nVoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI\n03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw=\n-----END CERTIFICATE-----\n\n# Issuer: CN=Certinomis - Autorité Racine O=Certinomis OU=0002 433998903\n# Subject: CN=Certinomis - Autorité Racine O=Certinomis OU=0002 433998903\n# Label: \"Certinomis - Autorité Racine\"\n# Serial: 1\n# MD5 Fingerprint: 7f:30:78:8c:03:e3:ca:c9:0a:e2:c9:ea:1e:aa:55:1a\n# SHA1 Fingerprint: 2e:14:da:ec:28:f0:fa:1e:8e:38:9a:4e:ab:eb:26:c0:0a:d3:83:c3\n# SHA256 Fingerprint: fc:bf:e2:88:62:06:f7:2b:27:59:3c:8b:07:02:97:e1:2d:76:9e:d1:0e:d7:93:07:05:a8:09:8e:ff:c1:4d:17\n-----BEGIN CERTIFICATE-----\nMIIFnDCCA4SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJGUjET\nMBEGA1UEChMKQ2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxJjAk\nBgNVBAMMHUNlcnRpbm9taXMgLSBBdXRvcml0w6kgUmFjaW5lMB4XDTA4MDkxNzA4\nMjg1OVoXDTI4MDkxNzA4Mjg1OVowYzELMAkGA1UEBhMCRlIxEzARBgNVBAoTCkNl\ncnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMSYwJAYDVQQDDB1DZXJ0\naW5vbWlzIC0gQXV0b3JpdMOpIFJhY2luZTCCAiIwDQYJKoZIhvcNAQEBBQADggIP\nADCCAgoCggIBAJ2Fn4bT46/HsmtuM+Cet0I0VZ35gb5j2CN2DpdUzZlMGvE5x4jY\nF1AMnmHawE5V3udauHpOd4cN5bjr+p5eex7Ezyh0x5P1FMYiKAT5kcOrJ3NqDi5N\n8y4oH3DfVS9O7cdxbwlyLu3VMpfQ8Vh30WC8Tl7bmoT2R2FFK/ZQpn9qcSdIhDWe\nrP5pqZ56XjUl+rSnSTV3lqc2W+HN3yNw2F1MpQiD8aYkOBOo7C+ooWfHpi2GR+6K\n/OybDnT0K0kCe5B1jPyZOQE51kqJ5Z52qz6WKDgmi92NjMD2AR5vpTESOH2VwnHu\n7XSu5DaiQ3XV8QCb4uTXzEIDS3h65X27uK4uIJPT5GHfceF2Z5c/tt9qc1pkIuVC\n28+BA5PY9OMQ4HL2AHCs8MF6DwV/zzRpRbWT5BnbUhYjBYkOjUjkJW+zeL9i9Qf6\nlSTClrLooyPCXQP8w9PlfMl1I9f09bze5N/NgL+RiH2nE7Q5uiy6vdFrzPOlKO1E\nnn1So2+WLhl+HPNbxxaOu2B9d2ZHVIIAEWBsMsGoOBvrbpgT1u449fCfDu/+MYHB\n0iSVL1N6aaLwD4ZFjliCK0wi1F6g530mJ0jfJUaNSih8hp75mxpZuWW/Bd22Ql09\n5gBIgl4g9xGC3srYn+Y3RyYe63j3YcNBZFgCQfna4NH4+ej9Uji29YnfAgMBAAGj\nWzBZMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQN\njLZh2kS40RR9w759XkjwzspqsDAXBgNVHSAEEDAOMAwGCiqBegFWAgIAAQEwDQYJ\nKoZIhvcNAQEFBQADggIBACQ+YAZ+He86PtvqrxyaLAEL9MW12Ukx9F1BjYkMTv9s\nov3/4gbIOZ/xWqndIlgVqIrTseYyCYIDbNc/CMf4uboAbbnW/FIyXaR/pDGUu7ZM\nOH8oMDX/nyNTt7buFHAAQCvaR6s0fl6nVjBhK4tDrP22iCj1a7Y+YEq6QpA0Z43q\n619FVDsXrIvkxmUP7tCMXWY5zjKn2BCXwH40nJ+U8/aGH88bc62UeYdocMMzpXDn\n2NU4lG9jeeu/Cg4I58UvD0KgKxRA/yHgBcUn4YQRE7rWhh1BCxMjidPJC+iKunqj\no3M3NYB9Ergzd0A4wPpeMNLytqOx1qKVl4GbUu1pTP+A5FPbVFsDbVRfsbjvJL1v\nnxHDx2TCDyhihWZeGnuyt++uNckZM6i4J9szVb9o4XVIRFb7zdNIu0eJOqxp9YDG\n5ERQL1TEqkPFMTFYvZbF6nVsmnWxTfj3l/+WFvKXTej28xH5On2KOG4Ey+HTRRWq\npdEdnV1j6CTmNhTih60bWfVEm/vXd3wfAXBioSAaosUaKPQhA+4u2cGA6rnZgtZb\ndsLLO7XSAPCjDuGtbkD326C00EauFddEwk01+dIL8hf2rGbVJLJP0RyZwG71fet0\nBLj5TXcJ17TPBzAJ8bgAVtkXFhYKK4bfjwEZGuW7gmP/vgt2Fl43N+bYdJeimUV5\n-----END CERTIFICATE-----\n\n# Issuer: CN=Root CA Generalitat Valenciana O=Generalitat Valenciana OU=PKIGVA\n# Subject: CN=Root CA Generalitat Valenciana O=Generalitat Valenciana OU=PKIGVA\n# Label: \"Root CA Generalitat Valenciana\"\n# Serial: 994436456\n# MD5 Fingerprint: 2c:8c:17:5e:b1:54:ab:93:17:b5:36:5a:db:d1:c6:f2\n# SHA1 Fingerprint: a0:73:e5:c5:bd:43:61:0d:86:4c:21:13:0a:85:58:57:cc:9c:ea:46\n# SHA256 Fingerprint: 8c:4e:df:d0:43:48:f3:22:96:9e:7e:29:a4:cd:4d:ca:00:46:55:06:1c:16:e1:b0:76:42:2e:f3:42:ad:63:0e\n-----BEGIN CERTIFICATE-----\nMIIGizCCBXOgAwIBAgIEO0XlaDANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJF\nUzEfMB0GA1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJ\nR1ZBMScwJQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwHhcN\nMDEwNzA2MTYyMjQ3WhcNMjEwNzAxMTUyMjQ3WjBoMQswCQYDVQQGEwJFUzEfMB0G\nA1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJR1ZBMScw\nJQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwggEiMA0GCSqG\nSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGKqtXETcvIorKA3Qdyu0togu8M1JAJke+\nWmmmO3I2F0zo37i7L3bhQEZ0ZQKQUgi0/6iMweDHiVYQOTPvaLRfX9ptI6GJXiKj\nSgbwJ/BXufjpTjJ3Cj9BZPPrZe52/lSqfR0grvPXdMIKX/UIKFIIzFVd0g/bmoGl\nu6GzwZTNVOAydTGRGmKy3nXiz0+J2ZGQD0EbtFpKd71ng+CT516nDOeB0/RSrFOy\nA8dEJvt55cs0YFAQexvba9dHq198aMpunUEDEO5rmXteJajCq+TA81yc477OMUxk\nHl6AovWDfgzWyoxVjr7gvkkHD6MkQXpYHYTqWBLI4bft75PelAgxAgMBAAGjggM7\nMIIDNzAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9vY3NwLnBr\naS5ndmEuZXMwEgYDVR0TAQH/BAgwBgEB/wIBAjCCAjQGA1UdIASCAiswggInMIIC\nIwYKKwYBBAG/VQIBADCCAhMwggHoBggrBgEFBQcCAjCCAdoeggHWAEEAdQB0AG8A\ncgBpAGQAYQBkACAAZABlACAAQwBlAHIAdABpAGYAaQBjAGEAYwBpAPMAbgAgAFIA\nYQDtAHoAIABkAGUAIABsAGEAIABHAGUAbgBlAHIAYQBsAGkAdABhAHQAIABWAGEA\nbABlAG4AYwBpAGEAbgBhAC4ADQAKAEwAYQAgAEQAZQBjAGwAYQByAGEAYwBpAPMA\nbgAgAGQAZQAgAFAAcgDhAGMAdABpAGMAYQBzACAAZABlACAAQwBlAHIAdABpAGYA\naQBjAGEAYwBpAPMAbgAgAHEAdQBlACAAcgBpAGcAZQAgAGUAbAAgAGYAdQBuAGMA\naQBvAG4AYQBtAGkAZQBuAHQAbwAgAGQAZQAgAGwAYQAgAHAAcgBlAHMAZQBuAHQA\nZQAgAEEAdQB0AG8AcgBpAGQAYQBkACAAZABlACAAQwBlAHIAdABpAGYAaQBjAGEA\nYwBpAPMAbgAgAHMAZQAgAGUAbgBjAHUAZQBuAHQAcgBhACAAZQBuACAAbABhACAA\nZABpAHIAZQBjAGMAaQDzAG4AIAB3AGUAYgAgAGgAdAB0AHAAOgAvAC8AdwB3AHcA\nLgBwAGsAaQAuAGcAdgBhAC4AZQBzAC8AYwBwAHMwJQYIKwYBBQUHAgEWGWh0dHA6\nLy93d3cucGtpLmd2YS5lcy9jcHMwHQYDVR0OBBYEFHs100DSHHgZZu90ECjcPk+y\neAT8MIGVBgNVHSMEgY0wgYqAFHs100DSHHgZZu90ECjcPk+yeAT8oWykajBoMQsw\nCQYDVQQGEwJFUzEfMB0GA1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0G\nA1UECxMGUEtJR1ZBMScwJQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVu\nY2lhbmGCBDtF5WgwDQYJKoZIhvcNAQEFBQADggEBACRhTvW1yEICKrNcda3Fbcrn\nlD+laJWIwVTAEGmiEi8YPyVQqHxK6sYJ2fR1xkDar1CdPaUWu20xxsdzCkj+IHLt\nb8zog2EWRpABlUt9jppSCS/2bxzkoXHPjCpaF3ODR00PNvsETUlR4hTJZGH71BTg\n9J63NI8KJr2XXPR5OkowGcytT6CYirQxlyric21+eLj4iIlPsSKRZEv1UN4D2+XF\nducTZnV+ZfsBn5OHiJ35Rld8TWCvmHMTI6QgkYH60GFmuH3Rr9ZvHmw96RH9qfmC\nIoaZM3Fa6hlXPZHNqcCjbgcTpsnt+GijnsNacgmHKNHEc8RzGF9QdRYxn7fofMM=\n-----END CERTIFICATE-----\n\n# Issuer: CN=A-Trust-nQual-03 O=A-Trust Ges. f. Sicherheitssysteme im elektr. Datenverkehr GmbH OU=A-Trust-nQual-03\n# Subject: CN=A-Trust-nQual-03 O=A-Trust Ges. f. Sicherheitssysteme im elektr. Datenverkehr GmbH OU=A-Trust-nQual-03\n# Label: \"A-Trust-nQual-03\"\n# Serial: 93214\n# MD5 Fingerprint: 49:63:ae:27:f4:d5:95:3d:d8:db:24:86:b8:9c:07:53\n# SHA1 Fingerprint: d3:c0:63:f2:19:ed:07:3e:34:ad:5d:75:0b:32:76:29:ff:d5:9a:f2\n# SHA256 Fingerprint: 79:3c:bf:45:59:b9:fd:e3:8a:b2:2d:f1:68:69:f6:98:81:ae:14:c4:b0:13:9a:c7:88:a7:8a:1a:fc:ca:02:fb\n-----BEGIN CERTIFICATE-----\nMIIDzzCCAregAwIBAgIDAWweMA0GCSqGSIb3DQEBBQUAMIGNMQswCQYDVQQGEwJB\nVDFIMEYGA1UECgw/QS1UcnVzdCBHZXMuIGYuIFNpY2hlcmhlaXRzc3lzdGVtZSBp\nbSBlbGVrdHIuIERhdGVudmVya2VociBHbWJIMRkwFwYDVQQLDBBBLVRydXN0LW5R\ndWFsLTAzMRkwFwYDVQQDDBBBLVRydXN0LW5RdWFsLTAzMB4XDTA1MDgxNzIyMDAw\nMFoXDTE1MDgxNzIyMDAwMFowgY0xCzAJBgNVBAYTAkFUMUgwRgYDVQQKDD9BLVRy\ndXN0IEdlcy4gZi4gU2ljaGVyaGVpdHNzeXN0ZW1lIGltIGVsZWt0ci4gRGF0ZW52\nZXJrZWhyIEdtYkgxGTAXBgNVBAsMEEEtVHJ1c3QtblF1YWwtMDMxGTAXBgNVBAMM\nEEEtVHJ1c3QtblF1YWwtMDMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\nAQCtPWFuA/OQO8BBC4SAzewqo51ru27CQoT3URThoKgtUaNR8t4j8DRE/5TrzAUj\nlUC5B3ilJfYKvUWG6Nm9wASOhURh73+nyfrBJcyFLGM/BWBzSQXgYHiVEEvc+RFZ\nznF/QJuKqiTfC0Li21a8StKlDJu3Qz7dg9MmEALP6iPESU7l0+m0iKsMrmKS1GWH\n2WrX9IWf5DMiJaXlyDO6w8dB3F/GaswADm0yqLaHNgBid5seHzTLkDx4iHQF63n1\nk3Flyp3HaxgtPVxO59X4PzF9j4fsCiIvI+n+u33J4PTs63zEsMMtYrWacdaxaujs\n2e3Vcuy+VwHOBVWf3tFgiBCzAgMBAAGjNjA0MA8GA1UdEwEB/wQFMAMBAf8wEQYD\nVR0OBAoECERqlWdVeRFPMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOC\nAQEAVdRU0VlIXLOThaq/Yy/kgM40ozRiPvbY7meIMQQDbwvUB/tOdQ/TLtPAF8fG\nKOwGDREkDg6lXb+MshOWcdzUzg4NCmgybLlBMRmrsQd7TZjTXLDR8KdCoLXEjq/+\n8T/0709GAHbrAvv5ndJAlseIOrifEXnzgGWovR/TeIGgUUw3tKZdJXDRZslo+S4R\nFGjxVJgIrCaSD96JntT6s3kr0qN51OyLrIdTaEJMUVF0HhsnLuP1Hyl0Te2v9+GS\nmYHovjrHF1D2t8b8m7CKa9aIA5GPBnc6hQLdmNVDeD/GMBWsm2vLV7eJUYs66MmE\nDNuxUCAKGkq6ahq97BvIxYSazQ==\n-----END CERTIFICATE-----\n\n# Issuer: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA\n# Subject: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA\n# Label: \"TWCA Root Certification Authority\"\n# Serial: 1\n# MD5 Fingerprint: aa:08:8f:f6:f9:7b:b7:f2:b1:a7:1e:9b:ea:ea:bd:79\n# SHA1 Fingerprint: cf:9e:87:6d:d3:eb:fc:42:26:97:a3:b5:a3:7a:a0:76:a9:06:23:48\n# SHA256 Fingerprint: bf:d8:8f:e1:10:1c:41:ae:3e:80:1b:f8:be:56:35:0e:e9:ba:d1:a6:b9:bd:51:5e:dc:5c:6d:5b:87:11:ac:44\n-----BEGIN CERTIFICATE-----\nMIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES\nMBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU\nV0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz\nWhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO\nLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm\naWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\nAQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE\nAcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH\nK3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX\nRfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z\nrX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx\n3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV\nHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq\nhkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC\nMErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls\nXebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D\nlhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn\naspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ\nYiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw==\n-----END CERTIFICATE-----\n\n# Issuer: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2\n# Subject: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2\n# Label: \"Security Communication RootCA2\"\n# Serial: 0\n# MD5 Fingerprint: 6c:39:7d:a4:0e:55:59:b2:3f:d6:41:b1:12:50:de:43\n# SHA1 Fingerprint: 5f:3b:8c:f2:f8:10:b3:7d:78:b4:ce:ec:19:19:c3:73:34:b9:c7:74\n# SHA256 Fingerprint: 51:3b:2c:ec:b8:10:d4:cd:e5:dd:85:39:1a:df:c6:c2:dd:60:d8:7b:b7:36:d2:b5:21:48:4a:a4:7a:0e:be:f6\n-----BEGIN CERTIFICATE-----\nMIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl\nMCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe\nU2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX\nDTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy\ndXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj\nYXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV\nOVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr\nzbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM\nVAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ\nhNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO\nojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw\nawNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs\nOPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3\nDQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF\ncoJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc\nokgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8\nt/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy\n1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/\nSjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03\n-----END CERTIFICATE-----\n\n# Issuer: CN=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority\n# Subject: CN=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority\n# Label: \"Hellenic Academic and Research Institutions RootCA 2011\"\n# Serial: 0\n# MD5 Fingerprint: 73:9f:4c:4b:73:5b:79:e9:fa:ba:1c:ef:6e:cb:d5:c9\n# SHA1 Fingerprint: fe:45:65:9b:79:03:5b:98:a1:61:b5:51:2e:ac:da:58:09:48:22:4d\n# SHA256 Fingerprint: bc:10:4f:15:a4:8b:e7:09:dc:a5:42:a7:e1:d4:b9:df:6f:05:45:27:e8:02:ea:a9:2d:59:54:44:25:8a:fe:71\n-----BEGIN CERTIFICATE-----\nMIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1Ix\nRDBCBgNVBAoTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1\ndGlvbnMgQ2VydC4gQXV0aG9yaXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1p\nYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIFJvb3RDQSAyMDExMB4XDTExMTIw\nNjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYTAkdSMUQwQgYDVQQK\nEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIENl\ncnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl\nc2VhcmNoIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEB\nBQADggEPADCCAQoCggEBAKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPz\ndYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJ\nfel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa71HFK9+WXesyHgLacEns\nbgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u8yBRQlqD\n75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSP\nFEDH3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNV\nHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp\n5dgTBCPuQSUwRwYDVR0eBEAwPqA8MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQu\nb3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQub3JnMA0GCSqGSIb3DQEBBQUA\nA4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVtXdMiKahsog2p\n6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8\nTqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7\ndIsXRSZMFpGD/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8Acys\nNnq/onN694/BtZqhFLKPM58N7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXI\nl7WdmplNsDz4SgCbZN2fOUvRJ9e4\n-----END CERTIFICATE-----\n\n# Issuer: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967\n# Subject: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967\n# Label: \"Actalis Authentication Root CA\"\n# Serial: 6271844772424770508\n# MD5 Fingerprint: 69:c1:0d:4f:07:a3:1b:c3:fe:56:3d:04:bc:11:f6:a6\n# SHA1 Fingerprint: f3:73:b3:87:06:5a:28:84:8a:f2:f3:4a:ce:19:2b:dd:c7:8e:9c:ac\n# SHA256 Fingerprint: 55:92:60:84:ec:96:3a:64:b9:6e:2a:be:01:ce:0b:a8:6a:64:fb:fe:bc:c7:aa:b5:af:c1:55:b3:7f:d7:60:66\n-----BEGIN CERTIFICATE-----\nMIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE\nBhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w\nMzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290\nIENBMB4XDTExMDkyMjExMjIwMloXDTMwMDkyMjExMjIwMlowazELMAkGA1UEBhMC\nSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1\nODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENB\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNv\nUTufClrJwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX\n4ay8IMKx4INRimlNAJZaby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9\nKK3giq0itFZljoZUj5NDKd45RnijMCO6zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/\ngCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1fYVEiVRvjRuPjPdA1Yprb\nrxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2oxgkg4YQ\n51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2F\nbe8lEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxe\nKF+w6D9Fz8+vm2/7hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4F\nv6MGn8i1zeQf1xcGDXqVdFUNaBr8EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbn\nfpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5jF66CyCU3nuDuP/jVo23Eek7\njPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLYiDrIn3hm7Ynz\nezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt\nifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAL\ne3KHwGCmSUyIWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70\njsNjLiNmsGe+b7bAEzlgqqI0JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDz\nWochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKxK3JCaKygvU5a2hi/a5iB0P2avl4V\nSM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+Xlff1ANATIGk0k9j\npwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC4yyX\nX04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+Ok\nfcvHlXHo2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7R\nK4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU\nZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU\nLysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT\nLnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg==\n-----END CERTIFICATE-----\n\n# Issuer: O=Trustis Limited OU=Trustis FPS Root CA\n# Subject: O=Trustis Limited OU=Trustis FPS Root CA\n# Label: \"Trustis FPS Root CA\"\n# Serial: 36053640375399034304724988975563710553\n# MD5 Fingerprint: 30:c9:e7:1e:6b:e6:14:eb:65:b2:16:69:20:31:67:4d\n# SHA1 Fingerprint: 3b:c0:38:0b:33:c3:f6:a6:0c:86:15:22:93:d9:df:f5:4b:81:c0:04\n# SHA256 Fingerprint: c1:b4:82:99:ab:a5:20:8f:e9:63:0a:ce:55:ca:68:a0:3e:da:5a:51:9c:88:02:a0:d3:a6:73:be:8f:8e:55:7d\n-----BEGIN CERTIFICATE-----\nMIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBF\nMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQL\nExNUcnVzdGlzIEZQUyBSb290IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTEx\nMzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1RydXN0aXMgTGltaXRlZDEc\nMBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD\nggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQRUN+\nAOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihH\niTHcDnlkH5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjj\nvSkCqPoc4Vu5g6hBSLwacY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA\n0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zto3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlB\nOrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEAAaNTMFEwDwYDVR0TAQH/\nBAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAdBgNVHQ4E\nFgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01\nGX2cGE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmW\nzaD+vkAMXBJV+JOCyinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP4\n1BIy+Q7DsdwyhEQsb8tGD+pmQQ9P8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZE\nf1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHVl/9D7S3B2l0pKoU/rGXuhg8F\njZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYliB6XzCGcKQEN\nZetX2fNXlrtIzYE=\n-----END CERTIFICATE-----\n\n# Issuer: CN=StartCom Certification Authority O=StartCom Ltd. OU=Secure Digital Certificate Signing\n# Subject: CN=StartCom Certification Authority O=StartCom Ltd. OU=Secure Digital Certificate Signing\n# Label: \"StartCom Certification Authority\"\n# Serial: 45\n# MD5 Fingerprint: c9:3b:0d:84:41:fc:a4:76:79:23:08:57:de:10:19:16\n# SHA1 Fingerprint: a3:f1:33:3f:e2:42:bf:cf:c5:d1:4e:8f:39:42:98:40:68:10:d1:a0\n# SHA256 Fingerprint: e1:78:90:ee:09:a3:fb:f4:f4:8b:9c:41:4a:17:d6:37:b7:a5:06:47:e9:bc:75:23:22:72:7f:cc:17:42:a9:11\n-----BEGIN CERTIFICATE-----\nMIIHhzCCBW+gAwIBAgIBLTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJTDEW\nMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg\nQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh\ndGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM3WhcNMzYwOTE3MTk0NjM2WjB9\nMQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi\nU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh\ncnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA\nA4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk\npMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf\nOQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C\nJi/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT\nKqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi\nHzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM\nAv+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w\n+2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+\nGkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3\nZzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B\n26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID\nAQABo4ICEDCCAgwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD\nVR0OBBYEFE4L7xqkQFulF2mHMMo0aEPQQa7yMB8GA1UdIwQYMBaAFE4L7xqkQFul\nF2mHMMo0aEPQQa7yMIIBWgYDVR0gBIIBUTCCAU0wggFJBgsrBgEEAYG1NwEBATCC\nATgwLgYIKwYBBQUHAgEWImh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5w\nZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL2ludGVybWVk\naWF0ZS5wZGYwgc8GCCsGAQUFBwICMIHCMCcWIFN0YXJ0IENvbW1lcmNpYWwgKFN0\nYXJ0Q29tKSBMdGQuMAMCAQEagZZMaW1pdGVkIExpYWJpbGl0eSwgcmVhZCB0aGUg\nc2VjdGlvbiAqTGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0\naWZpY2F0aW9uIEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93\nd3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgG\nCWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1\ndGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAgEAjo/n3JR5fPGFf59Jb2vKXfuM/gTF\nwWLRfUKKvFO3lANmMD+x5wqnUCBVJX92ehQN6wQOQOY+2IirByeDqXWmN3PH/UvS\nTa0XQMhGvjt/UfzDtgUx3M2FIk5xt/JxXrAaxrqTi3iSSoX4eA+D/i+tLPfkpLst\n0OcNOrg+zvZ49q5HJMqjNTbOx8aHmNrs++myziebiMMEofYLWWivydsQD032ZGNc\npRJvkrKTlMeIFw6Ttn5ii5B/q06f/ON1FE8qMt9bDeD1e5MNq6HPh+GlBEXoPBKl\nCcWw0bdT82AUuoVpaiF8H3VhFyAXe2w7QSlc4axa0c2Mm+tgHRns9+Ww2vl5GKVF\nP0lDV9LdJNUso/2RjSe15esUBppMeyG7Oq0wBhjA2MFrLH9ZXF2RsXAiV+uKa0hK\n1Q8p7MZAwC+ITGgBF3f0JBlPvfrhsiAhS90a2Cl9qrjeVOwhVYBsHvUwyKMQ5bLm\nKhQxw4UtjJixhlpPiVktucf3HMiKf8CdBUrmQk9io20ppB+Fq9vlgcitKj1MXVuE\nJnHEhV5xJMqlG2zYYdMa4FTbzrqpMrUi9nNBCV24F10OD5mQ1kfabwo6YigUZ4LZ\n8dCAWZvLMdibD4x3TrVoivJs9iQOLWxwxXPR3hTQcY+203sC9uO41Alua551hDnm\nfyWl8kgAwKQB2j8=\n-----END CERTIFICATE-----\n\n# Issuer: CN=StartCom Certification Authority G2 O=StartCom Ltd.\n# Subject: CN=StartCom Certification Authority G2 O=StartCom Ltd.\n# Label: \"StartCom Certification Authority G2\"\n# Serial: 59\n# MD5 Fingerprint: 78:4b:fb:9e:64:82:0a:d3:b8:4c:62:f3:64:f2:90:64\n# SHA1 Fingerprint: 31:f1:fd:68:22:63:20:ee:c6:3b:3f:9d:ea:4a:3e:53:7c:7c:39:17\n# SHA256 Fingerprint: c7:ba:65:67:de:93:a7:98:ae:1f:aa:79:1e:71:2d:37:8f:ae:1f:93:c4:39:7f:ea:44:1b:b7:cb:e6:fd:59:95\n-----BEGIN CERTIFICATE-----\nMIIFYzCCA0ugAwIBAgIBOzANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJJTDEW\nMBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlm\naWNhdGlvbiBBdXRob3JpdHkgRzIwHhcNMTAwMTAxMDEwMDAxWhcNMzkxMjMxMjM1\nOTAxWjBTMQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoG\nA1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgRzIwggIiMA0G\nCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2iTZbB7cgNr2Cu+EWIAOVeq8Oo1XJ\nJZlKxdBWQYeQTSFgpBSHO839sj60ZwNq7eEPS8CRhXBF4EKe3ikj1AENoBB5uNsD\nvfOpL9HG4A/LnooUCri99lZi8cVytjIl2bLzvWXFDSxu1ZJvGIsAQRSCb0AgJnoo\nD/Uefyf3lLE3PbfHkffiAez9lInhzG7TNtYKGXmu1zSCZf98Qru23QumNK9LYP5/\nQ0kGi4xDuFby2X8hQxfqp0iVAXV16iulQ5XqFYSdCI0mblWbq9zSOdIxHWDirMxW\nRST1HFSr7obdljKF+ExP6JV2tgXdNiNnvP8V4so75qbsO+wmETRIjfaAKxojAuuK\nHDp2KntWFhxyKrOq42ClAJ8Em+JvHhRYW6Vsi1g8w7pOOlz34ZYrPu8HvKTlXcxN\nnw3h3Kq74W4a7I/htkxNeXJdFzULHdfBR9qWJODQcqhaX2YtENwvKhOuJv4KHBnM\n0D4LnMgJLvlblnpHnOl68wVQdJVznjAJ85eCXuaPOQgeWeU1FEIT/wCc976qUM/i\nUUjXuG+v+E5+M5iSFGI6dWPPe/regjupuznixL0sAA7IF6wT700ljtizkC+p2il9\nHa90OrInwMEePnWjFqmveiJdnxMaz6eg6+OGCtP95paV1yPIN93EfKo2rJgaErHg\nTuixO/XWb/Ew1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE\nAwIBBjAdBgNVHQ4EFgQUS8W0QGutHLOlHGVuRjaJhwUMDrYwDQYJKoZIhvcNAQEL\nBQADggIBAHNXPyzVlTJ+N9uWkusZXn5T50HsEbZH77Xe7XRcxfGOSeD8bpkTzZ+K\n2s06Ctg6Wgk/XzTQLwPSZh0avZyQN8gMjgdalEVGKua+etqhqaRpEpKwfTbURIfX\nUfEpY9Z1zRbkJ4kd+MIySP3bmdCPX1R0zKxnNBFi2QwKN4fRoxdIjtIXHfbX/dtl\n6/2o1PXWT6RbdejF0mCy2wl+JYt7ulKSnj7oxXehPOBKc2thz4bcQ///If4jXSRK\n9dNtD2IEBVeC2m6kMyV5Sy5UGYvMLD0w6dEG/+gyRr61M3Z3qAFdlsHB1b6uJcDJ\nHgoJIIihDsnzb02CVAAgp9KP5DlUFy6NHrgbuxu9mk47EDTcnIhT76IxW1hPkWLI\nwpqazRVdOKnWvvgTtZ8SafJQYqz7Fzf07rh1Z2AQ+4NQ+US1dZxAF7L+/XldblhY\nXzD8AK6vM8EOTmy6p6ahfzLbOOCxchcKK5HsamMm7YnUeMx0HgX4a/6ManY5Ka5l\nIxKVCCIcl85bBu4M4ru8H0ST9tg4RQUh7eStqxK2A6RCLi3ECToDZ2mEmuFZkIoo\nhdVddLHRDiBYmxOlsGOm7XtH/UVVMKTumtTm4ofvmMkyghEpIrwACjFeLQ/Ajulr\nso8uBtjRkcfGEvRM/TAXw8HaOFvjqermobp573PYtlNXLfbQ4ddI\n-----END CERTIFICATE-----\n\n# Issuer: CN=Buypass Class 2 Root CA O=Buypass AS-983163327\n# Subject: CN=Buypass Class 2 Root CA O=Buypass AS-983163327\n# Label: \"Buypass Class 2 Root CA\"\n# Serial: 2\n# MD5 Fingerprint: 46:a7:d2:fe:45:fb:64:5a:a8:59:90:9b:78:44:9b:29\n# SHA1 Fingerprint: 49:0a:75:74:de:87:0a:47:fe:58:ee:f6:c7:6b:eb:c6:0b:12:40:99\n# SHA256 Fingerprint: 9a:11:40:25:19:7c:5b:b9:5d:94:e6:3d:55:cd:43:79:08:47:b6:46:b2:3c:df:11:ad:a4:a0:0e:ff:15:fb:48\n-----BEGIN CERTIFICATE-----\nMIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd\nMBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg\nQ2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow\nTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw\nHgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB\nBQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr\n6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV\nL4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91\n1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx\nMlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ\nQmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB\narcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr\nUs3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi\nFRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS\nP/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN\n9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP\nAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz\nuvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h\n9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s\nA20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t\nOluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo\n+fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7\nKcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2\nDISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us\nH8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ\nI+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7\n5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h\n3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz\nY11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA=\n-----END CERTIFICATE-----\n\n# Issuer: CN=Buypass Class 3 Root CA O=Buypass AS-983163327\n# Subject: CN=Buypass Class 3 Root CA O=Buypass AS-983163327\n# Label: \"Buypass Class 3 Root CA\"\n# Serial: 2\n# MD5 Fingerprint: 3d:3b:18:9e:2c:64:5a:e8:d5:88:ce:0e:f9:37:c2:ec\n# SHA1 Fingerprint: da:fa:f7:fa:66:84:ec:06:8f:14:50:bd:c7:c2:81:a5:bc:a9:64:57\n# SHA256 Fingerprint: ed:f7:eb:bc:a2:7a:2a:38:4d:38:7b:7d:40:10:c6:66:e2:ed:b4:84:3e:4c:29:b4:ae:1d:5b:93:32:e6:b2:4d\n-----BEGIN CERTIFICATE-----\nMIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd\nMBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg\nQ2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow\nTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw\nHgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB\nBQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y\nZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E\nN3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9\ntznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX\n0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c\n/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X\nKhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY\nzIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS\nO1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D\n34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP\nK9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3\nAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv\nTg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj\nQTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV\ncSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS\nIGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2\nHJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa\nO5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv\n033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u\ndmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE\nkbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41\n3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD\nu79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq\n4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc=\n-----END CERTIFICATE-----\n\n# Issuer: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center\n# Subject: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center\n# Label: \"T-TeleSec GlobalRoot Class 3\"\n# Serial: 1\n# MD5 Fingerprint: ca:fb:40:a8:4e:39:92:8a:1d:fe:8e:2f:c4:27:ea:ef\n# SHA1 Fingerprint: 55:a6:72:3e:cb:f2:ec:cd:c3:23:74:70:19:9d:2a:be:11:e3:81:d1\n# SHA256 Fingerprint: fd:73:da:d3:1c:64:4f:f1:b4:3b:ef:0c:cd:da:96:71:0b:9c:d9:87:5e:ca:7e:31:70:7a:f3:e9:6d:52:2b:bd\n-----BEGIN CERTIFICATE-----\nMIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx\nKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd\nBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl\nYyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1\nOTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy\naXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50\nZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G\nCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN\n8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/\nRLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4\nhqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5\nZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM\nEnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj\nQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1\nA/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy\nWL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ\n1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30\n6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT\n91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml\ne9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p\nTpPDpFQUWw==\n-----END CERTIFICATE-----\n\n# Issuer: CN=EE Certification Centre Root CA O=AS Sertifitseerimiskeskus\n# Subject: CN=EE Certification Centre Root CA O=AS Sertifitseerimiskeskus\n# Label: \"EE Certification Centre Root CA\"\n# Serial: 112324828676200291871926431888494945866\n# MD5 Fingerprint: 43:5e:88:d4:7d:1a:4a:7e:fd:84:2e:52:eb:01:d4:6f\n# SHA1 Fingerprint: c9:a8:b9:e7:55:80:5e:58:e3:53:77:a7:25:eb:af:c3:7b:27:cc:d7\n# SHA256 Fingerprint: 3e:84:ba:43:42:90:85:16:e7:75:73:c0:99:2f:09:79:ca:08:4e:46:85:68:1f:f1:95:cc:ba:8a:22:9b:8a:76\n-----BEGIN CERTIFICATE-----\nMIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1\nMQswCQYDVQQGEwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1\nczEoMCYGA1UEAwwfRUUgQ2VydGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYG\nCSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIwMTAxMDMwMTAxMDMwWhgPMjAzMDEy\nMTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlBUyBTZXJ0aWZpdHNl\nZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRyZSBS\nb290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEB\nAQUAA4IBDwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUy\neuuOF0+W2Ap7kaJjbMeMTC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvO\nbntl8jixwKIy72KyaOBhU8E2lf/slLo2rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIw\nWFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw93X2PaRka9ZP585ArQ/d\nMtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtNP2MbRMNE\n1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYD\nVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/\nzQas8fElyalL1BSZMEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYB\nBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEF\nBQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+RjxY6hUFaTlrg4wCQiZrxTFGGV\nv9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqMlIpPnTX/dqQG\nE5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u\nuSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIW\niAYLtqZLICjU3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/v\nGVCJYMzpJJUPwssd8m92kMfMdcGWxZ0=\n-----END CERTIFICATE-----\n\n# Issuer: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı O=TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş. (c) Aralık 2007\n# Subject: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı O=TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş. (c) Aralık 2007\n# Label: \"TURKTRUST Certificate Services Provider Root 2007\"\n# Serial: 1\n# MD5 Fingerprint: 2b:70:20:56:86:82:a0:18:c8:07:53:12:28:70:21:72\n# SHA1 Fingerprint: f1:7f:6f:b6:31:dc:99:e3:a3:c8:7f:fe:1c:f1:81:10:88:d9:60:33\n# SHA256 Fingerprint: 97:8c:d9:66:f2:fa:a0:7b:a7:aa:95:00:d9:c0:2e:9d:77:f2:cd:ad:a6:ad:6b:a7:4a:f4:b9:1c:66:59:3c:50\n-----BEGIN CERTIFICATE-----\nMIIEPTCCAyWgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvzE/MD0GA1UEAww2VMOc\nUktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx\nc8SxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMV4wXAYDVQQKDFVUw5xS\nS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kg\nSGl6bWV0bGVyaSBBLsWeLiAoYykgQXJhbMSxayAyMDA3MB4XDTA3MTIyNTE4Mzcx\nOVoXDTE3MTIyMjE4MzcxOVowgb8xPzA9BgNVBAMMNlTDnFJLVFJVU1QgRWxla3Ry\nb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTELMAkGA1UEBhMC\nVFIxDzANBgNVBAcMBkFua2FyYTFeMFwGA1UECgxVVMOcUktUUlVTVCBCaWxnaSDE\nsGxldGnFn2ltIHZlIEJpbGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkgQS7F\nni4gKGMpIEFyYWzEsWsgMjAwNzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\nggEBAKu3PgqMyKVYFeaK7yc9SrToJdPNM8Ig3BnuiD9NYvDdE3ePYakqtdTyuTFY\nKTsvP2qcb3N2Je40IIDu6rfwxArNK4aUyeNgsURSsloptJGXg9i3phQvKUmi8wUG\n+7RP2qFsmmaf8EMJyupyj+sA1zU511YXRxcw9L6/P8JorzZAwan0qafoEGsIiveG\nHtyaKhUG9qPw9ODHFNRRf8+0222vR5YXm3dx2KdxnSQM9pQ/hTEST7ruToK4uT6P\nIzdezKKqdfcYbwnTrqdUKDT74eA7YH2gvnmJhsifLfkKS8RQouf9eRbHegsYz85M\n733WB2+Y8a+xwXrXgTW4qhe04MsCAwEAAaNCMEAwHQYDVR0OBBYEFCnFkKslrxHk\nYb+j/4hhkeYO/pyBMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0G\nCSqGSIb3DQEBBQUAA4IBAQAQDdr4Ouwo0RSVgrESLFF6QSU2TJ/sPx+EnWVUXKgW\nAkD6bho3hO9ynYYKVZ1WKKxmLNA6VpM0ByWtCLCPyA8JWcqdmBzlVPi5RX9ql2+I\naE1KBiY3iAIOtsbWcpnOa3faYjGkVh+uX4132l32iPwa2Z61gfAyuOOI0JzzaqC5\nmxRZNTZPz/OOXl0XrRWV2N2y1RVuAE6zS89mlOTgzbUF2mNXi+WzqtvALhyQRNsa\nXRik7r4EW5nVcV9VZWRi1aKbBFmGyGJ353yCRWo9F7/snXUMrqNvWtMvmDb08PUZ\nqxFdyKbjKlhqQgnDvZImZjINXQhVdP+MmNAKpoRq0Tl9\n-----END CERTIFICATE-----\n\n# Issuer: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH\n# Subject: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH\n# Label: \"D-TRUST Root Class 3 CA 2 2009\"\n# Serial: 623603\n# MD5 Fingerprint: cd:e0:25:69:8d:47:ac:9c:89:35:90:f7:fd:51:3d:2f\n# SHA1 Fingerprint: 58:e8:ab:b0:36:15:33:fb:80:f7:9b:1b:6d:29:d3:ff:8d:5f:00:f0\n# SHA256 Fingerprint: 49:e7:a4:42:ac:f0:ea:62:87:05:00:54:b5:25:64:b6:50:e4:f4:9e:42:e3:48:d6:aa:38:e0:39:e9:57:b1:c1\n-----BEGIN CERTIFICATE-----\nMIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF\nMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD\nbGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha\nME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM\nHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB\nBQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03\nUAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42\ntSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R\nySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM\nlFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp\n/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G\nA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G\nA1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj\ndG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy\nMENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl\ncmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js\nL2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL\nBQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni\nacfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0\no3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K\nzCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8\nPIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y\nJohw1+qRzT65ysCQblrGXnRl11z+o+I=\n-----END CERTIFICATE-----\n\n# Issuer: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH\n# Subject: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH\n# Label: \"D-TRUST Root Class 3 CA 2 EV 2009\"\n# Serial: 623604\n# MD5 Fingerprint: aa:c6:43:2c:5e:2d:cd:c4:34:c0:50:4f:11:02:4f:b6\n# SHA1 Fingerprint: 96:c9:1b:0b:95:b4:10:98:42:fa:d0:d8:22:79:fe:60:fa:b9:16:83\n# SHA256 Fingerprint: ee:c5:49:6b:98:8c:e9:86:25:b9:34:09:2e:ec:29:08:be:d0:b0:f3:16:c2:d4:73:0c:84:ea:f1:f3:d3:48:81\n-----BEGIN CERTIFICATE-----\nMIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF\nMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD\nbGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw\nNDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV\nBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI\nhvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn\nljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0\n3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z\nqQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR\np75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8\nHgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw\nggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea\nHNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw\nOi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh\nc3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E\nRT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt\ndHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku\nY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp\n3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05\nnsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF\nCSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na\nxpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX\nKVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1\n-----END CERTIFICATE-----\n\n# Issuer: CN=Autoridad de Certificacion Raiz del Estado Venezolano O=Sistema Nacional de Certificacion Electronica OU=Superintendencia de Servicios de Certificacion Electronica\n# Subject: CN=PSCProcert O=Sistema Nacional de Certificacion Electronica OU=Proveedor de Certificados PROCERT\n# Label: \"PSCProcert\"\n# Serial: 11\n# MD5 Fingerprint: e6:24:e9:12:01:ae:0c:de:8e:85:c4:ce:a3:12:dd:ec\n# SHA1 Fingerprint: 70:c1:8d:74:b4:28:81:0a:e4:fd:a5:75:d7:01:9f:99:b0:3d:50:74\n# SHA256 Fingerprint: 3c:fc:3c:14:d1:f6:84:ff:17:e3:8c:43:ca:44:0c:00:b9:67:ec:93:3e:8b:fe:06:4c:a1:d7:2c:90:f2:ad:b0\n-----BEGIN CERTIFICATE-----\nMIIJhjCCB26gAwIBAgIBCzANBgkqhkiG9w0BAQsFADCCAR4xPjA8BgNVBAMTNUF1\ndG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIFJhaXogZGVsIEVzdGFkbyBWZW5lem9s\nYW5vMQswCQYDVQQGEwJWRTEQMA4GA1UEBxMHQ2FyYWNhczEZMBcGA1UECBMQRGlz\ndHJpdG8gQ2FwaXRhbDE2MDQGA1UEChMtU2lzdGVtYSBOYWNpb25hbCBkZSBDZXJ0\naWZpY2FjaW9uIEVsZWN0cm9uaWNhMUMwQQYDVQQLEzpTdXBlcmludGVuZGVuY2lh\nIGRlIFNlcnZpY2lvcyBkZSBDZXJ0aWZpY2FjaW9uIEVsZWN0cm9uaWNhMSUwIwYJ\nKoZIhvcNAQkBFhZhY3JhaXpAc3VzY2VydGUuZ29iLnZlMB4XDTEwMTIyODE2NTEw\nMFoXDTIwMTIyNTIzNTk1OVowgdExJjAkBgkqhkiG9w0BCQEWF2NvbnRhY3RvQHBy\nb2NlcnQubmV0LnZlMQ8wDQYDVQQHEwZDaGFjYW8xEDAOBgNVBAgTB01pcmFuZGEx\nKjAoBgNVBAsTIVByb3ZlZWRvciBkZSBDZXJ0aWZpY2Fkb3MgUFJPQ0VSVDE2MDQG\nA1UEChMtU2lzdGVtYSBOYWNpb25hbCBkZSBDZXJ0aWZpY2FjaW9uIEVsZWN0cm9u\naWNhMQswCQYDVQQGEwJWRTETMBEGA1UEAxMKUFNDUHJvY2VydDCCAiIwDQYJKoZI\nhvcNAQEBBQADggIPADCCAgoCggIBANW39KOUM6FGqVVhSQ2oh3NekS1wwQYalNo9\n7BVCwfWMrmoX8Yqt/ICV6oNEolt6Vc5Pp6XVurgfoCfAUFM+jbnADrgV3NZs+J74\nBCXfgI8Qhd19L3uA3VcAZCP4bsm+lU/hdezgfl6VzbHvvnpC2Mks0+saGiKLt38G\nieU89RLAu9MLmV+QfI4tL3czkkohRqipCKzx9hEC2ZUWno0vluYC3XXCFCpa1sl9\nJcLB/KpnheLsvtF8PPqv1W7/U0HU9TI4seJfxPmOEO8GqQKJ/+MMbpfg353bIdD0\nPghpbNjU5Db4g7ayNo+c7zo3Fn2/omnXO1ty0K+qP1xmk6wKImG20qCZyFSTXai2\n0b1dCl53lKItwIKOvMoDKjSuc/HUtQy9vmebVOvh+qBa7Dh+PsHMosdEMXXqP+UH\n0quhJZb25uSgXTcYOWEAM11G1ADEtMo88aKjPvM6/2kwLkDd9p+cJsmWN63nOaK/\n6mnbVSKVUyqUtd+tFjiBdWbjxywbk5yqjKPK2Ww8F22c3HxT4CAnQzb5EuE8XL1m\nv6JpIzi4mWCZDlZTOpx+FIywBm/xhnaQr/2v/pDGj59/i5IjnOcVdo/Vi5QTcmn7\nK2FjiO/mpF7moxdqWEfLcU8UC17IAggmosvpr2uKGcfLFFb14dq12fy/czja+eev\nbqQ34gcnAgMBAAGjggMXMIIDEzASBgNVHRMBAf8ECDAGAQH/AgEBMDcGA1UdEgQw\nMC6CD3N1c2NlcnRlLmdvYi52ZaAbBgVghl4CAqASDBBSSUYtRy0yMDAwNDAzNi0w\nMB0GA1UdDgQWBBRBDxk4qpl/Qguk1yeYVKIXTC1RVDCCAVAGA1UdIwSCAUcwggFD\ngBStuyIdxuDSAaj9dlBSk+2YwU2u06GCASakggEiMIIBHjE+MDwGA1UEAxM1QXV0\nb3JpZGFkIGRlIENlcnRpZmljYWNpb24gUmFpeiBkZWwgRXN0YWRvIFZlbmV6b2xh\nbm8xCzAJBgNVBAYTAlZFMRAwDgYDVQQHEwdDYXJhY2FzMRkwFwYDVQQIExBEaXN0\ncml0byBDYXBpdGFsMTYwNAYDVQQKEy1TaXN0ZW1hIE5hY2lvbmFsIGRlIENlcnRp\nZmljYWNpb24gRWxlY3Ryb25pY2ExQzBBBgNVBAsTOlN1cGVyaW50ZW5kZW5jaWEg\nZGUgU2VydmljaW9zIGRlIENlcnRpZmljYWNpb24gRWxlY3Ryb25pY2ExJTAjBgkq\nhkiG9w0BCQEWFmFjcmFpekBzdXNjZXJ0ZS5nb2IudmWCAQowDgYDVR0PAQH/BAQD\nAgEGME0GA1UdEQRGMESCDnByb2NlcnQubmV0LnZloBUGBWCGXgIBoAwMClBTQy0w\nMDAwMDKgGwYFYIZeAgKgEgwQUklGLUotMzE2MzUzNzMtNzB2BgNVHR8EbzBtMEag\nRKBChkBodHRwOi8vd3d3LnN1c2NlcnRlLmdvYi52ZS9sY3IvQ0VSVElGSUNBRE8t\nUkFJWi1TSEEzODRDUkxERVIuY3JsMCOgIaAfhh1sZGFwOi8vYWNyYWl6LnN1c2Nl\ncnRlLmdvYi52ZTA3BggrBgEFBQcBAQQrMCkwJwYIKwYBBQUHMAGGG2h0dHA6Ly9v\nY3NwLnN1c2NlcnRlLmdvYi52ZTBBBgNVHSAEOjA4MDYGBmCGXgMBAjAsMCoGCCsG\nAQUFBwIBFh5odHRwOi8vd3d3LnN1c2NlcnRlLmdvYi52ZS9kcGMwDQYJKoZIhvcN\nAQELBQADggIBACtZ6yKZu4SqT96QxtGGcSOeSwORR3C7wJJg7ODU523G0+1ng3dS\n1fLld6c2suNUvtm7CpsR72H0xpkzmfWvADmNg7+mvTV+LFwxNG9s2/NkAZiqlCxB\n3RWGymspThbASfzXg0gTB1GEMVKIu4YXx2sviiCtxQuPcD4quxtxj7mkoP3Yldmv\nWb8lK5jpY5MvYB7Eqvh39YtsL+1+LrVPQA3uvFd359m21D+VJzog1eWuq2w1n8Gh\nHVnchIHuTQfiSLaeS5UtQbHh6N5+LwUeaO6/u5BlOsju6rEYNxxik6SgMexxbJHm\npHmJWhSnFFAFTKQAVzAswbVhltw+HoSvOULP5dAssSS830DD7X9jSr3hTxJkhpXz\nsOfIt+FTvZLm8wyWuevo5pLtp4EJFAv8lXrPj9Y0TzYS3F7RNHXGRoAvlQSMx4bE\nqCaJqD8Zm4G7UaRKhqsLEQ+xrmNTbSjq3TNWOByyrYDT13K9mmyZY+gAu0F2Bbdb\nmRiKw7gSXFbPVgx96OLP7bx0R/vu0xdOIk9W/1DzLuY5poLWccret9W6aAjtmcz9\nopLLabid+Qqkpj5PkygqYWwHJgD/ll9ohri4zspV4KuxPX+Y1zMOWj3YeMLEYC/H\nYvBhkdI4sPaeVdtAgAUSM84dkpvRabP/v/GSCmE1P93+hvS84Bpxs2Km\n-----END CERTIFICATE-----\n\n# Issuer: CN=China Internet Network Information Center EV Certificates Root O=China Internet Network Information Center\n# Subject: CN=China Internet Network Information Center EV Certificates Root O=China Internet Network Information Center\n# Label: \"China Internet Network Information Center EV Certificates Root\"\n# Serial: 1218379777\n# MD5 Fingerprint: 55:5d:63:00:97:bd:6a:97:f5:67:ab:4b:fb:6e:63:15\n# SHA1 Fingerprint: 4f:99:aa:93:fb:2b:d1:37:26:a1:99:4a:ce:7f:f0:05:f2:93:5d:1e\n# SHA256 Fingerprint: 1c:01:c6:f4:db:b2:fe:fc:22:55:8b:2b:ca:32:56:3f:49:84:4a:cf:c3:2b:7b:e4:b0:ff:59:9f:9e:8c:7a:f7\n-----BEGIN CERTIFICATE-----\nMIID9zCCAt+gAwIBAgIESJ8AATANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMC\nQ04xMjAwBgNVBAoMKUNoaW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24g\nQ2VudGVyMUcwRQYDVQQDDD5DaGluYSBJbnRlcm5ldCBOZXR3b3JrIEluZm9ybWF0\naW9uIENlbnRlciBFViBDZXJ0aWZpY2F0ZXMgUm9vdDAeFw0xMDA4MzEwNzExMjVa\nFw0zMDA4MzEwNzExMjVaMIGKMQswCQYDVQQGEwJDTjEyMDAGA1UECgwpQ2hpbmEg\nSW50ZXJuZXQgTmV0d29yayBJbmZvcm1hdGlvbiBDZW50ZXIxRzBFBgNVBAMMPkNo\naW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24gQ2VudGVyIEVWIENlcnRp\nZmljYXRlcyBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm35z\n7r07eKpkQ0H1UN+U8i6yjUqORlTSIRLIOTJCBumD1Z9S7eVnAztUwYyZmczpwA//\nDdmEEbK40ctb3B75aDFk4Zv6dOtouSCV98YPjUesWgbdYavi7NifFy2cyjw1l1Vx\nzUOFsUcW9SxTgHbP0wBkvUCZ3czY28Sf1hNfQYOL+Q2HklY0bBoQCxfVWhyXWIQ8\nhBouXJE0bhlffxdpxWXvayHG1VA6v2G5BY3vbzQ6sm8UY78WO5upKv23KzhmBsUs\n4qpnHkWnjQRmQvaPK++IIGmPMowUc9orhpFjIpryp9vOiYurXccUwVswah+xt54u\ngQEC7c+WXmPbqOY4twIDAQABo2MwYTAfBgNVHSMEGDAWgBR8cks5x8DbYqVPm6oY\nNJKiyoOCWTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4E\nFgQUfHJLOcfA22KlT5uqGDSSosqDglkwDQYJKoZIhvcNAQEFBQADggEBACrDx0M3\nj92tpLIM7twUbY8opJhJywyA6vPtI2Z1fcXTIWd50XPFtQO3WKwMVC/GVhMPMdoG\n52U7HW8228gd+f2ABsqjPWYWqJ1MFn3AlUa1UeTiH9fqBk1jjZaM7+czV0I664zB\nechNdn3e9rG3geCg+aF4RhcaVpjwTj2rHO3sOdwHSPdj/gauwqRcalsyiMXHM4Ws\nZkJHwlgkmeHlPuV1LI5D1l08eB6olYIpUNHRFrrvwb562bTYzB5MRuF3sTGrvSrI\nzo9uoV1/A3U05K2JRVRevq4opbs/eHnrc7MKDf2+yfdWrPa37S+bISnHOLaVxATy\nwy39FCqQmbkHzJ8=\n-----END CERTIFICATE-----\n\n# Issuer: CN=Swisscom Root CA 2 O=Swisscom OU=Digital Certificate Services\n# Subject: CN=Swisscom Root CA 2 O=Swisscom OU=Digital Certificate Services\n# Label: \"Swisscom Root CA 2\"\n# Serial: 40698052477090394928831521023204026294\n# MD5 Fingerprint: 5b:04:69:ec:a5:83:94:63:18:a7:86:d0:e4:f2:6e:19\n# SHA1 Fingerprint: 77:47:4f:c6:30:e4:0f:4c:47:64:3f:84:ba:b8:c6:95:4a:8a:41:ec\n# SHA256 Fingerprint: f0:9b:12:2c:71:14:f4:a0:9b:d4:ea:4f:4a:99:d5:58:b4:6e:4c:25:cd:81:14:0d:29:c0:56:13:91:4c:38:41\n-----BEGIN CERTIFICATE-----\nMIIF2TCCA8GgAwIBAgIQHp4o6Ejy5e/DfEoeWhhntjANBgkqhkiG9w0BAQsFADBk\nMQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0\nYWwgQ2VydGlmaWNhdGUgU2VydmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3Qg\nQ0EgMjAeFw0xMTA2MjQwODM4MTRaFw0zMTA2MjUwNzM4MTRaMGQxCzAJBgNVBAYT\nAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZp\nY2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAyMIICIjAN\nBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAlUJOhJ1R5tMJ6HJaI2nbeHCOFvEr\njw0DzpPMLgAIe6szjPTpQOYXTKueuEcUMncy3SgM3hhLX3af+Dk7/E6J2HzFZ++r\n0rk0X2s682Q2zsKwzxNoysjL67XiPS4h3+os1OD5cJZM/2pYmLcX5BtS5X4HAB1f\n2uY+lQS3aYg5oUFgJWFLlTloYhyxCwWJwDaCFCE/rtuh/bxvHGCGtlOUSbkrRsVP\nACu/obvLP+DHVxxX6NZp+MEkUp2IVd3Chy50I9AU/SpHWrumnf2U5NGKpV+GY3aF\ny6//SSj8gO1MedK75MDvAe5QQQg1I3ArqRa0jG6F6bYRzzHdUyYb3y1aSgJA/MTA\ntukxGggo5WDDH8SQjhBiYEQN7Aq+VRhxLKX0srwVYv8c474d2h5Xszx+zYIdkeNL\n6yxSNLCK/RJOlrDrcH+eOfdmQrGrrFLadkBXeyq96G4DsguAhYidDMfCd7Camlf0\nuPoTXGiTOmekl9AbmbeGMktg2M7v0Ax/lZ9vh0+Hio5fCHyqW/xavqGRn1V9TrAL\nacywlKinh/LTSlDcX3KwFnUey7QYYpqwpzmqm59m2I2mbJYV4+by+PGDYmy7Velh\nk6M99bFXi08jsJvllGov34zflVEpYKELKeRcVVi3qPyZ7iVNTA6z00yPhOgpD/0Q\nVAKFyPnlw4vP5w8CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0hBBYw\nFDASBgdghXQBUwIBBgdghXQBUwIBMBIGA1UdEwEB/wQIMAYBAf8CAQcwHQYDVR0O\nBBYEFE0mICKJS9PVpAqhb97iEoHF8TwuMB8GA1UdIwQYMBaAFE0mICKJS9PVpAqh\nb97iEoHF8TwuMA0GCSqGSIb3DQEBCwUAA4ICAQAyCrKkG8t9voJXiblqf/P0wS4R\nfbgZPnm3qKhyN2abGu2sEzsOv2LwnN+ee6FTSA5BesogpxcbtnjsQJHzQq0Qw1zv\n/2BZf82Fo4s9SBwlAjxnffUy6S8w5X2lejjQ82YqZh6NM4OKb3xuqFp1mrjX2lhI\nREeoTPpMSQpKwhI3qEAMw8jh0FcNlzKVxzqfl9NX+Ave5XLzo9v/tdhZsnPdTSpx\nsrpJ9csc1fV5yJmz/MFMdOO0vSk3FQQoHt5FRnDsr7p4DooqzgB53MBfGWcsa0vv\naGgLQ+OswWIJ76bdZWGgr4RVSJFSHMYlkSrQwSIjYVmvRRGFHQEkNI/Ps/8XciAT\nwoCqISxxOQ7Qj1zB09GOInJGTB2Wrk9xseEFKZZZ9LuedT3PDTcNYtsmjGOpI99n\nBjx8Oto0QuFmtEYE3saWmA9LSHokMnWRn6z3aOkquVVlzl1h0ydw2Df+n7mvoC5W\nt6NlUe07qxS/TFED6F+KBZvuim6c779o+sjaC+NCydAXFJy3SuCvkychVSa1ZC+N\n8f+mQAWFBVzKBxlcCxMoTFh/wqXvRdpg065lYZ1Tg3TCrvJcwhbtkj6EPnNgiLx2\n9CzP0H1907he0ZESEOnN3col49XtmS++dYFLJPlFRpTJKSFTnCZFqhMX5OfNeOI5\nwSsSnqaeG8XmDtkx2Q==\n-----END CERTIFICATE-----\n\n# Issuer: CN=Swisscom Root EV CA 2 O=Swisscom OU=Digital Certificate Services\n# Subject: CN=Swisscom Root EV CA 2 O=Swisscom OU=Digital Certificate Services\n# Label: \"Swisscom Root EV CA 2\"\n# Serial: 322973295377129385374608406479535262296\n# MD5 Fingerprint: 7b:30:34:9f:dd:0a:4b:6b:35:ca:31:51:28:5d:ae:ec\n# SHA1 Fingerprint: e7:a1:90:29:d3:d5:52:dc:0d:0f:c6:92:d3:ea:88:0d:15:2e:1a:6b\n# SHA256 Fingerprint: d9:5f:ea:3c:a4:ee:dc:e7:4c:d7:6e:75:fc:6d:1f:f6:2c:44:1f:0f:a8:bc:77:f0:34:b1:9e:5d:b2:58:01:5d\n-----BEGIN CERTIFICATE-----\nMIIF4DCCA8igAwIBAgIRAPL6ZOJ0Y9ON/RAdBB92ylgwDQYJKoZIhvcNAQELBQAw\nZzELMAkGA1UEBhMCY2gxETAPBgNVBAoTCFN3aXNzY29tMSUwIwYDVQQLExxEaWdp\ndGFsIENlcnRpZmljYXRlIFNlcnZpY2VzMR4wHAYDVQQDExVTd2lzc2NvbSBSb290\nIEVWIENBIDIwHhcNMTEwNjI0MDk0NTA4WhcNMzEwNjI1MDg0NTA4WjBnMQswCQYD\nVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0YWwgQ2Vy\ndGlmaWNhdGUgU2VydmljZXMxHjAcBgNVBAMTFVN3aXNzY29tIFJvb3QgRVYgQ0Eg\nMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMT3HS9X6lds93BdY7Bx\nUglgRCgzo3pOCvrY6myLURYaVa5UJsTMRQdBTxB5f3HSek4/OE6zAMaVylvNwSqD\n1ycfMQ4jFrclyxy0uYAyXhqdk/HoPGAsp15XGVhRXrwsVgu42O+LgrQ8uMIkqBPH\noCE2G3pXKSinLr9xJZDzRINpUKTk4RtiGZQJo/PDvO/0vezbE53PnUgJUmfANykR\nHvvSEaeFGHR55E+FFOtSN+KxRdjMDUN/rhPSays/p8LiqG12W0OfvrSdsyaGOx9/\n5fLoZigWJdBLlzin5M8J0TbDC77aO0RYjb7xnglrPvMyxyuHxuxenPaHZa0zKcQv\nidm5y8kDnftslFGXEBuGCxobP/YCfnvUxVFkKJ3106yDgYjTdLRZncHrYTNaRdHL\nOdAGalNgHa/2+2m8atwBz735j9m9W8E6X47aD0upm50qKGsaCnw8qyIL5XctcfaC\nNYGu+HuB5ur+rPQam3Rc6I8k9l2dRsQs0h4rIWqDJ2dVSqTjyDKXZpBy2uPUZC5f\n46Fq9mDU5zXNysRojddxyNMkM3OxbPlq4SjbX8Y96L5V5jcb7STZDxmPX2MYWFCB\nUWVv8p9+agTnNCRxunZLWB4ZvRVgRaoMEkABnRDixzgHcgplwLa7JSnaFp6LNYth\n7eVxV4O1PHGf40+/fh6Bn0GXAgMBAAGjgYYwgYMwDgYDVR0PAQH/BAQDAgGGMB0G\nA1UdIQQWMBQwEgYHYIV0AVMCAgYHYIV0AVMCAjASBgNVHRMBAf8ECDAGAQH/AgED\nMB0GA1UdDgQWBBRF2aWBbj2ITY1x0kbBbkUe88SAnTAfBgNVHSMEGDAWgBRF2aWB\nbj2ITY1x0kbBbkUe88SAnTANBgkqhkiG9w0BAQsFAAOCAgEAlDpzBp9SSzBc1P6x\nXCX5145v9Ydkn+0UjrgEjihLj6p7jjm02Vj2e6E1CqGdivdj5eu9OYLU43otb98T\nPLr+flaYC/NUn81ETm484T4VvwYmneTwkLbUwp4wLh/vx3rEUMfqe9pQy3omywC0\nWqu1kx+AiYQElY2NfwmTv9SoqORjbdlk5LgpWgi/UOGED1V7XwgiG/W9mR4U9s70\nWBCCswo9GcG/W6uqmdjyMb3lOGbcWAXH7WMaLgqXfIeTK7KK4/HsGOV1timH59yL\nGn602MnTihdsfSlEvoqq9X46Lmgxk7lq2prg2+kupYTNHAq4Sgj5nPFhJpiTt3tm\n7JFe3VE/23MPrQRYCd0EApUKPtN236YQHoA96M2kZNEzx5LH4k5E4wnJTsJdhw4S\nnr8PyQUQ3nqjsTzyP6WqJ3mtMX0f/fwZacXduT98zca0wjAefm6S139hdlqP65VN\nvBFuIXxZN5nQBrz5Bm0yFqXZaajh3DyAHmBR3NdUIR7KYndP+tiPsys6DXhyyWhB\nWkdKwqPrGtcKqzwyVcgKEZzfdNbwQBUdyLmPtTbFr/giuMod89a2GQ+fYWVq6nTI\nfI/DT11lgh/ZDYnadXL77/FHZxOzyNEZiCcmmpl5fx7kLD977vHeTYuWl8PVP3wb\nI+2ksx0WckNLIOFZfsLorSa/ovc=\n-----END CERTIFICATE-----\n\n# Issuer: CN=CA Disig Root R1 O=Disig a.s.\n# Subject: CN=CA Disig Root R1 O=Disig a.s.\n# Label: \"CA Disig Root R1\"\n# Serial: 14052245610670616104\n# MD5 Fingerprint: be:ec:11:93:9a:f5:69:21:bc:d7:c1:c0:67:89:cc:2a\n# SHA1 Fingerprint: 8e:1c:74:f8:a6:20:b9:e5:8a:f4:61:fa:ec:2b:47:56:51:1a:52:c6\n# SHA256 Fingerprint: f9:6f:23:f4:c3:e7:9c:07:7a:46:98:8d:5a:f5:90:06:76:a0:f0:39:cb:64:5d:d1:75:49:b2:16:c8:24:40:ce\n-----BEGIN CERTIFICATE-----\nMIIFaTCCA1GgAwIBAgIJAMMDmu5QkG4oMA0GCSqGSIb3DQEBBQUAMFIxCzAJBgNV\nBAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu\nMRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIxMB4XDTEyMDcxOTA5MDY1NloXDTQy\nMDcxOTA5MDY1NlowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx\nEzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjEw\nggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCqw3j33Jijp1pedxiy3QRk\nD2P9m5YJgNXoqqXinCaUOuiZc4yd39ffg/N4T0Dhf9Kn0uXKE5Pn7cZ3Xza1lK/o\nOI7bm+V8u8yN63Vz4STN5qctGS7Y1oprFOsIYgrY3LMATcMjfF9DCCMyEtztDK3A\nfQ+lekLZWnDZv6fXARz2m6uOt0qGeKAeVjGu74IKgEH3G8muqzIm1Cxr7X1r5OJe\nIgpFy4QxTaz+29FHuvlglzmxZcfe+5nkCiKxLU3lSCZpq+Kq8/v8kiky6bM+TR8n\noc2OuRf7JT7JbvN32g0S9l3HuzYQ1VTW8+DiR0jm3hTaYVKvJrT1cU/J19IG32PK\n/yHoWQbgCNWEFVP3Q+V8xaCJmGtzxmjOZd69fwX3se72V6FglcXM6pM6vpmumwKj\nrckWtc7dXpl4fho5frLABaTAgqWjR56M6ly2vGfb5ipN0gTco65F97yLnByn1tUD\n3AjLLhbKXEAz6GfDLuemROoRRRw1ZS0eRWEkG4IupZ0zXWX4Qfkuy5Q/H6MMMSRE\n7cderVC6xkGbrPAXZcD4XW9boAo0PO7X6oifmPmvTiT6l7Jkdtqr9O3jw2Dv1fkC\nyC2fg69naQanMVXVz0tv/wQFx1isXxYb5dKj6zHbHzMVTdDypVP1y+E9Tmgt2BLd\nqvLmTZtJ5cUoobqwWsagtQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud\nDwEB/wQEAwIBBjAdBgNVHQ4EFgQUiQq0OJMa5qvum5EY+fU8PjXQ04IwDQYJKoZI\nhvcNAQEFBQADggIBADKL9p1Kyb4U5YysOMo6CdQbzoaz3evUuii+Eq5FLAR0rBNR\nxVgYZk2C2tXck8An4b58n1KeElb21Zyp9HWc+jcSjxyT7Ff+Bw+r1RL3D65hXlaA\nSfX8MPWbTx9BLxyE04nH4toCdu0Jz2zBuByDHBb6lM19oMgY0sidbvW9adRtPTXo\nHqJPYNcHKfyyo6SdbhWSVhlMCrDpfNIZTUJG7L399ldb3Zh+pE3McgODWF3vkzpB\nemOqfDqo9ayk0d2iLbYq/J8BjuIQscTK5GfbVSUZP/3oNn6z4eGBrxEWi1CXYBmC\nAMBrTXO40RMHPuq2MU/wQppt4hF05ZSsjYSVPCGvxdpHyN85YmLLW1AL14FABZyb\n7bq2ix4Eb5YgOe2kfSnbSM6C3NQCjR0EMVrHS/BsYVLXtFHCgWzN4funodKSds+x\nDzdYpPJScWc/DIh4gInByLUfkmO+p3qKViwaqKactV2zY9ATIKHrkWzQjX2v3wvk\nF7mGnjixlAxYjOBVqjtjbZqJYLhkKpLGN/R+Q0O3c+gB53+XD9fyexn9GtePyfqF\na3qdnom2piiZk4hA9z7NUaPK6u95RyG1/jLix8NRb76AdPCkwzryT+lf3xkK8jsT\nQ6wxpLPn6/wY1gGp8yqPNg7rtLG8t0zJa7+h89n07eLw4+1knj0vllJPgFOL\n-----END CERTIFICATE-----\n\n# Issuer: CN=CA Disig Root R2 O=Disig a.s.\n# Subject: CN=CA Disig Root R2 O=Disig a.s.\n# Label: \"CA Disig Root R2\"\n# Serial: 10572350602393338211\n# MD5 Fingerprint: 26:01:fb:d8:27:a7:17:9a:45:54:38:1a:43:01:3b:03\n# SHA1 Fingerprint: b5:61:eb:ea:a4:de:e4:25:4b:69:1a:98:a5:57:47:c2:34:c7:d9:71\n# SHA256 Fingerprint: e2:3d:4a:03:6d:7b:70:e9:f5:95:b1:42:20:79:d2:b9:1e:df:bb:1f:b6:51:a0:63:3e:aa:8a:9d:c5:f8:07:03\n-----BEGIN CERTIFICATE-----\nMIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV\nBAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu\nMRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy\nMDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx\nEzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw\nggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe\nNcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH\nPWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I\nx2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe\nQTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR\nyyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO\nQG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912\nH9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ\nQfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD\ni/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs\nnLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1\nrqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud\nDwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI\nhvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM\ntCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf\nGopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb\nlvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka\n+elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal\nTFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i\nnSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3\ngzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr\nG5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os\nzMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x\nL4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL\n-----END CERTIFICATE-----\n\n# Issuer: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV\n# Subject: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV\n# Label: \"ACCVRAIZ1\"\n# Serial: 6828503384748696800\n# MD5 Fingerprint: d0:a0:5a:ee:05:b6:09:94:21:a1:7d:f1:b2:29:82:02\n# SHA1 Fingerprint: 93:05:7a:88:15:c6:4f:ce:88:2f:fa:91:16:52:28:78:bc:53:64:17\n# SHA256 Fingerprint: 9a:6e:c0:12:e1:a7:da:9d:be:34:19:4d:47:8a:d7:c0:db:18:22:fb:07:1d:f1:29:81:49:6e:d1:04:38:41:13\n-----BEGIN CERTIFICATE-----\nMIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE\nAwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw\nCQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ\nBgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwHUEtJQUNDVjENMAsGA1UECgwEQUND\nVjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCb\nqau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gMjmoY\nHtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWo\nG2ioPej0RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpA\nlHPrzg5XPAOBOp0KoVdDaaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhr\nIA8wKFSVf+DuzgpmndFALW4ir50awQUZ0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/\n0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDGWuzndN9wrqODJerWx5eH\nk6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs78yM2x/47\n4KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMO\nm3WR5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpa\ncXpkatcnYGMN285J9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPl\nuUsXQA+xtrn13k/c4LOsOxFwYIRKQ26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYI\nKwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRwOi8vd3d3LmFjY3YuZXMvZmls\nZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEuY3J0MB8GCCsG\nAQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2\nVuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeT\nVfZW6oHlNsyMHj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIG\nCCsGAQUFBwICMIIBFB6CARAAQQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUA\ncgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBhAO0AegAgAGQAZQAgAGwAYQAgAEEA\nQwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUAYwBuAG8AbABvAGcA\n7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBjAHQA\ncgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAA\nQwBQAFMAIABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUA\nczAwBggrBgEFBQcCARYkaHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2Mu\naHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRt\naW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2MV9kZXIuY3JsMA4GA1Ud\nDwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZIhvcNAQEF\nBQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdp\nD70ER9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gU\nJyCpZET/LtZ1qmxNYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+m\nAM/EKXMRNt6GGT6d7hmKG9Ww7Y49nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepD\nvV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJTS+xJlsndQAJxGJ3KQhfnlms\ntn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3sCPdK6jT2iWH\n7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h\nI6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA\nh1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF\nd3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H\npPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7\n-----END CERTIFICATE-----\n\n# Issuer: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA\n# Subject: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA\n# Label: \"TWCA Global Root CA\"\n# Serial: 3262\n# MD5 Fingerprint: f9:03:7e:cf:e6:9e:3c:73:7a:2a:90:07:69:ff:2b:96\n# SHA1 Fingerprint: 9c:bb:48:53:f6:a4:f6:d3:52:a4:e8:32:52:55:60:13:f5:ad:af:65\n# SHA256 Fingerprint: 59:76:90:07:f7:68:5d:0f:cd:50:87:2f:9f:95:d5:75:5a:5b:2b:45:7d:81:f3:69:2b:61:0a:98:67:2f:0e:1b\n-----BEGIN CERTIFICATE-----\nMIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx\nEjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT\nVFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5\nNTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT\nB1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG\nSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF\n10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz\n0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh\nMBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH\nzIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc\n46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2\nyKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi\nlaLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP\noA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA\nBDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE\nqYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm\n4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB\n/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL\n1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn\nLhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF\nH6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo\nRI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+\nnile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh\n15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW\n6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW\nnsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j\nwa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz\naGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy\nKwbQBM0=\n-----END CERTIFICATE-----\n\n# Issuer: CN=TeliaSonera Root CA v1 O=TeliaSonera\n# Subject: CN=TeliaSonera Root CA v1 O=TeliaSonera\n# Label: \"TeliaSonera Root CA v1\"\n# Serial: 199041966741090107964904287217786801558\n# MD5 Fingerprint: 37:41:49:1b:18:56:9a:26:f5:ad:c2:66:fb:40:a5:4c\n# SHA1 Fingerprint: 43:13:bb:96:f1:d5:86:9b:c1:4e:6a:92:f6:cf:f6:34:69:87:82:37\n# SHA256 Fingerprint: dd:69:36:fe:21:f8:f0:77:c1:23:a1:a5:21:c1:22:24:f7:22:55:b7:3e:03:a7:26:06:93:e8:a2:4b:0f:a3:89\n-----BEGIN CERTIFICATE-----\nMIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw\nNzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv\nb3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD\nVQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2\nMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F\nVRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1\n7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X\nZ75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+\n/jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs\n81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm\ndtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe\nOh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu\nsDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4\npgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs\nslESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ\narMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD\nVR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG\n9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl\ndxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx\n0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj\nTQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed\nY2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7\nQ4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI\nOylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7\nvVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW\nt88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn\nHL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx\nSK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY=\n-----END CERTIFICATE-----\n\n# Issuer: CN=E-Tugra Certification Authority O=E-Tuğra EBG Bilişim Teknolojileri ve Hizmetleri A.Ş. OU=E-Tugra Sertifikasyon Merkezi\n# Subject: CN=E-Tugra Certification Authority O=E-Tuğra EBG Bilişim Teknolojileri ve Hizmetleri A.Ş. OU=E-Tugra Sertifikasyon Merkezi\n# Label: \"E-Tugra Certification Authority\"\n# Serial: 7667447206703254355\n# MD5 Fingerprint: b8:a1:03:63:b0:bd:21:71:70:8a:6f:13:3a:bb:79:49\n# SHA1 Fingerprint: 51:c6:e7:08:49:06:6e:f3:92:d4:5c:a0:0d:6d:a3:62:8f:c3:52:39\n# SHA256 Fingerprint: b0:bf:d5:2b:b0:d7:d9:bd:92:bf:5d:4d:c1:3d:a2:55:c0:2c:54:2f:37:83:65:ea:89:39:11:f5:5e:55:f2:3c\n-----BEGIN CERTIFICATE-----\nMIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNV\nBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBC\naWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNV\nBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQDDB9FLVR1\nZ3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMwNTEyMDk0OFoXDTIz\nMDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+\nBgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhp\nem1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN\nZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4vU/kwVRHoViVF56C/UY\nB4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vdhQd2h8y/L5VMzH2nPbxH\nD5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5KCKpbknSF\nQ9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEo\nq1+gElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3D\nk14opz8n8Y4e0ypQBaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcH\nfC425lAcP9tDJMW/hkd5s3kc91r0E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsut\ndEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gzrt48Ue7LE3wBf4QOXVGUnhMM\nti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAqjqFGOjGY5RH8\nzLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn\nrFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUX\nU8u3Zg5mTPj5dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6\nJyr+zE7S6E5UMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5\nXPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAF\nNzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAKkEh47U6YA5n+KGCR\nHTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jOXKqY\nGwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c\n77NCR807VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3\n+GbHeJAAFS6LrVE1Uweoa2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WK\nvJUawSg5TB9D0pH0clmKuVb8P7Sd2nCcdlqMQ1DujjByTd//SffGqWfZbawCEeI6\nFiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEVKV0jq9BgoRJP3vQXzTLl\nyb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gTDx4JnW2P\nAJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpD\ny4Q08ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8d\nNL/+I5c30jn6PQ0GC7TbO6Orb1wdtn7os4I07QZcJA==\n-----END CERTIFICATE-----\n\n# Issuer: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center\n# Subject: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center\n# Label: \"T-TeleSec GlobalRoot Class 2\"\n# Serial: 1\n# MD5 Fingerprint: 2b:9b:9e:e4:7b:6c:1f:00:72:1a:cc:c1:77:79:df:6a\n# SHA1 Fingerprint: 59:0d:2d:7d:88:4f:40:2e:61:7e:a5:62:32:17:65:cf:17:d8:94:e9\n# SHA256 Fingerprint: 91:e2:f5:78:8d:58:10:eb:a7:ba:58:73:7d:e1:54:8a:8e:ca:cd:01:45:98:bc:0b:14:3e:04:1b:17:05:25:52\n-----BEGIN CERTIFICATE-----\nMIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx\nKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd\nBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl\nYyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1\nOTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy\naXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50\nZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G\nCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd\nAqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC\nFoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi\n1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq\njnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ\nwI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj\nQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/\nWSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy\nNsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC\nuvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw\nIEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6\ng1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN\n9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP\nBSeOE6Fuwg==\n-----END CERTIFICATE-----\n\n# Issuer: CN=Atos TrustedRoot 2011 O=Atos\n# Subject: CN=Atos TrustedRoot 2011 O=Atos\n# Label: \"Atos TrustedRoot 2011\"\n# Serial: 6643877497813316402\n# MD5 Fingerprint: ae:b9:c4:32:4b:ac:7f:5d:66:cc:77:94:bb:2a:77:56\n# SHA1 Fingerprint: 2b:b1:f5:3e:55:0c:1d:c5:f1:d4:e6:b7:6a:46:4b:55:06:02:ac:21\n# SHA256 Fingerprint: f3:56:be:a2:44:b7:a9:1e:b3:5d:53:ca:9a:d7:86:4a:ce:01:8e:2d:35:d5:f8:f9:6d:df:68:a6:f4:1a:a4:74\n-----BEGIN CERTIFICATE-----\nMIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UE\nAwwVQXRvcyBUcnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQG\nEwJERTAeFw0xMTA3MDcxNDU4MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMM\nFUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMC\nREUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCVhTuXbyo7LjvPpvMp\nNb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr54rM\nVD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+\nSZFhyBH+DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ\n4J7sVaE3IqKHBAUsR320HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0L\ncp2AMBYHlT8oDv3FdU9T1nSatCQujgKRz3bFmx5VdJx4IbHwLfELn8LVlhgf8FQi\neowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7Rl+lwrrw7GWzbITAPBgNV\nHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZbNshMBgG\nA1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3\nDQEBCwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8j\nvZfza1zv7v1Apt+hk6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kP\nDpFrdRbhIfzYJsdHt6bPWHJxfrrhTZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pc\nmaHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a961qn8FYiqTxlVMYVqL2Gns2D\nlmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G3mB/ufNPRJLv\nKrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed\n-----END CERTIFICATE-----\n\n# Issuer: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited\n# Subject: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited\n# Label: \"QuoVadis Root CA 1 G3\"\n# Serial: 687049649626669250736271037606554624078720034195\n# MD5 Fingerprint: a4:bc:5b:3f:fe:37:9a:fa:64:f0:e2:fa:05:3d:0b:ab\n# SHA1 Fingerprint: 1b:8e:ea:57:96:29:1a:c9:39:ea:b8:0a:81:1a:73:73:c0:93:79:67\n# SHA256 Fingerprint: 8a:86:6f:d1:b2:76:b5:7e:57:8e:92:1c:65:82:8a:2b:ed:58:e9:f2:f2:88:05:41:34:b7:f1:f4:bf:c9:cc:74\n-----BEGIN CERTIFICATE-----\nMIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL\nBQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc\nBgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00\nMjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM\naW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG\nSIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV\nwedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe\nrNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341\n68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh\n4Pw5qlPafX7PGglTvF0FBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp\nUhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o\nabw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc\n3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G\nKubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt\nhfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO\nTk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt\nzCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB\nBjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD\nggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC\nMTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2\ncDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN\nqXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5\nYCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv\nb2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2\n8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k\nNSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj\nZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp\nq1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt\nnh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD\n-----END CERTIFICATE-----\n\n# Issuer: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited\n# Subject: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited\n# Label: \"QuoVadis Root CA 2 G3\"\n# Serial: 390156079458959257446133169266079962026824725800\n# MD5 Fingerprint: af:0c:86:6e:bf:40:2d:7f:0b:3e:12:50:ba:12:3d:06\n# SHA1 Fingerprint: 09:3c:61:f3:8b:8b:dc:7d:55:df:75:38:02:05:00:e1:25:f5:c8:36\n# SHA256 Fingerprint: 8f:e4:fb:0a:f9:3a:4d:0d:67:db:0b:eb:b2:3e:37:c7:1b:f3:25:dc:bc:dd:24:0e:a0:4d:af:58:b4:7e:18:40\n-----BEGIN CERTIFICATE-----\nMIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL\nBQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc\nBgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00\nMjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM\naW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG\nSIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf\nqq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW\nn4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym\nc5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+\nO7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1\no9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j\nIaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq\nIcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz\n8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh\nvNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l\n7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG\ncC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB\nBjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD\nggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66\nAarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC\nroijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga\nW/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n\nlv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE\n+V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV\ncsaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd\ndbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg\nKCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM\nHVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4\nWSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M\n-----END CERTIFICATE-----\n\n# Issuer: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited\n# Subject: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited\n# Label: \"QuoVadis Root CA 3 G3\"\n# Serial: 268090761170461462463995952157327242137089239581\n# MD5 Fingerprint: df:7d:b9:ad:54:6f:68:a1:df:89:57:03:97:43:b0:d7\n# SHA1 Fingerprint: 48:12:bd:92:3c:a8:c4:39:06:e7:30:6d:27:96:e6:a4:cf:22:2e:7d\n# SHA256 Fingerprint: 88:ef:81:de:20:2e:b0:18:45:2e:43:f8:64:72:5c:ea:5f:bd:1f:c2:d9:d2:05:73:07:09:c5:d8:b8:69:0f:46\n-----BEGIN CERTIFICATE-----\nMIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL\nBQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc\nBgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00\nMjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM\naW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG\nSIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR\n/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu\nFoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR\nU7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c\nra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR\nFHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k\nA9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw\neyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl\nsSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp\nVzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q\nA4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+\nydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB\nBjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD\nggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px\nKGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI\nFUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv\noxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg\nu/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP\n0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf\n3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl\n8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+\nDhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN\nPlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/\nywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0\n-----END CERTIFICATE-----\n\n# Issuer: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com\n# Subject: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com\n# Label: \"DigiCert Assured ID Root G2\"\n# Serial: 15385348160840213938643033620894905419\n# MD5 Fingerprint: 92:38:b9:f8:63:24:82:65:2c:57:33:e6:fe:81:8f:9d\n# SHA1 Fingerprint: a1:4b:48:d9:43:ee:0a:0e:40:90:4f:3c:e0:a4:c0:91:93:51:5d:3f\n# SHA256 Fingerprint: 7d:05:eb:b6:82:33:9f:8c:94:51:ee:09:4e:eb:fe:fa:79:53:a1:14:ed:b2:f4:49:49:45:2f:ab:7d:2f:c1:85\n-----BEGIN CERTIFICATE-----\nMIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl\nMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\nd3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv\nb3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG\nEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl\ncnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi\nMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA\nn61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc\nbiJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp\nEgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA\nbx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu\nYjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB\nAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW\nBBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI\nQW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I\n0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni\nlmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9\nB5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv\nON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo\nIhNzbM8m9Yop5w==\n-----END CERTIFICATE-----\n\n# Issuer: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com\n# Subject: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com\n# Label: \"DigiCert Assured ID Root G3\"\n# Serial: 15459312981008553731928384953135426796\n# MD5 Fingerprint: 7c:7f:65:31:0c:81:df:8d:ba:3e:99:e2:5c:ad:6e:fb\n# SHA1 Fingerprint: f5:17:a2:4f:9a:48:c6:c9:f8:a2:00:26:9f:dc:0f:48:2c:ab:30:89\n# SHA256 Fingerprint: 7e:37:cb:8b:4c:47:09:0c:ab:36:55:1b:a6:f4:5d:b8:40:68:0f:ba:16:6a:95:2d:b1:00:71:7f:43:05:3f:c2\n-----BEGIN CERTIFICATE-----\nMIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw\nCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu\nZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg\nRzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV\nUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu\nY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq\nhkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf\nZn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q\nRSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/\nBAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD\nAwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY\nJjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv\n6pZjamVFkpUBtA==\n-----END CERTIFICATE-----\n\n# Issuer: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com\n# Subject: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com\n# Label: \"DigiCert Global Root G2\"\n# Serial: 4293743540046975378534879503202253541\n# MD5 Fingerprint: e4:a6:8a:c8:54:ac:52:42:46:0a:fd:72:48:1b:2a:44\n# SHA1 Fingerprint: df:3c:24:f9:bf:d6:66:76:1b:26:80:73:fe:06:d1:cc:8d:4f:82:a4\n# SHA256 Fingerprint: cb:3c:cb:b7:60:31:e5:e0:13:8f:8d:d3:9a:23:f9:de:47:ff:c3:5e:43:c1:14:4c:ea:27:d4:6a:5a:b1:cb:5f\n-----BEGIN CERTIFICATE-----\nMIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh\nMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\nd3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH\nMjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT\nMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j\nb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG\n9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI\n2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx\n1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ\nq2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz\ntCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ\nvIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP\nBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV\n5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY\n1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4\nNeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG\nFdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91\n8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe\npLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl\nMrY=\n-----END CERTIFICATE-----\n\n# Issuer: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com\n# Subject: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com\n# Label: \"DigiCert Global Root G3\"\n# Serial: 7089244469030293291760083333884364146\n# MD5 Fingerprint: f5:5d:a4:50:a5:fb:28:7e:1e:0f:0d:cc:96:57:56:ca\n# SHA1 Fingerprint: 7e:04:de:89:6a:3e:66:6d:00:e6:87:d3:3f:fa:d9:3b:e8:3d:34:9e\n# SHA256 Fingerprint: 31:ad:66:48:f8:10:41:38:c7:38:f3:9e:a4:32:01:33:39:3e:3a:18:cc:02:29:6e:f9:7c:2a:c9:ef:67:31:d0\n-----BEGIN CERTIFICATE-----\nMIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw\nCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu\nZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe\nFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw\nEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x\nIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF\nK4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG\nfp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO\nZ9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd\nBgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx\nAK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/\noAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8\nsycX\n-----END CERTIFICATE-----\n\n# Issuer: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com\n# Subject: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com\n# Label: \"DigiCert Trusted Root G4\"\n# Serial: 7451500558977370777930084869016614236\n# MD5 Fingerprint: 78:f2:fc:aa:60:1f:2f:b4:eb:c9:37:ba:53:2e:75:49\n# SHA1 Fingerprint: dd:fb:16:cd:49:31:c9:73:a2:03:7d:3f:c8:3a:4d:7d:77:5d:05:e4\n# SHA256 Fingerprint: 55:2f:7b:dc:f1:a7:af:9e:6c:e6:72:01:7f:4f:12:ab:f7:72:40:c7:8e:76:1a:c2:03:d1:d9:d2:0a:c8:99:88\n-----BEGIN CERTIFICATE-----\nMIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi\nMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\nd3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg\nRzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV\nUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu\nY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG\nSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y\nithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If\nxp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV\nySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO\nDCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ\njdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/\nCNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi\nEhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM\nfRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY\nuKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK\nchYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t\n9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB\nhjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD\nggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2\nSV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd\n+SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc\nfFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa\nsjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N\ncCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N\n0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie\n4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI\nr/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1\n/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm\ngKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+\n-----END CERTIFICATE-----\n\n# Issuer: CN=Certification Authority of WoSign O=WoSign CA Limited\n# Subject: CN=Certification Authority of WoSign O=WoSign CA Limited\n# Label: \"WoSign\"\n# Serial: 125491772294754854453622855443212256657\n# MD5 Fingerprint: a1:f2:f9:b5:d2:c8:7a:74:b8:f3:05:f1:d7:e1:84:8d\n# SHA1 Fingerprint: b9:42:94:bf:91:ea:8f:b6:4b:e6:10:97:c7:fb:00:13:59:b6:76:cb\n# SHA256 Fingerprint: 4b:22:d5:a6:ae:c9:9f:3c:db:79:aa:5e:c0:68:38:47:9c:d5:ec:ba:71:64:f7:f2:2d:c1:d6:5f:63:d8:57:08\n-----BEGIN CERTIFICATE-----\nMIIFdjCCA16gAwIBAgIQXmjWEXGUY1BWAGjzPsnFkTANBgkqhkiG9w0BAQUFADBV\nMQswCQYDVQQGEwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxKjAoBgNV\nBAMTIUNlcnRpZmljYXRpb24gQXV0aG9yaXR5IG9mIFdvU2lnbjAeFw0wOTA4MDgw\nMTAwMDFaFw0zOTA4MDgwMTAwMDFaMFUxCzAJBgNVBAYTAkNOMRowGAYDVQQKExFX\nb1NpZ24gQ0EgTGltaXRlZDEqMCgGA1UEAxMhQ2VydGlmaWNhdGlvbiBBdXRob3Jp\ndHkgb2YgV29TaWduMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvcqN\nrLiRFVaXe2tcesLea9mhsMMQI/qnobLMMfo+2aYpbxY94Gv4uEBf2zmoAHqLoE1U\nfcIiePyOCbiohdfMlZdLdNiefvAA5A6JrkkoRBoQmTIPJYhTpA2zDxIIFgsDcScc\nf+Hb0v1naMQFXQoOXXDX2JegvFNBmpGN9J42Znp+VsGQX+axaCA2pIwkLCxHC1l2\nZjC1vt7tj/id07sBMOby8w7gLJKA84X5KIq0VC6a7fd2/BVoFutKbOsuEo/Uz/4M\nx1wdC34FMr5esAkqQtXJTpCzWQ27en7N1QhatH/YHGkR+ScPewavVIMYe+HdVHpR\naG53/Ma/UkpmRqGyZxq7o093oL5d//xWC0Nyd5DKnvnyOfUNqfTq1+ezEC8wQjch\nzDBwyYaYD8xYTYO7feUapTeNtqwylwA6Y3EkHp43xP901DfA4v6IRmAR3Qg/UDar\nuHqklWJqbrDKaiFaafPz+x1wOZXzp26mgYmhiMU7ccqjUu6Du/2gd/Tkb+dC221K\nmYo0SLwX3OSACCK28jHAPwQ+658geda4BmRkAjHXqc1S+4RFaQkAKtxVi8QGRkvA\nSh0JWzko/amrzgD5LkhLJuYwTKVYyrREgk/nkR4zw7CT/xH8gdLKH3Ep3XZPkiWv\nHYG3Dy+MwwbMLyejSuQOmbp8HkUff6oZRZb9/D0CAwEAAaNCMEAwDgYDVR0PAQH/\nBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFOFmzw7R8bNLtwYgFP6H\nEtX2/vs+MA0GCSqGSIb3DQEBBQUAA4ICAQCoy3JAsnbBfnv8rWTjMnvMPLZdRtP1\nLOJwXcgu2AZ9mNELIaCJWSQBnfmvCX0KI4I01fx8cpm5o9dU9OpScA7F9dY74ToJ\nMuYhOZO9sxXqT2r09Ys/L3yNWC7F4TmgPsc9SnOeQHrAK2GpZ8nzJLmzbVUsWh2e\nJXLOC62qx1ViC777Y7NhRCOjy+EaDveaBk3e1CNOIZZbOVtXHS9dCF4Jef98l7VN\ng64N1uajeeAz0JmWAjCnPv/So0M/BVoG6kQC2nz4SNAzqfkHx5Xh9T71XXG68pWp\ndIhhWeO/yloTunK0jF02h+mmxTwTv97QRCbut+wucPrXnbes5cVAWubXbHssw1ab\nR80LzvobtCHXt2a49CUwi1wNuepnsvRtrtWhnk/Yn+knArAdBtaP4/tIEp9/EaEQ\nPkxROpaw0RPxx9gmrjrKkcRpnd8BKWRRb2jaFOwIQZeQjdCygPLPwj2/kWjFgGce\nxGATVdVhmVd8upUPYUk6ynW8yQqTP2cOEvIo4jEbwFcW3wh8GcF+Dx+FHgo2fFt+\nJ7x6v+Db9NpSvd4MVHAxkUOVyLzwPt0JfjBkUO1/AaQzZ01oT74V77D2AhGiGxMl\nOtzCWfHjXEa7ZywCRuoeSKbmW9m1vFGikpbbqsY3Iqb+zCB0oy2pLmvLwIIRIbWT\nee5Ehr7XHuQe+w==\n-----END CERTIFICATE-----\n\n# Issuer: CN=CA 沃通根证书 O=WoSign CA Limited\n# Subject: CN=CA 沃通根证书 O=WoSign CA Limited\n# Label: \"WoSign China\"\n# Serial: 106921963437422998931660691310149453965\n# MD5 Fingerprint: 78:83:5b:52:16:76:c4:24:3b:83:78:e8:ac:da:9a:93\n# SHA1 Fingerprint: 16:32:47:8d:89:f9:21:3a:92:00:85:63:f5:a4:a7:d3:12:40:8a:d6\n# SHA256 Fingerprint: d6:f0:34:bd:94:aa:23:3f:02:97:ec:a4:24:5b:28:39:73:e4:47:aa:59:0f:31:0c:77:f4:8f:df:83:11:22:54\n-----BEGIN CERTIFICATE-----\nMIIFWDCCA0CgAwIBAgIQUHBrzdgT/BtOOzNy0hFIjTANBgkqhkiG9w0BAQsFADBG\nMQswCQYDVQQGEwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxGzAZBgNV\nBAMMEkNBIOayg+mAmuagueivgeS5pjAeFw0wOTA4MDgwMTAwMDFaFw0zOTA4MDgw\nMTAwMDFaMEYxCzAJBgNVBAYTAkNOMRowGAYDVQQKExFXb1NpZ24gQ0EgTGltaXRl\nZDEbMBkGA1UEAwwSQ0Eg5rKD6YCa5qC56K+B5LmmMIICIjANBgkqhkiG9w0BAQEF\nAAOCAg8AMIICCgKCAgEA0EkhHiX8h8EqwqzbdoYGTufQdDTc7WU1/FDWiD+k8H/r\nD195L4mx/bxjWDeTmzj4t1up+thxx7S8gJeNbEvxUNUqKaqoGXqW5pWOdO2XCld1\n9AXbbQs5uQF/qvbW2mzmBeCkTVL829B0txGMe41P/4eDrv8FAxNXUDf+jJZSEExf\nv5RxadmWPgxDT74wwJ85dE8GRV2j1lY5aAfMh09Qd5Nx2UQIsYo06Yms25tO4dnk\nUkWMLhQfkWsZHWgpLFbE4h4TV2TwYeO5Ed+w4VegG63XX9Gv2ystP9Bojg/qnw+L\nNVgbExz03jWhCl3W6t8Sb8D7aQdGctyB9gQjF+BNdeFyb7Ao65vh4YOhn0pdr8yb\n+gIgthhid5E7o9Vlrdx8kHccREGkSovrlXLp9glk3Kgtn3R46MGiCWOc76DbT52V\nqyBPt7D3h1ymoOQ3OMdc4zUPLK2jgKLsLl3Az+2LBcLmc272idX10kaO6m1jGx6K\nyX2m+Jzr5dVjhU1zZmkR/sgO9MHHZklTfuQZa/HpelmjbX7FF+Ynxu8b22/8DU0G\nAbQOXDBGVWCvOGU6yke6rCzMRh+yRpY/8+0mBe53oWprfi1tWFxK1I5nuPHa1UaK\nJ/kR8slC/k7e3x9cxKSGhxYzoacXGKUN5AXlK8IrC6KVkLn9YDxOiT7nnO4fuwEC\nAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O\nBBYEFOBNv9ybQV0T6GTwp+kVpOGBwboxMA0GCSqGSIb3DQEBCwUAA4ICAQBqinA4\nWbbaixjIvirTthnVZil6Xc1bL3McJk6jfW+rtylNpumlEYOnOXOvEESS5iVdT2H6\nyAa+Tkvv/vMx/sZ8cApBWNromUuWyXi8mHwCKe0JgOYKOoICKuLJL8hWGSbueBwj\n/feTZU7n85iYr83d2Z5AiDEoOqsuC7CsDCT6eiaY8xJhEPRdF/d+4niXVOKM6Cm6\njBAyvd0zaziGfjk9DgNyp115j0WKWa5bIW4xRtVZjc8VX90xJc/bYNaBRHIpAlf2\nltTW/+op2znFuCyKGo3Oy+dCMYYFaA6eFN0AkLppRQjbbpCBhqcqBT/mhDn4t/lX\nX0ykeVoQDF7Va/81XwVRHmyjdanPUIPTfPRm94KNPQx96N97qA4bLJyuQHCH2u2n\nFoJavjVsIE4iYdm8UXrNemHcSxH5/mc0zy4EZmFcV5cjjPOGG0jfKq+nwf/Yjj4D\nu9gqsPoUJbJRa4ZDhS4HIxaAjUz7tGM7zMN07RujHv41D198HRaG9Q7DlfEvr10l\nO1Hm13ZBONFLAzkopR6RctR9q5czxNM+4Gm2KHmgCY0c0f9BckgG/Jou5yD5m6Le\nie2uPAmvylezkolwQOQvT8Jwg0DXJCxr5wkf09XHwQj02w47HAcLQxGEIYbpgNR1\n2KvxAmLBsX5VYc8T1yaw15zLKYs4SgsOkI26oQ==\n-----END CERTIFICATE-----\n\n# Issuer: CN=COMODO RSA Certification Authority O=COMODO CA Limited\n# Subject: CN=COMODO RSA Certification Authority O=COMODO CA Limited\n# Label: \"COMODO RSA Certification Authority\"\n# Serial: 101909084537582093308941363524873193117\n# MD5 Fingerprint: 1b:31:b0:71:40:36:cc:14:36:91:ad:c4:3e:fd:ec:18\n# SHA1 Fingerprint: af:e5:d2:44:a8:d1:19:42:30:ff:47:9f:e2:f8:97:bb:cd:7a:8c:b4\n# SHA256 Fingerprint: 52:f0:e1:c4:e5:8e:c6:29:29:1b:60:31:7f:07:46:71:b8:5d:7e:a8:0d:5b:07:27:34:63:53:4b:32:b4:02:34\n-----BEGIN CERTIFICATE-----\nMIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB\nhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G\nA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV\nBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5\nMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT\nEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR\nQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh\ndGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR\n6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X\npz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC\n9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV\n/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf\nZd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z\n+pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w\nqP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah\nSL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC\nu9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf\nFobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq\ncrxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E\nFgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB\n/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl\nwFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM\n4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV\n2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna\nFxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ\nCuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK\nboHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke\njkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL\nS0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb\nQOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl\n0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB\nNVOFBkpdn627G190\n-----END CERTIFICATE-----\n\n# Issuer: CN=USERTrust RSA Certification Authority O=The USERTRUST Network\n# Subject: CN=USERTrust RSA Certification Authority O=The USERTRUST Network\n# Label: \"USERTrust RSA Certification Authority\"\n# Serial: 2645093764781058787591871645665788717\n# MD5 Fingerprint: 1b:fe:69:d1:91:b7:19:33:a3:72:a8:0f:e1:55:e5:b5\n# SHA1 Fingerprint: 2b:8f:1b:57:33:0d:bb:a2:d0:7a:6c:51:f7:0e:e9:0d:da:b9:ad:8e\n# SHA256 Fingerprint: e7:93:c9:b0:2f:d8:aa:13:e2:1c:31:22:8a:cc:b0:81:19:64:3b:74:9c:89:89:64:b1:74:6d:46:c3:d4:cb:d2\n-----BEGIN CERTIFICATE-----\nMIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB\niDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl\ncnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV\nBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw\nMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV\nBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU\naGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy\ndGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK\nAoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B\n3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY\ntJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/\nFp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2\nVN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT\n79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6\nc0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT\nYo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l\nc6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee\nUB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE\nHg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd\nBgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G\nA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF\nUp/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO\nVWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3\nATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs\n8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR\niQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze\nSf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ\nXHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/\nqS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB\nVXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB\nL6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG\njjxDah2nGN59PRbxYvnKkKj9\n-----END CERTIFICATE-----\n\n# Issuer: CN=USERTrust ECC Certification Authority O=The USERTRUST Network\n# Subject: CN=USERTrust ECC Certification Authority O=The USERTRUST Network\n# Label: \"USERTrust ECC Certification Authority\"\n# Serial: 123013823720199481456569720443997572134\n# MD5 Fingerprint: fa:68:bc:d9:b5:7f:ad:fd:c9:1d:06:83:28:cc:24:c1\n# SHA1 Fingerprint: d1:cb:ca:5d:b2:d5:2a:7f:69:3b:67:4d:e5:f0:5a:1d:0c:95:7d:f0\n# SHA256 Fingerprint: 4f:f4:60:d5:4b:9c:86:da:bf:bc:fc:57:12:e0:40:0d:2b:ed:3f:bc:4d:4f:bd:aa:86:e0:6a:dc:d2:a9:ad:7a\n-----BEGIN CERTIFICATE-----\nMIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL\nMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl\neSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT\nJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx\nMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT\nCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg\nVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm\naWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo\nI+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng\no4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G\nA1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD\nVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB\nzzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW\nRNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg=\n-----END CERTIFICATE-----\n\n# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4\n# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4\n# Label: \"GlobalSign ECC Root CA - R4\"\n# Serial: 14367148294922964480859022125800977897474\n# MD5 Fingerprint: 20:f0:27:68:d1:7e:a0:9d:0e:e6:2a:ca:df:5c:89:8e\n# SHA1 Fingerprint: 69:69:56:2e:40:80:f4:24:a1:e7:19:9f:14:ba:f3:ee:58:ab:6a:bb\n# SHA256 Fingerprint: be:c9:49:11:c2:95:56:76:db:6c:0a:55:09:86:d7:6e:3b:a0:05:66:7c:44:2c:97:62:b4:fb:b7:73:de:22:8c\n-----BEGIN CERTIFICATE-----\nMIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk\nMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH\nbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX\nDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD\nQSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ\nFspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw\nDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F\nuOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX\nkPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs\newv4n4Q=\n-----END CERTIFICATE-----\n\n# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5\n# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5\n# Label: \"GlobalSign ECC Root CA - R5\"\n# Serial: 32785792099990507226680698011560947931244\n# MD5 Fingerprint: 9f:ad:3b:1c:02:1e:8a:ba:17:74:38:81:0c:a2:bc:08\n# SHA1 Fingerprint: 1f:24:c6:30:cd:a4:18:ef:20:69:ff:ad:4f:dd:5f:46:3a:1b:69:aa\n# SHA256 Fingerprint: 17:9f:bc:14:8a:3d:d0:0f:d2:4e:a1:34:58:cc:43:bf:a7:f5:9c:81:82:d7:83:a5:13:f6:eb:ec:10:0c:89:24\n-----BEGIN CERTIFICATE-----\nMIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk\nMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH\nbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX\nDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD\nQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu\nMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc\n8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke\nhOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD\nVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI\nKoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg\n515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO\nxwy8p2Fp8fc74SrL+SvzZpA3\n-----END CERTIFICATE-----\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/cli.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhyper/cli\n~~~~~~~~~\n\nCommand line interface for Hyper inspired by Httpie.\n\"\"\"\nimport json\nimport locale\nimport logging\nimport sys\nfrom argparse import ArgumentParser, RawTextHelpFormatter\nfrom argparse import OPTIONAL, ZERO_OR_MORE\nfrom pprint import pformat\nfrom textwrap import dedent\n\nfrom hyper import HTTPConnection, HTTP20Connection\nfrom hyper import __version__\nfrom hyper.compat import is_py2, urlencode, urlsplit, write_to_stdout\nfrom hyper.common.util import to_host_port_tuple\n\n\nlog = logging.getLogger('hyper')\n\nPREFERRED_ENCODING = locale.getpreferredencoding()\n\n# Various separators used in args\nSEP_HEADERS = ':'\nSEP_QUERY = '=='\nSEP_DATA = '='\n\nSEP_GROUP_ITEMS = [\n    SEP_HEADERS,\n    SEP_QUERY,\n    SEP_DATA,\n]\n\n\nclass KeyValue(object):\n    \"\"\"Base key-value pair parsed from CLI.\"\"\"\n\n    def __init__(self, key, value, sep, orig):\n        self.key = key\n        self.value = value\n        self.sep = sep\n        self.orig = orig\n\n\nclass KeyValueArgType(object):\n    \"\"\"A key-value pair argument type used with `argparse`.\n\n    Parses a key-value arg and constructs a `KeyValue` instance.\n    Used for headers, form data, and other key-value pair types.\n    This class is inspired by httpie and implements simple tokenizer only.\n    \"\"\"\n    def __init__(self, *separators):\n        self.separators = separators\n\n    def __call__(self, string):\n        for sep in self.separators:\n            splitted = string.split(sep, 1)\n            if len(splitted) == 2:\n                key, value = splitted\n                return KeyValue(key, value, sep, string)\n\n\ndef make_positional_argument(parser):\n    parser.add_argument(\n        'method', metavar='METHOD', nargs=OPTIONAL, default='GET',\n        help=dedent(\"\"\"\n        The HTTP method to be used for the request\n        (GET, POST, PUT, DELETE, ...).\n        \"\"\"))\n    parser.add_argument(\n        '_url', metavar='URL',\n        help=dedent(\"\"\"\n        The scheme defaults to 'https://' if the URL does not include one.\n        \"\"\"))\n    parser.add_argument(\n        'items',\n        metavar='REQUEST_ITEM',\n        nargs=ZERO_OR_MORE,\n        type=KeyValueArgType(*SEP_GROUP_ITEMS),\n        help=dedent(\"\"\"\n        Optional key-value pairs to be included in the request.\n        The separator used determines the type:\n\n        ':' HTTP headers:\n\n            Referer:http://httpie.org  Cookie:foo=bar  User-Agent:bacon/1.0\n\n        '==' URL parameters to be appended to the request URI:\n\n            search==hyper\n\n        '=' Data fields to be serialized into a JSON object:\n\n            name=Hyper  language=Python  description='CLI HTTP client'\n        \"\"\"))\n\n\ndef make_troubleshooting_argument(parser):\n    parser.add_argument(\n        '--version', action='version', version=__version__,\n        help='Show version and exit.')\n    parser.add_argument(\n        '--debug', action='store_true', default=False,\n        help='Show debugging information (loglevel=DEBUG)')\n    parser.add_argument(\n        '--h2', action='store_true', default=False,\n        help=\"Do HTTP/2 directly in plaintext: skip plaintext upgrade\")\n\n\ndef set_url_info(args):\n    def split_host_and_port(hostname):\n        if ':' in hostname:\n            return to_host_port_tuple(hostname, default_port=443)\n        return hostname, None\n\n    class UrlInfo(object):\n        def __init__(self):\n            self.fragment = None\n            self.host = 'localhost'\n            self.netloc = None\n            self.path = '/'\n            self.port = 443\n            self.query = None\n            self.scheme = 'https'\n            self.secure = False\n\n    info = UrlInfo()\n    _result = urlsplit(args._url)\n    for attr in list(vars(info).keys()):\n        value = getattr(_result, attr, None)\n        if value:\n            setattr(info, attr, value)\n\n    if info.scheme == 'http' and not _result.port:\n        info.port = 80\n\n    # Set the secure arg is the scheme is HTTPS, otherwise do unsecured.\n    info.secure = info.scheme == 'https'\n\n    if info.netloc:\n        hostname, _ = split_host_and_port(info.netloc)\n        info.host = hostname  # ensure stripping port number\n    else:\n        if _result.path:\n            _path = _result.path.split('/', 1)\n            hostname, port = split_host_and_port(_path[0])\n            info.host = hostname\n            if info.path == _path[0]:\n                info.path = '/'\n            elif len(_path) == 2 and _path[1]:\n                info.path = '/' + _path[1]\n            if port is not None:\n                info.port = port\n\n    log.debug('Url Info: %s', vars(info))\n    args.url = info\n\n\ndef set_request_data(args):\n    body, headers, params = {}, {}, {}\n    for i in args.items:\n        if i.sep == SEP_HEADERS:\n            if i.key:\n                headers[i.key] = i.value\n            else:\n                # when overriding a HTTP/2 special header there will be a leading \n                # colon, which tricks the command line parser into thinking \n                # the header is empty\n                k, v = i.value.split(':', 1)\n                headers[':' + k] = v\n        elif i.sep == SEP_QUERY:\n            params[i.key] = i.value\n        elif i.sep == SEP_DATA:\n            value = i.value\n            if is_py2:  # pragma: no cover\n                value = value.decode(PREFERRED_ENCODING)\n            body[i.key] = value\n\n    if params:\n        args.url.path += '?' + urlencode(params)\n\n    if body:\n        content_type = 'application/json'\n        headers.setdefault('content-type', content_type)\n        args.body = json.dumps(body)\n\n    if args.method is None:\n        args.method = 'POST' if args.body else 'GET'\n\n    args.headers = headers\n\n\ndef parse_argument(argv=None):\n    parser = ArgumentParser(formatter_class=RawTextHelpFormatter)\n    parser.set_defaults(body=None, headers={})\n    make_positional_argument(parser)\n    make_troubleshooting_argument(parser)\n    args = parser.parse_args(sys.argv[1:] if argv is None else argv)\n\n    if args.debug:\n        handler = logging.StreamHandler()\n        handler.setLevel(logging.DEBUG)\n        log.addHandler(handler)\n        log.setLevel(logging.DEBUG)\n\n    set_url_info(args)\n    set_request_data(args)\n    return args\n\n\ndef get_content_type_and_charset(response):\n    charset = 'utf-8'\n    content_type = response.headers.get('content-type')\n    if content_type is None:\n        return 'unknown', charset\n\n    content_type = content_type[0].decode('utf-8').lower()\n    type_and_charset = content_type.split(';', 1)\n    ctype = type_and_charset[0].strip()\n    if len(type_and_charset) == 2:\n        charset = type_and_charset[1].strip().split('=')[1]\n\n    return ctype, charset\n\n\ndef request(args):\n    if not args.h2:\n        conn = HTTPConnection(\n            args.url.host, args.url.port, secure=args.url.secure\n        )\n    else:  # pragma: no cover\n        conn = HTTP20Connection(\n            args.url.host, args.url.port, secure=args.url.secure\n        )\n\n    conn.request(args.method, args.url.path, args.body, args.headers)\n    response = conn.get_response()\n    log.debug('Response Headers:\\n%s', pformat(response.headers))\n    ctype, charset = get_content_type_and_charset(response)\n    data = response.read()\n    return data\n\n\ndef main(argv=None):\n    args = parse_argument(argv)\n    log.debug('Commandline Argument: %s', args)\n    data = request(args)\n    write_to_stdout(data)\n\n\nif __name__ == '__main__':  # pragma: no cover\n    main()\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/common/__init__.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhyper/common\n~~~~~~~~~~~~\n\nCommon code in hyper.\n\"\"\"\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/common/bufsocket.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhyper/http20/bufsocket.py\n~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThis file implements a buffered socket wrapper.\n\nThe purpose of this is to avoid the overhead of unnecessary syscalls while\nallowing small reads from the network. This represents a potentially massive\nperformance optimisation at the cost of burning some memory in the userspace\nprocess.\n\"\"\"\nimport selectors2 as selectors\nimport socket\nfrom .exceptions import ConnectionResetError, LineTooLongError\n# import logging\n# logger = logging.getLogger()\n# logger.setLevel(logging.DEBUG)\n\n\nclass WriteBuffer(object):\n    def __init__(self, s=None):\n        if isinstance(s, bytes):\n            self.string_len = len(s)\n            self.buffer_list = [s]\n        elif isinstance(s, str):\n            self.string_len = len(s)\n            self.buffer_list = [bytes(s)]\n        else:\n            self.reset()\n\n    def reset(self):\n        self.buffer_list = []\n        self.string_len = 0\n\n    def __len__(self):\n        return self.string_len\n\n    def __add__(self, other):\n        self.append(other)\n        return self\n\n    def insert(self, s):\n        if isinstance(s, WriteBuffer):\n            self.buffer_list = s.buffer_list + self.buffer_list\n            self.string_len += s.string_len\n        elif isinstance(s, str):\n            self.buffer_list.insert(0, s)\n            self.string_len += len(s)\n        else:\n            raise Exception(\"WriteBuffer append not string or StringBuffer\")\n\n    def append(self, s):\n        if isinstance(s, WriteBuffer):\n            self.buffer_list.extend(s.buffer_list)\n            self.string_len += s.string_len\n        elif isinstance(s, bytes):\n            self.buffer_list.append(s)\n            self.string_len += len(s)\n        else:\n            raise Exception(\"WriteBuffer append not string or StringBuffer\")\n\n    def __str__(self):\n        return self.get_string()\n\n    def get_string(self):\n        return b\"\".join(self.buffer_list)\n\n\nclass BufferedSocket(object):\n    \"\"\"\n    A buffered socket wrapper.\n\n    The purpose of this is to avoid the overhead of unnecessary syscalls while\n    allowing small reads from the network. This represents a potentially\n    massive performance optimisation at the cost of burning some memory in the\n    userspace process.\n    \"\"\"\n    def __init__(self, sck, buffer_size=1000):\n        \"\"\"\n        Create the buffered socket.\n\n        :param sck: The socket to wrap.\n        :param buffer_size: The size of the backing buffer in bytes. This\n            parameter should be set to an appropriate value for your use case.\n            Small values of ``buffer_size`` increase the overhead of buffer\n            management: large values cause more memory to be used.\n        \"\"\"\n        # The wrapped socket.\n        self._sck = sck\n        self.select2 = selectors.DefaultSelector()\n        self.select2.register(sck, selectors.EVENT_READ)\n\n        # The buffer we're using.\n        self._backing_buffer = bytearray(buffer_size)\n        self._buffer_view = memoryview(self._backing_buffer)\n\n        # The size of the buffer.\n        self._buffer_size = buffer_size\n\n        # The start index in the memory view.\n        self._index = 0\n\n        # The number of bytes in the buffer.\n        self._bytes_in_buffer = 0\n\n        # record all bytes received from beginning\n        self.bytes_received = 0\n\n        # following is define for send buffer\n        # all send will be cache and send when flush called,\n        # combine data to reduce the api call\n        self.send_buffer = WriteBuffer()\n\n    def send(self, buf, flush=True):\n        self.send_buffer.append(buf)\n\n        if len(self.send_buffer) > 1300 or flush:\n            self.flush()\n\n    def flush(self):\n        if len(self.send_buffer):\n            data = self.send_buffer.get_string()\n            # logger.debug(\"buffer socket flush:%d\", len(data))\n            self.send_buffer.reset()\n\n            data_len = len(data)\n            start = 0\n            while start < data_len:\n                send_size = min(data_len - start, 65535)\n                sended = self._sck.send(data[start:start+send_size])\n                start += sended\n\n    @property\n    def _remaining_capacity(self):\n        \"\"\"\n        The maximum number of bytes the buffer could still contain.\n        \"\"\"\n        return self._buffer_size - self._index\n\n    @property\n    def _buffer_end(self):\n        \"\"\"\n        The index of the first free byte in the buffer.\n        \"\"\"\n        return self._index + self._bytes_in_buffer\n\n    @property\n    def can_read(self):\n        \"\"\"\n        Whether or not there is more data to read from the socket.\n        \"\"\"\n        if self._bytes_in_buffer:\n            return True\n\n        events = self.select2.select(timeout=0)\n        for key, event in events:\n            if event & selectors.EVENT_READ:\n                return True\n\n        return False\n\n    @property\n    def buffer(self):\n        \"\"\"\n        Get access to the buffer itself.\n        \"\"\"\n        return self._buffer_view[self._index:self._buffer_end]\n\n    def advance_buffer(self, count):\n        \"\"\"\n        Advances the buffer by the amount of data consumed outside the socket.\n        \"\"\"\n        self._index += count\n        self._bytes_in_buffer -= count\n\n    def new_buffer(self):\n        \"\"\"\n        This method moves all the data in the backing buffer to the start of\n        a new, fresh buffer. This gives the ability to read much more data.\n        \"\"\"\n        def read_all_from_buffer():\n            end = self._index + self._bytes_in_buffer\n            return self._buffer_view[self._index:end]\n\n        new_buffer = bytearray(self._buffer_size)\n        new_buffer_view = memoryview(new_buffer)\n        new_buffer_view[0:self._bytes_in_buffer] = read_all_from_buffer()\n\n        self._index = 0\n        self._backing_buffer = new_buffer\n        self._buffer_view = new_buffer_view\n\n        return\n\n    def recv(self, amt):\n        \"\"\"\n        Read some data from the socket.\n\n        :param amt: The amount of data to read.\n        :returns: A ``memoryview`` object containing the appropriate number of\n            bytes. The data *must* be copied out by the caller before the next\n            call to this function.\n        \"\"\"\n        # In this implementation you can never read more than the number of\n        # bytes in the buffer.\n        if amt > self._buffer_size:\n            amt = self._buffer_size\n\n        # If the amount of data we've been asked to read is less than the\n        # remaining space in the buffer, we need to clear out the buffer and\n        # start over.\n        if amt > self._remaining_capacity:\n            self.new_buffer()\n\n        # If there's still some room in the buffer, opportunistically attempt\n        # to read into it.\n        # If we don't actually _need_ the data (i.e. there's enough in the\n        # buffer to satisfy the request), use select to work out if the read\n        # attempt will block. If it will, don't bother reading. If we need the\n        # data, always do the read.\n        if self._bytes_in_buffer >= amt:\n            should_read = False\n            events = self.select2.select(timeout=0)\n            for key, event in events:\n                if event & selectors.EVENT_READ:\n                    should_read = True\n        else:\n            should_read = True\n\n        if ((self._remaining_capacity > self._bytes_in_buffer) and (should_read)):\n            while True:\n                count = 0\n                try:\n                    count = self._sck.recv_into(self._buffer_view[self._buffer_end:])\n                    break\n                except socket.error as e:\n                    if e.errno in [2, 11, 35, 10035]:\n                        if self._bytes_in_buffer >= amt:\n                            # It is not necessary to read, just continue\n                            break\n                        else:\n                            self.select2.select(timeout=10)\n                            continue\n                    else:\n                        raise e\n\n            # The socket just got closed. We should throw an exception if we\n            # were asked for more data than we can return.\n            if not count and amt > self._bytes_in_buffer:\n                raise ConnectionResetError()\n            self._bytes_in_buffer += count\n            self.bytes_received += count\n\n        # Read out the bytes and update the index.\n        amt = min(amt, self._bytes_in_buffer)\n        data = self._buffer_view[self._index:self._index+amt]\n\n        self._index += amt\n        self._bytes_in_buffer -= amt\n\n        return data\n\n    def recv_into(self, buf, nbytes):\n        if self._bytes_in_buffer >= nbytes:\n            buf[:] = self._buffer_view[self._index:self._index+nbytes]\n            self._index += nbytes\n            self._bytes_in_buffer -= nbytes\n            return nbytes\n\n        if self._bytes_in_buffer:\n            buf[:self._bytes_in_buffer] = self._buffer_view[self._index:self._index+self._bytes_in_buffer]\n            p = self._bytes_in_buffer\n            nbytes -= self._bytes_in_buffer\n            self._index = 0\n            self._bytes_in_buffer = 0\n        else:\n            p = 0\n\n        return self._sck.recv_into(buf[p:], nbytes)\n\n    def fill(self):\n        \"\"\"\n        Attempts to fill the buffer as much as possible. It will block for at\n        most the time required to have *one* ``recv_into`` call return.\n        \"\"\"\n        if not self._remaining_capacity:\n            self.new_buffer()\n\n        count = self._sck.recv_into(self._buffer_view[self._buffer_end:])\n        if not count:\n            raise ConnectionResetError()\n\n        self._bytes_in_buffer += count\n\n        return\n\n    def readline(self):\n        \"\"\"\n        Read up to a newline from the network and returns it. The implicit\n        maximum line length is the buffer size of the buffered socket.\n\n        Note that, unlike recv, this method absolutely *does* block until it\n        can read the line.\n\n        :returns: A ``memoryview`` object containing the appropriate number of\n            bytes. The data *must* be copied out by the caller before the next\n            call to this function.\n        \"\"\"\n        # First, check if there's anything in the buffer. This is one of those\n        # rare circumstances where this will work correctly on all platforms.\n        index = self._backing_buffer.find(\n            b'\\n',\n            self._index,\n            self._index + self._bytes_in_buffer\n        )\n\n        if index != -1:\n            length = index + 1 - self._index\n            data = self._buffer_view[self._index:self._index+length]\n            self._index += length\n            self._bytes_in_buffer -= length\n            return data\n\n        # In this case, we didn't find a newline in the buffer. To fix that,\n        # read some data into the buffer. To do our best to satisfy the read,\n        # we should shunt the data down in the buffer so that it's right at\n        # the start. We don't bother if we're already at the start of the\n        # buffer.\n        if self._index != 0:\n            self.new_buffer()\n\n        while self._bytes_in_buffer < self._buffer_size:\n            count = self._sck.recv_into(self._buffer_view[self._buffer_end:])\n            if not count:\n                raise ConnectionResetError()\n\n            # We have some more data. Again, look for a newline in that gap.\n            first_new_byte = self._buffer_end\n            self._bytes_in_buffer += count\n            index = self._backing_buffer.find(\n                b'\\n',\n                first_new_byte,\n                first_new_byte + count,\n            )\n\n            if index != -1:\n                # The length of the buffer is the index into the\n                # buffer at which we found the newline plus 1, minus the start\n                # index of the buffer, which really should be zero.\n                assert not self._index\n                length = index + 1\n                data = self._buffer_view[:length]\n                self._index += length\n                self._bytes_in_buffer -= length\n                return data\n\n        # If we got here, it means we filled the buffer without ever getting\n        # a newline. Time to throw an exception.\n        raise LineTooLongError()\n\n    def __getattr__(self, name):\n        return getattr(self._sck, name)\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/common/connection.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhyper/common/connection\n~~~~~~~~~~~~~~~~~~~~~~~\n\nHyper's HTTP/1.1 and HTTP/2 abstraction layer.\n\"\"\"\nfrom .exceptions import TLSUpgrade, HTTPUpgrade\nfrom ..http11.connection import HTTP11Connection\nfrom ..http20.connection import HTTP20Connection\nfrom ..tls import H2_NPN_PROTOCOLS, H2C_PROTOCOL\n\nclass HTTPConnection(object):\n    \"\"\"\n    An object representing a single HTTP connection to a server.\n\n    This object behaves similarly to the Python standard library's\n    ``HTTPConnection`` object, with a few critical differences.\n\n    Most of the standard library's arguments to the constructor are not\n    supported by hyper. Most optional parameters apply to *either* HTTP/1.1 or\n    HTTP/2.\n\n    :param host: The host to connect to. This may be an IP address or a\n        hostname, and optionally may include a port: for example,\n        ``'http2bin.org'``, ``'http2bin.org:443'`` or ``'127.0.0.1'``.\n    :param port: (optional) The port to connect to. If not provided and one also\n        isn't provided in the ``host`` parameter, defaults to 443.\n    :param secure: (optional) Whether the request should use TLS.\n        Defaults to ``False`` for most requests, but to ``True`` for any\n        request issued to port 443.\n    :param window_manager: (optional) The class to use to manage flow control\n        windows. This needs to be a subclass of the\n        :class:`BaseFlowControlManager <hyper.http20.window.BaseFlowControlManager>`.\n        If not provided,\n        :class:`FlowControlManager <hyper.http20.window.FlowControlManager>`\n        will be used.\n    :param enable_push: (optional) Whether the server is allowed to push\n        resources to the client (see\n        :meth:`get_pushes() <hyper.HTTP20Connection.get_pushes>`).\n    :param ssl_context: (optional) A class with custom certificate settings.\n        If not provided then hyper's default ``SSLContext`` is used instead.\n    :param proxy_host: (optional) The proxy to connect to.  This can be an IP address\n        or a host name and may include a port.\n    :param proxy_port: (optional) The proxy port to connect to. If not provided \n        and one also isn't provided in the ``proxy`` parameter, defaults to 8080.\n    \"\"\"\n    def __init__(self,\n                 host,\n                 port=None,\n                 secure=None,\n                 window_manager=None,\n                 enable_push=False,\n                 ssl_context=None,\n                 proxy_host=None,\n                 proxy_port=None,\n                 **kwargs):\n\n        self._host = host\n        self._port = port\n        self._h1_kwargs = {\n            'secure': secure, 'ssl_context': ssl_context, \n            'proxy_host': proxy_host, 'proxy_port': proxy_port \n        }\n        self._h2_kwargs = {\n            'window_manager': window_manager, 'enable_push': enable_push,\n            'secure': secure, 'ssl_context': ssl_context, \n            'proxy_host': proxy_host, 'proxy_port': proxy_port\n        }\n\n        # Add any unexpected kwargs to both dictionaries.\n        self._h1_kwargs.update(kwargs)\n        self._h2_kwargs.update(kwargs)\n\n        self._conn = HTTP11Connection(\n            self._host, self._port, **self._h1_kwargs\n        )\n\n    def request(self, method, url, body=None, headers={}):\n        \"\"\"\n        This will send a request to the server using the HTTP request method\n        ``method`` and the selector ``url``. If the ``body`` argument is\n        present, it should be string or bytes object of data to send after the\n        headers are finished. Strings are encoded as UTF-8. To use other\n        encodings, pass a bytes object. The Content-Length header is set to the\n        length of the body field.\n\n        :param method: The request method, e.g. ``'GET'``.\n        :param url: The URL to contact, e.g. ``'/path/segment'``.\n        :param body: (optional) The request body to send. Must be a bytestring\n            or a file-like object.\n        :param headers: (optional) The headers to send on the request.\n        :returns: A stream ID for the request, or ``None`` if the request is\n            made over HTTP/1.1.\n        \"\"\"\n        try:\n            return self._conn.request(\n                method=method, url=url, body=body, headers=headers\n            )\n        except TLSUpgrade as e:\n            # We upgraded in the NPN/ALPN handshake. We can just go straight to\n            # the world of HTTP/2. Replace the backing object and insert the\n            # socket into it.\n            assert e.negotiated in H2_NPN_PROTOCOLS\n\n            self._conn = HTTP20Connection(\n                self._host, self._port, **self._h2_kwargs\n            )\n            self._conn._sock = e.sock\n\n            # Because we skipped the connecting logic, we need to send the\n            # HTTP/2 preamble.\n            self._conn._send_preamble()\n\n            return self._conn.request(\n                method=method, url=url, body=body, headers=headers\n            )\n\n    def get_response(self, *args, **kwargs):\n        \"\"\"\n        Returns a response object.\n        \"\"\"\n        try:\n            return self._conn.get_response(*args, **kwargs)\n        except HTTPUpgrade as e:\n            # We upgraded via the HTTP Upgrade mechanism. We can just\n            # go straight to the world of HTTP/2. Replace the backing object\n            # and insert the socket into it.\n            assert e.negotiated == H2C_PROTOCOL\n\n            self._conn = HTTP20Connection(\n                self._host, self._port, **self._h2_kwargs\n            )\n\n            self._conn._sock = e.sock\n            # stream id 1 is used by the upgrade request and response\n            # and is half-closed by the client\n            self._conn._new_stream(stream_id=1, local_closed=True)\n\n            # HTTP/2 preamble must be sent after receipt of a HTTP/1.1 101\n            self._conn._send_preamble()\n\n            return self._conn.get_response(1)\n\n    # The following two methods are the implementation of the context manager\n    # protocol.\n    def __enter__(self):  # pragma: no cover\n        return self\n\n    def __exit__(self, type, value, tb):  # pragma: no cover\n        self._conn.close()\n        return False  # Never swallow exceptions.\n\n    # Can anyone say 'proxy object pattern'?\n    def __getattr__(self, name):\n        return getattr(self._conn, name)\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/common/decoder.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhyper/common/decoder\n~~~~~~~~~~~~~~~~~~~~\n\nContains hyper's code for handling compressed bodies.\n\"\"\"\nimport zlib\n\n\nclass DeflateDecoder(object):\n    \"\"\"\n    This is a decoding object that wraps ``zlib`` and is used for decoding\n    deflated content.\n\n    This rationale for the existence of this object is pretty unpleasant.\n    The HTTP RFC specifies that 'deflate' is a valid content encoding. However,\n    the spec _meant_ the zlib encoding form. Unfortunately, people who didn't\n    read the RFC very carefully actually implemented a different form of\n    'deflate'. Insanely, ``zlib`` handles them using two wbits values. This is\n    such a mess it's hard to adequately articulate.\n\n    This class was lovingly borrowed from the excellent urllib3 library under\n    license: see NOTICES. If you ever see @shazow, you should probably buy him\n    a drink or something.\n    \"\"\"\n    def __init__(self):\n        self._first_try = True\n        self._data = b''\n        self._obj = zlib.decompressobj(zlib.MAX_WBITS)\n\n    def __getattr__(self, name):\n        return getattr(self._obj, name)\n\n    def decompress(self, data):\n        if not self._first_try:\n            return self._obj.decompress(data)\n\n        self._data += data\n        try:\n            return self._obj.decompress(data)\n        except zlib.error:\n            self._first_try = False\n            self._obj = zlib.decompressobj(-zlib.MAX_WBITS)\n            try:\n                return self.decompress(self._data)\n            finally:\n                self._data = None\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/common/exceptions.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhyper/common/exceptions\n~~~~~~~~~~~~~~~~~~~~~~~\n\nContains hyper's exceptions.\n\"\"\"\nclass ChunkedDecodeError(Exception):\n    \"\"\"\n    An error was encountered while decoding a chunked response.\n    \"\"\"\n    pass\n\n\nclass InvalidResponseError(Exception):\n    \"\"\"\n    A problem was found with the response that makes it invalid.\n    \"\"\"\n    pass\n\n\nclass SocketError(Exception):\n    \"\"\"\n    An error occurred during socket operation.\n    \"\"\"\n    pass\n\n\nclass LineTooLongError(Exception):\n    \"\"\"\n    An attempt to read a line from a socket failed because no newline was\n    found.\n    \"\"\"\n    pass\n\n\n# Create our own ConnectionResetError.\ntry:  # pragma: no cover\n    ConnectionResetError = ConnectionResetError\nexcept NameError:  # pragma: no cover\n    class ConnectionResetError(BaseException):\n        \"\"\"\n        A HTTP connection was unexpectedly reset.\n        \"\"\"\n\nclass TLSUpgrade(Exception):\n    \"\"\"\n    We upgraded to a new protocol in the NPN/ALPN handshake.\n    \"\"\"\n    def __init__(self, negotiated, sock):\n        super(TLSUpgrade, self).__init__()\n        self.negotiated = negotiated\n        self.sock = sock\n\nclass HTTPUpgrade(Exception):\n    \"\"\"\n    We upgraded to a new protocol via the HTTP Upgrade response.\n    \"\"\"\n    def __init__(self, negotiated, sock):\n        super(HTTPUpgrade, self).__init__()\n        self.negotiated = negotiated\n        self.sock = sock\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/common/headers.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhyper/common/headers\n~~~~~~~~~~~~~~~~~~~~~\n\nContains hyper's structures for storing and working with HTTP headers.\n\"\"\"\ntry:\n    from collections import MutableMapping\nexcept:\n    from collections.abc import MutableMapping\n\n\nfrom hyper.common.util import to_bytestring, to_bytestring_tuple\n\n\nclass HTTPHeaderMap(MutableMapping):\n    \"\"\"\n    A structure that contains HTTP headers.\n\n    HTTP headers are a curious beast. At the surface level they look roughly\n    like a name-value set, but in practice they have many variations that\n    make them tricky:\n\n    - duplicate keys are allowed\n    - keys are compared case-insensitively\n    - duplicate keys are isomorphic to comma-separated values, *except when\n      they aren't*!\n    - they logically contain a form of ordering\n\n    This data structure is an attempt to preserve all of that information\n    while being as user-friendly as possible. It retains all of the mapping\n    convenience methods (allowing by-name indexing), while avoiding using a\n    dictionary for storage.\n\n    When iterated over, this structure returns headers in 'canonical form'.\n    This form is a tuple, where the first entry is the header name (in\n    lower-case), and the second entry is a list of header values (in original\n    case).\n\n    The mapping always emits both names and values in the form of bytestrings:\n    never unicode strings. It can accept names and values in unicode form, and\n    will automatically be encoded to bytestrings using UTF-8. The reason for\n    what appears to be a user-unfriendly decision here is primarily to allow\n    the broadest-possible compatibility (to make it possible to send headers in\n    unusual encodings) while ensuring that users are never confused about what\n    type of data they will receive.\n\n    .. warning:: Note that this data structure makes none of the performance\n                 guarantees of a dictionary. Lookup and deletion is not an O(1)\n                 operation. Inserting a new value *is* O(1), all other\n                 operations are O(n), including *replacing* a header entirely.\n    \"\"\"\n    def __init__(self, *args, **kwargs):\n        # The meat of the structure. In practice, headers are an ordered list\n        # of tuples. This early version of the data structure simply uses this\n        # directly under the covers.\n        #\n        # An important curiosity here is that the headers are not stored in\n        # 'canonical form', but are instead stored in the form they were\n        # provided in. This is to ensure that it is always possible to\n        # reproduce the original header structure if necessary. This leads to\n        # some unfortunate performance costs on structure access where it is\n        # often necessary to transform the data into canonical form on access.\n        # This cost is judged acceptable in low-level code like `hyper`, but\n        # higher-level abstractions should consider if they really require this\n        # logic.\n        self._items = []\n\n        for arg in args:\n            self._items.extend([to_bytestring_tuple(*x) for x in arg])\n\n        for k, v in list(kwargs.items()):\n            self._items.append(to_bytestring_tuple(k, v))\n\n    def __getitem__(self, key):\n        \"\"\"\n        Unlike the dict __getitem__, this returns a list of items in the order\n        they were added. These items are returned in 'canonical form', meaning\n        that comma-separated values are split into multiple values.\n        \"\"\"\n        key = to_bytestring(key)\n        values = []\n\n        for k, v in self._items:\n            if _keys_equal(k, key):\n                values.extend(x[1] for x in canonical_form(k, v))\n\n        if not values:\n            raise KeyError(\"Nonexistent header key: {}\".format(key))\n\n        return values\n\n    def __setitem__(self, key, value):\n        \"\"\"\n        Unlike the dict __setitem__, this appends to the list of items.\n        \"\"\"\n        self._items.append(to_bytestring_tuple(key, value))\n\n    def __delitem__(self, key):\n        \"\"\"\n        Sadly, __delitem__ is kind of stupid here, but the best we can do is\n        delete all headers with a given key. To correctly achieve the 'KeyError\n        on missing key' logic from dictionaries, we need to do this slowly.\n        \"\"\"\n        key = to_bytestring(key)\n        indices = []\n        for (i, (k, v)) in enumerate(self._items):\n            if _keys_equal(k, key):\n                indices.append(i)\n\n        if not indices:\n            raise KeyError(\"Nonexistent header key: {}\".format(key))\n\n        for i in indices[::-1]:\n            self._items.pop(i)\n\n    def __iter__(self):\n        \"\"\"\n        This mapping iterates like the list of tuples it is. The headers are\n        returned in canonical form.\n        \"\"\"\n        for pair in self._items:\n            for value in canonical_form(*pair):\n                yield value\n\n    def __len__(self):\n        \"\"\"\n        The length of this mapping is the number of individual headers in\n        canonical form. Sadly, this is a somewhat expensive operation.\n        \"\"\"\n        size = 0\n        for _ in self:\n            size += 1\n\n        return size\n\n    def __contains__(self, key):\n        \"\"\"\n        If any header is present with this key, returns True.\n        \"\"\"\n        key = to_bytestring(key)\n        return any(_keys_equal(key, k) for k, _ in self._items)\n\n    def keys(self):\n        \"\"\"\n        Returns an iterable of the header keys in the mapping. This explicitly\n        does not filter duplicates, ensuring that it's the same length as\n        len().\n        \"\"\"\n        for n, _ in self:\n            yield n\n\n    def items(self):\n        \"\"\"\n        This mapping iterates like the list of tuples it is.\n        \"\"\"\n        return self.__iter__()\n\n    def values(self):\n        \"\"\"\n        This is an almost nonsensical query on a header dictionary, but we\n        satisfy it in the exact same way we satisfy 'keys'.\n        \"\"\"\n        for _, v in self:\n            yield v\n\n    def get(self, name, default=None):\n        \"\"\"\n        Unlike the dict get, this returns a list of items in the order\n        they were added.\n        \"\"\"\n        try:\n            return self[name]\n        except KeyError:\n            return default\n\n    def iter_raw(self):\n        \"\"\"\n        Allows iterating over the headers in 'raw' form: that is, the form in\n        which they were added to the structure. This iteration is in order,\n        and can be used to rebuild the original headers (e.g. to determine\n        exactly what a server sent).\n        \"\"\"\n        for item in self._items:\n            yield item\n\n    def replace(self, key, value):\n        \"\"\"\n        Replace existing header with new value. If header doesn't exist this\n        method work like ``__setitem__``. Replacing leads to deletion of all\n        existing headers with the same name.\n        \"\"\"\n        key = to_bytestring(key)\n        indices = []\n        for (i, (k, v)) in enumerate(self._items):\n            if _keys_equal(k, key):\n                indices.append(i)\n\n        # If the key isn't present, this is easy: just append and abort early.\n        if not indices:\n            self._items.append((key, value))\n            return\n\n        # Delete all but the first. I swear, this is the correct slicing\n        # syntax!\n        base_index = indices[0]\n        for i in indices[:0:-1]:\n            self._items.pop(i)\n\n        del self._items[base_index]\n        self._items.insert(base_index, (key, value))\n\n    def merge(self, other):\n        \"\"\"\n        Merge another header set or any other dict-like into this one.\n        \"\"\"\n        # Short circuit to avoid infinite loops in case we try to merge into\n        # ourselves.\n        if other is self:\n            return\n\n        if isinstance(other, HTTPHeaderMap):\n            self._items.extend(other.iter_raw())\n            return\n\n        for k, v in list(other.items()):\n            self._items.append(to_bytestring_tuple(k, v))\n\n    def __eq__(self, other):\n        return self._items == other._items\n\n    def __ne__(self, other):\n        return self._items != other._items\n\n    def __str__(self):  # pragma: no cover\n        return 'HTTPHeaderMap(%s)' % self._items\n\n    def __repr__(self):  # pragma: no cover\n        return str(self)\n\n\ndef canonical_form(k, v):\n    \"\"\"\n    Returns an iterable of key-value-pairs corresponding to the header in\n    canonical form. This means that the header is split on commas unless for\n    any reason it's a super-special snowflake (I'm looking at you Set-Cookie).\n    \"\"\"\n    SPECIAL_SNOWFLAKES = set([b'set-cookie', b'set-cookie2'])\n\n    k = k.lower()\n\n    if k in SPECIAL_SNOWFLAKES:\n        yield k, v\n    else:\n        for sub_val in v.split(b','):\n            yield k, sub_val.strip()\n\n\ndef _keys_equal(x, y):\n    \"\"\"\n    Returns 'True' if the two keys are equal by the laws of HTTP headers.\n    \"\"\"\n    return x.lower() == y.lower()\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/common/util.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhyper/common/util\n~~~~~~~~~~~~~~~~~\n\nGeneral utility functions for use with hyper.\n\"\"\"\nfrom hyper.compat import str, bytes, imap\nfrom ..packages.rfc3986.uri import URIReference\nfrom ..compat import is_py3\nfrom six import string_types\n\n\ndef to_bytestring(element):\n    \"\"\"\n    Converts a single string to a bytestring, encoding via UTF-8 if needed.\n    \"\"\"\n    if isinstance(element, bytes):\n        return element\n    elif isinstance(element, memoryview):\n        return element.tobytes()\n    elif isinstance(element, bytes):\n        return element\n    elif isinstance(element, int):\n        return str(element)\n    if isinstance(element, string_types):\n        return element.encode('utf-8')\n    else:\n        raise ValueError(\"Non string type:%s\" % type(element))\n\n\ndef to_bytestring_tuple(*x):\n    \"\"\"\n    Converts the given strings to a bytestring if necessary, returning a\n    tuple. Uses ``to_bytestring``.\n    \"\"\"\n    return tuple(map(to_bytestring, x))\n\n\ndef to_host_port_tuple(host_port_str, default_port=80):\n    \"\"\"\n    Converts the given string containing a host and possibly a port\n    to a tuple.\n    \"\"\"\n    uri = URIReference(\n        scheme=None,\n        authority=host_port_str,\n        path=None,\n        query=None,\n        fragment=None\n    )\n\n    host = uri.host.strip('[]')\n    if not uri.port:\n        port = default_port\n    else:\n        port = int(uri.port)\n\n    return (host, port)\n\n\ndef to_native_string(string, encoding='utf-8'):\n    if isinstance(string, str):\n        return string\n\n    return string.decode(encoding) if is_py3 else string.encode(encoding)\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/compat.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhyper/compat\n~~~~~~~~~\n\nNormalizes the Python 2/3 API for internal use.\n\"\"\"\nfrom contextlib import contextmanager\nimport sys\nimport zlib\n\ntry:\n    from . import ssl_compat\nexcept ImportError:\n    # TODO log?\n    ssl_compat = None\n\n_ver = sys.version_info\nis_py2 = _ver[0] == 2\nis_py2_7_9_or_later = _ver[0] >= 2 and _ver[1] >= 7 and _ver[2] >= 9\nis_py3 = _ver[0] == 3\nis_py3_3 = is_py3 and _ver[1] >= 3\n\n@contextmanager\ndef ignore_missing():\n    try:\n        yield\n    except (AttributeError, NotImplementedError):  # pragma: no cover\n        pass\n\nif is_py2:\n    if is_py2_7_9_or_later:\n        import ssl\n    else:\n        ssl = ssl_compat\n\n    from urllib import urlencode\n    from urlparse import urlparse, urlsplit\n    from itertools import imap\n\n    def to_byte(char):\n        return ord(char)\n\n    def decode_hex(b):\n        return b.decode('hex')\n\n    def write_to_stdout(data):\n        sys.stdout.write(data + '\\n')\n        sys.stdout.flush()\n\n    # The standard zlib.compressobj() accepts only positional arguments.\n    def zlib_compressobj(level=6, method=zlib.DEFLATED, wbits=15, memlevel=8,\n                         strategy=zlib.Z_DEFAULT_STRATEGY):\n        return zlib.compressobj(level, method, wbits, memlevel, strategy)\n\n    str = str\n    bytes = str\n\nelif is_py3:\n    from urllib.parse import urlparse, urlsplit\n    imap = map\n\n    def to_byte(char):\n        return char\n\n    def decode_hex(b):\n        return bytes.fromhex(b)\n\n    def write_to_stdout(data):\n        sys.stdout.buffer.write(data + b'\\n')\n        sys.stdout.buffer.flush()\n\n    zlib_compressobj = zlib.compressobj\n\n    if is_py3_3:\n        ssl = ssl_compat\n    else:\n        pass\n\n    str = str\n    bytes = bytes\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/contrib.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhyper/contrib\n~~~~~~~~~~~~~\n\nContains a few utilities for use with other HTTP libraries.\n\"\"\"\ntry:\n    from requests.adapters import HTTPAdapter\n    from requests.models import Response\n    from requests.structures import CaseInsensitiveDict\n    from requests.utils import get_encoding_from_headers\n    from requests.cookies import extract_cookies_to_jar\nexcept ImportError:  # pragma: no cover\n    HTTPAdapter = object\n\nfrom hyper.common.connection import HTTPConnection\nfrom hyper.compat import urlparse\n\n\nclass HTTP20Adapter(HTTPAdapter):\n    \"\"\"\n    A Requests Transport Adapter that uses hyper to send requests over\n    HTTP/2. This implements some degree of connection pooling to maximise the\n    HTTP/2 gain.\n    \"\"\"\n    def __init__(self, *args, **kwargs):\n        #: A mapping between HTTP netlocs and ``HTTP20Connection`` objects.\n        self.connections = {}\n\n    def get_connection(self, host, port, scheme):\n        \"\"\"\n        Gets an appropriate HTTP/2 connection object based on host/port/scheme\n        tuples.\n        \"\"\"\n        secure = (scheme == 'https')\n\n        if port is None:  # pragma: no cover\n            port = 80 if not secure else 443\n\n        try:\n            conn = self.connections[(host, port, scheme)]\n        except KeyError:\n            conn = HTTPConnection(host, port, secure=secure)\n            self.connections[(host, port, scheme)] = conn\n\n        return conn\n\n    def send(self, request, stream=False, **kwargs):\n        \"\"\"\n        Sends a HTTP message to the server.\n        \"\"\"\n        parsed = urlparse(request.url)\n\n        conn = self.get_connection(parsed.hostname, parsed.port, parsed.scheme)\n\n        # Build the selector.\n        selector = parsed.path\n        selector += '?' + parsed.query if parsed.query else ''\n        selector += '#' + parsed.fragment if parsed.fragment else ''\n\n        conn.request(\n            request.method,\n            selector,\n            request.body,\n            request.headers\n        )\n        resp = conn.get_response()\n\n        r = self.build_response(request, resp)\n\n        if not stream:\n            r.content\n\n        return r\n\n    def build_response(self, request, resp):\n        \"\"\"\n        Builds a Requests' response object.  This emulates most of the logic of\n        the standard fuction but deals with the lack of the ``.headers``\n        property on the HTTP20Response object.\n\n        Additionally, this function builds in a number of features that are\n        purely for HTTPie. This is to allow maximum compatibility with what\n        urllib3 does, so that HTTPie doesn't fall over when it uses us.\n        \"\"\"\n        response = Response()\n\n        response.status_code = resp.status\n        response.headers = CaseInsensitiveDict(resp.headers.iter_raw())\n        response.raw = resp\n        response.reason = resp.reason\n        response.encoding = get_encoding_from_headers(response.headers)\n\n        extract_cookies_to_jar(response.cookies, request, response)\n        response.url = request.url\n\n        response.request = request\n        response.connection = self\n\n        # First horrible patch: Requests expects its raw responses to have a\n        # release_conn method, which I don't. We should monkeypatch a no-op on.\n        resp.release_conn = lambda: None\n\n        # Next, add the things HTTPie needs. It needs the following things:\n        #\n        # - The `raw` object has a property called `_original_response` that is\n        #   a `httplib` response object.\n        # - `raw._original_response` has three simple properties: `version`,\n        #   `status`, `reason`.\n        # - `raw._original_response.version` has one of three values: `9`,\n        #   `10`, `11`.\n        # - `raw._original_response.msg` exists.\n        # - `raw._original_response.msg._headers` exists and is an iterable of\n        #   two-tuples.\n        #\n        # We fake this out. Most of this exists on our response object already,\n        # and the rest can be faked.\n        #\n        # All of this exists for httpie, which I don't have any tests for,\n        # so I'm not going to bother adding test coverage for it.\n        class FakeOriginalResponse(object):  # pragma: no cover\n            def __init__(self, headers):\n                self._headers = headers\n\n            def get_all(self, name, default=None):\n                values = []\n\n                for n, v in self._headers:\n                    if n == name.lower():\n                        values.append(v)\n\n                if not values:\n                    return default\n\n                return values\n\n            def getheaders(self, name):\n                return self.get_all(name, [])\n\n\n        response.raw._original_response = orig = FakeOriginalResponse(None)\n        orig.version = 20\n        orig.status = resp.status\n        orig.reason = resp.reason\n        orig.msg = FakeOriginalResponse(resp.headers.iter_raw())\n\n        return response\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/http11/__init__.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhyper/http11\n~~~~~~~~~~~~\n\nThe HTTP/1.1 submodule that powers hyper.\n\"\"\"\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/http11/connection.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhyper/http11/connection\n~~~~~~~~~~~~~~~~~~~~~~~\n\nObjects that build hyper's connection-level HTTP/1.1 abstraction.\n\"\"\"\nimport logging\nimport os\nimport socket\nimport base64\n\ntry:\n    from collections import Iterable, Mapping\nexcept:\n    from collections.abc import Iterable, Mapping\n\nfrom .response import HTTP11Response\nfrom ..tls import wrap_socket, H2C_PROTOCOL\nfrom ..common.bufsocket import BufferedSocket\nfrom ..common.exceptions import TLSUpgrade, HTTPUpgrade\nfrom ..common.headers import HTTPHeaderMap\nfrom ..common.util import to_bytestring, to_host_port_tuple\nfrom ..compat import bytes\n\nfrom ..packages.hyperframe.frame import SettingsFrame\n\n# We prefer pycohttpparser to the pure-Python interpretation\ntry:  # pragma: no cover\n    from pycohttpparser.api import Parser\nexcept ImportError:  # pragma: no cover\n    from .parser import Parser\n\n\nlog = logging.getLogger(__name__)\n\nBODY_CHUNKED = 1\nBODY_FLAT = 2\n\n\nclass HTTP11Connection(object):\n    \"\"\"\n    An object representing a single HTTP/1.1 connection to a server.\n\n    :param host: The host to connect to. This may be an IP address or a\n        hostname, and optionally may include a port: for example,\n        ``'twitter.com'``, ``'twitter.com:443'`` or ``'127.0.0.1'``.\n    :param port: (optional) The port to connect to. If not provided and one also\n        isn't provided in the ``host`` parameter, defaults to 80.\n    :param secure: (optional) Whether the request should use TLS. Defaults to\n        ``False`` for most requests, but to ``True`` for any request issued to\n        port 443.\n    :param ssl_context: (optional) A class with custom certificate settings.\n        If not provided then hyper's default ``SSLContext`` is used instead.\n    :param proxy_host: (optional) The proxy to connect to.  This can be an IP \n        address or a host name and may include a port.\n    :param proxy_port: (optional) The proxy port to connect to. If not provided \n        and one also isn't provided in the ``proxy`` parameter, \n        defaults to 8080.\n    \"\"\"\n    def __init__(self, host, port=None, secure=None, ssl_context=None, \n                 proxy_host=None, proxy_port=None, **kwargs):\n        if port is None:\n            self.host, self.port = to_host_port_tuple(host, default_port=80)\n        else:\n            self.host, self.port = host, port\n\n        # Record whether we plan to secure the request. In future this should\n        # be extended to a security profile, but a bool will do for now.\n        # TODO: Actually do something with this!\n        if secure is not None:\n            self.secure = secure\n        elif self.port == 443:\n            self.secure = True\n        else:\n            self.secure = False\n\n        # only send http upgrade headers for non-secure connection\n        self._send_http_upgrade = not self.secure\n\n        self.ssl_context = ssl_context\n        self._sock = None\n\n        # Setup proxy details if applicable.\n        if proxy_host:\n            if proxy_port is None:\n                self.proxy_host, self.proxy_port = to_host_port_tuple(proxy_host, default_port=8080)\n            else:\n                self.proxy_host, self.proxy_port = proxy_host, proxy_port\n        else:\n            self.proxy_host = None\n            self.proxy_port = None\n\n        #: The size of the in-memory buffer used to store data from the\n        #: network. This is used as a performance optimisation. Increase buffer\n        #: size to improve performance: decrease it to conserve memory.\n        #: Defaults to 64kB.\n        self.network_buffer_size = 65536\n\n        #: The object used to perform HTTP/1.1 parsing. Needs to conform to\n        #: the standard hyper parsing interface.\n        self.parser = Parser()\n\n    def connect(self):\n        \"\"\"\n        Connect to the server specified when the object was created. This is a\n        no-op if we're already connected.\n\n        :returns: Nothing.\n        \"\"\"\n        if self._sock is None:\n            if not self.proxy_host:\n                host = self.host\n                port = self.port\n            else:\n                host = self.proxy_host\n                port = self.proxy_port\n                \n            sock = socket.create_connection((host, port), 5)\n            proto = None\n\n            if self.secure:\n                assert not self.proxy_host, \"Using a proxy with HTTPS not yet supported.\"\n                sock, proto = wrap_socket(sock, host, self.ssl_context)\n\n            log.debug(\"Selected protocol: %s\", proto)\n            sock = BufferedSocket(sock, self.network_buffer_size)\n\n            if proto not in ('http/1.1', None):\n                raise TLSUpgrade(proto, sock)\n\n            self._sock = sock\n\n        return\n\n    def request(self, method, url, body=None, headers={}):\n        \"\"\"\n        This will send a request to the server using the HTTP request method\n        ``method`` and the selector ``url``. If the ``body`` argument is\n        present, it should be string or bytes object of data to send after the\n        headers are finished. Strings are encoded as UTF-8. To use other\n        encodings, pass a bytes object. The Content-Length header is set to the\n        length of the body field.\n\n        :param method: The request method, e.g. ``'GET'``.\n        :param url: The URL to contact, e.g. ``'/path/segment'``.\n        :param body: (optional) The request body to send. Must be a bytestring\n            or a file-like object.\n        :param headers: (optional) The headers to send on the request.\n        :returns: Nothing.\n        \"\"\"\n        method = to_bytestring(method)\n        url = to_bytestring(url)\n\n        if not isinstance(headers, HTTPHeaderMap):\n            if isinstance(headers, Mapping):\n                headers = HTTPHeaderMap(list(headers.items()))\n            elif isinstance(headers, Iterable):\n                headers = HTTPHeaderMap(headers)\n            else:\n                raise ValueError('Header argument must be a dictionary or an iterable')\n\n        if self._sock is None:\n            self.connect()\n\n        if self._send_http_upgrade:\n            self._add_upgrade_headers(headers)\n            self._send_http_upgrade = False\n\n        # We may need extra headers.\n        if body:\n            body_type = self._add_body_headers(headers, body)\n\n        if b'host' not in headers:\n            headers[b'host'] = self.host\n\n        # Begin by emitting the header block.\n        self._send_headers(method, url, headers)\n\n        # Next, send the request body.\n        if body:\n            self._send_body(body, body_type)\n\n        return\n\n    def get_response(self):\n        \"\"\"\n        Returns a response object.\n\n        This is an early beta, so the response object is pretty stupid. That's\n        ok, we'll fix it later.\n        \"\"\"\n        headers = HTTPHeaderMap()\n\n        response = None\n        while response is None:\n            # 'encourage' the socket to receive data.\n            self._sock.fill()\n            response = self.parser.parse_response(self._sock.buffer)\n\n        for n, v in response.headers:\n            headers[n.tobytes()] = v.tobytes()\n\n        self._sock.advance_buffer(response.consumed)\n\n        if (response.status == 101 and \n           b'upgrade' in headers['connection'] and \n           H2C_PROTOCOL.encode('utf-8') in headers['upgrade']):\n            raise HTTPUpgrade(H2C_PROTOCOL, self._sock)\n\n        return HTTP11Response(\n            response.status,\n            response.msg.tobytes(),\n            headers,\n            self._sock,\n            self\n        )\n\n    def _send_headers(self, method, url, headers):\n        \"\"\"\n        Handles the logic of sending the header block.\n        \"\"\"\n        self._sock.send(b' '.join([method, url, b'HTTP/1.1\\r\\n']))\n\n        for name, value in headers.iter_raw():\n            name, value = to_bytestring(name), to_bytestring(value)\n            header = b''.join([name, b': ', value, b'\\r\\n'])\n            self._sock.send(header)\n\n        self._sock.send(b'\\r\\n')\n\n    def _add_body_headers(self, headers, body):\n        \"\"\"\n        Adds any headers needed for sending the request body. This will always\n        defer to the user-supplied header content.\n\n        :returns: One of (BODY_CHUNKED, BODY_FLAT), indicating what type of\n            request body should be used.\n        \"\"\"\n        if b'content-length' in headers:\n            return BODY_FLAT\n\n        if b'chunked' in headers.get(b'transfer-encoding', []):\n            return BODY_CHUNKED\n\n        # For bytestring bodies we upload the content with a fixed length.\n        # For file objects, we use the length of the file object.\n        if isinstance(body, bytes):\n            length = str(len(body)).encode('utf-8')\n        elif hasattr(body, 'fileno'):\n            length = str(os.fstat(body.fileno()).st_size).encode('utf-8')\n        else:\n            length = None\n\n        if length:\n            headers[b'content-length'] = length\n            return BODY_FLAT\n\n        headers[b'transfer-encoding'] = b'chunked'\n        return BODY_CHUNKED\n\n    def _add_upgrade_headers(self, headers):\n        # Add HTTP Upgrade headers.\n        headers[b'connection'] = b'Upgrade, HTTP2-Settings'\n        headers[b'upgrade'] = H2C_PROTOCOL\n        \n        # Encode SETTINGS frame payload in Base64 and put into the HTTP-2 Settings header.\n        http2_settings = SettingsFrame(0)\n        http2_settings.settings[SettingsFrame.INITIAL_WINDOW_SIZE] = 65535\n        headers[b'HTTP2-Settings'] = base64.b64encode(http2_settings.serialize_body())\n\n    def _send_body(self, body, body_type):\n        \"\"\"\n        Handles the HTTP/1.1 logic for sending HTTP bodies. This does magical\n        different things in different cases.\n        \"\"\"\n        if body_type == BODY_FLAT:\n            # Special case for files and other 'readable' objects.\n            if hasattr(body, 'read'):\n                while True:\n                    block = body.read(16*1024)\n                    if not block:\n                        break\n\n                    try:\n                        self._sock.send(block)\n                    except TypeError:\n                        raise ValueError(\n                            \"File objects must return bytestrings\"\n                        )\n\n                return\n\n            # Case for bytestrings.\n            elif isinstance(body, bytes):\n                self._sock.send(body)\n\n                return\n\n            # Iterables that set a specific content length.\n            else:\n                for item in body:\n                    try:\n                        self._sock.send(item)\n                    except TypeError:\n                        raise ValueError(\"Body must be a bytestring\")\n\n                return\n\n        # Chunked! For chunked bodies we don't special-case, we just iterate\n        # over what we have and send stuff out.\n        for chunk in body:\n            length = '{0:x}'.format(len(chunk)).encode('ascii')\n\n            # For now write this as four 'send' calls. That's probably\n            # inefficient, let's come back to it.\n            try:\n                self._sock.send(length)\n                self._sock.send(b'\\r\\n')\n                self._sock.send(chunk)\n                self._sock.send(b'\\r\\n')\n            except TypeError:\n                raise ValueError(\n                    \"Iterable bodies must always iterate in bytestrings\"\n                )\n\n        self._sock.send(b'0\\r\\n\\r\\n')\n        return\n\n    def close(self):\n        \"\"\"\n        Closes the connection. This closes the socket and then abandons the\n        reference to it. After calling this method, any outstanding\n        :class:`Response <hyper.http11.response.Response>` objects will throw\n        exceptions if attempts are made to read their bodies.\n\n        In some cases this method will automatically be called.\n\n        .. warning:: This method should absolutely only be called when you are\n                     certain the connection object is no longer needed.\n        \"\"\"\n        self._sock.close()\n        self._sock = None\n\n    # The following two methods are the implementation of the context manager\n    # protocol.\n    def __enter__(self):\n        return self\n\n    def __exit__(self, type, value, tb):\n        self.close()\n        return False  # Never swallow exceptions.\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/http11/parser.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhyper/http11/parser\n~~~~~~~~~~~~~~~~~~~\n\nThis module contains hyper's pure-Python HTTP/1.1 parser. This module defines\nan abstraction layer for HTTP/1.1 parsing that allows for dropping in other\nmodules if needed, in order to obtain speedups on your chosen platform.\n\"\"\"\nfrom collections import namedtuple\n\n\nResponse = namedtuple(\n    'Response', ['status', 'msg', 'minor_version', 'headers', 'consumed']\n)\n\n\nclass ParseError(Exception):\n    \"\"\"\n    An invalid HTTP message was passed to the parser.\n    \"\"\"\n    pass\n\n\nclass Parser(object):\n    \"\"\"\n    A single HTTP parser object.\n    This object is not thread-safe, and it does maintain state that is shared\n    across parsing requests. For this reason, make sure that access to this\n    object is synchronized if you use it across multiple threads.\n    \"\"\"\n    def __init__(self):\n        pass\n\n    def parse_response(self, buffer):\n        \"\"\"\n        Parses a single HTTP response from a buffer.\n        :param buffer: A ``memoryview`` object wrapping a buffer containing a\n            HTTP response.\n        :returns: A :class:`Response <hyper.http11.parser.Response>` object, or\n            ``None`` if there is not enough data in the buffer.\n        \"\"\"\n        # Begin by copying the data out of the buffer. This is necessary\n        # because as much as possible we want to use the built-in bytestring\n        # methods, rather than looping over the data in Python.\n        temp_buffer = buffer.tobytes()\n\n        index = temp_buffer.find(b'\\n')\n        if index == -1:\n            return None\n\n        version, status, reason = temp_buffer[0:index].split(None, 2)\n        if not version.startswith(b'HTTP/1.'):\n            raise ParseError(\"Not HTTP/1.X!\")\n\n        minor_version = int(version[7:])\n        status = int(status)\n        reason = memoryview(reason.strip())\n\n        # Chomp the newline.\n        index += 1\n\n        # Now, parse the headers out.\n        end_index = index\n        headers = []\n\n        while True:\n            end_index = temp_buffer.find(b'\\n', index)\n            if end_index == -1:\n                return None\n            elif (end_index - index) <= 1:\n                # Chomp the newline\n                end_index += 1\n                break\n\n            name, value = temp_buffer[index:end_index].split(b':', 1)\n            value = value.strip()\n            headers.append((memoryview(name), memoryview(value)))\n            index = end_index + 1\n\n        resp = Response(status, reason, minor_version, headers, end_index)\n        return resp\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/http11/response.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhyper/http11/response\n~~~~~~~~~~~~~~~~~~~~~\n\nContains the HTTP/1.1 equivalent of the HTTPResponse object defined in\nhttplib/http.client.\n\"\"\"\nimport logging\nimport weakref\nimport zlib\n\nfrom ..common.decoder import DeflateDecoder\nfrom ..common.exceptions import ChunkedDecodeError, InvalidResponseError\nfrom ..common.exceptions import ConnectionResetError\n\nlog = logging.getLogger(__name__)\n\n\nclass HTTP11Response(object):\n    \"\"\"\n    An ``HTTP11Response`` wraps the HTTP/1.1 response from the server. It\n    provides access to the response headers and the entity body. The response\n    is an iterable object and can be used in a with statement.\n    \"\"\"\n    def __init__(self, code, reason, headers, sock, connection=None):\n        #: The reason phrase returned by the server.\n        self.reason = reason\n\n        #: The status code returned by the server.\n        self.status = code\n\n        #: The response headers. These are determined upon creation, assigned\n        #: once, and never assigned again.\n        self.headers = headers\n\n        #: The response trailers. These are always intially ``None``.\n        self.trailers = None\n\n        # The socket this response is being sent over.\n        self._sock = sock\n\n        # Whether we expect the connection to be closed. If we do, we don't\n        # bother checking for content-length, we just keep reading until\n        # we no longer can.\n        self._expect_close = False\n        if b'close' in self.headers.get(b'connection', []):\n            self._expect_close = True\n\n        # The expected length of the body.\n        try:\n            self._length = int(self.headers[b'content-length'][0])\n        except KeyError:\n            self._length = None\n\n        # Whether we expect a chunked response.\n        self._chunked = b'chunked' in self.headers.get(b'transfer-encoding', [])\n\n        # One of the following must be true: we must expect that the connection\n        # will be closed following the body, or that a content-length was sent,\n        # or that we're getting a chunked response.\n        # FIXME: Remove naked assert, replace with something better.\n        assert self._expect_close or self._length is not None or self._chunked\n\n        # This object is used for decompressing gzipped request bodies. Right\n        # now we only support gzip because that's all the RFC mandates of us.\n        # Later we'll add support for more encodings.\n        # This 16 + MAX_WBITS nonsense is to force gzip. See this\n        # Stack Overflow answer for more:\n        # http://stackoverflow.com/a/2695466/1401686\n        if b'gzip' in self.headers.get(b'content-encoding', []):\n            self._decompressobj = zlib.decompressobj(16 + zlib.MAX_WBITS)\n        elif b'deflate' in self.headers.get(b'content-encoding', []):\n            self._decompressobj = DeflateDecoder()\n        else:\n            self._decompressobj = None\n\n        # This is a reference that allows for the Response class to tell the\n        # parent connection object to throw away its socket object. This is to\n        # be used when the connection is genuinely closed, so that the user\n        # can keep using the Connection object.\n        # Strictly, we take a weakreference to this so that we don't set up a\n        # reference cycle.\n        if connection is not None:\n            self._parent = weakref.ref(connection)\n        else:\n            self._parent = None\n\n        self._buffered_data = b''\n        self._chunker = None\n\n    def read(self, amt=None, decode_content=True):\n        \"\"\"\n        Reads the response body, or up to the next ``amt`` bytes.\n\n        :param amt: (optional) The amount of data to read. If not provided, all\n            the data will be read from the response.\n        :param decode_content: (optional) If ``True``, will transparently\n            decode the response data.\n        :returns: The read data. Note that if ``decode_content`` is set to\n            ``True``, the actual amount of data returned may be different to\n            the amount requested.\n        \"\"\"\n        # Return early if we've lost our connection.\n        if self._sock is None:\n            return b''\n\n        if self._chunked:\n            return self._normal_read_chunked(amt, decode_content)\n\n        # If we're asked to do a read without a length, we need to read\n        # everything. That means either the entire content length, or until the\n        # socket is closed, depending.\n        if amt is None:\n            if self._length is not None:\n                amt = self._length\n            elif self._expect_close:\n                return self._read_expect_closed(decode_content)\n            else:  # pragma: no cover\n                raise InvalidResponseError(\n                    \"Response must either have length or Connection: close\"\n                )\n\n        # Otherwise, we've been asked to do a bounded read. We should read no\n        # more than the remaining length, obviously.\n        # FIXME: Handle cases without _length\n        if self._length is not None:\n            amt = min(amt, self._length)\n\n        # If we are now going to read nothing, exit early. We still need to\n        # close the socket.\n        if not amt:\n            self.close(socket_close=self._expect_close)\n            return b''\n\n        # Now, issue reads until we read that length. This is to account for\n        # the fact that it's possible that we'll be asked to read more than\n        # 65kB in one shot.\n        to_read = amt\n        chunks = []\n\n        # Ideally I'd like this to read 'while to_read', but I want to be\n        # defensive against the admittedly unlikely case that the socket\n        # returns *more* data than I want.\n        while to_read > 0:\n            chunk = self._sock.recv(amt).tobytes()\n\n            # If we got an empty read, but were expecting more, the remote end\n            # has hung up. Raise an exception if we were expecting more data,\n            # but if we were expecting the remote end to close then it's ok.\n            if not chunk:\n                if self._length is not None or not self._expect_close:\n                    self.close(socket_close=True)\n                    raise ConnectionResetError(\"Remote end hung up!\")\n\n                break\n\n            to_read -= len(chunk)\n            chunks.append(chunk)\n\n        data = b''.join(chunks)\n        if self._length is not None:\n            self._length -= len(data)\n\n        # If we're at the end of the request, we have some cleaning up to do.\n        # Close the stream, and if necessary flush the buffer. Checking that\n        # we're at the end is actually obscenely complex: either we've read the\n        # full content-length or, if we were expecting a closed connection,\n        # we've had a read shorter than the requested amount. We also have to\n        # do this before we try to decompress the body.\n        end_of_request = (self._length == 0 or\n                          (self._expect_close and len(data) < amt))\n\n        # We may need to decode the body.\n        if decode_content and self._decompressobj and data:\n            data = self._decompressobj.decompress(data)\n\n        if decode_content and self._decompressobj and end_of_request:\n            data += self._decompressobj.flush()\n\n        # We're at the end. Close the connection. Explicit check for zero here\n        # because self._length might be None.\n        if end_of_request:\n            self.close(socket_close=self._expect_close)\n\n        return data\n\n    def read_chunked(self, decode_content=True):\n        \"\"\"\n        Reads chunked transfer encoded bodies. This method returns a generator:\n        each iteration of which yields one chunk *unless* the chunks are\n        compressed, in which case it yields whatever the decompressor provides\n        for each chunk.\n\n        .. warning:: This may yield the empty string, without that being the\n                     end of the body!\n        \"\"\"\n        if not self._chunked:\n            raise ChunkedDecodeError(\n                \"Attempted chunked read of non-chunked body.\"\n            )\n\n        # Return early if possible.\n        if self._sock is None:\n            return\n\n        while True:\n            # Read to the newline to get the chunk length. This is a\n            # hexadecimal integer.\n            chunk_length = int(self._sock.readline().tobytes().strip(), 16)\n            data = b''\n\n            # If the chunk length is zero, consume the newline and then we're\n            # done. If we were decompressing data, return the remaining data.\n            if not chunk_length:\n                self._sock.readline()\n\n                if decode_content and self._decompressobj:\n                    yield self._decompressobj.flush()\n\n                self.close(socket_close=self._expect_close)\n                break\n\n            # Then read that many bytes.\n            while chunk_length > 0:\n                chunk = self._sock.recv(chunk_length).tobytes()\n                data += chunk\n                chunk_length -= len(chunk)\n\n            assert chunk_length == 0\n\n            # Now, consume the newline.\n            self._sock.readline()\n\n            # We may need to decode the body.\n            if decode_content and self._decompressobj and data:\n                data = self._decompressobj.decompress(data)\n\n            yield data\n\n        return\n\n    def close(self, socket_close=False):\n        \"\"\"\n        Close the response. This causes the Response to lose access to the\n        backing socket. In some cases, it can also cause the backing connection\n        to be torn down.\n\n        :param socket_close: Whether to close the backing socket.\n        :returns: Nothing.\n        \"\"\"\n        if socket_close and self._parent is not None:\n            # The double call is necessary because we need to dereference the\n            # weakref. If the weakref is no longer valid, that's fine, there's\n            # no connection object to tell.\n            parent = self._parent()\n            if parent is not None:\n                parent.close()\n\n        self._sock = None\n\n    def _read_expect_closed(self, decode_content):\n        \"\"\"\n        Implements the logic for an unbounded read on a socket that we expect\n        to be closed by the remote end.\n        \"\"\"\n        # In this case, just read until we cannot read anymore. Then, close the\n        # socket, becuase we know we have to.\n        chunks = []\n        while True:\n            try:\n                chunk = self._sock.recv(65535).tobytes()\n                if not chunk:\n                    break\n            except ConnectionResetError:\n                break\n            else:\n                chunks.append(chunk)\n\n        self.close(socket_close=True)\n\n        # We may need to decompress the data.\n        data = b''.join(chunks)\n        if decode_content and self._decompressobj:\n            data = self._decompressobj.decompress(data)\n            data += self._decompressobj.flush()\n\n        return data\n\n    def _normal_read_chunked(self, amt, decode_content):\n        \"\"\"\n        Implements the logic for calling ``read()`` on a chunked response.\n        \"\"\"\n        # If we're doing a full read, read it as chunked and then just join\n        # the chunks together!\n        if amt is None:\n            return self._buffered_data + b''.join(self.read_chunked())\n\n        if self._chunker is None:\n            self._chunker = self.read_chunked()\n\n        # Otherwise, we have a certain amount of data we want to read.\n        current_amount = len(self._buffered_data)\n\n        extra_data = [self._buffered_data]\n        while current_amount < amt:\n            try:\n                chunk = next(self._chunker)\n            except StopIteration:\n                self.close(socket_close=self._expect_close)\n                break\n\n            current_amount += len(chunk)\n            extra_data.append(chunk)\n\n        data = b''.join(extra_data)\n        self._buffered_data = data[amt:]\n        return data[:amt]\n\n    # The following methods implement the context manager protocol.\n    def __enter__(self):\n        return self\n\n    def __exit__(self, *args):\n        self.close()\n        return False  # Never swallow exceptions.\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/http20/__init__.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhyper/http20\n~~~~~~~~~~~~\n\nThe HTTP/2 submodule that powers hyper.\n\"\"\"\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/http20/connection.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhyper/http20/connection\n~~~~~~~~~~~~~~~~~~~~~~~\n\nObjects that build hyper's connection-level HTTP/2 abstraction.\n\"\"\"\nfrom ..tls import wrap_socket, H2_NPN_PROTOCOLS, H2C_PROTOCOL\nfrom ..common.exceptions import ConnectionResetError\nfrom ..common.bufsocket import BufferedSocket\nfrom ..common.headers import HTTPHeaderMap\nfrom ..common.util import to_host_port_tuple, to_native_string, to_bytestring\nfrom ..packages.hyperframe.frame import (\n    FRAMES, DataFrame, PushPromiseFrame, RstStreamFrame,\n    SettingsFrame, Frame, WindowUpdateFrame, GoAwayFrame, PingFrame,\n    BlockedFrame, FRAME_MAX_LEN, FRAME_MAX_ALLOWED_LEN\n)\nfrom ..packages.hpack.hpack_compat import Encoder, Decoder\nfrom .stream import Stream\nfrom .response import HTTP20Response, HTTP20Push\nfrom .window import FlowControlManager\nfrom .exceptions import ConnectionError\nfrom . import errors\n\nimport errno\nimport logging\nimport socket\n\nlog = logging.getLogger(__name__)\n#log.setLevel(\"DEBUG\")\n\nDEFAULT_WINDOW_SIZE = 65535\n\n\nclass HTTP20Connection(object):\n    \"\"\"\n    An object representing a single HTTP/2 connection to a server.\n\n    This object behaves similarly to the Python standard library's\n    ``HTTPConnection`` object, with a few critical differences.\n\n    Most of the standard library's arguments to the constructor are irrelevant\n    for HTTP/2 or not supported by hyper.\n\n    :param host: The host to connect to. This may be an IP address or a\n        hostname, and optionally may include a port: for example,\n        ``'http2bin.org'``, ``'http2bin.org:443'`` or ``'127.0.0.1'``.\n    :param port: (optional) The port to connect to. If not provided and one also\n        isn't provided in the ``host`` parameter, defaults to 443.\n    :param secure: (optional) Whether the request should use TLS. Defaults to\n        ``False`` for most requests, but to ``True`` for any request issued to\n        port 443.\n    :param window_manager: (optional) The class to use to manage flow control\n        windows. This needs to be a subclass of the\n        :class:`BaseFlowControlManager <hyper.http20.window.BaseFlowControlManager>`.\n        If not provided,\n        :class:`FlowControlManager <hyper.http20.window.FlowControlManager>`\n        will be used.\n    :param enable_push: (optional) Whether the server is allowed to push\n        resources to the client (see\n        :meth:`get_pushes() <hyper.HTTP20Connection.get_pushes>`).\n    :param ssl_context: (optional) A class with custom certificate settings.\n        If not provided then hyper's default ``SSLContext`` is used instead.\n    :param proxy_host: (optional) The proxy to connect to.  This can be an IP address\n        or a host name and may include a port.\n    :param proxy_port: (optional) The proxy port to connect to. If not provided\n        and one also isn't provided in the ``proxy`` parameter, defaults to 8080.\n    \"\"\"\n    def __init__(self, ssl_sock, host=None, ip=None, port=None, secure=None, window_manager=None, enable_push=False,\n                 ssl_context=None, proxy_host=None, proxy_port=None, **kwargs):\n        \"\"\"\n        Creates an HTTP/2 connection to a specific server.\n        \"\"\"\n\n        self.ip = ip\n\n        if port is None:\n            self.host, self.port = to_host_port_tuple(host, default_port=443)\n        else:\n            self.host, self.port = host, port\n\n        if secure is not None:\n            self.secure = secure\n        elif self.port == 443:\n            self.secure = True\n        else:\n            self.secure = False\n\n        self._enable_push = enable_push\n        self.ssl_context = ssl_context\n\n        # Setup proxy details if applicable.\n        if proxy_host:\n            if proxy_port is None:\n                self.proxy_host, self.proxy_port = to_host_port_tuple(proxy_host, default_port=8080)\n            else:\n                self.proxy_host, self.proxy_port = proxy_host, proxy_port\n        else:\n            self.proxy_host = None\n            self.proxy_port = None\n\n        #: The size of the in-memory buffer used to store data from the\n        #: network. This is used as a performance optimisation. Increase buffer\n        #: size to improve performance: decrease it to conserve memory.\n        #: Defaults to 64kB.\n        self.network_buffer_size = 65536\n\n        # Create the mutable state.\n        self.__wm_class = window_manager or FlowControlManager\n        self.__init_state()\n\n        if ssl_sock:\n            self._sock = BufferedSocket(ssl_sock, self.network_buffer_size)\n\n            self._send_preamble()\n\n        return\n\n    def __init_state(self):\n        \"\"\"\n        Initializes the 'mutable state' portions of the HTTP/2 connection\n        object.\n\n        This method exists to enable HTTP20Connection objects to be reused if\n        they're closed, by resetting the connection object to its basic state\n        whenever it ends up closed. Any situation that needs to recreate the\n        connection can call this method and it will be done.\n\n        This is one of the only methods in hyper that is truly private, as\n        users should be strongly discouraged from messing about with connection\n        objects themselves.\n        \"\"\"\n        # Streams are stored in a dictionary keyed off their stream IDs. We\n        # also save the most recent one for easy access without having to walk\n        # the dictionary.\n        # Finally, we add a set of all streams that we or the remote party\n        # forcefully closed with RST_STREAM, to avoid encountering issues where\n        # frames were already in flight before the RST was processed.\n        self.streams = {}\n        self.recent_stream = None\n        self.next_stream_id = 1\n        self.reset_streams = set()\n\n        # Header encoding/decoding is at the connection scope, so we embed a\n        # header encoder and a decoder. These get passed to child stream\n        # objects.\n        self.encoder = Encoder()\n        self.decoder = Decoder()\n\n        # Values for the settings used on an HTTP/2 connection.\n        self._settings = {\n            SettingsFrame.INITIAL_WINDOW_SIZE: DEFAULT_WINDOW_SIZE,\n            SettingsFrame.SETTINGS_MAX_FRAME_SIZE: FRAME_MAX_LEN,\n        }\n\n        # The socket used to send data.\n        self._sock = None\n\n        # The inbound and outbound flow control windows.\n        self._out_flow_control_window = 65535\n\n        # Instantiate a window manager.\n        self.window_manager = self.__wm_class(65535)\n\n        return\n\n    def request(self, method, url, body=None, headers={}):\n        \"\"\"\n        This will send a request to the server using the HTTP request method\n        ``method`` and the selector ``url``. If the ``body`` argument is\n        present, it should be string or bytes object of data to send after the\n        headers are finished. Strings are encoded as UTF-8. To use other\n        encodings, pass a bytes object. The Content-Length header is set to the\n        length of the body field.\n\n        :param method: The request method, e.g. ``'GET'``.\n        :param url: The URL to contact, e.g. ``'/path/segment'``.\n        :param body: (optional) The request body to send. Must be a bytestring\n            or a file-like object.\n        :param headers: (optional) The headers to send on the request.\n        :returns: A stream ID for the request.\n        \"\"\"\n        stream_id = self.putrequest(method, url)\n\n        default_headers = (b':method', b':scheme', b':authority', b':path')\n        for name, value in list(headers.items()):\n            is_default = to_native_string(name) in default_headers\n            self.putheader(name, value, stream_id, replace=is_default)\n\n        # Convert the body to bytes if needed.\n        if body:\n            body = to_bytestring(body)\n\n        self.endheaders(message_body=body, final=True, stream_id=stream_id)\n\n        return stream_id\n\n    def _get_stream(self, stream_id):\n        return (self.streams[stream_id] if stream_id is not None\n                else self.recent_stream)\n\n    def get_response(self, stream_id=None):\n        \"\"\"\n        Should be called after a request is sent to get a response from the\n        server. If sending multiple parallel requests, pass the stream ID of\n        the request whose response you want. Returns a\n        :class:`HTTP20Response <hyper.HTTP20Response>` instance.\n        If you pass no ``stream_id``, you will receive the oldest\n        :class:`HTTPResponse <hyper.HTTP20Response>` still outstanding.\n\n        :param stream_id: (optional) The stream ID of the request for which to\n            get a response.\n        :returns: A :class:`HTTP20Response <hyper.HTTP20Response>` object.\n        \"\"\"\n        stream = self._get_stream(stream_id)\n        return HTTP20Response(stream.getheaders(), stream)\n\n    def get_pushes(self, stream_id=None, capture_all=False):\n        \"\"\"\n        Returns a generator that yields push promises from the server. **Note\n        that this method is not idempotent**: promises returned in one call\n        will not be returned in subsequent calls. Iterating through generators\n        returned by multiple calls to this method simultaneously results in\n        undefined behavior.\n\n        :param stream_id: (optional) The stream ID of the request for which to\n            get push promises.\n        :param capture_all: (optional) If ``False``, the generator will yield\n            all buffered push promises without blocking. If ``True``, the\n            generator will first yield all buffered push promises, then yield\n            additional ones as they arrive, and terminate when the original\n            stream closes.\n        :returns: A generator of :class:`HTTP20Push <hyper.HTTP20Push>` objects\n            corresponding to the streams pushed by the server.\n        \"\"\"\n        stream = self._get_stream(stream_id)\n        for promised_stream_id, headers in stream.get_pushes(capture_all):\n            yield HTTP20Push(\n                HTTPHeaderMap(headers), self.streams[promised_stream_id]\n            )\n\n    def connect(self):\n        \"\"\"\n        Connect to the server specified when the object was created. This is a\n        no-op if we're already connected.\n\n        :returns: Nothing.\n        \"\"\"\n        if self._sock is None:\n            if not self.proxy_host:\n                host = self.host\n                port = self.port\n            else:\n                host = self.proxy_host\n                port = self.proxy_port\n\n            if self.ip:\n                sock = socket.create_connection((self.ip, port), 5)\n            else:\n                sock = socket.create_connection((host, port), 5)\n\n            if self.secure:\n                assert not self.proxy_host, \"Using a proxy with HTTPS not yet supported.\"\n                sock, proto = wrap_socket(sock, host, self.ssl_context)\n            else:\n                proto = H2C_PROTOCOL\n\n            log.debug(\"Selected NPN protocol: %s\", proto)\n            assert proto in H2_NPN_PROTOCOLS or proto == H2C_PROTOCOL\n\n            self._sock = BufferedSocket(sock, self.network_buffer_size)\n\n            self._send_preamble()\n\n        return\n\n    def _send_preamble(self):\n        \"\"\"\n        Sends the necessary HTTP/2 preamble.\n        \"\"\"\n        # We need to send the connection header immediately on this\n        # connection, followed by an initial settings frame.\n        self._sock.send(b'PRI * HTTP/2.0\\r\\n\\r\\nSM\\r\\n\\r\\n')\n        f = SettingsFrame(0)\n        f.settings[SettingsFrame.ENABLE_PUSH] = int(self._enable_push)\n        self._send_cb(f)\n\n        # The server will also send an initial settings frame, so get it.\n        self._recv_cb()\n\n    def close(self, error_code=None):\n        \"\"\"\n        Close the connection to the server.\n\n        :param error_code: (optional) The error code to reset all streams with.\n        :returns: Nothing.\n        \"\"\"\n        # Close all streams\n        for stream in list(self.streams.values()):\n            log.debug(\"Close stream %d\" % stream.stream_id)\n            stream.close(error_code)\n\n        # Send GoAway frame to the server\n        try:\n            self._send_cb(GoAwayFrame(0), True)\n        except Exception as e:  # pragma: no cover\n            log.warn(\"GoAway frame could not be sent: %s\" % e)\n\n        if self._sock is not None:\n            self._sock.close()\n            self.__init_state()\n\n    def putrequest(self, method, selector, **kwargs):\n        \"\"\"\n        This should be the first call for sending a given HTTP request to a\n        server. It returns a stream ID for the given connection that should be\n        passed to all subsequent request building calls.\n\n        :param method: The request method, e.g. ``'GET'``.\n        :param selector: The path selector.\n        :returns: A stream ID for the request.\n        \"\"\"\n        # Create a new stream.\n        s = self._new_stream()\n\n        # To this stream we need to immediately add a few headers that are\n        # HTTP/2 specific. These are: \":method\", \":scheme\", \":authority\" and\n        # \":path\". We can set all of these now.\n        s.add_header(b\":method\", method)\n        s.add_header(b\":scheme\", b\"https\" if self.secure else b\"http\")\n        s.add_header(b\":authority\", self.host)\n        s.add_header(b\":path\", selector)\n\n        # Save the stream.\n        self.recent_stream = s\n\n        return s.stream_id\n\n    def putheader(self, header, argument, stream_id=None, replace=False):\n        \"\"\"\n        Sends an HTTP header to the server, with name ``header`` and value\n        ``argument``.\n\n        Unlike the ``httplib`` version of this function, this version does not\n        actually send anything when called. Instead, it queues the headers up\n        to be sent when you call\n        :meth:`endheaders() <hyper.HTTP20Connection.endheaders>`.\n\n        This method ensures that headers conform to the HTTP/2 specification.\n        In particular, it strips out the ``Connection`` header, as that header\n        is no longer valid in HTTP/2. This is to make it easy to write code\n        that runs correctly in both HTTP/1.1 and HTTP/2.\n\n        :param header: The name of the header.\n        :param argument: The value of the header.\n        :param stream_id: (optional) The stream ID of the request to add the\n            header to.\n        :returns: Nothing.\n        \"\"\"\n        stream = self._get_stream(stream_id)\n        stream.add_header(header, argument, replace)\n\n        return\n\n    def endheaders(self, message_body=None, final=False, stream_id=None):\n        \"\"\"\n        Sends the prepared headers to the server. If the ``message_body``\n        argument is provided it will also be sent to the server as the body of\n        the request, and the stream will immediately be closed. If the\n        ``final`` argument is set to True, the stream will also immediately\n        be closed: otherwise, the stream will be left open and subsequent calls\n        to ``send()`` will be required.\n\n        :param message_body: (optional) The body to send. May not be provided\n            assuming that ``send()`` will be called.\n        :param final: (optional) If the ``message_body`` parameter is provided,\n            should be set to ``True`` if no further data will be provided via\n            calls to :meth:`send() <hyper.HTTP20Connection.send>`.\n        :param stream_id: (optional) The stream ID of the request to finish\n            sending the headers on.\n        :returns: Nothing.\n        \"\"\"\n        self.connect()\n\n        stream = self._get_stream(stream_id)\n\n        # Close this if we've been told no more data is coming and we don't\n        # have any to send.\n        stream.open(final and message_body is None)\n\n        # Send whatever data we have.\n        if message_body is not None:\n            stream.send_data(message_body, final)\n\n        return\n\n    def send(self, data, final=False, stream_id=None):\n        \"\"\"\n        Sends some data to the server. This data will be sent immediately\n        (excluding the normal HTTP/2 flow control rules). If this is the last\n        data that will be sent as part of this request, the ``final`` argument\n        should be set to ``True``. This will cause the stream to be closed.\n\n        :param data: The data to send.\n        :param final: (optional) Whether this is the last bit of data to be\n            sent on this request.\n        :param stream_id: (optional) The stream ID of the request to send the\n            data on.\n        :returns: Nothing.\n        \"\"\"\n        stream = self._get_stream(stream_id)\n        stream.send_data(data, final)\n\n        return\n\n    def receive_frame(self, frame):\n        \"\"\"\n        Handles receiving frames intended for the stream.\n        \"\"\"\n        if frame.type == WindowUpdateFrame.type:\n            self._out_flow_control_window += frame.window_increment\n        elif frame.type == PingFrame.type:\n            if b'ACK' not in frame.flags:\n                # The spec requires us to reply with PING+ACK and identical data.\n                p = PingFrame(0)\n                p.flags.add('ACK')\n                p.opaque_data = frame.opaque_data\n                self._send_cb(p, True)\n        elif frame.type == SettingsFrame.type:\n            if b'ACK' not in frame.flags:\n                self._update_settings(frame)\n\n                # When the setting containing the max frame size value is out\n                # of range, the spec dictates to tear down the connection.\n                # Therefore we make sure the socket is still alive before\n                # returning the ack.\n                if self._sock is not None:\n                    f = SettingsFrame(0)\n                    f.flags.add(b'ACK')\n                    self._send_cb(f)\n        elif frame.type == GoAwayFrame.type:\n            # If we get GoAway with error code zero, we are doing a graceful\n            # shutdown and all is well. Otherwise, throw an exception.\n            self.close()\n\n            # If an error occured, try to read the error description from\n            # code registry otherwise use the frame's additional data.\n            if frame.error_code != 0:\n                try:\n                    name, number, description = errors.get_data(\n                        frame.error_code\n                    )\n                except ValueError:\n                    error_string = (\n                        \"Encountered error code %d, extra data %s\" %\n                        (frame.error_code, frame.additional_data)\n                    )\n                else:\n                    error_string = (\n                        \"Encountered error %s %s: %s\" %\n                        (name, number, description)\n                    )\n\n                raise ConnectionError(error_string)\n\n        elif frame.type == BlockedFrame.type:\n            increment = self.window_manager._blocked()\n            if increment:\n                f = WindowUpdateFrame(0)\n                f.window_increment = increment\n                self._send_cb(f, True)\n        elif frame.type in FRAMES:\n            # This frame isn't valid at this point.\n            raise ValueError(\"Unexpected frame %s.\" % frame)\n        else:  # pragma: no cover\n            # Unexpected frames belong to extensions. Just drop it on the\n            # floor, but log so that users know that something happened.\n            log.warning(\"Received unknown frame, type %d\", frame.type)\n            pass\n\n    def _update_settings(self, frame):\n        \"\"\"\n        Handles the data sent by a settings frame.\n        \"\"\"\n        if SettingsFrame.HEADER_TABLE_SIZE in frame.settings:\n            new_size = frame.settings[SettingsFrame.HEADER_TABLE_SIZE]\n\n            self._settings[SettingsFrame.HEADER_TABLE_SIZE] = new_size\n            self.encoder.header_table_size = new_size\n\n        if SettingsFrame.INITIAL_WINDOW_SIZE in frame.settings:\n            newsize = frame.settings[SettingsFrame.INITIAL_WINDOW_SIZE]\n            oldsize = self._settings[SettingsFrame.INITIAL_WINDOW_SIZE]\n            delta = newsize - oldsize\n\n            for stream in list(self.streams.values()):\n                stream._out_flow_control_window += delta\n\n            # Update the connection window size.\n            self._out_flow_control_window += delta\n\n            self._settings[SettingsFrame.INITIAL_WINDOW_SIZE] = newsize\n\n        if SettingsFrame.SETTINGS_MAX_FRAME_SIZE in frame.settings:\n            new_size = frame.settings[SettingsFrame.SETTINGS_MAX_FRAME_SIZE]\n            if FRAME_MAX_LEN <= new_size <= FRAME_MAX_ALLOWED_LEN:\n                self._settings[SettingsFrame.SETTINGS_MAX_FRAME_SIZE] = (\n                    new_size\n                )\n            else:\n                log.warning(\n                    \"Frame size %d is outside of allowed range\",\n                    new_size\n                )\n\n                # Tear the connection down with error code PROTOCOL_ERROR\n                self.close(1)\n                error_string = (\n                    \"Advertised frame size %d is outside of range\" % (new_size)\n                )\n                raise ConnectionError(error_string)\n\n    def _new_stream(self, stream_id=None, local_closed=False):\n        \"\"\"\n        Returns a new stream object for this connection.\n        \"\"\"\n        window_size = self._settings[SettingsFrame.INITIAL_WINDOW_SIZE]\n        s = Stream(\n            stream_id or self.next_stream_id, self._send_cb, self._recv_cb,\n            self._close_stream, self.encoder, self.decoder,\n            self.__wm_class(DEFAULT_WINDOW_SIZE), local_closed\n        )\n        s._out_flow_control_window = window_size\n        self.streams[s.stream_id] = s\n        self.next_stream_id += 2\n\n        return s\n\n    def _close_stream(self, stream_id, error_code=None):\n        \"\"\"\n        Called by a stream when it would like to be 'closed'.\n        \"\"\"\n        # Graceful shutdown of streams involves not emitting an error code\n        # at all.\n        if error_code:\n            self._send_rst_frame(stream_id, error_code)\n        else:\n            # Just delete the stream.\n            try:\n                del self.streams[stream_id]\n            except KeyError as e:  # pragma: no cover\n                log.warn(\n                    \"Stream with id %d does not exist: %s\",\n                    stream_id, e)\n\n    def _send_cb(self, frame, tolerate_peer_gone=False):\n        \"\"\"\n        This is the callback used by streams to send data on the connection.\n\n        It expects to receive a single frame, and then to serialize that frame\n        and send it on the connection. It does so obeying the connection-level\n        flow-control principles of HTTP/2.\n        \"\"\"\n        # Maintain our outgoing flow-control window.\n        #print(\"conn send\", frame)\n\n        if frame.type == DataFrame.type:\n            # If we don't have room in the flow control window, we need to look\n            # for a Window Update frame.\n            while self._out_flow_control_window < len(frame.data):\n                self._recv_cb()\n\n            self._out_flow_control_window -= len(frame.data)\n\n        data = frame.serialize()\n\n        max_frame_size = self._settings[SettingsFrame.SETTINGS_MAX_FRAME_SIZE]\n        if frame.body_len > max_frame_size:\n            raise ValueError(\n                     \"Frame size %d exceeds maximum frame size setting %d\" %\n                     (frame.body_len,\n                      self._settings[SettingsFrame.SETTINGS_MAX_FRAME_SIZE])\n            )\n\n        log.info(\n            \"Sending frame %s on stream %d\",\n            frame.__class__.__name__,\n            frame.stream_id\n        )\n\n        try:\n            self._sock.send(data)\n        except socket.error as e:\n            if (not tolerate_peer_gone or\n                e.errno not in (errno.EPIPE, errno.ECONNRESET)):\n                raise\n\n    def _adjust_receive_window(self, frame_len):\n        \"\"\"\n        Adjusts the window size in response to receiving a DATA frame of length\n        ``frame_len``. May send a WINDOWUPDATE frame if necessary.\n        \"\"\"\n        increment = self.window_manager._handle_frame(frame_len)\n\n        if increment:\n            f = WindowUpdateFrame(0)\n            f.window_increment = increment\n            self._send_cb(f, True)\n\n        return\n\n    def _consume_single_frame(self):\n        \"\"\"\n        Consumes a single frame from the TCP stream.\n\n        Right now this method really does a bit too much: it shouldn't be\n        responsible for determining if a frame is valid or to increase the\n        flow control window.\n        \"\"\"\n        # Begin by reading 9 bytes from the socket.\n        header = self._sock.recv(9)\n\n        # Parse the header. We can use the returned memoryview directly here.\n        frame, length = Frame.parse_frame_header(header)\n\n        if (length > FRAME_MAX_ALLOWED_LEN):\n            log.warning(\n                \"Frame size exceeded on stream %d (received: %d, max: %d)\",\n                frame.stream_id,\n                length,\n                FRAME_MAX_ALLOWED_LEN\n            )\n            self._send_rst_frame(frame.stream_id, 6) # 6 = FRAME_SIZE_ERROR\n\n        # Read the remaining data from the socket.\n        data = self._recv_payload(length)\n        self._consume_frame_payload(frame, data)\n\n    def _recv_payload(self, length):\n        \"\"\"\n        This receive function handles the situation where the underlying socket\n        has not received the full set of data. It spins on calling `recv`\n        until the full quantity of data is available before returning.\n\n        Note that this function makes us vulnerable to a DoS attack, where a\n        server can send part of a frame and then swallow the rest. We should\n        add support for socket timeouts here at some stage.\n        \"\"\"\n        # TODO: Fix DoS risk.\n        if not length:\n            return memoryview(b'')\n\n        buffer = bytearray(length)\n        buffer_view = memoryview(buffer)\n        index = 0\n        data_length = -1\n        # _sock.recv(length) might not read out all data if the given length\n        # is very large. So it should be to retrieve from socket repeatedly.\n        while length and data_length:\n            data = self._sock.recv(length)\n            data_length = len(data)\n            end = index + data_length\n            buffer_view[index:end] = data[:]\n            length -= data_length\n            index = end\n\n        return buffer_view[:end]\n\n    def _consume_frame_payload(self, frame, data):\n        \"\"\"\n        This builds and handles a frame.\n        \"\"\"\n        frame.parse_body(data)\n\n        #print(\"conn recv \", frame)\n        log.info(\n            \"Received frame %s on stream %d\",\n            frame.__class__.__name__,\n            frame.stream_id\n        )\n\n        # Maintain our flow control window. We do this by delegating to the\n        # chosen WindowManager.\n        if frame.type == DataFrame.type:\n            # Inform the WindowManager of how much data was received. If the\n            # manager tells us to increment the window, do so.\n            self._adjust_receive_window(frame.flow_controlled_length)\n        elif frame.type == PushPromiseFrame.type:\n            if self._enable_push:\n                self._new_stream(frame.promised_stream_id, local_closed=True)\n            else:\n                # Servers are forbidden from sending push promises when\n                # the ENABLE_PUSH setting is 0, but the spec leaves the client\n                # action undefined when they do it anyway. So we just refuse\n                # the stream and go about our business.\n                self._send_rst_frame(frame.promised_stream_id, 7)\n\n        # If this frame was received on a stream that has been reset, drop it.\n        if frame.stream_id in self.reset_streams:\n            log.info(\n                \"Stream %s has been reset, dropping frame.\", frame.stream_id\n            )\n            return\n\n        # Work out to whom this frame should go.\n        if frame.stream_id != 0:\n            try:\n                self.streams[frame.stream_id].receive_frame(frame)\n            except KeyError:\n                # If we receive an unexpected stream identifier then we\n                # cancel the stream with an error of type PROTOCOL_ERROR\n                self._send_rst_frame(frame.stream_id, 1)\n                log.warning(\n                    \"Unexpected stream identifier %d\" % (frame.stream_id)\n                )\n\n            # If this is a RST_STREAM frame, we may get more than one (because\n            # of frames in flight). Keep track.\n            if frame.type == RstStreamFrame.type:\n                self.reset_streams.add(frame.stream_id)\n        else:\n            self.receive_frame(frame)\n\n    def _recv_cb(self):\n        \"\"\"\n        This is the callback used by streams to read data from the connection.\n\n        It expects to read a single frame, and then to deserialize that frame\n        and pass it to the relevant stream. It then attempts to optimistically\n        read further frames (in an attempt to ensure that we see control frames\n        as early as possible).\n\n        This is generally called by a stream, not by the connection itself, and\n        it's likely that streams will read a frame that doesn't belong to them.\n        \"\"\"\n        self._consume_single_frame()\n        count = 9\n\n        while count and self._sock is not None and self._sock.can_read:\n            # If the connection has been closed, bail out.\n            try:\n                self._consume_single_frame()\n            except ConnectionResetError:\n                break\n\n            count -= 1\n\n    def _send_rst_frame(self, stream_id, error_code):\n        \"\"\"\n        Send reset stream frame with error code and remove stream from map.\n        \"\"\"\n        f = RstStreamFrame(stream_id)\n        f.error_code = error_code\n        self._send_cb(f)\n\n        try:\n            del self.streams[stream_id]\n        except KeyError as e:  # pragma: no cover\n            log.warn(\n                \"Stream with id %d does not exist: %s\",\n                stream_id, e)\n\n        # Keep track of the fact that we reset this stream in case there are\n        # other frames in flight.\n        self.reset_streams.add(stream_id)\n\n    # The following two methods are the implementation of the context manager\n    # protocol.\n    def __enter__(self):\n        return self\n\n    def __exit__(self, type, value, tb):\n        self.close()\n        return False  # Never swallow exceptions.\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/http20/errors.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhyper/http20/errors\n~~~~~~~~~~~~~~~~~~~\n\nGlobal error code registry containing the established HTTP/2 error codes.\nThe registry is based on a 32-bit space so we use the error code to index into\nthe array.\n\nThe current registry is available at:\nhttps://tools.ietf.org/html/rfc7540#section-11.4\n\"\"\"\n\nNO_ERROR =            {'Name': 'NO_ERROR',\n                       'Code': '0x0',\n                       'Description': 'Graceful shutdown'}\nPROTOCOL_ERROR =      {'Name': 'PROTOCOL_ERROR',\n                       'Code': '0x1',\n                       'Description': 'Protocol error detected'}\nINTERNAL_ERROR =      {'Name': 'INTERNAL_ERROR',\n                       'Code': '0x2',\n                       'Description': 'Implementation fault'}\nFLOW_CONTROL_ERROR =  {'Name': 'FLOW_CONTROL_ERROR',\n                       'Code': '0x3',\n                       'Description': 'Flow control limits exceeded'}\nSETTINGS_TIMEOUT =    {'Name': 'SETTINGS_TIMEOUT',\n                       'Code': '0x4',\n                       'Description': 'Settings not acknowledged'}\nSTREAM_CLOSED =       {'Name': 'STREAM_CLOSED',\n                       'Code': '0x5',\n                       'Description': 'Frame received for closed stream'}\nFRAME_SIZE_ERROR =    {'Name': 'FRAME_SIZE_ERROR',\n                       'Code': '0x6',\n                       'Description': 'Frame size incorrect'}\nREFUSED_STREAM =      {'Name': 'REFUSED_STREAM ',\n                       'Code': '0x7',\n                       'Description': 'Stream not processed'}\nCANCEL =              {'Name': 'CANCEL',\n                       'Code': '0x8',\n                       'Description': 'Stream cancelled'}\nCOMPRESSION_ERROR =   {'Name': 'COMPRESSION_ERROR',\n                       'Code': '0x9',\n                       'Description': 'Compression state not updated'}\nCONNECT_ERROR =       {'Name': 'CONNECT_ERROR',\n                       'Code': '0xa',\n                       'Description': \n                       'TCP connection error for CONNECT method'}\nENHANCE_YOUR_CALM =   {'Name': 'ENHANCE_YOUR_CALM',\n                       'Code': '0xb',\n                       'Description': 'Processing capacity exceeded'}\nINADEQUATE_SECURITY = {'Name': 'INADEQUATE_SECURITY',\n                       'Code': '0xc',\n                       'Description': \n                       'Negotiated TLS parameters not acceptable'}\nHTTP_1_1_REQUIRED =   {'Name': 'HTTP_1_1_REQUIRED', \n                       'Code': '0xd',\n                       'Description': 'Use HTTP/1.1 for the request'}\n\nH2_ERRORS = [NO_ERROR, PROTOCOL_ERROR, INTERNAL_ERROR, FLOW_CONTROL_ERROR,\n             SETTINGS_TIMEOUT, STREAM_CLOSED, FRAME_SIZE_ERROR, REFUSED_STREAM,\n             CANCEL, COMPRESSION_ERROR, CONNECT_ERROR, ENHANCE_YOUR_CALM,\n             INADEQUATE_SECURITY, HTTP_1_1_REQUIRED]\n\ndef get_data(error_code):\n    \"\"\"\n    Lookup the error code description, if not available throw a value error\n    \"\"\"\n    if error_code < 0 or error_code >= len(H2_ERRORS):\n        raise ValueError(\"Error code is invalid\")\n\n    name = H2_ERRORS[error_code]['Name']\n    number = H2_ERRORS[error_code]['Code']\n    description = H2_ERRORS[error_code]['Description']\n\n    return name, number, description\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/http20/exceptions.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhyper/http20/exceptions\n~~~~~~~~~~~~~~~~~~~~~~~\n\nThis defines exceptions used in the HTTP/2 portion of hyper.\n\"\"\"\n\nclass HTTP20Error(Exception):\n    \"\"\"\n    The base class for all of ``hyper``'s HTTP/2-related exceptions.\n    \"\"\"\n    pass\n\n\nclass HPACKEncodingError(HTTP20Error):\n    \"\"\"\n    An error has been encountered while performing HPACK encoding.\n    \"\"\"\n    pass\n\n\nclass HPACKDecodingError(HTTP20Error):\n    \"\"\"\n    An error has been encountered while performing HPACK decoding.\n    \"\"\"\n    pass\n\n\nclass ConnectionError(HTTP20Error):\n    \"\"\"\n    The remote party signalled an error affecting the entire HTTP/2\n    connection, and the connection has been closed.\n    \"\"\"\n    pass\n\n\nclass ProtocolError(HTTP20Error):\n    \"\"\"\n    The remote party violated the HTTP/2 protocol.\n    \"\"\"\n    pass\n\n\nclass StreamResetError(HTTP20Error):\n    \"\"\"\n    A stream was forcefully reset by the remote party.\n    \"\"\"\n    pass\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/http20/response.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhyper/http20/response\n~~~~~~~~~~~~~~~~~~~~~\n\nContains the HTTP/2 equivalent of the HTTPResponse object defined in\nhttplib/http.client.\n\"\"\"\nimport logging\nimport zlib\n\nfrom ..common.decoder import DeflateDecoder\nfrom ..common.headers import HTTPHeaderMap\n\nlog = logging.getLogger(__name__)\n\n\ndef strip_headers(headers):\n    \"\"\"\n    Strips the headers attached to the instance of any header beginning\n    with a colon that ``hyper`` doesn't understand. This method logs at\n    warning level about the deleted headers, for discoverability.\n    \"\"\"\n    # Convert to list to ensure that we don't mutate the headers while\n    # we iterate over them.\n    for name in list(headers.keys()):\n        if name.startswith(b':'):\n            del headers[name]\n\n\nclass HTTP20Response(object):\n    \"\"\"\n    An ``HTTP20Response`` wraps the HTTP/2 response from the server. It\n    provides access to the response headers and the entity body. The response\n    is an iterable object and can be used in a with statement (though due to\n    the persistent connections used in HTTP/2 this has no effect, and is done\n    soley for compatibility).\n    \"\"\"\n    def __init__(self, headers, stream):\n        #: The reason phrase returned by the server. This is not used in\n        #: HTTP/2, and so is always the empty string.\n        self.reason = ''\n\n        status = headers[b':status'][0]\n        strip_headers(headers)\n\n        #: The status code returned by the server.\n        self.status = int(status)\n\n        #: The response headers. These are determined upon creation, assigned\n        #: once, and never assigned again.\n        self.headers = headers\n\n        # The response trailers. These are always intially ``None``.\n        self._trailers = None\n\n        # The stream this response is being sent over.\n        self._stream = stream\n\n        # We always read in one-data-frame increments from the stream, so we\n        # may need to buffer some for incomplete reads.\n        self._data_buffer = b''\n\n        # This object is used for decompressing gzipped request bodies. Right\n        # now we only support gzip because that's all the RFC mandates of us.\n        # Later we'll add support for more encodings.\n        # This 16 + MAX_WBITS nonsense is to force gzip. See this\n        # Stack Overflow answer for more:\n        # http://stackoverflow.com/a/2695466/1401686\n        if b'gzip' in self.headers.get(b'content-encoding', []):\n            self._decompressobj = zlib.decompressobj(16 + zlib.MAX_WBITS)\n        elif b'deflate' in self.headers.get(b'content-encoding', []):\n            self._decompressobj = DeflateDecoder()\n        else:\n            self._decompressobj = None\n\n    @property\n    def trailers(self):\n        \"\"\"\n        Trailers on the HTTP message, if any.\n\n        .. warning:: Note that this property requires that the stream is\n                     totally exhausted. This means that, if you have not\n                     completely read from the stream, all stream data will be\n                     read into memory.\n        \"\"\"\n        if self._trailers is None:\n            self._trailers = self._stream.gettrailers() or HTTPHeaderMap()\n            strip_headers(self._trailers)\n\n        return self._trailers\n\n    def read(self, amt=None, decode_content=True):\n        \"\"\"\n        Reads the response body, or up to the next ``amt`` bytes.\n\n        :param amt: (optional) The amount of data to read. If not provided, all\n            the data will be read from the response.\n        :param decode_content: (optional) If ``True``, will transparently\n            decode the response data.\n        :returns: The read data. Note that if ``decode_content`` is set to\n            ``True``, the actual amount of data returned may be different to\n            the amount requested.\n        \"\"\"\n        if amt is not None and amt <= len(self._data_buffer):\n            data = self._data_buffer[:amt]\n            self._data_buffer = self._data_buffer[amt:]\n            response_complete = False\n        elif amt is not None:\n            read_amt = amt - len(self._data_buffer)\n            self._data_buffer += self._stream._read(read_amt)\n            data = self._data_buffer[:amt]\n            self._data_buffer = self._data_buffer[amt:]\n            response_complete = len(data) < amt\n        else:\n            data = b''.join([self._data_buffer, self._stream._read()])\n            response_complete = True\n\n        # We may need to decode the body.\n        if decode_content and self._decompressobj and data:\n            data = self._decompressobj.decompress(data)\n\n        # If we're at the end of the request, we have some cleaning up to do.\n        # Close the stream, and if necessary flush the buffer.\n        if response_complete:\n            if decode_content and self._decompressobj:\n                data += self._decompressobj.flush()\n\n            if self._stream.response_headers:\n                self.headers.merge(self._stream.response_headers)\n\n        # We're at the end. Close the connection.\n        if not data:\n            self.close()\n\n        return data\n\n    def read_chunked(self, decode_content=True):\n        \"\"\"\n        Reads chunked transfer encoded bodies. This method returns a generator:\n        each iteration of which yields one data frame *unless* the frames\n        contain compressed data and ``decode_content`` is ``True``, in which\n        case it yields whatever the decompressor provides for each chunk.\n\n        .. warning:: This may yield the empty string, without that being the\n                     end of the body!\n        \"\"\"\n        while True:\n            data = self._stream._read_one_frame()\n\n            if data is None:\n                break\n\n            if decode_content and self._decompressobj:\n                data = self._decompressobj.decompress(data)\n\n            yield data\n\n        if decode_content and self._decompressobj:\n            yield self._decompressobj.flush()\n\n        self.close()\n\n        return\n\n    def fileno(self):\n        \"\"\"\n        Return the ``fileno`` of the underlying socket. This function is\n        currently not implemented.\n        \"\"\"\n        raise NotImplementedError(\"Not currently implemented.\")\n\n    def close(self):\n        \"\"\"\n        Close the response. In effect this closes the backing HTTP/2 stream.\n\n        :returns: Nothing.\n        \"\"\"\n        self._stream.close()\n\n    # The following methods implement the context manager protocol.\n    def __enter__(self):\n        return self\n\n    def __exit__(self, *args):\n        self.close()\n        return False  # Never swallow exceptions.\n\n\nclass HTTP20Push(object):\n    \"\"\"\n    Represents a request-response pair sent by the server through the server\n    push mechanism.\n    \"\"\"\n    def __init__(self, request_headers, stream):\n        #: The scheme of the simulated request\n        self.scheme = request_headers[b':scheme'][0]\n        #: The method of the simulated request (must be safe and cacheable, e.g. GET)\n        self.method = request_headers[b':method'][0]\n        #: The authority of the simulated request (usually host:port)\n        self.authority = request_headers[b':authority'][0]\n        #: The path of the simulated request\n        self.path = request_headers[b':path'][0]\n\n        strip_headers(request_headers)\n\n        #: The headers the server attached to the simulated request.\n        self.request_headers = request_headers\n\n        self._stream = stream\n\n    def get_response(self):\n        \"\"\"\n        Get the pushed response provided by the server.\n\n        :returns: A :class:`HTTP20Response <hyper.HTTP20Response>` object\n            representing the pushed response.\n        \"\"\"\n        return HTTP20Response(self._stream.getheaders(), self._stream)\n\n    def cancel(self):\n        \"\"\"\n        Cancel the pushed response and close the stream.\n\n        :returns: Nothing.\n        \"\"\"\n        self._stream.close(8) # CANCEL\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/http20/stream.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhyper/http20/stream\n~~~~~~~~~~~~~~~~~~~\n\nObjects that make up the stream-level abstraction of hyper's HTTP/2 support.\n\nThese objects are not expected to be part of the public HTTP/2 API: they're\nintended purely for use inside hyper's HTTP/2 abstraction.\n\nConceptually, a single HTTP/2 connection is made up of many streams: each\nstream is an independent, bi-directional sequence of HTTP headers and data.\nEach stream is identified by a monotonically increasing integer, assigned to\nthe stream by the endpoint that initiated the stream.\n\"\"\"\nfrom ..common.headers import HTTPHeaderMap\nfrom ..packages.hyperframe.frame import (\n    FRAME_MAX_LEN, FRAMES, HeadersFrame, DataFrame, PushPromiseFrame,\n    WindowUpdateFrame, ContinuationFrame, BlockedFrame, RstStreamFrame\n)\nfrom .exceptions import ProtocolError, StreamResetError\nfrom .util import h2_safe_headers\nimport logging\n\nlog = logging.getLogger(__name__)\n#log.setLevel(\"DEBUG\")\n\n\n# Define a set of states for a HTTP/2 stream.\nSTATE_IDLE               = 0\nSTATE_OPEN               = 1\nSTATE_HALF_CLOSED_LOCAL  = 2\nSTATE_HALF_CLOSED_REMOTE = 3\nSTATE_CLOSED             = 4\n\n\n# Define the largest chunk of data we'll send in one go. Realistically, we\n# should take the MSS into account but that's pretty dull, so let's just say\n# 1kB and call it a day.\nMAX_CHUNK = 1024\n\n\nclass Stream(object):\n    \"\"\"\n    A single HTTP/2 stream.\n\n    A stream is an independent, bi-directional sequence of HTTP headers and\n    data. Each stream is identified by a single integer. From a HTTP\n    perspective, a stream _approximately_ matches a single request-response\n    pair.\n    \"\"\"\n    def __init__(self,\n                 stream_id,\n                 data_cb,\n                 recv_cb,\n                 close_cb,\n                 header_encoder,\n                 header_decoder,\n                 window_manager,\n                 local_closed=False):\n        self.stream_id = stream_id\n        self.state = STATE_HALF_CLOSED_LOCAL if local_closed else STATE_IDLE\n        self.headers = HTTPHeaderMap()\n\n        # Set to a key-value set of the response headers once their\n        # HEADERS..CONTINUATION frame sequence finishes.\n        self.response_headers = None\n\n        # Set to a key-value set of the response trailers once their\n        # HEADERS..CONTINUATION frame sequence finishes.\n        self.response_trailers = None\n\n        # A dict mapping the promised stream ID of a pushed resource to a\n        # key-value set of its request headers. Entries are added once their\n        # PUSH_PROMISE..CONTINUATION frame sequence finishes.\n        self.promised_headers = {}\n\n        # Chunks of encoded header data from the current\n        # (HEADERS|PUSH_PROMISE)..CONTINUATION frame sequence. Since sending any\n        # frame other than a CONTINUATION is disallowed while a header block is\n        # being transmitted, this and ``promised_stream_id`` are the only pieces\n        # of state we have to track.\n        self.header_data = []\n        self.promised_stream_id = None\n\n        # Unconsumed response data chunks. Empties after every call to _read().\n        self.data = []\n\n        # There are two flow control windows: one for data we're sending,\n        # one for data being sent to us.\n        self._in_window_manager = window_manager\n        self._out_flow_control_window = 65535\n\n        # This is the callback handed to the stream by its parent connection.\n        # It is called when the stream wants to send data. It expects to\n        # receive a list of frames that will be automatically serialized.\n        self._data_cb = data_cb\n\n        # Similarly, this is a callback that reads one frame off the\n        # connection.\n        self._recv_cb = recv_cb\n\n        # This is the callback to be called when the stream is closed.\n        self._close_cb = close_cb\n\n        # A reference to the header encoder and decoder objects belonging to\n        # the parent connection.\n        self._encoder = header_encoder\n        self._decoder = header_decoder\n\n    def add_header(self, name, value, replace=False):\n        \"\"\"\n        Adds a single HTTP header to the headers to be sent on the request.\n        \"\"\"\n        if not replace:\n            self.headers[name] = value\n        else:\n            self.headers.replace(name, value)\n\n\n    def send_data(self, data, final):\n        \"\"\"\n        Send some data on the stream. If this is the end of the data to be\n        sent, the ``final`` flag _must_ be set to True. If no data is to be\n        sent, set ``data`` to ``None``.\n        \"\"\"\n        # Define a utility iterator for file objects.\n        def file_iterator(fobj):\n            while True:\n                data = fobj.read(MAX_CHUNK)\n                yield data\n                if len(data) < MAX_CHUNK:\n                    break\n\n        # Build the appropriate iterator for the data, in chunks of CHUNK_SIZE.\n        if hasattr(data, 'read'):\n            chunks = file_iterator(data)\n        else:\n            chunks = (data[i:i+MAX_CHUNK]\n                      for i in range(0, len(data), MAX_CHUNK))\n\n        for chunk in chunks:\n            self._send_chunk(chunk, final)\n\n    @property\n    def _local_closed(self):\n        return self.state in (STATE_CLOSED, STATE_HALF_CLOSED_LOCAL)\n\n    @property\n    def _remote_closed(self):\n        return self.state in (STATE_CLOSED, STATE_HALF_CLOSED_REMOTE)\n\n    @property\n    def _local_open(self):\n        return self.state in (STATE_OPEN, STATE_HALF_CLOSED_REMOTE)\n\n    def _close_local(self):\n        self.state = (\n            STATE_HALF_CLOSED_LOCAL if self.state == STATE_OPEN\n            else STATE_CLOSED\n        )\n\n    def _close_remote(self):\n        self.state = (\n            STATE_HALF_CLOSED_REMOTE if self.state == STATE_OPEN\n            else STATE_CLOSED\n        )\n\n    def _read(self, amt=None):\n        \"\"\"\n        Read data from the stream. Unlike a normal read behaviour, this\n        function returns _at least_ ``amt`` data, but may return more.\n        \"\"\"\n        def listlen(list):\n            return sum(map(len, list))\n\n        # Keep reading until the stream is closed or we get enough data.\n        while not self._remote_closed and (amt is None or listlen(self.data) < amt):\n            self._recv_cb()\n\n        result = b''.join(self.data)\n        self.data = []\n        return result\n\n    def _read_one_frame(self):\n        \"\"\"\n        Reads a single data frame from the stream and returns it.\n        \"\"\"\n        # Keep reading until the stream is closed or we have a data frame.\n        while not self._remote_closed and not self.data:\n            self._recv_cb()\n\n        try:\n            return self.data.pop(0)\n        except IndexError:\n            return None\n\n    def receive_frame(self, frame):\n        \"\"\"\n        Handle a frame received on this stream.\n        \"\"\"\n        #print(\"stream recv %s\", frame)\n        if b'END_STREAM' in frame.flags:\n            log.debug(\"Closing remote side of stream\")\n            self._close_remote()\n\n        if frame.type == WindowUpdateFrame.type:\n            self._out_flow_control_window += frame.window_increment\n        elif frame.type == HeadersFrame.type:\n            # Begin the header block for the response headers.\n            self.promised_stream_id = None\n            self.header_data = [frame.data]\n        elif frame.type == PushPromiseFrame.type:\n            # Begin a header block for the request headers of a pushed resource.\n            self.promised_stream_id = frame.promised_stream_id\n            self.header_data = [frame.data]\n        elif frame.type == ContinuationFrame.type:\n            # Continue a header block begun with either HEADERS or PUSH_PROMISE.\n            self.header_data.append(frame.data)\n        elif frame.type == DataFrame.type:\n            # Increase the window size. Only do this if the data frame contains\n            # actual data.\n            size = frame.flow_controlled_length\n            increment = self._in_window_manager._handle_frame(size)\n\n            # Append the data to the buffer.\n            self.data.append(frame.data.tobytes())\n\n            if increment and not self._remote_closed:\n                w = WindowUpdateFrame(self.stream_id)\n                w.window_increment = increment\n                self._data_cb(w, True)\n        elif frame.type == BlockedFrame.type:\n            # If we've been blocked we may want to fixup the window.\n            increment = self._in_window_manager._blocked()\n            if increment:\n                w = WindowUpdateFrame(self.stream_id)\n                w.window_increment = increment\n                self._data_cb(w, True)\n        elif frame.type == RstStreamFrame.type:\n            self.close(0)\n            raise StreamResetError(\"Stream forcefully closed.\")\n        elif frame.type in FRAMES:\n            # This frame isn't valid at this point.\n            raise ValueError(\"Unexpected frame %s.\" % frame)\n        else:  # pragma: no cover\n            # Unknown frames belong to extensions. Just drop it on the\n            # floor, but log so that users know that something happened.\n            log.warning(\"Received unknown frame, type %d\", frame.type)\n            pass\n\n        if b'END_HEADERS' in frame.flags:\n            # Begin by decoding the header block. If this fails, we need to\n            # tear down the entire connection. TODO: actually do that.\n            if len(self.header_data) == 1:\n                headers = self._decoder.decode(self.header_data[0])\n            else:\n                headers = self._decoder.decode(b''.join(self.header_data.tobytes()))\n\n            # If we're involved in a PUSH_PROMISE sequence, this header block\n            # is the proposed request headers. Save it off. Otherwise, handle\n            # it as an in-stream HEADERS block.\n            if (self.promised_stream_id is None):\n                self._handle_header_block(headers)\n            else:\n                self.promised_headers[self.promised_stream_id] = headers\n\n            # We've handled the headers, zero them out.\n            self.header_data = None\n\n    def open(self, end):\n        \"\"\"\n        Open the stream. Does this by encoding and sending the headers: no more\n        calls to ``add_header`` are allowed after this method is called.\n        The `end` flag controls whether this will be the end of the stream, or\n        whether data will follow.\n        \"\"\"\n        # Strip any headers invalid in H2.\n        headers = h2_safe_headers(self.headers)\n\n        # Encode the headers.\n        encoded_headers = self._encoder.encode(headers)\n\n        # It's possible that there is a substantial amount of data here. The\n        # data needs to go into one HEADERS frame, followed by a number of\n        # CONTINUATION frames. For now, for ease of implementation, let's just\n        # assume that's never going to happen (16kB of headers is lots!).\n        # Additionally, since this is so unlikely, there's no point writing a\n        # test for this: it's just so simple.\n        if len(encoded_headers) > FRAME_MAX_LEN:  # pragma: no cover\n            raise ValueError(\"Header block too large.\")\n\n        header_frame = HeadersFrame(self.stream_id)\n        header_frame.data = encoded_headers\n\n        # If no data has been provided, this is the end of the stream. Either\n        # way, due to the restriction above it's definitely the end of the\n        # headers.\n        header_frame.flags.add(b'END_HEADERS')\n\n        if end:\n            header_frame.flags.add(b'END_STREAM')\n\n        # Send the header frame.\n        self._data_cb(header_frame)\n\n        # Transition the stream state appropriately.\n        self.state = STATE_HALF_CLOSED_LOCAL if end else STATE_OPEN\n\n        return\n\n    def getheaders(self):\n        \"\"\"\n        Once all data has been sent on this connection, returns a key-value set\n        of the headers of the response to the original request.\n        \"\"\"\n        assert self._local_closed\n\n        # Keep reading until all headers are received.\n        while self.response_headers is None:\n            self._recv_cb()\n\n        # Find the Content-Length header if present.\n        self._in_window_manager.document_size = (\n            int(self.response_headers.get(b'content-length', [0])[0])\n        )\n\n        return self.response_headers\n\n    def gettrailers(self):\n        \"\"\"\n        Once all data has been sent on this connection, returns a key-value set\n        of the trailers of the response to the original request.\n\n        .. warning:: Note that this method requires that the stream is\n                     totally exhausted. This means that, if you have not\n                     completely read from the stream, all stream data will be\n                     read into memory.\n\n        :returns: The key-value set of the trailers, or ``None`` if no trailers\n                  were sent.\n        \"\"\"\n        # Keep reading until the stream is done.\n        # TODO: Right now this doesn't handle CONTINUATION blocks in trailers.\n        # The idea of receiving such a thing is mind-boggling it's so unlikely,\n        # but we should fix this up at some stage.\n        while not self._remote_closed:\n            self._recv_cb()\n\n        return self.response_trailers\n\n    def get_pushes(self, capture_all=False):\n        \"\"\"\n        Returns a generator that yields push promises from the server. Note that\n        this method is not idempotent; promises returned in one call will not be\n        returned in subsequent calls. Iterating through generators returned by\n        multiple calls to this method simultaneously results in undefined\n        behavior.\n\n        :param capture_all: If ``False``, the generator will yield all buffered\n            push promises without blocking. If ``True``, the generator will\n            first yield all buffered push promises, then yield additional ones\n            as they arrive, and terminate when the original stream closes.\n        \"\"\"\n        while True:\n            for pair in list(self.promised_headers.items()):\n                yield pair\n            self.promised_headers = {}\n            if not capture_all or self._remote_closed:\n                break\n            self._recv_cb()\n\n    def close(self, error_code=None):\n        \"\"\"\n        Closes the stream. If the stream is currently open, attempts to close\n        it as gracefully as possible.\n\n        :param error_code: (optional) The error code to reset the stream with.\n        :returns: Nothing.\n        \"\"\"\n        # Right now let's not bother with grace, let's just call close on the\n        # connection. If not error code is provided then assume it is a\n        # gracefull shutdown.\n        self._close_cb(self.stream_id, error_code or 0)\n\n    def _handle_header_block(self, headers):\n        \"\"\"\n        Handles the logic for receiving a completed headers block.\n\n        A headers block is an uninterrupted sequence of one HEADERS frame\n        followed by zero or more CONTINUATION frames, and is terminated by a\n        frame bearing the END_HEADERS flag.\n\n        HTTP/2 allows receipt of up to three such blocks on a stream. The first\n        is optional, and contains a 1XX response. The second is mandatory, and\n        must contain a final response (200 or higher). The third is optional,\n        and may contain 'trailers', headers that are sent after a chunk-encoded\n        body is sent. This method enforces the logic associated with this,\n        storing the headers in the appropriate places.\n        \"\"\"\n        # At this stage we should check for a provisional response (1XX). As\n        # hyper doesn't currently support such responses, we'll leave that as a\n        # TODO.\n        # TODO: Handle 1XX responses here.\n\n        # The header block may be for trailers or headers. If we've already\n        # received headers these _must_ be for trailers.\n        if self.response_headers is None:\n            self.response_headers = HTTPHeaderMap(headers)\n        elif self.response_trailers is None:\n            self.response_trailers = HTTPHeaderMap(headers)\n        else:\n            # Received too many headers blocks.\n            raise ProtocolError(\"Too many header blocks.\")\n\n        return\n\n    def _send_chunk(self, data, final):\n        \"\"\"\n        Implements most of the sending logic.\n\n        Takes a single chunk of size at most MAX_CHUNK, wraps it in a frame and\n        sends it. Optionally sets the END_STREAM flag if this is the last chunk\n        (determined by being of size less than MAX_CHUNK) and no more data is\n        to be sent.\n        \"\"\"\n        assert self._local_open\n\n        f = DataFrame(self.stream_id)\n        f.data = data\n\n        # If the length of the data is less than MAX_CHUNK, we're probably\n        # at the end of the file. If this is the end of the data, mark it\n        # as END_STREAM.\n        if len(data) < MAX_CHUNK and final:\n            f.flags.add(b'END_STREAM')\n\n        # If we don't fit in the connection window, try popping frames off the\n        # connection in hope that one might be a Window Update frame.\n        while len(data) > self._out_flow_control_window:\n            self._recv_cb()\n\n        # Send the frame and decrement the flow control window.\n        self._data_cb(f)\n        self._out_flow_control_window -= len(data)\n\n        # If no more data is to be sent on this stream, transition our state.\n        if len(data) < MAX_CHUNK and final:\n            self._close_local()\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/http20/util.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhyper/http20/util\n~~~~~~~~~~~~~~~~~\n\nUtility functions for use with hyper.\n\"\"\"\nfrom collections import defaultdict\n\n\ndef combine_repeated_headers(kvset):\n    \"\"\"\n    Given a list of key-value pairs (like for HTTP headers!), combines pairs\n    with the same key together, separating the values with NULL bytes. This\n    function maintains the order of input keys, because it's awesome.\n    \"\"\"\n    def set_pop(set, item):\n        set.remove(item)\n        return item\n\n    headers = defaultdict(list)\n    keys = set()\n\n    for key, value in kvset:\n        headers[key].append(value)\n        keys.add(key)\n\n    return [(set_pop(keys, k), b'\\x00'.join(headers[k])) for k, v in kvset\n            if k in keys]\n\ndef split_repeated_headers(kvset):\n    \"\"\"\n    Given a set of key-value pairs (like for HTTP headers!), finds values that\n    have NULL bytes in them and splits them into a dictionary whose values are\n    lists.\n    \"\"\"\n    headers = defaultdict(list)\n\n    for key, value in kvset:\n        headers[key] = value.split(b'\\x00')\n\n    return dict(headers)\n\n\ndef h2_safe_headers(headers):\n    \"\"\"\n    This method takes a set of headers that are provided by the user and\n    transforms them into a form that is safe for emitting over HTTP/2.\n\n    Currently, this strips the Connection header and any header it refers to.\n    \"\"\"\n    stripped = {i.lower().strip() for k, v in headers if k == 'connection'\n                                  for i in v.split(',')}\n    stripped.add('connection')\n\n    return [header for header in headers if header[0] not in stripped]\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/http20/window.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhyper/http20/window\n~~~~~~~~~~~~~~~~~~~\n\nObjects that understand flow control in hyper.\n\nHTTP/2 implements connection- and stream-level flow control. This flow\ncontrol is mandatory. Unfortunately, it's difficult for hyper to be\nall that intelligent about how it manages flow control in a general case.\n\nThis module defines an interface for pluggable flow-control managers. These\nmanagers will define a flow-control policy. This policy will determine when to\nsend WINDOWUPDATE frames.\n\"\"\"\nclass BaseFlowControlManager(object):\n    \"\"\"\n    The abstract base class for flow control managers.\n\n    This class defines the interface for pluggable flow-control managers. A\n    flow-control manager defines a flow-control policy, which basically boils\n    down to deciding when to increase the flow control window.\n\n    This decision can be based on a number of factors:\n\n    - the initial window size,\n    - the size of the document being retrieved,\n    - the size of the received data frames,\n    - any other information the manager can obtain\n\n    A flow-control manager may be defined at the connection level or at the\n    stream level. If no stream-level flow-control manager is defined, an\n    instance of the connection-level flow control manager is used.\n\n    A class that inherits from this one must not adjust the member variables\n    defined in this class. They are updated and set by methods on this class.\n    \"\"\"\n    def __init__(self, initial_window_size, document_size=None):\n        #: The initial size of the connection window in bytes. This is set at\n        #: creation time.\n        self.initial_window_size = initial_window_size\n\n        #: The current size of the connection window. Any methods overridden\n        #: by the user must not adjust this value.\n        self.window_size = initial_window_size\n\n        #: The size of the document being retrieved, in bytes. This is\n        #: retrieved from the Content-Length header, if provided. Note that\n        #: the total number of bytes that will be received may be larger than\n        #: this value due to HTTP/2 padding. It should not be assumed that\n        #: simply because the the document size is smaller than the initial\n        #: window size that there will never be a need to increase the window\n        #: size.\n        self.document_size = document_size\n\n    def increase_window_size(self, frame_size):\n        \"\"\"\n        Determine whether or not to emit a WINDOWUPDATE frame.\n\n        This method should be overridden to determine, based on the state of\n        the system and the size of the received frame, whether or not a\n        WindowUpdate frame should be sent for the stream.\n\n        This method should *not* adjust any of the member variables of this\n        class.\n\n        Note that this method is called before the window size is decremented\n        as a result of the frame being handled.\n\n        :param frame_size: The size of the received frame. Note that this *may*\n          be zero. When this parameter is zero, it's possible that a\n          WINDOWUPDATE frame may want to be emitted anyway. A zero-length frame\n          size is usually associated with a change in the size of the receive\n          window due to a SETTINGS frame.\n        :returns: The amount to increase the receive window by. Return zero if\n          the window should not be increased.\n        \"\"\"\n        raise NotImplementedError(\n            \"FlowControlManager is an abstract base class\"\n        )\n\n    def blocked(self):\n        \"\"\"\n        Called whenever the remote endpoint reports that it is blocked behind\n        the flow control window.\n\n        When this method is called the remote endpoint is signaling that it\n        has more data to send and that the transport layer is capable of\n        transmitting it, but that the HTTP/2 flow control window prevents it\n        being sent.\n\n        This method should return the size by which the window should be\n        incremented, which may be zero. This method should *not* adjust any\n        of the member variables of this class.\n\n        :returns: The amount to increase the receive window by. Return zero if\n          the window should not be increased.\n        \"\"\"\n        raise NotImplementedError(\n            \"FlowControlManager is an abstract base class\"\n        )\n\n    def _handle_frame(self, frame_size):\n        \"\"\"\n        This internal method is called by the connection or stream that owns\n        the flow control manager. It handles the generic behaviour of flow\n        control managers: namely, keeping track of the window size.\n        \"\"\"\n        rc = self.increase_window_size(frame_size)\n        self.window_size -= frame_size\n        self.window_size += rc\n        return rc\n\n    def _blocked(self):\n        \"\"\"\n        This internal method is called by the connection or stream that owns\n        the flow control manager. It handles the generic behaviour of receiving\n        BLOCKED frames.\n        \"\"\"\n        rc = self.blocked()\n        self.window_size += rc\n        return rc\n\n\nclass FlowControlManager(BaseFlowControlManager):\n    \"\"\"\n    ``hyper``'s default flow control manager.\n\n    This implements hyper's flow control algorithms. This algorithm attempts to\n    reduce the number of WINDOWUPDATE frames we send without blocking the remote\n    endpoint behind the flow control window.\n\n    This algorithm will become more complicated over time. In the current form,\n    the algorithm is very simple:\n        - When the flow control window gets less than 1/4 of the maximum size,\n          increment back to the maximum.\n        - Otherwise, if the flow control window gets to less than 1kB, increment\n          back to the maximum.\n    \"\"\"\n    def increase_window_size(self, frame_size):\n        future_window_size = self.window_size - frame_size\n\n        if ((future_window_size < (self.initial_window_size / 4)) or\n            (future_window_size < 1000)):\n            return self.initial_window_size - future_window_size\n\n        return 0\n\n    def blocked(self):\n        return self.initial_window_size - self.window_size\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/httplib_compat.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhyper/httplib_compat\n~~~~~~~~~~~~~~~~~~~~\n\nThis file defines the publicly-accessible API for hyper. This API also\nconstitutes the abstraction layer between HTTP/1.1 and HTTP/2.\n\nThis API doesn't currently work, and is a lower priority than the HTTP/2\nstack at this time.\n\"\"\"\nimport socket\ntry:\n    import http.client as httplib\nexcept ImportError:\n    import http.client\n\nfrom .compat import ssl\nfrom .http20.tls import wrap_socket\n\n# If there's no NPN support, we're going to drop all support for HTTP/2.\ntry:\n    support_20 = ssl.HAS_NPN\nexcept AttributeError:\n    support_20 = False\n\n# The HTTPConnection object is currently always the underlying one.\nHTTPConnection = http.client.HTTPConnection\nHTTPSConnection = http.client.HTTPSConnection\n\n# If we have NPN support, define our custom one, otherwise just use the\n# default.\nif support_20:\n    class HTTPSConnection(object):\n        \"\"\"\n        An object representing a single HTTPS connection, whether HTTP/1.1 or\n        HTTP/2.\n\n        More specifically, this object represents an abstraction over the\n        distinction. This object encapsulates a connection object for one of\n        the specific types of connection, and delegates most of the work to\n        that object.\n        \"\"\"\n        def __init__(self, *args, **kwargs):\n            # Whatever arguments and keyword arguments are passed to this\n            # object need to be saved off for when we initialise one of our\n            # subsidiary objects.\n            self._original_args = args\n            self._original_kwargs = kwargs\n\n            # Set up some variables we're going to use later.\n            self._sock = None\n            self._conn = None\n\n            # Prepare our backlog of method calls.\n            self._call_queue = []\n\n        def __getattr__(self, name):\n            # Anything that can't be found on this instance is presumably a\n            # property of underlying connection object.\n            # We need to be a little bit careful here. There are a few methods\n            # that can act on a HTTPSConnection before it actually connects to\n            # the remote server. We don't want to change the semantics of the,\n            # HTTPSConnection so we need to spot these and queue them up. When\n            # we actually create the backing Connection, we'll apply them\n            # immediately. These methods can't throw exceptions, so we should\n            # be fine.\n            delay_methods = [\"set_tunnel\", \"set_debuglevel\"]\n\n            if self._conn is None and name in delay_methods:\n                # Return a little closure that saves off the method call to\n                # apply later.\n                def capture(obj, *args, **kwargs):\n                    self._call_queue.append((name, args, kwargs))\n                return capture\n            elif self._conn is None:\n                # We're being told to do something! We can now connect to the\n                # remote server and build the connection object.\n                self._delayed_connect()\n\n            # Call through to the underlying object.\n            return getattr(self._conn, name)\n\n        def _delayed_connect(self):\n            \"\"\"\n            Called when we need to work out what kind of HTTPS connection we're\n            actually going to use.\n            \"\"\"\n            # Because we're ghetto, we're going to quickly create a\n            # HTTPConnection object to parse the args and kwargs for us, and\n            # grab the values out.\n            tempconn = http.client.HTTPConnection(*self._original_args,\n                                              **self._original_kwargs)\n            host = tempconn.host\n            port = tempconn.port\n            timeout = tempconn.timeout\n            source_address = tempconn.source_address\n\n            # Connect to the remote server.\n            sock = socket.create_connection(\n                (host, port),\n                timeout,\n                source_address\n            )\n\n            # Wrap it in TLS. This needs to be looked at in future when I pull\n            # in the TLS verification logic from urllib3, but right now we\n            # accept insecurity because no-one's using this anyway.\n            sock = wrap_socket(sock, host)\n\n            # At this early stage the library can't do HTTP/2, so who cares?\n            tempconn.sock = sock\n            self._sock = sock\n            self._conn = tempconn\n\n            return\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/packages/__init__.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhyper/packages\n~~~~~~~~~~~~~~\n\nThis module contains external packages that are vendored into hyper.\n\"\"\"\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/packages/hpack/__init__.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhpack\n~~~~~\n\nHTTP/2 header encoding for Python.\n\"\"\"\nfrom .hpack import Encoder, Decoder\nfrom .struct import HeaderTuple, NeverIndexedHeaderTuple\nfrom .exceptions import (\n    HPACKError, HPACKDecodingError, InvalidTableIndex, OversizedHeaderListError\n)\n\n__all__ = [\n    'Encoder', 'Decoder', 'HPACKError', 'HPACKDecodingError',\n    'InvalidTableIndex', 'HeaderTuple', 'NeverIndexedHeaderTuple',\n    'OversizedHeaderListError'\n]\n\n__version__ = '3.0.0'\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/packages/hpack/compat.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhpack/compat\n~~~~~~~~~~~~\n\nNormalizes the Python 2/3 API for internal use.\n\"\"\"\nimport sys\n\n\n_ver = sys.version_info\nis_py2 = _ver[0] == 2\nis_py3 = _ver[0] == 3\n\nif is_py2:\n    def to_byte(char):\n        return ord(char)\n\n    def decode_hex(b):\n        return b.decode('hex')\n\n    def to_bytes(b):\n        if isinstance(b, memoryview):\n            return b.tobytes()\n        else:\n            return bytes(b)\n\n    str = str  # noqa\n    bytes = str\n\nelif is_py3:\n    def to_byte(char):\n        return char\n\n    def decode_hex(b):\n        return bytes.fromhex(b)\n\n    def to_bytes(b):\n        return bytes(b)\n\n    str = str\n    bytes = bytes\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/packages/hpack/exceptions.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhyper/http20/exceptions\n~~~~~~~~~~~~~~~~~~~~~~~\n\nThis defines exceptions used in the HTTP/2 portion of hyper.\n\"\"\"\n\n\nclass HPACKError(Exception):\n    \"\"\"\n    The base class for all ``hpack`` exceptions.\n    \"\"\"\n    pass\n\n\nclass HPACKDecodingError(HPACKError):\n    \"\"\"\n    An error has been encountered while performing HPACK decoding.\n    \"\"\"\n    pass\n\n\nclass InvalidTableIndex(HPACKDecodingError):\n    \"\"\"\n    An invalid table index was received.\n    \"\"\"\n    pass\n\n\nclass OversizedHeaderListError(HPACKDecodingError):\n    \"\"\"\n    A header list that was larger than we allow has been received. This may be\n    a DoS attack.\n\n    .. versionadded:: 2.3.0\n    \"\"\"\n    pass\n\n\nclass InvalidTableSizeError(HPACKDecodingError):\n    \"\"\"\n    An attempt was made to change the decoder table size to a value larger than\n    allowed, or the list was shrunk and the remote peer didn't shrink their\n    table size.\n\n    .. versionadded:: 3.0.0\n    \"\"\"\n    pass\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/packages/hpack/hpack.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhpack/hpack\n~~~~~~~~~~~\n\nImplements the HPACK header compression algorithm as detailed by the IETF.\n\"\"\"\nimport logging\n\nfrom .table import HeaderTable, table_entry_size\nfrom .compat import to_byte, to_bytes\nfrom .exceptions import (\n    HPACKDecodingError, OversizedHeaderListError, InvalidTableSizeError\n)\nfrom .huffman import HuffmanEncoder\nfrom .huffman_constants import (\n    REQUEST_CODES, REQUEST_CODES_LENGTH\n)\nfrom .huffman_table import decode_huffman\nfrom .struct import HeaderTuple, NeverIndexedHeaderTuple\n\nlog = logging.getLogger(__name__)\n\nINDEX_NONE = b'\\x00'\nINDEX_NEVER = b'\\x10'\nINDEX_INCREMENTAL = b'\\x40'\n\n# Precompute 2^i for 1-8 for use in prefix calcs.\n# Zero index is not used but there to save a subtraction\n# as prefix numbers are not zero indexed.\n_PREFIX_BIT_MAX_NUMBERS = [(2 ** i) - 1 for i in range(9)]\n\ntry:  # pragma: no cover\n    str = str\nexcept NameError:  # pragma: no cover\n    str = (str, bytes)\n\n\n# We default the maximum header list we're willing to accept to 64kB. That's a\n# lot of headers, but if applications want to raise it they can do.\nDEFAULT_MAX_HEADER_LIST_SIZE = 2 ** 16\n\n\ndef _unicode_if_needed(header, raw):\n    \"\"\"\n    Provides a header as a unicode string if raw is False, otherwise returns\n    it as a bytestring.\n    \"\"\"\n    name = to_bytes(header[0])\n    value = to_bytes(header[1])\n    if not raw:\n        name = name.decode('utf-8')\n        value = value.decode('utf-8')\n    return header.__class__(name, value)\n\n\ndef encode_integer(integer, prefix_bits):\n    \"\"\"\n    This encodes an integer according to the wacky integer encoding rules\n    defined in the HPACK spec.\n    \"\"\"\n    log.debug(\"Encoding %d with %d bits\", integer, prefix_bits)\n\n    if integer < 0:\n        raise ValueError(\n            \"Can only encode positive integers, got %s\" % integer\n        )\n\n    if prefix_bits < 1 or prefix_bits > 8:\n        raise ValueError(\n            \"Prefix bits must be between 1 and 8, got %s\" % prefix_bits\n        )\n\n    max_number = _PREFIX_BIT_MAX_NUMBERS[prefix_bits]\n\n    if integer < max_number:\n        return bytearray([integer])  # Seriously?\n    else:\n        elements = [max_number]\n        integer -= max_number\n\n        while integer >= 128:\n            elements.append((integer & 127) + 128)\n            integer >>= 7\n\n        elements.append(integer)\n\n        return bytearray(elements)\n\n\ndef decode_integer(data, prefix_bits):\n    \"\"\"\n    This decodes an integer according to the wacky integer encoding rules\n    defined in the HPACK spec. Returns a tuple of the decoded integer and the\n    number of bytes that were consumed from ``data`` in order to get that\n    integer.\n    \"\"\"\n    if prefix_bits < 1 or prefix_bits > 8:\n        raise ValueError(\n            \"Prefix bits must be between 1 and 8, got %s\" % prefix_bits\n        )\n\n    max_number = _PREFIX_BIT_MAX_NUMBERS[prefix_bits]\n    index = 1\n    shift = 0\n    mask = (0xFF >> (8 - prefix_bits))\n\n    try:\n        number = to_byte(data[0]) & mask\n        if number == max_number:\n            while True:\n                next_byte = to_byte(data[index])\n                index += 1\n\n                if next_byte >= 128:\n                    number += (next_byte - 128) << shift\n                else:\n                    number += next_byte << shift\n                    break\n                shift += 7\n\n    except IndexError:\n        raise HPACKDecodingError(\n            \"Unable to decode HPACK integer representation from %r\" % data\n        )\n\n    log.debug(\"Decoded %d, consumed %d bytes\", number, index)\n\n    return number, index\n\n\ndef _dict_to_iterable(header_dict):\n    \"\"\"\n    This converts a dictionary to an iterable of two-tuples. This is a\n    HPACK-specific function becuase it pulls \"special-headers\" out first and\n    then emits them.\n    \"\"\"\n    assert isinstance(header_dict, dict)\n    keys = sorted(\n        list(header_dict.keys()),\n        key=lambda k: not _to_bytes(k).startswith(b':')\n    )\n    for key in keys:\n        yield key, header_dict[key]\n\n\ndef _to_bytes(string):\n    \"\"\"\n    Convert string to bytes.\n    \"\"\"\n    if isinstance(string, bytes):\n        return string\n    if not isinstance(string, str):  # pragma: no cover\n        string = str(string)\n\n    return string if isinstance(string, bytes) else string.encode('utf-8')\n\n\nclass Encoder(object):\n    \"\"\"\n    An HPACK encoder object. This object takes HTTP headers and emits encoded\n    HTTP/2 header blocks.\n    \"\"\"\n\n    def __init__(self):\n        self.header_table = HeaderTable()\n        self.huffman_coder = HuffmanEncoder(\n            REQUEST_CODES, REQUEST_CODES_LENGTH\n        )\n        self.table_size_changes = []\n\n    @property\n    def header_table_size(self):\n        \"\"\"\n        Controls the size of the HPACK header table.\n        \"\"\"\n        return self.header_table.maxsize\n\n    @header_table_size.setter\n    def header_table_size(self, value):\n        self.header_table.maxsize = value\n        if self.header_table.resized:\n            self.table_size_changes.append(value)\n\n    def encode(self, headers, huffman=True):\n        \"\"\"\n        Takes a set of headers and encodes them into a HPACK-encoded header\n        block.\n\n        :param headers: The headers to encode. Must be either an iterable of\n                        tuples, an iterable of :class:`HeaderTuple\n                        <hpack.struct.HeaderTuple>`, or a ``dict``.\n\n                        If an iterable of tuples, the tuples may be either\n                        two-tuples or three-tuples. If they are two-tuples, the\n                        tuples must be of the format ``(name, value)``. If they\n                        are three-tuples, they must be of the format\n                        ``(name, value, sensitive)``, where ``sensitive`` is a\n                        boolean value indicating whether the header should be\n                        added to header tables anywhere. If not present,\n                        ``sensitive`` defaults to ``False``.\n\n                        If an iterable of :class:`HeaderTuple\n                        <hpack.struct.HeaderTuple>`, the tuples must always be\n                        two-tuples. Instead of using ``sensitive`` as a third\n                        tuple entry, use :class:`NeverIndexedHeaderTuple\n                        <hpack.struct.NeverIndexedHeaderTuple>` to request that\n                        the field never be indexed.\n\n                        .. warning:: HTTP/2 requires that all special headers\n                            (headers whose names begin with ``:`` characters)\n                            appear at the *start* of the header block. While\n                            this method will ensure that happens for ``dict``\n                            subclasses, callers using any other iterable of\n                            tuples **must** ensure they place their special\n                            headers at the start of the iterable.\n\n                            For efficiency reasons users should prefer to use\n                            iterables of two-tuples: fixing the ordering of\n                            dictionary headers is an expensive operation that\n                            should be avoided if possible.\n\n        :param huffman: (optional) Whether to Huffman-encode any header sent as\n                        a literal value. Except for use when debugging, it is\n                        recommended that this be left enabled.\n\n        :returns: A bytestring containing the HPACK-encoded header block.\n        \"\"\"\n        # Transforming the headers into a header block is a procedure that can\n        # be modeled as a chain or pipe. First, the headers are encoded. This\n        # encoding can be done a number of ways. If the header name-value pair\n        # are already in the header table we can represent them using the\n        # indexed representation: the same is true if they are in the static\n        # table. Otherwise, a literal representation will be used.\n        log.debug(\"HPACK encoding %s\", headers)\n        header_block = []\n\n        # Turn the headers into a list of tuples if possible. This is the\n        # natural way to interact with them in HPACK. Because dictionaries are\n        # un-ordered, we need to make sure we grab the \"special\" headers first.\n        if isinstance(headers, dict):\n            headers = _dict_to_iterable(headers)\n\n        # Before we begin, if the header table size has been changed we need\n        # to signal all changes since last emission appropriately.\n        if self.header_table.resized:\n            header_block.append(self._encode_table_size_change())\n            self.header_table.resized = False\n\n        # Add each header to the header block\n        for header in headers:\n            sensitive = False\n            if isinstance(header, HeaderTuple):\n                sensitive = not header.indexable\n            elif len(header) > 2:\n                sensitive = header[2]\n\n            header = (_to_bytes(header[0]), _to_bytes(header[1]))\n            header_block.append(self.add(header, sensitive, huffman))\n\n        header_block = b''.join(header_block)\n\n        log.debug(\"Encoded header block to %s\", header_block)\n\n        return header_block\n\n    def add(self, to_add, sensitive, huffman=False):\n        \"\"\"\n        This function takes a header key-value tuple and serializes it.\n        \"\"\"\n        log.debug(\"Adding %s to the header table\", to_add)\n\n        name, value = to_add\n\n        # Set our indexing mode\n        indexbit = INDEX_INCREMENTAL if not sensitive else INDEX_NEVER\n\n        # Search for a matching header in the header table.\n        match = self.header_table.search(name, value)\n\n        if match is None:\n            # Not in the header table. Encode using the literal syntax,\n            # and add it to the header table.\n            encoded = self._encode_literal(name, value, indexbit, huffman)\n            if not sensitive:\n                self.header_table.add(name, value)\n            return encoded\n\n        # The header is in the table, break out the values. If we matched\n        # perfectly, we can use the indexed representation: otherwise we\n        # can use the indexed literal.\n        index, name, perfect = match\n\n        if perfect:\n            # Indexed representation.\n            encoded = self._encode_indexed(index)\n        else:\n            # Indexed literal. We are going to add header to the\n            # header table unconditionally. It is a future todo to\n            # filter out headers which are known to be ineffective for\n            # indexing since they just take space in the table and\n            # pushed out other valuable headers.\n            encoded = self._encode_indexed_literal(\n                index, value, indexbit, huffman\n            )\n            if not sensitive:\n                self.header_table.add(name, value)\n\n        return encoded\n\n    def _encode_indexed(self, index):\n        \"\"\"\n        Encodes a header using the indexed representation.\n        \"\"\"\n        field = encode_integer(index, 7)\n        field[0] |= 0x80  # we set the top bit\n        return bytes(field)\n\n    def _encode_literal(self, name, value, indexbit, huffman=False):\n        \"\"\"\n        Encodes a header with a literal name and literal value. If ``indexing``\n        is True, the header will be added to the header table: otherwise it\n        will not.\n        \"\"\"\n        if huffman:\n            name = self.huffman_coder.encode(name)\n            value = self.huffman_coder.encode(value)\n\n        name_len = encode_integer(len(name), 7)\n        value_len = encode_integer(len(value), 7)\n\n        if huffman:\n            name_len[0] |= 0x80\n            value_len[0] |= 0x80\n\n        return b''.join(\n            [indexbit, bytes(name_len), name, bytes(value_len), value]\n        )\n\n    def _encode_indexed_literal(self, index, value, indexbit, huffman=False):\n        \"\"\"\n        Encodes a header with an indexed name and a literal value and performs\n        incremental indexing.\n        \"\"\"\n        if indexbit != INDEX_INCREMENTAL:\n            prefix = encode_integer(index, 4)\n        else:\n            prefix = encode_integer(index, 6)\n\n        prefix[0] |= ord(indexbit)\n\n        if huffman:\n            value = self.huffman_coder.encode(value)\n\n        value_len = encode_integer(len(value), 7)\n\n        if huffman:\n            value_len[0] |= 0x80\n\n        return b''.join([bytes(prefix), bytes(value_len), value])\n\n    def _encode_table_size_change(self):\n        \"\"\"\n        Produces the encoded form of all header table size change context\n        updates.\n        \"\"\"\n        block = b''\n        for size_bytes in self.table_size_changes:\n            size_bytes = encode_integer(size_bytes, 5)\n            size_bytes[0] |= 0x20\n            block += bytes(size_bytes)\n        self.table_size_changes = []\n        return block\n\n\nclass Decoder(object):\n    \"\"\"\n    An HPACK decoder object.\n\n    .. versionchanged:: 2.3.0\n       Added ``max_header_list_size`` argument.\n\n    :param max_header_list_size: The maximum decompressed size we will allow\n        for any single header block. This is a protection against DoS attacks\n        that attempt to force the application to expand a relatively small\n        amount of data into a really large header list, allowing enormous\n        amounts of memory to be allocated.\n\n        If this amount of data is exceeded, a `OversizedHeaderListError\n        <hpack.OversizedHeaderListError>` exception will be raised. At this\n        point the connection should be shut down, as the HPACK state will no\n        longer be useable.\n\n        Defaults to 64kB.\n    :type max_header_list_size: ``int``\n    \"\"\"\n    def __init__(self, max_header_list_size=DEFAULT_MAX_HEADER_LIST_SIZE):\n        self.header_table = HeaderTable()\n\n        #: The maximum decompressed size we will allow for any single header\n        #: block. This is a protection against DoS attacks that attempt to\n        #: force the application to expand a relatively small amount of data\n        #: into a really large header list, allowing enormous amounts of memory\n        #: to be allocated.\n        #:\n        #: If this amount of data is exceeded, a `OversizedHeaderListError\n        #: <hpack.OversizedHeaderListError>` exception will be raised. At this\n        #: point the connection should be shut down, as the HPACK state will no\n        #: longer be usable.\n        #:\n        #: Defaults to 64kB.\n        #:\n        #: .. versionadded:: 2.3.0\n        self.max_header_list_size = max_header_list_size\n\n        #: Maximum allowed header table size.\n        #:\n        #: A HTTP/2 implementation should set this to the most recent value of\n        #: SETTINGS_HEADER_TABLE_SIZE that it sent *and has received an ACK\n        #: for*. Once this setting is set, the actual header table size will be\n        #: checked at the end of each decoding run and whenever it is changed,\n        #: to confirm that it fits in this size.\n        self.max_allowed_table_size = self.header_table.maxsize\n\n    @property\n    def header_table_size(self):\n        \"\"\"\n        Controls the size of the HPACK header table.\n        \"\"\"\n        return self.header_table.maxsize\n\n    @header_table_size.setter\n    def header_table_size(self, value):\n        self.header_table.maxsize = value\n\n    def decode(self, data, raw=False):\n        \"\"\"\n        Takes an HPACK-encoded header block and decodes it into a header set.\n\n        :param data: A bytestring representing a complete HPACK-encoded header\n                     block.\n        :param raw: (optional) Whether to return the headers as tuples of raw\n                    byte strings or to decode them as UTF-8 before returning\n                    them. The default value is False, which returns tuples of\n                    Unicode strings\n        :returns: A list of two-tuples of ``(name, value)`` representing the\n                  HPACK-encoded headers, in the order they were decoded.\n        :raises HPACKDecodingError: If an error is encountered while decoding\n                                    the header block.\n        \"\"\"\n        log.debug(\"Decoding %s\", data)\n\n        if not isinstance(data, memoryview):\n            data_mem = memoryview(data)\n        else:\n            data_mem = data\n        headers = []\n        data_len = len(data)\n        inflated_size = 0\n        current_index = 0\n\n        while current_index < data_len:\n            # Work out what kind of header we're decoding.\n            # If the high bit is 1, it's an indexed field.\n            current = to_byte(data[current_index])\n            indexed = True if current & 0x80 else False\n\n            # Otherwise, if the second-highest bit is 1 it's a field that does\n            # alter the header table.\n            literal_index = True if current & 0x40 else False\n\n            # Otherwise, if the third-highest bit is 1 it's an encoding context\n            # update.\n            encoding_update = True if current & 0x20 else False\n\n            if indexed:\n                header, consumed = self._decode_indexed(\n                    data_mem[current_index:]\n                )\n            elif literal_index:\n                # It's a literal header that does affect the header table.\n                header, consumed = self._decode_literal_index(\n                    data_mem[current_index:]\n                )\n            elif encoding_update:\n                # It's an update to the encoding context. These are forbidden\n                # in a header block after any actual header.\n                if headers:\n                    raise HPACKDecodingError(\n                        \"Table size update not at the start of the block\"\n                    )\n                consumed = self._update_encoding_context(\n                    data_mem[current_index:]\n                )\n                header = None\n            else:\n                # It's a literal header that does not affect the header table.\n                header, consumed = self._decode_literal_no_index(\n                    data_mem[current_index:]\n                )\n\n            if header:\n                headers.append(header)\n                inflated_size += table_entry_size(*header)\n\n                if inflated_size > self.max_header_list_size:\n                    raise OversizedHeaderListError(\n                        \"A header list larger than %d has been received\" %\n                        self.max_header_list_size\n                    )\n\n            current_index += consumed\n\n        # Confirm that the table size is lower than the maximum. We do this\n        # here to ensure that we catch when the max has been *shrunk* and the\n        # remote peer hasn't actually done that.\n        self._assert_valid_table_size()\n\n        try:\n            return [_unicode_if_needed(h, raw) for h in headers]\n        except UnicodeDecodeError:\n            raise HPACKDecodingError(\"Unable to decode headers as UTF-8.\")\n\n    def _assert_valid_table_size(self):\n        \"\"\"\n        Check that the table size set by the encoder is lower than the maximum\n        we expect to have.\n        \"\"\"\n        if self.header_table_size > self.max_allowed_table_size:\n            raise InvalidTableSizeError(\n                \"Encoder did not shrink table size to within the max\"\n            )\n\n    def _update_encoding_context(self, data):\n        \"\"\"\n        Handles a byte that updates the encoding context.\n        \"\"\"\n        # We've been asked to resize the header table.\n        new_size, consumed = decode_integer(data, 5)\n        if new_size > self.max_allowed_table_size:\n            raise InvalidTableSizeError(\n                \"Encoder exceeded max allowable table size\"\n            )\n        self.header_table_size = new_size\n        return consumed\n\n    def _decode_indexed(self, data):\n        \"\"\"\n        Decodes a header represented using the indexed representation.\n        \"\"\"\n        index, consumed = decode_integer(data, 7)\n        header = HeaderTuple(*self.header_table.get_by_index(index))\n        log.debug(\"Decoded %s, consumed %d\", header, consumed)\n        return header, consumed\n\n    def _decode_literal_no_index(self, data):\n        return self._decode_literal(data, False)\n\n    def _decode_literal_index(self, data):\n        return self._decode_literal(data, True)\n\n    def _decode_literal(self, data, should_index):\n        \"\"\"\n        Decodes a header represented with a literal.\n        \"\"\"\n        total_consumed = 0\n\n        # When should_index is true, if the low six bits of the first byte are\n        # nonzero, the header name is indexed.\n        # When should_index is false, if the low four bits of the first byte\n        # are nonzero the header name is indexed.\n        if should_index:\n            indexed_name = to_byte(data[0]) & 0x3F\n            name_len = 6\n            not_indexable = False\n        else:\n            high_byte = to_byte(data[0])\n            indexed_name = high_byte & 0x0F\n            name_len = 4\n            not_indexable = high_byte & 0x10\n\n        if indexed_name:\n            # Indexed header name.\n            index, consumed = decode_integer(data, name_len)\n            name = self.header_table.get_by_index(index)[0]\n\n            total_consumed = consumed\n            length = 0\n        else:\n            # Literal header name. The first byte was consumed, so we need to\n            # move forward.\n            data = data[1:]\n\n            length, consumed = decode_integer(data, 7)\n            name = data[consumed:consumed + length]\n            if len(name) != length:\n                raise HPACKDecodingError(\"Truncated header block\")\n\n            if to_byte(data[0]) & 0x80:\n                name = decode_huffman(name)\n            total_consumed = consumed + length + 1  # Since we moved forward 1.\n\n        data = data[consumed + length:]\n\n        # The header value is definitely length-based.\n        length, consumed = decode_integer(data, 7)\n        value = data[consumed:consumed + length]\n        if len(value) != length:\n            raise HPACKDecodingError(\"Truncated header block\")\n\n        if to_byte(data[0]) & 0x80:\n            value = decode_huffman(value)\n\n        # Updated the total consumed length.\n        total_consumed += length + consumed\n\n        # If we have been told never to index the header field, encode that in\n        # the tuple we use.\n        if not_indexable:\n            header = NeverIndexedHeaderTuple(name, value)\n        else:\n            header = HeaderTuple(name, value)\n\n        # If we've been asked to index this, add it to the header table.\n        if should_index:\n            self.header_table.add(name, value)\n\n        log.debug(\n            \"Decoded %s, total consumed %d bytes, indexed %s\",\n            header,\n            total_consumed,\n            should_index\n        )\n\n        return header, total_consumed\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/packages/hpack/hpack_compat.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhpack/hpack_compat\n~~~~~~~~~~~~~~~~~~\n\nProvides an abstraction layer over two HPACK implementations.\n\nThis module has a pure-Python greenfield HPACK implementation that can be used\non all Python platforms. However, this implementation is both slower and more\nmemory-hungry than could be achieved with a C-language version. Additionally,\nnghttp2's HPACK implementation currently achieves better compression ratios\nthan hyper's in almost all benchmarks.\n\nFor those who care about efficiency and speed in HPACK, this module allows you\nto use nghttp2's HPACK implementation instead of ours. This module detects\nwhether the nghttp2 bindings are installed, and if they are it wraps them in\na hpack-compatible API and uses them instead of its own. If not, it falls back\nto the built-in Python bindings.\n\"\"\"\nimport logging\nfrom .hpack import _to_bytes\n\nlog = logging.getLogger(__name__)\n\n# Attempt to import nghttp2.\ntry:\n    import nghttp2\n    USE_NGHTTP2 = True\n    log.debug(\"Using nghttp2's HPACK implementation.\")\nexcept ImportError:\n    USE_NGHTTP2 = False\n    log.debug(\"Using our pure-Python HPACK implementation.\")\n\nif USE_NGHTTP2:  # noqa\n    class Encoder(object):\n        \"\"\"\n        An HPACK encoder object. This object takes HTTP headers and emits\n        encoded HTTP/2 header blocks.\n        \"\"\"\n        def __init__(self):\n            self._e = nghttp2.HDDeflater()\n\n        @property\n        def header_table_size(self):\n            \"\"\"\n            Returns the header table size. For the moment this isn't\n            useful, so we don't use it.\n            \"\"\"\n            raise NotImplementedError()\n\n        @header_table_size.setter\n        def header_table_size(self, value):\n            log.debug(\"Setting header table size to %d\", value)\n            self._e.change_table_size(value)\n\n        def encode(self, headers, huffman=True):\n            \"\"\"\n            Encode the headers. The huffman parameter has no effect, it is\n            simply present for compatibility.\n            \"\"\"\n            log.debug(\"HPACK encoding %s\", headers)\n\n            # Turn the headers into a list of tuples if possible. This is the\n            # natural way to interact with them in HPACK.\n            if isinstance(headers, dict):\n                headers = list(headers.items())\n\n            # Next, walk across the headers and turn them all into bytestrings.\n            headers = [(_to_bytes(n), _to_bytes(v)) for n, v in headers]\n\n            # Now, let nghttp2 do its thing.\n            header_block = self._e.deflate(headers)\n\n            return header_block\n\n    class Decoder(object):\n        \"\"\"\n        An HPACK decoder object.\n        \"\"\"\n        def __init__(self):\n            self._d = nghttp2.HDInflater()\n\n        @property\n        def header_table_size(self):\n            \"\"\"\n            Returns the header table size. For the moment this isn't\n            useful, so we don't use it.\n            \"\"\"\n            raise NotImplementedError()\n\n        @header_table_size.setter\n        def header_table_size(self, value):\n            log.debug(\"Setting header table size to %d\", value)\n            self._d.change_table_size(value)\n\n        def decode(self, data):\n            \"\"\"\n            Takes an HPACK-encoded header block and decodes it into a header\n            set.\n            \"\"\"\n            log.debug(\"Decoding %s\", data)\n\n            headers = self._d.inflate(data)\n            return [(n.decode('utf-8'), v.decode('utf-8')) for n, v in headers]\nelse:\n    # Grab the built-in encoder and decoder.\n    from .hpack import Encoder, Decoder  # noqa\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/packages/hpack/huffman.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhpack/huffman_decoder\n~~~~~~~~~~~~~~~~~~~~~\n\nAn implementation of a bitwise prefix tree specially built for decoding\nHuffman-coded content where we already know the Huffman table.\n\"\"\"\nfrom .compat import to_byte, decode_hex\n\n\nclass HuffmanEncoder(object):\n    \"\"\"\n    Encodes a string according to the Huffman encoding table defined in the\n    HPACK specification.\n    \"\"\"\n    def __init__(self, huffman_code_list, huffman_code_list_lengths):\n        self.huffman_code_list = huffman_code_list\n        self.huffman_code_list_lengths = huffman_code_list_lengths\n\n    def encode(self, bytes_to_encode):\n        \"\"\"\n        Given a string of bytes, encodes them according to the HPACK Huffman\n        specification.\n        \"\"\"\n        # If handed the empty string, just immediately return.\n        if not bytes_to_encode:\n            return b''\n\n        final_num = 0\n        final_int_len = 0\n\n        # Turn each byte into its huffman code. These codes aren't necessarily\n        # octet aligned, so keep track of how far through an octet we are. To\n        # handle this cleanly, just use a single giant integer.\n        for char in bytes_to_encode:\n            byte = to_byte(char)\n            bin_int_len = self.huffman_code_list_lengths[byte]\n            bin_int = self.huffman_code_list[byte] & (\n                2 ** (bin_int_len + 1) - 1\n            )\n            final_num <<= bin_int_len\n            final_num |= bin_int\n            final_int_len += bin_int_len\n\n        # Pad out to an octet with ones.\n        bits_to_be_padded = (8 - (final_int_len % 8)) % 8\n        final_num <<= bits_to_be_padded\n        final_num |= (1 << bits_to_be_padded) - 1\n\n        # Convert the number to hex and strip off the leading '0x' and the\n        # trailing 'L', if present.\n        final_num = hex(final_num)[2:].rstrip('L')\n\n        # If this is odd, prepend a zero.\n        final_num = '0' + final_num if len(final_num) % 2 != 0 else final_num\n\n        # This number should have twice as many digits as bytes. If not, we're\n        # missing some leading zeroes. Work out how many bytes we want and how\n        # many digits we have, then add the missing zero digits to the front.\n        total_bytes = (final_int_len + bits_to_be_padded) // 8\n        expected_digits = total_bytes * 2\n\n        if len(final_num) != expected_digits:\n            missing_digits = expected_digits - len(final_num)\n            final_num = ('0' * missing_digits) + final_num\n\n        return decode_hex(final_num)\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/packages/hpack/huffman_constants.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhpack/huffman_constants\n~~~~~~~~~~~~~~~~~~~~~~~\n\nDefines the constant Huffman table. This takes up an upsetting amount of space,\nbut c'est la vie.\n\"\"\"\n\nREQUEST_CODES = [\n    0x1ff8,\n    0x7fffd8,\n    0xfffffe2,\n    0xfffffe3,\n    0xfffffe4,\n    0xfffffe5,\n    0xfffffe6,\n    0xfffffe7,\n    0xfffffe8,\n    0xffffea,\n    0x3ffffffc,\n    0xfffffe9,\n    0xfffffea,\n    0x3ffffffd,\n    0xfffffeb,\n    0xfffffec,\n    0xfffffed,\n    0xfffffee,\n    0xfffffef,\n    0xffffff0,\n    0xffffff1,\n    0xffffff2,\n    0x3ffffffe,\n    0xffffff3,\n    0xffffff4,\n    0xffffff5,\n    0xffffff6,\n    0xffffff7,\n    0xffffff8,\n    0xffffff9,\n    0xffffffa,\n    0xffffffb,\n    0x14,\n    0x3f8,\n    0x3f9,\n    0xffa,\n    0x1ff9,\n    0x15,\n    0xf8,\n    0x7fa,\n    0x3fa,\n    0x3fb,\n    0xf9,\n    0x7fb,\n    0xfa,\n    0x16,\n    0x17,\n    0x18,\n    0x0,\n    0x1,\n    0x2,\n    0x19,\n    0x1a,\n    0x1b,\n    0x1c,\n    0x1d,\n    0x1e,\n    0x1f,\n    0x5c,\n    0xfb,\n    0x7ffc,\n    0x20,\n    0xffb,\n    0x3fc,\n    0x1ffa,\n    0x21,\n    0x5d,\n    0x5e,\n    0x5f,\n    0x60,\n    0x61,\n    0x62,\n    0x63,\n    0x64,\n    0x65,\n    0x66,\n    0x67,\n    0x68,\n    0x69,\n    0x6a,\n    0x6b,\n    0x6c,\n    0x6d,\n    0x6e,\n    0x6f,\n    0x70,\n    0x71,\n    0x72,\n    0xfc,\n    0x73,\n    0xfd,\n    0x1ffb,\n    0x7fff0,\n    0x1ffc,\n    0x3ffc,\n    0x22,\n    0x7ffd,\n    0x3,\n    0x23,\n    0x4,\n    0x24,\n    0x5,\n    0x25,\n    0x26,\n    0x27,\n    0x6,\n    0x74,\n    0x75,\n    0x28,\n    0x29,\n    0x2a,\n    0x7,\n    0x2b,\n    0x76,\n    0x2c,\n    0x8,\n    0x9,\n    0x2d,\n    0x77,\n    0x78,\n    0x79,\n    0x7a,\n    0x7b,\n    0x7ffe,\n    0x7fc,\n    0x3ffd,\n    0x1ffd,\n    0xffffffc,\n    0xfffe6,\n    0x3fffd2,\n    0xfffe7,\n    0xfffe8,\n    0x3fffd3,\n    0x3fffd4,\n    0x3fffd5,\n    0x7fffd9,\n    0x3fffd6,\n    0x7fffda,\n    0x7fffdb,\n    0x7fffdc,\n    0x7fffdd,\n    0x7fffde,\n    0xffffeb,\n    0x7fffdf,\n    0xffffec,\n    0xffffed,\n    0x3fffd7,\n    0x7fffe0,\n    0xffffee,\n    0x7fffe1,\n    0x7fffe2,\n    0x7fffe3,\n    0x7fffe4,\n    0x1fffdc,\n    0x3fffd8,\n    0x7fffe5,\n    0x3fffd9,\n    0x7fffe6,\n    0x7fffe7,\n    0xffffef,\n    0x3fffda,\n    0x1fffdd,\n    0xfffe9,\n    0x3fffdb,\n    0x3fffdc,\n    0x7fffe8,\n    0x7fffe9,\n    0x1fffde,\n    0x7fffea,\n    0x3fffdd,\n    0x3fffde,\n    0xfffff0,\n    0x1fffdf,\n    0x3fffdf,\n    0x7fffeb,\n    0x7fffec,\n    0x1fffe0,\n    0x1fffe1,\n    0x3fffe0,\n    0x1fffe2,\n    0x7fffed,\n    0x3fffe1,\n    0x7fffee,\n    0x7fffef,\n    0xfffea,\n    0x3fffe2,\n    0x3fffe3,\n    0x3fffe4,\n    0x7ffff0,\n    0x3fffe5,\n    0x3fffe6,\n    0x7ffff1,\n    0x3ffffe0,\n    0x3ffffe1,\n    0xfffeb,\n    0x7fff1,\n    0x3fffe7,\n    0x7ffff2,\n    0x3fffe8,\n    0x1ffffec,\n    0x3ffffe2,\n    0x3ffffe3,\n    0x3ffffe4,\n    0x7ffffde,\n    0x7ffffdf,\n    0x3ffffe5,\n    0xfffff1,\n    0x1ffffed,\n    0x7fff2,\n    0x1fffe3,\n    0x3ffffe6,\n    0x7ffffe0,\n    0x7ffffe1,\n    0x3ffffe7,\n    0x7ffffe2,\n    0xfffff2,\n    0x1fffe4,\n    0x1fffe5,\n    0x3ffffe8,\n    0x3ffffe9,\n    0xffffffd,\n    0x7ffffe3,\n    0x7ffffe4,\n    0x7ffffe5,\n    0xfffec,\n    0xfffff3,\n    0xfffed,\n    0x1fffe6,\n    0x3fffe9,\n    0x1fffe7,\n    0x1fffe8,\n    0x7ffff3,\n    0x3fffea,\n    0x3fffeb,\n    0x1ffffee,\n    0x1ffffef,\n    0xfffff4,\n    0xfffff5,\n    0x3ffffea,\n    0x7ffff4,\n    0x3ffffeb,\n    0x7ffffe6,\n    0x3ffffec,\n    0x3ffffed,\n    0x7ffffe7,\n    0x7ffffe8,\n    0x7ffffe9,\n    0x7ffffea,\n    0x7ffffeb,\n    0xffffffe,\n    0x7ffffec,\n    0x7ffffed,\n    0x7ffffee,\n    0x7ffffef,\n    0x7fffff0,\n    0x3ffffee,\n    0x3fffffff,\n]\n\nREQUEST_CODES_LENGTH = [\n    13, 23, 28, 28, 28, 28, 28, 28, 28, 24, 30, 28, 28, 30, 28, 28,\n    28, 28, 28, 28, 28, 28, 30, 28, 28, 28, 28, 28, 28, 28, 28, 28,\n     6, 10, 10, 12, 13,  6,  8, 11, 10, 10,  8, 11,  8,  6,  6,  6,\n     5,  5,  5,  6,  6,  6,  6,  6,  6,  6,  7,  8, 15,  6, 12, 10,\n    13,  6,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,\n     7,  7,  7,  7,  7,  7,  7,  7,  8,  7,  8, 13, 19, 13, 14,  6,\n    15,  5,  6,  5,  6,  5,  6,  6,  6,  5,  7,  7,  6,  6,  6,  5,\n     6,  7,  6,  5,  5,  6,  7,  7,  7,  7,  7, 15, 11, 14, 13, 28,\n    20, 22, 20, 20, 22, 22, 22, 23, 22, 23, 23, 23, 23, 23, 24, 23,\n    24, 24, 22, 23, 24, 23, 23, 23, 23, 21, 22, 23, 22, 23, 23, 24,\n    22, 21, 20, 22, 22, 23, 23, 21, 23, 22, 22, 24, 21, 22, 23, 23,\n    21, 21, 22, 21, 23, 22, 23, 23, 20, 22, 22, 22, 23, 22, 22, 23,\n    26, 26, 20, 19, 22, 23, 22, 25, 26, 26, 26, 27, 27, 26, 24, 25,\n    19, 21, 26, 27, 27, 26, 27, 24, 21, 21, 26, 26, 28, 27, 27, 27,\n    20, 24, 20, 21, 22, 21, 21, 23, 22, 22, 25, 25, 24, 24, 26, 23,\n    26, 27, 26, 26, 27, 27, 27, 27, 27, 28, 27, 27, 27, 27, 27, 26,\n    30,\n]\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/packages/hpack/huffman_table.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhpack/huffman_table\n~~~~~~~~~~~~~~~~~~~\n\nThis implementation of a Huffman decoding table for HTTP/2 is essentially a\nPython port of the work originally done for nghttp2's Huffman decoding. For\nthis reason, while this file is made available under the MIT license as is the\nrest of this module, this file is undoubtedly a derivative work of the nghttp2\nfile ``nghttp2_hd_huffman_data.c``, obtained from\nhttps://github.com/tatsuhiro-t/nghttp2/ at commit\nd2b55ad1a245e1d1964579fa3fac36ebf3939e72. That work is made available under\nthe Apache 2.0 license under the following terms:\n\n    Copyright (c) 2013 Tatsuhiro Tsujikawa\n\n    Permission is hereby granted, free of charge, to any person obtaining\n    a copy of this software and associated documentation files (the\n    \"Software\"), to deal in the Software without restriction, including\n    without limitation the rights to use, copy, modify, merge, publish,\n    distribute, sublicense, and/or sell copies of the Software, and to\n    permit persons to whom the Software is furnished to do so, subject to\n    the following conditions:\n\n    The above copyright notice and this permission notice shall be\n    included in all copies or substantial portions of the Software.\n\n    THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\n    LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n    OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\n    WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nThe essence of this approach is that it builds a finite state machine out of\n4-bit nibbles of Huffman coded data. The input function passes 4 bits worth of\ndata to the state machine each time, which uses those 4 bits of data along with\nthe current accumulated state data to process the data given.\n\nFor the sake of efficiency, the in-memory representation of the states,\ntransitions, and result values of the state machine are represented as a long\nlist containing three-tuples. This list is enormously long, and viewing it as\nan in-memory representation is not very clear, but it is laid out here in a way\nthat is intended to be *somewhat* more clear.\n\nEssentially, the list is structured as 256 collections of 16 entries (one for\neach nibble) of three-tuples. Each collection is called a \"node\", and the\nzeroth collection is called the \"root node\". The state machine tracks one\nvalue: the \"state\" byte.\n\nFor each nibble passed to the state machine, it first multiplies the \"state\"\nbyte by 16 and adds the numerical value of the nibble. This number is the index\ninto the large flat list.\n\nThe three-tuple that is found by looking up that index consists of three\nvalues:\n\n- a new state value, used for subsequent decoding\n- a collection of flags, used to determine whether data is emitted or whether\n  the state machine is complete.\n- the byte value to emit, assuming that emitting a byte is required.\n\nThe flags are consulted, if necessary a byte is emitted, and then the next\nnibble is used. This continues until the state machine believes it has\ncompletely Huffman-decoded the data.\n\nThis approach has relatively little indirection, and therefore performs\nrelatively well, particularly on implementations like PyPy where the cost of\nloops at the Python-level is not too expensive. The total number of loop\niterations is 4x the number of bytes passed to the decoder.\n\"\"\"\nfrom .exceptions import HPACKDecodingError\n\n\n# This defines the state machine \"class\" at the top of the file. The reason we\n# do this is to keep the terrifing monster state table at the *bottom* of the\n# file so you don't have to actually *look* at the damn thing.\ndef decode_huffman(huffman_string):\n    \"\"\"\n    Given a bytestring of Huffman-encoded data for HPACK, returns a bytestring\n    of the decompressed data.\n    \"\"\"\n    if not huffman_string:\n        return b''\n\n    state = 0\n    flags = 0\n    decoded_bytes = bytearray()\n\n    # Perversely, bytearrays are a lot more convenient across Python 2 and\n    # Python 3 because they behave *the same way* on both platforms. Given that\n    # we really do want numerical bytes when we iterate here, let's use a\n    # bytearray.\n    huffman_string = bytearray(huffman_string)\n\n    # This loop is unrolled somewhat. Because we use a nibble, not a byte, we\n    # need to handle each nibble twice. We unroll that: it makes the loop body\n    # a bit longer, but that's ok.\n    for input_byte in huffman_string:\n        index = (state * 16) + (input_byte >> 4)\n        state, flags, output_byte = HUFFMAN_TABLE[index]\n\n        if flags & HUFFMAN_FAIL:\n            raise HPACKDecodingError(\"Invalid Huffman String\")\n\n        if flags & HUFFMAN_EMIT_SYMBOL:\n            decoded_bytes.append(output_byte)\n\n        index = (state * 16) + (input_byte & 0x0F)\n        state, flags, output_byte = HUFFMAN_TABLE[index]\n\n        if flags & HUFFMAN_FAIL:\n            raise HPACKDecodingError(\"Invalid Huffman String\")\n\n        if flags & HUFFMAN_EMIT_SYMBOL:\n            decoded_bytes.append(output_byte)\n\n    if not (flags & HUFFMAN_COMPLETE):\n        raise HPACKDecodingError(\"Incomplete Huffman string\")\n\n    return bytes(decoded_bytes)\n\n\n# Some decoder flags to control state transitions.\nHUFFMAN_COMPLETE = 1\nHUFFMAN_EMIT_SYMBOL = (1 << 1)\nHUFFMAN_FAIL = (1 << 2)\n\n# This is the monster table. Avert your eyes, children.\nHUFFMAN_TABLE = [\n    # Node 0 (Root Node, never emits symbols.)\n    (4, 0, 0),\n    (5, 0, 0),\n    (7, 0, 0),\n    (8, 0, 0),\n    (11, 0, 0),\n    (12, 0, 0),\n    (16, 0, 0),\n    (19, 0, 0),\n    (25, 0, 0),\n    (28, 0, 0),\n    (32, 0, 0),\n    (35, 0, 0),\n    (42, 0, 0),\n    (49, 0, 0),\n    (57, 0, 0),\n    (64, HUFFMAN_COMPLETE, 0),\n\n    # Node 1\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 48),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 49),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 50),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 97),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 99),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 101),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 105),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 111),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 115),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 116),\n    (13, 0, 0),\n    (14, 0, 0),\n    (17, 0, 0),\n    (18, 0, 0),\n    (20, 0, 0),\n    (21, 0, 0),\n\n    # Node 2\n    (1, HUFFMAN_EMIT_SYMBOL, 48),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 48),\n    (1, HUFFMAN_EMIT_SYMBOL, 49),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 49),\n    (1, HUFFMAN_EMIT_SYMBOL, 50),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 50),\n    (1, HUFFMAN_EMIT_SYMBOL, 97),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 97),\n    (1, HUFFMAN_EMIT_SYMBOL, 99),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 99),\n    (1, HUFFMAN_EMIT_SYMBOL, 101),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 101),\n    (1, HUFFMAN_EMIT_SYMBOL, 105),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 105),\n    (1, HUFFMAN_EMIT_SYMBOL, 111),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 111),\n\n    # Node 3\n    (2, HUFFMAN_EMIT_SYMBOL, 48),\n    (9, HUFFMAN_EMIT_SYMBOL, 48),\n    (23, HUFFMAN_EMIT_SYMBOL, 48),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 48),\n    (2, HUFFMAN_EMIT_SYMBOL, 49),\n    (9, HUFFMAN_EMIT_SYMBOL, 49),\n    (23, HUFFMAN_EMIT_SYMBOL, 49),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 49),\n    (2, HUFFMAN_EMIT_SYMBOL, 50),\n    (9, HUFFMAN_EMIT_SYMBOL, 50),\n    (23, HUFFMAN_EMIT_SYMBOL, 50),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 50),\n    (2, HUFFMAN_EMIT_SYMBOL, 97),\n    (9, HUFFMAN_EMIT_SYMBOL, 97),\n    (23, HUFFMAN_EMIT_SYMBOL, 97),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 97),\n\n    # Node 4\n    (3, HUFFMAN_EMIT_SYMBOL, 48),\n    (6, HUFFMAN_EMIT_SYMBOL, 48),\n    (10, HUFFMAN_EMIT_SYMBOL, 48),\n    (15, HUFFMAN_EMIT_SYMBOL, 48),\n    (24, HUFFMAN_EMIT_SYMBOL, 48),\n    (31, HUFFMAN_EMIT_SYMBOL, 48),\n    (41, HUFFMAN_EMIT_SYMBOL, 48),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 48),\n    (3, HUFFMAN_EMIT_SYMBOL, 49),\n    (6, HUFFMAN_EMIT_SYMBOL, 49),\n    (10, HUFFMAN_EMIT_SYMBOL, 49),\n    (15, HUFFMAN_EMIT_SYMBOL, 49),\n    (24, HUFFMAN_EMIT_SYMBOL, 49),\n    (31, HUFFMAN_EMIT_SYMBOL, 49),\n    (41, HUFFMAN_EMIT_SYMBOL, 49),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 49),\n\n    # Node 5\n    (3, HUFFMAN_EMIT_SYMBOL, 50),\n    (6, HUFFMAN_EMIT_SYMBOL, 50),\n    (10, HUFFMAN_EMIT_SYMBOL, 50),\n    (15, HUFFMAN_EMIT_SYMBOL, 50),\n    (24, HUFFMAN_EMIT_SYMBOL, 50),\n    (31, HUFFMAN_EMIT_SYMBOL, 50),\n    (41, HUFFMAN_EMIT_SYMBOL, 50),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 50),\n    (3, HUFFMAN_EMIT_SYMBOL, 97),\n    (6, HUFFMAN_EMIT_SYMBOL, 97),\n    (10, HUFFMAN_EMIT_SYMBOL, 97),\n    (15, HUFFMAN_EMIT_SYMBOL, 97),\n    (24, HUFFMAN_EMIT_SYMBOL, 97),\n    (31, HUFFMAN_EMIT_SYMBOL, 97),\n    (41, HUFFMAN_EMIT_SYMBOL, 97),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 97),\n\n    # Node 6\n    (2, HUFFMAN_EMIT_SYMBOL, 99),\n    (9, HUFFMAN_EMIT_SYMBOL, 99),\n    (23, HUFFMAN_EMIT_SYMBOL, 99),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 99),\n    (2, HUFFMAN_EMIT_SYMBOL, 101),\n    (9, HUFFMAN_EMIT_SYMBOL, 101),\n    (23, HUFFMAN_EMIT_SYMBOL, 101),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 101),\n    (2, HUFFMAN_EMIT_SYMBOL, 105),\n    (9, HUFFMAN_EMIT_SYMBOL, 105),\n    (23, HUFFMAN_EMIT_SYMBOL, 105),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 105),\n    (2, HUFFMAN_EMIT_SYMBOL, 111),\n    (9, HUFFMAN_EMIT_SYMBOL, 111),\n    (23, HUFFMAN_EMIT_SYMBOL, 111),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 111),\n\n    # Node 7\n    (3, HUFFMAN_EMIT_SYMBOL, 99),\n    (6, HUFFMAN_EMIT_SYMBOL, 99),\n    (10, HUFFMAN_EMIT_SYMBOL, 99),\n    (15, HUFFMAN_EMIT_SYMBOL, 99),\n    (24, HUFFMAN_EMIT_SYMBOL, 99),\n    (31, HUFFMAN_EMIT_SYMBOL, 99),\n    (41, HUFFMAN_EMIT_SYMBOL, 99),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 99),\n    (3, HUFFMAN_EMIT_SYMBOL, 101),\n    (6, HUFFMAN_EMIT_SYMBOL, 101),\n    (10, HUFFMAN_EMIT_SYMBOL, 101),\n    (15, HUFFMAN_EMIT_SYMBOL, 101),\n    (24, HUFFMAN_EMIT_SYMBOL, 101),\n    (31, HUFFMAN_EMIT_SYMBOL, 101),\n    (41, HUFFMAN_EMIT_SYMBOL, 101),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 101),\n\n    # Node 8\n    (3, HUFFMAN_EMIT_SYMBOL, 105),\n    (6, HUFFMAN_EMIT_SYMBOL, 105),\n    (10, HUFFMAN_EMIT_SYMBOL, 105),\n    (15, HUFFMAN_EMIT_SYMBOL, 105),\n    (24, HUFFMAN_EMIT_SYMBOL, 105),\n    (31, HUFFMAN_EMIT_SYMBOL, 105),\n    (41, HUFFMAN_EMIT_SYMBOL, 105),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 105),\n    (3, HUFFMAN_EMIT_SYMBOL, 111),\n    (6, HUFFMAN_EMIT_SYMBOL, 111),\n    (10, HUFFMAN_EMIT_SYMBOL, 111),\n    (15, HUFFMAN_EMIT_SYMBOL, 111),\n    (24, HUFFMAN_EMIT_SYMBOL, 111),\n    (31, HUFFMAN_EMIT_SYMBOL, 111),\n    (41, HUFFMAN_EMIT_SYMBOL, 111),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 111),\n\n    # Node 9\n    (1, HUFFMAN_EMIT_SYMBOL, 115),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 115),\n    (1, HUFFMAN_EMIT_SYMBOL, 116),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 116),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 32),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 37),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 45),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 46),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 47),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 51),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 52),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 53),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 54),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 55),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 56),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 57),\n\n    # Node 10\n    (2, HUFFMAN_EMIT_SYMBOL, 115),\n    (9, HUFFMAN_EMIT_SYMBOL, 115),\n    (23, HUFFMAN_EMIT_SYMBOL, 115),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 115),\n    (2, HUFFMAN_EMIT_SYMBOL, 116),\n    (9, HUFFMAN_EMIT_SYMBOL, 116),\n    (23, HUFFMAN_EMIT_SYMBOL, 116),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 116),\n    (1, HUFFMAN_EMIT_SYMBOL, 32),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 32),\n    (1, HUFFMAN_EMIT_SYMBOL, 37),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 37),\n    (1, HUFFMAN_EMIT_SYMBOL, 45),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 45),\n    (1, HUFFMAN_EMIT_SYMBOL, 46),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 46),\n\n    # Node 11\n    (3, HUFFMAN_EMIT_SYMBOL, 115),\n    (6, HUFFMAN_EMIT_SYMBOL, 115),\n    (10, HUFFMAN_EMIT_SYMBOL, 115),\n    (15, HUFFMAN_EMIT_SYMBOL, 115),\n    (24, HUFFMAN_EMIT_SYMBOL, 115),\n    (31, HUFFMAN_EMIT_SYMBOL, 115),\n    (41, HUFFMAN_EMIT_SYMBOL, 115),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 115),\n    (3, HUFFMAN_EMIT_SYMBOL, 116),\n    (6, HUFFMAN_EMIT_SYMBOL, 116),\n    (10, HUFFMAN_EMIT_SYMBOL, 116),\n    (15, HUFFMAN_EMIT_SYMBOL, 116),\n    (24, HUFFMAN_EMIT_SYMBOL, 116),\n    (31, HUFFMAN_EMIT_SYMBOL, 116),\n    (41, HUFFMAN_EMIT_SYMBOL, 116),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 116),\n\n    # Node 12\n    (2, HUFFMAN_EMIT_SYMBOL, 32),\n    (9, HUFFMAN_EMIT_SYMBOL, 32),\n    (23, HUFFMAN_EMIT_SYMBOL, 32),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 32),\n    (2, HUFFMAN_EMIT_SYMBOL, 37),\n    (9, HUFFMAN_EMIT_SYMBOL, 37),\n    (23, HUFFMAN_EMIT_SYMBOL, 37),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 37),\n    (2, HUFFMAN_EMIT_SYMBOL, 45),\n    (9, HUFFMAN_EMIT_SYMBOL, 45),\n    (23, HUFFMAN_EMIT_SYMBOL, 45),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 45),\n    (2, HUFFMAN_EMIT_SYMBOL, 46),\n    (9, HUFFMAN_EMIT_SYMBOL, 46),\n    (23, HUFFMAN_EMIT_SYMBOL, 46),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 46),\n\n    # Node 13\n    (3, HUFFMAN_EMIT_SYMBOL, 32),\n    (6, HUFFMAN_EMIT_SYMBOL, 32),\n    (10, HUFFMAN_EMIT_SYMBOL, 32),\n    (15, HUFFMAN_EMIT_SYMBOL, 32),\n    (24, HUFFMAN_EMIT_SYMBOL, 32),\n    (31, HUFFMAN_EMIT_SYMBOL, 32),\n    (41, HUFFMAN_EMIT_SYMBOL, 32),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 32),\n    (3, HUFFMAN_EMIT_SYMBOL, 37),\n    (6, HUFFMAN_EMIT_SYMBOL, 37),\n    (10, HUFFMAN_EMIT_SYMBOL, 37),\n    (15, HUFFMAN_EMIT_SYMBOL, 37),\n    (24, HUFFMAN_EMIT_SYMBOL, 37),\n    (31, HUFFMAN_EMIT_SYMBOL, 37),\n    (41, HUFFMAN_EMIT_SYMBOL, 37),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 37),\n\n    # Node 14\n    (3, HUFFMAN_EMIT_SYMBOL, 45),\n    (6, HUFFMAN_EMIT_SYMBOL, 45),\n    (10, HUFFMAN_EMIT_SYMBOL, 45),\n    (15, HUFFMAN_EMIT_SYMBOL, 45),\n    (24, HUFFMAN_EMIT_SYMBOL, 45),\n    (31, HUFFMAN_EMIT_SYMBOL, 45),\n    (41, HUFFMAN_EMIT_SYMBOL, 45),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 45),\n    (3, HUFFMAN_EMIT_SYMBOL, 46),\n    (6, HUFFMAN_EMIT_SYMBOL, 46),\n    (10, HUFFMAN_EMIT_SYMBOL, 46),\n    (15, HUFFMAN_EMIT_SYMBOL, 46),\n    (24, HUFFMAN_EMIT_SYMBOL, 46),\n    (31, HUFFMAN_EMIT_SYMBOL, 46),\n    (41, HUFFMAN_EMIT_SYMBOL, 46),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 46),\n\n    # Node 15\n    (1, HUFFMAN_EMIT_SYMBOL, 47),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 47),\n    (1, HUFFMAN_EMIT_SYMBOL, 51),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 51),\n    (1, HUFFMAN_EMIT_SYMBOL, 52),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 52),\n    (1, HUFFMAN_EMIT_SYMBOL, 53),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 53),\n    (1, HUFFMAN_EMIT_SYMBOL, 54),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 54),\n    (1, HUFFMAN_EMIT_SYMBOL, 55),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 55),\n    (1, HUFFMAN_EMIT_SYMBOL, 56),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 56),\n    (1, HUFFMAN_EMIT_SYMBOL, 57),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 57),\n\n    # Node 16\n    (2, HUFFMAN_EMIT_SYMBOL, 47),\n    (9, HUFFMAN_EMIT_SYMBOL, 47),\n    (23, HUFFMAN_EMIT_SYMBOL, 47),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 47),\n    (2, HUFFMAN_EMIT_SYMBOL, 51),\n    (9, HUFFMAN_EMIT_SYMBOL, 51),\n    (23, HUFFMAN_EMIT_SYMBOL, 51),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 51),\n    (2, HUFFMAN_EMIT_SYMBOL, 52),\n    (9, HUFFMAN_EMIT_SYMBOL, 52),\n    (23, HUFFMAN_EMIT_SYMBOL, 52),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 52),\n    (2, HUFFMAN_EMIT_SYMBOL, 53),\n    (9, HUFFMAN_EMIT_SYMBOL, 53),\n    (23, HUFFMAN_EMIT_SYMBOL, 53),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 53),\n\n    # Node 17\n    (3, HUFFMAN_EMIT_SYMBOL, 47),\n    (6, HUFFMAN_EMIT_SYMBOL, 47),\n    (10, HUFFMAN_EMIT_SYMBOL, 47),\n    (15, HUFFMAN_EMIT_SYMBOL, 47),\n    (24, HUFFMAN_EMIT_SYMBOL, 47),\n    (31, HUFFMAN_EMIT_SYMBOL, 47),\n    (41, HUFFMAN_EMIT_SYMBOL, 47),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 47),\n    (3, HUFFMAN_EMIT_SYMBOL, 51),\n    (6, HUFFMAN_EMIT_SYMBOL, 51),\n    (10, HUFFMAN_EMIT_SYMBOL, 51),\n    (15, HUFFMAN_EMIT_SYMBOL, 51),\n    (24, HUFFMAN_EMIT_SYMBOL, 51),\n    (31, HUFFMAN_EMIT_SYMBOL, 51),\n    (41, HUFFMAN_EMIT_SYMBOL, 51),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 51),\n\n    # Node 18\n    (3, HUFFMAN_EMIT_SYMBOL, 52),\n    (6, HUFFMAN_EMIT_SYMBOL, 52),\n    (10, HUFFMAN_EMIT_SYMBOL, 52),\n    (15, HUFFMAN_EMIT_SYMBOL, 52),\n    (24, HUFFMAN_EMIT_SYMBOL, 52),\n    (31, HUFFMAN_EMIT_SYMBOL, 52),\n    (41, HUFFMAN_EMIT_SYMBOL, 52),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 52),\n    (3, HUFFMAN_EMIT_SYMBOL, 53),\n    (6, HUFFMAN_EMIT_SYMBOL, 53),\n    (10, HUFFMAN_EMIT_SYMBOL, 53),\n    (15, HUFFMAN_EMIT_SYMBOL, 53),\n    (24, HUFFMAN_EMIT_SYMBOL, 53),\n    (31, HUFFMAN_EMIT_SYMBOL, 53),\n    (41, HUFFMAN_EMIT_SYMBOL, 53),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 53),\n\n    # Node 19\n    (2, HUFFMAN_EMIT_SYMBOL, 54),\n    (9, HUFFMAN_EMIT_SYMBOL, 54),\n    (23, HUFFMAN_EMIT_SYMBOL, 54),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 54),\n    (2, HUFFMAN_EMIT_SYMBOL, 55),\n    (9, HUFFMAN_EMIT_SYMBOL, 55),\n    (23, HUFFMAN_EMIT_SYMBOL, 55),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 55),\n    (2, HUFFMAN_EMIT_SYMBOL, 56),\n    (9, HUFFMAN_EMIT_SYMBOL, 56),\n    (23, HUFFMAN_EMIT_SYMBOL, 56),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 56),\n    (2, HUFFMAN_EMIT_SYMBOL, 57),\n    (9, HUFFMAN_EMIT_SYMBOL, 57),\n    (23, HUFFMAN_EMIT_SYMBOL, 57),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 57),\n\n    # Node 20\n    (3, HUFFMAN_EMIT_SYMBOL, 54),\n    (6, HUFFMAN_EMIT_SYMBOL, 54),\n    (10, HUFFMAN_EMIT_SYMBOL, 54),\n    (15, HUFFMAN_EMIT_SYMBOL, 54),\n    (24, HUFFMAN_EMIT_SYMBOL, 54),\n    (31, HUFFMAN_EMIT_SYMBOL, 54),\n    (41, HUFFMAN_EMIT_SYMBOL, 54),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 54),\n    (3, HUFFMAN_EMIT_SYMBOL, 55),\n    (6, HUFFMAN_EMIT_SYMBOL, 55),\n    (10, HUFFMAN_EMIT_SYMBOL, 55),\n    (15, HUFFMAN_EMIT_SYMBOL, 55),\n    (24, HUFFMAN_EMIT_SYMBOL, 55),\n    (31, HUFFMAN_EMIT_SYMBOL, 55),\n    (41, HUFFMAN_EMIT_SYMBOL, 55),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 55),\n\n    # Node 21\n    (3, HUFFMAN_EMIT_SYMBOL, 56),\n    (6, HUFFMAN_EMIT_SYMBOL, 56),\n    (10, HUFFMAN_EMIT_SYMBOL, 56),\n    (15, HUFFMAN_EMIT_SYMBOL, 56),\n    (24, HUFFMAN_EMIT_SYMBOL, 56),\n    (31, HUFFMAN_EMIT_SYMBOL, 56),\n    (41, HUFFMAN_EMIT_SYMBOL, 56),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 56),\n    (3, HUFFMAN_EMIT_SYMBOL, 57),\n    (6, HUFFMAN_EMIT_SYMBOL, 57),\n    (10, HUFFMAN_EMIT_SYMBOL, 57),\n    (15, HUFFMAN_EMIT_SYMBOL, 57),\n    (24, HUFFMAN_EMIT_SYMBOL, 57),\n    (31, HUFFMAN_EMIT_SYMBOL, 57),\n    (41, HUFFMAN_EMIT_SYMBOL, 57),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 57),\n\n    # Node 22\n    (26, 0, 0),\n    (27, 0, 0),\n    (29, 0, 0),\n    (30, 0, 0),\n    (33, 0, 0),\n    (34, 0, 0),\n    (36, 0, 0),\n    (37, 0, 0),\n    (43, 0, 0),\n    (46, 0, 0),\n    (50, 0, 0),\n    (53, 0, 0),\n    (58, 0, 0),\n    (61, 0, 0),\n    (65, 0, 0),\n    (68, HUFFMAN_COMPLETE, 0),\n\n    # Node 23\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 61),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 65),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 95),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 98),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 100),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 102),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 103),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 104),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 108),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 109),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 110),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 112),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 114),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 117),\n    (38, 0, 0),\n    (39, 0, 0),\n\n    # Node 24\n    (1, HUFFMAN_EMIT_SYMBOL, 61),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 61),\n    (1, HUFFMAN_EMIT_SYMBOL, 65),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 65),\n    (1, HUFFMAN_EMIT_SYMBOL, 95),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 95),\n    (1, HUFFMAN_EMIT_SYMBOL, 98),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 98),\n    (1, HUFFMAN_EMIT_SYMBOL, 100),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 100),\n    (1, HUFFMAN_EMIT_SYMBOL, 102),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 102),\n    (1, HUFFMAN_EMIT_SYMBOL, 103),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 103),\n    (1, HUFFMAN_EMIT_SYMBOL, 104),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 104),\n\n    # Node 25\n    (2, HUFFMAN_EMIT_SYMBOL, 61),\n    (9, HUFFMAN_EMIT_SYMBOL, 61),\n    (23, HUFFMAN_EMIT_SYMBOL, 61),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 61),\n    (2, HUFFMAN_EMIT_SYMBOL, 65),\n    (9, HUFFMAN_EMIT_SYMBOL, 65),\n    (23, HUFFMAN_EMIT_SYMBOL, 65),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 65),\n    (2, HUFFMAN_EMIT_SYMBOL, 95),\n    (9, HUFFMAN_EMIT_SYMBOL, 95),\n    (23, HUFFMAN_EMIT_SYMBOL, 95),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 95),\n    (2, HUFFMAN_EMIT_SYMBOL, 98),\n    (9, HUFFMAN_EMIT_SYMBOL, 98),\n    (23, HUFFMAN_EMIT_SYMBOL, 98),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 98),\n\n    # Node 26\n    (3, HUFFMAN_EMIT_SYMBOL, 61),\n    (6, HUFFMAN_EMIT_SYMBOL, 61),\n    (10, HUFFMAN_EMIT_SYMBOL, 61),\n    (15, HUFFMAN_EMIT_SYMBOL, 61),\n    (24, HUFFMAN_EMIT_SYMBOL, 61),\n    (31, HUFFMAN_EMIT_SYMBOL, 61),\n    (41, HUFFMAN_EMIT_SYMBOL, 61),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 61),\n    (3, HUFFMAN_EMIT_SYMBOL, 65),\n    (6, HUFFMAN_EMIT_SYMBOL, 65),\n    (10, HUFFMAN_EMIT_SYMBOL, 65),\n    (15, HUFFMAN_EMIT_SYMBOL, 65),\n    (24, HUFFMAN_EMIT_SYMBOL, 65),\n    (31, HUFFMAN_EMIT_SYMBOL, 65),\n    (41, HUFFMAN_EMIT_SYMBOL, 65),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 65),\n\n    # Node 27\n    (3, HUFFMAN_EMIT_SYMBOL, 95),\n    (6, HUFFMAN_EMIT_SYMBOL, 95),\n    (10, HUFFMAN_EMIT_SYMBOL, 95),\n    (15, HUFFMAN_EMIT_SYMBOL, 95),\n    (24, HUFFMAN_EMIT_SYMBOL, 95),\n    (31, HUFFMAN_EMIT_SYMBOL, 95),\n    (41, HUFFMAN_EMIT_SYMBOL, 95),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 95),\n    (3, HUFFMAN_EMIT_SYMBOL, 98),\n    (6, HUFFMAN_EMIT_SYMBOL, 98),\n    (10, HUFFMAN_EMIT_SYMBOL, 98),\n    (15, HUFFMAN_EMIT_SYMBOL, 98),\n    (24, HUFFMAN_EMIT_SYMBOL, 98),\n    (31, HUFFMAN_EMIT_SYMBOL, 98),\n    (41, HUFFMAN_EMIT_SYMBOL, 98),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 98),\n\n    # Node 28\n    (2, HUFFMAN_EMIT_SYMBOL, 100),\n    (9, HUFFMAN_EMIT_SYMBOL, 100),\n    (23, HUFFMAN_EMIT_SYMBOL, 100),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 100),\n    (2, HUFFMAN_EMIT_SYMBOL, 102),\n    (9, HUFFMAN_EMIT_SYMBOL, 102),\n    (23, HUFFMAN_EMIT_SYMBOL, 102),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 102),\n    (2, HUFFMAN_EMIT_SYMBOL, 103),\n    (9, HUFFMAN_EMIT_SYMBOL, 103),\n    (23, HUFFMAN_EMIT_SYMBOL, 103),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 103),\n    (2, HUFFMAN_EMIT_SYMBOL, 104),\n    (9, HUFFMAN_EMIT_SYMBOL, 104),\n    (23, HUFFMAN_EMIT_SYMBOL, 104),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 104),\n\n    # Node 29\n    (3, HUFFMAN_EMIT_SYMBOL, 100),\n    (6, HUFFMAN_EMIT_SYMBOL, 100),\n    (10, HUFFMAN_EMIT_SYMBOL, 100),\n    (15, HUFFMAN_EMIT_SYMBOL, 100),\n    (24, HUFFMAN_EMIT_SYMBOL, 100),\n    (31, HUFFMAN_EMIT_SYMBOL, 100),\n    (41, HUFFMAN_EMIT_SYMBOL, 100),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 100),\n    (3, HUFFMAN_EMIT_SYMBOL, 102),\n    (6, HUFFMAN_EMIT_SYMBOL, 102),\n    (10, HUFFMAN_EMIT_SYMBOL, 102),\n    (15, HUFFMAN_EMIT_SYMBOL, 102),\n    (24, HUFFMAN_EMIT_SYMBOL, 102),\n    (31, HUFFMAN_EMIT_SYMBOL, 102),\n    (41, HUFFMAN_EMIT_SYMBOL, 102),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 102),\n\n    # Node 30\n    (3, HUFFMAN_EMIT_SYMBOL, 103),\n    (6, HUFFMAN_EMIT_SYMBOL, 103),\n    (10, HUFFMAN_EMIT_SYMBOL, 103),\n    (15, HUFFMAN_EMIT_SYMBOL, 103),\n    (24, HUFFMAN_EMIT_SYMBOL, 103),\n    (31, HUFFMAN_EMIT_SYMBOL, 103),\n    (41, HUFFMAN_EMIT_SYMBOL, 103),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 103),\n    (3, HUFFMAN_EMIT_SYMBOL, 104),\n    (6, HUFFMAN_EMIT_SYMBOL, 104),\n    (10, HUFFMAN_EMIT_SYMBOL, 104),\n    (15, HUFFMAN_EMIT_SYMBOL, 104),\n    (24, HUFFMAN_EMIT_SYMBOL, 104),\n    (31, HUFFMAN_EMIT_SYMBOL, 104),\n    (41, HUFFMAN_EMIT_SYMBOL, 104),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 104),\n\n    # Node 31\n    (1, HUFFMAN_EMIT_SYMBOL, 108),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 108),\n    (1, HUFFMAN_EMIT_SYMBOL, 109),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 109),\n    (1, HUFFMAN_EMIT_SYMBOL, 110),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 110),\n    (1, HUFFMAN_EMIT_SYMBOL, 112),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 112),\n    (1, HUFFMAN_EMIT_SYMBOL, 114),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 114),\n    (1, HUFFMAN_EMIT_SYMBOL, 117),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 117),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 58),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 66),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 67),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 68),\n\n    # Node 32\n    (2, HUFFMAN_EMIT_SYMBOL, 108),\n    (9, HUFFMAN_EMIT_SYMBOL, 108),\n    (23, HUFFMAN_EMIT_SYMBOL, 108),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 108),\n    (2, HUFFMAN_EMIT_SYMBOL, 109),\n    (9, HUFFMAN_EMIT_SYMBOL, 109),\n    (23, HUFFMAN_EMIT_SYMBOL, 109),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 109),\n    (2, HUFFMAN_EMIT_SYMBOL, 110),\n    (9, HUFFMAN_EMIT_SYMBOL, 110),\n    (23, HUFFMAN_EMIT_SYMBOL, 110),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 110),\n    (2, HUFFMAN_EMIT_SYMBOL, 112),\n    (9, HUFFMAN_EMIT_SYMBOL, 112),\n    (23, HUFFMAN_EMIT_SYMBOL, 112),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 112),\n\n    # Node 33\n    (3, HUFFMAN_EMIT_SYMBOL, 108),\n    (6, HUFFMAN_EMIT_SYMBOL, 108),\n    (10, HUFFMAN_EMIT_SYMBOL, 108),\n    (15, HUFFMAN_EMIT_SYMBOL, 108),\n    (24, HUFFMAN_EMIT_SYMBOL, 108),\n    (31, HUFFMAN_EMIT_SYMBOL, 108),\n    (41, HUFFMAN_EMIT_SYMBOL, 108),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 108),\n    (3, HUFFMAN_EMIT_SYMBOL, 109),\n    (6, HUFFMAN_EMIT_SYMBOL, 109),\n    (10, HUFFMAN_EMIT_SYMBOL, 109),\n    (15, HUFFMAN_EMIT_SYMBOL, 109),\n    (24, HUFFMAN_EMIT_SYMBOL, 109),\n    (31, HUFFMAN_EMIT_SYMBOL, 109),\n    (41, HUFFMAN_EMIT_SYMBOL, 109),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 109),\n\n    # Node 34\n    (3, HUFFMAN_EMIT_SYMBOL, 110),\n    (6, HUFFMAN_EMIT_SYMBOL, 110),\n    (10, HUFFMAN_EMIT_SYMBOL, 110),\n    (15, HUFFMAN_EMIT_SYMBOL, 110),\n    (24, HUFFMAN_EMIT_SYMBOL, 110),\n    (31, HUFFMAN_EMIT_SYMBOL, 110),\n    (41, HUFFMAN_EMIT_SYMBOL, 110),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 110),\n    (3, HUFFMAN_EMIT_SYMBOL, 112),\n    (6, HUFFMAN_EMIT_SYMBOL, 112),\n    (10, HUFFMAN_EMIT_SYMBOL, 112),\n    (15, HUFFMAN_EMIT_SYMBOL, 112),\n    (24, HUFFMAN_EMIT_SYMBOL, 112),\n    (31, HUFFMAN_EMIT_SYMBOL, 112),\n    (41, HUFFMAN_EMIT_SYMBOL, 112),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 112),\n\n    # Node 35\n    (2, HUFFMAN_EMIT_SYMBOL, 114),\n    (9, HUFFMAN_EMIT_SYMBOL, 114),\n    (23, HUFFMAN_EMIT_SYMBOL, 114),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 114),\n    (2, HUFFMAN_EMIT_SYMBOL, 117),\n    (9, HUFFMAN_EMIT_SYMBOL, 117),\n    (23, HUFFMAN_EMIT_SYMBOL, 117),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 117),\n    (1, HUFFMAN_EMIT_SYMBOL, 58),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 58),\n    (1, HUFFMAN_EMIT_SYMBOL, 66),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 66),\n    (1, HUFFMAN_EMIT_SYMBOL, 67),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 67),\n    (1, HUFFMAN_EMIT_SYMBOL, 68),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 68),\n\n    # Node 36\n    (3, HUFFMAN_EMIT_SYMBOL, 114),\n    (6, HUFFMAN_EMIT_SYMBOL, 114),\n    (10, HUFFMAN_EMIT_SYMBOL, 114),\n    (15, HUFFMAN_EMIT_SYMBOL, 114),\n    (24, HUFFMAN_EMIT_SYMBOL, 114),\n    (31, HUFFMAN_EMIT_SYMBOL, 114),\n    (41, HUFFMAN_EMIT_SYMBOL, 114),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 114),\n    (3, HUFFMAN_EMIT_SYMBOL, 117),\n    (6, HUFFMAN_EMIT_SYMBOL, 117),\n    (10, HUFFMAN_EMIT_SYMBOL, 117),\n    (15, HUFFMAN_EMIT_SYMBOL, 117),\n    (24, HUFFMAN_EMIT_SYMBOL, 117),\n    (31, HUFFMAN_EMIT_SYMBOL, 117),\n    (41, HUFFMAN_EMIT_SYMBOL, 117),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 117),\n\n    # Node 37\n    (2, HUFFMAN_EMIT_SYMBOL, 58),\n    (9, HUFFMAN_EMIT_SYMBOL, 58),\n    (23, HUFFMAN_EMIT_SYMBOL, 58),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 58),\n    (2, HUFFMAN_EMIT_SYMBOL, 66),\n    (9, HUFFMAN_EMIT_SYMBOL, 66),\n    (23, HUFFMAN_EMIT_SYMBOL, 66),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 66),\n    (2, HUFFMAN_EMIT_SYMBOL, 67),\n    (9, HUFFMAN_EMIT_SYMBOL, 67),\n    (23, HUFFMAN_EMIT_SYMBOL, 67),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 67),\n    (2, HUFFMAN_EMIT_SYMBOL, 68),\n    (9, HUFFMAN_EMIT_SYMBOL, 68),\n    (23, HUFFMAN_EMIT_SYMBOL, 68),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 68),\n\n    # Node 38\n    (3, HUFFMAN_EMIT_SYMBOL, 58),\n    (6, HUFFMAN_EMIT_SYMBOL, 58),\n    (10, HUFFMAN_EMIT_SYMBOL, 58),\n    (15, HUFFMAN_EMIT_SYMBOL, 58),\n    (24, HUFFMAN_EMIT_SYMBOL, 58),\n    (31, HUFFMAN_EMIT_SYMBOL, 58),\n    (41, HUFFMAN_EMIT_SYMBOL, 58),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 58),\n    (3, HUFFMAN_EMIT_SYMBOL, 66),\n    (6, HUFFMAN_EMIT_SYMBOL, 66),\n    (10, HUFFMAN_EMIT_SYMBOL, 66),\n    (15, HUFFMAN_EMIT_SYMBOL, 66),\n    (24, HUFFMAN_EMIT_SYMBOL, 66),\n    (31, HUFFMAN_EMIT_SYMBOL, 66),\n    (41, HUFFMAN_EMIT_SYMBOL, 66),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 66),\n\n    # Node 39\n    (3, HUFFMAN_EMIT_SYMBOL, 67),\n    (6, HUFFMAN_EMIT_SYMBOL, 67),\n    (10, HUFFMAN_EMIT_SYMBOL, 67),\n    (15, HUFFMAN_EMIT_SYMBOL, 67),\n    (24, HUFFMAN_EMIT_SYMBOL, 67),\n    (31, HUFFMAN_EMIT_SYMBOL, 67),\n    (41, HUFFMAN_EMIT_SYMBOL, 67),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 67),\n    (3, HUFFMAN_EMIT_SYMBOL, 68),\n    (6, HUFFMAN_EMIT_SYMBOL, 68),\n    (10, HUFFMAN_EMIT_SYMBOL, 68),\n    (15, HUFFMAN_EMIT_SYMBOL, 68),\n    (24, HUFFMAN_EMIT_SYMBOL, 68),\n    (31, HUFFMAN_EMIT_SYMBOL, 68),\n    (41, HUFFMAN_EMIT_SYMBOL, 68),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 68),\n\n    # Node 40\n    (44, 0, 0),\n    (45, 0, 0),\n    (47, 0, 0),\n    (48, 0, 0),\n    (51, 0, 0),\n    (52, 0, 0),\n    (54, 0, 0),\n    (55, 0, 0),\n    (59, 0, 0),\n    (60, 0, 0),\n    (62, 0, 0),\n    (63, 0, 0),\n    (66, 0, 0),\n    (67, 0, 0),\n    (69, 0, 0),\n    (72, HUFFMAN_COMPLETE, 0),\n\n    # Node 41\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 69),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 70),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 71),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 72),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 73),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 74),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 75),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 76),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 77),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 78),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 79),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 80),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 81),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 82),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 83),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 84),\n\n    # Node 42\n    (1, HUFFMAN_EMIT_SYMBOL, 69),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 69),\n    (1, HUFFMAN_EMIT_SYMBOL, 70),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 70),\n    (1, HUFFMAN_EMIT_SYMBOL, 71),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 71),\n    (1, HUFFMAN_EMIT_SYMBOL, 72),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 72),\n    (1, HUFFMAN_EMIT_SYMBOL, 73),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 73),\n    (1, HUFFMAN_EMIT_SYMBOL, 74),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 74),\n    (1, HUFFMAN_EMIT_SYMBOL, 75),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 75),\n    (1, HUFFMAN_EMIT_SYMBOL, 76),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 76),\n\n    # Node 43\n    (2, HUFFMAN_EMIT_SYMBOL, 69),\n    (9, HUFFMAN_EMIT_SYMBOL, 69),\n    (23, HUFFMAN_EMIT_SYMBOL, 69),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 69),\n    (2, HUFFMAN_EMIT_SYMBOL, 70),\n    (9, HUFFMAN_EMIT_SYMBOL, 70),\n    (23, HUFFMAN_EMIT_SYMBOL, 70),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 70),\n    (2, HUFFMAN_EMIT_SYMBOL, 71),\n    (9, HUFFMAN_EMIT_SYMBOL, 71),\n    (23, HUFFMAN_EMIT_SYMBOL, 71),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 71),\n    (2, HUFFMAN_EMIT_SYMBOL, 72),\n    (9, HUFFMAN_EMIT_SYMBOL, 72),\n    (23, HUFFMAN_EMIT_SYMBOL, 72),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 72),\n\n    # Node 44\n    (3, HUFFMAN_EMIT_SYMBOL, 69),\n    (6, HUFFMAN_EMIT_SYMBOL, 69),\n    (10, HUFFMAN_EMIT_SYMBOL, 69),\n    (15, HUFFMAN_EMIT_SYMBOL, 69),\n    (24, HUFFMAN_EMIT_SYMBOL, 69),\n    (31, HUFFMAN_EMIT_SYMBOL, 69),\n    (41, HUFFMAN_EMIT_SYMBOL, 69),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 69),\n    (3, HUFFMAN_EMIT_SYMBOL, 70),\n    (6, HUFFMAN_EMIT_SYMBOL, 70),\n    (10, HUFFMAN_EMIT_SYMBOL, 70),\n    (15, HUFFMAN_EMIT_SYMBOL, 70),\n    (24, HUFFMAN_EMIT_SYMBOL, 70),\n    (31, HUFFMAN_EMIT_SYMBOL, 70),\n    (41, HUFFMAN_EMIT_SYMBOL, 70),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 70),\n\n    # Node 45\n    (3, HUFFMAN_EMIT_SYMBOL, 71),\n    (6, HUFFMAN_EMIT_SYMBOL, 71),\n    (10, HUFFMAN_EMIT_SYMBOL, 71),\n    (15, HUFFMAN_EMIT_SYMBOL, 71),\n    (24, HUFFMAN_EMIT_SYMBOL, 71),\n    (31, HUFFMAN_EMIT_SYMBOL, 71),\n    (41, HUFFMAN_EMIT_SYMBOL, 71),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 71),\n    (3, HUFFMAN_EMIT_SYMBOL, 72),\n    (6, HUFFMAN_EMIT_SYMBOL, 72),\n    (10, HUFFMAN_EMIT_SYMBOL, 72),\n    (15, HUFFMAN_EMIT_SYMBOL, 72),\n    (24, HUFFMAN_EMIT_SYMBOL, 72),\n    (31, HUFFMAN_EMIT_SYMBOL, 72),\n    (41, HUFFMAN_EMIT_SYMBOL, 72),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 72),\n\n    # Node 46\n    (2, HUFFMAN_EMIT_SYMBOL, 73),\n    (9, HUFFMAN_EMIT_SYMBOL, 73),\n    (23, HUFFMAN_EMIT_SYMBOL, 73),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 73),\n    (2, HUFFMAN_EMIT_SYMBOL, 74),\n    (9, HUFFMAN_EMIT_SYMBOL, 74),\n    (23, HUFFMAN_EMIT_SYMBOL, 74),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 74),\n    (2, HUFFMAN_EMIT_SYMBOL, 75),\n    (9, HUFFMAN_EMIT_SYMBOL, 75),\n    (23, HUFFMAN_EMIT_SYMBOL, 75),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 75),\n    (2, HUFFMAN_EMIT_SYMBOL, 76),\n    (9, HUFFMAN_EMIT_SYMBOL, 76),\n    (23, HUFFMAN_EMIT_SYMBOL, 76),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 76),\n\n    # Node 47\n    (3, HUFFMAN_EMIT_SYMBOL, 73),\n    (6, HUFFMAN_EMIT_SYMBOL, 73),\n    (10, HUFFMAN_EMIT_SYMBOL, 73),\n    (15, HUFFMAN_EMIT_SYMBOL, 73),\n    (24, HUFFMAN_EMIT_SYMBOL, 73),\n    (31, HUFFMAN_EMIT_SYMBOL, 73),\n    (41, HUFFMAN_EMIT_SYMBOL, 73),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 73),\n    (3, HUFFMAN_EMIT_SYMBOL, 74),\n    (6, HUFFMAN_EMIT_SYMBOL, 74),\n    (10, HUFFMAN_EMIT_SYMBOL, 74),\n    (15, HUFFMAN_EMIT_SYMBOL, 74),\n    (24, HUFFMAN_EMIT_SYMBOL, 74),\n    (31, HUFFMAN_EMIT_SYMBOL, 74),\n    (41, HUFFMAN_EMIT_SYMBOL, 74),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 74),\n\n    # Node 48\n    (3, HUFFMAN_EMIT_SYMBOL, 75),\n    (6, HUFFMAN_EMIT_SYMBOL, 75),\n    (10, HUFFMAN_EMIT_SYMBOL, 75),\n    (15, HUFFMAN_EMIT_SYMBOL, 75),\n    (24, HUFFMAN_EMIT_SYMBOL, 75),\n    (31, HUFFMAN_EMIT_SYMBOL, 75),\n    (41, HUFFMAN_EMIT_SYMBOL, 75),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 75),\n    (3, HUFFMAN_EMIT_SYMBOL, 76),\n    (6, HUFFMAN_EMIT_SYMBOL, 76),\n    (10, HUFFMAN_EMIT_SYMBOL, 76),\n    (15, HUFFMAN_EMIT_SYMBOL, 76),\n    (24, HUFFMAN_EMIT_SYMBOL, 76),\n    (31, HUFFMAN_EMIT_SYMBOL, 76),\n    (41, HUFFMAN_EMIT_SYMBOL, 76),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 76),\n\n    # Node 49\n    (1, HUFFMAN_EMIT_SYMBOL, 77),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 77),\n    (1, HUFFMAN_EMIT_SYMBOL, 78),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 78),\n    (1, HUFFMAN_EMIT_SYMBOL, 79),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 79),\n    (1, HUFFMAN_EMIT_SYMBOL, 80),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 80),\n    (1, HUFFMAN_EMIT_SYMBOL, 81),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 81),\n    (1, HUFFMAN_EMIT_SYMBOL, 82),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 82),\n    (1, HUFFMAN_EMIT_SYMBOL, 83),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 83),\n    (1, HUFFMAN_EMIT_SYMBOL, 84),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 84),\n\n    # Node 50\n    (2, HUFFMAN_EMIT_SYMBOL, 77),\n    (9, HUFFMAN_EMIT_SYMBOL, 77),\n    (23, HUFFMAN_EMIT_SYMBOL, 77),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 77),\n    (2, HUFFMAN_EMIT_SYMBOL, 78),\n    (9, HUFFMAN_EMIT_SYMBOL, 78),\n    (23, HUFFMAN_EMIT_SYMBOL, 78),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 78),\n    (2, HUFFMAN_EMIT_SYMBOL, 79),\n    (9, HUFFMAN_EMIT_SYMBOL, 79),\n    (23, HUFFMAN_EMIT_SYMBOL, 79),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 79),\n    (2, HUFFMAN_EMIT_SYMBOL, 80),\n    (9, HUFFMAN_EMIT_SYMBOL, 80),\n    (23, HUFFMAN_EMIT_SYMBOL, 80),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 80),\n\n    # Node 51\n    (3, HUFFMAN_EMIT_SYMBOL, 77),\n    (6, HUFFMAN_EMIT_SYMBOL, 77),\n    (10, HUFFMAN_EMIT_SYMBOL, 77),\n    (15, HUFFMAN_EMIT_SYMBOL, 77),\n    (24, HUFFMAN_EMIT_SYMBOL, 77),\n    (31, HUFFMAN_EMIT_SYMBOL, 77),\n    (41, HUFFMAN_EMIT_SYMBOL, 77),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 77),\n    (3, HUFFMAN_EMIT_SYMBOL, 78),\n    (6, HUFFMAN_EMIT_SYMBOL, 78),\n    (10, HUFFMAN_EMIT_SYMBOL, 78),\n    (15, HUFFMAN_EMIT_SYMBOL, 78),\n    (24, HUFFMAN_EMIT_SYMBOL, 78),\n    (31, HUFFMAN_EMIT_SYMBOL, 78),\n    (41, HUFFMAN_EMIT_SYMBOL, 78),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 78),\n\n    # Node 52\n    (3, HUFFMAN_EMIT_SYMBOL, 79),\n    (6, HUFFMAN_EMIT_SYMBOL, 79),\n    (10, HUFFMAN_EMIT_SYMBOL, 79),\n    (15, HUFFMAN_EMIT_SYMBOL, 79),\n    (24, HUFFMAN_EMIT_SYMBOL, 79),\n    (31, HUFFMAN_EMIT_SYMBOL, 79),\n    (41, HUFFMAN_EMIT_SYMBOL, 79),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 79),\n    (3, HUFFMAN_EMIT_SYMBOL, 80),\n    (6, HUFFMAN_EMIT_SYMBOL, 80),\n    (10, HUFFMAN_EMIT_SYMBOL, 80),\n    (15, HUFFMAN_EMIT_SYMBOL, 80),\n    (24, HUFFMAN_EMIT_SYMBOL, 80),\n    (31, HUFFMAN_EMIT_SYMBOL, 80),\n    (41, HUFFMAN_EMIT_SYMBOL, 80),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 80),\n\n    # Node 53\n    (2, HUFFMAN_EMIT_SYMBOL, 81),\n    (9, HUFFMAN_EMIT_SYMBOL, 81),\n    (23, HUFFMAN_EMIT_SYMBOL, 81),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 81),\n    (2, HUFFMAN_EMIT_SYMBOL, 82),\n    (9, HUFFMAN_EMIT_SYMBOL, 82),\n    (23, HUFFMAN_EMIT_SYMBOL, 82),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 82),\n    (2, HUFFMAN_EMIT_SYMBOL, 83),\n    (9, HUFFMAN_EMIT_SYMBOL, 83),\n    (23, HUFFMAN_EMIT_SYMBOL, 83),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 83),\n    (2, HUFFMAN_EMIT_SYMBOL, 84),\n    (9, HUFFMAN_EMIT_SYMBOL, 84),\n    (23, HUFFMAN_EMIT_SYMBOL, 84),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 84),\n\n    # Node 54\n    (3, HUFFMAN_EMIT_SYMBOL, 81),\n    (6, HUFFMAN_EMIT_SYMBOL, 81),\n    (10, HUFFMAN_EMIT_SYMBOL, 81),\n    (15, HUFFMAN_EMIT_SYMBOL, 81),\n    (24, HUFFMAN_EMIT_SYMBOL, 81),\n    (31, HUFFMAN_EMIT_SYMBOL, 81),\n    (41, HUFFMAN_EMIT_SYMBOL, 81),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 81),\n    (3, HUFFMAN_EMIT_SYMBOL, 82),\n    (6, HUFFMAN_EMIT_SYMBOL, 82),\n    (10, HUFFMAN_EMIT_SYMBOL, 82),\n    (15, HUFFMAN_EMIT_SYMBOL, 82),\n    (24, HUFFMAN_EMIT_SYMBOL, 82),\n    (31, HUFFMAN_EMIT_SYMBOL, 82),\n    (41, HUFFMAN_EMIT_SYMBOL, 82),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 82),\n\n    # Node 55\n    (3, HUFFMAN_EMIT_SYMBOL, 83),\n    (6, HUFFMAN_EMIT_SYMBOL, 83),\n    (10, HUFFMAN_EMIT_SYMBOL, 83),\n    (15, HUFFMAN_EMIT_SYMBOL, 83),\n    (24, HUFFMAN_EMIT_SYMBOL, 83),\n    (31, HUFFMAN_EMIT_SYMBOL, 83),\n    (41, HUFFMAN_EMIT_SYMBOL, 83),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 83),\n    (3, HUFFMAN_EMIT_SYMBOL, 84),\n    (6, HUFFMAN_EMIT_SYMBOL, 84),\n    (10, HUFFMAN_EMIT_SYMBOL, 84),\n    (15, HUFFMAN_EMIT_SYMBOL, 84),\n    (24, HUFFMAN_EMIT_SYMBOL, 84),\n    (31, HUFFMAN_EMIT_SYMBOL, 84),\n    (41, HUFFMAN_EMIT_SYMBOL, 84),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 84),\n\n    # Node 56\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 85),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 86),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 87),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 89),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 106),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 107),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 113),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 118),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 119),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 120),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 121),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 122),\n    (70, 0, 0),\n    (71, 0, 0),\n    (73, 0, 0),\n    (74, HUFFMAN_COMPLETE, 0),\n\n    # Node 57\n    (1, HUFFMAN_EMIT_SYMBOL, 85),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 85),\n    (1, HUFFMAN_EMIT_SYMBOL, 86),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 86),\n    (1, HUFFMAN_EMIT_SYMBOL, 87),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 87),\n    (1, HUFFMAN_EMIT_SYMBOL, 89),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 89),\n    (1, HUFFMAN_EMIT_SYMBOL, 106),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 106),\n    (1, HUFFMAN_EMIT_SYMBOL, 107),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 107),\n    (1, HUFFMAN_EMIT_SYMBOL, 113),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 113),\n    (1, HUFFMAN_EMIT_SYMBOL, 118),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 118),\n\n    # Node 58\n    (2, HUFFMAN_EMIT_SYMBOL, 85),\n    (9, HUFFMAN_EMIT_SYMBOL, 85),\n    (23, HUFFMAN_EMIT_SYMBOL, 85),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 85),\n    (2, HUFFMAN_EMIT_SYMBOL, 86),\n    (9, HUFFMAN_EMIT_SYMBOL, 86),\n    (23, HUFFMAN_EMIT_SYMBOL, 86),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 86),\n    (2, HUFFMAN_EMIT_SYMBOL, 87),\n    (9, HUFFMAN_EMIT_SYMBOL, 87),\n    (23, HUFFMAN_EMIT_SYMBOL, 87),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 87),\n    (2, HUFFMAN_EMIT_SYMBOL, 89),\n    (9, HUFFMAN_EMIT_SYMBOL, 89),\n    (23, HUFFMAN_EMIT_SYMBOL, 89),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 89),\n\n    # Node 59\n    (3, HUFFMAN_EMIT_SYMBOL, 85),\n    (6, HUFFMAN_EMIT_SYMBOL, 85),\n    (10, HUFFMAN_EMIT_SYMBOL, 85),\n    (15, HUFFMAN_EMIT_SYMBOL, 85),\n    (24, HUFFMAN_EMIT_SYMBOL, 85),\n    (31, HUFFMAN_EMIT_SYMBOL, 85),\n    (41, HUFFMAN_EMIT_SYMBOL, 85),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 85),\n    (3, HUFFMAN_EMIT_SYMBOL, 86),\n    (6, HUFFMAN_EMIT_SYMBOL, 86),\n    (10, HUFFMAN_EMIT_SYMBOL, 86),\n    (15, HUFFMAN_EMIT_SYMBOL, 86),\n    (24, HUFFMAN_EMIT_SYMBOL, 86),\n    (31, HUFFMAN_EMIT_SYMBOL, 86),\n    (41, HUFFMAN_EMIT_SYMBOL, 86),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 86),\n\n    # Node 60\n    (3, HUFFMAN_EMIT_SYMBOL, 87),\n    (6, HUFFMAN_EMIT_SYMBOL, 87),\n    (10, HUFFMAN_EMIT_SYMBOL, 87),\n    (15, HUFFMAN_EMIT_SYMBOL, 87),\n    (24, HUFFMAN_EMIT_SYMBOL, 87),\n    (31, HUFFMAN_EMIT_SYMBOL, 87),\n    (41, HUFFMAN_EMIT_SYMBOL, 87),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 87),\n    (3, HUFFMAN_EMIT_SYMBOL, 89),\n    (6, HUFFMAN_EMIT_SYMBOL, 89),\n    (10, HUFFMAN_EMIT_SYMBOL, 89),\n    (15, HUFFMAN_EMIT_SYMBOL, 89),\n    (24, HUFFMAN_EMIT_SYMBOL, 89),\n    (31, HUFFMAN_EMIT_SYMBOL, 89),\n    (41, HUFFMAN_EMIT_SYMBOL, 89),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 89),\n\n    # Node 61\n    (2, HUFFMAN_EMIT_SYMBOL, 106),\n    (9, HUFFMAN_EMIT_SYMBOL, 106),\n    (23, HUFFMAN_EMIT_SYMBOL, 106),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 106),\n    (2, HUFFMAN_EMIT_SYMBOL, 107),\n    (9, HUFFMAN_EMIT_SYMBOL, 107),\n    (23, HUFFMAN_EMIT_SYMBOL, 107),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 107),\n    (2, HUFFMAN_EMIT_SYMBOL, 113),\n    (9, HUFFMAN_EMIT_SYMBOL, 113),\n    (23, HUFFMAN_EMIT_SYMBOL, 113),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 113),\n    (2, HUFFMAN_EMIT_SYMBOL, 118),\n    (9, HUFFMAN_EMIT_SYMBOL, 118),\n    (23, HUFFMAN_EMIT_SYMBOL, 118),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 118),\n\n    # Node 62\n    (3, HUFFMAN_EMIT_SYMBOL, 106),\n    (6, HUFFMAN_EMIT_SYMBOL, 106),\n    (10, HUFFMAN_EMIT_SYMBOL, 106),\n    (15, HUFFMAN_EMIT_SYMBOL, 106),\n    (24, HUFFMAN_EMIT_SYMBOL, 106),\n    (31, HUFFMAN_EMIT_SYMBOL, 106),\n    (41, HUFFMAN_EMIT_SYMBOL, 106),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 106),\n    (3, HUFFMAN_EMIT_SYMBOL, 107),\n    (6, HUFFMAN_EMIT_SYMBOL, 107),\n    (10, HUFFMAN_EMIT_SYMBOL, 107),\n    (15, HUFFMAN_EMIT_SYMBOL, 107),\n    (24, HUFFMAN_EMIT_SYMBOL, 107),\n    (31, HUFFMAN_EMIT_SYMBOL, 107),\n    (41, HUFFMAN_EMIT_SYMBOL, 107),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 107),\n\n    # Node 63\n    (3, HUFFMAN_EMIT_SYMBOL, 113),\n    (6, HUFFMAN_EMIT_SYMBOL, 113),\n    (10, HUFFMAN_EMIT_SYMBOL, 113),\n    (15, HUFFMAN_EMIT_SYMBOL, 113),\n    (24, HUFFMAN_EMIT_SYMBOL, 113),\n    (31, HUFFMAN_EMIT_SYMBOL, 113),\n    (41, HUFFMAN_EMIT_SYMBOL, 113),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 113),\n    (3, HUFFMAN_EMIT_SYMBOL, 118),\n    (6, HUFFMAN_EMIT_SYMBOL, 118),\n    (10, HUFFMAN_EMIT_SYMBOL, 118),\n    (15, HUFFMAN_EMIT_SYMBOL, 118),\n    (24, HUFFMAN_EMIT_SYMBOL, 118),\n    (31, HUFFMAN_EMIT_SYMBOL, 118),\n    (41, HUFFMAN_EMIT_SYMBOL, 118),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 118),\n\n    # Node 64\n    (1, HUFFMAN_EMIT_SYMBOL, 119),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 119),\n    (1, HUFFMAN_EMIT_SYMBOL, 120),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 120),\n    (1, HUFFMAN_EMIT_SYMBOL, 121),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 121),\n    (1, HUFFMAN_EMIT_SYMBOL, 122),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 122),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 38),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 42),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 44),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 59),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 88),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 90),\n    (75, 0, 0),\n    (78, 0, 0),\n\n    # Node 65\n    (2, HUFFMAN_EMIT_SYMBOL, 119),\n    (9, HUFFMAN_EMIT_SYMBOL, 119),\n    (23, HUFFMAN_EMIT_SYMBOL, 119),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 119),\n    (2, HUFFMAN_EMIT_SYMBOL, 120),\n    (9, HUFFMAN_EMIT_SYMBOL, 120),\n    (23, HUFFMAN_EMIT_SYMBOL, 120),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 120),\n    (2, HUFFMAN_EMIT_SYMBOL, 121),\n    (9, HUFFMAN_EMIT_SYMBOL, 121),\n    (23, HUFFMAN_EMIT_SYMBOL, 121),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 121),\n    (2, HUFFMAN_EMIT_SYMBOL, 122),\n    (9, HUFFMAN_EMIT_SYMBOL, 122),\n    (23, HUFFMAN_EMIT_SYMBOL, 122),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 122),\n\n    # Node 66\n    (3, HUFFMAN_EMIT_SYMBOL, 119),\n    (6, HUFFMAN_EMIT_SYMBOL, 119),\n    (10, HUFFMAN_EMIT_SYMBOL, 119),\n    (15, HUFFMAN_EMIT_SYMBOL, 119),\n    (24, HUFFMAN_EMIT_SYMBOL, 119),\n    (31, HUFFMAN_EMIT_SYMBOL, 119),\n    (41, HUFFMAN_EMIT_SYMBOL, 119),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 119),\n    (3, HUFFMAN_EMIT_SYMBOL, 120),\n    (6, HUFFMAN_EMIT_SYMBOL, 120),\n    (10, HUFFMAN_EMIT_SYMBOL, 120),\n    (15, HUFFMAN_EMIT_SYMBOL, 120),\n    (24, HUFFMAN_EMIT_SYMBOL, 120),\n    (31, HUFFMAN_EMIT_SYMBOL, 120),\n    (41, HUFFMAN_EMIT_SYMBOL, 120),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 120),\n\n    # Node 67\n    (3, HUFFMAN_EMIT_SYMBOL, 121),\n    (6, HUFFMAN_EMIT_SYMBOL, 121),\n    (10, HUFFMAN_EMIT_SYMBOL, 121),\n    (15, HUFFMAN_EMIT_SYMBOL, 121),\n    (24, HUFFMAN_EMIT_SYMBOL, 121),\n    (31, HUFFMAN_EMIT_SYMBOL, 121),\n    (41, HUFFMAN_EMIT_SYMBOL, 121),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 121),\n    (3, HUFFMAN_EMIT_SYMBOL, 122),\n    (6, HUFFMAN_EMIT_SYMBOL, 122),\n    (10, HUFFMAN_EMIT_SYMBOL, 122),\n    (15, HUFFMAN_EMIT_SYMBOL, 122),\n    (24, HUFFMAN_EMIT_SYMBOL, 122),\n    (31, HUFFMAN_EMIT_SYMBOL, 122),\n    (41, HUFFMAN_EMIT_SYMBOL, 122),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 122),\n\n    # Node 68\n    (1, HUFFMAN_EMIT_SYMBOL, 38),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 38),\n    (1, HUFFMAN_EMIT_SYMBOL, 42),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 42),\n    (1, HUFFMAN_EMIT_SYMBOL, 44),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 44),\n    (1, HUFFMAN_EMIT_SYMBOL, 59),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 59),\n    (1, HUFFMAN_EMIT_SYMBOL, 88),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 88),\n    (1, HUFFMAN_EMIT_SYMBOL, 90),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 90),\n    (76, 0, 0),\n    (77, 0, 0),\n    (79, 0, 0),\n    (81, 0, 0),\n\n    # Node 69\n    (2, HUFFMAN_EMIT_SYMBOL, 38),\n    (9, HUFFMAN_EMIT_SYMBOL, 38),\n    (23, HUFFMAN_EMIT_SYMBOL, 38),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 38),\n    (2, HUFFMAN_EMIT_SYMBOL, 42),\n    (9, HUFFMAN_EMIT_SYMBOL, 42),\n    (23, HUFFMAN_EMIT_SYMBOL, 42),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 42),\n    (2, HUFFMAN_EMIT_SYMBOL, 44),\n    (9, HUFFMAN_EMIT_SYMBOL, 44),\n    (23, HUFFMAN_EMIT_SYMBOL, 44),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 44),\n    (2, HUFFMAN_EMIT_SYMBOL, 59),\n    (9, HUFFMAN_EMIT_SYMBOL, 59),\n    (23, HUFFMAN_EMIT_SYMBOL, 59),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 59),\n\n    # Node 70\n    (3, HUFFMAN_EMIT_SYMBOL, 38),\n    (6, HUFFMAN_EMIT_SYMBOL, 38),\n    (10, HUFFMAN_EMIT_SYMBOL, 38),\n    (15, HUFFMAN_EMIT_SYMBOL, 38),\n    (24, HUFFMAN_EMIT_SYMBOL, 38),\n    (31, HUFFMAN_EMIT_SYMBOL, 38),\n    (41, HUFFMAN_EMIT_SYMBOL, 38),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 38),\n    (3, HUFFMAN_EMIT_SYMBOL, 42),\n    (6, HUFFMAN_EMIT_SYMBOL, 42),\n    (10, HUFFMAN_EMIT_SYMBOL, 42),\n    (15, HUFFMAN_EMIT_SYMBOL, 42),\n    (24, HUFFMAN_EMIT_SYMBOL, 42),\n    (31, HUFFMAN_EMIT_SYMBOL, 42),\n    (41, HUFFMAN_EMIT_SYMBOL, 42),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 42),\n\n    # Node 71\n    (3, HUFFMAN_EMIT_SYMBOL, 44),\n    (6, HUFFMAN_EMIT_SYMBOL, 44),\n    (10, HUFFMAN_EMIT_SYMBOL, 44),\n    (15, HUFFMAN_EMIT_SYMBOL, 44),\n    (24, HUFFMAN_EMIT_SYMBOL, 44),\n    (31, HUFFMAN_EMIT_SYMBOL, 44),\n    (41, HUFFMAN_EMIT_SYMBOL, 44),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 44),\n    (3, HUFFMAN_EMIT_SYMBOL, 59),\n    (6, HUFFMAN_EMIT_SYMBOL, 59),\n    (10, HUFFMAN_EMIT_SYMBOL, 59),\n    (15, HUFFMAN_EMIT_SYMBOL, 59),\n    (24, HUFFMAN_EMIT_SYMBOL, 59),\n    (31, HUFFMAN_EMIT_SYMBOL, 59),\n    (41, HUFFMAN_EMIT_SYMBOL, 59),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 59),\n\n    # Node 72\n    (2, HUFFMAN_EMIT_SYMBOL, 88),\n    (9, HUFFMAN_EMIT_SYMBOL, 88),\n    (23, HUFFMAN_EMIT_SYMBOL, 88),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 88),\n    (2, HUFFMAN_EMIT_SYMBOL, 90),\n    (9, HUFFMAN_EMIT_SYMBOL, 90),\n    (23, HUFFMAN_EMIT_SYMBOL, 90),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 90),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 33),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 34),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 40),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 41),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 63),\n    (80, 0, 0),\n    (82, 0, 0),\n    (84, 0, 0),\n\n    # Node 73\n    (3, HUFFMAN_EMIT_SYMBOL, 88),\n    (6, HUFFMAN_EMIT_SYMBOL, 88),\n    (10, HUFFMAN_EMIT_SYMBOL, 88),\n    (15, HUFFMAN_EMIT_SYMBOL, 88),\n    (24, HUFFMAN_EMIT_SYMBOL, 88),\n    (31, HUFFMAN_EMIT_SYMBOL, 88),\n    (41, HUFFMAN_EMIT_SYMBOL, 88),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 88),\n    (3, HUFFMAN_EMIT_SYMBOL, 90),\n    (6, HUFFMAN_EMIT_SYMBOL, 90),\n    (10, HUFFMAN_EMIT_SYMBOL, 90),\n    (15, HUFFMAN_EMIT_SYMBOL, 90),\n    (24, HUFFMAN_EMIT_SYMBOL, 90),\n    (31, HUFFMAN_EMIT_SYMBOL, 90),\n    (41, HUFFMAN_EMIT_SYMBOL, 90),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 90),\n\n    # Node 74\n    (1, HUFFMAN_EMIT_SYMBOL, 33),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 33),\n    (1, HUFFMAN_EMIT_SYMBOL, 34),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 34),\n    (1, HUFFMAN_EMIT_SYMBOL, 40),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 40),\n    (1, HUFFMAN_EMIT_SYMBOL, 41),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 41),\n    (1, HUFFMAN_EMIT_SYMBOL, 63),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 63),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 39),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 43),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 124),\n    (83, 0, 0),\n    (85, 0, 0),\n    (88, 0, 0),\n\n    # Node 75\n    (2, HUFFMAN_EMIT_SYMBOL, 33),\n    (9, HUFFMAN_EMIT_SYMBOL, 33),\n    (23, HUFFMAN_EMIT_SYMBOL, 33),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 33),\n    (2, HUFFMAN_EMIT_SYMBOL, 34),\n    (9, HUFFMAN_EMIT_SYMBOL, 34),\n    (23, HUFFMAN_EMIT_SYMBOL, 34),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 34),\n    (2, HUFFMAN_EMIT_SYMBOL, 40),\n    (9, HUFFMAN_EMIT_SYMBOL, 40),\n    (23, HUFFMAN_EMIT_SYMBOL, 40),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 40),\n    (2, HUFFMAN_EMIT_SYMBOL, 41),\n    (9, HUFFMAN_EMIT_SYMBOL, 41),\n    (23, HUFFMAN_EMIT_SYMBOL, 41),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 41),\n\n    # Node 76\n    (3, HUFFMAN_EMIT_SYMBOL, 33),\n    (6, HUFFMAN_EMIT_SYMBOL, 33),\n    (10, HUFFMAN_EMIT_SYMBOL, 33),\n    (15, HUFFMAN_EMIT_SYMBOL, 33),\n    (24, HUFFMAN_EMIT_SYMBOL, 33),\n    (31, HUFFMAN_EMIT_SYMBOL, 33),\n    (41, HUFFMAN_EMIT_SYMBOL, 33),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 33),\n    (3, HUFFMAN_EMIT_SYMBOL, 34),\n    (6, HUFFMAN_EMIT_SYMBOL, 34),\n    (10, HUFFMAN_EMIT_SYMBOL, 34),\n    (15, HUFFMAN_EMIT_SYMBOL, 34),\n    (24, HUFFMAN_EMIT_SYMBOL, 34),\n    (31, HUFFMAN_EMIT_SYMBOL, 34),\n    (41, HUFFMAN_EMIT_SYMBOL, 34),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 34),\n\n    # Node 77\n    (3, HUFFMAN_EMIT_SYMBOL, 40),\n    (6, HUFFMAN_EMIT_SYMBOL, 40),\n    (10, HUFFMAN_EMIT_SYMBOL, 40),\n    (15, HUFFMAN_EMIT_SYMBOL, 40),\n    (24, HUFFMAN_EMIT_SYMBOL, 40),\n    (31, HUFFMAN_EMIT_SYMBOL, 40),\n    (41, HUFFMAN_EMIT_SYMBOL, 40),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 40),\n    (3, HUFFMAN_EMIT_SYMBOL, 41),\n    (6, HUFFMAN_EMIT_SYMBOL, 41),\n    (10, HUFFMAN_EMIT_SYMBOL, 41),\n    (15, HUFFMAN_EMIT_SYMBOL, 41),\n    (24, HUFFMAN_EMIT_SYMBOL, 41),\n    (31, HUFFMAN_EMIT_SYMBOL, 41),\n    (41, HUFFMAN_EMIT_SYMBOL, 41),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 41),\n\n    # Node 78\n    (2, HUFFMAN_EMIT_SYMBOL, 63),\n    (9, HUFFMAN_EMIT_SYMBOL, 63),\n    (23, HUFFMAN_EMIT_SYMBOL, 63),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 63),\n    (1, HUFFMAN_EMIT_SYMBOL, 39),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 39),\n    (1, HUFFMAN_EMIT_SYMBOL, 43),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 43),\n    (1, HUFFMAN_EMIT_SYMBOL, 124),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 124),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 35),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 62),\n    (86, 0, 0),\n    (87, 0, 0),\n    (89, 0, 0),\n    (90, 0, 0),\n\n    # Node 79\n    (3, HUFFMAN_EMIT_SYMBOL, 63),\n    (6, HUFFMAN_EMIT_SYMBOL, 63),\n    (10, HUFFMAN_EMIT_SYMBOL, 63),\n    (15, HUFFMAN_EMIT_SYMBOL, 63),\n    (24, HUFFMAN_EMIT_SYMBOL, 63),\n    (31, HUFFMAN_EMIT_SYMBOL, 63),\n    (41, HUFFMAN_EMIT_SYMBOL, 63),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 63),\n    (2, HUFFMAN_EMIT_SYMBOL, 39),\n    (9, HUFFMAN_EMIT_SYMBOL, 39),\n    (23, HUFFMAN_EMIT_SYMBOL, 39),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 39),\n    (2, HUFFMAN_EMIT_SYMBOL, 43),\n    (9, HUFFMAN_EMIT_SYMBOL, 43),\n    (23, HUFFMAN_EMIT_SYMBOL, 43),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 43),\n\n    # Node 80\n    (3, HUFFMAN_EMIT_SYMBOL, 39),\n    (6, HUFFMAN_EMIT_SYMBOL, 39),\n    (10, HUFFMAN_EMIT_SYMBOL, 39),\n    (15, HUFFMAN_EMIT_SYMBOL, 39),\n    (24, HUFFMAN_EMIT_SYMBOL, 39),\n    (31, HUFFMAN_EMIT_SYMBOL, 39),\n    (41, HUFFMAN_EMIT_SYMBOL, 39),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 39),\n    (3, HUFFMAN_EMIT_SYMBOL, 43),\n    (6, HUFFMAN_EMIT_SYMBOL, 43),\n    (10, HUFFMAN_EMIT_SYMBOL, 43),\n    (15, HUFFMAN_EMIT_SYMBOL, 43),\n    (24, HUFFMAN_EMIT_SYMBOL, 43),\n    (31, HUFFMAN_EMIT_SYMBOL, 43),\n    (41, HUFFMAN_EMIT_SYMBOL, 43),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 43),\n\n    # Node 81\n    (2, HUFFMAN_EMIT_SYMBOL, 124),\n    (9, HUFFMAN_EMIT_SYMBOL, 124),\n    (23, HUFFMAN_EMIT_SYMBOL, 124),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 124),\n    (1, HUFFMAN_EMIT_SYMBOL, 35),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 35),\n    (1, HUFFMAN_EMIT_SYMBOL, 62),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 62),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 0),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 36),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 64),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 91),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 93),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 126),\n    (91, 0, 0),\n    (92, 0, 0),\n\n    # Node 82\n    (3, HUFFMAN_EMIT_SYMBOL, 124),\n    (6, HUFFMAN_EMIT_SYMBOL, 124),\n    (10, HUFFMAN_EMIT_SYMBOL, 124),\n    (15, HUFFMAN_EMIT_SYMBOL, 124),\n    (24, HUFFMAN_EMIT_SYMBOL, 124),\n    (31, HUFFMAN_EMIT_SYMBOL, 124),\n    (41, HUFFMAN_EMIT_SYMBOL, 124),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 124),\n    (2, HUFFMAN_EMIT_SYMBOL, 35),\n    (9, HUFFMAN_EMIT_SYMBOL, 35),\n    (23, HUFFMAN_EMIT_SYMBOL, 35),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 35),\n    (2, HUFFMAN_EMIT_SYMBOL, 62),\n    (9, HUFFMAN_EMIT_SYMBOL, 62),\n    (23, HUFFMAN_EMIT_SYMBOL, 62),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 62),\n\n    # Node 83\n    (3, HUFFMAN_EMIT_SYMBOL, 35),\n    (6, HUFFMAN_EMIT_SYMBOL, 35),\n    (10, HUFFMAN_EMIT_SYMBOL, 35),\n    (15, HUFFMAN_EMIT_SYMBOL, 35),\n    (24, HUFFMAN_EMIT_SYMBOL, 35),\n    (31, HUFFMAN_EMIT_SYMBOL, 35),\n    (41, HUFFMAN_EMIT_SYMBOL, 35),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 35),\n    (3, HUFFMAN_EMIT_SYMBOL, 62),\n    (6, HUFFMAN_EMIT_SYMBOL, 62),\n    (10, HUFFMAN_EMIT_SYMBOL, 62),\n    (15, HUFFMAN_EMIT_SYMBOL, 62),\n    (24, HUFFMAN_EMIT_SYMBOL, 62),\n    (31, HUFFMAN_EMIT_SYMBOL, 62),\n    (41, HUFFMAN_EMIT_SYMBOL, 62),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 62),\n\n    # Node 84\n    (1, HUFFMAN_EMIT_SYMBOL, 0),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 0),\n    (1, HUFFMAN_EMIT_SYMBOL, 36),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 36),\n    (1, HUFFMAN_EMIT_SYMBOL, 64),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 64),\n    (1, HUFFMAN_EMIT_SYMBOL, 91),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 91),\n    (1, HUFFMAN_EMIT_SYMBOL, 93),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 93),\n    (1, HUFFMAN_EMIT_SYMBOL, 126),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 126),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 94),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 125),\n    (93, 0, 0),\n    (94, 0, 0),\n\n    # Node 85\n    (2, HUFFMAN_EMIT_SYMBOL, 0),\n    (9, HUFFMAN_EMIT_SYMBOL, 0),\n    (23, HUFFMAN_EMIT_SYMBOL, 0),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 0),\n    (2, HUFFMAN_EMIT_SYMBOL, 36),\n    (9, HUFFMAN_EMIT_SYMBOL, 36),\n    (23, HUFFMAN_EMIT_SYMBOL, 36),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 36),\n    (2, HUFFMAN_EMIT_SYMBOL, 64),\n    (9, HUFFMAN_EMIT_SYMBOL, 64),\n    (23, HUFFMAN_EMIT_SYMBOL, 64),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 64),\n    (2, HUFFMAN_EMIT_SYMBOL, 91),\n    (9, HUFFMAN_EMIT_SYMBOL, 91),\n    (23, HUFFMAN_EMIT_SYMBOL, 91),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 91),\n\n    # Node 86\n    (3, HUFFMAN_EMIT_SYMBOL, 0),\n    (6, HUFFMAN_EMIT_SYMBOL, 0),\n    (10, HUFFMAN_EMIT_SYMBOL, 0),\n    (15, HUFFMAN_EMIT_SYMBOL, 0),\n    (24, HUFFMAN_EMIT_SYMBOL, 0),\n    (31, HUFFMAN_EMIT_SYMBOL, 0),\n    (41, HUFFMAN_EMIT_SYMBOL, 0),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 0),\n    (3, HUFFMAN_EMIT_SYMBOL, 36),\n    (6, HUFFMAN_EMIT_SYMBOL, 36),\n    (10, HUFFMAN_EMIT_SYMBOL, 36),\n    (15, HUFFMAN_EMIT_SYMBOL, 36),\n    (24, HUFFMAN_EMIT_SYMBOL, 36),\n    (31, HUFFMAN_EMIT_SYMBOL, 36),\n    (41, HUFFMAN_EMIT_SYMBOL, 36),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 36),\n\n    # Node 87\n    (3, HUFFMAN_EMIT_SYMBOL, 64),\n    (6, HUFFMAN_EMIT_SYMBOL, 64),\n    (10, HUFFMAN_EMIT_SYMBOL, 64),\n    (15, HUFFMAN_EMIT_SYMBOL, 64),\n    (24, HUFFMAN_EMIT_SYMBOL, 64),\n    (31, HUFFMAN_EMIT_SYMBOL, 64),\n    (41, HUFFMAN_EMIT_SYMBOL, 64),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 64),\n    (3, HUFFMAN_EMIT_SYMBOL, 91),\n    (6, HUFFMAN_EMIT_SYMBOL, 91),\n    (10, HUFFMAN_EMIT_SYMBOL, 91),\n    (15, HUFFMAN_EMIT_SYMBOL, 91),\n    (24, HUFFMAN_EMIT_SYMBOL, 91),\n    (31, HUFFMAN_EMIT_SYMBOL, 91),\n    (41, HUFFMAN_EMIT_SYMBOL, 91),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 91),\n\n    # Node 88\n    (2, HUFFMAN_EMIT_SYMBOL, 93),\n    (9, HUFFMAN_EMIT_SYMBOL, 93),\n    (23, HUFFMAN_EMIT_SYMBOL, 93),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 93),\n    (2, HUFFMAN_EMIT_SYMBOL, 126),\n    (9, HUFFMAN_EMIT_SYMBOL, 126),\n    (23, HUFFMAN_EMIT_SYMBOL, 126),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 126),\n    (1, HUFFMAN_EMIT_SYMBOL, 94),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 94),\n    (1, HUFFMAN_EMIT_SYMBOL, 125),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 125),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 60),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 96),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 123),\n    (95, 0, 0),\n\n    # Node 89\n    (3, HUFFMAN_EMIT_SYMBOL, 93),\n    (6, HUFFMAN_EMIT_SYMBOL, 93),\n    (10, HUFFMAN_EMIT_SYMBOL, 93),\n    (15, HUFFMAN_EMIT_SYMBOL, 93),\n    (24, HUFFMAN_EMIT_SYMBOL, 93),\n    (31, HUFFMAN_EMIT_SYMBOL, 93),\n    (41, HUFFMAN_EMIT_SYMBOL, 93),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 93),\n    (3, HUFFMAN_EMIT_SYMBOL, 126),\n    (6, HUFFMAN_EMIT_SYMBOL, 126),\n    (10, HUFFMAN_EMIT_SYMBOL, 126),\n    (15, HUFFMAN_EMIT_SYMBOL, 126),\n    (24, HUFFMAN_EMIT_SYMBOL, 126),\n    (31, HUFFMAN_EMIT_SYMBOL, 126),\n    (41, HUFFMAN_EMIT_SYMBOL, 126),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 126),\n\n    # Node 90\n    (2, HUFFMAN_EMIT_SYMBOL, 94),\n    (9, HUFFMAN_EMIT_SYMBOL, 94),\n    (23, HUFFMAN_EMIT_SYMBOL, 94),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 94),\n    (2, HUFFMAN_EMIT_SYMBOL, 125),\n    (9, HUFFMAN_EMIT_SYMBOL, 125),\n    (23, HUFFMAN_EMIT_SYMBOL, 125),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 125),\n    (1, HUFFMAN_EMIT_SYMBOL, 60),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 60),\n    (1, HUFFMAN_EMIT_SYMBOL, 96),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 96),\n    (1, HUFFMAN_EMIT_SYMBOL, 123),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 123),\n    (96, 0, 0),\n    (110, 0, 0),\n\n    # Node 91\n    (3, HUFFMAN_EMIT_SYMBOL, 94),\n    (6, HUFFMAN_EMIT_SYMBOL, 94),\n    (10, HUFFMAN_EMIT_SYMBOL, 94),\n    (15, HUFFMAN_EMIT_SYMBOL, 94),\n    (24, HUFFMAN_EMIT_SYMBOL, 94),\n    (31, HUFFMAN_EMIT_SYMBOL, 94),\n    (41, HUFFMAN_EMIT_SYMBOL, 94),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 94),\n    (3, HUFFMAN_EMIT_SYMBOL, 125),\n    (6, HUFFMAN_EMIT_SYMBOL, 125),\n    (10, HUFFMAN_EMIT_SYMBOL, 125),\n    (15, HUFFMAN_EMIT_SYMBOL, 125),\n    (24, HUFFMAN_EMIT_SYMBOL, 125),\n    (31, HUFFMAN_EMIT_SYMBOL, 125),\n    (41, HUFFMAN_EMIT_SYMBOL, 125),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 125),\n\n    # Node 92\n    (2, HUFFMAN_EMIT_SYMBOL, 60),\n    (9, HUFFMAN_EMIT_SYMBOL, 60),\n    (23, HUFFMAN_EMIT_SYMBOL, 60),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 60),\n    (2, HUFFMAN_EMIT_SYMBOL, 96),\n    (9, HUFFMAN_EMIT_SYMBOL, 96),\n    (23, HUFFMAN_EMIT_SYMBOL, 96),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 96),\n    (2, HUFFMAN_EMIT_SYMBOL, 123),\n    (9, HUFFMAN_EMIT_SYMBOL, 123),\n    (23, HUFFMAN_EMIT_SYMBOL, 123),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 123),\n    (97, 0, 0),\n    (101, 0, 0),\n    (111, 0, 0),\n    (133, 0, 0),\n\n    # Node 93\n    (3, HUFFMAN_EMIT_SYMBOL, 60),\n    (6, HUFFMAN_EMIT_SYMBOL, 60),\n    (10, HUFFMAN_EMIT_SYMBOL, 60),\n    (15, HUFFMAN_EMIT_SYMBOL, 60),\n    (24, HUFFMAN_EMIT_SYMBOL, 60),\n    (31, HUFFMAN_EMIT_SYMBOL, 60),\n    (41, HUFFMAN_EMIT_SYMBOL, 60),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 60),\n    (3, HUFFMAN_EMIT_SYMBOL, 96),\n    (6, HUFFMAN_EMIT_SYMBOL, 96),\n    (10, HUFFMAN_EMIT_SYMBOL, 96),\n    (15, HUFFMAN_EMIT_SYMBOL, 96),\n    (24, HUFFMAN_EMIT_SYMBOL, 96),\n    (31, HUFFMAN_EMIT_SYMBOL, 96),\n    (41, HUFFMAN_EMIT_SYMBOL, 96),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 96),\n\n    # Node 94\n    (3, HUFFMAN_EMIT_SYMBOL, 123),\n    (6, HUFFMAN_EMIT_SYMBOL, 123),\n    (10, HUFFMAN_EMIT_SYMBOL, 123),\n    (15, HUFFMAN_EMIT_SYMBOL, 123),\n    (24, HUFFMAN_EMIT_SYMBOL, 123),\n    (31, HUFFMAN_EMIT_SYMBOL, 123),\n    (41, HUFFMAN_EMIT_SYMBOL, 123),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 123),\n    (98, 0, 0),\n    (99, 0, 0),\n    (102, 0, 0),\n    (105, 0, 0),\n    (112, 0, 0),\n    (119, 0, 0),\n    (134, 0, 0),\n    (153, 0, 0),\n\n    # Node 95\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 92),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 195),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 208),\n    (100, 0, 0),\n    (103, 0, 0),\n    (104, 0, 0),\n    (106, 0, 0),\n    (107, 0, 0),\n    (113, 0, 0),\n    (116, 0, 0),\n    (120, 0, 0),\n    (126, 0, 0),\n    (135, 0, 0),\n    (142, 0, 0),\n    (154, 0, 0),\n    (169, 0, 0),\n\n    # Node 96\n    (1, HUFFMAN_EMIT_SYMBOL, 92),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 92),\n    (1, HUFFMAN_EMIT_SYMBOL, 195),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 195),\n    (1, HUFFMAN_EMIT_SYMBOL, 208),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 208),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 128),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 130),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 131),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 162),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 184),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 194),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 224),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 226),\n    (108, 0, 0),\n    (109, 0, 0),\n\n    # Node 97\n    (2, HUFFMAN_EMIT_SYMBOL, 92),\n    (9, HUFFMAN_EMIT_SYMBOL, 92),\n    (23, HUFFMAN_EMIT_SYMBOL, 92),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 92),\n    (2, HUFFMAN_EMIT_SYMBOL, 195),\n    (9, HUFFMAN_EMIT_SYMBOL, 195),\n    (23, HUFFMAN_EMIT_SYMBOL, 195),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 195),\n    (2, HUFFMAN_EMIT_SYMBOL, 208),\n    (9, HUFFMAN_EMIT_SYMBOL, 208),\n    (23, HUFFMAN_EMIT_SYMBOL, 208),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 208),\n    (1, HUFFMAN_EMIT_SYMBOL, 128),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 128),\n    (1, HUFFMAN_EMIT_SYMBOL, 130),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 130),\n\n    # Node 98\n    (3, HUFFMAN_EMIT_SYMBOL, 92),\n    (6, HUFFMAN_EMIT_SYMBOL, 92),\n    (10, HUFFMAN_EMIT_SYMBOL, 92),\n    (15, HUFFMAN_EMIT_SYMBOL, 92),\n    (24, HUFFMAN_EMIT_SYMBOL, 92),\n    (31, HUFFMAN_EMIT_SYMBOL, 92),\n    (41, HUFFMAN_EMIT_SYMBOL, 92),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 92),\n    (3, HUFFMAN_EMIT_SYMBOL, 195),\n    (6, HUFFMAN_EMIT_SYMBOL, 195),\n    (10, HUFFMAN_EMIT_SYMBOL, 195),\n    (15, HUFFMAN_EMIT_SYMBOL, 195),\n    (24, HUFFMAN_EMIT_SYMBOL, 195),\n    (31, HUFFMAN_EMIT_SYMBOL, 195),\n    (41, HUFFMAN_EMIT_SYMBOL, 195),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 195),\n\n    # Node 99\n    (3, HUFFMAN_EMIT_SYMBOL, 208),\n    (6, HUFFMAN_EMIT_SYMBOL, 208),\n    (10, HUFFMAN_EMIT_SYMBOL, 208),\n    (15, HUFFMAN_EMIT_SYMBOL, 208),\n    (24, HUFFMAN_EMIT_SYMBOL, 208),\n    (31, HUFFMAN_EMIT_SYMBOL, 208),\n    (41, HUFFMAN_EMIT_SYMBOL, 208),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 208),\n    (2, HUFFMAN_EMIT_SYMBOL, 128),\n    (9, HUFFMAN_EMIT_SYMBOL, 128),\n    (23, HUFFMAN_EMIT_SYMBOL, 128),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 128),\n    (2, HUFFMAN_EMIT_SYMBOL, 130),\n    (9, HUFFMAN_EMIT_SYMBOL, 130),\n    (23, HUFFMAN_EMIT_SYMBOL, 130),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 130),\n\n    # Node 100\n    (3, HUFFMAN_EMIT_SYMBOL, 128),\n    (6, HUFFMAN_EMIT_SYMBOL, 128),\n    (10, HUFFMAN_EMIT_SYMBOL, 128),\n    (15, HUFFMAN_EMIT_SYMBOL, 128),\n    (24, HUFFMAN_EMIT_SYMBOL, 128),\n    (31, HUFFMAN_EMIT_SYMBOL, 128),\n    (41, HUFFMAN_EMIT_SYMBOL, 128),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 128),\n    (3, HUFFMAN_EMIT_SYMBOL, 130),\n    (6, HUFFMAN_EMIT_SYMBOL, 130),\n    (10, HUFFMAN_EMIT_SYMBOL, 130),\n    (15, HUFFMAN_EMIT_SYMBOL, 130),\n    (24, HUFFMAN_EMIT_SYMBOL, 130),\n    (31, HUFFMAN_EMIT_SYMBOL, 130),\n    (41, HUFFMAN_EMIT_SYMBOL, 130),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 130),\n\n    # Node 101\n    (1, HUFFMAN_EMIT_SYMBOL, 131),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 131),\n    (1, HUFFMAN_EMIT_SYMBOL, 162),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 162),\n    (1, HUFFMAN_EMIT_SYMBOL, 184),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 184),\n    (1, HUFFMAN_EMIT_SYMBOL, 194),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 194),\n    (1, HUFFMAN_EMIT_SYMBOL, 224),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 224),\n    (1, HUFFMAN_EMIT_SYMBOL, 226),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 226),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 153),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 161),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 167),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 172),\n\n    # Node 102\n    (2, HUFFMAN_EMIT_SYMBOL, 131),\n    (9, HUFFMAN_EMIT_SYMBOL, 131),\n    (23, HUFFMAN_EMIT_SYMBOL, 131),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 131),\n    (2, HUFFMAN_EMIT_SYMBOL, 162),\n    (9, HUFFMAN_EMIT_SYMBOL, 162),\n    (23, HUFFMAN_EMIT_SYMBOL, 162),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 162),\n    (2, HUFFMAN_EMIT_SYMBOL, 184),\n    (9, HUFFMAN_EMIT_SYMBOL, 184),\n    (23, HUFFMAN_EMIT_SYMBOL, 184),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 184),\n    (2, HUFFMAN_EMIT_SYMBOL, 194),\n    (9, HUFFMAN_EMIT_SYMBOL, 194),\n    (23, HUFFMAN_EMIT_SYMBOL, 194),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 194),\n\n    # Node 103\n    (3, HUFFMAN_EMIT_SYMBOL, 131),\n    (6, HUFFMAN_EMIT_SYMBOL, 131),\n    (10, HUFFMAN_EMIT_SYMBOL, 131),\n    (15, HUFFMAN_EMIT_SYMBOL, 131),\n    (24, HUFFMAN_EMIT_SYMBOL, 131),\n    (31, HUFFMAN_EMIT_SYMBOL, 131),\n    (41, HUFFMAN_EMIT_SYMBOL, 131),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 131),\n    (3, HUFFMAN_EMIT_SYMBOL, 162),\n    (6, HUFFMAN_EMIT_SYMBOL, 162),\n    (10, HUFFMAN_EMIT_SYMBOL, 162),\n    (15, HUFFMAN_EMIT_SYMBOL, 162),\n    (24, HUFFMAN_EMIT_SYMBOL, 162),\n    (31, HUFFMAN_EMIT_SYMBOL, 162),\n    (41, HUFFMAN_EMIT_SYMBOL, 162),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 162),\n\n    # Node 104\n    (3, HUFFMAN_EMIT_SYMBOL, 184),\n    (6, HUFFMAN_EMIT_SYMBOL, 184),\n    (10, HUFFMAN_EMIT_SYMBOL, 184),\n    (15, HUFFMAN_EMIT_SYMBOL, 184),\n    (24, HUFFMAN_EMIT_SYMBOL, 184),\n    (31, HUFFMAN_EMIT_SYMBOL, 184),\n    (41, HUFFMAN_EMIT_SYMBOL, 184),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 184),\n    (3, HUFFMAN_EMIT_SYMBOL, 194),\n    (6, HUFFMAN_EMIT_SYMBOL, 194),\n    (10, HUFFMAN_EMIT_SYMBOL, 194),\n    (15, HUFFMAN_EMIT_SYMBOL, 194),\n    (24, HUFFMAN_EMIT_SYMBOL, 194),\n    (31, HUFFMAN_EMIT_SYMBOL, 194),\n    (41, HUFFMAN_EMIT_SYMBOL, 194),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 194),\n\n    # Node 105\n    (2, HUFFMAN_EMIT_SYMBOL, 224),\n    (9, HUFFMAN_EMIT_SYMBOL, 224),\n    (23, HUFFMAN_EMIT_SYMBOL, 224),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 224),\n    (2, HUFFMAN_EMIT_SYMBOL, 226),\n    (9, HUFFMAN_EMIT_SYMBOL, 226),\n    (23, HUFFMAN_EMIT_SYMBOL, 226),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 226),\n    (1, HUFFMAN_EMIT_SYMBOL, 153),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 153),\n    (1, HUFFMAN_EMIT_SYMBOL, 161),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 161),\n    (1, HUFFMAN_EMIT_SYMBOL, 167),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 167),\n    (1, HUFFMAN_EMIT_SYMBOL, 172),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 172),\n\n    # Node 106\n    (3, HUFFMAN_EMIT_SYMBOL, 224),\n    (6, HUFFMAN_EMIT_SYMBOL, 224),\n    (10, HUFFMAN_EMIT_SYMBOL, 224),\n    (15, HUFFMAN_EMIT_SYMBOL, 224),\n    (24, HUFFMAN_EMIT_SYMBOL, 224),\n    (31, HUFFMAN_EMIT_SYMBOL, 224),\n    (41, HUFFMAN_EMIT_SYMBOL, 224),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 224),\n    (3, HUFFMAN_EMIT_SYMBOL, 226),\n    (6, HUFFMAN_EMIT_SYMBOL, 226),\n    (10, HUFFMAN_EMIT_SYMBOL, 226),\n    (15, HUFFMAN_EMIT_SYMBOL, 226),\n    (24, HUFFMAN_EMIT_SYMBOL, 226),\n    (31, HUFFMAN_EMIT_SYMBOL, 226),\n    (41, HUFFMAN_EMIT_SYMBOL, 226),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 226),\n\n    # Node 107\n    (2, HUFFMAN_EMIT_SYMBOL, 153),\n    (9, HUFFMAN_EMIT_SYMBOL, 153),\n    (23, HUFFMAN_EMIT_SYMBOL, 153),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 153),\n    (2, HUFFMAN_EMIT_SYMBOL, 161),\n    (9, HUFFMAN_EMIT_SYMBOL, 161),\n    (23, HUFFMAN_EMIT_SYMBOL, 161),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 161),\n    (2, HUFFMAN_EMIT_SYMBOL, 167),\n    (9, HUFFMAN_EMIT_SYMBOL, 167),\n    (23, HUFFMAN_EMIT_SYMBOL, 167),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 167),\n    (2, HUFFMAN_EMIT_SYMBOL, 172),\n    (9, HUFFMAN_EMIT_SYMBOL, 172),\n    (23, HUFFMAN_EMIT_SYMBOL, 172),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 172),\n\n    # Node 108\n    (3, HUFFMAN_EMIT_SYMBOL, 153),\n    (6, HUFFMAN_EMIT_SYMBOL, 153),\n    (10, HUFFMAN_EMIT_SYMBOL, 153),\n    (15, HUFFMAN_EMIT_SYMBOL, 153),\n    (24, HUFFMAN_EMIT_SYMBOL, 153),\n    (31, HUFFMAN_EMIT_SYMBOL, 153),\n    (41, HUFFMAN_EMIT_SYMBOL, 153),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 153),\n    (3, HUFFMAN_EMIT_SYMBOL, 161),\n    (6, HUFFMAN_EMIT_SYMBOL, 161),\n    (10, HUFFMAN_EMIT_SYMBOL, 161),\n    (15, HUFFMAN_EMIT_SYMBOL, 161),\n    (24, HUFFMAN_EMIT_SYMBOL, 161),\n    (31, HUFFMAN_EMIT_SYMBOL, 161),\n    (41, HUFFMAN_EMIT_SYMBOL, 161),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 161),\n\n    # Node 109\n    (3, HUFFMAN_EMIT_SYMBOL, 167),\n    (6, HUFFMAN_EMIT_SYMBOL, 167),\n    (10, HUFFMAN_EMIT_SYMBOL, 167),\n    (15, HUFFMAN_EMIT_SYMBOL, 167),\n    (24, HUFFMAN_EMIT_SYMBOL, 167),\n    (31, HUFFMAN_EMIT_SYMBOL, 167),\n    (41, HUFFMAN_EMIT_SYMBOL, 167),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 167),\n    (3, HUFFMAN_EMIT_SYMBOL, 172),\n    (6, HUFFMAN_EMIT_SYMBOL, 172),\n    (10, HUFFMAN_EMIT_SYMBOL, 172),\n    (15, HUFFMAN_EMIT_SYMBOL, 172),\n    (24, HUFFMAN_EMIT_SYMBOL, 172),\n    (31, HUFFMAN_EMIT_SYMBOL, 172),\n    (41, HUFFMAN_EMIT_SYMBOL, 172),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 172),\n\n    # Node 110\n    (114, 0, 0),\n    (115, 0, 0),\n    (117, 0, 0),\n    (118, 0, 0),\n    (121, 0, 0),\n    (123, 0, 0),\n    (127, 0, 0),\n    (130, 0, 0),\n    (136, 0, 0),\n    (139, 0, 0),\n    (143, 0, 0),\n    (146, 0, 0),\n    (155, 0, 0),\n    (162, 0, 0),\n    (170, 0, 0),\n    (180, 0, 0),\n\n    # Node 111\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 176),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 177),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 179),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 209),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 216),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 217),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 227),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 229),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 230),\n    (122, 0, 0),\n    (124, 0, 0),\n    (125, 0, 0),\n    (128, 0, 0),\n    (129, 0, 0),\n    (131, 0, 0),\n    (132, 0, 0),\n\n    # Node 112\n    (1, HUFFMAN_EMIT_SYMBOL, 176),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 176),\n    (1, HUFFMAN_EMIT_SYMBOL, 177),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 177),\n    (1, HUFFMAN_EMIT_SYMBOL, 179),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 179),\n    (1, HUFFMAN_EMIT_SYMBOL, 209),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 209),\n    (1, HUFFMAN_EMIT_SYMBOL, 216),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 216),\n    (1, HUFFMAN_EMIT_SYMBOL, 217),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 217),\n    (1, HUFFMAN_EMIT_SYMBOL, 227),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 227),\n    (1, HUFFMAN_EMIT_SYMBOL, 229),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 229),\n\n    # Node 113\n    (2, HUFFMAN_EMIT_SYMBOL, 176),\n    (9, HUFFMAN_EMIT_SYMBOL, 176),\n    (23, HUFFMAN_EMIT_SYMBOL, 176),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 176),\n    (2, HUFFMAN_EMIT_SYMBOL, 177),\n    (9, HUFFMAN_EMIT_SYMBOL, 177),\n    (23, HUFFMAN_EMIT_SYMBOL, 177),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 177),\n    (2, HUFFMAN_EMIT_SYMBOL, 179),\n    (9, HUFFMAN_EMIT_SYMBOL, 179),\n    (23, HUFFMAN_EMIT_SYMBOL, 179),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 179),\n    (2, HUFFMAN_EMIT_SYMBOL, 209),\n    (9, HUFFMAN_EMIT_SYMBOL, 209),\n    (23, HUFFMAN_EMIT_SYMBOL, 209),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 209),\n\n    # Node 114\n    (3, HUFFMAN_EMIT_SYMBOL, 176),\n    (6, HUFFMAN_EMIT_SYMBOL, 176),\n    (10, HUFFMAN_EMIT_SYMBOL, 176),\n    (15, HUFFMAN_EMIT_SYMBOL, 176),\n    (24, HUFFMAN_EMIT_SYMBOL, 176),\n    (31, HUFFMAN_EMIT_SYMBOL, 176),\n    (41, HUFFMAN_EMIT_SYMBOL, 176),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 176),\n    (3, HUFFMAN_EMIT_SYMBOL, 177),\n    (6, HUFFMAN_EMIT_SYMBOL, 177),\n    (10, HUFFMAN_EMIT_SYMBOL, 177),\n    (15, HUFFMAN_EMIT_SYMBOL, 177),\n    (24, HUFFMAN_EMIT_SYMBOL, 177),\n    (31, HUFFMAN_EMIT_SYMBOL, 177),\n    (41, HUFFMAN_EMIT_SYMBOL, 177),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 177),\n\n    # Node 115\n    (3, HUFFMAN_EMIT_SYMBOL, 179),\n    (6, HUFFMAN_EMIT_SYMBOL, 179),\n    (10, HUFFMAN_EMIT_SYMBOL, 179),\n    (15, HUFFMAN_EMIT_SYMBOL, 179),\n    (24, HUFFMAN_EMIT_SYMBOL, 179),\n    (31, HUFFMAN_EMIT_SYMBOL, 179),\n    (41, HUFFMAN_EMIT_SYMBOL, 179),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 179),\n    (3, HUFFMAN_EMIT_SYMBOL, 209),\n    (6, HUFFMAN_EMIT_SYMBOL, 209),\n    (10, HUFFMAN_EMIT_SYMBOL, 209),\n    (15, HUFFMAN_EMIT_SYMBOL, 209),\n    (24, HUFFMAN_EMIT_SYMBOL, 209),\n    (31, HUFFMAN_EMIT_SYMBOL, 209),\n    (41, HUFFMAN_EMIT_SYMBOL, 209),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 209),\n\n    # Node 116\n    (2, HUFFMAN_EMIT_SYMBOL, 216),\n    (9, HUFFMAN_EMIT_SYMBOL, 216),\n    (23, HUFFMAN_EMIT_SYMBOL, 216),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 216),\n    (2, HUFFMAN_EMIT_SYMBOL, 217),\n    (9, HUFFMAN_EMIT_SYMBOL, 217),\n    (23, HUFFMAN_EMIT_SYMBOL, 217),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 217),\n    (2, HUFFMAN_EMIT_SYMBOL, 227),\n    (9, HUFFMAN_EMIT_SYMBOL, 227),\n    (23, HUFFMAN_EMIT_SYMBOL, 227),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 227),\n    (2, HUFFMAN_EMIT_SYMBOL, 229),\n    (9, HUFFMAN_EMIT_SYMBOL, 229),\n    (23, HUFFMAN_EMIT_SYMBOL, 229),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 229),\n\n    # Node 117\n    (3, HUFFMAN_EMIT_SYMBOL, 216),\n    (6, HUFFMAN_EMIT_SYMBOL, 216),\n    (10, HUFFMAN_EMIT_SYMBOL, 216),\n    (15, HUFFMAN_EMIT_SYMBOL, 216),\n    (24, HUFFMAN_EMIT_SYMBOL, 216),\n    (31, HUFFMAN_EMIT_SYMBOL, 216),\n    (41, HUFFMAN_EMIT_SYMBOL, 216),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 216),\n    (3, HUFFMAN_EMIT_SYMBOL, 217),\n    (6, HUFFMAN_EMIT_SYMBOL, 217),\n    (10, HUFFMAN_EMIT_SYMBOL, 217),\n    (15, HUFFMAN_EMIT_SYMBOL, 217),\n    (24, HUFFMAN_EMIT_SYMBOL, 217),\n    (31, HUFFMAN_EMIT_SYMBOL, 217),\n    (41, HUFFMAN_EMIT_SYMBOL, 217),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 217),\n\n    # Node 118\n    (3, HUFFMAN_EMIT_SYMBOL, 227),\n    (6, HUFFMAN_EMIT_SYMBOL, 227),\n    (10, HUFFMAN_EMIT_SYMBOL, 227),\n    (15, HUFFMAN_EMIT_SYMBOL, 227),\n    (24, HUFFMAN_EMIT_SYMBOL, 227),\n    (31, HUFFMAN_EMIT_SYMBOL, 227),\n    (41, HUFFMAN_EMIT_SYMBOL, 227),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 227),\n    (3, HUFFMAN_EMIT_SYMBOL, 229),\n    (6, HUFFMAN_EMIT_SYMBOL, 229),\n    (10, HUFFMAN_EMIT_SYMBOL, 229),\n    (15, HUFFMAN_EMIT_SYMBOL, 229),\n    (24, HUFFMAN_EMIT_SYMBOL, 229),\n    (31, HUFFMAN_EMIT_SYMBOL, 229),\n    (41, HUFFMAN_EMIT_SYMBOL, 229),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 229),\n\n    # Node 119\n    (1, HUFFMAN_EMIT_SYMBOL, 230),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 230),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 129),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 132),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 133),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 134),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 136),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 146),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 154),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 156),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 160),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 163),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 164),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 169),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 170),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 173),\n\n    # Node 120\n    (2, HUFFMAN_EMIT_SYMBOL, 230),\n    (9, HUFFMAN_EMIT_SYMBOL, 230),\n    (23, HUFFMAN_EMIT_SYMBOL, 230),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 230),\n    (1, HUFFMAN_EMIT_SYMBOL, 129),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 129),\n    (1, HUFFMAN_EMIT_SYMBOL, 132),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 132),\n    (1, HUFFMAN_EMIT_SYMBOL, 133),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 133),\n    (1, HUFFMAN_EMIT_SYMBOL, 134),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 134),\n    (1, HUFFMAN_EMIT_SYMBOL, 136),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 136),\n    (1, HUFFMAN_EMIT_SYMBOL, 146),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 146),\n\n    # Node 121\n    (3, HUFFMAN_EMIT_SYMBOL, 230),\n    (6, HUFFMAN_EMIT_SYMBOL, 230),\n    (10, HUFFMAN_EMIT_SYMBOL, 230),\n    (15, HUFFMAN_EMIT_SYMBOL, 230),\n    (24, HUFFMAN_EMIT_SYMBOL, 230),\n    (31, HUFFMAN_EMIT_SYMBOL, 230),\n    (41, HUFFMAN_EMIT_SYMBOL, 230),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 230),\n    (2, HUFFMAN_EMIT_SYMBOL, 129),\n    (9, HUFFMAN_EMIT_SYMBOL, 129),\n    (23, HUFFMAN_EMIT_SYMBOL, 129),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 129),\n    (2, HUFFMAN_EMIT_SYMBOL, 132),\n    (9, HUFFMAN_EMIT_SYMBOL, 132),\n    (23, HUFFMAN_EMIT_SYMBOL, 132),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 132),\n\n    # Node 122\n    (3, HUFFMAN_EMIT_SYMBOL, 129),\n    (6, HUFFMAN_EMIT_SYMBOL, 129),\n    (10, HUFFMAN_EMIT_SYMBOL, 129),\n    (15, HUFFMAN_EMIT_SYMBOL, 129),\n    (24, HUFFMAN_EMIT_SYMBOL, 129),\n    (31, HUFFMAN_EMIT_SYMBOL, 129),\n    (41, HUFFMAN_EMIT_SYMBOL, 129),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 129),\n    (3, HUFFMAN_EMIT_SYMBOL, 132),\n    (6, HUFFMAN_EMIT_SYMBOL, 132),\n    (10, HUFFMAN_EMIT_SYMBOL, 132),\n    (15, HUFFMAN_EMIT_SYMBOL, 132),\n    (24, HUFFMAN_EMIT_SYMBOL, 132),\n    (31, HUFFMAN_EMIT_SYMBOL, 132),\n    (41, HUFFMAN_EMIT_SYMBOL, 132),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 132),\n\n    # Node 123\n    (2, HUFFMAN_EMIT_SYMBOL, 133),\n    (9, HUFFMAN_EMIT_SYMBOL, 133),\n    (23, HUFFMAN_EMIT_SYMBOL, 133),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 133),\n    (2, HUFFMAN_EMIT_SYMBOL, 134),\n    (9, HUFFMAN_EMIT_SYMBOL, 134),\n    (23, HUFFMAN_EMIT_SYMBOL, 134),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 134),\n    (2, HUFFMAN_EMIT_SYMBOL, 136),\n    (9, HUFFMAN_EMIT_SYMBOL, 136),\n    (23, HUFFMAN_EMIT_SYMBOL, 136),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 136),\n    (2, HUFFMAN_EMIT_SYMBOL, 146),\n    (9, HUFFMAN_EMIT_SYMBOL, 146),\n    (23, HUFFMAN_EMIT_SYMBOL, 146),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 146),\n\n    # Node 124\n    (3, HUFFMAN_EMIT_SYMBOL, 133),\n    (6, HUFFMAN_EMIT_SYMBOL, 133),\n    (10, HUFFMAN_EMIT_SYMBOL, 133),\n    (15, HUFFMAN_EMIT_SYMBOL, 133),\n    (24, HUFFMAN_EMIT_SYMBOL, 133),\n    (31, HUFFMAN_EMIT_SYMBOL, 133),\n    (41, HUFFMAN_EMIT_SYMBOL, 133),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 133),\n    (3, HUFFMAN_EMIT_SYMBOL, 134),\n    (6, HUFFMAN_EMIT_SYMBOL, 134),\n    (10, HUFFMAN_EMIT_SYMBOL, 134),\n    (15, HUFFMAN_EMIT_SYMBOL, 134),\n    (24, HUFFMAN_EMIT_SYMBOL, 134),\n    (31, HUFFMAN_EMIT_SYMBOL, 134),\n    (41, HUFFMAN_EMIT_SYMBOL, 134),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 134),\n\n    # Node 125\n    (3, HUFFMAN_EMIT_SYMBOL, 136),\n    (6, HUFFMAN_EMIT_SYMBOL, 136),\n    (10, HUFFMAN_EMIT_SYMBOL, 136),\n    (15, HUFFMAN_EMIT_SYMBOL, 136),\n    (24, HUFFMAN_EMIT_SYMBOL, 136),\n    (31, HUFFMAN_EMIT_SYMBOL, 136),\n    (41, HUFFMAN_EMIT_SYMBOL, 136),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 136),\n    (3, HUFFMAN_EMIT_SYMBOL, 146),\n    (6, HUFFMAN_EMIT_SYMBOL, 146),\n    (10, HUFFMAN_EMIT_SYMBOL, 146),\n    (15, HUFFMAN_EMIT_SYMBOL, 146),\n    (24, HUFFMAN_EMIT_SYMBOL, 146),\n    (31, HUFFMAN_EMIT_SYMBOL, 146),\n    (41, HUFFMAN_EMIT_SYMBOL, 146),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 146),\n\n    # Node 126\n    (1, HUFFMAN_EMIT_SYMBOL, 154),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 154),\n    (1, HUFFMAN_EMIT_SYMBOL, 156),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 156),\n    (1, HUFFMAN_EMIT_SYMBOL, 160),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 160),\n    (1, HUFFMAN_EMIT_SYMBOL, 163),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 163),\n    (1, HUFFMAN_EMIT_SYMBOL, 164),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 164),\n    (1, HUFFMAN_EMIT_SYMBOL, 169),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 169),\n    (1, HUFFMAN_EMIT_SYMBOL, 170),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 170),\n    (1, HUFFMAN_EMIT_SYMBOL, 173),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 173),\n\n    # Node 127\n    (2, HUFFMAN_EMIT_SYMBOL, 154),\n    (9, HUFFMAN_EMIT_SYMBOL, 154),\n    (23, HUFFMAN_EMIT_SYMBOL, 154),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 154),\n    (2, HUFFMAN_EMIT_SYMBOL, 156),\n    (9, HUFFMAN_EMIT_SYMBOL, 156),\n    (23, HUFFMAN_EMIT_SYMBOL, 156),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 156),\n    (2, HUFFMAN_EMIT_SYMBOL, 160),\n    (9, HUFFMAN_EMIT_SYMBOL, 160),\n    (23, HUFFMAN_EMIT_SYMBOL, 160),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 160),\n    (2, HUFFMAN_EMIT_SYMBOL, 163),\n    (9, HUFFMAN_EMIT_SYMBOL, 163),\n    (23, HUFFMAN_EMIT_SYMBOL, 163),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 163),\n\n    # Node 128\n    (3, HUFFMAN_EMIT_SYMBOL, 154),\n    (6, HUFFMAN_EMIT_SYMBOL, 154),\n    (10, HUFFMAN_EMIT_SYMBOL, 154),\n    (15, HUFFMAN_EMIT_SYMBOL, 154),\n    (24, HUFFMAN_EMIT_SYMBOL, 154),\n    (31, HUFFMAN_EMIT_SYMBOL, 154),\n    (41, HUFFMAN_EMIT_SYMBOL, 154),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 154),\n    (3, HUFFMAN_EMIT_SYMBOL, 156),\n    (6, HUFFMAN_EMIT_SYMBOL, 156),\n    (10, HUFFMAN_EMIT_SYMBOL, 156),\n    (15, HUFFMAN_EMIT_SYMBOL, 156),\n    (24, HUFFMAN_EMIT_SYMBOL, 156),\n    (31, HUFFMAN_EMIT_SYMBOL, 156),\n    (41, HUFFMAN_EMIT_SYMBOL, 156),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 156),\n\n    # Node 129\n    (3, HUFFMAN_EMIT_SYMBOL, 160),\n    (6, HUFFMAN_EMIT_SYMBOL, 160),\n    (10, HUFFMAN_EMIT_SYMBOL, 160),\n    (15, HUFFMAN_EMIT_SYMBOL, 160),\n    (24, HUFFMAN_EMIT_SYMBOL, 160),\n    (31, HUFFMAN_EMIT_SYMBOL, 160),\n    (41, HUFFMAN_EMIT_SYMBOL, 160),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 160),\n    (3, HUFFMAN_EMIT_SYMBOL, 163),\n    (6, HUFFMAN_EMIT_SYMBOL, 163),\n    (10, HUFFMAN_EMIT_SYMBOL, 163),\n    (15, HUFFMAN_EMIT_SYMBOL, 163),\n    (24, HUFFMAN_EMIT_SYMBOL, 163),\n    (31, HUFFMAN_EMIT_SYMBOL, 163),\n    (41, HUFFMAN_EMIT_SYMBOL, 163),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 163),\n\n    # Node 130\n    (2, HUFFMAN_EMIT_SYMBOL, 164),\n    (9, HUFFMAN_EMIT_SYMBOL, 164),\n    (23, HUFFMAN_EMIT_SYMBOL, 164),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 164),\n    (2, HUFFMAN_EMIT_SYMBOL, 169),\n    (9, HUFFMAN_EMIT_SYMBOL, 169),\n    (23, HUFFMAN_EMIT_SYMBOL, 169),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 169),\n    (2, HUFFMAN_EMIT_SYMBOL, 170),\n    (9, HUFFMAN_EMIT_SYMBOL, 170),\n    (23, HUFFMAN_EMIT_SYMBOL, 170),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 170),\n    (2, HUFFMAN_EMIT_SYMBOL, 173),\n    (9, HUFFMAN_EMIT_SYMBOL, 173),\n    (23, HUFFMAN_EMIT_SYMBOL, 173),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 173),\n\n    # Node 131\n    (3, HUFFMAN_EMIT_SYMBOL, 164),\n    (6, HUFFMAN_EMIT_SYMBOL, 164),\n    (10, HUFFMAN_EMIT_SYMBOL, 164),\n    (15, HUFFMAN_EMIT_SYMBOL, 164),\n    (24, HUFFMAN_EMIT_SYMBOL, 164),\n    (31, HUFFMAN_EMIT_SYMBOL, 164),\n    (41, HUFFMAN_EMIT_SYMBOL, 164),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 164),\n    (3, HUFFMAN_EMIT_SYMBOL, 169),\n    (6, HUFFMAN_EMIT_SYMBOL, 169),\n    (10, HUFFMAN_EMIT_SYMBOL, 169),\n    (15, HUFFMAN_EMIT_SYMBOL, 169),\n    (24, HUFFMAN_EMIT_SYMBOL, 169),\n    (31, HUFFMAN_EMIT_SYMBOL, 169),\n    (41, HUFFMAN_EMIT_SYMBOL, 169),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 169),\n\n    # Node 132\n    (3, HUFFMAN_EMIT_SYMBOL, 170),\n    (6, HUFFMAN_EMIT_SYMBOL, 170),\n    (10, HUFFMAN_EMIT_SYMBOL, 170),\n    (15, HUFFMAN_EMIT_SYMBOL, 170),\n    (24, HUFFMAN_EMIT_SYMBOL, 170),\n    (31, HUFFMAN_EMIT_SYMBOL, 170),\n    (41, HUFFMAN_EMIT_SYMBOL, 170),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 170),\n    (3, HUFFMAN_EMIT_SYMBOL, 173),\n    (6, HUFFMAN_EMIT_SYMBOL, 173),\n    (10, HUFFMAN_EMIT_SYMBOL, 173),\n    (15, HUFFMAN_EMIT_SYMBOL, 173),\n    (24, HUFFMAN_EMIT_SYMBOL, 173),\n    (31, HUFFMAN_EMIT_SYMBOL, 173),\n    (41, HUFFMAN_EMIT_SYMBOL, 173),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 173),\n\n    # Node 133\n    (137, 0, 0),\n    (138, 0, 0),\n    (140, 0, 0),\n    (141, 0, 0),\n    (144, 0, 0),\n    (145, 0, 0),\n    (147, 0, 0),\n    (150, 0, 0),\n    (156, 0, 0),\n    (159, 0, 0),\n    (163, 0, 0),\n    (166, 0, 0),\n    (171, 0, 0),\n    (174, 0, 0),\n    (181, 0, 0),\n    (190, 0, 0),\n\n    # Node 134\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 178),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 181),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 185),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 186),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 187),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 189),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 190),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 196),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 198),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 228),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 232),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 233),\n    (148, 0, 0),\n    (149, 0, 0),\n    (151, 0, 0),\n    (152, 0, 0),\n\n    # Node 135\n    (1, HUFFMAN_EMIT_SYMBOL, 178),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 178),\n    (1, HUFFMAN_EMIT_SYMBOL, 181),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 181),\n    (1, HUFFMAN_EMIT_SYMBOL, 185),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 185),\n    (1, HUFFMAN_EMIT_SYMBOL, 186),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 186),\n    (1, HUFFMAN_EMIT_SYMBOL, 187),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 187),\n    (1, HUFFMAN_EMIT_SYMBOL, 189),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 189),\n    (1, HUFFMAN_EMIT_SYMBOL, 190),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 190),\n    (1, HUFFMAN_EMIT_SYMBOL, 196),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 196),\n\n    # Node 136\n    (2, HUFFMAN_EMIT_SYMBOL, 178),\n    (9, HUFFMAN_EMIT_SYMBOL, 178),\n    (23, HUFFMAN_EMIT_SYMBOL, 178),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 178),\n    (2, HUFFMAN_EMIT_SYMBOL, 181),\n    (9, HUFFMAN_EMIT_SYMBOL, 181),\n    (23, HUFFMAN_EMIT_SYMBOL, 181),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 181),\n    (2, HUFFMAN_EMIT_SYMBOL, 185),\n    (9, HUFFMAN_EMIT_SYMBOL, 185),\n    (23, HUFFMAN_EMIT_SYMBOL, 185),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 185),\n    (2, HUFFMAN_EMIT_SYMBOL, 186),\n    (9, HUFFMAN_EMIT_SYMBOL, 186),\n    (23, HUFFMAN_EMIT_SYMBOL, 186),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 186),\n\n    # Node 137\n    (3, HUFFMAN_EMIT_SYMBOL, 178),\n    (6, HUFFMAN_EMIT_SYMBOL, 178),\n    (10, HUFFMAN_EMIT_SYMBOL, 178),\n    (15, HUFFMAN_EMIT_SYMBOL, 178),\n    (24, HUFFMAN_EMIT_SYMBOL, 178),\n    (31, HUFFMAN_EMIT_SYMBOL, 178),\n    (41, HUFFMAN_EMIT_SYMBOL, 178),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 178),\n    (3, HUFFMAN_EMIT_SYMBOL, 181),\n    (6, HUFFMAN_EMIT_SYMBOL, 181),\n    (10, HUFFMAN_EMIT_SYMBOL, 181),\n    (15, HUFFMAN_EMIT_SYMBOL, 181),\n    (24, HUFFMAN_EMIT_SYMBOL, 181),\n    (31, HUFFMAN_EMIT_SYMBOL, 181),\n    (41, HUFFMAN_EMIT_SYMBOL, 181),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 181),\n\n    # Node 138\n    (3, HUFFMAN_EMIT_SYMBOL, 185),\n    (6, HUFFMAN_EMIT_SYMBOL, 185),\n    (10, HUFFMAN_EMIT_SYMBOL, 185),\n    (15, HUFFMAN_EMIT_SYMBOL, 185),\n    (24, HUFFMAN_EMIT_SYMBOL, 185),\n    (31, HUFFMAN_EMIT_SYMBOL, 185),\n    (41, HUFFMAN_EMIT_SYMBOL, 185),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 185),\n    (3, HUFFMAN_EMIT_SYMBOL, 186),\n    (6, HUFFMAN_EMIT_SYMBOL, 186),\n    (10, HUFFMAN_EMIT_SYMBOL, 186),\n    (15, HUFFMAN_EMIT_SYMBOL, 186),\n    (24, HUFFMAN_EMIT_SYMBOL, 186),\n    (31, HUFFMAN_EMIT_SYMBOL, 186),\n    (41, HUFFMAN_EMIT_SYMBOL, 186),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 186),\n\n    # Node 139\n    (2, HUFFMAN_EMIT_SYMBOL, 187),\n    (9, HUFFMAN_EMIT_SYMBOL, 187),\n    (23, HUFFMAN_EMIT_SYMBOL, 187),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 187),\n    (2, HUFFMAN_EMIT_SYMBOL, 189),\n    (9, HUFFMAN_EMIT_SYMBOL, 189),\n    (23, HUFFMAN_EMIT_SYMBOL, 189),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 189),\n    (2, HUFFMAN_EMIT_SYMBOL, 190),\n    (9, HUFFMAN_EMIT_SYMBOL, 190),\n    (23, HUFFMAN_EMIT_SYMBOL, 190),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 190),\n    (2, HUFFMAN_EMIT_SYMBOL, 196),\n    (9, HUFFMAN_EMIT_SYMBOL, 196),\n    (23, HUFFMAN_EMIT_SYMBOL, 196),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 196),\n\n    # Node 140\n    (3, HUFFMAN_EMIT_SYMBOL, 187),\n    (6, HUFFMAN_EMIT_SYMBOL, 187),\n    (10, HUFFMAN_EMIT_SYMBOL, 187),\n    (15, HUFFMAN_EMIT_SYMBOL, 187),\n    (24, HUFFMAN_EMIT_SYMBOL, 187),\n    (31, HUFFMAN_EMIT_SYMBOL, 187),\n    (41, HUFFMAN_EMIT_SYMBOL, 187),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 187),\n    (3, HUFFMAN_EMIT_SYMBOL, 189),\n    (6, HUFFMAN_EMIT_SYMBOL, 189),\n    (10, HUFFMAN_EMIT_SYMBOL, 189),\n    (15, HUFFMAN_EMIT_SYMBOL, 189),\n    (24, HUFFMAN_EMIT_SYMBOL, 189),\n    (31, HUFFMAN_EMIT_SYMBOL, 189),\n    (41, HUFFMAN_EMIT_SYMBOL, 189),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 189),\n\n    # Node 141\n    (3, HUFFMAN_EMIT_SYMBOL, 190),\n    (6, HUFFMAN_EMIT_SYMBOL, 190),\n    (10, HUFFMAN_EMIT_SYMBOL, 190),\n    (15, HUFFMAN_EMIT_SYMBOL, 190),\n    (24, HUFFMAN_EMIT_SYMBOL, 190),\n    (31, HUFFMAN_EMIT_SYMBOL, 190),\n    (41, HUFFMAN_EMIT_SYMBOL, 190),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 190),\n    (3, HUFFMAN_EMIT_SYMBOL, 196),\n    (6, HUFFMAN_EMIT_SYMBOL, 196),\n    (10, HUFFMAN_EMIT_SYMBOL, 196),\n    (15, HUFFMAN_EMIT_SYMBOL, 196),\n    (24, HUFFMAN_EMIT_SYMBOL, 196),\n    (31, HUFFMAN_EMIT_SYMBOL, 196),\n    (41, HUFFMAN_EMIT_SYMBOL, 196),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 196),\n\n    # Node 142\n    (1, HUFFMAN_EMIT_SYMBOL, 198),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 198),\n    (1, HUFFMAN_EMIT_SYMBOL, 228),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 228),\n    (1, HUFFMAN_EMIT_SYMBOL, 232),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 232),\n    (1, HUFFMAN_EMIT_SYMBOL, 233),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 233),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 1),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 135),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 137),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 138),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 139),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 140),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 141),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 143),\n\n    # Node 143\n    (2, HUFFMAN_EMIT_SYMBOL, 198),\n    (9, HUFFMAN_EMIT_SYMBOL, 198),\n    (23, HUFFMAN_EMIT_SYMBOL, 198),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 198),\n    (2, HUFFMAN_EMIT_SYMBOL, 228),\n    (9, HUFFMAN_EMIT_SYMBOL, 228),\n    (23, HUFFMAN_EMIT_SYMBOL, 228),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 228),\n    (2, HUFFMAN_EMIT_SYMBOL, 232),\n    (9, HUFFMAN_EMIT_SYMBOL, 232),\n    (23, HUFFMAN_EMIT_SYMBOL, 232),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 232),\n    (2, HUFFMAN_EMIT_SYMBOL, 233),\n    (9, HUFFMAN_EMIT_SYMBOL, 233),\n    (23, HUFFMAN_EMIT_SYMBOL, 233),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 233),\n\n    # Node 144\n    (3, HUFFMAN_EMIT_SYMBOL, 198),\n    (6, HUFFMAN_EMIT_SYMBOL, 198),\n    (10, HUFFMAN_EMIT_SYMBOL, 198),\n    (15, HUFFMAN_EMIT_SYMBOL, 198),\n    (24, HUFFMAN_EMIT_SYMBOL, 198),\n    (31, HUFFMAN_EMIT_SYMBOL, 198),\n    (41, HUFFMAN_EMIT_SYMBOL, 198),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 198),\n    (3, HUFFMAN_EMIT_SYMBOL, 228),\n    (6, HUFFMAN_EMIT_SYMBOL, 228),\n    (10, HUFFMAN_EMIT_SYMBOL, 228),\n    (15, HUFFMAN_EMIT_SYMBOL, 228),\n    (24, HUFFMAN_EMIT_SYMBOL, 228),\n    (31, HUFFMAN_EMIT_SYMBOL, 228),\n    (41, HUFFMAN_EMIT_SYMBOL, 228),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 228),\n\n    # Node 145\n    (3, HUFFMAN_EMIT_SYMBOL, 232),\n    (6, HUFFMAN_EMIT_SYMBOL, 232),\n    (10, HUFFMAN_EMIT_SYMBOL, 232),\n    (15, HUFFMAN_EMIT_SYMBOL, 232),\n    (24, HUFFMAN_EMIT_SYMBOL, 232),\n    (31, HUFFMAN_EMIT_SYMBOL, 232),\n    (41, HUFFMAN_EMIT_SYMBOL, 232),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 232),\n    (3, HUFFMAN_EMIT_SYMBOL, 233),\n    (6, HUFFMAN_EMIT_SYMBOL, 233),\n    (10, HUFFMAN_EMIT_SYMBOL, 233),\n    (15, HUFFMAN_EMIT_SYMBOL, 233),\n    (24, HUFFMAN_EMIT_SYMBOL, 233),\n    (31, HUFFMAN_EMIT_SYMBOL, 233),\n    (41, HUFFMAN_EMIT_SYMBOL, 233),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 233),\n\n    # Node 146\n    (1, HUFFMAN_EMIT_SYMBOL, 1),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 1),\n    (1, HUFFMAN_EMIT_SYMBOL, 135),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 135),\n    (1, HUFFMAN_EMIT_SYMBOL, 137),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 137),\n    (1, HUFFMAN_EMIT_SYMBOL, 138),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 138),\n    (1, HUFFMAN_EMIT_SYMBOL, 139),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 139),\n    (1, HUFFMAN_EMIT_SYMBOL, 140),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 140),\n    (1, HUFFMAN_EMIT_SYMBOL, 141),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 141),\n    (1, HUFFMAN_EMIT_SYMBOL, 143),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 143),\n\n    # Node 147\n    (2, HUFFMAN_EMIT_SYMBOL, 1),\n    (9, HUFFMAN_EMIT_SYMBOL, 1),\n    (23, HUFFMAN_EMIT_SYMBOL, 1),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 1),\n    (2, HUFFMAN_EMIT_SYMBOL, 135),\n    (9, HUFFMAN_EMIT_SYMBOL, 135),\n    (23, HUFFMAN_EMIT_SYMBOL, 135),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 135),\n    (2, HUFFMAN_EMIT_SYMBOL, 137),\n    (9, HUFFMAN_EMIT_SYMBOL, 137),\n    (23, HUFFMAN_EMIT_SYMBOL, 137),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 137),\n    (2, HUFFMAN_EMIT_SYMBOL, 138),\n    (9, HUFFMAN_EMIT_SYMBOL, 138),\n    (23, HUFFMAN_EMIT_SYMBOL, 138),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 138),\n\n    # Node 148\n    (3, HUFFMAN_EMIT_SYMBOL, 1),\n    (6, HUFFMAN_EMIT_SYMBOL, 1),\n    (10, HUFFMAN_EMIT_SYMBOL, 1),\n    (15, HUFFMAN_EMIT_SYMBOL, 1),\n    (24, HUFFMAN_EMIT_SYMBOL, 1),\n    (31, HUFFMAN_EMIT_SYMBOL, 1),\n    (41, HUFFMAN_EMIT_SYMBOL, 1),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 1),\n    (3, HUFFMAN_EMIT_SYMBOL, 135),\n    (6, HUFFMAN_EMIT_SYMBOL, 135),\n    (10, HUFFMAN_EMIT_SYMBOL, 135),\n    (15, HUFFMAN_EMIT_SYMBOL, 135),\n    (24, HUFFMAN_EMIT_SYMBOL, 135),\n    (31, HUFFMAN_EMIT_SYMBOL, 135),\n    (41, HUFFMAN_EMIT_SYMBOL, 135),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 135),\n\n    # Node 149\n    (3, HUFFMAN_EMIT_SYMBOL, 137),\n    (6, HUFFMAN_EMIT_SYMBOL, 137),\n    (10, HUFFMAN_EMIT_SYMBOL, 137),\n    (15, HUFFMAN_EMIT_SYMBOL, 137),\n    (24, HUFFMAN_EMIT_SYMBOL, 137),\n    (31, HUFFMAN_EMIT_SYMBOL, 137),\n    (41, HUFFMAN_EMIT_SYMBOL, 137),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 137),\n    (3, HUFFMAN_EMIT_SYMBOL, 138),\n    (6, HUFFMAN_EMIT_SYMBOL, 138),\n    (10, HUFFMAN_EMIT_SYMBOL, 138),\n    (15, HUFFMAN_EMIT_SYMBOL, 138),\n    (24, HUFFMAN_EMIT_SYMBOL, 138),\n    (31, HUFFMAN_EMIT_SYMBOL, 138),\n    (41, HUFFMAN_EMIT_SYMBOL, 138),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 138),\n\n    # Node 150\n    (2, HUFFMAN_EMIT_SYMBOL, 139),\n    (9, HUFFMAN_EMIT_SYMBOL, 139),\n    (23, HUFFMAN_EMIT_SYMBOL, 139),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 139),\n    (2, HUFFMAN_EMIT_SYMBOL, 140),\n    (9, HUFFMAN_EMIT_SYMBOL, 140),\n    (23, HUFFMAN_EMIT_SYMBOL, 140),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 140),\n    (2, HUFFMAN_EMIT_SYMBOL, 141),\n    (9, HUFFMAN_EMIT_SYMBOL, 141),\n    (23, HUFFMAN_EMIT_SYMBOL, 141),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 141),\n    (2, HUFFMAN_EMIT_SYMBOL, 143),\n    (9, HUFFMAN_EMIT_SYMBOL, 143),\n    (23, HUFFMAN_EMIT_SYMBOL, 143),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 143),\n\n    # Node 151\n    (3, HUFFMAN_EMIT_SYMBOL, 139),\n    (6, HUFFMAN_EMIT_SYMBOL, 139),\n    (10, HUFFMAN_EMIT_SYMBOL, 139),\n    (15, HUFFMAN_EMIT_SYMBOL, 139),\n    (24, HUFFMAN_EMIT_SYMBOL, 139),\n    (31, HUFFMAN_EMIT_SYMBOL, 139),\n    (41, HUFFMAN_EMIT_SYMBOL, 139),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 139),\n    (3, HUFFMAN_EMIT_SYMBOL, 140),\n    (6, HUFFMAN_EMIT_SYMBOL, 140),\n    (10, HUFFMAN_EMIT_SYMBOL, 140),\n    (15, HUFFMAN_EMIT_SYMBOL, 140),\n    (24, HUFFMAN_EMIT_SYMBOL, 140),\n    (31, HUFFMAN_EMIT_SYMBOL, 140),\n    (41, HUFFMAN_EMIT_SYMBOL, 140),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 140),\n\n    # Node 152\n    (3, HUFFMAN_EMIT_SYMBOL, 141),\n    (6, HUFFMAN_EMIT_SYMBOL, 141),\n    (10, HUFFMAN_EMIT_SYMBOL, 141),\n    (15, HUFFMAN_EMIT_SYMBOL, 141),\n    (24, HUFFMAN_EMIT_SYMBOL, 141),\n    (31, HUFFMAN_EMIT_SYMBOL, 141),\n    (41, HUFFMAN_EMIT_SYMBOL, 141),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 141),\n    (3, HUFFMAN_EMIT_SYMBOL, 143),\n    (6, HUFFMAN_EMIT_SYMBOL, 143),\n    (10, HUFFMAN_EMIT_SYMBOL, 143),\n    (15, HUFFMAN_EMIT_SYMBOL, 143),\n    (24, HUFFMAN_EMIT_SYMBOL, 143),\n    (31, HUFFMAN_EMIT_SYMBOL, 143),\n    (41, HUFFMAN_EMIT_SYMBOL, 143),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 143),\n\n    # Node 153\n    (157, 0, 0),\n    (158, 0, 0),\n    (160, 0, 0),\n    (161, 0, 0),\n    (164, 0, 0),\n    (165, 0, 0),\n    (167, 0, 0),\n    (168, 0, 0),\n    (172, 0, 0),\n    (173, 0, 0),\n    (175, 0, 0),\n    (177, 0, 0),\n    (182, 0, 0),\n    (185, 0, 0),\n    (191, 0, 0),\n    (207, 0, 0),\n\n    # Node 154\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 147),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 149),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 150),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 151),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 152),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 155),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 157),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 158),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 165),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 166),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 168),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 174),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 175),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 180),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 182),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 183),\n\n    # Node 155\n    (1, HUFFMAN_EMIT_SYMBOL, 147),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 147),\n    (1, HUFFMAN_EMIT_SYMBOL, 149),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 149),\n    (1, HUFFMAN_EMIT_SYMBOL, 150),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 150),\n    (1, HUFFMAN_EMIT_SYMBOL, 151),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 151),\n    (1, HUFFMAN_EMIT_SYMBOL, 152),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 152),\n    (1, HUFFMAN_EMIT_SYMBOL, 155),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 155),\n    (1, HUFFMAN_EMIT_SYMBOL, 157),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 157),\n    (1, HUFFMAN_EMIT_SYMBOL, 158),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 158),\n\n    # Node 156\n    (2, HUFFMAN_EMIT_SYMBOL, 147),\n    (9, HUFFMAN_EMIT_SYMBOL, 147),\n    (23, HUFFMAN_EMIT_SYMBOL, 147),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 147),\n    (2, HUFFMAN_EMIT_SYMBOL, 149),\n    (9, HUFFMAN_EMIT_SYMBOL, 149),\n    (23, HUFFMAN_EMIT_SYMBOL, 149),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 149),\n    (2, HUFFMAN_EMIT_SYMBOL, 150),\n    (9, HUFFMAN_EMIT_SYMBOL, 150),\n    (23, HUFFMAN_EMIT_SYMBOL, 150),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 150),\n    (2, HUFFMAN_EMIT_SYMBOL, 151),\n    (9, HUFFMAN_EMIT_SYMBOL, 151),\n    (23, HUFFMAN_EMIT_SYMBOL, 151),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 151),\n\n    # Node 157\n    (3, HUFFMAN_EMIT_SYMBOL, 147),\n    (6, HUFFMAN_EMIT_SYMBOL, 147),\n    (10, HUFFMAN_EMIT_SYMBOL, 147),\n    (15, HUFFMAN_EMIT_SYMBOL, 147),\n    (24, HUFFMAN_EMIT_SYMBOL, 147),\n    (31, HUFFMAN_EMIT_SYMBOL, 147),\n    (41, HUFFMAN_EMIT_SYMBOL, 147),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 147),\n    (3, HUFFMAN_EMIT_SYMBOL, 149),\n    (6, HUFFMAN_EMIT_SYMBOL, 149),\n    (10, HUFFMAN_EMIT_SYMBOL, 149),\n    (15, HUFFMAN_EMIT_SYMBOL, 149),\n    (24, HUFFMAN_EMIT_SYMBOL, 149),\n    (31, HUFFMAN_EMIT_SYMBOL, 149),\n    (41, HUFFMAN_EMIT_SYMBOL, 149),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 149),\n\n    # Node 158\n    (3, HUFFMAN_EMIT_SYMBOL, 150),\n    (6, HUFFMAN_EMIT_SYMBOL, 150),\n    (10, HUFFMAN_EMIT_SYMBOL, 150),\n    (15, HUFFMAN_EMIT_SYMBOL, 150),\n    (24, HUFFMAN_EMIT_SYMBOL, 150),\n    (31, HUFFMAN_EMIT_SYMBOL, 150),\n    (41, HUFFMAN_EMIT_SYMBOL, 150),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 150),\n    (3, HUFFMAN_EMIT_SYMBOL, 151),\n    (6, HUFFMAN_EMIT_SYMBOL, 151),\n    (10, HUFFMAN_EMIT_SYMBOL, 151),\n    (15, HUFFMAN_EMIT_SYMBOL, 151),\n    (24, HUFFMAN_EMIT_SYMBOL, 151),\n    (31, HUFFMAN_EMIT_SYMBOL, 151),\n    (41, HUFFMAN_EMIT_SYMBOL, 151),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 151),\n\n    # Node 159\n    (2, HUFFMAN_EMIT_SYMBOL, 152),\n    (9, HUFFMAN_EMIT_SYMBOL, 152),\n    (23, HUFFMAN_EMIT_SYMBOL, 152),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 152),\n    (2, HUFFMAN_EMIT_SYMBOL, 155),\n    (9, HUFFMAN_EMIT_SYMBOL, 155),\n    (23, HUFFMAN_EMIT_SYMBOL, 155),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 155),\n    (2, HUFFMAN_EMIT_SYMBOL, 157),\n    (9, HUFFMAN_EMIT_SYMBOL, 157),\n    (23, HUFFMAN_EMIT_SYMBOL, 157),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 157),\n    (2, HUFFMAN_EMIT_SYMBOL, 158),\n    (9, HUFFMAN_EMIT_SYMBOL, 158),\n    (23, HUFFMAN_EMIT_SYMBOL, 158),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 158),\n\n    # Node 160\n    (3, HUFFMAN_EMIT_SYMBOL, 152),\n    (6, HUFFMAN_EMIT_SYMBOL, 152),\n    (10, HUFFMAN_EMIT_SYMBOL, 152),\n    (15, HUFFMAN_EMIT_SYMBOL, 152),\n    (24, HUFFMAN_EMIT_SYMBOL, 152),\n    (31, HUFFMAN_EMIT_SYMBOL, 152),\n    (41, HUFFMAN_EMIT_SYMBOL, 152),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 152),\n    (3, HUFFMAN_EMIT_SYMBOL, 155),\n    (6, HUFFMAN_EMIT_SYMBOL, 155),\n    (10, HUFFMAN_EMIT_SYMBOL, 155),\n    (15, HUFFMAN_EMIT_SYMBOL, 155),\n    (24, HUFFMAN_EMIT_SYMBOL, 155),\n    (31, HUFFMAN_EMIT_SYMBOL, 155),\n    (41, HUFFMAN_EMIT_SYMBOL, 155),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 155),\n\n    # Node 161\n    (3, HUFFMAN_EMIT_SYMBOL, 157),\n    (6, HUFFMAN_EMIT_SYMBOL, 157),\n    (10, HUFFMAN_EMIT_SYMBOL, 157),\n    (15, HUFFMAN_EMIT_SYMBOL, 157),\n    (24, HUFFMAN_EMIT_SYMBOL, 157),\n    (31, HUFFMAN_EMIT_SYMBOL, 157),\n    (41, HUFFMAN_EMIT_SYMBOL, 157),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 157),\n    (3, HUFFMAN_EMIT_SYMBOL, 158),\n    (6, HUFFMAN_EMIT_SYMBOL, 158),\n    (10, HUFFMAN_EMIT_SYMBOL, 158),\n    (15, HUFFMAN_EMIT_SYMBOL, 158),\n    (24, HUFFMAN_EMIT_SYMBOL, 158),\n    (31, HUFFMAN_EMIT_SYMBOL, 158),\n    (41, HUFFMAN_EMIT_SYMBOL, 158),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 158),\n\n    # Node 162\n    (1, HUFFMAN_EMIT_SYMBOL, 165),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 165),\n    (1, HUFFMAN_EMIT_SYMBOL, 166),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 166),\n    (1, HUFFMAN_EMIT_SYMBOL, 168),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 168),\n    (1, HUFFMAN_EMIT_SYMBOL, 174),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 174),\n    (1, HUFFMAN_EMIT_SYMBOL, 175),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 175),\n    (1, HUFFMAN_EMIT_SYMBOL, 180),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 180),\n    (1, HUFFMAN_EMIT_SYMBOL, 182),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 182),\n    (1, HUFFMAN_EMIT_SYMBOL, 183),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 183),\n\n    # Node 163\n    (2, HUFFMAN_EMIT_SYMBOL, 165),\n    (9, HUFFMAN_EMIT_SYMBOL, 165),\n    (23, HUFFMAN_EMIT_SYMBOL, 165),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 165),\n    (2, HUFFMAN_EMIT_SYMBOL, 166),\n    (9, HUFFMAN_EMIT_SYMBOL, 166),\n    (23, HUFFMAN_EMIT_SYMBOL, 166),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 166),\n    (2, HUFFMAN_EMIT_SYMBOL, 168),\n    (9, HUFFMAN_EMIT_SYMBOL, 168),\n    (23, HUFFMAN_EMIT_SYMBOL, 168),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 168),\n    (2, HUFFMAN_EMIT_SYMBOL, 174),\n    (9, HUFFMAN_EMIT_SYMBOL, 174),\n    (23, HUFFMAN_EMIT_SYMBOL, 174),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 174),\n\n    # Node 164\n    (3, HUFFMAN_EMIT_SYMBOL, 165),\n    (6, HUFFMAN_EMIT_SYMBOL, 165),\n    (10, HUFFMAN_EMIT_SYMBOL, 165),\n    (15, HUFFMAN_EMIT_SYMBOL, 165),\n    (24, HUFFMAN_EMIT_SYMBOL, 165),\n    (31, HUFFMAN_EMIT_SYMBOL, 165),\n    (41, HUFFMAN_EMIT_SYMBOL, 165),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 165),\n    (3, HUFFMAN_EMIT_SYMBOL, 166),\n    (6, HUFFMAN_EMIT_SYMBOL, 166),\n    (10, HUFFMAN_EMIT_SYMBOL, 166),\n    (15, HUFFMAN_EMIT_SYMBOL, 166),\n    (24, HUFFMAN_EMIT_SYMBOL, 166),\n    (31, HUFFMAN_EMIT_SYMBOL, 166),\n    (41, HUFFMAN_EMIT_SYMBOL, 166),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 166),\n\n    # Node 165\n    (3, HUFFMAN_EMIT_SYMBOL, 168),\n    (6, HUFFMAN_EMIT_SYMBOL, 168),\n    (10, HUFFMAN_EMIT_SYMBOL, 168),\n    (15, HUFFMAN_EMIT_SYMBOL, 168),\n    (24, HUFFMAN_EMIT_SYMBOL, 168),\n    (31, HUFFMAN_EMIT_SYMBOL, 168),\n    (41, HUFFMAN_EMIT_SYMBOL, 168),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 168),\n    (3, HUFFMAN_EMIT_SYMBOL, 174),\n    (6, HUFFMAN_EMIT_SYMBOL, 174),\n    (10, HUFFMAN_EMIT_SYMBOL, 174),\n    (15, HUFFMAN_EMIT_SYMBOL, 174),\n    (24, HUFFMAN_EMIT_SYMBOL, 174),\n    (31, HUFFMAN_EMIT_SYMBOL, 174),\n    (41, HUFFMAN_EMIT_SYMBOL, 174),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 174),\n\n    # Node 166\n    (2, HUFFMAN_EMIT_SYMBOL, 175),\n    (9, HUFFMAN_EMIT_SYMBOL, 175),\n    (23, HUFFMAN_EMIT_SYMBOL, 175),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 175),\n    (2, HUFFMAN_EMIT_SYMBOL, 180),\n    (9, HUFFMAN_EMIT_SYMBOL, 180),\n    (23, HUFFMAN_EMIT_SYMBOL, 180),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 180),\n    (2, HUFFMAN_EMIT_SYMBOL, 182),\n    (9, HUFFMAN_EMIT_SYMBOL, 182),\n    (23, HUFFMAN_EMIT_SYMBOL, 182),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 182),\n    (2, HUFFMAN_EMIT_SYMBOL, 183),\n    (9, HUFFMAN_EMIT_SYMBOL, 183),\n    (23, HUFFMAN_EMIT_SYMBOL, 183),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 183),\n\n    # Node 167\n    (3, HUFFMAN_EMIT_SYMBOL, 175),\n    (6, HUFFMAN_EMIT_SYMBOL, 175),\n    (10, HUFFMAN_EMIT_SYMBOL, 175),\n    (15, HUFFMAN_EMIT_SYMBOL, 175),\n    (24, HUFFMAN_EMIT_SYMBOL, 175),\n    (31, HUFFMAN_EMIT_SYMBOL, 175),\n    (41, HUFFMAN_EMIT_SYMBOL, 175),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 175),\n    (3, HUFFMAN_EMIT_SYMBOL, 180),\n    (6, HUFFMAN_EMIT_SYMBOL, 180),\n    (10, HUFFMAN_EMIT_SYMBOL, 180),\n    (15, HUFFMAN_EMIT_SYMBOL, 180),\n    (24, HUFFMAN_EMIT_SYMBOL, 180),\n    (31, HUFFMAN_EMIT_SYMBOL, 180),\n    (41, HUFFMAN_EMIT_SYMBOL, 180),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 180),\n\n    # Node 168\n    (3, HUFFMAN_EMIT_SYMBOL, 182),\n    (6, HUFFMAN_EMIT_SYMBOL, 182),\n    (10, HUFFMAN_EMIT_SYMBOL, 182),\n    (15, HUFFMAN_EMIT_SYMBOL, 182),\n    (24, HUFFMAN_EMIT_SYMBOL, 182),\n    (31, HUFFMAN_EMIT_SYMBOL, 182),\n    (41, HUFFMAN_EMIT_SYMBOL, 182),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 182),\n    (3, HUFFMAN_EMIT_SYMBOL, 183),\n    (6, HUFFMAN_EMIT_SYMBOL, 183),\n    (10, HUFFMAN_EMIT_SYMBOL, 183),\n    (15, HUFFMAN_EMIT_SYMBOL, 183),\n    (24, HUFFMAN_EMIT_SYMBOL, 183),\n    (31, HUFFMAN_EMIT_SYMBOL, 183),\n    (41, HUFFMAN_EMIT_SYMBOL, 183),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 183),\n\n    # Node 169\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 188),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 191),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 197),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 231),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 239),\n    (176, 0, 0),\n    (178, 0, 0),\n    (179, 0, 0),\n    (183, 0, 0),\n    (184, 0, 0),\n    (186, 0, 0),\n    (187, 0, 0),\n    (192, 0, 0),\n    (199, 0, 0),\n    (208, 0, 0),\n    (223, 0, 0),\n\n    # Node 170\n    (1, HUFFMAN_EMIT_SYMBOL, 188),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 188),\n    (1, HUFFMAN_EMIT_SYMBOL, 191),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 191),\n    (1, HUFFMAN_EMIT_SYMBOL, 197),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 197),\n    (1, HUFFMAN_EMIT_SYMBOL, 231),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 231),\n    (1, HUFFMAN_EMIT_SYMBOL, 239),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 239),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 9),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 142),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 144),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 145),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 148),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 159),\n\n    # Node 171\n    (2, HUFFMAN_EMIT_SYMBOL, 188),\n    (9, HUFFMAN_EMIT_SYMBOL, 188),\n    (23, HUFFMAN_EMIT_SYMBOL, 188),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 188),\n    (2, HUFFMAN_EMIT_SYMBOL, 191),\n    (9, HUFFMAN_EMIT_SYMBOL, 191),\n    (23, HUFFMAN_EMIT_SYMBOL, 191),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 191),\n    (2, HUFFMAN_EMIT_SYMBOL, 197),\n    (9, HUFFMAN_EMIT_SYMBOL, 197),\n    (23, HUFFMAN_EMIT_SYMBOL, 197),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 197),\n    (2, HUFFMAN_EMIT_SYMBOL, 231),\n    (9, HUFFMAN_EMIT_SYMBOL, 231),\n    (23, HUFFMAN_EMIT_SYMBOL, 231),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 231),\n\n    # Node 172\n    (3, HUFFMAN_EMIT_SYMBOL, 188),\n    (6, HUFFMAN_EMIT_SYMBOL, 188),\n    (10, HUFFMAN_EMIT_SYMBOL, 188),\n    (15, HUFFMAN_EMIT_SYMBOL, 188),\n    (24, HUFFMAN_EMIT_SYMBOL, 188),\n    (31, HUFFMAN_EMIT_SYMBOL, 188),\n    (41, HUFFMAN_EMIT_SYMBOL, 188),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 188),\n    (3, HUFFMAN_EMIT_SYMBOL, 191),\n    (6, HUFFMAN_EMIT_SYMBOL, 191),\n    (10, HUFFMAN_EMIT_SYMBOL, 191),\n    (15, HUFFMAN_EMIT_SYMBOL, 191),\n    (24, HUFFMAN_EMIT_SYMBOL, 191),\n    (31, HUFFMAN_EMIT_SYMBOL, 191),\n    (41, HUFFMAN_EMIT_SYMBOL, 191),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 191),\n\n    # Node 173\n    (3, HUFFMAN_EMIT_SYMBOL, 197),\n    (6, HUFFMAN_EMIT_SYMBOL, 197),\n    (10, HUFFMAN_EMIT_SYMBOL, 197),\n    (15, HUFFMAN_EMIT_SYMBOL, 197),\n    (24, HUFFMAN_EMIT_SYMBOL, 197),\n    (31, HUFFMAN_EMIT_SYMBOL, 197),\n    (41, HUFFMAN_EMIT_SYMBOL, 197),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 197),\n    (3, HUFFMAN_EMIT_SYMBOL, 231),\n    (6, HUFFMAN_EMIT_SYMBOL, 231),\n    (10, HUFFMAN_EMIT_SYMBOL, 231),\n    (15, HUFFMAN_EMIT_SYMBOL, 231),\n    (24, HUFFMAN_EMIT_SYMBOL, 231),\n    (31, HUFFMAN_EMIT_SYMBOL, 231),\n    (41, HUFFMAN_EMIT_SYMBOL, 231),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 231),\n\n    # Node 174\n    (2, HUFFMAN_EMIT_SYMBOL, 239),\n    (9, HUFFMAN_EMIT_SYMBOL, 239),\n    (23, HUFFMAN_EMIT_SYMBOL, 239),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 239),\n    (1, HUFFMAN_EMIT_SYMBOL, 9),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 9),\n    (1, HUFFMAN_EMIT_SYMBOL, 142),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 142),\n    (1, HUFFMAN_EMIT_SYMBOL, 144),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 144),\n    (1, HUFFMAN_EMIT_SYMBOL, 145),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 145),\n    (1, HUFFMAN_EMIT_SYMBOL, 148),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 148),\n    (1, HUFFMAN_EMIT_SYMBOL, 159),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 159),\n\n    # Node 175\n    (3, HUFFMAN_EMIT_SYMBOL, 239),\n    (6, HUFFMAN_EMIT_SYMBOL, 239),\n    (10, HUFFMAN_EMIT_SYMBOL, 239),\n    (15, HUFFMAN_EMIT_SYMBOL, 239),\n    (24, HUFFMAN_EMIT_SYMBOL, 239),\n    (31, HUFFMAN_EMIT_SYMBOL, 239),\n    (41, HUFFMAN_EMIT_SYMBOL, 239),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 239),\n    (2, HUFFMAN_EMIT_SYMBOL, 9),\n    (9, HUFFMAN_EMIT_SYMBOL, 9),\n    (23, HUFFMAN_EMIT_SYMBOL, 9),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 9),\n    (2, HUFFMAN_EMIT_SYMBOL, 142),\n    (9, HUFFMAN_EMIT_SYMBOL, 142),\n    (23, HUFFMAN_EMIT_SYMBOL, 142),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 142),\n\n    # Node 176\n    (3, HUFFMAN_EMIT_SYMBOL, 9),\n    (6, HUFFMAN_EMIT_SYMBOL, 9),\n    (10, HUFFMAN_EMIT_SYMBOL, 9),\n    (15, HUFFMAN_EMIT_SYMBOL, 9),\n    (24, HUFFMAN_EMIT_SYMBOL, 9),\n    (31, HUFFMAN_EMIT_SYMBOL, 9),\n    (41, HUFFMAN_EMIT_SYMBOL, 9),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 9),\n    (3, HUFFMAN_EMIT_SYMBOL, 142),\n    (6, HUFFMAN_EMIT_SYMBOL, 142),\n    (10, HUFFMAN_EMIT_SYMBOL, 142),\n    (15, HUFFMAN_EMIT_SYMBOL, 142),\n    (24, HUFFMAN_EMIT_SYMBOL, 142),\n    (31, HUFFMAN_EMIT_SYMBOL, 142),\n    (41, HUFFMAN_EMIT_SYMBOL, 142),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 142),\n\n    # Node 177\n    (2, HUFFMAN_EMIT_SYMBOL, 144),\n    (9, HUFFMAN_EMIT_SYMBOL, 144),\n    (23, HUFFMAN_EMIT_SYMBOL, 144),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 144),\n    (2, HUFFMAN_EMIT_SYMBOL, 145),\n    (9, HUFFMAN_EMIT_SYMBOL, 145),\n    (23, HUFFMAN_EMIT_SYMBOL, 145),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 145),\n    (2, HUFFMAN_EMIT_SYMBOL, 148),\n    (9, HUFFMAN_EMIT_SYMBOL, 148),\n    (23, HUFFMAN_EMIT_SYMBOL, 148),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 148),\n    (2, HUFFMAN_EMIT_SYMBOL, 159),\n    (9, HUFFMAN_EMIT_SYMBOL, 159),\n    (23, HUFFMAN_EMIT_SYMBOL, 159),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 159),\n\n    # Node 178\n    (3, HUFFMAN_EMIT_SYMBOL, 144),\n    (6, HUFFMAN_EMIT_SYMBOL, 144),\n    (10, HUFFMAN_EMIT_SYMBOL, 144),\n    (15, HUFFMAN_EMIT_SYMBOL, 144),\n    (24, HUFFMAN_EMIT_SYMBOL, 144),\n    (31, HUFFMAN_EMIT_SYMBOL, 144),\n    (41, HUFFMAN_EMIT_SYMBOL, 144),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 144),\n    (3, HUFFMAN_EMIT_SYMBOL, 145),\n    (6, HUFFMAN_EMIT_SYMBOL, 145),\n    (10, HUFFMAN_EMIT_SYMBOL, 145),\n    (15, HUFFMAN_EMIT_SYMBOL, 145),\n    (24, HUFFMAN_EMIT_SYMBOL, 145),\n    (31, HUFFMAN_EMIT_SYMBOL, 145),\n    (41, HUFFMAN_EMIT_SYMBOL, 145),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 145),\n\n    # Node 179\n    (3, HUFFMAN_EMIT_SYMBOL, 148),\n    (6, HUFFMAN_EMIT_SYMBOL, 148),\n    (10, HUFFMAN_EMIT_SYMBOL, 148),\n    (15, HUFFMAN_EMIT_SYMBOL, 148),\n    (24, HUFFMAN_EMIT_SYMBOL, 148),\n    (31, HUFFMAN_EMIT_SYMBOL, 148),\n    (41, HUFFMAN_EMIT_SYMBOL, 148),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 148),\n    (3, HUFFMAN_EMIT_SYMBOL, 159),\n    (6, HUFFMAN_EMIT_SYMBOL, 159),\n    (10, HUFFMAN_EMIT_SYMBOL, 159),\n    (15, HUFFMAN_EMIT_SYMBOL, 159),\n    (24, HUFFMAN_EMIT_SYMBOL, 159),\n    (31, HUFFMAN_EMIT_SYMBOL, 159),\n    (41, HUFFMAN_EMIT_SYMBOL, 159),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 159),\n\n    # Node 180\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 171),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 206),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 215),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 225),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 236),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 237),\n    (188, 0, 0),\n    (189, 0, 0),\n    (193, 0, 0),\n    (196, 0, 0),\n    (200, 0, 0),\n    (203, 0, 0),\n    (209, 0, 0),\n    (216, 0, 0),\n    (224, 0, 0),\n    (238, 0, 0),\n\n    # Node 181\n    (1, HUFFMAN_EMIT_SYMBOL, 171),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 171),\n    (1, HUFFMAN_EMIT_SYMBOL, 206),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 206),\n    (1, HUFFMAN_EMIT_SYMBOL, 215),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 215),\n    (1, HUFFMAN_EMIT_SYMBOL, 225),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 225),\n    (1, HUFFMAN_EMIT_SYMBOL, 236),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 236),\n    (1, HUFFMAN_EMIT_SYMBOL, 237),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 237),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 199),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 207),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 234),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 235),\n\n    # Node 182\n    (2, HUFFMAN_EMIT_SYMBOL, 171),\n    (9, HUFFMAN_EMIT_SYMBOL, 171),\n    (23, HUFFMAN_EMIT_SYMBOL, 171),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 171),\n    (2, HUFFMAN_EMIT_SYMBOL, 206),\n    (9, HUFFMAN_EMIT_SYMBOL, 206),\n    (23, HUFFMAN_EMIT_SYMBOL, 206),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 206),\n    (2, HUFFMAN_EMIT_SYMBOL, 215),\n    (9, HUFFMAN_EMIT_SYMBOL, 215),\n    (23, HUFFMAN_EMIT_SYMBOL, 215),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 215),\n    (2, HUFFMAN_EMIT_SYMBOL, 225),\n    (9, HUFFMAN_EMIT_SYMBOL, 225),\n    (23, HUFFMAN_EMIT_SYMBOL, 225),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 225),\n\n    # Node 183\n    (3, HUFFMAN_EMIT_SYMBOL, 171),\n    (6, HUFFMAN_EMIT_SYMBOL, 171),\n    (10, HUFFMAN_EMIT_SYMBOL, 171),\n    (15, HUFFMAN_EMIT_SYMBOL, 171),\n    (24, HUFFMAN_EMIT_SYMBOL, 171),\n    (31, HUFFMAN_EMIT_SYMBOL, 171),\n    (41, HUFFMAN_EMIT_SYMBOL, 171),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 171),\n    (3, HUFFMAN_EMIT_SYMBOL, 206),\n    (6, HUFFMAN_EMIT_SYMBOL, 206),\n    (10, HUFFMAN_EMIT_SYMBOL, 206),\n    (15, HUFFMAN_EMIT_SYMBOL, 206),\n    (24, HUFFMAN_EMIT_SYMBOL, 206),\n    (31, HUFFMAN_EMIT_SYMBOL, 206),\n    (41, HUFFMAN_EMIT_SYMBOL, 206),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 206),\n\n    # Node 184\n    (3, HUFFMAN_EMIT_SYMBOL, 215),\n    (6, HUFFMAN_EMIT_SYMBOL, 215),\n    (10, HUFFMAN_EMIT_SYMBOL, 215),\n    (15, HUFFMAN_EMIT_SYMBOL, 215),\n    (24, HUFFMAN_EMIT_SYMBOL, 215),\n    (31, HUFFMAN_EMIT_SYMBOL, 215),\n    (41, HUFFMAN_EMIT_SYMBOL, 215),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 215),\n    (3, HUFFMAN_EMIT_SYMBOL, 225),\n    (6, HUFFMAN_EMIT_SYMBOL, 225),\n    (10, HUFFMAN_EMIT_SYMBOL, 225),\n    (15, HUFFMAN_EMIT_SYMBOL, 225),\n    (24, HUFFMAN_EMIT_SYMBOL, 225),\n    (31, HUFFMAN_EMIT_SYMBOL, 225),\n    (41, HUFFMAN_EMIT_SYMBOL, 225),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 225),\n\n    # Node 185\n    (2, HUFFMAN_EMIT_SYMBOL, 236),\n    (9, HUFFMAN_EMIT_SYMBOL, 236),\n    (23, HUFFMAN_EMIT_SYMBOL, 236),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 236),\n    (2, HUFFMAN_EMIT_SYMBOL, 237),\n    (9, HUFFMAN_EMIT_SYMBOL, 237),\n    (23, HUFFMAN_EMIT_SYMBOL, 237),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 237),\n    (1, HUFFMAN_EMIT_SYMBOL, 199),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 199),\n    (1, HUFFMAN_EMIT_SYMBOL, 207),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 207),\n    (1, HUFFMAN_EMIT_SYMBOL, 234),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 234),\n    (1, HUFFMAN_EMIT_SYMBOL, 235),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 235),\n\n    # Node 186\n    (3, HUFFMAN_EMIT_SYMBOL, 236),\n    (6, HUFFMAN_EMIT_SYMBOL, 236),\n    (10, HUFFMAN_EMIT_SYMBOL, 236),\n    (15, HUFFMAN_EMIT_SYMBOL, 236),\n    (24, HUFFMAN_EMIT_SYMBOL, 236),\n    (31, HUFFMAN_EMIT_SYMBOL, 236),\n    (41, HUFFMAN_EMIT_SYMBOL, 236),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 236),\n    (3, HUFFMAN_EMIT_SYMBOL, 237),\n    (6, HUFFMAN_EMIT_SYMBOL, 237),\n    (10, HUFFMAN_EMIT_SYMBOL, 237),\n    (15, HUFFMAN_EMIT_SYMBOL, 237),\n    (24, HUFFMAN_EMIT_SYMBOL, 237),\n    (31, HUFFMAN_EMIT_SYMBOL, 237),\n    (41, HUFFMAN_EMIT_SYMBOL, 237),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 237),\n\n    # Node 187\n    (2, HUFFMAN_EMIT_SYMBOL, 199),\n    (9, HUFFMAN_EMIT_SYMBOL, 199),\n    (23, HUFFMAN_EMIT_SYMBOL, 199),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 199),\n    (2, HUFFMAN_EMIT_SYMBOL, 207),\n    (9, HUFFMAN_EMIT_SYMBOL, 207),\n    (23, HUFFMAN_EMIT_SYMBOL, 207),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 207),\n    (2, HUFFMAN_EMIT_SYMBOL, 234),\n    (9, HUFFMAN_EMIT_SYMBOL, 234),\n    (23, HUFFMAN_EMIT_SYMBOL, 234),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 234),\n    (2, HUFFMAN_EMIT_SYMBOL, 235),\n    (9, HUFFMAN_EMIT_SYMBOL, 235),\n    (23, HUFFMAN_EMIT_SYMBOL, 235),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 235),\n\n    # Node 188\n    (3, HUFFMAN_EMIT_SYMBOL, 199),\n    (6, HUFFMAN_EMIT_SYMBOL, 199),\n    (10, HUFFMAN_EMIT_SYMBOL, 199),\n    (15, HUFFMAN_EMIT_SYMBOL, 199),\n    (24, HUFFMAN_EMIT_SYMBOL, 199),\n    (31, HUFFMAN_EMIT_SYMBOL, 199),\n    (41, HUFFMAN_EMIT_SYMBOL, 199),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 199),\n    (3, HUFFMAN_EMIT_SYMBOL, 207),\n    (6, HUFFMAN_EMIT_SYMBOL, 207),\n    (10, HUFFMAN_EMIT_SYMBOL, 207),\n    (15, HUFFMAN_EMIT_SYMBOL, 207),\n    (24, HUFFMAN_EMIT_SYMBOL, 207),\n    (31, HUFFMAN_EMIT_SYMBOL, 207),\n    (41, HUFFMAN_EMIT_SYMBOL, 207),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 207),\n\n    # Node 189\n    (3, HUFFMAN_EMIT_SYMBOL, 234),\n    (6, HUFFMAN_EMIT_SYMBOL, 234),\n    (10, HUFFMAN_EMIT_SYMBOL, 234),\n    (15, HUFFMAN_EMIT_SYMBOL, 234),\n    (24, HUFFMAN_EMIT_SYMBOL, 234),\n    (31, HUFFMAN_EMIT_SYMBOL, 234),\n    (41, HUFFMAN_EMIT_SYMBOL, 234),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 234),\n    (3, HUFFMAN_EMIT_SYMBOL, 235),\n    (6, HUFFMAN_EMIT_SYMBOL, 235),\n    (10, HUFFMAN_EMIT_SYMBOL, 235),\n    (15, HUFFMAN_EMIT_SYMBOL, 235),\n    (24, HUFFMAN_EMIT_SYMBOL, 235),\n    (31, HUFFMAN_EMIT_SYMBOL, 235),\n    (41, HUFFMAN_EMIT_SYMBOL, 235),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 235),\n\n    # Node 190\n    (194, 0, 0),\n    (195, 0, 0),\n    (197, 0, 0),\n    (198, 0, 0),\n    (201, 0, 0),\n    (202, 0, 0),\n    (204, 0, 0),\n    (205, 0, 0),\n    (210, 0, 0),\n    (213, 0, 0),\n    (217, 0, 0),\n    (220, 0, 0),\n    (225, 0, 0),\n    (231, 0, 0),\n    (239, 0, 0),\n    (246, 0, 0),\n\n    # Node 191\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 192),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 193),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 200),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 201),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 202),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 205),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 210),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 213),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 218),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 219),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 238),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 240),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 242),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 243),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 255),\n    (206, 0, 0),\n\n    # Node 192\n    (1, HUFFMAN_EMIT_SYMBOL, 192),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 192),\n    (1, HUFFMAN_EMIT_SYMBOL, 193),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 193),\n    (1, HUFFMAN_EMIT_SYMBOL, 200),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 200),\n    (1, HUFFMAN_EMIT_SYMBOL, 201),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 201),\n    (1, HUFFMAN_EMIT_SYMBOL, 202),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 202),\n    (1, HUFFMAN_EMIT_SYMBOL, 205),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 205),\n    (1, HUFFMAN_EMIT_SYMBOL, 210),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 210),\n    (1, HUFFMAN_EMIT_SYMBOL, 213),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 213),\n\n    # Node 193\n    (2, HUFFMAN_EMIT_SYMBOL, 192),\n    (9, HUFFMAN_EMIT_SYMBOL, 192),\n    (23, HUFFMAN_EMIT_SYMBOL, 192),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 192),\n    (2, HUFFMAN_EMIT_SYMBOL, 193),\n    (9, HUFFMAN_EMIT_SYMBOL, 193),\n    (23, HUFFMAN_EMIT_SYMBOL, 193),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 193),\n    (2, HUFFMAN_EMIT_SYMBOL, 200),\n    (9, HUFFMAN_EMIT_SYMBOL, 200),\n    (23, HUFFMAN_EMIT_SYMBOL, 200),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 200),\n    (2, HUFFMAN_EMIT_SYMBOL, 201),\n    (9, HUFFMAN_EMIT_SYMBOL, 201),\n    (23, HUFFMAN_EMIT_SYMBOL, 201),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 201),\n\n    # Node 194\n    (3, HUFFMAN_EMIT_SYMBOL, 192),\n    (6, HUFFMAN_EMIT_SYMBOL, 192),\n    (10, HUFFMAN_EMIT_SYMBOL, 192),\n    (15, HUFFMAN_EMIT_SYMBOL, 192),\n    (24, HUFFMAN_EMIT_SYMBOL, 192),\n    (31, HUFFMAN_EMIT_SYMBOL, 192),\n    (41, HUFFMAN_EMIT_SYMBOL, 192),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 192),\n    (3, HUFFMAN_EMIT_SYMBOL, 193),\n    (6, HUFFMAN_EMIT_SYMBOL, 193),\n    (10, HUFFMAN_EMIT_SYMBOL, 193),\n    (15, HUFFMAN_EMIT_SYMBOL, 193),\n    (24, HUFFMAN_EMIT_SYMBOL, 193),\n    (31, HUFFMAN_EMIT_SYMBOL, 193),\n    (41, HUFFMAN_EMIT_SYMBOL, 193),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 193),\n\n    # Node 195\n    (3, HUFFMAN_EMIT_SYMBOL, 200),\n    (6, HUFFMAN_EMIT_SYMBOL, 200),\n    (10, HUFFMAN_EMIT_SYMBOL, 200),\n    (15, HUFFMAN_EMIT_SYMBOL, 200),\n    (24, HUFFMAN_EMIT_SYMBOL, 200),\n    (31, HUFFMAN_EMIT_SYMBOL, 200),\n    (41, HUFFMAN_EMIT_SYMBOL, 200),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 200),\n    (3, HUFFMAN_EMIT_SYMBOL, 201),\n    (6, HUFFMAN_EMIT_SYMBOL, 201),\n    (10, HUFFMAN_EMIT_SYMBOL, 201),\n    (15, HUFFMAN_EMIT_SYMBOL, 201),\n    (24, HUFFMAN_EMIT_SYMBOL, 201),\n    (31, HUFFMAN_EMIT_SYMBOL, 201),\n    (41, HUFFMAN_EMIT_SYMBOL, 201),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 201),\n\n    # Node 196\n    (2, HUFFMAN_EMIT_SYMBOL, 202),\n    (9, HUFFMAN_EMIT_SYMBOL, 202),\n    (23, HUFFMAN_EMIT_SYMBOL, 202),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 202),\n    (2, HUFFMAN_EMIT_SYMBOL, 205),\n    (9, HUFFMAN_EMIT_SYMBOL, 205),\n    (23, HUFFMAN_EMIT_SYMBOL, 205),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 205),\n    (2, HUFFMAN_EMIT_SYMBOL, 210),\n    (9, HUFFMAN_EMIT_SYMBOL, 210),\n    (23, HUFFMAN_EMIT_SYMBOL, 210),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 210),\n    (2, HUFFMAN_EMIT_SYMBOL, 213),\n    (9, HUFFMAN_EMIT_SYMBOL, 213),\n    (23, HUFFMAN_EMIT_SYMBOL, 213),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 213),\n\n    # Node 197\n    (3, HUFFMAN_EMIT_SYMBOL, 202),\n    (6, HUFFMAN_EMIT_SYMBOL, 202),\n    (10, HUFFMAN_EMIT_SYMBOL, 202),\n    (15, HUFFMAN_EMIT_SYMBOL, 202),\n    (24, HUFFMAN_EMIT_SYMBOL, 202),\n    (31, HUFFMAN_EMIT_SYMBOL, 202),\n    (41, HUFFMAN_EMIT_SYMBOL, 202),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 202),\n    (3, HUFFMAN_EMIT_SYMBOL, 205),\n    (6, HUFFMAN_EMIT_SYMBOL, 205),\n    (10, HUFFMAN_EMIT_SYMBOL, 205),\n    (15, HUFFMAN_EMIT_SYMBOL, 205),\n    (24, HUFFMAN_EMIT_SYMBOL, 205),\n    (31, HUFFMAN_EMIT_SYMBOL, 205),\n    (41, HUFFMAN_EMIT_SYMBOL, 205),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 205),\n\n    # Node 198\n    (3, HUFFMAN_EMIT_SYMBOL, 210),\n    (6, HUFFMAN_EMIT_SYMBOL, 210),\n    (10, HUFFMAN_EMIT_SYMBOL, 210),\n    (15, HUFFMAN_EMIT_SYMBOL, 210),\n    (24, HUFFMAN_EMIT_SYMBOL, 210),\n    (31, HUFFMAN_EMIT_SYMBOL, 210),\n    (41, HUFFMAN_EMIT_SYMBOL, 210),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 210),\n    (3, HUFFMAN_EMIT_SYMBOL, 213),\n    (6, HUFFMAN_EMIT_SYMBOL, 213),\n    (10, HUFFMAN_EMIT_SYMBOL, 213),\n    (15, HUFFMAN_EMIT_SYMBOL, 213),\n    (24, HUFFMAN_EMIT_SYMBOL, 213),\n    (31, HUFFMAN_EMIT_SYMBOL, 213),\n    (41, HUFFMAN_EMIT_SYMBOL, 213),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 213),\n\n    # Node 199\n    (1, HUFFMAN_EMIT_SYMBOL, 218),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 218),\n    (1, HUFFMAN_EMIT_SYMBOL, 219),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 219),\n    (1, HUFFMAN_EMIT_SYMBOL, 238),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 238),\n    (1, HUFFMAN_EMIT_SYMBOL, 240),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 240),\n    (1, HUFFMAN_EMIT_SYMBOL, 242),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 242),\n    (1, HUFFMAN_EMIT_SYMBOL, 243),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 243),\n    (1, HUFFMAN_EMIT_SYMBOL, 255),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 255),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 203),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 204),\n\n    # Node 200\n    (2, HUFFMAN_EMIT_SYMBOL, 218),\n    (9, HUFFMAN_EMIT_SYMBOL, 218),\n    (23, HUFFMAN_EMIT_SYMBOL, 218),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 218),\n    (2, HUFFMAN_EMIT_SYMBOL, 219),\n    (9, HUFFMAN_EMIT_SYMBOL, 219),\n    (23, HUFFMAN_EMIT_SYMBOL, 219),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 219),\n    (2, HUFFMAN_EMIT_SYMBOL, 238),\n    (9, HUFFMAN_EMIT_SYMBOL, 238),\n    (23, HUFFMAN_EMIT_SYMBOL, 238),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 238),\n    (2, HUFFMAN_EMIT_SYMBOL, 240),\n    (9, HUFFMAN_EMIT_SYMBOL, 240),\n    (23, HUFFMAN_EMIT_SYMBOL, 240),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 240),\n\n    # Node 201\n    (3, HUFFMAN_EMIT_SYMBOL, 218),\n    (6, HUFFMAN_EMIT_SYMBOL, 218),\n    (10, HUFFMAN_EMIT_SYMBOL, 218),\n    (15, HUFFMAN_EMIT_SYMBOL, 218),\n    (24, HUFFMAN_EMIT_SYMBOL, 218),\n    (31, HUFFMAN_EMIT_SYMBOL, 218),\n    (41, HUFFMAN_EMIT_SYMBOL, 218),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 218),\n    (3, HUFFMAN_EMIT_SYMBOL, 219),\n    (6, HUFFMAN_EMIT_SYMBOL, 219),\n    (10, HUFFMAN_EMIT_SYMBOL, 219),\n    (15, HUFFMAN_EMIT_SYMBOL, 219),\n    (24, HUFFMAN_EMIT_SYMBOL, 219),\n    (31, HUFFMAN_EMIT_SYMBOL, 219),\n    (41, HUFFMAN_EMIT_SYMBOL, 219),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 219),\n\n    # Node 202\n    (3, HUFFMAN_EMIT_SYMBOL, 238),\n    (6, HUFFMAN_EMIT_SYMBOL, 238),\n    (10, HUFFMAN_EMIT_SYMBOL, 238),\n    (15, HUFFMAN_EMIT_SYMBOL, 238),\n    (24, HUFFMAN_EMIT_SYMBOL, 238),\n    (31, HUFFMAN_EMIT_SYMBOL, 238),\n    (41, HUFFMAN_EMIT_SYMBOL, 238),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 238),\n    (3, HUFFMAN_EMIT_SYMBOL, 240),\n    (6, HUFFMAN_EMIT_SYMBOL, 240),\n    (10, HUFFMAN_EMIT_SYMBOL, 240),\n    (15, HUFFMAN_EMIT_SYMBOL, 240),\n    (24, HUFFMAN_EMIT_SYMBOL, 240),\n    (31, HUFFMAN_EMIT_SYMBOL, 240),\n    (41, HUFFMAN_EMIT_SYMBOL, 240),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 240),\n\n    # Node 203\n    (2, HUFFMAN_EMIT_SYMBOL, 242),\n    (9, HUFFMAN_EMIT_SYMBOL, 242),\n    (23, HUFFMAN_EMIT_SYMBOL, 242),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 242),\n    (2, HUFFMAN_EMIT_SYMBOL, 243),\n    (9, HUFFMAN_EMIT_SYMBOL, 243),\n    (23, HUFFMAN_EMIT_SYMBOL, 243),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 243),\n    (2, HUFFMAN_EMIT_SYMBOL, 255),\n    (9, HUFFMAN_EMIT_SYMBOL, 255),\n    (23, HUFFMAN_EMIT_SYMBOL, 255),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 255),\n    (1, HUFFMAN_EMIT_SYMBOL, 203),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 203),\n    (1, HUFFMAN_EMIT_SYMBOL, 204),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 204),\n\n    # Node 204\n    (3, HUFFMAN_EMIT_SYMBOL, 242),\n    (6, HUFFMAN_EMIT_SYMBOL, 242),\n    (10, HUFFMAN_EMIT_SYMBOL, 242),\n    (15, HUFFMAN_EMIT_SYMBOL, 242),\n    (24, HUFFMAN_EMIT_SYMBOL, 242),\n    (31, HUFFMAN_EMIT_SYMBOL, 242),\n    (41, HUFFMAN_EMIT_SYMBOL, 242),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 242),\n    (3, HUFFMAN_EMIT_SYMBOL, 243),\n    (6, HUFFMAN_EMIT_SYMBOL, 243),\n    (10, HUFFMAN_EMIT_SYMBOL, 243),\n    (15, HUFFMAN_EMIT_SYMBOL, 243),\n    (24, HUFFMAN_EMIT_SYMBOL, 243),\n    (31, HUFFMAN_EMIT_SYMBOL, 243),\n    (41, HUFFMAN_EMIT_SYMBOL, 243),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 243),\n\n    # Node 205\n    (3, HUFFMAN_EMIT_SYMBOL, 255),\n    (6, HUFFMAN_EMIT_SYMBOL, 255),\n    (10, HUFFMAN_EMIT_SYMBOL, 255),\n    (15, HUFFMAN_EMIT_SYMBOL, 255),\n    (24, HUFFMAN_EMIT_SYMBOL, 255),\n    (31, HUFFMAN_EMIT_SYMBOL, 255),\n    (41, HUFFMAN_EMIT_SYMBOL, 255),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 255),\n    (2, HUFFMAN_EMIT_SYMBOL, 203),\n    (9, HUFFMAN_EMIT_SYMBOL, 203),\n    (23, HUFFMAN_EMIT_SYMBOL, 203),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 203),\n    (2, HUFFMAN_EMIT_SYMBOL, 204),\n    (9, HUFFMAN_EMIT_SYMBOL, 204),\n    (23, HUFFMAN_EMIT_SYMBOL, 204),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 204),\n\n    # Node 206\n    (3, HUFFMAN_EMIT_SYMBOL, 203),\n    (6, HUFFMAN_EMIT_SYMBOL, 203),\n    (10, HUFFMAN_EMIT_SYMBOL, 203),\n    (15, HUFFMAN_EMIT_SYMBOL, 203),\n    (24, HUFFMAN_EMIT_SYMBOL, 203),\n    (31, HUFFMAN_EMIT_SYMBOL, 203),\n    (41, HUFFMAN_EMIT_SYMBOL, 203),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 203),\n    (3, HUFFMAN_EMIT_SYMBOL, 204),\n    (6, HUFFMAN_EMIT_SYMBOL, 204),\n    (10, HUFFMAN_EMIT_SYMBOL, 204),\n    (15, HUFFMAN_EMIT_SYMBOL, 204),\n    (24, HUFFMAN_EMIT_SYMBOL, 204),\n    (31, HUFFMAN_EMIT_SYMBOL, 204),\n    (41, HUFFMAN_EMIT_SYMBOL, 204),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 204),\n\n    # Node 207\n    (211, 0, 0),\n    (212, 0, 0),\n    (214, 0, 0),\n    (215, 0, 0),\n    (218, 0, 0),\n    (219, 0, 0),\n    (221, 0, 0),\n    (222, 0, 0),\n    (226, 0, 0),\n    (228, 0, 0),\n    (232, 0, 0),\n    (235, 0, 0),\n    (240, 0, 0),\n    (243, 0, 0),\n    (247, 0, 0),\n    (250, 0, 0),\n\n    # Node 208\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 211),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 212),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 214),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 221),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 222),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 223),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 241),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 244),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 245),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 246),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 247),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 248),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 250),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 251),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 252),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 253),\n\n    # Node 209\n    (1, HUFFMAN_EMIT_SYMBOL, 211),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 211),\n    (1, HUFFMAN_EMIT_SYMBOL, 212),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 212),\n    (1, HUFFMAN_EMIT_SYMBOL, 214),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 214),\n    (1, HUFFMAN_EMIT_SYMBOL, 221),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 221),\n    (1, HUFFMAN_EMIT_SYMBOL, 222),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 222),\n    (1, HUFFMAN_EMIT_SYMBOL, 223),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 223),\n    (1, HUFFMAN_EMIT_SYMBOL, 241),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 241),\n    (1, HUFFMAN_EMIT_SYMBOL, 244),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 244),\n\n    # Node 210\n    (2, HUFFMAN_EMIT_SYMBOL, 211),\n    (9, HUFFMAN_EMIT_SYMBOL, 211),\n    (23, HUFFMAN_EMIT_SYMBOL, 211),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 211),\n    (2, HUFFMAN_EMIT_SYMBOL, 212),\n    (9, HUFFMAN_EMIT_SYMBOL, 212),\n    (23, HUFFMAN_EMIT_SYMBOL, 212),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 212),\n    (2, HUFFMAN_EMIT_SYMBOL, 214),\n    (9, HUFFMAN_EMIT_SYMBOL, 214),\n    (23, HUFFMAN_EMIT_SYMBOL, 214),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 214),\n    (2, HUFFMAN_EMIT_SYMBOL, 221),\n    (9, HUFFMAN_EMIT_SYMBOL, 221),\n    (23, HUFFMAN_EMIT_SYMBOL, 221),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 221),\n\n    # Node 211\n    (3, HUFFMAN_EMIT_SYMBOL, 211),\n    (6, HUFFMAN_EMIT_SYMBOL, 211),\n    (10, HUFFMAN_EMIT_SYMBOL, 211),\n    (15, HUFFMAN_EMIT_SYMBOL, 211),\n    (24, HUFFMAN_EMIT_SYMBOL, 211),\n    (31, HUFFMAN_EMIT_SYMBOL, 211),\n    (41, HUFFMAN_EMIT_SYMBOL, 211),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 211),\n    (3, HUFFMAN_EMIT_SYMBOL, 212),\n    (6, HUFFMAN_EMIT_SYMBOL, 212),\n    (10, HUFFMAN_EMIT_SYMBOL, 212),\n    (15, HUFFMAN_EMIT_SYMBOL, 212),\n    (24, HUFFMAN_EMIT_SYMBOL, 212),\n    (31, HUFFMAN_EMIT_SYMBOL, 212),\n    (41, HUFFMAN_EMIT_SYMBOL, 212),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 212),\n\n    # Node 212\n    (3, HUFFMAN_EMIT_SYMBOL, 214),\n    (6, HUFFMAN_EMIT_SYMBOL, 214),\n    (10, HUFFMAN_EMIT_SYMBOL, 214),\n    (15, HUFFMAN_EMIT_SYMBOL, 214),\n    (24, HUFFMAN_EMIT_SYMBOL, 214),\n    (31, HUFFMAN_EMIT_SYMBOL, 214),\n    (41, HUFFMAN_EMIT_SYMBOL, 214),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 214),\n    (3, HUFFMAN_EMIT_SYMBOL, 221),\n    (6, HUFFMAN_EMIT_SYMBOL, 221),\n    (10, HUFFMAN_EMIT_SYMBOL, 221),\n    (15, HUFFMAN_EMIT_SYMBOL, 221),\n    (24, HUFFMAN_EMIT_SYMBOL, 221),\n    (31, HUFFMAN_EMIT_SYMBOL, 221),\n    (41, HUFFMAN_EMIT_SYMBOL, 221),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 221),\n\n    # Node 213\n    (2, HUFFMAN_EMIT_SYMBOL, 222),\n    (9, HUFFMAN_EMIT_SYMBOL, 222),\n    (23, HUFFMAN_EMIT_SYMBOL, 222),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 222),\n    (2, HUFFMAN_EMIT_SYMBOL, 223),\n    (9, HUFFMAN_EMIT_SYMBOL, 223),\n    (23, HUFFMAN_EMIT_SYMBOL, 223),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 223),\n    (2, HUFFMAN_EMIT_SYMBOL, 241),\n    (9, HUFFMAN_EMIT_SYMBOL, 241),\n    (23, HUFFMAN_EMIT_SYMBOL, 241),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 241),\n    (2, HUFFMAN_EMIT_SYMBOL, 244),\n    (9, HUFFMAN_EMIT_SYMBOL, 244),\n    (23, HUFFMAN_EMIT_SYMBOL, 244),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 244),\n\n    # Node 214\n    (3, HUFFMAN_EMIT_SYMBOL, 222),\n    (6, HUFFMAN_EMIT_SYMBOL, 222),\n    (10, HUFFMAN_EMIT_SYMBOL, 222),\n    (15, HUFFMAN_EMIT_SYMBOL, 222),\n    (24, HUFFMAN_EMIT_SYMBOL, 222),\n    (31, HUFFMAN_EMIT_SYMBOL, 222),\n    (41, HUFFMAN_EMIT_SYMBOL, 222),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 222),\n    (3, HUFFMAN_EMIT_SYMBOL, 223),\n    (6, HUFFMAN_EMIT_SYMBOL, 223),\n    (10, HUFFMAN_EMIT_SYMBOL, 223),\n    (15, HUFFMAN_EMIT_SYMBOL, 223),\n    (24, HUFFMAN_EMIT_SYMBOL, 223),\n    (31, HUFFMAN_EMIT_SYMBOL, 223),\n    (41, HUFFMAN_EMIT_SYMBOL, 223),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 223),\n\n    # Node 215\n    (3, HUFFMAN_EMIT_SYMBOL, 241),\n    (6, HUFFMAN_EMIT_SYMBOL, 241),\n    (10, HUFFMAN_EMIT_SYMBOL, 241),\n    (15, HUFFMAN_EMIT_SYMBOL, 241),\n    (24, HUFFMAN_EMIT_SYMBOL, 241),\n    (31, HUFFMAN_EMIT_SYMBOL, 241),\n    (41, HUFFMAN_EMIT_SYMBOL, 241),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 241),\n    (3, HUFFMAN_EMIT_SYMBOL, 244),\n    (6, HUFFMAN_EMIT_SYMBOL, 244),\n    (10, HUFFMAN_EMIT_SYMBOL, 244),\n    (15, HUFFMAN_EMIT_SYMBOL, 244),\n    (24, HUFFMAN_EMIT_SYMBOL, 244),\n    (31, HUFFMAN_EMIT_SYMBOL, 244),\n    (41, HUFFMAN_EMIT_SYMBOL, 244),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 244),\n\n    # Node 216\n    (1, HUFFMAN_EMIT_SYMBOL, 245),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 245),\n    (1, HUFFMAN_EMIT_SYMBOL, 246),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 246),\n    (1, HUFFMAN_EMIT_SYMBOL, 247),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 247),\n    (1, HUFFMAN_EMIT_SYMBOL, 248),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 248),\n    (1, HUFFMAN_EMIT_SYMBOL, 250),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 250),\n    (1, HUFFMAN_EMIT_SYMBOL, 251),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 251),\n    (1, HUFFMAN_EMIT_SYMBOL, 252),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 252),\n    (1, HUFFMAN_EMIT_SYMBOL, 253),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 253),\n\n    # Node 217\n    (2, HUFFMAN_EMIT_SYMBOL, 245),\n    (9, HUFFMAN_EMIT_SYMBOL, 245),\n    (23, HUFFMAN_EMIT_SYMBOL, 245),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 245),\n    (2, HUFFMAN_EMIT_SYMBOL, 246),\n    (9, HUFFMAN_EMIT_SYMBOL, 246),\n    (23, HUFFMAN_EMIT_SYMBOL, 246),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 246),\n    (2, HUFFMAN_EMIT_SYMBOL, 247),\n    (9, HUFFMAN_EMIT_SYMBOL, 247),\n    (23, HUFFMAN_EMIT_SYMBOL, 247),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 247),\n    (2, HUFFMAN_EMIT_SYMBOL, 248),\n    (9, HUFFMAN_EMIT_SYMBOL, 248),\n    (23, HUFFMAN_EMIT_SYMBOL, 248),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 248),\n\n    # Node 218\n    (3, HUFFMAN_EMIT_SYMBOL, 245),\n    (6, HUFFMAN_EMIT_SYMBOL, 245),\n    (10, HUFFMAN_EMIT_SYMBOL, 245),\n    (15, HUFFMAN_EMIT_SYMBOL, 245),\n    (24, HUFFMAN_EMIT_SYMBOL, 245),\n    (31, HUFFMAN_EMIT_SYMBOL, 245),\n    (41, HUFFMAN_EMIT_SYMBOL, 245),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 245),\n    (3, HUFFMAN_EMIT_SYMBOL, 246),\n    (6, HUFFMAN_EMIT_SYMBOL, 246),\n    (10, HUFFMAN_EMIT_SYMBOL, 246),\n    (15, HUFFMAN_EMIT_SYMBOL, 246),\n    (24, HUFFMAN_EMIT_SYMBOL, 246),\n    (31, HUFFMAN_EMIT_SYMBOL, 246),\n    (41, HUFFMAN_EMIT_SYMBOL, 246),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 246),\n\n    # Node 219\n    (3, HUFFMAN_EMIT_SYMBOL, 247),\n    (6, HUFFMAN_EMIT_SYMBOL, 247),\n    (10, HUFFMAN_EMIT_SYMBOL, 247),\n    (15, HUFFMAN_EMIT_SYMBOL, 247),\n    (24, HUFFMAN_EMIT_SYMBOL, 247),\n    (31, HUFFMAN_EMIT_SYMBOL, 247),\n    (41, HUFFMAN_EMIT_SYMBOL, 247),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 247),\n    (3, HUFFMAN_EMIT_SYMBOL, 248),\n    (6, HUFFMAN_EMIT_SYMBOL, 248),\n    (10, HUFFMAN_EMIT_SYMBOL, 248),\n    (15, HUFFMAN_EMIT_SYMBOL, 248),\n    (24, HUFFMAN_EMIT_SYMBOL, 248),\n    (31, HUFFMAN_EMIT_SYMBOL, 248),\n    (41, HUFFMAN_EMIT_SYMBOL, 248),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 248),\n\n    # Node 220\n    (2, HUFFMAN_EMIT_SYMBOL, 250),\n    (9, HUFFMAN_EMIT_SYMBOL, 250),\n    (23, HUFFMAN_EMIT_SYMBOL, 250),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 250),\n    (2, HUFFMAN_EMIT_SYMBOL, 251),\n    (9, HUFFMAN_EMIT_SYMBOL, 251),\n    (23, HUFFMAN_EMIT_SYMBOL, 251),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 251),\n    (2, HUFFMAN_EMIT_SYMBOL, 252),\n    (9, HUFFMAN_EMIT_SYMBOL, 252),\n    (23, HUFFMAN_EMIT_SYMBOL, 252),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 252),\n    (2, HUFFMAN_EMIT_SYMBOL, 253),\n    (9, HUFFMAN_EMIT_SYMBOL, 253),\n    (23, HUFFMAN_EMIT_SYMBOL, 253),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 253),\n\n    # Node 221\n    (3, HUFFMAN_EMIT_SYMBOL, 250),\n    (6, HUFFMAN_EMIT_SYMBOL, 250),\n    (10, HUFFMAN_EMIT_SYMBOL, 250),\n    (15, HUFFMAN_EMIT_SYMBOL, 250),\n    (24, HUFFMAN_EMIT_SYMBOL, 250),\n    (31, HUFFMAN_EMIT_SYMBOL, 250),\n    (41, HUFFMAN_EMIT_SYMBOL, 250),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 250),\n    (3, HUFFMAN_EMIT_SYMBOL, 251),\n    (6, HUFFMAN_EMIT_SYMBOL, 251),\n    (10, HUFFMAN_EMIT_SYMBOL, 251),\n    (15, HUFFMAN_EMIT_SYMBOL, 251),\n    (24, HUFFMAN_EMIT_SYMBOL, 251),\n    (31, HUFFMAN_EMIT_SYMBOL, 251),\n    (41, HUFFMAN_EMIT_SYMBOL, 251),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 251),\n\n    # Node 222\n    (3, HUFFMAN_EMIT_SYMBOL, 252),\n    (6, HUFFMAN_EMIT_SYMBOL, 252),\n    (10, HUFFMAN_EMIT_SYMBOL, 252),\n    (15, HUFFMAN_EMIT_SYMBOL, 252),\n    (24, HUFFMAN_EMIT_SYMBOL, 252),\n    (31, HUFFMAN_EMIT_SYMBOL, 252),\n    (41, HUFFMAN_EMIT_SYMBOL, 252),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 252),\n    (3, HUFFMAN_EMIT_SYMBOL, 253),\n    (6, HUFFMAN_EMIT_SYMBOL, 253),\n    (10, HUFFMAN_EMIT_SYMBOL, 253),\n    (15, HUFFMAN_EMIT_SYMBOL, 253),\n    (24, HUFFMAN_EMIT_SYMBOL, 253),\n    (31, HUFFMAN_EMIT_SYMBOL, 253),\n    (41, HUFFMAN_EMIT_SYMBOL, 253),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 253),\n\n    # Node 223\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 254),\n    (227, 0, 0),\n    (229, 0, 0),\n    (230, 0, 0),\n    (233, 0, 0),\n    (234, 0, 0),\n    (236, 0, 0),\n    (237, 0, 0),\n    (241, 0, 0),\n    (242, 0, 0),\n    (244, 0, 0),\n    (245, 0, 0),\n    (248, 0, 0),\n    (249, 0, 0),\n    (251, 0, 0),\n    (252, 0, 0),\n\n    # Node 224\n    (1, HUFFMAN_EMIT_SYMBOL, 254),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 254),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 2),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 3),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 4),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 5),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 6),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 7),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 8),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 11),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 12),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 14),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 15),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 16),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 17),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 18),\n\n    # Node 225\n    (2, HUFFMAN_EMIT_SYMBOL, 254),\n    (9, HUFFMAN_EMIT_SYMBOL, 254),\n    (23, HUFFMAN_EMIT_SYMBOL, 254),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 254),\n    (1, HUFFMAN_EMIT_SYMBOL, 2),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 2),\n    (1, HUFFMAN_EMIT_SYMBOL, 3),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 3),\n    (1, HUFFMAN_EMIT_SYMBOL, 4),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 4),\n    (1, HUFFMAN_EMIT_SYMBOL, 5),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 5),\n    (1, HUFFMAN_EMIT_SYMBOL, 6),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 6),\n    (1, HUFFMAN_EMIT_SYMBOL, 7),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 7),\n\n    # Node 226\n    (3, HUFFMAN_EMIT_SYMBOL, 254),\n    (6, HUFFMAN_EMIT_SYMBOL, 254),\n    (10, HUFFMAN_EMIT_SYMBOL, 254),\n    (15, HUFFMAN_EMIT_SYMBOL, 254),\n    (24, HUFFMAN_EMIT_SYMBOL, 254),\n    (31, HUFFMAN_EMIT_SYMBOL, 254),\n    (41, HUFFMAN_EMIT_SYMBOL, 254),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 254),\n    (2, HUFFMAN_EMIT_SYMBOL, 2),\n    (9, HUFFMAN_EMIT_SYMBOL, 2),\n    (23, HUFFMAN_EMIT_SYMBOL, 2),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 2),\n    (2, HUFFMAN_EMIT_SYMBOL, 3),\n    (9, HUFFMAN_EMIT_SYMBOL, 3),\n    (23, HUFFMAN_EMIT_SYMBOL, 3),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 3),\n\n    # Node 227\n    (3, HUFFMAN_EMIT_SYMBOL, 2),\n    (6, HUFFMAN_EMIT_SYMBOL, 2),\n    (10, HUFFMAN_EMIT_SYMBOL, 2),\n    (15, HUFFMAN_EMIT_SYMBOL, 2),\n    (24, HUFFMAN_EMIT_SYMBOL, 2),\n    (31, HUFFMAN_EMIT_SYMBOL, 2),\n    (41, HUFFMAN_EMIT_SYMBOL, 2),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 2),\n    (3, HUFFMAN_EMIT_SYMBOL, 3),\n    (6, HUFFMAN_EMIT_SYMBOL, 3),\n    (10, HUFFMAN_EMIT_SYMBOL, 3),\n    (15, HUFFMAN_EMIT_SYMBOL, 3),\n    (24, HUFFMAN_EMIT_SYMBOL, 3),\n    (31, HUFFMAN_EMIT_SYMBOL, 3),\n    (41, HUFFMAN_EMIT_SYMBOL, 3),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 3),\n\n    # Node 228\n    (2, HUFFMAN_EMIT_SYMBOL, 4),\n    (9, HUFFMAN_EMIT_SYMBOL, 4),\n    (23, HUFFMAN_EMIT_SYMBOL, 4),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 4),\n    (2, HUFFMAN_EMIT_SYMBOL, 5),\n    (9, HUFFMAN_EMIT_SYMBOL, 5),\n    (23, HUFFMAN_EMIT_SYMBOL, 5),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 5),\n    (2, HUFFMAN_EMIT_SYMBOL, 6),\n    (9, HUFFMAN_EMIT_SYMBOL, 6),\n    (23, HUFFMAN_EMIT_SYMBOL, 6),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 6),\n    (2, HUFFMAN_EMIT_SYMBOL, 7),\n    (9, HUFFMAN_EMIT_SYMBOL, 7),\n    (23, HUFFMAN_EMIT_SYMBOL, 7),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 7),\n\n    # Node 229\n    (3, HUFFMAN_EMIT_SYMBOL, 4),\n    (6, HUFFMAN_EMIT_SYMBOL, 4),\n    (10, HUFFMAN_EMIT_SYMBOL, 4),\n    (15, HUFFMAN_EMIT_SYMBOL, 4),\n    (24, HUFFMAN_EMIT_SYMBOL, 4),\n    (31, HUFFMAN_EMIT_SYMBOL, 4),\n    (41, HUFFMAN_EMIT_SYMBOL, 4),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 4),\n    (3, HUFFMAN_EMIT_SYMBOL, 5),\n    (6, HUFFMAN_EMIT_SYMBOL, 5),\n    (10, HUFFMAN_EMIT_SYMBOL, 5),\n    (15, HUFFMAN_EMIT_SYMBOL, 5),\n    (24, HUFFMAN_EMIT_SYMBOL, 5),\n    (31, HUFFMAN_EMIT_SYMBOL, 5),\n    (41, HUFFMAN_EMIT_SYMBOL, 5),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 5),\n\n    # Node 230\n    (3, HUFFMAN_EMIT_SYMBOL, 6),\n    (6, HUFFMAN_EMIT_SYMBOL, 6),\n    (10, HUFFMAN_EMIT_SYMBOL, 6),\n    (15, HUFFMAN_EMIT_SYMBOL, 6),\n    (24, HUFFMAN_EMIT_SYMBOL, 6),\n    (31, HUFFMAN_EMIT_SYMBOL, 6),\n    (41, HUFFMAN_EMIT_SYMBOL, 6),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 6),\n    (3, HUFFMAN_EMIT_SYMBOL, 7),\n    (6, HUFFMAN_EMIT_SYMBOL, 7),\n    (10, HUFFMAN_EMIT_SYMBOL, 7),\n    (15, HUFFMAN_EMIT_SYMBOL, 7),\n    (24, HUFFMAN_EMIT_SYMBOL, 7),\n    (31, HUFFMAN_EMIT_SYMBOL, 7),\n    (41, HUFFMAN_EMIT_SYMBOL, 7),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 7),\n\n    # Node 231\n    (1, HUFFMAN_EMIT_SYMBOL, 8),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 8),\n    (1, HUFFMAN_EMIT_SYMBOL, 11),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 11),\n    (1, HUFFMAN_EMIT_SYMBOL, 12),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 12),\n    (1, HUFFMAN_EMIT_SYMBOL, 14),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 14),\n    (1, HUFFMAN_EMIT_SYMBOL, 15),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 15),\n    (1, HUFFMAN_EMIT_SYMBOL, 16),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 16),\n    (1, HUFFMAN_EMIT_SYMBOL, 17),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 17),\n    (1, HUFFMAN_EMIT_SYMBOL, 18),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 18),\n\n    # Node 232\n    (2, HUFFMAN_EMIT_SYMBOL, 8),\n    (9, HUFFMAN_EMIT_SYMBOL, 8),\n    (23, HUFFMAN_EMIT_SYMBOL, 8),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 8),\n    (2, HUFFMAN_EMIT_SYMBOL, 11),\n    (9, HUFFMAN_EMIT_SYMBOL, 11),\n    (23, HUFFMAN_EMIT_SYMBOL, 11),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 11),\n    (2, HUFFMAN_EMIT_SYMBOL, 12),\n    (9, HUFFMAN_EMIT_SYMBOL, 12),\n    (23, HUFFMAN_EMIT_SYMBOL, 12),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 12),\n    (2, HUFFMAN_EMIT_SYMBOL, 14),\n    (9, HUFFMAN_EMIT_SYMBOL, 14),\n    (23, HUFFMAN_EMIT_SYMBOL, 14),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 14),\n\n    # Node 233\n    (3, HUFFMAN_EMIT_SYMBOL, 8),\n    (6, HUFFMAN_EMIT_SYMBOL, 8),\n    (10, HUFFMAN_EMIT_SYMBOL, 8),\n    (15, HUFFMAN_EMIT_SYMBOL, 8),\n    (24, HUFFMAN_EMIT_SYMBOL, 8),\n    (31, HUFFMAN_EMIT_SYMBOL, 8),\n    (41, HUFFMAN_EMIT_SYMBOL, 8),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 8),\n    (3, HUFFMAN_EMIT_SYMBOL, 11),\n    (6, HUFFMAN_EMIT_SYMBOL, 11),\n    (10, HUFFMAN_EMIT_SYMBOL, 11),\n    (15, HUFFMAN_EMIT_SYMBOL, 11),\n    (24, HUFFMAN_EMIT_SYMBOL, 11),\n    (31, HUFFMAN_EMIT_SYMBOL, 11),\n    (41, HUFFMAN_EMIT_SYMBOL, 11),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 11),\n\n    # Node 234\n    (3, HUFFMAN_EMIT_SYMBOL, 12),\n    (6, HUFFMAN_EMIT_SYMBOL, 12),\n    (10, HUFFMAN_EMIT_SYMBOL, 12),\n    (15, HUFFMAN_EMIT_SYMBOL, 12),\n    (24, HUFFMAN_EMIT_SYMBOL, 12),\n    (31, HUFFMAN_EMIT_SYMBOL, 12),\n    (41, HUFFMAN_EMIT_SYMBOL, 12),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 12),\n    (3, HUFFMAN_EMIT_SYMBOL, 14),\n    (6, HUFFMAN_EMIT_SYMBOL, 14),\n    (10, HUFFMAN_EMIT_SYMBOL, 14),\n    (15, HUFFMAN_EMIT_SYMBOL, 14),\n    (24, HUFFMAN_EMIT_SYMBOL, 14),\n    (31, HUFFMAN_EMIT_SYMBOL, 14),\n    (41, HUFFMAN_EMIT_SYMBOL, 14),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 14),\n\n    # Node 235\n    (2, HUFFMAN_EMIT_SYMBOL, 15),\n    (9, HUFFMAN_EMIT_SYMBOL, 15),\n    (23, HUFFMAN_EMIT_SYMBOL, 15),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 15),\n    (2, HUFFMAN_EMIT_SYMBOL, 16),\n    (9, HUFFMAN_EMIT_SYMBOL, 16),\n    (23, HUFFMAN_EMIT_SYMBOL, 16),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 16),\n    (2, HUFFMAN_EMIT_SYMBOL, 17),\n    (9, HUFFMAN_EMIT_SYMBOL, 17),\n    (23, HUFFMAN_EMIT_SYMBOL, 17),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 17),\n    (2, HUFFMAN_EMIT_SYMBOL, 18),\n    (9, HUFFMAN_EMIT_SYMBOL, 18),\n    (23, HUFFMAN_EMIT_SYMBOL, 18),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 18),\n\n    # Node 236\n    (3, HUFFMAN_EMIT_SYMBOL, 15),\n    (6, HUFFMAN_EMIT_SYMBOL, 15),\n    (10, HUFFMAN_EMIT_SYMBOL, 15),\n    (15, HUFFMAN_EMIT_SYMBOL, 15),\n    (24, HUFFMAN_EMIT_SYMBOL, 15),\n    (31, HUFFMAN_EMIT_SYMBOL, 15),\n    (41, HUFFMAN_EMIT_SYMBOL, 15),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 15),\n    (3, HUFFMAN_EMIT_SYMBOL, 16),\n    (6, HUFFMAN_EMIT_SYMBOL, 16),\n    (10, HUFFMAN_EMIT_SYMBOL, 16),\n    (15, HUFFMAN_EMIT_SYMBOL, 16),\n    (24, HUFFMAN_EMIT_SYMBOL, 16),\n    (31, HUFFMAN_EMIT_SYMBOL, 16),\n    (41, HUFFMAN_EMIT_SYMBOL, 16),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 16),\n\n    # Node 237\n    (3, HUFFMAN_EMIT_SYMBOL, 17),\n    (6, HUFFMAN_EMIT_SYMBOL, 17),\n    (10, HUFFMAN_EMIT_SYMBOL, 17),\n    (15, HUFFMAN_EMIT_SYMBOL, 17),\n    (24, HUFFMAN_EMIT_SYMBOL, 17),\n    (31, HUFFMAN_EMIT_SYMBOL, 17),\n    (41, HUFFMAN_EMIT_SYMBOL, 17),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 17),\n    (3, HUFFMAN_EMIT_SYMBOL, 18),\n    (6, HUFFMAN_EMIT_SYMBOL, 18),\n    (10, HUFFMAN_EMIT_SYMBOL, 18),\n    (15, HUFFMAN_EMIT_SYMBOL, 18),\n    (24, HUFFMAN_EMIT_SYMBOL, 18),\n    (31, HUFFMAN_EMIT_SYMBOL, 18),\n    (41, HUFFMAN_EMIT_SYMBOL, 18),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 18),\n\n    # Node 238\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 19),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 20),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 21),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 23),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 24),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 25),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 26),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 27),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 28),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 29),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 30),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 31),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 127),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 220),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 249),\n    (253, 0, 0),\n\n    # Node 239\n    (1, HUFFMAN_EMIT_SYMBOL, 19),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 19),\n    (1, HUFFMAN_EMIT_SYMBOL, 20),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 20),\n    (1, HUFFMAN_EMIT_SYMBOL, 21),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 21),\n    (1, HUFFMAN_EMIT_SYMBOL, 23),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 23),\n    (1, HUFFMAN_EMIT_SYMBOL, 24),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 24),\n    (1, HUFFMAN_EMIT_SYMBOL, 25),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 25),\n    (1, HUFFMAN_EMIT_SYMBOL, 26),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 26),\n    (1, HUFFMAN_EMIT_SYMBOL, 27),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 27),\n\n    # Node 240\n    (2, HUFFMAN_EMIT_SYMBOL, 19),\n    (9, HUFFMAN_EMIT_SYMBOL, 19),\n    (23, HUFFMAN_EMIT_SYMBOL, 19),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 19),\n    (2, HUFFMAN_EMIT_SYMBOL, 20),\n    (9, HUFFMAN_EMIT_SYMBOL, 20),\n    (23, HUFFMAN_EMIT_SYMBOL, 20),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 20),\n    (2, HUFFMAN_EMIT_SYMBOL, 21),\n    (9, HUFFMAN_EMIT_SYMBOL, 21),\n    (23, HUFFMAN_EMIT_SYMBOL, 21),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 21),\n    (2, HUFFMAN_EMIT_SYMBOL, 23),\n    (9, HUFFMAN_EMIT_SYMBOL, 23),\n    (23, HUFFMAN_EMIT_SYMBOL, 23),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 23),\n\n    # Node 241\n    (3, HUFFMAN_EMIT_SYMBOL, 19),\n    (6, HUFFMAN_EMIT_SYMBOL, 19),\n    (10, HUFFMAN_EMIT_SYMBOL, 19),\n    (15, HUFFMAN_EMIT_SYMBOL, 19),\n    (24, HUFFMAN_EMIT_SYMBOL, 19),\n    (31, HUFFMAN_EMIT_SYMBOL, 19),\n    (41, HUFFMAN_EMIT_SYMBOL, 19),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 19),\n    (3, HUFFMAN_EMIT_SYMBOL, 20),\n    (6, HUFFMAN_EMIT_SYMBOL, 20),\n    (10, HUFFMAN_EMIT_SYMBOL, 20),\n    (15, HUFFMAN_EMIT_SYMBOL, 20),\n    (24, HUFFMAN_EMIT_SYMBOL, 20),\n    (31, HUFFMAN_EMIT_SYMBOL, 20),\n    (41, HUFFMAN_EMIT_SYMBOL, 20),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 20),\n\n    # Node 242\n    (3, HUFFMAN_EMIT_SYMBOL, 21),\n    (6, HUFFMAN_EMIT_SYMBOL, 21),\n    (10, HUFFMAN_EMIT_SYMBOL, 21),\n    (15, HUFFMAN_EMIT_SYMBOL, 21),\n    (24, HUFFMAN_EMIT_SYMBOL, 21),\n    (31, HUFFMAN_EMIT_SYMBOL, 21),\n    (41, HUFFMAN_EMIT_SYMBOL, 21),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 21),\n    (3, HUFFMAN_EMIT_SYMBOL, 23),\n    (6, HUFFMAN_EMIT_SYMBOL, 23),\n    (10, HUFFMAN_EMIT_SYMBOL, 23),\n    (15, HUFFMAN_EMIT_SYMBOL, 23),\n    (24, HUFFMAN_EMIT_SYMBOL, 23),\n    (31, HUFFMAN_EMIT_SYMBOL, 23),\n    (41, HUFFMAN_EMIT_SYMBOL, 23),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 23),\n\n    # Node 243\n    (2, HUFFMAN_EMIT_SYMBOL, 24),\n    (9, HUFFMAN_EMIT_SYMBOL, 24),\n    (23, HUFFMAN_EMIT_SYMBOL, 24),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 24),\n    (2, HUFFMAN_EMIT_SYMBOL, 25),\n    (9, HUFFMAN_EMIT_SYMBOL, 25),\n    (23, HUFFMAN_EMIT_SYMBOL, 25),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 25),\n    (2, HUFFMAN_EMIT_SYMBOL, 26),\n    (9, HUFFMAN_EMIT_SYMBOL, 26),\n    (23, HUFFMAN_EMIT_SYMBOL, 26),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 26),\n    (2, HUFFMAN_EMIT_SYMBOL, 27),\n    (9, HUFFMAN_EMIT_SYMBOL, 27),\n    (23, HUFFMAN_EMIT_SYMBOL, 27),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 27),\n\n    # Node 244\n    (3, HUFFMAN_EMIT_SYMBOL, 24),\n    (6, HUFFMAN_EMIT_SYMBOL, 24),\n    (10, HUFFMAN_EMIT_SYMBOL, 24),\n    (15, HUFFMAN_EMIT_SYMBOL, 24),\n    (24, HUFFMAN_EMIT_SYMBOL, 24),\n    (31, HUFFMAN_EMIT_SYMBOL, 24),\n    (41, HUFFMAN_EMIT_SYMBOL, 24),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 24),\n    (3, HUFFMAN_EMIT_SYMBOL, 25),\n    (6, HUFFMAN_EMIT_SYMBOL, 25),\n    (10, HUFFMAN_EMIT_SYMBOL, 25),\n    (15, HUFFMAN_EMIT_SYMBOL, 25),\n    (24, HUFFMAN_EMIT_SYMBOL, 25),\n    (31, HUFFMAN_EMIT_SYMBOL, 25),\n    (41, HUFFMAN_EMIT_SYMBOL, 25),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 25),\n\n    # Node 245\n    (3, HUFFMAN_EMIT_SYMBOL, 26),\n    (6, HUFFMAN_EMIT_SYMBOL, 26),\n    (10, HUFFMAN_EMIT_SYMBOL, 26),\n    (15, HUFFMAN_EMIT_SYMBOL, 26),\n    (24, HUFFMAN_EMIT_SYMBOL, 26),\n    (31, HUFFMAN_EMIT_SYMBOL, 26),\n    (41, HUFFMAN_EMIT_SYMBOL, 26),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 26),\n    (3, HUFFMAN_EMIT_SYMBOL, 27),\n    (6, HUFFMAN_EMIT_SYMBOL, 27),\n    (10, HUFFMAN_EMIT_SYMBOL, 27),\n    (15, HUFFMAN_EMIT_SYMBOL, 27),\n    (24, HUFFMAN_EMIT_SYMBOL, 27),\n    (31, HUFFMAN_EMIT_SYMBOL, 27),\n    (41, HUFFMAN_EMIT_SYMBOL, 27),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 27),\n\n    # Node 246\n    (1, HUFFMAN_EMIT_SYMBOL, 28),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 28),\n    (1, HUFFMAN_EMIT_SYMBOL, 29),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 29),\n    (1, HUFFMAN_EMIT_SYMBOL, 30),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 30),\n    (1, HUFFMAN_EMIT_SYMBOL, 31),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 31),\n    (1, HUFFMAN_EMIT_SYMBOL, 127),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 127),\n    (1, HUFFMAN_EMIT_SYMBOL, 220),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 220),\n    (1, HUFFMAN_EMIT_SYMBOL, 249),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 249),\n    (254, 0, 0),\n    (255, 0, 0),\n\n    # Node 247\n    (2, HUFFMAN_EMIT_SYMBOL, 28),\n    (9, HUFFMAN_EMIT_SYMBOL, 28),\n    (23, HUFFMAN_EMIT_SYMBOL, 28),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 28),\n    (2, HUFFMAN_EMIT_SYMBOL, 29),\n    (9, HUFFMAN_EMIT_SYMBOL, 29),\n    (23, HUFFMAN_EMIT_SYMBOL, 29),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 29),\n    (2, HUFFMAN_EMIT_SYMBOL, 30),\n    (9, HUFFMAN_EMIT_SYMBOL, 30),\n    (23, HUFFMAN_EMIT_SYMBOL, 30),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 30),\n    (2, HUFFMAN_EMIT_SYMBOL, 31),\n    (9, HUFFMAN_EMIT_SYMBOL, 31),\n    (23, HUFFMAN_EMIT_SYMBOL, 31),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 31),\n\n    # Node 248\n    (3, HUFFMAN_EMIT_SYMBOL, 28),\n    (6, HUFFMAN_EMIT_SYMBOL, 28),\n    (10, HUFFMAN_EMIT_SYMBOL, 28),\n    (15, HUFFMAN_EMIT_SYMBOL, 28),\n    (24, HUFFMAN_EMIT_SYMBOL, 28),\n    (31, HUFFMAN_EMIT_SYMBOL, 28),\n    (41, HUFFMAN_EMIT_SYMBOL, 28),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 28),\n    (3, HUFFMAN_EMIT_SYMBOL, 29),\n    (6, HUFFMAN_EMIT_SYMBOL, 29),\n    (10, HUFFMAN_EMIT_SYMBOL, 29),\n    (15, HUFFMAN_EMIT_SYMBOL, 29),\n    (24, HUFFMAN_EMIT_SYMBOL, 29),\n    (31, HUFFMAN_EMIT_SYMBOL, 29),\n    (41, HUFFMAN_EMIT_SYMBOL, 29),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 29),\n\n    # Node 249\n    (3, HUFFMAN_EMIT_SYMBOL, 30),\n    (6, HUFFMAN_EMIT_SYMBOL, 30),\n    (10, HUFFMAN_EMIT_SYMBOL, 30),\n    (15, HUFFMAN_EMIT_SYMBOL, 30),\n    (24, HUFFMAN_EMIT_SYMBOL, 30),\n    (31, HUFFMAN_EMIT_SYMBOL, 30),\n    (41, HUFFMAN_EMIT_SYMBOL, 30),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 30),\n    (3, HUFFMAN_EMIT_SYMBOL, 31),\n    (6, HUFFMAN_EMIT_SYMBOL, 31),\n    (10, HUFFMAN_EMIT_SYMBOL, 31),\n    (15, HUFFMAN_EMIT_SYMBOL, 31),\n    (24, HUFFMAN_EMIT_SYMBOL, 31),\n    (31, HUFFMAN_EMIT_SYMBOL, 31),\n    (41, HUFFMAN_EMIT_SYMBOL, 31),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 31),\n\n    # Node 250\n    (2, HUFFMAN_EMIT_SYMBOL, 127),\n    (9, HUFFMAN_EMIT_SYMBOL, 127),\n    (23, HUFFMAN_EMIT_SYMBOL, 127),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 127),\n    (2, HUFFMAN_EMIT_SYMBOL, 220),\n    (9, HUFFMAN_EMIT_SYMBOL, 220),\n    (23, HUFFMAN_EMIT_SYMBOL, 220),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 220),\n    (2, HUFFMAN_EMIT_SYMBOL, 249),\n    (9, HUFFMAN_EMIT_SYMBOL, 249),\n    (23, HUFFMAN_EMIT_SYMBOL, 249),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 249),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 10),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 13),\n    (0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 22),\n    (0, HUFFMAN_FAIL, 0),\n\n    # Node 251\n    (3, HUFFMAN_EMIT_SYMBOL, 127),\n    (6, HUFFMAN_EMIT_SYMBOL, 127),\n    (10, HUFFMAN_EMIT_SYMBOL, 127),\n    (15, HUFFMAN_EMIT_SYMBOL, 127),\n    (24, HUFFMAN_EMIT_SYMBOL, 127),\n    (31, HUFFMAN_EMIT_SYMBOL, 127),\n    (41, HUFFMAN_EMIT_SYMBOL, 127),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 127),\n    (3, HUFFMAN_EMIT_SYMBOL, 220),\n    (6, HUFFMAN_EMIT_SYMBOL, 220),\n    (10, HUFFMAN_EMIT_SYMBOL, 220),\n    (15, HUFFMAN_EMIT_SYMBOL, 220),\n    (24, HUFFMAN_EMIT_SYMBOL, 220),\n    (31, HUFFMAN_EMIT_SYMBOL, 220),\n    (41, HUFFMAN_EMIT_SYMBOL, 220),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 220),\n\n    # Node 252\n    (3, HUFFMAN_EMIT_SYMBOL, 249),\n    (6, HUFFMAN_EMIT_SYMBOL, 249),\n    (10, HUFFMAN_EMIT_SYMBOL, 249),\n    (15, HUFFMAN_EMIT_SYMBOL, 249),\n    (24, HUFFMAN_EMIT_SYMBOL, 249),\n    (31, HUFFMAN_EMIT_SYMBOL, 249),\n    (41, HUFFMAN_EMIT_SYMBOL, 249),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 249),\n    (1, HUFFMAN_EMIT_SYMBOL, 10),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 10),\n    (1, HUFFMAN_EMIT_SYMBOL, 13),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 13),\n    (1, HUFFMAN_EMIT_SYMBOL, 22),\n    (22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 22),\n    (0, HUFFMAN_FAIL, 0),\n    (0, HUFFMAN_FAIL, 0),\n\n    # Node 253\n    (2, HUFFMAN_EMIT_SYMBOL, 10),\n    (9, HUFFMAN_EMIT_SYMBOL, 10),\n    (23, HUFFMAN_EMIT_SYMBOL, 10),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 10),\n    (2, HUFFMAN_EMIT_SYMBOL, 13),\n    (9, HUFFMAN_EMIT_SYMBOL, 13),\n    (23, HUFFMAN_EMIT_SYMBOL, 13),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 13),\n    (2, HUFFMAN_EMIT_SYMBOL, 22),\n    (9, HUFFMAN_EMIT_SYMBOL, 22),\n    (23, HUFFMAN_EMIT_SYMBOL, 22),\n    (40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 22),\n    (0, HUFFMAN_FAIL, 0),\n    (0, HUFFMAN_FAIL, 0),\n    (0, HUFFMAN_FAIL, 0),\n    (0, HUFFMAN_FAIL, 0),\n\n    # Node 254\n    (3, HUFFMAN_EMIT_SYMBOL, 10),\n    (6, HUFFMAN_EMIT_SYMBOL, 10),\n    (10, HUFFMAN_EMIT_SYMBOL, 10),\n    (15, HUFFMAN_EMIT_SYMBOL, 10),\n    (24, HUFFMAN_EMIT_SYMBOL, 10),\n    (31, HUFFMAN_EMIT_SYMBOL, 10),\n    (41, HUFFMAN_EMIT_SYMBOL, 10),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 10),\n    (3, HUFFMAN_EMIT_SYMBOL, 13),\n    (6, HUFFMAN_EMIT_SYMBOL, 13),\n    (10, HUFFMAN_EMIT_SYMBOL, 13),\n    (15, HUFFMAN_EMIT_SYMBOL, 13),\n    (24, HUFFMAN_EMIT_SYMBOL, 13),\n    (31, HUFFMAN_EMIT_SYMBOL, 13),\n    (41, HUFFMAN_EMIT_SYMBOL, 13),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 13),\n\n    # Node 255\n    (3, HUFFMAN_EMIT_SYMBOL, 22),\n    (6, HUFFMAN_EMIT_SYMBOL, 22),\n    (10, HUFFMAN_EMIT_SYMBOL, 22),\n    (15, HUFFMAN_EMIT_SYMBOL, 22),\n    (24, HUFFMAN_EMIT_SYMBOL, 22),\n    (31, HUFFMAN_EMIT_SYMBOL, 22),\n    (41, HUFFMAN_EMIT_SYMBOL, 22),\n    (56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 22),\n    (0, HUFFMAN_FAIL, 0),\n    (0, HUFFMAN_FAIL, 0),\n    (0, HUFFMAN_FAIL, 0),\n    (0, HUFFMAN_FAIL, 0),\n    (0, HUFFMAN_FAIL, 0),\n    (0, HUFFMAN_FAIL, 0),\n    (0, HUFFMAN_FAIL, 0),\n    (0, HUFFMAN_FAIL, 0),\n]\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/packages/hpack/struct.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhpack/struct\n~~~~~~~~~~~~\n\nContains structures for representing header fields with associated metadata.\n\"\"\"\n\n\nclass HeaderTuple(tuple):\n    \"\"\"\n    A data structure that stores a single header field.\n\n    HTTP headers can be thought of as tuples of ``(field name, field value)``.\n    A single header block is a sequence of such tuples.\n\n    In HTTP/2, however, certain bits of additional information are required for\n    compressing these headers: in particular, whether the header field can be\n    safely added to the HPACK compression context.\n\n    This class stores a header that can be added to the compression context. In\n    all other ways it behaves exactly like a tuple.\n    \"\"\"\n    __slots__ = ()\n\n    indexable = True\n\n    def __new__(_cls, *args):\n        return tuple.__new__(_cls, args)\n\n\nclass NeverIndexedHeaderTuple(HeaderTuple):\n    \"\"\"\n    A data structure that stores a single header field that cannot be added to\n    a HTTP/2 header compression context.\n    \"\"\"\n    __slots__ = ()\n\n    indexable = False\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/packages/hpack/table.py",
    "content": "# -*- coding: utf-8 -*-\n# flake8: noqa\nfrom collections import deque\nimport logging\n\nfrom .exceptions import InvalidTableIndex\n\nlog = logging.getLogger(__name__)\n\n\ndef table_entry_size(name, value):\n    \"\"\"\n    Calculates the size of a single entry\n\n    This size is mostly irrelevant to us and defined\n    specifically to accommodate memory management for\n    lower level implementations. The 32 extra bytes are\n    considered the \"maximum\" overhead that would be\n    required to represent each entry in the table.\n\n    See RFC7541 Section 4.1\n    \"\"\"\n    return 32 + len(name) + len(value)\n\n\nclass HeaderTable(object):\n    \"\"\"\n    Implements the combined static and dynamic header table\n\n    The name and value arguments for all the functions\n    should ONLY be byte strings (b'') however this is not\n    strictly enforced in the interface.\n\n    See RFC7541 Section 2.3\n    \"\"\"\n    #: Default maximum size of the dynamic table. See\n    #:  RFC7540 Section 6.5.2.\n    DEFAULT_SIZE = 4096\n\n    #: Constant list of static headers. See RFC7541 Section\n    #:  2.3.1 and Appendix A\n    STATIC_TABLE = (\n        (b':authority'                  , b''             ),  # noqa\n        (b':method'                     , b'GET'          ),  # noqa\n        (b':method'                     , b'POST'         ),  # noqa\n        (b':path'                       , b'/'            ),  # noqa\n        (b':path'                       , b'/index.html'  ),  # noqa\n        (b':scheme'                     , b'http'         ),  # noqa\n        (b':scheme'                     , b'https'        ),  # noqa\n        (b':status'                     , b'200'          ),  # noqa\n        (b':status'                     , b'204'          ),  # noqa\n        (b':status'                     , b'206'          ),  # noqa\n        (b':status'                     , b'304'          ),  # noqa\n        (b':status'                     , b'400'          ),  # noqa\n        (b':status'                     , b'404'          ),  # noqa\n        (b':status'                     , b'500'          ),  # noqa\n        (b'accept-charset'              , b''             ),  # noqa\n        (b'accept-encoding'             , b'gzip, deflate'),  # noqa\n        (b'accept-language'             , b''             ),  # noqa\n        (b'accept-ranges'               , b''             ),  # noqa\n        (b'accept'                      , b''             ),  # noqa\n        (b'access-control-allow-origin' , b''             ),  # noqa\n        (b'age'                         , b''             ),  # noqa\n        (b'allow'                       , b''             ),  # noqa\n        (b'authorization'               , b''             ),  # noqa\n        (b'cache-control'               , b''             ),  # noqa\n        (b'content-disposition'         , b''             ),  # noqa\n        (b'content-encoding'            , b''             ),  # noqa\n        (b'content-language'            , b''             ),  # noqa\n        (b'content-length'              , b''             ),  # noqa\n        (b'content-location'            , b''             ),  # noqa\n        (b'content-range'               , b''             ),  # noqa\n        (b'content-type'                , b''             ),  # noqa\n        (b'cookie'                      , b''             ),  # noqa\n        (b'date'                        , b''             ),  # noqa\n        (b'etag'                        , b''             ),  # noqa\n        (b'expect'                      , b''             ),  # noqa\n        (b'expires'                     , b''             ),  # noqa\n        (b'from'                        , b''             ),  # noqa\n        (b'host'                        , b''             ),  # noqa\n        (b'if-match'                    , b''             ),  # noqa\n        (b'if-modified-since'           , b''             ),  # noqa\n        (b'if-none-match'               , b''             ),  # noqa\n        (b'if-range'                    , b''             ),  # noqa\n        (b'if-unmodified-since'         , b''             ),  # noqa\n        (b'last-modified'               , b''             ),  # noqa\n        (b'link'                        , b''             ),  # noqa\n        (b'location'                    , b''             ),  # noqa\n        (b'max-forwards'                , b''             ),  # noqa\n        (b'proxy-authenticate'          , b''             ),  # noqa\n        (b'proxy-authorization'         , b''             ),  # noqa\n        (b'range'                       , b''             ),  # noqa\n        (b'referer'                     , b''             ),  # noqa\n        (b'refresh'                     , b''             ),  # noqa\n        (b'retry-after'                 , b''             ),  # noqa\n        (b'server'                      , b''             ),  # noqa\n        (b'set-cookie'                  , b''             ),  # noqa\n        (b'strict-transport-security'   , b''             ),  # noqa\n        (b'transfer-encoding'           , b''             ),  # noqa\n        (b'user-agent'                  , b''             ),  # noqa\n        (b'vary'                        , b''             ),  # noqa\n        (b'via'                         , b''             ),  # noqa\n        (b'www-authenticate'            , b''             ),  # noqa\n    )  # noqa\n\n    STATIC_TABLE_LENGTH = len(STATIC_TABLE)\n\n    def __init__(self):\n        self._maxsize = HeaderTable.DEFAULT_SIZE\n        self._current_size = 0\n        self.resized = False\n        self.dynamic_entries = deque()\n\n    def get_by_index(self, index):\n        \"\"\"\n        Returns the entry specified by index\n\n        Note that the table is 1-based ie an index of 0 is\n        invalid.  This is due to the fact that a zero value\n        index signals that a completely unindexed header\n        follows.\n\n        The entry will either be from the static table or\n        the dynamic table depending on the value of index.\n        \"\"\"\n        original_index = index\n        index -= 1\n        if 0 <= index:\n            if index < HeaderTable.STATIC_TABLE_LENGTH:\n                return HeaderTable.STATIC_TABLE[index]\n\n            index -= HeaderTable.STATIC_TABLE_LENGTH\n            if index < len(self.dynamic_entries):\n                return self.dynamic_entries[index]\n\n        raise InvalidTableIndex(\"Invalid table index %d\" % original_index)\n\n    def __repr__(self):\n        return \"HeaderTable(%d, %s, %r)\" % (\n            self._maxsize,\n            self.resized,\n            self.dynamic_entries\n        )\n\n    def add(self, name, value):\n        \"\"\"\n        Adds a new entry to the table\n\n        We reduce the table size if the entry will make the\n        table size greater than maxsize.\n        \"\"\"\n        # We just clear the table if the entry is too big\n        size = table_entry_size(name, value)\n        if size > self._maxsize:\n            self.dynamic_entries.clear()\n            self._current_size = 0\n        else:\n            # Add new entry\n            self.dynamic_entries.appendleft((name, value))\n            self._current_size += size\n            self._shrink()\n\n    def search(self, name, value):\n        \"\"\"\n        Searches the table for the entry specified by name\n        and value\n\n        Returns one of the following:\n            - ``None``, no match at all\n            - ``(index, name, None)`` for partial matches on name only.\n            - ``(index, name, value)`` for perfect matches.\n        \"\"\"\n        offset = HeaderTable.STATIC_TABLE_LENGTH + 1\n        partial = None\n        for (i, (n, v)) in enumerate(HeaderTable.STATIC_TABLE):\n            if n == name:\n                if v == value:\n                    return i + 1, n, v\n                elif partial is None:\n                    partial = (i + 1, n, None)\n        for (i, (n, v)) in enumerate(self.dynamic_entries):\n            if n == name:\n                if v == value:\n                    return i + offset, n, v\n                elif partial is None:\n                    partial = (i + offset, n, None)\n        return partial\n\n    @property\n    def maxsize(self):\n        return self._maxsize\n\n    @maxsize.setter\n    def maxsize(self, newmax):\n        newmax = int(newmax)\n        log.debug(\"Resizing header table to %d from %d\", newmax, self._maxsize)\n        oldmax = self._maxsize\n        self._maxsize = newmax\n        self.resized = (newmax != oldmax)\n        if newmax <= 0:\n            self.dynamic_entries.clear()\n            self._current_size = 0\n        elif oldmax > newmax:\n            self._shrink()\n\n    def _shrink(self):\n        \"\"\"\n        Shrinks the dynamic table to be at or below maxsize\n        \"\"\"\n        cursize = self._current_size\n        while cursize > self._maxsize:\n            name, value = self.dynamic_entries.pop()\n            cursize -= table_entry_size(name, value)\n            log.debug(\"Evicting %s: %s from the header table\", name, value)\n        self._current_size = cursize\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/packages/hyperframe/__init__.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhyperframe\n~~~~~~~~~~\n\nA module for providing a pure-Python HTTP/2 framing layer.\n\"\"\"\n__version__ = '2.1.0'\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/packages/hyperframe/flags.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhyperframe/flags\n~~~~~~~~~~~~~~~~\n\nDefines basic Flag and Flags data structures.\n\"\"\"\nfrom collections import namedtuple\ntry:\n    from collections import MutableSet\nexcept:\n    from collections.abc import MutableSet\n\n\nFlag = namedtuple(\"Flag\", [\"name\", \"bit\"])\n\n\nclass Flags(MutableSet):\n    \"\"\"\n    A simple MutableSet implementation that will only accept known flags as elements.\n\n    Will behave like a regular set(), except that a ValueError will be thrown when .add()ing\n    unexpected flags.\n    \"\"\"\n    def __init__(self, defined_flags):\n        self._valid_flags = set(flag.name for flag in defined_flags)\n        self._flags = set()\n\n    def __contains__(self, x):\n        return self._flags.__contains__(x)\n\n    def __iter__(self):\n        return self._flags.__iter__()\n\n    def __len__(self):\n        return self._flags.__len__()\n\n    def discard(self, value):\n        return self._flags.discard(value)\n\n    def add(self, value):\n        if isinstance(value, str):\n            value = value.encode(\"utf-8\")\n        if value not in self._valid_flags:\n            raise ValueError(\"Unexpected flag: {}\".format(value))\n        return self._flags.add(value)\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/packages/hyperframe/frame.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhyperframe/frame\n~~~~~~~~~~~~~~~~\n\nDefines framing logic for HTTP/2. Provides both classes to represent framed\ndata and logic for aiding the connection when it comes to reading from the\nsocket.\n\"\"\"\nimport collections\nimport xstruct as struct\n\nfrom .flags import Flag, Flags\nfrom ...http20 import errors\n\n# The maximum initial length of a frame. Some frames have shorter maximum lengths.\nFRAME_MAX_LEN = (2 ** 14)\n\n# The maximum allowed length of a frame.\nFRAME_MAX_ALLOWED_LEN = (2 ** 24) - 1\n\n\nclass Frame(object):\n    \"\"\"\n    The base class for all HTTP/2 frames.\n    \"\"\"\n    # The flags defined on this type of frame.\n    defined_flags = []\n\n    # The type of the frame.\n    type = None\n\n    # If 'has-stream', the frame's stream_id must be non-zero. If 'no-stream',\n    # it must be zero. If 'either', it's not checked.\n    stream_association = None\n\n    def __init__(self, stream_id, flags=()):\n        self.stream_id = stream_id\n        self.flags = Flags(self.defined_flags)\n        self.body_len = 0\n\n        for flag in flags:\n            self.flags.add(flag)\n\n        if self.stream_association == 'has-stream' and not self.stream_id:\n            raise ValueError('Stream ID must be non-zero')\n        if self.stream_association == 'no-stream' and self.stream_id:\n            raise ValueError('Stream ID must be zero')\n\n    def _extra_info(self):\n        return \"\"\n\n    def __repr__(self):\n        out_str = \"{type}\".format(type=type(self).__name__)\n        if self.stream_id:\n            out_str += \" %d\" % self.stream_id\n\n        if len(self.flags):\n            out_str += \" F:\" + b\", \".join(self.flags).decode(\"ascii\")\n\n        extra_str = self._extra_info()\n        if extra_str:\n            out_str += \" \" + extra_str\n\n        return out_str\n\n    @staticmethod\n    def parse_frame_header(header):\n        \"\"\"\n        Takes a 9-byte frame header and returns a tuple of the appropriate\n        Frame object and the length that needs to be read from the socket.\n        \"\"\"\n        fields = struct.unpack(\"!HBBBL\", header)\n        # First 24 bits are frame length.\n        length = (fields[0] << 8) + fields[1]\n        type = fields[2]\n        flags = fields[3]\n        stream_id = fields[4]\n\n        if type not in FRAMES:\n            raise ValueError(\"Unknown frame type %d\" % type)\n\n        frame = FRAMES[type](stream_id)\n        frame.parse_flags(flags)\n        return frame, length\n\n    def parse_flags(self, flag_byte):\n        for flag, flag_bit in self.defined_flags:\n            if flag_byte & flag_bit:\n                self.flags.add(flag)\n\n        return self.flags\n\n    def serialize(self):\n        body = self.serialize_body()\n        self.body_len = len(body)\n\n        # Build the common frame header.\n        # First, get the flags.\n        flags = 0\n\n        for flag, flag_bit in self.defined_flags:\n            if flag in self.flags:\n                flags |= flag_bit\n\n        header = struct.pack(\n            \"!HBBBL\",\n            (self.body_len & 0xFFFF00) >> 8,  # Length is spread over top 24 bits\n            self.body_len & 0x0000FF,\n            self.type,\n            flags,\n            self.stream_id & 0x7FFFFFFF  # Stream ID is 32 bits.\n        )\n\n        return header + body\n\n    def serialize_body(self):\n        raise NotImplementedError()\n\n    def parse_body(self, data):\n        raise NotImplementedError()\n\n\nclass Padding(object):\n    \"\"\"\n    Mixin for frames that contain padding.\n    \"\"\"\n    def __init__(self, stream_id, pad_length=0, **kwargs):\n        super(Padding, self).__init__(stream_id, **kwargs)\n\n        self.pad_length = pad_length\n\n    def serialize_padding_data(self):\n        if b'PADDED' in self.flags:\n            return struct.pack('!B', self.pad_length)\n        return b''\n\n    def parse_padding_data(self, data):\n        if b'PADDED' in self.flags:\n            self.pad_length = struct.unpack('!B', data[:1])[0]\n            return 1\n        return 0\n\n    @property\n    def total_padding(self):\n        \"\"\"Return the total length of the padding, if any.\"\"\"\n        return self.pad_length\n\n    def _extra_info(self):\n        if self.pad_length:\n            return \"pad_len:%d\" % self.pad_length\n        else:\n            return \"\"\n\n\nclass Priority(object):\n    \"\"\"\n    Mixin for frames that contain priority data.\n    \"\"\"\n    def __init__(self, stream_id, depends_on=None, stream_weight=None, exclusive=None, **kwargs):\n        super(Priority, self).__init__(stream_id, **kwargs)\n\n        # The stream ID of the stream on which this stream depends.\n        self.depends_on = depends_on\n\n        # The weight of the stream. This is an integer between 0 and 256.\n        self.stream_weight = stream_weight\n\n        # Whether the exclusive bit was set.\n        self.exclusive = exclusive\n\n    def serialize_priority_data(self):\n        return struct.pack(\n            \"!LB\",\n            self.depends_on | (int(self.exclusive) << 31),\n            self.stream_weight\n        )\n\n    def parse_priority_data(self, data):\n        MASK = 0x80000000\n        self.depends_on, self.stream_weight = struct.unpack(\n            \"!LB\", data[:5]\n        )\n        self.exclusive = bool(self.depends_on & MASK)\n        self.depends_on &= ~MASK\n        return 5\n\n\nclass DataFrame(Padding, Frame):\n    \"\"\"\n    DATA frames convey arbitrary, variable-length sequences of octets\n    associated with a stream. One or more DATA frames are used, for instance,\n    to carry HTTP request or response payloads.\n    \"\"\"\n    defined_flags = [\n        Flag(b'END_STREAM', 0x01),\n        Flag(b'PADDED', 0x08),\n    ]\n\n    type = 0x0\n\n    stream_association = 'has-stream'\n\n    def __init__(self, stream_id, data=b'', **kwargs):\n        super(DataFrame, self).__init__(stream_id, **kwargs)\n\n        self.data = data\n\n    def serialize_body(self):\n        padding_data = self.serialize_padding_data()\n        padding = b'\\0' * self.total_padding\n        return b''.join([padding_data, self.data, padding])\n\n    def parse_body(self, data):\n        padding_data_length = self.parse_padding_data(data)\n        self.data = data[padding_data_length:len(data)-self.total_padding]\n        self.body_len = len(data)\n\n    @property\n    def flow_controlled_length(self):\n        \"\"\"\n        If the frame is padded we need to include the padding length byte in\n        the flow control used.\n        \"\"\"\n        padding_len = self.total_padding + 1 if self.total_padding else 0\n        return len(self.data) + padding_len\n\n    def _extra_info(self):\n        return \"len:%d\" % len(self.data)\n\n\nclass PriorityFrame(Priority, Frame):\n    \"\"\"\n    The PRIORITY frame specifies the sender-advised priority of a stream. It\n    can be sent at any time for an existing stream. This enables\n    reprioritisation of existing streams.\n    \"\"\"\n    defined_flags = []\n\n    type = 0x02\n\n    stream_association = 'has-stream'\n\n    def serialize_body(self):\n        return self.serialize_priority_data()\n\n    def parse_body(self, data):\n        self.parse_priority_data(data)\n        self.body_len = len(data)\n\n\nclass RstStreamFrame(Frame):\n    \"\"\"\n    The RST_STREAM frame allows for abnormal termination of a stream. When sent\n    by the initiator of a stream, it indicates that they wish to cancel the\n    stream or that an error condition has occurred. When sent by the receiver\n    of a stream, it indicates that either the receiver is rejecting the stream,\n    requesting that the stream be cancelled or that an error condition has\n    occurred.\n    \"\"\"\n    defined_flags = []\n\n    type = 0x03\n\n    stream_association = 'has-stream'\n\n    def __init__(self, stream_id, error_code=0, **kwargs):\n        super(RstStreamFrame, self).__init__(stream_id, **kwargs)\n\n        self.error_code = error_code\n\n    def serialize_body(self):\n        return struct.pack(\"!L\", self.error_code)\n\n    def parse_body(self, data):\n        if len(data) != 4:\n            raise ValueError()\n\n        self.error_code = struct.unpack(\"!L\", data)[0]\n        self.body_len = len(data)\n\n    def _extra_info(self):\n        return \"error_code:%d\" % self.error_code\n\n\nclass SettingsFrame(Frame):\n    \"\"\"\n    The SETTINGS frame conveys configuration parameters that affect how\n    endpoints communicate. The parameters are either constraints on peer\n    behavior or preferences.\n\n    Settings are not negotiated. Settings describe characteristics of the\n    sending peer, which are used by the receiving peer. Different values for\n    the same setting can be advertised by each peer. For example, a client\n    might set a high initial flow control window, whereas a server might set a\n    lower value to conserve resources.\n    \"\"\"\n    defined_flags = [Flag(b'ACK', 0x01)]\n\n    type = 0x04\n\n    stream_association = 'no-stream'\n\n    # We need to define the known settings, they may as well be class\n    # attributes.\n    HEADER_TABLE_SIZE             = 0x01\n    ENABLE_PUSH                   = 0x02\n    MAX_CONCURRENT_STREAMS        = 0x03\n    INITIAL_WINDOW_SIZE           = 0x04\n    SETTINGS_MAX_FRAME_SIZE       = 0x05\n    SETTINGS_MAX_HEADER_LIST_SIZE = 0x06\n\n    def __init__(self, stream_id=0, settings=None, **kwargs):\n        super(SettingsFrame, self).__init__(stream_id, **kwargs)\n\n        if settings and b\"ACK\" in kwargs.get(\"flags\", ()):\n            raise ValueError(\"Settings must be empty if ACK flag is set.\")\n\n        # A dictionary of the setting type byte to the value.\n        self.settings = settings or {}\n\n    def serialize_body(self):\n        settings = [struct.pack(\"!HL\", setting & 0xFF, value)\n                    for setting, value in list(self.settings.items())]\n        return b''.join(settings)\n\n    def parse_body(self, data):\n        for i in range(0, len(data), 6):\n            name, value = struct.unpack(\"!HL\", data[i:i+6])\n            self.settings[name] = value\n\n        self.body_len = len(data)\n\n    def _extra_info(self):\n        if not len(self.settings):\n            return \"\"\n\n        kv = []\n        for k in self.settings:\n            kv.append(str(k) + \":\" + str(self.settings[k]))\n\n        return \";\".join(kv)\n\n\nclass PushPromiseFrame(Padding, Frame):\n    \"\"\"\n    The PUSH_PROMISE frame is used to notify the peer endpoint in advance of\n    streams the sender intends to initiate.\n    \"\"\"\n    defined_flags = [\n        Flag(b'END_HEADERS', 0x04),\n        Flag(b'PADDED', 0x08)\n    ]\n\n    type = 0x05\n\n    stream_association = 'has-stream'\n\n    def __init__(self, stream_id, promised_stream_id=0, data=b'', **kwargs):\n        super(PushPromiseFrame, self).__init__(stream_id, **kwargs)\n\n        self.promised_stream_id = promised_stream_id\n        self.data = data\n\n    def serialize_body(self):\n        padding_data = self.serialize_padding_data()\n        padding = b'\\0' * self.total_padding\n        data = struct.pack(\"!L\", self.promised_stream_id)\n        return b''.join([padding_data, data, self.data, padding])\n\n    def parse_body(self, data):\n        padding_data_length = self.parse_padding_data(data)\n        self.promised_stream_id = struct.unpack(\"!L\", data[padding_data_length:padding_data_length + 4])[0]\n        self.data = data[padding_data_length + 4:].tobytes()\n        self.body_len = len(data)\n\n\nclass PingFrame(Frame):\n    \"\"\"\n    The PING frame is a mechanism for measuring a minimal round-trip time from\n    the sender, as well as determining whether an idle connection is still\n    functional. PING frames can be sent from any endpoint.\n    \"\"\"\n    defined_flags = [Flag(b'ACK', 0x01)]\n\n    type = 0x06\n\n    stream_association = 'no-stream'\n\n    def __init__(self, stream_id=0, opaque_data=b'', **kwargs):\n        super(PingFrame, self).__init__(stream_id, **kwargs)\n\n        self.opaque_data = opaque_data\n\n    def serialize_body(self):\n        if len(self.opaque_data) > 8:\n            raise ValueError()\n\n        data = self.opaque_data\n        data += b'\\x00' * (8 - len(self.opaque_data))\n        return data\n\n    def parse_body(self, data):\n        if len(data) > 8:\n            raise ValueError()\n\n        self.opaque_data = data.tobytes()\n        self.body_len = len(data)\n\n\nclass GoAwayFrame(Frame):\n    \"\"\"\n    The GOAWAY frame informs the remote peer to stop creating streams on this\n    connection. It can be sent from the client or the server. Once sent, the\n    sender will ignore frames sent on new streams for the remainder of the\n    connection.\n    \"\"\"\n    type = 0x07\n\n    stream_association = 'no-stream'\n\n    def __init__(self, stream_id=0, last_stream_id=0, error_code=0, additional_data=b'', **kwargs):\n        super(GoAwayFrame, self).__init__(stream_id, **kwargs)\n\n        self.last_stream_id = last_stream_id\n        self.error_code = error_code\n        self.additional_data = additional_data\n\n    def serialize_body(self):\n        data = struct.pack(\n            \"!LL\",\n            self.last_stream_id & 0x7FFFFFFF,\n            self.error_code\n        )\n        data += self.additional_data\n\n        return data\n\n    def parse_body(self, data):\n        self.last_stream_id, self.error_code = struct.unpack(\"!LL\", data[:8])\n        self.body_len = len(data)\n\n        if len(data) > 8:\n            self.additional_data = data[8:].tobytes()\n\n    def _extra_info(self):\n        if self.error_code != 0:\n            try:\n                name, number, description = errors.get_data(self.error_code)\n            except ValueError:\n                error_string = (\"Encountered error code %d, extra data %s\" % (self.error_code, self.additional_data))\n            else:\n                error_string = (\"Encountered error %s %s: %s\" % (name, number, description))\n        else:\n            error_string = \"\"\n\n        out_str = \"\"\n        if error_string:\n            out_str += \"error_string:%s\" % error_string\n        if self.additional_data:\n            out_str += \" additional_data:%s\" % self.additional_data\n\n        return out_str\n\n\nclass WindowUpdateFrame(Frame):\n    \"\"\"\n    The WINDOW_UPDATE frame is used to implement flow control.\n\n    Flow control operates at two levels: on each individual stream and on the\n    entire connection.\n\n    Both types of flow control are hop by hop; that is, only between the two\n    endpoints. Intermediaries do not forward WINDOW_UPDATE frames between\n    dependent connections. However, throttling of data transfer by any receiver\n    can indirectly cause the propagation of flow control information toward the\n    original sender.\n    \"\"\"\n    type = 0x08\n\n    stream_association = 'either'\n\n    def __init__(self, stream_id, window_increment=0, **kwargs):\n        super(WindowUpdateFrame, self).__init__(stream_id, **kwargs)\n\n        self.window_increment = window_increment\n\n    def serialize_body(self):\n        return struct.pack(\"!L\", self.window_increment & 0x7FFFFFFF)\n\n    def parse_body(self, data):\n        self.window_increment = struct.unpack(\"!L\", data)[0]\n        self.body_len = len(data)\n\n    def _extra_info(self):\n        return \"win_inc:%d\" % self.window_increment\n\n\nclass HeadersFrame(Padding, Priority, Frame):\n    \"\"\"\n    The HEADERS frame carries name-value pairs. It is used to open a stream.\n    HEADERS frames can be sent on a stream in the \"open\" or \"half closed\n    (remote)\" states.\n\n    The HeadersFrame class is actually basically a data frame in this\n    implementation, because of the requirement to control the sizes of frames.\n    A header block fragment that doesn't fit in an entire HEADERS frame needs\n    to be followed with CONTINUATION frames. From the perspective of the frame\n    building code the header block is an opaque data segment.\n    \"\"\"\n    type = 0x01\n\n    stream_association = 'has-stream'\n\n    defined_flags = [\n        Flag(b'END_STREAM', 0x01),\n        Flag(b'END_HEADERS', 0x04),\n        Flag(b'PADDED', 0x08),\n        Flag(b'PRIORITY', 0x20),\n    ]\n\n    def __init__(self, stream_id, data=b'', **kwargs):\n        super(HeadersFrame, self).__init__(stream_id, **kwargs)\n\n        self.data = data\n\n    def serialize_body(self):\n        padding_data = self.serialize_padding_data()\n        padding = b'\\0' * self.total_padding\n\n        if b'PRIORITY' in self.flags:\n            priority_data = self.serialize_priority_data()\n        else:\n            priority_data = b''\n\n        return b''.join([padding_data, priority_data, self.data, padding])\n\n    def parse_body(self, data):\n        padding_data_length = self.parse_padding_data(data)\n        data = data[padding_data_length:]\n\n        if b'PRIORITY' in self.flags:\n            priority_data_length = self.parse_priority_data(data)\n        else:\n            priority_data_length = 0\n\n        self.body_len = len(data)\n        self.data = data[priority_data_length:len(data)-self.total_padding]\n\n\nclass ContinuationFrame(Frame):\n    \"\"\"\n    The CONTINUATION frame is used to continue a sequence of header block\n    fragments. Any number of CONTINUATION frames can be sent on an existing\n    stream, as long as the preceding frame on the same stream is one of\n    HEADERS, PUSH_PROMISE or CONTINUATION without the END_HEADERS flag set.\n\n    Much like the HEADERS frame, hyper treats this as an opaque data frame with\n    different flags and a different type.\n    \"\"\"\n    type = 0x09\n\n    stream_association = 'has-stream'\n\n    defined_flags = [Flag(b'END_HEADERS', 0x04), ]\n\n    def __init__(self, stream_id, data=b'', **kwargs):\n        super(ContinuationFrame, self).__init__(stream_id, **kwargs)\n\n        self.data = data\n\n    def serialize_body(self):\n        return self.data\n\n    def parse_body(self, data):\n        self.data = data\n        self.body_len = len(data)\n\n\nOrigin = collections.namedtuple('Origin', ['scheme', 'host', 'port'])\n\n\nclass AltSvcFrame(Frame):\n    \"\"\"\n    The ALTSVC frame is used to advertise alternate services that the current\n    host, or a different one, can understand.\n    \"\"\"\n    type = 0xA\n\n    stream_association = 'no-stream'\n\n    def __init__(self, stream_id=0, host=b'', port=0, protocol_id=b'', max_age=0, origin=None, **kwargs):\n        super(AltSvcFrame, self).__init__(stream_id, **kwargs)\n\n        self.host = host\n        self.port = port\n        self.protocol_id = protocol_id\n        self.max_age = max_age\n        self.origin = origin\n\n    def serialize_origin(self):\n        if self.origin is not None:\n            if self.origin.port is None:\n                hostport = self.origin.host\n            else:\n                hostport = self.origin.host + b':' + str(self.origin.port).encode('ascii')\n            return self.origin.scheme + b'://' + hostport\n        return b''\n\n    def parse_origin(self, data):\n        if len(data) > 0:\n            data = data.tobytes()\n            scheme, hostport = data.split(b'://')\n            host, _, port = hostport.partition(b':')\n            self.origin = Origin(scheme=scheme, host=host,\n                                 port=int(port) if len(port) > 0 else None)\n\n    def serialize_body(self):\n        first = struct.pack(\"!LHxB\", self.max_age, self.port, len(self.protocol_id))\n        host_length = struct.pack(\"!B\", len(self.host))\n        return b''.join([first, self.protocol_id, host_length, self.host,\n                         self.serialize_origin()])\n\n    def parse_body(self, data):\n        self.body_len = len(data)\n        self.max_age, self.port, protocol_id_length = struct.unpack(\"!LHxB\", data[:8])\n        pos = 8\n        self.protocol_id = data[pos:pos+protocol_id_length].tobytes()\n        pos += protocol_id_length\n        host_length = struct.unpack(\"!B\", data[pos:pos+1])[0]\n        pos += 1\n        self.host = data[pos:pos+host_length].tobytes()\n        pos += host_length\n        self.parse_origin(data[pos:])\n\n\nclass BlockedFrame(Frame):\n    \"\"\"\n    The BLOCKED frame indicates that the sender is unable to send data due to a\n    closed flow control window.\n\n    The BLOCKED frame is used to provide feedback about the performance of flow\n    control for the purposes of performance tuning and debugging. The BLOCKED\n    frame can be sent by a peer when flow controlled data cannot be sent due to\n    the connection- or stream-level flow control. This frame MUST NOT be sent\n    if there are other reasons preventing data from being sent, either a lack\n    of available data, or the underlying transport being blocked.\n    \"\"\"\n    type = 0x0B\n\n    stream_association = 'both'\n\n    defined_flags = []\n\n    def serialize_body(self):\n        return b''\n\n    def parse_body(self, data):\n        pass\n\n\n# A map of type byte to frame class.\n_FRAME_CLASSES = [\n    DataFrame,\n    HeadersFrame,\n    PriorityFrame,\n    RstStreamFrame,\n    SettingsFrame,\n    PushPromiseFrame,\n    PingFrame,\n    GoAwayFrame,\n    WindowUpdateFrame,\n    ContinuationFrame,\n    AltSvcFrame,\n    BlockedFrame\n]\nFRAMES = {cls.type: cls for cls in _FRAME_CLASSES}\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/packages/rfc3986/LICENSE",
    "content": "Copyright 2014 Ian Cordasco, Rackspace\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/packages/rfc3986/__init__.py",
    "content": "# -*- coding: utf-8 -*-\n# Copyright (c) 2014 Rackspace\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#    http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n# implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"\nrfc3986\n=======\n\nAn implementation of semantics and validations described in RFC 3986. See\nhttp://rfc3986.rtfd.org/ for documentation.\n\n:copyright: (c) 2014 Rackspace\n:license: Apache v2.0, see LICENSE for details\n\"\"\"\n\n__title__ = 'rfc3986'\n__author__ = 'Ian Cordasco'\n__author_email__ = 'ian.cordasco@rackspace.com'\n__license__ = 'Apache v2.0'\n__copyright__ = 'Copyright 2014 Rackspace'\n__version__ = '0.3.0'\n\nfrom .api import (URIReference, uri_reference, is_valid_uri, normalize_uri,\n                  urlparse)\nfrom .parseresult import ParseResult\n\n__all__ = (\n    'ParseResult',\n    'URIReference',\n    'is_valid_uri',\n    'normalize_uri',\n    'uri_reference',\n    'urlparse',\n)\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/packages/rfc3986/api.py",
    "content": "# -*- coding: utf-8 -*-\n# Copyright (c) 2014 Rackspace\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#    http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n# implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\"\"\"\nrfc3986.api\n~~~~~~~~~~~\n\nThis defines the simple API to rfc3986. This module defines 3 functions and\nprovides access to the class ``URIReference``.\n\"\"\"\n\nfrom .uri import URIReference\nfrom .parseresult import ParseResult\n\n\ndef uri_reference(uri, encoding='utf-8'):\n    \"\"\"Parse a URI string into a URIReference.\n\n    This is a convenience function. You could achieve the same end by using\n    ``URIReference.from_string(uri)``.\n\n    :param str uri: The URI which needs to be parsed into a reference.\n    :param str encoding: The encoding of the string provided\n    :returns: A parsed URI\n    :rtype: :class:`URIReference`\n    \"\"\"\n    return URIReference.from_string(uri, encoding)\n\n\ndef is_valid_uri(uri, encoding='utf-8', **kwargs):\n    \"\"\"Determine if the URI given is valid.\n\n    This is a convenience function. You could use either\n    ``uri_reference(uri).is_valid()`` or\n    ``URIReference.from_string(uri).is_valid()`` to achieve the same result.\n\n    :param str uri: The URI to be validated.\n    :param str encoding: The encoding of the string provided\n    :param bool require_scheme: Set to ``True`` if you wish to require the\n        presence of the scheme component.\n    :param bool require_authority: Set to ``True`` if you wish to require the\n        presence of the authority component.\n    :param bool require_path: Set to ``True`` if you wish to require the\n        presence of the path component.\n    :param bool require_query: Set to ``True`` if you wish to require the\n        presence of the query component.\n    :param bool require_fragment: Set to ``True`` if you wish to require the\n        presence of the fragment component.\n    :returns: ``True`` if the URI is valid, ``False`` otherwise.\n    :rtype: bool\n    \"\"\"\n    return URIReference.from_string(uri, encoding).is_valid(**kwargs)\n\n\ndef normalize_uri(uri, encoding='utf-8'):\n    \"\"\"Normalize the given URI.\n\n    This is a convenience function. You could use either\n    ``uri_reference(uri).normalize().unsplit()`` or\n    ``URIReference.from_string(uri).normalize().unsplit()`` instead.\n\n    :param str uri: The URI to be normalized.\n    :param str encoding: The encoding of the string provided\n    :returns: The normalized URI.\n    :rtype: str\n    \"\"\"\n    normalized_reference = URIReference.from_string(uri, encoding).normalize()\n    return normalized_reference.unsplit()\n\n\ndef urlparse(uri, encoding='utf-8'):\n    \"\"\"Parse a given URI and return a ParseResult.\n\n    This is a partial replacement of the standard library's urlparse function.\n\n    :param str uri: The URI to be parsed.\n    :param str encoding: The encoding of the string provided.\n    :returns: A parsed URI\n    :rtype: :class:`~rfc3986.parseresult.ParseResult`\n    \"\"\"\n    return ParseResult.from_string(uri, encoding, strict=False)\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/packages/rfc3986/compat.py",
    "content": "# -*- coding: utf-8 -*-\n# Copyright (c) 2014 Rackspace\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#    http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n# implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\nimport sys\n\n\nif sys.version_info >= (3, 0):\n    str = str  # Python 3.x\n\n\ndef to_str(b, encoding):\n    if hasattr(b, 'decode') and not isinstance(b, str):\n        b = b.decode('utf-8')\n    return b\n\n\ndef to_bytes(s, encoding):\n    if hasattr(s, 'encode') and not isinstance(s, bytes):\n        s = s.encode('utf-8')\n    return s\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/packages/rfc3986/exceptions.py",
    "content": "# -*- coding: utf-8 -*-\nclass RFC3986Exception(Exception):\n    pass\n\n\nclass InvalidAuthority(RFC3986Exception):\n    def __init__(self, authority):\n        super(InvalidAuthority, self).__init__(\n            \"The authority ({0}) is not valid.\".format(authority))\n\n\nclass InvalidPort(RFC3986Exception):\n    def __init__(self, port):\n        super(InvalidPort, self).__init__(\n            'The port (\"{0}\") is not valid.'.format(port))\n\n\nclass ResolutionError(RFC3986Exception):\n    def __init__(self, uri):\n        super(ResolutionError, self).__init__(\n            \"{0} is not an absolute URI.\".format(uri.unsplit()))\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/packages/rfc3986/misc.py",
    "content": "# -*- coding: utf-8 -*-\n# Copyright (c) 2014 Rackspace\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#    http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n# implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\"\"\"\nrfc3986.misc\n~~~~~~~~~~~~\n\nThis module contains important constants, patterns, and compiled regular\nexpressions for parsing and validating URIs and their components.\n\"\"\"\n\nimport re\n\n# These are enumerated for the named tuple used as a superclass of\n# URIReference\nURI_COMPONENTS = ['scheme', 'authority', 'path', 'query', 'fragment']\n\nimportant_characters = {\n    'generic_delimiters': \":/?#[]@\",\n    'sub_delimiters': \"!$&'()*+,;=\",\n    # We need to escape the '*' in this case\n    're_sub_delimiters': \"!$&'()\\\\*+,;=\",\n    'unreserved_chars': ('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'\n                         '0123456789._~-'),\n    # We need to escape the '-' in this case:\n    're_unreserved': 'A-Za-z0-9._~\\\\-',\n    }\n# For details about delimiters and reserved characters, see:\n# http://tools.ietf.org/html/rfc3986#section-2.2\nGENERIC_DELIMITERS = set(important_characters['generic_delimiters'])\nSUB_DELIMITERS = set(important_characters['sub_delimiters'])\nRESERVED_CHARS = GENERIC_DELIMITERS.union(SUB_DELIMITERS)\n# For details about unreserved characters, see:\n# http://tools.ietf.org/html/rfc3986#section-2.3\nUNRESERVED_CHARS = set(important_characters['unreserved_chars'])\nNON_PCT_ENCODED = RESERVED_CHARS.union(UNRESERVED_CHARS).union('%')\n\n# Extracted from http://tools.ietf.org/html/rfc3986#appendix-B\ncomponent_pattern_dict = {\n    'scheme': '[^:/?#]+',\n    'authority': '[^/?#]*',\n    'path': '[^?#]*',\n    'query': '[^#]*',\n    'fragment': '.*',\n    }\n\n# See http://tools.ietf.org/html/rfc3986#appendix-B\n# In this case, we name each of the important matches so we can use\n# SRE_Match#groupdict to parse the values out if we so choose. This is also\n# modified to ignore other matches that are not important to the parsing of\n# the reference so we can also simply use SRE_Match#groups.\nexpression = ('(?:(?P<scheme>{scheme}):)?(?://(?P<authority>{authority}))?'\n              '(?P<path>{path})(?:\\\\?(?P<query>{query}))?'\n              '(?:#(?P<fragment>{fragment}))?'\n              ).format(**component_pattern_dict)\n\nURI_MATCHER = re.compile(expression)\n\n# #########################\n# Authority Matcher Section\n# #########################\n\n# Host patterns, see: http://tools.ietf.org/html/rfc3986#section-3.2.2\n# The pattern for a regular name, e.g.,  www.google.com, api.github.com\nreg_name = '(({0})*|[{1}]*)'.format(\n    '%[0-9A-Fa-f]{2}',\n    important_characters['re_sub_delimiters'] +\n    important_characters['re_unreserved']\n    )\n# The pattern for an IPv4 address, e.g., 192.168.255.255, 127.0.0.1,\nipv4 = '(\\\\d{1,3}.){3}\\\\d{1,3}'\n# Hexadecimal characters used in each piece of an IPv6 address\nhexdig = '[0-9A-Fa-f]{1,4}'\n# Least-significant 32 bits of an IPv6 address\nls32 = '({hex}:{hex}|{ipv4})'.format(hex=hexdig, ipv4=ipv4)\n# Substitutions into the following patterns for IPv6 patterns defined\n# http://tools.ietf.org/html/rfc3986#page-20\nsubs = {'hex': hexdig, 'ls32': ls32}\n\n# Below: h16 = hexdig, see: https://tools.ietf.org/html/rfc5234 for details\n# about ABNF (Augmented Backus-Naur Form) use in the comments\nvariations = [\n    #                            6( h16 \":\" ) ls32\n    '(%(hex)s:){6}%(ls32)s' % subs,\n    #                       \"::\" 5( h16 \":\" ) ls32\n    '::(%(hex)s:){5}%(ls32)s' % subs,\n    # [               h16 ] \"::\" 4( h16 \":\" ) ls32\n    '(%(hex)s)?::(%(hex)s:){4}%(ls32)s' % subs,\n    # [ *1( h16 \":\" ) h16 ] \"::\" 3( h16 \":\" ) ls32\n    '((%(hex)s:)?%(hex)s)?::(%(hex)s:){3}%(ls32)s' % subs,\n    # [ *2( h16 \":\" ) h16 ] \"::\" 2( h16 \":\" ) ls32\n    '((%(hex)s:){0,2}%(hex)s)?::(%(hex)s:){2}%(ls32)s' % subs,\n    # [ *3( h16 \":\" ) h16 ] \"::\"    h16 \":\"   ls32\n    '((%(hex)s:){0,3}%(hex)s)?::%(hex)s:%(ls32)s' % subs,\n    # [ *4( h16 \":\" ) h16 ] \"::\"              ls32\n    '((%(hex)s:){0,4}%(hex)s)?::%(ls32)s' % subs,\n    # [ *5( h16 \":\" ) h16 ] \"::\"              h16\n    '((%(hex)s:){0,5}%(hex)s)?::%(hex)s' % subs,\n    # [ *6( h16 \":\" ) h16 ] \"::\"\n    '((%(hex)s:){0,6}%(hex)s)?::' % subs,\n    ]\n\nipv6 = '(({0})|({1})|({2})|({3})|({4})|({5})|({6})|({7}))'.format(*variations)\n\nipv_future = 'v[0-9A-Fa-f]+.[%s]+' % (\n    important_characters['re_unreserved'] +\n    important_characters['re_sub_delimiters'] +\n    ':')\n\nip_literal = '\\\\[({0}|{1})\\\\]'.format(ipv6, ipv_future)\n\n# Pattern for matching the host piece of the authority\nHOST_PATTERN = '({0}|{1}|{2})'.format(reg_name, ipv4, ip_literal)\n\nSUBAUTHORITY_MATCHER = re.compile((\n    '^(?:(?P<userinfo>[A-Za-z0-9_.~\\\\-%:]+)@)?'  # userinfo\n    '(?P<host>{0}?)'  # host\n    ':?(?P<port>\\\\d+)?$'  # port\n    ).format(HOST_PATTERN))\n\nIPv4_MATCHER = re.compile('^' + ipv4 + '$')\n\n\n# ####################\n# Path Matcher Section\n# ####################\n\n# See http://tools.ietf.org/html/rfc3986#section-3.3 for more information\n# about the path patterns defined below.\n\n# Percent encoded character values\npct_encoded = '%[A-Fa-f0-9]{2}'\npchar = ('([' + important_characters['re_unreserved']\n         + important_characters['re_sub_delimiters']\n         + ':@]|%s)' % pct_encoded)\nsegments = {\n    'segment': pchar + '*',\n    # Non-zero length segment\n    'segment-nz': pchar + '+',\n    # Non-zero length segment without \":\"\n    'segment-nz-nc': pchar.replace(':', '') + '+'\n    }\n\n# Path types taken from Section 3.3 (linked above)\npath_empty = '^$'\npath_rootless = '%(segment-nz)s(/%(segment)s)*' % segments\npath_noscheme = '%(segment-nz-nc)s(/%(segment)s)*' % segments\npath_absolute = '/(%s)?' % path_rootless\npath_abempty = '(/%(segment)s)*' % segments\n\n# Matcher used to validate path components\nPATH_MATCHER = re.compile('^(%s|%s|%s|%s|%s)$' % (\n    path_abempty, path_absolute, path_noscheme, path_rootless, path_empty\n    ))\n\n\n# ##################################\n# Query and Fragment Matcher Section\n# ##################################\n\nQUERY_MATCHER = re.compile(\n    '^([/?:@' + important_characters['re_unreserved']\n    + important_characters['re_sub_delimiters']\n    + ']|%s)*$' % pct_encoded)\n\nFRAGMENT_MATCHER = QUERY_MATCHER\n\n# Scheme validation, see: http://tools.ietf.org/html/rfc3986#section-3.1\nSCHEME_MATCHER = re.compile('^[A-Za-z][A-Za-z0-9+.\\\\-]*$')\n\n# Relative reference matcher\n\n# See http://tools.ietf.org/html/rfc3986#section-4.2 for details\nrelative_part = '(//%s%s|%s|%s|%s)' % (\n    component_pattern_dict['authority'], path_abempty, path_absolute,\n    path_noscheme, path_empty\n    )\n\nRELATIVE_REF_MATCHER = re.compile('^%s(\\\\?%s)?(#%s)?$' % (\n    relative_part, QUERY_MATCHER.pattern, FRAGMENT_MATCHER.pattern\n    ))\n\n# See http://tools.ietf.org/html/rfc3986#section-3 for definition\nhier_part = '(//%s%s|%s|%s|%s)' % (\n    component_pattern_dict['authority'], path_abempty, path_absolute,\n    path_rootless, path_empty\n    )\n\n# See http://tools.ietf.org/html/rfc3986#section-4.3\nABSOLUTE_URI_MATCHER = re.compile('^%s:%s(\\\\?%s)?$' % (\n    component_pattern_dict['scheme'], hier_part, QUERY_MATCHER.pattern[1:-1]\n    ))\n\n\n# Path merger as defined in http://tools.ietf.org/html/rfc3986#section-5.2.3\ndef merge_paths(base_uri, relative_path):\n    \"\"\"Merge a base URI's path with a relative URI's path.\"\"\"\n    if base_uri.path is None and base_uri.authority is not None:\n        return '/' + relative_path\n    else:\n        path = base_uri.path or ''\n        index = path.rfind('/')\n        return path[:index] + '/' + relative_path\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/packages/rfc3986/normalizers.py",
    "content": "# -*- coding: utf-8 -*-\n# Copyright (c) 2014 Rackspace\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#    http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n# implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\nimport re\n\nfrom .compat import to_bytes\nfrom .misc import NON_PCT_ENCODED\n\n\ndef normalize_scheme(scheme):\n    return scheme.lower()\n\n\ndef normalize_authority(authority):\n    userinfo, host, port = authority\n    result = ''\n    if userinfo:\n        result += normalize_percent_characters(userinfo) + '@'\n    if host:\n        result += host.lower()\n    if port:\n        result += ':' + port\n    return result\n\n\ndef normalize_path(path):\n    if not path:\n        return path\n\n    path = normalize_percent_characters(path)\n    return remove_dot_segments(path)\n\n\ndef normalize_query(query):\n    return normalize_percent_characters(query)\n\n\ndef normalize_fragment(fragment):\n    return normalize_percent_characters(fragment)\n\n\nPERCENT_MATCHER = re.compile('%[A-Fa-f0-9]{2}')\n\n\ndef normalize_percent_characters(s):\n    \"\"\"All percent characters should be upper-cased.\n\n    For example, ``\"%3afoo%DF%ab\"`` should be turned into ``\"%3Afoo%DF%AB\"``.\n    \"\"\"\n    matches = set(PERCENT_MATCHER.findall(s))\n    for m in matches:\n        if not m.isupper():\n            s = s.replace(m, m.upper())\n    return s\n\n\ndef remove_dot_segments(s):\n    # See http://tools.ietf.org/html/rfc3986#section-5.2.4 for pseudo-code\n    segments = s.split('/')  # Turn the path into a list of segments\n    output = []  # Initialize the variable to use to store output\n\n    for segment in segments:\n        # '.' is the current directory, so ignore it, it is superfluous\n        if segment == '.':\n            continue\n        # Anything other than '..', should be appended to the output\n        elif segment != '..':\n            output.append(segment)\n        # In this case segment == '..', if we can, we should pop the last\n        # element\n        elif output:\n            output.pop()\n\n    # If the path starts with '/' and the output is empty or the first string\n    # is non-empty\n    if s.startswith('/') and (not output or output[0]):\n        output.insert(0, '')\n\n    # If the path starts with '/.' or '/..' ensure we add one more empty\n    # string to add a trailing '/'\n    if s.endswith(('/.', '/..')):\n        output.append('')\n\n    return '/'.join(output)\n\n\ndef encode_component(uri_component, encoding):\n    if uri_component is None:\n        return uri_component\n\n    uri_bytes = to_bytes(uri_component, encoding)\n\n    encoded_uri = bytearray()\n\n    for i in range(0, len(uri_bytes)):\n        # Will return a single character bytestring on both Python 2 & 3\n        byte = uri_bytes[i:i+1]\n        byte_ord = ord(byte)\n        if byte_ord < 128 and byte.decode() in NON_PCT_ENCODED:\n            encoded_uri.extend(byte)\n            continue\n        encoded_uri.extend('%{0:02x}'.format(byte_ord).encode())\n\n    return encoded_uri.decode(encoding)\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/packages/rfc3986/parseresult.py",
    "content": "# -*- coding: utf-8 -*-\n# Copyright (c) 2015 Ian Cordasco\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#    http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n# implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\nfrom collections import namedtuple\n\nfrom . import compat\nfrom . import exceptions\nfrom . import normalizers\nfrom . import uri\n\n__all__ = ('ParseResult', 'ParseResultBytes')\n\nPARSED_COMPONENTS = ('scheme', 'userinfo', 'host', 'port', 'path', 'query',\n                     'fragment')\n\n\nclass ParseResultMixin(object):\n    def _generate_authority(self, attributes):\n        # I swear I did not align the comparisons below. That's just how they\n        # happened to align based on pep8 and attribute lengths.\n        userinfo, host, port = (attributes[p]\n                                for p in ('userinfo', 'host', 'port'))\n        if (self.userinfo != userinfo or\n                self.host != host or\n                self.port != port):\n            if port:\n                port = '{0}'.format(port)\n            return normalizers.normalize_authority(\n                (compat.to_str(userinfo, self.encoding),\n                 compat.to_str(host, self.encoding),\n                 port)\n            )\n        return self.authority\n\n    def geturl(self):\n        \"\"\"Standard library shim to the unsplit method.\"\"\"\n        return self.unsplit()\n\n    @property\n    def hostname(self):\n        \"\"\"Standard library shim for the host portion of the URI.\"\"\"\n        return self.host\n\n    @property\n    def netloc(self):\n        \"\"\"Standard library shim for the authority portion of the URI.\"\"\"\n        return self.authority\n\n    @property\n    def params(self):\n        \"\"\"Standard library shim for the query portion of the URI.\"\"\"\n        return self.query\n\n\nclass ParseResult(namedtuple('ParseResult', PARSED_COMPONENTS),\n                  ParseResultMixin):\n    slots = ()\n\n    def __new__(cls, scheme, userinfo, host, port, path, query, fragment,\n                uri_ref, encoding='utf-8'):\n        parse_result = super(ParseResult, cls).__new__(\n            cls,\n            scheme or None,\n            userinfo or None,\n            host,\n            port or None,\n            path or None,\n            query or None,\n            fragment or None)\n        parse_result.encoding = encoding\n        parse_result.reference = uri_ref\n        return parse_result\n\n    @classmethod\n    def from_string(cls, uri_string, encoding='utf-8', strict=True):\n        \"\"\"Parse a URI from the given unicode URI string.\n\n        :param str uri_string: Unicode URI to be parsed into a reference.\n        :param str encoding: The encoding of the string provided\n        :param bool strict: Parse strictly according to :rfc:`3986` if True.\n            If False, parse similarly to the standard library's urlparse\n            function.\n        :returns: :class:`ParseResult` or subclass thereof\n        \"\"\"\n        reference = uri.URIReference.from_string(uri_string, encoding)\n        try:\n            subauthority = reference.authority_info()\n        except exceptions.InvalidAuthority:\n            if strict:\n                raise\n            userinfo, host, port = split_authority(reference.authority)\n        else:\n            # Thanks to Richard Barrell for this idea:\n            # https://twitter.com/0x2ba22e11/status/617338811975139328\n            userinfo, host, port = (subauthority.get(p)\n                                    for p in ('userinfo', 'host', 'port'))\n\n        if port:\n            try:\n                port = int(port)\n            except ValueError:\n                raise exceptions.InvalidPort(port)\n\n        return cls(scheme=reference.scheme,\n                   userinfo=userinfo,\n                   host=host,\n                   port=port,\n                   path=reference.path,\n                   query=reference.query,\n                   fragment=reference.fragment,\n                   uri_ref=reference,\n                   encoding=encoding)\n\n    @property\n    def authority(self):\n        \"\"\"Normalized authority generated from the subauthority parts.\"\"\"\n        return self.reference.authority\n\n    def copy_with(self, scheme=None, userinfo=None, host=None, port=None,\n                  path=None, query=None, fragment=None):\n        attributes = list(zip(PARSED_COMPONENTS,\n                         (scheme, userinfo, host, port, path, query, fragment)))\n        attrs_dict = {}\n        for name, value in attributes:\n            if value is None:\n                value = getattr(self, name)\n            attrs_dict[name] = value\n        authority = self._generate_authority(attrs_dict)\n        ref = self.reference.copy_with(scheme=attrs_dict['scheme'],\n                                       authority=authority,\n                                       path=attrs_dict['path'],\n                                       query=attrs_dict['query'],\n                                       fragment=attrs_dict['fragment'])\n        return ParseResult(uri_ref=ref, encoding=self.encoding, **attrs_dict)\n\n    def encode(self, encoding=None):\n        encoding = encoding or self.encoding\n        attrs = dict(\n            list(zip(PARSED_COMPONENTS,\n                (attr.encode(encoding) if hasattr(attr, 'encode') else attr\n                 for attr in self))))\n        return ParseResultBytes(\n            uri_ref=self.reference,\n            encoding=encoding,\n            **attrs\n        )\n\n    def unsplit(self, use_idna=False):\n        \"\"\"Create a URI string from the components.\n\n        :returns: The parsed URI reconstituted as a string.\n        :rtype: str\n        \"\"\"\n        parse_result = self\n        if use_idna and self.host:\n            hostbytes = self.host.encode('idna')\n            host = hostbytes.decode(self.encoding)\n            parse_result = self.copy_with(host=host)\n        return parse_result.reference.unsplit()\n\n\nclass ParseResultBytes(namedtuple('ParseResultBytes', PARSED_COMPONENTS),\n                       ParseResultMixin):\n    def __new__(cls, scheme, userinfo, host, port, path, query, fragment,\n                uri_ref, encoding='utf-8'):\n        parse_result = super(ParseResultBytes, cls).__new__(\n            cls,\n            scheme or None,\n            userinfo or None,\n            host,\n            port or None,\n            path or None,\n            query or None,\n            fragment or None)\n        parse_result.encoding = encoding\n        parse_result.reference = uri_ref\n        return parse_result\n\n    @classmethod\n    def from_string(cls, uri_string, encoding='utf-8', strict=True):\n        \"\"\"Parse a URI from the given unicode URI string.\n\n        :param str uri_string: Unicode URI to be parsed into a reference.\n        :param str encoding: The encoding of the string provided\n        :param bool strict: Parse strictly according to :rfc:`3986` if True.\n            If False, parse similarly to the standard library's urlparse\n            function.\n        :returns: :class:`ParseResultBytes` or subclass thereof\n        \"\"\"\n        reference = uri.URIReference.from_string(uri_string, encoding)\n        try:\n            subauthority = reference.authority_info()\n        except exceptions.InvalidAuthority:\n            if strict:\n                raise\n            userinfo, host, port = split_authority(reference.authority)\n        else:\n            # Thanks to Richard Barrell for this idea:\n            # https://twitter.com/0x2ba22e11/status/617338811975139328\n            userinfo, host, port = (subauthority.get(p)\n                                    for p in ('userinfo', 'host', 'port'))\n\n        if port:\n            try:\n                port = int(port)\n            except ValueError:\n                raise exceptions.InvalidPort(port)\n\n        to_bytes = compat.to_bytes\n        return cls(scheme=to_bytes(reference.scheme, encoding),\n                   userinfo=to_bytes(userinfo, encoding),\n                   host=to_bytes(host, encoding),\n                   port=port,\n                   path=to_bytes(reference.path, encoding),\n                   query=to_bytes(reference.query, encoding),\n                   fragment=to_bytes(reference.fragment, encoding),\n                   uri_ref=reference,\n                   encoding=encoding)\n\n    @property\n    def authority(self):\n        \"\"\"Normalized authority generated from the subauthority parts.\"\"\"\n        return self.reference.authority.encode(self.encoding)\n\n    def copy_with(self, scheme=None, userinfo=None, host=None, port=None,\n                  path=None, query=None, fragment=None):\n        attributes = list(zip(PARSED_COMPONENTS,\n                         (scheme, userinfo, host, port, path, query, fragment)))\n        attrs_dict = {}\n        for name, value in attributes:\n            if value is None:\n                value = getattr(self, name)\n            if not isinstance(value, bytes) and hasattr(value, 'encode'):\n                value = value.encode(self.encoding)\n            attrs_dict[name] = value\n        authority = self._generate_authority(attrs_dict)\n        to_str = compat.to_str\n        ref = self.reference.copy_with(\n            scheme=to_str(attrs_dict['scheme'], self.encoding),\n            authority=authority,\n            path=to_str(attrs_dict['path'], self.encoding),\n            query=to_str(attrs_dict['query'], self.encoding),\n            fragment=to_str(attrs_dict['fragment'], self.encoding)\n        )\n        return ParseResultBytes(\n            uri_ref=ref,\n            encoding=self.encoding,\n            **attrs_dict\n        )\n\n    def unsplit(self, use_idna=False):\n        \"\"\"Create a URI bytes object from the components.\n\n        :returns: The parsed URI reconstituted as a string.\n        :rtype: bytes\n        \"\"\"\n        parse_result = self\n        if use_idna and self.host:\n            # self.host is bytes, to encode to idna, we need to decode it\n            # first\n            host = self.host.decode(self.encoding)\n            hostbytes = host.encode('idna')\n            parse_result = self.copy_with(host=hostbytes)\n        uri = parse_result.reference.unsplit()\n        return uri.encode(self.encoding)\n\n\ndef split_authority(authority):\n    # Initialize our expected return values\n    userinfo = host = port = None\n    # Initialize an extra var we may need to use\n    extra_host = None\n    # Set-up rest in case there is no userinfo portion\n    rest = authority\n\n    if '@' in authority:\n        userinfo, rest = authority.rsplit('@', 1)\n\n    # Handle IPv6 host addresses\n    if rest.startswith('['):\n        host, rest = rest.split(']', 1)\n        host += ']'\n\n    if ':' in rest:\n        extra_host, port = rest.split(':', 1)\n    elif not host and rest:\n        host = rest\n\n    if extra_host and not host:\n        host = extra_host\n\n    return userinfo, host, port\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/packages/rfc3986/uri.py",
    "content": "# -*- coding: utf-8 -*-\n# Copyright (c) 2014 Rackspace\n# Copyright (c) 2015 Ian Cordasco\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#    http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n# implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\nfrom collections import namedtuple\n\nfrom .compat import to_str\nfrom .exceptions import InvalidAuthority, ResolutionError\nfrom .misc import (\n    ABSOLUTE_URI_MATCHER, FRAGMENT_MATCHER, IPv4_MATCHER, PATH_MATCHER,\n    QUERY_MATCHER, SCHEME_MATCHER, SUBAUTHORITY_MATCHER, URI_MATCHER,\n    URI_COMPONENTS, merge_paths\n    )\nfrom .normalizers import (\n    encode_component, normalize_scheme, normalize_authority, normalize_path,\n    normalize_query, normalize_fragment\n    )\n\n\nclass URIReference(namedtuple('URIReference', URI_COMPONENTS)):\n    slots = ()\n\n    def __new__(cls, scheme, authority, path, query, fragment,\n                encoding='utf-8'):\n        ref = super(URIReference, cls).__new__(\n            cls,\n            scheme or None,\n            authority or None,\n            path or None,\n            query or None,\n            fragment or None)\n        ref.encoding = encoding\n        return ref\n\n    def __eq__(self, other):\n        other_ref = other\n        if isinstance(other, tuple):\n            other_ref = URIReference(*other)\n        elif not isinstance(other, URIReference):\n            try:\n                other_ref = URIReference.from_string(other)\n            except TypeError:\n                raise TypeError(\n                    'Unable to compare URIReference() to {0}()'.format(\n                        type(other).__name__))\n\n        # See http://tools.ietf.org/html/rfc3986#section-6.2\n        naive_equality = tuple(self) == tuple(other_ref)\n        return naive_equality or self.normalized_equality(other_ref)\n\n    @classmethod\n    def from_string(cls, uri_string, encoding='utf-8'):\n        \"\"\"Parse a URI reference from the given unicode URI string.\n\n        :param str uri_string: Unicode URI to be parsed into a reference.\n        :param str encoding: The encoding of the string provided\n        :returns: :class:`URIReference` or subclass thereof\n        \"\"\"\n        uri_string = to_str(uri_string, encoding)\n\n        split_uri = URI_MATCHER.match(uri_string).groupdict()\n        return cls(split_uri['scheme'], split_uri['authority'],\n                   encode_component(split_uri['path'], encoding),\n                   encode_component(split_uri['query'], encoding),\n                   encode_component(split_uri['fragment'], encoding), encoding)\n\n    def authority_info(self):\n        \"\"\"Returns a dictionary with the ``userinfo``, ``host``, and ``port``.\n\n        If the authority is not valid, it will raise a ``InvalidAuthority``\n        Exception.\n\n        :returns:\n            ``{'userinfo': 'username:password', 'host': 'www.example.com',\n            'port': '80'}``\n        :rtype: dict\n        :raises InvalidAuthority: If the authority is not ``None`` and can not\n            be parsed.\n        \"\"\"\n        if not self.authority:\n            return {'userinfo': None, 'host': None, 'port': None}\n\n        match = SUBAUTHORITY_MATCHER.match(self.authority)\n\n        if match is None:\n            # In this case, we have an authority that was parsed from the URI\n            # Reference, but it cannot be further parsed by our\n            # SUBAUTHORITY_MATCHER. In this case it must not be a valid\n            # authority.\n            raise InvalidAuthority(self.authority.encode(self.encoding))\n\n        # We had a match, now let's ensure that it is actually a valid host\n        # address if it is IPv4\n        matches = match.groupdict()\n        host = matches.get('host')\n\n        if (host and IPv4_MATCHER.match(host) and not\n                valid_ipv4_host_address(host)):\n            # If we have a host, it appears to be IPv4 and it does not have\n            # valid bytes, it is an InvalidAuthority.\n            raise InvalidAuthority(self.authority.encode(self.encoding))\n\n        return matches\n\n    @property\n    def host(self):\n        \"\"\"If present, a string representing the host.\"\"\"\n        try:\n            authority = self.authority_info()\n        except InvalidAuthority:\n            return None\n        return authority['host']\n\n    @property\n    def port(self):\n        \"\"\"If present, the port (as a string) extracted from the authority.\"\"\"\n        try:\n            authority = self.authority_info()\n        except InvalidAuthority:\n            return None\n        return authority['port']\n\n    @property\n    def userinfo(self):\n        \"\"\"If present, the userinfo extracted from the authority.\"\"\"\n        try:\n            authority = self.authority_info()\n        except InvalidAuthority:\n            return None\n        return authority['userinfo']\n\n    def is_absolute(self):\n        \"\"\"Determine if this URI Reference is an absolute URI.\n\n        See http://tools.ietf.org/html/rfc3986#section-4.3 for explanation.\n\n        :returns: ``True`` if it is an absolute URI, ``False`` otherwise.\n        :rtype: bool\n        \"\"\"\n        return bool(ABSOLUTE_URI_MATCHER.match(self.unsplit()))\n\n    def is_valid(self, **kwargs):\n        \"\"\"Determines if the URI is valid.\n\n        :param bool require_scheme: Set to ``True`` if you wish to require the\n            presence of the scheme component.\n        :param bool require_authority: Set to ``True`` if you wish to require\n            the presence of the authority component.\n        :param bool require_path: Set to ``True`` if you wish to require the\n            presence of the path component.\n        :param bool require_query: Set to ``True`` if you wish to require the\n            presence of the query component.\n        :param bool require_fragment: Set to ``True`` if you wish to require\n            the presence of the fragment component.\n        :returns: ``True`` if the URI is valid. ``False`` otherwise.\n        :rtype: bool\n        \"\"\"\n        validators = [\n            (self.scheme_is_valid, kwargs.get('require_scheme', False)),\n            (self.authority_is_valid, kwargs.get('require_authority', False)),\n            (self.path_is_valid, kwargs.get('require_path', False)),\n            (self.query_is_valid, kwargs.get('require_query', False)),\n            (self.fragment_is_valid, kwargs.get('require_fragment', False)),\n            ]\n        return all(v(r) for v, r in validators)\n\n    def _is_valid(self, value, matcher, require):\n        if require:\n            return (value is not None\n                    and matcher.match(value))\n\n        # require is False and value is not None\n        return value is None or matcher.match(value)\n\n    def authority_is_valid(self, require=False):\n        \"\"\"Determines if the authority component is valid.\n\n        :param str require: Set to ``True`` to require the presence of this\n            component.\n        :returns: ``True`` if the authority is valid. ``False`` otherwise.\n        :rtype: bool\n        \"\"\"\n        try:\n            self.authority_info()\n        except InvalidAuthority:\n            return False\n\n        is_valid = self._is_valid(self.authority,\n                                  SUBAUTHORITY_MATCHER,\n                                  require)\n\n        # Ensure that IPv4 addresses have valid bytes\n        if is_valid and self.host and IPv4_MATCHER.match(self.host):\n            return valid_ipv4_host_address(self.host)\n\n        # Perhaps the host didn't exist or if it did, it wasn't an IPv4-like\n        # address. In either case, we want to rely on the `_is_valid` check,\n        # so let's return that.\n        return is_valid\n\n    def scheme_is_valid(self, require=False):\n        \"\"\"Determines if the scheme component is valid.\n\n        :param str require: Set to ``True`` to require the presence of this\n            component.\n        :returns: ``True`` if the scheme is valid. ``False`` otherwise.\n        :rtype: bool\n        \"\"\"\n        return self._is_valid(self.scheme, SCHEME_MATCHER, require)\n\n    def path_is_valid(self, require=False):\n        \"\"\"Determines if the path component is valid.\n\n        :param str require: Set to ``True`` to require the presence of this\n            component.\n        :returns: ``True`` if the path is valid. ``False`` otherwise.\n        :rtype: bool\n        \"\"\"\n        return self._is_valid(self.path, PATH_MATCHER, require)\n\n    def query_is_valid(self, require=False):\n        \"\"\"Determines if the query component is valid.\n\n        :param str require: Set to ``True`` to require the presence of this\n            component.\n        :returns: ``True`` if the query is valid. ``False`` otherwise.\n        :rtype: bool\n        \"\"\"\n        return self._is_valid(self.query, QUERY_MATCHER, require)\n\n    def fragment_is_valid(self, require=False):\n        \"\"\"Determines if the fragment component is valid.\n\n        :param str require: Set to ``True`` to require the presence of this\n            component.\n        :returns: ``True`` if the fragment is valid. ``False`` otherwise.\n        :rtype: bool\n        \"\"\"\n        return self._is_valid(self.fragment, FRAGMENT_MATCHER, require)\n\n    def normalize(self):\n        \"\"\"Normalize this reference as described in Section 6.2.2\n\n        This is not an in-place normalization. Instead this creates a new\n        URIReference.\n\n        :returns: A new reference object with normalized components.\n        :rtype: URIReference\n        \"\"\"\n        # See http://tools.ietf.org/html/rfc3986#section-6.2.2 for logic in\n        # this method.\n        return URIReference(normalize_scheme(self.scheme or ''),\n                            normalize_authority(\n                                (self.userinfo, self.host, self.port)),\n                            normalize_path(self.path or ''),\n                            normalize_query(self.query or ''),\n                            normalize_fragment(self.fragment or ''))\n\n    def normalized_equality(self, other_ref):\n        \"\"\"Compare this URIReference to another URIReference.\n\n        :param URIReference other_ref: (required), The reference with which\n            we're comparing.\n        :returns: ``True`` if the references are equal, ``False`` otherwise.\n        :rtype: bool\n        \"\"\"\n        return tuple(self.normalize()) == tuple(other_ref.normalize())\n\n    def resolve_with(self, base_uri, strict=False):\n        \"\"\"Use an absolute URI Reference to resolve this relative reference.\n\n        Assuming this is a relative reference that you would like to resolve,\n        use the provided base URI to resolve it.\n\n        See http://tools.ietf.org/html/rfc3986#section-5 for more information.\n\n        :param base_uri: Either a string or URIReference. It must be an\n            absolute URI or it will raise an exception.\n        :returns: A new URIReference which is the result of resolving this\n            reference using ``base_uri``.\n        :rtype: :class:`URIReference`\n        :raises ResolutionError: If the ``base_uri`` is not an absolute URI.\n        \"\"\"\n        if not isinstance(base_uri, URIReference):\n            base_uri = URIReference.from_string(base_uri)\n\n        if not base_uri.is_absolute():\n            raise ResolutionError(base_uri)\n\n        # This is optional per\n        # http://tools.ietf.org/html/rfc3986#section-5.2.1\n        base_uri = base_uri.normalize()\n\n        # The reference we're resolving\n        resolving = self\n\n        if not strict and resolving.scheme == base_uri.scheme:\n            resolving = resolving.copy_with(scheme=None)\n\n        # http://tools.ietf.org/html/rfc3986#page-32\n        if resolving.scheme is not None:\n            target = resolving.copy_with(path=normalize_path(resolving.path))\n        else:\n            if resolving.authority is not None:\n                target = resolving.copy_with(\n                    scheme=base_uri.scheme,\n                    path=normalize_path(resolving.path)\n                )\n            else:\n                if resolving.path is None:\n                    if resolving.query is not None:\n                        query = resolving.query\n                    else:\n                        query = base_uri.query\n                    target = resolving.copy_with(\n                        scheme=base_uri.scheme,\n                        authority=base_uri.authority,\n                        path=base_uri.path,\n                        query=query\n                    )\n                else:\n                    if resolving.path.startswith('/'):\n                        path = normalize_path(resolving.path)\n                    else:\n                        path = normalize_path(\n                            merge_paths(base_uri, resolving.path)\n                        )\n                    target = resolving.copy_with(\n                        scheme=base_uri.scheme,\n                        authority=base_uri.authority,\n                        path=path,\n                        query=resolving.query\n                    )\n        return target\n\n    def unsplit(self):\n        \"\"\"Create a URI string from the components.\n\n        :returns: The URI Reference reconstituted as a string.\n        :rtype: str\n        \"\"\"\n        # See http://tools.ietf.org/html/rfc3986#section-5.3\n        result_list = []\n        if self.scheme:\n            result_list.extend([self.scheme, ':'])\n        if self.authority:\n            result_list.extend(['//', self.authority])\n        if self.path:\n            result_list.append(self.path)\n        if self.query:\n            result_list.extend(['?', self.query])\n        if self.fragment:\n            result_list.extend(['#', self.fragment])\n        return ''.join(result_list)\n\n    def copy_with(self, scheme=None, authority=None, path=None, query=None,\n                  fragment=None):\n        attributes = {\n            'scheme': scheme,\n            'authority': authority,\n            'path': path,\n            'query': query,\n            'fragment': fragment,\n        }\n        for key, value in list(attributes.items()):\n            if value is None:\n                del attributes[key]\n        return self._replace(**attributes)\n\n\ndef valid_ipv4_host_address(host):\n    # If the host exists, and it might be IPv4, check each byte in the\n    # address.\n    return all([0 <= int(byte, base=10) <= 255 for byte in host.split('.')])\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/ssl_compat.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhyper/ssl_compat\n~~~~~~~~~\n\nShoves pyOpenSSL into an API that looks like the standard Python 3.x ssl module.\n\nCurrently exposes exactly those attributes, classes, and methods that we\nactually use in hyper (all method signatures are complete, however). May be\nexpanded to something more general-purpose in the future.\n\"\"\"\ntry:\n    import io as BytesIO\nexcept ImportError:\n    from io import BytesIO\nimport errno\nimport socket\nimport time\nimport re\n\nfrom OpenSSL import SSL as ossl\nfrom service_identity.pyopenssl import verify_hostname as _verify\n\nCERT_NONE = ossl.VERIFY_NONE\nCERT_REQUIRED = ossl.VERIFY_PEER | ossl.VERIFY_FAIL_IF_NO_PEER_CERT\n\n_OPENSSL_ATTRS = dict(\n    OP_NO_COMPRESSION='OP_NO_COMPRESSION',\n    PROTOCOL_TLSv1_2='TLSv1_2_METHOD',\n    PROTOCOL_SSLv23='SSLv23_METHOD',\n)\n\nfor external, internal in list(_OPENSSL_ATTRS.items()):\n    value = getattr(ossl, internal, None)\n    if value:\n        locals()[external] = value\n\nOP_ALL = 0\nfor bit in [31] + list(range(10)): # TODO figure out the names of these other flags\n    OP_ALL |= 1 << bit\n\nHAS_NPN = True\n\ndef _proxy(method):\n    return lambda self, *args, **kwargs: getattr(self._conn, method)(*args, **kwargs)\n\n# TODO missing some attributes\nclass SSLError(OSError):\n    pass\n\nclass CertificateError(SSLError):\n    pass\n\n\ndef verify_hostname(ssl_sock, server_hostname):\n    \"\"\"\n    A method nearly compatible with the stdlib's match_hostname.\n    \"\"\"\n    if isinstance(server_hostname, bytes):\n        server_hostname = server_hostname.decode('ascii')\n    return _verify(ssl_sock._conn, server_hostname)\n\n\nclass SSLSocket(object):\n    SSL_TIMEOUT = 3\n    SSL_RETRY = .01\n\n    def __init__(self, conn, server_side, do_handshake_on_connect,\n                 suppress_ragged_eofs, server_hostname, check_hostname):\n        self._conn = conn\n        self._do_handshake_on_connect = do_handshake_on_connect\n        self._suppress_ragged_eofs = suppress_ragged_eofs\n        self._check_hostname = check_hostname\n\n        if server_side:\n            self._conn.set_accept_state()\n        else:\n            if server_hostname:\n                self._conn.set_tlsext_host_name(server_hostname.encode('utf-8'))\n                self._server_hostname = server_hostname\n            self._conn.set_connect_state() # FIXME does this override do_handshake_on_connect=False?\n\n        if self.connected and self._do_handshake_on_connect:\n            self.do_handshake()\n\n    @property\n    def connected(self):\n        try:\n            self._conn.getpeername()\n        except socket.error as e:\n            if e.errno != errno.ENOTCONN:\n                # It's an exception other than the one we expected if we're not\n                # connected.\n                raise\n            return False\n        return True\n\n    # Lovingly stolen from CherryPy (http://svn.cherrypy.org/tags/cherrypy-3.2.1/cherrypy/wsgiserver/ssl_pyopenssl.py).\n    def _safe_ssl_call(self, suppress_ragged_eofs, call, *args, **kwargs):\n        \"\"\"Wrap the given call with SSL error-trapping.\"\"\"\n        start = time.time()\n        while True:\n            try:\n                return call(*args, **kwargs)\n            except (ossl.WantReadError, ossl.WantWriteError):\n                # Sleep and try again. This is dangerous, because it means\n                # the rest of the stack has no way of differentiating\n                # between a \"new handshake\" error and \"client dropped\".\n                # Note this isn't an endless loop: there's a timeout below.\n                time.sleep(self.SSL_RETRY)\n            except ossl.Error as e:\n                if suppress_ragged_eofs and e.args == (-1, 'Unexpected EOF'):\n                    return b''\n                raise socket.error(e.args[0])\n\n            if time.time() - start > self.SSL_TIMEOUT:\n                raise socket.timeout('timed out')\n\n    def connect(self, address):\n        self._conn.connect(address)\n        if self._do_handshake_on_connect:\n            self.do_handshake()\n\n    def do_handshake(self):\n        self._safe_ssl_call(False, self._conn.do_handshake)\n        if self._check_hostname:\n            verify_hostname(self, self._server_hostname)\n\n    def recv(self, bufsize, flags=None):\n        return self._safe_ssl_call(self._suppress_ragged_eofs, self._conn.recv,\n                               bufsize, flags)\n\n    def recv_into(self, buffer, bufsize=None, flags=None):\n        # A temporary recv_into implementation. Should be replaced when\n        # PyOpenSSL has merged pyca/pyopenssl#121.\n        if bufsize is None:\n            bufsize = len(buffer)\n\n        data = self.recv(bufsize, flags)\n        data_len = len(data)\n        buffer[0:data_len] = data\n        return data_len\n\n    def send(self, data, flags=None):\n        return self._safe_ssl_call(False, self._conn.send, data, flags)\n\n    def selected_npn_protocol(self):\n        proto = self._conn.get_next_proto_negotiated()\n        if isinstance(proto, bytes):\n            proto = proto.decode('ascii')\n\n        return proto if proto else None\n\n    def selected_alpn_protocol(self):\n        proto = self._conn.get_alpn_proto_negotiated()\n        if isinstance(proto, bytes):\n            proto = proto.decode('ascii')\n\n        return proto if proto else None\n\n    def getpeercert(self):\n        def resolve_alias(alias):\n            return dict(\n                C='countryName',\n                ST='stateOrProvinceName',\n                L='localityName',\n                O='organizationName',\n                OU='organizationalUnitName',\n                CN='commonName',\n            ).get(alias, alias)\n\n        def to_components(name):\n            # TODO Verify that these are actually *supposed* to all be single-element\n            # tuples, and that's not just a quirk of the examples I've seen.\n            return tuple([((resolve_alias(name.decode('utf-8')), value.decode('utf-8')),) for name, value in name.get_components()])\n\n        # The standard getpeercert() takes the nice X509 object tree returned\n        # by OpenSSL and turns it into a dict according to some format it seems\n        # to have made up on the spot. Here, we do our best to emulate that.\n        cert = self._conn.get_peer_certificate()\n        result = dict(\n            issuer=to_components(cert.get_issuer()),\n            subject=to_components(cert.get_subject()),\n            version=cert.get_subject(),\n            serialNumber=cert.get_serial_number(),\n            notBefore=cert.get_notBefore(),\n            notAfter=cert.get_notAfter(),\n        )\n        # TODO extensions, including subjectAltName (see _decode_certificate in _ssl.c)\n        return result\n\n    # a dash of magic to reduce boilerplate\n    for method in ['accept', 'bind', 'close', 'getsockname', 'listen', 'fileno']:\n        locals()[method] = _proxy(method)\n\n\nclass SSLContext(object):\n    def __init__(self, protocol):\n        self.protocol = protocol\n        self._ctx = ossl.Context(protocol)\n        self.options = OP_ALL\n        self.check_hostname = False\n        self.npn_protos = []\n\n    @property\n    def options(self):\n        return self._options\n\n    @options.setter\n    def options(self, value):\n        self._options = value\n        self._ctx.set_options(value)\n\n    @property\n    def verify_mode(self):\n        return self._ctx.get_verify_mode()\n\n    @verify_mode.setter\n    def verify_mode(self, value):\n        # TODO verify exception is raised on failure\n        self._ctx.set_verify(value, lambda conn, cert, errnum, errdepth, ok: ok)\n\n    def set_default_verify_paths(self):\n        self._ctx.set_default_verify_paths()\n\n    def load_verify_locations(self, cafile=None, capath=None, cadata=None):\n        # TODO factor out common code\n        if cafile is not None:\n            cafile = cafile.encode('utf-8')\n        if capath is not None:\n            capath = capath.encode('utf-8')\n        self._ctx.load_verify_locations(cafile, capath)\n        if cadata is not None:\n            self._ctx.load_verify_locations(BytesIO(cadata))\n\n    def load_cert_chain(self, certfile, keyfile=None, password=None):\n        self._ctx.use_certificate_file(certfile)\n        if password is not None:\n            self._ctx.set_passwd_cb(lambda max_length, prompt_twice, userdata: password)\n        self._ctx.use_privatekey_file(keyfile or certfile)\n\n    def set_npn_protocols(self, protocols):\n        self.protocols = list([x.encode('ascii') for x in protocols])\n\n        def cb(conn, protos):\n            # Detect the overlapping set of protocols.\n            overlap = set(protos) & set(self.protocols)\n\n            # Select the option that comes last in the list in the overlap.\n            for p in self.protocols:\n                if p in overlap:\n                    return p\n            else:\n                return b''\n\n        self._ctx.set_npn_select_callback(cb)\n\n    def set_alpn_protocols(self, protocols):\n        protocols = list([x.encode('ascii') for x in protocols])\n        self._ctx.set_alpn_protos(protocols)\n\n    def wrap_socket(self, sock, server_side=False, do_handshake_on_connect=True,\n                    suppress_ragged_eofs=True, server_hostname=None):\n        conn = ossl.Connection(self._ctx, sock)\n        return SSLSocket(conn, server_side, do_handshake_on_connect,\n                         suppress_ragged_eofs, server_hostname,\n                         # TODO what if this is changed after the fact?\n                         self.check_hostname)\n"
  },
  {
    "path": "code/default/lib/noarch/hyper/tls.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nhyper/tls\n~~~~~~~~~\n\nContains the TLS/SSL logic for use in hyper.\n\"\"\"\nimport os.path as path\n\nfrom .compat import ignore_missing, ssl\n\n\nNPN_PROTOCOL = 'h2'\nH2_NPN_PROTOCOLS = [NPN_PROTOCOL, 'h2-16', 'h2-15', 'h2-14']\nSUPPORTED_NPN_PROTOCOLS = H2_NPN_PROTOCOLS + ['http/1.1']\n\nH2C_PROTOCOL = 'h2c'\n\n# We have a singleton SSLContext object. There's no reason to be creating one\n# per connection.\n_context = None\n\n# Work out where our certificates are.\ncert_loc = path.join(path.dirname(__file__), 'certs.pem')\n\n\ndef wrap_socket(sock, server_hostname, ssl_context=None):\n    \"\"\"\n    A vastly simplified SSL wrapping function. We'll probably extend this to\n    do more things later.\n    \"\"\"\n    global _context\n\n    # create the singleton SSLContext we use\n    if _context is None:  # pragma: no cover\n        _context = init_context()\n\n    # if an SSLContext is provided then use it instead of default context\n    _ssl_context = ssl_context or _context\n\n    # the spec requires SNI support\n    _ssl_context.check_hostname = False\n    ssl_sock = _ssl_context.wrap_socket(sock, server_hostname=server_hostname)\n    # Setting SSLContext.check_hostname to True only verifies that the\n    # post-handshake servername matches that of the certificate. We also need\n    # to check that it matches the requested one.\n    if _ssl_context.check_hostname:  # pragma: no cover\n        try:\n            ssl.match_hostname(ssl_sock.getpeercert(), server_hostname)\n        except AttributeError:\n            ssl.verify_hostname(ssl_sock, server_hostname)  # pyopenssl\n\n    proto = None\n\n    # ALPN is newer, so we prefer it over NPN. The odds of us getting different\n    # answers is pretty low, but let's be sure.\n    with ignore_missing():\n        proto = ssl_sock.selected_alpn_protocol()\n\n    with ignore_missing():\n        if proto is None:\n            proto = ssl_sock.selected_npn_protocol()\n\n    return (ssl_sock, proto)\n\n\ndef init_context(cert_path=None):\n    \"\"\"\n    Create a new ``SSLContext`` that is correctly set up for an HTTP/2 connection.\n    This SSL context object can be customized and passed as a parameter to the\n    :class:`HTTPConnection <hyper.HTTPConnection>` class. Provide your\n    own certificate file in case you don’t want to use hyper’s default\n    certificate. The path to the certificate can be absolute or relative\n    to your working directory.\n\n    :param cert_path: (optional) The path to the certificate file.\n    :returns: An ``SSLContext`` correctly set up for HTTP/2.\n    \"\"\"\n    context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)\n    context.set_default_verify_paths()\n    context.load_verify_locations(cafile=cert_path or cert_loc)\n    context.verify_mode = ssl.CERT_REQUIRED\n    context.check_hostname = True\n\n    with ignore_missing():\n        context.set_npn_protocols(SUPPORTED_NPN_PROTOCOLS)\n\n    with ignore_missing():\n        context.set_alpn_protocols(SUPPORTED_NPN_PROTOCOLS)\n\n    # required by the spec\n    context.options |= ssl.OP_NO_COMPRESSION\n\n    return context\n"
  },
  {
    "path": "code/default/lib/noarch/idna/__init__.py",
    "content": "from .core import *\n"
  },
  {
    "path": "code/default/lib/noarch/idna/codec.py",
    "content": "from idna.core import encode, decode, alabel, ulabel, IDNAError\nimport codecs\nimport re\n\n_unicode_dots_re = re.compile('[\\u002e\\u3002\\uff0e\\uff61]')\n\nclass Codec(codecs.Codec):\n\n    def encode(self, data, errors='strict'):\n\n        if errors != 'strict':\n            raise IDNAError(\"Unsupported error handling \\\"{0}\\\"\".format(errors))\n\n        if not data:\n            return \"\", 0\n\n        return encode(data), len(data)\n\n    def decode(self, data, errors='strict'):\n\n        if errors != 'strict':\n            raise IDNAError(\"Unsupported error handling \\\"{0}\\\"\".format(errors))\n\n        if not data:\n            return \"\", 0\n\n        return decode(data), len(data)\n\nclass IncrementalEncoder(codecs.BufferedIncrementalEncoder):\n    def _buffer_encode(self, data, errors, final):\n        if errors != 'strict':\n            raise IDNAError(\"Unsupported error handling \\\"{0}\\\"\".format(errors))\n\n        if not data:\n            return (\"\", 0)\n\n        labels = _unicode_dots_re.split(data)\n        trailing_dot = ''\n        if labels:\n            if not labels[-1]:\n                trailing_dot = '.'\n                del labels[-1]\n            elif not final:\n                # Keep potentially unfinished label until the next call\n                del labels[-1]\n                if labels:\n                    trailing_dot = '.'\n\n        result = []\n        size = 0\n        for label in labels:\n            result.append(alabel(label))\n            if size:\n                size += 1\n            size += len(label)\n\n        # Join with U+002E\n        result = \".\".join(result) + trailing_dot\n        size += len(trailing_dot)\n        return (result, size)\n\nclass IncrementalDecoder(codecs.BufferedIncrementalDecoder):\n    def _buffer_decode(self, data, errors, final):\n        if errors != 'strict':\n            raise IDNAError(\"Unsupported error handling \\\"{0}\\\"\".format(errors))\n\n        if not data:\n            return (\"\", 0)\n\n        # IDNA allows decoding to operate on Unicode strings, too.\n        if isinstance(data, str):\n            labels = _unicode_dots_re.split(data)\n        else:\n            # Must be ASCII string\n            data = str(data)\n            str(data, \"ascii\")\n            labels = data.split(\".\")\n\n        trailing_dot = ''\n        if labels:\n            if not labels[-1]:\n                trailing_dot = '.'\n                del labels[-1]\n            elif not final:\n                # Keep potentially unfinished label until the next call\n                del labels[-1]\n                if labels:\n                    trailing_dot = '.'\n\n        result = []\n        size = 0\n        for label in labels:\n            result.append(ulabel(label))\n            if size:\n                size += 1\n            size += len(label)\n\n        result = \".\".join(result) + trailing_dot\n        size += len(trailing_dot)\n        return (result, size)\n\n\nclass StreamWriter(Codec, codecs.StreamWriter):\n    pass\n\nclass StreamReader(Codec, codecs.StreamReader):\n    pass\n\ndef getregentry():\n    return codecs.CodecInfo(\n        name='idna',\n        encode=Codec().encode,\n        decode=Codec().decode,\n        incrementalencoder=IncrementalEncoder,\n        incrementaldecoder=IncrementalDecoder,\n        streamwriter=StreamWriter,\n        streamreader=StreamReader,\n    )\n"
  },
  {
    "path": "code/default/lib/noarch/idna/compat.py",
    "content": "from idna.core import *\nfrom idna.codec import *\n\ndef ToASCII(label):\n    return encode(label)\n\ndef ToUnicode(label):\n    return decode(label)\n\ndef nameprep(s):\n    raise NotImplementedError(\"IDNA 2008 does not utilise nameprep protocol\")\n\n"
  },
  {
    "path": "code/default/lib/noarch/idna/core.py",
    "content": "from . import idnadata\nimport bisect\nimport unicodedata\nimport re\nimport sys\nfrom .intranges import intranges_contain\n\n_virama_combining_class = 9\n_alabel_prefix = b'xn--'\n_unicode_dots_re = re.compile('[\\u002e\\u3002\\uff0e\\uff61]')\n\nif sys.version_info[0] == 3:\n    str = str\n    chr = chr\n\nclass IDNAError(UnicodeError):\n    \"\"\" Base exception for all IDNA-encoding related problems \"\"\"\n    pass\n\n\nclass IDNABidiError(IDNAError):\n    \"\"\" Exception when bidirectional requirements are not satisfied \"\"\"\n    pass\n\n\nclass InvalidCodepoint(IDNAError):\n    \"\"\" Exception when a disallowed or unallocated codepoint is used \"\"\"\n    pass\n\n\nclass InvalidCodepointContext(IDNAError):\n    \"\"\" Exception when the codepoint is not valid in the context it is used \"\"\"\n    pass\n\n\ndef _combining_class(cp):\n    return unicodedata.combining(chr(cp))\n\ndef _is_script(cp, script):\n    return intranges_contain(ord(cp), idnadata.scripts[script])\n\ndef _punycode(s):\n    return s.encode('punycode')\n\ndef _unot(s):\n    return 'U+{0:04X}'.format(s)\n\n\ndef valid_label_length(label):\n\n    if len(label) > 63:\n        return False\n    return True\n\n\ndef valid_string_length(label, trailing_dot):\n\n    if len(label) > (254 if trailing_dot else 253):\n        return False\n    return True\n\n\ndef check_bidi(label, check_ltr=False):\n\n    # Bidi rules should only be applied if string contains RTL characters\n    bidi_label = False\n    for (idx, cp) in enumerate(label, 1):\n        direction = unicodedata.bidirectional(cp)\n        if direction == '':\n            # String likely comes from a newer version of Unicode\n            raise IDNABidiError('Unknown directionality in label {0} at position {1}'.format(repr(label), idx))\n        if direction in ['R', 'AL', 'AN']:\n            bidi_label = True\n            break\n    if not bidi_label and not check_ltr:\n        return True\n\n    # Bidi rule 1\n    direction = unicodedata.bidirectional(label[0])\n    if direction in ['R', 'AL']:\n        rtl = True\n    elif direction == 'L':\n        rtl = False\n    else:\n        raise IDNABidiError('First codepoint in label {0} must be directionality L, R or AL'.format(repr(label)))\n\n    valid_ending = False\n    number_type = False\n    for (idx, cp) in enumerate(label, 1):\n        direction = unicodedata.bidirectional(cp)\n\n        if rtl:\n            # Bidi rule 2\n            if not direction in ['R', 'AL', 'AN', 'EN', 'ES', 'CS', 'ET', 'ON', 'BN', 'NSM']:\n                raise IDNABidiError('Invalid direction for codepoint at position {0} in a right-to-left label'.format(idx))\n            # Bidi rule 3\n            if direction in ['R', 'AL', 'EN', 'AN']:\n                valid_ending = True\n            elif direction != 'NSM':\n                valid_ending = False\n            # Bidi rule 4\n            if direction in ['AN', 'EN']:\n                if not number_type:\n                    number_type = direction\n                else:\n                    if number_type != direction:\n                        raise IDNABidiError('Can not mix numeral types in a right-to-left label')\n        else:\n            # Bidi rule 5\n            if not direction in ['L', 'EN', 'ES', 'CS', 'ET', 'ON', 'BN', 'NSM']:\n                raise IDNABidiError('Invalid direction for codepoint at position {0} in a left-to-right label'.format(idx))\n            # Bidi rule 6\n            if direction in ['L', 'EN']:\n                valid_ending = True\n            elif direction != 'NSM':\n                valid_ending = False\n\n    if not valid_ending:\n        raise IDNABidiError('Label ends with illegal codepoint directionality')\n\n    return True\n\n\ndef check_initial_combiner(label):\n\n    if unicodedata.category(label[0])[0] == 'M':\n        raise IDNAError('Label begins with an illegal combining character')\n    return True\n\n\ndef check_hyphen_ok(label):\n\n    if label[2:4] == '--':\n        raise IDNAError('Label has disallowed hyphens in 3rd and 4th position')\n    if label[0] == '-' or label[-1] == '-':\n        raise IDNAError('Label must not start or end with a hyphen')\n    return True\n\n\ndef check_nfc(label):\n\n    if unicodedata.normalize('NFC', label) != label:\n        raise IDNAError('Label must be in Normalization Form C')\n\n\ndef valid_contextj(label, pos):\n\n    cp_value = ord(label[pos])\n\n    if cp_value == 0x200c:\n\n        if pos > 0:\n            if _combining_class(ord(label[pos - 1])) == _virama_combining_class:\n                return True\n\n        ok = False\n        for i in range(pos-1, -1, -1):\n            joining_type = idnadata.joining_types.get(ord(label[i]))\n            if joining_type == 'T':\n                continue\n            if joining_type in ['L', 'D']:\n                ok = True\n                break\n\n        if not ok:\n            return False\n\n        ok = False\n        for i in range(pos+1, len(label)):\n            joining_type = idnadata.joining_types.get(ord(label[i]))\n            if joining_type == 'T':\n                continue\n            if joining_type in ['R', 'D']:\n                ok = True\n                break\n        return ok\n\n    if cp_value == 0x200d:\n\n        if pos > 0:\n            if _combining_class(ord(label[pos - 1])) == _virama_combining_class:\n                return True\n        return False\n\n    else:\n\n        return False\n\n\ndef valid_contexto(label, pos, exception=False):\n\n    cp_value = ord(label[pos])\n\n    if cp_value == 0x00b7:\n        if 0 < pos < len(label)-1:\n            if ord(label[pos - 1]) == 0x006c and ord(label[pos + 1]) == 0x006c:\n                return True\n        return False\n\n    elif cp_value == 0x0375:\n        if pos < len(label)-1 and len(label) > 1:\n            return _is_script(label[pos + 1], 'Greek')\n        return False\n\n    elif cp_value == 0x05f3 or cp_value == 0x05f4:\n        if pos > 0:\n            return _is_script(label[pos - 1], 'Hebrew')\n        return False\n\n    elif cp_value == 0x30fb:\n        for cp in label:\n            if cp == '\\u30fb':\n                continue\n            if not _is_script(cp, 'Hiragana') and not _is_script(cp, 'Katakana') and not _is_script(cp, 'Han'):\n                return False\n        return True\n\n    elif 0x660 <= cp_value <= 0x669:\n        for cp in label:\n            if 0x6f0 <= ord(cp) <= 0x06f9:\n                return False\n        return True\n\n    elif 0x6f0 <= cp_value <= 0x6f9:\n        for cp in label:\n            if 0x660 <= ord(cp) <= 0x0669:\n                return False\n        return True\n\n\ndef check_label(label):\n\n    if isinstance(label, (bytes, bytearray)):\n        label = label.decode('utf-8')\n    if len(label) == 0:\n        raise IDNAError('Empty Label')\n\n    check_nfc(label)\n    check_hyphen_ok(label)\n    check_initial_combiner(label)\n\n    for (pos, cp) in enumerate(label):\n        cp_value = ord(cp)\n        if intranges_contain(cp_value, idnadata.codepoint_classes['PVALID']):\n            continue\n        elif intranges_contain(cp_value, idnadata.codepoint_classes['CONTEXTJ']):\n            if not valid_contextj(label, pos):\n                raise InvalidCodepointContext('Joiner {0} not allowed at position {1} in {2}'.format(_unot(cp_value), pos+1, repr(label)))\n        elif intranges_contain(cp_value, idnadata.codepoint_classes['CONTEXTO']):\n            if not valid_contexto(label, pos):\n                raise InvalidCodepointContext('Codepoint {0} not allowed at position {1} in {2}'.format(_unot(cp_value), pos+1, repr(label)))\n        else:\n            raise InvalidCodepoint('Codepoint {0} at position {1} of {2} not allowed'.format(_unot(cp_value), pos+1, repr(label)))\n\n    check_bidi(label)\n\n\ndef alabel(label):\n\n    try:\n        label = label.encode('ascii')\n        try:\n            ulabel(label)\n        except:\n            raise IDNAError('The label {0} is not a valid A-label'.format(label))\n        if not valid_label_length(label):\n            raise IDNAError('Label too long')\n        return label\n    except UnicodeError:\n        pass\n\n    if not label:\n        raise IDNAError('No Input')\n\n    label = str(label)\n    check_label(label)\n    label = _punycode(label)\n    label = _alabel_prefix + label\n\n    if not valid_label_length(label):\n        raise IDNAError('Label too long')\n\n    return label\n\n\ndef ulabel(label):\n\n    if not isinstance(label, (bytes, bytearray)):\n        try:\n            label = label.encode('ascii')\n        except UnicodeError:\n            check_label(label)\n            return label\n\n    label = label.lower()\n    if label.startswith(_alabel_prefix):\n        label = label[len(_alabel_prefix):]\n    else:\n        check_label(label)\n        return label.decode('ascii')\n\n    label = label.decode('punycode')\n    check_label(label)\n    return label\n\n\ndef uts46_remap(domain, std3_rules=True, transitional=False):\n    \"\"\"Re-map the characters in the string according to UTS46 processing.\"\"\"\n    from .uts46data import uts46data\n    output = \"\"\n    try:\n        for pos, char in enumerate(domain):\n            code_point = ord(char)\n            uts46row = uts46data[code_point if code_point < 256 else\n                bisect.bisect_left(uts46data, (code_point, \"Z\")) - 1]\n            status = uts46row[1]\n            replacement = uts46row[2] if len(uts46row) == 3 else None\n            if (status == \"V\" or\n                    (status == \"D\" and not transitional) or\n                    (status == \"3\" and std3_rules and replacement is None)):\n                output += char\n            elif replacement is not None and (status == \"M\" or\n                    (status == \"3\" and std3_rules) or\n                    (status == \"D\" and transitional)):\n                output += replacement\n            elif status != \"I\":\n                raise IndexError()\n        return unicodedata.normalize(\"NFC\", output)\n    except IndexError:\n        raise InvalidCodepoint(\n            \"Codepoint {0} not allowed at position {1} in {2}\".format(\n            _unot(code_point), pos + 1, repr(domain)))\n\n\ndef encode(s, strict=False, uts46=False, std3_rules=False, transitional=False):\n\n    if isinstance(s, (bytes, bytearray)):\n        s = s.decode(\"ascii\")\n    if uts46:\n        s = uts46_remap(s, std3_rules, transitional)\n    trailing_dot = False\n    result = []\n    if strict:\n        labels = s.split('.')\n    else:\n        labels = _unicode_dots_re.split(s)\n    while labels and not labels[0]:\n        del labels[0]\n    if not labels:\n        raise IDNAError('Empty domain')\n    if labels[-1] == '':\n        del labels[-1]\n        trailing_dot = True\n    for label in labels:\n        result.append(alabel(label))\n    if trailing_dot:\n        result.append(b'')\n    s = b'.'.join(result)\n    if not valid_string_length(s, trailing_dot):\n        raise IDNAError('Domain too long')\n    return s\n\n\ndef decode(s, strict=False, uts46=False, std3_rules=False):\n\n    if isinstance(s, (bytes, bytearray)):\n        s = s.decode(\"ascii\")\n    if uts46:\n        s = uts46_remap(s, std3_rules, False)\n    trailing_dot = False\n    result = []\n    if not strict:\n        labels = _unicode_dots_re.split(s)\n    else:\n        labels = s.split('.')\n    while labels and not labels[0]:\n        del labels[0]\n    if not labels:\n        raise IDNAError('Empty domain')\n    if not labels[-1]:\n        del labels[-1]\n        trailing_dot = True\n    for label in labels:\n        result.append(ulabel(label))\n    if trailing_dot:\n        result.append('')\n    return '.'.join(result)\n"
  },
  {
    "path": "code/default/lib/noarch/idna/idnadata.py",
    "content": "# This file is automatically generated by build-idnadata.py\n\nscripts = {\n    'Greek': (\n        (0x370, 0x374),\n        (0x375, 0x378),\n        (0x37a, 0x37e),\n        (0x384, 0x385),\n        (0x386, 0x387),\n        (0x388, 0x38b),\n        (0x38c, 0x38d),\n        (0x38e, 0x3a2),\n        (0x3a3, 0x3e2),\n        (0x3f0, 0x400),\n        (0x1d26, 0x1d2b),\n        (0x1d5d, 0x1d62),\n        (0x1d66, 0x1d6b),\n        (0x1dbf, 0x1dc0),\n        (0x1f00, 0x1f16),\n        (0x1f18, 0x1f1e),\n        (0x1f20, 0x1f46),\n        (0x1f48, 0x1f4e),\n        (0x1f50, 0x1f58),\n        (0x1f59, 0x1f5a),\n        (0x1f5b, 0x1f5c),\n        (0x1f5d, 0x1f5e),\n        (0x1f5f, 0x1f7e),\n        (0x1f80, 0x1fb5),\n        (0x1fb6, 0x1fc5),\n        (0x1fc6, 0x1fd4),\n        (0x1fd6, 0x1fdc),\n        (0x1fdd, 0x1ff0),\n        (0x1ff2, 0x1ff5),\n        (0x1ff6, 0x1fff),\n        (0x2126, 0x2127),\n        (0x10140, 0x1018b),\n        (0x1d200, 0x1d246),\n    ),\n    'Han': (\n        (0x2e80, 0x2e9a),\n        (0x2e9b, 0x2ef4),\n        (0x2f00, 0x2fd6),\n        (0x3005, 0x3006),\n        (0x3007, 0x3008),\n        (0x3021, 0x302a),\n        (0x3038, 0x303c),\n        (0x3400, 0x4db6),\n        (0x4e00, 0x9fcd),\n        (0xf900, 0xfa6e),\n        (0xfa70, 0xfada),\n        (0x20000, 0x2a6d7),\n        (0x2a700, 0x2b735),\n        (0x2b740, 0x2b81e),\n        (0x2f800, 0x2fa1e),\n    ),\n    'Hebrew': (\n        (0x591, 0x5c8),\n        (0x5d0, 0x5eb),\n        (0x5f0, 0x5f5),\n        (0xfb1d, 0xfb37),\n        (0xfb38, 0xfb3d),\n        (0xfb3e, 0xfb3f),\n        (0xfb40, 0xfb42),\n        (0xfb43, 0xfb45),\n        (0xfb46, 0xfb50),\n    ),\n    'Hiragana': (\n        (0x3041, 0x3097),\n        (0x309d, 0x30a0),\n        (0x1b001, 0x1b002),\n        (0x1f200, 0x1f201),\n    ),\n    'Katakana': (\n        (0x30a1, 0x30fb),\n        (0x30fd, 0x3100),\n        (0x31f0, 0x3200),\n        (0x32d0, 0x32ff),\n        (0x3300, 0x3358),\n        (0xff66, 0xff70),\n        (0xff71, 0xff9e),\n        (0x1b000, 0x1b001),\n    ),\n}\njoining_types = {\n    0x600: 'U',\n    0x601: 'U',\n    0x602: 'U',\n    0x603: 'U',\n    0x604: 'U',\n    0x608: 'U',\n    0x60b: 'U',\n    0x620: 'D',\n    0x621: 'U',\n    0x622: 'R',\n    0x623: 'R',\n    0x624: 'R',\n    0x625: 'R',\n    0x626: 'D',\n    0x627: 'R',\n    0x628: 'D',\n    0x629: 'R',\n    0x62a: 'D',\n    0x62b: 'D',\n    0x62c: 'D',\n    0x62d: 'D',\n    0x62e: 'D',\n    0x62f: 'R',\n    0x630: 'R',\n    0x631: 'R',\n    0x632: 'R',\n    0x633: 'D',\n    0x634: 'D',\n    0x635: 'D',\n    0x636: 'D',\n    0x637: 'D',\n    0x638: 'D',\n    0x639: 'D',\n    0x63a: 'D',\n    0x63b: 'D',\n    0x63c: 'D',\n    0x63d: 'D',\n    0x63e: 'D',\n    0x63f: 'D',\n    0x640: 'C',\n    0x641: 'D',\n    0x642: 'D',\n    0x643: 'D',\n    0x644: 'D',\n    0x645: 'D',\n    0x646: 'D',\n    0x647: 'D',\n    0x648: 'R',\n    0x649: 'D',\n    0x64a: 'D',\n    0x66e: 'D',\n    0x66f: 'D',\n    0x671: 'R',\n    0x672: 'R',\n    0x673: 'R',\n    0x674: 'U',\n    0x675: 'R',\n    0x676: 'R',\n    0x677: 'R',\n    0x678: 'D',\n    0x679: 'D',\n    0x67a: 'D',\n    0x67b: 'D',\n    0x67c: 'D',\n    0x67d: 'D',\n    0x67e: 'D',\n    0x67f: 'D',\n    0x680: 'D',\n    0x681: 'D',\n    0x682: 'D',\n    0x683: 'D',\n    0x684: 'D',\n    0x685: 'D',\n    0x686: 'D',\n    0x687: 'D',\n    0x688: 'R',\n    0x689: 'R',\n    0x68a: 'R',\n    0x68b: 'R',\n    0x68c: 'R',\n    0x68d: 'R',\n    0x68e: 'R',\n    0x68f: 'R',\n    0x690: 'R',\n    0x691: 'R',\n    0x692: 'R',\n    0x693: 'R',\n    0x694: 'R',\n    0x695: 'R',\n    0x696: 'R',\n    0x697: 'R',\n    0x698: 'R',\n    0x699: 'R',\n    0x69a: 'D',\n    0x69b: 'D',\n    0x69c: 'D',\n    0x69d: 'D',\n    0x69e: 'D',\n    0x69f: 'D',\n    0x6a0: 'D',\n    0x6a1: 'D',\n    0x6a2: 'D',\n    0x6a3: 'D',\n    0x6a4: 'D',\n    0x6a5: 'D',\n    0x6a6: 'D',\n    0x6a7: 'D',\n    0x6a8: 'D',\n    0x6a9: 'D',\n    0x6aa: 'D',\n    0x6ab: 'D',\n    0x6ac: 'D',\n    0x6ad: 'D',\n    0x6ae: 'D',\n    0x6af: 'D',\n    0x6b0: 'D',\n    0x6b1: 'D',\n    0x6b2: 'D',\n    0x6b3: 'D',\n    0x6b4: 'D',\n    0x6b5: 'D',\n    0x6b6: 'D',\n    0x6b7: 'D',\n    0x6b8: 'D',\n    0x6b9: 'D',\n    0x6ba: 'D',\n    0x6bb: 'D',\n    0x6bc: 'D',\n    0x6bd: 'D',\n    0x6be: 'D',\n    0x6bf: 'D',\n    0x6c0: 'R',\n    0x6c1: 'D',\n    0x6c2: 'D',\n    0x6c3: 'R',\n    0x6c4: 'R',\n    0x6c5: 'R',\n    0x6c6: 'R',\n    0x6c7: 'R',\n    0x6c8: 'R',\n    0x6c9: 'R',\n    0x6ca: 'R',\n    0x6cb: 'R',\n    0x6cc: 'D',\n    0x6cd: 'R',\n    0x6ce: 'D',\n    0x6cf: 'R',\n    0x6d0: 'D',\n    0x6d1: 'D',\n    0x6d2: 'R',\n    0x6d3: 'R',\n    0x6d5: 'R',\n    0x6dd: 'U',\n    0x6ee: 'R',\n    0x6ef: 'R',\n    0x6fa: 'D',\n    0x6fb: 'D',\n    0x6fc: 'D',\n    0x6ff: 'D',\n    0x710: 'R',\n    0x712: 'D',\n    0x713: 'D',\n    0x714: 'D',\n    0x715: 'R',\n    0x716: 'R',\n    0x717: 'R',\n    0x718: 'R',\n    0x719: 'R',\n    0x71a: 'D',\n    0x71b: 'D',\n    0x71c: 'D',\n    0x71d: 'D',\n    0x71e: 'R',\n    0x71f: 'D',\n    0x720: 'D',\n    0x721: 'D',\n    0x722: 'D',\n    0x723: 'D',\n    0x724: 'D',\n    0x725: 'D',\n    0x726: 'D',\n    0x727: 'D',\n    0x728: 'R',\n    0x729: 'D',\n    0x72a: 'R',\n    0x72b: 'D',\n    0x72c: 'R',\n    0x72d: 'D',\n    0x72e: 'D',\n    0x72f: 'R',\n    0x74d: 'R',\n    0x74e: 'D',\n    0x74f: 'D',\n    0x750: 'D',\n    0x751: 'D',\n    0x752: 'D',\n    0x753: 'D',\n    0x754: 'D',\n    0x755: 'D',\n    0x756: 'D',\n    0x757: 'D',\n    0x758: 'D',\n    0x759: 'R',\n    0x75a: 'R',\n    0x75b: 'R',\n    0x75c: 'D',\n    0x75d: 'D',\n    0x75e: 'D',\n    0x75f: 'D',\n    0x760: 'D',\n    0x761: 'D',\n    0x762: 'D',\n    0x763: 'D',\n    0x764: 'D',\n    0x765: 'D',\n    0x766: 'D',\n    0x767: 'D',\n    0x768: 'D',\n    0x769: 'D',\n    0x76a: 'D',\n    0x76b: 'R',\n    0x76c: 'R',\n    0x76d: 'D',\n    0x76e: 'D',\n    0x76f: 'D',\n    0x770: 'D',\n    0x771: 'R',\n    0x772: 'D',\n    0x773: 'R',\n    0x774: 'R',\n    0x775: 'D',\n    0x776: 'D',\n    0x777: 'D',\n    0x778: 'R',\n    0x779: 'R',\n    0x77a: 'D',\n    0x77b: 'D',\n    0x77c: 'D',\n    0x77d: 'D',\n    0x77e: 'D',\n    0x77f: 'D',\n    0x7ca: 'D',\n    0x7cb: 'D',\n    0x7cc: 'D',\n    0x7cd: 'D',\n    0x7ce: 'D',\n    0x7cf: 'D',\n    0x7d0: 'D',\n    0x7d1: 'D',\n    0x7d2: 'D',\n    0x7d3: 'D',\n    0x7d4: 'D',\n    0x7d5: 'D',\n    0x7d6: 'D',\n    0x7d7: 'D',\n    0x7d8: 'D',\n    0x7d9: 'D',\n    0x7da: 'D',\n    0x7db: 'D',\n    0x7dc: 'D',\n    0x7dd: 'D',\n    0x7de: 'D',\n    0x7df: 'D',\n    0x7e0: 'D',\n    0x7e1: 'D',\n    0x7e2: 'D',\n    0x7e3: 'D',\n    0x7e4: 'D',\n    0x7e5: 'D',\n    0x7e6: 'D',\n    0x7e7: 'D',\n    0x7e8: 'D',\n    0x7e9: 'D',\n    0x7ea: 'D',\n    0x7fa: 'C',\n    0x840: 'R',\n    0x841: 'D',\n    0x842: 'D',\n    0x843: 'D',\n    0x844: 'D',\n    0x845: 'D',\n    0x846: 'R',\n    0x847: 'D',\n    0x848: 'D',\n    0x849: 'R',\n    0x84a: 'D',\n    0x84b: 'D',\n    0x84c: 'D',\n    0x84d: 'D',\n    0x84e: 'D',\n    0x84f: 'R',\n    0x850: 'D',\n    0x851: 'D',\n    0x852: 'D',\n    0x853: 'D',\n    0x854: 'R',\n    0x855: 'D',\n    0x856: 'U',\n    0x857: 'U',\n    0x858: 'U',\n    0x8a0: 'D',\n    0x8a2: 'D',\n    0x8a3: 'D',\n    0x8a4: 'D',\n    0x8a5: 'D',\n    0x8a6: 'D',\n    0x8a7: 'D',\n    0x8a8: 'D',\n    0x8a9: 'D',\n    0x8aa: 'R',\n    0x8ab: 'R',\n    0x8ac: 'R',\n    0x1806: 'U',\n    0x1807: 'D',\n    0x180a: 'C',\n    0x180e: 'U',\n    0x1820: 'D',\n    0x1821: 'D',\n    0x1822: 'D',\n    0x1823: 'D',\n    0x1824: 'D',\n    0x1825: 'D',\n    0x1826: 'D',\n    0x1827: 'D',\n    0x1828: 'D',\n    0x1829: 'D',\n    0x182a: 'D',\n    0x182b: 'D',\n    0x182c: 'D',\n    0x182d: 'D',\n    0x182e: 'D',\n    0x182f: 'D',\n    0x1830: 'D',\n    0x1831: 'D',\n    0x1832: 'D',\n    0x1833: 'D',\n    0x1834: 'D',\n    0x1835: 'D',\n    0x1836: 'D',\n    0x1837: 'D',\n    0x1838: 'D',\n    0x1839: 'D',\n    0x183a: 'D',\n    0x183b: 'D',\n    0x183c: 'D',\n    0x183d: 'D',\n    0x183e: 'D',\n    0x183f: 'D',\n    0x1840: 'D',\n    0x1841: 'D',\n    0x1842: 'D',\n    0x1843: 'D',\n    0x1844: 'D',\n    0x1845: 'D',\n    0x1846: 'D',\n    0x1847: 'D',\n    0x1848: 'D',\n    0x1849: 'D',\n    0x184a: 'D',\n    0x184b: 'D',\n    0x184c: 'D',\n    0x184d: 'D',\n    0x184e: 'D',\n    0x184f: 'D',\n    0x1850: 'D',\n    0x1851: 'D',\n    0x1852: 'D',\n    0x1853: 'D',\n    0x1854: 'D',\n    0x1855: 'D',\n    0x1856: 'D',\n    0x1857: 'D',\n    0x1858: 'D',\n    0x1859: 'D',\n    0x185a: 'D',\n    0x185b: 'D',\n    0x185c: 'D',\n    0x185d: 'D',\n    0x185e: 'D',\n    0x185f: 'D',\n    0x1860: 'D',\n    0x1861: 'D',\n    0x1862: 'D',\n    0x1863: 'D',\n    0x1864: 'D',\n    0x1865: 'D',\n    0x1866: 'D',\n    0x1867: 'D',\n    0x1868: 'D',\n    0x1869: 'D',\n    0x186a: 'D',\n    0x186b: 'D',\n    0x186c: 'D',\n    0x186d: 'D',\n    0x186e: 'D',\n    0x186f: 'D',\n    0x1870: 'D',\n    0x1871: 'D',\n    0x1872: 'D',\n    0x1873: 'D',\n    0x1874: 'D',\n    0x1875: 'D',\n    0x1876: 'D',\n    0x1877: 'D',\n    0x1880: 'U',\n    0x1881: 'U',\n    0x1882: 'U',\n    0x1883: 'U',\n    0x1884: 'U',\n    0x1885: 'U',\n    0x1886: 'U',\n    0x1887: 'D',\n    0x1888: 'D',\n    0x1889: 'D',\n    0x188a: 'D',\n    0x188b: 'D',\n    0x188c: 'D',\n    0x188d: 'D',\n    0x188e: 'D',\n    0x188f: 'D',\n    0x1890: 'D',\n    0x1891: 'D',\n    0x1892: 'D',\n    0x1893: 'D',\n    0x1894: 'D',\n    0x1895: 'D',\n    0x1896: 'D',\n    0x1897: 'D',\n    0x1898: 'D',\n    0x1899: 'D',\n    0x189a: 'D',\n    0x189b: 'D',\n    0x189c: 'D',\n    0x189d: 'D',\n    0x189e: 'D',\n    0x189f: 'D',\n    0x18a0: 'D',\n    0x18a1: 'D',\n    0x18a2: 'D',\n    0x18a3: 'D',\n    0x18a4: 'D',\n    0x18a5: 'D',\n    0x18a6: 'D',\n    0x18a7: 'D',\n    0x18a8: 'D',\n    0x18aa: 'D',\n    0x200c: 'U',\n    0x200d: 'C',\n    0x2066: 'U',\n    0x2067: 'U',\n    0x2068: 'U',\n    0x2069: 'U',\n    0xa840: 'D',\n    0xa841: 'D',\n    0xa842: 'D',\n    0xa843: 'D',\n    0xa844: 'D',\n    0xa845: 'D',\n    0xa846: 'D',\n    0xa847: 'D',\n    0xa848: 'D',\n    0xa849: 'D',\n    0xa84a: 'D',\n    0xa84b: 'D',\n    0xa84c: 'D',\n    0xa84d: 'D',\n    0xa84e: 'D',\n    0xa84f: 'D',\n    0xa850: 'D',\n    0xa851: 'D',\n    0xa852: 'D',\n    0xa853: 'D',\n    0xa854: 'D',\n    0xa855: 'D',\n    0xa856: 'D',\n    0xa857: 'D',\n    0xa858: 'D',\n    0xa859: 'D',\n    0xa85a: 'D',\n    0xa85b: 'D',\n    0xa85c: 'D',\n    0xa85d: 'D',\n    0xa85e: 'D',\n    0xa85f: 'D',\n    0xa860: 'D',\n    0xa861: 'D',\n    0xa862: 'D',\n    0xa863: 'D',\n    0xa864: 'D',\n    0xa865: 'D',\n    0xa866: 'D',\n    0xa867: 'D',\n    0xa868: 'D',\n    0xa869: 'D',\n    0xa86a: 'D',\n    0xa86b: 'D',\n    0xa86c: 'D',\n    0xa86d: 'D',\n    0xa86e: 'D',\n    0xa86f: 'D',\n    0xa870: 'D',\n    0xa871: 'D',\n    0xa872: 'L',\n    0xa873: 'U',\n}\ncodepoint_classes = {\n    'PVALID': (\n        (0x2d, 0x2e),\n        (0x30, 0x3a),\n        (0x61, 0x7b),\n        (0xdf, 0xf7),\n        (0xf8, 0x100),\n        (0x101, 0x102),\n        (0x103, 0x104),\n        (0x105, 0x106),\n        (0x107, 0x108),\n        (0x109, 0x10a),\n        (0x10b, 0x10c),\n        (0x10d, 0x10e),\n        (0x10f, 0x110),\n        (0x111, 0x112),\n        (0x113, 0x114),\n        (0x115, 0x116),\n        (0x117, 0x118),\n        (0x119, 0x11a),\n        (0x11b, 0x11c),\n        (0x11d, 0x11e),\n        (0x11f, 0x120),\n        (0x121, 0x122),\n        (0x123, 0x124),\n        (0x125, 0x126),\n        (0x127, 0x128),\n        (0x129, 0x12a),\n        (0x12b, 0x12c),\n        (0x12d, 0x12e),\n        (0x12f, 0x130),\n        (0x131, 0x132),\n        (0x135, 0x136),\n        (0x137, 0x139),\n        (0x13a, 0x13b),\n        (0x13c, 0x13d),\n        (0x13e, 0x13f),\n        (0x142, 0x143),\n        (0x144, 0x145),\n        (0x146, 0x147),\n        (0x148, 0x149),\n        (0x14b, 0x14c),\n        (0x14d, 0x14e),\n        (0x14f, 0x150),\n        (0x151, 0x152),\n        (0x153, 0x154),\n        (0x155, 0x156),\n        (0x157, 0x158),\n        (0x159, 0x15a),\n        (0x15b, 0x15c),\n        (0x15d, 0x15e),\n        (0x15f, 0x160),\n        (0x161, 0x162),\n        (0x163, 0x164),\n        (0x165, 0x166),\n        (0x167, 0x168),\n        (0x169, 0x16a),\n        (0x16b, 0x16c),\n        (0x16d, 0x16e),\n        (0x16f, 0x170),\n        (0x171, 0x172),\n        (0x173, 0x174),\n        (0x175, 0x176),\n        (0x177, 0x178),\n        (0x17a, 0x17b),\n        (0x17c, 0x17d),\n        (0x17e, 0x17f),\n        (0x180, 0x181),\n        (0x183, 0x184),\n        (0x185, 0x186),\n        (0x188, 0x189),\n        (0x18c, 0x18e),\n        (0x192, 0x193),\n        (0x195, 0x196),\n        (0x199, 0x19c),\n        (0x19e, 0x19f),\n        (0x1a1, 0x1a2),\n        (0x1a3, 0x1a4),\n        (0x1a5, 0x1a6),\n        (0x1a8, 0x1a9),\n        (0x1aa, 0x1ac),\n        (0x1ad, 0x1ae),\n        (0x1b0, 0x1b1),\n        (0x1b4, 0x1b5),\n        (0x1b6, 0x1b7),\n        (0x1b9, 0x1bc),\n        (0x1bd, 0x1c4),\n        (0x1ce, 0x1cf),\n        (0x1d0, 0x1d1),\n        (0x1d2, 0x1d3),\n        (0x1d4, 0x1d5),\n        (0x1d6, 0x1d7),\n        (0x1d8, 0x1d9),\n        (0x1da, 0x1db),\n        (0x1dc, 0x1de),\n        (0x1df, 0x1e0),\n        (0x1e1, 0x1e2),\n        (0x1e3, 0x1e4),\n        (0x1e5, 0x1e6),\n        (0x1e7, 0x1e8),\n        (0x1e9, 0x1ea),\n        (0x1eb, 0x1ec),\n        (0x1ed, 0x1ee),\n        (0x1ef, 0x1f1),\n        (0x1f5, 0x1f6),\n        (0x1f9, 0x1fa),\n        (0x1fb, 0x1fc),\n        (0x1fd, 0x1fe),\n        (0x1ff, 0x200),\n        (0x201, 0x202),\n        (0x203, 0x204),\n        (0x205, 0x206),\n        (0x207, 0x208),\n        (0x209, 0x20a),\n        (0x20b, 0x20c),\n        (0x20d, 0x20e),\n        (0x20f, 0x210),\n        (0x211, 0x212),\n        (0x213, 0x214),\n        (0x215, 0x216),\n        (0x217, 0x218),\n        (0x219, 0x21a),\n        (0x21b, 0x21c),\n        (0x21d, 0x21e),\n        (0x21f, 0x220),\n        (0x221, 0x222),\n        (0x223, 0x224),\n        (0x225, 0x226),\n        (0x227, 0x228),\n        (0x229, 0x22a),\n        (0x22b, 0x22c),\n        (0x22d, 0x22e),\n        (0x22f, 0x230),\n        (0x231, 0x232),\n        (0x233, 0x23a),\n        (0x23c, 0x23d),\n        (0x23f, 0x241),\n        (0x242, 0x243),\n        (0x247, 0x248),\n        (0x249, 0x24a),\n        (0x24b, 0x24c),\n        (0x24d, 0x24e),\n        (0x24f, 0x2b0),\n        (0x2b9, 0x2c2),\n        (0x2c6, 0x2d2),\n        (0x2ec, 0x2ed),\n        (0x2ee, 0x2ef),\n        (0x300, 0x340),\n        (0x342, 0x343),\n        (0x346, 0x34f),\n        (0x350, 0x370),\n        (0x371, 0x372),\n        (0x373, 0x374),\n        (0x377, 0x378),\n        (0x37b, 0x37e),\n        (0x390, 0x391),\n        (0x3ac, 0x3cf),\n        (0x3d7, 0x3d8),\n        (0x3d9, 0x3da),\n        (0x3db, 0x3dc),\n        (0x3dd, 0x3de),\n        (0x3df, 0x3e0),\n        (0x3e1, 0x3e2),\n        (0x3e3, 0x3e4),\n        (0x3e5, 0x3e6),\n        (0x3e7, 0x3e8),\n        (0x3e9, 0x3ea),\n        (0x3eb, 0x3ec),\n        (0x3ed, 0x3ee),\n        (0x3ef, 0x3f0),\n        (0x3f3, 0x3f4),\n        (0x3f8, 0x3f9),\n        (0x3fb, 0x3fd),\n        (0x430, 0x460),\n        (0x461, 0x462),\n        (0x463, 0x464),\n        (0x465, 0x466),\n        (0x467, 0x468),\n        (0x469, 0x46a),\n        (0x46b, 0x46c),\n        (0x46d, 0x46e),\n        (0x46f, 0x470),\n        (0x471, 0x472),\n        (0x473, 0x474),\n        (0x475, 0x476),\n        (0x477, 0x478),\n        (0x479, 0x47a),\n        (0x47b, 0x47c),\n        (0x47d, 0x47e),\n        (0x47f, 0x480),\n        (0x481, 0x482),\n        (0x483, 0x488),\n        (0x48b, 0x48c),\n        (0x48d, 0x48e),\n        (0x48f, 0x490),\n        (0x491, 0x492),\n        (0x493, 0x494),\n        (0x495, 0x496),\n        (0x497, 0x498),\n        (0x499, 0x49a),\n        (0x49b, 0x49c),\n        (0x49d, 0x49e),\n        (0x49f, 0x4a0),\n        (0x4a1, 0x4a2),\n        (0x4a3, 0x4a4),\n        (0x4a5, 0x4a6),\n        (0x4a7, 0x4a8),\n        (0x4a9, 0x4aa),\n        (0x4ab, 0x4ac),\n        (0x4ad, 0x4ae),\n        (0x4af, 0x4b0),\n        (0x4b1, 0x4b2),\n        (0x4b3, 0x4b4),\n        (0x4b5, 0x4b6),\n        (0x4b7, 0x4b8),\n        (0x4b9, 0x4ba),\n        (0x4bb, 0x4bc),\n        (0x4bd, 0x4be),\n        (0x4bf, 0x4c0),\n        (0x4c2, 0x4c3),\n        (0x4c4, 0x4c5),\n        (0x4c6, 0x4c7),\n        (0x4c8, 0x4c9),\n        (0x4ca, 0x4cb),\n        (0x4cc, 0x4cd),\n        (0x4ce, 0x4d0),\n        (0x4d1, 0x4d2),\n        (0x4d3, 0x4d4),\n        (0x4d5, 0x4d6),\n        (0x4d7, 0x4d8),\n        (0x4d9, 0x4da),\n        (0x4db, 0x4dc),\n        (0x4dd, 0x4de),\n        (0x4df, 0x4e0),\n        (0x4e1, 0x4e2),\n        (0x4e3, 0x4e4),\n        (0x4e5, 0x4e6),\n        (0x4e7, 0x4e8),\n        (0x4e9, 0x4ea),\n        (0x4eb, 0x4ec),\n        (0x4ed, 0x4ee),\n        (0x4ef, 0x4f0),\n        (0x4f1, 0x4f2),\n        (0x4f3, 0x4f4),\n        (0x4f5, 0x4f6),\n        (0x4f7, 0x4f8),\n        (0x4f9, 0x4fa),\n        (0x4fb, 0x4fc),\n        (0x4fd, 0x4fe),\n        (0x4ff, 0x500),\n        (0x501, 0x502),\n        (0x503, 0x504),\n        (0x505, 0x506),\n        (0x507, 0x508),\n        (0x509, 0x50a),\n        (0x50b, 0x50c),\n        (0x50d, 0x50e),\n        (0x50f, 0x510),\n        (0x511, 0x512),\n        (0x513, 0x514),\n        (0x515, 0x516),\n        (0x517, 0x518),\n        (0x519, 0x51a),\n        (0x51b, 0x51c),\n        (0x51d, 0x51e),\n        (0x51f, 0x520),\n        (0x521, 0x522),\n        (0x523, 0x524),\n        (0x525, 0x526),\n        (0x527, 0x528),\n        (0x559, 0x55a),\n        (0x561, 0x587),\n        (0x591, 0x5be),\n        (0x5bf, 0x5c0),\n        (0x5c1, 0x5c3),\n        (0x5c4, 0x5c6),\n        (0x5c7, 0x5c8),\n        (0x5d0, 0x5eb),\n        (0x5f0, 0x5f3),\n        (0x610, 0x61b),\n        (0x620, 0x640),\n        (0x641, 0x660),\n        (0x66e, 0x675),\n        (0x679, 0x6d4),\n        (0x6d5, 0x6dd),\n        (0x6df, 0x6e9),\n        (0x6ea, 0x6f0),\n        (0x6fa, 0x700),\n        (0x710, 0x74b),\n        (0x74d, 0x7b2),\n        (0x7c0, 0x7f6),\n        (0x800, 0x82e),\n        (0x840, 0x85c),\n        (0x8a0, 0x8a1),\n        (0x8a2, 0x8ad),\n        (0x8e4, 0x8ff),\n        (0x900, 0x958),\n        (0x960, 0x964),\n        (0x966, 0x970),\n        (0x971, 0x978),\n        (0x979, 0x980),\n        (0x981, 0x984),\n        (0x985, 0x98d),\n        (0x98f, 0x991),\n        (0x993, 0x9a9),\n        (0x9aa, 0x9b1),\n        (0x9b2, 0x9b3),\n        (0x9b6, 0x9ba),\n        (0x9bc, 0x9c5),\n        (0x9c7, 0x9c9),\n        (0x9cb, 0x9cf),\n        (0x9d7, 0x9d8),\n        (0x9e0, 0x9e4),\n        (0x9e6, 0x9f2),\n        (0xa01, 0xa04),\n        (0xa05, 0xa0b),\n        (0xa0f, 0xa11),\n        (0xa13, 0xa29),\n        (0xa2a, 0xa31),\n        (0xa32, 0xa33),\n        (0xa35, 0xa36),\n        (0xa38, 0xa3a),\n        (0xa3c, 0xa3d),\n        (0xa3e, 0xa43),\n        (0xa47, 0xa49),\n        (0xa4b, 0xa4e),\n        (0xa51, 0xa52),\n        (0xa5c, 0xa5d),\n        (0xa66, 0xa76),\n        (0xa81, 0xa84),\n        (0xa85, 0xa8e),\n        (0xa8f, 0xa92),\n        (0xa93, 0xaa9),\n        (0xaaa, 0xab1),\n        (0xab2, 0xab4),\n        (0xab5, 0xaba),\n        (0xabc, 0xac6),\n        (0xac7, 0xaca),\n        (0xacb, 0xace),\n        (0xad0, 0xad1),\n        (0xae0, 0xae4),\n        (0xae6, 0xaf0),\n        (0xb01, 0xb04),\n        (0xb05, 0xb0d),\n        (0xb0f, 0xb11),\n        (0xb13, 0xb29),\n        (0xb2a, 0xb31),\n        (0xb32, 0xb34),\n        (0xb35, 0xb3a),\n        (0xb3c, 0xb45),\n        (0xb47, 0xb49),\n        (0xb4b, 0xb4e),\n        (0xb56, 0xb58),\n        (0xb5f, 0xb64),\n        (0xb66, 0xb70),\n        (0xb71, 0xb72),\n        (0xb82, 0xb84),\n        (0xb85, 0xb8b),\n        (0xb8e, 0xb91),\n        (0xb92, 0xb96),\n        (0xb99, 0xb9b),\n        (0xb9c, 0xb9d),\n        (0xb9e, 0xba0),\n        (0xba3, 0xba5),\n        (0xba8, 0xbab),\n        (0xbae, 0xbba),\n        (0xbbe, 0xbc3),\n        (0xbc6, 0xbc9),\n        (0xbca, 0xbce),\n        (0xbd0, 0xbd1),\n        (0xbd7, 0xbd8),\n        (0xbe6, 0xbf0),\n        (0xc01, 0xc04),\n        (0xc05, 0xc0d),\n        (0xc0e, 0xc11),\n        (0xc12, 0xc29),\n        (0xc2a, 0xc34),\n        (0xc35, 0xc3a),\n        (0xc3d, 0xc45),\n        (0xc46, 0xc49),\n        (0xc4a, 0xc4e),\n        (0xc55, 0xc57),\n        (0xc58, 0xc5a),\n        (0xc60, 0xc64),\n        (0xc66, 0xc70),\n        (0xc82, 0xc84),\n        (0xc85, 0xc8d),\n        (0xc8e, 0xc91),\n        (0xc92, 0xca9),\n        (0xcaa, 0xcb4),\n        (0xcb5, 0xcba),\n        (0xcbc, 0xcc5),\n        (0xcc6, 0xcc9),\n        (0xcca, 0xcce),\n        (0xcd5, 0xcd7),\n        (0xcde, 0xcdf),\n        (0xce0, 0xce4),\n        (0xce6, 0xcf0),\n        (0xcf1, 0xcf3),\n        (0xd02, 0xd04),\n        (0xd05, 0xd0d),\n        (0xd0e, 0xd11),\n        (0xd12, 0xd3b),\n        (0xd3d, 0xd45),\n        (0xd46, 0xd49),\n        (0xd4a, 0xd4f),\n        (0xd57, 0xd58),\n        (0xd60, 0xd64),\n        (0xd66, 0xd70),\n        (0xd7a, 0xd80),\n        (0xd82, 0xd84),\n        (0xd85, 0xd97),\n        (0xd9a, 0xdb2),\n        (0xdb3, 0xdbc),\n        (0xdbd, 0xdbe),\n        (0xdc0, 0xdc7),\n        (0xdca, 0xdcb),\n        (0xdcf, 0xdd5),\n        (0xdd6, 0xdd7),\n        (0xdd8, 0xde0),\n        (0xdf2, 0xdf4),\n        (0xe01, 0xe33),\n        (0xe34, 0xe3b),\n        (0xe40, 0xe4f),\n        (0xe50, 0xe5a),\n        (0xe81, 0xe83),\n        (0xe84, 0xe85),\n        (0xe87, 0xe89),\n        (0xe8a, 0xe8b),\n        (0xe8d, 0xe8e),\n        (0xe94, 0xe98),\n        (0xe99, 0xea0),\n        (0xea1, 0xea4),\n        (0xea5, 0xea6),\n        (0xea7, 0xea8),\n        (0xeaa, 0xeac),\n        (0xead, 0xeb3),\n        (0xeb4, 0xeba),\n        (0xebb, 0xebe),\n        (0xec0, 0xec5),\n        (0xec6, 0xec7),\n        (0xec8, 0xece),\n        (0xed0, 0xeda),\n        (0xede, 0xee0),\n        (0xf00, 0xf01),\n        (0xf0b, 0xf0c),\n        (0xf18, 0xf1a),\n        (0xf20, 0xf2a),\n        (0xf35, 0xf36),\n        (0xf37, 0xf38),\n        (0xf39, 0xf3a),\n        (0xf3e, 0xf43),\n        (0xf44, 0xf48),\n        (0xf49, 0xf4d),\n        (0xf4e, 0xf52),\n        (0xf53, 0xf57),\n        (0xf58, 0xf5c),\n        (0xf5d, 0xf69),\n        (0xf6a, 0xf6d),\n        (0xf71, 0xf73),\n        (0xf74, 0xf75),\n        (0xf7a, 0xf81),\n        (0xf82, 0xf85),\n        (0xf86, 0xf93),\n        (0xf94, 0xf98),\n        (0xf99, 0xf9d),\n        (0xf9e, 0xfa2),\n        (0xfa3, 0xfa7),\n        (0xfa8, 0xfac),\n        (0xfad, 0xfb9),\n        (0xfba, 0xfbd),\n        (0xfc6, 0xfc7),\n        (0x1000, 0x104a),\n        (0x1050, 0x109e),\n        (0x10d0, 0x10fb),\n        (0x10fd, 0x1100),\n        (0x1200, 0x1249),\n        (0x124a, 0x124e),\n        (0x1250, 0x1257),\n        (0x1258, 0x1259),\n        (0x125a, 0x125e),\n        (0x1260, 0x1289),\n        (0x128a, 0x128e),\n        (0x1290, 0x12b1),\n        (0x12b2, 0x12b6),\n        (0x12b8, 0x12bf),\n        (0x12c0, 0x12c1),\n        (0x12c2, 0x12c6),\n        (0x12c8, 0x12d7),\n        (0x12d8, 0x1311),\n        (0x1312, 0x1316),\n        (0x1318, 0x135b),\n        (0x135d, 0x1360),\n        (0x1380, 0x1390),\n        (0x13a0, 0x13f5),\n        (0x1401, 0x166d),\n        (0x166f, 0x1680),\n        (0x1681, 0x169b),\n        (0x16a0, 0x16eb),\n        (0x1700, 0x170d),\n        (0x170e, 0x1715),\n        (0x1720, 0x1735),\n        (0x1740, 0x1754),\n        (0x1760, 0x176d),\n        (0x176e, 0x1771),\n        (0x1772, 0x1774),\n        (0x1780, 0x17b4),\n        (0x17b6, 0x17d4),\n        (0x17d7, 0x17d8),\n        (0x17dc, 0x17de),\n        (0x17e0, 0x17ea),\n        (0x1810, 0x181a),\n        (0x1820, 0x1878),\n        (0x1880, 0x18ab),\n        (0x18b0, 0x18f6),\n        (0x1900, 0x191d),\n        (0x1920, 0x192c),\n        (0x1930, 0x193c),\n        (0x1946, 0x196e),\n        (0x1970, 0x1975),\n        (0x1980, 0x19ac),\n        (0x19b0, 0x19ca),\n        (0x19d0, 0x19da),\n        (0x1a00, 0x1a1c),\n        (0x1a20, 0x1a5f),\n        (0x1a60, 0x1a7d),\n        (0x1a7f, 0x1a8a),\n        (0x1a90, 0x1a9a),\n        (0x1aa7, 0x1aa8),\n        (0x1b00, 0x1b4c),\n        (0x1b50, 0x1b5a),\n        (0x1b6b, 0x1b74),\n        (0x1b80, 0x1bf4),\n        (0x1c00, 0x1c38),\n        (0x1c40, 0x1c4a),\n        (0x1c4d, 0x1c7e),\n        (0x1cd0, 0x1cd3),\n        (0x1cd4, 0x1cf7),\n        (0x1d00, 0x1d2c),\n        (0x1d2f, 0x1d30),\n        (0x1d3b, 0x1d3c),\n        (0x1d4e, 0x1d4f),\n        (0x1d6b, 0x1d78),\n        (0x1d79, 0x1d9b),\n        (0x1dc0, 0x1de7),\n        (0x1dfc, 0x1e00),\n        (0x1e01, 0x1e02),\n        (0x1e03, 0x1e04),\n        (0x1e05, 0x1e06),\n        (0x1e07, 0x1e08),\n        (0x1e09, 0x1e0a),\n        (0x1e0b, 0x1e0c),\n        (0x1e0d, 0x1e0e),\n        (0x1e0f, 0x1e10),\n        (0x1e11, 0x1e12),\n        (0x1e13, 0x1e14),\n        (0x1e15, 0x1e16),\n        (0x1e17, 0x1e18),\n        (0x1e19, 0x1e1a),\n        (0x1e1b, 0x1e1c),\n        (0x1e1d, 0x1e1e),\n        (0x1e1f, 0x1e20),\n        (0x1e21, 0x1e22),\n        (0x1e23, 0x1e24),\n        (0x1e25, 0x1e26),\n        (0x1e27, 0x1e28),\n        (0x1e29, 0x1e2a),\n        (0x1e2b, 0x1e2c),\n        (0x1e2d, 0x1e2e),\n        (0x1e2f, 0x1e30),\n        (0x1e31, 0x1e32),\n        (0x1e33, 0x1e34),\n        (0x1e35, 0x1e36),\n        (0x1e37, 0x1e38),\n        (0x1e39, 0x1e3a),\n        (0x1e3b, 0x1e3c),\n        (0x1e3d, 0x1e3e),\n        (0x1e3f, 0x1e40),\n        (0x1e41, 0x1e42),\n        (0x1e43, 0x1e44),\n        (0x1e45, 0x1e46),\n        (0x1e47, 0x1e48),\n        (0x1e49, 0x1e4a),\n        (0x1e4b, 0x1e4c),\n        (0x1e4d, 0x1e4e),\n        (0x1e4f, 0x1e50),\n        (0x1e51, 0x1e52),\n        (0x1e53, 0x1e54),\n        (0x1e55, 0x1e56),\n        (0x1e57, 0x1e58),\n        (0x1e59, 0x1e5a),\n        (0x1e5b, 0x1e5c),\n        (0x1e5d, 0x1e5e),\n        (0x1e5f, 0x1e60),\n        (0x1e61, 0x1e62),\n        (0x1e63, 0x1e64),\n        (0x1e65, 0x1e66),\n        (0x1e67, 0x1e68),\n        (0x1e69, 0x1e6a),\n        (0x1e6b, 0x1e6c),\n        (0x1e6d, 0x1e6e),\n        (0x1e6f, 0x1e70),\n        (0x1e71, 0x1e72),\n        (0x1e73, 0x1e74),\n        (0x1e75, 0x1e76),\n        (0x1e77, 0x1e78),\n        (0x1e79, 0x1e7a),\n        (0x1e7b, 0x1e7c),\n        (0x1e7d, 0x1e7e),\n        (0x1e7f, 0x1e80),\n        (0x1e81, 0x1e82),\n        (0x1e83, 0x1e84),\n        (0x1e85, 0x1e86),\n        (0x1e87, 0x1e88),\n        (0x1e89, 0x1e8a),\n        (0x1e8b, 0x1e8c),\n        (0x1e8d, 0x1e8e),\n        (0x1e8f, 0x1e90),\n        (0x1e91, 0x1e92),\n        (0x1e93, 0x1e94),\n        (0x1e95, 0x1e9a),\n        (0x1e9c, 0x1e9e),\n        (0x1e9f, 0x1ea0),\n        (0x1ea1, 0x1ea2),\n        (0x1ea3, 0x1ea4),\n        (0x1ea5, 0x1ea6),\n        (0x1ea7, 0x1ea8),\n        (0x1ea9, 0x1eaa),\n        (0x1eab, 0x1eac),\n        (0x1ead, 0x1eae),\n        (0x1eaf, 0x1eb0),\n        (0x1eb1, 0x1eb2),\n        (0x1eb3, 0x1eb4),\n        (0x1eb5, 0x1eb6),\n        (0x1eb7, 0x1eb8),\n        (0x1eb9, 0x1eba),\n        (0x1ebb, 0x1ebc),\n        (0x1ebd, 0x1ebe),\n        (0x1ebf, 0x1ec0),\n        (0x1ec1, 0x1ec2),\n        (0x1ec3, 0x1ec4),\n        (0x1ec5, 0x1ec6),\n        (0x1ec7, 0x1ec8),\n        (0x1ec9, 0x1eca),\n        (0x1ecb, 0x1ecc),\n        (0x1ecd, 0x1ece),\n        (0x1ecf, 0x1ed0),\n        (0x1ed1, 0x1ed2),\n        (0x1ed3, 0x1ed4),\n        (0x1ed5, 0x1ed6),\n        (0x1ed7, 0x1ed8),\n        (0x1ed9, 0x1eda),\n        (0x1edb, 0x1edc),\n        (0x1edd, 0x1ede),\n        (0x1edf, 0x1ee0),\n        (0x1ee1, 0x1ee2),\n        (0x1ee3, 0x1ee4),\n        (0x1ee5, 0x1ee6),\n        (0x1ee7, 0x1ee8),\n        (0x1ee9, 0x1eea),\n        (0x1eeb, 0x1eec),\n        (0x1eed, 0x1eee),\n        (0x1eef, 0x1ef0),\n        (0x1ef1, 0x1ef2),\n        (0x1ef3, 0x1ef4),\n        (0x1ef5, 0x1ef6),\n        (0x1ef7, 0x1ef8),\n        (0x1ef9, 0x1efa),\n        (0x1efb, 0x1efc),\n        (0x1efd, 0x1efe),\n        (0x1eff, 0x1f08),\n        (0x1f10, 0x1f16),\n        (0x1f20, 0x1f28),\n        (0x1f30, 0x1f38),\n        (0x1f40, 0x1f46),\n        (0x1f50, 0x1f58),\n        (0x1f60, 0x1f68),\n        (0x1f70, 0x1f71),\n        (0x1f72, 0x1f73),\n        (0x1f74, 0x1f75),\n        (0x1f76, 0x1f77),\n        (0x1f78, 0x1f79),\n        (0x1f7a, 0x1f7b),\n        (0x1f7c, 0x1f7d),\n        (0x1fb0, 0x1fb2),\n        (0x1fb6, 0x1fb7),\n        (0x1fc6, 0x1fc7),\n        (0x1fd0, 0x1fd3),\n        (0x1fd6, 0x1fd8),\n        (0x1fe0, 0x1fe3),\n        (0x1fe4, 0x1fe8),\n        (0x1ff6, 0x1ff7),\n        (0x214e, 0x214f),\n        (0x2184, 0x2185),\n        (0x2c30, 0x2c5f),\n        (0x2c61, 0x2c62),\n        (0x2c65, 0x2c67),\n        (0x2c68, 0x2c69),\n        (0x2c6a, 0x2c6b),\n        (0x2c6c, 0x2c6d),\n        (0x2c71, 0x2c72),\n        (0x2c73, 0x2c75),\n        (0x2c76, 0x2c7c),\n        (0x2c81, 0x2c82),\n        (0x2c83, 0x2c84),\n        (0x2c85, 0x2c86),\n        (0x2c87, 0x2c88),\n        (0x2c89, 0x2c8a),\n        (0x2c8b, 0x2c8c),\n        (0x2c8d, 0x2c8e),\n        (0x2c8f, 0x2c90),\n        (0x2c91, 0x2c92),\n        (0x2c93, 0x2c94),\n        (0x2c95, 0x2c96),\n        (0x2c97, 0x2c98),\n        (0x2c99, 0x2c9a),\n        (0x2c9b, 0x2c9c),\n        (0x2c9d, 0x2c9e),\n        (0x2c9f, 0x2ca0),\n        (0x2ca1, 0x2ca2),\n        (0x2ca3, 0x2ca4),\n        (0x2ca5, 0x2ca6),\n        (0x2ca7, 0x2ca8),\n        (0x2ca9, 0x2caa),\n        (0x2cab, 0x2cac),\n        (0x2cad, 0x2cae),\n        (0x2caf, 0x2cb0),\n        (0x2cb1, 0x2cb2),\n        (0x2cb3, 0x2cb4),\n        (0x2cb5, 0x2cb6),\n        (0x2cb7, 0x2cb8),\n        (0x2cb9, 0x2cba),\n        (0x2cbb, 0x2cbc),\n        (0x2cbd, 0x2cbe),\n        (0x2cbf, 0x2cc0),\n        (0x2cc1, 0x2cc2),\n        (0x2cc3, 0x2cc4),\n        (0x2cc5, 0x2cc6),\n        (0x2cc7, 0x2cc8),\n        (0x2cc9, 0x2cca),\n        (0x2ccb, 0x2ccc),\n        (0x2ccd, 0x2cce),\n        (0x2ccf, 0x2cd0),\n        (0x2cd1, 0x2cd2),\n        (0x2cd3, 0x2cd4),\n        (0x2cd5, 0x2cd6),\n        (0x2cd7, 0x2cd8),\n        (0x2cd9, 0x2cda),\n        (0x2cdb, 0x2cdc),\n        (0x2cdd, 0x2cde),\n        (0x2cdf, 0x2ce0),\n        (0x2ce1, 0x2ce2),\n        (0x2ce3, 0x2ce5),\n        (0x2cec, 0x2ced),\n        (0x2cee, 0x2cf2),\n        (0x2cf3, 0x2cf4),\n        (0x2d00, 0x2d26),\n        (0x2d27, 0x2d28),\n        (0x2d2d, 0x2d2e),\n        (0x2d30, 0x2d68),\n        (0x2d7f, 0x2d97),\n        (0x2da0, 0x2da7),\n        (0x2da8, 0x2daf),\n        (0x2db0, 0x2db7),\n        (0x2db8, 0x2dbf),\n        (0x2dc0, 0x2dc7),\n        (0x2dc8, 0x2dcf),\n        (0x2dd0, 0x2dd7),\n        (0x2dd8, 0x2ddf),\n        (0x2de0, 0x2e00),\n        (0x2e2f, 0x2e30),\n        (0x3005, 0x3008),\n        (0x302a, 0x302e),\n        (0x303c, 0x303d),\n        (0x3041, 0x3097),\n        (0x3099, 0x309b),\n        (0x309d, 0x309f),\n        (0x30a1, 0x30fb),\n        (0x30fc, 0x30ff),\n        (0x3105, 0x312e),\n        (0x31a0, 0x31bb),\n        (0x31f0, 0x3200),\n        (0x3400, 0x4db6),\n        (0x4e00, 0x9fcd),\n        (0xa000, 0xa48d),\n        (0xa4d0, 0xa4fe),\n        (0xa500, 0xa60d),\n        (0xa610, 0xa62c),\n        (0xa641, 0xa642),\n        (0xa643, 0xa644),\n        (0xa645, 0xa646),\n        (0xa647, 0xa648),\n        (0xa649, 0xa64a),\n        (0xa64b, 0xa64c),\n        (0xa64d, 0xa64e),\n        (0xa64f, 0xa650),\n        (0xa651, 0xa652),\n        (0xa653, 0xa654),\n        (0xa655, 0xa656),\n        (0xa657, 0xa658),\n        (0xa659, 0xa65a),\n        (0xa65b, 0xa65c),\n        (0xa65d, 0xa65e),\n        (0xa65f, 0xa660),\n        (0xa661, 0xa662),\n        (0xa663, 0xa664),\n        (0xa665, 0xa666),\n        (0xa667, 0xa668),\n        (0xa669, 0xa66a),\n        (0xa66b, 0xa66c),\n        (0xa66d, 0xa670),\n        (0xa674, 0xa67e),\n        (0xa67f, 0xa680),\n        (0xa681, 0xa682),\n        (0xa683, 0xa684),\n        (0xa685, 0xa686),\n        (0xa687, 0xa688),\n        (0xa689, 0xa68a),\n        (0xa68b, 0xa68c),\n        (0xa68d, 0xa68e),\n        (0xa68f, 0xa690),\n        (0xa691, 0xa692),\n        (0xa693, 0xa694),\n        (0xa695, 0xa696),\n        (0xa697, 0xa698),\n        (0xa69f, 0xa6e6),\n        (0xa6f0, 0xa6f2),\n        (0xa717, 0xa720),\n        (0xa723, 0xa724),\n        (0xa725, 0xa726),\n        (0xa727, 0xa728),\n        (0xa729, 0xa72a),\n        (0xa72b, 0xa72c),\n        (0xa72d, 0xa72e),\n        (0xa72f, 0xa732),\n        (0xa733, 0xa734),\n        (0xa735, 0xa736),\n        (0xa737, 0xa738),\n        (0xa739, 0xa73a),\n        (0xa73b, 0xa73c),\n        (0xa73d, 0xa73e),\n        (0xa73f, 0xa740),\n        (0xa741, 0xa742),\n        (0xa743, 0xa744),\n        (0xa745, 0xa746),\n        (0xa747, 0xa748),\n        (0xa749, 0xa74a),\n        (0xa74b, 0xa74c),\n        (0xa74d, 0xa74e),\n        (0xa74f, 0xa750),\n        (0xa751, 0xa752),\n        (0xa753, 0xa754),\n        (0xa755, 0xa756),\n        (0xa757, 0xa758),\n        (0xa759, 0xa75a),\n        (0xa75b, 0xa75c),\n        (0xa75d, 0xa75e),\n        (0xa75f, 0xa760),\n        (0xa761, 0xa762),\n        (0xa763, 0xa764),\n        (0xa765, 0xa766),\n        (0xa767, 0xa768),\n        (0xa769, 0xa76a),\n        (0xa76b, 0xa76c),\n        (0xa76d, 0xa76e),\n        (0xa76f, 0xa770),\n        (0xa771, 0xa779),\n        (0xa77a, 0xa77b),\n        (0xa77c, 0xa77d),\n        (0xa77f, 0xa780),\n        (0xa781, 0xa782),\n        (0xa783, 0xa784),\n        (0xa785, 0xa786),\n        (0xa787, 0xa789),\n        (0xa78c, 0xa78d),\n        (0xa78e, 0xa78f),\n        (0xa791, 0xa792),\n        (0xa793, 0xa794),\n        (0xa7a1, 0xa7a2),\n        (0xa7a3, 0xa7a4),\n        (0xa7a5, 0xa7a6),\n        (0xa7a7, 0xa7a8),\n        (0xa7a9, 0xa7aa),\n        (0xa7fa, 0xa828),\n        (0xa840, 0xa874),\n        (0xa880, 0xa8c5),\n        (0xa8d0, 0xa8da),\n        (0xa8e0, 0xa8f8),\n        (0xa8fb, 0xa8fc),\n        (0xa900, 0xa92e),\n        (0xa930, 0xa954),\n        (0xa980, 0xa9c1),\n        (0xa9cf, 0xa9da),\n        (0xaa00, 0xaa37),\n        (0xaa40, 0xaa4e),\n        (0xaa50, 0xaa5a),\n        (0xaa60, 0xaa77),\n        (0xaa7a, 0xaa7c),\n        (0xaa80, 0xaac3),\n        (0xaadb, 0xaade),\n        (0xaae0, 0xaaf0),\n        (0xaaf2, 0xaaf7),\n        (0xab01, 0xab07),\n        (0xab09, 0xab0f),\n        (0xab11, 0xab17),\n        (0xab20, 0xab27),\n        (0xab28, 0xab2f),\n        (0xabc0, 0xabeb),\n        (0xabec, 0xabee),\n        (0xabf0, 0xabfa),\n        (0xac00, 0xd7a4),\n        (0xfa0e, 0xfa10),\n        (0xfa11, 0xfa12),\n        (0xfa13, 0xfa15),\n        (0xfa1f, 0xfa20),\n        (0xfa21, 0xfa22),\n        (0xfa23, 0xfa25),\n        (0xfa27, 0xfa2a),\n        (0xfb1e, 0xfb1f),\n        (0xfe20, 0xfe27),\n        (0xfe73, 0xfe74),\n        (0x10000, 0x1000c),\n        (0x1000d, 0x10027),\n        (0x10028, 0x1003b),\n        (0x1003c, 0x1003e),\n        (0x1003f, 0x1004e),\n        (0x10050, 0x1005e),\n        (0x10080, 0x100fb),\n        (0x101fd, 0x101fe),\n        (0x10280, 0x1029d),\n        (0x102a0, 0x102d1),\n        (0x10300, 0x1031f),\n        (0x10330, 0x10341),\n        (0x10342, 0x1034a),\n        (0x10380, 0x1039e),\n        (0x103a0, 0x103c4),\n        (0x103c8, 0x103d0),\n        (0x10428, 0x1049e),\n        (0x104a0, 0x104aa),\n        (0x10800, 0x10806),\n        (0x10808, 0x10809),\n        (0x1080a, 0x10836),\n        (0x10837, 0x10839),\n        (0x1083c, 0x1083d),\n        (0x1083f, 0x10856),\n        (0x10900, 0x10916),\n        (0x10920, 0x1093a),\n        (0x10980, 0x109b8),\n        (0x109be, 0x109c0),\n        (0x10a00, 0x10a04),\n        (0x10a05, 0x10a07),\n        (0x10a0c, 0x10a14),\n        (0x10a15, 0x10a18),\n        (0x10a19, 0x10a34),\n        (0x10a38, 0x10a3b),\n        (0x10a3f, 0x10a40),\n        (0x10a60, 0x10a7d),\n        (0x10b00, 0x10b36),\n        (0x10b40, 0x10b56),\n        (0x10b60, 0x10b73),\n        (0x10c00, 0x10c49),\n        (0x11000, 0x11047),\n        (0x11066, 0x11070),\n        (0x11080, 0x110bb),\n        (0x110d0, 0x110e9),\n        (0x110f0, 0x110fa),\n        (0x11100, 0x11135),\n        (0x11136, 0x11140),\n        (0x11180, 0x111c5),\n        (0x111d0, 0x111da),\n        (0x11680, 0x116b8),\n        (0x116c0, 0x116ca),\n        (0x12000, 0x1236f),\n        (0x13000, 0x1342f),\n        (0x16800, 0x16a39),\n        (0x16f00, 0x16f45),\n        (0x16f50, 0x16f7f),\n        (0x16f8f, 0x16fa0),\n        (0x1b000, 0x1b002),\n        (0x20000, 0x2a6d7),\n        (0x2a700, 0x2b735),\n        (0x2b740, 0x2b81e),\n    ),\n    'CONTEXTJ': (\n        (0x200c, 0x200e),\n    ),\n    'CONTEXTO': (\n        (0xb7, 0xb8),\n        (0x375, 0x376),\n        (0x5f3, 0x5f5),\n        (0x660, 0x66a),\n        (0x6f0, 0x6fa),\n        (0x30fb, 0x30fc),\n    ),\n}\n"
  },
  {
    "path": "code/default/lib/noarch/idna/intranges.py",
    "content": "\"\"\"\nGiven a list of integers, made up of (hopefully) a small number of long runs\nof consecutive integers, compute a representation of the form\n((start1, end1), (start2, end2) ...). Then answer the question \"was x present\nin the original list?\" in time O(log(# runs)).\n\"\"\"\n\nimport bisect\n\ndef intranges_from_list(list_):\n    \"\"\"Represent a list of integers as a sequence of ranges:\n    ((start_0, end_0), (start_1, end_1), ...), such that the original\n    integers are exactly those x such that start_i <= x < end_i for some i.\n    \"\"\"\n\n    sorted_list = sorted(list_)\n    ranges = []\n    last_write = -1\n    for i in range(len(sorted_list)):\n        if i+1 < len(sorted_list):\n            if sorted_list[i] == sorted_list[i+1]-1:\n                continue\n        current_range = sorted_list[last_write+1:i+1]\n        range_tuple = (current_range[0], current_range[-1] + 1)\n        ranges.append(range_tuple)\n        last_write = i\n\n    return tuple(ranges)\n\n\ndef intranges_contain(int_, ranges):\n    \"\"\"Determine if `int_` falls into one of the ranges in `ranges`.\"\"\"\n    tuple_ = (int_, int_)\n    pos = bisect.bisect_left(ranges, tuple_)\n    # we could be immediately ahead of a tuple (start, end)\n    # with start < int_ <= end\n    if pos > 0:\n        left, right = ranges[pos-1]\n        if left <= int_ < right:\n            return True\n    # or we could be immediately behind a tuple (int_, end)\n    if pos < len(ranges):\n        left, _ = ranges[pos]\n        if left == int_:\n            return True\n    return False\n"
  },
  {
    "path": "code/default/lib/noarch/idna/uts46data.py",
    "content": "# This file is automatically generated by tools/build-uts46data.py\n# vim: set fileencoding=utf-8 :\n\n\"\"\"IDNA Mapping Table from UTS46.\"\"\"\n\nuts46data = (\n    (0x0, '3'),\n    (0x1, '3'),\n    (0x2, '3'),\n    (0x3, '3'),\n    (0x4, '3'),\n    (0x5, '3'),\n    (0x6, '3'),\n    (0x7, '3'),\n    (0x8, '3'),\n    (0x9, '3'),\n    (0xA, '3'),\n    (0xB, '3'),\n    (0xC, '3'),\n    (0xD, '3'),\n    (0xE, '3'),\n    (0xF, '3'),\n    (0x10, '3'),\n    (0x11, '3'),\n    (0x12, '3'),\n    (0x13, '3'),\n    (0x14, '3'),\n    (0x15, '3'),\n    (0x16, '3'),\n    (0x17, '3'),\n    (0x18, '3'),\n    (0x19, '3'),\n    (0x1A, '3'),\n    (0x1B, '3'),\n    (0x1C, '3'),\n    (0x1D, '3'),\n    (0x1E, '3'),\n    (0x1F, '3'),\n    (0x20, '3'),\n    (0x21, '3'),\n    (0x22, '3'),\n    (0x23, '3'),\n    (0x24, '3'),\n    (0x25, '3'),\n    (0x26, '3'),\n    (0x27, '3'),\n    (0x28, '3'),\n    (0x29, '3'),\n    (0x2A, '3'),\n    (0x2B, '3'),\n    (0x2C, '3'),\n    (0x2D, 'V'),\n    (0x2E, 'V'),\n    (0x2F, '3'),\n    (0x30, 'V'),\n    (0x31, 'V'),\n    (0x32, 'V'),\n    (0x33, 'V'),\n    (0x34, 'V'),\n    (0x35, 'V'),\n    (0x36, 'V'),\n    (0x37, 'V'),\n    (0x38, 'V'),\n    (0x39, 'V'),\n    (0x3A, '3'),\n    (0x3B, '3'),\n    (0x3C, '3'),\n    (0x3D, '3'),\n    (0x3E, '3'),\n    (0x3F, '3'),\n    (0x40, '3'),\n    (0x41, 'M', 'a'),\n    (0x42, 'M', 'b'),\n    (0x43, 'M', 'c'),\n    (0x44, 'M', 'd'),\n    (0x45, 'M', 'e'),\n    (0x46, 'M', 'f'),\n    (0x47, 'M', 'g'),\n    (0x48, 'M', 'h'),\n    (0x49, 'M', 'i'),\n    (0x4A, 'M', 'j'),\n    (0x4B, 'M', 'k'),\n    (0x4C, 'M', 'l'),\n    (0x4D, 'M', 'm'),\n    (0x4E, 'M', 'n'),\n    (0x4F, 'M', 'o'),\n    (0x50, 'M', 'p'),\n    (0x51, 'M', 'q'),\n    (0x52, 'M', 'r'),\n    (0x53, 'M', 's'),\n    (0x54, 'M', 't'),\n    (0x55, 'M', 'u'),\n    (0x56, 'M', 'v'),\n    (0x57, 'M', 'w'),\n    (0x58, 'M', 'x'),\n    (0x59, 'M', 'y'),\n    (0x5A, 'M', 'z'),\n    (0x5B, '3'),\n    (0x5C, '3'),\n    (0x5D, '3'),\n    (0x5E, '3'),\n    (0x5F, '3'),\n    (0x60, '3'),\n    (0x61, 'V'),\n    (0x62, 'V'),\n    (0x63, 'V'),\n    (0x64, 'V'),\n    (0x65, 'V'),\n    (0x66, 'V'),\n    (0x67, 'V'),\n    (0x68, 'V'),\n    (0x69, 'V'),\n    (0x6A, 'V'),\n    (0x6B, 'V'),\n    (0x6C, 'V'),\n    (0x6D, 'V'),\n    (0x6E, 'V'),\n    (0x6F, 'V'),\n    (0x70, 'V'),\n    (0x71, 'V'),\n    (0x72, 'V'),\n    (0x73, 'V'),\n    (0x74, 'V'),\n    (0x75, 'V'),\n    (0x76, 'V'),\n    (0x77, 'V'),\n    (0x78, 'V'),\n    (0x79, 'V'),\n    (0x7A, 'V'),\n    (0x7B, '3'),\n    (0x7C, '3'),\n    (0x7D, '3'),\n    (0x7E, '3'),\n    (0x7F, '3'),\n    (0x80, 'X'),\n    (0x81, 'X'),\n    (0x82, 'X'),\n    (0x83, 'X'),\n    (0x84, 'X'),\n    (0x85, 'X'),\n    (0x86, 'X'),\n    (0x87, 'X'),\n    (0x88, 'X'),\n    (0x89, 'X'),\n    (0x8A, 'X'),\n    (0x8B, 'X'),\n    (0x8C, 'X'),\n    (0x8D, 'X'),\n    (0x8E, 'X'),\n    (0x8F, 'X'),\n    (0x90, 'X'),\n    (0x91, 'X'),\n    (0x92, 'X'),\n    (0x93, 'X'),\n    (0x94, 'X'),\n    (0x95, 'X'),\n    (0x96, 'X'),\n    (0x97, 'X'),\n    (0x98, 'X'),\n    (0x99, 'X'),\n    (0x9A, 'X'),\n    (0x9B, 'X'),\n    (0x9C, 'X'),\n    (0x9D, 'X'),\n    (0x9E, 'X'),\n    (0x9F, 'X'),\n    (0xA0, '3', ' '),\n    (0xA1, 'V'),\n    (0xA2, 'V'),\n    (0xA3, 'V'),\n    (0xA4, 'V'),\n    (0xA5, 'V'),\n    (0xA6, 'V'),\n    (0xA7, 'V'),\n    (0xA8, '3', ' ̈'),\n    (0xA9, 'V'),\n    (0xAA, 'M', 'a'),\n    (0xAB, 'V'),\n    (0xAC, 'V'),\n    (0xAD, 'I'),\n    (0xAE, 'V'),\n    (0xAF, '3', ' ̄'),\n    (0xB0, 'V'),\n    (0xB1, 'V'),\n    (0xB2, 'M', '2'),\n    (0xB3, 'M', '3'),\n    (0xB4, '3', ' ́'),\n    (0xB5, 'M', 'μ'),\n    (0xB6, 'V'),\n    (0xB7, 'V'),\n    (0xB8, '3', ' ̧'),\n    (0xB9, 'M', '1'),\n    (0xBA, 'M', 'o'),\n    (0xBB, 'V'),\n    (0xBC, 'M', '1⁄4'),\n    (0xBD, 'M', '1⁄2'),\n    (0xBE, 'M', '3⁄4'),\n    (0xBF, 'V'),\n    (0xC0, 'M', 'à'),\n    (0xC1, 'M', 'á'),\n    (0xC2, 'M', 'â'),\n    (0xC3, 'M', 'ã'),\n    (0xC4, 'M', 'ä'),\n    (0xC5, 'M', 'å'),\n    (0xC6, 'M', 'æ'),\n    (0xC7, 'M', 'ç'),\n    (0xC8, 'M', 'è'),\n    (0xC9, 'M', 'é'),\n    (0xCA, 'M', 'ê'),\n    (0xCB, 'M', 'ë'),\n    (0xCC, 'M', 'ì'),\n    (0xCD, 'M', 'í'),\n    (0xCE, 'M', 'î'),\n    (0xCF, 'M', 'ï'),\n    (0xD0, 'M', 'ð'),\n    (0xD1, 'M', 'ñ'),\n    (0xD2, 'M', 'ò'),\n    (0xD3, 'M', 'ó'),\n    (0xD4, 'M', 'ô'),\n    (0xD5, 'M', 'õ'),\n    (0xD6, 'M', 'ö'),\n    (0xD7, 'V'),\n    (0xD8, 'M', 'ø'),\n    (0xD9, 'M', 'ù'),\n    (0xDA, 'M', 'ú'),\n    (0xDB, 'M', 'û'),\n    (0xDC, 'M', 'ü'),\n    (0xDD, 'M', 'ý'),\n    (0xDE, 'M', 'þ'),\n    (0xDF, 'D', 'ss'),\n    (0xE0, 'V'),\n    (0xE1, 'V'),\n    (0xE2, 'V'),\n    (0xE3, 'V'),\n    (0xE4, 'V'),\n    (0xE5, 'V'),\n    (0xE6, 'V'),\n    (0xE7, 'V'),\n    (0xE8, 'V'),\n    (0xE9, 'V'),\n    (0xEA, 'V'),\n    (0xEB, 'V'),\n    (0xEC, 'V'),\n    (0xED, 'V'),\n    (0xEE, 'V'),\n    (0xEF, 'V'),\n    (0xF0, 'V'),\n    (0xF1, 'V'),\n    (0xF2, 'V'),\n    (0xF3, 'V'),\n    (0xF4, 'V'),\n    (0xF5, 'V'),\n    (0xF6, 'V'),\n    (0xF7, 'V'),\n    (0xF8, 'V'),\n    (0xF9, 'V'),\n    (0xFA, 'V'),\n    (0xFB, 'V'),\n    (0xFC, 'V'),\n    (0xFD, 'V'),\n    (0xFE, 'V'),\n    (0xFF, 'V'),\n    (0x100, 'M', 'ā'),\n    (0x101, 'V'),\n    (0x102, 'M', 'ă'),\n    (0x103, 'V'),\n    (0x104, 'M', 'ą'),\n    (0x105, 'V'),\n    (0x106, 'M', 'ć'),\n    (0x107, 'V'),\n    (0x108, 'M', 'ĉ'),\n    (0x109, 'V'),\n    (0x10A, 'M', 'ċ'),\n    (0x10B, 'V'),\n    (0x10C, 'M', 'č'),\n    (0x10D, 'V'),\n    (0x10E, 'M', 'ď'),\n    (0x10F, 'V'),\n    (0x110, 'M', 'đ'),\n    (0x111, 'V'),\n    (0x112, 'M', 'ē'),\n    (0x113, 'V'),\n    (0x114, 'M', 'ĕ'),\n    (0x115, 'V'),\n    (0x116, 'M', 'ė'),\n    (0x117, 'V'),\n    (0x118, 'M', 'ę'),\n    (0x119, 'V'),\n    (0x11A, 'M', 'ě'),\n    (0x11B, 'V'),\n    (0x11C, 'M', 'ĝ'),\n    (0x11D, 'V'),\n    (0x11E, 'M', 'ğ'),\n    (0x11F, 'V'),\n    (0x120, 'M', 'ġ'),\n    (0x121, 'V'),\n    (0x122, 'M', 'ģ'),\n    (0x123, 'V'),\n    (0x124, 'M', 'ĥ'),\n    (0x125, 'V'),\n    (0x126, 'M', 'ħ'),\n    (0x127, 'V'),\n    (0x128, 'M', 'ĩ'),\n    (0x129, 'V'),\n    (0x12A, 'M', 'ī'),\n    (0x12B, 'V'),\n    (0x12C, 'M', 'ĭ'),\n    (0x12D, 'V'),\n    (0x12E, 'M', 'į'),\n    (0x12F, 'V'),\n    (0x130, 'M', 'i̇'),\n    (0x131, 'V'),\n    (0x132, 'M', 'ij'),\n    (0x134, 'M', 'ĵ'),\n    (0x135, 'V'),\n    (0x136, 'M', 'ķ'),\n    (0x137, 'V'),\n    (0x139, 'M', 'ĺ'),\n    (0x13A, 'V'),\n    (0x13B, 'M', 'ļ'),\n    (0x13C, 'V'),\n    (0x13D, 'M', 'ľ'),\n    (0x13E, 'V'),\n    (0x13F, 'M', 'l·'),\n    (0x141, 'M', 'ł'),\n    (0x142, 'V'),\n    (0x143, 'M', 'ń'),\n    (0x144, 'V'),\n    (0x145, 'M', 'ņ'),\n    (0x146, 'V'),\n    (0x147, 'M', 'ň'),\n    (0x148, 'V'),\n    (0x149, 'M', 'ʼn'),\n    (0x14A, 'M', 'ŋ'),\n    (0x14B, 'V'),\n    (0x14C, 'M', 'ō'),\n    (0x14D, 'V'),\n    (0x14E, 'M', 'ŏ'),\n    (0x14F, 'V'),\n    (0x150, 'M', 'ő'),\n    (0x151, 'V'),\n    (0x152, 'M', 'œ'),\n    (0x153, 'V'),\n    (0x154, 'M', 'ŕ'),\n    (0x155, 'V'),\n    (0x156, 'M', 'ŗ'),\n    (0x157, 'V'),\n    (0x158, 'M', 'ř'),\n    (0x159, 'V'),\n    (0x15A, 'M', 'ś'),\n    (0x15B, 'V'),\n    (0x15C, 'M', 'ŝ'),\n    (0x15D, 'V'),\n    (0x15E, 'M', 'ş'),\n    (0x15F, 'V'),\n    (0x160, 'M', 'š'),\n    (0x161, 'V'),\n    (0x162, 'M', 'ţ'),\n    (0x163, 'V'),\n    (0x164, 'M', 'ť'),\n    (0x165, 'V'),\n    (0x166, 'M', 'ŧ'),\n    (0x167, 'V'),\n    (0x168, 'M', 'ũ'),\n    (0x169, 'V'),\n    (0x16A, 'M', 'ū'),\n    (0x16B, 'V'),\n    (0x16C, 'M', 'ŭ'),\n    (0x16D, 'V'),\n    (0x16E, 'M', 'ů'),\n    (0x16F, 'V'),\n    (0x170, 'M', 'ű'),\n    (0x171, 'V'),\n    (0x172, 'M', 'ų'),\n    (0x173, 'V'),\n    (0x174, 'M', 'ŵ'),\n    (0x175, 'V'),\n    (0x176, 'M', 'ŷ'),\n    (0x177, 'V'),\n    (0x178, 'M', 'ÿ'),\n    (0x179, 'M', 'ź'),\n    (0x17A, 'V'),\n    (0x17B, 'M', 'ż'),\n    (0x17C, 'V'),\n    (0x17D, 'M', 'ž'),\n    (0x17E, 'V'),\n    (0x17F, 'M', 's'),\n    (0x180, 'V'),\n    (0x181, 'M', 'ɓ'),\n    (0x182, 'M', 'ƃ'),\n    (0x183, 'V'),\n    (0x184, 'M', 'ƅ'),\n    (0x185, 'V'),\n    (0x186, 'M', 'ɔ'),\n    (0x187, 'M', 'ƈ'),\n    (0x188, 'V'),\n    (0x189, 'M', 'ɖ'),\n    (0x18A, 'M', 'ɗ'),\n    (0x18B, 'M', 'ƌ'),\n    (0x18C, 'V'),\n    (0x18E, 'M', 'ǝ'),\n    (0x18F, 'M', 'ə'),\n    (0x190, 'M', 'ɛ'),\n    (0x191, 'M', 'ƒ'),\n    (0x192, 'V'),\n    (0x193, 'M', 'ɠ'),\n    (0x194, 'M', 'ɣ'),\n    (0x195, 'V'),\n    (0x196, 'M', 'ɩ'),\n    (0x197, 'M', 'ɨ'),\n    (0x198, 'M', 'ƙ'),\n    (0x199, 'V'),\n    (0x19C, 'M', 'ɯ'),\n    (0x19D, 'M', 'ɲ'),\n    (0x19E, 'V'),\n    (0x19F, 'M', 'ɵ'),\n    (0x1A0, 'M', 'ơ'),\n    (0x1A1, 'V'),\n    (0x1A2, 'M', 'ƣ'),\n    (0x1A3, 'V'),\n    (0x1A4, 'M', 'ƥ'),\n    (0x1A5, 'V'),\n    (0x1A6, 'M', 'ʀ'),\n    (0x1A7, 'M', 'ƨ'),\n    (0x1A8, 'V'),\n    (0x1A9, 'M', 'ʃ'),\n    (0x1AA, 'V'),\n    (0x1AC, 'M', 'ƭ'),\n    (0x1AD, 'V'),\n    (0x1AE, 'M', 'ʈ'),\n    (0x1AF, 'M', 'ư'),\n    (0x1B0, 'V'),\n    (0x1B1, 'M', 'ʊ'),\n    (0x1B2, 'M', 'ʋ'),\n    (0x1B3, 'M', 'ƴ'),\n    (0x1B4, 'V'),\n    (0x1B5, 'M', 'ƶ'),\n    (0x1B6, 'V'),\n    (0x1B7, 'M', 'ʒ'),\n    (0x1B8, 'M', 'ƹ'),\n    (0x1B9, 'V'),\n    (0x1BC, 'M', 'ƽ'),\n    (0x1BD, 'V'),\n    (0x1C4, 'M', 'dž'),\n    (0x1C7, 'M', 'lj'),\n    (0x1CA, 'M', 'nj'),\n    (0x1CD, 'M', 'ǎ'),\n    (0x1CE, 'V'),\n    (0x1CF, 'M', 'ǐ'),\n    (0x1D0, 'V'),\n    (0x1D1, 'M', 'ǒ'),\n    (0x1D2, 'V'),\n    (0x1D3, 'M', 'ǔ'),\n    (0x1D4, 'V'),\n    (0x1D5, 'M', 'ǖ'),\n    (0x1D6, 'V'),\n    (0x1D7, 'M', 'ǘ'),\n    (0x1D8, 'V'),\n    (0x1D9, 'M', 'ǚ'),\n    (0x1DA, 'V'),\n    (0x1DB, 'M', 'ǜ'),\n    (0x1DC, 'V'),\n    (0x1DE, 'M', 'ǟ'),\n    (0x1DF, 'V'),\n    (0x1E0, 'M', 'ǡ'),\n    (0x1E1, 'V'),\n    (0x1E2, 'M', 'ǣ'),\n    (0x1E3, 'V'),\n    (0x1E4, 'M', 'ǥ'),\n    (0x1E5, 'V'),\n    (0x1E6, 'M', 'ǧ'),\n    (0x1E7, 'V'),\n    (0x1E8, 'M', 'ǩ'),\n    (0x1E9, 'V'),\n    (0x1EA, 'M', 'ǫ'),\n    (0x1EB, 'V'),\n    (0x1EC, 'M', 'ǭ'),\n    (0x1ED, 'V'),\n    (0x1EE, 'M', 'ǯ'),\n    (0x1EF, 'V'),\n    (0x1F1, 'M', 'dz'),\n    (0x1F4, 'M', 'ǵ'),\n    (0x1F5, 'V'),\n    (0x1F6, 'M', 'ƕ'),\n    (0x1F7, 'M', 'ƿ'),\n    (0x1F8, 'M', 'ǹ'),\n    (0x1F9, 'V'),\n    (0x1FA, 'M', 'ǻ'),\n    (0x1FB, 'V'),\n    (0x1FC, 'M', 'ǽ'),\n    (0x1FD, 'V'),\n    (0x1FE, 'M', 'ǿ'),\n    (0x1FF, 'V'),\n    (0x200, 'M', 'ȁ'),\n    (0x201, 'V'),\n    (0x202, 'M', 'ȃ'),\n    (0x203, 'V'),\n    (0x204, 'M', 'ȅ'),\n    (0x205, 'V'),\n    (0x206, 'M', 'ȇ'),\n    (0x207, 'V'),\n    (0x208, 'M', 'ȉ'),\n    (0x209, 'V'),\n    (0x20A, 'M', 'ȋ'),\n    (0x20B, 'V'),\n    (0x20C, 'M', 'ȍ'),\n    (0x20D, 'V'),\n    (0x20E, 'M', 'ȏ'),\n    (0x20F, 'V'),\n    (0x210, 'M', 'ȑ'),\n    (0x211, 'V'),\n    (0x212, 'M', 'ȓ'),\n    (0x213, 'V'),\n    (0x214, 'M', 'ȕ'),\n    (0x215, 'V'),\n    (0x216, 'M', 'ȗ'),\n    (0x217, 'V'),\n    (0x218, 'M', 'ș'),\n    (0x219, 'V'),\n    (0x21A, 'M', 'ț'),\n    (0x21B, 'V'),\n    (0x21C, 'M', 'ȝ'),\n    (0x21D, 'V'),\n    (0x21E, 'M', 'ȟ'),\n    (0x21F, 'V'),\n    (0x220, 'M', 'ƞ'),\n    (0x221, 'V'),\n    (0x222, 'M', 'ȣ'),\n    (0x223, 'V'),\n    (0x224, 'M', 'ȥ'),\n    (0x225, 'V'),\n    (0x226, 'M', 'ȧ'),\n    (0x227, 'V'),\n    (0x228, 'M', 'ȩ'),\n    (0x229, 'V'),\n    (0x22A, 'M', 'ȫ'),\n    (0x22B, 'V'),\n    (0x22C, 'M', 'ȭ'),\n    (0x22D, 'V'),\n    (0x22E, 'M', 'ȯ'),\n    (0x22F, 'V'),\n    (0x230, 'M', 'ȱ'),\n    (0x231, 'V'),\n    (0x232, 'M', 'ȳ'),\n    (0x233, 'V'),\n    (0x23A, 'M', 'ⱥ'),\n    (0x23B, 'M', 'ȼ'),\n    (0x23C, 'V'),\n    (0x23D, 'M', 'ƚ'),\n    (0x23E, 'M', 'ⱦ'),\n    (0x23F, 'V'),\n    (0x241, 'M', 'ɂ'),\n    (0x242, 'V'),\n    (0x243, 'M', 'ƀ'),\n    (0x244, 'M', 'ʉ'),\n    (0x245, 'M', 'ʌ'),\n    (0x246, 'M', 'ɇ'),\n    (0x247, 'V'),\n    (0x248, 'M', 'ɉ'),\n    (0x249, 'V'),\n    (0x24A, 'M', 'ɋ'),\n    (0x24B, 'V'),\n    (0x24C, 'M', 'ɍ'),\n    (0x24D, 'V'),\n    (0x24E, 'M', 'ɏ'),\n    (0x24F, 'V'),\n    (0x2B0, 'M', 'h'),\n    (0x2B1, 'M', 'ɦ'),\n    (0x2B2, 'M', 'j'),\n    (0x2B3, 'M', 'r'),\n    (0x2B4, 'M', 'ɹ'),\n    (0x2B5, 'M', 'ɻ'),\n    (0x2B6, 'M', 'ʁ'),\n    (0x2B7, 'M', 'w'),\n    (0x2B8, 'M', 'y'),\n    (0x2B9, 'V'),\n    (0x2D8, '3', ' ̆'),\n    (0x2D9, '3', ' ̇'),\n    (0x2DA, '3', ' ̊'),\n    (0x2DB, '3', ' ̨'),\n    (0x2DC, '3', ' ̃'),\n    (0x2DD, '3', ' ̋'),\n    (0x2DE, 'V'),\n    (0x2E0, 'M', 'ɣ'),\n    (0x2E1, 'M', 'l'),\n    (0x2E2, 'M', 's'),\n    (0x2E3, 'M', 'x'),\n    (0x2E4, 'M', 'ʕ'),\n    (0x2E5, 'V'),\n    (0x340, 'M', '̀'),\n    (0x341, 'M', '́'),\n    (0x342, 'V'),\n    (0x343, 'M', '̓'),\n    (0x344, 'M', '̈́'),\n    (0x345, 'M', 'ι'),\n    (0x346, 'V'),\n    (0x34F, 'I'),\n    (0x350, 'V'),\n    (0x370, 'M', 'ͱ'),\n    (0x371, 'V'),\n    (0x372, 'M', 'ͳ'),\n    (0x373, 'V'),\n    (0x374, 'M', 'ʹ'),\n    (0x375, 'V'),\n    (0x376, 'M', 'ͷ'),\n    (0x377, 'V'),\n    (0x378, 'X'),\n    (0x37A, '3', ' ι'),\n    (0x37B, 'V'),\n    (0x37E, '3', ';'),\n    (0x37F, 'X'),\n    (0x384, '3', ' ́'),\n    (0x385, '3', ' ̈́'),\n    (0x386, 'M', 'ά'),\n    (0x387, 'M', '·'),\n    (0x388, 'M', 'έ'),\n    (0x389, 'M', 'ή'),\n    (0x38A, 'M', 'ί'),\n    (0x38B, 'X'),\n    (0x38C, 'M', 'ό'),\n    (0x38D, 'X'),\n    (0x38E, 'M', 'ύ'),\n    (0x38F, 'M', 'ώ'),\n    (0x390, 'V'),\n    (0x391, 'M', 'α'),\n    (0x392, 'M', 'β'),\n    (0x393, 'M', 'γ'),\n    (0x394, 'M', 'δ'),\n    (0x395, 'M', 'ε'),\n    (0x396, 'M', 'ζ'),\n    (0x397, 'M', 'η'),\n    (0x398, 'M', 'θ'),\n    (0x399, 'M', 'ι'),\n    (0x39A, 'M', 'κ'),\n    (0x39B, 'M', 'λ'),\n    (0x39C, 'M', 'μ'),\n    (0x39D, 'M', 'ν'),\n    (0x39E, 'M', 'ξ'),\n    (0x39F, 'M', 'ο'),\n    (0x3A0, 'M', 'π'),\n    (0x3A1, 'M', 'ρ'),\n    (0x3A2, 'X'),\n    (0x3A3, 'M', 'σ'),\n    (0x3A4, 'M', 'τ'),\n    (0x3A5, 'M', 'υ'),\n    (0x3A6, 'M', 'φ'),\n    (0x3A7, 'M', 'χ'),\n    (0x3A8, 'M', 'ψ'),\n    (0x3A9, 'M', 'ω'),\n    (0x3AA, 'M', 'ϊ'),\n    (0x3AB, 'M', 'ϋ'),\n    (0x3AC, 'V'),\n    (0x3C2, 'D', 'σ'),\n    (0x3C3, 'V'),\n    (0x3CF, 'M', 'ϗ'),\n    (0x3D0, 'M', 'β'),\n    (0x3D1, 'M', 'θ'),\n    (0x3D2, 'M', 'υ'),\n    (0x3D3, 'M', 'ύ'),\n    (0x3D4, 'M', 'ϋ'),\n    (0x3D5, 'M', 'φ'),\n    (0x3D6, 'M', 'π'),\n    (0x3D7, 'V'),\n    (0x3D8, 'M', 'ϙ'),\n    (0x3D9, 'V'),\n    (0x3DA, 'M', 'ϛ'),\n    (0x3DB, 'V'),\n    (0x3DC, 'M', 'ϝ'),\n    (0x3DD, 'V'),\n    (0x3DE, 'M', 'ϟ'),\n    (0x3DF, 'V'),\n    (0x3E0, 'M', 'ϡ'),\n    (0x3E1, 'V'),\n    (0x3E2, 'M', 'ϣ'),\n    (0x3E3, 'V'),\n    (0x3E4, 'M', 'ϥ'),\n    (0x3E5, 'V'),\n    (0x3E6, 'M', 'ϧ'),\n    (0x3E7, 'V'),\n    (0x3E8, 'M', 'ϩ'),\n    (0x3E9, 'V'),\n    (0x3EA, 'M', 'ϫ'),\n    (0x3EB, 'V'),\n    (0x3EC, 'M', 'ϭ'),\n    (0x3ED, 'V'),\n    (0x3EE, 'M', 'ϯ'),\n    (0x3EF, 'V'),\n    (0x3F0, 'M', 'κ'),\n    (0x3F1, 'M', 'ρ'),\n    (0x3F2, 'M', 'σ'),\n    (0x3F3, 'V'),\n    (0x3F4, 'M', 'θ'),\n    (0x3F5, 'M', 'ε'),\n    (0x3F6, 'V'),\n    (0x3F7, 'M', 'ϸ'),\n    (0x3F8, 'V'),\n    (0x3F9, 'M', 'σ'),\n    (0x3FA, 'M', 'ϻ'),\n    (0x3FB, 'V'),\n    (0x3FD, 'M', 'ͻ'),\n    (0x3FE, 'M', 'ͼ'),\n    (0x3FF, 'M', 'ͽ'),\n    (0x400, 'M', 'ѐ'),\n    (0x401, 'M', 'ё'),\n    (0x402, 'M', 'ђ'),\n    (0x403, 'M', 'ѓ'),\n    (0x404, 'M', 'є'),\n    (0x405, 'M', 'ѕ'),\n    (0x406, 'M', 'і'),\n    (0x407, 'M', 'ї'),\n    (0x408, 'M', 'ј'),\n    (0x409, 'M', 'љ'),\n    (0x40A, 'M', 'њ'),\n    (0x40B, 'M', 'ћ'),\n    (0x40C, 'M', 'ќ'),\n    (0x40D, 'M', 'ѝ'),\n    (0x40E, 'M', 'ў'),\n    (0x40F, 'M', 'џ'),\n    (0x410, 'M', 'а'),\n    (0x411, 'M', 'б'),\n    (0x412, 'M', 'в'),\n    (0x413, 'M', 'г'),\n    (0x414, 'M', 'д'),\n    (0x415, 'M', 'е'),\n    (0x416, 'M', 'ж'),\n    (0x417, 'M', 'з'),\n    (0x418, 'M', 'и'),\n    (0x419, 'M', 'й'),\n    (0x41A, 'M', 'к'),\n    (0x41B, 'M', 'л'),\n    (0x41C, 'M', 'м'),\n    (0x41D, 'M', 'н'),\n    (0x41E, 'M', 'о'),\n    (0x41F, 'M', 'п'),\n    (0x420, 'M', 'р'),\n    (0x421, 'M', 'с'),\n    (0x422, 'M', 'т'),\n    (0x423, 'M', 'у'),\n    (0x424, 'M', 'ф'),\n    (0x425, 'M', 'х'),\n    (0x426, 'M', 'ц'),\n    (0x427, 'M', 'ч'),\n    (0x428, 'M', 'ш'),\n    (0x429, 'M', 'щ'),\n    (0x42A, 'M', 'ъ'),\n    (0x42B, 'M', 'ы'),\n    (0x42C, 'M', 'ь'),\n    (0x42D, 'M', 'э'),\n    (0x42E, 'M', 'ю'),\n    (0x42F, 'M', 'я'),\n    (0x430, 'V'),\n    (0x460, 'M', 'ѡ'),\n    (0x461, 'V'),\n    (0x462, 'M', 'ѣ'),\n    (0x463, 'V'),\n    (0x464, 'M', 'ѥ'),\n    (0x465, 'V'),\n    (0x466, 'M', 'ѧ'),\n    (0x467, 'V'),\n    (0x468, 'M', 'ѩ'),\n    (0x469, 'V'),\n    (0x46A, 'M', 'ѫ'),\n    (0x46B, 'V'),\n    (0x46C, 'M', 'ѭ'),\n    (0x46D, 'V'),\n    (0x46E, 'M', 'ѯ'),\n    (0x46F, 'V'),\n    (0x470, 'M', 'ѱ'),\n    (0x471, 'V'),\n    (0x472, 'M', 'ѳ'),\n    (0x473, 'V'),\n    (0x474, 'M', 'ѵ'),\n    (0x475, 'V'),\n    (0x476, 'M', 'ѷ'),\n    (0x477, 'V'),\n    (0x478, 'M', 'ѹ'),\n    (0x479, 'V'),\n    (0x47A, 'M', 'ѻ'),\n    (0x47B, 'V'),\n    (0x47C, 'M', 'ѽ'),\n    (0x47D, 'V'),\n    (0x47E, 'M', 'ѿ'),\n    (0x47F, 'V'),\n    (0x480, 'M', 'ҁ'),\n    (0x481, 'V'),\n    (0x48A, 'M', 'ҋ'),\n    (0x48B, 'V'),\n    (0x48C, 'M', 'ҍ'),\n    (0x48D, 'V'),\n    (0x48E, 'M', 'ҏ'),\n    (0x48F, 'V'),\n    (0x490, 'M', 'ґ'),\n    (0x491, 'V'),\n    (0x492, 'M', 'ғ'),\n    (0x493, 'V'),\n    (0x494, 'M', 'ҕ'),\n    (0x495, 'V'),\n    (0x496, 'M', 'җ'),\n    (0x497, 'V'),\n    (0x498, 'M', 'ҙ'),\n    (0x499, 'V'),\n    (0x49A, 'M', 'қ'),\n    (0x49B, 'V'),\n    (0x49C, 'M', 'ҝ'),\n    (0x49D, 'V'),\n    (0x49E, 'M', 'ҟ'),\n    (0x49F, 'V'),\n    (0x4A0, 'M', 'ҡ'),\n    (0x4A1, 'V'),\n    (0x4A2, 'M', 'ң'),\n    (0x4A3, 'V'),\n    (0x4A4, 'M', 'ҥ'),\n    (0x4A5, 'V'),\n    (0x4A6, 'M', 'ҧ'),\n    (0x4A7, 'V'),\n    (0x4A8, 'M', 'ҩ'),\n    (0x4A9, 'V'),\n    (0x4AA, 'M', 'ҫ'),\n    (0x4AB, 'V'),\n    (0x4AC, 'M', 'ҭ'),\n    (0x4AD, 'V'),\n    (0x4AE, 'M', 'ү'),\n    (0x4AF, 'V'),\n    (0x4B0, 'M', 'ұ'),\n    (0x4B1, 'V'),\n    (0x4B2, 'M', 'ҳ'),\n    (0x4B3, 'V'),\n    (0x4B4, 'M', 'ҵ'),\n    (0x4B5, 'V'),\n    (0x4B6, 'M', 'ҷ'),\n    (0x4B7, 'V'),\n    (0x4B8, 'M', 'ҹ'),\n    (0x4B9, 'V'),\n    (0x4BA, 'M', 'һ'),\n    (0x4BB, 'V'),\n    (0x4BC, 'M', 'ҽ'),\n    (0x4BD, 'V'),\n    (0x4BE, 'M', 'ҿ'),\n    (0x4BF, 'V'),\n    (0x4C0, 'X'),\n    (0x4C1, 'M', 'ӂ'),\n    (0x4C2, 'V'),\n    (0x4C3, 'M', 'ӄ'),\n    (0x4C4, 'V'),\n    (0x4C5, 'M', 'ӆ'),\n    (0x4C6, 'V'),\n    (0x4C7, 'M', 'ӈ'),\n    (0x4C8, 'V'),\n    (0x4C9, 'M', 'ӊ'),\n    (0x4CA, 'V'),\n    (0x4CB, 'M', 'ӌ'),\n    (0x4CC, 'V'),\n    (0x4CD, 'M', 'ӎ'),\n    (0x4CE, 'V'),\n    (0x4D0, 'M', 'ӑ'),\n    (0x4D1, 'V'),\n    (0x4D2, 'M', 'ӓ'),\n    (0x4D3, 'V'),\n    (0x4D4, 'M', 'ӕ'),\n    (0x4D5, 'V'),\n    (0x4D6, 'M', 'ӗ'),\n    (0x4D7, 'V'),\n    (0x4D8, 'M', 'ә'),\n    (0x4D9, 'V'),\n    (0x4DA, 'M', 'ӛ'),\n    (0x4DB, 'V'),\n    (0x4DC, 'M', 'ӝ'),\n    (0x4DD, 'V'),\n    (0x4DE, 'M', 'ӟ'),\n    (0x4DF, 'V'),\n    (0x4E0, 'M', 'ӡ'),\n    (0x4E1, 'V'),\n    (0x4E2, 'M', 'ӣ'),\n    (0x4E3, 'V'),\n    (0x4E4, 'M', 'ӥ'),\n    (0x4E5, 'V'),\n    (0x4E6, 'M', 'ӧ'),\n    (0x4E7, 'V'),\n    (0x4E8, 'M', 'ө'),\n    (0x4E9, 'V'),\n    (0x4EA, 'M', 'ӫ'),\n    (0x4EB, 'V'),\n    (0x4EC, 'M', 'ӭ'),\n    (0x4ED, 'V'),\n    (0x4EE, 'M', 'ӯ'),\n    (0x4EF, 'V'),\n    (0x4F0, 'M', 'ӱ'),\n    (0x4F1, 'V'),\n    (0x4F2, 'M', 'ӳ'),\n    (0x4F3, 'V'),\n    (0x4F4, 'M', 'ӵ'),\n    (0x4F5, 'V'),\n    (0x4F6, 'M', 'ӷ'),\n    (0x4F7, 'V'),\n    (0x4F8, 'M', 'ӹ'),\n    (0x4F9, 'V'),\n    (0x4FA, 'M', 'ӻ'),\n    (0x4FB, 'V'),\n    (0x4FC, 'M', 'ӽ'),\n    (0x4FD, 'V'),\n    (0x4FE, 'M', 'ӿ'),\n    (0x4FF, 'V'),\n    (0x500, 'M', 'ԁ'),\n    (0x501, 'V'),\n    (0x502, 'M', 'ԃ'),\n    (0x503, 'V'),\n    (0x504, 'M', 'ԅ'),\n    (0x505, 'V'),\n    (0x506, 'M', 'ԇ'),\n    (0x507, 'V'),\n    (0x508, 'M', 'ԉ'),\n    (0x509, 'V'),\n    (0x50A, 'M', 'ԋ'),\n    (0x50B, 'V'),\n    (0x50C, 'M', 'ԍ'),\n    (0x50D, 'V'),\n    (0x50E, 'M', 'ԏ'),\n    (0x50F, 'V'),\n    (0x510, 'M', 'ԑ'),\n    (0x511, 'V'),\n    (0x512, 'M', 'ԓ'),\n    (0x513, 'V'),\n    (0x514, 'M', 'ԕ'),\n    (0x515, 'V'),\n    (0x516, 'M', 'ԗ'),\n    (0x517, 'V'),\n    (0x518, 'M', 'ԙ'),\n    (0x519, 'V'),\n    (0x51A, 'M', 'ԛ'),\n    (0x51B, 'V'),\n    (0x51C, 'M', 'ԝ'),\n    (0x51D, 'V'),\n    (0x51E, 'M', 'ԟ'),\n    (0x51F, 'V'),\n    (0x520, 'M', 'ԡ'),\n    (0x521, 'V'),\n    (0x522, 'M', 'ԣ'),\n    (0x523, 'V'),\n    (0x524, 'M', 'ԥ'),\n    (0x525, 'V'),\n    (0x526, 'M', 'ԧ'),\n    (0x527, 'V'),\n    (0x528, 'X'),\n    (0x531, 'M', 'ա'),\n    (0x532, 'M', 'բ'),\n    (0x533, 'M', 'գ'),\n    (0x534, 'M', 'դ'),\n    (0x535, 'M', 'ե'),\n    (0x536, 'M', 'զ'),\n    (0x537, 'M', 'է'),\n    (0x538, 'M', 'ը'),\n    (0x539, 'M', 'թ'),\n    (0x53A, 'M', 'ժ'),\n    (0x53B, 'M', 'ի'),\n    (0x53C, 'M', 'լ'),\n    (0x53D, 'M', 'խ'),\n    (0x53E, 'M', 'ծ'),\n    (0x53F, 'M', 'կ'),\n    (0x540, 'M', 'հ'),\n    (0x541, 'M', 'ձ'),\n    (0x542, 'M', 'ղ'),\n    (0x543, 'M', 'ճ'),\n    (0x544, 'M', 'մ'),\n    (0x545, 'M', 'յ'),\n    (0x546, 'M', 'ն'),\n    (0x547, 'M', 'շ'),\n    (0x548, 'M', 'ո'),\n    (0x549, 'M', 'չ'),\n    (0x54A, 'M', 'պ'),\n    (0x54B, 'M', 'ջ'),\n    (0x54C, 'M', 'ռ'),\n    (0x54D, 'M', 'ս'),\n    (0x54E, 'M', 'վ'),\n    (0x54F, 'M', 'տ'),\n    (0x550, 'M', 'ր'),\n    (0x551, 'M', 'ց'),\n    (0x552, 'M', 'ւ'),\n    (0x553, 'M', 'փ'),\n    (0x554, 'M', 'ք'),\n    (0x555, 'M', 'օ'),\n    (0x556, 'M', 'ֆ'),\n    (0x557, 'X'),\n    (0x559, 'V'),\n    (0x560, 'X'),\n    (0x561, 'V'),\n    (0x587, 'M', 'եւ'),\n    (0x588, 'X'),\n    (0x589, 'V'),\n    (0x58B, 'X'),\n    (0x58F, 'V'),\n    (0x590, 'X'),\n    (0x591, 'V'),\n    (0x5C8, 'X'),\n    (0x5D0, 'V'),\n    (0x5EB, 'X'),\n    (0x5F0, 'V'),\n    (0x5F5, 'X'),\n    (0x606, 'V'),\n    (0x61C, 'X'),\n    (0x61E, 'V'),\n    (0x675, 'M', 'اٴ'),\n    (0x676, 'M', 'وٴ'),\n    (0x677, 'M', 'ۇٴ'),\n    (0x678, 'M', 'يٴ'),\n    (0x679, 'V'),\n    (0x6DD, 'X'),\n    (0x6DE, 'V'),\n    (0x70E, 'X'),\n    (0x710, 'V'),\n    (0x74B, 'X'),\n    (0x74D, 'V'),\n    (0x7B2, 'X'),\n    (0x7C0, 'V'),\n    (0x7FB, 'X'),\n    (0x800, 'V'),\n    (0x82E, 'X'),\n    (0x830, 'V'),\n    (0x83F, 'X'),\n    (0x840, 'V'),\n    (0x85C, 'X'),\n    (0x85E, 'V'),\n    (0x85F, 'X'),\n    (0x8A0, 'V'),\n    (0x8A1, 'X'),\n    (0x8A2, 'V'),\n    (0x8AD, 'X'),\n    (0x8E4, 'V'),\n    (0x8FF, 'X'),\n    (0x900, 'V'),\n    (0x958, 'M', 'क़'),\n    (0x959, 'M', 'ख़'),\n    (0x95A, 'M', 'ग़'),\n    (0x95B, 'M', 'ज़'),\n    (0x95C, 'M', 'ड़'),\n    (0x95D, 'M', 'ढ़'),\n    (0x95E, 'M', 'फ़'),\n    (0x95F, 'M', 'य़'),\n    (0x960, 'V'),\n    (0x978, 'X'),\n    (0x979, 'V'),\n    (0x980, 'X'),\n    (0x981, 'V'),\n    (0x984, 'X'),\n    (0x985, 'V'),\n    (0x98D, 'X'),\n    (0x98F, 'V'),\n    (0x991, 'X'),\n    (0x993, 'V'),\n    (0x9A9, 'X'),\n    (0x9AA, 'V'),\n    (0x9B1, 'X'),\n    (0x9B2, 'V'),\n    (0x9B3, 'X'),\n    (0x9B6, 'V'),\n    (0x9BA, 'X'),\n    (0x9BC, 'V'),\n    (0x9C5, 'X'),\n    (0x9C7, 'V'),\n    (0x9C9, 'X'),\n    (0x9CB, 'V'),\n    (0x9CF, 'X'),\n    (0x9D7, 'V'),\n    (0x9D8, 'X'),\n    (0x9DC, 'M', 'ড়'),\n    (0x9DD, 'M', 'ঢ়'),\n    (0x9DE, 'X'),\n    (0x9DF, 'M', 'য়'),\n    (0x9E0, 'V'),\n    (0x9E4, 'X'),\n    (0x9E6, 'V'),\n    (0x9FC, 'X'),\n    (0xA01, 'V'),\n    (0xA04, 'X'),\n    (0xA05, 'V'),\n    (0xA0B, 'X'),\n    (0xA0F, 'V'),\n    (0xA11, 'X'),\n    (0xA13, 'V'),\n    (0xA29, 'X'),\n    (0xA2A, 'V'),\n    (0xA31, 'X'),\n    (0xA32, 'V'),\n    (0xA33, 'M', 'ਲ਼'),\n    (0xA34, 'X'),\n    (0xA35, 'V'),\n    (0xA36, 'M', 'ਸ਼'),\n    (0xA37, 'X'),\n    (0xA38, 'V'),\n    (0xA3A, 'X'),\n    (0xA3C, 'V'),\n    (0xA3D, 'X'),\n    (0xA3E, 'V'),\n    (0xA43, 'X'),\n    (0xA47, 'V'),\n    (0xA49, 'X'),\n    (0xA4B, 'V'),\n    (0xA4E, 'X'),\n    (0xA51, 'V'),\n    (0xA52, 'X'),\n    (0xA59, 'M', 'ਖ਼'),\n    (0xA5A, 'M', 'ਗ਼'),\n    (0xA5B, 'M', 'ਜ਼'),\n    (0xA5C, 'V'),\n    (0xA5D, 'X'),\n    (0xA5E, 'M', 'ਫ਼'),\n    (0xA5F, 'X'),\n    (0xA66, 'V'),\n    (0xA76, 'X'),\n    (0xA81, 'V'),\n    (0xA84, 'X'),\n    (0xA85, 'V'),\n    (0xA8E, 'X'),\n    (0xA8F, 'V'),\n    (0xA92, 'X'),\n    (0xA93, 'V'),\n    (0xAA9, 'X'),\n    (0xAAA, 'V'),\n    (0xAB1, 'X'),\n    (0xAB2, 'V'),\n    (0xAB4, 'X'),\n    (0xAB5, 'V'),\n    (0xABA, 'X'),\n    (0xABC, 'V'),\n    (0xAC6, 'X'),\n    (0xAC7, 'V'),\n    (0xACA, 'X'),\n    (0xACB, 'V'),\n    (0xACE, 'X'),\n    (0xAD0, 'V'),\n    (0xAD1, 'X'),\n    (0xAE0, 'V'),\n    (0xAE4, 'X'),\n    (0xAE6, 'V'),\n    (0xAF2, 'X'),\n    (0xB01, 'V'),\n    (0xB04, 'X'),\n    (0xB05, 'V'),\n    (0xB0D, 'X'),\n    (0xB0F, 'V'),\n    (0xB11, 'X'),\n    (0xB13, 'V'),\n    (0xB29, 'X'),\n    (0xB2A, 'V'),\n    (0xB31, 'X'),\n    (0xB32, 'V'),\n    (0xB34, 'X'),\n    (0xB35, 'V'),\n    (0xB3A, 'X'),\n    (0xB3C, 'V'),\n    (0xB45, 'X'),\n    (0xB47, 'V'),\n    (0xB49, 'X'),\n    (0xB4B, 'V'),\n    (0xB4E, 'X'),\n    (0xB56, 'V'),\n    (0xB58, 'X'),\n    (0xB5C, 'M', 'ଡ଼'),\n    (0xB5D, 'M', 'ଢ଼'),\n    (0xB5E, 'X'),\n    (0xB5F, 'V'),\n    (0xB64, 'X'),\n    (0xB66, 'V'),\n    (0xB78, 'X'),\n    (0xB82, 'V'),\n    (0xB84, 'X'),\n    (0xB85, 'V'),\n    (0xB8B, 'X'),\n    (0xB8E, 'V'),\n    (0xB91, 'X'),\n    (0xB92, 'V'),\n    (0xB96, 'X'),\n    (0xB99, 'V'),\n    (0xB9B, 'X'),\n    (0xB9C, 'V'),\n    (0xB9D, 'X'),\n    (0xB9E, 'V'),\n    (0xBA0, 'X'),\n    (0xBA3, 'V'),\n    (0xBA5, 'X'),\n    (0xBA8, 'V'),\n    (0xBAB, 'X'),\n    (0xBAE, 'V'),\n    (0xBBA, 'X'),\n    (0xBBE, 'V'),\n    (0xBC3, 'X'),\n    (0xBC6, 'V'),\n    (0xBC9, 'X'),\n    (0xBCA, 'V'),\n    (0xBCE, 'X'),\n    (0xBD0, 'V'),\n    (0xBD1, 'X'),\n    (0xBD7, 'V'),\n    (0xBD8, 'X'),\n    (0xBE6, 'V'),\n    (0xBFB, 'X'),\n    (0xC01, 'V'),\n    (0xC04, 'X'),\n    (0xC05, 'V'),\n    (0xC0D, 'X'),\n    (0xC0E, 'V'),\n    (0xC11, 'X'),\n    (0xC12, 'V'),\n    (0xC29, 'X'),\n    (0xC2A, 'V'),\n    (0xC34, 'X'),\n    (0xC35, 'V'),\n    (0xC3A, 'X'),\n    (0xC3D, 'V'),\n    (0xC45, 'X'),\n    (0xC46, 'V'),\n    (0xC49, 'X'),\n    (0xC4A, 'V'),\n    (0xC4E, 'X'),\n    (0xC55, 'V'),\n    (0xC57, 'X'),\n    (0xC58, 'V'),\n    (0xC5A, 'X'),\n    (0xC60, 'V'),\n    (0xC64, 'X'),\n    (0xC66, 'V'),\n    (0xC70, 'X'),\n    (0xC78, 'V'),\n    (0xC80, 'X'),\n    (0xC82, 'V'),\n    (0xC84, 'X'),\n    (0xC85, 'V'),\n    (0xC8D, 'X'),\n    (0xC8E, 'V'),\n    (0xC91, 'X'),\n    (0xC92, 'V'),\n    (0xCA9, 'X'),\n    (0xCAA, 'V'),\n    (0xCB4, 'X'),\n    (0xCB5, 'V'),\n    (0xCBA, 'X'),\n    (0xCBC, 'V'),\n    (0xCC5, 'X'),\n    (0xCC6, 'V'),\n    (0xCC9, 'X'),\n    (0xCCA, 'V'),\n    (0xCCE, 'X'),\n    (0xCD5, 'V'),\n    (0xCD7, 'X'),\n    (0xCDE, 'V'),\n    (0xCDF, 'X'),\n    (0xCE0, 'V'),\n    (0xCE4, 'X'),\n    (0xCE6, 'V'),\n    (0xCF0, 'X'),\n    (0xCF1, 'V'),\n    (0xCF3, 'X'),\n    (0xD02, 'V'),\n    (0xD04, 'X'),\n    (0xD05, 'V'),\n    (0xD0D, 'X'),\n    (0xD0E, 'V'),\n    (0xD11, 'X'),\n    (0xD12, 'V'),\n    (0xD3B, 'X'),\n    (0xD3D, 'V'),\n    (0xD45, 'X'),\n    (0xD46, 'V'),\n    (0xD49, 'X'),\n    (0xD4A, 'V'),\n    (0xD4F, 'X'),\n    (0xD57, 'V'),\n    (0xD58, 'X'),\n    (0xD60, 'V'),\n    (0xD64, 'X'),\n    (0xD66, 'V'),\n    (0xD76, 'X'),\n    (0xD79, 'V'),\n    (0xD80, 'X'),\n    (0xD82, 'V'),\n    (0xD84, 'X'),\n    (0xD85, 'V'),\n    (0xD97, 'X'),\n    (0xD9A, 'V'),\n    (0xDB2, 'X'),\n    (0xDB3, 'V'),\n    (0xDBC, 'X'),\n    (0xDBD, 'V'),\n    (0xDBE, 'X'),\n    (0xDC0, 'V'),\n    (0xDC7, 'X'),\n    (0xDCA, 'V'),\n    (0xDCB, 'X'),\n    (0xDCF, 'V'),\n    (0xDD5, 'X'),\n    (0xDD6, 'V'),\n    (0xDD7, 'X'),\n    (0xDD8, 'V'),\n    (0xDE0, 'X'),\n    (0xDF2, 'V'),\n    (0xDF5, 'X'),\n    (0xE01, 'V'),\n    (0xE33, 'M', 'ํา'),\n    (0xE34, 'V'),\n    (0xE3B, 'X'),\n    (0xE3F, 'V'),\n    (0xE5C, 'X'),\n    (0xE81, 'V'),\n    (0xE83, 'X'),\n    (0xE84, 'V'),\n    (0xE85, 'X'),\n    (0xE87, 'V'),\n    (0xE89, 'X'),\n    (0xE8A, 'V'),\n    (0xE8B, 'X'),\n    (0xE8D, 'V'),\n    (0xE8E, 'X'),\n    (0xE94, 'V'),\n    (0xE98, 'X'),\n    (0xE99, 'V'),\n    (0xEA0, 'X'),\n    (0xEA1, 'V'),\n    (0xEA4, 'X'),\n    (0xEA5, 'V'),\n    (0xEA6, 'X'),\n    (0xEA7, 'V'),\n    (0xEA8, 'X'),\n    (0xEAA, 'V'),\n    (0xEAC, 'X'),\n    (0xEAD, 'V'),\n    (0xEB3, 'M', 'ໍາ'),\n    (0xEB4, 'V'),\n    (0xEBA, 'X'),\n    (0xEBB, 'V'),\n    (0xEBE, 'X'),\n    (0xEC0, 'V'),\n    (0xEC5, 'X'),\n    (0xEC6, 'V'),\n    (0xEC7, 'X'),\n    (0xEC8, 'V'),\n    (0xECE, 'X'),\n    (0xED0, 'V'),\n    (0xEDA, 'X'),\n    (0xEDC, 'M', 'ຫນ'),\n    (0xEDD, 'M', 'ຫມ'),\n    (0xEDE, 'V'),\n    (0xEE0, 'X'),\n    (0xF00, 'V'),\n    (0xF0C, 'M', '་'),\n    (0xF0D, 'V'),\n    (0xF43, 'M', 'གྷ'),\n    (0xF44, 'V'),\n    (0xF48, 'X'),\n    (0xF49, 'V'),\n    (0xF4D, 'M', 'ཌྷ'),\n    (0xF4E, 'V'),\n    (0xF52, 'M', 'དྷ'),\n    (0xF53, 'V'),\n    (0xF57, 'M', 'བྷ'),\n    (0xF58, 'V'),\n    (0xF5C, 'M', 'ཛྷ'),\n    (0xF5D, 'V'),\n    (0xF69, 'M', 'ཀྵ'),\n    (0xF6A, 'V'),\n    (0xF6D, 'X'),\n    (0xF71, 'V'),\n    (0xF73, 'M', 'ཱི'),\n    (0xF74, 'V'),\n    (0xF75, 'M', 'ཱུ'),\n    (0xF76, 'M', 'ྲྀ'),\n    (0xF77, 'M', 'ྲཱྀ'),\n    (0xF78, 'M', 'ླྀ'),\n    (0xF79, 'M', 'ླཱྀ'),\n    (0xF7A, 'V'),\n    (0xF81, 'M', 'ཱྀ'),\n    (0xF82, 'V'),\n    (0xF93, 'M', 'ྒྷ'),\n    (0xF94, 'V'),\n    (0xF98, 'X'),\n    (0xF99, 'V'),\n    (0xF9D, 'M', 'ྜྷ'),\n    (0xF9E, 'V'),\n    (0xFA2, 'M', 'ྡྷ'),\n    (0xFA3, 'V'),\n    (0xFA7, 'M', 'ྦྷ'),\n    (0xFA8, 'V'),\n    (0xFAC, 'M', 'ྫྷ'),\n    (0xFAD, 'V'),\n    (0xFB9, 'M', 'ྐྵ'),\n    (0xFBA, 'V'),\n    (0xFBD, 'X'),\n    (0xFBE, 'V'),\n    (0xFCD, 'X'),\n    (0xFCE, 'V'),\n    (0xFDB, 'X'),\n    (0x1000, 'V'),\n    (0x10A0, 'X'),\n    (0x10C7, 'M', 'ⴧ'),\n    (0x10C8, 'X'),\n    (0x10CD, 'M', 'ⴭ'),\n    (0x10CE, 'X'),\n    (0x10D0, 'V'),\n    (0x10FC, 'M', 'ნ'),\n    (0x10FD, 'V'),\n    (0x115F, 'X'),\n    (0x1161, 'V'),\n    (0x1249, 'X'),\n    (0x124A, 'V'),\n    (0x124E, 'X'),\n    (0x1250, 'V'),\n    (0x1257, 'X'),\n    (0x1258, 'V'),\n    (0x1259, 'X'),\n    (0x125A, 'V'),\n    (0x125E, 'X'),\n    (0x1260, 'V'),\n    (0x1289, 'X'),\n    (0x128A, 'V'),\n    (0x128E, 'X'),\n    (0x1290, 'V'),\n    (0x12B1, 'X'),\n    (0x12B2, 'V'),\n    (0x12B6, 'X'),\n    (0x12B8, 'V'),\n    (0x12BF, 'X'),\n    (0x12C0, 'V'),\n    (0x12C1, 'X'),\n    (0x12C2, 'V'),\n    (0x12C6, 'X'),\n    (0x12C8, 'V'),\n    (0x12D7, 'X'),\n    (0x12D8, 'V'),\n    (0x1311, 'X'),\n    (0x1312, 'V'),\n    (0x1316, 'X'),\n    (0x1318, 'V'),\n    (0x135B, 'X'),\n    (0x135D, 'V'),\n    (0x137D, 'X'),\n    (0x1380, 'V'),\n    (0x139A, 'X'),\n    (0x13A0, 'V'),\n    (0x13F5, 'X'),\n    (0x1400, 'V'),\n    (0x1680, 'X'),\n    (0x1681, 'V'),\n    (0x169D, 'X'),\n    (0x16A0, 'V'),\n    (0x16F1, 'X'),\n    (0x1700, 'V'),\n    (0x170D, 'X'),\n    (0x170E, 'V'),\n    (0x1715, 'X'),\n    (0x1720, 'V'),\n    (0x1737, 'X'),\n    (0x1740, 'V'),\n    (0x1754, 'X'),\n    (0x1760, 'V'),\n    (0x176D, 'X'),\n    (0x176E, 'V'),\n    (0x1771, 'X'),\n    (0x1772, 'V'),\n    (0x1774, 'X'),\n    (0x1780, 'V'),\n    (0x17B4, 'X'),\n    (0x17B6, 'V'),\n    (0x17DE, 'X'),\n    (0x17E0, 'V'),\n    (0x17EA, 'X'),\n    (0x17F0, 'V'),\n    (0x17FA, 'X'),\n    (0x1800, 'V'),\n    (0x1806, 'X'),\n    (0x1807, 'V'),\n    (0x180B, 'I'),\n    (0x180E, 'X'),\n    (0x1810, 'V'),\n    (0x181A, 'X'),\n    (0x1820, 'V'),\n    (0x1878, 'X'),\n    (0x1880, 'V'),\n    (0x18AB, 'X'),\n    (0x18B0, 'V'),\n    (0x18F6, 'X'),\n    (0x1900, 'V'),\n    (0x191D, 'X'),\n    (0x1920, 'V'),\n    (0x192C, 'X'),\n    (0x1930, 'V'),\n    (0x193C, 'X'),\n    (0x1940, 'V'),\n    (0x1941, 'X'),\n    (0x1944, 'V'),\n    (0x196E, 'X'),\n    (0x1970, 'V'),\n    (0x1975, 'X'),\n    (0x1980, 'V'),\n    (0x19AC, 'X'),\n    (0x19B0, 'V'),\n    (0x19CA, 'X'),\n    (0x19D0, 'V'),\n    (0x19DB, 'X'),\n    (0x19DE, 'V'),\n    (0x1A1C, 'X'),\n    (0x1A1E, 'V'),\n    (0x1A5F, 'X'),\n    (0x1A60, 'V'),\n    (0x1A7D, 'X'),\n    (0x1A7F, 'V'),\n    (0x1A8A, 'X'),\n    (0x1A90, 'V'),\n    (0x1A9A, 'X'),\n    (0x1AA0, 'V'),\n    (0x1AAE, 'X'),\n    (0x1B00, 'V'),\n    (0x1B4C, 'X'),\n    (0x1B50, 'V'),\n    (0x1B7D, 'X'),\n    (0x1B80, 'V'),\n    (0x1BF4, 'X'),\n    (0x1BFC, 'V'),\n    (0x1C38, 'X'),\n    (0x1C3B, 'V'),\n    (0x1C4A, 'X'),\n    (0x1C4D, 'V'),\n    (0x1C80, 'X'),\n    (0x1CC0, 'V'),\n    (0x1CC8, 'X'),\n    (0x1CD0, 'V'),\n    (0x1CF7, 'X'),\n    (0x1D00, 'V'),\n    (0x1D2C, 'M', 'a'),\n    (0x1D2D, 'M', 'æ'),\n    (0x1D2E, 'M', 'b'),\n    (0x1D2F, 'V'),\n    (0x1D30, 'M', 'd'),\n    (0x1D31, 'M', 'e'),\n    (0x1D32, 'M', 'ǝ'),\n    (0x1D33, 'M', 'g'),\n    (0x1D34, 'M', 'h'),\n    (0x1D35, 'M', 'i'),\n    (0x1D36, 'M', 'j'),\n    (0x1D37, 'M', 'k'),\n    (0x1D38, 'M', 'l'),\n    (0x1D39, 'M', 'm'),\n    (0x1D3A, 'M', 'n'),\n    (0x1D3B, 'V'),\n    (0x1D3C, 'M', 'o'),\n    (0x1D3D, 'M', 'ȣ'),\n    (0x1D3E, 'M', 'p'),\n    (0x1D3F, 'M', 'r'),\n    (0x1D40, 'M', 't'),\n    (0x1D41, 'M', 'u'),\n    (0x1D42, 'M', 'w'),\n    (0x1D43, 'M', 'a'),\n    (0x1D44, 'M', 'ɐ'),\n    (0x1D45, 'M', 'ɑ'),\n    (0x1D46, 'M', 'ᴂ'),\n    (0x1D47, 'M', 'b'),\n    (0x1D48, 'M', 'd'),\n    (0x1D49, 'M', 'e'),\n    (0x1D4A, 'M', 'ə'),\n    (0x1D4B, 'M', 'ɛ'),\n    (0x1D4C, 'M', 'ɜ'),\n    (0x1D4D, 'M', 'g'),\n    (0x1D4E, 'V'),\n    (0x1D4F, 'M', 'k'),\n    (0x1D50, 'M', 'm'),\n    (0x1D51, 'M', 'ŋ'),\n    (0x1D52, 'M', 'o'),\n    (0x1D53, 'M', 'ɔ'),\n    (0x1D54, 'M', 'ᴖ'),\n    (0x1D55, 'M', 'ᴗ'),\n    (0x1D56, 'M', 'p'),\n    (0x1D57, 'M', 't'),\n    (0x1D58, 'M', 'u'),\n    (0x1D59, 'M', 'ᴝ'),\n    (0x1D5A, 'M', 'ɯ'),\n    (0x1D5B, 'M', 'v'),\n    (0x1D5C, 'M', 'ᴥ'),\n    (0x1D5D, 'M', 'β'),\n    (0x1D5E, 'M', 'γ'),\n    (0x1D5F, 'M', 'δ'),\n    (0x1D60, 'M', 'φ'),\n    (0x1D61, 'M', 'χ'),\n    (0x1D62, 'M', 'i'),\n    (0x1D63, 'M', 'r'),\n    (0x1D64, 'M', 'u'),\n    (0x1D65, 'M', 'v'),\n    (0x1D66, 'M', 'β'),\n    (0x1D67, 'M', 'γ'),\n    (0x1D68, 'M', 'ρ'),\n    (0x1D69, 'M', 'φ'),\n    (0x1D6A, 'M', 'χ'),\n    (0x1D6B, 'V'),\n    (0x1D78, 'M', 'н'),\n    (0x1D79, 'V'),\n    (0x1D9B, 'M', 'ɒ'),\n    (0x1D9C, 'M', 'c'),\n    (0x1D9D, 'M', 'ɕ'),\n    (0x1D9E, 'M', 'ð'),\n    (0x1D9F, 'M', 'ɜ'),\n    (0x1DA0, 'M', 'f'),\n    (0x1DA1, 'M', 'ɟ'),\n    (0x1DA2, 'M', 'ɡ'),\n    (0x1DA3, 'M', 'ɥ'),\n    (0x1DA4, 'M', 'ɨ'),\n    (0x1DA5, 'M', 'ɩ'),\n    (0x1DA6, 'M', 'ɪ'),\n    (0x1DA7, 'M', 'ᵻ'),\n    (0x1DA8, 'M', 'ʝ'),\n    (0x1DA9, 'M', 'ɭ'),\n    (0x1DAA, 'M', 'ᶅ'),\n    (0x1DAB, 'M', 'ʟ'),\n    (0x1DAC, 'M', 'ɱ'),\n    (0x1DAD, 'M', 'ɰ'),\n    (0x1DAE, 'M', 'ɲ'),\n    (0x1DAF, 'M', 'ɳ'),\n    (0x1DB0, 'M', 'ɴ'),\n    (0x1DB1, 'M', 'ɵ'),\n    (0x1DB2, 'M', 'ɸ'),\n    (0x1DB3, 'M', 'ʂ'),\n    (0x1DB4, 'M', 'ʃ'),\n    (0x1DB5, 'M', 'ƫ'),\n    (0x1DB6, 'M', 'ʉ'),\n    (0x1DB7, 'M', 'ʊ'),\n    (0x1DB8, 'M', 'ᴜ'),\n    (0x1DB9, 'M', 'ʋ'),\n    (0x1DBA, 'M', 'ʌ'),\n    (0x1DBB, 'M', 'z'),\n    (0x1DBC, 'M', 'ʐ'),\n    (0x1DBD, 'M', 'ʑ'),\n    (0x1DBE, 'M', 'ʒ'),\n    (0x1DBF, 'M', 'θ'),\n    (0x1DC0, 'V'),\n    (0x1DE7, 'X'),\n    (0x1DFC, 'V'),\n    (0x1E00, 'M', 'ḁ'),\n    (0x1E01, 'V'),\n    (0x1E02, 'M', 'ḃ'),\n    (0x1E03, 'V'),\n    (0x1E04, 'M', 'ḅ'),\n    (0x1E05, 'V'),\n    (0x1E06, 'M', 'ḇ'),\n    (0x1E07, 'V'),\n    (0x1E08, 'M', 'ḉ'),\n    (0x1E09, 'V'),\n    (0x1E0A, 'M', 'ḋ'),\n    (0x1E0B, 'V'),\n    (0x1E0C, 'M', 'ḍ'),\n    (0x1E0D, 'V'),\n    (0x1E0E, 'M', 'ḏ'),\n    (0x1E0F, 'V'),\n    (0x1E10, 'M', 'ḑ'),\n    (0x1E11, 'V'),\n    (0x1E12, 'M', 'ḓ'),\n    (0x1E13, 'V'),\n    (0x1E14, 'M', 'ḕ'),\n    (0x1E15, 'V'),\n    (0x1E16, 'M', 'ḗ'),\n    (0x1E17, 'V'),\n    (0x1E18, 'M', 'ḙ'),\n    (0x1E19, 'V'),\n    (0x1E1A, 'M', 'ḛ'),\n    (0x1E1B, 'V'),\n    (0x1E1C, 'M', 'ḝ'),\n    (0x1E1D, 'V'),\n    (0x1E1E, 'M', 'ḟ'),\n    (0x1E1F, 'V'),\n    (0x1E20, 'M', 'ḡ'),\n    (0x1E21, 'V'),\n    (0x1E22, 'M', 'ḣ'),\n    (0x1E23, 'V'),\n    (0x1E24, 'M', 'ḥ'),\n    (0x1E25, 'V'),\n    (0x1E26, 'M', 'ḧ'),\n    (0x1E27, 'V'),\n    (0x1E28, 'M', 'ḩ'),\n    (0x1E29, 'V'),\n    (0x1E2A, 'M', 'ḫ'),\n    (0x1E2B, 'V'),\n    (0x1E2C, 'M', 'ḭ'),\n    (0x1E2D, 'V'),\n    (0x1E2E, 'M', 'ḯ'),\n    (0x1E2F, 'V'),\n    (0x1E30, 'M', 'ḱ'),\n    (0x1E31, 'V'),\n    (0x1E32, 'M', 'ḳ'),\n    (0x1E33, 'V'),\n    (0x1E34, 'M', 'ḵ'),\n    (0x1E35, 'V'),\n    (0x1E36, 'M', 'ḷ'),\n    (0x1E37, 'V'),\n    (0x1E38, 'M', 'ḹ'),\n    (0x1E39, 'V'),\n    (0x1E3A, 'M', 'ḻ'),\n    (0x1E3B, 'V'),\n    (0x1E3C, 'M', 'ḽ'),\n    (0x1E3D, 'V'),\n    (0x1E3E, 'M', 'ḿ'),\n    (0x1E3F, 'V'),\n    (0x1E40, 'M', 'ṁ'),\n    (0x1E41, 'V'),\n    (0x1E42, 'M', 'ṃ'),\n    (0x1E43, 'V'),\n    (0x1E44, 'M', 'ṅ'),\n    (0x1E45, 'V'),\n    (0x1E46, 'M', 'ṇ'),\n    (0x1E47, 'V'),\n    (0x1E48, 'M', 'ṉ'),\n    (0x1E49, 'V'),\n    (0x1E4A, 'M', 'ṋ'),\n    (0x1E4B, 'V'),\n    (0x1E4C, 'M', 'ṍ'),\n    (0x1E4D, 'V'),\n    (0x1E4E, 'M', 'ṏ'),\n    (0x1E4F, 'V'),\n    (0x1E50, 'M', 'ṑ'),\n    (0x1E51, 'V'),\n    (0x1E52, 'M', 'ṓ'),\n    (0x1E53, 'V'),\n    (0x1E54, 'M', 'ṕ'),\n    (0x1E55, 'V'),\n    (0x1E56, 'M', 'ṗ'),\n    (0x1E57, 'V'),\n    (0x1E58, 'M', 'ṙ'),\n    (0x1E59, 'V'),\n    (0x1E5A, 'M', 'ṛ'),\n    (0x1E5B, 'V'),\n    (0x1E5C, 'M', 'ṝ'),\n    (0x1E5D, 'V'),\n    (0x1E5E, 'M', 'ṟ'),\n    (0x1E5F, 'V'),\n    (0x1E60, 'M', 'ṡ'),\n    (0x1E61, 'V'),\n    (0x1E62, 'M', 'ṣ'),\n    (0x1E63, 'V'),\n    (0x1E64, 'M', 'ṥ'),\n    (0x1E65, 'V'),\n    (0x1E66, 'M', 'ṧ'),\n    (0x1E67, 'V'),\n    (0x1E68, 'M', 'ṩ'),\n    (0x1E69, 'V'),\n    (0x1E6A, 'M', 'ṫ'),\n    (0x1E6B, 'V'),\n    (0x1E6C, 'M', 'ṭ'),\n    (0x1E6D, 'V'),\n    (0x1E6E, 'M', 'ṯ'),\n    (0x1E6F, 'V'),\n    (0x1E70, 'M', 'ṱ'),\n    (0x1E71, 'V'),\n    (0x1E72, 'M', 'ṳ'),\n    (0x1E73, 'V'),\n    (0x1E74, 'M', 'ṵ'),\n    (0x1E75, 'V'),\n    (0x1E76, 'M', 'ṷ'),\n    (0x1E77, 'V'),\n    (0x1E78, 'M', 'ṹ'),\n    (0x1E79, 'V'),\n    (0x1E7A, 'M', 'ṻ'),\n    (0x1E7B, 'V'),\n    (0x1E7C, 'M', 'ṽ'),\n    (0x1E7D, 'V'),\n    (0x1E7E, 'M', 'ṿ'),\n    (0x1E7F, 'V'),\n    (0x1E80, 'M', 'ẁ'),\n    (0x1E81, 'V'),\n    (0x1E82, 'M', 'ẃ'),\n    (0x1E83, 'V'),\n    (0x1E84, 'M', 'ẅ'),\n    (0x1E85, 'V'),\n    (0x1E86, 'M', 'ẇ'),\n    (0x1E87, 'V'),\n    (0x1E88, 'M', 'ẉ'),\n    (0x1E89, 'V'),\n    (0x1E8A, 'M', 'ẋ'),\n    (0x1E8B, 'V'),\n    (0x1E8C, 'M', 'ẍ'),\n    (0x1E8D, 'V'),\n    (0x1E8E, 'M', 'ẏ'),\n    (0x1E8F, 'V'),\n    (0x1E90, 'M', 'ẑ'),\n    (0x1E91, 'V'),\n    (0x1E92, 'M', 'ẓ'),\n    (0x1E93, 'V'),\n    (0x1E94, 'M', 'ẕ'),\n    (0x1E95, 'V'),\n    (0x1E9A, 'M', 'aʾ'),\n    (0x1E9B, 'M', 'ṡ'),\n    (0x1E9C, 'V'),\n    (0x1E9E, 'M', 'ss'),\n    (0x1E9F, 'V'),\n    (0x1EA0, 'M', 'ạ'),\n    (0x1EA1, 'V'),\n    (0x1EA2, 'M', 'ả'),\n    (0x1EA3, 'V'),\n    (0x1EA4, 'M', 'ấ'),\n    (0x1EA5, 'V'),\n    (0x1EA6, 'M', 'ầ'),\n    (0x1EA7, 'V'),\n    (0x1EA8, 'M', 'ẩ'),\n    (0x1EA9, 'V'),\n    (0x1EAA, 'M', 'ẫ'),\n    (0x1EAB, 'V'),\n    (0x1EAC, 'M', 'ậ'),\n    (0x1EAD, 'V'),\n    (0x1EAE, 'M', 'ắ'),\n    (0x1EAF, 'V'),\n    (0x1EB0, 'M', 'ằ'),\n    (0x1EB1, 'V'),\n    (0x1EB2, 'M', 'ẳ'),\n    (0x1EB3, 'V'),\n    (0x1EB4, 'M', 'ẵ'),\n    (0x1EB5, 'V'),\n    (0x1EB6, 'M', 'ặ'),\n    (0x1EB7, 'V'),\n    (0x1EB8, 'M', 'ẹ'),\n    (0x1EB9, 'V'),\n    (0x1EBA, 'M', 'ẻ'),\n    (0x1EBB, 'V'),\n    (0x1EBC, 'M', 'ẽ'),\n    (0x1EBD, 'V'),\n    (0x1EBE, 'M', 'ế'),\n    (0x1EBF, 'V'),\n    (0x1EC0, 'M', 'ề'),\n    (0x1EC1, 'V'),\n    (0x1EC2, 'M', 'ể'),\n    (0x1EC3, 'V'),\n    (0x1EC4, 'M', 'ễ'),\n    (0x1EC5, 'V'),\n    (0x1EC6, 'M', 'ệ'),\n    (0x1EC7, 'V'),\n    (0x1EC8, 'M', 'ỉ'),\n    (0x1EC9, 'V'),\n    (0x1ECA, 'M', 'ị'),\n    (0x1ECB, 'V'),\n    (0x1ECC, 'M', 'ọ'),\n    (0x1ECD, 'V'),\n    (0x1ECE, 'M', 'ỏ'),\n    (0x1ECF, 'V'),\n    (0x1ED0, 'M', 'ố'),\n    (0x1ED1, 'V'),\n    (0x1ED2, 'M', 'ồ'),\n    (0x1ED3, 'V'),\n    (0x1ED4, 'M', 'ổ'),\n    (0x1ED5, 'V'),\n    (0x1ED6, 'M', 'ỗ'),\n    (0x1ED7, 'V'),\n    (0x1ED8, 'M', 'ộ'),\n    (0x1ED9, 'V'),\n    (0x1EDA, 'M', 'ớ'),\n    (0x1EDB, 'V'),\n    (0x1EDC, 'M', 'ờ'),\n    (0x1EDD, 'V'),\n    (0x1EDE, 'M', 'ở'),\n    (0x1EDF, 'V'),\n    (0x1EE0, 'M', 'ỡ'),\n    (0x1EE1, 'V'),\n    (0x1EE2, 'M', 'ợ'),\n    (0x1EE3, 'V'),\n    (0x1EE4, 'M', 'ụ'),\n    (0x1EE5, 'V'),\n    (0x1EE6, 'M', 'ủ'),\n    (0x1EE7, 'V'),\n    (0x1EE8, 'M', 'ứ'),\n    (0x1EE9, 'V'),\n    (0x1EEA, 'M', 'ừ'),\n    (0x1EEB, 'V'),\n    (0x1EEC, 'M', 'ử'),\n    (0x1EED, 'V'),\n    (0x1EEE, 'M', 'ữ'),\n    (0x1EEF, 'V'),\n    (0x1EF0, 'M', 'ự'),\n    (0x1EF1, 'V'),\n    (0x1EF2, 'M', 'ỳ'),\n    (0x1EF3, 'V'),\n    (0x1EF4, 'M', 'ỵ'),\n    (0x1EF5, 'V'),\n    (0x1EF6, 'M', 'ỷ'),\n    (0x1EF7, 'V'),\n    (0x1EF8, 'M', 'ỹ'),\n    (0x1EF9, 'V'),\n    (0x1EFA, 'M', 'ỻ'),\n    (0x1EFB, 'V'),\n    (0x1EFC, 'M', 'ỽ'),\n    (0x1EFD, 'V'),\n    (0x1EFE, 'M', 'ỿ'),\n    (0x1EFF, 'V'),\n    (0x1F08, 'M', 'ἀ'),\n    (0x1F09, 'M', 'ἁ'),\n    (0x1F0A, 'M', 'ἂ'),\n    (0x1F0B, 'M', 'ἃ'),\n    (0x1F0C, 'M', 'ἄ'),\n    (0x1F0D, 'M', 'ἅ'),\n    (0x1F0E, 'M', 'ἆ'),\n    (0x1F0F, 'M', 'ἇ'),\n    (0x1F10, 'V'),\n    (0x1F16, 'X'),\n    (0x1F18, 'M', 'ἐ'),\n    (0x1F19, 'M', 'ἑ'),\n    (0x1F1A, 'M', 'ἒ'),\n    (0x1F1B, 'M', 'ἓ'),\n    (0x1F1C, 'M', 'ἔ'),\n    (0x1F1D, 'M', 'ἕ'),\n    (0x1F1E, 'X'),\n    (0x1F20, 'V'),\n    (0x1F28, 'M', 'ἠ'),\n    (0x1F29, 'M', 'ἡ'),\n    (0x1F2A, 'M', 'ἢ'),\n    (0x1F2B, 'M', 'ἣ'),\n    (0x1F2C, 'M', 'ἤ'),\n    (0x1F2D, 'M', 'ἥ'),\n    (0x1F2E, 'M', 'ἦ'),\n    (0x1F2F, 'M', 'ἧ'),\n    (0x1F30, 'V'),\n    (0x1F38, 'M', 'ἰ'),\n    (0x1F39, 'M', 'ἱ'),\n    (0x1F3A, 'M', 'ἲ'),\n    (0x1F3B, 'M', 'ἳ'),\n    (0x1F3C, 'M', 'ἴ'),\n    (0x1F3D, 'M', 'ἵ'),\n    (0x1F3E, 'M', 'ἶ'),\n    (0x1F3F, 'M', 'ἷ'),\n    (0x1F40, 'V'),\n    (0x1F46, 'X'),\n    (0x1F48, 'M', 'ὀ'),\n    (0x1F49, 'M', 'ὁ'),\n    (0x1F4A, 'M', 'ὂ'),\n    (0x1F4B, 'M', 'ὃ'),\n    (0x1F4C, 'M', 'ὄ'),\n    (0x1F4D, 'M', 'ὅ'),\n    (0x1F4E, 'X'),\n    (0x1F50, 'V'),\n    (0x1F58, 'X'),\n    (0x1F59, 'M', 'ὑ'),\n    (0x1F5A, 'X'),\n    (0x1F5B, 'M', 'ὓ'),\n    (0x1F5C, 'X'),\n    (0x1F5D, 'M', 'ὕ'),\n    (0x1F5E, 'X'),\n    (0x1F5F, 'M', 'ὗ'),\n    (0x1F60, 'V'),\n    (0x1F68, 'M', 'ὠ'),\n    (0x1F69, 'M', 'ὡ'),\n    (0x1F6A, 'M', 'ὢ'),\n    (0x1F6B, 'M', 'ὣ'),\n    (0x1F6C, 'M', 'ὤ'),\n    (0x1F6D, 'M', 'ὥ'),\n    (0x1F6E, 'M', 'ὦ'),\n    (0x1F6F, 'M', 'ὧ'),\n    (0x1F70, 'V'),\n    (0x1F71, 'M', 'ά'),\n    (0x1F72, 'V'),\n    (0x1F73, 'M', 'έ'),\n    (0x1F74, 'V'),\n    (0x1F75, 'M', 'ή'),\n    (0x1F76, 'V'),\n    (0x1F77, 'M', 'ί'),\n    (0x1F78, 'V'),\n    (0x1F79, 'M', 'ό'),\n    (0x1F7A, 'V'),\n    (0x1F7B, 'M', 'ύ'),\n    (0x1F7C, 'V'),\n    (0x1F7D, 'M', 'ώ'),\n    (0x1F7E, 'X'),\n    (0x1F80, 'M', 'ἀι'),\n    (0x1F81, 'M', 'ἁι'),\n    (0x1F82, 'M', 'ἂι'),\n    (0x1F83, 'M', 'ἃι'),\n    (0x1F84, 'M', 'ἄι'),\n    (0x1F85, 'M', 'ἅι'),\n    (0x1F86, 'M', 'ἆι'),\n    (0x1F87, 'M', 'ἇι'),\n    (0x1F88, 'M', 'ἀι'),\n    (0x1F89, 'M', 'ἁι'),\n    (0x1F8A, 'M', 'ἂι'),\n    (0x1F8B, 'M', 'ἃι'),\n    (0x1F8C, 'M', 'ἄι'),\n    (0x1F8D, 'M', 'ἅι'),\n    (0x1F8E, 'M', 'ἆι'),\n    (0x1F8F, 'M', 'ἇι'),\n    (0x1F90, 'M', 'ἠι'),\n    (0x1F91, 'M', 'ἡι'),\n    (0x1F92, 'M', 'ἢι'),\n    (0x1F93, 'M', 'ἣι'),\n    (0x1F94, 'M', 'ἤι'),\n    (0x1F95, 'M', 'ἥι'),\n    (0x1F96, 'M', 'ἦι'),\n    (0x1F97, 'M', 'ἧι'),\n    (0x1F98, 'M', 'ἠι'),\n    (0x1F99, 'M', 'ἡι'),\n    (0x1F9A, 'M', 'ἢι'),\n    (0x1F9B, 'M', 'ἣι'),\n    (0x1F9C, 'M', 'ἤι'),\n    (0x1F9D, 'M', 'ἥι'),\n    (0x1F9E, 'M', 'ἦι'),\n    (0x1F9F, 'M', 'ἧι'),\n    (0x1FA0, 'M', 'ὠι'),\n    (0x1FA1, 'M', 'ὡι'),\n    (0x1FA2, 'M', 'ὢι'),\n    (0x1FA3, 'M', 'ὣι'),\n    (0x1FA4, 'M', 'ὤι'),\n    (0x1FA5, 'M', 'ὥι'),\n    (0x1FA6, 'M', 'ὦι'),\n    (0x1FA7, 'M', 'ὧι'),\n    (0x1FA8, 'M', 'ὠι'),\n    (0x1FA9, 'M', 'ὡι'),\n    (0x1FAA, 'M', 'ὢι'),\n    (0x1FAB, 'M', 'ὣι'),\n    (0x1FAC, 'M', 'ὤι'),\n    (0x1FAD, 'M', 'ὥι'),\n    (0x1FAE, 'M', 'ὦι'),\n    (0x1FAF, 'M', 'ὧι'),\n    (0x1FB0, 'V'),\n    (0x1FB2, 'M', 'ὰι'),\n    (0x1FB3, 'M', 'αι'),\n    (0x1FB4, 'M', 'άι'),\n    (0x1FB5, 'X'),\n    (0x1FB6, 'V'),\n    (0x1FB7, 'M', 'ᾶι'),\n    (0x1FB8, 'M', 'ᾰ'),\n    (0x1FB9, 'M', 'ᾱ'),\n    (0x1FBA, 'M', 'ὰ'),\n    (0x1FBB, 'M', 'ά'),\n    (0x1FBC, 'M', 'αι'),\n    (0x1FBD, '3', ' ̓'),\n    (0x1FBE, 'M', 'ι'),\n    (0x1FBF, '3', ' ̓'),\n    (0x1FC0, '3', ' ͂'),\n    (0x1FC1, '3', ' ̈͂'),\n    (0x1FC2, 'M', 'ὴι'),\n    (0x1FC3, 'M', 'ηι'),\n    (0x1FC4, 'M', 'ήι'),\n    (0x1FC5, 'X'),\n    (0x1FC6, 'V'),\n    (0x1FC7, 'M', 'ῆι'),\n    (0x1FC8, 'M', 'ὲ'),\n    (0x1FC9, 'M', 'έ'),\n    (0x1FCA, 'M', 'ὴ'),\n    (0x1FCB, 'M', 'ή'),\n    (0x1FCC, 'M', 'ηι'),\n    (0x1FCD, '3', ' ̓̀'),\n    (0x1FCE, '3', ' ̓́'),\n    (0x1FCF, '3', ' ̓͂'),\n    (0x1FD0, 'V'),\n    (0x1FD3, 'M', 'ΐ'),\n    (0x1FD4, 'X'),\n    (0x1FD6, 'V'),\n    (0x1FD8, 'M', 'ῐ'),\n    (0x1FD9, 'M', 'ῑ'),\n    (0x1FDA, 'M', 'ὶ'),\n    (0x1FDB, 'M', 'ί'),\n    (0x1FDC, 'X'),\n    (0x1FDD, '3', ' ̔̀'),\n    (0x1FDE, '3', ' ̔́'),\n    (0x1FDF, '3', ' ̔͂'),\n    (0x1FE0, 'V'),\n    (0x1FE3, 'M', 'ΰ'),\n    (0x1FE4, 'V'),\n    (0x1FE8, 'M', 'ῠ'),\n    (0x1FE9, 'M', 'ῡ'),\n    (0x1FEA, 'M', 'ὺ'),\n    (0x1FEB, 'M', 'ύ'),\n    (0x1FEC, 'M', 'ῥ'),\n    (0x1FED, '3', ' ̈̀'),\n    (0x1FEE, '3', ' ̈́'),\n    (0x1FEF, '3', '`'),\n    (0x1FF0, 'X'),\n    (0x1FF2, 'M', 'ὼι'),\n    (0x1FF3, 'M', 'ωι'),\n    (0x1FF4, 'M', 'ώι'),\n    (0x1FF5, 'X'),\n    (0x1FF6, 'V'),\n    (0x1FF7, 'M', 'ῶι'),\n    (0x1FF8, 'M', 'ὸ'),\n    (0x1FF9, 'M', 'ό'),\n    (0x1FFA, 'M', 'ὼ'),\n    (0x1FFB, 'M', 'ώ'),\n    (0x1FFC, 'M', 'ωι'),\n    (0x1FFD, '3', ' ́'),\n    (0x1FFE, '3', ' ̔'),\n    (0x1FFF, 'X'),\n    (0x2000, '3', ' '),\n    (0x200B, 'I'),\n    (0x200C, 'D', ''),\n    (0x200E, 'X'),\n    (0x2010, 'V'),\n    (0x2011, 'M', '‐'),\n    (0x2012, 'V'),\n    (0x2017, '3', ' ̳'),\n    (0x2018, 'V'),\n    (0x2024, 'X'),\n    (0x2027, 'V'),\n    (0x2028, 'X'),\n    (0x202F, '3', ' '),\n    (0x2030, 'V'),\n    (0x2033, 'M', '′′'),\n    (0x2034, 'M', '′′′'),\n    (0x2035, 'V'),\n    (0x2036, 'M', '‵‵'),\n    (0x2037, 'M', '‵‵‵'),\n    (0x2038, 'V'),\n    (0x203C, '3', '!!'),\n    (0x203D, 'V'),\n    (0x203E, '3', ' ̅'),\n    (0x203F, 'V'),\n    (0x2047, '3', '??'),\n    (0x2048, '3', '?!'),\n    (0x2049, '3', '!?'),\n    (0x204A, 'V'),\n    (0x2057, 'M', '′′′′'),\n    (0x2058, 'V'),\n    (0x205F, '3', ' '),\n    (0x2060, 'I'),\n    (0x2061, 'X'),\n    (0x2064, 'I'),\n    (0x2065, 'X'),\n    (0x2070, 'M', '0'),\n    (0x2071, 'M', 'i'),\n    (0x2072, 'X'),\n    (0x2074, 'M', '4'),\n    (0x2075, 'M', '5'),\n    (0x2076, 'M', '6'),\n    (0x2077, 'M', '7'),\n    (0x2078, 'M', '8'),\n    (0x2079, 'M', '9'),\n    (0x207A, '3', '+'),\n    (0x207B, 'M', '−'),\n    (0x207C, '3', '='),\n    (0x207D, '3', '('),\n    (0x207E, '3', ')'),\n    (0x207F, 'M', 'n'),\n    (0x2080, 'M', '0'),\n    (0x2081, 'M', '1'),\n    (0x2082, 'M', '2'),\n    (0x2083, 'M', '3'),\n    (0x2084, 'M', '4'),\n    (0x2085, 'M', '5'),\n    (0x2086, 'M', '6'),\n    (0x2087, 'M', '7'),\n    (0x2088, 'M', '8'),\n    (0x2089, 'M', '9'),\n    (0x208A, '3', '+'),\n    (0x208B, 'M', '−'),\n    (0x208C, '3', '='),\n    (0x208D, '3', '('),\n    (0x208E, '3', ')'),\n    (0x208F, 'X'),\n    (0x2090, 'M', 'a'),\n    (0x2091, 'M', 'e'),\n    (0x2092, 'M', 'o'),\n    (0x2093, 'M', 'x'),\n    (0x2094, 'M', 'ə'),\n    (0x2095, 'M', 'h'),\n    (0x2096, 'M', 'k'),\n    (0x2097, 'M', 'l'),\n    (0x2098, 'M', 'm'),\n    (0x2099, 'M', 'n'),\n    (0x209A, 'M', 'p'),\n    (0x209B, 'M', 's'),\n    (0x209C, 'M', 't'),\n    (0x209D, 'X'),\n    (0x20A0, 'V'),\n    (0x20A8, 'M', 'rs'),\n    (0x20A9, 'V'),\n    (0x20BB, 'X'),\n    (0x20D0, 'V'),\n    (0x20F1, 'X'),\n    (0x2100, '3', 'a/c'),\n    (0x2101, '3', 'a/s'),\n    (0x2102, 'M', 'c'),\n    (0x2103, 'M', '°c'),\n    (0x2104, 'V'),\n    (0x2105, '3', 'c/o'),\n    (0x2106, '3', 'c/u'),\n    (0x2107, 'M', 'ɛ'),\n    (0x2108, 'V'),\n    (0x2109, 'M', '°f'),\n    (0x210A, 'M', 'g'),\n    (0x210B, 'M', 'h'),\n    (0x210F, 'M', 'ħ'),\n    (0x2110, 'M', 'i'),\n    (0x2112, 'M', 'l'),\n    (0x2114, 'V'),\n    (0x2115, 'M', 'n'),\n    (0x2116, 'M', 'no'),\n    (0x2117, 'V'),\n    (0x2119, 'M', 'p'),\n    (0x211A, 'M', 'q'),\n    (0x211B, 'M', 'r'),\n    (0x211E, 'V'),\n    (0x2120, 'M', 'sm'),\n    (0x2121, 'M', 'tel'),\n    (0x2122, 'M', 'tm'),\n    (0x2123, 'V'),\n    (0x2124, 'M', 'z'),\n    (0x2125, 'V'),\n    (0x2126, 'M', 'ω'),\n    (0x2127, 'V'),\n    (0x2128, 'M', 'z'),\n    (0x2129, 'V'),\n    (0x212A, 'M', 'k'),\n    (0x212B, 'M', 'å'),\n    (0x212C, 'M', 'b'),\n    (0x212D, 'M', 'c'),\n    (0x212E, 'V'),\n    (0x212F, 'M', 'e'),\n    (0x2131, 'M', 'f'),\n    (0x2132, 'X'),\n    (0x2133, 'M', 'm'),\n    (0x2134, 'M', 'o'),\n    (0x2135, 'M', 'א'),\n    (0x2136, 'M', 'ב'),\n    (0x2137, 'M', 'ג'),\n    (0x2138, 'M', 'ד'),\n    (0x2139, 'M', 'i'),\n    (0x213A, 'V'),\n    (0x213B, 'M', 'fax'),\n    (0x213C, 'M', 'π'),\n    (0x213D, 'M', 'γ'),\n    (0x213F, 'M', 'π'),\n    (0x2140, 'M', '∑'),\n    (0x2141, 'V'),\n    (0x2145, 'M', 'd'),\n    (0x2147, 'M', 'e'),\n    (0x2148, 'M', 'i'),\n    (0x2149, 'M', 'j'),\n    (0x214A, 'V'),\n    (0x2150, 'M', '1⁄7'),\n    (0x2151, 'M', '1⁄9'),\n    (0x2152, 'M', '1⁄10'),\n    (0x2153, 'M', '1⁄3'),\n    (0x2154, 'M', '2⁄3'),\n    (0x2155, 'M', '1⁄5'),\n    (0x2156, 'M', '2⁄5'),\n    (0x2157, 'M', '3⁄5'),\n    (0x2158, 'M', '4⁄5'),\n    (0x2159, 'M', '1⁄6'),\n    (0x215A, 'M', '5⁄6'),\n    (0x215B, 'M', '1⁄8'),\n    (0x215C, 'M', '3⁄8'),\n    (0x215D, 'M', '5⁄8'),\n    (0x215E, 'M', '7⁄8'),\n    (0x215F, 'M', '1⁄'),\n    (0x2160, 'M', 'i'),\n    (0x2161, 'M', 'ii'),\n    (0x2162, 'M', 'iii'),\n    (0x2163, 'M', 'iv'),\n    (0x2164, 'M', 'v'),\n    (0x2165, 'M', 'vi'),\n    (0x2166, 'M', 'vii'),\n    (0x2167, 'M', 'viii'),\n    (0x2168, 'M', 'ix'),\n    (0x2169, 'M', 'x'),\n    (0x216A, 'M', 'xi'),\n    (0x216B, 'M', 'xii'),\n    (0x216C, 'M', 'l'),\n    (0x216D, 'M', 'c'),\n    (0x216E, 'M', 'd'),\n    (0x216F, 'M', 'm'),\n    (0x2170, 'M', 'i'),\n    (0x2171, 'M', 'ii'),\n    (0x2172, 'M', 'iii'),\n    (0x2173, 'M', 'iv'),\n    (0x2174, 'M', 'v'),\n    (0x2175, 'M', 'vi'),\n    (0x2176, 'M', 'vii'),\n    (0x2177, 'M', 'viii'),\n    (0x2178, 'M', 'ix'),\n    (0x2179, 'M', 'x'),\n    (0x217A, 'M', 'xi'),\n    (0x217B, 'M', 'xii'),\n    (0x217C, 'M', 'l'),\n    (0x217D, 'M', 'c'),\n    (0x217E, 'M', 'd'),\n    (0x217F, 'M', 'm'),\n    (0x2180, 'V'),\n    (0x2183, 'X'),\n    (0x2184, 'V'),\n    (0x2189, 'M', '0⁄3'),\n    (0x218A, 'X'),\n    (0x2190, 'V'),\n    (0x222C, 'M', '∫∫'),\n    (0x222D, 'M', '∫∫∫'),\n    (0x222E, 'V'),\n    (0x222F, 'M', '∮∮'),\n    (0x2230, 'M', '∮∮∮'),\n    (0x2231, 'V'),\n    (0x2260, '3'),\n    (0x2261, 'V'),\n    (0x226E, '3'),\n    (0x2270, 'V'),\n    (0x2329, 'M', '〈'),\n    (0x232A, 'M', '〉'),\n    (0x232B, 'V'),\n    (0x23F4, 'X'),\n    (0x2400, 'V'),\n    (0x2427, 'X'),\n    (0x2440, 'V'),\n    (0x244B, 'X'),\n    (0x2460, 'M', '1'),\n    (0x2461, 'M', '2'),\n    (0x2462, 'M', '3'),\n    (0x2463, 'M', '4'),\n    (0x2464, 'M', '5'),\n    (0x2465, 'M', '6'),\n    (0x2466, 'M', '7'),\n    (0x2467, 'M', '8'),\n    (0x2468, 'M', '9'),\n    (0x2469, 'M', '10'),\n    (0x246A, 'M', '11'),\n    (0x246B, 'M', '12'),\n    (0x246C, 'M', '13'),\n    (0x246D, 'M', '14'),\n    (0x246E, 'M', '15'),\n    (0x246F, 'M', '16'),\n    (0x2470, 'M', '17'),\n    (0x2471, 'M', '18'),\n    (0x2472, 'M', '19'),\n    (0x2473, 'M', '20'),\n    (0x2474, '3', '(1)'),\n    (0x2475, '3', '(2)'),\n    (0x2476, '3', '(3)'),\n    (0x2477, '3', '(4)'),\n    (0x2478, '3', '(5)'),\n    (0x2479, '3', '(6)'),\n    (0x247A, '3', '(7)'),\n    (0x247B, '3', '(8)'),\n    (0x247C, '3', '(9)'),\n    (0x247D, '3', '(10)'),\n    (0x247E, '3', '(11)'),\n    (0x247F, '3', '(12)'),\n    (0x2480, '3', '(13)'),\n    (0x2481, '3', '(14)'),\n    (0x2482, '3', '(15)'),\n    (0x2483, '3', '(16)'),\n    (0x2484, '3', '(17)'),\n    (0x2485, '3', '(18)'),\n    (0x2486, '3', '(19)'),\n    (0x2487, '3', '(20)'),\n    (0x2488, 'X'),\n    (0x249C, '3', '(a)'),\n    (0x249D, '3', '(b)'),\n    (0x249E, '3', '(c)'),\n    (0x249F, '3', '(d)'),\n    (0x24A0, '3', '(e)'),\n    (0x24A1, '3', '(f)'),\n    (0x24A2, '3', '(g)'),\n    (0x24A3, '3', '(h)'),\n    (0x24A4, '3', '(i)'),\n    (0x24A5, '3', '(j)'),\n    (0x24A6, '3', '(k)'),\n    (0x24A7, '3', '(l)'),\n    (0x24A8, '3', '(m)'),\n    (0x24A9, '3', '(n)'),\n    (0x24AA, '3', '(o)'),\n    (0x24AB, '3', '(p)'),\n    (0x24AC, '3', '(q)'),\n    (0x24AD, '3', '(r)'),\n    (0x24AE, '3', '(s)'),\n    (0x24AF, '3', '(t)'),\n    (0x24B0, '3', '(u)'),\n    (0x24B1, '3', '(v)'),\n    (0x24B2, '3', '(w)'),\n    (0x24B3, '3', '(x)'),\n    (0x24B4, '3', '(y)'),\n    (0x24B5, '3', '(z)'),\n    (0x24B6, 'M', 'a'),\n    (0x24B7, 'M', 'b'),\n    (0x24B8, 'M', 'c'),\n    (0x24B9, 'M', 'd'),\n    (0x24BA, 'M', 'e'),\n    (0x24BB, 'M', 'f'),\n    (0x24BC, 'M', 'g'),\n    (0x24BD, 'M', 'h'),\n    (0x24BE, 'M', 'i'),\n    (0x24BF, 'M', 'j'),\n    (0x24C0, 'M', 'k'),\n    (0x24C1, 'M', 'l'),\n    (0x24C2, 'M', 'm'),\n    (0x24C3, 'M', 'n'),\n    (0x24C4, 'M', 'o'),\n    (0x24C5, 'M', 'p'),\n    (0x24C6, 'M', 'q'),\n    (0x24C7, 'M', 'r'),\n    (0x24C8, 'M', 's'),\n    (0x24C9, 'M', 't'),\n    (0x24CA, 'M', 'u'),\n    (0x24CB, 'M', 'v'),\n    (0x24CC, 'M', 'w'),\n    (0x24CD, 'M', 'x'),\n    (0x24CE, 'M', 'y'),\n    (0x24CF, 'M', 'z'),\n    (0x24D0, 'M', 'a'),\n    (0x24D1, 'M', 'b'),\n    (0x24D2, 'M', 'c'),\n    (0x24D3, 'M', 'd'),\n    (0x24D4, 'M', 'e'),\n    (0x24D5, 'M', 'f'),\n    (0x24D6, 'M', 'g'),\n    (0x24D7, 'M', 'h'),\n    (0x24D8, 'M', 'i'),\n    (0x24D9, 'M', 'j'),\n    (0x24DA, 'M', 'k'),\n    (0x24DB, 'M', 'l'),\n    (0x24DC, 'M', 'm'),\n    (0x24DD, 'M', 'n'),\n    (0x24DE, 'M', 'o'),\n    (0x24DF, 'M', 'p'),\n    (0x24E0, 'M', 'q'),\n    (0x24E1, 'M', 'r'),\n    (0x24E2, 'M', 's'),\n    (0x24E3, 'M', 't'),\n    (0x24E4, 'M', 'u'),\n    (0x24E5, 'M', 'v'),\n    (0x24E6, 'M', 'w'),\n    (0x24E7, 'M', 'x'),\n    (0x24E8, 'M', 'y'),\n    (0x24E9, 'M', 'z'),\n    (0x24EA, 'M', '0'),\n    (0x24EB, 'V'),\n    (0x2700, 'X'),\n    (0x2701, 'V'),\n    (0x2A0C, 'M', '∫∫∫∫'),\n    (0x2A0D, 'V'),\n    (0x2A74, '3', '::='),\n    (0x2A75, '3', '=='),\n    (0x2A76, '3', '==='),\n    (0x2A77, 'V'),\n    (0x2ADC, 'M', '⫝̸'),\n    (0x2ADD, 'V'),\n    (0x2B4D, 'X'),\n    (0x2B50, 'V'),\n    (0x2B5A, 'X'),\n    (0x2C00, 'M', 'ⰰ'),\n    (0x2C01, 'M', 'ⰱ'),\n    (0x2C02, 'M', 'ⰲ'),\n    (0x2C03, 'M', 'ⰳ'),\n    (0x2C04, 'M', 'ⰴ'),\n    (0x2C05, 'M', 'ⰵ'),\n    (0x2C06, 'M', 'ⰶ'),\n    (0x2C07, 'M', 'ⰷ'),\n    (0x2C08, 'M', 'ⰸ'),\n    (0x2C09, 'M', 'ⰹ'),\n    (0x2C0A, 'M', 'ⰺ'),\n    (0x2C0B, 'M', 'ⰻ'),\n    (0x2C0C, 'M', 'ⰼ'),\n    (0x2C0D, 'M', 'ⰽ'),\n    (0x2C0E, 'M', 'ⰾ'),\n    (0x2C0F, 'M', 'ⰿ'),\n    (0x2C10, 'M', 'ⱀ'),\n    (0x2C11, 'M', 'ⱁ'),\n    (0x2C12, 'M', 'ⱂ'),\n    (0x2C13, 'M', 'ⱃ'),\n    (0x2C14, 'M', 'ⱄ'),\n    (0x2C15, 'M', 'ⱅ'),\n    (0x2C16, 'M', 'ⱆ'),\n    (0x2C17, 'M', 'ⱇ'),\n    (0x2C18, 'M', 'ⱈ'),\n    (0x2C19, 'M', 'ⱉ'),\n    (0x2C1A, 'M', 'ⱊ'),\n    (0x2C1B, 'M', 'ⱋ'),\n    (0x2C1C, 'M', 'ⱌ'),\n    (0x2C1D, 'M', 'ⱍ'),\n    (0x2C1E, 'M', 'ⱎ'),\n    (0x2C1F, 'M', 'ⱏ'),\n    (0x2C20, 'M', 'ⱐ'),\n    (0x2C21, 'M', 'ⱑ'),\n    (0x2C22, 'M', 'ⱒ'),\n    (0x2C23, 'M', 'ⱓ'),\n    (0x2C24, 'M', 'ⱔ'),\n    (0x2C25, 'M', 'ⱕ'),\n    (0x2C26, 'M', 'ⱖ'),\n    (0x2C27, 'M', 'ⱗ'),\n    (0x2C28, 'M', 'ⱘ'),\n    (0x2C29, 'M', 'ⱙ'),\n    (0x2C2A, 'M', 'ⱚ'),\n    (0x2C2B, 'M', 'ⱛ'),\n    (0x2C2C, 'M', 'ⱜ'),\n    (0x2C2D, 'M', 'ⱝ'),\n    (0x2C2E, 'M', 'ⱞ'),\n    (0x2C2F, 'X'),\n    (0x2C30, 'V'),\n    (0x2C5F, 'X'),\n    (0x2C60, 'M', 'ⱡ'),\n    (0x2C61, 'V'),\n    (0x2C62, 'M', 'ɫ'),\n    (0x2C63, 'M', 'ᵽ'),\n    (0x2C64, 'M', 'ɽ'),\n    (0x2C65, 'V'),\n    (0x2C67, 'M', 'ⱨ'),\n    (0x2C68, 'V'),\n    (0x2C69, 'M', 'ⱪ'),\n    (0x2C6A, 'V'),\n    (0x2C6B, 'M', 'ⱬ'),\n    (0x2C6C, 'V'),\n    (0x2C6D, 'M', 'ɑ'),\n    (0x2C6E, 'M', 'ɱ'),\n    (0x2C6F, 'M', 'ɐ'),\n    (0x2C70, 'M', 'ɒ'),\n    (0x2C71, 'V'),\n    (0x2C72, 'M', 'ⱳ'),\n    (0x2C73, 'V'),\n    (0x2C75, 'M', 'ⱶ'),\n    (0x2C76, 'V'),\n    (0x2C7C, 'M', 'j'),\n    (0x2C7D, 'M', 'v'),\n    (0x2C7E, 'M', 'ȿ'),\n    (0x2C7F, 'M', 'ɀ'),\n    (0x2C80, 'M', 'ⲁ'),\n    (0x2C81, 'V'),\n    (0x2C82, 'M', 'ⲃ'),\n    (0x2C83, 'V'),\n    (0x2C84, 'M', 'ⲅ'),\n    (0x2C85, 'V'),\n    (0x2C86, 'M', 'ⲇ'),\n    (0x2C87, 'V'),\n    (0x2C88, 'M', 'ⲉ'),\n    (0x2C89, 'V'),\n    (0x2C8A, 'M', 'ⲋ'),\n    (0x2C8B, 'V'),\n    (0x2C8C, 'M', 'ⲍ'),\n    (0x2C8D, 'V'),\n    (0x2C8E, 'M', 'ⲏ'),\n    (0x2C8F, 'V'),\n    (0x2C90, 'M', 'ⲑ'),\n    (0x2C91, 'V'),\n    (0x2C92, 'M', 'ⲓ'),\n    (0x2C93, 'V'),\n    (0x2C94, 'M', 'ⲕ'),\n    (0x2C95, 'V'),\n    (0x2C96, 'M', 'ⲗ'),\n    (0x2C97, 'V'),\n    (0x2C98, 'M', 'ⲙ'),\n    (0x2C99, 'V'),\n    (0x2C9A, 'M', 'ⲛ'),\n    (0x2C9B, 'V'),\n    (0x2C9C, 'M', 'ⲝ'),\n    (0x2C9D, 'V'),\n    (0x2C9E, 'M', 'ⲟ'),\n    (0x2C9F, 'V'),\n    (0x2CA0, 'M', 'ⲡ'),\n    (0x2CA1, 'V'),\n    (0x2CA2, 'M', 'ⲣ'),\n    (0x2CA3, 'V'),\n    (0x2CA4, 'M', 'ⲥ'),\n    (0x2CA5, 'V'),\n    (0x2CA6, 'M', 'ⲧ'),\n    (0x2CA7, 'V'),\n    (0x2CA8, 'M', 'ⲩ'),\n    (0x2CA9, 'V'),\n    (0x2CAA, 'M', 'ⲫ'),\n    (0x2CAB, 'V'),\n    (0x2CAC, 'M', 'ⲭ'),\n    (0x2CAD, 'V'),\n    (0x2CAE, 'M', 'ⲯ'),\n    (0x2CAF, 'V'),\n    (0x2CB0, 'M', 'ⲱ'),\n    (0x2CB1, 'V'),\n    (0x2CB2, 'M', 'ⲳ'),\n    (0x2CB3, 'V'),\n    (0x2CB4, 'M', 'ⲵ'),\n    (0x2CB5, 'V'),\n    (0x2CB6, 'M', 'ⲷ'),\n    (0x2CB7, 'V'),\n    (0x2CB8, 'M', 'ⲹ'),\n    (0x2CB9, 'V'),\n    (0x2CBA, 'M', 'ⲻ'),\n    (0x2CBB, 'V'),\n    (0x2CBC, 'M', 'ⲽ'),\n    (0x2CBD, 'V'),\n    (0x2CBE, 'M', 'ⲿ'),\n    (0x2CBF, 'V'),\n    (0x2CC0, 'M', 'ⳁ'),\n    (0x2CC1, 'V'),\n    (0x2CC2, 'M', 'ⳃ'),\n    (0x2CC3, 'V'),\n    (0x2CC4, 'M', 'ⳅ'),\n    (0x2CC5, 'V'),\n    (0x2CC6, 'M', 'ⳇ'),\n    (0x2CC7, 'V'),\n    (0x2CC8, 'M', 'ⳉ'),\n    (0x2CC9, 'V'),\n    (0x2CCA, 'M', 'ⳋ'),\n    (0x2CCB, 'V'),\n    (0x2CCC, 'M', 'ⳍ'),\n    (0x2CCD, 'V'),\n    (0x2CCE, 'M', 'ⳏ'),\n    (0x2CCF, 'V'),\n    (0x2CD0, 'M', 'ⳑ'),\n    (0x2CD1, 'V'),\n    (0x2CD2, 'M', 'ⳓ'),\n    (0x2CD3, 'V'),\n    (0x2CD4, 'M', 'ⳕ'),\n    (0x2CD5, 'V'),\n    (0x2CD6, 'M', 'ⳗ'),\n    (0x2CD7, 'V'),\n    (0x2CD8, 'M', 'ⳙ'),\n    (0x2CD9, 'V'),\n    (0x2CDA, 'M', 'ⳛ'),\n    (0x2CDB, 'V'),\n    (0x2CDC, 'M', 'ⳝ'),\n    (0x2CDD, 'V'),\n    (0x2CDE, 'M', 'ⳟ'),\n    (0x2CDF, 'V'),\n    (0x2CE0, 'M', 'ⳡ'),\n    (0x2CE1, 'V'),\n    (0x2CE2, 'M', 'ⳣ'),\n    (0x2CE3, 'V'),\n    (0x2CEB, 'M', 'ⳬ'),\n    (0x2CEC, 'V'),\n    (0x2CED, 'M', 'ⳮ'),\n    (0x2CEE, 'V'),\n    (0x2CF2, 'M', 'ⳳ'),\n    (0x2CF3, 'V'),\n    (0x2CF4, 'X'),\n    (0x2CF9, 'V'),\n    (0x2D26, 'X'),\n    (0x2D27, 'V'),\n    (0x2D28, 'X'),\n    (0x2D2D, 'V'),\n    (0x2D2E, 'X'),\n    (0x2D30, 'V'),\n    (0x2D68, 'X'),\n    (0x2D6F, 'M', 'ⵡ'),\n    (0x2D70, 'V'),\n    (0x2D71, 'X'),\n    (0x2D7F, 'V'),\n    (0x2D97, 'X'),\n    (0x2DA0, 'V'),\n    (0x2DA7, 'X'),\n    (0x2DA8, 'V'),\n    (0x2DAF, 'X'),\n    (0x2DB0, 'V'),\n    (0x2DB7, 'X'),\n    (0x2DB8, 'V'),\n    (0x2DBF, 'X'),\n    (0x2DC0, 'V'),\n    (0x2DC7, 'X'),\n    (0x2DC8, 'V'),\n    (0x2DCF, 'X'),\n    (0x2DD0, 'V'),\n    (0x2DD7, 'X'),\n    (0x2DD8, 'V'),\n    (0x2DDF, 'X'),\n    (0x2DE0, 'V'),\n    (0x2E3C, 'X'),\n    (0x2E80, 'V'),\n    (0x2E9A, 'X'),\n    (0x2E9B, 'V'),\n    (0x2E9F, 'M', '母'),\n    (0x2EA0, 'V'),\n    (0x2EF3, 'M', '龟'),\n    (0x2EF4, 'X'),\n    (0x2F00, 'M', '一'),\n    (0x2F01, 'M', '丨'),\n    (0x2F02, 'M', '丶'),\n    (0x2F03, 'M', '丿'),\n    (0x2F04, 'M', '乙'),\n    (0x2F05, 'M', '亅'),\n    (0x2F06, 'M', '二'),\n    (0x2F07, 'M', '亠'),\n    (0x2F08, 'M', '人'),\n    (0x2F09, 'M', '儿'),\n    (0x2F0A, 'M', '入'),\n    (0x2F0B, 'M', '八'),\n    (0x2F0C, 'M', '冂'),\n    (0x2F0D, 'M', '冖'),\n    (0x2F0E, 'M', '冫'),\n    (0x2F0F, 'M', '几'),\n    (0x2F10, 'M', '凵'),\n    (0x2F11, 'M', '刀'),\n    (0x2F12, 'M', '力'),\n    (0x2F13, 'M', '勹'),\n    (0x2F14, 'M', '匕'),\n    (0x2F15, 'M', '匚'),\n    (0x2F16, 'M', '匸'),\n    (0x2F17, 'M', '十'),\n    (0x2F18, 'M', '卜'),\n    (0x2F19, 'M', '卩'),\n    (0x2F1A, 'M', '厂'),\n    (0x2F1B, 'M', '厶'),\n    (0x2F1C, 'M', '又'),\n    (0x2F1D, 'M', '口'),\n    (0x2F1E, 'M', '囗'),\n    (0x2F1F, 'M', '土'),\n    (0x2F20, 'M', '士'),\n    (0x2F21, 'M', '夂'),\n    (0x2F22, 'M', '夊'),\n    (0x2F23, 'M', '夕'),\n    (0x2F24, 'M', '大'),\n    (0x2F25, 'M', '女'),\n    (0x2F26, 'M', '子'),\n    (0x2F27, 'M', '宀'),\n    (0x2F28, 'M', '寸'),\n    (0x2F29, 'M', '小'),\n    (0x2F2A, 'M', '尢'),\n    (0x2F2B, 'M', '尸'),\n    (0x2F2C, 'M', '屮'),\n    (0x2F2D, 'M', '山'),\n    (0x2F2E, 'M', '巛'),\n    (0x2F2F, 'M', '工'),\n    (0x2F30, 'M', '己'),\n    (0x2F31, 'M', '巾'),\n    (0x2F32, 'M', '干'),\n    (0x2F33, 'M', '幺'),\n    (0x2F34, 'M', '广'),\n    (0x2F35, 'M', '廴'),\n    (0x2F36, 'M', '廾'),\n    (0x2F37, 'M', '弋'),\n    (0x2F38, 'M', '弓'),\n    (0x2F39, 'M', '彐'),\n    (0x2F3A, 'M', '彡'),\n    (0x2F3B, 'M', '彳'),\n    (0x2F3C, 'M', '心'),\n    (0x2F3D, 'M', '戈'),\n    (0x2F3E, 'M', '戶'),\n    (0x2F3F, 'M', '手'),\n    (0x2F40, 'M', '支'),\n    (0x2F41, 'M', '攴'),\n    (0x2F42, 'M', '文'),\n    (0x2F43, 'M', '斗'),\n    (0x2F44, 'M', '斤'),\n    (0x2F45, 'M', '方'),\n    (0x2F46, 'M', '无'),\n    (0x2F47, 'M', '日'),\n    (0x2F48, 'M', '曰'),\n    (0x2F49, 'M', '月'),\n    (0x2F4A, 'M', '木'),\n    (0x2F4B, 'M', '欠'),\n    (0x2F4C, 'M', '止'),\n    (0x2F4D, 'M', '歹'),\n    (0x2F4E, 'M', '殳'),\n    (0x2F4F, 'M', '毋'),\n    (0x2F50, 'M', '比'),\n    (0x2F51, 'M', '毛'),\n    (0x2F52, 'M', '氏'),\n    (0x2F53, 'M', '气'),\n    (0x2F54, 'M', '水'),\n    (0x2F55, 'M', '火'),\n    (0x2F56, 'M', '爪'),\n    (0x2F57, 'M', '父'),\n    (0x2F58, 'M', '爻'),\n    (0x2F59, 'M', '爿'),\n    (0x2F5A, 'M', '片'),\n    (0x2F5B, 'M', '牙'),\n    (0x2F5C, 'M', '牛'),\n    (0x2F5D, 'M', '犬'),\n    (0x2F5E, 'M', '玄'),\n    (0x2F5F, 'M', '玉'),\n    (0x2F60, 'M', '瓜'),\n    (0x2F61, 'M', '瓦'),\n    (0x2F62, 'M', '甘'),\n    (0x2F63, 'M', '生'),\n    (0x2F64, 'M', '用'),\n    (0x2F65, 'M', '田'),\n    (0x2F66, 'M', '疋'),\n    (0x2F67, 'M', '疒'),\n    (0x2F68, 'M', '癶'),\n    (0x2F69, 'M', '白'),\n    (0x2F6A, 'M', '皮'),\n    (0x2F6B, 'M', '皿'),\n    (0x2F6C, 'M', '目'),\n    (0x2F6D, 'M', '矛'),\n    (0x2F6E, 'M', '矢'),\n    (0x2F6F, 'M', '石'),\n    (0x2F70, 'M', '示'),\n    (0x2F71, 'M', '禸'),\n    (0x2F72, 'M', '禾'),\n    (0x2F73, 'M', '穴'),\n    (0x2F74, 'M', '立'),\n    (0x2F75, 'M', '竹'),\n    (0x2F76, 'M', '米'),\n    (0x2F77, 'M', '糸'),\n    (0x2F78, 'M', '缶'),\n    (0x2F79, 'M', '网'),\n    (0x2F7A, 'M', '羊'),\n    (0x2F7B, 'M', '羽'),\n    (0x2F7C, 'M', '老'),\n    (0x2F7D, 'M', '而'),\n    (0x2F7E, 'M', '耒'),\n    (0x2F7F, 'M', '耳'),\n    (0x2F80, 'M', '聿'),\n    (0x2F81, 'M', '肉'),\n    (0x2F82, 'M', '臣'),\n    (0x2F83, 'M', '自'),\n    (0x2F84, 'M', '至'),\n    (0x2F85, 'M', '臼'),\n    (0x2F86, 'M', '舌'),\n    (0x2F87, 'M', '舛'),\n    (0x2F88, 'M', '舟'),\n    (0x2F89, 'M', '艮'),\n    (0x2F8A, 'M', '色'),\n    (0x2F8B, 'M', '艸'),\n    (0x2F8C, 'M', '虍'),\n    (0x2F8D, 'M', '虫'),\n    (0x2F8E, 'M', '血'),\n    (0x2F8F, 'M', '行'),\n    (0x2F90, 'M', '衣'),\n    (0x2F91, 'M', '襾'),\n    (0x2F92, 'M', '見'),\n    (0x2F93, 'M', '角'),\n    (0x2F94, 'M', '言'),\n    (0x2F95, 'M', '谷'),\n    (0x2F96, 'M', '豆'),\n    (0x2F97, 'M', '豕'),\n    (0x2F98, 'M', '豸'),\n    (0x2F99, 'M', '貝'),\n    (0x2F9A, 'M', '赤'),\n    (0x2F9B, 'M', '走'),\n    (0x2F9C, 'M', '足'),\n    (0x2F9D, 'M', '身'),\n    (0x2F9E, 'M', '車'),\n    (0x2F9F, 'M', '辛'),\n    (0x2FA0, 'M', '辰'),\n    (0x2FA1, 'M', '辵'),\n    (0x2FA2, 'M', '邑'),\n    (0x2FA3, 'M', '酉'),\n    (0x2FA4, 'M', '釆'),\n    (0x2FA5, 'M', '里'),\n    (0x2FA6, 'M', '金'),\n    (0x2FA7, 'M', '長'),\n    (0x2FA8, 'M', '門'),\n    (0x2FA9, 'M', '阜'),\n    (0x2FAA, 'M', '隶'),\n    (0x2FAB, 'M', '隹'),\n    (0x2FAC, 'M', '雨'),\n    (0x2FAD, 'M', '靑'),\n    (0x2FAE, 'M', '非'),\n    (0x2FAF, 'M', '面'),\n    (0x2FB0, 'M', '革'),\n    (0x2FB1, 'M', '韋'),\n    (0x2FB2, 'M', '韭'),\n    (0x2FB3, 'M', '音'),\n    (0x2FB4, 'M', '頁'),\n    (0x2FB5, 'M', '風'),\n    (0x2FB6, 'M', '飛'),\n    (0x2FB7, 'M', '食'),\n    (0x2FB8, 'M', '首'),\n    (0x2FB9, 'M', '香'),\n    (0x2FBA, 'M', '馬'),\n    (0x2FBB, 'M', '骨'),\n    (0x2FBC, 'M', '高'),\n    (0x2FBD, 'M', '髟'),\n    (0x2FBE, 'M', '鬥'),\n    (0x2FBF, 'M', '鬯'),\n    (0x2FC0, 'M', '鬲'),\n    (0x2FC1, 'M', '鬼'),\n    (0x2FC2, 'M', '魚'),\n    (0x2FC3, 'M', '鳥'),\n    (0x2FC4, 'M', '鹵'),\n    (0x2FC5, 'M', '鹿'),\n    (0x2FC6, 'M', '麥'),\n    (0x2FC7, 'M', '麻'),\n    (0x2FC8, 'M', '黃'),\n    (0x2FC9, 'M', '黍'),\n    (0x2FCA, 'M', '黑'),\n    (0x2FCB, 'M', '黹'),\n    (0x2FCC, 'M', '黽'),\n    (0x2FCD, 'M', '鼎'),\n    (0x2FCE, 'M', '鼓'),\n    (0x2FCF, 'M', '鼠'),\n    (0x2FD0, 'M', '鼻'),\n    (0x2FD1, 'M', '齊'),\n    (0x2FD2, 'M', '齒'),\n    (0x2FD3, 'M', '龍'),\n    (0x2FD4, 'M', '龜'),\n    (0x2FD5, 'M', '龠'),\n    (0x2FD6, 'X'),\n    (0x3000, '3', ' '),\n    (0x3001, 'V'),\n    (0x3002, 'M', '.'),\n    (0x3003, 'V'),\n    (0x3036, 'M', '〒'),\n    (0x3037, 'V'),\n    (0x3038, 'M', '十'),\n    (0x3039, 'M', '卄'),\n    (0x303A, 'M', '卅'),\n    (0x303B, 'V'),\n    (0x3040, 'X'),\n    (0x3041, 'V'),\n    (0x3097, 'X'),\n    (0x3099, 'V'),\n    (0x309B, '3', ' ゙'),\n    (0x309C, '3', ' ゚'),\n    (0x309D, 'V'),\n    (0x309F, 'M', 'より'),\n    (0x30A0, 'V'),\n    (0x30FF, 'M', 'コト'),\n    (0x3100, 'X'),\n    (0x3105, 'V'),\n    (0x312E, 'X'),\n    (0x3131, 'M', 'ᄀ'),\n    (0x3132, 'M', 'ᄁ'),\n    (0x3133, 'M', 'ᆪ'),\n    (0x3134, 'M', 'ᄂ'),\n    (0x3135, 'M', 'ᆬ'),\n    (0x3136, 'M', 'ᆭ'),\n    (0x3137, 'M', 'ᄃ'),\n    (0x3138, 'M', 'ᄄ'),\n    (0x3139, 'M', 'ᄅ'),\n    (0x313A, 'M', 'ᆰ'),\n    (0x313B, 'M', 'ᆱ'),\n    (0x313C, 'M', 'ᆲ'),\n    (0x313D, 'M', 'ᆳ'),\n    (0x313E, 'M', 'ᆴ'),\n    (0x313F, 'M', 'ᆵ'),\n    (0x3140, 'M', 'ᄚ'),\n    (0x3141, 'M', 'ᄆ'),\n    (0x3142, 'M', 'ᄇ'),\n    (0x3143, 'M', 'ᄈ'),\n    (0x3144, 'M', 'ᄡ'),\n    (0x3145, 'M', 'ᄉ'),\n    (0x3146, 'M', 'ᄊ'),\n    (0x3147, 'M', 'ᄋ'),\n    (0x3148, 'M', 'ᄌ'),\n    (0x3149, 'M', 'ᄍ'),\n    (0x314A, 'M', 'ᄎ'),\n    (0x314B, 'M', 'ᄏ'),\n    (0x314C, 'M', 'ᄐ'),\n    (0x314D, 'M', 'ᄑ'),\n    (0x314E, 'M', 'ᄒ'),\n    (0x314F, 'M', 'ᅡ'),\n    (0x3150, 'M', 'ᅢ'),\n    (0x3151, 'M', 'ᅣ'),\n    (0x3152, 'M', 'ᅤ'),\n    (0x3153, 'M', 'ᅥ'),\n    (0x3154, 'M', 'ᅦ'),\n    (0x3155, 'M', 'ᅧ'),\n    (0x3156, 'M', 'ᅨ'),\n    (0x3157, 'M', 'ᅩ'),\n    (0x3158, 'M', 'ᅪ'),\n    (0x3159, 'M', 'ᅫ'),\n    (0x315A, 'M', 'ᅬ'),\n    (0x315B, 'M', 'ᅭ'),\n    (0x315C, 'M', 'ᅮ'),\n    (0x315D, 'M', 'ᅯ'),\n    (0x315E, 'M', 'ᅰ'),\n    (0x315F, 'M', 'ᅱ'),\n    (0x3160, 'M', 'ᅲ'),\n    (0x3161, 'M', 'ᅳ'),\n    (0x3162, 'M', 'ᅴ'),\n    (0x3163, 'M', 'ᅵ'),\n    (0x3164, 'X'),\n    (0x3165, 'M', 'ᄔ'),\n    (0x3166, 'M', 'ᄕ'),\n    (0x3167, 'M', 'ᇇ'),\n    (0x3168, 'M', 'ᇈ'),\n    (0x3169, 'M', 'ᇌ'),\n    (0x316A, 'M', 'ᇎ'),\n    (0x316B, 'M', 'ᇓ'),\n    (0x316C, 'M', 'ᇗ'),\n    (0x316D, 'M', 'ᇙ'),\n    (0x316E, 'M', 'ᄜ'),\n    (0x316F, 'M', 'ᇝ'),\n    (0x3170, 'M', 'ᇟ'),\n    (0x3171, 'M', 'ᄝ'),\n    (0x3172, 'M', 'ᄞ'),\n    (0x3173, 'M', 'ᄠ'),\n    (0x3174, 'M', 'ᄢ'),\n    (0x3175, 'M', 'ᄣ'),\n    (0x3176, 'M', 'ᄧ'),\n    (0x3177, 'M', 'ᄩ'),\n    (0x3178, 'M', 'ᄫ'),\n    (0x3179, 'M', 'ᄬ'),\n    (0x317A, 'M', 'ᄭ'),\n    (0x317B, 'M', 'ᄮ'),\n    (0x317C, 'M', 'ᄯ'),\n    (0x317D, 'M', 'ᄲ'),\n    (0x317E, 'M', 'ᄶ'),\n    (0x317F, 'M', 'ᅀ'),\n    (0x3180, 'M', 'ᅇ'),\n    (0x3181, 'M', 'ᅌ'),\n    (0x3182, 'M', 'ᇱ'),\n    (0x3183, 'M', 'ᇲ'),\n    (0x3184, 'M', 'ᅗ'),\n    (0x3185, 'M', 'ᅘ'),\n    (0x3186, 'M', 'ᅙ'),\n    (0x3187, 'M', 'ᆄ'),\n    (0x3188, 'M', 'ᆅ'),\n    (0x3189, 'M', 'ᆈ'),\n    (0x318A, 'M', 'ᆑ'),\n    (0x318B, 'M', 'ᆒ'),\n    (0x318C, 'M', 'ᆔ'),\n    (0x318D, 'M', 'ᆞ'),\n    (0x318E, 'M', 'ᆡ'),\n    (0x318F, 'X'),\n    (0x3190, 'V'),\n    (0x3192, 'M', '一'),\n    (0x3193, 'M', '二'),\n    (0x3194, 'M', '三'),\n    (0x3195, 'M', '四'),\n    (0x3196, 'M', '上'),\n    (0x3197, 'M', '中'),\n    (0x3198, 'M', '下'),\n    (0x3199, 'M', '甲'),\n    (0x319A, 'M', '乙'),\n    (0x319B, 'M', '丙'),\n    (0x319C, 'M', '丁'),\n    (0x319D, 'M', '天'),\n    (0x319E, 'M', '地'),\n    (0x319F, 'M', '人'),\n    (0x31A0, 'V'),\n    (0x31BB, 'X'),\n    (0x31C0, 'V'),\n    (0x31E4, 'X'),\n    (0x31F0, 'V'),\n    (0x3200, '3', '(ᄀ)'),\n    (0x3201, '3', '(ᄂ)'),\n    (0x3202, '3', '(ᄃ)'),\n    (0x3203, '3', '(ᄅ)'),\n    (0x3204, '3', '(ᄆ)'),\n    (0x3205, '3', '(ᄇ)'),\n    (0x3206, '3', '(ᄉ)'),\n    (0x3207, '3', '(ᄋ)'),\n    (0x3208, '3', '(ᄌ)'),\n    (0x3209, '3', '(ᄎ)'),\n    (0x320A, '3', '(ᄏ)'),\n    (0x320B, '3', '(ᄐ)'),\n    (0x320C, '3', '(ᄑ)'),\n    (0x320D, '3', '(ᄒ)'),\n    (0x320E, '3', '(가)'),\n    (0x320F, '3', '(나)'),\n    (0x3210, '3', '(다)'),\n    (0x3211, '3', '(라)'),\n    (0x3212, '3', '(마)'),\n    (0x3213, '3', '(바)'),\n    (0x3214, '3', '(사)'),\n    (0x3215, '3', '(아)'),\n    (0x3216, '3', '(자)'),\n    (0x3217, '3', '(차)'),\n    (0x3218, '3', '(카)'),\n    (0x3219, '3', '(타)'),\n    (0x321A, '3', '(파)'),\n    (0x321B, '3', '(하)'),\n    (0x321C, '3', '(주)'),\n    (0x321D, '3', '(오전)'),\n    (0x321E, '3', '(오후)'),\n    (0x321F, 'X'),\n    (0x3220, '3', '(一)'),\n    (0x3221, '3', '(二)'),\n    (0x3222, '3', '(三)'),\n    (0x3223, '3', '(四)'),\n    (0x3224, '3', '(五)'),\n    (0x3225, '3', '(六)'),\n    (0x3226, '3', '(七)'),\n    (0x3227, '3', '(八)'),\n    (0x3228, '3', '(九)'),\n    (0x3229, '3', '(十)'),\n    (0x322A, '3', '(月)'),\n    (0x322B, '3', '(火)'),\n    (0x322C, '3', '(水)'),\n    (0x322D, '3', '(木)'),\n    (0x322E, '3', '(金)'),\n    (0x322F, '3', '(土)'),\n    (0x3230, '3', '(日)'),\n    (0x3231, '3', '(株)'),\n    (0x3232, '3', '(有)'),\n    (0x3233, '3', '(社)'),\n    (0x3234, '3', '(名)'),\n    (0x3235, '3', '(特)'),\n    (0x3236, '3', '(財)'),\n    (0x3237, '3', '(祝)'),\n    (0x3238, '3', '(労)'),\n    (0x3239, '3', '(代)'),\n    (0x323A, '3', '(呼)'),\n    (0x323B, '3', '(学)'),\n    (0x323C, '3', '(監)'),\n    (0x323D, '3', '(企)'),\n    (0x323E, '3', '(資)'),\n    (0x323F, '3', '(協)'),\n    (0x3240, '3', '(祭)'),\n    (0x3241, '3', '(休)'),\n    (0x3242, '3', '(自)'),\n    (0x3243, '3', '(至)'),\n    (0x3244, 'M', '問'),\n    (0x3245, 'M', '幼'),\n    (0x3246, 'M', '文'),\n    (0x3247, 'M', '箏'),\n    (0x3248, 'V'),\n    (0x3250, 'M', 'pte'),\n    (0x3251, 'M', '21'),\n    (0x3252, 'M', '22'),\n    (0x3253, 'M', '23'),\n    (0x3254, 'M', '24'),\n    (0x3255, 'M', '25'),\n    (0x3256, 'M', '26'),\n    (0x3257, 'M', '27'),\n    (0x3258, 'M', '28'),\n    (0x3259, 'M', '29'),\n    (0x325A, 'M', '30'),\n    (0x325B, 'M', '31'),\n    (0x325C, 'M', '32'),\n    (0x325D, 'M', '33'),\n    (0x325E, 'M', '34'),\n    (0x325F, 'M', '35'),\n    (0x3260, 'M', 'ᄀ'),\n    (0x3261, 'M', 'ᄂ'),\n    (0x3262, 'M', 'ᄃ'),\n    (0x3263, 'M', 'ᄅ'),\n    (0x3264, 'M', 'ᄆ'),\n    (0x3265, 'M', 'ᄇ'),\n    (0x3266, 'M', 'ᄉ'),\n    (0x3267, 'M', 'ᄋ'),\n    (0x3268, 'M', 'ᄌ'),\n    (0x3269, 'M', 'ᄎ'),\n    (0x326A, 'M', 'ᄏ'),\n    (0x326B, 'M', 'ᄐ'),\n    (0x326C, 'M', 'ᄑ'),\n    (0x326D, 'M', 'ᄒ'),\n    (0x326E, 'M', '가'),\n    (0x326F, 'M', '나'),\n    (0x3270, 'M', '다'),\n    (0x3271, 'M', '라'),\n    (0x3272, 'M', '마'),\n    (0x3273, 'M', '바'),\n    (0x3274, 'M', '사'),\n    (0x3275, 'M', '아'),\n    (0x3276, 'M', '자'),\n    (0x3277, 'M', '차'),\n    (0x3278, 'M', '카'),\n    (0x3279, 'M', '타'),\n    (0x327A, 'M', '파'),\n    (0x327B, 'M', '하'),\n    (0x327C, 'M', '참고'),\n    (0x327D, 'M', '주의'),\n    (0x327E, 'M', '우'),\n    (0x327F, 'V'),\n    (0x3280, 'M', '一'),\n    (0x3281, 'M', '二'),\n    (0x3282, 'M', '三'),\n    (0x3283, 'M', '四'),\n    (0x3284, 'M', '五'),\n    (0x3285, 'M', '六'),\n    (0x3286, 'M', '七'),\n    (0x3287, 'M', '八'),\n    (0x3288, 'M', '九'),\n    (0x3289, 'M', '十'),\n    (0x328A, 'M', '月'),\n    (0x328B, 'M', '火'),\n    (0x328C, 'M', '水'),\n    (0x328D, 'M', '木'),\n    (0x328E, 'M', '金'),\n    (0x328F, 'M', '土'),\n    (0x3290, 'M', '日'),\n    (0x3291, 'M', '株'),\n    (0x3292, 'M', '有'),\n    (0x3293, 'M', '社'),\n    (0x3294, 'M', '名'),\n    (0x3295, 'M', '特'),\n    (0x3296, 'M', '財'),\n    (0x3297, 'M', '祝'),\n    (0x3298, 'M', '労'),\n    (0x3299, 'M', '秘'),\n    (0x329A, 'M', '男'),\n    (0x329B, 'M', '女'),\n    (0x329C, 'M', '適'),\n    (0x329D, 'M', '優'),\n    (0x329E, 'M', '印'),\n    (0x329F, 'M', '注'),\n    (0x32A0, 'M', '項'),\n    (0x32A1, 'M', '休'),\n    (0x32A2, 'M', '写'),\n    (0x32A3, 'M', '正'),\n    (0x32A4, 'M', '上'),\n    (0x32A5, 'M', '中'),\n    (0x32A6, 'M', '下'),\n    (0x32A7, 'M', '左'),\n    (0x32A8, 'M', '右'),\n    (0x32A9, 'M', '医'),\n    (0x32AA, 'M', '宗'),\n    (0x32AB, 'M', '学'),\n    (0x32AC, 'M', '監'),\n    (0x32AD, 'M', '企'),\n    (0x32AE, 'M', '資'),\n    (0x32AF, 'M', '協'),\n    (0x32B0, 'M', '夜'),\n    (0x32B1, 'M', '36'),\n    (0x32B2, 'M', '37'),\n    (0x32B3, 'M', '38'),\n    (0x32B4, 'M', '39'),\n    (0x32B5, 'M', '40'),\n    (0x32B6, 'M', '41'),\n    (0x32B7, 'M', '42'),\n    (0x32B8, 'M', '43'),\n    (0x32B9, 'M', '44'),\n    (0x32BA, 'M', '45'),\n    (0x32BB, 'M', '46'),\n    (0x32BC, 'M', '47'),\n    (0x32BD, 'M', '48'),\n    (0x32BE, 'M', '49'),\n    (0x32BF, 'M', '50'),\n    (0x32C0, 'M', '1月'),\n    (0x32C1, 'M', '2月'),\n    (0x32C2, 'M', '3月'),\n    (0x32C3, 'M', '4月'),\n    (0x32C4, 'M', '5月'),\n    (0x32C5, 'M', '6月'),\n    (0x32C6, 'M', '7月'),\n    (0x32C7, 'M', '8月'),\n    (0x32C8, 'M', '9月'),\n    (0x32C9, 'M', '10月'),\n    (0x32CA, 'M', '11月'),\n    (0x32CB, 'M', '12月'),\n    (0x32CC, 'M', 'hg'),\n    (0x32CD, 'M', 'erg'),\n    (0x32CE, 'M', 'ev'),\n    (0x32CF, 'M', 'ltd'),\n    (0x32D0, 'M', 'ア'),\n    (0x32D1, 'M', 'イ'),\n    (0x32D2, 'M', 'ウ'),\n    (0x32D3, 'M', 'エ'),\n    (0x32D4, 'M', 'オ'),\n    (0x32D5, 'M', 'カ'),\n    (0x32D6, 'M', 'キ'),\n    (0x32D7, 'M', 'ク'),\n    (0x32D8, 'M', 'ケ'),\n    (0x32D9, 'M', 'コ'),\n    (0x32DA, 'M', 'サ'),\n    (0x32DB, 'M', 'シ'),\n    (0x32DC, 'M', 'ス'),\n    (0x32DD, 'M', 'セ'),\n    (0x32DE, 'M', 'ソ'),\n    (0x32DF, 'M', 'タ'),\n    (0x32E0, 'M', 'チ'),\n    (0x32E1, 'M', 'ツ'),\n    (0x32E2, 'M', 'テ'),\n    (0x32E3, 'M', 'ト'),\n    (0x32E4, 'M', 'ナ'),\n    (0x32E5, 'M', 'ニ'),\n    (0x32E6, 'M', 'ヌ'),\n    (0x32E7, 'M', 'ネ'),\n    (0x32E8, 'M', 'ノ'),\n    (0x32E9, 'M', 'ハ'),\n    (0x32EA, 'M', 'ヒ'),\n    (0x32EB, 'M', 'フ'),\n    (0x32EC, 'M', 'ヘ'),\n    (0x32ED, 'M', 'ホ'),\n    (0x32EE, 'M', 'マ'),\n    (0x32EF, 'M', 'ミ'),\n    (0x32F0, 'M', 'ム'),\n    (0x32F1, 'M', 'メ'),\n    (0x32F2, 'M', 'モ'),\n    (0x32F3, 'M', 'ヤ'),\n    (0x32F4, 'M', 'ユ'),\n    (0x32F5, 'M', 'ヨ'),\n    (0x32F6, 'M', 'ラ'),\n    (0x32F7, 'M', 'リ'),\n    (0x32F8, 'M', 'ル'),\n    (0x32F9, 'M', 'レ'),\n    (0x32FA, 'M', 'ロ'),\n    (0x32FB, 'M', 'ワ'),\n    (0x32FC, 'M', 'ヰ'),\n    (0x32FD, 'M', 'ヱ'),\n    (0x32FE, 'M', 'ヲ'),\n    (0x32FF, 'X'),\n    (0x3300, 'M', 'アパート'),\n    (0x3301, 'M', 'アルファ'),\n    (0x3302, 'M', 'アンペア'),\n    (0x3303, 'M', 'アール'),\n    (0x3304, 'M', 'イニング'),\n    (0x3305, 'M', 'インチ'),\n    (0x3306, 'M', 'ウォン'),\n    (0x3307, 'M', 'エスクード'),\n    (0x3308, 'M', 'エーカー'),\n    (0x3309, 'M', 'オンス'),\n    (0x330A, 'M', 'オーム'),\n    (0x330B, 'M', 'カイリ'),\n    (0x330C, 'M', 'カラット'),\n    (0x330D, 'M', 'カロリー'),\n    (0x330E, 'M', 'ガロン'),\n    (0x330F, 'M', 'ガンマ'),\n    (0x3310, 'M', 'ギガ'),\n    (0x3311, 'M', 'ギニー'),\n    (0x3312, 'M', 'キュリー'),\n    (0x3313, 'M', 'ギルダー'),\n    (0x3314, 'M', 'キロ'),\n    (0x3315, 'M', 'キログラム'),\n    (0x3316, 'M', 'キロメートル'),\n    (0x3317, 'M', 'キロワット'),\n    (0x3318, 'M', 'グラム'),\n    (0x3319, 'M', 'グラムトン'),\n    (0x331A, 'M', 'クルゼイロ'),\n    (0x331B, 'M', 'クローネ'),\n    (0x331C, 'M', 'ケース'),\n    (0x331D, 'M', 'コルナ'),\n    (0x331E, 'M', 'コーポ'),\n    (0x331F, 'M', 'サイクル'),\n    (0x3320, 'M', 'サンチーム'),\n    (0x3321, 'M', 'シリング'),\n    (0x3322, 'M', 'センチ'),\n    (0x3323, 'M', 'セント'),\n    (0x3324, 'M', 'ダース'),\n    (0x3325, 'M', 'デシ'),\n    (0x3326, 'M', 'ドル'),\n    (0x3327, 'M', 'トン'),\n    (0x3328, 'M', 'ナノ'),\n    (0x3329, 'M', 'ノット'),\n    (0x332A, 'M', 'ハイツ'),\n    (0x332B, 'M', 'パーセント'),\n    (0x332C, 'M', 'パーツ'),\n    (0x332D, 'M', 'バーレル'),\n    (0x332E, 'M', 'ピアストル'),\n    (0x332F, 'M', 'ピクル'),\n    (0x3330, 'M', 'ピコ'),\n    (0x3331, 'M', 'ビル'),\n    (0x3332, 'M', 'ファラッド'),\n    (0x3333, 'M', 'フィート'),\n    (0x3334, 'M', 'ブッシェル'),\n    (0x3335, 'M', 'フラン'),\n    (0x3336, 'M', 'ヘクタール'),\n    (0x3337, 'M', 'ペソ'),\n    (0x3338, 'M', 'ペニヒ'),\n    (0x3339, 'M', 'ヘルツ'),\n    (0x333A, 'M', 'ペンス'),\n    (0x333B, 'M', 'ページ'),\n    (0x333C, 'M', 'ベータ'),\n    (0x333D, 'M', 'ポイント'),\n    (0x333E, 'M', 'ボルト'),\n    (0x333F, 'M', 'ホン'),\n    (0x3340, 'M', 'ポンド'),\n    (0x3341, 'M', 'ホール'),\n    (0x3342, 'M', 'ホーン'),\n    (0x3343, 'M', 'マイクロ'),\n    (0x3344, 'M', 'マイル'),\n    (0x3345, 'M', 'マッハ'),\n    (0x3346, 'M', 'マルク'),\n    (0x3347, 'M', 'マンション'),\n    (0x3348, 'M', 'ミクロン'),\n    (0x3349, 'M', 'ミリ'),\n    (0x334A, 'M', 'ミリバール'),\n    (0x334B, 'M', 'メガ'),\n    (0x334C, 'M', 'メガトン'),\n    (0x334D, 'M', 'メートル'),\n    (0x334E, 'M', 'ヤード'),\n    (0x334F, 'M', 'ヤール'),\n    (0x3350, 'M', 'ユアン'),\n    (0x3351, 'M', 'リットル'),\n    (0x3352, 'M', 'リラ'),\n    (0x3353, 'M', 'ルピー'),\n    (0x3354, 'M', 'ルーブル'),\n    (0x3355, 'M', 'レム'),\n    (0x3356, 'M', 'レントゲン'),\n    (0x3357, 'M', 'ワット'),\n    (0x3358, 'M', '0点'),\n    (0x3359, 'M', '1点'),\n    (0x335A, 'M', '2点'),\n    (0x335B, 'M', '3点'),\n    (0x335C, 'M', '4点'),\n    (0x335D, 'M', '5点'),\n    (0x335E, 'M', '6点'),\n    (0x335F, 'M', '7点'),\n    (0x3360, 'M', '8点'),\n    (0x3361, 'M', '9点'),\n    (0x3362, 'M', '10点'),\n    (0x3363, 'M', '11点'),\n    (0x3364, 'M', '12点'),\n    (0x3365, 'M', '13点'),\n    (0x3366, 'M', '14点'),\n    (0x3367, 'M', '15点'),\n    (0x3368, 'M', '16点'),\n    (0x3369, 'M', '17点'),\n    (0x336A, 'M', '18点'),\n    (0x336B, 'M', '19点'),\n    (0x336C, 'M', '20点'),\n    (0x336D, 'M', '21点'),\n    (0x336E, 'M', '22点'),\n    (0x336F, 'M', '23点'),\n    (0x3370, 'M', '24点'),\n    (0x3371, 'M', 'hpa'),\n    (0x3372, 'M', 'da'),\n    (0x3373, 'M', 'au'),\n    (0x3374, 'M', 'bar'),\n    (0x3375, 'M', 'ov'),\n    (0x3376, 'M', 'pc'),\n    (0x3377, 'M', 'dm'),\n    (0x3378, 'M', 'dm2'),\n    (0x3379, 'M', 'dm3'),\n    (0x337A, 'M', 'iu'),\n    (0x337B, 'M', '平成'),\n    (0x337C, 'M', '昭和'),\n    (0x337D, 'M', '大正'),\n    (0x337E, 'M', '明治'),\n    (0x337F, 'M', '株式会社'),\n    (0x3380, 'M', 'pa'),\n    (0x3381, 'M', 'na'),\n    (0x3382, 'M', 'μa'),\n    (0x3383, 'M', 'ma'),\n    (0x3384, 'M', 'ka'),\n    (0x3385, 'M', 'kb'),\n    (0x3386, 'M', 'mb'),\n    (0x3387, 'M', 'gb'),\n    (0x3388, 'M', 'cal'),\n    (0x3389, 'M', 'kcal'),\n    (0x338A, 'M', 'pf'),\n    (0x338B, 'M', 'nf'),\n    (0x338C, 'M', 'μf'),\n    (0x338D, 'M', 'μg'),\n    (0x338E, 'M', 'mg'),\n    (0x338F, 'M', 'kg'),\n    (0x3390, 'M', 'hz'),\n    (0x3391, 'M', 'khz'),\n    (0x3392, 'M', 'mhz'),\n    (0x3393, 'M', 'ghz'),\n    (0x3394, 'M', 'thz'),\n    (0x3395, 'M', 'μl'),\n    (0x3396, 'M', 'ml'),\n    (0x3397, 'M', 'dl'),\n    (0x3398, 'M', 'kl'),\n    (0x3399, 'M', 'fm'),\n    (0x339A, 'M', 'nm'),\n    (0x339B, 'M', 'μm'),\n    (0x339C, 'M', 'mm'),\n    (0x339D, 'M', 'cm'),\n    (0x339E, 'M', 'km'),\n    (0x339F, 'M', 'mm2'),\n    (0x33A0, 'M', 'cm2'),\n    (0x33A1, 'M', 'm2'),\n    (0x33A2, 'M', 'km2'),\n    (0x33A3, 'M', 'mm3'),\n    (0x33A4, 'M', 'cm3'),\n    (0x33A5, 'M', 'm3'),\n    (0x33A6, 'M', 'km3'),\n    (0x33A7, 'M', 'm∕s'),\n    (0x33A8, 'M', 'm∕s2'),\n    (0x33A9, 'M', 'pa'),\n    (0x33AA, 'M', 'kpa'),\n    (0x33AB, 'M', 'mpa'),\n    (0x33AC, 'M', 'gpa'),\n    (0x33AD, 'M', 'rad'),\n    (0x33AE, 'M', 'rad∕s'),\n    (0x33AF, 'M', 'rad∕s2'),\n    (0x33B0, 'M', 'ps'),\n    (0x33B1, 'M', 'ns'),\n    (0x33B2, 'M', 'μs'),\n    (0x33B3, 'M', 'ms'),\n    (0x33B4, 'M', 'pv'),\n    (0x33B5, 'M', 'nv'),\n    (0x33B6, 'M', 'μv'),\n    (0x33B7, 'M', 'mv'),\n    (0x33B8, 'M', 'kv'),\n    (0x33B9, 'M', 'mv'),\n    (0x33BA, 'M', 'pw'),\n    (0x33BB, 'M', 'nw'),\n    (0x33BC, 'M', 'μw'),\n    (0x33BD, 'M', 'mw'),\n    (0x33BE, 'M', 'kw'),\n    (0x33BF, 'M', 'mw'),\n    (0x33C0, 'M', 'kω'),\n    (0x33C1, 'M', 'mω'),\n    (0x33C2, 'X'),\n    (0x33C3, 'M', 'bq'),\n    (0x33C4, 'M', 'cc'),\n    (0x33C5, 'M', 'cd'),\n    (0x33C6, 'M', 'c∕kg'),\n    (0x33C7, 'X'),\n    (0x33C8, 'M', 'db'),\n    (0x33C9, 'M', 'gy'),\n    (0x33CA, 'M', 'ha'),\n    (0x33CB, 'M', 'hp'),\n    (0x33CC, 'M', 'in'),\n    (0x33CD, 'M', 'kk'),\n    (0x33CE, 'M', 'km'),\n    (0x33CF, 'M', 'kt'),\n    (0x33D0, 'M', 'lm'),\n    (0x33D1, 'M', 'ln'),\n    (0x33D2, 'M', 'log'),\n    (0x33D3, 'M', 'lx'),\n    (0x33D4, 'M', 'mb'),\n    (0x33D5, 'M', 'mil'),\n    (0x33D6, 'M', 'mol'),\n    (0x33D7, 'M', 'ph'),\n    (0x33D8, 'X'),\n    (0x33D9, 'M', 'ppm'),\n    (0x33DA, 'M', 'pr'),\n    (0x33DB, 'M', 'sr'),\n    (0x33DC, 'M', 'sv'),\n    (0x33DD, 'M', 'wb'),\n    (0x33DE, 'M', 'v∕m'),\n    (0x33DF, 'M', 'a∕m'),\n    (0x33E0, 'M', '1日'),\n    (0x33E1, 'M', '2日'),\n    (0x33E2, 'M', '3日'),\n    (0x33E3, 'M', '4日'),\n    (0x33E4, 'M', '5日'),\n    (0x33E5, 'M', '6日'),\n    (0x33E6, 'M', '7日'),\n    (0x33E7, 'M', '8日'),\n    (0x33E8, 'M', '9日'),\n    (0x33E9, 'M', '10日'),\n    (0x33EA, 'M', '11日'),\n    (0x33EB, 'M', '12日'),\n    (0x33EC, 'M', '13日'),\n    (0x33ED, 'M', '14日'),\n    (0x33EE, 'M', '15日'),\n    (0x33EF, 'M', '16日'),\n    (0x33F0, 'M', '17日'),\n    (0x33F1, 'M', '18日'),\n    (0x33F2, 'M', '19日'),\n    (0x33F3, 'M', '20日'),\n    (0x33F4, 'M', '21日'),\n    (0x33F5, 'M', '22日'),\n    (0x33F6, 'M', '23日'),\n    (0x33F7, 'M', '24日'),\n    (0x33F8, 'M', '25日'),\n    (0x33F9, 'M', '26日'),\n    (0x33FA, 'M', '27日'),\n    (0x33FB, 'M', '28日'),\n    (0x33FC, 'M', '29日'),\n    (0x33FD, 'M', '30日'),\n    (0x33FE, 'M', '31日'),\n    (0x33FF, 'M', 'gal'),\n    (0x3400, 'V'),\n    (0x4DB6, 'X'),\n    (0x4DC0, 'V'),\n    (0x9FCD, 'X'),\n    (0xA000, 'V'),\n    (0xA48D, 'X'),\n    (0xA490, 'V'),\n    (0xA4C7, 'X'),\n    (0xA4D0, 'V'),\n    (0xA62C, 'X'),\n    (0xA640, 'M', 'ꙁ'),\n    (0xA641, 'V'),\n    (0xA642, 'M', 'ꙃ'),\n    (0xA643, 'V'),\n    (0xA644, 'M', 'ꙅ'),\n    (0xA645, 'V'),\n    (0xA646, 'M', 'ꙇ'),\n    (0xA647, 'V'),\n    (0xA648, 'M', 'ꙉ'),\n    (0xA649, 'V'),\n    (0xA64A, 'M', 'ꙋ'),\n    (0xA64B, 'V'),\n    (0xA64C, 'M', 'ꙍ'),\n    (0xA64D, 'V'),\n    (0xA64E, 'M', 'ꙏ'),\n    (0xA64F, 'V'),\n    (0xA650, 'M', 'ꙑ'),\n    (0xA651, 'V'),\n    (0xA652, 'M', 'ꙓ'),\n    (0xA653, 'V'),\n    (0xA654, 'M', 'ꙕ'),\n    (0xA655, 'V'),\n    (0xA656, 'M', 'ꙗ'),\n    (0xA657, 'V'),\n    (0xA658, 'M', 'ꙙ'),\n    (0xA659, 'V'),\n    (0xA65A, 'M', 'ꙛ'),\n    (0xA65B, 'V'),\n    (0xA65C, 'M', 'ꙝ'),\n    (0xA65D, 'V'),\n    (0xA65E, 'M', 'ꙟ'),\n    (0xA65F, 'V'),\n    (0xA660, 'M', 'ꙡ'),\n    (0xA661, 'V'),\n    (0xA662, 'M', 'ꙣ'),\n    (0xA663, 'V'),\n    (0xA664, 'M', 'ꙥ'),\n    (0xA665, 'V'),\n    (0xA666, 'M', 'ꙧ'),\n    (0xA667, 'V'),\n    (0xA668, 'M', 'ꙩ'),\n    (0xA669, 'V'),\n    (0xA66A, 'M', 'ꙫ'),\n    (0xA66B, 'V'),\n    (0xA66C, 'M', 'ꙭ'),\n    (0xA66D, 'V'),\n    (0xA680, 'M', 'ꚁ'),\n    (0xA681, 'V'),\n    (0xA682, 'M', 'ꚃ'),\n    (0xA683, 'V'),\n    (0xA684, 'M', 'ꚅ'),\n    (0xA685, 'V'),\n    (0xA686, 'M', 'ꚇ'),\n    (0xA687, 'V'),\n    (0xA688, 'M', 'ꚉ'),\n    (0xA689, 'V'),\n    (0xA68A, 'M', 'ꚋ'),\n    (0xA68B, 'V'),\n    (0xA68C, 'M', 'ꚍ'),\n    (0xA68D, 'V'),\n    (0xA68E, 'M', 'ꚏ'),\n    (0xA68F, 'V'),\n    (0xA690, 'M', 'ꚑ'),\n    (0xA691, 'V'),\n    (0xA692, 'M', 'ꚓ'),\n    (0xA693, 'V'),\n    (0xA694, 'M', 'ꚕ'),\n    (0xA695, 'V'),\n    (0xA696, 'M', 'ꚗ'),\n    (0xA697, 'V'),\n    (0xA698, 'X'),\n    (0xA69F, 'V'),\n    (0xA6F8, 'X'),\n    (0xA700, 'V'),\n    (0xA722, 'M', 'ꜣ'),\n    (0xA723, 'V'),\n    (0xA724, 'M', 'ꜥ'),\n    (0xA725, 'V'),\n    (0xA726, 'M', 'ꜧ'),\n    (0xA727, 'V'),\n    (0xA728, 'M', 'ꜩ'),\n    (0xA729, 'V'),\n    (0xA72A, 'M', 'ꜫ'),\n    (0xA72B, 'V'),\n    (0xA72C, 'M', 'ꜭ'),\n    (0xA72D, 'V'),\n    (0xA72E, 'M', 'ꜯ'),\n    (0xA72F, 'V'),\n    (0xA732, 'M', 'ꜳ'),\n    (0xA733, 'V'),\n    (0xA734, 'M', 'ꜵ'),\n    (0xA735, 'V'),\n    (0xA736, 'M', 'ꜷ'),\n    (0xA737, 'V'),\n    (0xA738, 'M', 'ꜹ'),\n    (0xA739, 'V'),\n    (0xA73A, 'M', 'ꜻ'),\n    (0xA73B, 'V'),\n    (0xA73C, 'M', 'ꜽ'),\n    (0xA73D, 'V'),\n    (0xA73E, 'M', 'ꜿ'),\n    (0xA73F, 'V'),\n    (0xA740, 'M', 'ꝁ'),\n    (0xA741, 'V'),\n    (0xA742, 'M', 'ꝃ'),\n    (0xA743, 'V'),\n    (0xA744, 'M', 'ꝅ'),\n    (0xA745, 'V'),\n    (0xA746, 'M', 'ꝇ'),\n    (0xA747, 'V'),\n    (0xA748, 'M', 'ꝉ'),\n    (0xA749, 'V'),\n    (0xA74A, 'M', 'ꝋ'),\n    (0xA74B, 'V'),\n    (0xA74C, 'M', 'ꝍ'),\n    (0xA74D, 'V'),\n    (0xA74E, 'M', 'ꝏ'),\n    (0xA74F, 'V'),\n    (0xA750, 'M', 'ꝑ'),\n    (0xA751, 'V'),\n    (0xA752, 'M', 'ꝓ'),\n    (0xA753, 'V'),\n    (0xA754, 'M', 'ꝕ'),\n    (0xA755, 'V'),\n    (0xA756, 'M', 'ꝗ'),\n    (0xA757, 'V'),\n    (0xA758, 'M', 'ꝙ'),\n    (0xA759, 'V'),\n    (0xA75A, 'M', 'ꝛ'),\n    (0xA75B, 'V'),\n    (0xA75C, 'M', 'ꝝ'),\n    (0xA75D, 'V'),\n    (0xA75E, 'M', 'ꝟ'),\n    (0xA75F, 'V'),\n    (0xA760, 'M', 'ꝡ'),\n    (0xA761, 'V'),\n    (0xA762, 'M', 'ꝣ'),\n    (0xA763, 'V'),\n    (0xA764, 'M', 'ꝥ'),\n    (0xA765, 'V'),\n    (0xA766, 'M', 'ꝧ'),\n    (0xA767, 'V'),\n    (0xA768, 'M', 'ꝩ'),\n    (0xA769, 'V'),\n    (0xA76A, 'M', 'ꝫ'),\n    (0xA76B, 'V'),\n    (0xA76C, 'M', 'ꝭ'),\n    (0xA76D, 'V'),\n    (0xA76E, 'M', 'ꝯ'),\n    (0xA76F, 'V'),\n    (0xA770, 'M', 'ꝯ'),\n    (0xA771, 'V'),\n    (0xA779, 'M', 'ꝺ'),\n    (0xA77A, 'V'),\n    (0xA77B, 'M', 'ꝼ'),\n    (0xA77C, 'V'),\n    (0xA77D, 'M', 'ᵹ'),\n    (0xA77E, 'M', 'ꝿ'),\n    (0xA77F, 'V'),\n    (0xA780, 'M', 'ꞁ'),\n    (0xA781, 'V'),\n    (0xA782, 'M', 'ꞃ'),\n    (0xA783, 'V'),\n    (0xA784, 'M', 'ꞅ'),\n    (0xA785, 'V'),\n    (0xA786, 'M', 'ꞇ'),\n    (0xA787, 'V'),\n    (0xA78B, 'M', 'ꞌ'),\n    (0xA78C, 'V'),\n    (0xA78D, 'M', 'ɥ'),\n    (0xA78E, 'V'),\n    (0xA78F, 'X'),\n    (0xA790, 'M', 'ꞑ'),\n    (0xA791, 'V'),\n    (0xA792, 'M', 'ꞓ'),\n    (0xA793, 'V'),\n    (0xA794, 'X'),\n    (0xA7A0, 'M', 'ꞡ'),\n    (0xA7A1, 'V'),\n    (0xA7A2, 'M', 'ꞣ'),\n    (0xA7A3, 'V'),\n    (0xA7A4, 'M', 'ꞥ'),\n    (0xA7A5, 'V'),\n    (0xA7A6, 'M', 'ꞧ'),\n    (0xA7A7, 'V'),\n    (0xA7A8, 'M', 'ꞩ'),\n    (0xA7A9, 'V'),\n    (0xA7AA, 'M', 'ɦ'),\n    (0xA7AB, 'X'),\n    (0xA7F8, 'M', 'ħ'),\n    (0xA7F9, 'M', 'œ'),\n    (0xA7FA, 'V'),\n    (0xA82C, 'X'),\n    (0xA830, 'V'),\n    (0xA83A, 'X'),\n    (0xA840, 'V'),\n    (0xA878, 'X'),\n    (0xA880, 'V'),\n    (0xA8C5, 'X'),\n    (0xA8CE, 'V'),\n    (0xA8DA, 'X'),\n    (0xA8E0, 'V'),\n    (0xA8FC, 'X'),\n    (0xA900, 'V'),\n    (0xA954, 'X'),\n    (0xA95F, 'V'),\n    (0xA97D, 'X'),\n    (0xA980, 'V'),\n    (0xA9CE, 'X'),\n    (0xA9CF, 'V'),\n    (0xA9DA, 'X'),\n    (0xA9DE, 'V'),\n    (0xA9E0, 'X'),\n    (0xAA00, 'V'),\n    (0xAA37, 'X'),\n    (0xAA40, 'V'),\n    (0xAA4E, 'X'),\n    (0xAA50, 'V'),\n    (0xAA5A, 'X'),\n    (0xAA5C, 'V'),\n    (0xAA7C, 'X'),\n    (0xAA80, 'V'),\n    (0xAAC3, 'X'),\n    (0xAADB, 'V'),\n    (0xAAF7, 'X'),\n    (0xAB01, 'V'),\n    (0xAB07, 'X'),\n    (0xAB09, 'V'),\n    (0xAB0F, 'X'),\n    (0xAB11, 'V'),\n    (0xAB17, 'X'),\n    (0xAB20, 'V'),\n    (0xAB27, 'X'),\n    (0xAB28, 'V'),\n    (0xAB2F, 'X'),\n    (0xABC0, 'V'),\n    (0xABEE, 'X'),\n    (0xABF0, 'V'),\n    (0xABFA, 'X'),\n    (0xAC00, 'V'),\n    (0xD7A4, 'X'),\n    (0xD7B0, 'V'),\n    (0xD7C7, 'X'),\n    (0xD7CB, 'V'),\n    (0xD7FC, 'X'),\n    (0xF900, 'M', '豈'),\n    (0xF901, 'M', '更'),\n    (0xF902, 'M', '車'),\n    (0xF903, 'M', '賈'),\n    (0xF904, 'M', '滑'),\n    (0xF905, 'M', '串'),\n    (0xF906, 'M', '句'),\n    (0xF907, 'M', '龜'),\n    (0xF909, 'M', '契'),\n    (0xF90A, 'M', '金'),\n    (0xF90B, 'M', '喇'),\n    (0xF90C, 'M', '奈'),\n    (0xF90D, 'M', '懶'),\n    (0xF90E, 'M', '癩'),\n    (0xF90F, 'M', '羅'),\n    (0xF910, 'M', '蘿'),\n    (0xF911, 'M', '螺'),\n    (0xF912, 'M', '裸'),\n    (0xF913, 'M', '邏'),\n    (0xF914, 'M', '樂'),\n    (0xF915, 'M', '洛'),\n    (0xF916, 'M', '烙'),\n    (0xF917, 'M', '珞'),\n    (0xF918, 'M', '落'),\n    (0xF919, 'M', '酪'),\n    (0xF91A, 'M', '駱'),\n    (0xF91B, 'M', '亂'),\n    (0xF91C, 'M', '卵'),\n    (0xF91D, 'M', '欄'),\n    (0xF91E, 'M', '爛'),\n    (0xF91F, 'M', '蘭'),\n    (0xF920, 'M', '鸞'),\n    (0xF921, 'M', '嵐'),\n    (0xF922, 'M', '濫'),\n    (0xF923, 'M', '藍'),\n    (0xF924, 'M', '襤'),\n    (0xF925, 'M', '拉'),\n    (0xF926, 'M', '臘'),\n    (0xF927, 'M', '蠟'),\n    (0xF928, 'M', '廊'),\n    (0xF929, 'M', '朗'),\n    (0xF92A, 'M', '浪'),\n    (0xF92B, 'M', '狼'),\n    (0xF92C, 'M', '郎'),\n    (0xF92D, 'M', '來'),\n    (0xF92E, 'M', '冷'),\n    (0xF92F, 'M', '勞'),\n    (0xF930, 'M', '擄'),\n    (0xF931, 'M', '櫓'),\n    (0xF932, 'M', '爐'),\n    (0xF933, 'M', '盧'),\n    (0xF934, 'M', '老'),\n    (0xF935, 'M', '蘆'),\n    (0xF936, 'M', '虜'),\n    (0xF937, 'M', '路'),\n    (0xF938, 'M', '露'),\n    (0xF939, 'M', '魯'),\n    (0xF93A, 'M', '鷺'),\n    (0xF93B, 'M', '碌'),\n    (0xF93C, 'M', '祿'),\n    (0xF93D, 'M', '綠'),\n    (0xF93E, 'M', '菉'),\n    (0xF93F, 'M', '錄'),\n    (0xF940, 'M', '鹿'),\n    (0xF941, 'M', '論'),\n    (0xF942, 'M', '壟'),\n    (0xF943, 'M', '弄'),\n    (0xF944, 'M', '籠'),\n    (0xF945, 'M', '聾'),\n    (0xF946, 'M', '牢'),\n    (0xF947, 'M', '磊'),\n    (0xF948, 'M', '賂'),\n    (0xF949, 'M', '雷'),\n    (0xF94A, 'M', '壘'),\n    (0xF94B, 'M', '屢'),\n    (0xF94C, 'M', '樓'),\n    (0xF94D, 'M', '淚'),\n    (0xF94E, 'M', '漏'),\n    (0xF94F, 'M', '累'),\n    (0xF950, 'M', '縷'),\n    (0xF951, 'M', '陋'),\n    (0xF952, 'M', '勒'),\n    (0xF953, 'M', '肋'),\n    (0xF954, 'M', '凜'),\n    (0xF955, 'M', '凌'),\n    (0xF956, 'M', '稜'),\n    (0xF957, 'M', '綾'),\n    (0xF958, 'M', '菱'),\n    (0xF959, 'M', '陵'),\n    (0xF95A, 'M', '讀'),\n    (0xF95B, 'M', '拏'),\n    (0xF95C, 'M', '樂'),\n    (0xF95D, 'M', '諾'),\n    (0xF95E, 'M', '丹'),\n    (0xF95F, 'M', '寧'),\n    (0xF960, 'M', '怒'),\n    (0xF961, 'M', '率'),\n    (0xF962, 'M', '異'),\n    (0xF963, 'M', '北'),\n    (0xF964, 'M', '磻'),\n    (0xF965, 'M', '便'),\n    (0xF966, 'M', '復'),\n    (0xF967, 'M', '不'),\n    (0xF968, 'M', '泌'),\n    (0xF969, 'M', '數'),\n    (0xF96A, 'M', '索'),\n    (0xF96B, 'M', '參'),\n    (0xF96C, 'M', '塞'),\n    (0xF96D, 'M', '省'),\n    (0xF96E, 'M', '葉'),\n    (0xF96F, 'M', '說'),\n    (0xF970, 'M', '殺'),\n    (0xF971, 'M', '辰'),\n    (0xF972, 'M', '沈'),\n    (0xF973, 'M', '拾'),\n    (0xF974, 'M', '若'),\n    (0xF975, 'M', '掠'),\n    (0xF976, 'M', '略'),\n    (0xF977, 'M', '亮'),\n    (0xF978, 'M', '兩'),\n    (0xF979, 'M', '凉'),\n    (0xF97A, 'M', '梁'),\n    (0xF97B, 'M', '糧'),\n    (0xF97C, 'M', '良'),\n    (0xF97D, 'M', '諒'),\n    (0xF97E, 'M', '量'),\n    (0xF97F, 'M', '勵'),\n    (0xF980, 'M', '呂'),\n    (0xF981, 'M', '女'),\n    (0xF982, 'M', '廬'),\n    (0xF983, 'M', '旅'),\n    (0xF984, 'M', '濾'),\n    (0xF985, 'M', '礪'),\n    (0xF986, 'M', '閭'),\n    (0xF987, 'M', '驪'),\n    (0xF988, 'M', '麗'),\n    (0xF989, 'M', '黎'),\n    (0xF98A, 'M', '力'),\n    (0xF98B, 'M', '曆'),\n    (0xF98C, 'M', '歷'),\n    (0xF98D, 'M', '轢'),\n    (0xF98E, 'M', '年'),\n    (0xF98F, 'M', '憐'),\n    (0xF990, 'M', '戀'),\n    (0xF991, 'M', '撚'),\n    (0xF992, 'M', '漣'),\n    (0xF993, 'M', '煉'),\n    (0xF994, 'M', '璉'),\n    (0xF995, 'M', '秊'),\n    (0xF996, 'M', '練'),\n    (0xF997, 'M', '聯'),\n    (0xF998, 'M', '輦'),\n    (0xF999, 'M', '蓮'),\n    (0xF99A, 'M', '連'),\n    (0xF99B, 'M', '鍊'),\n    (0xF99C, 'M', '列'),\n    (0xF99D, 'M', '劣'),\n    (0xF99E, 'M', '咽'),\n    (0xF99F, 'M', '烈'),\n    (0xF9A0, 'M', '裂'),\n    (0xF9A1, 'M', '說'),\n    (0xF9A2, 'M', '廉'),\n    (0xF9A3, 'M', '念'),\n    (0xF9A4, 'M', '捻'),\n    (0xF9A5, 'M', '殮'),\n    (0xF9A6, 'M', '簾'),\n    (0xF9A7, 'M', '獵'),\n    (0xF9A8, 'M', '令'),\n    (0xF9A9, 'M', '囹'),\n    (0xF9AA, 'M', '寧'),\n    (0xF9AB, 'M', '嶺'),\n    (0xF9AC, 'M', '怜'),\n    (0xF9AD, 'M', '玲'),\n    (0xF9AE, 'M', '瑩'),\n    (0xF9AF, 'M', '羚'),\n    (0xF9B0, 'M', '聆'),\n    (0xF9B1, 'M', '鈴'),\n    (0xF9B2, 'M', '零'),\n    (0xF9B3, 'M', '靈'),\n    (0xF9B4, 'M', '領'),\n    (0xF9B5, 'M', '例'),\n    (0xF9B6, 'M', '禮'),\n    (0xF9B7, 'M', '醴'),\n    (0xF9B8, 'M', '隸'),\n    (0xF9B9, 'M', '惡'),\n    (0xF9BA, 'M', '了'),\n    (0xF9BB, 'M', '僚'),\n    (0xF9BC, 'M', '寮'),\n    (0xF9BD, 'M', '尿'),\n    (0xF9BE, 'M', '料'),\n    (0xF9BF, 'M', '樂'),\n    (0xF9C0, 'M', '燎'),\n    (0xF9C1, 'M', '療'),\n    (0xF9C2, 'M', '蓼'),\n    (0xF9C3, 'M', '遼'),\n    (0xF9C4, 'M', '龍'),\n    (0xF9C5, 'M', '暈'),\n    (0xF9C6, 'M', '阮'),\n    (0xF9C7, 'M', '劉'),\n    (0xF9C8, 'M', '杻'),\n    (0xF9C9, 'M', '柳'),\n    (0xF9CA, 'M', '流'),\n    (0xF9CB, 'M', '溜'),\n    (0xF9CC, 'M', '琉'),\n    (0xF9CD, 'M', '留'),\n    (0xF9CE, 'M', '硫'),\n    (0xF9CF, 'M', '紐'),\n    (0xF9D0, 'M', '類'),\n    (0xF9D1, 'M', '六'),\n    (0xF9D2, 'M', '戮'),\n    (0xF9D3, 'M', '陸'),\n    (0xF9D4, 'M', '倫'),\n    (0xF9D5, 'M', '崙'),\n    (0xF9D6, 'M', '淪'),\n    (0xF9D7, 'M', '輪'),\n    (0xF9D8, 'M', '律'),\n    (0xF9D9, 'M', '慄'),\n    (0xF9DA, 'M', '栗'),\n    (0xF9DB, 'M', '率'),\n    (0xF9DC, 'M', '隆'),\n    (0xF9DD, 'M', '利'),\n    (0xF9DE, 'M', '吏'),\n    (0xF9DF, 'M', '履'),\n    (0xF9E0, 'M', '易'),\n    (0xF9E1, 'M', '李'),\n    (0xF9E2, 'M', '梨'),\n    (0xF9E3, 'M', '泥'),\n    (0xF9E4, 'M', '理'),\n    (0xF9E5, 'M', '痢'),\n    (0xF9E6, 'M', '罹'),\n    (0xF9E7, 'M', '裏'),\n    (0xF9E8, 'M', '裡'),\n    (0xF9E9, 'M', '里'),\n    (0xF9EA, 'M', '離'),\n    (0xF9EB, 'M', '匿'),\n    (0xF9EC, 'M', '溺'),\n    (0xF9ED, 'M', '吝'),\n    (0xF9EE, 'M', '燐'),\n    (0xF9EF, 'M', '璘'),\n    (0xF9F0, 'M', '藺'),\n    (0xF9F1, 'M', '隣'),\n    (0xF9F2, 'M', '鱗'),\n    (0xF9F3, 'M', '麟'),\n    (0xF9F4, 'M', '林'),\n    (0xF9F5, 'M', '淋'),\n    (0xF9F6, 'M', '臨'),\n    (0xF9F7, 'M', '立'),\n    (0xF9F8, 'M', '笠'),\n    (0xF9F9, 'M', '粒'),\n    (0xF9FA, 'M', '狀'),\n    (0xF9FB, 'M', '炙'),\n    (0xF9FC, 'M', '識'),\n    (0xF9FD, 'M', '什'),\n    (0xF9FE, 'M', '茶'),\n    (0xF9FF, 'M', '刺'),\n    (0xFA00, 'M', '切'),\n    (0xFA01, 'M', '度'),\n    (0xFA02, 'M', '拓'),\n    (0xFA03, 'M', '糖'),\n    (0xFA04, 'M', '宅'),\n    (0xFA05, 'M', '洞'),\n    (0xFA06, 'M', '暴'),\n    (0xFA07, 'M', '輻'),\n    (0xFA08, 'M', '行'),\n    (0xFA09, 'M', '降'),\n    (0xFA0A, 'M', '見'),\n    (0xFA0B, 'M', '廓'),\n    (0xFA0C, 'M', '兀'),\n    (0xFA0D, 'M', '嗀'),\n    (0xFA0E, 'V'),\n    (0xFA10, 'M', '塚'),\n    (0xFA11, 'V'),\n    (0xFA12, 'M', '晴'),\n    (0xFA13, 'V'),\n    (0xFA15, 'M', '凞'),\n    (0xFA16, 'M', '猪'),\n    (0xFA17, 'M', '益'),\n    (0xFA18, 'M', '礼'),\n    (0xFA19, 'M', '神'),\n    (0xFA1A, 'M', '祥'),\n    (0xFA1B, 'M', '福'),\n    (0xFA1C, 'M', '靖'),\n    (0xFA1D, 'M', '精'),\n    (0xFA1E, 'M', '羽'),\n    (0xFA1F, 'V'),\n    (0xFA20, 'M', '蘒'),\n    (0xFA21, 'V'),\n    (0xFA22, 'M', '諸'),\n    (0xFA23, 'V'),\n    (0xFA25, 'M', '逸'),\n    (0xFA26, 'M', '都'),\n    (0xFA27, 'V'),\n    (0xFA2A, 'M', '飯'),\n    (0xFA2B, 'M', '飼'),\n    (0xFA2C, 'M', '館'),\n    (0xFA2D, 'M', '鶴'),\n    (0xFA2E, 'M', '郞'),\n    (0xFA2F, 'M', '隷'),\n    (0xFA30, 'M', '侮'),\n    (0xFA31, 'M', '僧'),\n    (0xFA32, 'M', '免'),\n    (0xFA33, 'M', '勉'),\n    (0xFA34, 'M', '勤'),\n    (0xFA35, 'M', '卑'),\n    (0xFA36, 'M', '喝'),\n    (0xFA37, 'M', '嘆'),\n    (0xFA38, 'M', '器'),\n    (0xFA39, 'M', '塀'),\n    (0xFA3A, 'M', '墨'),\n    (0xFA3B, 'M', '層'),\n    (0xFA3C, 'M', '屮'),\n    (0xFA3D, 'M', '悔'),\n    (0xFA3E, 'M', '慨'),\n    (0xFA3F, 'M', '憎'),\n    (0xFA40, 'M', '懲'),\n    (0xFA41, 'M', '敏'),\n    (0xFA42, 'M', '既'),\n    (0xFA43, 'M', '暑'),\n    (0xFA44, 'M', '梅'),\n    (0xFA45, 'M', '海'),\n    (0xFA46, 'M', '渚'),\n    (0xFA47, 'M', '漢'),\n    (0xFA48, 'M', '煮'),\n    (0xFA49, 'M', '爫'),\n    (0xFA4A, 'M', '琢'),\n    (0xFA4B, 'M', '碑'),\n    (0xFA4C, 'M', '社'),\n    (0xFA4D, 'M', '祉'),\n    (0xFA4E, 'M', '祈'),\n    (0xFA4F, 'M', '祐'),\n    (0xFA50, 'M', '祖'),\n    (0xFA51, 'M', '祝'),\n    (0xFA52, 'M', '禍'),\n    (0xFA53, 'M', '禎'),\n    (0xFA54, 'M', '穀'),\n    (0xFA55, 'M', '突'),\n    (0xFA56, 'M', '節'),\n    (0xFA57, 'M', '練'),\n    (0xFA58, 'M', '縉'),\n    (0xFA59, 'M', '繁'),\n    (0xFA5A, 'M', '署'),\n    (0xFA5B, 'M', '者'),\n    (0xFA5C, 'M', '臭'),\n    (0xFA5D, 'M', '艹'),\n    (0xFA5F, 'M', '著'),\n    (0xFA60, 'M', '褐'),\n    (0xFA61, 'M', '視'),\n    (0xFA62, 'M', '謁'),\n    (0xFA63, 'M', '謹'),\n    (0xFA64, 'M', '賓'),\n    (0xFA65, 'M', '贈'),\n    (0xFA66, 'M', '辶'),\n    (0xFA67, 'M', '逸'),\n    (0xFA68, 'M', '難'),\n    (0xFA69, 'M', '響'),\n    (0xFA6A, 'M', '頻'),\n    (0xFA6B, 'M', '恵'),\n    (0xFA6C, 'M', '𤋮'),\n    (0xFA6D, 'M', '舘'),\n    (0xFA6E, 'X'),\n    (0xFA70, 'M', '並'),\n    (0xFA71, 'M', '况'),\n    (0xFA72, 'M', '全'),\n    (0xFA73, 'M', '侀'),\n    (0xFA74, 'M', '充'),\n    (0xFA75, 'M', '冀'),\n    (0xFA76, 'M', '勇'),\n    (0xFA77, 'M', '勺'),\n    (0xFA78, 'M', '喝'),\n    (0xFA79, 'M', '啕'),\n    (0xFA7A, 'M', '喙'),\n    (0xFA7B, 'M', '嗢'),\n    (0xFA7C, 'M', '塚'),\n    (0xFA7D, 'M', '墳'),\n    (0xFA7E, 'M', '奄'),\n    (0xFA7F, 'M', '奔'),\n    (0xFA80, 'M', '婢'),\n    (0xFA81, 'M', '嬨'),\n    (0xFA82, 'M', '廒'),\n    (0xFA83, 'M', '廙'),\n    (0xFA84, 'M', '彩'),\n    (0xFA85, 'M', '徭'),\n    (0xFA86, 'M', '惘'),\n    (0xFA87, 'M', '慎'),\n    (0xFA88, 'M', '愈'),\n    (0xFA89, 'M', '憎'),\n    (0xFA8A, 'M', '慠'),\n    (0xFA8B, 'M', '懲'),\n    (0xFA8C, 'M', '戴'),\n    (0xFA8D, 'M', '揄'),\n    (0xFA8E, 'M', '搜'),\n    (0xFA8F, 'M', '摒'),\n    (0xFA90, 'M', '敖'),\n    (0xFA91, 'M', '晴'),\n    (0xFA92, 'M', '朗'),\n    (0xFA93, 'M', '望'),\n    (0xFA94, 'M', '杖'),\n    (0xFA95, 'M', '歹'),\n    (0xFA96, 'M', '殺'),\n    (0xFA97, 'M', '流'),\n    (0xFA98, 'M', '滛'),\n    (0xFA99, 'M', '滋'),\n    (0xFA9A, 'M', '漢'),\n    (0xFA9B, 'M', '瀞'),\n    (0xFA9C, 'M', '煮'),\n    (0xFA9D, 'M', '瞧'),\n    (0xFA9E, 'M', '爵'),\n    (0xFA9F, 'M', '犯'),\n    (0xFAA0, 'M', '猪'),\n    (0xFAA1, 'M', '瑱'),\n    (0xFAA2, 'M', '甆'),\n    (0xFAA3, 'M', '画'),\n    (0xFAA4, 'M', '瘝'),\n    (0xFAA5, 'M', '瘟'),\n    (0xFAA6, 'M', '益'),\n    (0xFAA7, 'M', '盛'),\n    (0xFAA8, 'M', '直'),\n    (0xFAA9, 'M', '睊'),\n    (0xFAAA, 'M', '着'),\n    (0xFAAB, 'M', '磌'),\n    (0xFAAC, 'M', '窱'),\n    (0xFAAD, 'M', '節'),\n    (0xFAAE, 'M', '类'),\n    (0xFAAF, 'M', '絛'),\n    (0xFAB0, 'M', '練'),\n    (0xFAB1, 'M', '缾'),\n    (0xFAB2, 'M', '者'),\n    (0xFAB3, 'M', '荒'),\n    (0xFAB4, 'M', '華'),\n    (0xFAB5, 'M', '蝹'),\n    (0xFAB6, 'M', '襁'),\n    (0xFAB7, 'M', '覆'),\n    (0xFAB8, 'M', '視'),\n    (0xFAB9, 'M', '調'),\n    (0xFABA, 'M', '諸'),\n    (0xFABB, 'M', '請'),\n    (0xFABC, 'M', '謁'),\n    (0xFABD, 'M', '諾'),\n    (0xFABE, 'M', '諭'),\n    (0xFABF, 'M', '謹'),\n    (0xFAC0, 'M', '變'),\n    (0xFAC1, 'M', '贈'),\n    (0xFAC2, 'M', '輸'),\n    (0xFAC3, 'M', '遲'),\n    (0xFAC4, 'M', '醙'),\n    (0xFAC5, 'M', '鉶'),\n    (0xFAC6, 'M', '陼'),\n    (0xFAC7, 'M', '難'),\n    (0xFAC8, 'M', '靖'),\n    (0xFAC9, 'M', '韛'),\n    (0xFACA, 'M', '響'),\n    (0xFACB, 'M', '頋'),\n    (0xFACC, 'M', '頻'),\n    (0xFACD, 'M', '鬒'),\n    (0xFACE, 'M', '龜'),\n    (0xFACF, 'M', '𢡊'),\n    (0xFAD0, 'M', '𢡄'),\n    (0xFAD1, 'M', '𣏕'),\n    (0xFAD2, 'M', '㮝'),\n    (0xFAD3, 'M', '䀘'),\n    (0xFAD4, 'M', '䀹'),\n    (0xFAD5, 'M', '𥉉'),\n    (0xFAD6, 'M', '𥳐'),\n    (0xFAD7, 'M', '𧻓'),\n    (0xFAD8, 'M', '齃'),\n    (0xFAD9, 'M', '龎'),\n    (0xFADA, 'X'),\n    (0xFB00, 'M', 'ff'),\n    (0xFB01, 'M', 'fi'),\n    (0xFB02, 'M', 'fl'),\n    (0xFB03, 'M', 'ffi'),\n    (0xFB04, 'M', 'ffl'),\n    (0xFB05, 'M', 'st'),\n    (0xFB07, 'X'),\n    (0xFB13, 'M', 'մն'),\n    (0xFB14, 'M', 'մե'),\n    (0xFB15, 'M', 'մի'),\n    (0xFB16, 'M', 'վն'),\n    (0xFB17, 'M', 'մխ'),\n    (0xFB18, 'X'),\n    (0xFB1D, 'M', 'יִ'),\n    (0xFB1E, 'V'),\n    (0xFB1F, 'M', 'ײַ'),\n    (0xFB20, 'M', 'ע'),\n    (0xFB21, 'M', 'א'),\n    (0xFB22, 'M', 'ד'),\n    (0xFB23, 'M', 'ה'),\n    (0xFB24, 'M', 'כ'),\n    (0xFB25, 'M', 'ל'),\n    (0xFB26, 'M', 'ם'),\n    (0xFB27, 'M', 'ר'),\n    (0xFB28, 'M', 'ת'),\n    (0xFB29, '3', '+'),\n    (0xFB2A, 'M', 'שׁ'),\n    (0xFB2B, 'M', 'שׂ'),\n    (0xFB2C, 'M', 'שּׁ'),\n    (0xFB2D, 'M', 'שּׂ'),\n    (0xFB2E, 'M', 'אַ'),\n    (0xFB2F, 'M', 'אָ'),\n    (0xFB30, 'M', 'אּ'),\n    (0xFB31, 'M', 'בּ'),\n    (0xFB32, 'M', 'גּ'),\n    (0xFB33, 'M', 'דּ'),\n    (0xFB34, 'M', 'הּ'),\n    (0xFB35, 'M', 'וּ'),\n    (0xFB36, 'M', 'זּ'),\n    (0xFB37, 'X'),\n    (0xFB38, 'M', 'טּ'),\n    (0xFB39, 'M', 'יּ'),\n    (0xFB3A, 'M', 'ךּ'),\n    (0xFB3B, 'M', 'כּ'),\n    (0xFB3C, 'M', 'לּ'),\n    (0xFB3D, 'X'),\n    (0xFB3E, 'M', 'מּ'),\n    (0xFB3F, 'X'),\n    (0xFB40, 'M', 'נּ'),\n    (0xFB41, 'M', 'סּ'),\n    (0xFB42, 'X'),\n    (0xFB43, 'M', 'ףּ'),\n    (0xFB44, 'M', 'פּ'),\n    (0xFB45, 'X'),\n    (0xFB46, 'M', 'צּ'),\n    (0xFB47, 'M', 'קּ'),\n    (0xFB48, 'M', 'רּ'),\n    (0xFB49, 'M', 'שּ'),\n    (0xFB4A, 'M', 'תּ'),\n    (0xFB4B, 'M', 'וֹ'),\n    (0xFB4C, 'M', 'בֿ'),\n    (0xFB4D, 'M', 'כֿ'),\n    (0xFB4E, 'M', 'פֿ'),\n    (0xFB4F, 'M', 'אל'),\n    (0xFB50, 'M', 'ٱ'),\n    (0xFB52, 'M', 'ٻ'),\n    (0xFB56, 'M', 'پ'),\n    (0xFB5A, 'M', 'ڀ'),\n    (0xFB5E, 'M', 'ٺ'),\n    (0xFB62, 'M', 'ٿ'),\n    (0xFB66, 'M', 'ٹ'),\n    (0xFB6A, 'M', 'ڤ'),\n    (0xFB6E, 'M', 'ڦ'),\n    (0xFB72, 'M', 'ڄ'),\n    (0xFB76, 'M', 'ڃ'),\n    (0xFB7A, 'M', 'چ'),\n    (0xFB7E, 'M', 'ڇ'),\n    (0xFB82, 'M', 'ڍ'),\n    (0xFB84, 'M', 'ڌ'),\n    (0xFB86, 'M', 'ڎ'),\n    (0xFB88, 'M', 'ڈ'),\n    (0xFB8A, 'M', 'ژ'),\n    (0xFB8C, 'M', 'ڑ'),\n    (0xFB8E, 'M', 'ک'),\n    (0xFB92, 'M', 'گ'),\n    (0xFB96, 'M', 'ڳ'),\n    (0xFB9A, 'M', 'ڱ'),\n    (0xFB9E, 'M', 'ں'),\n    (0xFBA0, 'M', 'ڻ'),\n    (0xFBA4, 'M', 'ۀ'),\n    (0xFBA6, 'M', 'ہ'),\n    (0xFBAA, 'M', 'ھ'),\n    (0xFBAE, 'M', 'ے'),\n    (0xFBB0, 'M', 'ۓ'),\n    (0xFBB2, 'V'),\n    (0xFBC2, 'X'),\n    (0xFBD3, 'M', 'ڭ'),\n    (0xFBD7, 'M', 'ۇ'),\n    (0xFBD9, 'M', 'ۆ'),\n    (0xFBDB, 'M', 'ۈ'),\n    (0xFBDD, 'M', 'ۇٴ'),\n    (0xFBDE, 'M', 'ۋ'),\n    (0xFBE0, 'M', 'ۅ'),\n    (0xFBE2, 'M', 'ۉ'),\n    (0xFBE4, 'M', 'ې'),\n    (0xFBE8, 'M', 'ى'),\n    (0xFBEA, 'M', 'ئا'),\n    (0xFBEC, 'M', 'ئە'),\n    (0xFBEE, 'M', 'ئو'),\n    (0xFBF0, 'M', 'ئۇ'),\n    (0xFBF2, 'M', 'ئۆ'),\n    (0xFBF4, 'M', 'ئۈ'),\n    (0xFBF6, 'M', 'ئې'),\n    (0xFBF9, 'M', 'ئى'),\n    (0xFBFC, 'M', 'ی'),\n    (0xFC00, 'M', 'ئج'),\n    (0xFC01, 'M', 'ئح'),\n    (0xFC02, 'M', 'ئم'),\n    (0xFC03, 'M', 'ئى'),\n    (0xFC04, 'M', 'ئي'),\n    (0xFC05, 'M', 'بج'),\n    (0xFC06, 'M', 'بح'),\n    (0xFC07, 'M', 'بخ'),\n    (0xFC08, 'M', 'بم'),\n    (0xFC09, 'M', 'بى'),\n    (0xFC0A, 'M', 'بي'),\n    (0xFC0B, 'M', 'تج'),\n    (0xFC0C, 'M', 'تح'),\n    (0xFC0D, 'M', 'تخ'),\n    (0xFC0E, 'M', 'تم'),\n    (0xFC0F, 'M', 'تى'),\n    (0xFC10, 'M', 'تي'),\n    (0xFC11, 'M', 'ثج'),\n    (0xFC12, 'M', 'ثم'),\n    (0xFC13, 'M', 'ثى'),\n    (0xFC14, 'M', 'ثي'),\n    (0xFC15, 'M', 'جح'),\n    (0xFC16, 'M', 'جم'),\n    (0xFC17, 'M', 'حج'),\n    (0xFC18, 'M', 'حم'),\n    (0xFC19, 'M', 'خج'),\n    (0xFC1A, 'M', 'خح'),\n    (0xFC1B, 'M', 'خم'),\n    (0xFC1C, 'M', 'سج'),\n    (0xFC1D, 'M', 'سح'),\n    (0xFC1E, 'M', 'سخ'),\n    (0xFC1F, 'M', 'سم'),\n    (0xFC20, 'M', 'صح'),\n    (0xFC21, 'M', 'صم'),\n    (0xFC22, 'M', 'ضج'),\n    (0xFC23, 'M', 'ضح'),\n    (0xFC24, 'M', 'ضخ'),\n    (0xFC25, 'M', 'ضم'),\n    (0xFC26, 'M', 'طح'),\n    (0xFC27, 'M', 'طم'),\n    (0xFC28, 'M', 'ظم'),\n    (0xFC29, 'M', 'عج'),\n    (0xFC2A, 'M', 'عم'),\n    (0xFC2B, 'M', 'غج'),\n    (0xFC2C, 'M', 'غم'),\n    (0xFC2D, 'M', 'فج'),\n    (0xFC2E, 'M', 'فح'),\n    (0xFC2F, 'M', 'فخ'),\n    (0xFC30, 'M', 'فم'),\n    (0xFC31, 'M', 'فى'),\n    (0xFC32, 'M', 'في'),\n    (0xFC33, 'M', 'قح'),\n    (0xFC34, 'M', 'قم'),\n    (0xFC35, 'M', 'قى'),\n    (0xFC36, 'M', 'قي'),\n    (0xFC37, 'M', 'كا'),\n    (0xFC38, 'M', 'كج'),\n    (0xFC39, 'M', 'كح'),\n    (0xFC3A, 'M', 'كخ'),\n    (0xFC3B, 'M', 'كل'),\n    (0xFC3C, 'M', 'كم'),\n    (0xFC3D, 'M', 'كى'),\n    (0xFC3E, 'M', 'كي'),\n    (0xFC3F, 'M', 'لج'),\n    (0xFC40, 'M', 'لح'),\n    (0xFC41, 'M', 'لخ'),\n    (0xFC42, 'M', 'لم'),\n    (0xFC43, 'M', 'لى'),\n    (0xFC44, 'M', 'لي'),\n    (0xFC45, 'M', 'مج'),\n    (0xFC46, 'M', 'مح'),\n    (0xFC47, 'M', 'مخ'),\n    (0xFC48, 'M', 'مم'),\n    (0xFC49, 'M', 'مى'),\n    (0xFC4A, 'M', 'مي'),\n    (0xFC4B, 'M', 'نج'),\n    (0xFC4C, 'M', 'نح'),\n    (0xFC4D, 'M', 'نخ'),\n    (0xFC4E, 'M', 'نم'),\n    (0xFC4F, 'M', 'نى'),\n    (0xFC50, 'M', 'ني'),\n    (0xFC51, 'M', 'هج'),\n    (0xFC52, 'M', 'هم'),\n    (0xFC53, 'M', 'هى'),\n    (0xFC54, 'M', 'هي'),\n    (0xFC55, 'M', 'يج'),\n    (0xFC56, 'M', 'يح'),\n    (0xFC57, 'M', 'يخ'),\n    (0xFC58, 'M', 'يم'),\n    (0xFC59, 'M', 'يى'),\n    (0xFC5A, 'M', 'يي'),\n    (0xFC5B, 'M', 'ذٰ'),\n    (0xFC5C, 'M', 'رٰ'),\n    (0xFC5D, 'M', 'ىٰ'),\n    (0xFC5E, '3', ' ٌّ'),\n    (0xFC5F, '3', ' ٍّ'),\n    (0xFC60, '3', ' َّ'),\n    (0xFC61, '3', ' ُّ'),\n    (0xFC62, '3', ' ِّ'),\n    (0xFC63, '3', ' ّٰ'),\n    (0xFC64, 'M', 'ئر'),\n    (0xFC65, 'M', 'ئز'),\n    (0xFC66, 'M', 'ئم'),\n    (0xFC67, 'M', 'ئن'),\n    (0xFC68, 'M', 'ئى'),\n    (0xFC69, 'M', 'ئي'),\n    (0xFC6A, 'M', 'بر'),\n    (0xFC6B, 'M', 'بز'),\n    (0xFC6C, 'M', 'بم'),\n    (0xFC6D, 'M', 'بن'),\n    (0xFC6E, 'M', 'بى'),\n    (0xFC6F, 'M', 'بي'),\n    (0xFC70, 'M', 'تر'),\n    (0xFC71, 'M', 'تز'),\n    (0xFC72, 'M', 'تم'),\n    (0xFC73, 'M', 'تن'),\n    (0xFC74, 'M', 'تى'),\n    (0xFC75, 'M', 'تي'),\n    (0xFC76, 'M', 'ثر'),\n    (0xFC77, 'M', 'ثز'),\n    (0xFC78, 'M', 'ثم'),\n    (0xFC79, 'M', 'ثن'),\n    (0xFC7A, 'M', 'ثى'),\n    (0xFC7B, 'M', 'ثي'),\n    (0xFC7C, 'M', 'فى'),\n    (0xFC7D, 'M', 'في'),\n    (0xFC7E, 'M', 'قى'),\n    (0xFC7F, 'M', 'قي'),\n    (0xFC80, 'M', 'كا'),\n    (0xFC81, 'M', 'كل'),\n    (0xFC82, 'M', 'كم'),\n    (0xFC83, 'M', 'كى'),\n    (0xFC84, 'M', 'كي'),\n    (0xFC85, 'M', 'لم'),\n    (0xFC86, 'M', 'لى'),\n    (0xFC87, 'M', 'لي'),\n    (0xFC88, 'M', 'ما'),\n    (0xFC89, 'M', 'مم'),\n    (0xFC8A, 'M', 'نر'),\n    (0xFC8B, 'M', 'نز'),\n    (0xFC8C, 'M', 'نم'),\n    (0xFC8D, 'M', 'نن'),\n    (0xFC8E, 'M', 'نى'),\n    (0xFC8F, 'M', 'ني'),\n    (0xFC90, 'M', 'ىٰ'),\n    (0xFC91, 'M', 'ير'),\n    (0xFC92, 'M', 'يز'),\n    (0xFC93, 'M', 'يم'),\n    (0xFC94, 'M', 'ين'),\n    (0xFC95, 'M', 'يى'),\n    (0xFC96, 'M', 'يي'),\n    (0xFC97, 'M', 'ئج'),\n    (0xFC98, 'M', 'ئح'),\n    (0xFC99, 'M', 'ئخ'),\n    (0xFC9A, 'M', 'ئم'),\n    (0xFC9B, 'M', 'ئه'),\n    (0xFC9C, 'M', 'بج'),\n    (0xFC9D, 'M', 'بح'),\n    (0xFC9E, 'M', 'بخ'),\n    (0xFC9F, 'M', 'بم'),\n    (0xFCA0, 'M', 'به'),\n    (0xFCA1, 'M', 'تج'),\n    (0xFCA2, 'M', 'تح'),\n    (0xFCA3, 'M', 'تخ'),\n    (0xFCA4, 'M', 'تم'),\n    (0xFCA5, 'M', 'ته'),\n    (0xFCA6, 'M', 'ثم'),\n    (0xFCA7, 'M', 'جح'),\n    (0xFCA8, 'M', 'جم'),\n    (0xFCA9, 'M', 'حج'),\n    (0xFCAA, 'M', 'حم'),\n    (0xFCAB, 'M', 'خج'),\n    (0xFCAC, 'M', 'خم'),\n    (0xFCAD, 'M', 'سج'),\n    (0xFCAE, 'M', 'سح'),\n    (0xFCAF, 'M', 'سخ'),\n    (0xFCB0, 'M', 'سم'),\n    (0xFCB1, 'M', 'صح'),\n    (0xFCB2, 'M', 'صخ'),\n    (0xFCB3, 'M', 'صم'),\n    (0xFCB4, 'M', 'ضج'),\n    (0xFCB5, 'M', 'ضح'),\n    (0xFCB6, 'M', 'ضخ'),\n    (0xFCB7, 'M', 'ضم'),\n    (0xFCB8, 'M', 'طح'),\n    (0xFCB9, 'M', 'ظم'),\n    (0xFCBA, 'M', 'عج'),\n    (0xFCBB, 'M', 'عم'),\n    (0xFCBC, 'M', 'غج'),\n    (0xFCBD, 'M', 'غم'),\n    (0xFCBE, 'M', 'فج'),\n    (0xFCBF, 'M', 'فح'),\n    (0xFCC0, 'M', 'فخ'),\n    (0xFCC1, 'M', 'فم'),\n    (0xFCC2, 'M', 'قح'),\n    (0xFCC3, 'M', 'قم'),\n    (0xFCC4, 'M', 'كج'),\n    (0xFCC5, 'M', 'كح'),\n    (0xFCC6, 'M', 'كخ'),\n    (0xFCC7, 'M', 'كل'),\n    (0xFCC8, 'M', 'كم'),\n    (0xFCC9, 'M', 'لج'),\n    (0xFCCA, 'M', 'لح'),\n    (0xFCCB, 'M', 'لخ'),\n    (0xFCCC, 'M', 'لم'),\n    (0xFCCD, 'M', 'له'),\n    (0xFCCE, 'M', 'مج'),\n    (0xFCCF, 'M', 'مح'),\n    (0xFCD0, 'M', 'مخ'),\n    (0xFCD1, 'M', 'مم'),\n    (0xFCD2, 'M', 'نج'),\n    (0xFCD3, 'M', 'نح'),\n    (0xFCD4, 'M', 'نخ'),\n    (0xFCD5, 'M', 'نم'),\n    (0xFCD6, 'M', 'نه'),\n    (0xFCD7, 'M', 'هج'),\n    (0xFCD8, 'M', 'هم'),\n    (0xFCD9, 'M', 'هٰ'),\n    (0xFCDA, 'M', 'يج'),\n    (0xFCDB, 'M', 'يح'),\n    (0xFCDC, 'M', 'يخ'),\n    (0xFCDD, 'M', 'يم'),\n    (0xFCDE, 'M', 'يه'),\n    (0xFCDF, 'M', 'ئم'),\n    (0xFCE0, 'M', 'ئه'),\n    (0xFCE1, 'M', 'بم'),\n    (0xFCE2, 'M', 'به'),\n    (0xFCE3, 'M', 'تم'),\n    (0xFCE4, 'M', 'ته'),\n    (0xFCE5, 'M', 'ثم'),\n    (0xFCE6, 'M', 'ثه'),\n    (0xFCE7, 'M', 'سم'),\n    (0xFCE8, 'M', 'سه'),\n    (0xFCE9, 'M', 'شم'),\n    (0xFCEA, 'M', 'شه'),\n    (0xFCEB, 'M', 'كل'),\n    (0xFCEC, 'M', 'كم'),\n    (0xFCED, 'M', 'لم'),\n    (0xFCEE, 'M', 'نم'),\n    (0xFCEF, 'M', 'نه'),\n    (0xFCF0, 'M', 'يم'),\n    (0xFCF1, 'M', 'يه'),\n    (0xFCF2, 'M', 'ـَّ'),\n    (0xFCF3, 'M', 'ـُّ'),\n    (0xFCF4, 'M', 'ـِّ'),\n    (0xFCF5, 'M', 'طى'),\n    (0xFCF6, 'M', 'طي'),\n    (0xFCF7, 'M', 'عى'),\n    (0xFCF8, 'M', 'عي'),\n    (0xFCF9, 'M', 'غى'),\n    (0xFCFA, 'M', 'غي'),\n    (0xFCFB, 'M', 'سى'),\n    (0xFCFC, 'M', 'سي'),\n    (0xFCFD, 'M', 'شى'),\n    (0xFCFE, 'M', 'شي'),\n    (0xFCFF, 'M', 'حى'),\n    (0xFD00, 'M', 'حي'),\n    (0xFD01, 'M', 'جى'),\n    (0xFD02, 'M', 'جي'),\n    (0xFD03, 'M', 'خى'),\n    (0xFD04, 'M', 'خي'),\n    (0xFD05, 'M', 'صى'),\n    (0xFD06, 'M', 'صي'),\n    (0xFD07, 'M', 'ضى'),\n    (0xFD08, 'M', 'ضي'),\n    (0xFD09, 'M', 'شج'),\n    (0xFD0A, 'M', 'شح'),\n    (0xFD0B, 'M', 'شخ'),\n    (0xFD0C, 'M', 'شم'),\n    (0xFD0D, 'M', 'شر'),\n    (0xFD0E, 'M', 'سر'),\n    (0xFD0F, 'M', 'صر'),\n    (0xFD10, 'M', 'ضر'),\n    (0xFD11, 'M', 'طى'),\n    (0xFD12, 'M', 'طي'),\n    (0xFD13, 'M', 'عى'),\n    (0xFD14, 'M', 'عي'),\n    (0xFD15, 'M', 'غى'),\n    (0xFD16, 'M', 'غي'),\n    (0xFD17, 'M', 'سى'),\n    (0xFD18, 'M', 'سي'),\n    (0xFD19, 'M', 'شى'),\n    (0xFD1A, 'M', 'شي'),\n    (0xFD1B, 'M', 'حى'),\n    (0xFD1C, 'M', 'حي'),\n    (0xFD1D, 'M', 'جى'),\n    (0xFD1E, 'M', 'جي'),\n    (0xFD1F, 'M', 'خى'),\n    (0xFD20, 'M', 'خي'),\n    (0xFD21, 'M', 'صى'),\n    (0xFD22, 'M', 'صي'),\n    (0xFD23, 'M', 'ضى'),\n    (0xFD24, 'M', 'ضي'),\n    (0xFD25, 'M', 'شج'),\n    (0xFD26, 'M', 'شح'),\n    (0xFD27, 'M', 'شخ'),\n    (0xFD28, 'M', 'شم'),\n    (0xFD29, 'M', 'شر'),\n    (0xFD2A, 'M', 'سر'),\n    (0xFD2B, 'M', 'صر'),\n    (0xFD2C, 'M', 'ضر'),\n    (0xFD2D, 'M', 'شج'),\n    (0xFD2E, 'M', 'شح'),\n    (0xFD2F, 'M', 'شخ'),\n    (0xFD30, 'M', 'شم'),\n    (0xFD31, 'M', 'سه'),\n    (0xFD32, 'M', 'شه'),\n    (0xFD33, 'M', 'طم'),\n    (0xFD34, 'M', 'سج'),\n    (0xFD35, 'M', 'سح'),\n    (0xFD36, 'M', 'سخ'),\n    (0xFD37, 'M', 'شج'),\n    (0xFD38, 'M', 'شح'),\n    (0xFD39, 'M', 'شخ'),\n    (0xFD3A, 'M', 'طم'),\n    (0xFD3B, 'M', 'ظم'),\n    (0xFD3C, 'M', 'اً'),\n    (0xFD3E, 'V'),\n    (0xFD40, 'X'),\n    (0xFD50, 'M', 'تجم'),\n    (0xFD51, 'M', 'تحج'),\n    (0xFD53, 'M', 'تحم'),\n    (0xFD54, 'M', 'تخم'),\n    (0xFD55, 'M', 'تمج'),\n    (0xFD56, 'M', 'تمح'),\n    (0xFD57, 'M', 'تمخ'),\n    (0xFD58, 'M', 'جمح'),\n    (0xFD5A, 'M', 'حمي'),\n    (0xFD5B, 'M', 'حمى'),\n    (0xFD5C, 'M', 'سحج'),\n    (0xFD5D, 'M', 'سجح'),\n    (0xFD5E, 'M', 'سجى'),\n    (0xFD5F, 'M', 'سمح'),\n    (0xFD61, 'M', 'سمج'),\n    (0xFD62, 'M', 'سمم'),\n    (0xFD64, 'M', 'صحح'),\n    (0xFD66, 'M', 'صمم'),\n    (0xFD67, 'M', 'شحم'),\n    (0xFD69, 'M', 'شجي'),\n    (0xFD6A, 'M', 'شمخ'),\n    (0xFD6C, 'M', 'شمم'),\n    (0xFD6E, 'M', 'ضحى'),\n    (0xFD6F, 'M', 'ضخم'),\n    (0xFD71, 'M', 'طمح'),\n    (0xFD73, 'M', 'طمم'),\n    (0xFD74, 'M', 'طمي'),\n    (0xFD75, 'M', 'عجم'),\n    (0xFD76, 'M', 'عمم'),\n    (0xFD78, 'M', 'عمى'),\n    (0xFD79, 'M', 'غمم'),\n    (0xFD7A, 'M', 'غمي'),\n    (0xFD7B, 'M', 'غمى'),\n    (0xFD7C, 'M', 'فخم'),\n    (0xFD7E, 'M', 'قمح'),\n    (0xFD7F, 'M', 'قمم'),\n    (0xFD80, 'M', 'لحم'),\n    (0xFD81, 'M', 'لحي'),\n    (0xFD82, 'M', 'لحى'),\n    (0xFD83, 'M', 'لجج'),\n    (0xFD85, 'M', 'لخم'),\n    (0xFD87, 'M', 'لمح'),\n    (0xFD89, 'M', 'محج'),\n    (0xFD8A, 'M', 'محم'),\n    (0xFD8B, 'M', 'محي'),\n    (0xFD8C, 'M', 'مجح'),\n    (0xFD8D, 'M', 'مجم'),\n    (0xFD8E, 'M', 'مخج'),\n    (0xFD8F, 'M', 'مخم'),\n    (0xFD90, 'X'),\n    (0xFD92, 'M', 'مجخ'),\n    (0xFD93, 'M', 'همج'),\n    (0xFD94, 'M', 'همم'),\n    (0xFD95, 'M', 'نحم'),\n    (0xFD96, 'M', 'نحى'),\n    (0xFD97, 'M', 'نجم'),\n    (0xFD99, 'M', 'نجى'),\n    (0xFD9A, 'M', 'نمي'),\n    (0xFD9B, 'M', 'نمى'),\n    (0xFD9C, 'M', 'يمم'),\n    (0xFD9E, 'M', 'بخي'),\n    (0xFD9F, 'M', 'تجي'),\n    (0xFDA0, 'M', 'تجى'),\n    (0xFDA1, 'M', 'تخي'),\n    (0xFDA2, 'M', 'تخى'),\n    (0xFDA3, 'M', 'تمي'),\n    (0xFDA4, 'M', 'تمى'),\n    (0xFDA5, 'M', 'جمي'),\n    (0xFDA6, 'M', 'جحى'),\n    (0xFDA7, 'M', 'جمى'),\n    (0xFDA8, 'M', 'سخى'),\n    (0xFDA9, 'M', 'صحي'),\n    (0xFDAA, 'M', 'شحي'),\n    (0xFDAB, 'M', 'ضحي'),\n    (0xFDAC, 'M', 'لجي'),\n    (0xFDAD, 'M', 'لمي'),\n    (0xFDAE, 'M', 'يحي'),\n    (0xFDAF, 'M', 'يجي'),\n    (0xFDB0, 'M', 'يمي'),\n    (0xFDB1, 'M', 'ممي'),\n    (0xFDB2, 'M', 'قمي'),\n    (0xFDB3, 'M', 'نحي'),\n    (0xFDB4, 'M', 'قمح'),\n    (0xFDB5, 'M', 'لحم'),\n    (0xFDB6, 'M', 'عمي'),\n    (0xFDB7, 'M', 'كمي'),\n    (0xFDB8, 'M', 'نجح'),\n    (0xFDB9, 'M', 'مخي'),\n    (0xFDBA, 'M', 'لجم'),\n    (0xFDBB, 'M', 'كمم'),\n    (0xFDBC, 'M', 'لجم'),\n    (0xFDBD, 'M', 'نجح'),\n    (0xFDBE, 'M', 'جحي'),\n    (0xFDBF, 'M', 'حجي'),\n    (0xFDC0, 'M', 'مجي'),\n    (0xFDC1, 'M', 'فمي'),\n    (0xFDC2, 'M', 'بحي'),\n    (0xFDC3, 'M', 'كمم'),\n    (0xFDC4, 'M', 'عجم'),\n    (0xFDC5, 'M', 'صمم'),\n    (0xFDC6, 'M', 'سخي'),\n    (0xFDC7, 'M', 'نجي'),\n    (0xFDC8, 'X'),\n    (0xFDF0, 'M', 'صلے'),\n    (0xFDF1, 'M', 'قلے'),\n    (0xFDF2, 'M', 'الله'),\n    (0xFDF3, 'M', 'اكبر'),\n    (0xFDF4, 'M', 'محمد'),\n    (0xFDF5, 'M', 'صلعم'),\n    (0xFDF6, 'M', 'رسول'),\n    (0xFDF7, 'M', 'عليه'),\n    (0xFDF8, 'M', 'وسلم'),\n    (0xFDF9, 'M', 'صلى'),\n    (0xFDFA, '3', 'صلى الله عليه وسلم'),\n    (0xFDFB, '3', 'جل جلاله'),\n    (0xFDFC, 'M', 'ریال'),\n    (0xFDFD, 'V'),\n    (0xFDFE, 'X'),\n    (0xFE00, 'I'),\n    (0xFE10, '3', ','),\n    (0xFE11, 'M', '、'),\n    (0xFE12, 'X'),\n    (0xFE13, '3', ':'),\n    (0xFE14, '3', ';'),\n    (0xFE15, '3', '!'),\n    (0xFE16, '3', '?'),\n    (0xFE17, 'M', '〖'),\n    (0xFE18, 'M', '〗'),\n    (0xFE19, 'X'),\n    (0xFE20, 'V'),\n    (0xFE27, 'X'),\n    (0xFE31, 'M', '—'),\n    (0xFE32, 'M', '–'),\n    (0xFE33, '3', '_'),\n    (0xFE35, '3', '('),\n    (0xFE36, '3', ')'),\n    (0xFE37, '3', '{'),\n    (0xFE38, '3', '}'),\n    (0xFE39, 'M', '〔'),\n    (0xFE3A, 'M', '〕'),\n    (0xFE3B, 'M', '【'),\n    (0xFE3C, 'M', '】'),\n    (0xFE3D, 'M', '《'),\n    (0xFE3E, 'M', '》'),\n    (0xFE3F, 'M', '〈'),\n    (0xFE40, 'M', '〉'),\n    (0xFE41, 'M', '「'),\n    (0xFE42, 'M', '」'),\n    (0xFE43, 'M', '『'),\n    (0xFE44, 'M', '』'),\n    (0xFE45, 'V'),\n    (0xFE47, '3', '['),\n    (0xFE48, '3', ']'),\n    (0xFE49, '3', ' ̅'),\n    (0xFE4D, '3', '_'),\n    (0xFE50, '3', ','),\n    (0xFE51, 'M', '、'),\n    (0xFE52, 'X'),\n    (0xFE54, '3', ';'),\n    (0xFE55, '3', ':'),\n    (0xFE56, '3', '?'),\n    (0xFE57, '3', '!'),\n    (0xFE58, 'M', '—'),\n    (0xFE59, '3', '('),\n    (0xFE5A, '3', ')'),\n    (0xFE5B, '3', '{'),\n    (0xFE5C, '3', '}'),\n    (0xFE5D, 'M', '〔'),\n    (0xFE5E, 'M', '〕'),\n    (0xFE5F, '3', '#'),\n    (0xFE60, '3', '&'),\n    (0xFE61, '3', '*'),\n    (0xFE62, '3', '+'),\n    (0xFE63, 'M', '-'),\n    (0xFE64, '3', '<'),\n    (0xFE65, '3', '>'),\n    (0xFE66, '3', '='),\n    (0xFE67, 'X'),\n    (0xFE68, '3', '\\\\'),\n    (0xFE69, '3', '$'),\n    (0xFE6A, '3', '%'),\n    (0xFE6B, '3', '@'),\n    (0xFE6C, 'X'),\n    (0xFE70, '3', ' ً'),\n    (0xFE71, 'M', 'ـً'),\n    (0xFE72, '3', ' ٌ'),\n    (0xFE73, 'V'),\n    (0xFE74, '3', ' ٍ'),\n    (0xFE75, 'X'),\n    (0xFE76, '3', ' َ'),\n    (0xFE77, 'M', 'ـَ'),\n    (0xFE78, '3', ' ُ'),\n    (0xFE79, 'M', 'ـُ'),\n    (0xFE7A, '3', ' ِ'),\n    (0xFE7B, 'M', 'ـِ'),\n    (0xFE7C, '3', ' ّ'),\n    (0xFE7D, 'M', 'ـّ'),\n    (0xFE7E, '3', ' ْ'),\n    (0xFE7F, 'M', 'ـْ'),\n    (0xFE80, 'M', 'ء'),\n    (0xFE81, 'M', 'آ'),\n    (0xFE83, 'M', 'أ'),\n    (0xFE85, 'M', 'ؤ'),\n    (0xFE87, 'M', 'إ'),\n    (0xFE89, 'M', 'ئ'),\n    (0xFE8D, 'M', 'ا'),\n    (0xFE8F, 'M', 'ب'),\n    (0xFE93, 'M', 'ة'),\n    (0xFE95, 'M', 'ت'),\n    (0xFE99, 'M', 'ث'),\n    (0xFE9D, 'M', 'ج'),\n    (0xFEA1, 'M', 'ح'),\n    (0xFEA5, 'M', 'خ'),\n    (0xFEA9, 'M', 'د'),\n    (0xFEAB, 'M', 'ذ'),\n    (0xFEAD, 'M', 'ر'),\n    (0xFEAF, 'M', 'ز'),\n    (0xFEB1, 'M', 'س'),\n    (0xFEB5, 'M', 'ش'),\n    (0xFEB9, 'M', 'ص'),\n    (0xFEBD, 'M', 'ض'),\n    (0xFEC1, 'M', 'ط'),\n    (0xFEC5, 'M', 'ظ'),\n    (0xFEC9, 'M', 'ع'),\n    (0xFECD, 'M', 'غ'),\n    (0xFED1, 'M', 'ف'),\n    (0xFED5, 'M', 'ق'),\n    (0xFED9, 'M', 'ك'),\n    (0xFEDD, 'M', 'ل'),\n    (0xFEE1, 'M', 'م'),\n    (0xFEE5, 'M', 'ن'),\n    (0xFEE9, 'M', 'ه'),\n    (0xFEED, 'M', 'و'),\n    (0xFEEF, 'M', 'ى'),\n    (0xFEF1, 'M', 'ي'),\n    (0xFEF5, 'M', 'لآ'),\n    (0xFEF7, 'M', 'لأ'),\n    (0xFEF9, 'M', 'لإ'),\n    (0xFEFB, 'M', 'لا'),\n    (0xFEFD, 'X'),\n    (0xFEFF, 'I'),\n    (0xFF00, 'X'),\n    (0xFF01, '3', '!'),\n    (0xFF02, '3', '\"'),\n    (0xFF03, '3', '#'),\n    (0xFF04, '3', '$'),\n    (0xFF05, '3', '%'),\n    (0xFF06, '3', '&'),\n    (0xFF07, '3', '\\''),\n    (0xFF08, '3', '('),\n    (0xFF09, '3', ')'),\n    (0xFF0A, '3', '*'),\n    (0xFF0B, '3', '+'),\n    (0xFF0C, '3', ','),\n    (0xFF0D, 'M', '-'),\n    (0xFF0E, 'M', '.'),\n    (0xFF0F, '3', '/'),\n    (0xFF10, 'M', '0'),\n    (0xFF11, 'M', '1'),\n    (0xFF12, 'M', '2'),\n    (0xFF13, 'M', '3'),\n    (0xFF14, 'M', '4'),\n    (0xFF15, 'M', '5'),\n    (0xFF16, 'M', '6'),\n    (0xFF17, 'M', '7'),\n    (0xFF18, 'M', '8'),\n    (0xFF19, 'M', '9'),\n    (0xFF1A, '3', ':'),\n    (0xFF1B, '3', ';'),\n    (0xFF1C, '3', '<'),\n    (0xFF1D, '3', '='),\n    (0xFF1E, '3', '>'),\n    (0xFF1F, '3', '?'),\n    (0xFF20, '3', '@'),\n    (0xFF21, 'M', 'a'),\n    (0xFF22, 'M', 'b'),\n    (0xFF23, 'M', 'c'),\n    (0xFF24, 'M', 'd'),\n    (0xFF25, 'M', 'e'),\n    (0xFF26, 'M', 'f'),\n    (0xFF27, 'M', 'g'),\n    (0xFF28, 'M', 'h'),\n    (0xFF29, 'M', 'i'),\n    (0xFF2A, 'M', 'j'),\n    (0xFF2B, 'M', 'k'),\n    (0xFF2C, 'M', 'l'),\n    (0xFF2D, 'M', 'm'),\n    (0xFF2E, 'M', 'n'),\n    (0xFF2F, 'M', 'o'),\n    (0xFF30, 'M', 'p'),\n    (0xFF31, 'M', 'q'),\n    (0xFF32, 'M', 'r'),\n    (0xFF33, 'M', 's'),\n    (0xFF34, 'M', 't'),\n    (0xFF35, 'M', 'u'),\n    (0xFF36, 'M', 'v'),\n    (0xFF37, 'M', 'w'),\n    (0xFF38, 'M', 'x'),\n    (0xFF39, 'M', 'y'),\n    (0xFF3A, 'M', 'z'),\n    (0xFF3B, '3', '['),\n    (0xFF3C, '3', '\\\\'),\n    (0xFF3D, '3', ']'),\n    (0xFF3E, '3', '^'),\n    (0xFF3F, '3', '_'),\n    (0xFF40, '3', '`'),\n    (0xFF41, 'M', 'a'),\n    (0xFF42, 'M', 'b'),\n    (0xFF43, 'M', 'c'),\n    (0xFF44, 'M', 'd'),\n    (0xFF45, 'M', 'e'),\n    (0xFF46, 'M', 'f'),\n    (0xFF47, 'M', 'g'),\n    (0xFF48, 'M', 'h'),\n    (0xFF49, 'M', 'i'),\n    (0xFF4A, 'M', 'j'),\n    (0xFF4B, 'M', 'k'),\n    (0xFF4C, 'M', 'l'),\n    (0xFF4D, 'M', 'm'),\n    (0xFF4E, 'M', 'n'),\n    (0xFF4F, 'M', 'o'),\n    (0xFF50, 'M', 'p'),\n    (0xFF51, 'M', 'q'),\n    (0xFF52, 'M', 'r'),\n    (0xFF53, 'M', 's'),\n    (0xFF54, 'M', 't'),\n    (0xFF55, 'M', 'u'),\n    (0xFF56, 'M', 'v'),\n    (0xFF57, 'M', 'w'),\n    (0xFF58, 'M', 'x'),\n    (0xFF59, 'M', 'y'),\n    (0xFF5A, 'M', 'z'),\n    (0xFF5B, '3', '{'),\n    (0xFF5C, '3', '|'),\n    (0xFF5D, '3', '}'),\n    (0xFF5E, '3', '~'),\n    (0xFF5F, 'M', '⦅'),\n    (0xFF60, 'M', '⦆'),\n    (0xFF61, 'M', '.'),\n    (0xFF62, 'M', '「'),\n    (0xFF63, 'M', '」'),\n    (0xFF64, 'M', '、'),\n    (0xFF65, 'M', '・'),\n    (0xFF66, 'M', 'ヲ'),\n    (0xFF67, 'M', 'ァ'),\n    (0xFF68, 'M', 'ィ'),\n    (0xFF69, 'M', 'ゥ'),\n    (0xFF6A, 'M', 'ェ'),\n    (0xFF6B, 'M', 'ォ'),\n    (0xFF6C, 'M', 'ャ'),\n    (0xFF6D, 'M', 'ュ'),\n    (0xFF6E, 'M', 'ョ'),\n    (0xFF6F, 'M', 'ッ'),\n    (0xFF70, 'M', 'ー'),\n    (0xFF71, 'M', 'ア'),\n    (0xFF72, 'M', 'イ'),\n    (0xFF73, 'M', 'ウ'),\n    (0xFF74, 'M', 'エ'),\n    (0xFF75, 'M', 'オ'),\n    (0xFF76, 'M', 'カ'),\n    (0xFF77, 'M', 'キ'),\n    (0xFF78, 'M', 'ク'),\n    (0xFF79, 'M', 'ケ'),\n    (0xFF7A, 'M', 'コ'),\n    (0xFF7B, 'M', 'サ'),\n    (0xFF7C, 'M', 'シ'),\n    (0xFF7D, 'M', 'ス'),\n    (0xFF7E, 'M', 'セ'),\n    (0xFF7F, 'M', 'ソ'),\n    (0xFF80, 'M', 'タ'),\n    (0xFF81, 'M', 'チ'),\n    (0xFF82, 'M', 'ツ'),\n    (0xFF83, 'M', 'テ'),\n    (0xFF84, 'M', 'ト'),\n    (0xFF85, 'M', 'ナ'),\n    (0xFF86, 'M', 'ニ'),\n    (0xFF87, 'M', 'ヌ'),\n    (0xFF88, 'M', 'ネ'),\n    (0xFF89, 'M', 'ノ'),\n    (0xFF8A, 'M', 'ハ'),\n    (0xFF8B, 'M', 'ヒ'),\n    (0xFF8C, 'M', 'フ'),\n    (0xFF8D, 'M', 'ヘ'),\n    (0xFF8E, 'M', 'ホ'),\n    (0xFF8F, 'M', 'マ'),\n    (0xFF90, 'M', 'ミ'),\n    (0xFF91, 'M', 'ム'),\n    (0xFF92, 'M', 'メ'),\n    (0xFF93, 'M', 'モ'),\n    (0xFF94, 'M', 'ヤ'),\n    (0xFF95, 'M', 'ユ'),\n    (0xFF96, 'M', 'ヨ'),\n    (0xFF97, 'M', 'ラ'),\n    (0xFF98, 'M', 'リ'),\n    (0xFF99, 'M', 'ル'),\n    (0xFF9A, 'M', 'レ'),\n    (0xFF9B, 'M', 'ロ'),\n    (0xFF9C, 'M', 'ワ'),\n    (0xFF9D, 'M', 'ン'),\n    (0xFF9E, 'M', '゙'),\n    (0xFF9F, 'M', '゚'),\n    (0xFFA0, 'X'),\n    (0xFFA1, 'M', 'ᄀ'),\n    (0xFFA2, 'M', 'ᄁ'),\n    (0xFFA3, 'M', 'ᆪ'),\n    (0xFFA4, 'M', 'ᄂ'),\n    (0xFFA5, 'M', 'ᆬ'),\n    (0xFFA6, 'M', 'ᆭ'),\n    (0xFFA7, 'M', 'ᄃ'),\n    (0xFFA8, 'M', 'ᄄ'),\n    (0xFFA9, 'M', 'ᄅ'),\n    (0xFFAA, 'M', 'ᆰ'),\n    (0xFFAB, 'M', 'ᆱ'),\n    (0xFFAC, 'M', 'ᆲ'),\n    (0xFFAD, 'M', 'ᆳ'),\n    (0xFFAE, 'M', 'ᆴ'),\n    (0xFFAF, 'M', 'ᆵ'),\n    (0xFFB0, 'M', 'ᄚ'),\n    (0xFFB1, 'M', 'ᄆ'),\n    (0xFFB2, 'M', 'ᄇ'),\n    (0xFFB3, 'M', 'ᄈ'),\n    (0xFFB4, 'M', 'ᄡ'),\n    (0xFFB5, 'M', 'ᄉ'),\n    (0xFFB6, 'M', 'ᄊ'),\n    (0xFFB7, 'M', 'ᄋ'),\n    (0xFFB8, 'M', 'ᄌ'),\n    (0xFFB9, 'M', 'ᄍ'),\n    (0xFFBA, 'M', 'ᄎ'),\n    (0xFFBB, 'M', 'ᄏ'),\n    (0xFFBC, 'M', 'ᄐ'),\n    (0xFFBD, 'M', 'ᄑ'),\n    (0xFFBE, 'M', 'ᄒ'),\n    (0xFFBF, 'X'),\n    (0xFFC2, 'M', 'ᅡ'),\n    (0xFFC3, 'M', 'ᅢ'),\n    (0xFFC4, 'M', 'ᅣ'),\n    (0xFFC5, 'M', 'ᅤ'),\n    (0xFFC6, 'M', 'ᅥ'),\n    (0xFFC7, 'M', 'ᅦ'),\n    (0xFFC8, 'X'),\n    (0xFFCA, 'M', 'ᅧ'),\n    (0xFFCB, 'M', 'ᅨ'),\n    (0xFFCC, 'M', 'ᅩ'),\n    (0xFFCD, 'M', 'ᅪ'),\n    (0xFFCE, 'M', 'ᅫ'),\n    (0xFFCF, 'M', 'ᅬ'),\n    (0xFFD0, 'X'),\n    (0xFFD2, 'M', 'ᅭ'),\n    (0xFFD3, 'M', 'ᅮ'),\n    (0xFFD4, 'M', 'ᅯ'),\n    (0xFFD5, 'M', 'ᅰ'),\n    (0xFFD6, 'M', 'ᅱ'),\n    (0xFFD7, 'M', 'ᅲ'),\n    (0xFFD8, 'X'),\n    (0xFFDA, 'M', 'ᅳ'),\n    (0xFFDB, 'M', 'ᅴ'),\n    (0xFFDC, 'M', 'ᅵ'),\n    (0xFFDD, 'X'),\n    (0xFFE0, 'M', '¢'),\n    (0xFFE1, 'M', '£'),\n    (0xFFE2, 'M', '¬'),\n    (0xFFE3, '3', ' ̄'),\n    (0xFFE4, 'M', '¦'),\n    (0xFFE5, 'M', '¥'),\n    (0xFFE6, 'M', '₩'),\n    (0xFFE7, 'X'),\n    (0xFFE8, 'M', '│'),\n    (0xFFE9, 'M', '←'),\n    (0xFFEA, 'M', '↑'),\n    (0xFFEB, 'M', '→'),\n    (0xFFEC, 'M', '↓'),\n    (0xFFED, 'M', '■'),\n    (0xFFEE, 'M', '○'),\n    (0xFFEF, 'X'),\n    (0x10000, 'V'),\n    (0x1000C, 'X'),\n    (0x1000D, 'V'),\n    (0x10027, 'X'),\n    (0x10028, 'V'),\n    (0x1003B, 'X'),\n    (0x1003C, 'V'),\n    (0x1003E, 'X'),\n    (0x1003F, 'V'),\n    (0x1004E, 'X'),\n    (0x10050, 'V'),\n    (0x1005E, 'X'),\n    (0x10080, 'V'),\n    (0x100FB, 'X'),\n    (0x10100, 'V'),\n    (0x10103, 'X'),\n    (0x10107, 'V'),\n    (0x10134, 'X'),\n    (0x10137, 'V'),\n    (0x1018B, 'X'),\n    (0x10190, 'V'),\n    (0x1019C, 'X'),\n    (0x101D0, 'V'),\n    (0x101FE, 'X'),\n    (0x10280, 'V'),\n    (0x1029D, 'X'),\n    (0x102A0, 'V'),\n    (0x102D1, 'X'),\n    (0x10300, 'V'),\n    (0x1031F, 'X'),\n    (0x10320, 'V'),\n    (0x10324, 'X'),\n    (0x10330, 'V'),\n    (0x1034B, 'X'),\n    (0x10380, 'V'),\n    (0x1039E, 'X'),\n    (0x1039F, 'V'),\n    (0x103C4, 'X'),\n    (0x103C8, 'V'),\n    (0x103D6, 'X'),\n    (0x10400, 'M', '𐐨'),\n    (0x10401, 'M', '𐐩'),\n    (0x10402, 'M', '𐐪'),\n    (0x10403, 'M', '𐐫'),\n    (0x10404, 'M', '𐐬'),\n    (0x10405, 'M', '𐐭'),\n    (0x10406, 'M', '𐐮'),\n    (0x10407, 'M', '𐐯'),\n    (0x10408, 'M', '𐐰'),\n    (0x10409, 'M', '𐐱'),\n    (0x1040A, 'M', '𐐲'),\n    (0x1040B, 'M', '𐐳'),\n    (0x1040C, 'M', '𐐴'),\n    (0x1040D, 'M', '𐐵'),\n    (0x1040E, 'M', '𐐶'),\n    (0x1040F, 'M', '𐐷'),\n    (0x10410, 'M', '𐐸'),\n    (0x10411, 'M', '𐐹'),\n    (0x10412, 'M', '𐐺'),\n    (0x10413, 'M', '𐐻'),\n    (0x10414, 'M', '𐐼'),\n    (0x10415, 'M', '𐐽'),\n    (0x10416, 'M', '𐐾'),\n    (0x10417, 'M', '𐐿'),\n    (0x10418, 'M', '𐑀'),\n    (0x10419, 'M', '𐑁'),\n    (0x1041A, 'M', '𐑂'),\n    (0x1041B, 'M', '𐑃'),\n    (0x1041C, 'M', '𐑄'),\n    (0x1041D, 'M', '𐑅'),\n    (0x1041E, 'M', '𐑆'),\n    (0x1041F, 'M', '𐑇'),\n    (0x10420, 'M', '𐑈'),\n    (0x10421, 'M', '𐑉'),\n    (0x10422, 'M', '𐑊'),\n    (0x10423, 'M', '𐑋'),\n    (0x10424, 'M', '𐑌'),\n    (0x10425, 'M', '𐑍'),\n    (0x10426, 'M', '𐑎'),\n    (0x10427, 'M', '𐑏'),\n    (0x10428, 'V'),\n    (0x1049E, 'X'),\n    (0x104A0, 'V'),\n    (0x104AA, 'X'),\n    (0x10800, 'V'),\n    (0x10806, 'X'),\n    (0x10808, 'V'),\n    (0x10809, 'X'),\n    (0x1080A, 'V'),\n    (0x10836, 'X'),\n    (0x10837, 'V'),\n    (0x10839, 'X'),\n    (0x1083C, 'V'),\n    (0x1083D, 'X'),\n    (0x1083F, 'V'),\n    (0x10856, 'X'),\n    (0x10857, 'V'),\n    (0x10860, 'X'),\n    (0x10900, 'V'),\n    (0x1091C, 'X'),\n    (0x1091F, 'V'),\n    (0x1093A, 'X'),\n    (0x1093F, 'V'),\n    (0x10940, 'X'),\n    (0x10980, 'V'),\n    (0x109B8, 'X'),\n    (0x109BE, 'V'),\n    (0x109C0, 'X'),\n    (0x10A00, 'V'),\n    (0x10A04, 'X'),\n    (0x10A05, 'V'),\n    (0x10A07, 'X'),\n    (0x10A0C, 'V'),\n    (0x10A14, 'X'),\n    (0x10A15, 'V'),\n    (0x10A18, 'X'),\n    (0x10A19, 'V'),\n    (0x10A34, 'X'),\n    (0x10A38, 'V'),\n    (0x10A3B, 'X'),\n    (0x10A3F, 'V'),\n    (0x10A48, 'X'),\n    (0x10A50, 'V'),\n    (0x10A59, 'X'),\n    (0x10A60, 'V'),\n    (0x10A80, 'X'),\n    (0x10B00, 'V'),\n    (0x10B36, 'X'),\n    (0x10B39, 'V'),\n    (0x10B56, 'X'),\n    (0x10B58, 'V'),\n    (0x10B73, 'X'),\n    (0x10B78, 'V'),\n    (0x10B80, 'X'),\n    (0x10C00, 'V'),\n    (0x10C49, 'X'),\n    (0x10E60, 'V'),\n    (0x10E7F, 'X'),\n    (0x11000, 'V'),\n    (0x1104E, 'X'),\n    (0x11052, 'V'),\n    (0x11070, 'X'),\n    (0x11080, 'V'),\n    (0x110BD, 'X'),\n    (0x110BE, 'V'),\n    (0x110C2, 'X'),\n    (0x110D0, 'V'),\n    (0x110E9, 'X'),\n    (0x110F0, 'V'),\n    (0x110FA, 'X'),\n    (0x11100, 'V'),\n    (0x11135, 'X'),\n    (0x11136, 'V'),\n    (0x11144, 'X'),\n    (0x11180, 'V'),\n    (0x111C9, 'X'),\n    (0x111D0, 'V'),\n    (0x111DA, 'X'),\n    (0x11680, 'V'),\n    (0x116B8, 'X'),\n    (0x116C0, 'V'),\n    (0x116CA, 'X'),\n    (0x12000, 'V'),\n    (0x1236F, 'X'),\n    (0x12400, 'V'),\n    (0x12463, 'X'),\n    (0x12470, 'V'),\n    (0x12474, 'X'),\n    (0x13000, 'V'),\n    (0x1342F, 'X'),\n    (0x16800, 'V'),\n    (0x16A39, 'X'),\n    (0x16F00, 'V'),\n    (0x16F45, 'X'),\n    (0x16F50, 'V'),\n    (0x16F7F, 'X'),\n    (0x16F8F, 'V'),\n    (0x16FA0, 'X'),\n    (0x1B000, 'V'),\n    (0x1B002, 'X'),\n    (0x1D000, 'V'),\n    (0x1D0F6, 'X'),\n    (0x1D100, 'V'),\n    (0x1D127, 'X'),\n    (0x1D129, 'V'),\n    (0x1D15E, 'M', '𝅗𝅥'),\n    (0x1D15F, 'M', '𝅘𝅥'),\n    (0x1D160, 'M', '𝅘𝅥𝅮'),\n    (0x1D161, 'M', '𝅘𝅥𝅯'),\n    (0x1D162, 'M', '𝅘𝅥𝅰'),\n    (0x1D163, 'M', '𝅘𝅥𝅱'),\n    (0x1D164, 'M', '𝅘𝅥𝅲'),\n    (0x1D165, 'V'),\n    (0x1D173, 'X'),\n    (0x1D17B, 'V'),\n    (0x1D1BB, 'M', '𝆹𝅥'),\n    (0x1D1BC, 'M', '𝆺𝅥'),\n    (0x1D1BD, 'M', '𝆹𝅥𝅮'),\n    (0x1D1BE, 'M', '𝆺𝅥𝅮'),\n    (0x1D1BF, 'M', '𝆹𝅥𝅯'),\n    (0x1D1C0, 'M', '𝆺𝅥𝅯'),\n    (0x1D1C1, 'V'),\n    (0x1D1DE, 'X'),\n    (0x1D200, 'V'),\n    (0x1D246, 'X'),\n    (0x1D300, 'V'),\n    (0x1D357, 'X'),\n    (0x1D360, 'V'),\n    (0x1D372, 'X'),\n    (0x1D400, 'M', 'a'),\n    (0x1D401, 'M', 'b'),\n    (0x1D402, 'M', 'c'),\n    (0x1D403, 'M', 'd'),\n    (0x1D404, 'M', 'e'),\n    (0x1D405, 'M', 'f'),\n    (0x1D406, 'M', 'g'),\n    (0x1D407, 'M', 'h'),\n    (0x1D408, 'M', 'i'),\n    (0x1D409, 'M', 'j'),\n    (0x1D40A, 'M', 'k'),\n    (0x1D40B, 'M', 'l'),\n    (0x1D40C, 'M', 'm'),\n    (0x1D40D, 'M', 'n'),\n    (0x1D40E, 'M', 'o'),\n    (0x1D40F, 'M', 'p'),\n    (0x1D410, 'M', 'q'),\n    (0x1D411, 'M', 'r'),\n    (0x1D412, 'M', 's'),\n    (0x1D413, 'M', 't'),\n    (0x1D414, 'M', 'u'),\n    (0x1D415, 'M', 'v'),\n    (0x1D416, 'M', 'w'),\n    (0x1D417, 'M', 'x'),\n    (0x1D418, 'M', 'y'),\n    (0x1D419, 'M', 'z'),\n    (0x1D41A, 'M', 'a'),\n    (0x1D41B, 'M', 'b'),\n    (0x1D41C, 'M', 'c'),\n    (0x1D41D, 'M', 'd'),\n    (0x1D41E, 'M', 'e'),\n    (0x1D41F, 'M', 'f'),\n    (0x1D420, 'M', 'g'),\n    (0x1D421, 'M', 'h'),\n    (0x1D422, 'M', 'i'),\n    (0x1D423, 'M', 'j'),\n    (0x1D424, 'M', 'k'),\n    (0x1D425, 'M', 'l'),\n    (0x1D426, 'M', 'm'),\n    (0x1D427, 'M', 'n'),\n    (0x1D428, 'M', 'o'),\n    (0x1D429, 'M', 'p'),\n    (0x1D42A, 'M', 'q'),\n    (0x1D42B, 'M', 'r'),\n    (0x1D42C, 'M', 's'),\n    (0x1D42D, 'M', 't'),\n    (0x1D42E, 'M', 'u'),\n    (0x1D42F, 'M', 'v'),\n    (0x1D430, 'M', 'w'),\n    (0x1D431, 'M', 'x'),\n    (0x1D432, 'M', 'y'),\n    (0x1D433, 'M', 'z'),\n    (0x1D434, 'M', 'a'),\n    (0x1D435, 'M', 'b'),\n    (0x1D436, 'M', 'c'),\n    (0x1D437, 'M', 'd'),\n    (0x1D438, 'M', 'e'),\n    (0x1D439, 'M', 'f'),\n    (0x1D43A, 'M', 'g'),\n    (0x1D43B, 'M', 'h'),\n    (0x1D43C, 'M', 'i'),\n    (0x1D43D, 'M', 'j'),\n    (0x1D43E, 'M', 'k'),\n    (0x1D43F, 'M', 'l'),\n    (0x1D440, 'M', 'm'),\n    (0x1D441, 'M', 'n'),\n    (0x1D442, 'M', 'o'),\n    (0x1D443, 'M', 'p'),\n    (0x1D444, 'M', 'q'),\n    (0x1D445, 'M', 'r'),\n    (0x1D446, 'M', 's'),\n    (0x1D447, 'M', 't'),\n    (0x1D448, 'M', 'u'),\n    (0x1D449, 'M', 'v'),\n    (0x1D44A, 'M', 'w'),\n    (0x1D44B, 'M', 'x'),\n    (0x1D44C, 'M', 'y'),\n    (0x1D44D, 'M', 'z'),\n    (0x1D44E, 'M', 'a'),\n    (0x1D44F, 'M', 'b'),\n    (0x1D450, 'M', 'c'),\n    (0x1D451, 'M', 'd'),\n    (0x1D452, 'M', 'e'),\n    (0x1D453, 'M', 'f'),\n    (0x1D454, 'M', 'g'),\n    (0x1D455, 'X'),\n    (0x1D456, 'M', 'i'),\n    (0x1D457, 'M', 'j'),\n    (0x1D458, 'M', 'k'),\n    (0x1D459, 'M', 'l'),\n    (0x1D45A, 'M', 'm'),\n    (0x1D45B, 'M', 'n'),\n    (0x1D45C, 'M', 'o'),\n    (0x1D45D, 'M', 'p'),\n    (0x1D45E, 'M', 'q'),\n    (0x1D45F, 'M', 'r'),\n    (0x1D460, 'M', 's'),\n    (0x1D461, 'M', 't'),\n    (0x1D462, 'M', 'u'),\n    (0x1D463, 'M', 'v'),\n    (0x1D464, 'M', 'w'),\n    (0x1D465, 'M', 'x'),\n    (0x1D466, 'M', 'y'),\n    (0x1D467, 'M', 'z'),\n    (0x1D468, 'M', 'a'),\n    (0x1D469, 'M', 'b'),\n    (0x1D46A, 'M', 'c'),\n    (0x1D46B, 'M', 'd'),\n    (0x1D46C, 'M', 'e'),\n    (0x1D46D, 'M', 'f'),\n    (0x1D46E, 'M', 'g'),\n    (0x1D46F, 'M', 'h'),\n    (0x1D470, 'M', 'i'),\n    (0x1D471, 'M', 'j'),\n    (0x1D472, 'M', 'k'),\n    (0x1D473, 'M', 'l'),\n    (0x1D474, 'M', 'm'),\n    (0x1D475, 'M', 'n'),\n    (0x1D476, 'M', 'o'),\n    (0x1D477, 'M', 'p'),\n    (0x1D478, 'M', 'q'),\n    (0x1D479, 'M', 'r'),\n    (0x1D47A, 'M', 's'),\n    (0x1D47B, 'M', 't'),\n    (0x1D47C, 'M', 'u'),\n    (0x1D47D, 'M', 'v'),\n    (0x1D47E, 'M', 'w'),\n    (0x1D47F, 'M', 'x'),\n    (0x1D480, 'M', 'y'),\n    (0x1D481, 'M', 'z'),\n    (0x1D482, 'M', 'a'),\n    (0x1D483, 'M', 'b'),\n    (0x1D484, 'M', 'c'),\n    (0x1D485, 'M', 'd'),\n    (0x1D486, 'M', 'e'),\n    (0x1D487, 'M', 'f'),\n    (0x1D488, 'M', 'g'),\n    (0x1D489, 'M', 'h'),\n    (0x1D48A, 'M', 'i'),\n    (0x1D48B, 'M', 'j'),\n    (0x1D48C, 'M', 'k'),\n    (0x1D48D, 'M', 'l'),\n    (0x1D48E, 'M', 'm'),\n    (0x1D48F, 'M', 'n'),\n    (0x1D490, 'M', 'o'),\n    (0x1D491, 'M', 'p'),\n    (0x1D492, 'M', 'q'),\n    (0x1D493, 'M', 'r'),\n    (0x1D494, 'M', 's'),\n    (0x1D495, 'M', 't'),\n    (0x1D496, 'M', 'u'),\n    (0x1D497, 'M', 'v'),\n    (0x1D498, 'M', 'w'),\n    (0x1D499, 'M', 'x'),\n    (0x1D49A, 'M', 'y'),\n    (0x1D49B, 'M', 'z'),\n    (0x1D49C, 'M', 'a'),\n    (0x1D49D, 'X'),\n    (0x1D49E, 'M', 'c'),\n    (0x1D49F, 'M', 'd'),\n    (0x1D4A0, 'X'),\n    (0x1D4A2, 'M', 'g'),\n    (0x1D4A3, 'X'),\n    (0x1D4A5, 'M', 'j'),\n    (0x1D4A6, 'M', 'k'),\n    (0x1D4A7, 'X'),\n    (0x1D4A9, 'M', 'n'),\n    (0x1D4AA, 'M', 'o'),\n    (0x1D4AB, 'M', 'p'),\n    (0x1D4AC, 'M', 'q'),\n    (0x1D4AD, 'X'),\n    (0x1D4AE, 'M', 's'),\n    (0x1D4AF, 'M', 't'),\n    (0x1D4B0, 'M', 'u'),\n    (0x1D4B1, 'M', 'v'),\n    (0x1D4B2, 'M', 'w'),\n    (0x1D4B3, 'M', 'x'),\n    (0x1D4B4, 'M', 'y'),\n    (0x1D4B5, 'M', 'z'),\n    (0x1D4B6, 'M', 'a'),\n    (0x1D4B7, 'M', 'b'),\n    (0x1D4B8, 'M', 'c'),\n    (0x1D4B9, 'M', 'd'),\n    (0x1D4BA, 'X'),\n    (0x1D4BB, 'M', 'f'),\n    (0x1D4BC, 'X'),\n    (0x1D4BD, 'M', 'h'),\n    (0x1D4BE, 'M', 'i'),\n    (0x1D4BF, 'M', 'j'),\n    (0x1D4C0, 'M', 'k'),\n    (0x1D4C1, 'M', 'l'),\n    (0x1D4C2, 'M', 'm'),\n    (0x1D4C3, 'M', 'n'),\n    (0x1D4C4, 'X'),\n    (0x1D4C5, 'M', 'p'),\n    (0x1D4C6, 'M', 'q'),\n    (0x1D4C7, 'M', 'r'),\n    (0x1D4C8, 'M', 's'),\n    (0x1D4C9, 'M', 't'),\n    (0x1D4CA, 'M', 'u'),\n    (0x1D4CB, 'M', 'v'),\n    (0x1D4CC, 'M', 'w'),\n    (0x1D4CD, 'M', 'x'),\n    (0x1D4CE, 'M', 'y'),\n    (0x1D4CF, 'M', 'z'),\n    (0x1D4D0, 'M', 'a'),\n    (0x1D4D1, 'M', 'b'),\n    (0x1D4D2, 'M', 'c'),\n    (0x1D4D3, 'M', 'd'),\n    (0x1D4D4, 'M', 'e'),\n    (0x1D4D5, 'M', 'f'),\n    (0x1D4D6, 'M', 'g'),\n    (0x1D4D7, 'M', 'h'),\n    (0x1D4D8, 'M', 'i'),\n    (0x1D4D9, 'M', 'j'),\n    (0x1D4DA, 'M', 'k'),\n    (0x1D4DB, 'M', 'l'),\n    (0x1D4DC, 'M', 'm'),\n    (0x1D4DD, 'M', 'n'),\n    (0x1D4DE, 'M', 'o'),\n    (0x1D4DF, 'M', 'p'),\n    (0x1D4E0, 'M', 'q'),\n    (0x1D4E1, 'M', 'r'),\n    (0x1D4E2, 'M', 's'),\n    (0x1D4E3, 'M', 't'),\n    (0x1D4E4, 'M', 'u'),\n    (0x1D4E5, 'M', 'v'),\n    (0x1D4E6, 'M', 'w'),\n    (0x1D4E7, 'M', 'x'),\n    (0x1D4E8, 'M', 'y'),\n    (0x1D4E9, 'M', 'z'),\n    (0x1D4EA, 'M', 'a'),\n    (0x1D4EB, 'M', 'b'),\n    (0x1D4EC, 'M', 'c'),\n    (0x1D4ED, 'M', 'd'),\n    (0x1D4EE, 'M', 'e'),\n    (0x1D4EF, 'M', 'f'),\n    (0x1D4F0, 'M', 'g'),\n    (0x1D4F1, 'M', 'h'),\n    (0x1D4F2, 'M', 'i'),\n    (0x1D4F3, 'M', 'j'),\n    (0x1D4F4, 'M', 'k'),\n    (0x1D4F5, 'M', 'l'),\n    (0x1D4F6, 'M', 'm'),\n    (0x1D4F7, 'M', 'n'),\n    (0x1D4F8, 'M', 'o'),\n    (0x1D4F9, 'M', 'p'),\n    (0x1D4FA, 'M', 'q'),\n    (0x1D4FB, 'M', 'r'),\n    (0x1D4FC, 'M', 's'),\n    (0x1D4FD, 'M', 't'),\n    (0x1D4FE, 'M', 'u'),\n    (0x1D4FF, 'M', 'v'),\n    (0x1D500, 'M', 'w'),\n    (0x1D501, 'M', 'x'),\n    (0x1D502, 'M', 'y'),\n    (0x1D503, 'M', 'z'),\n    (0x1D504, 'M', 'a'),\n    (0x1D505, 'M', 'b'),\n    (0x1D506, 'X'),\n    (0x1D507, 'M', 'd'),\n    (0x1D508, 'M', 'e'),\n    (0x1D509, 'M', 'f'),\n    (0x1D50A, 'M', 'g'),\n    (0x1D50B, 'X'),\n    (0x1D50D, 'M', 'j'),\n    (0x1D50E, 'M', 'k'),\n    (0x1D50F, 'M', 'l'),\n    (0x1D510, 'M', 'm'),\n    (0x1D511, 'M', 'n'),\n    (0x1D512, 'M', 'o'),\n    (0x1D513, 'M', 'p'),\n    (0x1D514, 'M', 'q'),\n    (0x1D515, 'X'),\n    (0x1D516, 'M', 's'),\n    (0x1D517, 'M', 't'),\n    (0x1D518, 'M', 'u'),\n    (0x1D519, 'M', 'v'),\n    (0x1D51A, 'M', 'w'),\n    (0x1D51B, 'M', 'x'),\n    (0x1D51C, 'M', 'y'),\n    (0x1D51D, 'X'),\n    (0x1D51E, 'M', 'a'),\n    (0x1D51F, 'M', 'b'),\n    (0x1D520, 'M', 'c'),\n    (0x1D521, 'M', 'd'),\n    (0x1D522, 'M', 'e'),\n    (0x1D523, 'M', 'f'),\n    (0x1D524, 'M', 'g'),\n    (0x1D525, 'M', 'h'),\n    (0x1D526, 'M', 'i'),\n    (0x1D527, 'M', 'j'),\n    (0x1D528, 'M', 'k'),\n    (0x1D529, 'M', 'l'),\n    (0x1D52A, 'M', 'm'),\n    (0x1D52B, 'M', 'n'),\n    (0x1D52C, 'M', 'o'),\n    (0x1D52D, 'M', 'p'),\n    (0x1D52E, 'M', 'q'),\n    (0x1D52F, 'M', 'r'),\n    (0x1D530, 'M', 's'),\n    (0x1D531, 'M', 't'),\n    (0x1D532, 'M', 'u'),\n    (0x1D533, 'M', 'v'),\n    (0x1D534, 'M', 'w'),\n    (0x1D535, 'M', 'x'),\n    (0x1D536, 'M', 'y'),\n    (0x1D537, 'M', 'z'),\n    (0x1D538, 'M', 'a'),\n    (0x1D539, 'M', 'b'),\n    (0x1D53A, 'X'),\n    (0x1D53B, 'M', 'd'),\n    (0x1D53C, 'M', 'e'),\n    (0x1D53D, 'M', 'f'),\n    (0x1D53E, 'M', 'g'),\n    (0x1D53F, 'X'),\n    (0x1D540, 'M', 'i'),\n    (0x1D541, 'M', 'j'),\n    (0x1D542, 'M', 'k'),\n    (0x1D543, 'M', 'l'),\n    (0x1D544, 'M', 'm'),\n    (0x1D545, 'X'),\n    (0x1D546, 'M', 'o'),\n    (0x1D547, 'X'),\n    (0x1D54A, 'M', 's'),\n    (0x1D54B, 'M', 't'),\n    (0x1D54C, 'M', 'u'),\n    (0x1D54D, 'M', 'v'),\n    (0x1D54E, 'M', 'w'),\n    (0x1D54F, 'M', 'x'),\n    (0x1D550, 'M', 'y'),\n    (0x1D551, 'X'),\n    (0x1D552, 'M', 'a'),\n    (0x1D553, 'M', 'b'),\n    (0x1D554, 'M', 'c'),\n    (0x1D555, 'M', 'd'),\n    (0x1D556, 'M', 'e'),\n    (0x1D557, 'M', 'f'),\n    (0x1D558, 'M', 'g'),\n    (0x1D559, 'M', 'h'),\n    (0x1D55A, 'M', 'i'),\n    (0x1D55B, 'M', 'j'),\n    (0x1D55C, 'M', 'k'),\n    (0x1D55D, 'M', 'l'),\n    (0x1D55E, 'M', 'm'),\n    (0x1D55F, 'M', 'n'),\n    (0x1D560, 'M', 'o'),\n    (0x1D561, 'M', 'p'),\n    (0x1D562, 'M', 'q'),\n    (0x1D563, 'M', 'r'),\n    (0x1D564, 'M', 's'),\n    (0x1D565, 'M', 't'),\n    (0x1D566, 'M', 'u'),\n    (0x1D567, 'M', 'v'),\n    (0x1D568, 'M', 'w'),\n    (0x1D569, 'M', 'x'),\n    (0x1D56A, 'M', 'y'),\n    (0x1D56B, 'M', 'z'),\n    (0x1D56C, 'M', 'a'),\n    (0x1D56D, 'M', 'b'),\n    (0x1D56E, 'M', 'c'),\n    (0x1D56F, 'M', 'd'),\n    (0x1D570, 'M', 'e'),\n    (0x1D571, 'M', 'f'),\n    (0x1D572, 'M', 'g'),\n    (0x1D573, 'M', 'h'),\n    (0x1D574, 'M', 'i'),\n    (0x1D575, 'M', 'j'),\n    (0x1D576, 'M', 'k'),\n    (0x1D577, 'M', 'l'),\n    (0x1D578, 'M', 'm'),\n    (0x1D579, 'M', 'n'),\n    (0x1D57A, 'M', 'o'),\n    (0x1D57B, 'M', 'p'),\n    (0x1D57C, 'M', 'q'),\n    (0x1D57D, 'M', 'r'),\n    (0x1D57E, 'M', 's'),\n    (0x1D57F, 'M', 't'),\n    (0x1D580, 'M', 'u'),\n    (0x1D581, 'M', 'v'),\n    (0x1D582, 'M', 'w'),\n    (0x1D583, 'M', 'x'),\n    (0x1D584, 'M', 'y'),\n    (0x1D585, 'M', 'z'),\n    (0x1D586, 'M', 'a'),\n    (0x1D587, 'M', 'b'),\n    (0x1D588, 'M', 'c'),\n    (0x1D589, 'M', 'd'),\n    (0x1D58A, 'M', 'e'),\n    (0x1D58B, 'M', 'f'),\n    (0x1D58C, 'M', 'g'),\n    (0x1D58D, 'M', 'h'),\n    (0x1D58E, 'M', 'i'),\n    (0x1D58F, 'M', 'j'),\n    (0x1D590, 'M', 'k'),\n    (0x1D591, 'M', 'l'),\n    (0x1D592, 'M', 'm'),\n    (0x1D593, 'M', 'n'),\n    (0x1D594, 'M', 'o'),\n    (0x1D595, 'M', 'p'),\n    (0x1D596, 'M', 'q'),\n    (0x1D597, 'M', 'r'),\n    (0x1D598, 'M', 's'),\n    (0x1D599, 'M', 't'),\n    (0x1D59A, 'M', 'u'),\n    (0x1D59B, 'M', 'v'),\n    (0x1D59C, 'M', 'w'),\n    (0x1D59D, 'M', 'x'),\n    (0x1D59E, 'M', 'y'),\n    (0x1D59F, 'M', 'z'),\n    (0x1D5A0, 'M', 'a'),\n    (0x1D5A1, 'M', 'b'),\n    (0x1D5A2, 'M', 'c'),\n    (0x1D5A3, 'M', 'd'),\n    (0x1D5A4, 'M', 'e'),\n    (0x1D5A5, 'M', 'f'),\n    (0x1D5A6, 'M', 'g'),\n    (0x1D5A7, 'M', 'h'),\n    (0x1D5A8, 'M', 'i'),\n    (0x1D5A9, 'M', 'j'),\n    (0x1D5AA, 'M', 'k'),\n    (0x1D5AB, 'M', 'l'),\n    (0x1D5AC, 'M', 'm'),\n    (0x1D5AD, 'M', 'n'),\n    (0x1D5AE, 'M', 'o'),\n    (0x1D5AF, 'M', 'p'),\n    (0x1D5B0, 'M', 'q'),\n    (0x1D5B1, 'M', 'r'),\n    (0x1D5B2, 'M', 's'),\n    (0x1D5B3, 'M', 't'),\n    (0x1D5B4, 'M', 'u'),\n    (0x1D5B5, 'M', 'v'),\n    (0x1D5B6, 'M', 'w'),\n    (0x1D5B7, 'M', 'x'),\n    (0x1D5B8, 'M', 'y'),\n    (0x1D5B9, 'M', 'z'),\n    (0x1D5BA, 'M', 'a'),\n    (0x1D5BB, 'M', 'b'),\n    (0x1D5BC, 'M', 'c'),\n    (0x1D5BD, 'M', 'd'),\n    (0x1D5BE, 'M', 'e'),\n    (0x1D5BF, 'M', 'f'),\n    (0x1D5C0, 'M', 'g'),\n    (0x1D5C1, 'M', 'h'),\n    (0x1D5C2, 'M', 'i'),\n    (0x1D5C3, 'M', 'j'),\n    (0x1D5C4, 'M', 'k'),\n    (0x1D5C5, 'M', 'l'),\n    (0x1D5C6, 'M', 'm'),\n    (0x1D5C7, 'M', 'n'),\n    (0x1D5C8, 'M', 'o'),\n    (0x1D5C9, 'M', 'p'),\n    (0x1D5CA, 'M', 'q'),\n    (0x1D5CB, 'M', 'r'),\n    (0x1D5CC, 'M', 's'),\n    (0x1D5CD, 'M', 't'),\n    (0x1D5CE, 'M', 'u'),\n    (0x1D5CF, 'M', 'v'),\n    (0x1D5D0, 'M', 'w'),\n    (0x1D5D1, 'M', 'x'),\n    (0x1D5D2, 'M', 'y'),\n    (0x1D5D3, 'M', 'z'),\n    (0x1D5D4, 'M', 'a'),\n    (0x1D5D5, 'M', 'b'),\n    (0x1D5D6, 'M', 'c'),\n    (0x1D5D7, 'M', 'd'),\n    (0x1D5D8, 'M', 'e'),\n    (0x1D5D9, 'M', 'f'),\n    (0x1D5DA, 'M', 'g'),\n    (0x1D5DB, 'M', 'h'),\n    (0x1D5DC, 'M', 'i'),\n    (0x1D5DD, 'M', 'j'),\n    (0x1D5DE, 'M', 'k'),\n    (0x1D5DF, 'M', 'l'),\n    (0x1D5E0, 'M', 'm'),\n    (0x1D5E1, 'M', 'n'),\n    (0x1D5E2, 'M', 'o'),\n    (0x1D5E3, 'M', 'p'),\n    (0x1D5E4, 'M', 'q'),\n    (0x1D5E5, 'M', 'r'),\n    (0x1D5E6, 'M', 's'),\n    (0x1D5E7, 'M', 't'),\n    (0x1D5E8, 'M', 'u'),\n    (0x1D5E9, 'M', 'v'),\n    (0x1D5EA, 'M', 'w'),\n    (0x1D5EB, 'M', 'x'),\n    (0x1D5EC, 'M', 'y'),\n    (0x1D5ED, 'M', 'z'),\n    (0x1D5EE, 'M', 'a'),\n    (0x1D5EF, 'M', 'b'),\n    (0x1D5F0, 'M', 'c'),\n    (0x1D5F1, 'M', 'd'),\n    (0x1D5F2, 'M', 'e'),\n    (0x1D5F3, 'M', 'f'),\n    (0x1D5F4, 'M', 'g'),\n    (0x1D5F5, 'M', 'h'),\n    (0x1D5F6, 'M', 'i'),\n    (0x1D5F7, 'M', 'j'),\n    (0x1D5F8, 'M', 'k'),\n    (0x1D5F9, 'M', 'l'),\n    (0x1D5FA, 'M', 'm'),\n    (0x1D5FB, 'M', 'n'),\n    (0x1D5FC, 'M', 'o'),\n    (0x1D5FD, 'M', 'p'),\n    (0x1D5FE, 'M', 'q'),\n    (0x1D5FF, 'M', 'r'),\n    (0x1D600, 'M', 's'),\n    (0x1D601, 'M', 't'),\n    (0x1D602, 'M', 'u'),\n    (0x1D603, 'M', 'v'),\n    (0x1D604, 'M', 'w'),\n    (0x1D605, 'M', 'x'),\n    (0x1D606, 'M', 'y'),\n    (0x1D607, 'M', 'z'),\n    (0x1D608, 'M', 'a'),\n    (0x1D609, 'M', 'b'),\n    (0x1D60A, 'M', 'c'),\n    (0x1D60B, 'M', 'd'),\n    (0x1D60C, 'M', 'e'),\n    (0x1D60D, 'M', 'f'),\n    (0x1D60E, 'M', 'g'),\n    (0x1D60F, 'M', 'h'),\n    (0x1D610, 'M', 'i'),\n    (0x1D611, 'M', 'j'),\n    (0x1D612, 'M', 'k'),\n    (0x1D613, 'M', 'l'),\n    (0x1D614, 'M', 'm'),\n    (0x1D615, 'M', 'n'),\n    (0x1D616, 'M', 'o'),\n    (0x1D617, 'M', 'p'),\n    (0x1D618, 'M', 'q'),\n    (0x1D619, 'M', 'r'),\n    (0x1D61A, 'M', 's'),\n    (0x1D61B, 'M', 't'),\n    (0x1D61C, 'M', 'u'),\n    (0x1D61D, 'M', 'v'),\n    (0x1D61E, 'M', 'w'),\n    (0x1D61F, 'M', 'x'),\n    (0x1D620, 'M', 'y'),\n    (0x1D621, 'M', 'z'),\n    (0x1D622, 'M', 'a'),\n    (0x1D623, 'M', 'b'),\n    (0x1D624, 'M', 'c'),\n    (0x1D625, 'M', 'd'),\n    (0x1D626, 'M', 'e'),\n    (0x1D627, 'M', 'f'),\n    (0x1D628, 'M', 'g'),\n    (0x1D629, 'M', 'h'),\n    (0x1D62A, 'M', 'i'),\n    (0x1D62B, 'M', 'j'),\n    (0x1D62C, 'M', 'k'),\n    (0x1D62D, 'M', 'l'),\n    (0x1D62E, 'M', 'm'),\n    (0x1D62F, 'M', 'n'),\n    (0x1D630, 'M', 'o'),\n    (0x1D631, 'M', 'p'),\n    (0x1D632, 'M', 'q'),\n    (0x1D633, 'M', 'r'),\n    (0x1D634, 'M', 's'),\n    (0x1D635, 'M', 't'),\n    (0x1D636, 'M', 'u'),\n    (0x1D637, 'M', 'v'),\n    (0x1D638, 'M', 'w'),\n    (0x1D639, 'M', 'x'),\n    (0x1D63A, 'M', 'y'),\n    (0x1D63B, 'M', 'z'),\n    (0x1D63C, 'M', 'a'),\n    (0x1D63D, 'M', 'b'),\n    (0x1D63E, 'M', 'c'),\n    (0x1D63F, 'M', 'd'),\n    (0x1D640, 'M', 'e'),\n    (0x1D641, 'M', 'f'),\n    (0x1D642, 'M', 'g'),\n    (0x1D643, 'M', 'h'),\n    (0x1D644, 'M', 'i'),\n    (0x1D645, 'M', 'j'),\n    (0x1D646, 'M', 'k'),\n    (0x1D647, 'M', 'l'),\n    (0x1D648, 'M', 'm'),\n    (0x1D649, 'M', 'n'),\n    (0x1D64A, 'M', 'o'),\n    (0x1D64B, 'M', 'p'),\n    (0x1D64C, 'M', 'q'),\n    (0x1D64D, 'M', 'r'),\n    (0x1D64E, 'M', 's'),\n    (0x1D64F, 'M', 't'),\n    (0x1D650, 'M', 'u'),\n    (0x1D651, 'M', 'v'),\n    (0x1D652, 'M', 'w'),\n    (0x1D653, 'M', 'x'),\n    (0x1D654, 'M', 'y'),\n    (0x1D655, 'M', 'z'),\n    (0x1D656, 'M', 'a'),\n    (0x1D657, 'M', 'b'),\n    (0x1D658, 'M', 'c'),\n    (0x1D659, 'M', 'd'),\n    (0x1D65A, 'M', 'e'),\n    (0x1D65B, 'M', 'f'),\n    (0x1D65C, 'M', 'g'),\n    (0x1D65D, 'M', 'h'),\n    (0x1D65E, 'M', 'i'),\n    (0x1D65F, 'M', 'j'),\n    (0x1D660, 'M', 'k'),\n    (0x1D661, 'M', 'l'),\n    (0x1D662, 'M', 'm'),\n    (0x1D663, 'M', 'n'),\n    (0x1D664, 'M', 'o'),\n    (0x1D665, 'M', 'p'),\n    (0x1D666, 'M', 'q'),\n    (0x1D667, 'M', 'r'),\n    (0x1D668, 'M', 's'),\n    (0x1D669, 'M', 't'),\n    (0x1D66A, 'M', 'u'),\n    (0x1D66B, 'M', 'v'),\n    (0x1D66C, 'M', 'w'),\n    (0x1D66D, 'M', 'x'),\n    (0x1D66E, 'M', 'y'),\n    (0x1D66F, 'M', 'z'),\n    (0x1D670, 'M', 'a'),\n    (0x1D671, 'M', 'b'),\n    (0x1D672, 'M', 'c'),\n    (0x1D673, 'M', 'd'),\n    (0x1D674, 'M', 'e'),\n    (0x1D675, 'M', 'f'),\n    (0x1D676, 'M', 'g'),\n    (0x1D677, 'M', 'h'),\n    (0x1D678, 'M', 'i'),\n    (0x1D679, 'M', 'j'),\n    (0x1D67A, 'M', 'k'),\n    (0x1D67B, 'M', 'l'),\n    (0x1D67C, 'M', 'm'),\n    (0x1D67D, 'M', 'n'),\n    (0x1D67E, 'M', 'o'),\n    (0x1D67F, 'M', 'p'),\n    (0x1D680, 'M', 'q'),\n    (0x1D681, 'M', 'r'),\n    (0x1D682, 'M', 's'),\n    (0x1D683, 'M', 't'),\n    (0x1D684, 'M', 'u'),\n    (0x1D685, 'M', 'v'),\n    (0x1D686, 'M', 'w'),\n    (0x1D687, 'M', 'x'),\n    (0x1D688, 'M', 'y'),\n    (0x1D689, 'M', 'z'),\n    (0x1D68A, 'M', 'a'),\n    (0x1D68B, 'M', 'b'),\n    (0x1D68C, 'M', 'c'),\n    (0x1D68D, 'M', 'd'),\n    (0x1D68E, 'M', 'e'),\n    (0x1D68F, 'M', 'f'),\n    (0x1D690, 'M', 'g'),\n    (0x1D691, 'M', 'h'),\n    (0x1D692, 'M', 'i'),\n    (0x1D693, 'M', 'j'),\n    (0x1D694, 'M', 'k'),\n    (0x1D695, 'M', 'l'),\n    (0x1D696, 'M', 'm'),\n    (0x1D697, 'M', 'n'),\n    (0x1D698, 'M', 'o'),\n    (0x1D699, 'M', 'p'),\n    (0x1D69A, 'M', 'q'),\n    (0x1D69B, 'M', 'r'),\n    (0x1D69C, 'M', 's'),\n    (0x1D69D, 'M', 't'),\n    (0x1D69E, 'M', 'u'),\n    (0x1D69F, 'M', 'v'),\n    (0x1D6A0, 'M', 'w'),\n    (0x1D6A1, 'M', 'x'),\n    (0x1D6A2, 'M', 'y'),\n    (0x1D6A3, 'M', 'z'),\n    (0x1D6A4, 'M', 'ı'),\n    (0x1D6A5, 'M', 'ȷ'),\n    (0x1D6A6, 'X'),\n    (0x1D6A8, 'M', 'α'),\n    (0x1D6A9, 'M', 'β'),\n    (0x1D6AA, 'M', 'γ'),\n    (0x1D6AB, 'M', 'δ'),\n    (0x1D6AC, 'M', 'ε'),\n    (0x1D6AD, 'M', 'ζ'),\n    (0x1D6AE, 'M', 'η'),\n    (0x1D6AF, 'M', 'θ'),\n    (0x1D6B0, 'M', 'ι'),\n    (0x1D6B1, 'M', 'κ'),\n    (0x1D6B2, 'M', 'λ'),\n    (0x1D6B3, 'M', 'μ'),\n    (0x1D6B4, 'M', 'ν'),\n    (0x1D6B5, 'M', 'ξ'),\n    (0x1D6B6, 'M', 'ο'),\n    (0x1D6B7, 'M', 'π'),\n    (0x1D6B8, 'M', 'ρ'),\n    (0x1D6B9, 'M', 'θ'),\n    (0x1D6BA, 'M', 'σ'),\n    (0x1D6BB, 'M', 'τ'),\n    (0x1D6BC, 'M', 'υ'),\n    (0x1D6BD, 'M', 'φ'),\n    (0x1D6BE, 'M', 'χ'),\n    (0x1D6BF, 'M', 'ψ'),\n    (0x1D6C0, 'M', 'ω'),\n    (0x1D6C1, 'M', '∇'),\n    (0x1D6C2, 'M', 'α'),\n    (0x1D6C3, 'M', 'β'),\n    (0x1D6C4, 'M', 'γ'),\n    (0x1D6C5, 'M', 'δ'),\n    (0x1D6C6, 'M', 'ε'),\n    (0x1D6C7, 'M', 'ζ'),\n    (0x1D6C8, 'M', 'η'),\n    (0x1D6C9, 'M', 'θ'),\n    (0x1D6CA, 'M', 'ι'),\n    (0x1D6CB, 'M', 'κ'),\n    (0x1D6CC, 'M', 'λ'),\n    (0x1D6CD, 'M', 'μ'),\n    (0x1D6CE, 'M', 'ν'),\n    (0x1D6CF, 'M', 'ξ'),\n    (0x1D6D0, 'M', 'ο'),\n    (0x1D6D1, 'M', 'π'),\n    (0x1D6D2, 'M', 'ρ'),\n    (0x1D6D3, 'M', 'σ'),\n    (0x1D6D5, 'M', 'τ'),\n    (0x1D6D6, 'M', 'υ'),\n    (0x1D6D7, 'M', 'φ'),\n    (0x1D6D8, 'M', 'χ'),\n    (0x1D6D9, 'M', 'ψ'),\n    (0x1D6DA, 'M', 'ω'),\n    (0x1D6DB, 'M', '∂'),\n    (0x1D6DC, 'M', 'ε'),\n    (0x1D6DD, 'M', 'θ'),\n    (0x1D6DE, 'M', 'κ'),\n    (0x1D6DF, 'M', 'φ'),\n    (0x1D6E0, 'M', 'ρ'),\n    (0x1D6E1, 'M', 'π'),\n    (0x1D6E2, 'M', 'α'),\n    (0x1D6E3, 'M', 'β'),\n    (0x1D6E4, 'M', 'γ'),\n    (0x1D6E5, 'M', 'δ'),\n    (0x1D6E6, 'M', 'ε'),\n    (0x1D6E7, 'M', 'ζ'),\n    (0x1D6E8, 'M', 'η'),\n    (0x1D6E9, 'M', 'θ'),\n    (0x1D6EA, 'M', 'ι'),\n    (0x1D6EB, 'M', 'κ'),\n    (0x1D6EC, 'M', 'λ'),\n    (0x1D6ED, 'M', 'μ'),\n    (0x1D6EE, 'M', 'ν'),\n    (0x1D6EF, 'M', 'ξ'),\n    (0x1D6F0, 'M', 'ο'),\n    (0x1D6F1, 'M', 'π'),\n    (0x1D6F2, 'M', 'ρ'),\n    (0x1D6F3, 'M', 'θ'),\n    (0x1D6F4, 'M', 'σ'),\n    (0x1D6F5, 'M', 'τ'),\n    (0x1D6F6, 'M', 'υ'),\n    (0x1D6F7, 'M', 'φ'),\n    (0x1D6F8, 'M', 'χ'),\n    (0x1D6F9, 'M', 'ψ'),\n    (0x1D6FA, 'M', 'ω'),\n    (0x1D6FB, 'M', '∇'),\n    (0x1D6FC, 'M', 'α'),\n    (0x1D6FD, 'M', 'β'),\n    (0x1D6FE, 'M', 'γ'),\n    (0x1D6FF, 'M', 'δ'),\n    (0x1D700, 'M', 'ε'),\n    (0x1D701, 'M', 'ζ'),\n    (0x1D702, 'M', 'η'),\n    (0x1D703, 'M', 'θ'),\n    (0x1D704, 'M', 'ι'),\n    (0x1D705, 'M', 'κ'),\n    (0x1D706, 'M', 'λ'),\n    (0x1D707, 'M', 'μ'),\n    (0x1D708, 'M', 'ν'),\n    (0x1D709, 'M', 'ξ'),\n    (0x1D70A, 'M', 'ο'),\n    (0x1D70B, 'M', 'π'),\n    (0x1D70C, 'M', 'ρ'),\n    (0x1D70D, 'M', 'σ'),\n    (0x1D70F, 'M', 'τ'),\n    (0x1D710, 'M', 'υ'),\n    (0x1D711, 'M', 'φ'),\n    (0x1D712, 'M', 'χ'),\n    (0x1D713, 'M', 'ψ'),\n    (0x1D714, 'M', 'ω'),\n    (0x1D715, 'M', '∂'),\n    (0x1D716, 'M', 'ε'),\n    (0x1D717, 'M', 'θ'),\n    (0x1D718, 'M', 'κ'),\n    (0x1D719, 'M', 'φ'),\n    (0x1D71A, 'M', 'ρ'),\n    (0x1D71B, 'M', 'π'),\n    (0x1D71C, 'M', 'α'),\n    (0x1D71D, 'M', 'β'),\n    (0x1D71E, 'M', 'γ'),\n    (0x1D71F, 'M', 'δ'),\n    (0x1D720, 'M', 'ε'),\n    (0x1D721, 'M', 'ζ'),\n    (0x1D722, 'M', 'η'),\n    (0x1D723, 'M', 'θ'),\n    (0x1D724, 'M', 'ι'),\n    (0x1D725, 'M', 'κ'),\n    (0x1D726, 'M', 'λ'),\n    (0x1D727, 'M', 'μ'),\n    (0x1D728, 'M', 'ν'),\n    (0x1D729, 'M', 'ξ'),\n    (0x1D72A, 'M', 'ο'),\n    (0x1D72B, 'M', 'π'),\n    (0x1D72C, 'M', 'ρ'),\n    (0x1D72D, 'M', 'θ'),\n    (0x1D72E, 'M', 'σ'),\n    (0x1D72F, 'M', 'τ'),\n    (0x1D730, 'M', 'υ'),\n    (0x1D731, 'M', 'φ'),\n    (0x1D732, 'M', 'χ'),\n    (0x1D733, 'M', 'ψ'),\n    (0x1D734, 'M', 'ω'),\n    (0x1D735, 'M', '∇'),\n    (0x1D736, 'M', 'α'),\n    (0x1D737, 'M', 'β'),\n    (0x1D738, 'M', 'γ'),\n    (0x1D739, 'M', 'δ'),\n    (0x1D73A, 'M', 'ε'),\n    (0x1D73B, 'M', 'ζ'),\n    (0x1D73C, 'M', 'η'),\n    (0x1D73D, 'M', 'θ'),\n    (0x1D73E, 'M', 'ι'),\n    (0x1D73F, 'M', 'κ'),\n    (0x1D740, 'M', 'λ'),\n    (0x1D741, 'M', 'μ'),\n    (0x1D742, 'M', 'ν'),\n    (0x1D743, 'M', 'ξ'),\n    (0x1D744, 'M', 'ο'),\n    (0x1D745, 'M', 'π'),\n    (0x1D746, 'M', 'ρ'),\n    (0x1D747, 'M', 'σ'),\n    (0x1D749, 'M', 'τ'),\n    (0x1D74A, 'M', 'υ'),\n    (0x1D74B, 'M', 'φ'),\n    (0x1D74C, 'M', 'χ'),\n    (0x1D74D, 'M', 'ψ'),\n    (0x1D74E, 'M', 'ω'),\n    (0x1D74F, 'M', '∂'),\n    (0x1D750, 'M', 'ε'),\n    (0x1D751, 'M', 'θ'),\n    (0x1D752, 'M', 'κ'),\n    (0x1D753, 'M', 'φ'),\n    (0x1D754, 'M', 'ρ'),\n    (0x1D755, 'M', 'π'),\n    (0x1D756, 'M', 'α'),\n    (0x1D757, 'M', 'β'),\n    (0x1D758, 'M', 'γ'),\n    (0x1D759, 'M', 'δ'),\n    (0x1D75A, 'M', 'ε'),\n    (0x1D75B, 'M', 'ζ'),\n    (0x1D75C, 'M', 'η'),\n    (0x1D75D, 'M', 'θ'),\n    (0x1D75E, 'M', 'ι'),\n    (0x1D75F, 'M', 'κ'),\n    (0x1D760, 'M', 'λ'),\n    (0x1D761, 'M', 'μ'),\n    (0x1D762, 'M', 'ν'),\n    (0x1D763, 'M', 'ξ'),\n    (0x1D764, 'M', 'ο'),\n    (0x1D765, 'M', 'π'),\n    (0x1D766, 'M', 'ρ'),\n    (0x1D767, 'M', 'θ'),\n    (0x1D768, 'M', 'σ'),\n    (0x1D769, 'M', 'τ'),\n    (0x1D76A, 'M', 'υ'),\n    (0x1D76B, 'M', 'φ'),\n    (0x1D76C, 'M', 'χ'),\n    (0x1D76D, 'M', 'ψ'),\n    (0x1D76E, 'M', 'ω'),\n    (0x1D76F, 'M', '∇'),\n    (0x1D770, 'M', 'α'),\n    (0x1D771, 'M', 'β'),\n    (0x1D772, 'M', 'γ'),\n    (0x1D773, 'M', 'δ'),\n    (0x1D774, 'M', 'ε'),\n    (0x1D775, 'M', 'ζ'),\n    (0x1D776, 'M', 'η'),\n    (0x1D777, 'M', 'θ'),\n    (0x1D778, 'M', 'ι'),\n    (0x1D779, 'M', 'κ'),\n    (0x1D77A, 'M', 'λ'),\n    (0x1D77B, 'M', 'μ'),\n    (0x1D77C, 'M', 'ν'),\n    (0x1D77D, 'M', 'ξ'),\n    (0x1D77E, 'M', 'ο'),\n    (0x1D77F, 'M', 'π'),\n    (0x1D780, 'M', 'ρ'),\n    (0x1D781, 'M', 'σ'),\n    (0x1D783, 'M', 'τ'),\n    (0x1D784, 'M', 'υ'),\n    (0x1D785, 'M', 'φ'),\n    (0x1D786, 'M', 'χ'),\n    (0x1D787, 'M', 'ψ'),\n    (0x1D788, 'M', 'ω'),\n    (0x1D789, 'M', '∂'),\n    (0x1D78A, 'M', 'ε'),\n    (0x1D78B, 'M', 'θ'),\n    (0x1D78C, 'M', 'κ'),\n    (0x1D78D, 'M', 'φ'),\n    (0x1D78E, 'M', 'ρ'),\n    (0x1D78F, 'M', 'π'),\n    (0x1D790, 'M', 'α'),\n    (0x1D791, 'M', 'β'),\n    (0x1D792, 'M', 'γ'),\n    (0x1D793, 'M', 'δ'),\n    (0x1D794, 'M', 'ε'),\n    (0x1D795, 'M', 'ζ'),\n    (0x1D796, 'M', 'η'),\n    (0x1D797, 'M', 'θ'),\n    (0x1D798, 'M', 'ι'),\n    (0x1D799, 'M', 'κ'),\n    (0x1D79A, 'M', 'λ'),\n    (0x1D79B, 'M', 'μ'),\n    (0x1D79C, 'M', 'ν'),\n    (0x1D79D, 'M', 'ξ'),\n    (0x1D79E, 'M', 'ο'),\n    (0x1D79F, 'M', 'π'),\n    (0x1D7A0, 'M', 'ρ'),\n    (0x1D7A1, 'M', 'θ'),\n    (0x1D7A2, 'M', 'σ'),\n    (0x1D7A3, 'M', 'τ'),\n    (0x1D7A4, 'M', 'υ'),\n    (0x1D7A5, 'M', 'φ'),\n    (0x1D7A6, 'M', 'χ'),\n    (0x1D7A7, 'M', 'ψ'),\n    (0x1D7A8, 'M', 'ω'),\n    (0x1D7A9, 'M', '∇'),\n    (0x1D7AA, 'M', 'α'),\n    (0x1D7AB, 'M', 'β'),\n    (0x1D7AC, 'M', 'γ'),\n    (0x1D7AD, 'M', 'δ'),\n    (0x1D7AE, 'M', 'ε'),\n    (0x1D7AF, 'M', 'ζ'),\n    (0x1D7B0, 'M', 'η'),\n    (0x1D7B1, 'M', 'θ'),\n    (0x1D7B2, 'M', 'ι'),\n    (0x1D7B3, 'M', 'κ'),\n    (0x1D7B4, 'M', 'λ'),\n    (0x1D7B5, 'M', 'μ'),\n    (0x1D7B6, 'M', 'ν'),\n    (0x1D7B7, 'M', 'ξ'),\n    (0x1D7B8, 'M', 'ο'),\n    (0x1D7B9, 'M', 'π'),\n    (0x1D7BA, 'M', 'ρ'),\n    (0x1D7BB, 'M', 'σ'),\n    (0x1D7BD, 'M', 'τ'),\n    (0x1D7BE, 'M', 'υ'),\n    (0x1D7BF, 'M', 'φ'),\n    (0x1D7C0, 'M', 'χ'),\n    (0x1D7C1, 'M', 'ψ'),\n    (0x1D7C2, 'M', 'ω'),\n    (0x1D7C3, 'M', '∂'),\n    (0x1D7C4, 'M', 'ε'),\n    (0x1D7C5, 'M', 'θ'),\n    (0x1D7C6, 'M', 'κ'),\n    (0x1D7C7, 'M', 'φ'),\n    (0x1D7C8, 'M', 'ρ'),\n    (0x1D7C9, 'M', 'π'),\n    (0x1D7CA, 'M', 'ϝ'),\n    (0x1D7CC, 'X'),\n    (0x1D7CE, 'M', '0'),\n    (0x1D7CF, 'M', '1'),\n    (0x1D7D0, 'M', '2'),\n    (0x1D7D1, 'M', '3'),\n    (0x1D7D2, 'M', '4'),\n    (0x1D7D3, 'M', '5'),\n    (0x1D7D4, 'M', '6'),\n    (0x1D7D5, 'M', '7'),\n    (0x1D7D6, 'M', '8'),\n    (0x1D7D7, 'M', '9'),\n    (0x1D7D8, 'M', '0'),\n    (0x1D7D9, 'M', '1'),\n    (0x1D7DA, 'M', '2'),\n    (0x1D7DB, 'M', '3'),\n    (0x1D7DC, 'M', '4'),\n    (0x1D7DD, 'M', '5'),\n    (0x1D7DE, 'M', '6'),\n    (0x1D7DF, 'M', '7'),\n    (0x1D7E0, 'M', '8'),\n    (0x1D7E1, 'M', '9'),\n    (0x1D7E2, 'M', '0'),\n    (0x1D7E3, 'M', '1'),\n    (0x1D7E4, 'M', '2'),\n    (0x1D7E5, 'M', '3'),\n    (0x1D7E6, 'M', '4'),\n    (0x1D7E7, 'M', '5'),\n    (0x1D7E8, 'M', '6'),\n    (0x1D7E9, 'M', '7'),\n    (0x1D7EA, 'M', '8'),\n    (0x1D7EB, 'M', '9'),\n    (0x1D7EC, 'M', '0'),\n    (0x1D7ED, 'M', '1'),\n    (0x1D7EE, 'M', '2'),\n    (0x1D7EF, 'M', '3'),\n    (0x1D7F0, 'M', '4'),\n    (0x1D7F1, 'M', '5'),\n    (0x1D7F2, 'M', '6'),\n    (0x1D7F3, 'M', '7'),\n    (0x1D7F4, 'M', '8'),\n    (0x1D7F5, 'M', '9'),\n    (0x1D7F6, 'M', '0'),\n    (0x1D7F7, 'M', '1'),\n    (0x1D7F8, 'M', '2'),\n    (0x1D7F9, 'M', '3'),\n    (0x1D7FA, 'M', '4'),\n    (0x1D7FB, 'M', '5'),\n    (0x1D7FC, 'M', '6'),\n    (0x1D7FD, 'M', '7'),\n    (0x1D7FE, 'M', '8'),\n    (0x1D7FF, 'M', '9'),\n    (0x1D800, 'X'),\n    (0x1EE00, 'M', 'ا'),\n    (0x1EE01, 'M', 'ب'),\n    (0x1EE02, 'M', 'ج'),\n    (0x1EE03, 'M', 'د'),\n    (0x1EE04, 'X'),\n    (0x1EE05, 'M', 'و'),\n    (0x1EE06, 'M', 'ز'),\n    (0x1EE07, 'M', 'ح'),\n    (0x1EE08, 'M', 'ط'),\n    (0x1EE09, 'M', 'ي'),\n    (0x1EE0A, 'M', 'ك'),\n    (0x1EE0B, 'M', 'ل'),\n    (0x1EE0C, 'M', 'م'),\n    (0x1EE0D, 'M', 'ن'),\n    (0x1EE0E, 'M', 'س'),\n    (0x1EE0F, 'M', 'ع'),\n    (0x1EE10, 'M', 'ف'),\n    (0x1EE11, 'M', 'ص'),\n    (0x1EE12, 'M', 'ق'),\n    (0x1EE13, 'M', 'ر'),\n    (0x1EE14, 'M', 'ش'),\n    (0x1EE15, 'M', 'ت'),\n    (0x1EE16, 'M', 'ث'),\n    (0x1EE17, 'M', 'خ'),\n    (0x1EE18, 'M', 'ذ'),\n    (0x1EE19, 'M', 'ض'),\n    (0x1EE1A, 'M', 'ظ'),\n    (0x1EE1B, 'M', 'غ'),\n    (0x1EE1C, 'M', 'ٮ'),\n    (0x1EE1D, 'M', 'ں'),\n    (0x1EE1E, 'M', 'ڡ'),\n    (0x1EE1F, 'M', 'ٯ'),\n    (0x1EE20, 'X'),\n    (0x1EE21, 'M', 'ب'),\n    (0x1EE22, 'M', 'ج'),\n    (0x1EE23, 'X'),\n    (0x1EE24, 'M', 'ه'),\n    (0x1EE25, 'X'),\n    (0x1EE27, 'M', 'ح'),\n    (0x1EE28, 'X'),\n    (0x1EE29, 'M', 'ي'),\n    (0x1EE2A, 'M', 'ك'),\n    (0x1EE2B, 'M', 'ل'),\n    (0x1EE2C, 'M', 'م'),\n    (0x1EE2D, 'M', 'ن'),\n    (0x1EE2E, 'M', 'س'),\n    (0x1EE2F, 'M', 'ع'),\n    (0x1EE30, 'M', 'ف'),\n    (0x1EE31, 'M', 'ص'),\n    (0x1EE32, 'M', 'ق'),\n    (0x1EE33, 'X'),\n    (0x1EE34, 'M', 'ش'),\n    (0x1EE35, 'M', 'ت'),\n    (0x1EE36, 'M', 'ث'),\n    (0x1EE37, 'M', 'خ'),\n    (0x1EE38, 'X'),\n    (0x1EE39, 'M', 'ض'),\n    (0x1EE3A, 'X'),\n    (0x1EE3B, 'M', 'غ'),\n    (0x1EE3C, 'X'),\n    (0x1EE42, 'M', 'ج'),\n    (0x1EE43, 'X'),\n    (0x1EE47, 'M', 'ح'),\n    (0x1EE48, 'X'),\n    (0x1EE49, 'M', 'ي'),\n    (0x1EE4A, 'X'),\n    (0x1EE4B, 'M', 'ل'),\n    (0x1EE4C, 'X'),\n    (0x1EE4D, 'M', 'ن'),\n    (0x1EE4E, 'M', 'س'),\n    (0x1EE4F, 'M', 'ع'),\n    (0x1EE50, 'X'),\n    (0x1EE51, 'M', 'ص'),\n    (0x1EE52, 'M', 'ق'),\n    (0x1EE53, 'X'),\n    (0x1EE54, 'M', 'ش'),\n    (0x1EE55, 'X'),\n    (0x1EE57, 'M', 'خ'),\n    (0x1EE58, 'X'),\n    (0x1EE59, 'M', 'ض'),\n    (0x1EE5A, 'X'),\n    (0x1EE5B, 'M', 'غ'),\n    (0x1EE5C, 'X'),\n    (0x1EE5D, 'M', 'ں'),\n    (0x1EE5E, 'X'),\n    (0x1EE5F, 'M', 'ٯ'),\n    (0x1EE60, 'X'),\n    (0x1EE61, 'M', 'ب'),\n    (0x1EE62, 'M', 'ج'),\n    (0x1EE63, 'X'),\n    (0x1EE64, 'M', 'ه'),\n    (0x1EE65, 'X'),\n    (0x1EE67, 'M', 'ح'),\n    (0x1EE68, 'M', 'ط'),\n    (0x1EE69, 'M', 'ي'),\n    (0x1EE6A, 'M', 'ك'),\n    (0x1EE6B, 'X'),\n    (0x1EE6C, 'M', 'م'),\n    (0x1EE6D, 'M', 'ن'),\n    (0x1EE6E, 'M', 'س'),\n    (0x1EE6F, 'M', 'ع'),\n    (0x1EE70, 'M', 'ف'),\n    (0x1EE71, 'M', 'ص'),\n    (0x1EE72, 'M', 'ق'),\n    (0x1EE73, 'X'),\n    (0x1EE74, 'M', 'ش'),\n    (0x1EE75, 'M', 'ت'),\n    (0x1EE76, 'M', 'ث'),\n    (0x1EE77, 'M', 'خ'),\n    (0x1EE78, 'X'),\n    (0x1EE79, 'M', 'ض'),\n    (0x1EE7A, 'M', 'ظ'),\n    (0x1EE7B, 'M', 'غ'),\n    (0x1EE7C, 'M', 'ٮ'),\n    (0x1EE7D, 'X'),\n    (0x1EE7E, 'M', 'ڡ'),\n    (0x1EE7F, 'X'),\n    (0x1EE80, 'M', 'ا'),\n    (0x1EE81, 'M', 'ب'),\n    (0x1EE82, 'M', 'ج'),\n    (0x1EE83, 'M', 'د'),\n    (0x1EE84, 'M', 'ه'),\n    (0x1EE85, 'M', 'و'),\n    (0x1EE86, 'M', 'ز'),\n    (0x1EE87, 'M', 'ح'),\n    (0x1EE88, 'M', 'ط'),\n    (0x1EE89, 'M', 'ي'),\n    (0x1EE8A, 'X'),\n    (0x1EE8B, 'M', 'ل'),\n    (0x1EE8C, 'M', 'م'),\n    (0x1EE8D, 'M', 'ن'),\n    (0x1EE8E, 'M', 'س'),\n    (0x1EE8F, 'M', 'ع'),\n    (0x1EE90, 'M', 'ف'),\n    (0x1EE91, 'M', 'ص'),\n    (0x1EE92, 'M', 'ق'),\n    (0x1EE93, 'M', 'ر'),\n    (0x1EE94, 'M', 'ش'),\n    (0x1EE95, 'M', 'ت'),\n    (0x1EE96, 'M', 'ث'),\n    (0x1EE97, 'M', 'خ'),\n    (0x1EE98, 'M', 'ذ'),\n    (0x1EE99, 'M', 'ض'),\n    (0x1EE9A, 'M', 'ظ'),\n    (0x1EE9B, 'M', 'غ'),\n    (0x1EE9C, 'X'),\n    (0x1EEA1, 'M', 'ب'),\n    (0x1EEA2, 'M', 'ج'),\n    (0x1EEA3, 'M', 'د'),\n    (0x1EEA4, 'X'),\n    (0x1EEA5, 'M', 'و'),\n    (0x1EEA6, 'M', 'ز'),\n    (0x1EEA7, 'M', 'ح'),\n    (0x1EEA8, 'M', 'ط'),\n    (0x1EEA9, 'M', 'ي'),\n    (0x1EEAA, 'X'),\n    (0x1EEAB, 'M', 'ل'),\n    (0x1EEAC, 'M', 'م'),\n    (0x1EEAD, 'M', 'ن'),\n    (0x1EEAE, 'M', 'س'),\n    (0x1EEAF, 'M', 'ع'),\n    (0x1EEB0, 'M', 'ف'),\n    (0x1EEB1, 'M', 'ص'),\n    (0x1EEB2, 'M', 'ق'),\n    (0x1EEB3, 'M', 'ر'),\n    (0x1EEB4, 'M', 'ش'),\n    (0x1EEB5, 'M', 'ت'),\n    (0x1EEB6, 'M', 'ث'),\n    (0x1EEB7, 'M', 'خ'),\n    (0x1EEB8, 'M', 'ذ'),\n    (0x1EEB9, 'M', 'ض'),\n    (0x1EEBA, 'M', 'ظ'),\n    (0x1EEBB, 'M', 'غ'),\n    (0x1EEBC, 'X'),\n    (0x1EEF0, 'V'),\n    (0x1EEF2, 'X'),\n    (0x1F000, 'V'),\n    (0x1F02C, 'X'),\n    (0x1F030, 'V'),\n    (0x1F094, 'X'),\n    (0x1F0A0, 'V'),\n    (0x1F0AF, 'X'),\n    (0x1F0B1, 'V'),\n    (0x1F0BF, 'X'),\n    (0x1F0C1, 'V'),\n    (0x1F0D0, 'X'),\n    (0x1F0D1, 'V'),\n    (0x1F0E0, 'X'),\n    (0x1F101, '3', '0,'),\n    (0x1F102, '3', '1,'),\n    (0x1F103, '3', '2,'),\n    (0x1F104, '3', '3,'),\n    (0x1F105, '3', '4,'),\n    (0x1F106, '3', '5,'),\n    (0x1F107, '3', '6,'),\n    (0x1F108, '3', '7,'),\n    (0x1F109, '3', '8,'),\n    (0x1F10A, '3', '9,'),\n    (0x1F10B, 'X'),\n    (0x1F110, '3', '(a)'),\n    (0x1F111, '3', '(b)'),\n    (0x1F112, '3', '(c)'),\n    (0x1F113, '3', '(d)'),\n    (0x1F114, '3', '(e)'),\n    (0x1F115, '3', '(f)'),\n    (0x1F116, '3', '(g)'),\n    (0x1F117, '3', '(h)'),\n    (0x1F118, '3', '(i)'),\n    (0x1F119, '3', '(j)'),\n    (0x1F11A, '3', '(k)'),\n    (0x1F11B, '3', '(l)'),\n    (0x1F11C, '3', '(m)'),\n    (0x1F11D, '3', '(n)'),\n    (0x1F11E, '3', '(o)'),\n    (0x1F11F, '3', '(p)'),\n    (0x1F120, '3', '(q)'),\n    (0x1F121, '3', '(r)'),\n    (0x1F122, '3', '(s)'),\n    (0x1F123, '3', '(t)'),\n    (0x1F124, '3', '(u)'),\n    (0x1F125, '3', '(v)'),\n    (0x1F126, '3', '(w)'),\n    (0x1F127, '3', '(x)'),\n    (0x1F128, '3', '(y)'),\n    (0x1F129, '3', '(z)'),\n    (0x1F12A, 'M', '〔s〕'),\n    (0x1F12B, 'M', 'c'),\n    (0x1F12C, 'M', 'r'),\n    (0x1F12D, 'M', 'cd'),\n    (0x1F12E, 'M', 'wz'),\n    (0x1F12F, 'X'),\n    (0x1F130, 'M', 'a'),\n    (0x1F131, 'M', 'b'),\n    (0x1F132, 'M', 'c'),\n    (0x1F133, 'M', 'd'),\n    (0x1F134, 'M', 'e'),\n    (0x1F135, 'M', 'f'),\n    (0x1F136, 'M', 'g'),\n    (0x1F137, 'M', 'h'),\n    (0x1F138, 'M', 'i'),\n    (0x1F139, 'M', 'j'),\n    (0x1F13A, 'M', 'k'),\n    (0x1F13B, 'M', 'l'),\n    (0x1F13C, 'M', 'm'),\n    (0x1F13D, 'M', 'n'),\n    (0x1F13E, 'M', 'o'),\n    (0x1F13F, 'M', 'p'),\n    (0x1F140, 'M', 'q'),\n    (0x1F141, 'M', 'r'),\n    (0x1F142, 'M', 's'),\n    (0x1F143, 'M', 't'),\n    (0x1F144, 'M', 'u'),\n    (0x1F145, 'M', 'v'),\n    (0x1F146, 'M', 'w'),\n    (0x1F147, 'M', 'x'),\n    (0x1F148, 'M', 'y'),\n    (0x1F149, 'M', 'z'),\n    (0x1F14A, 'M', 'hv'),\n    (0x1F14B, 'M', 'mv'),\n    (0x1F14C, 'M', 'sd'),\n    (0x1F14D, 'M', 'ss'),\n    (0x1F14E, 'M', 'ppv'),\n    (0x1F14F, 'M', 'wc'),\n    (0x1F150, 'V'),\n    (0x1F16A, 'M', 'mc'),\n    (0x1F16B, 'M', 'md'),\n    (0x1F16C, 'X'),\n    (0x1F170, 'V'),\n    (0x1F190, 'M', 'dj'),\n    (0x1F191, 'V'),\n    (0x1F19B, 'X'),\n    (0x1F1E6, 'V'),\n    (0x1F200, 'M', 'ほか'),\n    (0x1F201, 'M', 'ココ'),\n    (0x1F202, 'M', 'サ'),\n    (0x1F203, 'X'),\n    (0x1F210, 'M', '手'),\n    (0x1F211, 'M', '字'),\n    (0x1F212, 'M', '双'),\n    (0x1F213, 'M', 'デ'),\n    (0x1F214, 'M', '二'),\n    (0x1F215, 'M', '多'),\n    (0x1F216, 'M', '解'),\n    (0x1F217, 'M', '天'),\n    (0x1F218, 'M', '交'),\n    (0x1F219, 'M', '映'),\n    (0x1F21A, 'M', '無'),\n    (0x1F21B, 'M', '料'),\n    (0x1F21C, 'M', '前'),\n    (0x1F21D, 'M', '後'),\n    (0x1F21E, 'M', '再'),\n    (0x1F21F, 'M', '新'),\n    (0x1F220, 'M', '初'),\n    (0x1F221, 'M', '終'),\n    (0x1F222, 'M', '生'),\n    (0x1F223, 'M', '販'),\n    (0x1F224, 'M', '声'),\n    (0x1F225, 'M', '吹'),\n    (0x1F226, 'M', '演'),\n    (0x1F227, 'M', '投'),\n    (0x1F228, 'M', '捕'),\n    (0x1F229, 'M', '一'),\n    (0x1F22A, 'M', '三'),\n    (0x1F22B, 'M', '遊'),\n    (0x1F22C, 'M', '左'),\n    (0x1F22D, 'M', '中'),\n    (0x1F22E, 'M', '右'),\n    (0x1F22F, 'M', '指'),\n    (0x1F230, 'M', '走'),\n    (0x1F231, 'M', '打'),\n    (0x1F232, 'M', '禁'),\n    (0x1F233, 'M', '空'),\n    (0x1F234, 'M', '合'),\n    (0x1F235, 'M', '満'),\n    (0x1F236, 'M', '有'),\n    (0x1F237, 'M', '月'),\n    (0x1F238, 'M', '申'),\n    (0x1F239, 'M', '割'),\n    (0x1F23A, 'M', '営'),\n    (0x1F23B, 'X'),\n    (0x1F240, 'M', '〔本〕'),\n    (0x1F241, 'M', '〔三〕'),\n    (0x1F242, 'M', '〔二〕'),\n    (0x1F243, 'M', '〔安〕'),\n    (0x1F244, 'M', '〔点〕'),\n    (0x1F245, 'M', '〔打〕'),\n    (0x1F246, 'M', '〔盗〕'),\n    (0x1F247, 'M', '〔勝〕'),\n    (0x1F248, 'M', '〔敗〕'),\n    (0x1F249, 'X'),\n    (0x1F250, 'M', '得'),\n    (0x1F251, 'M', '可'),\n    (0x1F252, 'X'),\n    (0x1F300, 'V'),\n    (0x1F321, 'X'),\n    (0x1F330, 'V'),\n    (0x1F336, 'X'),\n    (0x1F337, 'V'),\n    (0x1F37D, 'X'),\n    (0x1F380, 'V'),\n    (0x1F394, 'X'),\n    (0x1F3A0, 'V'),\n    (0x1F3C5, 'X'),\n    (0x1F3C6, 'V'),\n    (0x1F3CB, 'X'),\n    (0x1F3E0, 'V'),\n    (0x1F3F1, 'X'),\n    (0x1F400, 'V'),\n    (0x1F43F, 'X'),\n    (0x1F440, 'V'),\n    (0x1F441, 'X'),\n    (0x1F442, 'V'),\n    (0x1F4F8, 'X'),\n    (0x1F4F9, 'V'),\n    (0x1F4FD, 'X'),\n    (0x1F500, 'V'),\n    (0x1F53E, 'X'),\n    (0x1F540, 'V'),\n    (0x1F544, 'X'),\n    (0x1F550, 'V'),\n    (0x1F568, 'X'),\n    (0x1F5FB, 'V'),\n    (0x1F641, 'X'),\n    (0x1F645, 'V'),\n    (0x1F650, 'X'),\n    (0x1F680, 'V'),\n    (0x1F6C6, 'X'),\n    (0x1F700, 'V'),\n    (0x1F774, 'X'),\n    (0x20000, 'V'),\n    (0x2A6D7, 'X'),\n    (0x2A700, 'V'),\n    (0x2B735, 'X'),\n    (0x2B740, 'V'),\n    (0x2B81E, 'X'),\n    (0x2F800, 'M', '丽'),\n    (0x2F801, 'M', '丸'),\n    (0x2F802, 'M', '乁'),\n    (0x2F803, 'M', '𠄢'),\n    (0x2F804, 'M', '你'),\n    (0x2F805, 'M', '侮'),\n    (0x2F806, 'M', '侻'),\n    (0x2F807, 'M', '倂'),\n    (0x2F808, 'M', '偺'),\n    (0x2F809, 'M', '備'),\n    (0x2F80A, 'M', '僧'),\n    (0x2F80B, 'M', '像'),\n    (0x2F80C, 'M', '㒞'),\n    (0x2F80D, 'M', '𠘺'),\n    (0x2F80E, 'M', '免'),\n    (0x2F80F, 'M', '兔'),\n    (0x2F810, 'M', '兤'),\n    (0x2F811, 'M', '具'),\n    (0x2F812, 'M', '𠔜'),\n    (0x2F813, 'M', '㒹'),\n    (0x2F814, 'M', '內'),\n    (0x2F815, 'M', '再'),\n    (0x2F816, 'M', '𠕋'),\n    (0x2F817, 'M', '冗'),\n    (0x2F818, 'M', '冤'),\n    (0x2F819, 'M', '仌'),\n    (0x2F81A, 'M', '冬'),\n    (0x2F81B, 'M', '况'),\n    (0x2F81C, 'M', '𩇟'),\n    (0x2F81D, 'M', '凵'),\n    (0x2F81E, 'M', '刃'),\n    (0x2F81F, 'M', '㓟'),\n    (0x2F820, 'M', '刻'),\n    (0x2F821, 'M', '剆'),\n    (0x2F822, 'M', '割'),\n    (0x2F823, 'M', '剷'),\n    (0x2F824, 'M', '㔕'),\n    (0x2F825, 'M', '勇'),\n    (0x2F826, 'M', '勉'),\n    (0x2F827, 'M', '勤'),\n    (0x2F828, 'M', '勺'),\n    (0x2F829, 'M', '包'),\n    (0x2F82A, 'M', '匆'),\n    (0x2F82B, 'M', '北'),\n    (0x2F82C, 'M', '卉'),\n    (0x2F82D, 'M', '卑'),\n    (0x2F82E, 'M', '博'),\n    (0x2F82F, 'M', '即'),\n    (0x2F830, 'M', '卽'),\n    (0x2F831, 'M', '卿'),\n    (0x2F834, 'M', '𠨬'),\n    (0x2F835, 'M', '灰'),\n    (0x2F836, 'M', '及'),\n    (0x2F837, 'M', '叟'),\n    (0x2F838, 'M', '𠭣'),\n    (0x2F839, 'M', '叫'),\n    (0x2F83A, 'M', '叱'),\n    (0x2F83B, 'M', '吆'),\n    (0x2F83C, 'M', '咞'),\n    (0x2F83D, 'M', '吸'),\n    (0x2F83E, 'M', '呈'),\n    (0x2F83F, 'M', '周'),\n    (0x2F840, 'M', '咢'),\n    (0x2F841, 'M', '哶'),\n    (0x2F842, 'M', '唐'),\n    (0x2F843, 'M', '啓'),\n    (0x2F844, 'M', '啣'),\n    (0x2F845, 'M', '善'),\n    (0x2F847, 'M', '喙'),\n    (0x2F848, 'M', '喫'),\n    (0x2F849, 'M', '喳'),\n    (0x2F84A, 'M', '嗂'),\n    (0x2F84B, 'M', '圖'),\n    (0x2F84C, 'M', '嘆'),\n    (0x2F84D, 'M', '圗'),\n    (0x2F84E, 'M', '噑'),\n    (0x2F84F, 'M', '噴'),\n    (0x2F850, 'M', '切'),\n    (0x2F851, 'M', '壮'),\n    (0x2F852, 'M', '城'),\n    (0x2F853, 'M', '埴'),\n    (0x2F854, 'M', '堍'),\n    (0x2F855, 'M', '型'),\n    (0x2F856, 'M', '堲'),\n    (0x2F857, 'M', '報'),\n    (0x2F858, 'M', '墬'),\n    (0x2F859, 'M', '𡓤'),\n    (0x2F85A, 'M', '売'),\n    (0x2F85B, 'M', '壷'),\n    (0x2F85C, 'M', '夆'),\n    (0x2F85D, 'M', '多'),\n    (0x2F85E, 'M', '夢'),\n    (0x2F85F, 'M', '奢'),\n    (0x2F860, 'M', '𡚨'),\n    (0x2F861, 'M', '𡛪'),\n    (0x2F862, 'M', '姬'),\n    (0x2F863, 'M', '娛'),\n    (0x2F864, 'M', '娧'),\n    (0x2F865, 'M', '姘'),\n    (0x2F866, 'M', '婦'),\n    (0x2F867, 'M', '㛮'),\n    (0x2F868, 'X'),\n    (0x2F869, 'M', '嬈'),\n    (0x2F86A, 'M', '嬾'),\n    (0x2F86C, 'M', '𡧈'),\n    (0x2F86D, 'M', '寃'),\n    (0x2F86E, 'M', '寘'),\n    (0x2F86F, 'M', '寧'),\n    (0x2F870, 'M', '寳'),\n    (0x2F871, 'M', '𡬘'),\n    (0x2F872, 'M', '寿'),\n    (0x2F873, 'M', '将'),\n    (0x2F874, 'X'),\n    (0x2F875, 'M', '尢'),\n    (0x2F876, 'M', '㞁'),\n    (0x2F877, 'M', '屠'),\n    (0x2F878, 'M', '屮'),\n    (0x2F879, 'M', '峀'),\n    (0x2F87A, 'M', '岍'),\n    (0x2F87B, 'M', '𡷤'),\n    (0x2F87C, 'M', '嵃'),\n    (0x2F87D, 'M', '𡷦'),\n    (0x2F87E, 'M', '嵮'),\n    (0x2F87F, 'M', '嵫'),\n    (0x2F880, 'M', '嵼'),\n    (0x2F881, 'M', '巡'),\n    (0x2F882, 'M', '巢'),\n    (0x2F883, 'M', '㠯'),\n    (0x2F884, 'M', '巽'),\n    (0x2F885, 'M', '帨'),\n    (0x2F886, 'M', '帽'),\n    (0x2F887, 'M', '幩'),\n    (0x2F888, 'M', '㡢'),\n    (0x2F889, 'M', '𢆃'),\n    (0x2F88A, 'M', '㡼'),\n    (0x2F88B, 'M', '庰'),\n    (0x2F88C, 'M', '庳'),\n    (0x2F88D, 'M', '庶'),\n    (0x2F88E, 'M', '廊'),\n    (0x2F88F, 'M', '𪎒'),\n    (0x2F890, 'M', '廾'),\n    (0x2F891, 'M', '𢌱'),\n    (0x2F893, 'M', '舁'),\n    (0x2F894, 'M', '弢'),\n    (0x2F896, 'M', '㣇'),\n    (0x2F897, 'M', '𣊸'),\n    (0x2F898, 'M', '𦇚'),\n    (0x2F899, 'M', '形'),\n    (0x2F89A, 'M', '彫'),\n    (0x2F89B, 'M', '㣣'),\n    (0x2F89C, 'M', '徚'),\n    (0x2F89D, 'M', '忍'),\n    (0x2F89E, 'M', '志'),\n    (0x2F89F, 'M', '忹'),\n    (0x2F8A0, 'M', '悁'),\n    (0x2F8A1, 'M', '㤺'),\n    (0x2F8A2, 'M', '㤜'),\n    (0x2F8A3, 'M', '悔'),\n    (0x2F8A4, 'M', '𢛔'),\n    (0x2F8A5, 'M', '惇'),\n    (0x2F8A6, 'M', '慈'),\n    (0x2F8A7, 'M', '慌'),\n    (0x2F8A8, 'M', '慎'),\n    (0x2F8A9, 'M', '慌'),\n    (0x2F8AA, 'M', '慺'),\n    (0x2F8AB, 'M', '憎'),\n    (0x2F8AC, 'M', '憲'),\n    (0x2F8AD, 'M', '憤'),\n    (0x2F8AE, 'M', '憯'),\n    (0x2F8AF, 'M', '懞'),\n    (0x2F8B0, 'M', '懲'),\n    (0x2F8B1, 'M', '懶'),\n    (0x2F8B2, 'M', '成'),\n    (0x2F8B3, 'M', '戛'),\n    (0x2F8B4, 'M', '扝'),\n    (0x2F8B5, 'M', '抱'),\n    (0x2F8B6, 'M', '拔'),\n    (0x2F8B7, 'M', '捐'),\n    (0x2F8B8, 'M', '𢬌'),\n    (0x2F8B9, 'M', '挽'),\n    (0x2F8BA, 'M', '拼'),\n    (0x2F8BB, 'M', '捨'),\n    (0x2F8BC, 'M', '掃'),\n    (0x2F8BD, 'M', '揤'),\n    (0x2F8BE, 'M', '𢯱'),\n    (0x2F8BF, 'M', '搢'),\n    (0x2F8C0, 'M', '揅'),\n    (0x2F8C1, 'M', '掩'),\n    (0x2F8C2, 'M', '㨮'),\n    (0x2F8C3, 'M', '摩'),\n    (0x2F8C4, 'M', '摾'),\n    (0x2F8C5, 'M', '撝'),\n    (0x2F8C6, 'M', '摷'),\n    (0x2F8C7, 'M', '㩬'),\n    (0x2F8C8, 'M', '敏'),\n    (0x2F8C9, 'M', '敬'),\n    (0x2F8CA, 'M', '𣀊'),\n    (0x2F8CB, 'M', '旣'),\n    (0x2F8CC, 'M', '書'),\n    (0x2F8CD, 'M', '晉'),\n    (0x2F8CE, 'M', '㬙'),\n    (0x2F8CF, 'M', '暑'),\n    (0x2F8D0, 'M', '㬈'),\n    (0x2F8D1, 'M', '㫤'),\n    (0x2F8D2, 'M', '冒'),\n    (0x2F8D3, 'M', '冕'),\n    (0x2F8D4, 'M', '最'),\n    (0x2F8D5, 'M', '暜'),\n    (0x2F8D6, 'M', '肭'),\n    (0x2F8D7, 'M', '䏙'),\n    (0x2F8D8, 'M', '朗'),\n    (0x2F8D9, 'M', '望'),\n    (0x2F8DA, 'M', '朡'),\n    (0x2F8DB, 'M', '杞'),\n    (0x2F8DC, 'M', '杓'),\n    (0x2F8DD, 'M', '𣏃'),\n    (0x2F8DE, 'M', '㭉'),\n    (0x2F8DF, 'M', '柺'),\n    (0x2F8E0, 'M', '枅'),\n    (0x2F8E1, 'M', '桒'),\n    (0x2F8E2, 'M', '梅'),\n    (0x2F8E3, 'M', '𣑭'),\n    (0x2F8E4, 'M', '梎'),\n    (0x2F8E5, 'M', '栟'),\n    (0x2F8E6, 'M', '椔'),\n    (0x2F8E7, 'M', '㮝'),\n    (0x2F8E8, 'M', '楂'),\n    (0x2F8E9, 'M', '榣'),\n    (0x2F8EA, 'M', '槪'),\n    (0x2F8EB, 'M', '檨'),\n    (0x2F8EC, 'M', '𣚣'),\n    (0x2F8ED, 'M', '櫛'),\n    (0x2F8EE, 'M', '㰘'),\n    (0x2F8EF, 'M', '次'),\n    (0x2F8F0, 'M', '𣢧'),\n    (0x2F8F1, 'M', '歔'),\n    (0x2F8F2, 'M', '㱎'),\n    (0x2F8F3, 'M', '歲'),\n    (0x2F8F4, 'M', '殟'),\n    (0x2F8F5, 'M', '殺'),\n    (0x2F8F6, 'M', '殻'),\n    (0x2F8F7, 'M', '𣪍'),\n    (0x2F8F8, 'M', '𡴋'),\n    (0x2F8F9, 'M', '𣫺'),\n    (0x2F8FA, 'M', '汎'),\n    (0x2F8FB, 'M', '𣲼'),\n    (0x2F8FC, 'M', '沿'),\n    (0x2F8FD, 'M', '泍'),\n    (0x2F8FE, 'M', '汧'),\n    (0x2F8FF, 'M', '洖'),\n    (0x2F900, 'M', '派'),\n    (0x2F901, 'M', '海'),\n    (0x2F902, 'M', '流'),\n    (0x2F903, 'M', '浩'),\n    (0x2F904, 'M', '浸'),\n    (0x2F905, 'M', '涅'),\n    (0x2F906, 'M', '𣴞'),\n    (0x2F907, 'M', '洴'),\n    (0x2F908, 'M', '港'),\n    (0x2F909, 'M', '湮'),\n    (0x2F90A, 'M', '㴳'),\n    (0x2F90B, 'M', '滋'),\n    (0x2F90C, 'M', '滇'),\n    (0x2F90D, 'M', '𣻑'),\n    (0x2F90E, 'M', '淹'),\n    (0x2F90F, 'M', '潮'),\n    (0x2F910, 'M', '𣽞'),\n    (0x2F911, 'M', '𣾎'),\n    (0x2F912, 'M', '濆'),\n    (0x2F913, 'M', '瀹'),\n    (0x2F914, 'M', '瀞'),\n    (0x2F915, 'M', '瀛'),\n    (0x2F916, 'M', '㶖'),\n    (0x2F917, 'M', '灊'),\n    (0x2F918, 'M', '災'),\n    (0x2F919, 'M', '灷'),\n    (0x2F91A, 'M', '炭'),\n    (0x2F91B, 'M', '𠔥'),\n    (0x2F91C, 'M', '煅'),\n    (0x2F91D, 'M', '𤉣'),\n    (0x2F91E, 'M', '熜'),\n    (0x2F91F, 'X'),\n    (0x2F920, 'M', '爨'),\n    (0x2F921, 'M', '爵'),\n    (0x2F922, 'M', '牐'),\n    (0x2F923, 'M', '𤘈'),\n    (0x2F924, 'M', '犀'),\n    (0x2F925, 'M', '犕'),\n    (0x2F926, 'M', '𤜵'),\n    (0x2F927, 'M', '𤠔'),\n    (0x2F928, 'M', '獺'),\n    (0x2F929, 'M', '王'),\n    (0x2F92A, 'M', '㺬'),\n    (0x2F92B, 'M', '玥'),\n    (0x2F92C, 'M', '㺸'),\n    (0x2F92E, 'M', '瑇'),\n    (0x2F92F, 'M', '瑜'),\n    (0x2F930, 'M', '瑱'),\n    (0x2F931, 'M', '璅'),\n    (0x2F932, 'M', '瓊'),\n    (0x2F933, 'M', '㼛'),\n    (0x2F934, 'M', '甤'),\n    (0x2F935, 'M', '𤰶'),\n    (0x2F936, 'M', '甾'),\n    (0x2F937, 'M', '𤲒'),\n    (0x2F938, 'M', '異'),\n    (0x2F939, 'M', '𢆟'),\n    (0x2F93A, 'M', '瘐'),\n    (0x2F93B, 'M', '𤾡'),\n    (0x2F93C, 'M', '𤾸'),\n    (0x2F93D, 'M', '𥁄'),\n    (0x2F93E, 'M', '㿼'),\n    (0x2F93F, 'M', '䀈'),\n    (0x2F940, 'M', '直'),\n    (0x2F941, 'M', '𥃳'),\n    (0x2F942, 'M', '𥃲'),\n    (0x2F943, 'M', '𥄙'),\n    (0x2F944, 'M', '𥄳'),\n    (0x2F945, 'M', '眞'),\n    (0x2F946, 'M', '真'),\n    (0x2F948, 'M', '睊'),\n    (0x2F949, 'M', '䀹'),\n    (0x2F94A, 'M', '瞋'),\n    (0x2F94B, 'M', '䁆'),\n    (0x2F94C, 'M', '䂖'),\n    (0x2F94D, 'M', '𥐝'),\n    (0x2F94E, 'M', '硎'),\n    (0x2F94F, 'M', '碌'),\n    (0x2F950, 'M', '磌'),\n    (0x2F951, 'M', '䃣'),\n    (0x2F952, 'M', '𥘦'),\n    (0x2F953, 'M', '祖'),\n    (0x2F954, 'M', '𥚚'),\n    (0x2F955, 'M', '𥛅'),\n    (0x2F956, 'M', '福'),\n    (0x2F957, 'M', '秫'),\n    (0x2F958, 'M', '䄯'),\n    (0x2F959, 'M', '穀'),\n    (0x2F95A, 'M', '穊'),\n    (0x2F95B, 'M', '穏'),\n    (0x2F95C, 'M', '𥥼'),\n    (0x2F95D, 'M', '𥪧'),\n    (0x2F95F, 'X'),\n    (0x2F960, 'M', '䈂'),\n    (0x2F961, 'M', '𥮫'),\n    (0x2F962, 'M', '篆'),\n    (0x2F963, 'M', '築'),\n    (0x2F964, 'M', '䈧'),\n    (0x2F965, 'M', '𥲀'),\n    (0x2F966, 'M', '糒'),\n    (0x2F967, 'M', '䊠'),\n    (0x2F968, 'M', '糨'),\n    (0x2F969, 'M', '糣'),\n    (0x2F96A, 'M', '紀'),\n    (0x2F96B, 'M', '𥾆'),\n    (0x2F96C, 'M', '絣'),\n    (0x2F96D, 'M', '䌁'),\n    (0x2F96E, 'M', '緇'),\n    (0x2F96F, 'M', '縂'),\n    (0x2F970, 'M', '繅'),\n    (0x2F971, 'M', '䌴'),\n    (0x2F972, 'M', '𦈨'),\n    (0x2F973, 'M', '𦉇'),\n    (0x2F974, 'M', '䍙'),\n    (0x2F975, 'M', '𦋙'),\n    (0x2F976, 'M', '罺'),\n    (0x2F977, 'M', '𦌾'),\n    (0x2F978, 'M', '羕'),\n    (0x2F979, 'M', '翺'),\n    (0x2F97A, 'M', '者'),\n    (0x2F97B, 'M', '𦓚'),\n    (0x2F97C, 'M', '𦔣'),\n    (0x2F97D, 'M', '聠'),\n    (0x2F97E, 'M', '𦖨'),\n    (0x2F97F, 'M', '聰'),\n    (0x2F980, 'M', '𣍟'),\n    (0x2F981, 'M', '䏕'),\n    (0x2F982, 'M', '育'),\n    (0x2F983, 'M', '脃'),\n    (0x2F984, 'M', '䐋'),\n    (0x2F985, 'M', '脾'),\n    (0x2F986, 'M', '媵'),\n    (0x2F987, 'M', '𦞧'),\n    (0x2F988, 'M', '𦞵'),\n    (0x2F989, 'M', '𣎓'),\n    (0x2F98A, 'M', '𣎜'),\n    (0x2F98B, 'M', '舁'),\n    (0x2F98C, 'M', '舄'),\n    (0x2F98D, 'M', '辞'),\n    (0x2F98E, 'M', '䑫'),\n    (0x2F98F, 'M', '芑'),\n    (0x2F990, 'M', '芋'),\n    (0x2F991, 'M', '芝'),\n    (0x2F992, 'M', '劳'),\n    (0x2F993, 'M', '花'),\n    (0x2F994, 'M', '芳'),\n    (0x2F995, 'M', '芽'),\n    (0x2F996, 'M', '苦'),\n    (0x2F997, 'M', '𦬼'),\n    (0x2F998, 'M', '若'),\n    (0x2F999, 'M', '茝'),\n    (0x2F99A, 'M', '荣'),\n    (0x2F99B, 'M', '莭'),\n    (0x2F99C, 'M', '茣'),\n    (0x2F99D, 'M', '莽'),\n    (0x2F99E, 'M', '菧'),\n    (0x2F99F, 'M', '著'),\n    (0x2F9A0, 'M', '荓'),\n    (0x2F9A1, 'M', '菊'),\n    (0x2F9A2, 'M', '菌'),\n    (0x2F9A3, 'M', '菜'),\n    (0x2F9A4, 'M', '𦰶'),\n    (0x2F9A5, 'M', '𦵫'),\n    (0x2F9A6, 'M', '𦳕'),\n    (0x2F9A7, 'M', '䔫'),\n    (0x2F9A8, 'M', '蓱'),\n    (0x2F9A9, 'M', '蓳'),\n    (0x2F9AA, 'M', '蔖'),\n    (0x2F9AB, 'M', '𧏊'),\n    (0x2F9AC, 'M', '蕤'),\n    (0x2F9AD, 'M', '𦼬'),\n    (0x2F9AE, 'M', '䕝'),\n    (0x2F9AF, 'M', '䕡'),\n    (0x2F9B0, 'M', '𦾱'),\n    (0x2F9B1, 'M', '𧃒'),\n    (0x2F9B2, 'M', '䕫'),\n    (0x2F9B3, 'M', '虐'),\n    (0x2F9B4, 'M', '虜'),\n    (0x2F9B5, 'M', '虧'),\n    (0x2F9B6, 'M', '虩'),\n    (0x2F9B7, 'M', '蚩'),\n    (0x2F9B8, 'M', '蚈'),\n    (0x2F9B9, 'M', '蜎'),\n    (0x2F9BA, 'M', '蛢'),\n    (0x2F9BB, 'M', '蝹'),\n    (0x2F9BC, 'M', '蜨'),\n    (0x2F9BD, 'M', '蝫'),\n    (0x2F9BE, 'M', '螆'),\n    (0x2F9BF, 'X'),\n    (0x2F9C0, 'M', '蟡'),\n    (0x2F9C1, 'M', '蠁'),\n    (0x2F9C2, 'M', '䗹'),\n    (0x2F9C3, 'M', '衠'),\n    (0x2F9C4, 'M', '衣'),\n    (0x2F9C5, 'M', '𧙧'),\n    (0x2F9C6, 'M', '裗'),\n    (0x2F9C7, 'M', '裞'),\n    (0x2F9C8, 'M', '䘵'),\n    (0x2F9C9, 'M', '裺'),\n    (0x2F9CA, 'M', '㒻'),\n    (0x2F9CB, 'M', '𧢮'),\n    (0x2F9CC, 'M', '𧥦'),\n    (0x2F9CD, 'M', '䚾'),\n    (0x2F9CE, 'M', '䛇'),\n    (0x2F9CF, 'M', '誠'),\n    (0x2F9D0, 'M', '諭'),\n    (0x2F9D1, 'M', '變'),\n    (0x2F9D2, 'M', '豕'),\n    (0x2F9D3, 'M', '𧲨'),\n    (0x2F9D4, 'M', '貫'),\n    (0x2F9D5, 'M', '賁'),\n    (0x2F9D6, 'M', '贛'),\n    (0x2F9D7, 'M', '起'),\n    (0x2F9D8, 'M', '𧼯'),\n    (0x2F9D9, 'M', '𠠄'),\n    (0x2F9DA, 'M', '跋'),\n    (0x2F9DB, 'M', '趼'),\n    (0x2F9DC, 'M', '跰'),\n    (0x2F9DD, 'M', '𠣞'),\n    (0x2F9DE, 'M', '軔'),\n    (0x2F9DF, 'M', '輸'),\n    (0x2F9E0, 'M', '𨗒'),\n    (0x2F9E1, 'M', '𨗭'),\n    (0x2F9E2, 'M', '邔'),\n    (0x2F9E3, 'M', '郱'),\n    (0x2F9E4, 'M', '鄑'),\n    (0x2F9E5, 'M', '𨜮'),\n    (0x2F9E6, 'M', '鄛'),\n    (0x2F9E7, 'M', '鈸'),\n    (0x2F9E8, 'M', '鋗'),\n    (0x2F9E9, 'M', '鋘'),\n    (0x2F9EA, 'M', '鉼'),\n    (0x2F9EB, 'M', '鏹'),\n    (0x2F9EC, 'M', '鐕'),\n    (0x2F9ED, 'M', '𨯺'),\n    (0x2F9EE, 'M', '開'),\n    (0x2F9EF, 'M', '䦕'),\n    (0x2F9F0, 'M', '閷'),\n    (0x2F9F1, 'M', '𨵷'),\n    (0x2F9F2, 'M', '䧦'),\n    (0x2F9F3, 'M', '雃'),\n    (0x2F9F4, 'M', '嶲'),\n    (0x2F9F5, 'M', '霣'),\n    (0x2F9F6, 'M', '𩅅'),\n    (0x2F9F7, 'M', '𩈚'),\n    (0x2F9F8, 'M', '䩮'),\n    (0x2F9F9, 'M', '䩶'),\n    (0x2F9FA, 'M', '韠'),\n    (0x2F9FB, 'M', '𩐊'),\n    (0x2F9FC, 'M', '䪲'),\n    (0x2F9FD, 'M', '𩒖'),\n    (0x2F9FE, 'M', '頋'),\n    (0x2FA00, 'M', '頩'),\n    (0x2FA01, 'M', '𩖶'),\n    (0x2FA02, 'M', '飢'),\n    (0x2FA03, 'M', '䬳'),\n    (0x2FA04, 'M', '餩'),\n    (0x2FA05, 'M', '馧'),\n    (0x2FA06, 'M', '駂'),\n    (0x2FA07, 'M', '駾'),\n    (0x2FA08, 'M', '䯎'),\n    (0x2FA09, 'M', '𩬰'),\n    (0x2FA0A, 'M', '鬒'),\n    (0x2FA0B, 'M', '鱀'),\n    (0x2FA0C, 'M', '鳽'),\n    (0x2FA0D, 'M', '䳎'),\n    (0x2FA0E, 'M', '䳭'),\n    (0x2FA0F, 'M', '鵧'),\n    (0x2FA10, 'M', '𪃎'),\n    (0x2FA11, 'M', '䳸'),\n    (0x2FA12, 'M', '𪄅'),\n    (0x2FA13, 'M', '𪈎'),\n    (0x2FA14, 'M', '𪊑'),\n    (0x2FA15, 'M', '麻'),\n    (0x2FA16, 'M', '䵖'),\n    (0x2FA17, 'M', '黹'),\n    (0x2FA18, 'M', '黾'),\n    (0x2FA19, 'M', '鼅'),\n    (0x2FA1A, 'M', '鼏'),\n    (0x2FA1B, 'M', '鼖'),\n    (0x2FA1C, 'M', '鼻'),\n    (0x2FA1D, 'M', '𪘀'),\n    (0x2FA1E, 'X'),\n    (0xE0100, 'I'),\n    (0xE01F0, 'X'),\n)\n"
  },
  {
    "path": "code/default/lib/noarch/lru_cache.py",
    "content": "import collections\nimport json\nimport threading\n\n\nclass LruCache(object):\n\n    def __init__(self, capacity=3000):\n        self.capacity = capacity\n        self.cache = collections.OrderedDict()\n        self.lock = threading.Lock()\n        self.running = True\n\n    def get(self, key):\n        with self.lock:\n            record = None\n            try:\n                record = self.cache.pop(key)\n                self.cache[key] = record\n            except KeyError:\n                pass\n            return record\n\n    def set(self, key, record):\n        with self.lock:\n            try:\n                self.cache.pop(key)\n            except KeyError:\n                if len(self.cache) >= self.capacity:\n                    self.cache.popitem(last=False)\n\n            self.cache[key] = record\n\n    def __str__(self):\n        out_str = \"\"\n        for key, value in list(self.cache.items()):\n            if isinstance(value, str):\n                out_str += \" %s => %s<br>\\n\" % (key, value)\n            elif isinstance(value, dict) or isinstance(value, list):\n                out_str += \" %s => %s<br>\\n\" % (key, json.dumps(value))\n\n        return out_str\n\n    def __len__(self):\n        return len(self.cache)\n\n    def __contains__(self, item):\n        return item in self.cache\n\n    def __iter__(self):\n        return self.cache.__iter__()\n\n    def __getitem__(self, item):\n        return self.cache.__getitem__(item)\n\n    def __setitem__(self, key, value):\n        return self.set(key, value)\n\n    def __delitem__(self, key):\n        self.cache.__delitem__(key)"
  },
  {
    "path": "code/default/lib/noarch/os_platform.py",
    "content": "import sys\nimport os\n\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\ndefault_path = os.path.abspath(os.path.join(current_path, os.pardir))\nhas_desktop = False\n\nif sys.platform.startswith(\"linux\"):\n    if os.path.isfile(\"/system/bin/dalvikvm\") or os.path.isfile(\"/system/bin/dalvikvm64\"):\n        platform = \"android\"\n        has_desktop = True\n    else:\n        platform = \"linux\"\nelif sys.platform == \"win32\":\n    has_desktop = True\n    platform = \"windows\"\n\nelif sys.platform == \"darwin\":\n    has_desktop = True\n    platform = \"mac\"\nelse:\n    platform = sys.platform\n"
  },
  {
    "path": "code/default/lib/noarch/pyasn1/__init__.py",
    "content": "import sys\n\n# https://www.python.org/dev/peps/pep-0396/\n__version__ = '0.4.3'\n\nif sys.version_info[:2] < (2, 4):\n    raise RuntimeError('PyASN1 requires Python 2.4 or later')\n"
  },
  {
    "path": "code/default/lib/noarch/pyasn1/codec/__init__.py",
    "content": "# This file is necessary to make this directory a package.\n"
  },
  {
    "path": "code/default/lib/noarch/pyasn1/codec/ber/__init__.py",
    "content": "# This file is necessary to make this directory a package.\n"
  },
  {
    "path": "code/default/lib/noarch/pyasn1/codec/ber/decoder.py",
    "content": "#\n# This file is part of pyasn1 software.\n#\n# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>\n# License: http://snmplabs.com/pyasn1/license.html\n#\nfrom pyasn1 import debug\nfrom pyasn1 import error\nfrom pyasn1.codec.ber import eoo\nfrom pyasn1.compat.integer import from_bytes\nfrom pyasn1.compat.octets import oct2int, octs2ints, ints2octs, null\nfrom pyasn1.type import base\nfrom pyasn1.type import char\nfrom pyasn1.type import tag\nfrom pyasn1.type import tagmap\nfrom pyasn1.type import univ\nfrom pyasn1.type import useful\n\n__all__ = ['decode']\n\nnoValue = base.noValue\n\n\nclass AbstractDecoder(object):\n    protoComponent = None\n\n    def valueDecoder(self, substrate, asn1Spec,\n                     tagSet=None, length=None, state=None,\n                     decodeFun=None, substrateFun=None,\n                     **options):\n        raise error.PyAsn1Error('Decoder not implemented for %s' % (tagSet,))\n\n    def indefLenValueDecoder(self, substrate, asn1Spec,\n                             tagSet=None, length=None, state=None,\n                             decodeFun=None, substrateFun=None,\n                             **options):\n        raise error.PyAsn1Error('Indefinite length mode decoder not implemented for %s' % (tagSet,))\n\n\nclass AbstractSimpleDecoder(AbstractDecoder):\n    @staticmethod\n    def substrateCollector(asn1Object, substrate, length):\n        return substrate[:length], substrate[length:]\n\n    def _createComponent(self, asn1Spec, tagSet, value, **options):\n        if options.get('native'):\n            return value\n        elif asn1Spec is None:\n            return self.protoComponent.clone(value, tagSet=tagSet)\n        elif value is noValue:\n            return asn1Spec\n        else:\n            return asn1Spec.clone(value)\n\n\nclass ExplicitTagDecoder(AbstractSimpleDecoder):\n    protoComponent = univ.Any('')\n\n    def valueDecoder(self, substrate, asn1Spec,\n                     tagSet=None, length=None, state=None,\n                     decodeFun=None, substrateFun=None,\n                     **options):\n        if substrateFun:\n            return substrateFun(\n                self._createComponent(asn1Spec, tagSet, '', **options),\n                substrate, length\n            )\n\n        head, tail = substrate[:length], substrate[length:]\n\n        value, _ = decodeFun(head, asn1Spec, tagSet, length, **options)\n\n        return value, tail\n\n    def indefLenValueDecoder(self, substrate, asn1Spec,\n                             tagSet=None, length=None, state=None,\n                             decodeFun=None, substrateFun=None,\n                             **options):\n        if substrateFun:\n            return substrateFun(\n                self._createComponent(asn1Spec, tagSet, '', **options),\n                substrate, length\n            )\n\n        value, substrate = decodeFun(substrate, asn1Spec, tagSet, length, **options)\n\n        eooMarker, substrate = decodeFun(substrate, allowEoo=True, **options)\n\n        if eooMarker is eoo.endOfOctets:\n            return value, substrate\n        else:\n            raise error.PyAsn1Error('Missing end-of-octets terminator')\n\n\nexplicitTagDecoder = ExplicitTagDecoder()\n\n\nclass IntegerDecoder(AbstractSimpleDecoder):\n    protoComponent = univ.Integer(0)\n\n    def valueDecoder(self, substrate, asn1Spec,\n                     tagSet=None, length=None, state=None,\n                     decodeFun=None, substrateFun=None,\n                     **options):\n\n        if tagSet[0].tagFormat != tag.tagFormatSimple:\n            raise error.PyAsn1Error('Simple tag format expected')\n\n        head, tail = substrate[:length], substrate[length:]\n\n        if not head:\n            return self._createComponent(asn1Spec, tagSet, 0, **options), tail\n\n        value = from_bytes(head, signed=True)\n\n        return self._createComponent(asn1Spec, tagSet, value, **options), tail\n\n\nclass BooleanDecoder(IntegerDecoder):\n    protoComponent = univ.Boolean(0)\n\n    def _createComponent(self, asn1Spec, tagSet, value, **options):\n        return IntegerDecoder._createComponent(self, asn1Spec, tagSet, value and 1 or 0, **options)\n\n\nclass BitStringDecoder(AbstractSimpleDecoder):\n    protoComponent = univ.BitString(())\n    supportConstructedForm = True\n\n    def valueDecoder(self, substrate, asn1Spec,\n                     tagSet=None, length=None, state=None,\n                     decodeFun=None, substrateFun=None,\n                     **options):\n        head, tail = substrate[:length], substrate[length:]\n\n        if substrateFun:\n            return substrateFun(self._createComponent(asn1Spec, tagSet, noValue, **options),\n                                substrate, length)\n\n        if not head:\n            raise error.PyAsn1Error('Empty BIT STRING substrate')\n\n        if tagSet[0].tagFormat == tag.tagFormatSimple:  # XXX what tag to check?\n\n            trailingBits = oct2int(head[0])\n            if trailingBits > 7:\n                raise error.PyAsn1Error(\n                    'Trailing bits overflow %s' % trailingBits\n                )\n\n            value = self.protoComponent.fromOctetString(head[1:], internalFormat=True, padding=trailingBits)\n\n            return self._createComponent(asn1Spec, tagSet, value, **options), tail\n\n        if not self.supportConstructedForm:\n            raise error.PyAsn1Error('Constructed encoding form prohibited at %s' % self.__class__.__name__)\n\n        # All inner fragments are of the same type, treat them as octet string\n        substrateFun = self.substrateCollector\n\n        bitString = self.protoComponent.fromOctetString(null, internalFormat=True)\n\n        while head:\n            component, head = decodeFun(head, self.protoComponent,\n                                        substrateFun=substrateFun, **options)\n\n            trailingBits = oct2int(component[0])\n            if trailingBits > 7:\n                raise error.PyAsn1Error(\n                    'Trailing bits overflow %s' % trailingBits\n                )\n\n            bitString = self.protoComponent.fromOctetString(\n                component[1:], internalFormat=True,\n                prepend=bitString, padding=trailingBits\n            )\n\n        return self._createComponent(asn1Spec, tagSet, bitString, **options), tail\n\n    def indefLenValueDecoder(self, substrate, asn1Spec,\n                             tagSet=None, length=None, state=None,\n                             decodeFun=None, substrateFun=None,\n                             **options):\n\n        if substrateFun:\n            return substrateFun(self._createComponent(asn1Spec, tagSet, noValue, **options), substrate, length)\n\n        # All inner fragments are of the same type, treat them as octet string\n        substrateFun = self.substrateCollector\n\n        bitString = self.protoComponent.fromOctetString(null, internalFormat=True)\n\n        while substrate:\n            component, substrate = decodeFun(substrate, self.protoComponent,\n                                             substrateFun=substrateFun,\n                                             allowEoo=True, **options)\n            if component is eoo.endOfOctets:\n                break\n\n            trailingBits = oct2int(component[0])\n            if trailingBits > 7:\n                raise error.PyAsn1Error(\n                    'Trailing bits overflow %s' % trailingBits\n                )\n\n            bitString = self.protoComponent.fromOctetString(\n                component[1:], internalFormat=True,\n                prepend=bitString, padding=trailingBits\n            )\n\n        else:\n            raise error.SubstrateUnderrunError('No EOO seen before substrate ends')\n\n        return self._createComponent(asn1Spec, tagSet, bitString, **options), substrate\n\n\nclass OctetStringDecoder(AbstractSimpleDecoder):\n    protoComponent = univ.OctetString('')\n    supportConstructedForm = True\n\n    def valueDecoder(self, substrate, asn1Spec,\n                     tagSet=None, length=None, state=None,\n                     decodeFun=None, substrateFun=None,\n                     **options):\n        head, tail = substrate[:length], substrate[length:]\n\n        if substrateFun:\n            return substrateFun(self._createComponent(asn1Spec, tagSet, noValue, **options),\n                                substrate, length)\n\n        if tagSet[0].tagFormat == tag.tagFormatSimple:  # XXX what tag to check?\n            return self._createComponent(asn1Spec, tagSet, head, **options), tail\n\n        if not self.supportConstructedForm:\n            raise error.PyAsn1Error('Constructed encoding form prohibited at %s' % self.__class__.__name__)\n\n        # All inner fragments are of the same type, treat them as octet string\n        substrateFun = self.substrateCollector\n\n        header = null\n\n        while head:\n            component, head = decodeFun(head, self.protoComponent,\n                                        substrateFun=substrateFun,\n                                        **options)\n            header += component\n\n        return self._createComponent(asn1Spec, tagSet, header, **options), tail\n\n    def indefLenValueDecoder(self, substrate, asn1Spec,\n                             tagSet=None, length=None, state=None,\n                             decodeFun=None, substrateFun=None,\n                             **options):\n        if substrateFun and substrateFun is not self.substrateCollector:\n            asn1Object = self._createComponent(asn1Spec, tagSet, noValue, **options)\n            return substrateFun(asn1Object, substrate, length)\n\n        # All inner fragments are of the same type, treat them as octet string\n        substrateFun = self.substrateCollector\n\n        header = null\n\n        while substrate:\n            component, substrate = decodeFun(substrate,\n                                             self.protoComponent,\n                                             substrateFun=substrateFun,\n                                             allowEoo=True, **options)\n            if component is eoo.endOfOctets:\n                break\n            header += component\n        else:\n            raise error.SubstrateUnderrunError(\n                'No EOO seen before substrate ends'\n            )\n\n        return self._createComponent(asn1Spec, tagSet, header, **options), substrate\n\n\nclass NullDecoder(AbstractSimpleDecoder):\n    protoComponent = univ.Null('')\n\n    def valueDecoder(self, substrate, asn1Spec,\n                     tagSet=None, length=None, state=None,\n                     decodeFun=None, substrateFun=None,\n                     **options):\n\n        if tagSet[0].tagFormat != tag.tagFormatSimple:\n            raise error.PyAsn1Error('Simple tag format expected')\n\n        head, tail = substrate[:length], substrate[length:]\n\n        component = self._createComponent(asn1Spec, tagSet, '', **options)\n\n        if head:\n            raise error.PyAsn1Error('Unexpected %d-octet substrate for Null' % length)\n\n        return component, tail\n\n\nclass ObjectIdentifierDecoder(AbstractSimpleDecoder):\n    protoComponent = univ.ObjectIdentifier(())\n\n    def valueDecoder(self, substrate, asn1Spec,\n                     tagSet=None, length=None, state=None,\n                     decodeFun=None, substrateFun=None,\n                     **options):\n        if tagSet[0].tagFormat != tag.tagFormatSimple:\n            raise error.PyAsn1Error('Simple tag format expected')\n\n        head, tail = substrate[:length], substrate[length:]\n        if not head:\n            raise error.PyAsn1Error('Empty substrate')\n\n        head = octs2ints(head)\n\n        oid = ()\n        index = 0\n        substrateLen = len(head)\n        while index < substrateLen:\n            subId = head[index]\n            index += 1\n            if subId < 128:\n                oid += (subId,)\n            elif subId > 128:\n                # Construct subid from a number of octets\n                nextSubId = subId\n                subId = 0\n                while nextSubId >= 128:\n                    subId = (subId << 7) + (nextSubId & 0x7F)\n                    if index >= substrateLen:\n                        raise error.SubstrateUnderrunError(\n                            'Short substrate for sub-OID past %s' % (oid,)\n                        )\n                    nextSubId = head[index]\n                    index += 1\n                oid += ((subId << 7) + nextSubId,)\n            elif subId == 128:\n                # ASN.1 spec forbids leading zeros (0x80) in OID\n                # encoding, tolerating it opens a vulnerability. See\n                # https://www.esat.kuleuven.be/cosic/publications/article-1432.pdf\n                # page 7\n                raise error.PyAsn1Error('Invalid octet 0x80 in OID encoding')\n\n        # Decode two leading arcs\n        if 0 <= oid[0] <= 39:\n            oid = (0,) + oid\n        elif 40 <= oid[0] <= 79:\n            oid = (1, oid[0] - 40) + oid[1:]\n        elif oid[0] >= 80:\n            oid = (2, oid[0] - 80) + oid[1:]\n        else:\n            raise error.PyAsn1Error('Malformed first OID octet: %s' % head[0])\n\n        return self._createComponent(asn1Spec, tagSet, oid, **options), tail\n\n\nclass RealDecoder(AbstractSimpleDecoder):\n    protoComponent = univ.Real()\n\n    def valueDecoder(self, substrate, asn1Spec,\n                     tagSet=None, length=None, state=None,\n                     decodeFun=None, substrateFun=None,\n                     **options):\n        if tagSet[0].tagFormat != tag.tagFormatSimple:\n            raise error.PyAsn1Error('Simple tag format expected')\n\n        head, tail = substrate[:length], substrate[length:]\n\n        if not head:\n            return self._createComponent(asn1Spec, tagSet, 0.0, **options), tail\n\n        fo = oct2int(head[0])\n        head = head[1:]\n        if fo & 0x80:  # binary encoding\n            if not head:\n                raise error.PyAsn1Error(\"Incomplete floating-point value\")\n            n = (fo & 0x03) + 1\n            if n == 4:\n                n = oct2int(head[0])\n                head = head[1:]\n            eo, head = head[:n], head[n:]\n            if not eo or not head:\n                raise error.PyAsn1Error('Real exponent screwed')\n            e = oct2int(eo[0]) & 0x80 and -1 or 0\n            while eo:  # exponent\n                e <<= 8\n                e |= oct2int(eo[0])\n                eo = eo[1:]\n            b = fo >> 4 & 0x03  # base bits\n            if b > 2:\n                raise error.PyAsn1Error('Illegal Real base')\n            if b == 1:  # encbase = 8\n                e *= 3\n            elif b == 2:  # encbase = 16\n                e *= 4\n            p = 0\n            while head:  # value\n                p <<= 8\n                p |= oct2int(head[0])\n                head = head[1:]\n            if fo & 0x40:  # sign bit\n                p = -p\n            sf = fo >> 2 & 0x03  # scale bits\n            p *= 2 ** sf\n            value = (p, 2, e)\n        elif fo & 0x40:  # infinite value\n            value = fo & 0x01 and '-inf' or 'inf'\n        elif fo & 0xc0 == 0:  # character encoding\n            if not head:\n                raise error.PyAsn1Error(\"Incomplete floating-point value\")\n            try:\n                if fo & 0x3 == 0x1:  # NR1\n                    value = (int(head), 10, 0)\n                elif fo & 0x3 == 0x2:  # NR2\n                    value = float(head)\n                elif fo & 0x3 == 0x3:  # NR3\n                    value = float(head)\n                else:\n                    raise error.SubstrateUnderrunError(\n                        'Unknown NR (tag %s)' % fo\n                    )\n            except ValueError:\n                raise error.SubstrateUnderrunError(\n                    'Bad character Real syntax'\n                )\n        else:\n            raise error.SubstrateUnderrunError(\n                'Unknown encoding (tag %s)' % fo\n            )\n        return self._createComponent(asn1Spec, tagSet, value, **options), tail\n\n\nclass AbstractConstructedDecoder(AbstractDecoder):\n    protoComponent = None\n\n\nclass UniversalConstructedTypeDecoder(AbstractConstructedDecoder):\n    protoRecordComponent = None\n    protoSequenceComponent = None\n\n    def _getComponentTagMap(self, asn1Object, idx):\n        raise NotImplementedError()\n\n    def _getComponentPositionByType(self, asn1Object, tagSet, idx):\n        raise NotImplementedError()\n\n    def _decodeComponents(self, substrate, tagSet=None, decodeFun=None, **options):\n        components = []\n        componentTypes = set()\n        while substrate:\n            component, substrate = decodeFun(substrate, **options)\n            if component is eoo.endOfOctets:\n                break\n            components.append(component)\n            componentTypes.add(component.tagSet)\n\n        # Now we have to guess is it SEQUENCE/SET or SEQUENCE OF/SET OF\n        # The heuristics is:\n        # * 1+ components of different types -> likely SEQUENCE/SET\n        # * otherwise -> likely SEQUENCE OF/SET OF\n        if len(componentTypes) > 1:\n            protoComponent = self.protoRecordComponent\n        else:\n            protoComponent = self.protoSequenceComponent\n\n        asn1Object = protoComponent.clone(\n            # construct tagSet from base tag from prototype ASN.1 object\n            # and additional tags recovered from the substrate\n            tagSet=tag.TagSet(protoComponent.tagSet.baseTag, *tagSet.superTags)\n        )\n\n        for idx, component in enumerate(components):\n            asn1Object.setComponentByPosition(\n                idx, component,\n                verifyConstraints=False,\n                matchTags=False, matchConstraints=False\n            )\n\n        return asn1Object, substrate\n\n    def valueDecoder(self, substrate, asn1Spec,\n                     tagSet=None, length=None, state=None,\n                     decodeFun=None, substrateFun=None,\n                     **options):\n        if tagSet[0].tagFormat != tag.tagFormatConstructed:\n            raise error.PyAsn1Error('Constructed tag format expected')\n\n        head, tail = substrate[:length], substrate[length:]\n\n        if substrateFun is not None:\n            if asn1Spec is not None:\n                asn1Object = asn1Spec.clone()\n            elif self.protoComponent is not None:\n                asn1Object = self.protoComponent.clone(tagSet=tagSet)\n            else:\n                asn1Object = self.protoRecordComponent, self.protoSequenceComponent\n\n            return substrateFun(asn1Object, substrate, length)\n\n        if asn1Spec is None:\n            asn1Object, trailing = self._decodeComponents(\n                head, tagSet=tagSet, decodeFun=decodeFun, **options\n            )\n            if trailing:\n                raise error.PyAsn1Error('Unused trailing %d octets encountered' % len(trailing))\n            return asn1Object, tail\n\n        asn1Object = asn1Spec.clone()\n\n        if asn1Spec.typeId in (univ.Sequence.typeId, univ.Set.typeId):\n\n            namedTypes = asn1Spec.componentType\n\n            isSetType = asn1Spec.typeId == univ.Set.typeId\n            isDeterministic = not isSetType and not namedTypes.hasOptionalOrDefault\n\n            seenIndices = set()\n            idx = 0\n            while head:\n                if not namedTypes:\n                    componentType = None\n                elif isSetType:\n                    componentType = namedTypes.tagMapUnique\n                else:\n                    try:\n                        if isDeterministic:\n                            componentType = namedTypes[idx].asn1Object\n                        elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted:\n                            componentType = namedTypes.getTagMapNearPosition(idx)\n                        else:\n                            componentType = namedTypes[idx].asn1Object\n                    except IndexError:\n                        raise error.PyAsn1Error(\n                            'Excessive components decoded at %r' % (asn1Spec,)\n                        )\n\n                component, head = decodeFun(head, componentType, **options)\n\n                if not isDeterministic and namedTypes:\n                    if isSetType:\n                        idx = namedTypes.getPositionByType(component.effectiveTagSet)\n                    elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted:\n                        idx = namedTypes.getPositionNearType(component.effectiveTagSet, idx)\n\n                asn1Object.setComponentByPosition(\n                    idx, component,\n                    verifyConstraints=False,\n                    matchTags=False, matchConstraints=False\n                )\n\n                seenIndices.add(idx)\n                idx += 1\n\n            if namedTypes:\n                if not namedTypes.requiredComponents.issubset(seenIndices):\n                    raise error.PyAsn1Error('ASN.1 object %s has uninitialized components' % asn1Object.__class__.__name__)\n\n                if  namedTypes.hasOpenTypes:\n\n                    openTypes = options.get('openTypes', {})\n\n                    if openTypes or options.get('decodeOpenTypes', False):\n\n                        for idx, namedType in enumerate(namedTypes.namedTypes):\n                            if not namedType.openType:\n                                continue\n\n                            if namedType.isOptional and not asn1Object.getComponentByPosition(idx).isValue:\n                                continue\n\n                            governingValue = asn1Object.getComponentByName(\n                                namedType.openType.name\n                            )\n\n                            try:\n                                openType = openTypes[governingValue]\n\n                            except KeyError:\n\n                                try:\n                                    openType = namedType.openType[governingValue]\n\n                                except KeyError:\n                                    continue\n\n                            component, rest = decodeFun(\n                                asn1Object.getComponentByPosition(idx).asOctets(),\n                                asn1Spec=openType\n                            )\n\n                            asn1Object.setComponentByPosition(idx, component)\n\n            else:\n                asn1Object.verifySizeSpec()\n\n        else:\n            asn1Object = asn1Spec.clone()\n\n            componentType = asn1Spec.componentType\n\n            idx = 0\n\n            while head:\n                component, head = decodeFun(head, componentType, **options)\n                asn1Object.setComponentByPosition(\n                    idx, component,\n                    verifyConstraints=False,\n                    matchTags=False, matchConstraints=False\n                )\n                idx += 1\n\n        return asn1Object, tail\n\n    def indefLenValueDecoder(self, substrate, asn1Spec,\n                             tagSet=None, length=None, state=None,\n                             decodeFun=None, substrateFun=None,\n                             **options):\n        if tagSet[0].tagFormat != tag.tagFormatConstructed:\n            raise error.PyAsn1Error('Constructed tag format expected')\n\n        if substrateFun is not None:\n            if asn1Spec is not None:\n                asn1Object = asn1Spec.clone()\n            elif self.protoComponent is not None:\n                asn1Object = self.protoComponent.clone(tagSet=tagSet)\n            else:\n                asn1Object = self.protoRecordComponent, self.protoSequenceComponent\n\n            return substrateFun(asn1Object, substrate, length)\n\n        if asn1Spec is None:\n            return self._decodeComponents(\n                substrate, tagSet=tagSet, decodeFun=decodeFun, allowEoo=True, **options\n            )\n\n        asn1Object = asn1Spec.clone()\n\n        if asn1Spec.typeId in (univ.Sequence.typeId, univ.Set.typeId):\n\n            namedTypes = asn1Object.componentType\n\n            isSetType = asn1Object.typeId == univ.Set.typeId\n            isDeterministic = not isSetType and not namedTypes.hasOptionalOrDefault\n\n            seenIndices = set()\n            idx = 0\n            while substrate:\n                if len(namedTypes) <= idx:\n                    asn1Spec = None\n                elif isSetType:\n                    asn1Spec = namedTypes.tagMapUnique\n                else:\n                    try:\n                        if isDeterministic:\n                            asn1Spec = namedTypes[idx].asn1Object\n                        elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted:\n                            asn1Spec = namedTypes.getTagMapNearPosition(idx)\n                        else:\n                            asn1Spec = namedTypes[idx].asn1Object\n                    except IndexError:\n                        raise error.PyAsn1Error(\n                            'Excessive components decoded at %r' % (asn1Object,)\n                        )\n\n                component, substrate = decodeFun(substrate, asn1Spec, allowEoo=True, **options)\n                if component is eoo.endOfOctets:\n                    break\n\n                if not isDeterministic and namedTypes:\n                    if isSetType:\n                        idx = namedTypes.getPositionByType(component.effectiveTagSet)\n                    elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted:\n                        idx = namedTypes.getPositionNearType(component.effectiveTagSet, idx)\n\n                asn1Object.setComponentByPosition(\n                    idx, component,\n                    verifyConstraints=False,\n                    matchTags=False, matchConstraints=False\n                )\n\n                seenIndices.add(idx)\n                idx += 1\n\n            else:\n                raise error.SubstrateUnderrunError(\n                    'No EOO seen before substrate ends'\n                )\n\n            if namedTypes:\n                if not namedTypes.requiredComponents.issubset(seenIndices):\n                    raise error.PyAsn1Error('ASN.1 object %s has uninitialized components' % asn1Object.__class__.__name__)\n\n                if  namedTypes.hasOpenTypes:\n\n                    openTypes = options.get('openTypes', None)\n\n                    if openTypes or options.get('decodeOpenTypes', False):\n\n                        for idx, namedType in enumerate(namedTypes.namedTypes):\n                            if not namedType.openType:\n                                continue\n\n                            if namedType.isOptional and not asn1Object.getComponentByPosition(idx).isValue:\n                                continue\n\n                            governingValue = asn1Object.getComponentByName(\n                                namedType.openType.name\n                            )\n\n                            try:\n                                openType = openTypes[governingValue]\n\n                            except KeyError:\n\n                                try:\n                                    openType = namedType.openType[governingValue]\n\n                                except KeyError:\n                                    continue\n\n                            component, rest = decodeFun(\n                                asn1Object.getComponentByPosition(idx).asOctets(),\n                                asn1Spec=openType, allowEoo=True\n                            )\n\n                            if component is not eoo.endOfOctets:\n                                asn1Object.setComponentByPosition(idx, component)\n\n                else:\n                    asn1Object.verifySizeSpec()\n\n        else:\n            asn1Object = asn1Spec.clone()\n\n            componentType = asn1Spec.componentType\n\n            idx = 0\n\n            while substrate:\n                component, substrate = decodeFun(substrate, componentType, allowEoo=True, **options)\n\n                if component is eoo.endOfOctets:\n                    break\n\n                asn1Object.setComponentByPosition(\n                    idx, component,\n                    verifyConstraints=False,\n                    matchTags=False, matchConstraints=False\n                )\n                idx += 1\n            else:\n                raise error.SubstrateUnderrunError(\n                    'No EOO seen before substrate ends'\n                )\n\n        return asn1Object, substrate\n\n\nclass SequenceOrSequenceOfDecoder(UniversalConstructedTypeDecoder):\n    protoRecordComponent = univ.Sequence()\n    protoSequenceComponent = univ.SequenceOf()\n\n\nclass SequenceDecoder(SequenceOrSequenceOfDecoder):\n    protoComponent = univ.Sequence()\n\n\nclass SequenceOfDecoder(SequenceOrSequenceOfDecoder):\n    protoComponent = univ.SequenceOf()\n\n\nclass SetOrSetOfDecoder(UniversalConstructedTypeDecoder):\n    protoRecordComponent = univ.Set()\n    protoSequenceComponent = univ.SetOf()\n\n\nclass SetDecoder(SetOrSetOfDecoder):\n    protoComponent = univ.Set()\n\n\n\nclass SetOfDecoder(SetOrSetOfDecoder):\n    protoComponent = univ.SetOf()\n\n\nclass ChoiceDecoder(AbstractConstructedDecoder):\n    protoComponent = univ.Choice()\n\n    def valueDecoder(self, substrate, asn1Spec,\n                     tagSet=None, length=None, state=None,\n                     decodeFun=None, substrateFun=None,\n                     **options):\n        head, tail = substrate[:length], substrate[length:]\n\n        if asn1Spec is None:\n            asn1Object = self.protoComponent.clone(tagSet=tagSet)\n        else:\n            asn1Object = asn1Spec.clone()\n\n        if substrateFun:\n            return substrateFun(asn1Object, substrate, length)\n\n        if asn1Object.tagSet == tagSet:  # explicitly tagged Choice\n            component, head = decodeFun(\n                head, asn1Object.componentTagMap, **options\n            )\n\n        else:\n            component, head = decodeFun(\n                head, asn1Object.componentTagMap,\n                tagSet, length, state, **options\n            )\n\n        effectiveTagSet = component.effectiveTagSet\n\n        asn1Object.setComponentByType(\n            effectiveTagSet, component,\n            verifyConstraints=False,\n            matchTags=False, matchConstraints=False,\n            innerFlag=False\n        )\n\n        return asn1Object, tail\n\n    def indefLenValueDecoder(self, substrate, asn1Spec,\n                             tagSet=None, length=None, state=None,\n                             decodeFun=None, substrateFun=None,\n                             **options):\n        if asn1Spec is None:\n            asn1Object = self.protoComponent.clone(tagSet=tagSet)\n        else:\n            asn1Object = asn1Spec.clone()\n\n        if substrateFun:\n            return substrateFun(asn1Object, substrate, length)\n\n        if asn1Object.tagSet == tagSet:  # explicitly tagged Choice\n            component, substrate = decodeFun(\n                substrate, asn1Object.componentType.tagMapUnique, **options\n            )\n            # eat up EOO marker\n            eooMarker, substrate = decodeFun(\n                substrate, allowEoo=True, **options\n            )\n            if eooMarker is not eoo.endOfOctets:\n                raise error.PyAsn1Error('No EOO seen before substrate ends')\n\n        else:\n            component, substrate = decodeFun(\n                substrate, asn1Object.componentType.tagMapUnique,\n                tagSet, length, state, **options\n            )\n\n        effectiveTagSet = component.effectiveTagSet\n\n        asn1Object.setComponentByType(\n            effectiveTagSet, component,\n            verifyConstraints=False,\n            matchTags=False, matchConstraints=False,\n            innerFlag=False\n        )\n\n        return asn1Object, substrate\n\n\nclass AnyDecoder(AbstractSimpleDecoder):\n    protoComponent = univ.Any()\n\n    def valueDecoder(self, substrate, asn1Spec,\n                     tagSet=None, length=None, state=None,\n                     decodeFun=None, substrateFun=None,\n                     **options):\n        if asn1Spec is None or asn1Spec is not None and tagSet != asn1Spec.tagSet:\n            fullSubstrate = options['fullSubstrate']\n\n            # untagged Any container, recover inner header substrate\n            length += len(fullSubstrate) - len(substrate)\n            substrate = fullSubstrate\n\n        if substrateFun:\n            return substrateFun(self._createComponent(asn1Spec, tagSet, noValue, **options),\n                                substrate, length)\n\n        head, tail = substrate[:length], substrate[length:]\n\n        return self._createComponent(asn1Spec, tagSet, head, **options), tail\n\n    def indefLenValueDecoder(self, substrate, asn1Spec,\n                             tagSet=None, length=None, state=None,\n                             decodeFun=None, substrateFun=None,\n                             **options):\n        if asn1Spec is not None and tagSet == asn1Spec.tagSet:\n            # tagged Any type -- consume header substrate\n            header = null\n        else:\n            fullSubstrate = options['fullSubstrate']\n\n            # untagged Any, recover header substrate\n            header = fullSubstrate[:-len(substrate)]\n\n        # Any components do not inherit initial tag\n        asn1Spec = self.protoComponent\n\n        if substrateFun and substrateFun is not self.substrateCollector:\n            asn1Object = self._createComponent(asn1Spec, tagSet, noValue, **options)\n            return substrateFun(asn1Object, header + substrate, length + len(header))\n\n        # All inner fragments are of the same type, treat them as octet string\n        substrateFun = self.substrateCollector\n\n        while substrate:\n            component, substrate = decodeFun(substrate, asn1Spec,\n                                             substrateFun=substrateFun,\n                                             allowEoo=True, **options)\n            if component is eoo.endOfOctets:\n                break\n            header += component\n        else:\n            raise error.SubstrateUnderrunError(\n                'No EOO seen before substrate ends'\n            )\n        if substrateFun:\n            return header, substrate\n        else:\n            return self._createComponent(asn1Spec, tagSet, header, **options), substrate\n\n\n# character string types\nclass UTF8StringDecoder(OctetStringDecoder):\n    protoComponent = char.UTF8String()\n\n\nclass NumericStringDecoder(OctetStringDecoder):\n    protoComponent = char.NumericString()\n\n\nclass PrintableStringDecoder(OctetStringDecoder):\n    protoComponent = char.PrintableString()\n\n\nclass TeletexStringDecoder(OctetStringDecoder):\n    protoComponent = char.TeletexString()\n\n\nclass VideotexStringDecoder(OctetStringDecoder):\n    protoComponent = char.VideotexString()\n\n\nclass IA5StringDecoder(OctetStringDecoder):\n    protoComponent = char.IA5String()\n\n\nclass GraphicStringDecoder(OctetStringDecoder):\n    protoComponent = char.GraphicString()\n\n\nclass VisibleStringDecoder(OctetStringDecoder):\n    protoComponent = char.VisibleString()\n\n\nclass GeneralStringDecoder(OctetStringDecoder):\n    protoComponent = char.GeneralString()\n\n\nclass UniversalStringDecoder(OctetStringDecoder):\n    protoComponent = char.UniversalString()\n\n\nclass BMPStringDecoder(OctetStringDecoder):\n    protoComponent = char.BMPString()\n\n\n# \"useful\" types\nclass ObjectDescriptorDecoder(OctetStringDecoder):\n    protoComponent = useful.ObjectDescriptor()\n\n\nclass GeneralizedTimeDecoder(OctetStringDecoder):\n    protoComponent = useful.GeneralizedTime()\n\n\nclass UTCTimeDecoder(OctetStringDecoder):\n    protoComponent = useful.UTCTime()\n\n\ntagMap = {\n    univ.Integer.tagSet: IntegerDecoder(),\n    univ.Boolean.tagSet: BooleanDecoder(),\n    univ.BitString.tagSet: BitStringDecoder(),\n    univ.OctetString.tagSet: OctetStringDecoder(),\n    univ.Null.tagSet: NullDecoder(),\n    univ.ObjectIdentifier.tagSet: ObjectIdentifierDecoder(),\n    univ.Enumerated.tagSet: IntegerDecoder(),\n    univ.Real.tagSet: RealDecoder(),\n    univ.Sequence.tagSet: SequenceOrSequenceOfDecoder(),  # conflicts with SequenceOf\n    univ.Set.tagSet: SetOrSetOfDecoder(),  # conflicts with SetOf\n    univ.Choice.tagSet: ChoiceDecoder(),  # conflicts with Any\n    # character string types\n    char.UTF8String.tagSet: UTF8StringDecoder(),\n    char.NumericString.tagSet: NumericStringDecoder(),\n    char.PrintableString.tagSet: PrintableStringDecoder(),\n    char.TeletexString.tagSet: TeletexStringDecoder(),\n    char.VideotexString.tagSet: VideotexStringDecoder(),\n    char.IA5String.tagSet: IA5StringDecoder(),\n    char.GraphicString.tagSet: GraphicStringDecoder(),\n    char.VisibleString.tagSet: VisibleStringDecoder(),\n    char.GeneralString.tagSet: GeneralStringDecoder(),\n    char.UniversalString.tagSet: UniversalStringDecoder(),\n    char.BMPString.tagSet: BMPStringDecoder(),\n    # useful types\n    useful.ObjectDescriptor.tagSet: ObjectDescriptorDecoder(),\n    useful.GeneralizedTime.tagSet: GeneralizedTimeDecoder(),\n    useful.UTCTime.tagSet: UTCTimeDecoder()\n}\n\n# Type-to-codec map for ambiguous ASN.1 types\ntypeMap = {\n    univ.Set.typeId: SetDecoder(),\n    univ.SetOf.typeId: SetOfDecoder(),\n    univ.Sequence.typeId: SequenceDecoder(),\n    univ.SequenceOf.typeId: SequenceOfDecoder(),\n    univ.Choice.typeId: ChoiceDecoder(),\n    univ.Any.typeId: AnyDecoder()\n}\n\n# Put in non-ambiguous types for faster codec lookup\nfor typeDecoder in list(tagMap.values()):\n    if typeDecoder.protoComponent is not None:\n        typeId = typeDecoder.protoComponent.__class__.typeId\n        if typeId is not None and typeId not in typeMap:\n            typeMap[typeId] = typeDecoder\n\n\n(stDecodeTag,\n stDecodeLength,\n stGetValueDecoder,\n stGetValueDecoderByAsn1Spec,\n stGetValueDecoderByTag,\n stTryAsExplicitTag,\n stDecodeValue,\n stDumpRawValue,\n stErrorCondition,\n stStop) = [x for x in range(10)]\n\n\nclass Decoder(object):\n    defaultErrorState = stErrorCondition\n    #    defaultErrorState = stDumpRawValue\n    defaultRawDecoder = AnyDecoder()\n    supportIndefLength = True\n\n    # noinspection PyDefaultArgument\n    def __init__(self, tagMap, typeMap={}):\n        self.__tagMap = tagMap\n        self.__typeMap = typeMap\n        # Tag & TagSet objects caches\n        self.__tagCache = {}\n        self.__tagSetCache = {}\n        self.__eooSentinel = ints2octs((0, 0))\n\n    def __call__(self, substrate, asn1Spec=None,\n                 tagSet=None, length=None, state=stDecodeTag,\n                 decodeFun=None, substrateFun=None,\n                 **options):\n\n        if debug.logger & debug.flagDecoder:\n            logger = debug.logger\n        else:\n            logger = None\n\n        if logger:\n            logger('decoder called at scope %s with state %d, working with up to %d octets of substrate: %s' % (debug.scope, state, len(substrate), debug.hexdump(substrate)))\n\n        allowEoo = options.pop('allowEoo', False)\n\n        # Look for end-of-octets sentinel\n        if allowEoo and self.supportIndefLength:\n            if substrate[:2] == self.__eooSentinel:\n                if logger:\n                    logger('end-of-octets sentinel found')\n                return eoo.endOfOctets, substrate[2:]\n\n        value = noValue\n\n        tagMap = self.__tagMap\n        typeMap = self.__typeMap\n        tagCache = self.__tagCache\n        tagSetCache = self.__tagSetCache\n\n        fullSubstrate = substrate\n\n        while state is not stStop:\n            if state is stDecodeTag:\n                if not substrate:\n                    raise error.SubstrateUnderrunError(\n                        'Short octet stream on tag decoding'\n                    )\n                # Decode tag\n                isShortTag = True\n                firstOctet = substrate[0]\n                substrate = substrate[1:]\n                try:\n                    lastTag = tagCache[firstOctet]\n                except KeyError:\n                    integerTag = oct2int(firstOctet)\n                    tagClass = integerTag & 0xC0\n                    tagFormat = integerTag & 0x20\n                    tagId = integerTag & 0x1F\n                    if tagId == 0x1F:\n                        isShortTag = False\n                        lengthOctetIdx = 0\n                        tagId = 0\n                        try:\n                            while True:\n                                integerTag = oct2int(substrate[lengthOctetIdx])\n                                lengthOctetIdx += 1\n                                tagId <<= 7\n                                tagId |= (integerTag & 0x7F)\n                                if not integerTag & 0x80:\n                                    break\n                            substrate = substrate[lengthOctetIdx:]\n                        except IndexError:\n                            raise error.SubstrateUnderrunError(\n                                'Short octet stream on long tag decoding'\n                            )\n                    lastTag = tag.Tag(\n                        tagClass=tagClass, tagFormat=tagFormat, tagId=tagId\n                    )\n                    if isShortTag:\n                        # cache short tags\n                        tagCache[firstOctet] = lastTag\n                if tagSet is None:\n                    if isShortTag:\n                        try:\n                            tagSet = tagSetCache[firstOctet]\n                        except KeyError:\n                            # base tag not recovered\n                            tagSet = tag.TagSet((), lastTag)\n                            tagSetCache[firstOctet] = tagSet\n                    else:\n                        tagSet = tag.TagSet((), lastTag)\n                else:\n                    tagSet = lastTag + tagSet\n                state = stDecodeLength\n                if logger:\n                    logger('tag decoded into %s, decoding length' % tagSet)\n            if state is stDecodeLength:\n                # Decode length\n                if not substrate:\n                    raise error.SubstrateUnderrunError(\n                        'Short octet stream on length decoding'\n                    )\n                firstOctet = oct2int(substrate[0])\n                if firstOctet < 128:\n                    size = 1\n                    length = firstOctet\n                elif firstOctet > 128:\n                    size = firstOctet & 0x7F\n                    # encoded in size bytes\n                    encodedLength = octs2ints(substrate[1:size + 1])\n                    # missing check on maximum size, which shouldn't be a\n                    # problem, we can handle more than is possible\n                    if len(encodedLength) != size:\n                        raise error.SubstrateUnderrunError(\n                            '%s<%s at %s' % (size, len(encodedLength), tagSet)\n                        )\n                    length = 0\n                    for lengthOctet in encodedLength:\n                        length <<= 8\n                        length |= lengthOctet\n                    size += 1\n                else:\n                    size = 1\n                    length = -1\n\n                substrate = substrate[size:]\n                if length == -1:\n                    if not self.supportIndefLength:\n                        raise error.PyAsn1Error('Indefinite length encoding not supported by this codec')\n                else:\n                    if len(substrate) < length:\n                        raise error.SubstrateUnderrunError('%d-octet short' % (length - len(substrate)))\n                state = stGetValueDecoder\n                if logger:\n                    logger('value length decoded into %d, payload substrate is: %s' % (length, debug.hexdump(length == -1 and substrate or substrate[:length])))\n            if state is stGetValueDecoder:\n                if asn1Spec is None:\n                    state = stGetValueDecoderByTag\n                else:\n                    state = stGetValueDecoderByAsn1Spec\n            #\n            # There're two ways of creating subtypes in ASN.1 what influences\n            # decoder operation. These methods are:\n            # 1) Either base types used in or no IMPLICIT tagging has been\n            #    applied on subtyping.\n            # 2) Subtype syntax drops base type information (by means of\n            #    IMPLICIT tagging.\n            # The first case allows for complete tag recovery from substrate\n            # while the second one requires original ASN.1 type spec for\n            # decoding.\n            #\n            # In either case a set of tags (tagSet) is coming from substrate\n            # in an incremental, tag-by-tag fashion (this is the case of\n            # EXPLICIT tag which is most basic). Outermost tag comes first\n            # from the wire.\n            #\n            if state is stGetValueDecoderByTag:\n                try:\n                    concreteDecoder = tagMap[tagSet]\n                except KeyError:\n                    concreteDecoder = None\n                if concreteDecoder:\n                    state = stDecodeValue\n                else:\n                    try:\n                        concreteDecoder = tagMap[tagSet[:1]]\n                    except KeyError:\n                        concreteDecoder = None\n                    if concreteDecoder:\n                        state = stDecodeValue\n                    else:\n                        state = stTryAsExplicitTag\n                if logger:\n                    logger('codec %s chosen by a built-in type, decoding %s' % (concreteDecoder and concreteDecoder.__class__.__name__ or \"<none>\", state is stDecodeValue and 'value' or 'as explicit tag'))\n                    debug.scope.push(concreteDecoder is None and '?' or concreteDecoder.protoComponent.__class__.__name__)\n            if state is stGetValueDecoderByAsn1Spec:\n                if asn1Spec.__class__ is tagmap.TagMap:\n                    try:\n                        chosenSpec = asn1Spec[tagSet]\n                    except KeyError:\n                        chosenSpec = None\n                    if logger:\n                        logger('candidate ASN.1 spec is a map of:')\n                        for firstOctet, v in list(asn1Spec.presentTypes.items()):\n                            logger('  %s -> %s' % (firstOctet, v.__class__.__name__))\n                        if asn1Spec.skipTypes:\n                            logger('but neither of: ')\n                            for firstOctet, v in list(asn1Spec.skipTypes.items()):\n                                logger('  %s -> %s' % (firstOctet, v.__class__.__name__))\n                        logger('new candidate ASN.1 spec is %s, chosen by %s' % (chosenSpec is None and '<none>' or chosenSpec.prettyPrintType(), tagSet))\n                elif tagSet == asn1Spec.tagSet or tagSet in asn1Spec.tagMap:\n                    chosenSpec = asn1Spec\n                    if logger:\n                        logger('candidate ASN.1 spec is %s' % asn1Spec.__class__.__name__)\n                else:\n                    chosenSpec = None\n\n                if chosenSpec is not None:\n                    try:\n                        # ambiguous type or just faster codec lookup\n                        concreteDecoder = typeMap[chosenSpec.typeId]\n                        if logger:\n                            logger('value decoder chosen for an ambiguous type by type ID %s' % (chosenSpec.typeId,))\n                    except KeyError:\n                        # use base type for codec lookup to recover untagged types\n                        baseTagSet = tag.TagSet(chosenSpec.tagSet.baseTag,  chosenSpec.tagSet.baseTag)\n                        try:\n                            # base type or tagged subtype\n                            concreteDecoder = tagMap[baseTagSet]\n                            if logger:\n                                logger('value decoder chosen by base %s' % (baseTagSet,))\n                        except KeyError:\n                            concreteDecoder = None\n                    if concreteDecoder:\n                        asn1Spec = chosenSpec\n                        state = stDecodeValue\n                    else:\n                        state = stTryAsExplicitTag\n                else:\n                    concreteDecoder = None\n                    state = stTryAsExplicitTag\n                if logger:\n                    logger('codec %s chosen by ASN.1 spec, decoding %s' % (state is stDecodeValue and concreteDecoder.__class__.__name__ or \"<none>\", state is stDecodeValue and 'value' or 'as explicit tag'))\n                    debug.scope.push(chosenSpec is None and '?' or chosenSpec.__class__.__name__)\n            if state is stDecodeValue:\n                if not options.get('recursiveFlag', True) and not substrateFun:  # deprecate this\n                    substrateFun = lambda a, b, c: (a, b[:c])\n\n                options.update(fullSubstrate=fullSubstrate)\n\n                if length == -1:  # indef length\n                    value, substrate = concreteDecoder.indefLenValueDecoder(\n                        substrate, asn1Spec,\n                        tagSet, length, stGetValueDecoder,\n                        self, substrateFun,\n                        **options\n                    )\n                else:\n                    value, substrate = concreteDecoder.valueDecoder(\n                        substrate, asn1Spec,\n                        tagSet, length, stGetValueDecoder,\n                        self, substrateFun,\n                        **options\n                    )\n\n                if logger:\n                    logger('codec %s yields type %s, value:\\n%s\\n...remaining substrate is: %s' % (concreteDecoder.__class__.__name__, value.__class__.__name__, isinstance(value, base.Asn1Item) and value.prettyPrint() or value, substrate and debug.hexdump(substrate) or '<none>'))\n\n                state = stStop\n                break\n            if state is stTryAsExplicitTag:\n                if tagSet and tagSet[0].tagFormat == tag.tagFormatConstructed and tagSet[0].tagClass != tag.tagClassUniversal:\n                    # Assume explicit tagging\n                    concreteDecoder = explicitTagDecoder\n                    state = stDecodeValue\n                else:\n                    concreteDecoder = None\n                    state = self.defaultErrorState\n                if logger:\n                    logger('codec %s chosen, decoding %s' % (concreteDecoder and concreteDecoder.__class__.__name__ or \"<none>\", state is stDecodeValue and 'value' or 'as failure'))\n            if state is stDumpRawValue:\n                concreteDecoder = self.defaultRawDecoder\n                if logger:\n                    logger('codec %s chosen, decoding value' % concreteDecoder.__class__.__name__)\n                state = stDecodeValue\n            if state is stErrorCondition:\n                raise error.PyAsn1Error(\n                    '%s not in asn1Spec: %r' % (tagSet, asn1Spec)\n                )\n        if logger:\n            debug.scope.pop()\n            logger('decoder left scope %s, call completed' % debug.scope)\n        return value, substrate\n\n\n#: Turns BER octet stream into an ASN.1 object.\n#:\n#: Takes BER octet-stream and decode it into an ASN.1 object\n#: (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative) which\n#: may be a scalar or an arbitrary nested structure.\n#:\n#: Parameters\n#: ----------\n#: substrate: :py:class:`bytes` (Python 3) or :py:class:`str` (Python 2)\n#:     BER octet-stream\n#:\n#: Keyword Args\n#: ------------\n#: asn1Spec: any pyasn1 type object e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative\n#:     A pyasn1 type object to act as a template guiding the decoder. Depending on the ASN.1 structure\n#:     being decoded, *asn1Spec* may or may not be required. Most common reason for\n#:     it to require is that ASN.1 structure is encoded in *IMPLICIT* tagging mode.\n#:\n#: Returns\n#: -------\n#: : :py:class:`tuple`\n#:     A tuple of pyasn1 object recovered from BER substrate (:py:class:`~pyasn1.type.base.PyAsn1Item` derivative)\n#:     and the unprocessed trailing portion of the *substrate* (may be empty)\n#:\n#: Raises\n#: ------\n#: :py:class:`~pyasn1.error.PyAsn1Error`\n#:     On decoding errors\n#:\n#: Examples\n#: --------\n#: Decode BER serialisation without ASN.1 schema\n#:\n#: .. code-block:: pycon\n#:\n#:    >>> s, _ = decode(b'0\\t\\x02\\x01\\x01\\x02\\x01\\x02\\x02\\x01\\x03')\n#:    >>> str(s)\n#:    SequenceOf:\n#:     1 2 3\n#:\n#: Decode BER serialisation with ASN.1 schema\n#:\n#: .. code-block:: pycon\n#:\n#:    >>> seq = SequenceOf(componentType=Integer())\n#:    >>> s, _ = decode(b'0\\t\\x02\\x01\\x01\\x02\\x01\\x02\\x02\\x01\\x03', asn1Spec=seq)\n#:    >>> str(s)\n#:    SequenceOf:\n#:     1 2 3\n#:\ndecode = Decoder(tagMap, typeMap)\n\n# XXX\n# non-recursive decoding; return position rather than substrate\n"
  },
  {
    "path": "code/default/lib/noarch/pyasn1/codec/ber/encoder.py",
    "content": "#\n# This file is part of pyasn1 software.\n#\n# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>\n# License: http://snmplabs.com/pyasn1/license.html\n#\nfrom pyasn1 import debug\nfrom pyasn1 import error\nfrom pyasn1.codec.ber import eoo\nfrom pyasn1.compat.integer import to_bytes\nfrom pyasn1.compat.octets import (int2oct, oct2int, ints2octs, null,\n                                  str2octs, isOctetsType)\nfrom pyasn1.type import char\nfrom pyasn1.type import tag\nfrom pyasn1.type import univ\nfrom pyasn1.type import useful\n\n__all__ = ['encode']\n\n\nclass AbstractItemEncoder(object):\n    supportIndefLenMode = True\n\n    # An outcome of otherwise legit call `encodeFun(eoo.endOfOctets)`\n    eooIntegerSubstrate = (0, 0)\n    eooOctetsSubstrate = ints2octs(eooIntegerSubstrate)\n\n    # noinspection PyMethodMayBeStatic\n    def encodeTag(self, singleTag, isConstructed):\n        tagClass, tagFormat, tagId = singleTag\n        encodedTag = tagClass | tagFormat\n        if isConstructed:\n            encodedTag |= tag.tagFormatConstructed\n        if tagId < 31:\n            return encodedTag | tagId,\n        else:\n            substrate = tagId & 0x7f,\n            tagId >>= 7\n            while tagId:\n                substrate = (0x80 | (tagId & 0x7f),) + substrate\n                tagId >>= 7\n            return (encodedTag | 0x1F,) + substrate\n\n    def encodeLength(self, length, defMode):\n        if not defMode and self.supportIndefLenMode:\n            return (0x80,)\n        if length < 0x80:\n            return length,\n        else:\n            substrate = ()\n            while length:\n                substrate = (length & 0xff,) + substrate\n                length >>= 8\n            substrateLen = len(substrate)\n            if substrateLen > 126:\n                raise error.PyAsn1Error('Length octets overflow (%d)' % substrateLen)\n            return (0x80 | substrateLen,) + substrate\n\n    def encodeValue(self, value, asn1Spec, encodeFun, **options):\n        raise error.PyAsn1Error('Not implemented')\n\n    def encode(self, value, asn1Spec=None, encodeFun=None, **options):\n\n        if asn1Spec is None:\n            tagSet = value.tagSet\n        else:\n            tagSet = asn1Spec.tagSet\n\n        # untagged item?\n        if not tagSet:\n            substrate, isConstructed, isOctets = self.encodeValue(\n                value, asn1Spec, encodeFun, **options\n            )\n            return substrate\n\n        defMode = options.get('defMode', True)\n\n        for idx, singleTag in enumerate(tagSet.superTags):\n\n            defModeOverride = defMode\n\n            # base tag?\n            if not idx:\n                substrate, isConstructed, isOctets = self.encodeValue(\n                    value, asn1Spec, encodeFun, **options\n                )\n\n                if not substrate and isConstructed and options.get('ifNotEmpty', False):\n                    return substrate\n\n                # primitive form implies definite mode\n                if not isConstructed:\n                    defModeOverride = True\n\n            header = self.encodeTag(singleTag, isConstructed)\n            header += self.encodeLength(len(substrate), defModeOverride)\n\n            if isOctets:\n                substrate = ints2octs(header) + substrate\n\n                if not defModeOverride:\n                    substrate += self.eooOctetsSubstrate\n\n            else:\n                substrate = header + substrate\n\n                if not defModeOverride:\n                    substrate += self.eooIntegerSubstrate\n\n        if not isOctets:\n            substrate = ints2octs(substrate)\n\n        return substrate\n\n\nclass EndOfOctetsEncoder(AbstractItemEncoder):\n    def encodeValue(self, value, asn1Spec, encodeFun, **options):\n        return null, False, True\n\n\nclass BooleanEncoder(AbstractItemEncoder):\n    supportIndefLenMode = False\n\n    def encodeValue(self, value, asn1Spec, encodeFun, **options):\n        return value and (1,) or (0,), False, False\n\n\nclass IntegerEncoder(AbstractItemEncoder):\n    supportIndefLenMode = False\n    supportCompactZero = False\n\n    def encodeValue(self, value, asn1Spec, encodeFun, **options):\n        if value == 0:\n            # de-facto way to encode zero\n            if self.supportCompactZero:\n                return (), False, False\n            else:\n                return (0,), False, False\n\n        return to_bytes(int(value), signed=True), False, True\n\n\nclass BitStringEncoder(AbstractItemEncoder):\n    def encodeValue(self, value, asn1Spec, encodeFun, **options):\n        if asn1Spec is not None:\n            # TODO: try to avoid ASN.1 schema instantiation\n            value = asn1Spec.clone(value)\n\n        valueLength = len(value)\n        if valueLength % 8:\n            alignedValue = value << (8 - valueLength % 8)\n        else:\n            alignedValue = value\n\n        maxChunkSize = options.get('maxChunkSize', 0)\n        if not maxChunkSize or len(alignedValue) <= maxChunkSize * 8:\n            substrate = alignedValue.asOctets()\n            return int2oct(len(substrate) * 8 - valueLength) + substrate, False, True\n\n        baseTag = value.tagSet.baseTag\n\n        # strip off explicit tags\n        if baseTag:\n            tagSet = tag.TagSet(baseTag, baseTag)\n        else:\n            tagSet = tag.TagSet()\n\n        alignedValue = alignedValue.clone(tagSet=tagSet)\n\n        stop = 0\n        substrate = null\n        while stop < valueLength:\n            start = stop\n            stop = min(start + maxChunkSize * 8, valueLength)\n            substrate += encodeFun(alignedValue[start:stop], asn1Spec, **options)\n\n        return substrate, True, True\n\n\nclass OctetStringEncoder(AbstractItemEncoder):\n\n    def encodeValue(self, value, asn1Spec, encodeFun, **options):\n\n        if asn1Spec is None:\n            substrate = value.asOctets()\n\n        elif not isOctetsType(value):\n            substrate = asn1Spec.clone(value).asOctets()\n\n        else:\n            substrate = value\n\n        maxChunkSize = options.get('maxChunkSize', 0)\n\n        if not maxChunkSize or len(substrate) <= maxChunkSize:\n            return substrate, False, True\n\n        else:\n\n            # strip off explicit tags for inner chunks\n\n            if asn1Spec is None:\n                baseTag = value.tagSet.baseTag\n\n                # strip off explicit tags\n                if baseTag:\n                    tagSet = tag.TagSet(baseTag, baseTag)\n                else:\n                    tagSet = tag.TagSet()\n\n                asn1Spec = value.clone(tagSet=tagSet)\n\n            elif not isOctetsType(value):\n                baseTag = asn1Spec.tagSet.baseTag\n\n                # strip off explicit tags\n                if baseTag:\n                    tagSet = tag.TagSet(baseTag, baseTag)\n                else:\n                    tagSet = tag.TagSet()\n\n                asn1Spec = asn1Spec.clone(tagSet=tagSet)\n\n            pos = 0\n            substrate = null\n\n            while True:\n                chunk = value[pos:pos + maxChunkSize]\n                if not chunk:\n                    break\n\n                substrate += encodeFun(chunk, asn1Spec, **options)\n                pos += maxChunkSize\n\n            return substrate, True, True\n\n\nclass NullEncoder(AbstractItemEncoder):\n    supportIndefLenMode = False\n\n    def encodeValue(self, value, asn1Spec, encodeFun, **options):\n        return null, False, True\n\n\nclass ObjectIdentifierEncoder(AbstractItemEncoder):\n    supportIndefLenMode = False\n\n    def encodeValue(self, value, asn1Spec, encodeFun, **options):\n        if asn1Spec is not None:\n            value = asn1Spec.clone(value)\n\n        oid = value.asTuple()\n\n        # Build the first pair\n        try:\n            first = oid[0]\n            second = oid[1]\n\n        except IndexError:\n            raise error.PyAsn1Error('Short OID %s' % (value,))\n\n        if 0 <= second <= 39:\n            if first == 1:\n                oid = (second + 40,) + oid[2:]\n            elif first == 0:\n                oid = (second,) + oid[2:]\n            elif first == 2:\n                oid = (second + 80,) + oid[2:]\n            else:\n                raise error.PyAsn1Error('Impossible first/second arcs at %s' % (value,))\n        elif first == 2:\n            oid = (second + 80,) + oid[2:]\n        else:\n            raise error.PyAsn1Error('Impossible first/second arcs at %s' % (value,))\n\n        octets = ()\n\n        # Cycle through subIds\n        for subOid in oid:\n            if 0 <= subOid <= 127:\n                # Optimize for the common case\n                octets += (subOid,)\n            elif subOid > 127:\n                # Pack large Sub-Object IDs\n                res = (subOid & 0x7f,)\n                subOid >>= 7\n                while subOid:\n                    res = (0x80 | (subOid & 0x7f),) + res\n                    subOid >>= 7\n                # Add packed Sub-Object ID to resulted Object ID\n                octets += res\n            else:\n                raise error.PyAsn1Error('Negative OID arc %s at %s' % (subOid, value))\n\n        return octets, False, False\n\n\nclass RealEncoder(AbstractItemEncoder):\n    supportIndefLenMode = 0\n    binEncBase = 2  # set to None to choose encoding base automatically\n\n    @staticmethod\n    def _dropFloatingPoint(m, encbase, e):\n        ms, es = 1, 1\n        if m < 0:\n            ms = -1  # mantissa sign\n        if e < 0:\n            es = -1  # exponenta sign \n        m *= ms\n        if encbase == 8:\n            m *= 2 ** (abs(e) % 3 * es)\n            e = abs(e) // 3 * es\n        elif encbase == 16:\n            m *= 2 ** (abs(e) % 4 * es)\n            e = abs(e) // 4 * es\n\n        while True:\n            if int(m) != m:\n                m *= encbase\n                e -= 1\n                continue\n            break\n        return ms, int(m), encbase, e\n\n    def _chooseEncBase(self, value):\n        m, b, e = value\n        encBase = [2, 8, 16]\n        if value.binEncBase in encBase:\n            return self._dropFloatingPoint(m, value.binEncBase, e)\n        elif self.binEncBase in encBase:\n            return self._dropFloatingPoint(m, self.binEncBase, e)\n        # auto choosing base 2/8/16 \n        mantissa = [m, m, m]\n        exponenta = [e, e, e]\n        sign = 1\n        encbase = 2\n        e = float('inf')\n        for i in range(3):\n            (sign,\n             mantissa[i],\n             encBase[i],\n             exponenta[i]) = self._dropFloatingPoint(mantissa[i], encBase[i], exponenta[i])\n            if abs(exponenta[i]) < abs(e) or (abs(exponenta[i]) == abs(e) and mantissa[i] < m):\n                e = exponenta[i]\n                m = int(mantissa[i])\n                encbase = encBase[i]\n        return sign, m, encbase, e\n\n    def encodeValue(self, value, asn1Spec, encodeFun, **options):\n        if asn1Spec is not None:\n            value = asn1Spec.clone(value)\n\n        if value.isPlusInf:\n            return (0x40,), False, False\n        if value.isMinusInf:\n            return (0x41,), False, False\n        m, b, e = value\n        if not m:\n            return null, False, True\n        if b == 10:\n            return str2octs('\\x03%dE%s%d' % (m, e == 0 and '+' or '', e)), False, True\n        elif b == 2:\n            fo = 0x80  # binary encoding\n            ms, m, encbase, e = self._chooseEncBase(value)\n            if ms < 0:  # mantissa sign\n                fo |= 0x40  # sign bit\n            # exponenta & mantissa normalization\n            if encbase == 2:\n                while m & 0x1 == 0:\n                    m >>= 1\n                    e += 1\n            elif encbase == 8:\n                while m & 0x7 == 0:\n                    m >>= 3\n                    e += 1\n                fo |= 0x10\n            else:  # encbase = 16\n                while m & 0xf == 0:\n                    m >>= 4\n                    e += 1\n                fo |= 0x20\n            sf = 0  # scale factor\n            while m & 0x1 == 0:\n                m >>= 1\n                sf += 1\n            if sf > 3:\n                raise error.PyAsn1Error('Scale factor overflow')  # bug if raised\n            fo |= sf << 2\n            eo = null\n            if e == 0 or e == -1:\n                eo = int2oct(e & 0xff)\n            else:\n                while e not in (0, -1):\n                    eo = int2oct(e & 0xff) + eo\n                    e >>= 8\n                if e == 0 and eo and oct2int(eo[0]) & 0x80:\n                    eo = int2oct(0) + eo\n                if e == -1 and eo and not (oct2int(eo[0]) & 0x80):\n                    eo = int2oct(0xff) + eo\n            n = len(eo)\n            if n > 0xff:\n                raise error.PyAsn1Error('Real exponent overflow')\n            if n == 1:\n                pass\n            elif n == 2:\n                fo |= 1\n            elif n == 3:\n                fo |= 2\n            else:\n                fo |= 3\n                eo = int2oct(n & 0xff) + eo\n            po = null\n            while m:\n                po = int2oct(m & 0xff) + po\n                m >>= 8\n            substrate = int2oct(fo) + eo + po\n            return substrate, False, True\n        else:\n            raise error.PyAsn1Error('Prohibited Real base %s' % b)\n\n\nclass SequenceEncoder(AbstractItemEncoder):\n    omitEmptyOptionals = False\n\n    # TODO: handling three flavors of input is too much -- split over codecs\n\n    def encodeValue(self, value, asn1Spec, encodeFun, **options):\n\n        substrate = null\n\n        if asn1Spec is None:\n            # instance of ASN.1 schema\n            value.verifySizeSpec()\n\n            namedTypes = value.componentType\n\n            for idx, component in enumerate(value.values()):\n                if namedTypes:\n                    namedType = namedTypes[idx]\n\n                    if namedType.isOptional and not component.isValue:\n                            continue\n\n                    if namedType.isDefaulted and component == namedType.asn1Object:\n                            continue\n\n                    if self.omitEmptyOptionals:\n                        options.update(ifNotEmpty=namedType.isOptional)\n\n                chunk = encodeFun(component, asn1Spec, **options)\n\n                # wrap open type blob if needed\n                if namedTypes and namedType.openType:\n                    wrapType = namedType.asn1Object\n                    if wrapType.tagSet and not wrapType.isSameTypeWith(component):\n                        chunk = encodeFun(chunk, wrapType, **options)\n\n                substrate += chunk\n\n        else:\n            # bare Python value + ASN.1 schema\n            for idx, namedType in enumerate(asn1Spec.componentType.namedTypes):\n\n                try:\n                    component = value[namedType.name]\n\n                except KeyError:\n                    raise error.PyAsn1Error('Component name \"%s\" not found in %r' % (namedType.name, value))\n\n                if namedType.isOptional and namedType.name not in value:\n                    continue\n\n                if namedType.isDefaulted and component == namedType.asn1Object:\n                    continue\n\n                if self.omitEmptyOptionals:\n                    options.update(ifNotEmpty=namedType.isOptional)\n\n                chunk = encodeFun(component, asn1Spec[idx], **options)\n\n                # wrap open type blob if needed\n                if namedType.openType:\n                    wrapType = namedType.asn1Object\n                    if wrapType.tagSet and not wrapType.isSameTypeWith(component):\n                        chunk = encodeFun(chunk, wrapType, **options)\n\n                substrate += chunk\n\n        return substrate, True, True\n\n\nclass SequenceOfEncoder(AbstractItemEncoder):\n    def encodeValue(self, value, asn1Spec, encodeFun, **options):\n        if asn1Spec is None:\n            value.verifySizeSpec()\n        else:\n            asn1Spec = asn1Spec.componentType\n\n        substrate = null\n\n        for idx, component in enumerate(value):\n            substrate += encodeFun(value[idx], asn1Spec, **options)\n\n        return substrate, True, True\n\n\nclass ChoiceEncoder(AbstractItemEncoder):\n    def encodeValue(self, value, asn1Spec, encodeFun, **options):\n        if asn1Spec is None:\n            component = value.getComponent()\n        else:\n            names = [namedType.name for namedType in asn1Spec.componentType.namedTypes\n                     if namedType.name in value]\n            if len(names) != 1:\n                raise error.PyAsn1Error('%s components for Choice at %r' % (len(names) and 'Multiple ' or 'None ', value))\n\n            name = names[0]\n\n            component = value[name]\n            asn1Spec = asn1Spec[name]\n\n        return encodeFun(component, asn1Spec, **options), True, True\n\n\nclass AnyEncoder(OctetStringEncoder):\n    def encodeValue(self, value, asn1Spec, encodeFun, **options):\n        if asn1Spec is None:\n            value = value.asOctets()\n        elif not isOctetsType(value):\n            value = asn1Spec.clone(value).asOctets()\n\n        return value, not options.get('defMode', True), True\n\n\ntagMap = {\n    eoo.endOfOctets.tagSet: EndOfOctetsEncoder(),\n    univ.Boolean.tagSet: BooleanEncoder(),\n    univ.Integer.tagSet: IntegerEncoder(),\n    univ.BitString.tagSet: BitStringEncoder(),\n    univ.OctetString.tagSet: OctetStringEncoder(),\n    univ.Null.tagSet: NullEncoder(),\n    univ.ObjectIdentifier.tagSet: ObjectIdentifierEncoder(),\n    univ.Enumerated.tagSet: IntegerEncoder(),\n    univ.Real.tagSet: RealEncoder(),\n    # Sequence & Set have same tags as SequenceOf & SetOf\n    univ.SequenceOf.tagSet: SequenceOfEncoder(),\n    univ.SetOf.tagSet: SequenceOfEncoder(),\n    univ.Choice.tagSet: ChoiceEncoder(),\n    # character string types\n    char.UTF8String.tagSet: OctetStringEncoder(),\n    char.NumericString.tagSet: OctetStringEncoder(),\n    char.PrintableString.tagSet: OctetStringEncoder(),\n    char.TeletexString.tagSet: OctetStringEncoder(),\n    char.VideotexString.tagSet: OctetStringEncoder(),\n    char.IA5String.tagSet: OctetStringEncoder(),\n    char.GraphicString.tagSet: OctetStringEncoder(),\n    char.VisibleString.tagSet: OctetStringEncoder(),\n    char.GeneralString.tagSet: OctetStringEncoder(),\n    char.UniversalString.tagSet: OctetStringEncoder(),\n    char.BMPString.tagSet: OctetStringEncoder(),\n    # useful types\n    useful.ObjectDescriptor.tagSet: OctetStringEncoder(),\n    useful.GeneralizedTime.tagSet: OctetStringEncoder(),\n    useful.UTCTime.tagSet: OctetStringEncoder()\n}\n\n# Put in ambiguous & non-ambiguous types for faster codec lookup\ntypeMap = {\n    univ.Boolean.typeId: BooleanEncoder(),\n    univ.Integer.typeId: IntegerEncoder(),\n    univ.BitString.typeId: BitStringEncoder(),\n    univ.OctetString.typeId: OctetStringEncoder(),\n    univ.Null.typeId: NullEncoder(),\n    univ.ObjectIdentifier.typeId: ObjectIdentifierEncoder(),\n    univ.Enumerated.typeId: IntegerEncoder(),\n    univ.Real.typeId: RealEncoder(),\n    # Sequence & Set have same tags as SequenceOf & SetOf\n    univ.Set.typeId: SequenceEncoder(),\n    univ.SetOf.typeId: SequenceOfEncoder(),\n    univ.Sequence.typeId: SequenceEncoder(),\n    univ.SequenceOf.typeId: SequenceOfEncoder(),\n    univ.Choice.typeId: ChoiceEncoder(),\n    univ.Any.typeId: AnyEncoder(),\n    # character string types\n    char.UTF8String.typeId: OctetStringEncoder(),\n    char.NumericString.typeId: OctetStringEncoder(),\n    char.PrintableString.typeId: OctetStringEncoder(),\n    char.TeletexString.typeId: OctetStringEncoder(),\n    char.VideotexString.typeId: OctetStringEncoder(),\n    char.IA5String.typeId: OctetStringEncoder(),\n    char.GraphicString.typeId: OctetStringEncoder(),\n    char.VisibleString.typeId: OctetStringEncoder(),\n    char.GeneralString.typeId: OctetStringEncoder(),\n    char.UniversalString.typeId: OctetStringEncoder(),\n    char.BMPString.typeId: OctetStringEncoder(),\n    # useful types\n    useful.ObjectDescriptor.typeId: OctetStringEncoder(),\n    useful.GeneralizedTime.typeId: OctetStringEncoder(),\n    useful.UTCTime.typeId: OctetStringEncoder()\n}\n\n\nclass Encoder(object):\n    fixedDefLengthMode = None\n    fixedChunkSize = None\n\n    # noinspection PyDefaultArgument\n    def __init__(self, tagMap, typeMap={}):\n        self.__tagMap = tagMap\n        self.__typeMap = typeMap\n\n    def __call__(self, value, asn1Spec=None, **options):\n        try:\n            if asn1Spec is None:\n                typeId = value.typeId\n            else:\n                typeId = asn1Spec.typeId\n\n        except AttributeError:\n            raise error.PyAsn1Error('Value %r is not ASN.1 type instance '\n                                    'and \"asn1Spec\" not given' % (value,))\n\n        if debug.logger & debug.flagEncoder:\n            logger = debug.logger\n        else:\n            logger = None\n\n        if logger:\n            logger('encoder called in %sdef mode, chunk size %s for '\n                   'type %s, value:\\n%s' % (not options.get('defMode', True) and 'in' or '', options.get('maxChunkSize', 0), asn1Spec is None and value.prettyPrintType() or asn1Spec.prettyPrintType(), value))\n\n        if self.fixedDefLengthMode is not None:\n            options.update(defMode=self.fixedDefLengthMode)\n\n        if self.fixedChunkSize is not None:\n            options.update(maxChunkSize=self.fixedChunkSize)\n\n\n        try:\n            concreteEncoder = self.__typeMap[typeId]\n\n            if logger:\n                logger('using value codec %s chosen by type ID %s' % (concreteEncoder.__class__.__name__, typeId))\n\n        except KeyError:\n            if asn1Spec is None:\n                tagSet = value.tagSet\n            else:\n                tagSet = asn1Spec.tagSet\n\n            # use base type for codec lookup to recover untagged types\n            baseTagSet = tag.TagSet(tagSet.baseTag, tagSet.baseTag)\n\n            try:\n                concreteEncoder = self.__tagMap[baseTagSet]\n\n            except KeyError:\n                raise error.PyAsn1Error('No encoder for %r (%s)' % (value, tagSet))\n\n            if logger:\n                logger('using value codec %s chosen by tagSet %s' % (concreteEncoder.__class__.__name__, tagSet))\n\n        substrate = concreteEncoder.encode(value, asn1Spec, self, **options)\n\n        if logger:\n            logger('codec %s built %s octets of substrate: %s\\nencoder completed' % (concreteEncoder, len(substrate), debug.hexdump(substrate)))\n\n        return substrate\n\n#: Turns ASN.1 object into BER octet stream.\n#:\n#: Takes any ASN.1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative)\n#: walks all its components recursively and produces a BER octet stream.\n#:\n#: Parameters\n#: ----------\n#: value: either a Python or pyasn1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative)\n#:     A Python or pyasn1 object to encode. If Python object is given, `asnSpec`\n#:     parameter is required to guide the encoding process.\n#:\n#: Keyword Args\n#: ------------\n#: asn1Spec:\n#:     Optional ASN.1 schema or value object e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative\n#:\n#: defMode: :py:class:`bool`\n#:     If `False`, produces indefinite length encoding\n#:\n#: maxChunkSize: :py:class:`int`\n#:     Maximum chunk size in chunked encoding mode (0 denotes unlimited chunk size)\n#:\n#: Returns\n#: -------\n#: : :py:class:`bytes` (Python 3) or :py:class:`str` (Python 2)\n#:     Given ASN.1 object encoded into BER octetstream\n#:\n#: Raises\n#: ------\n#: :py:class:`~pyasn1.error.PyAsn1Error`\n#:     On encoding errors\n#:\n#: Examples\n#: --------\n#: Encode Python value into BER with ASN.1 schema\n#:\n#: .. code-block:: pycon\n#:\n#:    >>> seq = SequenceOf(componentType=Integer())\n#:    >>> encode([1, 2, 3], asn1Spec=seq)\n#:    b'0\\t\\x02\\x01\\x01\\x02\\x01\\x02\\x02\\x01\\x03'\n#:\n#: Encode ASN.1 value object into BER\n#:\n#: .. code-block:: pycon\n#:\n#:    >>> seq = SequenceOf(componentType=Integer())\n#:    >>> seq.extend([1, 2, 3])\n#:    >>> encode(seq)\n#:    b'0\\t\\x02\\x01\\x01\\x02\\x01\\x02\\x02\\x01\\x03'\n#:\nencode = Encoder(tagMap, typeMap)\n"
  },
  {
    "path": "code/default/lib/noarch/pyasn1/codec/ber/eoo.py",
    "content": "#\n# This file is part of pyasn1 software.\n#\n# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>\n# License: http://snmplabs.com/pyasn1/license.html\n#\nfrom pyasn1.type import base\nfrom pyasn1.type import tag\n\n__all__ = ['endOfOctets']\n\n\nclass EndOfOctets(base.AbstractSimpleAsn1Item):\n    defaultValue = 0\n    tagSet = tag.initTagSet(\n        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x00)\n    )\n\n    _instance = None\n\n    def __new__(cls, *args, **kwargs):\n        if cls._instance is None:\n            cls._instance = object.__new__(cls, *args, **kwargs)\n\n        return cls._instance\n\n\nendOfOctets = EndOfOctets()\n"
  },
  {
    "path": "code/default/lib/noarch/pyasn1/codec/cer/__init__.py",
    "content": "# This file is necessary to make this directory a package.\n"
  },
  {
    "path": "code/default/lib/noarch/pyasn1/codec/cer/decoder.py",
    "content": "#\n# This file is part of pyasn1 software.\n#\n# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>\n# License: http://snmplabs.com/pyasn1/license.html\n#\nfrom pyasn1 import error\nfrom pyasn1.codec.ber import decoder\nfrom pyasn1.compat.octets import oct2int\nfrom pyasn1.type import univ\n\n__all__ = ['decode']\n\n\nclass BooleanDecoder(decoder.AbstractSimpleDecoder):\n    protoComponent = univ.Boolean(0)\n\n    def valueDecoder(self, substrate, asn1Spec,\n                     tagSet=None, length=None, state=None,\n                     decodeFun=None, substrateFun=None,\n                     **options):\n        head, tail = substrate[:length], substrate[length:]\n        if not head or length != 1:\n            raise error.PyAsn1Error('Not single-octet Boolean payload')\n        byte = oct2int(head[0])\n        # CER/DER specifies encoding of TRUE as 0xFF and FALSE as 0x0, while\n        # BER allows any non-zero value as TRUE; cf. sections 8.2.2. and 11.1 \n        # in https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf\n        if byte == 0xff:\n            value = 1\n        elif byte == 0x00:\n            value = 0\n        else:\n            raise error.PyAsn1Error('Unexpected Boolean payload: %s' % byte)\n        return self._createComponent(asn1Spec, tagSet, value, **options), tail\n\n# TODO: prohibit non-canonical encoding\nBitStringDecoder = decoder.BitStringDecoder\nOctetStringDecoder = decoder.OctetStringDecoder\nRealDecoder = decoder.RealDecoder\n\ntagMap = decoder.tagMap.copy()\ntagMap.update(\n    {univ.Boolean.tagSet: BooleanDecoder(),\n     univ.BitString.tagSet: BitStringDecoder(),\n     univ.OctetString.tagSet: OctetStringDecoder(),\n     univ.Real.tagSet: RealDecoder()}\n)\n\ntypeMap = decoder.typeMap.copy()\n\n# Put in non-ambiguous types for faster codec lookup\nfor typeDecoder in list(tagMap.values()):\n    if typeDecoder.protoComponent is not None:\n        typeId = typeDecoder.protoComponent.__class__.typeId\n        if typeId is not None and typeId not in typeMap:\n            typeMap[typeId] = typeDecoder\n\n\nclass Decoder(decoder.Decoder):\n    pass\n\n\n#: Turns CER octet stream into an ASN.1 object.\n#:\n#: Takes CER octet-stream and decode it into an ASN.1 object\n#: (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative) which\n#: may be a scalar or an arbitrary nested structure.\n#:\n#: Parameters\n#: ----------\n#: substrate: :py:class:`bytes` (Python 3) or :py:class:`str` (Python 2)\n#:     CER octet-stream\n#:\n#: Keyword Args\n#: ------------\n#: asn1Spec: any pyasn1 type object e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative\n#:     A pyasn1 type object to act as a template guiding the decoder. Depending on the ASN.1 structure\n#:     being decoded, *asn1Spec* may or may not be required. Most common reason for\n#:     it to require is that ASN.1 structure is encoded in *IMPLICIT* tagging mode.\n#:\n#: Returns\n#: -------\n#: : :py:class:`tuple`\n#:     A tuple of pyasn1 object recovered from CER substrate (:py:class:`~pyasn1.type.base.PyAsn1Item` derivative)\n#:     and the unprocessed trailing portion of the *substrate* (may be empty)\n#:\n#: Raises\n#: ------\n#: :py:class:`~pyasn1.error.PyAsn1Error`\n#:     On decoding errors\n#:\n#: Examples\n#: --------\n#: Decode CER serialisation without ASN.1 schema\n#:\n#: .. code-block:: pycon\n#:\n#:    >>> s, _ = decode(b'0\\x80\\x02\\x01\\x01\\x02\\x01\\x02\\x02\\x01\\x03\\x00\\x00')\n#:    >>> str(s)\n#:    SequenceOf:\n#:     1 2 3\n#:\n#: Decode CER serialisation with ASN.1 schema\n#:\n#: .. code-block:: pycon\n#:\n#:    >>> seq = SequenceOf(componentType=Integer())\n#:    >>> s, _ = decode(b'0\\x80\\x02\\x01\\x01\\x02\\x01\\x02\\x02\\x01\\x03\\x00\\x00', asn1Spec=seq)\n#:    >>> str(s)\n#:    SequenceOf:\n#:     1 2 3\n#:\ndecode = Decoder(tagMap, decoder.typeMap)\n"
  },
  {
    "path": "code/default/lib/noarch/pyasn1/codec/cer/encoder.py",
    "content": "#\n# This file is part of pyasn1 software.\n#\n# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>\n# License: http://snmplabs.com/pyasn1/license.html\n#\nfrom pyasn1 import error\nfrom pyasn1.codec.ber import encoder\nfrom pyasn1.compat.octets import str2octs, null\nfrom pyasn1.type import univ\nfrom pyasn1.type import useful\n\n__all__ = ['encode']\n\n\nclass BooleanEncoder(encoder.IntegerEncoder):\n    def encodeValue(self, value, asn1Spec, encodeFun, **options):\n        if value == 0:\n            substrate = (0,)\n        else:\n            substrate = (255,)\n        return substrate, False, False\n\n\nclass RealEncoder(encoder.RealEncoder):\n    def _chooseEncBase(self, value):\n        m, b, e = value\n        return self._dropFloatingPoint(m, b, e)\n\n\n# specialized GeneralStringEncoder here\n\nclass TimeEncoderMixIn(object):\n    zchar, = str2octs('Z')\n    pluschar, = str2octs('+')\n    minuschar, = str2octs('-')\n    commachar, = str2octs(',')\n    minLength = 12\n    maxLength = 19\n\n    def encodeValue(self, value, asn1Spec, encodeFun, **options):\n        # Encoding constraints:\n        # - minutes are mandatory, seconds are optional\n        # - subseconds must NOT be zero\n        # - no hanging fraction dot\n        # - time in UTC (Z)\n        # - only dot is allowed for fractions\n\n        if asn1Spec is not None:\n            value = asn1Spec.clone(value)\n\n        octets = value.asOctets()\n\n        if not self.minLength < len(octets) < self.maxLength:\n            raise error.PyAsn1Error('Length constraint violated: %r' % value)\n\n        if self.pluschar in octets or self.minuschar in octets:\n            raise error.PyAsn1Error('Must be UTC time: %r' % octets)\n\n        if octets[-1] != self.zchar:\n            raise error.PyAsn1Error('Missing \"Z\" time zone specifier: %r' % octets)\n\n        if self.commachar in octets:\n            raise error.PyAsn1Error('Comma in fractions disallowed: %r' % value)\n\n        options.update(maxChunkSize=1000)\n\n        return encoder.OctetStringEncoder.encodeValue(\n            self, value, asn1Spec, encodeFun, **options\n        )\n\n\nclass GeneralizedTimeEncoder(TimeEncoderMixIn, encoder.OctetStringEncoder):\n    minLength = 12\n    maxLength = 19\n\n\nclass UTCTimeEncoder(TimeEncoderMixIn, encoder.OctetStringEncoder):\n    minLength = 10\n    maxLength = 14\n\n\nclass SetEncoder(encoder.SequenceEncoder):\n    @staticmethod\n    def _componentSortKey(componentAndType):\n        \"\"\"Sort SET components by tag\n\n        Sort regardless of the Choice value (static sort)\n        \"\"\"\n        component, asn1Spec = componentAndType\n\n        if asn1Spec is None:\n            asn1Spec = component\n\n        if asn1Spec.typeId == univ.Choice.typeId and not asn1Spec.tagSet:\n            if asn1Spec.tagSet:\n                return asn1Spec.tagSet\n            else:\n                return asn1Spec.componentType.minTagSet\n        else:\n            return asn1Spec.tagSet\n\n    def encodeValue(self, value, asn1Spec, encodeFun, **options):\n\n        substrate = null\n\n        comps = []\n        compsMap = {}\n\n        if asn1Spec is None:\n            # instance of ASN.1 schema\n            value.verifySizeSpec()\n\n            namedTypes = value.componentType\n\n            for idx, component in enumerate(value.values()):\n                if namedTypes:\n                    namedType = namedTypes[idx]\n\n                    if namedType.isOptional and not component.isValue:\n                            continue\n\n                    if namedType.isDefaulted and component == namedType.asn1Object:\n                            continue\n\n                    compsMap[id(component)] = namedType\n\n                else:\n                    compsMap[id(component)] = None\n\n                comps.append((component, asn1Spec))\n\n        else:\n            # bare Python value + ASN.1 schema\n            for idx, namedType in enumerate(asn1Spec.componentType.namedTypes):\n\n                try:\n                    component = value[namedType.name]\n\n                except KeyError:\n                    raise error.PyAsn1Error('Component name \"%s\" not found in %r' % (namedType.name, value))\n\n                if namedType.isOptional and namedType.name not in value:\n                    continue\n\n                if namedType.isDefaulted and component == namedType.asn1Object:\n                    continue\n\n                compsMap[id(component)] = namedType\n                comps.append((component, asn1Spec[idx]))\n\n        for comp, compType in sorted(comps, key=self._componentSortKey):\n            namedType = compsMap[id(comp)]\n\n            if namedType:\n                options.update(ifNotEmpty=namedType.isOptional)\n\n            chunk = encodeFun(comp, compType, **options)\n\n            # wrap open type blob if needed\n            if namedType and namedType.openType:\n                wrapType = namedType.asn1Object\n                if wrapType.tagSet and not wrapType.isSameTypeWith(comp):\n                    chunk = encodeFun(chunk, wrapType, **options)\n\n            substrate += chunk\n\n        return substrate, True, True\n\n\nclass SetOfEncoder(encoder.SequenceOfEncoder):\n    def encodeValue(self, value, asn1Spec, encodeFun, **options):\n        if asn1Spec is None:\n            value.verifySizeSpec()\n        else:\n            asn1Spec = asn1Spec.componentType\n\n        components = [encodeFun(x, asn1Spec, **options)\n                      for x in value]\n\n        # sort by serialised and padded components\n        if len(components) > 1:\n            zero = str2octs('\\x00')\n            maxLen = max(list(map(len, components)))\n            paddedComponents = [\n                (x.ljust(maxLen, zero), x) for x in components\n                ]\n            paddedComponents.sort(key=lambda x: x[0])\n\n            components = [x[1] for x in paddedComponents]\n\n        substrate = null.join(components)\n\n        return substrate, True, True\n\n\nclass SequenceEncoder(encoder.SequenceEncoder):\n    omitEmptyOptionals = True\n\n\nclass SequenceOfEncoder(encoder.SequenceOfEncoder):\n    def encodeValue(self, value, asn1Spec, encodeFun, **options):\n\n        if options.get('ifNotEmpty', False) and not len(value):\n            return null, True, True\n\n        if asn1Spec is None:\n            value.verifySizeSpec()\n        else:\n            asn1Spec = asn1Spec.componentType\n\n        substrate = null\n\n        for idx, component in enumerate(value):\n            substrate += encodeFun(value[idx], asn1Spec, **options)\n\n        return substrate, True, True\n\n\ntagMap = encoder.tagMap.copy()\ntagMap.update({\n    univ.Boolean.tagSet: BooleanEncoder(),\n    univ.Real.tagSet: RealEncoder(),\n    useful.GeneralizedTime.tagSet: GeneralizedTimeEncoder(),\n    useful.UTCTime.tagSet: UTCTimeEncoder(),\n    # Sequence & Set have same tags as SequenceOf & SetOf\n    univ.SetOf.tagSet: SetOfEncoder(),\n    univ.Sequence.typeId: SequenceEncoder()\n})\n\ntypeMap = encoder.typeMap.copy()\ntypeMap.update({\n    univ.Boolean.typeId: BooleanEncoder(),\n    univ.Real.typeId: RealEncoder(),\n    useful.GeneralizedTime.typeId: GeneralizedTimeEncoder(),\n    useful.UTCTime.typeId: UTCTimeEncoder(),\n    # Sequence & Set have same tags as SequenceOf & SetOf\n    univ.Set.typeId: SetEncoder(),\n    univ.SetOf.typeId: SetOfEncoder(),\n    univ.Sequence.typeId: SequenceEncoder(),\n    univ.SequenceOf.typeId: SequenceOfEncoder()\n})\n\n\nclass Encoder(encoder.Encoder):\n    fixedDefLengthMode = False\n    fixedChunkSize = 1000\n\n#: Turns ASN.1 object into CER octet stream.\n#:\n#: Takes any ASN.1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative)\n#: walks all its components recursively and produces a CER octet stream.\n#:\n#: Parameters\n#: ----------\n#: value: either a Python or pyasn1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative)\n#:     A Python or pyasn1 object to encode. If Python object is given, `asnSpec`\n#:     parameter is required to guide the encoding process.\n#:\n#: Keyword Args\n#: ------------\n#: asn1Spec:\n#:     Optional ASN.1 schema or value object e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative\n#:\n#: Returns\n#: -------\n#: : :py:class:`bytes` (Python 3) or :py:class:`str` (Python 2)\n#:     Given ASN.1 object encoded into BER octet-stream\n#:\n#: Raises\n#: ------\n#: :py:class:`~pyasn1.error.PyAsn1Error`\n#:     On encoding errors\n#:\n#: Examples\n#: --------\n#: Encode Python value into CER with ASN.1 schema\n#:\n#: .. code-block:: pycon\n#:\n#:    >>> seq = SequenceOf(componentType=Integer())\n#:    >>> encode([1, 2, 3], asn1Spec=seq)\n#:    b'0\\x80\\x02\\x01\\x01\\x02\\x01\\x02\\x02\\x01\\x03\\x00\\x00'\n#:\n#: Encode ASN.1 value object into CER\n#:\n#: .. code-block:: pycon\n#:\n#:    >>> seq = SequenceOf(componentType=Integer())\n#:    >>> seq.extend([1, 2, 3])\n#:    >>> encode(seq)\n#:    b'0\\x80\\x02\\x01\\x01\\x02\\x01\\x02\\x02\\x01\\x03\\x00\\x00'\n#:\nencode = Encoder(tagMap, typeMap)\n\n# EncoderFactory queries class instance and builds a map of tags -> encoders\n"
  },
  {
    "path": "code/default/lib/noarch/pyasn1/codec/der/__init__.py",
    "content": "# This file is necessary to make this directory a package.\n"
  },
  {
    "path": "code/default/lib/noarch/pyasn1/codec/der/decoder.py",
    "content": "#\n# This file is part of pyasn1 software.\n#\n# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>\n# License: http://snmplabs.com/pyasn1/license.html\n#\nfrom pyasn1.codec.cer import decoder\nfrom pyasn1.type import univ\n\n__all__ = ['decode']\n\n\nclass BitStringDecoder(decoder.BitStringDecoder):\n    supportConstructedForm = False\n\n\nclass OctetStringDecoder(decoder.OctetStringDecoder):\n    supportConstructedForm = False\n\n# TODO: prohibit non-canonical encoding\nRealDecoder = decoder.RealDecoder\n\ntagMap = decoder.tagMap.copy()\ntagMap.update(\n    {univ.BitString.tagSet: BitStringDecoder(),\n     univ.OctetString.tagSet: OctetStringDecoder(),\n     univ.Real.tagSet: RealDecoder()}\n)\n\ntypeMap = decoder.typeMap.copy()\n\n# Put in non-ambiguous types for faster codec lookup\nfor typeDecoder in list(tagMap.values()):\n    if typeDecoder.protoComponent is not None:\n        typeId = typeDecoder.protoComponent.__class__.typeId\n        if typeId is not None and typeId not in typeMap:\n            typeMap[typeId] = typeDecoder\n\n\nclass Decoder(decoder.Decoder):\n    supportIndefLength = False\n\n\n#: Turns DER octet stream into an ASN.1 object.\n#:\n#: Takes DER octet-stream and decode it into an ASN.1 object\n#: (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative) which\n#: may be a scalar or an arbitrary nested structure.\n#:\n#: Parameters\n#: ----------\n#: substrate: :py:class:`bytes` (Python 3) or :py:class:`str` (Python 2)\n#:     DER octet-stream\n#:\n#: Keyword Args\n#: ------------\n#: asn1Spec: any pyasn1 type object e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative\n#:     A pyasn1 type object to act as a template guiding the decoder. Depending on the ASN.1 structure\n#:     being decoded, *asn1Spec* may or may not be required. Most common reason for\n#:     it to require is that ASN.1 structure is encoded in *IMPLICIT* tagging mode.\n#:\n#: Returns\n#: -------\n#: : :py:class:`tuple`\n#:     A tuple of pyasn1 object recovered from DER substrate (:py:class:`~pyasn1.type.base.PyAsn1Item` derivative)\n#:     and the unprocessed trailing portion of the *substrate* (may be empty)\n#:\n#: Raises\n#: ------\n#: :py:class:`~pyasn1.error.PyAsn1Error`\n#:     On decoding errors\n#:\n#: Examples\n#: --------\n#: Decode DER serialisation without ASN.1 schema\n#:\n#: .. code-block:: pycon\n#:\n#:    >>> s, _ = decode(b'0\\t\\x02\\x01\\x01\\x02\\x01\\x02\\x02\\x01\\x03')\n#:    >>> str(s)\n#:    SequenceOf:\n#:     1 2 3\n#:\n#: Decode DER serialisation with ASN.1 schema\n#:\n#: .. code-block:: pycon\n#:\n#:    >>> seq = SequenceOf(componentType=Integer())\n#:    >>> s, _ = decode(b'0\\t\\x02\\x01\\x01\\x02\\x01\\x02\\x02\\x01\\x03', asn1Spec=seq)\n#:    >>> str(s)\n#:    SequenceOf:\n#:     1 2 3\n#:\ndecode = Decoder(tagMap, typeMap)\n"
  },
  {
    "path": "code/default/lib/noarch/pyasn1/codec/der/encoder.py",
    "content": "#\n# This file is part of pyasn1 software.\n#\n# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>\n# License: http://snmplabs.com/pyasn1/license.html\n#\nfrom pyasn1 import error\nfrom pyasn1.codec.cer import encoder\nfrom pyasn1.type import univ\n\n__all__ = ['encode']\n\n\nclass SetEncoder(encoder.SetEncoder):\n    @staticmethod\n    def _componentSortKey(componentAndType):\n        \"\"\"Sort SET components by tag\n\n        Sort depending on the actual Choice value (dynamic sort)\n        \"\"\"\n        component, asn1Spec = componentAndType\n\n        if asn1Spec is None:\n            compType = component\n        else:\n            compType = asn1Spec\n\n        if compType.typeId == univ.Choice.typeId and not compType.tagSet:\n            if asn1Spec is None:\n                return component.getComponent().tagSet\n            else:\n                # TODO: move out of sorting key function\n                names = [namedType.name for namedType in asn1Spec.componentType.namedTypes\n                         if namedType.name in component]\n                if len(names) != 1:\n                    raise error.PyAsn1Error(\n                        '%s components for Choice at %r' % (len(names) and 'Multiple ' or 'None ', component))\n\n                # TODO: support nested CHOICE ordering\n                return asn1Spec[names[0]].tagSet\n\n        else:\n            return compType.tagSet\n\ntagMap = encoder.tagMap.copy()\ntagMap.update({\n    # Set & SetOf have same tags\n    univ.Set.tagSet: SetEncoder()\n})\n\ntypeMap = encoder.typeMap.copy()\ntypeMap.update({\n    # Set & SetOf have same tags\n    univ.Set.typeId: SetEncoder()\n})\n\n\nclass Encoder(encoder.Encoder):\n    fixedDefLengthMode = True\n    fixedChunkSize = 0\n\n#: Turns ASN.1 object into DER octet stream.\n#:\n#: Takes any ASN.1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative)\n#: walks all its components recursively and produces a DER octet stream.\n#:\n#: Parameters\n#: ----------\n#: value: either a Python or pyasn1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative)\n#:     A Python or pyasn1 object to encode. If Python object is given, `asnSpec`\n#:     parameter is required to guide the encoding process.\n#:\n#: Keyword Args\n#: ------------\n#: asn1Spec:\n#:     Optional ASN.1 schema or value object e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative\n#:\n#: Returns\n#: -------\n#: : :py:class:`bytes` (Python 3) or :py:class:`str` (Python 2)\n#:     Given ASN.1 object encoded into BER octet-stream\n#:\n#: Raises\n#: ------\n#: :py:class:`~pyasn1.error.PyAsn1Error`\n#:     On encoding errors\n#:\n#: Examples\n#: --------\n#: Encode Python value into DER with ASN.1 schema\n#:\n#: .. code-block:: pycon\n#:\n#:    >>> seq = SequenceOf(componentType=Integer())\n#:    >>> encode([1, 2, 3], asn1Spec=seq)\n#:    b'0\\t\\x02\\x01\\x01\\x02\\x01\\x02\\x02\\x01\\x03'\n#:\n#: Encode ASN.1 value object into DER\n#:\n#: .. code-block:: pycon\n#:\n#:    >>> seq = SequenceOf(componentType=Integer())\n#:    >>> seq.extend([1, 2, 3])\n#:    >>> encode(seq)\n#:    b'0\\t\\x02\\x01\\x01\\x02\\x01\\x02\\x02\\x01\\x03'\n#:\nencode = Encoder(tagMap, typeMap)\n"
  },
  {
    "path": "code/default/lib/noarch/pyasn1/codec/native/__init__.py",
    "content": "# This file is necessary to make this directory a package.\n"
  },
  {
    "path": "code/default/lib/noarch/pyasn1/codec/native/decoder.py",
    "content": "#\n# This file is part of pyasn1 software.\n#\n# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>\n# License: http://snmplabs.com/pyasn1/license.html\n#\nfrom pyasn1 import debug\nfrom pyasn1 import error\nfrom pyasn1.type import base\nfrom pyasn1.type import char\nfrom pyasn1.type import tag\nfrom pyasn1.type import univ\nfrom pyasn1.type import useful\n\n__all__ = ['decode']\n\n\nclass AbstractScalarDecoder(object):\n    def __call__(self, pyObject, asn1Spec, decodeFun=None, **options):\n        return asn1Spec.clone(pyObject)\n\n\nclass BitStringDecoder(AbstractScalarDecoder):\n    def __call__(self, pyObject, asn1Spec, decodeFun=None, **options):\n        return asn1Spec.clone(univ.BitString.fromBinaryString(pyObject))\n\n\nclass SequenceOrSetDecoder(object):\n    def __call__(self, pyObject, asn1Spec, decodeFun=None, **options):\n        asn1Value = asn1Spec.clone()\n\n        componentsTypes = asn1Spec.componentType\n\n        for field in asn1Value:\n            if field in pyObject:\n                asn1Value[field] = decodeFun(pyObject[field], componentsTypes[field].asn1Object, **options)\n\n        return asn1Value\n\n\nclass SequenceOfOrSetOfDecoder(object):\n    def __call__(self, pyObject, asn1Spec, decodeFun=None, **options):\n        asn1Value = asn1Spec.clone()\n\n        for pyValue in pyObject:\n            asn1Value.append(decodeFun(pyValue, asn1Spec.componentType), **options)\n\n        return asn1Value\n\n\nclass ChoiceDecoder(object):\n    def __call__(self, pyObject, asn1Spec, decodeFun=None, **options):\n        asn1Value = asn1Spec.clone()\n\n        componentsTypes = asn1Spec.componentType\n\n        for field in pyObject:\n            if field in componentsTypes:\n                asn1Value[field] = decodeFun(pyObject[field], componentsTypes[field].asn1Object, **options)\n                break\n\n        return asn1Value\n\n\ntagMap = {\n    univ.Integer.tagSet: AbstractScalarDecoder(),\n    univ.Boolean.tagSet: AbstractScalarDecoder(),\n    univ.BitString.tagSet: BitStringDecoder(),\n    univ.OctetString.tagSet: AbstractScalarDecoder(),\n    univ.Null.tagSet: AbstractScalarDecoder(),\n    univ.ObjectIdentifier.tagSet: AbstractScalarDecoder(),\n    univ.Enumerated.tagSet: AbstractScalarDecoder(),\n    univ.Real.tagSet: AbstractScalarDecoder(),\n    univ.Sequence.tagSet: SequenceOrSetDecoder(),  # conflicts with SequenceOf\n    univ.Set.tagSet: SequenceOrSetDecoder(),  # conflicts with SetOf\n    univ.Choice.tagSet: ChoiceDecoder(),  # conflicts with Any\n    # character string types\n    char.UTF8String.tagSet: AbstractScalarDecoder(),\n    char.NumericString.tagSet: AbstractScalarDecoder(),\n    char.PrintableString.tagSet: AbstractScalarDecoder(),\n    char.TeletexString.tagSet: AbstractScalarDecoder(),\n    char.VideotexString.tagSet: AbstractScalarDecoder(),\n    char.IA5String.tagSet: AbstractScalarDecoder(),\n    char.GraphicString.tagSet: AbstractScalarDecoder(),\n    char.VisibleString.tagSet: AbstractScalarDecoder(),\n    char.GeneralString.tagSet: AbstractScalarDecoder(),\n    char.UniversalString.tagSet: AbstractScalarDecoder(),\n    char.BMPString.tagSet: AbstractScalarDecoder(),\n    # useful types\n    useful.ObjectDescriptor.tagSet: AbstractScalarDecoder(),\n    useful.GeneralizedTime.tagSet: AbstractScalarDecoder(),\n    useful.UTCTime.tagSet: AbstractScalarDecoder()\n}\n\n# Put in ambiguous & non-ambiguous types for faster codec lookup\ntypeMap = {\n    univ.Integer.typeId: AbstractScalarDecoder(),\n    univ.Boolean.typeId: AbstractScalarDecoder(),\n    univ.BitString.typeId: BitStringDecoder(),\n    univ.OctetString.typeId: AbstractScalarDecoder(),\n    univ.Null.typeId: AbstractScalarDecoder(),\n    univ.ObjectIdentifier.typeId: AbstractScalarDecoder(),\n    univ.Enumerated.typeId: AbstractScalarDecoder(),\n    univ.Real.typeId: AbstractScalarDecoder(),\n    # ambiguous base types\n    univ.Set.typeId: SequenceOrSetDecoder(),\n    univ.SetOf.typeId: SequenceOfOrSetOfDecoder(),\n    univ.Sequence.typeId: SequenceOrSetDecoder(),\n    univ.SequenceOf.typeId: SequenceOfOrSetOfDecoder(),\n    univ.Choice.typeId: ChoiceDecoder(),\n    univ.Any.typeId: AbstractScalarDecoder(),\n    # character string types\n    char.UTF8String.typeId: AbstractScalarDecoder(),\n    char.NumericString.typeId: AbstractScalarDecoder(),\n    char.PrintableString.typeId: AbstractScalarDecoder(),\n    char.TeletexString.typeId: AbstractScalarDecoder(),\n    char.VideotexString.typeId: AbstractScalarDecoder(),\n    char.IA5String.typeId: AbstractScalarDecoder(),\n    char.GraphicString.typeId: AbstractScalarDecoder(),\n    char.VisibleString.typeId: AbstractScalarDecoder(),\n    char.GeneralString.typeId: AbstractScalarDecoder(),\n    char.UniversalString.typeId: AbstractScalarDecoder(),\n    char.BMPString.typeId: AbstractScalarDecoder(),\n    # useful types\n    useful.ObjectDescriptor.typeId: AbstractScalarDecoder(),\n    useful.GeneralizedTime.typeId: AbstractScalarDecoder(),\n    useful.UTCTime.typeId: AbstractScalarDecoder()\n}\n\n\nclass Decoder(object):\n\n    # noinspection PyDefaultArgument\n    def __init__(self, tagMap, typeMap):\n        self.__tagMap = tagMap\n        self.__typeMap = typeMap\n\n    def __call__(self, pyObject, asn1Spec, **options):\n        if debug.logger & debug.flagDecoder:\n            logger = debug.logger\n        else:\n            logger = None\n        if logger:\n            debug.scope.push(type(pyObject).__name__)\n            logger('decoder called at scope %s, working with type %s' % (debug.scope, type(pyObject).__name__))\n\n        if asn1Spec is None or not isinstance(asn1Spec, base.Asn1Item):\n            raise error.PyAsn1Error('asn1Spec is not valid (should be an instance of an ASN.1 Item, not %s)' % asn1Spec.__class__.__name__)\n\n        try:\n            valueDecoder = self.__typeMap[asn1Spec.typeId]\n\n        except KeyError:\n            # use base type for codec lookup to recover untagged types\n            baseTagSet = tag.TagSet(asn1Spec.tagSet.baseTag, asn1Spec.tagSet.baseTag)\n\n            try:\n                valueDecoder = self.__tagMap[baseTagSet]\n            except KeyError:\n                raise error.PyAsn1Error('Unknown ASN.1 tag %s' % asn1Spec.tagSet)\n\n        if logger:\n            logger('calling decoder %s on Python type %s <%s>' % (type(valueDecoder).__name__, type(pyObject).__name__, repr(pyObject)))\n\n        value = valueDecoder(pyObject, asn1Spec, self, **options)\n\n        if logger:\n            logger('decoder %s produced ASN.1 type %s <%s>' % (type(valueDecoder).__name__, type(value).__name__, repr(value)))\n            debug.scope.pop()\n\n        return value\n\n\n#: Turns Python objects of built-in types into ASN.1 objects.\n#:\n#: Takes Python objects of built-in types and turns them into a tree of\n#: ASN.1 objects (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative) which\n#: may be a scalar or an arbitrary nested structure.\n#:\n#: Parameters\n#: ----------\n#: pyObject: :py:class:`object`\n#:     A scalar or nested Python objects\n#:\n#: Keyword Args\n#: ------------\n#: asn1Spec: any pyasn1 type object e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative\n#:     A pyasn1 type object to act as a template guiding the decoder. It is required\n#:     for successful interpretation of Python objects mapping into their ASN.1\n#:     representations.\n#:\n#: Returns\n#: -------\n#: : :py:class:`~pyasn1.type.base.PyAsn1Item` derivative\n#:     A scalar or constructed pyasn1 object\n#:\n#: Raises\n#: ------\n#: :py:class:`~pyasn1.error.PyAsn1Error`\n#:     On decoding errors\n#:\n#: Examples\n#: --------\n#: Decode native Python object into ASN.1 objects with ASN.1 schema\n#:\n#: .. code-block:: pycon\n#:\n#:    >>> seq = SequenceOf(componentType=Integer())\n#:    >>> s, _ = decode([1, 2, 3], asn1Spec=seq)\n#:    >>> str(s)\n#:    SequenceOf:\n#:     1 2 3\n#:\ndecode = Decoder(tagMap, typeMap)\n"
  },
  {
    "path": "code/default/lib/noarch/pyasn1/codec/native/encoder.py",
    "content": "#\n# This file is part of pyasn1 software.\n#\n# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>\n# License: http://snmplabs.com/pyasn1/license.html\n#\ntry:\n    from collections import OrderedDict\n\nexcept ImportError:\n    OrderedDict = dict\n\nfrom pyasn1 import debug\nfrom pyasn1 import error\nfrom pyasn1.type import base\nfrom pyasn1.type import char\nfrom pyasn1.type import tag\nfrom pyasn1.type import univ\nfrom pyasn1.type import useful\n\n__all__ = ['encode']\n\n\nclass AbstractItemEncoder(object):\n    def encode(self, value, encodeFun, **options):\n        raise error.PyAsn1Error('Not implemented')\n\n\nclass BooleanEncoder(AbstractItemEncoder):\n    def encode(self, value, encodeFun, **options):\n        return bool(value)\n\n\nclass IntegerEncoder(AbstractItemEncoder):\n    def encode(self, value, encodeFun, **options):\n        return int(value)\n\n\nclass BitStringEncoder(AbstractItemEncoder):\n    def encode(self, value, encodeFun, **options):\n        return str(value)\n\n\nclass OctetStringEncoder(AbstractItemEncoder):\n    def encode(self, value, encodeFun, **options):\n        return value.asOctets()\n\n\nclass TextStringEncoder(AbstractItemEncoder):\n    def encode(self, value, encodeFun, **options):\n        return str(value)\n\n\nclass NullEncoder(AbstractItemEncoder):\n    def encode(self, value, encodeFun, **options):\n        return None\n\n\nclass ObjectIdentifierEncoder(AbstractItemEncoder):\n    def encode(self, value, encodeFun, **options):\n        return str(value)\n\n\nclass RealEncoder(AbstractItemEncoder):\n    def encode(self, value, encodeFun, **options):\n        return float(value)\n\n\nclass SetEncoder(AbstractItemEncoder):\n    protoDict = dict\n\n    def encode(self, value, encodeFun, **options):\n        value.verifySizeSpec()\n\n        namedTypes = value.componentType\n        substrate = self.protoDict()\n\n        for idx, (key, subValue) in enumerate(value.items()):\n            if namedTypes and namedTypes[idx].isOptional and not value[idx].isValue:\n                continue\n            substrate[key] = encodeFun(subValue, **options)\n        return substrate\n\n\nclass SequenceEncoder(SetEncoder):\n    protoDict = OrderedDict\n\n\nclass SequenceOfEncoder(AbstractItemEncoder):\n    def encode(self, value, encodeFun, **options):\n        value.verifySizeSpec()\n        return [encodeFun(x, **options) for x in value]\n\n\nclass ChoiceEncoder(SequenceEncoder):\n    pass\n\n\nclass AnyEncoder(AbstractItemEncoder):\n    def encode(self, value, encodeFun, **options):\n        return value.asOctets()\n\n\ntagMap = {\n    univ.Boolean.tagSet: BooleanEncoder(),\n    univ.Integer.tagSet: IntegerEncoder(),\n    univ.BitString.tagSet: BitStringEncoder(),\n    univ.OctetString.tagSet: OctetStringEncoder(),\n    univ.Null.tagSet: NullEncoder(),\n    univ.ObjectIdentifier.tagSet: ObjectIdentifierEncoder(),\n    univ.Enumerated.tagSet: IntegerEncoder(),\n    univ.Real.tagSet: RealEncoder(),\n    # Sequence & Set have same tags as SequenceOf & SetOf\n    univ.SequenceOf.tagSet: SequenceOfEncoder(),\n    univ.SetOf.tagSet: SequenceOfEncoder(),\n    univ.Choice.tagSet: ChoiceEncoder(),\n    # character string types\n    char.UTF8String.tagSet: TextStringEncoder(),\n    char.NumericString.tagSet: TextStringEncoder(),\n    char.PrintableString.tagSet: TextStringEncoder(),\n    char.TeletexString.tagSet: TextStringEncoder(),\n    char.VideotexString.tagSet: TextStringEncoder(),\n    char.IA5String.tagSet: TextStringEncoder(),\n    char.GraphicString.tagSet: TextStringEncoder(),\n    char.VisibleString.tagSet: TextStringEncoder(),\n    char.GeneralString.tagSet: TextStringEncoder(),\n    char.UniversalString.tagSet: TextStringEncoder(),\n    char.BMPString.tagSet: TextStringEncoder(),\n    # useful types\n    useful.ObjectDescriptor.tagSet: OctetStringEncoder(),\n    useful.GeneralizedTime.tagSet: OctetStringEncoder(),\n    useful.UTCTime.tagSet: OctetStringEncoder()\n}\n\n# Type-to-codec map for ambiguous ASN.1 types\ntypeMap = {\n    univ.Set.typeId: SetEncoder(),\n    univ.SetOf.typeId: SequenceOfEncoder(),\n    univ.Sequence.typeId: SequenceEncoder(),\n    univ.SequenceOf.typeId: SequenceOfEncoder(),\n    univ.Choice.typeId: ChoiceEncoder(),\n    univ.Any.typeId: AnyEncoder()\n}\n\n\nclass Encoder(object):\n\n    # noinspection PyDefaultArgument\n    def __init__(self, tagMap, typeMap={}):\n        self.__tagMap = tagMap\n        self.__typeMap = typeMap\n\n    def __call__(self, value, **options):\n        if not isinstance(value, base.Asn1Item):\n            raise error.PyAsn1Error('value is not valid (should be an instance of an ASN.1 Item)')\n\n        if debug.logger & debug.flagEncoder:\n            logger = debug.logger\n        else:\n            logger = None\n\n        if logger:\n            debug.scope.push(type(value).__name__)\n            logger('encoder called for type %s <%s>' % (type(value).__name__, value.prettyPrint()))\n\n        tagSet = value.tagSet\n\n        try:\n            concreteEncoder = self.__typeMap[value.typeId]\n\n        except KeyError:\n            # use base type for codec lookup to recover untagged types\n            baseTagSet = tag.TagSet(value.tagSet.baseTag, value.tagSet.baseTag)\n\n            try:\n                concreteEncoder = self.__tagMap[baseTagSet]\n\n            except KeyError:\n                raise error.PyAsn1Error('No encoder for %s' % (value,))\n\n        if logger:\n            logger('using value codec %s chosen by %s' % (concreteEncoder.__class__.__name__, tagSet))\n\n        pyObject = concreteEncoder.encode(value, self, **options)\n\n        if logger:\n            logger('encoder %s produced: %s' % (type(concreteEncoder).__name__, repr(pyObject)))\n            debug.scope.pop()\n\n        return pyObject\n\n\n#: Turns ASN.1 object into a Python built-in type object(s).\n#:\n#: Takes any ASN.1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative)\n#: walks all its components recursively and produces a Python built-in type or a tree\n#: of those.\n#:\n#: One exception is that instead of :py:class:`dict`, the :py:class:`OrderedDict`\n#: can be produced (whenever available) to preserve ordering of the components\n#: in ASN.1 SEQUENCE.\n#:\n#: Parameters\n#: ----------\n#  asn1Value: any pyasn1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative)\n#:     pyasn1 object to encode (or a tree of them)\n#:\n#: Returns\n#: -------\n#: : :py:class:`object`\n#:     Python built-in type instance (or a tree of them)\n#:\n#: Raises\n#: ------\n#: :py:class:`~pyasn1.error.PyAsn1Error`\n#:     On encoding errors\n#:\n#: Examples\n#: --------\n#: Encode ASN.1 value object into native Python types\n#:\n#: .. code-block:: pycon\n#:\n#:    >>> seq = SequenceOf(componentType=Integer())\n#:    >>> seq.extend([1, 2, 3])\n#:    >>> encode(seq)\n#:    [1, 2, 3]\n#:\nencode = Encoder(tagMap, typeMap)\n"
  },
  {
    "path": "code/default/lib/noarch/pyasn1/compat/__init__.py",
    "content": "# This file is necessary to make this directory a package.\n"
  },
  {
    "path": "code/default/lib/noarch/pyasn1/compat/binary.py",
    "content": "#\n# This file is part of pyasn1 software.\n#\n# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>\n# License: http://snmplabs.com/pyasn1/license.html\n#\nfrom sys import version_info\n\nif version_info[0:2] < (2, 6):\n    def bin(value):\n        bitstring = []\n\n        if value > 0:\n            prefix = '0b'\n        elif value < 0:\n            prefix = '-0b'\n            value = abs(value)\n        else:\n            prefix = '0b0'\n\n        while value:\n            if value & 1 == 1:\n                bitstring.append('1')\n            else:\n                bitstring.append('0')\n\n            value >>= 1\n\n        bitstring.reverse()\n\n        return prefix + ''.join(bitstring)\nelse:\n    bin = bin\n"
  },
  {
    "path": "code/default/lib/noarch/pyasn1/compat/calling.py",
    "content": "#\n# This file is part of pyasn1 software.\n#\n# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>\n# License: http://snmplabs.com/pyasn1/license.html\n#\nfrom sys import version_info\n\n__all__ = ['callable']\n\n\nif (2, 7) < version_info[:2] < (3, 2):\n    import collections\n\n    def callable(x):\n        return isinstance(x, collections.Callable)\n\nelse:\n\n    callable = callable\n"
  },
  {
    "path": "code/default/lib/noarch/pyasn1/compat/dateandtime.py",
    "content": "#\n# This file is part of pyasn1 software.\n#\n# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>\n# License: http://snmplabs.com/pyasn1/license.html\n#\nimport time\nfrom datetime import datetime\nfrom sys import version_info\n\n__all__ = ['strptime']\n\n\nif version_info[:2] <= (2, 4):\n\n    def strptime(text, dateFormat):\n        return datetime(*(time.strptime(text, dateFormat)[0:6]))\n\nelse:\n\n    def strptime(text, dateFormat):\n        return datetime.strptime(text, dateFormat)\n"
  },
  {
    "path": "code/default/lib/noarch/pyasn1/compat/integer.py",
    "content": "#\n# This file is part of pyasn1 software.\n#\n# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>\n# License: http://snmplabs.com/pyasn1/license.html\n#\nimport sys\n\ntry:\n    import platform\n\n    implementation = platform.python_implementation()\n\nexcept (ImportError, AttributeError):\n    implementation = 'CPython'\n\nfrom pyasn1.compat.octets import oct2int, null, ensureString\n\nif sys.version_info[0:2] < (3, 2) or implementation != 'CPython':\n    from binascii import a2b_hex, b2a_hex\n\n    if sys.version_info[0] > 2:\n        long = int\n\n    def from_bytes(octets, signed=False):\n        if not octets:\n            return 0\n\n        value = int(b2a_hex(ensureString(octets)), 16)\n\n        if signed and oct2int(octets[0]) & 0x80:\n            return value - (1 << len(octets) * 8)\n\n        return value\n\n    def to_bytes(value, signed=False, length=0):\n        if value < 0:\n            if signed:\n                bits = bitLength(value)\n\n                # two's complement form\n                maxValue = 1 << bits\n                valueToEncode = (value + maxValue) % maxValue\n\n            else:\n                raise OverflowError('can\\'t convert negative int to unsigned')\n        elif value == 0 and length == 0:\n            return null\n        else:\n            bits = 0\n            valueToEncode = value\n\n        hexValue = hex(valueToEncode)[2:]\n        if hexValue.endswith('L'):\n            hexValue = hexValue[:-1]\n\n        if len(hexValue) & 1:\n            hexValue = '0' + hexValue\n\n        # padding may be needed for two's complement encoding\n        if value != valueToEncode or length:\n            hexLength = len(hexValue) * 4\n\n            padLength = max(length, bits)\n\n            if padLength > hexLength:\n                hexValue = '00' * ((padLength - hexLength - 1) // 8 + 1) + hexValue\n            elif length and hexLength - length > 7:\n                raise OverflowError('int too big to convert')\n\n        firstOctet = int(hexValue[:2], 16)\n\n        if signed:\n            if firstOctet & 0x80:\n                if value >= 0:\n                    hexValue = '00' + hexValue\n            elif value < 0:\n                hexValue = 'ff' + hexValue\n\n        octets_value = a2b_hex(hexValue)\n\n        return octets_value\n\n    def bitLength(number):\n        # bits in unsigned number\n        hexValue = hex(abs(number))\n        bits = len(hexValue) - 2\n        if hexValue.endswith('L'):\n            bits -= 1\n        if bits & 1:\n            bits += 1\n        bits *= 4\n        # TODO: strip lhs zeros\n        return bits\n\nelse:\n\n    def from_bytes(octets, signed=False):\n        return int.from_bytes(bytes(octets), 'big', signed=signed)\n\n    def to_bytes(value, signed=False, length=0):\n        length = max(value.bit_length(), length)\n\n        if signed and length % 8 == 0:\n            length += 1\n\n        return value.to_bytes(length // 8 + (length % 8 and 1 or 0), 'big', signed=signed)\n\n    def bitLength(number):\n        return int(number).bit_length()\n"
  },
  {
    "path": "code/default/lib/noarch/pyasn1/compat/octets.py",
    "content": "#\n# This file is part of pyasn1 software.\n#\n# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>\n# License: http://snmplabs.com/pyasn1/license.html\n#\nfrom sys import version_info\n\nif version_info[0] <= 2:\n    int2oct = chr\n    # noinspection PyPep8\n    ints2octs = lambda s: ''.join([int2oct(x) for x in s])\n    null = ''\n    oct2int = ord\n    # TODO: refactor to return a sequence of ints\n    # noinspection PyPep8\n    octs2ints = lambda s: [oct2int(x) for x in s]\n    # noinspection PyPep8\n    str2octs = lambda x: x\n    # noinspection PyPep8\n    octs2str = lambda x: x\n    # noinspection PyPep8\n    isOctetsType = lambda s: isinstance(s, str)\n    # noinspection PyPep8\n    isStringType = lambda s: isinstance(s, str)\n    # noinspection PyPep8\n    ensureString = str\nelse:\n    ints2octs = bytes\n    # noinspection PyPep8\n    int2oct = lambda x: ints2octs((x,))\n    null = ints2octs()\n    # noinspection PyPep8\n    oct2int = lambda x: x\n    # noinspection PyPep8\n    octs2ints = lambda x: x\n    # noinspection PyPep8\n    str2octs = lambda x: x.encode('iso-8859-1')\n    # noinspection PyPep8\n    octs2str = lambda x: x.decode('iso-8859-1')\n    # noinspection PyPep8\n    isOctetsType = lambda s: isinstance(s, bytes)\n    # noinspection PyPep8\n    isStringType = lambda s: isinstance(s, str)\n    # noinspection PyPep8\n    ensureString = bytes\n"
  },
  {
    "path": "code/default/lib/noarch/pyasn1/compat/string.py",
    "content": "#\n# This file is part of pyasn1 software.\n#\n# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>\n# License: http://snmplabs.com/pyasn1/license.html\n#\nfrom sys import version_info\n\nif version_info[:2] <= (2, 5):\n\n    def partition(string, sep):\n        try:\n            a, c = string.split(sep, 1)\n\n        except ValueError:\n            a, b, c = string, '', ''\n\n        else:\n            b = sep\n\n        return a, b, c\n\nelse:\n\n    def partition(string, sep):\n        return string.partition(sep)\n"
  },
  {
    "path": "code/default/lib/noarch/pyasn1/debug.py",
    "content": "#\n# This file is part of pyasn1 software.\n#\n# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>\n# License: http://snmplabs.com/pyasn1/license.html\n#\nimport logging\n\nfrom pyasn1 import __version__\nfrom pyasn1 import error\nfrom pyasn1.compat.octets import octs2ints\n\n__all__ = ['Debug', 'setLogger', 'hexdump']\n\nflagNone = 0x0000\nflagEncoder = 0x0001\nflagDecoder = 0x0002\nflagAll = 0xffff\n\nflagMap = {\n    'none': flagNone,\n    'encoder': flagEncoder,\n    'decoder': flagDecoder,\n    'all': flagAll\n}\n\n\nclass Printer(object):\n    # noinspection PyShadowingNames\n    def __init__(self, logger=None, handler=None, formatter=None):\n        if logger is None:\n            logger = logging.getLogger('pyasn1')\n\n        logger.setLevel(logging.DEBUG)\n\n        if handler is None:\n            handler = logging.StreamHandler()\n\n        if formatter is None:\n            formatter = logging.Formatter('%(asctime)s %(name)s: %(message)s')\n\n        handler.setFormatter(formatter)\n        handler.setLevel(logging.DEBUG)\n        logger.addHandler(handler)\n\n        self.__logger = logger\n\n    def __call__(self, msg):\n        self.__logger.debug(msg)\n\n    def __str__(self):\n        return '<python logging>'\n\n\nif hasattr(logging, 'NullHandler'):\n    NullHandler = logging.NullHandler\n\nelse:\n    # Python 2.6 and older\n    class NullHandler(logging.Handler):\n        def emit(self, record):\n            pass\n\n\nclass Debug(object):\n    defaultPrinter = Printer()\n\n    def __init__(self, *flags, **options):\n        self._flags = flagNone\n\n        if 'loggerName' in options:\n            # route our logs to parent logger\n            self._printer = Printer(\n                logger=logging.getLogger(options['loggerName']),\n                handler=NullHandler()\n            )\n\n        elif 'printer' in options:\n            self._printer = options.get('printer')\n\n        else:\n            self._printer = self.defaultPrinter\n\n        self._printer('running pyasn1 %s, debug flags %s' % (__version__, ', '.join(flags)))\n\n        for flag in flags:\n            inverse = flag and flag[0] in ('!', '~')\n            if inverse:\n                flag = flag[1:]\n            try:\n                if inverse:\n                    self._flags &= ~flagMap[flag]\n                else:\n                    self._flags |= flagMap[flag]\n            except KeyError:\n                raise error.PyAsn1Error('bad debug flag %s' % flag)\n\n            self._printer(\"debug category '%s' %s\" % (flag, inverse and 'disabled' or 'enabled'))\n\n    def __str__(self):\n        return 'logger %s, flags %x' % (self._printer, self._flags)\n\n    def __call__(self, msg):\n        self._printer(msg)\n\n    def __and__(self, flag):\n        return self._flags & flag\n\n    def __rand__(self, flag):\n        return flag & self._flags\n\n\nlogger = 0\n\n\ndef setLogger(userLogger):\n    global logger\n\n    if userLogger:\n        logger = userLogger\n    else:\n        logger = 0\n\n\ndef hexdump(octets):\n    return ' '.join(\n        ['%s%.2X' % (n % 16 == 0 and ('\\n%.5d: ' % n) or '', x)\n         for n, x in zip(list(range(len(octets))), octs2ints(octets))]\n    )\n\n\nclass Scope(object):\n    def __init__(self):\n        self._list = []\n\n    def __str__(self): return '.'.join(self._list)\n\n    def push(self, token):\n        self._list.append(token)\n\n    def pop(self):\n        return self._list.pop()\n\n\nscope = Scope()\n"
  },
  {
    "path": "code/default/lib/noarch/pyasn1/error.py",
    "content": "#\n# This file is part of pyasn1 software.\n#\n# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>\n# License: http://snmplabs.com/pyasn1/license.html\n#\n\n\nclass PyAsn1Error(Exception):\n    \"\"\"Create pyasn1 exception object\n\n    The `PyAsn1Error` exception represents generic, usually fatal, error.\n    \"\"\"\n\n\nclass ValueConstraintError(PyAsn1Error):\n    \"\"\"Create pyasn1 exception object\n\n    The `ValueConstraintError` exception indicates an ASN.1 value\n    constraint violation.\n    \"\"\"\n\n\nclass SubstrateUnderrunError(PyAsn1Error):\n    \"\"\"Create pyasn1 exception object\n\n    The `SubstrateUnderrunError` exception indicates insufficient serialised\n    data on input of a deserialisation routine.\n    \"\"\"\n"
  },
  {
    "path": "code/default/lib/noarch/pyasn1/type/__init__.py",
    "content": "# This file is necessary to make this directory a package.\n"
  },
  {
    "path": "code/default/lib/noarch/pyasn1/type/base.py",
    "content": "#\n# This file is part of pyasn1 software.\n#\n# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>\n# License: http://snmplabs.com/pyasn1/license.html\n#\nimport sys\n\nfrom pyasn1 import error\nfrom pyasn1.compat import calling\nfrom pyasn1.type import constraint\nfrom pyasn1.type import tag\nfrom pyasn1.type import tagmap\n\n__all__ = ['Asn1Item', 'Asn1ItemBase', 'AbstractSimpleAsn1Item', 'AbstractConstructedAsn1Item']\n\n\nclass Asn1Item(object):\n    @classmethod\n    def getTypeId(cls, increment=1):\n        try:\n            Asn1Item._typeCounter += increment\n        except AttributeError:\n            Asn1Item._typeCounter = increment\n        return Asn1Item._typeCounter\n\n\nclass Asn1ItemBase(Asn1Item):\n    #: Set or return a :py:class:`~pyasn1.type.tag.TagSet` object representing\n    #: ASN.1 tag(s) associated with |ASN.1| type.\n    tagSet = tag.TagSet()\n\n    #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`\n    #: object imposing constraints on initialization values.\n    subtypeSpec = constraint.ConstraintsIntersection()\n\n    # Disambiguation ASN.1 types identification\n    typeId = None\n\n    def __init__(self, **kwargs):\n        readOnly = {\n            'tagSet': self.tagSet,\n            'subtypeSpec': self.subtypeSpec\n        }\n\n        readOnly.update(kwargs)\n\n        self.__dict__.update(readOnly)\n\n        self._readOnly = readOnly\n\n    def __setattr__(self, name, value):\n        if name[0] != '_' and name in self._readOnly:\n            raise error.PyAsn1Error('read-only instance attribute \"%s\"' % name)\n\n        self.__dict__[name] = value\n\n    def __str__(self):\n        return self.prettyPrint()\n\n    @property\n    def readOnly(self):\n        return self._readOnly\n\n    @property\n    def effectiveTagSet(self):\n        \"\"\"For |ASN.1| type is equivalent to *tagSet*\n        \"\"\"\n        return self.tagSet  # used by untagged types\n\n    @property\n    def tagMap(self):\n        \"\"\"Return a :class:`~pyasn1.type.tagmap.TagMap` object mapping ASN.1 tags to ASN.1 objects within callee object.\n        \"\"\"\n        return tagmap.TagMap({self.tagSet: self})\n\n    def isSameTypeWith(self, other, matchTags=True, matchConstraints=True):\n        \"\"\"Examine |ASN.1| type for equality with other ASN.1 type.\n\n        ASN.1 tags (:py:mod:`~pyasn1.type.tag`) and constraints\n        (:py:mod:`~pyasn1.type.constraint`) are examined when carrying\n        out ASN.1 types comparison.\n\n        Python class inheritance relationship is NOT considered.\n\n        Parameters\n        ----------\n        other: a pyasn1 type object\n            Class instance representing ASN.1 type.\n\n        Returns\n        -------\n        : :class:`bool`\n            :class:`True` if *other* is |ASN.1| type,\n            :class:`False` otherwise.\n        \"\"\"\n        return (self is other or\n                (not matchTags or self.tagSet == other.tagSet) and\n                (not matchConstraints or self.subtypeSpec == other.subtypeSpec))\n\n    def isSuperTypeOf(self, other, matchTags=True, matchConstraints=True):\n        \"\"\"Examine |ASN.1| type for subtype relationship with other ASN.1 type.\n\n        ASN.1 tags (:py:mod:`~pyasn1.type.tag`) and constraints\n        (:py:mod:`~pyasn1.type.constraint`) are examined when carrying\n        out ASN.1 types comparison.\n\n        Python class inheritance relationship is NOT considered.\n\n        Parameters\n        ----------\n            other: a pyasn1 type object\n                Class instance representing ASN.1 type.\n\n        Returns\n        -------\n            : :class:`bool`\n                :class:`True` if *other* is a subtype of |ASN.1| type,\n                :class:`False` otherwise.\n        \"\"\"\n        return (not matchTags or\n                (self.tagSet.isSuperTagSetOf(other.tagSet)) and\n                 (not matchConstraints or self.subtypeSpec.isSuperTypeOf(other.subtypeSpec)))\n\n    @staticmethod\n    def isNoValue(*values):\n        for value in values:\n            if value is not noValue:\n                return False\n        return True\n\n    def prettyPrint(self, scope=0):\n        raise NotImplementedError()\n\n    # backward compatibility\n\n    def getTagSet(self):\n        return self.tagSet\n\n    def getEffectiveTagSet(self):\n        return self.effectiveTagSet\n\n    def getTagMap(self):\n        return self.tagMap\n\n    def getSubtypeSpec(self):\n        return self.subtypeSpec\n\n    def hasValue(self):\n        return self.isValue\n\n\nclass NoValue(object):\n    \"\"\"Create a singleton instance of NoValue class.\n\n    The *NoValue* sentinel object represents an instance of ASN.1 schema\n    object as opposed to ASN.1 value object.\n\n    Only ASN.1 schema-related operations can be performed on ASN.1\n    schema objects.\n\n    Warning\n    -------\n    Any operation attempted on the *noValue* object will raise the\n    *PyAsn1Error* exception.\n    \"\"\"\n    skipMethods = set(\n        ('__slots__',\n         # attributes\n         '__getattribute__',\n         '__getattr__',\n         '__setattr__',\n         '__delattr__',\n         # class instance\n         '__class__',\n         '__init__',\n         '__del__',\n         '__new__',\n         '__repr__',\n         '__qualname__',\n         '__objclass__',\n         'im_class',\n         '__sizeof__',\n         # pickle protocol\n         '__reduce__',\n         '__reduce_ex__',\n         '__getnewargs__',\n         '__getinitargs__',\n         '__getstate__',\n         '__setstate__')\n    )\n\n    _instance = None\n\n    def __new__(cls):\n        if cls._instance is None:\n            def getPlug(name):\n                def plug(self, *args, **kw):\n                    raise error.PyAsn1Error('Attempted \"%s\" operation on ASN.1 schema object' % name)\n                return plug\n\n            op_names = [name\n                        for typ in (str, int, list, dict)\n                        for name in dir(typ)\n                        if (name not in cls.skipMethods and\n                            name.startswith('__') and\n                            name.endswith('__') and\n                            calling.callable(getattr(typ, name)))]\n\n            for name in set(op_names):\n                setattr(cls, name, getPlug(name))\n\n            cls._instance = object.__new__(cls)\n\n        return cls._instance\n\n    def __getattr__(self, attr):\n        if attr in self.skipMethods:\n            raise AttributeError('Attribute %s not present' % attr)\n\n        raise error.PyAsn1Error('Attempted \"%s\" operation on ASN.1 schema object' % attr)\n\n    def __repr__(self):\n        return '<%s object at 0x%x>' % (self.__class__.__name__, id(self))\n\n\nnoValue = NoValue()\n\n\n# Base class for \"simple\" ASN.1 objects. These are immutable.\nclass AbstractSimpleAsn1Item(Asn1ItemBase):\n    #: Default payload value\n    defaultValue = noValue\n\n    def __init__(self, value=noValue, **kwargs):\n        Asn1ItemBase.__init__(self, **kwargs)\n        if value is noValue:\n            value = self.defaultValue\n        else:\n            value = self.prettyIn(value)\n            try:\n                self.subtypeSpec(value)\n\n            except error.PyAsn1Error:\n                exType, exValue, exTb = sys.exc_info()\n                raise exType('%s at %s' % (exValue, self.__class__.__name__))\n\n        self._value = value\n\n    def __repr__(self):\n        representation = '%s %s object at 0x%x' % (\n            self.__class__.__name__, self.isValue and 'value' or 'schema', id(self)\n        )\n\n        for attr, value in list(self.readOnly.items()):\n            if value:\n                representation += ' %s %s' % (attr, value)\n\n        if self.isValue:\n            value = self.prettyPrint()\n            if len(value) > 32:\n                value = value[:16] + '...' + value[-16:]\n            representation += ' payload [%s]' % value\n\n        return '<%s>' % representation\n\n    def __eq__(self, other):\n        return self is other and True or self._value == other\n\n    def __ne__(self, other):\n        return self._value != other\n\n    def __lt__(self, other):\n        return self._value < other\n\n    def __le__(self, other):\n        return self._value <= other\n\n    def __gt__(self, other):\n        return self._value > other\n\n    def __ge__(self, other):\n        return self._value >= other\n\n    if sys.version_info[0] <= 2:\n        def __nonzero__(self):\n            return self._value and True or False\n    else:\n        def __bool__(self):\n            return self._value and True or False\n\n    def __hash__(self):\n        return hash(self._value)\n\n    @property\n    def isValue(self):\n        \"\"\"Indicate that |ASN.1| object represents ASN.1 value.\n\n        If *isValue* is `False` then this object represents just ASN.1 schema.\n\n        If *isValue* is `True` then, in addition to its ASN.1 schema features,\n        this object can also be used like a Python built-in object (e.g. `int`,\n        `str`, `dict` etc.).\n\n        Returns\n        -------\n        : :class:`bool`\n            :class:`False` if object represents just ASN.1 schema.\n            :class:`True` if object represents ASN.1 schema and can be used as a normal value.\n\n        Note\n        ----\n        There is an important distinction between PyASN1 schema and value objects.\n        The PyASN1 schema objects can only participate in ASN.1 schema-related\n        operations (e.g. defining or testing the structure of the data). Most\n        obvious uses of ASN.1 schema is to guide serialisation codecs whilst\n        encoding/decoding serialised ASN.1 contents.\n\n        The PyASN1 value objects can **additionally** participate in many operations\n        involving regular Python objects (e.g. arithmetic, comprehension etc).\n        \"\"\"\n        return self._value is not noValue\n\n    def clone(self, value=noValue, **kwargs):\n        \"\"\"Create a modified version of |ASN.1| schema or value object.\n\n        The `clone()` method accepts the same set arguments as |ASN.1|\n        class takes on instantiation except that all arguments\n        of the `clone()` method are optional.\n\n        Whatever arguments are supplied, they are used to create a copy\n        of `self` taking precedence over the ones used to instantiate `self`.\n\n        Note\n        ----\n        Due to the immutable nature of the |ASN.1| object, if no arguments\n        are supplied, no new |ASN.1| object will be created and `self` will\n        be returned instead.\n        \"\"\"\n        if value is noValue:\n            if not kwargs:\n                return self\n\n            value = self._value\n\n        initilaizers = self.readOnly.copy()\n        initilaizers.update(kwargs)\n\n        return self.__class__(value, **initilaizers)\n\n    def subtype(self, value=noValue, **kwargs):\n        \"\"\"Create a specialization of |ASN.1| schema or value object.\n\n        The subtype relationship between ASN.1 types has no correlation with\n        subtype relationship between Python types. ASN.1 type is mainly identified\n        by its tag(s) (:py:class:`~pyasn1.type.tag.TagSet`) and value range\n        constraints (:py:class:`~pyasn1.type.constraint.ConstraintsIntersection`).\n        These ASN.1 type properties are implemented as |ASN.1| attributes.  \n\n        The `subtype()` method accepts the same set arguments as |ASN.1|\n        class takes on instantiation except that all parameters\n        of the `subtype()` method are optional.\n\n        With the exception of the arguments described below, the rest of\n        supplied arguments they are used to create a copy of `self` taking\n        precedence over the ones used to instantiate `self`.\n\n        The following arguments to `subtype()` create a ASN.1 subtype out of\n        |ASN.1| type:\n\n        Other Parameters\n        ----------------\n        implicitTag: :py:class:`~pyasn1.type.tag.Tag`\n            Implicitly apply given ASN.1 tag object to `self`'s\n            :py:class:`~pyasn1.type.tag.TagSet`, then use the result as\n            new object's ASN.1 tag(s).\n\n        explicitTag: :py:class:`~pyasn1.type.tag.Tag`\n            Explicitly apply given ASN.1 tag object to `self`'s\n            :py:class:`~pyasn1.type.tag.TagSet`, then use the result as\n            new object's ASN.1 tag(s).\n\n        subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`\n            Add ASN.1 constraints object to one of the `self`'s, then\n            use the result as new object's ASN.1 constraints.\n\n        Returns\n        -------\n        :\n            new instance of |ASN.1| schema or value object\n\n        Note\n        ----\n        Due to the immutable nature of the |ASN.1| object, if no arguments\n        are supplied, no new |ASN.1| object will be created and `self` will\n        be returned instead.\n        \"\"\"\n        if value is noValue:\n            if not kwargs:\n                return self\n\n            value = self._value\n\n        initializers = self.readOnly.copy()\n\n        implicitTag = kwargs.pop('implicitTag', None)\n        if implicitTag is not None:\n            initializers['tagSet'] = self.tagSet.tagImplicitly(implicitTag)\n\n        explicitTag = kwargs.pop('explicitTag', None)\n        if explicitTag is not None:\n            initializers['tagSet'] = self.tagSet.tagExplicitly(explicitTag)\n\n        for arg, option in list(kwargs.items()):\n            initializers[arg] += option\n\n        return self.__class__(value, **initializers)\n\n    def prettyIn(self, value):\n        return value\n\n    def prettyOut(self, value):\n        return str(value)\n\n    def prettyPrint(self, scope=0):\n        return self.prettyOut(self._value)\n\n    # noinspection PyUnusedLocal\n    def prettyPrintType(self, scope=0):\n        return '%s -> %s' % (self.tagSet, self.__class__.__name__)\n\n#\n# Constructed types:\n# * There are five of them: Sequence, SequenceOf/SetOf, Set and Choice\n# * ASN1 types and values are represened by Python class instances\n# * Value initialization is made for defaulted components only\n# * Primary method of component addressing is by-position. Data model for base\n#   type is Python sequence. Additional type-specific addressing methods\n#   may be implemented for particular types.\n# * SequenceOf and SetOf types do not implement any additional methods\n# * Sequence, Set and Choice types also implement by-identifier addressing\n# * Sequence, Set and Choice types also implement by-asn1-type (tag) addressing\n# * Sequence and Set types may include optional and defaulted\n#   components\n# * Constructed types hold a reference to component types used for value\n#   verification and ordering.\n# * Component type is a scalar type for SequenceOf/SetOf types and a list\n#   of types for Sequence/Set/Choice.\n#\n\n\nclass AbstractConstructedAsn1Item(Asn1ItemBase):\n\n    #: If `True`, requires exact component type matching,\n    #: otherwise subtype relation is only enforced\n    strictConstraints = False\n\n    componentType = None\n    sizeSpec = None\n\n    def __init__(self, **kwargs):\n        readOnly = {\n            'componentType': self.componentType,\n            'sizeSpec': self.sizeSpec\n        }\n        readOnly.update(kwargs)\n\n        Asn1ItemBase.__init__(self, **readOnly)\n\n        self._componentValues = []\n\n    def __repr__(self):\n        representation = '%s %s object at 0x%x' % (\n            self.__class__.__name__, self.isValue and 'value' or 'schema', id(self)\n        )\n\n        for attr, value in list(self.readOnly.items()):\n            if value is not noValue:\n                representation += ' %s=%r' % (attr, value)\n\n        if self.isValue and self._componentValues:\n            representation += ' payload [%s]' % ', '.join([repr(x) for x in self._componentValues])\n\n        return '<%s>' % representation\n\n    def __eq__(self, other):\n        return self is other and True or self._componentValues == other\n\n    def __ne__(self, other):\n        return self._componentValues != other\n\n    def __lt__(self, other):\n        return self._componentValues < other\n\n    def __le__(self, other):\n        return self._componentValues <= other\n\n    def __gt__(self, other):\n        return self._componentValues > other\n\n    def __ge__(self, other):\n        return self._componentValues >= other\n\n    if sys.version_info[0] <= 2:\n        def __nonzero__(self):\n            return self._componentValues and True or False\n    else:\n        def __bool__(self):\n            return self._componentValues and True or False\n\n    def __len__(self):\n        return len(self._componentValues)\n\n    def _cloneComponentValues(self, myClone, cloneValueFlag):\n        pass\n\n    def clone(self, **kwargs):\n        \"\"\"Create a modified version of |ASN.1| schema object.\n\n        The `clone()` method accepts the same set arguments as |ASN.1|\n        class takes on instantiation except that all arguments\n        of the `clone()` method are optional.\n\n        Whatever arguments are supplied, they are used to create a copy\n        of `self` taking precedence over the ones used to instantiate `self`.\n\n        Possible values of `self` are never copied over thus `clone()` can\n        only create a new schema object.\n\n        Returns\n        -------\n        :\n            new instance of |ASN.1| type/value\n\n        Note\n        ----\n        Due to the mutable nature of the |ASN.1| object, even if no arguments\n        are supplied, new |ASN.1| object will always be created as a shallow\n        copy of `self`.\n        \"\"\"\n        cloneValueFlag = kwargs.pop('cloneValueFlag', False)\n\n        initilaizers = self.readOnly.copy()\n        initilaizers.update(kwargs)\n\n        clone = self.__class__(**initilaizers)\n\n        if cloneValueFlag:\n            self._cloneComponentValues(clone, cloneValueFlag)\n\n        return clone\n\n    def subtype(self, **kwargs):\n        \"\"\"Create a specialization of |ASN.1| schema object.\n\n        The `subtype()` method accepts the same set arguments as |ASN.1|\n        class takes on instantiation except that all parameters\n        of the `subtype()` method are optional.\n\n        With the exception of the arguments described below, the rest of\n        supplied arguments they are used to create a copy of `self` taking\n        precedence over the ones used to instantiate `self`.\n\n        The following arguments to `subtype()` create a ASN.1 subtype out of\n        |ASN.1| type.\n\n        Other Parameters\n        ----------------\n        implicitTag: :py:class:`~pyasn1.type.tag.Tag`\n            Implicitly apply given ASN.1 tag object to `self`'s\n            :py:class:`~pyasn1.type.tag.TagSet`, then use the result as\n            new object's ASN.1 tag(s).\n\n        explicitTag: :py:class:`~pyasn1.type.tag.Tag`\n            Explicitly apply given ASN.1 tag object to `self`'s\n            :py:class:`~pyasn1.type.tag.TagSet`, then use the result as\n            new object's ASN.1 tag(s).\n\n        subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`\n            Add ASN.1 constraints object to one of the `self`'s, then\n            use the result as new object's ASN.1 constraints.\n\n\n        Returns\n        -------\n        :\n            new instance of |ASN.1| type/value\n\n        Note\n        ----\n        Due to the immutable nature of the |ASN.1| object, if no arguments\n        are supplied, no new |ASN.1| object will be created and `self` will\n        be returned instead.\n        \"\"\"\n\n        initializers = self.readOnly.copy()\n\n        cloneValueFlag = kwargs.pop('cloneValueFlag', False)\n\n        implicitTag = kwargs.pop('implicitTag', None)\n        if implicitTag is not None:\n            initializers['tagSet'] = self.tagSet.tagImplicitly(implicitTag)\n\n        explicitTag = kwargs.pop('explicitTag', None)\n        if explicitTag is not None:\n            initializers['tagSet'] = self.tagSet.tagExplicitly(explicitTag)\n\n        for arg, option in list(kwargs.items()):\n            initializers[arg] += option\n\n        clone = self.__class__(**initializers)\n\n        if cloneValueFlag:\n            self._cloneComponentValues(clone, cloneValueFlag)\n\n        return clone\n\n    def verifySizeSpec(self):\n        self.sizeSpec(self)\n\n    def getComponentByPosition(self, idx):\n        raise error.PyAsn1Error('Method not implemented')\n\n    def setComponentByPosition(self, idx, value, verifyConstraints=True):\n        raise error.PyAsn1Error('Method not implemented')\n\n    def setComponents(self, *args, **kwargs):\n        for idx, value in enumerate(args):\n            self[idx] = value\n        for k in kwargs:\n            self[k] = kwargs[k]\n        return self\n\n    def clear(self):\n        self._componentValues = []\n\n    # backward compatibility\n\n    def setDefaultComponents(self):\n        pass\n\n    def getComponentType(self):\n        return self.componentType\n"
  },
  {
    "path": "code/default/lib/noarch/pyasn1/type/char.py",
    "content": "#\n# This file is part of pyasn1 software.\n#\n# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>\n# License: http://snmplabs.com/pyasn1/license.html\n#\nimport sys\n\nfrom pyasn1 import error\nfrom pyasn1.type import tag\nfrom pyasn1.type import univ\n\n__all__ = ['NumericString', 'PrintableString', 'TeletexString', 'T61String', 'VideotexString',\n           'IA5String', 'GraphicString', 'VisibleString', 'ISO646String',\n           'GeneralString', 'UniversalString', 'BMPString', 'UTF8String']\n\nNoValue = univ.NoValue\nnoValue = univ.noValue\n\n\nclass AbstractCharacterString(univ.OctetString):\n    \"\"\"Creates |ASN.1| schema or value object.\n\n    |ASN.1| objects are immutable and duck-type Python 2 :class:`unicode` or Python 3 :class:`str`.\n    When used in octet-stream context, |ASN.1| type assumes \"|encoding|\" encoding.\n\n    Keyword Args\n    ------------\n    value: :class:`unicode`, :class:`str`, :class:`bytes` or |ASN.1| object\n        unicode object (Python 2) or string (Python 3), alternatively string\n        (Python 2) or bytes (Python 3) representing octet-stream of serialised\n        unicode string (note `encoding` parameter) or |ASN.1| class instance.\n\n    tagSet: :py:class:`~pyasn1.type.tag.TagSet`\n        Object representing non-default ASN.1 tag(s)\n\n    subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`\n        Object representing non-default ASN.1 subtype constraint(s)\n\n    encoding: :py:class:`str`\n        Unicode codec ID to encode/decode :class:`unicode` (Python 2) or\n        :class:`str` (Python 3) the payload when |ASN.1| object is used\n        in octet-stream context.\n\n    Raises\n    ------\n    :py:class:`~pyasn1.error.PyAsn1Error`\n        On constraint violation or bad initializer.\n    \"\"\"\n\n    if sys.version_info[0] <= 2:\n        def __str__(self):\n            try:\n                # `str` is Py2 text representation\n                return self._value.encode(self.encoding)\n\n            except UnicodeEncodeError:\n                raise error.PyAsn1Error(\n                    \"Can't encode string '%s' with codec %s\" % (self._value, self.encoding)\n                )\n\n        def __unicode__(self):\n            return str(self._value)\n\n        def prettyIn(self, value):\n            try:\n                if isinstance(value, str):\n                    return value\n                elif isinstance(value, str):\n                    return value.decode(self.encoding)\n                elif isinstance(value, (tuple, list)):\n                    return self.prettyIn(''.join([chr(x) for x in value]))\n                elif isinstance(value, univ.OctetString):\n                    return value.asOctets().decode(self.encoding)\n                else:\n                    return str(value)\n\n            except (UnicodeDecodeError, LookupError):\n                raise error.PyAsn1Error(\n                    \"Can't decode string '%s' with codec %s\" % (value, self.encoding)\n                )\n\n        def asOctets(self, padding=True):\n            return str(self)\n\n        def asNumbers(self, padding=True):\n            return tuple([ord(x) for x in str(self)])\n\n    else:\n        def __str__(self):\n            # `unicode` is Py3 text representation\n            return str(self._value)\n\n        def __bytes__(self):\n            try:\n                return self._value.encode(self.encoding)\n            except UnicodeEncodeError:\n                raise error.PyAsn1Error(\n                    \"Can't encode string '%s' with codec %s\" % (self._value, self.encoding)\n                )\n\n        def prettyIn(self, value):\n            try:\n                if isinstance(value, str):\n                    return value\n                elif isinstance(value, bytes):\n                    return value.decode(self.encoding)\n                elif isinstance(value, (tuple, list)):\n                    return self.prettyIn(bytes(value))\n                elif isinstance(value, univ.OctetString):\n                    return value.asOctets().decode(self.encoding)\n                else:\n                    return str(value)\n\n            except (UnicodeDecodeError, LookupError):\n                raise error.PyAsn1Error(\n                    \"Can't decode string '%s' with codec %s\" % (value, self.encoding)\n                )\n\n        def asOctets(self, padding=True):\n            return bytes(self)\n\n        def asNumbers(self, padding=True):\n            return tuple(bytes(self))\n\n    #\n    # See OctetString.prettyPrint() for the explanation\n    #\n\n    def prettyOut(self, value):\n        return value\n\n    def prettyPrint(self, scope=0):\n        # first see if subclass has its own .prettyOut()\n        value = self.prettyOut(self._value)\n\n        if value is not self._value:\n            return value\n\n        return AbstractCharacterString.__str__(self)\n\n    def __reversed__(self):\n        return reversed(self._value)\n\n\nclass NumericString(AbstractCharacterString):\n    __doc__ = AbstractCharacterString.__doc__\n\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)\n    #: associated with |ASN.1| type.\n    tagSet = AbstractCharacterString.tagSet.tagImplicitly(\n        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 18)\n    )\n    encoding = 'us-ascii'\n\n    # Optimization for faster codec lookup\n    typeId = AbstractCharacterString.getTypeId()\n\n\nclass PrintableString(AbstractCharacterString):\n    __doc__ = AbstractCharacterString.__doc__\n\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)\n    #: associated with |ASN.1| type.\n    tagSet = AbstractCharacterString.tagSet.tagImplicitly(\n        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 19)\n    )\n    encoding = 'us-ascii'\n\n    # Optimization for faster codec lookup\n    typeId = AbstractCharacterString.getTypeId()\n\n\nclass TeletexString(AbstractCharacterString):\n    __doc__ = AbstractCharacterString.__doc__\n\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)\n    #: associated with |ASN.1| type.\n    tagSet = AbstractCharacterString.tagSet.tagImplicitly(\n        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 20)\n    )\n    encoding = 'iso-8859-1'\n\n    # Optimization for faster codec lookup\n    typeId = AbstractCharacterString.getTypeId()\n\n\nclass T61String(TeletexString):\n    __doc__ = TeletexString.__doc__\n\n    # Optimization for faster codec lookup\n    typeId = AbstractCharacterString.getTypeId()\n\n\nclass VideotexString(AbstractCharacterString):\n    __doc__ = AbstractCharacterString.__doc__\n\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)\n    #: associated with |ASN.1| type.\n    tagSet = AbstractCharacterString.tagSet.tagImplicitly(\n        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 21)\n    )\n    encoding = 'iso-8859-1'\n\n    # Optimization for faster codec lookup\n    typeId = AbstractCharacterString.getTypeId()\n\n\nclass IA5String(AbstractCharacterString):\n    __doc__ = AbstractCharacterString.__doc__\n\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)\n    #: associated with |ASN.1| type.\n    tagSet = AbstractCharacterString.tagSet.tagImplicitly(\n        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 22)\n    )\n    encoding = 'us-ascii'\n\n    # Optimization for faster codec lookup\n    typeId = AbstractCharacterString.getTypeId()\n\n\nclass GraphicString(AbstractCharacterString):\n    __doc__ = AbstractCharacterString.__doc__\n\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)\n    #: associated with |ASN.1| type.\n    tagSet = AbstractCharacterString.tagSet.tagImplicitly(\n        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 25)\n    )\n    encoding = 'iso-8859-1'\n\n    # Optimization for faster codec lookup\n    typeId = AbstractCharacterString.getTypeId()\n\n\nclass VisibleString(AbstractCharacterString):\n    __doc__ = AbstractCharacterString.__doc__\n\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)\n    #: associated with |ASN.1| type.\n    tagSet = AbstractCharacterString.tagSet.tagImplicitly(\n        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 26)\n    )\n    encoding = 'us-ascii'\n\n    # Optimization for faster codec lookup\n    typeId = AbstractCharacterString.getTypeId()\n\n\nclass ISO646String(VisibleString):\n    __doc__ = VisibleString.__doc__\n\n    # Optimization for faster codec lookup\n    typeId = AbstractCharacterString.getTypeId()\n\nclass GeneralString(AbstractCharacterString):\n    __doc__ = AbstractCharacterString.__doc__\n\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)\n    #: associated with |ASN.1| type.\n    tagSet = AbstractCharacterString.tagSet.tagImplicitly(\n        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 27)\n    )\n    encoding = 'iso-8859-1'\n\n    # Optimization for faster codec lookup\n    typeId = AbstractCharacterString.getTypeId()\n\n\nclass UniversalString(AbstractCharacterString):\n    __doc__ = AbstractCharacterString.__doc__\n\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)\n    #: associated with |ASN.1| type.\n    tagSet = AbstractCharacterString.tagSet.tagImplicitly(\n        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 28)\n    )\n    encoding = \"utf-32-be\"\n\n    # Optimization for faster codec lookup\n    typeId = AbstractCharacterString.getTypeId()\n\n\nclass BMPString(AbstractCharacterString):\n    __doc__ = AbstractCharacterString.__doc__\n\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)\n    #: associated with |ASN.1| type.\n    tagSet = AbstractCharacterString.tagSet.tagImplicitly(\n        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 30)\n    )\n    encoding = \"utf-16-be\"\n\n    # Optimization for faster codec lookup\n    typeId = AbstractCharacterString.getTypeId()\n\n\nclass UTF8String(AbstractCharacterString):\n    __doc__ = AbstractCharacterString.__doc__\n\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)\n    #: associated with |ASN.1| type.\n    tagSet = AbstractCharacterString.tagSet.tagImplicitly(\n        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12)\n    )\n    encoding = \"utf-8\"\n\n    # Optimization for faster codec lookup\n    typeId = AbstractCharacterString.getTypeId()\n"
  },
  {
    "path": "code/default/lib/noarch/pyasn1/type/constraint.py",
    "content": "#\n# This file is part of pyasn1 software.\n#\n# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>\n# License: http://snmplabs.com/pyasn1/license.html\n#\n# Original concept and code by Mike C. Fletcher.\n#\nimport sys\n\nfrom pyasn1.type import error\n\n__all__ = ['SingleValueConstraint', 'ContainedSubtypeConstraint',\n           'ValueRangeConstraint', 'ValueSizeConstraint',\n           'PermittedAlphabetConstraint', 'InnerTypeConstraint',\n           'ConstraintsExclusion', 'ConstraintsIntersection',\n           'ConstraintsUnion']\n\n\nclass AbstractConstraint(object):\n\n    def __init__(self, *values):\n        self._valueMap = set()\n        self._setValues(values)\n        self.__hash = hash((self.__class__.__name__, self._values))\n\n    def __call__(self, value, idx=None):\n        if not self._values:\n            return\n\n        try:\n            self._testValue(value, idx)\n\n        except error.ValueConstraintError:\n            raise error.ValueConstraintError(\n                '%s failed at: %r' % (self, sys.exc_info()[1])\n            )\n\n    def __repr__(self):\n        representation = '%s object at 0x%x' % (self.__class__.__name__, id(self))\n\n        if self._values:\n            representation += ' consts %s' % ', '.join([repr(x) for x in self._values])\n\n        return '<%s>' % representation\n\n    def __eq__(self, other):\n        return self is other and True or self._values == other\n\n    def __ne__(self, other):\n        return self._values != other\n\n    def __lt__(self, other):\n        return self._values < other\n\n    def __le__(self, other):\n        return self._values <= other\n\n    def __gt__(self, other):\n        return self._values > other\n\n    def __ge__(self, other):\n        return self._values >= other\n\n    if sys.version_info[0] <= 2:\n        def __nonzero__(self):\n            return self._values and True or False\n    else:\n        def __bool__(self):\n            return self._values and True or False\n\n    def __hash__(self):\n        return self.__hash\n\n    def _setValues(self, values):\n        self._values = values\n\n    def _testValue(self, value, idx):\n        raise error.ValueConstraintError(value)\n\n    # Constraints derivation logic\n    def getValueMap(self):\n        return self._valueMap\n\n    def isSuperTypeOf(self, otherConstraint):\n        # TODO: fix possible comparison of set vs scalars here\n        return (otherConstraint is self or\n                not self._values or\n                otherConstraint == self or\n                self in otherConstraint.getValueMap())\n\n    def isSubTypeOf(self, otherConstraint):\n        return (otherConstraint is self or\n                not self or\n                otherConstraint == self or\n                otherConstraint in self._valueMap)\n\n\nclass SingleValueConstraint(AbstractConstraint):\n    \"\"\"Create a SingleValueConstraint object.\n\n    The SingleValueConstraint satisfies any value that\n    is present in the set of permitted values.\n\n    The SingleValueConstraint object can be applied to\n    any ASN.1 type.\n\n    Parameters\n    ----------\n    values: :class:`int`\n        Full set of values permitted by this constraint object.\n\n    Examples\n    --------\n    .. code-block:: python\n\n        class DivisorOfSix(Integer):\n            '''\n            ASN.1 specification:\n\n            Divisor-Of-6 ::= INTEGER (1 | 2 | 3 | 6)\n            '''\n            subtypeSpec = SingleValueConstraint(1, 2, 3, 6)\n\n        # this will succeed\n        divisor_of_six = DivisorOfSix(1)\n\n        # this will raise ValueConstraintError\n        divisor_of_six = DivisorOfSix(7)\n    \"\"\"\n    def _setValues(self, values):\n        self._values = values\n        self._set = set(values)\n\n    def _testValue(self, value, idx):\n        if value not in self._set:\n            raise error.ValueConstraintError(value)\n\n\nclass ContainedSubtypeConstraint(AbstractConstraint):\n    \"\"\"Create a ContainedSubtypeConstraint object.\n\n    The ContainedSubtypeConstraint satisfies any value that\n    is present in the set of permitted values and also\n    satisfies included constraints.\n\n    The ContainedSubtypeConstraint object can be applied to\n    any ASN.1 type.\n\n    Parameters\n    ----------\n    values:\n        Full set of values and constraint objects permitted\n        by this constraint object.\n\n    Examples\n    --------\n    .. code-block:: python\n\n        class DivisorOfEighteen(Integer):\n            '''\n            ASN.1 specification:\n\n            Divisors-of-18 ::= INTEGER (INCLUDES Divisors-of-6 | 9 | 18)\n            '''\n            subtypeSpec = ContainedSubtypeConstraint(\n                SingleValueConstraint(1, 2, 3, 6), 9, 18\n            )\n\n        # this will succeed\n        divisor_of_eighteen = DivisorOfEighteen(9)\n\n        # this will raise ValueConstraintError\n        divisor_of_eighteen = DivisorOfEighteen(10)\n    \"\"\"\n    def _testValue(self, value, idx):\n        for constraint in self._values:\n            if isinstance(constraint, AbstractConstraint):\n                constraint(value, idx)\n            elif value not in self._set:\n                raise error.ValueConstraintError(value)\n\n\nclass ValueRangeConstraint(AbstractConstraint):\n    \"\"\"Create a ValueRangeConstraint object.\n\n    The ValueRangeConstraint satisfies any value that\n    falls in the range of permitted values.\n\n    The ValueRangeConstraint object can only be applied\n    to :class:`~pyasn1.type.univ.Integer` and\n    :class:`~pyasn1.type.univ.Real` types.\n\n    Parameters\n    ----------\n    start: :class:`int`\n        Minimum permitted value in the range (inclusive)\n\n    end: :class:`int`\n        Maximum permitted value in the range (inclusive)\n\n    Examples\n    --------\n    .. code-block:: python\n\n        class TeenAgeYears(Integer):\n            '''\n            ASN.1 specification:\n\n            TeenAgeYears ::= INTEGER (13 .. 19)\n            '''\n            subtypeSpec = ValueRangeConstraint(13, 19)\n\n        # this will succeed\n        teen_year = TeenAgeYears(18)\n\n        # this will raise ValueConstraintError\n        teen_year = TeenAgeYears(20)\n    \"\"\"\n    def _testValue(self, value, idx):\n        if value < self.start or value > self.stop:\n            raise error.ValueConstraintError(value)\n\n    def _setValues(self, values):\n        if len(values) != 2:\n            raise error.PyAsn1Error(\n                '%s: bad constraint values' % (self.__class__.__name__,)\n            )\n        self.start, self.stop = values\n        if self.start > self.stop:\n            raise error.PyAsn1Error(\n                '%s: screwed constraint values (start > stop): %s > %s' % (\n                    self.__class__.__name__,\n                    self.start, self.stop\n                )\n            )\n        AbstractConstraint._setValues(self, values)\n\n\nclass ValueSizeConstraint(ValueRangeConstraint):\n    \"\"\"Create a ValueSizeConstraint object.\n\n    The ValueSizeConstraint satisfies any value for\n    as long as its size falls within the range of\n    permitted sizes.\n\n    The ValueSizeConstraint object can be applied\n    to :class:`~pyasn1.type.univ.BitString`,\n    :class:`~pyasn1.type.univ.OctetString` (including\n    all :ref:`character ASN.1 types <type.char>`),\n    :class:`~pyasn1.type.univ.SequenceOf`\n    and :class:`~pyasn1.type.univ.SetOf` types.\n\n    Parameters\n    ----------\n    minimum: :class:`int`\n        Minimum permitted size of the value (inclusive)\n\n    maximum: :class:`int`\n        Maximum permitted size of the value (inclusive)\n\n    Examples\n    --------\n    .. code-block:: python\n\n        class BaseballTeamRoster(SetOf):\n            '''\n            ASN.1 specification:\n\n            BaseballTeamRoster ::= SET SIZE (1..25) OF PlayerNames\n            '''\n            componentType = PlayerNames()\n            subtypeSpec = ValueSizeConstraint(1, 25)\n\n        # this will succeed\n        team = BaseballTeamRoster()\n        team.extend(['Jan', 'Matej'])\n        encode(team)\n\n        # this will raise ValueConstraintError\n        team = BaseballTeamRoster()\n        team.extend(['Jan'] * 26)\n        encode(team)\n\n    Note\n    ----\n    Whenever ValueSizeConstraint is applied to mutable types\n    (e.g. :class:`~pyasn1.type.univ.SequenceOf`,\n    :class:`~pyasn1.type.univ.SetOf`), constraint\n    validation only happens at the serialisation phase rather\n    than schema instantiation phase (as it is with immutable\n    types).\n    \"\"\"\n    def _testValue(self, value, idx):\n        valueSize = len(value)\n        if valueSize < self.start or valueSize > self.stop:\n            raise error.ValueConstraintError(value)\n\n\nclass PermittedAlphabetConstraint(SingleValueConstraint):\n    \"\"\"Create a PermittedAlphabetConstraint object.\n\n    The PermittedAlphabetConstraint satisfies any character\n    string for as long as all its characters are present in\n    the set of permitted characters.\n\n    The PermittedAlphabetConstraint object can only be applied\n    to the :ref:`character ASN.1 types <type.char>` such as\n    :class:`~pyasn1.type.char.IA5String`.\n\n    Parameters\n    ----------\n    alphabet: :class:`str`\n        Full set of characters permitted by this constraint object.\n\n    Examples\n    --------\n    .. code-block:: python\n\n        class BooleanValue(IA5String):\n            '''\n            ASN.1 specification:\n\n            BooleanValue ::= IA5String (FROM ('T' | 'F'))\n            '''\n            subtypeSpec = PermittedAlphabetConstraint('T', 'F')\n\n        # this will succeed\n        truth = BooleanValue('T')\n        truth = BooleanValue('TF')\n\n        # this will raise ValueConstraintError\n        garbage = BooleanValue('TAF')\n    \"\"\"\n    def _setValues(self, values):\n        self._values = values\n        self._set = set(values)\n\n    def _testValue(self, value, idx):\n        if not self._set.issuperset(value):\n            raise error.ValueConstraintError(value)\n\n\n# This is a bit kludgy, meaning two op modes within a single constraint\nclass InnerTypeConstraint(AbstractConstraint):\n    \"\"\"Value must satisfy the type and presence constraints\"\"\"\n\n    def _testValue(self, value, idx):\n        if self.__singleTypeConstraint:\n            self.__singleTypeConstraint(value)\n        elif self.__multipleTypeConstraint:\n            if idx not in self.__multipleTypeConstraint:\n                raise error.ValueConstraintError(value)\n            constraint, status = self.__multipleTypeConstraint[idx]\n            if status == 'ABSENT':  # XXX presense is not checked!\n                raise error.ValueConstraintError(value)\n            constraint(value)\n\n    def _setValues(self, values):\n        self.__multipleTypeConstraint = {}\n        self.__singleTypeConstraint = None\n        for v in values:\n            if isinstance(v, tuple):\n                self.__multipleTypeConstraint[v[0]] = v[1], v[2]\n            else:\n                self.__singleTypeConstraint = v\n        AbstractConstraint._setValues(self, values)\n\n\n# Logic operations on constraints\n\nclass ConstraintsExclusion(AbstractConstraint):\n    \"\"\"Create a ConstraintsExclusion logic operator object.\n\n    The ConstraintsExclusion logic operator succeeds when the\n    value does *not* satisfy the operand constraint.\n\n    The ConstraintsExclusion object can be applied to\n    any constraint and logic operator object.\n\n    Parameters\n    ----------\n    constraint:\n        Constraint or logic operator object.\n\n    Examples\n    --------\n    .. code-block:: python\n\n        class Lipogramme(IA5STRING):\n            '''\n            ASN.1 specification:\n\n            Lipogramme ::=\n                IA5String (FROM (ALL EXCEPT (\"e\"|\"E\")))\n            '''\n            subtypeSpec = ConstraintsExclusion(\n                PermittedAlphabetConstraint('e', 'E')\n            )\n\n        # this will succeed\n        lipogramme = Lipogramme('A work of fiction?')\n\n        # this will raise ValueConstraintError\n        lipogramme = Lipogramme('Eel')\n\n    Warning\n    -------\n    The above example involving PermittedAlphabetConstraint might\n    not work due to the way how PermittedAlphabetConstraint works.\n    The other constraints might work with ConstraintsExclusion\n    though.\n    \"\"\"\n    def _testValue(self, value, idx):\n        try:\n            self._values[0](value, idx)\n        except error.ValueConstraintError:\n            return\n        else:\n            raise error.ValueConstraintError(value)\n\n    def _setValues(self, values):\n        if len(values) != 1:\n            raise error.PyAsn1Error('Single constraint expected')\n\n        AbstractConstraint._setValues(self, values)\n\n\nclass AbstractConstraintSet(AbstractConstraint):\n\n    def __getitem__(self, idx):\n        return self._values[idx]\n\n    def __iter__(self):\n        return iter(self._values)\n\n    def __add__(self, value):\n        return self.__class__(*(self._values + (value,)))\n\n    def __radd__(self, value):\n        return self.__class__(*((value,) + self._values))\n\n    def __len__(self):\n        return len(self._values)\n\n    # Constraints inclusion in sets\n\n    def _setValues(self, values):\n        self._values = values\n        for constraint in values:\n            if constraint:\n                self._valueMap.add(constraint)\n                self._valueMap.update(constraint.getValueMap())\n\n\nclass ConstraintsIntersection(AbstractConstraintSet):\n    \"\"\"Create a ConstraintsIntersection logic operator object.\n\n    The ConstraintsIntersection logic operator only succeeds\n    if *all* its operands succeed.\n\n    The ConstraintsIntersection object can be applied to\n    any constraint and logic operator objects.\n\n    The ConstraintsIntersection object duck-types the immutable\n    container object like Python :py:class:`tuple`.\n\n    Parameters\n    ----------\n    constraints:\n        Constraint or logic operator objects.\n\n    Examples\n    --------\n    .. code-block:: python\n\n        class CapitalAndSmall(IA5String):\n            '''\n            ASN.1 specification:\n\n            CapitalAndSmall ::=\n                IA5String (FROM (\"A\"..\"Z\"|\"a\"..\"z\"))\n            '''\n            subtypeSpec = ConstraintsIntersection(\n                PermittedAlphabetConstraint('A', 'Z'),\n                PermittedAlphabetConstraint('a', 'z')\n            )\n\n        # this will succeed\n        capital_and_small = CapitalAndSmall('Hello')\n\n        # this will raise ValueConstraintError\n        capital_and_small = CapitalAndSmall('hello')\n    \"\"\"\n    def _testValue(self, value, idx):\n        for constraint in self._values:\n            constraint(value, idx)\n\n\nclass ConstraintsUnion(AbstractConstraintSet):\n    \"\"\"Create a ConstraintsUnion logic operator object.\n\n    The ConstraintsUnion logic operator only succeeds if\n    *at least a single* operand succeeds.\n\n    The ConstraintsUnion object can be applied to\n    any constraint and logic operator objects.\n\n    The ConstraintsUnion object duck-types the immutable\n    container object like Python :py:class:`tuple`.\n\n    Parameters\n    ----------\n    constraints:\n        Constraint or logic operator objects.\n\n    Examples\n    --------\n    .. code-block:: python\n\n        class CapitalOrSmall(IA5String):\n            '''\n            ASN.1 specification:\n\n            CapitalOrSmall ::=\n                IA5String (FROM (\"A\"..\"Z\") | FROM (\"a\"..\"z\"))\n            '''\n            subtypeSpec = ConstraintsIntersection(\n                PermittedAlphabetConstraint('A', 'Z'),\n                PermittedAlphabetConstraint('a', 'z')\n            )\n\n        # this will succeed\n        capital_or_small = CapitalAndSmall('Hello')\n\n        # this will raise ValueConstraintError\n        capital_or_small = CapitalOrSmall('hello!')\n    \"\"\"\n    def _testValue(self, value, idx):\n        for constraint in self._values:\n            try:\n                constraint(value, idx)\n            except error.ValueConstraintError:\n                pass\n            else:\n                return\n\n        raise error.ValueConstraintError(\n            'all of %s failed for \"%s\"' % (self._values, value)\n        )\n\n# TODO:\n# refactor InnerTypeConstraint\n# add tests for type check\n# implement other constraint types\n# make constraint validation easy to skip\n"
  },
  {
    "path": "code/default/lib/noarch/pyasn1/type/error.py",
    "content": "#\n# This file is part of pyasn1 software.\n#\n# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>\n# License: http://snmplabs.com/pyasn1/license.html\n#\nfrom pyasn1.error import PyAsn1Error\n\n\nclass ValueConstraintError(PyAsn1Error):\n    pass\n"
  },
  {
    "path": "code/default/lib/noarch/pyasn1/type/namedtype.py",
    "content": "#\n# This file is part of pyasn1 software.\n#\n# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>\n# License: http://snmplabs.com/pyasn1/license.html\n#\nimport sys\n\nfrom pyasn1 import error\nfrom pyasn1.type import tag\nfrom pyasn1.type import tagmap\n\n__all__ = ['NamedType', 'OptionalNamedType', 'DefaultedNamedType',\n           'NamedTypes']\n\ntry:\n    any\n\nexcept NameError:\n    any = lambda x: bool(list(filter(bool, x)))\n\n\nclass NamedType(object):\n    \"\"\"Create named field object for a constructed ASN.1 type.\n\n    The |NamedType| object represents a single name and ASN.1 type of a constructed ASN.1 type.\n\n    |NamedType| objects are immutable and duck-type Python :class:`tuple` objects\n    holding *name* and *asn1Object* components.\n\n    Parameters\n    ----------\n    name: :py:class:`str`\n        Field name\n\n    asn1Object:\n        ASN.1 type object\n    \"\"\"\n    isOptional = False\n    isDefaulted = False\n\n    def __init__(self, name, asn1Object, openType=None):\n        self.__name = name\n        self.__type = asn1Object\n        self.__nameAndType = name, asn1Object\n        self.__openType = openType\n\n    def __repr__(self):\n        representation = '%s=%r' % (self.name, self.asn1Object)\n\n        if self.openType:\n            representation += ' openType: %r' % self.openType\n\n        return '<%s object at 0x%x type %s>' % (self.__class__.__name__, id(self), representation)\n\n    def __eq__(self, other):\n        return self.__nameAndType == other\n\n    def __ne__(self, other):\n        return self.__nameAndType != other\n\n    def __lt__(self, other):\n        return self.__nameAndType < other\n\n    def __le__(self, other):\n        return self.__nameAndType <= other\n\n    def __gt__(self, other):\n        return self.__nameAndType > other\n\n    def __ge__(self, other):\n        return self.__nameAndType >= other\n\n    def __hash__(self):\n        return hash(self.__nameAndType)\n\n    def __getitem__(self, idx):\n        return self.__nameAndType[idx]\n\n    def __iter__(self):\n        return iter(self.__nameAndType)\n\n    @property\n    def name(self):\n        return self.__name\n\n    @property\n    def asn1Object(self):\n        return self.__type\n\n    @property\n    def openType(self):\n        return self.__openType\n\n    # Backward compatibility\n\n    def getName(self):\n        return self.name\n\n    def getType(self):\n        return self.asn1Object\n\n\nclass OptionalNamedType(NamedType):\n    __doc__ = NamedType.__doc__\n\n    isOptional = True\n\n\nclass DefaultedNamedType(NamedType):\n    __doc__ = NamedType.__doc__\n\n    isDefaulted = True\n\n\nclass NamedTypes(object):\n    \"\"\"Create a collection of named fields for a constructed ASN.1 type.\n\n    The NamedTypes object represents a collection of named fields of a constructed ASN.1 type.\n\n    *NamedTypes* objects are immutable and duck-type Python :class:`dict` objects\n    holding *name* as keys and ASN.1 type object as values.\n\n    Parameters\n    ----------\n    *namedTypes: :class:`~pyasn1.type.namedtype.NamedType`\n\n    Examples\n    --------\n\n    .. code-block:: python\n\n        class Description(Sequence):\n            '''\n            ASN.1 specification:\n\n            Description ::= SEQUENCE {\n                surname    IA5String,\n                first-name IA5String OPTIONAL,\n                age        INTEGER DEFAULT 40\n            }\n            '''\n            componentType = NamedTypes(\n                NamedType('surname', IA5String()),\n                OptionalNamedType('first-name', IA5String()),\n                DefaultedNamedType('age', Integer(40))\n            )\n\n        descr = Description()\n        descr['surname'] = 'Smith'\n        descr['first-name'] = 'John'\n    \"\"\"\n    def __init__(self, *namedTypes, **kwargs):\n        self.__namedTypes = namedTypes\n        self.__namedTypesLen = len(self.__namedTypes)\n        self.__minTagSet = self.__computeMinTagSet()\n        self.__nameToPosMap = self.__computeNameToPosMap()\n        self.__tagToPosMap = self.__computeTagToPosMap()\n        self.__ambiguousTypes = 'terminal' not in kwargs and self.__computeAmbiguousTypes() or {}\n        self.__uniqueTagMap = self.__computeTagMaps(unique=True)\n        self.__nonUniqueTagMap = self.__computeTagMaps(unique=False)\n        self.__hasOptionalOrDefault = any([True for namedType in self.__namedTypes\n                                           if namedType.isDefaulted or namedType.isOptional])\n        self.__hasOpenTypes = any([True for namedType in self.__namedTypes\n                                   if namedType.openType])\n\n        self.__requiredComponents = frozenset(\n                [idx for idx, nt in enumerate(self.__namedTypes) if not nt.isOptional and not nt.isDefaulted]\n            )\n        self.__keys = frozenset([namedType.name for namedType in self.__namedTypes])\n        self.__values = tuple([namedType.asn1Object for namedType in self.__namedTypes])\n        self.__items = tuple([(namedType.name, namedType.asn1Object) for namedType in self.__namedTypes])\n\n    def __repr__(self):\n        representation = ', '.join(['%r' % x for x in self.__namedTypes])\n        return '<%s object at 0x%x types %s>' % (self.__class__.__name__, id(self), representation)\n\n    def __eq__(self, other):\n        return self.__namedTypes == other\n\n    def __ne__(self, other):\n        return self.__namedTypes != other\n\n    def __lt__(self, other):\n        return self.__namedTypes < other\n\n    def __le__(self, other):\n        return self.__namedTypes <= other\n\n    def __gt__(self, other):\n        return self.__namedTypes > other\n\n    def __ge__(self, other):\n        return self.__namedTypes >= other\n\n    def __hash__(self):\n        return hash(self.__namedTypes)\n\n    def __getitem__(self, idx):\n        try:\n            return self.__namedTypes[idx]\n\n        except TypeError:\n            return self.__namedTypes[self.__nameToPosMap[idx]]\n\n    def __contains__(self, key):\n        return key in self.__nameToPosMap\n\n    def __iter__(self):\n        return (x[0] for x in self.__namedTypes)\n\n    if sys.version_info[0] <= 2:\n        def __nonzero__(self):\n            return self.__namedTypesLen > 0\n    else:\n        def __bool__(self):\n            return self.__namedTypesLen > 0\n\n    def __len__(self):\n        return self.__namedTypesLen\n\n    # Python dict protocol\n\n    def values(self):\n        return self.__values\n\n    def keys(self):\n        return self.__keys\n\n    def items(self):\n        return self.__items\n\n    def clone(self):\n        return self.__class__(*self.__namedTypes)\n\n    class PostponedError(object):\n        def __init__(self, errorMsg):\n            self.__errorMsg = errorMsg\n\n        def __getitem__(self, item):\n            raise  error.PyAsn1Error(self.__errorMsg)\n\n    def __computeTagToPosMap(self):\n        tagToPosMap = {}\n        for idx, namedType in enumerate(self.__namedTypes):\n            tagMap = namedType.asn1Object.tagMap\n            if isinstance(tagMap, NamedTypes.PostponedError):\n                return tagMap\n            if not tagMap:\n                continue\n            for _tagSet in tagMap.presentTypes:\n                if _tagSet in tagToPosMap:\n                    return NamedTypes.PostponedError('Duplicate component tag %s at %s' % (_tagSet, namedType))\n                tagToPosMap[_tagSet] = idx\n\n        return tagToPosMap\n\n    def __computeNameToPosMap(self):\n        nameToPosMap = {}\n        for idx, namedType in enumerate(self.__namedTypes):\n            if namedType.name in nameToPosMap:\n                return NamedTypes.PostponedError('Duplicate component name %s at %s' % (namedType.name, namedType))\n            nameToPosMap[namedType.name] = idx\n\n        return nameToPosMap\n\n    def __computeAmbiguousTypes(self):\n        ambigiousTypes = {}\n        partialAmbigiousTypes = ()\n        for idx, namedType in reversed(tuple(enumerate(self.__namedTypes))):\n            if namedType.isOptional or namedType.isDefaulted:\n                partialAmbigiousTypes = (namedType,) + partialAmbigiousTypes\n            else:\n                partialAmbigiousTypes = (namedType,)\n            if len(partialAmbigiousTypes) == len(self.__namedTypes):\n                ambigiousTypes[idx] = self\n            else:\n                ambigiousTypes[idx] = NamedTypes(*partialAmbigiousTypes, **dict(terminal=True))\n        return ambigiousTypes\n\n    def getTypeByPosition(self, idx):\n        \"\"\"Return ASN.1 type object by its position in fields set.\n\n        Parameters\n        ----------\n        idx: :py:class:`int`\n            Field index\n\n        Returns\n        -------\n        :\n            ASN.1 type\n\n        Raises\n        ------\n        : :class:`~pyasn1.error.PyAsn1Error`\n            If given position is out of fields range\n        \"\"\"\n        try:\n            return self.__namedTypes[idx].asn1Object\n\n        except IndexError:\n            raise error.PyAsn1Error('Type position out of range')\n\n    def getPositionByType(self, tagSet):\n        \"\"\"Return field position by its ASN.1 type.\n\n        Parameters\n        ----------\n        tagSet: :class:`~pysnmp.type.tag.TagSet`\n            ASN.1 tag set distinguishing one ASN.1 type from others.\n\n        Returns\n        -------\n        : :py:class:`int`\n            ASN.1 type position in fields set\n\n        Raises\n        ------\n        : :class:`~pyasn1.error.PyAsn1Error`\n            If *tagSet* is not present or ASN.1 types are not unique within callee *NamedTypes*\n        \"\"\"\n        try:\n            return self.__tagToPosMap[tagSet]\n\n        except KeyError:\n            raise error.PyAsn1Error('Type %s not found' % (tagSet,))\n\n    def getNameByPosition(self, idx):\n        \"\"\"Return field name by its position in fields set.\n\n        Parameters\n        ----------\n        idx: :py:class:`idx`\n            Field index\n\n        Returns\n        -------\n        : :py:class:`str`\n            Field name\n\n        Raises\n        ------\n        : :class:`~pyasn1.error.PyAsn1Error`\n            If given field name is not present in callee *NamedTypes*\n        \"\"\"\n        try:\n            return self.__namedTypes[idx].name\n\n        except IndexError:\n            raise error.PyAsn1Error('Type position out of range')\n\n    def getPositionByName(self, name):\n        \"\"\"Return field position by filed name.\n\n        Parameters\n        ----------\n        name: :py:class:`str`\n            Field name\n\n        Returns\n        -------\n        : :py:class:`int`\n            Field position in fields set\n\n        Raises\n        ------\n        : :class:`~pyasn1.error.PyAsn1Error`\n            If *name* is not present or not unique within callee *NamedTypes*\n        \"\"\"\n        try:\n            return self.__nameToPosMap[name]\n\n        except KeyError:\n            raise error.PyAsn1Error('Name %s not found' % (name,))\n\n    def getTagMapNearPosition(self, idx):\n        \"\"\"Return ASN.1 types that are allowed at or past given field position.\n\n        Some ASN.1 serialisation allow for skipping optional and defaulted fields.\n        Some constructed ASN.1 types allow reordering of the fields. When recovering\n        such objects it may be important to know which types can possibly be\n        present at any given position in the field sets.\n\n        Parameters\n        ----------\n        idx: :py:class:`int`\n            Field index\n\n        Returns\n        -------\n        : :class:`~pyasn1.type.tagmap.TagMap`\n            Map if ASN.1 types allowed at given field position\n\n        Raises\n        ------\n        : :class:`~pyasn1.error.PyAsn1Error`\n            If given position is out of fields range\n        \"\"\"\n        try:\n            return self.__ambiguousTypes[idx].tagMap\n\n        except KeyError:\n            raise error.PyAsn1Error('Type position out of range')\n\n    def getPositionNearType(self, tagSet, idx):\n        \"\"\"Return the closest field position where given ASN.1 type is allowed.\n\n        Some ASN.1 serialisation allow for skipping optional and defaulted fields.\n        Some constructed ASN.1 types allow reordering of the fields. When recovering\n        such objects it may be important to know at which field position, in field set,\n        given *tagSet* is allowed at or past *idx* position.\n\n        Parameters\n        ----------\n        tagSet: :class:`~pyasn1.type.tag.TagSet`\n           ASN.1 type which field position to look up\n\n        idx: :py:class:`int`\n            Field position at or past which to perform ASN.1 type look up\n\n        Returns\n        -------\n        : :py:class:`int`\n            Field position in fields set\n\n        Raises\n        ------\n        : :class:`~pyasn1.error.PyAsn1Error`\n            If *tagSet* is not present or not unique within callee *NamedTypes*\n            or *idx* is out of fields range\n        \"\"\"\n        try:\n            return idx + self.__ambiguousTypes[idx].getPositionByType(tagSet)\n\n        except KeyError:\n            raise error.PyAsn1Error('Type position out of range')\n\n    def __computeMinTagSet(self):\n        minTagSet = None\n        for namedType in self.__namedTypes:\n            asn1Object = namedType.asn1Object\n\n            try:\n                tagSet = asn1Object.minTagSet\n\n            except AttributeError:\n                tagSet = asn1Object.tagSet\n\n            if minTagSet is None or tagSet < minTagSet:\n                minTagSet = tagSet\n\n        return minTagSet or tag.TagSet()\n\n    @property\n    def minTagSet(self):\n        \"\"\"Return the minimal TagSet among ASN.1 type in callee *NamedTypes*.\n\n        Some ASN.1 types/serialisation protocols require ASN.1 types to be\n        arranged based on their numerical tag value. The *minTagSet* property\n        returns that.\n\n        Returns\n        -------\n        : :class:`~pyasn1.type.tagset.TagSet`\n            Minimal TagSet among ASN.1 types in callee *NamedTypes*\n        \"\"\"\n        return self.__minTagSet\n\n    def __computeTagMaps(self, unique):\n        presentTypes = {}\n        skipTypes = {}\n        defaultType = None\n        for namedType in self.__namedTypes:\n            tagMap = namedType.asn1Object.tagMap\n            if isinstance(tagMap, NamedTypes.PostponedError):\n                return tagMap\n            for tagSet in tagMap:\n                if unique and tagSet in presentTypes:\n                    return NamedTypes.PostponedError('Non-unique tagSet %s of %s at %s' % (tagSet, namedType, self))\n                presentTypes[tagSet] = namedType.asn1Object\n            skipTypes.update(tagMap.skipTypes)\n\n            if defaultType is None:\n                defaultType = tagMap.defaultType\n            elif tagMap.defaultType is not None:\n                return NamedTypes.PostponedError('Duplicate default ASN.1 type at %s' % (self,))\n\n        return tagmap.TagMap(presentTypes, skipTypes, defaultType)\n\n    @property\n    def tagMap(self):\n        \"\"\"Return a *TagMap* object from tags and types recursively.\n\n        Return a :class:`~pyasn1.type.tagmap.TagMap` object by\n        combining tags from *TagMap* objects of children types and\n        associating them with their immediate child type.\n\n        Example\n        -------\n        .. code-block:: python\n\n           OuterType ::= CHOICE {\n               innerType INTEGER\n           }\n\n        Calling *.tagMap* on *OuterType* will yield a map like this:\n\n        .. code-block:: python\n\n           Integer.tagSet -> Choice\n        \"\"\"\n        return self.__nonUniqueTagMap\n\n    @property\n    def tagMapUnique(self):\n        \"\"\"Return a *TagMap* object from unique tags and types recursively.\n\n        Return a :class:`~pyasn1.type.tagmap.TagMap` object by\n        combining tags from *TagMap* objects of children types and\n        associating them with their immediate child type.\n\n        Example\n        -------\n        .. code-block:: python\n\n           OuterType ::= CHOICE {\n               innerType INTEGER\n           }\n\n        Calling *.tagMapUnique* on *OuterType* will yield a map like this:\n\n        .. code-block:: python\n\n           Integer.tagSet -> Choice\n\n        Note\n        ----\n\n        Duplicate *TagSet* objects found in the tree of children\n        types would cause error.\n        \"\"\"\n        return self.__uniqueTagMap\n\n    @property\n    def hasOptionalOrDefault(self):\n        return self.__hasOptionalOrDefault\n\n    @property\n    def hasOpenTypes(self):\n        return self.__hasOpenTypes\n\n    @property\n    def namedTypes(self):\n        return tuple(self.__namedTypes)\n\n    @property\n    def requiredComponents(self):\n        return self.__requiredComponents\n"
  },
  {
    "path": "code/default/lib/noarch/pyasn1/type/namedval.py",
    "content": "#\n# This file is part of pyasn1 software.\n#\n# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>\n# License: http://snmplabs.com/pyasn1/license.html\n#\n# ASN.1 named integers\n#\nfrom pyasn1 import error\n\n__all__ = ['NamedValues']\n\n\nclass NamedValues(object):\n    \"\"\"Create named values object.\n\n    The |NamedValues| object represents a collection of string names\n    associated with numeric IDs. These objects are used for giving\n    names to otherwise numerical values.\n\n    |NamedValues| objects are immutable and duck-type Python\n    :class:`dict` object mapping ID to name and vice-versa.\n\n    Parameters\n    ----------\n    \\*args: variable number of two-element :py:class:`tuple`\n\n        name: :py:class:`str`\n            Value label\n\n        value: :py:class:`int`\n            Numeric value\n\n    Keyword Args\n    ------------\n    name: :py:class:`str`\n        Value label\n\n    value: :py:class:`int`\n        Numeric value\n\n    Examples\n    --------\n\n    .. code-block:: pycon\n\n        >>> nv = NamedValues('a', 'b', ('c', 0), d=1)\n        >>> nv\n        >>> {'c': 0, 'd': 1, 'a': 2, 'b': 3}\n        >>> nv[0]\n        'c'\n        >>> nv['a']\n        2\n    \"\"\"\n    def __init__(self, *args, **kwargs):\n        self.__names = {}\n        self.__numbers = {}\n\n        anonymousNames = []\n\n        for namedValue in args:\n            if isinstance(namedValue, (tuple, list)):\n                try:\n                    name, number = namedValue\n\n                except ValueError:\n                    raise error.PyAsn1Error('Not a proper attribute-value pair %r' % (namedValue,))\n\n            else:\n                anonymousNames.append(namedValue)\n                continue\n\n            if name in self.__names:\n                raise error.PyAsn1Error('Duplicate name %s' % (name,))\n\n            if number in self.__numbers:\n                raise error.PyAsn1Error('Duplicate number  %s=%s' % (name, number))\n\n            self.__names[name] = number\n            self.__numbers[number] = name\n\n        for name, number in list(kwargs.items()):\n            if name in self.__names:\n                raise error.PyAsn1Error('Duplicate name %s' % (name,))\n\n            if number in self.__numbers:\n                raise error.PyAsn1Error('Duplicate number  %s=%s' % (name, number))\n\n            self.__names[name] = number\n            self.__numbers[number] = name\n\n        if anonymousNames:\n\n            number = self.__numbers and max(self.__numbers) + 1 or 0\n\n            for name in anonymousNames:\n\n                if name in self.__names:\n                    raise error.PyAsn1Error('Duplicate name %s' % (name,))\n\n                self.__names[name] = number\n                self.__numbers[number] = name\n\n                number += 1\n\n    def __repr__(self):\n        representation = ', '.join(['%s=%d' % x for x in list(self.items())])\n\n        if len(representation) > 64:\n            representation = representation[:32] + '...' + representation[-32:]\n\n        return '<%s object 0x%x enums %s>' % (self.__class__.__name__, id(self), representation)\n\n    def __eq__(self, other):\n        return dict(self) == other\n\n    def __ne__(self, other):\n        return dict(self) != other\n\n    def __lt__(self, other):\n        return dict(self) < other\n\n    def __le__(self, other):\n        return dict(self) <= other\n\n    def __gt__(self, other):\n        return dict(self) > other\n\n    def __ge__(self, other):\n        return dict(self) >= other\n\n    def __hash__(self):\n        return hash(list(self.items()))\n\n    # Python dict protocol (read-only)\n\n    def __getitem__(self, key):\n        try:\n            return self.__numbers[key]\n\n        except KeyError:\n            return self.__names[key]\n\n    def __len__(self):\n        return len(self.__names)\n\n    def __contains__(self, key):\n        return key in self.__names or key in self.__numbers\n\n    def __iter__(self):\n        return iter(self.__names)\n\n    def values(self):\n        return iter(self.__numbers)\n\n    def keys(self):\n        return iter(self.__names)\n\n    def items(self):\n        for name in self.__names:\n            yield name, self.__names[name]\n\n    # support merging\n\n    def __add__(self, namedValues):\n        return self.__class__(*tuple(self.items()) + tuple(namedValues.items()))\n\n    # XXX clone/subtype?\n\n    def clone(self, *args, **kwargs):\n        new = self.__class__(*args, **kwargs)\n        return self + new\n\n    # legacy protocol\n\n    def getName(self, value):\n        if value in self.__numbers:\n            return self.__numbers[value]\n\n    def getValue(self, name):\n        if name in self.__names:\n            return self.__names[name]\n\n    def getValues(self, *names):\n        try:\n            return [self.__names[name] for name in names]\n\n        except KeyError:\n            raise error.PyAsn1Error(\n                'Unknown bit identifier(s): %s' % (set(names).difference(self.__names),)\n            )\n"
  },
  {
    "path": "code/default/lib/noarch/pyasn1/type/opentype.py",
    "content": "#\n# This file is part of pyasn1 software.\n#\n# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>\n# License: http://snmplabs.com/pyasn1/license.html\n#\n\n__all__ = ['OpenType']\n\n\nclass OpenType(object):\n    \"\"\"Create ASN.1 type map indexed by a value\n\n    The *DefinedBy* object models the ASN.1 *DEFINED BY* clause which maps\n    values to ASN.1 types in the context of the ASN.1 SEQUENCE/SET type.\n\n    OpenType objects are duck-type a read-only Python :class:`dict` objects,\n    however the passed `typeMap` is stored by reference.\n\n    Parameters\n    ----------\n    name: :py:class:`str`\n        Field name\n\n    typeMap: :py:class:`dict`\n        A map of value->ASN.1 type. It's stored by reference and can be\n        mutated later to register new mappings.\n\n    Examples\n    --------\n    .. code-block:: python\n\n        openType = OpenType(\n            'id',\n            {1: Integer(),\n             2: OctetString()}\n        )\n        Sequence(\n            componentType=NamedTypes(\n                NamedType('id', Integer()),\n                NamedType('blob', Any(), openType=openType)\n            )\n        )\n    \"\"\"\n\n    def __init__(self, name, typeMap=None):\n        self.__name = name\n        if typeMap is None:\n            self.__typeMap = {}\n        else:\n            self.__typeMap = typeMap\n\n    @property\n    def name(self):\n        return self.__name\n\n    # Python dict protocol\n\n    def values(self):\n        return list(self.__typeMap.values())\n\n    def keys(self):\n        return list(self.__typeMap.keys())\n\n    def items(self):\n        return list(self.__typeMap.items())\n\n    def __contains__(self, key):\n        return key in self.__typeMap\n\n    def __getitem__(self, key):\n        return self.__typeMap[key]\n\n    def __iter__(self):\n        return iter(self.__typeMap)\n"
  },
  {
    "path": "code/default/lib/noarch/pyasn1/type/tag.py",
    "content": "#\n# This file is part of pyasn1 software.\n#\n# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>\n# License: http://snmplabs.com/pyasn1/license.html\n#\nfrom pyasn1 import error\n\n__all__ = ['tagClassUniversal', 'tagClassApplication', 'tagClassContext',\n           'tagClassPrivate', 'tagFormatSimple', 'tagFormatConstructed',\n           'tagCategoryImplicit', 'tagCategoryExplicit',\n           'tagCategoryUntagged', 'Tag', 'TagSet']\n\n#: Identifier for ASN.1 class UNIVERSAL\ntagClassUniversal = 0x00\n\n#: Identifier for ASN.1 class APPLICATION\ntagClassApplication = 0x40\n\n#: Identifier for ASN.1 class context-specific\ntagClassContext = 0x80\n\n#: Identifier for ASN.1 class private\ntagClassPrivate = 0xC0\n\n#: Identifier for \"simple\" ASN.1 structure (e.g. scalar)\ntagFormatSimple = 0x00\n\n#: Identifier for \"constructed\" ASN.1 structure (e.g. may have inner components)\ntagFormatConstructed = 0x20\n\ntagCategoryImplicit = 0x01\ntagCategoryExplicit = 0x02\ntagCategoryUntagged = 0x04\n\n\nclass Tag(object):\n    \"\"\"Create ASN.1 tag\n\n    Represents ASN.1 tag that can be attached to a ASN.1 type to make\n    types distinguishable from each other.\n\n    *Tag* objects are immutable and duck-type Python :class:`tuple` objects\n    holding three integer components of a tag.\n\n    Parameters\n    ----------\n    tagClass: :py:class:`int`\n        Tag *class* value\n\n    tagFormat: :py:class:`int`\n        Tag *format* value\n\n    tagId: :py:class:`int`\n        Tag ID value\n    \"\"\"\n    def __init__(self, tagClass, tagFormat, tagId):\n        if tagId < 0:\n            raise error.PyAsn1Error('Negative tag ID (%s) not allowed' % tagId)\n        self.__tagClass = tagClass\n        self.__tagFormat = tagFormat\n        self.__tagId = tagId\n        self.__tagClassId = tagClass, tagId\n        self.__hash = hash(self.__tagClassId)\n\n    def __repr__(self):\n        representation = '[%s:%s:%s]' % (self.__tagClass, self.__tagFormat, self.__tagId)\n        return '<%s object at 0x%x tag %s>' % (self.__class__.__name__, id(self), representation)\n\n    def __eq__(self, other):\n        return self.__tagClassId == other\n\n    def __ne__(self, other):\n        return self.__tagClassId != other\n\n    def __lt__(self, other):\n        return self.__tagClassId < other\n\n    def __le__(self, other):\n        return self.__tagClassId <= other\n\n    def __gt__(self, other):\n        return self.__tagClassId > other\n\n    def __ge__(self, other):\n        return self.__tagClassId >= other\n\n    def __hash__(self):\n        return self.__hash\n\n    def __getitem__(self, idx):\n        if idx == 0:\n            return self.__tagClass\n        elif idx == 1:\n            return self.__tagFormat\n        elif idx == 2:\n            return self.__tagId\n        else:\n            raise IndexError()\n\n    def __iter__(self):\n        yield self.__tagClass\n        yield self.__tagFormat\n        yield self.__tagId\n\n    def __and__(self, otherTag):\n        return self.__class__(self.__tagClass & otherTag.tagClass,\n                              self.__tagFormat & otherTag.tagFormat,\n                              self.__tagId & otherTag.tagId)\n\n    def __or__(self, otherTag):\n        return self.__class__(self.__tagClass | otherTag.tagClass,\n                              self.__tagFormat | otherTag.tagFormat,\n                              self.__tagId | otherTag.tagId)\n\n    @property\n    def tagClass(self):\n        \"\"\"ASN.1 tag class\n\n        Returns\n        -------\n        : :py:class:`int`\n            Tag class\n        \"\"\"\n        return self.__tagClass\n\n    @property\n    def tagFormat(self):\n        \"\"\"ASN.1 tag format\n\n        Returns\n        -------\n        : :py:class:`int`\n            Tag format\n        \"\"\"\n        return self.__tagFormat\n\n    @property\n    def tagId(self):\n        \"\"\"ASN.1 tag ID\n\n        Returns\n        -------\n        : :py:class:`int`\n            Tag ID\n        \"\"\"\n        return self.__tagId\n\n\nclass TagSet(object):\n    \"\"\"Create a collection of ASN.1 tags\n\n    Represents a combination of :class:`~pyasn1.type.tag.Tag` objects\n    that can be attached to a ASN.1 type to make types distinguishable\n    from each other.\n\n    *TagSet* objects are immutable and duck-type Python :class:`tuple` objects\n    holding arbitrary number of :class:`~pyasn1.type.tag.Tag` objects.\n\n    Parameters\n    ----------\n    baseTag: :class:`~pyasn1.type.tag.Tag`\n        Base *Tag* object. This tag survives IMPLICIT tagging.\n\n    *superTags: :class:`~pyasn1.type.tag.Tag`\n        Additional *Tag* objects taking part in subtyping.\n\n    Examples\n    --------\n    .. code-block:: python\n\n        class OrderNumber(NumericString):\n            '''\n            ASN.1 specification\n\n            Order-number ::=\n                [APPLICATION 5] IMPLICIT NumericString\n            '''\n            tagSet = NumericString.tagSet.tagImplicitly(\n                Tag(tagClassApplication, tagFormatSimple, 5)\n            )\n\n        orderNumber = OrderNumber('1234')\n    \"\"\"\n    def __init__(self, baseTag=(), *superTags):\n        self.__baseTag = baseTag\n        self.__superTags = superTags\n        self.__superTagsClassId = tuple(\n            [(superTag.tagClass, superTag.tagId) for superTag in superTags]\n        )\n        self.__lenOfSuperTags = len(superTags)\n        self.__hash = hash(self.__superTagsClassId)\n\n    def __repr__(self):\n        representation = '-'.join(['%s:%s:%s' % (x.tagClass, x.tagFormat, x.tagId)\n                                   for x in self.__superTags])\n        if representation:\n            representation = 'tags ' + representation\n        else:\n            representation = 'untagged'\n\n        return '<%s object at 0x%x %s>' % (self.__class__.__name__, id(self), representation)\n\n    def __add__(self, superTag):\n        return self.__class__(self.__baseTag, *self.__superTags + (superTag,))\n\n    def __radd__(self, superTag):\n        return self.__class__(self.__baseTag, *(superTag,) + self.__superTags)\n\n    def __getitem__(self, i):\n        if i.__class__ is slice:\n            return self.__class__(self.__baseTag, *self.__superTags[i])\n        else:\n            return self.__superTags[i]\n\n    def __eq__(self, other):\n        return self.__superTagsClassId == other\n\n    def __ne__(self, other):\n        return self.__superTagsClassId != other\n\n    def __lt__(self, other):\n        return self.__superTagsClassId < other\n\n    def __le__(self, other):\n        return self.__superTagsClassId <= other\n\n    def __gt__(self, other):\n        return self.__superTagsClassId > other\n\n    def __ge__(self, other):\n        return self.__superTagsClassId >= other\n\n    def __hash__(self):\n        return self.__hash\n\n    def __len__(self):\n        return self.__lenOfSuperTags\n\n    @property\n    def baseTag(self):\n        \"\"\"Return base ASN.1 tag\n\n        Returns\n        -------\n        : :class:`~pyasn1.type.tag.Tag`\n            Base tag of this *TagSet*\n        \"\"\"\n        return self.__baseTag\n\n    @property\n    def superTags(self):\n        \"\"\"Return ASN.1 tags\n\n        Returns\n        -------\n        : :py:class:`tuple`\n            Tuple of :class:`~pyasn1.type.tag.Tag` objects that this *TagSet* contains\n        \"\"\"\n        return self.__superTags\n\n    def tagExplicitly(self, superTag):\n        \"\"\"Return explicitly tagged *TagSet*\n\n        Create a new *TagSet* representing callee *TagSet* explicitly tagged\n        with passed tag(s). With explicit tagging mode, new tags are appended\n        to existing tag(s).\n\n        Parameters\n        ----------\n        superTag: :class:`~pyasn1.type.tag.Tag`\n            *Tag* object to tag this *TagSet*\n\n        Returns\n        -------\n        : :class:`~pyasn1.type.tag.TagSet`\n            New *TagSet* object\n        \"\"\"\n        if superTag.tagClass == tagClassUniversal:\n            raise error.PyAsn1Error(\"Can't tag with UNIVERSAL class tag\")\n        if superTag.tagFormat != tagFormatConstructed:\n            superTag = Tag(superTag.tagClass, tagFormatConstructed, superTag.tagId)\n        return self + superTag\n\n    def tagImplicitly(self, superTag):\n        \"\"\"Return implicitly tagged *TagSet*\n\n        Create a new *TagSet* representing callee *TagSet* implicitly tagged\n        with passed tag(s). With implicit tagging mode, new tag(s) replace the\n        last existing tag.\n\n        Parameters\n        ----------\n        superTag: :class:`~pyasn1.type.tag.Tag`\n            *Tag* object to tag this *TagSet*\n\n        Returns\n        -------\n        : :class:`~pyasn1.type.tag.TagSet`\n            New *TagSet* object\n        \"\"\"\n        if self.__superTags:\n            superTag = Tag(superTag.tagClass, self.__superTags[-1].tagFormat, superTag.tagId)\n        return self[:-1] + superTag\n\n    def isSuperTagSetOf(self, tagSet):\n        \"\"\"Test type relationship against given *TagSet*\n\n        The callee is considered to be a supertype of given *TagSet*\n        tag-wise if all tags in *TagSet* are present in the callee and\n        they are in the same order.\n\n        Parameters\n        ----------\n        tagSet: :class:`~pyasn1.type.tag.TagSet`\n            *TagSet* object to evaluate against the callee\n\n        Returns\n        -------\n        : :py:class:`bool`\n            `True` if callee is a supertype of *tagSet*\n        \"\"\"\n        if len(tagSet) < self.__lenOfSuperTags:\n            return False\n        return self.__superTags == tagSet[:self.__lenOfSuperTags]\n\n    # Backward compatibility\n\n    def getBaseTag(self):\n        return self.__baseTag\n\ndef initTagSet(tag):\n    return TagSet(tag, tag)\n"
  },
  {
    "path": "code/default/lib/noarch/pyasn1/type/tagmap.py",
    "content": "#\n# This file is part of pyasn1 software.\n#\n# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>\n# License: http://snmplabs.com/pyasn1/license.html\n#\nfrom pyasn1 import error\n\n__all__ = ['TagMap']\n\n\nclass TagMap(object):\n    \"\"\"Map *TagSet* objects to ASN.1 types\n\n    Create an object mapping *TagSet* object to ASN.1 type.\n\n    *TagMap* objects are immutable and duck-type read-only Python\n    :class:`dict` objects holding *TagSet* objects as keys and ASN.1\n    type objects as values.\n\n    Parameters\n    ----------\n    presentTypes: :py:class:`dict`\n        Map of :class:`~pyasn1.type.tag.TagSet` to ASN.1 objects considered\n        as being unconditionally present in the *TagMap*.\n\n    skipTypes: :py:class:`dict`\n        A collection of :class:`~pyasn1.type.tag.TagSet` objects considered\n        as absent in the *TagMap* even when *defaultType* is present.\n\n    defaultType: ASN.1 type object\n        An ASN.1 type object callee *TagMap* returns for any *TagSet* key not present\n        in *presentTypes* (unless given key is present in *skipTypes*).\n    \"\"\"\n    def __init__(self, presentTypes=None, skipTypes=None, defaultType=None):\n        self.__presentTypes = presentTypes or {}\n        self.__skipTypes = skipTypes or {}\n        self.__defaultType = defaultType\n\n    def __contains__(self, tagSet):\n        return (tagSet in self.__presentTypes or\n                self.__defaultType is not None and tagSet not in self.__skipTypes)\n\n    def __getitem__(self, tagSet):\n        try:\n            return self.__presentTypes[tagSet]\n        except KeyError:\n            if self.__defaultType is None:\n                raise KeyError()\n            elif tagSet in self.__skipTypes:\n                raise error.PyAsn1Error('Key in negative map')\n            else:\n                return self.__defaultType\n\n    def __iter__(self):\n        return iter(self.__presentTypes)\n\n    def __repr__(self):\n        representation = '%s object at 0x%x' % (self.__class__.__name__, id(self))\n\n        if self.__presentTypes:\n            representation += ' present %s' % repr(self.__presentTypes)\n\n        if self.__skipTypes:\n            representation += ' skip %s' % repr(self.__skipTypes)\n\n        if self.__defaultType is not None:\n            representation += ' default %s' % repr(self.__defaultType)\n\n        return '<%s>' % representation\n\n    @property\n    def presentTypes(self):\n        \"\"\"Return *TagSet* to ASN.1 type map present in callee *TagMap*\"\"\"\n        return self.__presentTypes\n\n    @property\n    def skipTypes(self):\n        \"\"\"Return *TagSet* collection unconditionally absent in callee *TagMap*\"\"\"\n        return self.__skipTypes\n\n    @property\n    def defaultType(self):\n        \"\"\"Return default ASN.1 type being returned for any missing *TagSet*\"\"\"\n        return self.__defaultType\n\n    # Backward compatibility\n\n    def getPosMap(self):\n        return self.presentTypes\n\n    def getNegMap(self):\n        return self.skipTypes\n\n    def getDef(self):\n        return self.defaultType\n"
  },
  {
    "path": "code/default/lib/noarch/pyasn1/type/univ.py",
    "content": "#\n# This file is part of pyasn1 software.\n#\n# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>\n# License: http://snmplabs.com/pyasn1/license.html\n#\nimport math\nimport sys\n\nfrom pyasn1 import error\nfrom pyasn1.codec.ber import eoo\nfrom pyasn1.compat import binary\nfrom pyasn1.compat import integer\nfrom pyasn1.compat import octets\nfrom pyasn1.type import base\nfrom pyasn1.type import constraint\nfrom pyasn1.type import namedtype\nfrom pyasn1.type import namedval\nfrom pyasn1.type import tag\nfrom pyasn1.type import tagmap\n\nNoValue = base.NoValue\nnoValue = NoValue()\n\n__all__ = ['Integer', 'Boolean', 'BitString', 'OctetString', 'Null',\n           'ObjectIdentifier', 'Real', 'Enumerated',\n           'SequenceOfAndSetOfBase', 'SequenceOf', 'SetOf',\n           'SequenceAndSetBase', 'Sequence', 'Set', 'Choice', 'Any',\n           'NoValue', 'noValue']\n\n# \"Simple\" ASN.1 types (yet incomplete)\n\n\nclass Integer(base.AbstractSimpleAsn1Item):\n    \"\"\"Create |ASN.1| type or object.\n\n    |ASN.1| objects are immutable and duck-type Python :class:`int` objects.\n\n    Keyword Args\n    ------------\n    value: :class:`int`, :class:`str` or |ASN.1| object\n        Python integer or string literal or |ASN.1| class instance.\n\n    tagSet: :py:class:`~pyasn1.type.tag.TagSet`\n        Object representing non-default ASN.1 tag(s)\n\n    subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`\n        Object representing non-default ASN.1 subtype constraint(s)\n\n    namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`\n        Object representing non-default symbolic aliases for numbers\n\n    Raises\n    ------\n    :py:class:`~pyasn1.error.PyAsn1Error`\n        On constraint violation or bad initializer.\n\n    Examples\n    --------\n\n    .. code-block:: python\n\n        class ErrorCode(Integer):\n            '''\n            ASN.1 specification:\n\n            ErrorCode ::=\n                INTEGER { disk-full(1), no-disk(-1),\n                          disk-not-formatted(2) }\n\n            error ErrorCode ::= disk-full\n            '''\n            namedValues = NamedValues(\n                ('disk-full', 1), ('no-disk', -1),\n                ('disk-not-formatted', 2)\n            )\n\n        error = ErrorCode('disk-full')\n    \"\"\"\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)\n    #: associated with |ASN.1| type.\n    tagSet = tag.initTagSet(\n        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x02)\n    )\n\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object\n    #: imposing constraints on |ASN.1| type initialization values.\n    subtypeSpec = constraint.ConstraintsIntersection()\n\n    #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object\n    #: representing symbolic aliases for numbers\n    namedValues = namedval.NamedValues()\n\n    # Optimization for faster codec lookup\n    typeId = base.AbstractSimpleAsn1Item.getTypeId()\n\n    def __init__(self, value=noValue, **kwargs):\n        if 'namedValues' not in kwargs:\n            kwargs['namedValues'] = self.namedValues\n\n        base.AbstractSimpleAsn1Item.__init__(self, value, **kwargs)\n\n    def __and__(self, value):\n        return self.clone(self._value & value)\n\n    def __rand__(self, value):\n        return self.clone(value & self._value)\n\n    def __or__(self, value):\n        return self.clone(self._value | value)\n\n    def __ror__(self, value):\n        return self.clone(value | self._value)\n\n    def __xor__(self, value):\n        return self.clone(self._value ^ value)\n\n    def __rxor__(self, value):\n        return self.clone(value ^ self._value)\n\n    def __lshift__(self, value):\n        return self.clone(self._value << value)\n\n    def __rshift__(self, value):\n        return self.clone(self._value >> value)\n\n    def __add__(self, value):\n        return self.clone(self._value + value)\n\n    def __radd__(self, value):\n        return self.clone(value + self._value)\n\n    def __sub__(self, value):\n        return self.clone(self._value - value)\n\n    def __rsub__(self, value):\n        return self.clone(value - self._value)\n\n    def __mul__(self, value):\n        return self.clone(self._value * value)\n\n    def __rmul__(self, value):\n        return self.clone(value * self._value)\n\n    def __mod__(self, value):\n        return self.clone(self._value % value)\n\n    def __rmod__(self, value):\n        return self.clone(value % self._value)\n\n    def __pow__(self, value, modulo=None):\n        return self.clone(pow(self._value, value, modulo))\n\n    def __rpow__(self, value):\n        return self.clone(pow(value, self._value))\n\n    def __floordiv__(self, value):\n        return self.clone(self._value // value)\n\n    def __rfloordiv__(self, value):\n        return self.clone(value // self._value)\n\n    if sys.version_info[0] <= 2:\n        def __div__(self, value):\n            if isinstance(value, float):\n                return Real(self._value / value)\n            else:\n                return self.clone(self._value / value)\n\n        def __rdiv__(self, value):\n            if isinstance(value, float):\n                return Real(value / self._value)\n            else:\n                return self.clone(value / self._value)\n    else:\n        def __truediv__(self, value):\n            return Real(self._value / value)\n\n        def __rtruediv__(self, value):\n            return Real(value / self._value)\n\n        def __divmod__(self, value):\n            return self.clone(divmod(self._value, value))\n\n        def __rdivmod__(self, value):\n            return self.clone(divmod(value, self._value))\n\n        __hash__ = base.AbstractSimpleAsn1Item.__hash__\n\n    def __int__(self):\n        return int(self._value)\n\n    if sys.version_info[0] <= 2:\n        def __long__(self):\n            return int(self._value)\n\n    def __float__(self):\n        return float(self._value)\n\n    def __abs__(self):\n        return self.clone(abs(self._value))\n\n    def __index__(self):\n        return int(self._value)\n\n    def __pos__(self):\n        return self.clone(+self._value)\n\n    def __neg__(self):\n        return self.clone(-self._value)\n\n    def __invert__(self):\n        return self.clone(~self._value)\n\n    def __round__(self, n=0):\n        r = round(self._value, n)\n        if n:\n            return self.clone(r)\n        else:\n            return r\n\n    def __floor__(self):\n        return math.floor(self._value)\n\n    def __ceil__(self):\n        return math.ceil(self._value)\n\n    if sys.version_info[0:2] > (2, 5):\n        def __trunc__(self):\n            return self.clone(math.trunc(self._value))\n\n    def __lt__(self, value):\n        return self._value < value\n\n    def __le__(self, value):\n        return self._value <= value\n\n    def __eq__(self, value):\n        return self._value == value\n\n    def __ne__(self, value):\n        return self._value != value\n\n    def __gt__(self, value):\n        return self._value > value\n\n    def __ge__(self, value):\n        return self._value >= value\n\n    def prettyIn(self, value):\n        try:\n            return int(value)\n\n        except ValueError:\n            try:\n                return self.namedValues[value]\n\n            except KeyError:\n                raise error.PyAsn1Error(\n                    'Can\\'t coerce %r into integer: %s' % (value, sys.exc_info()[1])\n                )\n\n    def prettyOut(self, value):\n        try:\n            return str(self.namedValues[value])\n\n        except KeyError:\n            return str(value)\n\n    # backward compatibility\n\n    def getNamedValues(self):\n        return self.namedValues\n\n\nclass Boolean(Integer):\n    \"\"\"Create |ASN.1| type or object.\n\n    |ASN.1| objects are immutable and duck-type Python :class:`int` objects.\n\n    Keyword Args\n    ------------\n    value: :class:`int`, :class:`str` or |ASN.1| object\n        Python integer or boolean or string literal or |ASN.1| class instance.\n\n    tagSet: :py:class:`~pyasn1.type.tag.TagSet`\n        Object representing non-default ASN.1 tag(s)\n\n    subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`\n        Object representing non-default ASN.1 subtype constraint(s)\n\n    namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`\n        Object representing non-default symbolic aliases for numbers\n\n    Raises\n    ------\n    :py:class:`~pyasn1.error.PyAsn1Error`\n        On constraint violation or bad initializer.\n\n    Examples\n    --------\n    .. code-block:: python\n\n        class RoundResult(Boolean):\n            '''\n            ASN.1 specification:\n\n            RoundResult ::= BOOLEAN\n\n            ok RoundResult ::= TRUE\n            ko RoundResult ::= FALSE\n            '''\n        ok = RoundResult(True)\n        ko = RoundResult(False)\n    \"\"\"\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)\n    #: associated with |ASN.1| type.\n    tagSet = tag.initTagSet(\n        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x01),\n    )\n\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object\n    #: imposing constraints on |ASN.1| type initialization values.\n    subtypeSpec = Integer.subtypeSpec + constraint.SingleValueConstraint(0, 1)\n\n    #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object\n    #: representing symbolic aliases for numbers\n    namedValues = namedval.NamedValues(('False', 0), ('True', 1))\n\n    # Optimization for faster codec lookup\n    typeId = Integer.getTypeId()\n\nif sys.version_info[0] < 3:\n    SizedIntegerBase = int\nelse:\n    SizedIntegerBase = int\n\n\nclass SizedInteger(SizedIntegerBase):\n    bitLength = leadingZeroBits = None\n\n    def setBitLength(self, bitLength):\n        self.bitLength = bitLength\n        self.leadingZeroBits = max(bitLength - integer.bitLength(self), 0)\n        return self\n\n    def __len__(self):\n        if self.bitLength is None:\n            self.setBitLength(integer.bitLength(self))\n\n        return self.bitLength\n\n\nclass BitString(base.AbstractSimpleAsn1Item):\n    \"\"\"Create |ASN.1| schema or value object.\n\n    |ASN.1| objects are immutable and duck-type both Python :class:`tuple` (as a tuple\n    of bits) and :class:`int` objects.\n\n    Keyword Args\n    ------------\n    value: :class:`int`, :class:`str` or |ASN.1| object\n        Python integer or string literal representing binary or hexadecimal\n        number or sequence of integer bits or |ASN.1| object.\n\n    tagSet: :py:class:`~pyasn1.type.tag.TagSet`\n        Object representing non-default ASN.1 tag(s)\n\n    subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`\n        Object representing non-default ASN.1 subtype constraint(s)\n\n    namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`\n        Object representing non-default symbolic aliases for numbers\n\n    binValue: :py:class:`str`\n        Binary string initializer to use instead of the *value*.\n        Example: '10110011'.\n\n    hexValue: :py:class:`str`\n        Hexadecimal string initializer to use instead of the *value*.\n        Example: 'DEADBEEF'.\n\n    Raises\n    ------\n    :py:class:`~pyasn1.error.PyAsn1Error`\n        On constraint violation or bad initializer.\n\n    Examples\n    --------\n    .. code-block:: python\n\n        class Rights(BitString):\n            '''\n            ASN.1 specification:\n\n            Rights ::= BIT STRING { user-read(0), user-write(1),\n                                    group-read(2), group-write(3),\n                                    other-read(4), other-write(5) }\n\n            group1 Rights ::= { group-read, group-write }\n            group2 Rights ::= '0011'B\n            group3 Rights ::= '3'H\n            '''\n            namedValues = NamedValues(\n                ('user-read', 0), ('user-write', 1),\n                ('group-read', 2), ('group-write', 3),\n                ('other-read', 4), ('other-write', 5)\n            )\n\n        group1 = Rights(('group-read', 'group-write'))\n        group2 = Rights('0011')\n        group3 = Rights(0x3)\n    \"\"\"\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)\n    #: associated with |ASN.1| type.\n    tagSet = tag.initTagSet(\n        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x03)\n    )\n\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object\n    #: imposing constraints on |ASN.1| type initialization values.\n    subtypeSpec = constraint.ConstraintsIntersection()\n\n    #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object\n    #: representing symbolic aliases for numbers\n    namedValues = namedval.NamedValues()\n\n    # Optimization for faster codec lookup\n    typeId = base.AbstractSimpleAsn1Item.getTypeId()\n\n    defaultBinValue = defaultHexValue = noValue\n\n    def __init__(self, value=noValue, **kwargs):\n        if value is noValue:\n            if kwargs:\n                try:\n                    value = self.fromBinaryString(kwargs.pop('binValue'), internalFormat=True)\n\n                except KeyError:\n                    pass\n\n                try:\n                    value = self.fromHexString(kwargs.pop('hexValue'), internalFormat=True)\n\n                except KeyError:\n                    pass\n\n        if value is noValue:\n            if self.defaultBinValue is not noValue:\n                value = self.fromBinaryString(self.defaultBinValue, internalFormat=True)\n\n            elif self.defaultHexValue is not noValue:\n                value = self.fromHexString(self.defaultHexValue, internalFormat=True)\n\n        if 'namedValues' not in kwargs:\n            kwargs['namedValues'] = self.namedValues\n\n        base.AbstractSimpleAsn1Item.__init__(self, value, **kwargs)\n\n    def __str__(self):\n        return self.asBinary()\n\n    def __eq__(self, other):\n        other = self.prettyIn(other)\n        return self is other or self._value == other and len(self._value) == len(other)\n\n    def __ne__(self, other):\n        other = self.prettyIn(other)\n        return self._value != other or len(self._value) != len(other)\n\n    def __lt__(self, other):\n        other = self.prettyIn(other)\n        return len(self._value) < len(other) or len(self._value) == len(other) and self._value < other\n\n    def __le__(self, other):\n        other = self.prettyIn(other)\n        return len(self._value) <= len(other) or len(self._value) == len(other) and self._value <= other\n\n    def __gt__(self, other):\n        other = self.prettyIn(other)\n        return len(self._value) > len(other) or len(self._value) == len(other) and self._value > other\n\n    def __ge__(self, other):\n        other = self.prettyIn(other)\n        return len(self._value) >= len(other) or len(self._value) == len(other) and self._value >= other\n\n    # Immutable sequence object protocol\n\n    def __len__(self):\n        return len(self._value)\n\n    def __getitem__(self, i):\n        if i.__class__ is slice:\n            return self.clone([self[x] for x in range(*i.indices(len(self)))])\n        else:\n            length = len(self._value) - 1\n            if i > length or i < 0:\n                raise IndexError('bit index out of range')\n            return (self._value >> (length - i)) & 1\n\n    def __iter__(self):\n        length = len(self._value)\n        while length:\n            length -= 1\n            yield (self._value >> length) & 1\n\n    def __reversed__(self):\n        return reversed(tuple(self))\n\n    # arithmetic operators\n\n    def __add__(self, value):\n        value = self.prettyIn(value)\n        return self.clone(SizedInteger(self._value << len(value) | value).setBitLength(len(self._value) + len(value)))\n\n    def __radd__(self, value):\n        value = self.prettyIn(value)\n        return self.clone(SizedInteger(value << len(self._value) | self._value).setBitLength(len(self._value) + len(value)))\n\n    def __mul__(self, value):\n        bitString = self._value\n        while value > 1:\n            bitString <<= len(self._value)\n            bitString |= self._value\n            value -= 1\n        return self.clone(bitString)\n\n    def __rmul__(self, value):\n        return self * value\n\n    def __lshift__(self, count):\n        return self.clone(SizedInteger(self._value << count).setBitLength(len(self._value) + count))\n\n    def __rshift__(self, count):\n        return self.clone(SizedInteger(self._value >> count).setBitLength(max(0, len(self._value) - count)))\n\n    def __int__(self):\n        return self._value\n\n    def __float__(self):\n        return float(self._value)\n\n    if sys.version_info[0] < 3:\n        def __long__(self):\n            return self._value\n\n    def asNumbers(self):\n        \"\"\"Get |ASN.1| value as a sequence of 8-bit integers.\n\n        If |ASN.1| object length is not a multiple of 8, result\n        will be left-padded with zeros.\n        \"\"\"\n        return tuple(octets.octs2ints(self.asOctets()))\n\n    def asOctets(self):\n        \"\"\"Get |ASN.1| value as a sequence of octets.\n\n        If |ASN.1| object length is not a multiple of 8, result\n        will be left-padded with zeros.\n        \"\"\"\n        return integer.to_bytes(self._value, length=len(self))\n\n    def asInteger(self):\n        \"\"\"Get |ASN.1| value as a single integer value.\n        \"\"\"\n        return self._value\n\n    def asBinary(self):\n        \"\"\"Get |ASN.1| value as a text string of bits.\n        \"\"\"\n        binString = binary.bin(self._value)[2:]\n        return '0' * (len(self._value) - len(binString)) + binString\n\n    @classmethod\n    def fromHexString(cls, value, internalFormat=False, prepend=None):\n        \"\"\"Create a |ASN.1| object initialized from the hex string.\n\n        Parameters\n        ----------\n        value: :class:`str`\n            Text string like 'DEADBEEF'\n        \"\"\"\n        try:\n            value = SizedInteger(value, 16).setBitLength(len(value) * 4)\n\n        except ValueError:\n            raise error.PyAsn1Error('%s.fromHexString() error: %s' % (cls.__name__, sys.exc_info()[1]))\n\n        if prepend is not None:\n            value = SizedInteger(\n                (SizedInteger(prepend) << len(value)) | value\n            ).setBitLength(len(prepend) + len(value))\n\n        if not internalFormat:\n            value = cls(value)\n\n        return value\n\n    @classmethod\n    def fromBinaryString(cls, value, internalFormat=False, prepend=None):\n        \"\"\"Create a |ASN.1| object initialized from a string of '0' and '1'.\n\n        Parameters\n        ----------\n        value: :class:`str`\n            Text string like '1010111'\n        \"\"\"\n        try:\n            value = SizedInteger(value or '0', 2).setBitLength(len(value))\n\n        except ValueError:\n            raise error.PyAsn1Error('%s.fromBinaryString() error: %s' % (cls.__name__, sys.exc_info()[1]))\n\n        if prepend is not None:\n            value = SizedInteger(\n                (SizedInteger(prepend) << len(value)) | value\n            ).setBitLength(len(prepend) + len(value))\n\n        if not internalFormat:\n            value = cls(value)\n\n        return value\n\n    @classmethod\n    def fromOctetString(cls, value, internalFormat=False, prepend=None, padding=0):\n        \"\"\"Create a |ASN.1| object initialized from a string.\n\n        Parameters\n        ----------\n        value: :class:`str` (Py2) or :class:`bytes` (Py3)\n            Text string like '\\\\\\\\x01\\\\\\\\xff' (Py2) or b'\\\\\\\\x01\\\\\\\\xff' (Py3)\n        \"\"\"\n        value = SizedInteger(integer.from_bytes(value) >> padding).setBitLength(len(value) * 8 - padding)\n\n        if prepend is not None:\n            value = SizedInteger(\n                (SizedInteger(prepend) << len(value)) | value\n            ).setBitLength(len(prepend) + len(value))\n\n        if not internalFormat:\n            value = cls(value)\n\n        return value\n\n    def prettyIn(self, value):\n        if isinstance(value, SizedInteger):\n            return value\n        elif octets.isStringType(value):\n            if not value:\n                return SizedInteger(0).setBitLength(0)\n\n            elif value[0] == '\\'':  # \"'1011'B\" -- ASN.1 schema representation (deprecated)\n                if value[-2:] == '\\'B':\n                    return self.fromBinaryString(value[1:-2], internalFormat=True)\n                elif value[-2:] == '\\'H':\n                    return self.fromHexString(value[1:-2], internalFormat=True)\n                else:\n                    raise error.PyAsn1Error(\n                        'Bad BIT STRING value notation %s' % (value,)\n                    )\n\n            elif self.namedValues and not value.isdigit():  # named bits like 'Urgent, Active'\n                names = [x.strip() for x in value.split(',')]\n\n                try:\n\n                    bitPositions = [self.namedValues[name] for name in names]\n\n                except KeyError:\n                    raise error.PyAsn1Error('unknown bit name(s) in %r' % (names,))\n\n                rightmostPosition = max(bitPositions)\n\n                number = 0\n                for bitPosition in bitPositions:\n                    number |= 1 << (rightmostPosition - bitPosition)\n\n                return SizedInteger(number).setBitLength(rightmostPosition + 1)\n\n            elif value.startswith('0x'):\n                return self.fromHexString(value[2:], internalFormat=True)\n\n            elif value.startswith('0b'):\n                return self.fromBinaryString(value[2:], internalFormat=True)\n\n            else:  # assume plain binary string like '1011'\n                return self.fromBinaryString(value, internalFormat=True)\n\n        elif isinstance(value, (tuple, list)):\n            return self.fromBinaryString(''.join([b and '1' or '0' for b in value]), internalFormat=True)\n\n        elif isinstance(value, BitString):\n            return SizedInteger(value).setBitLength(len(value))\n\n        elif isinstance(value, intTypes):\n            return SizedInteger(value)\n\n        else:\n            raise error.PyAsn1Error(\n                'Bad BitString initializer type \\'%s\\'' % (value,)\n            )\n\n\ntry:\n    # noinspection PyStatementEffect\n    all\n\nexcept NameError:  # Python 2.4\n    # noinspection PyShadowingBuiltins\n    def all(iterable):\n        for element in iterable:\n            if not element:\n                return False\n        return True\n\n\nclass OctetString(base.AbstractSimpleAsn1Item):\n    \"\"\"Create |ASN.1| schema or value object.\n\n    |ASN.1| objects are immutable and duck-type Python 2 :class:`str` or Python 3 :class:`bytes`.\n    When used in Unicode context, |ASN.1| type assumes \"|encoding|\" serialisation.\n\n    Keyword Args\n    ------------\n    value: :class:`str`, :class:`bytes` or |ASN.1| object\n        string (Python 2) or bytes (Python 3), alternatively unicode object\n        (Python 2) or string (Python 3) representing character string to be\n        serialised into octets (note `encoding` parameter) or |ASN.1| object.\n\n    tagSet: :py:class:`~pyasn1.type.tag.TagSet`\n        Object representing non-default ASN.1 tag(s)\n\n    subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`\n        Object representing non-default ASN.1 subtype constraint(s)\n\n    encoding: :py:class:`str`\n        Unicode codec ID to encode/decode :class:`unicode` (Python 2) or\n        :class:`str` (Python 3) the payload when |ASN.1| object is used\n        in text string context.\n\n    binValue: :py:class:`str`\n        Binary string initializer to use instead of the *value*.\n        Example: '10110011'.\n\n    hexValue: :py:class:`str`\n        Hexadecimal string initializer to use instead of the *value*.\n        Example: 'DEADBEEF'.\n\n    Raises\n    ------\n    :py:class:`~pyasn1.error.PyAsn1Error`\n        On constraint violation or bad initializer.\n\n    Examples\n    --------\n    .. code-block:: python\n\n        class Icon(OctetString):\n            '''\n            ASN.1 specification:\n\n            Icon ::= OCTET STRING\n\n            icon1 Icon ::= '001100010011001000110011'B\n            icon2 Icon ::= '313233'H\n            '''\n        icon1 = Icon.fromBinaryString('001100010011001000110011')\n        icon2 = Icon.fromHexString('313233')\n    \"\"\"\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)\n    #: associated with |ASN.1| type.\n    tagSet = tag.initTagSet(\n        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x04)\n    )\n\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object\n    #: imposing constraints on |ASN.1| type initialization values.\n    subtypeSpec = constraint.ConstraintsIntersection()\n\n    # Optimization for faster codec lookup\n    typeId = base.AbstractSimpleAsn1Item.getTypeId()\n\n    defaultBinValue = defaultHexValue = noValue\n    encoding = 'iso-8859-1'\n\n    def __init__(self, value=noValue, **kwargs):\n        if kwargs:\n            if value is noValue:\n                try:\n                    value = self.fromBinaryString(kwargs.pop('binValue'))\n\n                except KeyError:\n                    pass\n\n                try:\n                    value = self.fromHexString(kwargs.pop('hexValue'))\n\n                except KeyError:\n                    pass\n\n        if value is noValue:\n            if self.defaultBinValue is not noValue:\n                value = self.fromBinaryString(self.defaultBinValue)\n\n            elif self.defaultHexValue is not noValue:\n                value = self.fromHexString(self.defaultHexValue)\n\n        if 'encoding' not in kwargs:\n            kwargs['encoding'] = self.encoding\n\n        base.AbstractSimpleAsn1Item.__init__(self, value, **kwargs)\n\n    if sys.version_info[0] <= 2:\n        def prettyIn(self, value):\n            if isinstance(value, str):\n                return value\n            elif isinstance(value, str):\n                try:\n                    return value.encode(self.encoding)\n                except (LookupError, UnicodeEncodeError):\n                    raise error.PyAsn1Error(\n                        \"Can't encode string '%s' with codec %s\" % (value, self.encoding)\n                    )\n            elif isinstance(value, (tuple, list)):\n                try:\n                    return ''.join([chr(x) for x in value])\n                except ValueError:\n                    raise error.PyAsn1Error(\n                        \"Bad %s initializer '%s'\" % (self.__class__.__name__, value)\n                    )\n            else:\n                return str(value)\n\n        def __str__(self):\n            return str(self._value)\n\n        def __unicode__(self):\n            try:\n                return self._value.decode(self.encoding)\n\n            except UnicodeDecodeError:\n                raise error.PyAsn1Error(\n                    \"Can't decode string '%s' with codec %s\" % (self._value, self.encoding)\n                )\n\n        def asOctets(self):\n            return str(self._value)\n\n        def asNumbers(self):\n            return tuple([ord(x) for x in self._value])\n\n    else:\n        def prettyIn(self, value):\n            if isinstance(value, bytes):\n                return value\n            elif isinstance(value, str):\n                try:\n                    return value.encode(self.encoding)\n                except UnicodeEncodeError:\n                    raise error.PyAsn1Error(\n                        \"Can't encode string '%s' with '%s' codec\" % (value, self.encoding)\n                    )\n            elif isinstance(value, OctetString):  # a shortcut, bytes() would work the same way\n                return value.asOctets()\n            elif isinstance(value, base.AbstractSimpleAsn1Item):  # this mostly targets Integer objects\n                return self.prettyIn(str(value))\n            elif isinstance(value, (tuple, list)):\n                return self.prettyIn(bytes(value))\n            else:\n                return bytes(value)\n\n        def __str__(self):\n            try:\n                return self._value.decode(self.encoding)\n\n            except UnicodeDecodeError:\n                raise error.PyAsn1Error(\n                    \"Can't decode string '%s' with '%s' codec at '%s'\" % (self._value, self.encoding, self.__class__.__name__)\n                )\n\n        def __bytes__(self):\n            return bytes(self._value)\n\n        def asOctets(self):\n            return bytes(self._value)\n\n        def asNumbers(self):\n            return tuple(self._value)\n\n    #\n    # Normally, `.prettyPrint()` is called from `__str__()`. Historically,\n    # OctetString.prettyPrint() used to return hexified payload\n    # representation in cases when non-printable content is present. At the\n    # same time `str()` used to produce either octet-stream (Py2) or\n    # text (Py3) representations.\n    #\n    # Therefore `OctetString.__str__()` -> `.prettyPrint()` call chain is\n    # reversed to preserve the original behaviour.\n    #\n    # Eventually we should deprecate `.prettyPrint()` / `.prettyOut()` harness\n    # and end up with just `__str__()` producing hexified representation while\n    # both text and octet-stream representation should only be requested via\n    # the `.asOctets()` method.\n    #\n    # Note: ASN.1 OCTET STRING is never mean to contain text!\n    #\n\n    def prettyOut(self, value):\n        return value\n\n    def prettyPrint(self, scope=0):\n        # first see if subclass has its own .prettyOut()\n        value = self.prettyOut(self._value)\n\n        if value is not self._value:\n            return value\n\n        numbers = self.asNumbers()\n\n        for x in numbers:\n            # hexify if needed\n            if x < 32 or x > 126:\n                return '0x' + ''.join(('%.2x' % x for x in numbers))\n        else:\n            # this prevents infinite recursion\n            return OctetString.__str__(self)\n\n    @staticmethod\n    def fromBinaryString(value):\n        \"\"\"Create a |ASN.1| object initialized from a string of '0' and '1'.\n\n        Parameters\n        ----------\n        value: :class:`str`\n            Text string like '1010111'\n        \"\"\"\n        bitNo = 8\n        byte = 0\n        r = []\n        for v in value:\n            if bitNo:\n                bitNo -= 1\n            else:\n                bitNo = 7\n                r.append(byte)\n                byte = 0\n            if v in ('0', '1'):\n                v = int(v)\n            else:\n                raise error.PyAsn1Error(\n                    'Non-binary OCTET STRING initializer %s' % (v,)\n                )\n            byte |= v << bitNo\n\n        r.append(byte)\n\n        return octets.ints2octs(r)\n\n    @staticmethod\n    def fromHexString(value):\n        \"\"\"Create a |ASN.1| object initialized from the hex string.\n\n        Parameters\n        ----------\n        value: :class:`str`\n            Text string like 'DEADBEEF'\n        \"\"\"\n        r = []\n        p = []\n        for v in value:\n            if p:\n                r.append(int(p + v, 16))\n                p = None\n            else:\n                p = v\n        if p:\n            r.append(int(p + '0', 16))\n\n        return octets.ints2octs(r)\n\n    # Immutable sequence object protocol\n\n    def __len__(self):\n        return len(self._value)\n\n    def __getitem__(self, i):\n        if i.__class__ is slice:\n            return self.clone(self._value[i])\n        else:\n            return self._value[i]\n\n    def __iter__(self):\n        return iter(self._value)\n\n    def __contains__(self, value):\n        return value in self._value\n\n    def __add__(self, value):\n        return self.clone(self._value + self.prettyIn(value))\n\n    def __radd__(self, value):\n        return self.clone(self.prettyIn(value) + self._value)\n\n    def __mul__(self, value):\n        return self.clone(self._value * value)\n\n    def __rmul__(self, value):\n        return self * value\n\n    def __int__(self):\n        return int(self._value)\n\n    def __float__(self):\n        return float(self._value)\n\n    def __reversed__(self):\n        return reversed(self._value)\n\n\nclass Null(OctetString):\n    \"\"\"Create |ASN.1| schema or value object.\n\n    |ASN.1| objects are immutable and duck-type Python :class:`str` objects (always empty).\n\n    Keyword Args\n    ------------\n    value: :class:`str` or :py:class:`~pyasn1.type.univ.Null` object\n        Python empty string literal or any object that evaluates to `False`\n\n    tagSet: :py:class:`~pyasn1.type.tag.TagSet`\n        Object representing non-default ASN.1 tag(s)\n\n    Raises\n    ------\n    :py:class:`~pyasn1.error.PyAsn1Error`\n        On constraint violation or bad initializer.\n\n    Examples\n    --------\n    .. code-block:: python\n\n        class Ack(Null):\n            '''\n            ASN.1 specification:\n\n            Ack ::= NULL\n            '''\n        ack = Ack('')\n    \"\"\"\n\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)\n    #: associated with |ASN.1| type.\n    tagSet = tag.initTagSet(\n        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x05)\n    )\n    subtypeSpec = OctetString.subtypeSpec + constraint.SingleValueConstraint(octets.str2octs(''))\n\n    # Optimization for faster codec lookup\n    typeId = OctetString.getTypeId()\n\n    def prettyIn(self, value):\n        if value:\n            return value\n\n        return octets.str2octs('')\n\nif sys.version_info[0] <= 2:\n    intTypes = (int, int)\nelse:\n    intTypes = (int,)\n\nnumericTypes = intTypes + (float,)\n\n\nclass ObjectIdentifier(base.AbstractSimpleAsn1Item):\n    \"\"\"Create |ASN.1| schema or value object.\n\n    |ASN.1| objects are immutable and duck-type Python :class:`tuple` objects (tuple of non-negative integers).\n\n    Keyword Args\n    ------------\n    value: :class:`tuple`, :class:`str` or |ASN.1| object\n        Python sequence of :class:`int` or string literal or |ASN.1| object.\n\n    tagSet: :py:class:`~pyasn1.type.tag.TagSet`\n        Object representing non-default ASN.1 tag(s)\n\n    subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`\n        Object representing non-default ASN.1 subtype constraint(s)\n\n    Raises\n    ------\n    :py:class:`~pyasn1.error.PyAsn1Error`\n        On constraint violation or bad initializer.\n\n    Examples\n    --------\n    .. code-block:: python\n\n        class ID(ObjectIdentifier):\n            '''\n            ASN.1 specification:\n\n            ID ::= OBJECT IDENTIFIER\n\n            id-edims ID ::= { joint-iso-itu-t mhs-motif(6) edims(7) }\n            id-bp ID ::= { id-edims 11 }\n            '''\n        id_edims = ID('2.6.7')\n        id_bp = id_edims + (11,)\n    \"\"\"\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)\n    #: associated with |ASN.1| type.\n    tagSet = tag.initTagSet(\n        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x06)\n    )\n\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object\n    #: imposing constraints on |ASN.1| type initialization values.\n    subtypeSpec = constraint.ConstraintsIntersection()\n\n    # Optimization for faster codec lookup\n    typeId = base.AbstractSimpleAsn1Item.getTypeId()\n\n    def __add__(self, other):\n        return self.clone(self._value + other)\n\n    def __radd__(self, other):\n        return self.clone(other + self._value)\n\n    def asTuple(self):\n        return self._value\n\n    # Sequence object protocol\n\n    def __len__(self):\n        return len(self._value)\n\n    def __getitem__(self, i):\n        if i.__class__ is slice:\n            return self.clone(self._value[i])\n        else:\n            return self._value[i]\n\n    def __iter__(self):\n        return iter(self._value)\n\n    def __contains__(self, value):\n        return value in self._value\n\n    def index(self, suboid):\n        return self._value.index(suboid)\n\n    def isPrefixOf(self, other):\n        \"\"\"Indicate if this |ASN.1| object is a prefix of other |ASN.1| object.\n\n        Parameters\n        ----------\n        other: |ASN.1| object\n            |ASN.1| object\n\n        Returns\n        -------\n        : :class:`bool`\n            :class:`True` if this |ASN.1| object is a parent (e.g. prefix) of the other |ASN.1| object\n            or :class:`False` otherwise.\n        \"\"\"\n        l = len(self)\n        if l <= len(other):\n            if self._value[:l] == other[:l]:\n                return True\n        return False\n\n    def prettyIn(self, value):\n        if isinstance(value, ObjectIdentifier):\n            return tuple(value)\n        elif octets.isStringType(value):\n            if '-' in value:\n                raise error.PyAsn1Error(\n                    'Malformed Object ID %s at %s: %s' % (value, self.__class__.__name__, sys.exc_info()[1])\n                )\n            try:\n                return tuple([int(subOid) for subOid in value.split('.') if subOid])\n            except ValueError:\n                raise error.PyAsn1Error(\n                    'Malformed Object ID %s at %s: %s' % (value, self.__class__.__name__, sys.exc_info()[1])\n                )\n\n        try:\n            tupleOfInts = tuple([int(subOid) for subOid in value if subOid >= 0])\n\n        except (ValueError, TypeError):\n            raise error.PyAsn1Error(\n                'Malformed Object ID %s at %s: %s' % (value, self.__class__.__name__, sys.exc_info()[1])\n            )\n\n        if len(tupleOfInts) == len(value):\n            return tupleOfInts\n\n        raise error.PyAsn1Error('Malformed Object ID %s at %s' % (value, self.__class__.__name__))\n\n    def prettyOut(self, value):\n        return '.'.join([str(x) for x in value])\n\n\nclass Real(base.AbstractSimpleAsn1Item):\n    \"\"\"Create |ASN.1| schema or value object.\n\n    |ASN.1| objects are immutable and duck-type Python :class:`float` objects.\n    Additionally, |ASN.1| objects behave like a :class:`tuple` in which case its\n    elements are mantissa, base and exponent.\n\n    Keyword Args\n    ------------\n    value: :class:`tuple`, :class:`float` or |ASN.1| object\n        Python sequence of :class:`int` (representing mantissa, base and\n        exponent) or float instance or *Real* class instance.\n\n    tagSet: :py:class:`~pyasn1.type.tag.TagSet`\n        Object representing non-default ASN.1 tag(s)\n\n    subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`\n        Object representing non-default ASN.1 subtype constraint(s)\n\n    Raises\n    ------\n    :py:class:`~pyasn1.error.PyAsn1Error`\n        On constraint violation or bad initializer.\n\n    Examples\n    --------\n    .. code-block:: python\n\n        class Pi(Real):\n            '''\n            ASN.1 specification:\n\n            Pi ::= REAL\n\n            pi Pi ::= { mantissa 314159, base 10, exponent -5 }\n\n            '''\n        pi = Pi((314159, 10, -5))\n    \"\"\"\n    binEncBase = None  # binEncBase = 16 is recommended for large numbers\n\n    try:\n        _plusInf = float('inf')\n        _minusInf = float('-inf')\n        _inf = _plusInf, _minusInf\n\n    except ValueError:\n        # Infinity support is platform and Python dependent\n        _plusInf = _minusInf = None\n        _inf = ()\n\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)\n    #: associated with |ASN.1| type.\n    tagSet = tag.initTagSet(\n        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x09)\n    )\n\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object\n    #: imposing constraints on |ASN.1| type initialization values.\n    subtypeSpec = constraint.ConstraintsIntersection()\n\n    # Optimization for faster codec lookup\n    typeId = base.AbstractSimpleAsn1Item.getTypeId()\n\n    @staticmethod\n    def __normalizeBase10(value):\n        m, b, e = value\n        while m and m % 10 == 0:\n            m /= 10\n            e += 1\n        return m, b, e\n\n    def prettyIn(self, value):\n        if isinstance(value, tuple) and len(value) == 3:\n            if (not isinstance(value[0], numericTypes) or\n                    not isinstance(value[1], intTypes) or\n                    not isinstance(value[2], intTypes)):\n                raise error.PyAsn1Error('Lame Real value syntax: %s' % (value,))\n            if (isinstance(value[0], float) and\n                    self._inf and value[0] in self._inf):\n                return value[0]\n            if value[1] not in (2, 10):\n                raise error.PyAsn1Error(\n                    'Prohibited base for Real value: %s' % (value[1],)\n                )\n            if value[1] == 10:\n                value = self.__normalizeBase10(value)\n            return value\n        elif isinstance(value, intTypes):\n            return self.__normalizeBase10((value, 10, 0))\n        elif isinstance(value, float) or octets.isStringType(value):\n            if octets.isStringType(value):\n                try:\n                    value = float(value)\n                except ValueError:\n                    raise error.PyAsn1Error(\n                        'Bad real value syntax: %s' % (value,)\n                    )\n            if self._inf and value in self._inf:\n                return value\n            else:\n                e = 0\n                while int(value) != value:\n                    value *= 10\n                    e -= 1\n                return self.__normalizeBase10((int(value), 10, e))\n        elif isinstance(value, Real):\n            return tuple(value)\n        raise error.PyAsn1Error(\n            'Bad real value syntax: %s' % (value,)\n        )\n\n    def prettyPrint(self, scope=0):\n        try:\n            return self.prettyOut(float(self))\n\n        except OverflowError:\n            return '<overflow>'\n\n    @property\n    def isPlusInf(self):\n        \"\"\"Indicate PLUS-INFINITY object value\n\n        Returns\n        -------\n        : :class:`bool`\n            :class:`True` if calling object represents plus infinity\n            or :class:`False` otherwise.\n\n        \"\"\"\n        return self._value == self._plusInf\n\n    @property\n    def isMinusInf(self):\n        \"\"\"Indicate MINUS-INFINITY object value\n\n        Returns\n        -------\n        : :class:`bool`\n            :class:`True` if calling object represents minus infinity\n            or :class:`False` otherwise.\n        \"\"\"\n        return self._value == self._minusInf\n\n    @property\n    def isInf(self):\n        return self._value in self._inf\n\n    def __add__(self, value):\n        return self.clone(float(self) + value)\n\n    def __radd__(self, value):\n        return self + value\n\n    def __mul__(self, value):\n        return self.clone(float(self) * value)\n\n    def __rmul__(self, value):\n        return self * value\n\n    def __sub__(self, value):\n        return self.clone(float(self) - value)\n\n    def __rsub__(self, value):\n        return self.clone(value - float(self))\n\n    def __mod__(self, value):\n        return self.clone(float(self) % value)\n\n    def __rmod__(self, value):\n        return self.clone(value % float(self))\n\n    def __pow__(self, value, modulo=None):\n        return self.clone(pow(float(self), value, modulo))\n\n    def __rpow__(self, value):\n        return self.clone(pow(value, float(self)))\n\n    if sys.version_info[0] <= 2:\n        def __div__(self, value):\n            return self.clone(float(self) / value)\n\n        def __rdiv__(self, value):\n            return self.clone(value / float(self))\n    else:\n        def __truediv__(self, value):\n            return self.clone(float(self) / value)\n\n        def __rtruediv__(self, value):\n            return self.clone(value / float(self))\n\n        def __divmod__(self, value):\n            return self.clone(float(self) // value)\n\n        def __rdivmod__(self, value):\n            return self.clone(value // float(self))\n\n    def __int__(self):\n        return int(float(self))\n\n    if sys.version_info[0] <= 2:\n        def __long__(self):\n            return int(float(self))\n\n    def __float__(self):\n        if self._value in self._inf:\n            return self._value\n        else:\n            return float(\n                self._value[0] * pow(self._value[1], self._value[2])\n            )\n\n    def __abs__(self):\n        return self.clone(abs(float(self)))\n\n    def __pos__(self):\n        return self.clone(+float(self))\n\n    def __neg__(self):\n        return self.clone(-float(self))\n\n    def __round__(self, n=0):\n        r = round(float(self), n)\n        if n:\n            return self.clone(r)\n        else:\n            return r\n\n    def __floor__(self):\n        return self.clone(math.floor(float(self)))\n\n    def __ceil__(self):\n        return self.clone(math.ceil(float(self)))\n\n    if sys.version_info[0:2] > (2, 5):\n        def __trunc__(self):\n            return self.clone(math.trunc(float(self)))\n\n    def __lt__(self, value):\n        return float(self) < value\n\n    def __le__(self, value):\n        return float(self) <= value\n\n    def __eq__(self, value):\n        return float(self) == value\n\n    def __ne__(self, value):\n        return float(self) != value\n\n    def __gt__(self, value):\n        return float(self) > value\n\n    def __ge__(self, value):\n        return float(self) >= value\n\n    if sys.version_info[0] <= 2:\n        def __nonzero__(self):\n            return bool(float(self))\n    else:\n        def __bool__(self):\n            return bool(float(self))\n\n        __hash__ = base.AbstractSimpleAsn1Item.__hash__\n\n    def __getitem__(self, idx):\n        if self._value in self._inf:\n            raise error.PyAsn1Error('Invalid infinite value operation')\n        else:\n            return self._value[idx]\n\n    # compatibility stubs\n\n    def isPlusInfinity(self):\n        return self.isPlusInf\n\n    def isMinusInfinity(self):\n        return self.isMinusInf\n\n    def isInfinity(self):\n        return self.isInf\n\n\nclass Enumerated(Integer):\n    \"\"\"Create |ASN.1| type or object.\n\n    |ASN.1| objects are immutable and duck-type Python :class:`int` objects.\n\n    Keyword Args\n    ------------\n    value: :class:`int`, :class:`str` or |ASN.1| object\n        Python integer or string literal or |ASN.1| class instance.\n\n    tagSet: :py:class:`~pyasn1.type.tag.TagSet`\n        Object representing non-default ASN.1 tag(s)\n\n    subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`\n        Object representing non-default ASN.1 subtype constraint(s)\n\n    namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`\n        Object representing non-default symbolic aliases for numbers\n\n    Raises\n    ------\n    :py:class:`~pyasn1.error.PyAsn1Error`\n        On constraint violation or bad initializer.\n\n    Examples\n    --------\n\n    .. code-block:: python\n\n        class RadioButton(Enumerated):\n            '''\n            ASN.1 specification:\n\n            RadioButton ::= ENUMERATED { button1(0), button2(1),\n                                         button3(2) }\n\n            selected-by-default RadioButton ::= button1\n            '''\n            namedValues = NamedValues(\n                ('button1', 0), ('button2', 1),\n                ('button3', 2)\n            )\n\n        selected_by_default = RadioButton('button1')\n    \"\"\"\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)\n    #: associated with |ASN.1| type.\n    tagSet = tag.initTagSet(\n        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x0A)\n    )\n\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object\n    #: imposing constraints on |ASN.1| type initialization values.\n    subtypeSpec = constraint.ConstraintsIntersection()\n\n    # Optimization for faster codec lookup\n    typeId = Integer.getTypeId()\n\n    #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object\n    #: representing symbolic aliases for numbers\n    namedValues = namedval.NamedValues()\n\n\n# \"Structured\" ASN.1 types\n\nclass SequenceOfAndSetOfBase(base.AbstractConstructedAsn1Item):\n    \"\"\"Create |ASN.1| type.\n\n    |ASN.1| objects are mutable and duck-type Python :class:`list` objects.\n\n    Keyword Args\n    ------------\n    componentType : :py:class:`~pyasn1.type.base.PyAsn1Item` derivative\n        A pyasn1 object representing ASN.1 type allowed within |ASN.1| type\n\n    tagSet: :py:class:`~pyasn1.type.tag.TagSet`\n        Object representing non-default ASN.1 tag(s)\n\n    subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`\n        Object representing non-default ASN.1 subtype constraint(s)\n\n    sizeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`\n        Object representing collection size constraint\n\n    Examples\n    --------\n\n    .. code-block:: python\n\n        class LotteryDraw(SequenceOf):  #  SetOf is similar\n            '''\n            ASN.1 specification:\n\n            LotteryDraw ::= SEQUENCE OF INTEGER\n            '''\n            componentType = Integer()\n\n        lotteryDraw = LotteryDraw()\n        lotteryDraw.extend([123, 456, 789])\n    \"\"\"\n    def __init__(self, *args, **kwargs):\n        # support positional params for backward compatibility\n        if args:\n            for key, value in zip(('componentType', 'tagSet',\n                                   'subtypeSpec', 'sizeSpec'), args):\n                if key in kwargs:\n                    raise error.PyAsn1Error('Conflicting positional and keyword params!')\n                kwargs['componentType'] = value\n\n        base.AbstractConstructedAsn1Item.__init__(self, **kwargs)\n\n    # Python list protocol\n\n    def __getitem__(self, idx):\n        try:\n            return self.getComponentByPosition(idx)\n\n        except error.PyAsn1Error:\n            raise IndexError(sys.exc_info()[1])\n\n    def __setitem__(self, idx, value):\n        try:\n            self.setComponentByPosition(idx, value)\n\n        except error.PyAsn1Error:\n            raise IndexError(sys.exc_info()[1])\n\n    def clear(self):\n        self._componentValues = []\n\n    def append(self, value):\n        self[len(self)] = value\n\n    def count(self, value):\n        return self._componentValues.count(value)\n\n    def extend(self, values):\n        for value in values:\n            self.append(value)\n\n    def index(self, value, start=0, stop=None):\n        if stop is None:\n            stop = len(self)\n        try:\n            return self._componentValues.index(value, start, stop)\n\n        except error.PyAsn1Error:\n            raise ValueError(sys.exc_info()[1])\n\n    def reverse(self):\n        self._componentValues.reverse()\n\n    def sort(self, key=None, reverse=False):\n        self._componentValues.sort(key=key, reverse=reverse)\n\n    def __iter__(self):\n        return iter(self._componentValues)\n\n    def _cloneComponentValues(self, myClone, cloneValueFlag):\n        for idx, componentValue in enumerate(self._componentValues):\n            if componentValue is not noValue:\n                if isinstance(componentValue, base.AbstractConstructedAsn1Item):\n                    myClone.setComponentByPosition(\n                        idx, componentValue.clone(cloneValueFlag=cloneValueFlag)\n                    )\n                else:\n                    myClone.setComponentByPosition(idx, componentValue.clone())\n\n    def getComponentByPosition(self, idx, default=noValue, instantiate=True):\n        \"\"\"Return |ASN.1| type component value by position.\n\n        Equivalent to Python sequence subscription operation (e.g. `[]`).\n\n        Parameters\n        ----------\n        idx : :class:`int`\n            Component index (zero-based). Must either refer to an existing\n            component or to N+1 component (if *componentType* is set). In the latter\n            case a new component type gets instantiated and appended to the |ASN.1|\n            sequence.\n\n        Keyword Args\n        ------------\n        default: :class:`object`\n            If set and requested component is a schema object, return the `default`\n            object instead of the requested component.\n\n        instantiate: :class:`bool`\n            If `True` (default), inner component will be automatically instantiated.\n            If 'False' either existing component or the `noValue` object will be\n            returned.\n\n        Returns\n        -------\n        : :py:class:`~pyasn1.type.base.PyAsn1Item`\n            Instantiate |ASN.1| component type or return existing component value\n\n        Examples\n        --------\n\n        .. code-block:: python\n\n            # can also be SetOf\n            class MySequenceOf(SequenceOf):\n                componentType = OctetString()\n\n            s = MySequenceOf()\n\n            # returns component #0 with `.isValue` property False\n            s.getComponentByPosition(0)\n\n            # returns None\n            s.getComponentByPosition(0, default=None)\n\n            s.clear()\n\n            # returns noValue\n            s.getComponentByPosition(0, instantiate=False)\n\n            # sets component #0 to OctetString() ASN.1 schema\n            # object and returns it\n            s.getComponentByPosition(0, instantiate=True)\n\n            # sets component #0 to ASN.1 value object\n            s.setComponentByPosition(0, 'ABCD')\n\n            # returns OctetString('ABCD') value object\n            s.getComponentByPosition(0, instantiate=False)\n\n            s.clear()\n\n            # returns noValue\n            s.getComponentByPosition(0, instantiate=False)\n        \"\"\"\n        try:\n            componentValue = self._componentValues[idx]\n\n        except IndexError:\n            if not instantiate:\n                return default\n\n            self.setComponentByPosition(idx)\n\n            componentValue = self._componentValues[idx]\n\n        if default is noValue or componentValue.isValue:\n            return componentValue\n        else:\n            return default\n\n    def setComponentByPosition(self, idx, value=noValue,\n                               verifyConstraints=True,\n                               matchTags=True,\n                               matchConstraints=True):\n        \"\"\"Assign |ASN.1| type component by position.\n\n        Equivalent to Python sequence item assignment operation (e.g. `[]`)\n        or list.append() (when idx == len(self)).\n\n        Parameters\n        ----------\n        idx: :class:`int`\n            Component index (zero-based). Must either refer to existing\n            component or to N+1 component. In the latter case a new component\n            type gets instantiated (if *componentType* is set, or given ASN.1\n            object is taken otherwise) and appended to the |ASN.1| sequence.\n\n        Keyword Args\n        ------------\n        value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative\n            A Python value to initialize |ASN.1| component with (if *componentType* is set)\n            or ASN.1 value object to assign to |ASN.1| component.\n\n        verifyConstraints: :class:`bool`\n             If `False`, skip constraints validation\n\n        matchTags: :class:`bool`\n             If `False`, skip component tags matching\n\n        matchConstraints: :class:`bool`\n             If `False`, skip component constraints matching\n\n        Returns\n        -------\n        self\n\n        Raises\n        ------\n        IndexError:\n            When idx > len(self)\n        \"\"\"\n        componentType = self.componentType\n\n        try:\n            currentValue = self._componentValues[idx]\n        except IndexError:\n            currentValue = noValue\n\n            if len(self._componentValues) < idx:\n                raise error.PyAsn1Error('Component index out of range')\n\n        if value is noValue:\n            if componentType is not None:\n                value = componentType.clone()\n            elif currentValue is noValue:\n                raise error.PyAsn1Error('Component type not defined')\n        elif not isinstance(value, base.Asn1Item):\n            if componentType is not None and isinstance(componentType, base.AbstractSimpleAsn1Item):\n                value = componentType.clone(value=value)\n            elif currentValue is not noValue and isinstance(currentValue, base.AbstractSimpleAsn1Item):\n                value = currentValue.clone(value=value)\n            else:\n                raise error.PyAsn1Error('Non-ASN.1 value %r and undefined component type at %r' % (value, self))\n        elif componentType is not None:\n            if self.strictConstraints:\n                if not componentType.isSameTypeWith(value, matchTags, matchConstraints):\n                    raise error.PyAsn1Error('Component value is tag-incompatible: %r vs %r' % (value, componentType))\n            else:\n                if not componentType.isSuperTypeOf(value, matchTags, matchConstraints):\n                    raise error.PyAsn1Error('Component value is tag-incompatible: %r vs %r' % (value, componentType))\n\n        if verifyConstraints and value.isValue:\n            try:\n                self.subtypeSpec(value, idx)\n\n            except error.PyAsn1Error:\n                exType, exValue, exTb = sys.exc_info()\n                raise exType('%s at %s' % (exValue, self.__class__.__name__))\n\n        if currentValue is noValue:\n            self._componentValues.append(value)\n        else:\n            self._componentValues[idx] = value\n\n        return self\n\n    @property\n    def componentTagMap(self):\n        if self.componentType is not None:\n            return self.componentType.tagMap\n\n    def prettyPrint(self, scope=0):\n        scope += 1\n        representation = self.__class__.__name__ + ':\\n'\n        for idx, componentValue in enumerate(self._componentValues):\n            representation += ' ' * scope\n            if (componentValue is noValue and\n                    self.componentType is not None):\n                representation += '<empty>'\n            else:\n                representation += componentValue.prettyPrint(scope)\n        return representation\n\n    def prettyPrintType(self, scope=0):\n        scope += 1\n        representation = '%s -> %s {\\n' % (self.tagSet, self.__class__.__name__)\n        if self.componentType is not None:\n            representation += ' ' * scope\n            representation += self.componentType.prettyPrintType(scope)\n        return representation + '\\n' + ' ' * (scope - 1) + '}'\n\n\n    @property\n    def isValue(self):\n        \"\"\"Indicate that |ASN.1| object represents ASN.1 value.\n\n        If *isValue* is `False` then this object represents just ASN.1 schema.\n\n        If *isValue* is `True` then, in addition to its ASN.1 schema features,\n        this object can also be used like a Python built-in object (e.g. `int`,\n        `str`, `dict` etc.).\n\n        Returns\n        -------\n        : :class:`bool`\n            :class:`False` if object represents just ASN.1 schema.\n            :class:`True` if object represents ASN.1 schema and can be used as a normal value.\n\n        Note\n        ----\n        There is an important distinction between PyASN1 schema and value objects.\n        The PyASN1 schema objects can only participate in ASN.1 schema-related\n        operations (e.g. defining or testing the structure of the data). Most\n        obvious uses of ASN.1 schema is to guide serialisation codecs whilst\n        encoding/decoding serialised ASN.1 contents.\n\n        The PyASN1 value objects can **additionally** participate in many operations\n        involving regular Python objects (e.g. arithmetic, comprehension etc).\n        \"\"\"\n        for componentValue in self._componentValues:\n            if componentValue is noValue or not componentValue.isValue:\n                return False\n\n        return True\n\n\nclass SequenceOf(SequenceOfAndSetOfBase):\n    __doc__ = SequenceOfAndSetOfBase.__doc__\n\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)\n    #: associated with |ASN.1| type.\n    tagSet = tag.initTagSet(\n        tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10)\n    )\n\n    #: Default :py:class:`~pyasn1.type.base.PyAsn1Item` derivative\n    #: object representing ASN.1 type allowed within |ASN.1| type\n    componentType = None\n\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object\n    #: imposing constraints on |ASN.1| type initialization values.\n    subtypeSpec = constraint.ConstraintsIntersection()\n\n    #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`\n    #: object imposing size constraint on |ASN.1| objects\n    sizeSpec = constraint.ConstraintsIntersection()\n\n    # Disambiguation ASN.1 types identification\n    typeId = SequenceOfAndSetOfBase.getTypeId()\n\n\nclass SetOf(SequenceOfAndSetOfBase):\n    __doc__ = SequenceOfAndSetOfBase.__doc__\n\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)\n    #: associated with |ASN.1| type.\n    tagSet = tag.initTagSet(\n        tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11)\n    )\n\n    #: Default :py:class:`~pyasn1.type.base.PyAsn1Item` derivative\n    #: object representing ASN.1 type allowed within |ASN.1| type\n    componentType = None\n\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object\n    #: imposing constraints on |ASN.1| type initialization values.\n    subtypeSpec = constraint.ConstraintsIntersection()\n\n    #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`\n    #: object imposing size constraint on |ASN.1| objects\n    sizeSpec = constraint.ConstraintsIntersection()\n\n    # Disambiguation ASN.1 types identification\n    typeId = SequenceOfAndSetOfBase.getTypeId()\n\n\nclass SequenceAndSetBase(base.AbstractConstructedAsn1Item):\n    \"\"\"Create |ASN.1| type.\n\n    |ASN.1| objects are mutable and duck-type Python :class:`dict` objects.\n\n    Keyword Args\n    ------------\n    componentType: :py:class:`~pyasn1.type.namedtype.NamedType`\n        Object holding named ASN.1 types allowed within this collection\n\n    tagSet: :py:class:`~pyasn1.type.tag.TagSet`\n        Object representing non-default ASN.1 tag(s)\n\n    subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`\n        Object representing non-default ASN.1 subtype constraint(s)\n\n    sizeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`\n        Object representing collection size constraint\n\n    Examples\n    --------\n\n    .. code-block:: python\n\n        class Description(Sequence):  #  Set is similar\n            '''\n            ASN.1 specification:\n\n            Description ::= SEQUENCE {\n                surname    IA5String,\n                first-name IA5String OPTIONAL,\n                age        INTEGER DEFAULT 40\n            }\n            '''\n            componentType = NamedTypes(\n                NamedType('surname', IA5String()),\n                OptionalNamedType('first-name', IA5String()),\n                DefaultedNamedType('age', Integer(40))\n            )\n\n        descr = Description()\n        descr['surname'] = 'Smith'\n        descr['first-name'] = 'John'\n    \"\"\"\n    #: Default :py:class:`~pyasn1.type.namedtype.NamedTypes`\n    #: object representing named ASN.1 types allowed within |ASN.1| type\n    componentType = namedtype.NamedTypes()\n\n\n    class DynamicNames(object):\n        \"\"\"Fields names/positions mapping for component-less objects\"\"\"\n        def __init__(self):\n            self._keyToIdxMap = {}\n            self._idxToKeyMap = {}\n\n        def __len__(self):\n            return len(self._keyToIdxMap)\n\n        def __contains__(self, item):\n            return item in self._keyToIdxMap or item in self._idxToKeyMap\n\n        def __iter__(self):\n            return (self._idxToKeyMap[idx] for idx in range(len(self._idxToKeyMap)))\n\n        def __getitem__(self, item):\n            try:\n                return self._keyToIdxMap[item]\n\n            except KeyError:\n                return self._idxToKeyMap[item]\n\n        def getNameByPosition(self, idx):\n            try:\n                return self._idxToKeyMap[idx]\n\n            except KeyError:\n                raise error.PyAsn1Error('Type position out of range')\n\n        def getPositionByName(self, name):\n            try:\n                return self._keyToIdxMap[name]\n\n            except KeyError:\n                raise error.PyAsn1Error('Name %s not found' % (name,))\n\n        def addField(self, idx):\n            self._keyToIdxMap['field-%d' % idx] = idx\n            self._idxToKeyMap[idx] = 'field-%d' % idx\n\n\n    def __init__(self, **kwargs):\n        base.AbstractConstructedAsn1Item.__init__(self, **kwargs)\n        self._componentTypeLen = len(self.componentType)\n        self._dynamicNames = self._componentTypeLen or self.DynamicNames()\n\n    def __getitem__(self, idx):\n        if octets.isStringType(idx):\n            try:\n                return self.getComponentByName(idx)\n\n            except error.PyAsn1Error:\n                # duck-typing dict\n                raise KeyError(sys.exc_info()[1])\n\n        else:\n            try:\n                return self.getComponentByPosition(idx)\n\n            except error.PyAsn1Error:\n                # duck-typing list\n                raise IndexError(sys.exc_info()[1])\n\n    def __setitem__(self, idx, value):\n        if octets.isStringType(idx):\n            try:\n                self.setComponentByName(idx, value)\n\n            except error.PyAsn1Error:\n                # duck-typing dict\n                raise KeyError(sys.exc_info()[1])\n\n        else:\n            try:\n                self.setComponentByPosition(idx, value)\n\n            except error.PyAsn1Error:\n                # duck-typing list\n                raise IndexError(sys.exc_info()[1])\n\n    def __contains__(self, key):\n        if self._componentTypeLen:\n            return key in self.componentType\n        else:\n            return key in self._dynamicNames\n\n    def __iter__(self):\n        return iter(self.componentType or self._dynamicNames)\n\n    # Python dict protocol\n\n    def values(self):\n        for idx in range(self._componentTypeLen or len(self._dynamicNames)):\n            yield self[idx]\n\n    def keys(self):\n        return iter(self)\n\n    def items(self):\n        for idx in range(self._componentTypeLen or len(self._dynamicNames)):\n            if self._componentTypeLen:\n                yield self.componentType[idx].name, self[idx]\n            else:\n                yield self._dynamicNames[idx], self[idx]\n\n    def update(self, *iterValue, **mappingValue):\n        for k, v in iterValue:\n            self[k] = v\n        for k in mappingValue:\n            self[k] = mappingValue[k]\n\n    def clear(self):\n        self._componentValues = []\n        self._dynamicNames = self.DynamicNames()\n\n    def _cloneComponentValues(self, myClone, cloneValueFlag):\n        for idx, componentValue in enumerate(self._componentValues):\n            if componentValue is not noValue:\n                if isinstance(componentValue, base.AbstractConstructedAsn1Item):\n                    myClone.setComponentByPosition(\n                        idx, componentValue.clone(cloneValueFlag=cloneValueFlag)\n                    )\n                else:\n                    myClone.setComponentByPosition(idx, componentValue.clone())\n\n    def getComponentByName(self, name, default=noValue, instantiate=True):\n        \"\"\"Returns |ASN.1| type component by name.\n\n        Equivalent to Python :class:`dict` subscription operation (e.g. `[]`).\n\n        Parameters\n        ----------\n        name: :class:`str`\n            |ASN.1| type component name\n\n        Keyword Args\n        ------------\n        default: :class:`object`\n            If set and requested component is a schema object, return the `default`\n            object instead of the requested component.\n\n        instantiate: :class:`bool`\n            If `True` (default), inner component will be automatically instantiated.\n            If 'False' either existing component or the `noValue` object will be\n            returned.\n\n        Returns\n        -------\n        : :py:class:`~pyasn1.type.base.PyAsn1Item`\n            Instantiate |ASN.1| component type or return existing component value\n        \"\"\"\n        if self._componentTypeLen:\n            idx = self.componentType.getPositionByName(name)\n        else:\n            try:\n                idx = self._dynamicNames.getPositionByName(name)\n\n            except KeyError:\n                raise error.PyAsn1Error('Name %s not found' % (name,))\n\n        return self.getComponentByPosition(idx, default=default, instantiate=instantiate)\n\n    def setComponentByName(self, name, value=noValue,\n                           verifyConstraints=True,\n                           matchTags=True,\n                           matchConstraints=True):\n        \"\"\"Assign |ASN.1| type component by name.\n\n        Equivalent to Python :class:`dict` item assignment operation (e.g. `[]`).\n\n        Parameters\n        ----------\n        name: :class:`str`\n            |ASN.1| type component name\n\n        Keyword Args\n        ------------\n        value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative\n            A Python value to initialize |ASN.1| component with (if *componentType* is set)\n            or ASN.1 value object to assign to |ASN.1| component.\n\n        verifyConstraints: :class:`bool`\n             If `False`, skip constraints validation\n\n        matchTags: :class:`bool`\n             If `False`, skip component tags matching\n\n        matchConstraints: :class:`bool`\n             If `False`, skip component constraints matching\n\n        Returns\n        -------\n        self\n        \"\"\"\n        if self._componentTypeLen:\n            idx = self.componentType.getPositionByName(name)\n        else:\n            try:\n                idx = self._dynamicNames.getPositionByName(name)\n\n            except KeyError:\n                raise error.PyAsn1Error('Name %s not found' % (name,))\n\n        return self.setComponentByPosition(\n            idx, value, verifyConstraints, matchTags, matchConstraints\n        )\n\n    def getComponentByPosition(self, idx, default=noValue, instantiate=True):\n        \"\"\"Returns |ASN.1| type component by index.\n\n        Equivalent to Python sequence subscription operation (e.g. `[]`).\n\n        Parameters\n        ----------\n        idx: :class:`int`\n            Component index (zero-based). Must either refer to an existing\n            component or (if *componentType* is set) new ASN.1 schema object gets\n            instantiated.\n\n        Keyword Args\n        ------------\n        default: :class:`object`\n            If set and requested component is a schema object, return the `default`\n            object instead of the requested component.\n\n        instantiate: :class:`bool`\n            If `True` (default), inner component will be automatically instantiated.\n            If 'False' either existing component or the `noValue` object will be\n            returned.\n\n        Returns\n        -------\n        : :py:class:`~pyasn1.type.base.PyAsn1Item`\n            a PyASN1 object\n\n        Examples\n        --------\n\n        .. code-block:: python\n\n            # can also be Set\n            class MySequence(Sequence):\n                componentType = NamedTypes(\n                    NamedType('id', OctetString())\n                )\n\n            s = MySequence()\n\n            # returns component #0 with `.isValue` property False\n            s.getComponentByPosition(0)\n\n            # returns None\n            s.getComponentByPosition(0, default=None)\n\n            s.clear()\n\n            # returns noValue\n            s.getComponentByPosition(0, instantiate=False)\n\n            # sets component #0 to OctetString() ASN.1 schema\n            # object and returns it\n            s.getComponentByPosition(0, instantiate=True)\n\n            # sets component #0 to ASN.1 value object\n            s.setComponentByPosition(0, 'ABCD')\n\n            # returns OctetString('ABCD') value object\n            s.getComponentByPosition(0, instantiate=False)\n\n            s.clear()\n\n            # returns noValue\n            s.getComponentByPosition(0, instantiate=False)\n        \"\"\"\n        try:\n            componentValue = self._componentValues[idx]\n\n        except IndexError:\n            componentValue = noValue\n\n        if not instantiate:\n            if componentValue is noValue or not componentValue.isValue:\n                return default\n            else:\n                return componentValue\n\n        if componentValue is noValue:\n            self.setComponentByPosition(idx)\n\n        componentValue = self._componentValues[idx]\n\n        if default is noValue or componentValue.isValue:\n            return componentValue\n        else:\n            return default\n\n    def setComponentByPosition(self, idx, value=noValue,\n                               verifyConstraints=True,\n                               matchTags=True,\n                               matchConstraints=True):\n        \"\"\"Assign |ASN.1| type component by position.\n\n        Equivalent to Python sequence item assignment operation (e.g. `[]`).\n\n        Parameters\n        ----------\n        idx : :class:`int`\n            Component index (zero-based). Must either refer to existing\n            component (if *componentType* is set) or to N+1 component\n            otherwise. In the latter case a new component of given ASN.1\n            type gets instantiated and appended to |ASN.1| sequence.\n\n        Keyword Args\n        ------------\n        value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative\n            A Python value to initialize |ASN.1| component with (if *componentType* is set)\n            or ASN.1 value object to assign to |ASN.1| component.\n\n        verifyConstraints : :class:`bool`\n             If `False`, skip constraints validation\n\n        matchTags: :class:`bool`\n             If `False`, skip component tags matching\n\n        matchConstraints: :class:`bool`\n             If `False`, skip component constraints matching\n\n        Returns\n        -------\n        self\n        \"\"\"\n        componentType = self.componentType\n        componentTypeLen = self._componentTypeLen\n\n        try:\n            currentValue = self._componentValues[idx]\n\n        except IndexError:\n            currentValue = noValue\n            if componentTypeLen:\n                if componentTypeLen < idx:\n                    raise error.PyAsn1Error('component index out of range')\n\n                self._componentValues = [noValue] * componentTypeLen\n\n        if value is noValue:\n            if componentTypeLen:\n                value = componentType.getTypeByPosition(idx).clone()\n\n            elif currentValue is noValue:\n                raise error.PyAsn1Error('Component type not defined')\n\n        elif not isinstance(value, base.Asn1Item):\n            if componentTypeLen:\n                subComponentType = componentType.getTypeByPosition(idx)\n                if isinstance(subComponentType, base.AbstractSimpleAsn1Item):\n                    value = subComponentType.clone(value=value)\n\n                else:\n                    raise error.PyAsn1Error('%s can cast only scalar values' % componentType.__class__.__name__)\n\n            elif currentValue is not noValue and isinstance(currentValue, base.AbstractSimpleAsn1Item):\n                value = currentValue.clone(value=value)\n\n            else:\n                raise error.PyAsn1Error('%s undefined component type' % componentType.__class__.__name__)\n\n        elif (matchTags or matchConstraints) and componentTypeLen:\n            subComponentType = componentType.getTypeByPosition(idx)\n            if subComponentType is not noValue:\n                subtypeChecker = (self.strictConstraints and\n                                  subComponentType.isSameTypeWith or\n                                  subComponentType.isSuperTypeOf)\n\n                if not subtypeChecker(value, matchTags, matchConstraints):\n                    if not componentType[idx].openType:\n                        raise error.PyAsn1Error('Component value is tag-incompatible: %r vs %r' % (value, componentType))\n\n        if verifyConstraints and value.isValue:\n            try:\n                self.subtypeSpec(value, idx)\n\n            except error.PyAsn1Error:\n                exType, exValue, exTb = sys.exc_info()\n                raise exType('%s at %s' % (exValue, self.__class__.__name__))\n\n        if componentTypeLen or idx in self._dynamicNames:\n            self._componentValues[idx] = value\n\n        elif len(self._componentValues) == idx:\n            self._componentValues.append(value)\n            self._dynamicNames.addField(idx)\n\n        else:\n            raise error.PyAsn1Error('Component index out of range')\n\n        return self\n\n    @property\n    def isValue(self):\n        \"\"\"Indicate that |ASN.1| object represents ASN.1 value.\n\n        If *isValue* is `False` then this object represents just ASN.1 schema.\n\n        If *isValue* is `True` then, in addition to its ASN.1 schema features,\n        this object can also be used like a Python built-in object (e.g. `int`,\n        `str`, `dict` etc.).\n\n        Returns\n        -------\n        : :class:`bool`\n            :class:`False` if object represents just ASN.1 schema.\n            :class:`True` if object represents ASN.1 schema and can be used as a normal value.\n\n        Note\n        ----\n        There is an important distinction between PyASN1 schema and value objects.\n        The PyASN1 schema objects can only participate in ASN.1 schema-related\n        operations (e.g. defining or testing the structure of the data). Most\n        obvious uses of ASN.1 schema is to guide serialisation codecs whilst\n        encoding/decoding serialised ASN.1 contents.\n\n        The PyASN1 value objects can **additionally** participate in many operations\n        involving regular Python objects (e.g. arithmetic, comprehension etc).\n        \"\"\"\n        componentType = self.componentType\n\n        if componentType:\n            for idx, subComponentType in enumerate(componentType.namedTypes):\n                if subComponentType.isDefaulted or subComponentType.isOptional:\n                    continue\n\n                if not self._componentValues:\n                    return False\n\n                componentValue = self._componentValues[idx]\n                if componentValue is noValue or not componentValue.isValue:\n                    return False\n\n        else:\n            for componentValue in self._componentValues:\n                if componentValue is noValue or not componentValue.isValue:\n                    return False\n\n        return True\n\n    def prettyPrint(self, scope=0):\n        \"\"\"Return an object representation string.\n\n        Returns\n        -------\n        : :class:`str`\n            Human-friendly object representation.\n        \"\"\"\n        scope += 1\n        representation = self.__class__.__name__ + ':\\n'\n        for idx, componentValue in enumerate(self._componentValues):\n            if componentValue is not noValue:\n                representation += ' ' * scope\n                if self.componentType:\n                    representation += self.componentType.getNameByPosition(idx)\n                else:\n                    representation += self._dynamicNames.getNameByPosition(idx)\n                representation = '%s=%s\\n' % (\n                    representation, componentValue.prettyPrint(scope)\n                )\n        return representation\n\n    def prettyPrintType(self, scope=0):\n        scope += 1\n        representation = '%s -> %s {\\n' % (self.tagSet, self.__class__.__name__)\n        for idx, componentType in enumerate(list(self.componentType.values()) or self._componentValues):\n            representation += ' ' * scope\n            if self.componentType:\n                representation += '\"%s\"' % self.componentType.getNameByPosition(idx)\n            else:\n                representation += '\"%s\"' % self._dynamicNames.getNameByPosition(idx)\n            representation = '%s = %s\\n' % (\n                representation, componentType.prettyPrintType(scope)\n            )\n        return representation + '\\n' + ' ' * (scope - 1) + '}'\n\n    # backward compatibility\n\n    def setDefaultComponents(self):\n        return self\n\n    def getComponentType(self):\n        if self._componentTypeLen:\n            return self.componentType\n\n    def getNameByPosition(self, idx):\n        if self._componentTypeLen:\n            return self.componentType[idx].name\n\n\nclass Sequence(SequenceAndSetBase):\n    __doc__ = SequenceAndSetBase.__doc__\n\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)\n    #: associated with |ASN.1| type.\n    tagSet = tag.initTagSet(\n        tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10)\n    )\n\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object\n    #: imposing constraints on |ASN.1| type initialization values.\n    subtypeSpec = constraint.ConstraintsIntersection()\n\n    #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`\n    #: object imposing constraints on |ASN.1| objects\n    sizeSpec = constraint.ConstraintsIntersection()\n\n    #: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`)\n    #: object imposing size constraint on |ASN.1| objects\n    componentType = namedtype.NamedTypes()\n\n    # Disambiguation ASN.1 types identification\n    typeId = SequenceAndSetBase.getTypeId()\n\n    # backward compatibility\n\n    def getComponentTagMapNearPosition(self, idx):\n        if self.componentType:\n            return self.componentType.getTagMapNearPosition(idx)\n\n    def getComponentPositionNearType(self, tagSet, idx):\n        if self.componentType:\n            return self.componentType.getPositionNearType(tagSet, idx)\n        else:\n            return idx\n\n\nclass Set(SequenceAndSetBase):\n    __doc__ = SequenceAndSetBase.__doc__\n\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)\n    #: associated with |ASN.1| type.\n    tagSet = tag.initTagSet(\n        tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11)\n    )\n\n    #: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`)\n    #: object representing ASN.1 type allowed within |ASN.1| type\n    componentType = namedtype.NamedTypes()\n\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object\n    #: imposing constraints on |ASN.1| type initialization values.\n    subtypeSpec = constraint.ConstraintsIntersection()\n\n    #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`\n    #: object imposing constraints on |ASN.1| objects\n    sizeSpec = constraint.ConstraintsIntersection()\n\n    # Disambiguation ASN.1 types identification\n    typeId = SequenceAndSetBase.getTypeId()\n\n    def getComponent(self, innerFlag=False):\n        return self\n\n    def getComponentByType(self, tagSet, default=noValue,\n                           instantiate=True, innerFlag=False):\n        \"\"\"Returns |ASN.1| type component by ASN.1 tag.\n\n        Parameters\n        ----------\n        tagSet : :py:class:`~pyasn1.type.tag.TagSet`\n            Object representing ASN.1 tags to identify one of\n            |ASN.1| object component\n\n        Keyword Args\n        ------------\n        default: :class:`object`\n            If set and requested component is a schema object, return the `default`\n            object instead of the requested component.\n\n        instantiate: :class:`bool`\n            If `True` (default), inner component will be automatically instantiated.\n            If 'False' either existing component or the `noValue` object will be\n            returned.\n\n        Returns\n        -------\n        : :py:class:`~pyasn1.type.base.PyAsn1Item`\n            a pyasn1 object\n        \"\"\"\n        componentValue = self.getComponentByPosition(\n            self.componentType.getPositionByType(tagSet),\n            default=default, instantiate=instantiate\n        )\n        if innerFlag and isinstance(componentValue, Set):\n            # get inner component by inner tagSet\n            return componentValue.getComponent(innerFlag=True)\n        else:\n            # get outer component by inner tagSet\n            return componentValue\n\n    def setComponentByType(self, tagSet, value=noValue,\n                           verifyConstraints=True,\n                           matchTags=True,\n                           matchConstraints=True,\n                           innerFlag=False):\n        \"\"\"Assign |ASN.1| type component by ASN.1 tag.\n\n        Parameters\n        ----------\n        tagSet : :py:class:`~pyasn1.type.tag.TagSet`\n            Object representing ASN.1 tags to identify one of\n            |ASN.1| object component\n\n        Keyword Args\n        ------------\n        value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative\n            A Python value to initialize |ASN.1| component with (if *componentType* is set)\n            or ASN.1 value object to assign to |ASN.1| component.\n\n        verifyConstraints : :class:`bool`\n            If `False`, skip constraints validation\n\n        matchTags: :class:`bool`\n            If `False`, skip component tags matching\n\n        matchConstraints: :class:`bool`\n            If `False`, skip component constraints matching\n\n        innerFlag: :class:`bool`\n            If `True`, search for matching *tagSet* recursively.\n\n        Returns\n        -------\n        self\n        \"\"\"\n        idx = self.componentType.getPositionByType(tagSet)\n\n        if innerFlag:  # set inner component by inner tagSet\n            componentType = self.componentType.getTypeByPosition(idx)\n\n            if componentType.tagSet:\n                return self.setComponentByPosition(\n                    idx, value, verifyConstraints, matchTags, matchConstraints\n                )\n            else:\n                componentType = self.getComponentByPosition(idx)\n                return componentType.setComponentByType(\n                    tagSet, value, verifyConstraints, matchTags, matchConstraints, innerFlag=innerFlag\n                )\n        else:  # set outer component by inner tagSet\n            return self.setComponentByPosition(\n                idx, value, verifyConstraints, matchTags, matchConstraints\n            )\n\n    @property\n    def componentTagMap(self):\n        if self.componentType:\n            return self.componentType.tagMapUnique\n\n\nclass Choice(Set):\n    \"\"\"Create |ASN.1| type.\n\n    |ASN.1| objects are mutable and duck-type Python :class:`dict` objects.\n\n    Keyword Args\n    ------------\n    componentType: :py:class:`~pyasn1.type.namedtype.NamedType`\n        Object holding named ASN.1 types allowed within this collection\n\n    tagSet: :py:class:`~pyasn1.type.tag.TagSet`\n        Object representing non-default ASN.1 tag(s)\n\n    subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`\n        Object representing non-default ASN.1 subtype constraint(s)\n\n    sizeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`\n        Object representing collection size constraint\n\n    Examples\n    --------\n\n    .. code-block:: python\n\n        class Afters(Choice):\n            '''\n            ASN.1 specification:\n\n            Afters ::= CHOICE {\n                cheese  [0] IA5String,\n                dessert [1] IA5String\n            }\n            '''\n            componentType = NamedTypes(\n                NamedType('cheese', IA5String().subtype(\n                    implicitTag=Tag(tagClassContext, tagFormatSimple, 0)\n                ),\n                NamedType('dessert', IA5String().subtype(\n                    implicitTag=Tag(tagClassContext, tagFormatSimple, 1)\n                )\n            )\n\n        afters = Afters()\n        afters['cheese'] = 'Mascarpone'\n    \"\"\"\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)\n    #: associated with |ASN.1| type.\n    tagSet = tag.TagSet()  # untagged\n\n    #: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`)\n    #: object representing ASN.1 type allowed within |ASN.1| type\n    componentType = namedtype.NamedTypes()\n\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object\n    #: imposing constraints on |ASN.1| type initialization values.\n    subtypeSpec = constraint.ConstraintsIntersection()\n\n    #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`\n    #: object imposing size constraint on |ASN.1| objects\n    sizeSpec = constraint.ConstraintsIntersection(\n        constraint.ValueSizeConstraint(1, 1)\n    )\n\n    # Disambiguation ASN.1 types identification\n    typeId = Set.getTypeId()\n\n    _currentIdx = None\n\n    def __eq__(self, other):\n        if self._componentValues:\n            return self._componentValues[self._currentIdx] == other\n        return NotImplemented\n\n    def __ne__(self, other):\n        if self._componentValues:\n            return self._componentValues[self._currentIdx] != other\n        return NotImplemented\n\n    def __lt__(self, other):\n        if self._componentValues:\n            return self._componentValues[self._currentIdx] < other\n        return NotImplemented\n\n    def __le__(self, other):\n        if self._componentValues:\n            return self._componentValues[self._currentIdx] <= other\n        return NotImplemented\n\n    def __gt__(self, other):\n        if self._componentValues:\n            return self._componentValues[self._currentIdx] > other\n        return NotImplemented\n\n    def __ge__(self, other):\n        if self._componentValues:\n            return self._componentValues[self._currentIdx] >= other\n        return NotImplemented\n\n    if sys.version_info[0] <= 2:\n        def __nonzero__(self):\n            return self._componentValues and True or False\n    else:\n        def __bool__(self):\n            return self._componentValues and True or False\n\n    def __len__(self):\n        return self._currentIdx is not None and 1 or 0\n\n    def __contains__(self, key):\n        if self._currentIdx is None:\n            return False\n        return key == self.componentType[self._currentIdx].getName()\n\n    def __iter__(self):\n        if self._currentIdx is None:\n            raise StopIteration\n        yield self.componentType[self._currentIdx].getName()\n\n    # Python dict protocol\n\n    def values(self):\n        if self._currentIdx is not None:\n            yield self._componentValues[self._currentIdx]\n\n    def keys(self):\n        if self._currentIdx is not None:\n            yield self.componentType[self._currentIdx].getName()\n\n    def items(self):\n        if self._currentIdx is not None:\n            yield self.componentType[self._currentIdx].getName(), self[self._currentIdx]\n\n    def verifySizeSpec(self):\n        if self._currentIdx is None:\n            raise error.PyAsn1Error('Component not chosen')\n\n    def _cloneComponentValues(self, myClone, cloneValueFlag):\n        try:\n            component = self.getComponent()\n        except error.PyAsn1Error:\n            pass\n        else:\n            if isinstance(component, Choice):\n                tagSet = component.effectiveTagSet\n            else:\n                tagSet = component.tagSet\n            if isinstance(component, base.AbstractConstructedAsn1Item):\n                myClone.setComponentByType(\n                    tagSet, component.clone(cloneValueFlag=cloneValueFlag)\n                )\n            else:\n                myClone.setComponentByType(tagSet, component.clone())\n\n    def getComponentByPosition(self, idx, default=noValue, instantiate=True):\n        __doc__ = Set.__doc__\n\n        if self._currentIdx is None or self._currentIdx != idx:\n            return Set.getComponentByPosition(self, idx, default=default,\n                                              instantiate=instantiate)\n\n        return self._componentValues[idx]\n\n    def setComponentByPosition(self, idx, value=noValue,\n                               verifyConstraints=True,\n                               matchTags=True,\n                               matchConstraints=True):\n        \"\"\"Assign |ASN.1| type component by position.\n\n        Equivalent to Python sequence item assignment operation (e.g. `[]`).\n\n        Parameters\n        ----------\n        idx: :class:`int`\n            Component index (zero-based). Must either refer to existing\n            component or to N+1 component. In the latter case a new component\n            type gets instantiated (if *componentType* is set, or given ASN.1\n            object is taken otherwise) and appended to the |ASN.1| sequence.\n\n        Keyword Args\n        ------------\n        value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative\n            A Python value to initialize |ASN.1| component with (if *componentType* is set)\n            or ASN.1 value object to assign to |ASN.1| component. Once a new value is\n            set to *idx* component, previous value is dropped.\n\n        verifyConstraints : :class:`bool`\n            If `False`, skip constraints validation\n\n        matchTags: :class:`bool`\n            If `False`, skip component tags matching\n\n        matchConstraints: :class:`bool`\n            If `False`, skip component constraints matching\n\n        Returns\n        -------\n        self\n        \"\"\"\n        oldIdx = self._currentIdx\n        Set.setComponentByPosition(self, idx, value, verifyConstraints, matchTags, matchConstraints)\n        self._currentIdx = idx\n        if oldIdx is not None and oldIdx != idx:\n            self._componentValues[oldIdx] = noValue\n        return self\n\n    @property\n    def effectiveTagSet(self):\n        \"\"\"Return a :class:`~pyasn1.type.tag.TagSet` object of the currently initialized component or self (if |ASN.1| is tagged).\"\"\"\n        if self.tagSet:\n            return self.tagSet\n        else:\n            component = self.getComponent()\n            return component.effectiveTagSet\n\n    @property\n    def tagMap(self):\n        \"\"\"\"Return a :class:`~pyasn1.type.tagmap.TagMap` object mapping\n            ASN.1 tags to ASN.1 objects contained within callee.\n        \"\"\"\n        if self.tagSet:\n            return Set.tagMap.fget(self)\n        else:\n            return self.componentType.tagMapUnique\n\n    def getComponent(self, innerFlag=False):\n        \"\"\"Return currently assigned component of the |ASN.1| object.\n\n        Returns\n        -------\n        : :py:class:`~pyasn1.type.base.PyAsn1Item`\n            a PyASN1 object\n        \"\"\"\n        if self._currentIdx is None:\n            raise error.PyAsn1Error('Component not chosen')\n        else:\n            c = self._componentValues[self._currentIdx]\n            if innerFlag and isinstance(c, Choice):\n                return c.getComponent(innerFlag)\n            else:\n                return c\n\n    def getName(self, innerFlag=False):\n        \"\"\"Return the name of currently assigned component of the |ASN.1| object.\n\n        Returns\n        -------\n        : :py:class:`str`\n            |ASN.1| component name\n        \"\"\"\n        if self._currentIdx is None:\n            raise error.PyAsn1Error('Component not chosen')\n        else:\n            if innerFlag:\n                c = self._componentValues[self._currentIdx]\n                if isinstance(c, Choice):\n                    return c.getName(innerFlag)\n            return self.componentType.getNameByPosition(self._currentIdx)\n\n    @property\n    def isValue(self):\n        \"\"\"Indicate that |ASN.1| object represents ASN.1 value.\n\n        If *isValue* is `False` then this object represents just ASN.1 schema.\n\n        If *isValue* is `True` then, in addition to its ASN.1 schema features,\n        this object can also be used like a Python built-in object (e.g. `int`,\n        `str`, `dict` etc.).\n\n        Returns\n        -------\n        : :class:`bool`\n            :class:`False` if object represents just ASN.1 schema.\n            :class:`True` if object represents ASN.1 schema and can be used as a normal value.\n\n        Note\n        ----\n        There is an important distinction between PyASN1 schema and value objects.\n        The PyASN1 schema objects can only participate in ASN.1 schema-related\n        operations (e.g. defining or testing the structure of the data). Most\n        obvious uses of ASN.1 schema is to guide serialisation codecs whilst\n        encoding/decoding serialised ASN.1 contents.\n\n        The PyASN1 value objects can **additionally** participate in many operations\n        involving regular Python objects (e.g. arithmetic, comprehension etc).\n        \"\"\"\n        if self._currentIdx is None:\n            return False\n\n        componentValue = self._componentValues[self._currentIdx]\n\n        return componentValue is not noValue and componentValue.isValue\n\n    def clear(self):\n        self._currentIdx = None\n        Set.clear(self)\n\n    # compatibility stubs\n\n    def getMinTagSet(self):\n        return self.minTagSet\n\n\nclass Any(OctetString):\n    \"\"\"Create |ASN.1| schema or value object.\n\n    |ASN.1| objects are immutable and duck-type Python 2 :class:`str` or Python 3\n    :class:`bytes`. When used in Unicode context, |ASN.1| type assumes \"|encoding|\"\n    serialisation.\n\n    Keyword Args\n    ------------\n    value: :class:`str`, :class:`bytes` or |ASN.1| object\n        string (Python 2) or bytes (Python 3), alternatively unicode object\n        (Python 2) or string (Python 3) representing character string to be\n        serialised into octets (note `encoding` parameter) or |ASN.1| object.\n\n    tagSet: :py:class:`~pyasn1.type.tag.TagSet`\n        Object representing non-default ASN.1 tag(s)\n\n    subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`\n        Object representing non-default ASN.1 subtype constraint(s)\n\n    encoding: :py:class:`str`\n        Unicode codec ID to encode/decode :class:`unicode` (Python 2) or\n        :class:`str` (Python 3) the payload when |ASN.1| object is used\n        in text string context.\n\n    binValue: :py:class:`str`\n        Binary string initializer to use instead of the *value*.\n        Example: '10110011'.\n\n    hexValue: :py:class:`str`\n        Hexadecimal string initializer to use instead of the *value*.\n        Example: 'DEADBEEF'.\n\n    Raises\n    ------\n    :py:class:`~pyasn1.error.PyAsn1Error`\n        On constraint violation or bad initializer.\n\n    Examples\n    --------\n    .. code-block:: python\n\n        class Error(Sequence):\n            '''\n            ASN.1 specification:\n\n            Error ::= SEQUENCE {\n                code      INTEGER,\n                parameter ANY DEFINED BY code  -- Either INTEGER or REAL\n            }\n            '''\n            componentType=NamedTypes(\n                NamedType('code', Integer()),\n                NamedType('parameter', Any(),\n                          openType=OpenType('code', {1: Integer(),\n                                                     2: Real()}))\n            )\n\n        error = Error()\n        error['code'] = 1\n        error['parameter'] = Integer(1234)\n    \"\"\"\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)\n    #: associated with |ASN.1| type.\n    tagSet = tag.TagSet()  # untagged\n\n    #: Set (on class, not on instance) or return a\n    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object\n    #: imposing constraints on |ASN.1| type initialization values.\n    subtypeSpec = constraint.ConstraintsIntersection()\n\n    # Disambiguation ASN.1 types identification\n    typeId = OctetString.getTypeId()\n\n    @property\n    def tagMap(self):\n        \"\"\"\"Return a :class:`~pyasn1.type.tagmap.TagMap` object mapping\n            ASN.1 tags to ASN.1 objects contained within callee.\n        \"\"\"\n        try:\n            return self._tagMap\n\n        except AttributeError:\n            self._tagMap = tagmap.TagMap(\n                {self.tagSet: self},\n                {eoo.endOfOctets.tagSet: eoo.endOfOctets},\n                self\n            )\n\n            return self._tagMap\n\n# XXX\n# coercion rules?\n"
  },
  {
    "path": "code/default/lib/noarch/pyasn1/type/useful.py",
    "content": "#\n# This file is part of pyasn1 software.\n#\n# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>\n# License: http://snmplabs.com/pyasn1/license.html\n#\nimport datetime\n\nfrom pyasn1 import error\nfrom pyasn1.compat import dateandtime\nfrom pyasn1.compat import string\nfrom pyasn1.type import char\nfrom pyasn1.type import tag\nfrom pyasn1.type import univ\n\n__all__ = ['ObjectDescriptor', 'GeneralizedTime', 'UTCTime']\n\nNoValue = univ.NoValue\nnoValue = univ.noValue\n\n\nclass ObjectDescriptor(char.GraphicString):\n    __doc__ = char.GraphicString.__doc__\n\n    #: Default :py:class:`~pyasn1.type.tag.TagSet` object for |ASN.1| objects\n    tagSet = char.GraphicString.tagSet.tagImplicitly(\n        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 7)\n    )\n\n    # Optimization for faster codec lookup\n    typeId = char.GraphicString.getTypeId()\n\n\nclass TimeMixIn(object):\n\n    _yearsDigits = 4\n    _hasSubsecond = False\n    _optionalMinutes = False\n    _shortTZ = False\n\n    class FixedOffset(datetime.tzinfo):\n        \"\"\"Fixed offset in minutes east from UTC.\"\"\"\n\n        # defaulted arguments required\n        # https: // docs.python.org / 2.3 / lib / datetime - tzinfo.html\n        def __init__(self, offset=0, name='UTC'):\n            self.__offset = datetime.timedelta(minutes=offset)\n            self.__name = name\n\n        def utcoffset(self, dt):\n            return self.__offset\n\n        def tzname(self, dt):\n            return self.__name\n\n        def dst(self, dt):\n            return datetime.timedelta(0)\n\n    UTC = FixedOffset()\n\n    @property\n    def asDateTime(self):\n        \"\"\"Create :py:class:`datetime.datetime` object from a |ASN.1| object.\n\n        Returns\n        -------\n        :\n            new instance of :py:class:`datetime.datetime` object\n        \"\"\"\n        text = str(self)\n        if text.endswith('Z'):\n            tzinfo = TimeMixIn.UTC\n            text = text[:-1]\n\n        elif '-' in text or '+' in text:\n            if '+' in text:\n                text, plusminus, tz = string.partition(text, '+')\n            else:\n                text, plusminus, tz = string.partition(text, '-')\n\n            if self._shortTZ and len(tz) == 2:\n                tz += '00'\n\n            if len(tz) != 4:\n                raise error.PyAsn1Error('malformed time zone offset %s' % tz)\n\n            try:\n                minutes = int(tz[:2]) * 60 + int(tz[2:])\n                if plusminus == '-':\n                    minutes *= -1\n\n            except ValueError:\n                raise error.PyAsn1Error('unknown time specification %s' % self)\n\n            tzinfo = TimeMixIn.FixedOffset(minutes, '?')\n\n        else:\n            tzinfo = None\n\n        if '.' in text or ',' in text:\n            if '.' in text:\n                text, _, ms = string.partition(text, '.')\n            else:\n                text, _, ms = string.partition(text, ',')\n\n            try:\n                ms = int(ms) * 10000\n\n            except ValueError:\n                raise error.PyAsn1Error('bad sub-second time specification %s' % self)\n\n        else:\n            ms = 0\n\n        if self._optionalMinutes and len(text) - self._yearsDigits == 6:\n            text += '0000'\n        elif len(text) - self._yearsDigits == 8:\n            text += '00'\n\n        try:\n            dt = dateandtime.strptime(text, self._yearsDigits == 4 and '%Y%m%d%H%M%S' or '%y%m%d%H%M%S')\n\n        except ValueError:\n            raise error.PyAsn1Error('malformed datetime format %s' % self)\n\n        return dt.replace(microsecond=ms, tzinfo=tzinfo)\n\n    @classmethod\n    def fromDateTime(cls, dt):\n        \"\"\"Create |ASN.1| object from a :py:class:`datetime.datetime` object.\n\n        Parameters\n        ----------\n        dt: :py:class:`datetime.datetime` object\n            The `datetime.datetime` object to initialize the |ASN.1| object\n            from\n\n        Returns\n        -------\n        :\n            new instance of |ASN.1| value\n        \"\"\"\n        text = dt.strftime(cls._yearsDigits == 4 and '%Y%m%d%H%M%S' or '%y%m%d%H%M%S')\n        if cls._hasSubsecond:\n            text += '.%d' % (dt.microsecond // 10000)\n\n        if dt.utcoffset():\n            seconds = dt.utcoffset().seconds\n            if seconds < 0:\n                text += '-'\n            else:\n                text += '+'\n            text += '%.2d%.2d' % (seconds // 3600, seconds % 3600)\n        else:\n            text += 'Z'\n\n        return cls(text)\n\n\nclass GeneralizedTime(char.VisibleString, TimeMixIn):\n    __doc__ = char.VisibleString.__doc__\n\n    #: Default :py:class:`~pyasn1.type.tag.TagSet` object for |ASN.1| objects\n    tagSet = char.VisibleString.tagSet.tagImplicitly(\n        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 24)\n    )\n\n    # Optimization for faster codec lookup\n    typeId = char.VideotexString.getTypeId()\n\n    _yearsDigits = 4\n    _hasSubsecond = True\n    _optionalMinutes = True\n    _shortTZ = True\n\n\nclass UTCTime(char.VisibleString, TimeMixIn):\n    __doc__ = char.VisibleString.__doc__\n\n    #: Default :py:class:`~pyasn1.type.tag.TagSet` object for |ASN.1| objects\n    tagSet = char.VisibleString.tagSet.tagImplicitly(\n        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 23)\n    )\n\n    # Optimization for faster codec lookup\n    typeId = char.VideotexString.getTypeId()\n\n    _yearsDigits = 2\n    _hasSubsecond = False\n    _optionalMinutes = False\n    _shortTZ = False\n"
  },
  {
    "path": "code/default/lib/noarch/scrypto/__init__.py",
    "content": "#!/usr/bin/env python\n\n# Copyright (c) 2014 clowwindy\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in\n# all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n# SOFTWARE.\n\n\n"
  },
  {
    "path": "code/default/lib/noarch/scrypto/ctypes_openssl.py",
    "content": "#!/usr/bin/env python\n\n# Copyright (c) 2014 clowwindy\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in\n# all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n# SOFTWARE.\n\n\n\nimport xlog\nfrom ctypes import CDLL, c_char_p, c_int, c_long, byref,\\\n    create_string_buffer, c_void_p\n\n__all__ = ['ciphers']\n\nlibcrypto = None\nloaded = False\n\nbuf_size = 2048\n\n\ndef load_openssl():\n    global loaded, libcrypto, buf\n\n    from ctypes.util import find_library\n    for p in ('crypto', 'eay32', 'libeay32'):\n        libcrypto_path = find_library(p)\n        if libcrypto_path:\n            break\n    else:\n        raise Exception('libcrypto(OpenSSL) not found')\n    xlog.info('loading libcrypto from %s', libcrypto_path)\n    libcrypto = CDLL(libcrypto_path)\n    libcrypto.EVP_get_cipherbyname.restype = c_void_p\n    libcrypto.EVP_CIPHER_CTX_new.restype = c_void_p\n\n    libcrypto.EVP_CipherInit_ex.argtypes = (c_void_p, c_void_p, c_char_p,\n                                            c_char_p, c_char_p, c_int)\n\n    libcrypto.EVP_CipherUpdate.argtypes = (c_void_p, c_void_p, c_void_p,\n                                           c_char_p, c_int)\n\n    libcrypto.EVP_CIPHER_CTX_cleanup.argtypes = (c_void_p,)\n    libcrypto.EVP_CIPHER_CTX_free.argtypes = (c_void_p,)\n    if hasattr(libcrypto, 'OpenSSL_add_all_ciphers'):\n        libcrypto.OpenSSL_add_all_ciphers()\n\n    buf = create_string_buffer(buf_size)\n    loaded = True\n\n\ndef load_cipher(cipher_name):\n    func_name = b'EVP_' + cipher_name.replace(b'-', b'_')\n    if bytes != str:\n        func_name = str(func_name, 'utf-8')\n    cipher = getattr(libcrypto, func_name, None)\n    if cipher:\n        cipher.restype = c_void_p\n        return cipher()\n    return None\n\n\nclass CtypesCrypto(object):\n    def __init__(self, cipher_name, key, iv, op):\n        if not loaded:\n            load_openssl()\n        self._ctx = None\n        cipher = libcrypto.EVP_get_cipherbyname(cipher_name)\n        if not cipher:\n            cipher = load_cipher(cipher_name)\n        if not cipher:\n            raise Exception('cipher %s not found in libcrypto' % cipher_name)\n        key_ptr = c_char_p(key)\n        iv_ptr = c_char_p(iv)\n        self._ctx = libcrypto.EVP_CIPHER_CTX_new()\n        if not self._ctx:\n            raise Exception('can not create cipher context')\n        r = libcrypto.EVP_CipherInit_ex(self._ctx, cipher, None,\n                                        key_ptr, iv_ptr, c_int(op))\n        if not r:\n            self.clean()\n            raise Exception('can not initialize cipher context')\n\n    def update(self, data):\n        global buf_size, buf\n        cipher_out_len = c_long(0)\n        l = len(data)\n        if buf_size < l:\n            buf_size = l * 2\n            buf = create_string_buffer(buf_size)\n        libcrypto.EVP_CipherUpdate(self._ctx, byref(buf),\n                                   byref(cipher_out_len), c_char_p(data), l)\n        # buf is copied to a str object when we access buf.raw\n        return buf.raw[:cipher_out_len.value]\n\n    def __del__(self):\n        self.clean()\n\n    def clean(self):\n        if self._ctx:\n            libcrypto.EVP_CIPHER_CTX_cleanup(self._ctx)\n            libcrypto.EVP_CIPHER_CTX_free(self._ctx)\n\n\nciphers = {\n    b'aes-128-cfb': (16, 16, CtypesCrypto),\n    b'aes-192-cfb': (24, 16, CtypesCrypto),\n    b'aes-256-cfb': (32, 16, CtypesCrypto),\n    b'aes-128-ofb': (16, 16, CtypesCrypto),\n    b'aes-192-ofb': (24, 16, CtypesCrypto),\n    b'aes-256-ofb': (32, 16, CtypesCrypto),\n    b'aes-128-ctr': (16, 16, CtypesCrypto),\n    b'aes-192-ctr': (24, 16, CtypesCrypto),\n    b'aes-256-ctr': (32, 16, CtypesCrypto),\n    b'aes-128-cfb8': (16, 16, CtypesCrypto),\n    b'aes-192-cfb8': (24, 16, CtypesCrypto),\n    b'aes-256-cfb8': (32, 16, CtypesCrypto),\n    b'aes-128-cfb1': (16, 16, CtypesCrypto),\n    b'aes-192-cfb1': (24, 16, CtypesCrypto),\n    b'aes-256-cfb1': (32, 16, CtypesCrypto),\n    b'bf-cfb': (16, 8, CtypesCrypto),\n    b'camellia-128-cfb': (16, 16, CtypesCrypto),\n    b'camellia-192-cfb': (24, 16, CtypesCrypto),\n    b'camellia-256-cfb': (32, 16, CtypesCrypto),\n    b'cast5-cfb': (16, 8, CtypesCrypto),\n    b'des-cfb': (8, 8, CtypesCrypto),\n    b'idea-cfb': (16, 8, CtypesCrypto),\n    b'rc2-cfb': (16, 8, CtypesCrypto),\n    b'rc4': (16, 0, CtypesCrypto),\n    b'seed-cfb': (16, 16, CtypesCrypto),\n}\n\n\ndef run_method(method):\n    from shadowsocks.crypto import util\n\n    cipher = CtypesCrypto(method, b'k' * 32, b'i' * 16, 1)\n    decipher = CtypesCrypto(method, b'k' * 32, b'i' * 16, 0)\n\n    util.run_cipher(cipher, decipher)\n\n\ndef test_aes_128_cfb():\n    run_method(b'aes-128-cfb')\n\n\ndef test_aes_256_cfb():\n    run_method(b'aes-256-cfb')\n\n\ndef test_aes_128_cfb8():\n    run_method(b'aes-128-cfb8')\n\n\ndef test_aes_256_ofb():\n    run_method(b'aes-256-ofb')\n\n\ndef test_aes_256_ctr():\n    run_method(b'aes-256-ctr')\n\n\ndef test_bf_cfb():\n    run_method(b'bf-cfb')\n\n\ndef test_rc4():\n    run_method(b'rc4')\n\n\nif __name__ == '__main__':\n    test_aes_128_cfb()\n"
  },
  {
    "path": "code/default/lib/noarch/scrypto/m2.py",
    "content": "#!/usr/bin/env python\n\n# Copyright (c) 2014 clowwindy\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in\n# all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n# SOFTWARE.\n\n\n\nimport sys\nimport xlog\n\n__all__ = ['ciphers']\n\nhas_m2 = True\ntry:\n    __import__('M2Crypto')\nexcept ImportError:\n    has_m2 = False\n\n\ndef create_cipher(alg, key, iv, op, key_as_bytes=0, d=None, salt=None, i=1,\n                  padding=1):\n\n    import M2Crypto.EVP\n    return M2Crypto.EVP.Cipher(alg.replace('-', '_'), key, iv, op,\n                               key_as_bytes=0, d='md5', salt=None, i=1,\n                               padding=1)\n\n\ndef err(alg, key, iv, op, key_as_bytes=0, d=None, salt=None, i=1, padding=1):\n    xlog.error(('M2Crypto is required to use %s, please run'\n                   ' `apt-get install python-m2crypto`') % alg)\n    sys.exit(1)\n\n\nif has_m2:\n    ciphers = {\n        b'aes-128-cfb': (16, 16, create_cipher),\n        b'aes-192-cfb': (24, 16, create_cipher),\n        b'aes-256-cfb': (32, 16, create_cipher),\n        b'bf-cfb': (16, 8, create_cipher),\n        b'camellia-128-cfb': (16, 16, create_cipher),\n        b'camellia-192-cfb': (24, 16, create_cipher),\n        b'camellia-256-cfb': (32, 16, create_cipher),\n        b'cast5-cfb': (16, 8, create_cipher),\n        b'des-cfb': (8, 8, create_cipher),\n        b'idea-cfb': (16, 8, create_cipher),\n        b'rc2-cfb': (16, 8, create_cipher),\n        b'rc4': (16, 0, create_cipher),\n        b'seed-cfb': (16, 16, create_cipher),\n    }\nelse:\n    ciphers = {}\n\n\ndef run_method(method):\n    from shadowsocks.crypto import util\n\n    cipher = create_cipher(method, b'k' * 32, b'i' * 16, 1)\n    decipher = create_cipher(method, b'k' * 32, b'i' * 16, 0)\n\n    util.run_cipher(cipher, decipher)\n\n\ndef check_env():\n    # skip this test on pypy and Python 3\n    try:\n        import __pypy__\n        del __pypy__\n        from nose.plugins.skip import SkipTest\n        raise SkipTest\n    except ImportError:\n        pass\n    if bytes != str:\n        from nose.plugins.skip import SkipTest\n        raise SkipTest\n\n\ndef test_aes_128_cfb():\n    check_env()\n    run_method(b'aes-128-cfb')\n\n\ndef test_aes_256_cfb():\n    check_env()\n    run_method(b'aes-256-cfb')\n\n\ndef test_bf_cfb():\n    check_env()\n    run_method(b'bf-cfb')\n\n\ndef test_rc4():\n    check_env()\n    run_method(b'rc4')\n\n\nif __name__ == '__main__':\n    test_aes_128_cfb()\n"
  },
  {
    "path": "code/default/lib/noarch/scrypto/rc4_md5.py",
    "content": "#!/usr/bin/env python\n\n# Copyright (c) 2014 clowwindy\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in\n# all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n# SOFTWARE.\n\n\n\nimport hashlib\n\n\n__all__ = ['ciphers']\n\n\ndef create_cipher(alg, key, iv, op, key_as_bytes=0, d=None, salt=None,\n                  i=1, padding=1):\n    md5 = hashlib.md5()\n    md5.update(key)\n    md5.update(iv)\n    rc4_key = md5.digest()\n\n    try:\n        from crypto import ctypes_openssl\n        return ctypes_openssl.CtypesCrypto(b'rc4', rc4_key, b'', op)\n    except:\n        import M2Crypto.EVP\n        return M2Crypto.EVP.Cipher(b'rc4', rc4_key, b'', op,\n                                   key_as_bytes=0, d='md5', salt=None, i=1,\n                                   padding=1)\n\n\nciphers = {\n    b'rc4-md5': (16, 16, create_cipher),\n}\n\n\ndef test():\n    from shadowsocks.crypto import util\n\n    cipher = create_cipher(b'rc4-md5', b'k' * 32, b'i' * 16, 1)\n    decipher = create_cipher(b'rc4-md5', b'k' * 32, b'i' * 16, 0)\n\n    util.run_cipher(cipher, decipher)\n\n\nif __name__ == '__main__':\n    test()\n"
  },
  {
    "path": "code/default/lib/noarch/scrypto/salsa20_ctr.py",
    "content": "#!/usr/bin/env python\n\n# Copyright (c) 2014 clowwindy\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in\n# all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n# SOFTWARE.\n\n\n\nimport struct\nimport xlog\nimport sys\n\nslow_xor = False\nimported = False\n\nsalsa20 = None\nnumpy = None\n\nBLOCK_SIZE = 16384\n\n\ndef run_imports():\n    global imported, slow_xor, salsa20, numpy\n    if not imported:\n        imported = True\n        try:\n            numpy = __import__('numpy')\n        except ImportError:\n            xlog.error('can not import numpy, using SLOW XOR')\n            xlog.error('please install numpy if you use salsa20')\n            slow_xor = True\n        try:\n            salsa20 = __import__('salsa20')\n        except ImportError:\n            xlog.error('you have to install salsa20 before you use salsa20')\n            sys.exit(1)\n\n\ndef numpy_xor(a, b):\n    if slow_xor:\n        return py_xor_str(a, b)\n    dtype = numpy.byte\n    if len(a) % 4 == 0:\n        dtype = numpy.uint32\n    elif len(a) % 2 == 0:\n        dtype = numpy.uint16\n\n    ab = numpy.frombuffer(a, dtype=dtype)\n    bb = numpy.frombuffer(b, dtype=dtype)\n    c = numpy.bitwise_xor(ab, bb)\n    r = c.tostring()\n    return r\n\n\ndef py_xor_str(a, b):\n    c = []\n    if bytes == str:\n        for i in range(0, len(a)):\n            c.append(chr(ord(a[i]) ^ ord(b[i])))\n        return ''.join(c)\n    else:\n        for i in range(0, len(a)):\n            c.append(a[i] ^ b[i])\n        return bytes(c)\n\n\nclass Salsa20Cipher(object):\n    \"\"\"a salsa20 CTR implemetation, provides m2crypto like cipher API\"\"\"\n\n    def __init__(self, alg, key, iv, op, key_as_bytes=0, d=None, salt=None,\n                 i=1, padding=1):\n        run_imports()\n        if alg != b'salsa20-ctr':\n            raise Exception('unknown algorithm')\n        self._key = key\n        self._nonce = struct.unpack('<Q', iv)[0]\n        self._pos = 0\n        self._next_stream()\n\n    def _next_stream(self):\n        self._nonce &= 0xFFFFFFFFFFFFFFFF\n        self._stream = salsa20.Salsa20_keystream(BLOCK_SIZE,\n                                                 struct.pack('<Q',\n                                                             self._nonce),\n                                                 self._key)\n        self._nonce += 1\n\n    def update(self, data):\n        results = []\n        while True:\n            remain = BLOCK_SIZE - self._pos\n            cur_data = data[:remain]\n            cur_data_len = len(cur_data)\n            cur_stream = self._stream[self._pos:self._pos + cur_data_len]\n            self._pos = self._pos + cur_data_len\n            data = data[remain:]\n\n            results.append(numpy_xor(cur_data, cur_stream))\n\n            if self._pos >= BLOCK_SIZE:\n                self._next_stream()\n                self._pos = 0\n            if not data:\n                break\n        return b''.join(results)\n\n\nciphers = {\n    b'salsa20-ctr': (32, 8, Salsa20Cipher),\n}\n\n\ndef test():\n    from shadowsocks.crypto import util\n\n    cipher = Salsa20Cipher(b'salsa20-ctr', b'k' * 32, b'i' * 8, 1)\n    decipher = Salsa20Cipher(b'salsa20-ctr', b'k' * 32, b'i' * 8, 1)\n\n    util.run_cipher(cipher, decipher)\n\n\nif __name__ == '__main__':\n    test()\n"
  },
  {
    "path": "code/default/lib/noarch/scrypto/table.py",
    "content": "# !/usr/bin/env python\n\n# Copyright (c) 2014 clowwindy\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in\n# all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n# SOFTWARE.\n\n\n\nimport string\nimport struct\nimport hashlib\n\n\n__all__ = ['ciphers']\n\ncached_tables = {}\n\nif hasattr(string, 'maketrans'):\n    maketrans = string.maketrans\n    translate = string.translate\nelse:\n    maketrans = bytes.maketrans\n    translate = bytes.translate\n\n\ndef get_table(key):\n    m = hashlib.md5()\n    m.update(key)\n    s = m.digest()\n    a, b = struct.unpack('<QQ', s)\n    table = maketrans(b'', b'')\n    table = [table[i: i + 1] for i in range(len(table))]\n    for i in range(1, 1024):\n        table.sort(key=lambda x: int(a % (ord(x) + i)))\n    return table\n\n\ndef init_table(key):\n    if key not in cached_tables:\n        encrypt_table = b''.join(get_table(key))\n        decrypt_table = maketrans(encrypt_table, maketrans(b'', b''))\n        cached_tables[key] = [encrypt_table, decrypt_table]\n    return cached_tables[key]\n\n\nclass TableCipher(object):\n    def __init__(self, cipher_name, key, iv, op):\n        self._encrypt_table, self._decrypt_table = init_table(key)\n        self._op = op\n\n    def update(self, data):\n        if self._op:\n            return translate(data, self._encrypt_table)\n        else:\n            return translate(data, self._decrypt_table)\n\n\nciphers = {\n    b'table': (0, 0, TableCipher)\n}\n\n\ndef test_table_result():\n    from shadowsocks.common import ord\n    target1 = [\n        [60, 53, 84, 138, 217, 94, 88, 23, 39, 242, 219, 35, 12, 157, 165, 181,\n         255, 143, 83, 247, 162, 16, 31, 209, 190, 171, 115, 65, 38, 41, 21,\n         245, 236, 46, 121, 62, 166, 233, 44, 154, 153, 145, 230, 49, 128, 216,\n         173, 29, 241, 119, 64, 229, 194, 103, 131, 110, 26, 197, 218, 59, 204,\n         56, 27, 34, 141, 221, 149, 239, 192, 195, 24, 155, 170, 183, 11, 254,\n         213, 37, 137, 226, 75, 203, 55, 19, 72, 248, 22, 129, 33, 175, 178,\n         10, 198, 71, 77, 36, 113, 167, 48, 2, 117, 140, 142, 66, 199, 232,\n         243, 32, 123, 54, 51, 82, 57, 177, 87, 251, 150, 196, 133, 5, 253,\n         130, 8, 184, 14, 152, 231, 3, 186, 159, 76, 89, 228, 205, 156, 96,\n         163, 146, 18, 91, 132, 85, 80, 109, 172, 176, 105, 13, 50, 235, 127,\n         0, 189, 95, 98, 136, 250, 200, 108, 179, 211, 214, 106, 168, 78, 79,\n         74, 210, 30, 73, 201, 151, 208, 114, 101, 174, 92, 52, 120, 240, 15,\n         169, 220, 182, 81, 224, 43, 185, 40, 99, 180, 17, 212, 158, 42, 90, 9,\n         191, 45, 6, 25, 4, 222, 67, 126, 1, 116, 124, 206, 69, 61, 7, 68, 97,\n         202, 63, 244, 20, 28, 58, 93, 134, 104, 144, 227, 147, 102, 118, 135,\n         148, 47, 238, 86, 112, 122, 70, 107, 215, 100, 139, 223, 225, 164,\n         237, 111, 125, 207, 160, 187, 246, 234, 161, 188, 193, 249, 252],\n        [151, 205, 99, 127, 201, 119, 199, 211, 122, 196, 91, 74, 12, 147, 124,\n         180, 21, 191, 138, 83, 217, 30, 86, 7, 70, 200, 56, 62, 218, 47, 168,\n         22, 107, 88, 63, 11, 95, 77, 28, 8, 188, 29, 194, 186, 38, 198, 33,\n         230, 98, 43, 148, 110, 177, 1, 109, 82, 61, 112, 219, 59, 0, 210, 35,\n         215, 50, 27, 103, 203, 212, 209, 235, 93, 84, 169, 166, 80, 130, 94,\n         164, 165, 142, 184, 111, 18, 2, 141, 232, 114, 6, 131, 195, 139, 176,\n         220, 5, 153, 135, 213, 154, 189, 238, 174, 226, 53, 222, 146, 162,\n         236, 158, 143, 55, 244, 233, 96, 173, 26, 206, 100, 227, 49, 178, 34,\n         234, 108, 207, 245, 204, 150, 44, 87, 121, 54, 140, 118, 221, 228,\n         155, 78, 3, 239, 101, 64, 102, 17, 223, 41, 137, 225, 229, 66, 116,\n         171, 125, 40, 39, 71, 134, 13, 193, 129, 247, 251, 20, 136, 242, 14,\n         36, 97, 163, 181, 72, 25, 144, 46, 175, 89, 145, 113, 90, 159, 190,\n         15, 183, 73, 123, 187, 128, 248, 252, 152, 24, 197, 68, 253, 52, 69,\n         117, 57, 92, 104, 157, 170, 214, 81, 60, 133, 208, 246, 172, 23, 167,\n         160, 192, 76, 161, 237, 45, 4, 58, 10, 182, 65, 202, 240, 185, 241,\n         79, 224, 132, 51, 42, 126, 105, 37, 250, 149, 32, 243, 231, 67, 179,\n         48, 9, 106, 216, 31, 249, 19, 85, 254, 156, 115, 255, 120, 75, 16]]\n\n    target2 = [\n        [124, 30, 170, 247, 27, 127, 224, 59, 13, 22, 196, 76, 72, 154, 32,\n         209, 4, 2, 131, 62, 101, 51, 230, 9, 166, 11, 99, 80, 208, 112, 36,\n         248, 81, 102, 130, 88, 218, 38, 168, 15, 241, 228, 167, 117, 158, 41,\n         10, 180, 194, 50, 204, 243, 246, 251, 29, 198, 219, 210, 195, 21, 54,\n         91, 203, 221, 70, 57, 183, 17, 147, 49, 133, 65, 77, 55, 202, 122,\n         162, 169, 188, 200, 190, 125, 63, 244, 96, 31, 107, 106, 74, 143, 116,\n         148, 78, 46, 1, 137, 150, 110, 181, 56, 95, 139, 58, 3, 231, 66, 165,\n         142, 242, 43, 192, 157, 89, 175, 109, 220, 128, 0, 178, 42, 255, 20,\n         214, 185, 83, 160, 253, 7, 23, 92, 111, 153, 26, 226, 33, 176, 144,\n         18, 216, 212, 28, 151, 71, 206, 222, 182, 8, 174, 205, 201, 152, 240,\n         155, 108, 223, 104, 239, 98, 164, 211, 184, 34, 193, 14, 114, 187, 40,\n         254, 12, 67, 93, 217, 6, 94, 16, 19, 82, 86, 245, 24, 197, 134, 132,\n         138, 229, 121, 5, 235, 238, 85, 47, 103, 113, 179, 69, 250, 45, 135,\n         156, 25, 61, 75, 44, 146, 189, 84, 207, 172, 119, 53, 123, 186, 120,\n         171, 68, 227, 145, 136, 100, 90, 48, 79, 159, 149, 39, 213, 236, 126,\n         52, 60, 225, 199, 105, 73, 233, 252, 118, 215, 35, 115, 64, 37, 97,\n         129, 161, 177, 87, 237, 141, 173, 191, 163, 140, 234, 232, 249],\n        [117, 94, 17, 103, 16, 186, 172, 127, 146, 23, 46, 25, 168, 8, 163, 39,\n         174, 67, 137, 175, 121, 59, 9, 128, 179, 199, 132, 4, 140, 54, 1, 85,\n         14, 134, 161, 238, 30, 241, 37, 224, 166, 45, 119, 109, 202, 196, 93,\n         190, 220, 69, 49, 21, 228, 209, 60, 73, 99, 65, 102, 7, 229, 200, 19,\n         82, 240, 71, 105, 169, 214, 194, 64, 142, 12, 233, 88, 201, 11, 72,\n         92, 221, 27, 32, 176, 124, 205, 189, 177, 246, 35, 112, 219, 61, 129,\n         170, 173, 100, 84, 242, 157, 26, 218, 20, 33, 191, 155, 232, 87, 86,\n         153, 114, 97, 130, 29, 192, 164, 239, 90, 43, 236, 208, 212, 185, 75,\n         210, 0, 81, 227, 5, 116, 243, 34, 18, 182, 70, 181, 197, 217, 95, 183,\n         101, 252, 248, 107, 89, 136, 216, 203, 68, 91, 223, 96, 141, 150, 131,\n         13, 152, 198, 111, 44, 222, 125, 244, 76, 251, 158, 106, 24, 42, 38,\n         77, 2, 213, 207, 249, 147, 113, 135, 245, 118, 193, 47, 98, 145, 66,\n         160, 123, 211, 165, 78, 204, 80, 250, 110, 162, 48, 58, 10, 180, 55,\n         231, 79, 149, 74, 62, 50, 148, 143, 206, 28, 15, 57, 159, 139, 225,\n         122, 237, 138, 171, 36, 56, 115, 63, 144, 154, 6, 230, 133, 215, 41,\n         184, 22, 104, 254, 234, 253, 187, 226, 247, 188, 156, 151, 40, 108,\n         51, 83, 178, 52, 3, 31, 255, 195, 53, 235, 126, 167, 120]]\n\n    encrypt_table = b''.join(get_table(b'foobar!'))\n    decrypt_table = maketrans(encrypt_table, maketrans(b'', b''))\n\n    for i in range(0, 256):\n        assert (target1[0][i] == ord(encrypt_table[i]))\n        assert (target1[1][i] == ord(decrypt_table[i]))\n\n    encrypt_table = b''.join(get_table(b'barfoo!'))\n    decrypt_table = maketrans(encrypt_table, maketrans(b'', b''))\n\n    for i in range(0, 256):\n        assert (target2[0][i] == ord(encrypt_table[i]))\n        assert (target2[1][i] == ord(decrypt_table[i]))\n\n\ndef test_encryption():\n    from shadowsocks.crypto import util\n\n    cipher = TableCipher(b'table', b'test', b'', 1)\n    decipher = TableCipher(b'table', b'test', b'', 0)\n\n    util.run_cipher(cipher, decipher)\n\n\nif __name__ == '__main__':\n    test_table_result()\n    test_encryption()\n"
  },
  {
    "path": "code/default/lib/noarch/scrypto/util.py",
    "content": "#!/usr/bin/env python\n\n# Copyright (c) 2014 clowwindy\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in\n# all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n# SOFTWARE.\n\n\ndef run_cipher(cipher, decipher):\n    from os import urandom\n    import random\n    import time\n\n    BLOCK_SIZE = 16384\n    rounds = 1 * 1024\n    plain = urandom(BLOCK_SIZE * rounds)\n\n    results = []\n    pos = 0\n    print('test start')\n    start = time.time()\n    while pos < len(plain):\n        l = random.randint(100, 32768)\n        c = cipher.update(plain[pos:pos + l])\n        results.append(c)\n        pos += l\n    pos = 0\n    c = b''.join(results)\n    results = []\n    while pos < len(plain):\n        l = random.randint(100, 32768)\n        results.append(decipher.update(c[pos:pos + l]))\n        pos += l\n    end = time.time()\n    print(('speed: %d bytes/s' % (BLOCK_SIZE * rounds / (end - start))))\n    assert b''.join(results) == plain\n"
  },
  {
    "path": "code/default/lib/noarch/selectors2.py",
    "content": "\"\"\" Back-ported, durable, and portable selectors \"\"\"\r\n\r\n# MIT License\r\n#\r\n# Copyright (c) 2017 Seth Michael Larson\r\n#\r\n# Permission is hereby granted, free of charge, to any person obtaining a copy\r\n# of this software and associated documentation files (the \"Software\"), to deal\r\n# in the Software without restriction, including without limitation the rights\r\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n# copies of the Software, and to permit persons to whom the Software is\r\n# furnished to do so, subject to the following conditions:\r\n#\r\n# The above copyright notice and this permission notice shall be included in all\r\n# copies or substantial portions of the Software.\r\n#\r\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n# SOFTWARE.\r\n\r\nfrom collections import namedtuple\r\nfrom collections.abc import Mapping\r\nimport errno\r\nimport math\r\nimport platform\r\nimport select\r\nimport socket\r\nimport sys\r\nimport time\r\n\r\ntry:\r\n    monotonic = time.monotonic\r\nexcept AttributeError:\r\n    monotonic = time.time\r\n\r\n__author__ = 'Seth Michael Larson'\r\n__email__ = 'sethmichaellarson@protonmail.com'\r\n__version__ = '2.0.2'\r\n__license__ = 'MIT'\r\n__url__ = 'https://www.github.com/SethMichaelLarson/selectors2'\r\n\r\n__all__ = ['EVENT_READ',\r\n           'EVENT_WRITE',\r\n           'SelectorKey',\r\n           'DefaultSelector',\r\n           'BaseSelector']\r\n\r\nEVENT_READ = (1 << 0)\r\nEVENT_WRITE = (1 << 1)\r\n_DEFAULT_SELECTOR = None\r\n_SYSCALL_SENTINEL = object()  # Sentinel in case a system call returns None.\r\n_ERROR_TYPES = (OSError, IOError, socket.error)\r\n\r\ntry:\r\n    _INTEGER_TYPES = (int, long)\r\nexcept NameError:\r\n    _INTEGER_TYPES = (int,)\r\n\r\n\r\nSelectorKey = namedtuple('SelectorKey', ['fileobj', 'fd', 'events', 'data'])\r\n\r\n\r\nclass _SelectorMapping(Mapping):\r\n    \"\"\" Mapping of file objects to selector keys \"\"\"\r\n\r\n    def __init__(self, selector):\r\n        self._selector = selector\r\n\r\n    def __len__(self):\r\n        return len(self._selector._fd_to_key)\r\n\r\n    def __getitem__(self, fileobj):\r\n        try:\r\n            fd = self._selector._fileobj_lookup(fileobj)\r\n            return self._selector._fd_to_key[fd]\r\n        except KeyError:\r\n            raise KeyError(\"{0!r} is not registered.\".format(fileobj))\r\n\r\n    def __iter__(self):\r\n        return iter(self._selector._fd_to_key)\r\n\r\n\r\ndef _fileobj_to_fd(fileobj):\r\n    \"\"\" Return a file descriptor from a file object. If\r\n    given an integer will simply return that integer back. \"\"\"\r\n    if isinstance(fileobj, _INTEGER_TYPES):\r\n        fd = fileobj\r\n    else:\r\n        for _integer_type in _INTEGER_TYPES:\r\n            try:\r\n                fd = _integer_type(fileobj.fileno())\r\n                break\r\n            except (AttributeError, TypeError, ValueError):\r\n                continue\r\n        else:\r\n            raise ValueError(\"Invalid file object: {0!r}\".format(fileobj))\r\n    if fd < 0:\r\n        raise ValueError(\"Invalid file descriptor: {0}\".format(fd))\r\n    return fd\r\n\r\n\r\nclass BaseSelector(object):\r\n    \"\"\" Abstract Selector class\r\n\r\n    A selector supports registering file objects to be monitored\r\n    for specific I/O events.\r\n\r\n    A file object is a file descriptor or any object with a\r\n    `fileno()` method. An arbitrary object can be attached to the\r\n    file object which can be used for example to store context info,\r\n    a callback, etc.\r\n\r\n    A selector can use various implementations (select(), poll(), epoll(),\r\n    and kqueue()) depending on the platform. The 'DefaultSelector' class uses\r\n    the most efficient implementation for the current platform.\r\n    \"\"\"\r\n    def __init__(self):\r\n        # Maps file descriptors to keys.\r\n        self._fd_to_key = {}\r\n\r\n        # Read-only mapping returned by get_map()\r\n        self._map = _SelectorMapping(self)\r\n\r\n    def _fileobj_lookup(self, fileobj):\r\n        \"\"\" Return a file descriptor from a file object.\r\n        This wraps _fileobj_to_fd() to do an exhaustive\r\n        search in case the object is invalid but we still\r\n        have it in our map. Used by unregister() so we can\r\n        unregister an object that was previously registered\r\n        even if it is closed. It is also used by _SelectorMapping\r\n        \"\"\"\r\n        try:\r\n            return _fileobj_to_fd(fileobj)\r\n        except ValueError:\r\n\r\n            # Search through all our mapped keys.\r\n            for key in self._fd_to_key.values():\r\n                if key.fileobj is fileobj:\r\n                    return key.fd\r\n\r\n            # Raise ValueError after all.\r\n            raise\r\n\r\n    def register(self, fileobj, events, data=None):\r\n        \"\"\" Register a file object for a set of events to monitor. \"\"\"\r\n        if (not events) or (events & ~(EVENT_READ | EVENT_WRITE)):\r\n            raise ValueError(\"Invalid events: {0!r}\".format(events))\r\n\r\n        key = SelectorKey(fileobj, self._fileobj_lookup(fileobj), events, data)\r\n\r\n        if key.fd in self._fd_to_key:\r\n            raise KeyError(\"{0!r} (FD {1}) is already registered\"\r\n                           .format(fileobj, key.fd))\r\n\r\n        self._fd_to_key[key.fd] = key\r\n        return key\r\n\r\n    def unregister(self, fileobj):\r\n        \"\"\" Unregister a file object from being monitored. \"\"\"\r\n        try:\r\n            key = self._fd_to_key.pop(self._fileobj_lookup(fileobj))\r\n        except KeyError:\r\n            raise KeyError(\"{0!r} is not registered\".format(fileobj))\r\n\r\n        # Getting the fileno of a closed socket on Windows errors with EBADF.\r\n        except socket.error as err:\r\n            if err.errno != errno.EBADF:\r\n                raise\r\n            else:\r\n                for key in self._fd_to_key.values():\r\n                    if key.fileobj is fileobj:\r\n                        self._fd_to_key.pop(key.fd)\r\n                        break\r\n                else:\r\n                    raise KeyError(\"{0!r} is not registered\".format(fileobj))\r\n        return key\r\n\r\n    def modify(self, fileobj, events, data=None):\r\n        \"\"\" Change a registered file object monitored events and data. \"\"\"\r\n        # NOTE: Some subclasses optimize this operation even further.\r\n        try:\r\n            key = self._fd_to_key[self._fileobj_lookup(fileobj)]\r\n        except KeyError:\r\n            raise KeyError(\"{0!r} is not registered\".format(fileobj))\r\n\r\n        if events != key.events:\r\n            self.unregister(fileobj)\r\n            key = self.register(fileobj, events, data)\r\n\r\n        elif data != key.data:\r\n            # Use a shortcut to update the data.\r\n            key = key._replace(data=data)\r\n            self._fd_to_key[key.fd] = key\r\n\r\n        return key\r\n\r\n    def register_event(self, fileobj, event, data):\r\n        try:\r\n            key = self._fd_to_key[self._fileobj_lookup(fileobj)]\r\n        except KeyError:\r\n            # not registered any event before, register\r\n            return self.register(fileobj, event, data)\r\n\r\n        if key.events & event:\r\n            # event already registered\r\n            return\r\n        else:\r\n            events = (key.events | event)\r\n            self.unregister(fileobj)\r\n            self.register(fileobj, events, data)\r\n\r\n    def unregister_event(self, fileobj, event):\r\n        # Return None if fileobj is removed or not exists\r\n\r\n        try:\r\n            key = self._fd_to_key[self._fileobj_lookup(fileobj)]\r\n        except KeyError:\r\n            # not exists\r\n            return\r\n\r\n        if not key.events & event:\r\n            # this event is not registered\r\n            return key\r\n\r\n        if key.events == event:\r\n            self.unregister(fileobj)\r\n            return\r\n        else:\r\n            events = (key.events & ~(event))\r\n            data = key.data\r\n            self.unregister(fileobj)\r\n            return self.register(fileobj, events, data)\r\n\r\n    def select(self, timeout=None):\r\n        \"\"\" Perform the actual selection until some monitored file objects\r\n        are ready or the timeout expires. \"\"\"\r\n        raise NotImplementedError()\r\n\r\n    def close(self):\r\n        \"\"\" Close the selector. This must be called to ensure that all\r\n        underlying resources are freed. \"\"\"\r\n        self._fd_to_key.clear()\r\n        self._map = None\r\n\r\n    def get_key(self, fileobj):\r\n        \"\"\" Return the key associated with a registered file object. \"\"\"\r\n        mapping = self.get_map()\r\n        if mapping is None:\r\n            raise RuntimeError(\"Selector is closed\")\r\n        try:\r\n            return mapping[fileobj]\r\n        except KeyError:\r\n            raise KeyError(\"{0!r} is not registered\".format(fileobj))\r\n\r\n    def get_map(self):\r\n        \"\"\" Return a mapping of file objects to selector keys \"\"\"\r\n        return self._map\r\n\r\n    def _key_from_fd(self, fd):\r\n        \"\"\" Return the key associated to a given file descriptor\r\n         Return None if it is not found. \"\"\"\r\n        try:\r\n            return self._fd_to_key[fd]\r\n        except KeyError:\r\n            return None\r\n\r\n    def __enter__(self):\r\n        return self\r\n\r\n    def __exit__(self, *_):\r\n        self.close()\r\n\r\n\r\n# Almost all platforms have select.select()\r\nif hasattr(select, \"select\"):\r\n    class SelectSelector(BaseSelector):\r\n        \"\"\" Select-based selector. \"\"\"\r\n        def __init__(self):\r\n            super(SelectSelector, self).__init__()\r\n            self._readers = set()\r\n            self._writers = set()\r\n\r\n        def register(self, fileobj, events, data=None):\r\n            key = super(SelectSelector, self).register(fileobj, events, data)\r\n            if events & EVENT_READ:\r\n                self._readers.add(key.fd)\r\n            if events & EVENT_WRITE:\r\n                self._writers.add(key.fd)\r\n            return key\r\n\r\n        def unregister(self, fileobj):\r\n            key = super(SelectSelector, self).unregister(fileobj)\r\n            self._readers.discard(key.fd)\r\n            self._writers.discard(key.fd)\r\n            return key\r\n\r\n        def select(self, timeout=None):\r\n            # Selecting on empty lists on Windows errors out.\r\n            if not len(self._readers) and not len(self._writers):\r\n                return []\r\n\r\n            timeout = None if timeout is None else max(timeout, 0.0)\r\n            ready = []\r\n            r, w, _ = _syscall_wrapper(self._wrap_select, True, self._readers,\r\n                                       self._writers, timeout=timeout)\r\n            r = set(r)\r\n            w = set(w)\r\n            for fd in r | w:\r\n                events = 0\r\n                if fd in r:\r\n                    events |= EVENT_READ\r\n                if fd in w:\r\n                    events |= EVENT_WRITE\r\n\r\n                key = self._key_from_fd(fd)\r\n                if key:\r\n                    ready.append((key, events & key.events))\r\n            return ready\r\n\r\n        def _wrap_select(self, r, w, timeout=None):\r\n            \"\"\" Wrapper for select.select because timeout is a positional arg \"\"\"\r\n            return select.select(r, w, [], timeout)\r\n\r\n    __all__.append('SelectSelector')\r\n\r\n    # Jython has a different implementation of .fileno() for socket objects.\r\n    if platform.python_implementation() == 'Jython':\r\n        class _JythonSelectorMapping(object):\r\n            \"\"\" This is an implementation of _SelectorMapping that is built\r\n            for use specifically with Jython, which does not provide a hashable\r\n            value from socket.socket.fileno(). \"\"\"\r\n\r\n            def __init__(self, selector):\r\n                assert isinstance(selector, JythonSelectSelector)\r\n                self._selector = selector\r\n\r\n            def __len__(self):\r\n                return len(self._selector._sockets)\r\n\r\n            def __getitem__(self, fileobj):\r\n                for sock, key in self._selector._sockets:\r\n                    if sock is fileobj:\r\n                        return key\r\n                else:\r\n                    raise KeyError(\"{0!r} is not registered.\".format(fileobj))\r\n\r\n        class JythonSelectSelector(SelectSelector):\r\n            \"\"\" This is an implementation of SelectSelector that is for Jython\r\n            which works around that Jython's socket.socket.fileno() does not\r\n            return an integer fd value. All SelectorKey.fd will be equal to -1\r\n            and should not be used. This instead uses object id to compare fileobj\r\n            and will only use select.select as it's the only selector that allows\r\n            directly passing in socket objects rather than registering fds.\r\n            See: http://bugs.jython.org/issue1678\r\n                 https://wiki.python.org/jython/NewSocketModule#socket.fileno.28.29_does_not_return_an_integer\r\n            \"\"\"\r\n\r\n            def __init__(self):\r\n                super(JythonSelectSelector, self).__init__()\r\n\r\n                self._sockets = []  # Uses a list of tuples instead of dictionary.\r\n                self._map = _JythonSelectorMapping(self)\r\n                self._readers = []\r\n                self._writers = []\r\n\r\n                # Jython has a select.cpython_compatible_select function in older versions.\r\n                self._select_func = getattr(select, 'cpython_compatible_select', select.select)\r\n\r\n            def register(self, fileobj, events, data=None):\r\n                for sock, _ in self._sockets:\r\n                    if sock is fileobj:\r\n                        raise KeyError(\"{0!r} is already registered\"\r\n                                       .format(fileobj, sock))\r\n\r\n                key = SelectorKey(fileobj, -1, events, data)\r\n                self._sockets.append((fileobj, key))\r\n\r\n                if events & EVENT_READ:\r\n                    self._readers.append(fileobj)\r\n                if events & EVENT_WRITE:\r\n                    self._writers.append(fileobj)\r\n                return key\r\n\r\n            def unregister(self, fileobj):\r\n                for i, (sock, key) in enumerate(self._sockets):\r\n                    if sock is fileobj:\r\n                        break\r\n                else:\r\n                    raise KeyError(\"{0!r} is not registered.\".format(fileobj))\r\n\r\n                if key.events & EVENT_READ:\r\n                    self._readers.remove(fileobj)\r\n                if key.events & EVENT_WRITE:\r\n                    self._writers.remove(fileobj)\r\n\r\n                del self._sockets[i]\r\n                return key\r\n\r\n            def _wrap_select(self, r, w, timeout=None):\r\n                \"\"\" Wrapper for select.select because timeout is a positional arg \"\"\"\r\n                return self._select_func(r, w, [], timeout)\r\n\r\n        __all__.append('JythonSelectSelector')\r\n        SelectSelector = JythonSelectSelector  # Override so the wrong selector isn't used.\r\n\r\n\r\nif hasattr(select, \"poll\"):\r\n    class PollSelector(BaseSelector):\r\n        \"\"\" Poll-based selector \"\"\"\r\n        def __init__(self):\r\n            super(PollSelector, self).__init__()\r\n            self._poll = select.poll()\r\n\r\n        def register(self, fileobj, events, data=None):\r\n            key = super(PollSelector, self).register(fileobj, events, data)\r\n            event_mask = 0\r\n            if events & EVENT_READ:\r\n                event_mask |= select.POLLIN\r\n            if events & EVENT_WRITE:\r\n                event_mask |= select.POLLOUT\r\n            self._poll.register(key.fd, event_mask)\r\n            return key\r\n\r\n        def unregister(self, fileobj):\r\n            key = super(PollSelector, self).unregister(fileobj)\r\n            self._poll.unregister(key.fd)\r\n            return key\r\n\r\n        def _wrap_poll(self, timeout=None):\r\n            \"\"\" Wrapper function for select.poll.poll() so that\r\n            _syscall_wrapper can work with only seconds. \"\"\"\r\n            if timeout is not None:\r\n                if timeout <= 0:\r\n                    timeout = 0\r\n                else:\r\n                    # select.poll.poll() has a resolution of 1 millisecond,\r\n                    # round away from zero to wait *at least* timeout seconds.\r\n                    timeout = math.ceil(timeout * 1000)\r\n\r\n            result = self._poll.poll(timeout)\r\n            return result\r\n\r\n        def select(self, timeout=None):\r\n            ready = []\r\n            fd_events = _syscall_wrapper(self._wrap_poll, True, timeout=timeout)\r\n            for fd, event_mask in fd_events:\r\n                events = 0\r\n                if event_mask & ~select.POLLIN:\r\n                    events |= EVENT_WRITE\r\n                if event_mask & ~select.POLLOUT:\r\n                    events |= EVENT_READ\r\n\r\n                key = self._key_from_fd(fd)\r\n                if key:\r\n                    ready.append((key, events & key.events))\r\n\r\n            return ready\r\n\r\n    __all__.append('PollSelector')\r\n\r\nif hasattr(select, \"epoll\"):\r\n    class EpollSelector(BaseSelector):\r\n        \"\"\" Epoll-based selector \"\"\"\r\n        def __init__(self):\r\n            super(EpollSelector, self).__init__()\r\n            self._epoll = select.epoll()\r\n\r\n        def fileno(self):\r\n            return self._epoll.fileno()\r\n\r\n        def register(self, fileobj, events, data=None):\r\n            key = super(EpollSelector, self).register(fileobj, events, data)\r\n            events_mask = 0\r\n            if events & EVENT_READ:\r\n                events_mask |= select.EPOLLIN\r\n            if events & EVENT_WRITE:\r\n                events_mask |= select.EPOLLOUT\r\n            _syscall_wrapper(self._epoll.register, False, key.fd, events_mask)\r\n            return key\r\n\r\n        def unregister(self, fileobj):\r\n            key = super(EpollSelector, self).unregister(fileobj)\r\n            try:\r\n                _syscall_wrapper(self._epoll.unregister, False, key.fd)\r\n            except _ERROR_TYPES:\r\n                # This can occur when the fd was closed since registry.\r\n                pass\r\n            return key\r\n\r\n        def select(self, timeout=None):\r\n            if timeout is not None:\r\n                if timeout <= 0:\r\n                    timeout = 0.0\r\n                else:\r\n                    # select.epoll.poll() has a resolution of 1 millisecond\r\n                    # but luckily takes seconds so we don't need a wrapper\r\n                    # like PollSelector. Just for better rounding.\r\n                    timeout = math.ceil(timeout * 1000) * 0.001\r\n                timeout = float(timeout)\r\n            else:\r\n                timeout = -1.0  # epoll.poll() must have a float.\r\n\r\n            # We always want at least 1 to ensure that select can be called\r\n            # with no file descriptors registered. Otherwise will fail.\r\n            max_events = max(len(self._fd_to_key), 1)\r\n\r\n            ready = []\r\n            fd_events = _syscall_wrapper(self._epoll.poll, True,\r\n                                         timeout=timeout,\r\n                                         maxevents=max_events)\r\n            for fd, event_mask in fd_events:\r\n                events = 0\r\n                if event_mask & ~select.EPOLLIN:\r\n                    events |= EVENT_WRITE\r\n                if event_mask & ~select.EPOLLOUT:\r\n                    events |= EVENT_READ\r\n\r\n                key = self._key_from_fd(fd)\r\n                if key:\r\n                    ready.append((key, events & key.events))\r\n            return ready\r\n\r\n        def close(self):\r\n            self._epoll.close()\r\n            super(EpollSelector, self).close()\r\n\r\n    __all__.append('EpollSelector')\r\n\r\n\r\nif hasattr(select, \"devpoll\"):\r\n    class DevpollSelector(BaseSelector):\r\n        \"\"\"Solaris /dev/poll selector.\"\"\"\r\n\r\n        def __init__(self):\r\n            super(DevpollSelector, self).__init__()\r\n            self._devpoll = select.devpoll()\r\n\r\n        def fileno(self):\r\n            return self._devpoll.fileno()\r\n\r\n        def register(self, fileobj, events, data=None):\r\n            key = super(DevpollSelector, self).register(fileobj, events, data)\r\n            poll_events = 0\r\n            if events & EVENT_READ:\r\n                poll_events |= select.POLLIN\r\n            if events & EVENT_WRITE:\r\n                poll_events |= select.POLLOUT\r\n            self._devpoll.register(key.fd, poll_events)\r\n            return key\r\n\r\n        def unregister(self, fileobj):\r\n            key = super(DevpollSelector, self).unregister(fileobj)\r\n            self._devpoll.unregister(key.fd)\r\n            return key\r\n\r\n        def _wrap_poll(self, timeout=None):\r\n            \"\"\" Wrapper function for select.poll.poll() so that\r\n            _syscall_wrapper can work with only seconds. \"\"\"\r\n            if timeout is not None:\r\n                if timeout <= 0:\r\n                    timeout = 0\r\n                else:\r\n                    # select.devpoll.poll() has a resolution of 1 millisecond,\r\n                    # round away from zero to wait *at least* timeout seconds.\r\n                    timeout = math.ceil(timeout * 1000)\r\n\r\n            result = self._devpoll.poll(timeout)\r\n            return result\r\n\r\n        def select(self, timeout=None):\r\n            ready = []\r\n            fd_events = _syscall_wrapper(self._wrap_poll, True, timeout=timeout)\r\n            for fd, event_mask in fd_events:\r\n                events = 0\r\n                if event_mask & ~select.POLLIN:\r\n                    events |= EVENT_WRITE\r\n                if event_mask & ~select.POLLOUT:\r\n                    events |= EVENT_READ\r\n\r\n                key = self._key_from_fd(fd)\r\n                if key:\r\n                    ready.append((key, events & key.events))\r\n\r\n            return ready\r\n\r\n        def close(self):\r\n            self._devpoll.close()\r\n            super(DevpollSelector, self).close()\r\n\r\n    __all__.append('DevpollSelector')\r\n\r\n\r\nif hasattr(select, \"kqueue\"):\r\n    class KqueueSelector(BaseSelector):\r\n        \"\"\" Kqueue / Kevent-based selector \"\"\"\r\n        def __init__(self):\r\n            super(KqueueSelector, self).__init__()\r\n            self._kqueue = select.kqueue()\r\n\r\n        def fileno(self):\r\n            return self._kqueue.fileno()\r\n\r\n        def register(self, fileobj, events, data=None):\r\n            key = super(KqueueSelector, self).register(fileobj, events, data)\r\n            if events & EVENT_READ:\r\n                kevent = select.kevent(key.fd,\r\n                                       select.KQ_FILTER_READ,\r\n                                       select.KQ_EV_ADD)\r\n\r\n                _syscall_wrapper(self._wrap_control, False, [kevent], 0, 0)\r\n\r\n            if events & EVENT_WRITE:\r\n                kevent = select.kevent(key.fd,\r\n                                       select.KQ_FILTER_WRITE,\r\n                                       select.KQ_EV_ADD)\r\n\r\n                _syscall_wrapper(self._wrap_control, False, [kevent], 0, 0)\r\n\r\n            return key\r\n\r\n        def unregister(self, fileobj):\r\n            key = super(KqueueSelector, self).unregister(fileobj)\r\n            if key.events & EVENT_READ:\r\n                kevent = select.kevent(key.fd,\r\n                                       select.KQ_FILTER_READ,\r\n                                       select.KQ_EV_DELETE)\r\n                try:\r\n                    _syscall_wrapper(self._wrap_control, False, [kevent], 0, 0)\r\n                except _ERROR_TYPES:\r\n                    pass\r\n            if key.events & EVENT_WRITE:\r\n                kevent = select.kevent(key.fd,\r\n                                       select.KQ_FILTER_WRITE,\r\n                                       select.KQ_EV_DELETE)\r\n                try:\r\n                    _syscall_wrapper(self._wrap_control, False, [kevent], 0, 0)\r\n                except _ERROR_TYPES:\r\n                    pass\r\n\r\n            return key\r\n\r\n        def select(self, timeout=None):\r\n            if timeout is not None:\r\n                timeout = max(timeout, 0)\r\n\r\n            max_events = len(self._fd_to_key) * 2\r\n            ready_fds = {}\r\n\r\n            kevent_list = _syscall_wrapper(self._wrap_control, True,\r\n                                           None, max_events, timeout=timeout)\r\n\r\n            for kevent in kevent_list:\r\n                fd = kevent.ident\r\n                event_mask = kevent.filter\r\n                events = 0\r\n                if event_mask == select.KQ_FILTER_READ:\r\n                    events |= EVENT_READ\r\n                if event_mask == select.KQ_FILTER_WRITE:\r\n                    events |= EVENT_WRITE\r\n\r\n                key = self._key_from_fd(fd)\r\n                if key:\r\n                    if key.fd not in ready_fds:\r\n                        ready_fds[key.fd] = (key, events & key.events)\r\n                    else:\r\n                        old_events = ready_fds[key.fd][1]\r\n                        ready_fds[key.fd] = (key, (events | old_events) & key.events)\r\n\r\n            return list(ready_fds.values())\r\n\r\n        def close(self):\r\n            self._kqueue.close()\r\n            super(KqueueSelector, self).close()\r\n\r\n        def _wrap_control(self, changelist, max_events, timeout):\r\n            return self._kqueue.control(changelist, max_events, timeout)\r\n\r\n    __all__.append('KqueueSelector')\r\n\r\n\r\ndef _can_allocate(struct):\r\n    \"\"\" Checks that select structs can be allocated by the underlying\r\n    operating system, not just advertised by the select module. We don't\r\n    check select() because we'll be hopeful that most platforms that\r\n    don't have it available will not advertise it. (ie: GAE) \"\"\"\r\n    try:\r\n        # select.poll() objects won't fail until used.\r\n        if struct == 'poll':\r\n            p = select.poll()\r\n            p.poll(0)\r\n\r\n        # All others will fail on allocation.\r\n        else:\r\n            getattr(select, struct)().close()\r\n        return True\r\n    except (OSError, AttributeError):\r\n        return False\r\n\r\n\r\n# Python 3.5 uses a more direct route to wrap system calls to increase speed.\r\nif sys.version_info >= (3, 5):\r\n    def _syscall_wrapper(func, _, *args, **kwargs):\r\n        \"\"\" This is the short-circuit version of the below logic\r\n        because in Python 3.5+ all selectors restart system calls. \"\"\"\r\n        return func(*args, **kwargs)\r\nelse:\r\n    def _syscall_wrapper(func, recalc_timeout, *args, **kwargs):\r\n        \"\"\" Wrapper function for syscalls that could fail due to EINTR.\r\n        All functions should be retried if there is time left in the timeout\r\n        in accordance with PEP 475. \"\"\"\r\n        timeout = kwargs.get(\"timeout\", None)\r\n        if timeout is None:\r\n            expires = None\r\n            recalc_timeout = False\r\n        else:\r\n            timeout = float(timeout)\r\n            if timeout < 0.0:  # Timeout less than 0 treated as no timeout.\r\n                expires = None\r\n            else:\r\n                expires = monotonic() + timeout\r\n\r\n        if recalc_timeout and 'timeout' not in kwargs:\r\n            raise ValueError(\r\n                'Timeout must be in kwargs to be recalculated')\r\n\r\n        result = _SYSCALL_SENTINEL\r\n        while result is _SYSCALL_SENTINEL:\r\n            try:\r\n                result = func(*args, **kwargs)\r\n            # OSError is thrown by select.select\r\n            # IOError is thrown by select.epoll.poll\r\n            # select.error is thrown by select.poll.poll\r\n            # Aren't we thankful for Python 3.x rework for exceptions?\r\n            except (OSError, IOError, select.error) as e:\r\n                # select.error wasn't a subclass of OSError in the past.\r\n                errcode = None\r\n                if hasattr(e, 'errno') and e.errno is not None:\r\n                    errcode = e.errno\r\n                elif hasattr(e, 'args'):\r\n                    errcode = e.args[0]\r\n\r\n                # Also test for the Windows equivalent of EINTR.\r\n                is_interrupt = (errcode == errno.EINTR or (hasattr(errno, 'WSAEINTR') and\r\n                                                           errcode == errno.WSAEINTR))\r\n\r\n                if is_interrupt:\r\n                    if expires is not None:\r\n                        current_time = monotonic()\r\n                        if current_time > expires:\r\n                            raise OSError(errno.ETIMEDOUT, 'Connection timed out')\r\n                        if recalc_timeout:\r\n                            kwargs[\"timeout\"] = expires - current_time\r\n                    continue\r\n                raise\r\n        return result\r\n\r\n\r\n# Choose the best implementation, roughly:\r\n# kqueue == devpoll == epoll > poll > select\r\n# select() also can't accept a FD > FD_SETSIZE (usually around 1024)\r\ndef DefaultSelector():\r\n    \"\"\" This function serves as a first call for DefaultSelector to\r\n    detect if the select module is being monkey-patched incorrectly\r\n    by eventlet, greenlet, and preserve proper behavior. \"\"\"\r\n    global _DEFAULT_SELECTOR\r\n    if _DEFAULT_SELECTOR is None:\r\n        if platform.python_implementation() == 'Jython':  # Platform-specific: Jython\r\n            _DEFAULT_SELECTOR = JythonSelectSelector\r\n        elif _can_allocate('kqueue'):\r\n            _DEFAULT_SELECTOR = KqueueSelector\r\n        elif _can_allocate('devpoll'):\r\n            _DEFAULT_SELECTOR = DevpollSelector\r\n        elif _can_allocate('epoll'):\r\n            _DEFAULT_SELECTOR = EpollSelector\r\n        elif _can_allocate('poll'):\r\n            _DEFAULT_SELECTOR = PollSelector\r\n        elif hasattr(select, 'select'):\r\n            _DEFAULT_SELECTOR = SelectSelector\r\n        else:  # Platform-specific: AppEngine\r\n            raise RuntimeError('Platform does not have a selector.')\r\n    return _DEFAULT_SELECTOR()\r\n"
  },
  {
    "path": "code/default/lib/noarch/simple_http_client.py",
    "content": "\nimport selectors2 as selectors\nfrom xlog import getLogger\nxlog = getLogger(\"simple_http_client\")\n\ntry:\n    # py3\n    from urllib.parse import urlparse, urlsplit\n    from http.client import IncompleteRead\nexcept ImportError:\n    # py2\n    from urlparse import urlparse, urlsplit\n    from httplib import IncompleteRead\n\nimport socket\nimport time\nimport os\nimport utils\nimport ssl\n\n\nclass Connection():\n    def __init__(self, sock):\n        self.sock = sock\n        self.create_time = time.time()\n\n    def close(self):\n        self.sock.close()\n\n\nclass BaseResponse(object):\n    def __init__(self, status=601, reason=b\"\", headers={}, body=b\"\"):\n        self.status = status\n        self.reason = reason\n        self.headers = {}\n        for key in headers:\n            if isinstance(key, tuple):\n                key, value = key\n            else:\n                value = headers[key]\n            key = key.title()\n            self.headers[key] = value\n\n        self.text = body\n\n    def getheader(self, key, default_value=b\"\"):\n        key = key.title()\n        if key in self.headers:\n            return self.headers[key]\n        else:\n            return default_value\n\n\nclass TxtResponse(BaseResponse):\n    def __init__(self, buf):\n        BaseResponse.__init__(self)\n        if isinstance(buf, memoryview):\n            self.view = buf\n            self.read_buffer = buf.tobytes()\n        elif isinstance(buf, str):\n            self.read_buffer = utils.to_bytes(buf)\n            self.view = memoryview(self.read_buffer)\n        elif isinstance(buf, bytes):\n            self.read_buffer = buf\n            self.view = memoryview(buf)\n        else:\n            raise Exception(\"TxtResponse error\")\n\n        self.buffer_start = 0\n        self.version = None\n        self.info = None\n        self.body = None\n        self.parse()\n\n    def read_line(self):\n        n1 = self.read_buffer.find(b\"\\r\\n\", self.buffer_start)\n        if n1 == -1:\n            raise Exception(\"read_line fail\")\n\n        line = self.read_buffer[self.buffer_start:n1]\n        self.buffer_start = n1 + 2\n        return line\n\n    def read_headers(self):\n        n1 = self.read_buffer.find(b\"\\r\\n\\r\\n\", self.buffer_start)\n        if n1 == -1:\n            raise Exception(\"read_headers fail\")\n        block = self.read_buffer[self.buffer_start:n1]\n        self.buffer_start = n1 + 4\n        return block\n\n    def parse(self):\n        requestline = self.read_line()\n        words = requestline.split()\n        if len(words) < 2:\n            raise Exception(\"status line:%s\" % requestline)\n\n        self.version = words[0]\n        self.status = int(words[1])\n        self.info = b\" \".join(words[2:])\n\n        self.headers = {}\n        header_block = self.read_headers()\n        lines = header_block.split(b\"\\r\\n\")\n        for line in lines:\n            p = line.find(b\":\")\n            key = line[0:p]\n            value = line[p + 2:]\n            key = str(key.title())\n            self.headers[key] = value\n\n        self.body = self.view[self.buffer_start:]\n        self.read_buffer = b\"\"\n        self.buffer_start = 0\n\n\nclass Response(BaseResponse):\n\n    def __init__(self, sock):\n        BaseResponse.__init__(self)\n        self.sock = sock\n        self.sock.settimeout(1)\n        self.sock.setblocking(0)\n        self.read_buffer = b\"\"\n        self.buffer_start = 0\n        self.chunked = False\n        self.version = None\n        self.content_length = None\n        self.select2 = selectors.DefaultSelector()\n        self.select2.register(sock, selectors.EVENT_READ)\n\n    def __del__(self):\n        try:\n            self.select2.unregister(self.sock)\n        except:\n            pass\n\n        try:\n            socket.socket.close(self.sock)\n        except:\n            pass\n\n    def recv(self, to_read=8192, timeout=30.0):\n        if timeout < 0:\n            raise Exception(\"recv timeout\")\n\n        start_time = time.time()\n        end_time = start_time + timeout\n        while time.time() < end_time:\n            try:\n                return self.sock.recv(to_read)\n            except (BlockingIOError, socket.error) as e:\n                if e.errno in [2, 11, 35, 60, 10035]:\n                    time_left = end_time - time.time()\n                    if time_left < 0:\n                        break\n\n                    # select.select([self.sock], [], [self.sock], time_left)\n                    self.select2.select(timeout=time_left)\n                    continue\n                else:\n                    raise e\n\n        raise Exception(\"recv timeout\")\n\n    def read_line(self, timeout=60.0):\n        start_time = time.time()\n        end_time = start_time + timeout\n        while True:\n            n1 = self.read_buffer.find(b\"\\r\\n\", self.buffer_start)\n            if n1 > -1:\n                line = self.read_buffer[self.buffer_start:n1]\n                self.buffer_start = n1 + 2\n                return line\n\n            if time.time() > end_time:\n                raise socket.timeout()\n\n            time_left = end_time - time.time()\n            data = self.recv(8192, time_left)\n\n            if isinstance(data, int):\n                continue\n            if data and len(data):\n                self.read_buffer += data\n            else:\n                time_left = end_time - time.time()\n                if time_left < 0:\n                    raise socket.error\n\n    def read_headers(self, timeout=60.0):\n        start_time = time.time()\n        lines = []\n        while True:\n            left_time = timeout - (time.time() - start_time)\n            line = self.read_line(left_time)\n            if len(line.strip()) == 0:\n                return b\"\\r\\n\".join(lines)\n\n            lines.append(line)\n\n    def begin(self, timeout=60.0):\n        start_time = time.time()\n        line = self.read_line(timeout)\n\n        requestline = line.rstrip(b'\\r\\n')\n        words = requestline.split()\n        if len(words) < 2:\n            raise Exception(\"status line:%s\" % requestline)\n\n        self.version = words[0]\n        self.status = int(words[1])\n        self.reason = b\" \".join(words[2:])\n\n        self.headers = {}\n        timeout -= time.time() - start_time\n        timeout = max(timeout, 0.1)\n        header_block = self.read_headers(timeout)\n        lines = header_block.split(b\"\\r\\n\")\n        for line in lines:\n            p = line.find(b\":\")\n            key = line[0:p]\n            value = line[p + 2:]\n            key = key.title()\n            self.headers[key] = value\n\n        self.content_length = self.getheader(b\"content-length\", b\"\")\n        if b\"chunked\" in self.getheader(b\"Transfer-Encoding\", b\"\"):\n            self.chunked = True\n\n        if b\"gzip\" in self.getheader(b\"Transfer-Encoding\", b\"\"):\n            print(\"gzip not work\")\n\n    def _read_plain(self, read_len, timeout):\n        if read_len == 0:\n            return \"\"\n\n        if read_len is not None and len(self.read_buffer) - self.buffer_start > read_len:\n            out_str = self.read_buffer[self.buffer_start:self.buffer_start + read_len]\n            self.buffer_start += read_len\n            if len(self.read_buffer) == self.buffer_start:\n                self.read_buffer = b\"\"\n                self.buffer_start = 0\n            return out_str\n\n        start_time = time.time()\n        end_time = start_time + timeout\n        out_len = len(self.read_buffer) - self.buffer_start\n        out_list = [self.read_buffer[self.buffer_start:]]\n\n        self.read_buffer = b\"\"\n        self.buffer_start = 0\n\n        while time.time() - start_time < timeout:\n            if not read_len and out_len > 0:\n                break\n\n            if read_len and out_len >= read_len:\n                break\n\n            if read_len:\n                to_read = read_len - out_len\n                to_read = min(to_read, 65535)\n            else:\n                to_read = 65535\n\n            time_left = end_time - time.time()\n            data = self.recv(to_read, time_left)\n\n            if data:\n                out_list.append(data)\n                out_len += len(data)\n            else:\n                time_left = start_time + timeout - time.time()\n                if time_left < 0:\n                    raise socket.error\n\n                # r, w, e = select.select([self.sock], [], [self.sock], time_left)\n                events = self.select2.select(timeout=time_left)\n                for key, event in events:\n                    if not event & selectors.EVENT_READ:\n                        raise socket.error\n\n        if read_len is not None and out_len < read_len:\n            raise socket.timeout()\n\n        return b\"\".join(out_list)\n\n    def _read_size(self, read_len, timeout):\n        if len(self.read_buffer) - self.buffer_start > read_len:\n            buf = memoryview(self.read_buffer)\n            out_str = buf[self.buffer_start:self.buffer_start + read_len]\n            self.buffer_start += read_len\n            if len(self.read_buffer) == self.buffer_start:\n                self.read_buffer = b\"\"\n                self.buffer_start = 0\n            return out_str\n\n        start_time = time.time()\n        out_len = len(self.read_buffer) - self.buffer_start\n        out_bytes = bytearray(read_len)\n        view = memoryview(out_bytes)\n        view[0:out_len] = self.read_buffer[self.buffer_start:]\n\n        self.read_buffer = b\"\"\n        self.buffer_start = 0\n\n        while time.time() - start_time < timeout:\n            if out_len >= read_len:\n                break\n\n            to_read = read_len - out_len\n            to_read = min(to_read, 65535)\n\n            try:\n                nbytes = self.sock.recv_into(view[out_len:], to_read)\n            except (BlockingIOError, socket.error) as e:\n                if e.errno in [2, 11, 35, 60, 10035]:\n                    time_left = start_time + timeout - time.time()\n                    if time_left < 0:\n                        raise socket.timeout\n\n                    # select.select([self.sock], [], [self.sock], time_left)\n                    self.select2.select(timeout=time_left)\n                    continue\n                else:\n                    raise e\n\n            out_len += nbytes\n        if out_len < read_len:\n            raise socket.timeout()\n\n        return out_bytes\n\n    def _read_chunked(self, timeout):\n        line = self.read_line(timeout)\n        chunk_size = int(line, 16)\n        dat = self._read_plain(chunk_size + 2, timeout)\n        return dat[:-2]\n\n    def read(self, read_len=None, timeout=60):\n        if not self.chunked:\n            data = self._read_plain(read_len, timeout)\n        else:\n            data = self._read_chunked(timeout)\n        return data\n\n    def readall(self, timeout=60):\n        start_time = time.time()\n        if self.chunked:\n            out_list = []\n            while True:\n                time_left = timeout - (time.time() - start_time)\n                if time_left < 0:\n                    raise socket.timeout()\n\n                dat = self._read_chunked(time_left)\n                if not dat:\n                    break\n\n                out_list.append(dat)\n\n            return b\"\".join(out_list)\n        else:\n            return self._read_plain(int(self.content_length), timeout=timeout)\n\n\nclass Client(object):\n    def __init__(self, proxy=None, timeout=60, cert=\"\"):\n        self.timeout = timeout\n        self.cert = cert\n        self.sock = None\n        self.host = None\n        self.port = None\n        self.tls = None\n        self.ssl_context = None\n\n        if isinstance(proxy, str):\n            proxy_sp = urlsplit(proxy)\n\n            self.proxy = {\n                \"type\": proxy_sp.scheme,\n                \"host\": proxy_sp.hostname,\n                \"port\": proxy_sp.port,\n                \"user\": proxy_sp.username,\n                \"pass\": proxy_sp.password\n            }\n        elif isinstance(proxy, dict):\n            self.proxy = proxy\n        else:\n            self.proxy = None\n\n    @staticmethod\n    def direct_connect(host, port):\n        connect_timeout = 30\n\n        if b':' in host:\n            info = [(socket.AF_INET6, socket.SOCK_STREAM, 0, \"\", (host, port, 0, 0))]\n        elif utils.check_ip_valid4(host):\n            info = [(socket.AF_INET, socket.SOCK_STREAM, 0, \"\", (host, port))]\n        else:\n            try:\n                info = socket.getaddrinfo(host, port, socket.AF_UNSPEC,\n                                          socket.SOCK_STREAM)\n            except socket.gaierror:\n                info = [(socket.AF_INET, socket.SOCK_STREAM, 0, \"\", (host, port))]\n\n        for res in info:\n            af, socktype, proto, canonname, sa = res\n            ip_port = (sa[0], sa[1])\n            s = None\n            try:\n                s = socket.socket(af, socktype, proto)\n                # See http://groups.google.com/group/cherrypy-users/\n                #        browse_frm/thread/bbfe5eb39c904fe0\n\n                s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)\n                s.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 32 * 1024)\n                s.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, True)\n                s.settimeout(connect_timeout)\n                s.connect(ip_port)\n                return s\n            except socket.error as e:\n                xlog.warn(\"direct connect %s except:%r\", sa, e)\n                if s:\n                    s.close()\n\n        return None\n\n    def connect(self, host, port, tls):\n        if self.sock and host == self.host and port == self.port and self.tls == tls:\n            return self.sock\n\n        if not self.proxy:\n            sock = self.direct_connect(host, port)\n            if not sock:\n                return None\n        else:\n            connect_timeout = self.timeout\n\n            import socks\n\n            sock = socks.socksocket(socket.AF_INET)\n            sock.set_proxy(proxy_type=self.proxy[\"type\"],\n                           addr=self.proxy[\"host\"],\n                           port=self.proxy[\"port\"], rdns=True,\n                           username=self.proxy[\"user\"],\n                           password=self.proxy[\"pass\"])\n\n            sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)\n            sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 32 * 1024)\n            sock.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, True)\n            sock.settimeout(connect_timeout)\n            sock.connect((host, port))\n\n            # conn_time = time.time() - start_time\n            # xlog.debug(\"proxy:%s tcp conn:%s time:%d\", proxy[\"host\"], host, conn_time * 1000)\n\n        if tls:\n            if not self.ssl_context:\n                self.ssl_context = ssl.create_default_context()\n                self.ssl_context.check_hostname = False\n                self.ssl_context.verify_mode = ssl.CERT_REQUIRED\n\n            if os.path.isfile(self.cert):\n                sock = self.ssl_context.wrap_socket(sock, server_hostname=host)\n\n        self.sock = sock\n        self.host = host\n        self.port = port\n        self.tls = tls\n\n        return sock\n\n    def request(self, method, url, headers=None, body=b\"\", read_payload=True):\n        if headers is None:\n            headers = {}\n        method = utils.to_bytes(method)\n        url = utils.to_bytes(url)\n\n        upl = urlsplit(url)\n        headers[\"Content-Length\"] = str(len(body))\n        headers[\"Host\"] = upl.netloc\n        port = upl.port\n        if not port:\n            if upl.scheme == b\"http\":\n                port = 80\n            elif upl.scheme == b\"https\":\n                port = 443\n            else:\n                raise Exception(\"unknown method:%s\" % upl.scheme)\n\n        path = upl.path\n        if not path:\n            path = b\"/\"\n\n        if upl.query:\n            path += b\"?\" + upl.query\n\n        try:\n            sock = self.connect(upl.hostname, port, upl.scheme == b\"https\")\n        except Exception as e:\n            xlog.warn(\"connect %s:%s fail:%r\", upl.hostname, port, e)\n            return None\n\n        if not sock:\n            return None\n\n        request_data = b'%s %s HTTP/1.1\\r\\n' % (method, path)\n\n        for k, v in headers.items():\n            if isinstance(v, int):\n                request_data += b'%s: %d\\r\\n' % (utils.to_bytes(k), v)\n            else:\n                request_data += b'%s: %s\\r\\n' % (utils.to_bytes(k), utils.to_bytes(v))\n\n        request_data += b'\\r\\n'\n\n        body = utils.to_bytes(body)\n\n        try:\n            if len(request_data) + len(body) < 1300:\n                body = request_data + body\n            else:\n                sock.send(request_data)\n\n            payload_len = len(body)\n            start = 0\n            while start < payload_len:\n                send_size = min(payload_len - start, 65535)\n                sended = sock.send(body[start:start + send_size])\n                start += sended\n\n            sock.settimeout(self.timeout)\n            response = Response(sock)\n\n            response.begin(timeout=self.timeout)\n        except Exception as e:\n            return None\n\n        if response.status != 200:\n            # logging.warn(\"status:%r\", response.status)\n            return response\n\n        if not read_payload:\n            return response\n\n        if b'Transfer-Encoding' in response.headers:\n            data_buffer = []\n            while True:\n                try:\n                    data = response.read(8192, timeout=self.timeout)\n                except IncompleteRead as e:\n                    data = e.partial\n                except Exception as e:\n                    raise e\n\n                if not data:\n                    break\n                else:\n                    data_buffer.append(data)\n\n            response.text = b\"\".join(data_buffer)\n            return response\n        else:\n            content_length = int(response.getheader(b'Content-Length', b\"0\"))\n            if content_length:\n                response.text = response.read(content_length, timeout=self.timeout)\n\n            return response\n\n\ndef request(method=\"GET\", url=None, headers=None, body=b\"\", proxy=None, timeout=60, read_payload=True):\n    if headers is None:\n        headers = {}\n    if not url:\n        raise Exception(\"no url\")\n\n    client = Client(proxy, timeout=timeout)\n    return client.request(method, url, headers, body, read_payload)\n"
  },
  {
    "path": "code/default/lib/noarch/simple_http_server.py",
    "content": "import os\nimport datetime\nimport threading\nimport socket\nimport errno\nimport sys\nimport select\nimport time\nimport json\nimport base64\nimport hashlib\nimport struct\n\ntry:\n    from urllib.parse import urlparse, urlencode, parse_qs\n    from urllib.request import urlopen, Request\n    from urllib.error import HTTPError\nexcept ImportError:\n    from urlparse import urlparse, parse_qs\n    from urllib import urlencode\n    from urllib2 import urlopen, Request, HTTPError\n    import mimetools\n\nimport xlog\nimport utils\n\n\nclass GetReqTimeout(Exception):\n    pass\n\n\nclass ParseReqFail(Exception):\n    def __init__(self, message):\n        self.message = message\n\n    def __str__(self):\n        # for %s\n        return repr(self.message)\n\n    def __repr__(self):\n        # for %r\n        return repr(self.message)\n\n\nclass HttpServerHandler():\n    WebSocket_MAGIC_GUID = b\"258EAFA5-E914-47DA-95CA-C5AB0DC85B11\"\n    default_request_version = b\"HTTP/1.1\"\n\n    rbufsize = 32 * 1024\n    wbufsize = 32 * 1024\n\n    res_headers = {}\n\n    def __init__(self, sock, client, args, logger=None):\n        self.connection = sock\n        sock.setblocking(1)\n        sock.settimeout(60)\n        self.rfile = self.connection.makefile('rb', self.rbufsize)\n        self.wfile = self.connection.makefile('wb', self.wbufsize)\n        self.client_address = client\n        self.args = args\n        if logger:\n            self.logger = logger\n        else:\n            self.logger = xlog.getLogger(\"simple_http_server\")\n        # self.logger.debug(\"new connect from:%s\", self.address_string())\n\n        self.setup()\n\n    def set_CORS(self, headers):\n        self.res_headers = headers\n\n    def setup(self):\n        pass\n\n    def __del__(self):\n        try:\n            socket.socket.close(self.connection)\n        except:\n            pass\n\n    def handle(self):\n        # self.logger.info('Connected from %r', self.client_address)\n        while True:\n            try:\n                self.close_connection = 1\n                self.handle_one_request()\n            except Exception as e:\n                self.logger.warn(\"handle err:%r close\", e)\n                self.close_connection = 1\n\n            if self.close_connection:\n                break\n        self.connection.close()\n        # self.logger.debug(\"closed from %s:%d\", self.client_address[0], self.client_address[1])\n\n    def address_string(self):\n        return '%s:%s' % self.client_address[:2]\n\n    def parse_headers(self):\n        headers = {}\n        while True:\n            line = self.rfile.readline(65537)\n            line = line.strip()\n            if len(line) == 0:\n                break\n\n            k, v = line.split(b\":\", 1)\n            key = k.title()\n            headers[key] = v.lstrip()\n        return headers\n\n    def parse_request(self):\n        try:\n            self.raw_requestline = self.rfile.readline(65537)\n        except:\n            raise GetReqTimeout()\n\n        if not self.raw_requestline:\n            raise GetReqTimeout()\n\n        if len(self.raw_requestline) > 65536:\n            raise ParseReqFail(\"Recv command line too large\")\n\n        if self.raw_requestline[0] == '\\x16':\n            raise socket.error\n\n        self.command = b''  # set in case of error on the first line\n        self.path = b''\n        self.request_version = version = self.default_request_version\n\n        requestline = self.raw_requestline\n        requestline = requestline.rstrip(b'\\r\\n')\n        self.requestline = requestline\n        words = requestline.split()\n        if len(words) == 3:\n            command, path, version = words\n            if version[:5] != b'HTTP/':\n                raise ParseReqFail(\"Req command format fail:%s\" % requestline)\n\n            try:\n                base_version_number = version.split(b'/', 1)[1]\n                version_number = base_version_number.split(b\".\")\n                # RFC 2145 section 3.1 says there can be only one \".\" and\n                #   - major and minor numbers MUST be treated as\n                #      separate integers;\n                #   - HTTP/2.4 is a lower version than HTTP/2.13, which in\n                #      turn is lower than HTTP/12.3;\n                #   - Leading zeros MUST be ignored by recipients.\n                if len(version_number) != 2:\n                    raise ParseReqFail(\"Req command format fail:%s\" % requestline)\n                version_number = int(version_number[0]), int(version_number[1])\n            except (ValueError, IndexError):\n                raise ParseReqFail(\"Req command format fail:%s\" % requestline)\n            if version_number >= (1, 1):\n                self.close_connection = 0\n            if version_number >= (2, 0):\n                raise ParseReqFail(\"Req command format fail:%s\" % requestline)\n        elif len(words) == 2:\n            command, path = words\n            self.close_connection = 1\n            if command != b'GET':\n                raise ParseReqFail(\"Req command format HTTP/0.9 line:%s\" % requestline)\n        elif not words:\n            raise ParseReqFail(\"Req command format fail:%s\" % requestline)\n        else:\n            raise ParseReqFail(\"Req command format fail:%s\" % requestline)\n        self.command, self.path, self.request_version = command, path, version\n\n        # Parse HTTP headers\n        self.headers = self.parse_headers()\n\n        self.host = self.headers.get(b'Host', b\"\")\n        conntype = self.headers.get(b'Connection', b\"\")\n        if conntype.lower() == b'close':\n            self.close_connection = 1\n        elif conntype.lower() == b'keep-alive':\n            self.close_connection = 0\n\n        self.upgrade = self.headers.get(b'Upgrade', b\"\").lower()\n\n        return True\n\n    def unpack_reqs(self, reqs):\n        query = {}\n        for key, val1 in reqs.items():\n            if isinstance(val1, list):\n                query[key] = val1[0]\n            else:\n                query[key] = val1\n        return query\n\n    def handle_one_request(self):\n        try:\n            self.parse_request()\n\n            self.close_connection = 0\n\n            if self.upgrade == b\"websocket\":\n                self.do_WebSocket()\n            elif self.command == b\"GET\":\n                self.do_GET()\n            elif self.command == b\"POST\":\n                self.do_POST()\n            elif self.command == b\"CONNECT\":\n                self.do_CONNECT()\n            elif self.command == b\"HEAD\":\n                self.do_HEAD()\n            elif self.command == b\"DELETE\":\n                self.do_DELETE()\n            elif self.command == b\"OPTIONS\":\n                self.do_OPTIONS()\n            elif self.command == b\"PUT\":\n                self.do_PUT()\n            else:\n                self.logger.warn(\"unhandler cmd:%s path:%s from:%s\", self.command, self.path, self.address_string())\n                return\n\n            self.wfile.flush()  # actually send the response if not already done.\n        except ParseReqFail as e:\n            self.logger.warn(\"parse req except:%r\", e)\n            self.close_connection = 1\n        except socket.error as e:\n            self.logger.warn(\"socket error:%r\", e)\n            self.close_connection = 1\n        except IOError as e:\n            if e.errno == errno.EPIPE:\n                self.logger.warn(\"PIPE error:%r\", e)\n                pass\n            else:\n                self.logger.warn(\"IOError:%r\", e)\n                pass\n            # except OpenSSL.SSL.SysCallError as e:\n            #    self.logger.warn(\"socket error:%r\", e)\n            self.close_connection = 1\n        except GetReqTimeout as e:\n            # self.logger.exception(\"GetReqTimeout %r\", e)\n            self.close_connection = 1\n        except Exception as e:\n            self.logger.exception(\"handler:%r cmd:%s path:%s from:%s\", e, self.command, self.path,\n                                  self.address_string())\n            self.close_connection = 1\n\n    def WebSocket_handshake(self):\n        protocol = self.headers.get(b\"Sec-WebSocket-Protocol\", b\"\")\n        if protocol:\n            self.logger.info(\"Sec-WebSocket-Protocol:%s\", protocol)\n        version = self.headers.get(b\"Sec-WebSocket-Version\", b\"\")\n        if version != b\"13\":\n            self.logger.warn(\"Sec-WebSocket-Version:%s\", version)\n            self.close_connection = 1\n            return False\n\n        key = self.headers[b\"Sec-WebSocket-Key\"]\n        self.WebSocket_key = key\n        digest = base64.b64encode(hashlib.sha1(key + self.WebSocket_MAGIC_GUID).hexdigest().decode('hex'))\n        response = b'HTTP/1.1 101 Switching Protocols\\r\\n'\n        response += b'Upgrade: websocket\\r\\n'\n        response += b'Connection: Upgrade\\r\\n'\n        response += b'Sec-WebSocket-Accept: %s\\r\\n\\r\\n' % digest\n        self.wfile.write(response)\n        return True\n\n    def WebSocket_send_message(self, message):\n        self.wfile.write(chr(129))\n        length = len(message)\n        if length <= 125:\n            self.wfile.write(chr(length))\n        elif length >= 126 and length <= 65535:\n            self.wfile.write(126)\n            self.wfile.write(struct.pack(\">H\", length))\n        else:\n            self.wfile.write(127)\n            self.wfile.write(struct.pack(\">Q\", length))\n        self.wfile.write(message)\n\n    def WebSocket_receive_worker(self):\n        while not self.close_connection:\n            try:\n                h = self.rfile.read(2)\n                if h is None or len(h) == 0:\n                    break\n\n                length = ord(h[1]) & 127\n                if length == 126:\n                    length = struct.unpack(\">H\", self.rfile.read(2))[0]\n                elif length == 127:\n                    length = struct.unpack(\">Q\", self.rfile.read(8))[0]\n                masks = [ord(byte) for byte in self.rfile.read(4)]\n                decoded = \"\"\n                for char in self.rfile.read(length):\n                    decoded += chr(ord(char) ^ masks[len(decoded) % 4])\n                try:\n                    self.WebSocket_on_message(decoded)\n                except Exception as e:\n                    self.logger.warn(\"WebSocket %s except on process message, %r\", self.WebSocket_key, e)\n            except Exception as e:\n                self.logger.exception(\"WebSocket %s exception:%r\", self.WebSocket_key, e)\n                break\n\n        self.WebSocket_on_close()\n        self.close_connection = 1\n\n    def WebSocket_on_message(self, message):\n        self.logger.debug(\"websocket message:%s\", message)\n\n    def WebSocket_on_close(self):\n        self.logger.debug(\"websocket closed\")\n\n    def do_WebSocket(self):\n        self.logger.info(\"WebSocket cmd:%s path:%s from:%s\", self.command, self.path, self.address_string())\n        self.logger.info(\"Host:%s\", self.headers.get(\"Host\", \"\"))\n\n        if not self.WebSocket_on_connect():\n            return\n\n        if not self.WebSocket_handshake():\n            self.logger.warn(\"WebSocket handshake fail.\")\n            return\n\n        self.WebSocket_receive_worker()\n\n    def WebSocket_on_connect(self):\n        # Define the function and return True to accept\n        self.logger.warn(\"unhandled WebSocket from %s\", self.address_string())\n        self.send_error(501, \"Not supported\")\n        self.close_connection = 1\n\n        return False\n\n    def do_GET(self):\n        self.logger.warn(\"unhandler cmd:%s from:%s\", self.command, self.address_string())\n\n    def do_POST(self):\n        self.logger.warn(\"unhandler cmd:%s from:%s\", self.command, self.address_string())\n\n    def do_PUT(self):\n        self.logger.warn(\"unhandler cmd:%s from:%s\", self.command, self.address_string())\n\n    def do_DELETE(self):\n        self.logger.warn(\"unhandler cmd:%s from:%s\", self.command, self.address_string())\n\n    def do_OPTIONS(self):\n        self.logger.warn(\"unhandler cmd:%s from:%s\", self.command, self.address_string())\n\n    def do_HEAD(self):\n        self.logger.warn(\"unhandler cmd:%s from:%s\", self.command, self.address_string())\n\n    def do_CONNECT(self):\n        self.logger.warn(\"unhandler cmd:%s from:%s\", self.command, self.address_string())\n\n    def send_not_found(self):\n        self.close_connection = 1\n        content = b\"File not found.\"\n        self.wfile.write(b'HTTP/1.1 404\\r\\nContent-Length: %d\\r\\nConnection: close\\r\\n\\r\\n%s' % (len(content), content))\n\n    def send_error(self, code, message=None):\n        self.close_connection = 1\n        self.wfile.write(b'HTTP/1.1 %d\\r\\n' % code)\n        self.wfile.write(b'Connection: close\\r\\n\\r\\n')\n        if message:\n            self.wfile.write(utils.to_bytes(message))\n\n    def send_response(self, mimetype=b\"\", content=b\"\", headers=b\"\", status=200):\n        data = []\n        data.append(b'HTTP/1.1 %d\\r\\n' % status)\n        if len(mimetype):\n            data.append(b'Content-Type: %s\\r\\n' % utils.to_bytes(mimetype))\n\n        content = utils.to_bytes(content)\n\n        for key in self.res_headers:\n            data.append(b\"%s: %s\\r\\n\" % (utils.to_bytes(key), utils.to_bytes(self.res_headers[key])))\n        data.append(b'Content-Length: %d\\r\\n' % len(content))\n\n        if len(headers):\n            if isinstance(headers, dict):\n                headers = utils.to_bytes(headers)\n                if b'Content-Length' in headers:\n                    del headers[b'Content-Length']\n                for key in headers:\n                    data.append(b\"%s: %s\\r\\n\" % (utils.to_bytes(key), utils.to_bytes(headers[key])))\n            elif isinstance(headers, str):\n                data.append(headers.encode(\"utf-8\"))\n            elif isinstance(headers, bytes):\n                data.append(headers)\n        data.append(b\"\\r\\n\")\n\n        if len(content) < 1024:\n            data.append(content)\n            data_str = b\"\".join(data)\n            self.wfile.write(data_str)\n        else:\n            data_str = b\"\".join(data)\n            self.wfile.write(data_str)\n            if len(content):\n                self.wfile.write(content)\n\n    def send_redirect(self, url, headers={}, content=b\"\", status=307, text=b\"Temporary Redirect\"):\n        url = utils.to_bytes(url)\n        headers = utils.to_bytes(headers)\n        content = utils.to_bytes(content)\n\n        headers[b\"Location\"] = url\n        data = []\n        data.append(b'HTTP/1.1 %d\\r\\n' % status)\n        data.append(b'Content-Length: %s\\r\\n' % len(content))\n\n        if len(headers):\n            if isinstance(headers, dict):\n                for key in headers:\n                    data.append(b\"%s: %s\\r\\n\" % (key, headers[key]))\n            elif isinstance(headers, str):\n                data.append(headers)\n        data.append(b\"\\r\\n\")\n\n        data.append(content)\n        data_str = b\"\".join(data)\n        self.wfile.write(data_str)\n\n    def send_response_nc(self, mimetype=b\"\", content=b\"\", headers=b\"\", status=200):\n        no_cache_headers = b\"Cache-Control: no-cache, no-store, must-revalidate\\r\\nPragma: no-cache\\r\\nExpires: 0\\r\\n\"\n        return self.send_response(mimetype, content, no_cache_headers + headers, status)\n\n    def send_file(self, filename, mimetype):\n        try:\n            if not os.path.isfile(filename):\n                self.send_not_found()\n                return\n\n            file_size = os.path.getsize(filename)\n            tme = (datetime.datetime.today() + datetime.timedelta(minutes=0)).strftime('%a, %d %b %Y %H:%M:%S GMT')\n            head = b'HTTP/1.1 200\\r\\nAccess-Control-Allow-Origin: *\\r\\nCache-Control:no-cache\\r\\n'\n            head += b'Expires: %s\\r\\nContent-Type: %s\\r\\nContent-Length: %s\\r\\n\\r\\n' % utils.to_bytes(\n                (tme, mimetype, file_size))\n            self.wfile.write(head)\n\n            with open(filename, 'rb') as fp:\n                while True:\n                    data = fp.read(65535)\n                    if not data:\n                        break\n                    self.wfile.write(data)\n        except:\n            pass\n            # self.logger.warn(\"download broken\")\n\n    def response_json(self, res_arr, headers=b\"\"):\n        data = json.dumps(utils.to_str(res_arr), indent=0, sort_keys=True)\n        self.send_response(b'application/json', data, headers=headers)\n\n\nclass HTTPServer():\n    def __init__(self, address, handler, args=(), use_https=False, cert=\"\", logger=xlog, max_thread=1024,\n                 check_listen_interval=None):\n        self.sockets = []\n        if isinstance(address, tuple):\n            self.server_address = [address]\n        else:\n            # server can listen multi-port\n            self.server_address = address\n        self.handler = handler\n        self.logger = logger\n        self.args = args\n        self.use_https = use_https\n        self.cert = cert\n        self.max_thread = max_thread\n        self.check_listen_interval = check_listen_interval\n        # self.logger.info(\"server %s:%d started.\", address[0], address[1])\n\n    def start(self):\n        self.init_socket()\n        self.http_thread = threading.Thread(target=self.serve_forever, name=\"serve_%s\" % self.server_address)\n        self.http_thread.daemon = True\n        self.http_thread.start()\n\n    def init_socket(self):\n        server_address = self.server_address\n        ips = [ip for ip, _ in server_address]\n        listen_all_v4 = b\"0.0.0.0\" in ips\n        listen_all_v6 = b\"::\" in ips\n        for ip, port in server_address:\n            if ip not in (b\"0.0.0.0\", b\"::\") and (\n                    listen_all_v4 and b'.' in ip or\n                    listen_all_v6 and b':' in ip):\n                continue\n            self.add_listen((ip, port))\n\n    def add_listen(self, addr):\n        ip = addr[0]\n        port = addr[1]\n        if isinstance(ip, str):\n            ip = ip.encode(\"ascii\")\n\n        if b\":\" in ip:\n            sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)\n        else:\n            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)\n\n        sock.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, True)\n        addr = tuple((ip, port))\n        try:\n            sock.bind(addr)\n        except Exception as e:\n            err_string = \"bind to %s:%d fail:%r\" % (addr[0], addr[1], e)\n            self.logger.error(err_string)\n            raise Exception(err_string)\n\n        if self.use_https:\n            import OpenSSL\n            if hasattr(OpenSSL.SSL, \"TLSv1_2_METHOD\"):\n                ssl_version = OpenSSL.SSL.TLSv1_2_METHOD\n            elif hasattr(OpenSSL.SSL, \"TLSv1_1_METHOD\"):\n                ssl_version = OpenSSL.SSL.TLSv1_1_METHOD\n            elif hasattr(OpenSSL.SSL, \"TLSv1_METHOD\"):\n                ssl_version = OpenSSL.SSL.TLSv1_METHOD\n\n            ctx = OpenSSL.SSL.Context(ssl_version)\n            # server.pem's location (containing the server private key and the server certificate).\n            fpem = self.cert\n            ctx.use_privatekey_file(fpem)\n            ctx.use_certificate_file(fpem)\n            sock = OpenSSL.SSL.Connection(ctx, sock)\n        sock.listen(200)\n        self.sockets.append(sock)\n        self.logger.info(\"server %s:%d started.\", addr[0], addr[1])\n\n    def serve_forever(self):\n        self.running = True\n        if not self.sockets:\n            self.init_socket()\n\n        last_connect_time = time.time()\n        if hasattr(select, 'epoll'):\n            fn_map = {}\n            p = select.epoll()\n            for sock in self.sockets:\n                fn = sock.fileno()\n                sock.setblocking(0)\n                p.register(fn, select.EPOLLIN | select.EPOLLHUP | select.EPOLLPRI)\n                fn_map[fn] = sock\n\n            while self.running:\n                try:\n                    try:\n                        events = p.poll(timeout=1)\n                    except IOError as e:\n                        self.logger.exception(\"poll except:%r\", e)\n                        if e.errno != 4:  # EINTR:\n                            raise\n                        else:\n                            time.sleep(1)\n                            continue\n\n                    if not self.running:\n                        break\n\n                    for fn, event in events:\n                        if fn not in fn_map:\n                            self.logger.error(\"p.poll get fn:%d\", fn)\n                            continue\n\n                        sock = fn_map[fn]\n                        try:\n                            (sock, address) = sock.accept()\n                        except IOError as e:\n                            self.logger.warn(\"socket accept fail %r.\", e)\n                            if e.args[0] == 11:\n                                # Resource temporarily unavailable is EAGAIN\n                                # and that's not really an error.\n                                # It means \"I don't have answer for you right now and\n                                # you have told me not to wait,\n                                # so here I am returning without answer.\"\n                                continue\n\n                            if e.args[0] == 24:\n                                self.logger.warn(\"max file opened when sock.accept\")\n                                time.sleep(30)\n                                continue\n\n                            self.logger.warn(\"socket accept fail(errno: %s).\", e.args[0])\n                            continue\n\n                        last_connect_time = time.time()\n                        try:\n                            self.process_connect(sock, address)\n                        except Exception as e:\n                            self.logger.exception(\"process connect error:%r\", e)\n\n                    if self.check_listen_interval and last_connect_time + self.check_listen_interval < time.time():\n                        self.check_listen_port_or_reset()\n                        last_connect_time = time.time()\n                except Exception as e:\n                    self.logger.exception(\"serve except:%r\", e)\n        else:\n            while self.running:\n                try:\n                    try:\n                        r, w, e = select.select(self.sockets, [], [], 1)\n                    except Exception as e:\n                        continue\n\n                    if not self.running:\n                        break\n\n                    for rsock in r:\n                        try:\n                            (sock, address) = rsock.accept()\n                        except IOError as e:\n                            self.logger.warn(\"socket accept fail(errno: %s).\", e.args[0])\n                            if e.args[0] == 10022:\n                                self.logger.info(\"restart socket server.\")\n                                self.server_close()\n                                self.init_socket()\n                            break\n\n                        last_connect_time = time.time()\n                        self.process_connect(sock, address)\n\n                    if self.check_listen_interval and last_connect_time + self.check_listen_interval < time.time():\n                        self.check_listen_port_or_reset()\n                        last_connect_time = time.time()\n                except Exception as e:\n                    self.logger.exception(\"serve except:%r\", e)\n        self.server_close()\n\n    def process_connect(self, sock, address):\n        # self.logger.debug(\"connect from %s:%d\", address[0], address[1])\n        if threading.active_count() > self.max_thread:\n            self.logger.warn(\"thread num exceed the limit. drop request from %s.\", address)\n            sock.close()\n            return\n\n        client_obj = self.handler(sock, address, self.args)\n        client_thread = threading.Thread(target=client_obj.handle, name=\"handle_%s:%d\" % address)\n        client_thread.start()\n\n    def check_listen_port(self, ip, port):\n        if ':' in ip:\n            info = [(socket.AF_INET6, socket.SOCK_STREAM, 0, \"\", (ip, port, 0, 0))]\n        else:\n            if \"0.0.0.0\" in ip:\n                ip = \"127.0.0.1\"\n\n            info = [(socket.AF_INET, socket.SOCK_STREAM, 0, \"\", (ip, port))]\n\n        for res in info:\n            af, socktype, proto, canonname, sa = res\n            ip_port = (sa[0], sa[1])\n            s = None\n            try:\n                s = socket.socket(af, socktype, proto)\n                s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)\n                s.settimeout(1)\n                s.connect(ip_port)\n                return s\n            except socket.error as e:\n                xlog.warn(\"connect %s except:%r\", sa, e)\n                if s:\n                    s.close()\n\n    def check_listen_port_or_reset(self):\n        for ip, port in self.server_address:\n            res = self.check_listen_port(ip, port)\n            if res:\n                return\n\n            self.logger.warn(\"Listen %s:%d check failed, try restart listening\", ip, port)\n            self.shutdown()\n            time.sleep(3)\n            self.start()\n            return\n\n    def shutdown(self):\n        self.logger.info(\"shutdown\")\n        self.running = False\n        self.server_close()\n\n    def server_close(self):\n        self.logger.info(\"server_close\")\n        for sock in self.sockets:\n            sock.close()\n        self.sockets = []\n\n\nclass TestHttpServer(HttpServerHandler):\n    def __init__(self, sock, client, args):\n        self.data_path = utils.to_bytes(args)\n        HttpServerHandler.__init__(self, sock, client, args)\n\n    def generate_random_lowercase(self, n):\n        min_lc = ord(b'a')\n        len_lc = 26\n        ba = bytearray(os.urandom(n))\n        for i, b in enumerate(ba):\n            ba[i] = min_lc + b % len_lc  # convert 0..255 to 97..122\n        # sys.stdout.buffer.write(ba)\n        return ba\n\n    def WebSocket_on_connect(self):\n        return True\n\n    def WebSocket_on_message(self, message):\n        self.WebSocket_send_message(message)\n\n    def do_GET(self):\n        url_path = urlparse(self.path).path\n        req = urlparse(self.path).query\n        reqs = parse_qs(req, keep_blank_values=True)\n\n        self.logger.debug(\"GET %s from %s:%d\", self.path, self.client_address[0], self.client_address[1])\n\n        if url_path == b\"/test\":\n            tme = (datetime.datetime.today() + datetime.timedelta(minutes=330)).strftime('%a, %d %b %Y %H:%M:%S GMT')\n            tme = utils.to_bytes(tme)\n            head = b'HTTP/1.1 200\\r\\nAccess-Control-Allow-Origin: *\\r\\nCache-Control:public, max-age=31536000\\r\\n'\n            head += b'Expires: %s\\r\\nContent-Type: text/plain\\r\\nContent-Length: 4\\r\\n\\r\\nOK\\r\\n' % (tme)\n            self.wfile.write(head)\n\n        elif url_path == b'/':\n            data = b\"OK\\r\\n\"\n            self.wfile.write(\n                b'HTTP/1.1 200\\r\\nAccess-Control-Allow-Origin: *\\r\\nContent-Length: %d\\r\\n\\r\\n%s' % (len(data), data))\n        elif url_path == b'/null':\n            mimetype = b\"application/x-binary\"\n            if b\"size\" in reqs:\n                file_size = int(reqs[b'size'][0])\n            else:\n                file_size = 1024 * 1024 * 1024\n\n            self.wfile.write(b'HTTP/1.1 200\\r\\nContent-Type: %s\\r\\nContent-Length: %s\\r\\n\\r\\n' % (mimetype, file_size))\n            start = 0\n            data = self.generate_random_lowercase(65535)\n            while start < file_size:\n                left = file_size - start\n                send_batch = min(left, 65535)\n                self.wfile.write(data[:send_batch])\n                start += send_batch\n        else:\n            if b\"..\" in url_path[1:]:\n                return self.send_not_found()\n\n            target = os.path.join(self.data_path, url_path[1:])\n            if os.path.isfile(target):\n                self.send_file(target, b\"application/x-binary\")\n            else:\n                self.wfile.write(b'HTTP/1.1 404\\r\\nContent-Length: 0\\r\\n\\r\\n')\n\n\ndef main(data_path=\".\"):\n    xlog.info(\"listen http on 8880\")\n    httpd = HTTPServer(('', 8880), TestHttpServer, data_path)\n    httpd.start()\n\n    while True:\n        time.sleep(10)\n\n\nif __name__ == \"__main__\":\n    if len(sys.argv) > 2:\n        data_path = sys.argv[1]\n    else:\n        data_path = \"\"\n\n    try:\n        main(data_path=data_path)\n    except Exception:\n        import traceback\n\n        traceback.print_exc(file=sys.stdout)\n    except KeyboardInterrupt:\n        sys.exit()\n"
  },
  {
    "path": "code/default/lib/noarch/simple_queue.py",
    "content": "import time\nimport threading\nimport sys\n\n# This simple Queue fix the performance problem in the system build-in Queue.\n# Every get with time out will run in thread sleep check sleep check...\n# cost too many CPU and delay queue response.\n\n# This solution will run a thread to check timeout, default is 0.1 second.\n# And message send queue with no delay, use thread lock/release.\n\n\nlist_lock = threading.Lock()\nth_lock = threading.Lock()\nqueue_list = []\ntimer_th = None\n\ntimeout_interval = 0.1\n\n# User can change  timeout_interval to bigger to reduce CPU load.\n\n\ndef timer_thread():\n    global timer_th\n    while True:\n        with list_lock:\n            to_del = []\n            wait_count = 0\n            for q in queue_list:\n                wait_count += q.check()\n\n                c = sys.getrefcount(q)\n                # print(c, id(q))\n                if c <= 3:\n                    # reference of object, less then 3 means no out side use.\n                    to_del.append(q)\n\n            for q in to_del:\n                # print(\"del queue\")\n                queue_list.remove(q)\n\n            if wait_count == 0:\n                break\n\n        time.sleep(timeout_interval)\n\n    with th_lock:\n        timer_th = None\n    # print(\"simple queue timer exit\")\n\n\ndef _add_queue(qq):\n    with list_lock:\n        queue_list.append(qq)\n\n\ndef _add_wait():\n    global timer_th\n    with th_lock:\n        if not timer_th:\n            timer_th = threading.Thread(target=timer_thread)\n            timer_th.start()\n\n\nclass Queue(object):\n    def __init__(self):\n        self.lock = threading.Lock()\n        self.queue = []\n        self.waiters = []\n        self.running = True\n        _add_queue(self)\n\n    def __sizeof__(self):\n        return len(self.queue)\n\n    def _qsize(self):\n        return len(self.queue)\n\n    def reset(self):\n        self.running = False\n        self.queue = []\n        self.notify_all()\n        self.running = True\n\n    def check(self):\n        if not self.waiters:\n            return 0\n\n        try:\n            if time.time() > self.waiters[0][0]:\n                self.notify()\n        except:\n            pass\n\n        return 1\n\n    def put(self, item):\n        with self.lock:\n            self.queue.append(item)\n            self.notify()\n\n    def get(self, timeout=None):\n        if not timeout:\n            with self.lock:\n                if not self.queue:\n                    return\n                else:\n                    return self.queue.pop(0)\n\n        end_time = time.time() + timeout\n        while self.running:\n            with self.lock:\n                if self.queue:\n                    return self.queue.pop(0)\n\n            if time.time() > end_time:\n                return\n\n            self.wait(end_time)\n\n    def notify_all(self):\n        while self.waiters:\n            self.notify()\n\n    def notify(self):\n        if len(self.waiters) == 0:\n            return\n\n        try:\n            end_time, lock = self.waiters.pop(0)\n            lock.release()\n        except:\n            pass\n\n    def wait(self, end_time):\n        with self.lock:\n            lock = threading.Lock()\n            lock.acquire()\n\n            if len(self.waiters) == 0:\n                self.waiters.append((end_time, lock))\n            else:\n                is_max = True\n                for i in range(0, len(self.waiters)):\n                    try:\n                        iend_time, ilock = self.waiters[i]\n                        if iend_time > end_time:\n                            is_max = False\n                            break\n                    except Exception as e:\n                        if i >= len(self.waiters):\n                            break\n                        # xlog.warn(\"get %d from size:%d fail.\", i, len(self.waiters))\n                        continue\n\n                if is_max:\n                    self.waiters.append((end_time, lock))\n                else:\n                    self.waiters.insert(i, (end_time, lock))\n\n            _add_wait()\n\n        lock.acquire()\n"
  },
  {
    "path": "code/default/lib/noarch/six.py",
    "content": "# Copyright (c) 2010-2020 Benjamin Peterson\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in all\n# copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n# SOFTWARE.\n\n\"\"\"Utilities for writing code that runs on Python 2 and 3\"\"\"\n\nfrom __future__ import absolute_import\n\nimport functools\nimport itertools\nimport operator\nimport sys\nimport types\n\n__author__ = \"Benjamin Peterson <benjamin@python.org>\"\n__version__ = \"1.16.0\"\n\n\n# Useful for very coarse version differentiation.\nPY2 = sys.version_info[0] == 2\nPY3 = sys.version_info[0] == 3\nPY34 = sys.version_info[0:2] >= (3, 4)\n\nif PY3:\n    string_types = str,\n    integer_types = int,\n    class_types = type,\n    text_type = str\n    binary_type = bytes\n\n    MAXSIZE = sys.maxsize\nelse:\n    string_types = basestring,\n    integer_types = (int, long)\n    class_types = (type, types.ClassType)\n    text_type = unicode\n    binary_type = str\n\n    if sys.platform.startswith(\"java\"):\n        # Jython always uses 32 bits.\n        MAXSIZE = int((1 << 31) - 1)\n    else:\n        # It's possible to have sizeof(long) != sizeof(Py_ssize_t).\n        class X(object):\n\n            def __len__(self):\n                return 1 << 31\n        try:\n            len(X())\n        except OverflowError:\n            # 32-bit\n            MAXSIZE = int((1 << 31) - 1)\n        else:\n            # 64-bit\n            MAXSIZE = int((1 << 63) - 1)\n        del X\n\nif PY34:\n    from importlib.util import spec_from_loader\nelse:\n    spec_from_loader = None\n\n\ndef _add_doc(func, doc):\n    \"\"\"Add documentation to a function.\"\"\"\n    func.__doc__ = doc\n\n\ndef _import_module(name):\n    \"\"\"Import module, returning the module after the last dot.\"\"\"\n    __import__(name)\n    return sys.modules[name]\n\n\nclass _LazyDescr(object):\n\n    def __init__(self, name):\n        self.name = name\n\n    def __get__(self, obj, tp):\n        result = self._resolve()\n        setattr(obj, self.name, result)  # Invokes __set__.\n        try:\n            # This is a bit ugly, but it avoids running this again by\n            # removing this descriptor.\n            delattr(obj.__class__, self.name)\n        except AttributeError:\n            pass\n        return result\n\n\nclass MovedModule(_LazyDescr):\n\n    def __init__(self, name, old, new=None):\n        super(MovedModule, self).__init__(name)\n        if PY3:\n            if new is None:\n                new = name\n            self.mod = new\n        else:\n            self.mod = old\n\n    def _resolve(self):\n        return _import_module(self.mod)\n\n    def __getattr__(self, attr):\n        _module = self._resolve()\n        value = getattr(_module, attr)\n        setattr(self, attr, value)\n        return value\n\n\nclass _LazyModule(types.ModuleType):\n\n    def __init__(self, name):\n        super(_LazyModule, self).__init__(name)\n        self.__doc__ = self.__class__.__doc__\n\n    def __dir__(self):\n        attrs = [\"__doc__\", \"__name__\"]\n        attrs += [attr.name for attr in self._moved_attributes]\n        return attrs\n\n    # Subclasses should override this\n    _moved_attributes = []\n\n\nclass MovedAttribute(_LazyDescr):\n\n    def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None):\n        super(MovedAttribute, self).__init__(name)\n        if PY3:\n            if new_mod is None:\n                new_mod = name\n            self.mod = new_mod\n            if new_attr is None:\n                if old_attr is None:\n                    new_attr = name\n                else:\n                    new_attr = old_attr\n            self.attr = new_attr\n        else:\n            self.mod = old_mod\n            if old_attr is None:\n                old_attr = name\n            self.attr = old_attr\n\n    def _resolve(self):\n        module = _import_module(self.mod)\n        return getattr(module, self.attr)\n\n\nclass _SixMetaPathImporter(object):\n\n    \"\"\"\n    A meta path importer to import six.moves and its submodules.\n\n    This class implements a PEP302 finder and loader. It should be compatible\n    with Python 2.5 and all existing versions of Python3\n    \"\"\"\n\n    def __init__(self, six_module_name):\n        self.name = six_module_name\n        self.known_modules = {}\n\n    def _add_module(self, mod, *fullnames):\n        for fullname in fullnames:\n            self.known_modules[self.name + \".\" + fullname] = mod\n\n    def _get_module(self, fullname):\n        return self.known_modules[self.name + \".\" + fullname]\n\n    def find_module(self, fullname, path=None):\n        if fullname in self.known_modules:\n            return self\n        return None\n\n    def find_spec(self, fullname, path, target=None):\n        if fullname in self.known_modules:\n            return spec_from_loader(fullname, self)\n        return None\n\n    def __get_module(self, fullname):\n        try:\n            return self.known_modules[fullname]\n        except KeyError:\n            raise ImportError(\"This loader does not know module \" + fullname)\n\n    def load_module(self, fullname):\n        try:\n            # in case of a reload\n            return sys.modules[fullname]\n        except KeyError:\n            pass\n        mod = self.__get_module(fullname)\n        if isinstance(mod, MovedModule):\n            mod = mod._resolve()\n        else:\n            mod.__loader__ = self\n        sys.modules[fullname] = mod\n        return mod\n\n    def is_package(self, fullname):\n        \"\"\"\n        Return true, if the named module is a package.\n\n        We need this method to get correct spec objects with\n        Python 3.4 (see PEP451)\n        \"\"\"\n        return hasattr(self.__get_module(fullname), \"__path__\")\n\n    def get_code(self, fullname):\n        \"\"\"Return None\n\n        Required, if is_package is implemented\"\"\"\n        self.__get_module(fullname)  # eventually raises ImportError\n        return None\n    get_source = get_code  # same as get_code\n\n    def create_module(self, spec):\n        return self.load_module(spec.name)\n\n    def exec_module(self, module):\n        pass\n\n_importer = _SixMetaPathImporter(__name__)\n\n\nclass _MovedItems(_LazyModule):\n\n    \"\"\"Lazy loading of moved objects\"\"\"\n    __path__ = []  # mark as package\n\n\n_moved_attributes = [\n    MovedAttribute(\"cStringIO\", \"cStringIO\", \"io\", \"StringIO\"),\n    MovedAttribute(\"filter\", \"itertools\", \"builtins\", \"ifilter\", \"filter\"),\n    MovedAttribute(\"filterfalse\", \"itertools\", \"itertools\", \"ifilterfalse\", \"filterfalse\"),\n    MovedAttribute(\"input\", \"__builtin__\", \"builtins\", \"raw_input\", \"input\"),\n    MovedAttribute(\"intern\", \"__builtin__\", \"sys\"),\n    MovedAttribute(\"map\", \"itertools\", \"builtins\", \"imap\", \"map\"),\n    MovedAttribute(\"getcwd\", \"os\", \"os\", \"getcwdu\", \"getcwd\"),\n    MovedAttribute(\"getcwdb\", \"os\", \"os\", \"getcwd\", \"getcwdb\"),\n    MovedAttribute(\"getoutput\", \"commands\", \"subprocess\"),\n    MovedAttribute(\"range\", \"__builtin__\", \"builtins\", \"xrange\", \"range\"),\n    MovedAttribute(\"reload_module\", \"__builtin__\", \"importlib\" if PY34 else \"imp\", \"reload\"),\n    MovedAttribute(\"reduce\", \"__builtin__\", \"functools\"),\n    MovedAttribute(\"shlex_quote\", \"pipes\", \"shlex\", \"quote\"),\n    MovedAttribute(\"StringIO\", \"StringIO\", \"io\"),\n    MovedAttribute(\"UserDict\", \"UserDict\", \"collections\"),\n    MovedAttribute(\"UserList\", \"UserList\", \"collections\"),\n    MovedAttribute(\"UserString\", \"UserString\", \"collections\"),\n    MovedAttribute(\"xrange\", \"__builtin__\", \"builtins\", \"xrange\", \"range\"),\n    MovedAttribute(\"zip\", \"itertools\", \"builtins\", \"izip\", \"zip\"),\n    MovedAttribute(\"zip_longest\", \"itertools\", \"itertools\", \"izip_longest\", \"zip_longest\"),\n    MovedModule(\"builtins\", \"__builtin__\"),\n    MovedModule(\"configparser\", \"ConfigParser\"),\n    MovedModule(\"collections_abc\", \"collections\", \"collections.abc\" if sys.version_info >= (3, 3) else \"collections\"),\n    MovedModule(\"copyreg\", \"copy_reg\"),\n    MovedModule(\"dbm_gnu\", \"gdbm\", \"dbm.gnu\"),\n    MovedModule(\"dbm_ndbm\", \"dbm\", \"dbm.ndbm\"),\n    MovedModule(\"_dummy_thread\", \"dummy_thread\", \"_dummy_thread\" if sys.version_info < (3, 9) else \"_thread\"),\n    MovedModule(\"http_cookiejar\", \"cookielib\", \"http.cookiejar\"),\n    MovedModule(\"http_cookies\", \"Cookie\", \"http.cookies\"),\n    MovedModule(\"html_entities\", \"htmlentitydefs\", \"html.entities\"),\n    MovedModule(\"html_parser\", \"HTMLParser\", \"html.parser\"),\n    MovedModule(\"http_client\", \"httplib\", \"http.client\"),\n    MovedModule(\"email_mime_base\", \"email.MIMEBase\", \"email.mime.base\"),\n    MovedModule(\"email_mime_image\", \"email.MIMEImage\", \"email.mime.image\"),\n    MovedModule(\"email_mime_multipart\", \"email.MIMEMultipart\", \"email.mime.multipart\"),\n    MovedModule(\"email_mime_nonmultipart\", \"email.MIMENonMultipart\", \"email.mime.nonmultipart\"),\n    MovedModule(\"email_mime_text\", \"email.MIMEText\", \"email.mime.text\"),\n    MovedModule(\"BaseHTTPServer\", \"BaseHTTPServer\", \"http.server\"),\n    MovedModule(\"CGIHTTPServer\", \"CGIHTTPServer\", \"http.server\"),\n    MovedModule(\"SimpleHTTPServer\", \"SimpleHTTPServer\", \"http.server\"),\n    MovedModule(\"cPickle\", \"cPickle\", \"pickle\"),\n    MovedModule(\"queue\", \"Queue\"),\n    MovedModule(\"reprlib\", \"repr\"),\n    MovedModule(\"socketserver\", \"SocketServer\"),\n    MovedModule(\"_thread\", \"thread\", \"_thread\"),\n    MovedModule(\"tkinter\", \"Tkinter\"),\n    MovedModule(\"tkinter_dialog\", \"Dialog\", \"tkinter.dialog\"),\n    MovedModule(\"tkinter_filedialog\", \"FileDialog\", \"tkinter.filedialog\"),\n    MovedModule(\"tkinter_scrolledtext\", \"ScrolledText\", \"tkinter.scrolledtext\"),\n    MovedModule(\"tkinter_simpledialog\", \"SimpleDialog\", \"tkinter.simpledialog\"),\n    MovedModule(\"tkinter_tix\", \"Tix\", \"tkinter.tix\"),\n    MovedModule(\"tkinter_ttk\", \"ttk\", \"tkinter.ttk\"),\n    MovedModule(\"tkinter_constants\", \"Tkconstants\", \"tkinter.constants\"),\n    MovedModule(\"tkinter_dnd\", \"Tkdnd\", \"tkinter.dnd\"),\n    MovedModule(\"tkinter_colorchooser\", \"tkColorChooser\",\n                \"tkinter.colorchooser\"),\n    MovedModule(\"tkinter_commondialog\", \"tkCommonDialog\",\n                \"tkinter.commondialog\"),\n    MovedModule(\"tkinter_tkfiledialog\", \"tkFileDialog\", \"tkinter.filedialog\"),\n    MovedModule(\"tkinter_font\", \"tkFont\", \"tkinter.font\"),\n    MovedModule(\"tkinter_messagebox\", \"tkMessageBox\", \"tkinter.messagebox\"),\n    MovedModule(\"tkinter_tksimpledialog\", \"tkSimpleDialog\",\n                \"tkinter.simpledialog\"),\n    MovedModule(\"urllib_parse\", __name__ + \".moves.urllib_parse\", \"urllib.parse\"),\n    MovedModule(\"urllib_error\", __name__ + \".moves.urllib_error\", \"urllib.error\"),\n    MovedModule(\"urllib\", __name__ + \".moves.urllib\", __name__ + \".moves.urllib\"),\n    MovedModule(\"urllib_robotparser\", \"robotparser\", \"urllib.robotparser\"),\n    MovedModule(\"xmlrpc_client\", \"xmlrpclib\", \"xmlrpc.client\"),\n    MovedModule(\"xmlrpc_server\", \"SimpleXMLRPCServer\", \"xmlrpc.server\"),\n]\n# Add windows specific modules.\nif sys.platform == \"win32\":\n    _moved_attributes += [\n        MovedModule(\"winreg\", \"_winreg\"),\n    ]\n\nfor attr in _moved_attributes:\n    setattr(_MovedItems, attr.name, attr)\n    if isinstance(attr, MovedModule):\n        _importer._add_module(attr, \"moves.\" + attr.name)\ndel attr\n\n_MovedItems._moved_attributes = _moved_attributes\n\nmoves = _MovedItems(__name__ + \".moves\")\n_importer._add_module(moves, \"moves\")\n\n\nclass Module_six_moves_urllib_parse(_LazyModule):\n\n    \"\"\"Lazy loading of moved objects in six.moves.urllib_parse\"\"\"\n\n\n_urllib_parse_moved_attributes = [\n    MovedAttribute(\"ParseResult\", \"urlparse\", \"urllib.parse\"),\n    MovedAttribute(\"SplitResult\", \"urlparse\", \"urllib.parse\"),\n    MovedAttribute(\"parse_qs\", \"urlparse\", \"urllib.parse\"),\n    MovedAttribute(\"parse_qsl\", \"urlparse\", \"urllib.parse\"),\n    MovedAttribute(\"urldefrag\", \"urlparse\", \"urllib.parse\"),\n    MovedAttribute(\"urljoin\", \"urlparse\", \"urllib.parse\"),\n    MovedAttribute(\"urlparse\", \"urlparse\", \"urllib.parse\"),\n    MovedAttribute(\"urlsplit\", \"urlparse\", \"urllib.parse\"),\n    MovedAttribute(\"urlunparse\", \"urlparse\", \"urllib.parse\"),\n    MovedAttribute(\"urlunsplit\", \"urlparse\", \"urllib.parse\"),\n    MovedAttribute(\"quote\", \"urllib\", \"urllib.parse\"),\n    MovedAttribute(\"quote_plus\", \"urllib\", \"urllib.parse\"),\n    MovedAttribute(\"unquote\", \"urllib\", \"urllib.parse\"),\n    MovedAttribute(\"unquote_plus\", \"urllib\", \"urllib.parse\"),\n    MovedAttribute(\"unquote_to_bytes\", \"urllib\", \"urllib.parse\", \"unquote\", \"unquote_to_bytes\"),\n    MovedAttribute(\"urlencode\", \"urllib\", \"urllib.parse\"),\n    MovedAttribute(\"splitquery\", \"urllib\", \"urllib.parse\"),\n    MovedAttribute(\"splittag\", \"urllib\", \"urllib.parse\"),\n    MovedAttribute(\"splituser\", \"urllib\", \"urllib.parse\"),\n    MovedAttribute(\"splitvalue\", \"urllib\", \"urllib.parse\"),\n    MovedAttribute(\"uses_fragment\", \"urlparse\", \"urllib.parse\"),\n    MovedAttribute(\"uses_netloc\", \"urlparse\", \"urllib.parse\"),\n    MovedAttribute(\"uses_params\", \"urlparse\", \"urllib.parse\"),\n    MovedAttribute(\"uses_query\", \"urlparse\", \"urllib.parse\"),\n    MovedAttribute(\"uses_relative\", \"urlparse\", \"urllib.parse\"),\n]\nfor attr in _urllib_parse_moved_attributes:\n    setattr(Module_six_moves_urllib_parse, attr.name, attr)\ndel attr\n\nModule_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes\n\n_importer._add_module(Module_six_moves_urllib_parse(__name__ + \".moves.urllib_parse\"),\n                      \"moves.urllib_parse\", \"moves.urllib.parse\")\n\n\nclass Module_six_moves_urllib_error(_LazyModule):\n\n    \"\"\"Lazy loading of moved objects in six.moves.urllib_error\"\"\"\n\n\n_urllib_error_moved_attributes = [\n    MovedAttribute(\"URLError\", \"urllib2\", \"urllib.error\"),\n    MovedAttribute(\"HTTPError\", \"urllib2\", \"urllib.error\"),\n    MovedAttribute(\"ContentTooShortError\", \"urllib\", \"urllib.error\"),\n]\nfor attr in _urllib_error_moved_attributes:\n    setattr(Module_six_moves_urllib_error, attr.name, attr)\ndel attr\n\nModule_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes\n\n_importer._add_module(Module_six_moves_urllib_error(__name__ + \".moves.urllib.error\"),\n                      \"moves.urllib_error\", \"moves.urllib.error\")\n\n\nclass Module_six_moves_urllib_request(_LazyModule):\n\n    \"\"\"Lazy loading of moved objects in six.moves.urllib_request\"\"\"\n\n\n_urllib_request_moved_attributes = [\n    MovedAttribute(\"urlopen\", \"urllib2\", \"urllib.request\"),\n    MovedAttribute(\"install_opener\", \"urllib2\", \"urllib.request\"),\n    MovedAttribute(\"build_opener\", \"urllib2\", \"urllib.request\"),\n    MovedAttribute(\"pathname2url\", \"urllib\", \"urllib.request\"),\n    MovedAttribute(\"url2pathname\", \"urllib\", \"urllib.request\"),\n    MovedAttribute(\"getproxies\", \"urllib\", \"urllib.request\"),\n    MovedAttribute(\"Request\", \"urllib2\", \"urllib.request\"),\n    MovedAttribute(\"OpenerDirector\", \"urllib2\", \"urllib.request\"),\n    MovedAttribute(\"HTTPDefaultErrorHandler\", \"urllib2\", \"urllib.request\"),\n    MovedAttribute(\"HTTPRedirectHandler\", \"urllib2\", \"urllib.request\"),\n    MovedAttribute(\"HTTPCookieProcessor\", \"urllib2\", \"urllib.request\"),\n    MovedAttribute(\"ProxyHandler\", \"urllib2\", \"urllib.request\"),\n    MovedAttribute(\"BaseHandler\", \"urllib2\", \"urllib.request\"),\n    MovedAttribute(\"HTTPPasswordMgr\", \"urllib2\", \"urllib.request\"),\n    MovedAttribute(\"HTTPPasswordMgrWithDefaultRealm\", \"urllib2\", \"urllib.request\"),\n    MovedAttribute(\"AbstractBasicAuthHandler\", \"urllib2\", \"urllib.request\"),\n    MovedAttribute(\"HTTPBasicAuthHandler\", \"urllib2\", \"urllib.request\"),\n    MovedAttribute(\"ProxyBasicAuthHandler\", \"urllib2\", \"urllib.request\"),\n    MovedAttribute(\"AbstractDigestAuthHandler\", \"urllib2\", \"urllib.request\"),\n    MovedAttribute(\"HTTPDigestAuthHandler\", \"urllib2\", \"urllib.request\"),\n    MovedAttribute(\"ProxyDigestAuthHandler\", \"urllib2\", \"urllib.request\"),\n    MovedAttribute(\"HTTPHandler\", \"urllib2\", \"urllib.request\"),\n    MovedAttribute(\"HTTPSHandler\", \"urllib2\", \"urllib.request\"),\n    MovedAttribute(\"FileHandler\", \"urllib2\", \"urllib.request\"),\n    MovedAttribute(\"FTPHandler\", \"urllib2\", \"urllib.request\"),\n    MovedAttribute(\"CacheFTPHandler\", \"urllib2\", \"urllib.request\"),\n    MovedAttribute(\"UnknownHandler\", \"urllib2\", \"urllib.request\"),\n    MovedAttribute(\"HTTPErrorProcessor\", \"urllib2\", \"urllib.request\"),\n    MovedAttribute(\"urlretrieve\", \"urllib\", \"urllib.request\"),\n    MovedAttribute(\"urlcleanup\", \"urllib\", \"urllib.request\"),\n    MovedAttribute(\"URLopener\", \"urllib\", \"urllib.request\"),\n    MovedAttribute(\"FancyURLopener\", \"urllib\", \"urllib.request\"),\n    MovedAttribute(\"proxy_bypass\", \"urllib\", \"urllib.request\"),\n    MovedAttribute(\"parse_http_list\", \"urllib2\", \"urllib.request\"),\n    MovedAttribute(\"parse_keqv_list\", \"urllib2\", \"urllib.request\"),\n]\nfor attr in _urllib_request_moved_attributes:\n    setattr(Module_six_moves_urllib_request, attr.name, attr)\ndel attr\n\nModule_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes\n\n_importer._add_module(Module_six_moves_urllib_request(__name__ + \".moves.urllib.request\"),\n                      \"moves.urllib_request\", \"moves.urllib.request\")\n\n\nclass Module_six_moves_urllib_response(_LazyModule):\n\n    \"\"\"Lazy loading of moved objects in six.moves.urllib_response\"\"\"\n\n\n_urllib_response_moved_attributes = [\n    MovedAttribute(\"addbase\", \"urllib\", \"urllib.response\"),\n    MovedAttribute(\"addclosehook\", \"urllib\", \"urllib.response\"),\n    MovedAttribute(\"addinfo\", \"urllib\", \"urllib.response\"),\n    MovedAttribute(\"addinfourl\", \"urllib\", \"urllib.response\"),\n]\nfor attr in _urllib_response_moved_attributes:\n    setattr(Module_six_moves_urllib_response, attr.name, attr)\ndel attr\n\nModule_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes\n\n_importer._add_module(Module_six_moves_urllib_response(__name__ + \".moves.urllib.response\"),\n                      \"moves.urllib_response\", \"moves.urllib.response\")\n\n\nclass Module_six_moves_urllib_robotparser(_LazyModule):\n\n    \"\"\"Lazy loading of moved objects in six.moves.urllib_robotparser\"\"\"\n\n\n_urllib_robotparser_moved_attributes = [\n    MovedAttribute(\"RobotFileParser\", \"robotparser\", \"urllib.robotparser\"),\n]\nfor attr in _urllib_robotparser_moved_attributes:\n    setattr(Module_six_moves_urllib_robotparser, attr.name, attr)\ndel attr\n\nModule_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes\n\n_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + \".moves.urllib.robotparser\"),\n                      \"moves.urllib_robotparser\", \"moves.urllib.robotparser\")\n\n\nclass Module_six_moves_urllib(types.ModuleType):\n\n    \"\"\"Create a six.moves.urllib namespace that resembles the Python 3 namespace\"\"\"\n    __path__ = []  # mark as package\n    parse = _importer._get_module(\"moves.urllib_parse\")\n    error = _importer._get_module(\"moves.urllib_error\")\n    request = _importer._get_module(\"moves.urllib_request\")\n    response = _importer._get_module(\"moves.urllib_response\")\n    robotparser = _importer._get_module(\"moves.urllib_robotparser\")\n\n    def __dir__(self):\n        return ['parse', 'error', 'request', 'response', 'robotparser']\n\n_importer._add_module(Module_six_moves_urllib(__name__ + \".moves.urllib\"),\n                      \"moves.urllib\")\n\n\ndef add_move(move):\n    \"\"\"Add an item to six.moves.\"\"\"\n    setattr(_MovedItems, move.name, move)\n\n\ndef remove_move(name):\n    \"\"\"Remove item from six.moves.\"\"\"\n    try:\n        delattr(_MovedItems, name)\n    except AttributeError:\n        try:\n            del moves.__dict__[name]\n        except KeyError:\n            raise AttributeError(\"no such move, %r\" % (name,))\n\n\nif PY3:\n    _meth_func = \"__func__\"\n    _meth_self = \"__self__\"\n\n    _func_closure = \"__closure__\"\n    _func_code = \"__code__\"\n    _func_defaults = \"__defaults__\"\n    _func_globals = \"__globals__\"\nelse:\n    _meth_func = \"im_func\"\n    _meth_self = \"im_self\"\n\n    _func_closure = \"func_closure\"\n    _func_code = \"func_code\"\n    _func_defaults = \"func_defaults\"\n    _func_globals = \"func_globals\"\n\n\ntry:\n    advance_iterator = next\nexcept NameError:\n    def advance_iterator(it):\n        return it.next()\nnext = advance_iterator\n\n\ntry:\n    callable = callable\nexcept NameError:\n    def callable(obj):\n        return any(\"__call__\" in klass.__dict__ for klass in type(obj).__mro__)\n\n\nif PY3:\n    def get_unbound_function(unbound):\n        return unbound\n\n    create_bound_method = types.MethodType\n\n    def create_unbound_method(func, cls):\n        return func\n\n    Iterator = object\nelse:\n    def get_unbound_function(unbound):\n        return unbound.im_func\n\n    def create_bound_method(func, obj):\n        return types.MethodType(func, obj, obj.__class__)\n\n    def create_unbound_method(func, cls):\n        return types.MethodType(func, None, cls)\n\n    class Iterator(object):\n\n        def next(self):\n            return type(self).__next__(self)\n\n    callable = callable\n_add_doc(get_unbound_function,\n         \"\"\"Get the function out of a possibly unbound function\"\"\")\n\n\nget_method_function = operator.attrgetter(_meth_func)\nget_method_self = operator.attrgetter(_meth_self)\nget_function_closure = operator.attrgetter(_func_closure)\nget_function_code = operator.attrgetter(_func_code)\nget_function_defaults = operator.attrgetter(_func_defaults)\nget_function_globals = operator.attrgetter(_func_globals)\n\n\nif PY3:\n    def iterkeys(d, **kw):\n        return iter(d.keys(**kw))\n\n    def itervalues(d, **kw):\n        return iter(d.values(**kw))\n\n    def iteritems(d, **kw):\n        return iter(d.items(**kw))\n\n    def iterlists(d, **kw):\n        return iter(d.lists(**kw))\n\n    viewkeys = operator.methodcaller(\"keys\")\n\n    viewvalues = operator.methodcaller(\"values\")\n\n    viewitems = operator.methodcaller(\"items\")\nelse:\n    def iterkeys(d, **kw):\n        return d.iterkeys(**kw)\n\n    def itervalues(d, **kw):\n        return d.itervalues(**kw)\n\n    def iteritems(d, **kw):\n        return d.iteritems(**kw)\n\n    def iterlists(d, **kw):\n        return d.iterlists(**kw)\n\n    viewkeys = operator.methodcaller(\"viewkeys\")\n\n    viewvalues = operator.methodcaller(\"viewvalues\")\n\n    viewitems = operator.methodcaller(\"viewitems\")\n\n_add_doc(iterkeys, \"Return an iterator over the keys of a dictionary.\")\n_add_doc(itervalues, \"Return an iterator over the values of a dictionary.\")\n_add_doc(iteritems,\n         \"Return an iterator over the (key, value) pairs of a dictionary.\")\n_add_doc(iterlists,\n         \"Return an iterator over the (key, [values]) pairs of a dictionary.\")\n\n\nif PY3:\n    def b(s):\n        return s.encode(\"latin-1\")\n\n    def u(s):\n        return s\n    unichr = chr\n    import struct\n    int2byte = struct.Struct(\">B\").pack\n    del struct\n    byte2int = operator.itemgetter(0)\n    indexbytes = operator.getitem\n    iterbytes = iter\n    import io\n    StringIO = io.StringIO\n    BytesIO = io.BytesIO\n    del io\n    _assertCountEqual = \"assertCountEqual\"\n    if sys.version_info[1] <= 1:\n        _assertRaisesRegex = \"assertRaisesRegexp\"\n        _assertRegex = \"assertRegexpMatches\"\n        _assertNotRegex = \"assertNotRegexpMatches\"\n    else:\n        _assertRaisesRegex = \"assertRaisesRegex\"\n        _assertRegex = \"assertRegex\"\n        _assertNotRegex = \"assertNotRegex\"\nelse:\n    def b(s):\n        return s\n    # Workaround for standalone backslash\n\n    def u(s):\n        return unicode(s.replace(r'\\\\', r'\\\\\\\\'), \"unicode_escape\")\n    unichr = unichr\n    int2byte = chr\n\n    def byte2int(bs):\n        return ord(bs[0])\n\n    def indexbytes(buf, i):\n        return ord(buf[i])\n    iterbytes = functools.partial(itertools.imap, ord)\n    import StringIO\n    StringIO = BytesIO = StringIO.StringIO\n    _assertCountEqual = \"assertItemsEqual\"\n    _assertRaisesRegex = \"assertRaisesRegexp\"\n    _assertRegex = \"assertRegexpMatches\"\n    _assertNotRegex = \"assertNotRegexpMatches\"\n_add_doc(b, \"\"\"Byte literal\"\"\")\n_add_doc(u, \"\"\"Text literal\"\"\")\n\n\ndef assertCountEqual(self, *args, **kwargs):\n    return getattr(self, _assertCountEqual)(*args, **kwargs)\n\n\ndef assertRaisesRegex(self, *args, **kwargs):\n    return getattr(self, _assertRaisesRegex)(*args, **kwargs)\n\n\ndef assertRegex(self, *args, **kwargs):\n    return getattr(self, _assertRegex)(*args, **kwargs)\n\n\ndef assertNotRegex(self, *args, **kwargs):\n    return getattr(self, _assertNotRegex)(*args, **kwargs)\n\n\nif PY3:\n    exec_ = getattr(moves.builtins, \"exec\")\n\n    def reraise(tp, value, tb=None):\n        try:\n            if value is None:\n                value = tp()\n            if value.__traceback__ is not tb:\n                raise value.with_traceback(tb)\n            raise value\n        finally:\n            value = None\n            tb = None\n\nelse:\n    def exec_(_code_, _globs_=None, _locs_=None):\n        \"\"\"Execute code in a namespace.\"\"\"\n        if _globs_ is None:\n            frame = sys._getframe(1)\n            _globs_ = frame.f_globals\n            if _locs_ is None:\n                _locs_ = frame.f_locals\n            del frame\n        elif _locs_ is None:\n            _locs_ = _globs_\n        exec(\"\"\"exec _code_ in _globs_, _locs_\"\"\")\n\n    exec_(\"\"\"def reraise(tp, value, tb=None):\n    try:\n        raise tp, value, tb\n    finally:\n        tb = None\n\"\"\")\n\n\nif sys.version_info[:2] > (3,):\n    exec_(\"\"\"def raise_from(value, from_value):\n    try:\n        raise value from from_value\n    finally:\n        value = None\n\"\"\")\nelse:\n    def raise_from(value, from_value):\n        raise value\n\n\nprint_ = getattr(moves.builtins, \"print\", None)\nif print_ is None:\n    def print_(*args, **kwargs):\n        \"\"\"The new-style print function for Python 2.4 and 2.5.\"\"\"\n        fp = kwargs.pop(\"file\", sys.stdout)\n        if fp is None:\n            return\n\n        def write(data):\n            if not isinstance(data, basestring):\n                data = str(data)\n            # If the file has an encoding, encode unicode with it.\n            if (isinstance(fp, file) and\n                    isinstance(data, unicode) and\n                    fp.encoding is not None):\n                errors = getattr(fp, \"errors\", None)\n                if errors is None:\n                    errors = \"strict\"\n                data = data.encode(fp.encoding, errors)\n            fp.write(data)\n        want_unicode = False\n        sep = kwargs.pop(\"sep\", None)\n        if sep is not None:\n            if isinstance(sep, unicode):\n                want_unicode = True\n            elif not isinstance(sep, str):\n                raise TypeError(\"sep must be None or a string\")\n        end = kwargs.pop(\"end\", None)\n        if end is not None:\n            if isinstance(end, unicode):\n                want_unicode = True\n            elif not isinstance(end, str):\n                raise TypeError(\"end must be None or a string\")\n        if kwargs:\n            raise TypeError(\"invalid keyword arguments to print()\")\n        if not want_unicode:\n            for arg in args:\n                if isinstance(arg, unicode):\n                    want_unicode = True\n                    break\n        if want_unicode:\n            newline = unicode(\"\\n\")\n            space = unicode(\" \")\n        else:\n            newline = \"\\n\"\n            space = \" \"\n        if sep is None:\n            sep = space\n        if end is None:\n            end = newline\n        for i, arg in enumerate(args):\n            if i:\n                write(sep)\n            write(arg)\n        write(end)\nif sys.version_info[:2] < (3, 3):\n    _print = print_\n\n    def print_(*args, **kwargs):\n        fp = kwargs.get(\"file\", sys.stdout)\n        flush = kwargs.pop(\"flush\", False)\n        _print(*args, **kwargs)\n        if flush and fp is not None:\n            fp.flush()\n\n_add_doc(reraise, \"\"\"Reraise an exception.\"\"\")\n\nif sys.version_info[0:2] < (3, 4):\n    # This does exactly the same what the :func:`py3:functools.update_wrapper`\n    # function does on Python versions after 3.2. It sets the ``__wrapped__``\n    # attribute on ``wrapper`` object and it doesn't raise an error if any of\n    # the attributes mentioned in ``assigned`` and ``updated`` are missing on\n    # ``wrapped`` object.\n    def _update_wrapper(wrapper, wrapped,\n                        assigned=functools.WRAPPER_ASSIGNMENTS,\n                        updated=functools.WRAPPER_UPDATES):\n        for attr in assigned:\n            try:\n                value = getattr(wrapped, attr)\n            except AttributeError:\n                continue\n            else:\n                setattr(wrapper, attr, value)\n        for attr in updated:\n            getattr(wrapper, attr).update(getattr(wrapped, attr, {}))\n        wrapper.__wrapped__ = wrapped\n        return wrapper\n    _update_wrapper.__doc__ = functools.update_wrapper.__doc__\n\n    def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS,\n              updated=functools.WRAPPER_UPDATES):\n        return functools.partial(_update_wrapper, wrapped=wrapped,\n                                 assigned=assigned, updated=updated)\n    wraps.__doc__ = functools.wraps.__doc__\n\nelse:\n    wraps = functools.wraps\n\n\ndef with_metaclass(meta, *bases):\n    \"\"\"Create a base class with a metaclass.\"\"\"\n    # This requires a bit of explanation: the basic idea is to make a dummy\n    # metaclass for one level of class instantiation that replaces itself with\n    # the actual metaclass.\n    class metaclass(type):\n\n        def __new__(cls, name, this_bases, d):\n            if sys.version_info[:2] >= (3, 7):\n                # This version introduced PEP 560 that requires a bit\n                # of extra care (we mimic what is done by __build_class__).\n                resolved_bases = types.resolve_bases(bases)\n                if resolved_bases is not bases:\n                    d['__orig_bases__'] = bases\n            else:\n                resolved_bases = bases\n            return meta(name, resolved_bases, d)\n\n        @classmethod\n        def __prepare__(cls, name, this_bases):\n            return meta.__prepare__(name, bases)\n    return type.__new__(metaclass, 'temporary_class', (), {})\n\n\ndef add_metaclass(metaclass):\n    \"\"\"Class decorator for creating a class with a metaclass.\"\"\"\n    def wrapper(cls):\n        orig_vars = cls.__dict__.copy()\n        slots = orig_vars.get('__slots__')\n        if slots is not None:\n            if isinstance(slots, str):\n                slots = [slots]\n            for slots_var in slots:\n                orig_vars.pop(slots_var)\n        orig_vars.pop('__dict__', None)\n        orig_vars.pop('__weakref__', None)\n        if hasattr(cls, '__qualname__'):\n            orig_vars['__qualname__'] = cls.__qualname__\n        return metaclass(cls.__name__, cls.__bases__, orig_vars)\n    return wrapper\n\n\ndef ensure_binary(s, encoding='utf-8', errors='strict'):\n    \"\"\"Coerce **s** to six.binary_type.\n\n    For Python 2:\n      - `unicode` -> encoded to `str`\n      - `str` -> `str`\n\n    For Python 3:\n      - `str` -> encoded to `bytes`\n      - `bytes` -> `bytes`\n    \"\"\"\n    if isinstance(s, binary_type):\n        return s\n    if isinstance(s, text_type):\n        return s.encode(encoding, errors)\n    raise TypeError(\"not expecting type '%s'\" % type(s))\n\n\ndef ensure_str(s, encoding='utf-8', errors='strict'):\n    \"\"\"Coerce *s* to `str`.\n\n    For Python 2:\n      - `unicode` -> encoded to `str`\n      - `str` -> `str`\n\n    For Python 3:\n      - `str` -> `str`\n      - `bytes` -> decoded to `str`\n    \"\"\"\n    # Optimization: Fast return for the common case.\n    if type(s) is str:\n        return s\n    if PY2 and isinstance(s, text_type):\n        return s.encode(encoding, errors)\n    elif PY3 and isinstance(s, binary_type):\n        return s.decode(encoding, errors)\n    elif not isinstance(s, (text_type, binary_type)):\n        raise TypeError(\"not expecting type '%s'\" % type(s))\n    return s\n\n\ndef ensure_text(s, encoding='utf-8', errors='strict'):\n    \"\"\"Coerce *s* to six.text_type.\n\n    For Python 2:\n      - `unicode` -> `unicode`\n      - `str` -> `unicode`\n\n    For Python 3:\n      - `str` -> `str`\n      - `bytes` -> decoded to `str`\n    \"\"\"\n    if isinstance(s, binary_type):\n        return s.decode(encoding, errors)\n    elif isinstance(s, text_type):\n        return s\n    else:\n        raise TypeError(\"not expecting type '%s'\" % type(s))\n\n\ndef python_2_unicode_compatible(klass):\n    \"\"\"\n    A class decorator that defines __unicode__ and __str__ methods under Python 2.\n    Under Python 3 it does nothing.\n\n    To support Python 2 and 3 with a single code base, define a __str__ method\n    returning text and apply this decorator to the class.\n    \"\"\"\n    if PY2:\n        if '__str__' not in klass.__dict__:\n            raise ValueError(\"@python_2_unicode_compatible cannot be applied \"\n                             \"to %s because it doesn't define __str__().\" %\n                             klass.__name__)\n        klass.__unicode__ = klass.__str__\n        klass.__str__ = lambda self: self.__unicode__().encode('utf-8')\n    return klass\n\n\n# Complete the moves implementation.\n# This code is at the end of this module to speed up module loading.\n# Turn this module into a package.\n__path__ = []  # required for PEP 302 and PEP 451\n__package__ = __name__  # see PEP 366 @ReservedAssignment\nif globals().get(\"__spec__\") is not None:\n    __spec__.submodule_search_locations = []  # PEP 451 @UndefinedVariable\n# Remove other six meta path importers, since they cause problems. This can\n# happen if six is removed from sys.modules and then reloaded. (Setuptools does\n# this for some reason.)\nif sys.meta_path:\n    for i, importer in enumerate(sys.meta_path):\n        # Here's some real nastiness: Another \"instance\" of the six module might\n        # be floating around. Therefore, we can't use isinstance() to check for\n        # the six meta path importer, since the other six instance will have\n        # inserted an importer with different class.\n        if (type(importer).__name__ == \"_SixMetaPathImporter\" and\n                importer.name == __name__):\n            del sys.meta_path[i]\n            break\n    del i, importer\n# Finally, add the importer to the meta path import hook.\nsys.meta_path.append(_importer)\n"
  },
  {
    "path": "code/default/lib/noarch/socks.py",
    "content": "\"\"\"\nSocksiPy - Python SOCKS module.\nVersion 1.5.1\n\nCopyright 2006 Dan-Haim. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without modification,\nare permitted provided that the following conditions are met:\n1. Redistributions of source code must retain the above copyright notice, this\n   list of conditions and the following disclaimer.\n2. Redistributions in binary form must reproduce the above copyright notice,\n   this list of conditions and the following disclaimer in the documentation\n   and/or other materials provided with the distribution.\n3. Neither the name of Dan Haim nor the names of his contributors may be used\n   to endorse or promote products derived from this software without specific\n   prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY DAN HAIM \"AS IS\" AND ANY EXPRESS OR IMPLIED\nWARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO\nEVENT SHALL DAN HAIM OR HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\nINCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA\nOR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\nLIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\nOF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMANGE.\n\n\nThis module provides a standard socket-like interface for Python\nfor tunneling connections through SOCKS proxies.\n\n===============================================================================\n\nMinor modifications made by Christopher Gilbert (http://motomastyle.com/)\nfor use in PyLoris (http://pyloris.sourceforge.net/)\n\nMinor modifications made by Mario Vilas (http://breakingcode.wordpress.com/)\nmainly to merge bug fixes found in Sourceforge\n\nModifications made by Anorov (https://github.com/Anorov)\n-Forked and renamed to PySocks\n-Fixed issue with HTTP proxy failure checking (same bug that was in the old ___recvall() method)\n-Included SocksiPyHandler (sockshandler.py), to be used as a urllib2 handler,\n courtesy of e000 (https://github.com/e000): https://gist.github.com/869791#file_socksipyhandler.py\n-Re-styled code to make it readable\n    -Aliased PROXY_TYPE_SOCKS5 -> SOCKS5 etc.\n    -Improved exception handling and output\n    -Removed irritating use of sequence indexes, replaced with tuple unpacked variables\n    -Fixed up Python 3 bytestring handling - chr(0x03).encode() -> b\"\\x03\"\n    -Other general fixes\n-Added clarification that the HTTP proxy connection method only supports CONNECT-style tunneling HTTP proxies\n-Various small bug fixes\n\"\"\"\n\n__version__ = \"1.5.1\"\n\nimport os, sys\nfrom base64 import b64encode\nimport socket\nimport struct\nfrom errno import EOPNOTSUPP, EINVAL, EAGAIN\nfrom io import BytesIO, SEEK_CUR\ntry:\n    from collections import Callable\nexcept:\n    from collections.abc import Callable\n\nfrom six import string_types\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\npython_path = os.path.abspath( os.path.join(current_path, os.pardir, os.pardir))\nif sys.platform == \"win32\":\n    win32_lib = os.path.abspath( os.path.join(python_path, 'lib', 'win32'))\n    sys.path.append(win32_lib)\n    import win_inet_pton\n    inet_pton = win_inet_pton.inet_pton\n    inet_ntop = win_inet_pton.inet_ntop\nelse:\n    inet_pton = socket.inet_pton\n    inet_ntop = socket.inet_ntop\n\nimport utils\n\nPROXY_TYPE_SOCKS4 = SOCKS4 = 1\nPROXY_TYPE_SOCKS5 = SOCKS5 = 2\nPROXY_TYPE_HTTP = HTTP = 3\n\nPRINTABLE_PROXY_TYPES = {SOCKS4: \"SOCKS4\", SOCKS5: \"SOCKS5\", HTTP: \"HTTP\"}\n\n_orgsocket = _orig_socket = socket.socket\n\n\nclass ProxyError(IOError):\n    \"\"\"\n    socket_err contains original socket.error exception.\n    \"\"\"\n    def __init__(self, msg, socket_err=None):\n        self.msg = msg\n        self.socket_err = socket_err\n\n        if socket_err:\n            self.msg += \": {0}\".format(socket_err)\n\n    def __str__(self):\n        return self.msg\n\n    def __repr__(self):\n        # for %r\n        return repr(self.msg)\n\n\nclass GeneralProxyError(ProxyError): pass\nclass ProxyConnectionError(ProxyError): pass\nclass SOCKS5AuthError(ProxyError): pass\nclass SOCKS5Error(ProxyError): pass\nclass SOCKS4Error(ProxyError): pass\nclass HTTPError(ProxyError): pass\n\n\nSOCKS4_ERRORS = { 0x5B: \"Request rejected or failed\",\n                  0x5C: \"Request rejected because SOCKS server cannot connect to identd on the client\",\n                  0x5D: \"Request rejected because the client program and identd report different user-ids\"\n                }\n\nSOCKS5_ERRORS = { 0x01: \"General SOCKS server failure\",\n                  0x02: \"Connection not allowed by ruleset\",\n                  0x03: \"Network unreachable\",\n                  0x04: \"Host unreachable\",\n                  0x05: \"Connection refused\",\n                  0x06: \"TTL expired\",\n                  0x07: \"Command not supported, or protocol error\",\n                  0x08: \"Address type not supported\"\n                }\n\nDEFAULT_PORTS = { SOCKS4: 1080,\n                  SOCKS5: 1080,\n                  HTTP: 8080\n                }\n\n\ndef set_default_proxy(proxy_type=None, addr=None, port=None, rdns=True, username=None, password=None):\n    \"\"\"\n    set_default_proxy(proxy_type, addr[, port[, rdns[, username, password]]])\n\n    Sets a default proxy which all further socksocket objects will use,\n    unless explicitly changed. All parameters are as for socket.set_proxy().\n    \"\"\"\n    proxy_type = utils.bytes2str_only(proxy_type)\n    addr = utils.to_str(addr)\n    if isinstance(port, bytes):\n        port = int(utils.to_str(port))\n    else:\n        port = int(port)\n    username = utils.to_bytes(username)\n    password = utils.to_bytes(password)\n\n    if isinstance(proxy_type, str):\n        proxy_type = proxy_type.lower()\n        if \"http\" in proxy_type:\n            proxy_type = PROXY_TYPE_HTTP\n        elif \"socks5\" in proxy_type:\n            proxy_type = PROXY_TYPE_SOCKS5\n        elif \"socks4\" in proxy_type:\n            proxy_type = PROXY_TYPE_SOCKS4\n        else:\n            raise ProxyError(\"unknown proxy type:%s\" % proxy_type)\n\n    socksocket.default_proxy = (proxy_type, addr, port, rdns,\n                                username if username else None,\n                                password if password else None)\n\n\nsetdefaultproxy = set_default_proxy\n\n\ndef get_default_proxy():\n    \"\"\"\n    Returns the default proxy, set by set_default_proxy.\n    \"\"\"\n    return socksocket.default_proxy\n\n\ngetdefaultproxy = get_default_proxy\n\n\ndef wrap_module(module):\n    \"\"\"\n    Attempts to replace a module's socket library with a SOCKS socket. Must set\n    a default proxy using set_default_proxy(...) first.\n    This will only work on modules that import socket directly into the namespace;\n    most of the Python Standard Library falls into this category.\n    \"\"\"\n    if socksocket.default_proxy:\n        module.socket.socket = socksocket\n    else:\n        raise GeneralProxyError(\"No default proxy specified\")\n\nwrapmodule = wrap_module\n\n\ndef create_connection(dest_pair, proxy_type=None, proxy_addr=None,\n                      proxy_port=None, proxy_username=None,\n                      proxy_password=None, timeout=None):\n    \"\"\"create_connection(dest_pair, *[, timeout], **proxy_args) -> socket object\n\n    Like socket.create_connection(), but connects to proxy\n    before returning the socket object.\n\n    dest_pair - 2-tuple of (IP/hostname, port).\n    **proxy_args - Same args passed to socksocket.set_proxy().\n    timeout - Optional socket timeout value, in seconds.\n    \"\"\"\n    sock = socksocket()\n    if isinstance(timeout, (int, float)):\n        sock.settimeout(timeout)\n    sock.set_proxy(proxy_type, proxy_addr, proxy_port,\n                   proxy_username, proxy_password)\n    sock.connect(dest_pair)\n    return sock\n\n\nclass _BaseSocket(socket.socket):\n    \"\"\"Allows Python 2's \"delegated\" methods such as send() to be overridden\n    \"\"\"\n    def __init__(self, *pos, **kw):\n        _orig_socket.__init__(self, *pos, **kw)\n\n        self._savedmethods = dict()\n        for name in self._savenames:\n            self._savedmethods[name] = getattr(self, name)\n            delattr(self, name)  # Allows normal overriding mechanism to work\n\n    _savenames = list()\n\n\ndef _makemethod(name):\n    return lambda self, *pos, **kw: self._savedmethods[name](*pos, **kw)\n\n\nfor name in (\"sendto\", \"send\", \"recvfrom\", \"recv\"):\n    method = getattr(_BaseSocket, name, None)\n\n    # Determine if the method is not defined the usual way\n    # as a function in the class.\n    # Python 2 uses __slots__, so there are descriptors for each method,\n    # but they are not functions.\n    if not isinstance(method, Callable):\n        _BaseSocket._savenames.append(name)\n        setattr(_BaseSocket, name, _makemethod(name))\n\n\nclass socksocket(_BaseSocket):\n    \"\"\"socksocket([family[, type[, proto]]]) -> socket object\n\n    Open a SOCKS enabled socket. The parameters are the same as\n    those of the standard socket init. In order for SOCKS to work,\n    you must specify family=AF_INET and proto=0.\n    The \"type\" argument must be either SOCK_STREAM or SOCK_DGRAM.\n    \"\"\"\n\n    default_proxy = None\n\n    def __init__(self, family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0, _sock=None):\n        if type not in {socket.SOCK_STREAM, socket.SOCK_DGRAM}:\n            msg = \"Socket type must be stream or datagram, not {!r}\"\n            raise ValueError(msg.format(type))\n\n        self._proxyconn = None  # TCP connection to keep UDP relay alive\n        self.resolve_dest = True\n\n        if self.default_proxy:\n            self.proxy = self.default_proxy\n            proxy_host = self.proxy[1]\n            if utils.check_ip_valid6(proxy_host):\n                family=socket.AF_INET6\n            elif utils.check_ip_valid4(proxy_host):\n                family=socket.AF_INET\n\n        else:\n            self.proxy = (None, None, None, None, None, None)\n\n        _BaseSocket.__init__(self, family, type, proto, _sock)\n\n        self.proxy_sockname = None\n        self.proxy_peername = None\n\n    def _readall(self, file, count):\n        \"\"\"\n        Receive EXACTLY the number of bytes requested from the file object.\n        Blocks until the required number of bytes have been received.\n        \"\"\"\n        data = b\"\"\n        while len(data) < count:\n            d = file.read(count - len(data))\n            if not d:\n                raise GeneralProxyError(\"Connection closed unexpectedly\")\n            data += d\n        return data\n\n    def set_proxy(self, proxy_type=None, addr=None, port=None, rdns=True, username=None, password=None):\n        \"\"\"set_proxy(proxy_type, addr[, port[, rdns[, username[, password]]]])\n        Sets the proxy to be used.\n\n        proxy_type -    The type of the proxy to be used. Three types\n                        are supported: PROXY_TYPE_SOCKS4 (including socks4a),\n                        PROXY_TYPE_SOCKS5 and PROXY_TYPE_HTTP\n        addr -        The address of the server (IP or DNS).\n        port -        The port of the server. Defaults to 1080 for SOCKS\n                       servers and 8080 for HTTP proxy servers.\n        rdns -        Should DNS queries be performed on the remote side\n                       (rather than the local side). The default is True.\n                       Note: This has no effect with SOCKS4 servers.\n        username -    Username to authenticate with to the server.\n                       The default is no authentication.\n        password -    Password to authenticate with to the server.\n                       Only relevant when username is also provided.\n        \"\"\"\n\n        proxy_type = utils.bytes2str_only(proxy_type)\n        addr = utils.to_str(addr)\n        if isinstance(port, bytes):\n            port = int(utils.to_str(port))\n        else:\n            port = int(port)\n        username = utils.to_bytes(username)\n        password = utils.to_bytes(password)\n\n        if isinstance(proxy_type, string_types):\n            proxy_type = proxy_type.lower()\n            if \"http\" in proxy_type:\n                proxy_type = PROXY_TYPE_HTTP\n                self.resolve_dest = False\n            elif \"socks5\" in proxy_type:\n                if proxy_type == \"socks5h\":\n                    self.resolve_dest = False\n                    rdns = True\n                proxy_type = PROXY_TYPE_SOCKS5\n            elif \"socks4\" in proxy_type:\n                proxy_type = PROXY_TYPE_SOCKS4\n            else:\n                raise ProxyError(\"unknown proxy type:%s\" % proxy_type)\n\n        self.proxy = (proxy_type, addr, port, rdns,\n                      username if username else None,\n                      password if password else None)\n\n    setproxy = set_proxy\n\n    def bind(self, *pos, **kw):\n        \"\"\"\n        Implements proxy connection for UDP sockets,\n        which happens during the bind() phase.\n        \"\"\"\n        proxy_type, proxy_addr, proxy_port, rdns, username, password = self.proxy\n        if not proxy_type or self.type != socket.SOCK_DGRAM:\n            return _orig_socket.bind(self, *pos, **kw)\n\n        if self._proxyconn:\n            raise socket.error(EINVAL, \"Socket already bound to an address\")\n        if proxy_type != SOCKS5:\n            msg = \"UDP only supported by SOCKS5 proxy type\"\n            raise socket.error(EOPNOTSUPP, msg)\n        _BaseSocket.bind(self, *pos, **kw)\n\n        # Need to specify actual local port because\n        # some relays drop packets if a port of zero is specified.\n        # Avoid specifying host address in case of NAT though.\n        _, port = self.getsockname()\n        dst = (\"0\", port)\n\n        self._proxyconn = _orig_socket()\n        proxy = self._proxy_addr()\n        self._proxyconn.connect(proxy)\n\n        UDP_ASSOCIATE = b\"\\x03\"\n        _, relay = self._SOCKS5_request(self._proxyconn, UDP_ASSOCIATE, dst)\n\n        # The relay is most likely on the same host as the SOCKS proxy,\n        # but some proxies return a private IP address (10.x.y.z)\n        host, _ = proxy\n        _, port = relay\n        _BaseSocket.connect(self, (host, port))\n        self.proxy_sockname = (\"0.0.0.0\", 0)  # Unknown\n\n    def sendto(self, bytes, *args, **kwargs):\n        if self.type != socket.SOCK_DGRAM:\n            return _BaseSocket.sendto(self, bytes, *args, **kwargs)\n        if not self._proxyconn:\n            self.bind((\"\", 0))\n\n        address = args[-1]\n        flags = args[:-1]\n\n        header = BytesIO()\n        RSV = b\"\\x00\\x00\"\n        header.write(RSV)\n        STANDALONE = b\"\\x00\"\n        header.write(STANDALONE)\n        self._write_SOCKS5_address(address, header)\n\n        sent = _BaseSocket.send(self, header.getvalue() + bytes, *flags, **kwargs)\n        return sent - header.tell()\n\n    def send(self, bytes, flags=0, **kwargs):\n        if self.type == socket.SOCK_DGRAM:\n            return self.sendto(bytes, flags, self.proxy_peername, **kwargs)\n        else:\n            return _BaseSocket.send(self, bytes, flags, **kwargs)\n\n    def recvfrom(self, bufsize, flags=0):\n        if self.type != socket.SOCK_DGRAM:\n            return _BaseSocket.recvfrom(self, bufsize, flags)\n        if not self._proxyconn:\n            self.bind((\"\", 0))\n\n        buf = BytesIO(_BaseSocket.recv(self, bufsize, flags))\n        buf.seek(+2, SEEK_CUR)\n        frag = buf.read(1)\n        if ord(frag):\n            raise NotImplementedError(\"Received UDP packet fragment\")\n        fromhost, fromport = self._read_SOCKS5_address(buf)\n\n        if self.proxy_peername:\n            peerhost, peerport = self.proxy_peername\n            if fromhost != peerhost or peerport not in (0, fromport):\n                raise socket.error(EAGAIN, \"Packet filtered\")\n\n        return (buf.read(), (fromhost, fromport))\n\n    def recv(self, *pos, **kw):\n        bytes, _ = self.recvfrom(*pos, **kw)\n        return bytes\n\n    def close(self):\n        if self._proxyconn:\n            self._proxyconn.close()\n        return _BaseSocket.close(self)\n\n    def get_proxy_sockname(self):\n        \"\"\"\n        Returns the bound IP address and port number at the proxy.\n        \"\"\"\n        return self.proxy_sockname\n\n    getproxysockname = get_proxy_sockname\n\n    def get_proxy_peername(self):\n        \"\"\"\n        Returns the IP and port number of the proxy.\n        \"\"\"\n        return _BaseSocket.getpeername(self)\n\n    getproxypeername = get_proxy_peername\n\n    def get_peername(self):\n        \"\"\"\n        Returns the IP address and port number of the destination\n        machine (note: get_proxy_peername returns the proxy)\n        \"\"\"\n        return self.proxy_peername\n\n    getpeername = get_peername\n\n    def _negotiate_SOCKS5(self, *dest_addr):\n        \"\"\"\n        Negotiates a stream connection through a SOCKS5 server.\n        \"\"\"\n        CONNECT = b\"\\x01\"\n        self.proxy_peername, self.proxy_sockname = self._SOCKS5_request(self,\n            CONNECT, dest_addr)\n\n    def _SOCKS5_request(self, conn, cmd, dst):\n        \"\"\"\n        Send SOCKS5 request with given command (CMD field) and\n        address (DST field). Returns resolved DST address that was used.\n        \"\"\"\n        proxy_type, addr, port, rdns, username, password = self.proxy\n\n        writer = conn.makefile(\"wb\")\n        reader = conn.makefile(\"rb\", 0)  # buffering=0 renamed in Python 3\n        try:\n            # First we'll send the authentication packages we support.\n            if username and password:\n                # The username/password details were supplied to the\n                # set_proxy method so we support the USERNAME/PASSWORD\n                # authentication (in addition to the standard none).\n                writer.write(b\"\\x05\\x02\\x00\\x02\")\n            else:\n                # No username/password were entered, therefore we\n                # only support connections with no authentication.\n                writer.write(b\"\\x05\\x01\\x00\")\n\n            # We'll receive the server's response to determine which\n            # method was selected\n            writer.flush()\n            chosen_auth = self._readall(reader, 2)\n\n            if chosen_auth[0:1] != b\"\\x05\":\n                # Note: string[i:i+1] is used because indexing of a bytestring\n                # via bytestring[i] yields an integer in Python 3\n                raise GeneralProxyError(\"SOCKS5 proxy server sent invalid data\")\n\n            # Check the chosen authentication method\n\n            if chosen_auth[1:2] == b\"\\x02\":\n                # Okay, we need to perform a basic username/password\n                # authentication.\n                writer.write(b\"\\x01\" + chr(len(username)).encode()\n                             + username\n                             + chr(len(password)).encode()\n                             + password)\n                writer.flush()\n                auth_status = self._readall(reader, 2)\n                if auth_status[0:1] != b\"\\x01\":\n                    # Bad response\n                    raise GeneralProxyError(\"SOCKS5 proxy server sent invalid data\")\n                if auth_status[1:2] != b\"\\x00\":\n                    # Authentication failed\n                    raise SOCKS5AuthError(\"SOCKS5 authentication failed\")\n\n                # Otherwise, authentication succeeded\n\n            # No authentication is required if 0x00\n            elif chosen_auth[1:2] != b\"\\x00\":\n                # Reaching here is always bad\n                if chosen_auth[1:2] == b\"\\xFF\":\n                    raise SOCKS5AuthError(\"All offered SOCKS5 authentication methods were rejected\")\n                else:\n                    raise GeneralProxyError(\"SOCKS5 proxy server sent invalid data\")\n\n            # Now we can request the actual connection\n            writer.write(b\"\\x05\" + cmd + b\"\\x00\")\n            resolved = self._write_SOCKS5_address(dst, writer)\n            writer.flush()\n\n            # Get the response\n            resp = self._readall(reader, 3)\n            if resp[0:1] != b\"\\x05\":\n                raise GeneralProxyError(\"SOCKS5 proxy server sent invalid data\")\n\n            status = ord(resp[1:2])\n            if status != 0x00:\n                # Connection failed: server returned an error\n                error = SOCKS5_ERRORS.get(status, \"Unknown error\")\n                raise SOCKS5Error(\"{0:#04x}: {1}\".format(status, error))\n\n            # Get the bound address/port\n            bnd = self._read_SOCKS5_address(reader)\n            return (resolved, bnd)\n        finally:\n            reader.close()\n            writer.close()\n\n    def _write_SOCKS5_address(self, addr, file):\n        \"\"\"\n        Return the host and port packed for the SOCKS5 protocol,\n        and the resolved address as a tuple object.\n        \"\"\"\n        host, port = addr\n        host = utils.to_str(host)\n        proxy_type, _, _, rdns, username, password = self.proxy\n\n        if utils.check_ip_valid6(host):\n            addr_bytes = inet_pton(socket.AF_INET6, host)\n            file.write(b\"\\x04\" + addr_bytes)\n        elif utils.check_ip_valid4(host):\n            addr_bytes = socket.inet_aton(host)\n            file.write(b\"\\x01\" + addr_bytes)\n        else:\n            if rdns:\n                # Resolve remotely\n                host_bytes = host.encode(\"utf-8\")\n                file.write(b\"\\x03\" + chr(len(host_bytes)).encode() + host_bytes)\n            else:\n                # Resolve locally\n                addr_bytes = socket.inet_aton(socket.gethostbyname(host))\n                file.write(b\"\\x01\" + addr_bytes)\n                host = socket.inet_ntoa(addr_bytes)\n\n        file.write(struct.pack(\">H\", port))\n        return host, port\n\n    def _read_SOCKS5_address(self, file):\n        atyp = self._readall(file, 1)\n        if atyp == b\"\\x01\":\n            addr = socket.inet_ntoa(self._readall(file, 4))\n        elif atyp == b\"\\x03\":\n            length = self._readall(file, 1)\n            addr = self._readall(file, ord(length))\n        elif atyp == b\"\\x04\":\n            addr = inet_ntop(socket.AF_INET6, self._readall(file, 16))\n        else:\n            raise GeneralProxyError(\"SOCKS5 proxy server sent invalid data\")\n\n        port = struct.unpack(\">H\", self._readall(file, 2))[0]\n        return addr, port\n\n    def _negotiate_SOCKS4(self, dest_addr, dest_port):\n        \"\"\"\n        Negotiates a connection through a SOCKS4 server.\n        \"\"\"\n        proxy_type, addr, port, rdns, username, password = self.proxy\n        dest_addr = utils.to_str(dest_addr)\n\n        writer = self.makefile(\"wb\")\n        reader = self.makefile(\"rb\", 0)  # buffering=0 renamed in Python 3\n        try:\n            # Check if the destination address provided is an IP address\n            remote_resolve = False\n            try:\n                addr_bytes = socket.inet_aton(dest_addr)\n            except socket.error as e:\n                # It's a DNS name. Check where it should be resolved.\n                if rdns:\n                    addr_bytes = b\"\\x00\\x00\\x00\\x01\"\n                    remote_resolve = True\n                else:\n                    addr_bytes = socket.inet_aton(socket.gethostbyname(dest_addr))\n\n            # Construct the request packet\n            writer.write(struct.pack(\">BBH\", 0x04, 0x01, dest_port))\n            writer.write(addr_bytes)\n\n            # The username parameter is considered userid for SOCKS4\n            if username:\n                writer.write(username)\n            writer.write(b\"\\x00\")\n\n            # DNS name if remote resolving is required\n            # NOTE: This is actually an extension to the SOCKS4 protocol\n            # called SOCKS4A and may not be supported in all cases.\n            if remote_resolve:\n                writer.write(dest_addr.encode('utf-8') + b\"\\x00\")\n            writer.flush()\n\n            # Get the response from the server\n            resp = self._readall(reader, 8)\n            if resp[0:1] != b\"\\x00\":\n                # Bad data\n                raise GeneralProxyError(\"SOCKS4 proxy server sent invalid data\")\n\n            status = ord(resp[1:2])\n            if status != 0x5A:\n                # Connection failed: server returned an error\n                error = SOCKS4_ERRORS.get(status, \"Unknown error\")\n                raise SOCKS4Error(\"{0:#04x}: {1}\".format(status, error))\n\n            # Get the bound address/port\n            self.proxy_sockname = (socket.inet_ntoa(resp[4:]), struct.unpack(\">H\", resp[2:4])[0])\n            if remote_resolve:\n                self.proxy_peername = socket.inet_ntoa(addr_bytes), dest_port\n            else:\n                self.proxy_peername = dest_addr, dest_port\n        finally:\n            reader.close()\n            writer.close()\n\n    def _negotiate_HTTP(self, dest_host, dest_port):\n        \"\"\"\n        Negotiates a connection through an HTTP server.\n        NOTE: This currently only supports HTTP CONNECT-style proxies.\n        \"\"\"\n        proxy_type, proxy_addr, port, rdns, username, password = self.proxy\n\n        # If we need to resolve locally, we do this now\n        dest_host = utils.to_bytes(dest_host)\n        if b\":\" not in dest_host and not rdns:\n            dest_addr = socket.gethostbyname(dest_host)\n            dest_addr = utils.to_bytes(dest_addr)\n        else:\n            dest_addr = dest_host\n\n        http_headers = [\n            (b\"CONNECT \" + utils.to_bytes(dest_addr) + b\":\"\n             + str(dest_port).encode() + b\" HTTP/1.1\"),\n            b\"Host: \" + dest_addr\n        ]\n\n        if username and password:\n            http_headers.append(b\"Proxy-Authorization: basic \"\n                                + b64encode(username + b\":\" + password))\n\n        http_headers.append(b\"\\r\\n\")\n\n        self.sendall(b\"\\r\\n\".join(http_headers))\n\n        # We just need the first line to check if the connection was successful\n        fobj = self.makefile(\"rb\")\n        status_line = fobj.readline()\n        fobj.close()\n\n        if not status_line:\n            raise GeneralProxyError(\"Connection closed unexpectedly\")\n\n        try:\n            proto, status_code, status_msg = status_line.split(b\" \", 2)\n        except ValueError:\n            raise GeneralProxyError(\"HTTP proxy server sent invalid response\")\n\n        if not proto.startswith(b\"HTTP/\"):\n            raise GeneralProxyError(\"Proxy server does not appear to be an HTTP proxy\")\n\n        try:\n            status_code = int(status_code)\n        except ValueError:\n            raise HTTPError(\"HTTP proxy server did not return a valid HTTP status\")\n\n        if status_code != 200:\n            error = \"{0}: {1}\".format(status_code, status_msg)\n            if status_code in (400, 403, 405):\n                # It's likely that the HTTP proxy server does not support the CONNECT tunneling method\n                error += (\"\\n[*] Note: The HTTP proxy server may not be supported by PySocks\"\n                          \" (must be a CONNECT tunnel proxy)\")\n            raise HTTPError(error)\n\n        self.proxy_sockname = (b\"0.0.0.0\", 0)\n        self.proxy_peername = dest_addr, dest_port\n\n    _proxy_negotiators = {\n                           SOCKS4: _negotiate_SOCKS4,\n                           SOCKS5: _negotiate_SOCKS5,\n                           HTTP: _negotiate_HTTP\n                         }\n\n    def connect(self, dest_pair):\n        \"\"\"\n        Connects to the specified destination through a proxy.\n        Uses the same API as socket's connect().\n        To select the proxy server, use set_proxy().\n\n        dest_pair\n        \"\"\"\n        if len(dest_pair) == 2:\n            # IPv4\n            dest_addr, dest_port = dest_pair\n        elif len(dest_pair) == 4:\n            # IPv6\n            dest_addr, dest_port, st_zero, st_stream  = dest_pair\n        else:\n            raise GeneralProxyError(\"Invalid destination-connection (host, port) pair\")\n\n        if self.type == socket.SOCK_DGRAM:\n            if not self._proxyconn:\n                self.bind((\"\", 0))\n            if self.resolve_dest:\n                dest_addr = socket.gethostbyname(dest_addr)\n\n            # If the host address is INADDR_ANY or similar, reset the peer\n            # address so that packets are received from any peer\n            if dest_addr == \"0.0.0.0\" and not dest_port:\n                self.proxy_peername = None\n            else:\n                self.proxy_peername = (dest_addr, dest_port)\n            return\n\n        proxy_type, proxy_host, proxy_port, rdns, username, password = self.proxy\n        proxy_host = utils.to_bytes(proxy_host)\n\n        # Do a minimal input check first\n        if not dest_addr or not isinstance(dest_port, int):\n            raise GeneralProxyError(\"Invalid destination-connection (host, port) pair\")\n\n        if proxy_type is None:\n            # Treat like regular socket object\n            _BaseSocket.connect(self, (dest_addr, dest_port))\n            return\n\n        proxy_port = proxy_port or DEFAULT_PORTS.get(proxy_type)\n        if not proxy_port:\n            raise GeneralProxyError(\"Invalid proxy port\")\n\n        try:\n            # Initial connection to proxy server\n            proxy_ip = socket.gethostbyname(proxy_host)\n            _BaseSocket.connect(self, (proxy_ip, proxy_port))\n        except socket.error as error:\n            # Error while connecting to proxy\n            self.close()\n            proxy_server = \"{0}:{1}\".format(proxy_host, proxy_port)\n            printable_type = PRINTABLE_PROXY_TYPES[proxy_type]\n\n            msg = \"Error connecting to {0} proxy {1}\".format(printable_type,\n                                                           proxy_server)\n            raise ProxyConnectionError(msg, error)\n\n        else:\n            # Connected to proxy server, now negotiate\n            try:\n                # Calls negotiate_{SOCKS4, SOCKS5, HTTP}\n                negotiate = self._proxy_negotiators[proxy_type]\n                negotiate(self, dest_addr, dest_port)\n            except socket.error as error:\n                # Wrap socket errors\n                self.close()\n                raise GeneralProxyError(\"Socket error\", error)\n            except ProxyError:\n                # Protocol error while negotiating with proxy\n                self.close()\n                raise\n\n\nif __name__ == \"__main__\":\n    name = \"abc\"\n    name2 = name.encode('idna')\n    print(name2)"
  },
  {
    "path": "code/default/lib/noarch/sortedcontainers/__init__.py",
    "content": "# -*- coding: utf-8 -*-\n\n\"\"\"\nsortedcontainers Sorted Container Types Library\n===============================================\n\nSortedContainers is an Apache2 licensed containers library, written in\npure-Python, and fast as C-extensions.\n\nPython's standard library is great until you need a sorted container type. Many\nwill attest that you can get really far without one, but the moment you\n**really need** a sorted list, dict, or set, you're faced with a dozen\ndifferent implementations, most using C-extensions without great documentation\nand benchmarking.\n\nThings shouldn't be this way. Not in Python.\n\n::\n\n    >>> from sortedcontainers import SortedList, SortedDict, SortedSet\n    >>> sl = SortedList(xrange(10000000))\n    >>> 1234567 in sl\n    True\n    >>> sl[7654321]\n    7654321\n    >>> sl.add(1234567)\n    >>> sl.count(1234567)\n    2\n    >>> sl *= 3\n    >>> len(sl)\n    30000003\n\nSortedContainers takes all of the work out of Python sorted types - making your\ndeployment and use of Python easy. There's no need to install a C compiler or\npre-build and distribute custom extensions. Performance is a feature and\ntesting has 100% coverage with unit tests and hours of stress.\n\n:copyright: (c) 2014 by Grant Jenks.\n:license: Apache 2.0, see LICENSE for more details.\n\n\"\"\"\n\n__title__ = 'sortedcontainers'\n__version__ = '0.9.4'\n__build__ = 0x000904\n__author__ = 'Grant Jenks'\n__license__ = 'Apache 2.0'\n__copyright__ = 'Copyright 2014 Grant Jenks'\n\nfrom .sortedlist import SortedList\nfrom .sortedset import SortedSet\nfrom .sorteddict import SortedDict\nfrom .sortedlistwithkey import SortedListWithKey\n\n__all__ = ['SortedList', 'SortedSet', 'SortedDict', 'SortedListWithKey']\n"
  },
  {
    "path": "code/default/lib/noarch/sortedcontainers/sorteddict.py",
    "content": "# -*- coding: utf-8 -*-\n#\n# Sorted dict implementation.\n\nfrom .sortedset import SortedSet\nfrom .sortedlist import SortedList, recursive_repr\nfrom .sortedlistwithkey import SortedListWithKey\nfrom collections import Set, Sequence\nfrom collections import KeysView as AbstractKeysView\nfrom collections import ValuesView as AbstractValuesView\nfrom collections import ItemsView as AbstractItemsView\n\nfrom functools import wraps\nfrom sys import hexversion\n\n_NotGiven = object()\n\n\ndef not26(func):\n    \"\"\"Function decorator for methods not implemented in Python 2.6.\"\"\"\n\n    @wraps(func)\n    def errfunc(*args, **kwargs):\n        raise NotImplementedError\n\n    if hexversion < 0x02070000:\n        return errfunc\n    else:\n        return func\n\n\nclass _IlocWrapper:\n    def __init__(self, _dict):\n        self._dict = _dict\n\n    def __len__(self):\n        return len(self._dict)\n\n    def __getitem__(self, index):\n        \"\"\"\n        Very efficiently return the key at index *index* in iteration. Supports\n        negative indices and slice notation. Raises IndexError on invalid\n        *index*.\n        \"\"\"\n        return self._dict._list[index]\n\n    def __delitem__(self, index):\n        \"\"\"\n        Remove the ``sdict[sdict.iloc[index]]`` from *sdict*. Supports negative\n        indices and slice notation. Raises IndexError on invalid *index*.\n        \"\"\"\n        _temp = self._dict\n        _list = _temp._list\n        _delitem = _temp._delitem\n\n        if isinstance(index, slice):\n            keys = _list[index]\n            del _list[index]\n            for key in keys:\n                _delitem(key)\n        else:\n            key = _list[index]\n            del _list[index]\n            _delitem(key)\n\n\nclass SortedDict(dict):\n    \"\"\"\n    A SortedDict provides the same methods as a dict.  Additionally, a\n    SortedDict efficiently maintains its keys in sorted order. Consequently, the\n    keys method will return the keys in sorted order, the popitem method will\n    remove the item with the highest key, etc.\n    \"\"\"\n\n    def __init__(self, *args, **kwargs):\n        \"\"\"\n        A SortedDict provides the same methods as a dict.  Additionally, a\n        SortedDict efficiently maintains its keys in sorted order. Consequently,\n        the keys method will return the keys in sorted order, the popitem method\n        will remove the item with the highest key, etc.\n\n        An optional *key* argument defines a callable that, like the `key`\n        argument to Python's `sorted` function, extracts a comparison key from\n        each dict key. If no function is specified, the default compares the\n        dict keys directly. The `key` argument must be provided as a positional\n        argument and must come before all other arguments.\n\n        An optional *load* argument defines the load factor of the internal list\n        used to maintain sort order. If present, this argument must come before\n        an iterable. The default load factor of '1000' works well for lists from\n        tens to tens of millions of elements.  Good practice is to use a value\n        that is the cube root of the list size.  With billions of elements, the\n        best load factor depends on your usage.  It's best to leave the load\n        factor at the default until you start benchmarking.\n\n        An optional *iterable* argument provides an initial series of items to\n        populate the SortedDict.  Each item in the series must itself contain\n        two items.  The first is used as a key in the new dictionary, and the\n        second as the key's value. If a given key is seen more than once, the\n        last value associated with it is retained in the new dictionary.\n\n        If keyword arguments are given, the keywords themselves with their\n        associated values are added as items to the dictionary. If a key is\n        specified both in the positional argument and as a keyword argument, the\n        value associated with the keyword is retained in the dictionary. For\n        example, these all return a dictionary equal to ``{\"one\": 2, \"two\":\n        3}``:\n\n        * ``SortedDict(one=2, two=3)``\n        * ``SortedDict({'one': 2, 'two': 3})``\n        * ``SortedDict(zip(('one', 'two'), (2, 3)))``\n        * ``SortedDict([['two', 3], ['one', 2]])``\n\n        The first example only works for keys that are valid Python\n        identifiers; the others work with any valid keys.\n        \"\"\"\n        if len(args) > 0 and (args[0] is None or callable(args[0])):\n            self._key = args[0]\n            args = args[1:]\n        else:\n            self._key = None\n\n        if len(args) > 0 and type(args[0]) == int:\n            self._load = args[0]\n            args = args[1:]\n        else:\n            self._load = 1000\n\n        if self._key is None:\n            self._list = SortedList(load=self._load)\n        else:\n            self._list = SortedListWithKey(key=self._key, load=self._load)\n\n        # Cache function pointers to dict methods.\n\n        _dict = super(SortedDict, self)\n        self._dict = _dict\n        self._clear = _dict.clear\n        self._delitem = _dict.__delitem__\n        self._iter = _dict.__iter__\n        self._pop = _dict.pop\n        self._setdefault = _dict.setdefault\n        self._setitem = _dict.__setitem__\n        self._update = _dict.update\n\n        # Cache function pointers to SortedList methods.\n\n        self._list_add = self._list.add\n        self._list_bisect_left = self._list.bisect_left\n        self._list_bisect_right = self._list.bisect_right\n        self._list_clear = self._list.clear\n        self._list_index = self._list.index\n        self._list_pop = self._list.pop\n        self._list_remove = self._list.remove\n        self._list_update = self._list.update\n\n        self.iloc = _IlocWrapper(self)\n\n        self.update(*args, **kwargs)\n\n    def clear(self):\n        \"\"\"Remove all elements from the dictionary.\"\"\"\n        self._clear()\n        self._list_clear()\n\n    def __delitem__(self, key):\n        \"\"\"\n        Remove ``d[key]`` from *d*.  Raises a KeyError if *key* is not in the\n        dictionary.\n        \"\"\"\n        self._delitem(key)\n        self._list_remove(key)\n\n    def __iter__(self):\n        \"\"\"Create an iterator over the sorted keys of the dictionary.\"\"\"\n        return iter(self._list)\n\n    def __reversed__(self):\n        \"\"\"\n        Create a reversed iterator over the sorted keys of the dictionary.\n        \"\"\"\n        return reversed(self._list)\n\n    def __setitem__(self, key, value):\n        \"\"\"Set `d[key]` to *value*.\"\"\"\n        if key not in self:\n            self._list_add(key)\n        self._setitem(key, value)\n\n    def copy(self):\n        \"\"\"Return a shallow copy of the sorted dictionary.\"\"\"\n        return self.__class__(self._key, self._load, iter(self.items()))\n\n    __copy__ = copy\n\n    @classmethod\n    def fromkeys(cls, seq, value=None):\n        \"\"\"\n        Create a new dictionary with keys from *seq* and values set to *value*.\n        \"\"\"\n        return cls((key, value) for key in seq)\n\n    if hexversion < 0x03000000:\n        def items(self):\n            \"\"\"\n            Return a list of the dictionary's items (``(key, value)`` pairs).\n            \"\"\"\n            return list(self.items())\n    else:\n        def items(self):\n            \"\"\"\n            Return a new ItemsView of the dictionary's items.  In addition to\n            the methods provided by the built-in `view` the ItemsView is\n            indexable (e.g. ``d.items()[5]``).\n            \"\"\"\n            return ItemsView(self)\n\n    def iteritems(self):\n        \"\"\"Return an iterable over the items (``(key, value)`` pairs).\"\"\"\n        return iter((key, self[key]) for key in self._list)\n\n    if hexversion < 0x03000000:\n        def keys(self):\n            \"\"\"Return a SortedSet of the dictionary's keys.\"\"\"\n            return SortedSet(self._list, key=self._key, load=self._load)\n    else:\n        def keys(self):\n            \"\"\"\n            Return a new KeysView of the dictionary's keys.  In addition to the\n            methods provided by the built-in `view` the KeysView is indexable\n            (e.g. ``d.keys()[5]``).\n            \"\"\"\n            return KeysView(self)\n\n    def iterkeys(self):\n        \"\"\"Return an iterable over the keys of the dictionary.\"\"\"\n        return iter(self._list)\n\n    if hexversion < 0x03000000:\n        def values(self):\n            \"\"\"Return a list of the dictionary's values.\"\"\"\n            return list(self.values())\n    else:\n        def values(self):\n            \"\"\"\n            Return a new :class:`ValuesView` of the dictionary's values.\n            In addition to the methods provided by the built-in `view` the\n            ValuesView is indexable (e.g., ``d.values()[5]``).\n            \"\"\"\n            return ValuesView(self)\n\n    def itervalues(self):\n        \"\"\"Return an iterable over the values of the dictionary.\"\"\"\n        return iter(self[key] for key in self._list)\n\n    def pop(self, key, default=_NotGiven):\n        \"\"\"\n        If *key* is in the dictionary, remove it and return its value,\n        else return *default*. If *default* is not given and *key* is not in\n        the dictionary, a KeyError is raised.\n        \"\"\"\n        if key in self:\n            self._list_remove(key)\n            return self._pop(key)\n        else:\n            if default is _NotGiven:\n                raise KeyError(key)\n            else:\n                return default\n\n    def popitem(self):\n        \"\"\"\n        Remove and return the ``(key, value)`` pair with the greatest *key*\n        from the dictionary.\n\n        If the dictionary is empty, calling `popitem` raises a\n        KeyError`.\n        \"\"\"\n        if not len(self):\n            raise KeyError('popitem(): dictionary is empty')\n\n        key = self._list_pop()\n        value = self._pop(key)\n\n        return (key, value)\n\n    def setdefault(self, key, default=None):\n        \"\"\"\n        If *key* is in the dictionary, return its value.  If not, insert *key*\n        with a value of *default* and return *default*.  *default* defaults to\n        ``None``.\n        \"\"\"\n        if key in self:\n            return self[key]\n        else:\n            self._setitem(key, default)\n            self._list_add(key)\n            return default\n\n    def update(self, *args, **kwargs):\n        \"\"\"\n        Update the dictionary with the key/value pairs from *other*, overwriting\n        existing keys.\n\n        *update* accepts either another dictionary object or an iterable of\n        key/value pairs (as a tuple or other iterable of length two).  If\n        keyword arguments are specified, the dictionary is then updated with\n        those key/value pairs: ``d.update(red=1, blue=2)``.\n        \"\"\"\n        if not len(self):\n            self._update(*args, **kwargs)\n            self._list_update(self._iter())\n            return\n\n        if (len(kwargs) == 0 and len(args) == 1 and isinstance(args[0], dict)):\n            pairs = args[0]\n        else:\n            pairs = dict(*args, **kwargs)\n\n        if (10 * len(pairs)) > len(self):\n            self._update(pairs)\n            self._list_clear()\n            self._list_update(self._iter())\n        else:\n            for key in pairs:\n                self[key] = pairs[key]\n\n    def index(self, key, start=None, stop=None):\n        \"\"\"\n        Return the smallest *k* such that `d.iloc[k] == key` and `i <= k < j`.\n        Raises `ValueError` if *key* is not present.  *stop* defaults to the end\n        of the set.  *start* defaults to the beginning.  Negative indexes are\n        supported, as for slice indices.\n        \"\"\"\n        return self._list_index(key, start, stop)\n\n    def bisect_left(self, key):\n        \"\"\"\n        Similar to the ``bisect`` module in the standard library, this returns\n        an appropriate index to insert *key* in SortedDict. If *key* is\n        already present in SortedDict, the insertion point will be before (to\n        the left of) any existing entries.\n        \"\"\"\n        return self._list_bisect_left(key)\n\n    def bisect(self, key):\n        \"\"\"Same as bisect_right.\"\"\"\n        return self._list_bisect_right(key)\n\n    def bisect_right(self, key):\n        \"\"\"\n        Same as `bisect_left`, but if *key* is already present in SortedDict,\n        the insertion point will be after (to the right of) any existing\n        entries.\n        \"\"\"\n        return self._list_bisect_right(key)\n\n    @not26\n    def viewkeys(self):\n        \"\"\"\n        In Python 2.7 and later, return a new `KeysView` of the dictionary's\n        keys.\n\n        In Python 2.6, raise a NotImplementedError.\n        \"\"\"\n        return KeysView(self)\n\n    @not26\n    def viewvalues(self):\n        \"\"\"\n        In Python 2.7 and later, return a new `ValuesView` of the dictionary's\n        values.\n\n        In Python 2.6, raise a NotImplementedError.\n        \"\"\"\n        return ValuesView(self)\n\n    @not26\n    def viewitems(self):\n        \"\"\"\n        In Python 2.7 and later, return a new `ItemsView` of the dictionary's\n        items.\n\n        In Python 2.6, raise a NotImplementedError.\n        \"\"\"\n        return ItemsView(self)\n\n    def __reduce__(self):\n        return (self.__class__, (self._key, self._load, list(self.items())))\n\n    @recursive_repr\n    def __repr__(self):\n        temp = '{0}({1}, {2}, {{{3}}})'\n        items = ', '.join('{0}: {1}'.format(repr(key), repr(self[key]))\n                          for key in self._list)\n        return temp.format(\n            self.__class__.__name__,\n            repr(self._key),\n            repr(self._load),\n            items\n        )\n\n    def _check(self):\n        self._list._check()\n        assert len(self) == len(self._list)\n        assert all(val in self for val in self._list)\n\n\nclass KeysView(AbstractKeysView, Set, Sequence):\n    \"\"\"\n    A KeysView object is a dynamic view of the dictionary's keys, which\n    means that when the dictionary's keys change, the view reflects\n    those changes.\n\n    The KeysView class implements the Set and Sequence Abstract Base Classes.\n    \"\"\"\n    if hexversion < 0x03000000:\n        def __init__(self, sorted_dict):\n            \"\"\"\n            Initialize a KeysView from a SortedDict container as *sorted_dict*.\n            \"\"\"\n            self._list = sorted_dict._list\n            self._view = sorted_dict._dict.keys()\n    else:\n        def __init__(self, sorted_dict):\n            \"\"\"\n            Initialize a KeysView from a SortedDict container as *sorted_dict*.\n            \"\"\"\n            self._list = sorted_dict._list\n            self._view = list(sorted_dict._dict.keys())\n\n    def __len__(self):\n        \"\"\"Return the number of entries in the dictionary.\"\"\"\n        return len(self._view)\n\n    def __contains__(self, key):\n        \"\"\"\n        Return True if and only if *key* is one of the underlying dictionary's\n        keys.\n        \"\"\"\n        return key in self._view\n\n    def __iter__(self):\n        \"\"\"\n        Return an iterable over the keys in the dictionary. Keys are iterated\n        over in their sorted order.\n\n        Iterating views while adding or deleting entries in the dictionary may\n        raise a RuntimeError or fail to iterate over all entries.\n        \"\"\"\n        return iter(self._list)\n\n    def __getitem__(self, index):\n        \"\"\"Return the key at position *index*.\"\"\"\n        return self._list[index]\n\n    def __reversed__(self):\n        \"\"\"\n        Return a reversed iterable over the keys in the dictionary. Keys are\n        iterated over in their reverse sort order.\n\n        Iterating views while adding or deleting entries in the dictionary may\n        raise a RuntimeError or fail to iterate over all entries.\n        \"\"\"\n        return reversed(self._list)\n\n    def index(self, value, start=None, stop=None):\n        \"\"\"\n        Return the smallest *k* such that `keysview[k] == value` and `start <= k\n        < end`.  Raises `KeyError` if *value* is not present.  *stop* defaults\n        to the end of the set.  *start* defaults to the beginning.  Negative\n        indexes are supported, as for slice indices.\n        \"\"\"\n        return self._list.index(value, start, stop)\n\n    def count(self, value):\n        \"\"\"Return the number of occurrences of *value* in the set.\"\"\"\n        return 1 if value in self._view else 0\n\n    def __eq__(self, that):\n        \"\"\"Test set-like equality with *that*.\"\"\"\n        return self._view == that\n\n    def __ne__(self, that):\n        \"\"\"Test set-like inequality with *that*.\"\"\"\n        return self._view != that\n\n    def __lt__(self, that):\n        \"\"\"Test whether self is a proper subset of *that*.\"\"\"\n        return self._view < that\n\n    def __gt__(self, that):\n        \"\"\"Test whether self is a proper superset of *that*.\"\"\"\n        return self._view > that\n\n    def __le__(self, that):\n        \"\"\"Test whether self is contained within *that*.\"\"\"\n        return self._view <= that\n\n    def __ge__(self, that):\n        \"\"\"Test whether *that* is contained within self.\"\"\"\n        return self._view >= that\n\n    def __and__(self, that):\n        \"\"\"Return a SortedSet of the intersection of self and *that*.\"\"\"\n        return SortedSet(self._view & that)\n\n    def __or__(self, that):\n        \"\"\"Return a SortedSet of the union of self and *that*.\"\"\"\n        return SortedSet(self._view | that)\n\n    def __sub__(self, that):\n        \"\"\"Return a SortedSet of the difference of self and *that*.\"\"\"\n        return SortedSet(self._view - that)\n\n    def __xor__(self, that):\n        \"\"\"Return a SortedSet of the symmetric difference of self and *that*.\"\"\"\n        return SortedSet(self._view ^ that)\n\n    if hexversion < 0x03000000:\n        def isdisjoint(self, that):\n            \"\"\"Return True if and only if *that* is disjoint with self.\"\"\"\n            return not any(key in self._list for key in that)\n    else:\n        def isdisjoint(self, that):\n            \"\"\"Return True if and only if *that* is disjoint with self.\"\"\"\n            return self._view.isdisjoint(that)\n\n    @recursive_repr\n    def __repr__(self):\n        return 'SortedDict_keys({0})'.format(repr(list(self)))\n\n\nclass ValuesView(AbstractValuesView, Sequence):\n    \"\"\"\n    A ValuesView object is a dynamic view of the dictionary's values, which\n    means that when the dictionary's values change, the view reflects those\n    changes.\n\n    The ValuesView class implements the Sequence Abstract Base Class.\n    \"\"\"\n    if hexversion < 0x03000000:\n        def __init__(self, sorted_dict):\n            \"\"\"\n            Initialize a ValuesView from a SortedDict container as\n            *sorted_dict*.\n            \"\"\"\n            self._dict = sorted_dict\n            self._list = sorted_dict._list\n            self._view = sorted_dict._dict.values()\n    else:\n        def __init__(self, sorted_dict):\n            \"\"\"\n            Initialize a ValuesView from a SortedDict container as\n            *sorted_dict*.\n            \"\"\"\n            self._dict = sorted_dict\n            self._list = sorted_dict._list\n            self._view = list(sorted_dict._dict.values())\n\n    def __len__(self):\n        \"\"\"Return the number of entries in the dictionary.\"\"\"\n        return len(self._dict)\n\n    def __contains__(self, value):\n        \"\"\"\n        Return True if and only if *value* is on the underlying dictionary's\n        values.\n        \"\"\"\n        return value in self._view\n\n    def __iter__(self):\n        \"\"\"\n        Return an iterator over the values in the dictionary.  Values are\n        iterated over in sorted order of the keys.\n\n        Iterating views while adding or deleting entries in the dictionary may\n        raise a `RuntimeError` or fail to iterate over all entries.\n        \"\"\"\n        _dict = self._dict\n        return iter(_dict[key] for key in self._list)\n\n    def __getitem__(self, index):\n        \"\"\"\n        Efficiently return value at *index* in iteration.\n\n        Supports slice notation and negative indexes.\n        \"\"\"\n        _dict, _list = self._dict, self._list\n        if isinstance(index, slice):\n            return [_dict[key] for key in _list[index]]\n        else:\n            return _dict[_list[index]]\n\n    def __reversed__(self):\n        \"\"\"\n        Return a reverse iterator over the values in the dictionary.  Values are\n        iterated over in reverse sort order of the keys.\n\n        Iterating views while adding or deleting entries in the dictionary may\n        raise a `RuntimeError` or fail to iterate over all entries.\n        \"\"\"\n        _dict = self._dict\n        return iter(_dict[key] for key in reversed(self._list))\n\n    def index(self, value):\n        \"\"\"\n        Return index of *value* in self.\n\n        Raises ValueError if *value* is not found.\n        \"\"\"\n        for idx, val in enumerate(self):\n            if value == val:\n                return idx\n        else:\n            raise ValueError('{0} is not in dict'.format(repr(value)))\n    def count(self, value):\n        \"\"\"Return the number of occurrences of *value* in self.\"\"\"\n        return len([val for val in self._dict.values() if val == value])\n      \n    def __lt__(self, that):\n        raise TypeError\n\n    def __gt__(self, that):\n        raise TypeError\n\n    def __le__(self, that):\n        raise TypeError\n\n    def __ge__(self, that):\n        raise TypeError\n\n    def __and__(self, that):\n        raise TypeError\n\n    def __or__(self, that):\n        raise TypeError\n\n    def __sub__(self, that):\n        raise TypeError\n\n    def __xor__(self, that):\n        raise TypeError\n\n    @recursive_repr\n    def __repr__(self):\n        return 'SortedDict_values({0})'.format(repr(list(self)))\n\n\nclass ItemsView(AbstractItemsView, Set, Sequence):\n    \"\"\"\n    An ItemsView object is a dynamic view of the dictionary's ``(key,\n    value)`` pairs, which means that when the dictionary changes, the\n    view reflects those changes.\n\n    The ItemsView class implements the Set and Sequence Abstract Base Classes.\n    However, the set-like operations (``&``, ``|``, ``-``, ``^``) will only\n    operate correctly if all of the dictionary's values are hashable.\n    \"\"\"\n    if hexversion < 0x03000000:\n        def __init__(self, sorted_dict):\n            \"\"\"\n            Initialize an ItemsView from a SortedDict container as\n            *sorted_dict*.\n            \"\"\"\n            self._dict = sorted_dict\n            self._list = sorted_dict._list\n            self._view = sorted_dict._dict.items()\n    else:\n        def __init__(self, sorted_dict):\n            \"\"\"\n            Initialize an ItemsView from a SortedDict container as\n            *sorted_dict*.\n            \"\"\"\n            self._dict = sorted_dict\n            self._list = sorted_dict._list\n            self._view = list(sorted_dict._dict.items())\n\n    def __len__(self):\n        \"\"\"Return the number of entries in the dictionary.\"\"\"\n        return len(self._view)\n\n    def __contains__(self, key):\n        \"\"\"\n        Return True if and only if *key* is one of the underlying dictionary's\n        items.\n        \"\"\"\n        return key in self._view\n\n    def __iter__(self):\n        \"\"\"\n        Return an iterable over the items in the dictionary. Items are iterated\n        over in their sorted order.\n\n        Iterating views while adding or deleting entries in the dictionary may\n        raise a RuntimeError or fail to iterate over all entries.\n        \"\"\"\n        _dict = self._dict\n        return iter((key, _dict[key]) for key in self._list)\n\n    def __getitem__(self, index):\n        \"\"\"Return the item as position *index*.\"\"\"\n        _dict, _list = self._dict, self._list\n        if isinstance(index, slice):\n            return [(key, _dict[key]) for key in _list[index]]\n        else:\n            key = _list[index]\n            return (key, _dict[key])\n\n    def __reversed__(self):\n        \"\"\"\n        Return a reversed iterable over the items in the dictionary. Items are\n        iterated over in their reverse sort order.\n\n        Iterating views while adding or deleting entries in the dictionary may\n        raise a RuntimeError or fail to iterate over all entries.\n        \"\"\"\n        _dict = self._dict\n        return iter((key, _dict[key]) for key in reversed(self._list))\n\n    def index(self, key, start=None, stop=None):\n        \"\"\"\n        Return the smallest *k* such that `itemssview[k] == key` and `start <= k\n        < end`.  Raises `KeyError` if *key* is not present.  *stop* defaults\n        to the end of the set.  *start* defaults to the beginning.  Negative\n        indexes are supported, as for slice indices.\n        \"\"\"\n        temp, value = key\n        pos = self._list.index(temp, start, stop)\n        if value == self._dict[temp]:\n            return pos\n        else:\n            raise ValueError('{0} is not in dict'.format(repr(key)))\n\n    def count(self, item):\n        \"\"\"Return the number of occurrences of *item* in the set.\"\"\"\n        key, value = item\n        return 1 if key in self._dict and self._dict[key] == value else 0\n\n    def __eq__(self, that):\n        \"\"\"Test set-like equality with *that*.\"\"\"\n        return self._view == that\n\n    def __ne__(self, that):\n        \"\"\"Test set-like inequality with *that*.\"\"\"\n        return self._view != that\n\n    def __lt__(self, that):\n        \"\"\"Test whether self is a proper subset of *that*.\"\"\"\n        return self._view < that\n\n    def __gt__(self, that):\n        \"\"\"Test whether self is a proper superset of *that*.\"\"\"\n        return self._view > that\n\n    def __le__(self, that):\n        \"\"\"Test whether self is contained within *that*.\"\"\"\n        return self._view <= that\n\n    def __ge__(self, that):\n        \"\"\"Test whether *that* is contained within self.\"\"\"\n        return self._view >= that\n\n    def __and__(self, that):\n        \"\"\"Return a SortedSet of the intersection of self and *that*.\"\"\"\n        return SortedSet(self._view & that)\n\n    def __or__(self, that):\n        \"\"\"Return a SortedSet of the union of self and *that*.\"\"\"\n        return SortedSet(self._view | that)\n\n    def __sub__(self, that):\n        \"\"\"Return a SortedSet of the difference of self and *that*.\"\"\"\n        return SortedSet(self._view - that)\n\n    def __xor__(self, that):\n        \"\"\"Return a SortedSet of the symmetric difference of self and *that*.\"\"\"\n        return SortedSet(self._view ^ that)\n\n    if hexversion < 0x03000000:\n        def isdisjoint(self, that):\n            \"\"\"Return True if and only if *that* is disjoint with self.\"\"\"\n            _dict = self._dict\n            for key, value in that:\n                if key in _dict and _dict[key] == value:\n                    return False\n            return True\n    else:\n        def isdisjoint(self, that):\n            \"\"\"Return True if and only if *that* is disjoint with self.\"\"\"\n            return self._view.isdisjoint(that)\n\n    @recursive_repr\n    def __repr__(self):\n        return 'SortedDict_items({0})'.format(repr(list(self)))\n"
  },
  {
    "path": "code/default/lib/noarch/sortedcontainers/sortedlist.py",
    "content": "# -*- coding: utf-8 -*-\n#\n# Sorted list implementation.\n\n\nfrom sys import hexversion\n\nfrom bisect import bisect_left, bisect_right, insort\nfrom itertools import chain, repeat, starmap\nfrom collections import MutableSequence\nfrom operator import iadd, add\nfrom functools import wraps\nfrom math import log\n\nif hexversion < 0x03000000:\n    \n    \n    try:\n        from _thread import get_ident\n    except ImportError:\n        from _dummy_thread import get_ident\nelse:\n    from functools import reduce\n    try:\n        from _thread import get_ident\n    except ImportError:\n        from _dummy_thread import get_ident\n\ndef recursive_repr(func):\n    \"\"\"Decorator to prevent infinite repr recursion.\"\"\"\n    repr_running = set()\n\n    @wraps(func)\n    def wrapper(self):\n        key = id(self), get_ident()\n\n        if key in repr_running:\n            return '...'\n\n        repr_running.add(key)\n\n        try:\n            return func(self)\n        finally:\n            repr_running.discard(key)\n\n    return wrapper\n\nclass SortedList(MutableSequence):\n    \"\"\"\n    SortedList provides most of the same methods as a list but keeps the items\n    in sorted order.\n    \"\"\"\n\n    def __init__(self, iterable=None, load=1000):\n        \"\"\"\n        SortedList provides most of the same methods as a list but keeps the\n        items in sorted order.\n\n        An optional *iterable* provides an initial series of items to populate\n        the SortedList.\n\n        An optional *load* specifies the load-factor of the list. The default\n        load factor of '1000' works well for lists from tens to tens of millions\n        of elements.  Good practice is to use a value that is the cube root of\n        the list size.  With billions of elements, the best load factor depends\n        on your usage.  It's best to leave the load factor at the default until\n        you start benchmarking.\n        \"\"\"\n        self._len, self._maxes, self._lists, self._index = 0, [], [], []\n        self._load, self._twice, self._half = load, load * 2, load >> 1\n        self._offset = 0\n\n        if iterable is not None:\n            self.update(iterable)\n\n    def clear(self):\n        \"\"\"Remove all the elements from the list.\"\"\"\n        self._len = 0\n        del self._maxes[:]\n        del self._lists[:]\n        del self._index[:]\n\n    def add(self, val):\n        \"\"\"Add the element *val* to the list.\"\"\"\n        _maxes, _lists = self._maxes, self._lists\n\n        if _maxes:\n            pos = bisect_right(_maxes, val)\n\n            if pos == len(_maxes):\n                pos -= 1\n                _maxes[pos] = val\n                _lists[pos].append(val)\n            else:\n                insort(_lists[pos], val)\n\n            self._expand(pos)\n        else:\n            _maxes.append(val)\n            _lists.append([val])\n\n        self._len += 1\n\n    def _expand(self, pos):\n        \"\"\"Splits sublists that are more than double the load level.\n\n        Updates the index when the sublist length is less than double the load\n        level. This requires incrementing the nodes in a traversal from the leaf\n        node to the root. For an example traversal see self._loc.\n        \"\"\"\n        _lists, _index = self._lists, self._index\n\n        if len(_lists[pos]) > self._twice:\n            _maxes, _load = self._maxes, self._load\n            half = _lists[pos][_load:]\n            del _lists[pos][_load:]\n            _maxes[pos] = _lists[pos][-1]\n            _maxes.insert(pos + 1, half[-1])\n            _lists.insert(pos + 1, half)\n            del _index[:]\n        else:\n            if len(_index) > 0:\n                child = self._offset + pos\n                while child > 0:\n                    _index[child] += 1\n                    child = (child - 1) >> 1\n                _index[0] += 1\n\n    def update(self, iterable):\n        \"\"\"Update the list by adding all elements from *iterable*.\"\"\"\n        _maxes, _lists = self._maxes, self._lists\n        values = sorted(iterable)\n\n        if _maxes:\n            if len(values) * 4 >= self._len:\n                values.extend(chain.from_iterable(_lists))\n                values.sort()\n                self.clear()\n            else:\n                _add = self.add\n                for val in values:\n                    _add(val)\n                return\n\n        _load, _index = self._load, self._index\n        _lists.extend(values[pos:(pos + _load)]\n                      for pos in range(0, len(values), _load))\n        _maxes.extend(sublist[-1] for sublist in _lists)\n        self._len = len(values)\n        del _index[:]\n\n    def __contains__(self, val):\n        \"\"\"Return True if and only if *val* is an element in the list.\"\"\"\n        _maxes = self._maxes\n\n        if not _maxes:\n            return False\n\n        pos = bisect_left(_maxes, val)\n\n        if pos == len(_maxes):\n            return False\n\n        _lists = self._lists\n        idx = bisect_left(_lists[pos], val)\n        return _lists[pos][idx] == val\n\n    def discard(self, val):\n        \"\"\"\n        Remove the first occurrence of *val*.\n\n        If *val* is not a member, does nothing.\n        \"\"\"\n        _maxes = self._maxes\n\n        if not _maxes:\n            return\n\n        pos = bisect_left(_maxes, val)\n\n        if pos == len(_maxes):\n            return\n\n        _lists = self._lists\n        idx = bisect_left(_lists[pos], val)\n        if _lists[pos][idx] == val:\n            self._delete(pos, idx)\n\n    def remove(self, val):\n        \"\"\"\n        Remove first occurrence of *val*.\n\n        Raises ValueError if *val* is not present.\n        \"\"\"\n        _maxes = self._maxes\n\n        if not _maxes:\n            raise ValueError('{0} not in list'.format(repr(val)))\n\n        pos = bisect_left(_maxes, val)\n\n        if pos == len(_maxes):\n            raise ValueError('{0} not in list'.format(repr(val)))\n\n        _lists = self._lists\n        idx = bisect_left(_lists[pos], val)\n        if _lists[pos][idx] == val:\n            self._delete(pos, idx)\n        else:\n            raise ValueError('{0} not in list'.format(repr(val)))\n\n    def _delete(self, pos, idx):\n        \"\"\"Delete the item at the given (pos, idx).\n\n        Combines lists that are less than half the load level.\n\n        Updates the index when the sublist length is more than half the load\n        level. This requires decrementing the nodes in a traversal from the leaf\n        node to the root. For an example traversal see self._loc.\n        \"\"\"\n        _maxes, _lists, _index = self._maxes, self._lists, self._index\n\n        lists_pos = _lists[pos]\n\n        del lists_pos[idx]\n        self._len -= 1\n\n        len_lists_pos = len(lists_pos)\n\n        if len_lists_pos > self._half:\n\n            _maxes[pos] = lists_pos[-1]\n\n            if len(_index) > 0:\n                child = self._offset + pos\n                while child > 0:\n                    _index[child] -= 1\n                    child = (child - 1) >> 1\n                _index[0] -= 1\n\n        elif len(_lists) > 1:\n\n            if not pos:\n                pos += 1\n\n            prev = pos - 1\n            _lists[prev].extend(_lists[pos])\n            _maxes[prev] = _lists[prev][-1]\n\n            del _maxes[pos]\n            del _lists[pos]\n            del _index[:]\n\n            self._expand(prev)\n\n        elif len_lists_pos:\n\n            _maxes[pos] = lists_pos[-1]\n\n        else:\n\n            del _maxes[pos]\n            del _lists[pos]\n            del _index[:]\n\n    def _loc(self, pos, idx):\n        \"\"\"Convert an index pair (alpha, beta) into a single index that corresponds to\n        the position of the value in the sorted list.\n\n        Most queries require the index be built. Details of the index are\n        described in self._build_index.\n\n        Indexing requires traversing the tree from a leaf node to the root. The\n        parent of each node is easily computable at (pos - 1) // 2.\n\n        Left-child nodes are always at odd indices and right-child nodes are\n        always at even indices.\n\n        When traversing up from a right-child node, increment the total by the\n        left-child node.\n\n        The final index is the sum from traversal and the index in the sublist.\n\n        For example, using the index from self._build_index:\n\n        _index = 14 5 9 3 2 4 5\n        _offset = 3\n\n        Tree:\n\n                 14\n              5      9\n            3   2  4   5\n\n        Converting index pair (2, 3) into a single index involves iterating like\n        so:\n\n        1. Starting at the leaf node: offset + alpha = 3 + 2 = 5. We identify\n           the node as a left-child node. At such nodes, we simply traverse to\n           the parent.\n\n        2. At node 9, position 2, we recognize the node as a right-child node\n           and accumulate the left-child in our total. Total is now 5 and we\n           traverse to the parent at position 0.\n\n        3. Iteration ends at the root.\n\n        Computing the index is the sum of the total and beta: 5 + 3 = 8.\n        \"\"\"\n        if not pos:\n            return idx\n\n        _index = self._index\n\n        if not len(_index):\n            self._build_index()\n\n        total = 0\n\n        # Increment pos to point in the index to len(self._lists[pos]).\n\n        pos += self._offset\n\n        # Iterate until reaching the root of the index tree at pos = 0.\n\n        while pos:\n\n            # Right-child nodes are at odd indices. At such indices\n            # account the total below the left child node.\n\n            if not (pos & 1):\n                total += _index[pos - 1]\n\n            # Advance pos to the parent node.\n\n            pos = (pos - 1) >> 1\n\n        return total + idx\n\n    def _pos(self, idx):\n        \"\"\"Convert an index into a pair (alpha, beta) that can be used to access\n        the corresponding _lists[alpha][beta] position.\n\n        Most queries require the index be built. Details of the index are\n        described in self._build_index.\n\n        Indexing requires traversing the tree to a leaf node. Each node has\n        two children which are easily computable. Given an index, pos, the\n        left-child is at pos * 2 + 1 and the right-child is at pos * 2 + 2.\n\n        When the index is less than the left-child, traversal moves to the\n        left sub-tree. Otherwise, the index is decremented by the left-child\n        and traversal moves to the right sub-tree.\n\n        At a child node, the indexing pair is computed from the relative\n        position of the child node as compared with the offset and the remaining\n        index.\n\n        For example, using the index from self._build_index:\n\n        _index = 14 5 9 3 2 4 5\n        _offset = 3\n\n        Tree:\n\n                 14\n              5      9\n            3   2  4   5\n\n        Indexing position 8 involves iterating like so:\n\n        1. Starting at the root, position 0, 8 is compared with the left-child\n           node (5) which it is greater than. When greater the index is\n           decremented and the position is updated to the right child node.\n\n        2. At node 9 with index 3, we again compare the index to the left-child\n           node with value 4. Because the index is the less than the left-child\n           node, we simply traverse to the left.\n\n        3. At node 4 with index 3, we recognize that we are at a leaf node and\n           stop iterating.\n\n        4. To compute the sublist index, we subtract the offset from the index\n           of the leaf node: 5 - 3 = 2. To compute the index in the sublist, we\n           simply use the index remaining from iteration. In this case, 3.\n\n        The final index pair from our example is (2, 3) which corresponds to\n        index 8 in the sorted list.\n        \"\"\"\n        _len, _lists = self._len, self._lists\n\n        if idx < 0:\n            last_len = len(_lists[-1])\n            if (-idx) <= last_len:\n                return len(_lists) - 1, last_len + idx\n            idx += _len\n            if idx < 0:\n                raise IndexError('list index out of range')\n        elif idx >= _len:\n            raise IndexError('list index out of range')\n\n        if idx < len(_lists[0]):\n            return 0, idx\n\n        _index = self._index\n\n        if not len(_index):\n            self._build_index()\n\n        pos = 0\n        len_index = len(_index)\n        child = (pos << 1) + 1\n\n        while child < len_index:\n            index_child = _index[child]\n\n            if idx < index_child:\n                pos = child\n            else:\n                idx -= index_child\n                pos = child + 1\n\n            child = (pos << 1) + 1\n\n        return (pos - self._offset, idx)\n\n    def _build_index(self):\n        \"\"\"Build an index for indexing the sorted list.\n\n        Indexes are represented as binary trees in a dense array notation\n        similar to a binary heap.\n\n        For example, given a _lists representation storing integers:\n\n        [0]: 1 2 3\n        [1]: 4 5\n        [2]: 6 7 8 9\n        [3]: 10 11 12 13 14\n\n        The first transformation maps the sub-lists by their length. The\n        first row of the index is the length of the sub-lists.\n\n        [0]: 3 2 4 5\n\n        Each row after that is the sum of consecutive pairs of the previous row:\n\n        [1]: 5 9\n        [2]: 14\n\n        Finally, the index is built by concatenating these lists together:\n\n        _index = 14 5 9 3 2 4 5\n\n        An offset storing the start of the first row is also stored:\n\n        _offset = 3\n\n        When built, the index can be used for efficient indexing into the list.\n        See the comment and notes on self._pos for details.\n        \"\"\"\n        row0 = list(map(len, self._lists))\n\n        if len(row0) == 1:\n            self._index[:] = row0\n            self._offset = 0\n            return\n\n        head = iter(row0)\n        tail = iter(head)\n        row1 = list(starmap(add, list(zip(head, tail))))\n\n        if len(row0) & 1:\n            row1.append(row0[-1])\n\n        if len(row1) == 1:\n            self._index[:] = row1 + row0\n            self._offset = 1\n            return\n\n        size = 2 ** (int(log(len(row1) - 1, 2)) + 1)\n        row1.extend(repeat(0, size - len(row1)))\n        tree = [row0, row1]\n\n        while len(tree[-1]) > 1:\n            head = iter(tree[-1])\n            tail = iter(head)\n            row = list(starmap(add, list(zip(head, tail))))\n            tree.append(row)\n\n        reduce(iadd, reversed(tree), self._index)\n        self._offset = size * 2 - 1\n\n    def _slice(self, slc):\n        start, stop, step = slc.start, slc.stop, slc.step\n\n        if step == 0:\n            raise ValueError('slice step cannot be zero')\n\n        # Set defaults for missing values.\n\n        if step is None:\n            step = 1\n\n        if step > 0:\n            if start is None:\n                start = 0\n\n            if stop is None:\n                stop = len(self)\n            elif stop < 0:\n                stop += len(self)\n        else:\n            if start is None:\n                start = len(self) - 1\n\n            if stop is None:\n                stop = -1\n            elif stop < 0:\n                stop += len(self)\n\n        if start < 0:\n            start += len(self)\n\n        # Fix indices that are too big or too small.\n        # Slice notation is surprisingly permissive\n        # where normal indexing would raise IndexError.\n\n        if step > 0:\n            if start < 0:\n                start = 0\n            elif start > len(self):\n                start = len(self)\n\n            if stop < 0:\n                stop = 0\n            elif stop > len(self):\n                stop = len(self)\n        else:\n            if start < 0:\n                start = -1\n            elif start >= len(self):\n                start = len(self) - 1\n\n            if stop < 0:\n                stop = -1\n            elif stop > len(self):\n                stop = len(self)\n\n        return start, stop, step\n\n    def __delitem__(self, idx):\n        \"\"\"Remove the element at *idx*. Supports slicing.\"\"\"\n        if isinstance(idx, slice):\n            start, stop, step = self._slice(idx)\n\n            if ((step == 1) and (start < stop)\n                    and ((stop - start) * 8 >= self._len)):\n\n                values = self[:start]\n                if stop < self._len:\n                    values += self[stop:]\n                self.clear()\n                self.update(values)\n                return\n\n            indices = list(range(start, stop, step))\n\n            # Delete items from greatest index to least so\n            # that the indices remain valid throughout iteration.\n\n            if step > 0:\n                indices = reversed(indices)\n\n            _pos, _delete = self._pos, self._delete\n\n            for index in indices:\n                pos, idx = _pos(index)\n                _delete(pos, idx)\n        else:\n            pos, idx = self._pos(idx)\n            self._delete(pos, idx)\n\n    def __getitem__(self, idx):\n        \"\"\"Return the element at *idx*. Supports slicing.\"\"\"\n        _lists = self._lists\n\n        if isinstance(idx, slice):\n            start, stop, step = self._slice(idx)\n\n            if step == 1 and start < stop:\n                if start == 0 and stop == self._len:\n                    return self.as_list()\n\n                start_pos, start_idx = self._pos(start)\n\n                if stop == self._len:\n                    stop_pos = len(_lists) - 1\n                    stop_idx = len(_lists[stop_pos])\n                else:\n                    stop_pos, stop_idx = self._pos(stop)\n\n                if start_pos == stop_pos:\n                    return _lists[start_pos][start_idx:stop_idx]\n\n                prefix = _lists[start_pos][start_idx:]\n                middle = _lists[(start_pos + 1):stop_pos]\n                result = reduce(iadd, middle, prefix)\n                result += _lists[stop_pos][:stop_idx]\n\n                return result\n\n            if step == -1 and start > stop:\n                result = self[(stop + 1):(start + 1)]\n                result.reverse()\n                return result\n\n            # Return a list because a negative step could\n            # reverse the order of the items and this could\n            # be the desired behavior.\n\n            indices = list(range(start, stop, step))\n            return list(self[index] for index in indices)\n        else:\n            pos, idx = self._pos(idx)\n            return _lists[pos][idx]\n\n    def _check_order(self, idx, val):\n        _lists, _len = self._lists, self._len\n\n        pos, loc = self._pos(idx)\n\n        if idx < 0:\n            idx += _len\n\n        # Check that the inserted value is not less than the\n        # previous value.\n\n        if idx > 0:\n            idx_prev = loc - 1\n            pos_prev = pos\n\n            if idx_prev < 0:\n                pos_prev -= 1\n                idx_prev = len(_lists[pos_prev]) - 1\n\n            if _lists[pos_prev][idx_prev] > val:\n                msg = '{0} not in sort order at index {1}'.format(repr(val), idx)\n                raise ValueError(msg)\n\n        # Check that the inserted value is not greater than\n        # the previous value.\n\n        if idx < (_len - 1):\n            idx_next = loc + 1\n            pos_next = pos\n\n            if idx_next == len(_lists[pos_next]):\n                pos_next += 1\n                idx_next = 0\n\n            if _lists[pos_next][idx_next] < val:\n                msg = '{0} not in sort order at index {1}'.format(repr(val), idx)\n                raise ValueError(msg)\n\n    def __setitem__(self, index, value):\n        \"\"\"\n        Replace the item at position *index* with *value*.\n\n        Supports slice notation. Raises a :exc:`ValueError` if the sort order\n        would be violated. When used with a slice and iterable, the\n        :exc:`ValueError` is raised before the list is mutated if the sort order\n        would be violated by the operation.\n        \"\"\"\n        _maxes, _lists, _pos = self._maxes, self._lists, self._pos\n        _check_order = self._check_order\n\n        if isinstance(index, slice):\n            start, stop, step = self._slice(index)\n            indices = list(range(start, stop, step))\n\n            if step != 1:\n                if not hasattr(value, '__len__'):\n                    value = list(value)\n\n                indices = list(indices)\n\n                if len(value) != len(indices):\n                    raise ValueError(\n                        'attempt to assign sequence of size {0}'\n                        ' to extended slice of size {1}'\n                        .format(len(value), len(indices)))\n\n                # Keep a log of values that are set so that we can\n                # roll back changes if ordering is violated.\n\n                log = []\n                _append = log.append\n\n                for idx, val in zip(indices, value):\n                    pos, loc = _pos(idx)\n                    _append((idx, _lists[pos][loc], val))\n                    _lists[pos][loc] = val\n                    if len(_lists[pos]) == (loc + 1):\n                        _maxes[pos] = val\n\n                try:\n                    # Validate ordering of new values.\n\n                    for idx, oldval, newval in log:\n                        _check_order(idx, newval)\n\n                except ValueError:\n\n                    # Roll back changes from log.\n\n                    for idx, oldval, newval in log:\n                        pos, loc = _pos(idx)\n                        _lists[pos][loc] = oldval\n                        if len(_lists[pos]) == (loc + 1):\n                            _maxes[pos] = oldval\n\n                    raise\n            else:\n                # Test ordering using indexing. If the value given\n                # doesn't support getitem, convert it to a list.\n\n                if not hasattr(value, '__getitem__'):\n                    value = list(value)\n\n                # Check that the given values are ordered properly.\n\n                ordered = all(value[pos - 1] <= value[pos]\n                              for pos in range(1, len(value)))\n\n                if not ordered:\n                    raise ValueError('given sequence not in sort order')\n\n                # Check ordering in context of sorted list.\n\n                if not start or not len(value):\n                    # Nothing to check on the lhs.\n                    pass\n                else:\n                    if self[start - 1] > value[0]:\n                        msg = '{0} not in sort order at index {1}'.format(repr(value[0]), start)\n                        raise ValueError(msg)\n\n                if stop == len(self) or not len(value):\n                    # Nothing to check on the rhs.\n                    pass\n                else:\n                    # \"stop\" is exclusive so we don't need\n                    # to add one for the index.\n                    if self[stop] < value[-1]:\n                        msg = '{0} not in sort order at index {1}'.format(repr(value[-1]), stop)\n                        raise ValueError(msg)\n\n                # Delete the existing values.\n\n                del self[index]\n\n                # Insert the new values.\n\n                _insert = self.insert\n                for idx, val in enumerate(value):\n                    _insert(start + idx, val)\n        else:\n            pos, loc = _pos(index)\n            _check_order(index, value)\n            _lists[pos][loc] = value\n            if len(_lists[pos]) == (loc + 1):\n                _maxes[pos] = value\n\n    def __iter__(self):\n        \"\"\"Create an iterator over the list.\"\"\"\n        return chain.from_iterable(self._lists)\n\n    def __reversed__(self):\n        \"\"\"Create an iterator to traverse the list in reverse.\"\"\"\n        return chain.from_iterable(list(map(reversed, reversed(self._lists))))\n\n    def __len__(self):\n        \"\"\"Return the number of elements in the list.\"\"\"\n        return self._len\n\n    def bisect_left(self, val):\n        \"\"\"\n        Similar to the *bisect* module in the standard library, this returns an\n        appropriate index to insert *val*. If *val* is already present, the\n        insertion point will be before (to the left of) any existing entries.\n        \"\"\"\n        _maxes = self._maxes\n\n        if not _maxes:\n            return 0\n\n        pos = bisect_left(_maxes, val)\n\n        if pos == len(_maxes):\n            return self._len\n\n        idx = bisect_left(self._lists[pos], val)\n\n        return self._loc(pos, idx)\n\n    def bisect_right(self, val):\n        \"\"\"\n        Same as *bisect_left*, but if *val* is already present, the insertion\n        point will be after (to the right of) any existing entries.\n        \"\"\"\n        _maxes = self._maxes\n\n        if not _maxes:\n            return 0\n\n        pos = bisect_right(_maxes, val)\n\n        if pos == len(_maxes):\n            return self._len\n\n        idx = bisect_right(self._lists[pos], val)\n\n        return self._loc(pos, idx)\n\n    bisect = bisect_right\n\n    def count(self, val):\n        \"\"\"Return the number of occurrences of *val* in the list.\"\"\"\n        _maxes = self._maxes\n\n        if not _maxes:\n            return 0\n\n        pos_left = bisect_left(_maxes, val)\n\n        if pos_left == len(_maxes):\n            return 0\n\n        _lists = self._lists\n        idx_left = bisect_left(_lists[pos_left], val)\n        pos_right = bisect_right(_maxes, val)\n\n        if pos_right == len(_maxes):\n            return self._len - self._loc(pos_left, idx_left)\n\n        idx_right = bisect_right(_lists[pos_right], val)\n\n        if pos_left == pos_right:\n            return idx_right - idx_left\n\n        right = self._loc(pos_right, idx_right)\n        left = self._loc(pos_left, idx_left)\n\n        return right - left\n\n    def copy(self):\n        \"\"\"Return a shallow copy of the sorted list.\"\"\"\n        return self.__class__(self, load=self._load)\n\n    __copy__ = copy\n\n    def append(self, val):\n        \"\"\"\n        Append the element *val* to the list. Raises a ValueError if the *val*\n        would violate the sort order.\n        \"\"\"\n        _maxes, _lists = self._maxes, self._lists\n\n        if not _maxes:\n            _maxes.append(val)\n            _lists.append([val])\n            self._len = 1\n            return\n\n        pos = len(_lists) - 1\n\n        if val < _lists[pos][-1]:\n            msg = '{0} not in sort order at index {1}'.format(repr(val), self._len)\n            raise ValueError(msg)\n\n        _maxes[pos] = val\n        _lists[pos].append(val)\n        self._len += 1\n        self._expand(pos)\n\n    def extend(self, values):\n        \"\"\"\n        Extend the list by appending all elements from the *values*. Raises a\n        ValueError if the sort order would be violated.\n        \"\"\"\n        _maxes, _lists, _load = self._maxes, self._lists, self._load\n\n        if not isinstance(values, list):\n            values = list(values)\n\n        if any(values[pos - 1] > values[pos]\n               for pos in range(1, len(values))):\n            raise ValueError('given sequence not in sort order')\n\n        offset = 0\n\n        if _maxes:\n            if values[0] < _lists[-1][-1]:\n                msg = '{0} not in sort order at index {1}'.format(repr(values[0]), self._len)\n                raise ValueError(msg)\n\n            if len(_lists[-1]) < self._half:\n                _lists[-1].extend(values[:_load])\n                _maxes[-1] = _lists[-1][-1]\n                offset = _load\n\n        len_lists = len(_lists)\n\n        for idx in range(offset, len(values), _load):\n            _lists.append(values[idx:(idx + _load)])\n            _maxes.append(_lists[-1][-1])\n\n        _index = self._index\n\n        if len_lists == len(_lists):\n            len_index = len(_index)\n            if len_index > 0:\n                len_values = len(values)\n                child = len_index - 1\n                while child:\n                    _index[child] += len_values\n                    child = (child - 1) >> 1\n                _index[0] += len_values\n        else:\n            del _index[:]\n\n        self._len += len(values)\n\n    def insert(self, idx, val):\n        \"\"\"\n        Insert the element *val* into the list at *idx*. Raises a ValueError if\n        the *val* at *idx* would violate the sort order.\n        \"\"\"\n        _maxes, _lists, _len = self._maxes, self._lists, self._len\n\n        if idx < 0:\n            idx += _len\n        if idx < 0:\n            idx = 0\n        if idx > _len:\n            idx = _len\n\n        if not _maxes:\n            # The idx must be zero by the inequalities above.\n            _maxes.append(val)\n            _lists.append([val])\n            self._len = 1\n            return\n\n        if not idx:\n            if val > _lists[0][0]:\n                msg = '{0} not in sort order at index {1}'.format(repr(val), 0)\n                raise ValueError(msg)\n            else:\n                _lists[0].insert(0, val)\n                self._expand(0)\n                self._len += 1\n                return\n\n        if idx == _len:\n            pos = len(_lists) - 1\n            if _lists[pos][-1] > val:\n                msg = '{0} not in sort order at index {1}'.format(repr(val), _len)\n                raise ValueError(msg)\n            else:\n                _lists[pos].append(val)\n                _maxes[pos] = _lists[pos][-1]\n                self._expand(pos)\n                self._len += 1\n                return\n\n        pos, idx = self._pos(idx)\n        idx_before = idx - 1\n        if idx_before < 0:\n            pos_before = pos - 1\n            idx_before = len(_lists[pos_before]) - 1\n        else:\n            pos_before = pos\n\n        before = _lists[pos_before][idx_before]\n        if before <= val <= _lists[pos][idx]:\n            _lists[pos].insert(idx, val)\n            self._expand(pos)\n            self._len += 1\n        else:\n            msg = '{0} not in sort order at index {1}'.format(repr(val), idx)\n            raise ValueError(msg)\n\n    def pop(self, idx=-1):\n        \"\"\"\n        Remove and return item at *idx* (default last).  Raises IndexError if\n        list is empty or index is out of range.  Negative indices are supported,\n        as for slice indices.\n        \"\"\"\n        if (idx < 0 and -idx > self._len) or (idx >= self._len):\n            raise IndexError('pop index out of range')\n\n        pos, idx = self._pos(idx)\n        val = self._lists[pos][idx]\n        self._delete(pos, idx)\n\n        return val\n\n    def index(self, val, start=None, stop=None):\n        \"\"\"\n        Return the smallest *k* such that L[k] == val and i <= k < j`.  Raises\n        ValueError if *val* is not present.  *stop* defaults to the end of the\n        list. *start* defaults to the beginning. Negative indices are supported,\n        as for slice indices.\n        \"\"\"\n        _len, _maxes = self._len, self._maxes\n\n        if not _maxes:\n            raise ValueError('{0} is not in list'.format(repr(val)))\n\n        if start is None:\n            start = 0\n        if start < 0:\n            start += _len\n        if start < 0:\n            start = 0\n\n        if stop is None:\n            stop = _len\n        if stop < 0:\n            stop += _len\n        if stop > _len:\n            stop = _len\n\n        if stop <= start:\n            raise ValueError('{0} is not in list'.format(repr(val)))\n\n        stop -= 1\n        pos_left = bisect_left(_maxes, val)\n\n        if pos_left == len(_maxes):\n            raise ValueError('{0} is not in list'.format(repr(val)))\n\n        _lists = self._lists\n        idx_left = bisect_left(_lists[pos_left], val)\n\n        if _lists[pos_left][idx_left] != val:\n            raise ValueError('{0} is not in list'.format(repr(val)))\n\n        left = self._loc(pos_left, idx_left)\n\n        if start <= left:\n            if left <= stop:\n                return left\n        else:\n            right = self.bisect_right(val) - 1\n\n            if start <= right:\n                return start\n\n        raise ValueError('{0} is not in list'.format(repr(val)))\n\n    def as_list(self):\n        \"\"\"Very efficiently convert the SortedList to a list.\"\"\"\n        return reduce(iadd, self._lists, [])\n\n    def __add__(self, that):\n        \"\"\"\n        Return a new sorted list containing all the elements in *self* and\n        *that*. Elements in *that* do not need to be properly ordered with\n        respect to *self*.\n        \"\"\"\n        values = self.as_list()\n        values.extend(that)\n        return self.__class__(values, load=self._load)\n\n    def __iadd__(self, that):\n        \"\"\"\n        Update *self* to include all values in *that*. Elements in *that* do not\n        need to be properly ordered with respect to *self*.\n        \"\"\"\n        self.update(that)\n        return self\n\n    def __mul__(self, that):\n        \"\"\"\n        Return a new sorted list containing *that* shallow copies of each item\n        in SortedList.\n        \"\"\"\n        values = self.as_list() * that\n        return self.__class__(values, load=self._load)\n\n    def __imul__(self, that):\n        \"\"\"\n        Increase the length of the list by appending *that* shallow copies of\n        each item.\n        \"\"\"\n        values = self.as_list() * that\n        self.clear()\n        self.update(values)\n        return self\n\n    def __eq__(self, that):\n        \"\"\"Compare two Sequences for equality.\"\"\"\n        return ((self._len == len(that))\n                and all(lhs == rhs for lhs, rhs in zip(self, that)))\n\n    def __ne__(self, that):\n        \"\"\"Compare two Sequences for inequality.\"\"\"\n        return ((self._len != len(that))\n                or any(lhs != rhs for lhs, rhs in zip(self, that)))\n\n    def __lt__(self, that):\n        \"\"\"Compare two Sequences for less than.\"\"\"\n        return ((self._len <= len(that))\n                and all(lhs < rhs for lhs, rhs in zip(self, that)))\n\n    def __le__(self, that):\n        \"\"\"Compare two Sequences for less than equal.\"\"\"\n        return ((self._len <= len(that))\n                and all(lhs <= rhs for lhs, rhs in zip(self, that)))\n\n    def __gt__(self, that):\n        \"\"\"Compare two Sequences for greater than.\"\"\"\n        return ((self._len >= len(that))\n                and all(lhs > rhs for lhs, rhs in zip(self, that)))\n\n    def __ge__(self, that):\n        \"\"\"Compare two Sequences for greater than equal.\"\"\"\n        return ((self._len >= len(that))\n                and all(lhs >= rhs for lhs, rhs in zip(self, that)))\n\n    @recursive_repr\n    def __repr__(self):\n        \"\"\"Return string representation of SortedList.\"\"\"\n        temp = '{0}({1}, load={2})'\n        return temp.format(\n            self.__class__.__name__,\n            repr(list(self)),\n            repr(self._load)\n        )\n\n    def _check(self):\n        try:\n            # Check load parameters.\n\n            assert self._load >= 4\n            assert self._half == (self._load >> 1)\n            assert self._twice == (self._load * 2)\n\n            # Check empty sorted list case.\n\n            if self._maxes == []:\n                assert self._lists == []\n                return\n\n            assert len(self._maxes) > 0 and len(self._lists) > 0\n\n            # Check all sublists are sorted.\n\n            assert all(sublist[pos - 1] <= sublist[pos]\n                       for sublist in self._lists\n                       for pos in range(1, len(sublist)))\n\n            # Check beginning/end of sublists are sorted.\n\n            for pos in range(1, len(self._lists)):\n                assert self._lists[pos - 1][-1] <= self._lists[pos][0]\n\n            # Check length of _maxes and _lists match.\n\n            assert len(self._maxes) == len(self._lists)\n\n            # Check _maxes is a map of _lists.\n\n            assert all(self._maxes[pos] == self._lists[pos][-1]\n                       for pos in range(len(self._maxes)))\n\n            # Check load level is less than _twice.\n\n            assert all(len(sublist) <= self._twice for sublist in self._lists)\n\n            # Check load level is greater than _half for all\n            # but the last sublist.\n\n            assert all(len(self._lists[pos]) >= self._half\n                       for pos in range(0, len(self._lists) - 1))\n\n            # Check length.\n\n            assert self._len == sum(len(sublist) for sublist in self._lists)\n\n            # Check index.\n\n            if len(self._index):\n                assert len(self._index) == self._offset + len(self._lists)\n                assert self._len == self._index[0]\n\n                def test_offset_pos(pos):\n                    from_index = self._index[self._offset + pos]\n                    return from_index == len(self._lists[pos])\n\n                assert all(test_offset_pos(pos)\n                           for pos in range(len(self._lists)))\n\n                for pos in range(self._offset):\n                    child = (pos << 1) + 1\n                    if self._index[pos] == 0:\n                        assert child >= len(self._index)\n                    elif child + 1 == len(self._index):\n                        assert self._index[pos] == self._index[child]\n                    else:\n                        child_sum = self._index[child] + self._index[child + 1]\n                        assert self._index[pos] == child_sum\n\n        except:\n            import sys\n            import traceback\n\n            traceback.print_exc(file=sys.stdout)\n\n            print('len', self._len)\n            print('load', self._load, self._half, self._twice)\n            print('offset', self._offset)\n            print('len_index', len(self._index))\n            print('index', self._index)\n            print('len_maxes', len(self._maxes))\n            print('maxes', self._maxes)\n            print('len_lists', len(self._lists))\n            print('lists', self._lists)\n\n            raise\n"
  },
  {
    "path": "code/default/lib/noarch/sortedcontainers/sortedlistwithkey.py",
    "content": "# -*- coding: utf-8 -*-\n#\n# Sorted list implementation.\n\n\nfrom sys import hexversion\n\nfrom .sortedlist import recursive_repr\nfrom bisect import bisect_left, bisect_right, insort\nfrom itertools import chain, repeat, starmap\nfrom collections import MutableSequence\nfrom operator import iadd, add\nfrom functools import wraps\nfrom math import log\ntry:\n    from functools import reduce\nexcept ImportError:\n    pass\n\ndef identity(value):\n    return value\n\nclass SortedListWithKey(MutableSequence):\n    \"\"\"\n    SortedList provides most of the same methods as a list but keeps the items\n    in sorted order.\n    \"\"\"\n\n    def __init__(self, iterable=None, key=identity, load=1000):\n        \"\"\"\n        SortedList provides most of the same methods as a list but keeps the\n        items in sorted order.\n\n        An optional *iterable* provides an initial series of items to populate\n        the SortedList.\n\n        An optional *load* specifies the load-factor of the list. The default\n        load factor of '1000' works well for lists from tens to tens of millions\n        of elements.  Good practice is to use a value that is the cube root of\n        the list size.  With billions of elements, the best load factor depends\n        on your usage.  It's best to leave the load factor at the default until\n        you start benchmarking.\n        \"\"\"\n        self._len, self._maxes, self._lists, self._keys, self._index = 0, [], [], [], []\n        self._key, self._load, self._twice, self._half = key, load, load * 2, load >> 1\n        self._offset = 0\n\n        if iterable is not None:\n            self.update(iterable)\n\n    def clear(self):\n        \"\"\"Remove all the elements from the list.\"\"\"\n        self._len = 0\n        del self._maxes[:]\n        del self._lists[:]\n        del self._keys[:]\n        del self._index[:]\n\n    def add(self, val):\n        \"\"\"Add the element *val* to the list.\"\"\"\n        _maxes, _lists, _keys = self._maxes, self._lists, self._keys\n\n        key = self._key(val)\n\n        if _maxes:\n            pos = bisect_right(_maxes, key)\n\n            if pos == len(_maxes):\n                pos -= 1\n                _maxes[pos] = key\n                _keys[pos].append(key)\n                _lists[pos].append(val)\n            else:\n                idx = bisect_right(_keys[pos], key)\n                _keys[pos].insert(idx, key)\n                _lists[pos].insert(idx, val)\n\n            self._expand(pos)\n        else:\n            _maxes.append(key)\n            _keys.append([key])\n            _lists.append([val])\n\n        self._len += 1\n\n    def _expand(self, pos):\n        \"\"\"\n        Splits sublists that are more than double the load level.\n\n        Updates the index when the sublist length is less than double the load\n        level. This requires incrementing the nodes in a traversal from the leaf\n        node to the root. For an example traversal see self._loc.\n        \"\"\"\n        _lists, _keys, _index = self._lists, self._keys, self._index\n\n        if len(_keys[pos]) > self._twice:\n            _maxes, _load = self._maxes, self._load\n\n            half = _keys[pos][_load:]\n            half_list = _lists[pos][_load:]\n            del _keys[pos][_load:]\n            del _lists[pos][_load:]\n            _maxes[pos] = _keys[pos][-1]\n\n            _maxes.insert(pos + 1, half[-1])\n            _keys.insert(pos + 1, half)\n            _lists.insert(pos + 1, half_list)\n\n            del _index[:]\n        else:\n            if len(_index) > 0:\n                child = self._offset + pos\n                while child > 0:\n                    _index[child] += 1\n                    child = (child - 1) >> 1\n                _index[0] += 1\n\n    def update(self, iterable):\n        \"\"\"Update the list by adding all elements from *iterable*.\"\"\"\n        _maxes, _lists, _keys = self._maxes, self._lists, self._keys\n        values = sorted(iterable, key=self._key)\n\n        if _maxes:\n            if len(values) * 4 >= self._len:\n                values.extend(chain.from_iterable(_lists))\n                values.sort(key=self._key)\n                self.clear()\n            else:\n                _add = self.add\n                for val in values:\n                    _add(val)\n                return\n\n        _load, _index = self._load, self._index\n        _lists.extend(values[pos:(pos + _load)]\n                      for pos in range(0, len(values), _load))\n        _keys.extend(list(map(self._key, _list)) for _list in _lists)\n        _maxes.extend(sublist[-1] for sublist in _keys)\n        self._len = len(values)\n        del _index[:]\n\n    def __contains__(self, val):\n        \"\"\"Return True if and only if *val* is an element in the list.\"\"\"\n        _maxes = self._maxes\n\n        if not _maxes:\n            return False\n\n        key = self._key(val)\n        pos = bisect_left(_maxes, key)\n\n        if pos == len(_maxes):\n            return False\n\n        _keys = self._keys\n        _lists = self._lists\n\n        idx = bisect_left(_keys[pos], key)\n\n        len_keys = len(_keys)\n        len_sublist = len(_keys[pos])\n\n        while True:\n            if _keys[pos][idx] != key:\n                return False\n            if _lists[pos][idx] == val:\n                return True\n            idx += 1\n            if idx == len_sublist:\n                pos += 1\n                if pos == len_keys:\n                    return False\n                len_sublist = len(_keys[pos])\n                idx = 0\n\n    def discard(self, val):\n        \"\"\"\n        Remove the first occurrence of *val*.\n\n        If *val* is not a member, does nothing.\n        \"\"\"\n        _maxes = self._maxes\n\n        if not _maxes:\n            return\n\n        key = self._key(val)\n        pos = bisect_left(_maxes, key)\n\n        if pos == len(_maxes):\n            return\n\n        _keys = self._keys\n        _lists = self._lists\n        idx = bisect_left(_keys[pos], key)\n\n        len_keys = len(_keys)\n        len_sublist = len(_keys[pos])\n\n        while True:\n            if _keys[pos][idx] != key:\n                return\n            if _lists[pos][idx] == val:\n                self._delete(pos, idx)\n                return\n            idx += 1\n            if idx == len_sublist:\n                pos += 1\n                if pos == len_keys:\n                    return\n                len_sublist = len(_keys[pos])\n                idx = 0\n\n    def remove(self, val):\n        \"\"\"\n        Remove first occurrence of *val*.\n\n        Raises ValueError if *val* is not present.\n        \"\"\"\n        _maxes = self._maxes\n\n        if not _maxes:\n            raise ValueError('{0} not in list'.format(repr(val)))\n\n        key = self._key(val)\n        pos = bisect_left(_maxes, key)\n\n        if pos == len(_maxes):\n            raise ValueError('{0} not in list'.format(repr(val)))\n\n        _keys = self._keys\n        _lists = self._lists\n        idx = bisect_left(_keys[pos], key)\n\n        len_keys = len(_keys)\n        len_sublist = len(_keys[pos])\n\n        while True:\n            if _keys[pos][idx] != key:\n                raise ValueError('{0} not in list'.format(repr(val)))\n            if _lists[pos][idx] == val:\n                self._delete(pos, idx)\n                return\n            idx += 1\n            if idx == len_sublist:\n                pos += 1\n                if pos == len_keys:\n                    raise ValueError('{0} not in list'.format(repr(val)))\n                len_sublist = len(_keys[pos])\n                idx = 0\n\n    def _delete(self, pos, idx):\n        \"\"\"\n        Delete the item at the given (pos, idx).\n\n        Combines lists that are less than half the load level.\n\n        Updates the index when the sublist length is more than half the load\n        level. This requires decrementing the nodes in a traversal from the leaf\n        node to the root. For an example traversal see self._loc.\n        \"\"\"\n        _maxes, _lists, _keys, _index = self._maxes, self._lists, self._keys, self._index\n\n        keys_pos = _keys[pos]\n        lists_pos = _lists[pos]\n\n        del keys_pos[idx]\n        del lists_pos[idx]\n        self._len -= 1\n\n        len_keys_pos = len(keys_pos)\n\n        if len_keys_pos > self._half:\n\n            _maxes[pos] = keys_pos[-1]\n\n            if len(_index) > 0:\n                child = self._offset + pos\n                while child > 0:\n                    _index[child] -= 1\n                    child = (child - 1) >> 1\n                _index[0] -= 1\n\n        elif len(_keys) > 1:\n\n            if not pos:\n                pos += 1\n\n            prev = pos - 1\n            _keys[prev].extend(_keys[pos])\n            _lists[prev].extend(_lists[pos])\n            _maxes[prev] = _keys[prev][-1]\n\n            del _keys[pos]\n            del _lists[pos]\n            del _maxes[pos]\n            del _index[:]\n\n            self._expand(prev)\n\n        elif len_keys_pos:\n\n            _maxes[pos] = keys_pos[-1]\n\n        else:\n\n            del _keys[pos]\n            del _lists[pos]\n            del _maxes[pos]\n            del _index[:]\n\n    def _loc(self, pos, idx):\n        \"\"\"Convert an index pair (alpha, beta) into a single index that corresponds to\n        the position of the value in the sorted list.\n\n        Most queries require the index be built. Details of the index are\n        described in self._build_index.\n\n        Indexing requires traversing the tree from a leaf node to the root. The\n        parent of each node is easily computable at (pos - 1) // 2.\n\n        Left-child nodes are always at odd indices and right-child nodes are\n        always at even indices.\n\n        When traversing up from a right-child node, increment the total by the\n        left-child node.\n\n        The final index is the sum from traversal and the index in the sublist.\n\n        For example, using the index from self._build_index:\n\n        _index = 14 5 9 3 2 4 5\n        _offset = 3\n\n        Tree:\n\n                 14\n              5      9\n            3   2  4   5\n\n        Converting index pair (2, 3) into a single index involves iterating like\n        so:\n\n        1. Starting at the leaf node: offset + alpha = 3 + 2 = 5. We identify\n           the node as a left-child node. At such nodes, we simply traverse to\n           the parent.\n\n        2. At node 9, position 2, we recognize the node as a right-child node\n           and accumulate the left-child in our total. Total is now 5 and we\n           traverse to the parent at position 0.\n\n        3. Iteration ends at the root.\n\n        Computing the index is the sum of the total and beta: 5 + 3 = 8.\n        \"\"\"\n        if not pos:\n            return idx\n\n        _index = self._index\n\n        if not len(_index):\n            self._build_index()\n\n        total = 0\n\n        # Increment pos to point in the index to len(self._lists[pos]).\n\n        pos += self._offset\n\n        # Iterate until reaching the root of the index tree at pos = 0.\n\n        while pos:\n\n            # Right-child nodes are at odd indices. At such indices\n            # account the total below the left child node.\n\n            if not (pos & 1):\n                total += _index[pos - 1]\n\n            # Advance pos to the parent node.\n\n            pos = (pos - 1) >> 1\n\n        return total + idx\n\n    def _pos(self, idx):\n        \"\"\"Convert an index into a pair (alpha, beta) that can be used to access\n        the corresponding _lists[alpha][beta] position.\n\n        Most queries require the index be built. Details of the index are\n        described in self._build_index.\n\n        Indexing requires traversing the tree to a leaf node. Each node has\n        two children which are easily computable. Given an index, pos, the\n        left-child is at pos * 2 + 1 and the right-child is at pos * 2 + 2.\n\n        When the index is less than the left-child, traversal moves to the\n        left sub-tree. Otherwise, the index is decremented by the left-child\n        and traversal moves to the right sub-tree.\n\n        At a child node, the indexing pair is computed from the relative\n        position of the child node as compared with the offset and the remaining\n        index.\n\n        For example, using the index from self._build_index:\n\n        _index = 14 5 9 3 2 4 5\n        _offset = 3\n\n        Tree:\n\n                 14\n              5      9\n            3   2  4   5\n\n        Indexing position 8 involves iterating like so:\n\n        1. Starting at the root, position 0, 8 is compared with the left-child\n           node (5) which it is greater than. When greater the index is\n           decremented and the position is updated to the right child node.\n\n        2. At node 9 with index 3, we again compare the index to the left-child\n           node with value 4. Because the index is the less than the left-child\n           node, we simply traverse to the left.\n\n        3. At node 4 with index 3, we recognize that we are at a leaf node and\n           stop iterating.\n\n        4. To compute the sublist index, we subtract the offset from the index\n           of the leaf node: 5 - 3 = 2. To compute the index in the sublist, we\n           simply use the index remaining from iteration. In this case, 3.\n\n        The final index pair from our example is (2, 3) which corresponds to\n        index 8 in the sorted list.\n        \"\"\"\n        _len, _lists = self._len, self._lists\n\n        if idx < 0:\n            last_len = len(_lists[-1])\n            if (-idx) <= last_len:\n                return len(_lists) - 1, last_len + idx\n            idx += _len\n            if idx < 0:\n                raise IndexError('list index out of range')\n        elif idx >= _len:\n            raise IndexError('list index out of range')\n\n        if idx < len(_lists[0]):\n            return 0, idx\n\n        _index = self._index\n\n        if not len(_index):\n            self._build_index()\n\n        pos = 0\n        len_index = len(_index)\n        child = (pos << 1) + 1\n\n        while child < len_index:\n            index_child = _index[child]\n\n            if idx < index_child:\n                pos = child\n            else:\n                idx -= index_child\n                pos = child + 1\n\n            child = (pos << 1) + 1\n\n        return (pos - self._offset, idx)\n\n    def _build_index(self):\n        \"\"\"Build an index for indexing the sorted list.\n\n        Indexes are represented as binary trees in a dense array notation\n        similar to a binary heap.\n\n        For example, given a _lists representation storing integers:\n\n        [0]: 1 2 3\n        [1]: 4 5\n        [2]: 6 7 8 9\n        [3]: 10 11 12 13 14\n\n        The first transformation maps the sub-lists by their length. The\n        first row of the index is the length of the sub-lists.\n\n        [0]: 3 2 4 5\n\n        Each row after that is the sum of consecutive pairs of the previous row:\n\n        [1]: 5 9\n        [2]: 14\n\n        Finally, the index is built by concatenating these lists together:\n\n        _index = 14 5 9 3 2 4 5\n\n        An offset storing the start of the first row is also stored:\n\n        _offset = 3\n\n        When built, the index can be used for efficient indexing into the list.\n        See the comment and notes on self._pos for details.\n        \"\"\"\n        row0 = list(map(len, self._lists))\n\n        if len(row0) == 1:\n            self._index[:] = row0\n            self._offset = 0\n            return\n\n        head = iter(row0)\n        tail = iter(head)\n        row1 = list(starmap(add, list(zip(head, tail))))\n\n        if len(row0) & 1:\n            row1.append(row0[-1])\n\n        if len(row1) == 1:\n            self._index[:] = row1 + row0\n            self._offset = 1\n            return\n\n        size = 2 ** (int(log(len(row1) - 1, 2)) + 1)\n        row1.extend(repeat(0, size - len(row1)))\n        tree = [row0, row1]\n\n        while len(tree[-1]) > 1:\n            head = iter(tree[-1])\n            tail = iter(head)\n            row = list(starmap(add, list(zip(head, tail))))\n            tree.append(row)\n\n        reduce(iadd, reversed(tree), self._index)\n        self._offset = size * 2 - 1\n\n    def _slice(self, slc):\n        start, stop, step = slc.start, slc.stop, slc.step\n\n        if step == 0:\n            raise ValueError('slice step cannot be zero')\n\n        # Set defaults for missing values.\n\n        if step is None:\n            step = 1\n\n        if step > 0:\n            if start is None:\n                start = 0\n\n            if stop is None:\n                stop = len(self)\n            elif stop < 0:\n                stop += len(self)\n        else:\n            if start is None:\n                start = len(self) - 1\n\n            if stop is None:\n                stop = -1\n            elif stop < 0:\n                stop += len(self)\n\n        if start < 0:\n            start += len(self)\n\n        # Fix indices that are too big or too small.\n        # Slice notation is surprisingly permissive\n        # where normal indexing would raise IndexError.\n\n        if step > 0:\n            if start < 0:\n                start = 0\n            elif start > len(self):\n                start = len(self)\n\n            if stop < 0:\n                stop = 0\n            elif stop > len(self):\n                stop = len(self)\n        else:\n            if start < 0:\n                start = -1\n            elif start >= len(self):\n                start = len(self) - 1\n\n            if stop < 0:\n                stop = -1\n            elif stop > len(self):\n                stop = len(self)\n\n        return start, stop, step\n\n    def __delitem__(self, idx):\n        \"\"\"Remove the element at *idx*. Supports slicing.\"\"\"\n        if isinstance(idx, slice):\n            start, stop, step = self._slice(idx)\n\n            if ((step == 1) and (start < stop)\n                    and ((stop - start) * 8 >= self._len)):\n\n                values = self[:start]\n                if stop < self._len:\n                    values += self[stop:]\n                self.clear()\n                self.update(values)\n                return\n\n            indices = list(range(start, stop, step))\n\n            # Delete items from greatest index to least so\n            # that the indices remain valid throughout iteration.\n\n            if step > 0:\n                indices = reversed(indices)\n\n            _pos, _delete = self._pos, self._delete\n\n            for index in indices:\n                pos, idx = _pos(index)\n                _delete(pos, idx)\n        else:\n            pos, idx = self._pos(idx)\n            self._delete(pos, idx)\n\n    def __getitem__(self, idx):\n        \"\"\"Return the element at *idx*. Supports slicing.\"\"\"\n        _lists = self._lists\n\n        if isinstance(idx, slice):\n            start, stop, step = self._slice(idx)\n\n            if step == 1 and start < stop:\n                if start == 0 and stop == self._len:\n                    return self.as_list()\n\n                start_pos, start_idx = self._pos(start)\n\n                if stop == self._len:\n                    stop_pos = len(_lists) - 1\n                    stop_idx = len(_lists[stop_pos])\n                else:\n                    stop_pos, stop_idx = self._pos(stop)\n\n                if start_pos == stop_pos:\n                    return _lists[start_pos][start_idx:stop_idx]\n\n                prefix = _lists[start_pos][start_idx:]\n                middle = _lists[(start_pos + 1):stop_pos]\n                result = reduce(iadd, middle, prefix)\n                result += _lists[stop_pos][:stop_idx]\n\n                return result\n\n            if step == -1 and start > stop:\n                result = self[(stop + 1):(start + 1)]\n                result.reverse()\n                return result\n\n            # Return a list because a negative step could\n            # reverse the order of the items and this could\n            # be the desired behavior.\n\n            indices = list(range(start, stop, step))\n            return list(self[index] for index in indices)\n        else:\n            pos, idx = self._pos(idx)\n            return _lists[pos][idx]\n\n    def _check_order(self, idx, key, val):\n        _keys, _len = self._keys, self._len\n\n        pos, loc = self._pos(idx)\n\n        if idx < 0:\n            idx += _len\n\n        # Check that the inserted value is not less than the\n        # previous value.\n\n        if idx > 0:\n            idx_prev = loc - 1\n            pos_prev = pos\n\n            if idx_prev < 0:\n                pos_prev -= 1\n                idx_prev = len(_keys[pos_prev]) - 1\n\n            if _keys[pos_prev][idx_prev] > key:\n                msg = '{0} not in sort order at index {1}'.format(repr(val), idx)\n                raise ValueError(msg)\n\n        # Check that the inserted value is not greater than\n        # the previous value.\n\n        if idx < (_len - 1):\n            idx_next = loc + 1\n            pos_next = pos\n\n            if idx_next == len(_keys[pos_next]):\n                pos_next += 1\n                idx_next = 0\n\n            if _keys[pos_next][idx_next] < key:\n                msg = '{0} not in sort order at index {1}'.format(repr(val), idx)\n                raise ValueError(msg)\n\n    def __setitem__(self, index, value):\n        \"\"\"\n        Replace the item at position *index* with *value*.\n\n        Supports slice notation. Raises a :exc:`ValueError` if the sort order\n        would be violated. When used with a slice and iterable, the\n        :exc:`ValueError` is raised before the list is mutated if the sort order\n        would be violated by the operation.\n        \"\"\"\n        _maxes, _lists, _keys, _pos = self._maxes, self._lists, self._keys, self._pos\n        _check_order = self._check_order\n\n        if isinstance(index, slice):\n            start, stop, step = self._slice(index)\n            indices = list(range(start, stop, step))\n\n            if step != 1:\n                if not hasattr(value, '__len__'):\n                    value = list(value)\n\n                indices = list(indices)\n\n                if len(value) != len(indices):\n                    raise ValueError(\n                        'attempt to assign sequence of size {0}'\n                        ' to extended slice of size {1}'\n                        .format(len(value), len(indices)))\n\n                # Keep a log of values that are set so that we can\n                # roll back changes if ordering is violated.\n\n                log = []\n                _append = log.append\n\n                for idx, val in zip(indices, value):\n                    pos, loc = _pos(idx)\n                    key = self._key(val)\n                    _append((idx, _keys[pos][loc], key, _lists[pos][loc], val))\n                    _keys[pos][loc] = key\n                    _lists[pos][loc] = val\n                    if len(_keys[pos]) == (loc + 1):\n                        _maxes[pos] = key\n\n                try:\n                    # Validate ordering of new values.\n\n                    for idx, oldkey, newkey, oldval, newval in log:\n                        _check_order(idx, newkey, newval)\n\n                except ValueError:\n\n                    # Roll back changes from log.\n\n                    for idx, oldkey, newkey, oldval, newval in log:\n                        pos, loc = _pos(idx)\n                        _keys[pos][loc] = oldkey\n                        _lists[pos][loc] = oldval\n                        if len(_keys[pos]) == (loc + 1):\n                            _maxes[pos] = oldkey\n\n                    raise\n            else:\n                # Test ordering using indexing. If the value given\n                # doesn't support getitem, convert it to a list.\n\n                if not hasattr(value, '__getitem__'):\n                    value = list(value)\n\n                # Check that the given values are ordered properly.\n\n                keys = list(map(self._key, value))\n                ordered = all(keys[pos - 1] <= keys[pos]\n                              for pos in range(1, len(keys)))\n\n                if not ordered:\n                    raise ValueError('given sequence not in sort order')\n\n                # Check ordering in context of sorted list.\n\n                if not start or not len(value):\n                    # Nothing to check on the lhs.\n                    pass\n                else:\n                    pos, loc = _pos(start - 1)\n                    if _keys[pos][loc] > keys[0]:\n                        msg = '{0} not in sort order at index {1}'.format(repr(value[0]), start)\n                        raise ValueError(msg)\n\n                if stop == len(self) or not len(value):\n                    # Nothing to check on the rhs.\n                    pass\n                else:\n                    # \"stop\" is exclusive so we don't need\n                    # to add one for the index.\n                    pos, loc = _pos(stop)\n                    if _keys[pos][loc] < keys[-1]:\n                        msg = '{0} not in sort order at index {1}'.format(repr(value[-1]), stop)\n                        raise ValueError(msg)\n\n                # Delete the existing values.\n\n                del self[index]\n\n                # Insert the new values.\n\n                _insert = self.insert\n                for idx, val in enumerate(value):\n                    _insert(start + idx, val)\n        else:\n            pos, loc = _pos(index)\n            key = self._key(value)\n            _check_order(index, key, value)\n            _keys[pos][loc] = key\n            _lists[pos][loc] = value\n            if len(_lists[pos]) == (loc + 1):\n                _maxes[pos] = key\n\n    def __iter__(self):\n        \"\"\"Create an iterator over the list.\"\"\"\n        return chain.from_iterable(self._lists)\n\n    def __reversed__(self):\n        \"\"\"Create an iterator to traverse the list in reverse.\"\"\"\n        return chain.from_iterable(list(map(reversed, reversed(self._lists))))\n\n    def __len__(self):\n        \"\"\"Return the number of elements in the list.\"\"\"\n        return self._len\n\n    def bisect_left(self, val):\n        \"\"\"\n        Similar to the *bisect* module in the standard library, this returns an\n        appropriate index to insert *val*. If *val* is already present, the\n        insertion point will be before (to the left of) any existing entries.\n        \"\"\"\n        _maxes = self._maxes\n\n        if not _maxes:\n            return 0\n\n        key = self._key(val)\n        pos = bisect_left(_maxes, key)\n\n        if pos == len(_maxes):\n            return self._len\n\n        idx = bisect_left(self._keys[pos], key)\n\n        return self._loc(pos, idx)\n\n    def bisect_right(self, val):\n        \"\"\"\n        Same as *bisect_left*, but if *val* is already present, the insertion\n        point will be after (to the right of) any existing entries.\n        \"\"\"\n        _maxes = self._maxes\n\n        if not _maxes:\n            return 0\n\n        key = self._key(val)\n        pos = bisect_right(_maxes, key)\n\n        if pos == len(_maxes):\n            return self._len\n\n        idx = bisect_right(self._keys[pos], key)\n\n        return self._loc(pos, idx)\n\n    bisect = bisect_right\n\n    def count(self, val):\n        \"\"\"Return the number of occurrences of *val* in the list.\"\"\"\n        _maxes = self._maxes\n\n        if not _maxes:\n            return 0\n\n        key = self._key(val)\n        pos = bisect_left(_maxes, key)\n\n        if pos == len(_maxes):\n            return 0\n\n        _keys = self._keys\n        _lists = self._lists\n\n        idx = bisect_left(_keys[pos], key)\n\n        total = 0\n        len_keys = len(_keys)\n        len_sublist = len(_keys[pos])\n\n        while True:\n            if _keys[pos][idx] != key:\n                return total\n            if _lists[pos][idx] == val:\n                total += 1\n            idx += 1\n            if idx == len_sublist:\n                pos += 1\n                if pos == len_keys:\n                    return total\n                len_sublist = len(_keys[pos])\n                idx = 0\n\n    def copy(self):\n        \"\"\"Return a shallow copy of the sorted list.\"\"\"\n        return self.__class__(self, key=self._key, load=self._load)\n\n    __copy__ = copy\n\n    def append(self, val):\n        \"\"\"\n        Append the element *val* to the list. Raises a ValueError if the *val*\n        would violate the sort order.\n        \"\"\"\n        _maxes, _lists, _keys = self._maxes, self._lists, self._keys\n\n        key = self._key(val)\n\n        if not _maxes:\n            _maxes.append(key)\n            _keys.append([key])\n            _lists.append([val])\n            self._len = 1\n            return\n\n        pos = len(_keys) - 1\n\n        if key < _keys[pos][-1]:\n            msg = '{0} not in sort order at index {1}'.format(repr(val), self._len)\n            raise ValueError(msg)\n\n        _maxes[pos] = key\n        _keys[pos].append(key)\n        _lists[pos].append(val)\n        self._len += 1\n        self._expand(pos)\n\n    def extend(self, values):\n        \"\"\"\n        Extend the list by appending all elements from the *values*. Raises a\n        ValueError if the sort order would be violated.\n        \"\"\"\n        _maxes, _keys, _lists, _load = self._maxes, self._keys, self._lists, self._load\n\n        if not isinstance(values, list):\n            values = list(values)\n\n        keys = list(map(self._key, values))\n\n        if any(keys[pos - 1] > keys[pos]\n               for pos in range(1, len(keys))):\n            raise ValueError('given sequence not in sort order')\n\n        offset = 0\n\n        if _maxes:\n            if keys[0] < _keys[-1][-1]:\n                msg = '{0} not in sort order at index {1}'.format(repr(values[0]), self._len)\n                raise ValueError(msg)\n\n            if len(_keys[-1]) < self._half:\n                _lists[-1].extend(values[:_load])\n                _keys[-1].extend(keys[:_load])\n                _maxes[-1] = _keys[-1][-1]\n                offset = _load\n\n        len_keys = len(_keys)\n\n        for idx in range(offset, len(keys), _load):\n            _lists.append(values[idx:(idx + _load)])\n            _keys.append(keys[idx:(idx + _load)])\n            _maxes.append(_keys[-1][-1])\n\n        _index = self._index\n\n        if len_keys == len(_keys):\n            len_index = len(_index)\n            if len_index > 0:\n                len_values = len(values)\n                child = len_index - 1\n                while child:\n                    _index[child] += len_values\n                    child = (child - 1) >> 1\n                _index[0] += len_values\n        else:\n            del _index[:]\n\n        self._len += len(values)\n\n    def insert(self, idx, val):\n        \"\"\"\n        Insert the element *val* into the list at *idx*. Raises a ValueError if\n        the *val* at *idx* would violate the sort order.\n        \"\"\"\n        _maxes, _lists, _keys, _len = self._maxes, self._lists, self._keys, self._len\n\n        if idx < 0:\n            idx += _len\n        if idx < 0:\n            idx = 0\n        if idx > _len:\n            idx = _len\n\n        key = self._key(val)\n\n        if not _maxes:\n            # The idx must be zero by the inequalities above.\n            _maxes.append(key)\n            _lists.append([val])\n            _keys.append([key])\n            self._len = 1\n            return\n\n        if not idx:\n            if key > _keys[0][0]:\n                msg = '{0} not in sort order at index {1}'.format(repr(val), 0)\n                raise ValueError(msg)\n            else:\n                _keys[0].insert(0, key)\n                _lists[0].insert(0, val)\n                self._expand(0)\n                self._len += 1\n                return\n\n        if idx == _len:\n            pos = len(_keys) - 1\n            if _keys[pos][-1] > key:\n                msg = '{0} not in sort order at index {1}'.format(repr(val), _len)\n                raise ValueError(msg)\n            else:\n                _keys[pos].append(key)\n                _lists[pos].append(val)\n                _maxes[pos] = _keys[pos][-1]\n                self._expand(pos)\n                self._len += 1\n                return\n\n        pos, idx = self._pos(idx)\n        idx_before = idx - 1\n        if idx_before < 0:\n            pos_before = pos - 1\n            idx_before = len(_keys[pos_before]) - 1\n        else:\n            pos_before = pos\n\n        before = _keys[pos_before][idx_before]\n        if before <= key <= _keys[pos][idx]:\n            _lists[pos].insert(idx, val)\n            _keys[pos].insert(idx, key)\n            self._expand(pos)\n            self._len += 1\n        else:\n            msg = '{0} not in sort order at index {1}'.format(repr(val), idx)\n            raise ValueError(msg)\n\n    def pop(self, idx=-1):\n        \"\"\"\n        Remove and return item at *idx* (default last).  Raises IndexError if\n        list is empty or index is out of range.  Negative indices are supported,\n        as for slice indices.\n        \"\"\"\n        if (idx < 0 and -idx > self._len) or (idx >= self._len):\n            raise IndexError('pop index out of range')\n\n        pos, idx = self._pos(idx)\n        val = self._lists[pos][idx]\n        self._delete(pos, idx)\n\n        return val\n\n    def index(self, val, start=None, stop=None):\n        \"\"\"\n        Return the smallest *k* such that L[k] == val and i <= k < j`.  Raises\n        ValueError if *val* is not present.  *stop* defaults to the end of the\n        list. *start* defaults to the beginning. Negative indices are supported,\n        as for slice indices.\n        \"\"\"\n        _len, _maxes = self._len, self._maxes\n\n        if not _maxes:\n            raise ValueError('{0} is not in list'.format(repr(val)))\n\n        if start is None:\n            start = 0\n        if start < 0:\n            start += _len\n        if start < 0:\n            start = 0\n\n        if stop is None:\n            stop = _len\n        if stop < 0:\n            stop += _len\n        if stop > _len:\n            stop = _len\n\n        if stop <= start:\n            raise ValueError('{0} is not in list'.format(repr(val)))\n\n        stop -= 1\n        key = self._key(val)\n        pos = bisect_left(_maxes, key)\n\n        if pos == len(_maxes):\n            raise ValueError('{0} is not in list'.format(repr(val)))\n\n        _keys = self._keys\n        _lists = self._lists\n\n        idx = bisect_left(_keys[pos], key)\n\n        len_keys = len(_keys)\n        len_sublist = len(_keys[pos])\n\n        while True:\n            if _keys[pos][idx] != key:\n                raise ValueError('{0} is not in list'.format(repr(val)))\n            if _lists[pos][idx] == val:\n                loc = self._loc(pos, idx)\n                if start <= loc <= stop:\n                    return loc\n                elif loc > stop:\n                    break\n            idx += 1\n            if idx == len_sublist:\n                pos += 1\n                if pos == len_keys:\n                    raise ValueError('{0} is not in list'.format(repr(val)))\n                len_sublist = len(_keys[pos])\n                idx = 0\n\n        raise ValueError('{0} is not in list'.format(repr(val)))\n\n    def as_list(self):\n        \"\"\"Very efficiently convert the SortedList to a list.\"\"\"\n        return reduce(iadd, self._lists, [])\n\n    def __add__(self, that):\n        \"\"\"\n        Return a new sorted list containing all the elements in *self* and\n        *that*. Elements in *that* do not need to be properly ordered with\n        respect to *self*.\n        \"\"\"\n        values = self.as_list()\n        values.extend(that)\n        return self.__class__(values, key=self._key, load=self._load)\n\n    def __iadd__(self, that):\n        \"\"\"\n        Update *self* to include all values in *that*. Elements in *that* do not\n        need to be properly ordered with respect to *self*.\n        \"\"\"\n        self.update(that)\n        return self\n\n    def __mul__(self, that):\n        \"\"\"\n        Return a new sorted list containing *that* shallow copies of each item\n        in SortedList.\n        \"\"\"\n        values = self.as_list() * that\n        return self.__class__(values, key=self._key, load=self._load)\n\n    def __imul__(self, that):\n        \"\"\"\n        Increase the length of the list by appending *that* shallow copies of\n        each item.\n        \"\"\"\n        values = self.as_list() * that\n        self.clear()\n        self.update(values)\n        return self\n\n    def __eq__(self, that):\n        \"\"\"Compare two Sequences for equality.\"\"\"\n        return ((self._len == len(that))\n                and all(lhs == rhs for lhs, rhs in zip(self, that)))\n\n    def __ne__(self, that):\n        \"\"\"Compare two Sequences for inequality.\"\"\"\n        return ((self._len != len(that))\n                or any(lhs != rhs for lhs, rhs in zip(self, that)))\n\n    def __lt__(self, that):\n        \"\"\"Compare two Sequences for less than.\"\"\"\n        return ((self._len <= len(that))\n                and all(lhs < rhs for lhs, rhs in zip(self, that)))\n\n    def __le__(self, that):\n        \"\"\"Compare two Sequences for less than equal.\"\"\"\n        return ((self._len <= len(that))\n                and all(lhs <= rhs for lhs, rhs in zip(self, that)))\n\n    def __gt__(self, that):\n        \"\"\"Compare two Sequences for greater than.\"\"\"\n        return ((self._len >= len(that))\n                and all(lhs > rhs for lhs, rhs in zip(self, that)))\n\n    def __ge__(self, that):\n        \"\"\"Compare two Sequences for greater than equal.\"\"\"\n        return ((self._len >= len(that))\n                and all(lhs >= rhs for lhs, rhs in zip(self, that)))\n\n    @recursive_repr\n    def __repr__(self):\n        \"\"\"Return string representation of SortedListWithKey.\"\"\"\n        temp = '{0}({1}, key={2}, load={3})'\n        return temp.format(\n            self.__class__.__name__,\n            repr(list(self)),\n            repr(self._key),\n            repr(self._load)\n        )\n\n    def _check(self):\n        try:\n            # Check load parameters.\n\n            assert self._load >= 4\n            assert self._half == (self._load >> 1)\n            assert self._twice == (self._load * 2)\n\n            # Check empty sorted list case.\n\n            if self._maxes == []:\n                assert self._keys == []\n                assert self._lists == []\n                return\n\n            assert len(self._maxes) > 0 and len(self._keys) > 0 and len(self._lists) > 0\n\n            # Check all sublists are sorted.\n\n            assert all(sublist[pos - 1] <= sublist[pos]\n                       for sublist in self._keys\n                       for pos in range(1, len(sublist)))\n\n            # Check beginning/end of sublists are sorted.\n\n            for pos in range(1, len(self._keys)):\n                assert self._keys[pos - 1][-1] <= self._keys[pos][0]\n\n            # Check length of _maxes and _lists match.\n\n            assert len(self._maxes) == len(self._lists) == len(self._keys)\n\n            # Check _keys matches _key mapped to _lists.\n\n            assert all(len(val_list) == len(key_list)\n                       for val_list, key_list in zip(self._lists, self._keys))\n            assert all(self._key(val) == key for val, key in\n                       zip((_val for _val_list in self._lists for _val in _val_list),\n                           (_key for _key_list in self._keys for _key in _key_list)))\n\n            # Check _maxes is a map of _keys.\n\n            assert all(self._maxes[pos] == self._keys[pos][-1]\n                       for pos in range(len(self._maxes)))\n\n            # Check load level is less than _twice.\n\n            assert all(len(sublist) <= self._twice for sublist in self._lists)\n\n            # Check load level is greater than _half for all\n            # but the last sublist.\n\n            assert all(len(self._lists[pos]) >= self._half\n                       for pos in range(0, len(self._lists) - 1))\n\n            # Check length.\n\n            assert self._len == sum(len(sublist) for sublist in self._lists)\n\n            # Check index.\n\n            if len(self._index):\n                assert len(self._index) == self._offset + len(self._lists)\n                assert self._len == self._index[0]\n\n                def test_offset_pos(pos):\n                    from_index = self._index[self._offset + pos]\n                    return from_index == len(self._lists[pos])\n\n                assert all(test_offset_pos(pos)\n                           for pos in range(len(self._lists)))\n\n                for pos in range(self._offset):\n                    child = (pos << 1) + 1\n                    if self._index[pos] == 0:\n                        assert child >= len(self._index)\n                    elif child + 1 == len(self._index):\n                        assert self._index[pos] == self._index[child]\n                    else:\n                        child_sum = self._index[child] + self._index[child + 1]\n                        assert self._index[pos] == child_sum\n\n        except:\n            import sys\n            import traceback\n\n            traceback.print_exc(file=sys.stdout)\n\n            print('len', self._len)\n            print('load', self._load, self._half, self._twice)\n            print('offset', self._offset)\n            print('len_index', len(self._index))\n            print('index', self._index)\n            print('len_maxes', len(self._maxes))\n            print('maxes', self._maxes)\n            print('len_keys', len(self._keys))\n            print('keys', self._keys)\n            print('len_lists', len(self._lists))\n            print('lists', self._lists)\n\n            raise\n"
  },
  {
    "path": "code/default/lib/noarch/sortedcontainers/sortedset.py",
    "content": "# -*- coding: utf-8 -*-\n#\n# Sorted set implementation.\n\nfrom .sortedlist import SortedList, recursive_repr\nfrom .sortedlistwithkey import SortedListWithKey\nfrom collections import Set, MutableSet, Sequence\nfrom itertools import chain\nimport operator as op\n\nclass SortedSet(MutableSet, Sequence):\n    \"\"\"\n    A `SortedSet` provides the same methods as a `set`.  Additionally, a\n    `SortedSet` maintains its items in sorted order, allowing the `SortedSet` to\n    be indexed.\n\n    Unlike a `set`, a `SortedSet` requires items be hashable and comparable.\n    \"\"\"\n    def __init__(self, iterable=None, key=None, load=1000, _set=None):\n        \"\"\"\n        A `SortedSet` provides the same methods as a `set`.  Additionally, a\n        `SortedSet` maintains its items in sorted order, allowing the\n        `SortedSet` to be indexed.\n\n        An optional *iterable* provides an initial series of items to populate\n        the `SortedSet`.\n\n        An optional *key* argument defines a callable that, like the `key`\n        argument to Python's `sorted` function, extracts a comparison key from\n        each set item. If no function is specified, the default compares the\n        set items directly.\n\n        An optional *load* specifies the load-factor of the set. The default\n        load factor of '1000' works well for sets from tens to tens of millions\n        of elements.  Good practice is to use a value that is the cube root of\n        the set size.  With billions of elements, the best load factor depends\n        on your usage.  It's best to leave the load factor at the default until\n        you start benchmarking.\n        \"\"\"\n        self._key = key\n        self._load = load\n\n        self._set = set() if _set is None else _set\n\n        _set = self._set\n        self.isdisjoint = _set.isdisjoint\n        self.issubset = _set.issubset\n        self.issuperset = _set.issuperset\n\n        if key is None:\n            self._list = SortedList(self._set, load=load)\n        else:\n            self._list = SortedListWithKey(self._set, key=key, load=load)\n\n        _list = self._list\n        self.bisect_left = _list.bisect_left\n        self.bisect = _list.bisect\n        self.bisect_right = _list.bisect_right\n        self.index = _list.index\n\n        if iterable is not None:\n            self.update(iterable)\n\n    def __contains__(self, value):\n        \"\"\"Return True if and only if *value* is an element in the set.\"\"\"\n        return (value in self._set)\n\n    def __getitem__(self, index):\n        \"\"\"\n        Return the element at position *index*.\n\n        Supports slice notation and negative indexes.\n        \"\"\"\n        return self._list[index]\n\n    def __delitem__(self, index):\n        \"\"\"\n        Remove the element at position *index*.\n\n        Supports slice notation and negative indexes.\n        \"\"\"\n        _list = self._list\n        if isinstance(index, slice):\n            values = _list[index]\n            self._set.difference_update(values)\n        else:\n            value = _list[index]\n            self._set.remove(value)\n        del _list[index]\n\n    def _make_cmp(set_op, doc):\n        def comparer(self, that):\n            if isinstance(that, SortedSet):\n                return set_op(self._set, that._set)\n            elif isinstance(that, Set):\n                return set_op(self._set, that)\n            else:\n                raise TypeError('can only compare to a Set')\n\n        comparer.__name__ = '__{0}__'.format(set_op.__name__)\n        comparer.__doc__ = 'Return True if and only if ' + doc\n\n        return comparer\n\n    __eq__ = _make_cmp(op.eq, 'self and *that* are equal sets.')\n    __ne__ = _make_cmp(op.ne, 'self and *that* are inequal sets.')\n    __lt__ = _make_cmp(op.lt, 'self is a proper subset of *that*.')\n    __gt__ = _make_cmp(op.gt, 'self is a proper superset of *that*.')\n    __le__ = _make_cmp(op.le, 'self is a subset of *that*.')\n    __ge__ = _make_cmp(op.ge, 'self is a superset of *that*.')\n\n    def __len__(self):\n        \"\"\"Return the number of elements in the set.\"\"\"\n        return len(self._set)\n\n    def __iter__(self):\n        \"\"\"\n        Return an iterator over the SortedSet. Elements are iterated over\n        in their sorted order.\n        \"\"\"\n        return iter(self._list)\n\n    def __reversed__(self):\n        \"\"\"\n        Return an iterator over the SortedSet. Elements are iterated over\n        in their reversed sorted order.\n        \"\"\"\n        return reversed(self._list)\n\n    def add(self, value):\n        \"\"\"Add the element *value* to the set.\"\"\"\n        if value not in self._set:\n            self._set.add(value)\n            self._list.add(value)\n\n    def clear(self):\n        \"\"\"Remove all elements from the set.\"\"\"\n        self._set.clear()\n        self._list.clear()\n\n    def copy(self):\n        \"\"\"Create a shallow copy of the sorted set.\"\"\"\n        return self.__class__(key=self._key, load=self._load, _set=set(self._set))\n\n    __copy__ = copy\n\n    def count(self, value):\n        \"\"\"Return the number of occurrences of *value* in the set.\"\"\"\n        return 1 if value in self._set else 0\n\n    def discard(self, value):\n        \"\"\"\n        Remove the first occurrence of *value*.  If *value* is not a member,\n        does nothing.\n        \"\"\"\n        if value in self._set:\n            self._set.remove(value)\n            self._list.discard(value)\n\n    def pop(self, index=-1):\n        \"\"\"\n        Remove and return item at *index* (default last).  Raises IndexError if\n        set is empty or index is out of range.  Negative indexes are supported,\n        as for slice indices.\n        \"\"\"\n        value = self._list.pop(index)\n        self._set.remove(value)\n        return value\n\n    def remove(self, value):\n        \"\"\"\n        Remove first occurrence of *value*.  Raises ValueError if\n        *value* is not present.\n        \"\"\"\n        self._set.remove(value)\n        self._list.remove(value)\n\n    def difference(self, *iterables):\n        \"\"\"\n        Return a new set with elements in the set that are not in the\n        *iterables*.\n        \"\"\"\n        diff = self._set.difference(*iterables)\n        new_set = self.__class__(key=self._key, load=self._load, _set=diff)\n        return new_set\n\n    __sub__ = difference\n    __rsub__ = __sub__\n\n    def difference_update(self, *iterables):\n        \"\"\"\n        Update the set, removing elements found in keeping only elements\n        found in any of the *iterables*.\n        \"\"\"\n        values = set(chain(*iterables))\n        if (4 * len(values)) > len(self):\n            self._set.difference_update(values)\n            self._list.clear()\n            self._list.update(self._set)\n        else:\n            _discard = self.discard\n            for value in values:\n                _discard(value)\n        return self\n\n    __isub__ = difference_update\n\n    def intersection(self, *iterables):\n        \"\"\"\n        Return a new set with elements common to the set and all *iterables*.\n        \"\"\"\n        comb = self._set.intersection(*iterables)\n        new_set = self.__class__(key=self._key, load=self._load, _set=comb)\n        return new_set\n\n    __and__ = intersection\n    __rand__ = __and__\n\n    def intersection_update(self, *iterables):\n        \"\"\"\n        Update the set, keeping only elements found in it and all *iterables*.\n        \"\"\"\n        self._set.intersection_update(*iterables)\n        self._list.clear()\n        self._list.update(self._set)\n        return self\n\n    __iand__ = intersection_update\n\n    def symmetric_difference(self, that):\n        \"\"\"\n        Return a new set with elements in either *self* or *that* but not both.\n        \"\"\"\n        diff = self._set.symmetric_difference(that)\n        new_set = self.__class__(key=self._key, load=self._load, _set=diff)\n        return new_set\n\n    __xor__ = symmetric_difference\n    __rxor__ = __xor__\n\n    def symmetric_difference_update(self, that):\n        \"\"\"\n        Update the set, keeping only elements found in either *self* or *that*,\n        but not in both.\n        \"\"\"\n        self._set.symmetric_difference_update(that)\n        self._list.clear()\n        self._list.update(self._set)\n        return self\n\n    __ixor__ = symmetric_difference_update\n\n    def union(self, *iterables):\n        \"\"\"\n        Return a new SortedSet with elements from the set and all *iterables*.\n        \"\"\"\n        return self.__class__(chain(iter(self), *iterables), key=self._key, load=self._load)\n\n    __or__ = union\n    __ror__ = __or__\n\n    def update(self, *iterables):\n        \"\"\"Update the set, adding elements from all *iterables*.\"\"\"\n        values = set(chain(*iterables))\n        if (4 * len(values)) > len(self):\n            self._set.update(values)\n            self._list.clear()\n            self._list.update(self._set)\n        else:\n            _add = self.add\n            for value in values:\n                _add(value)\n        return self\n\n    __ior__ = union\n\n    def __reduce__(self):\n        return (self.__class__, ((), self._key, self._load, self._set))\n\n    @recursive_repr\n    def __repr__(self):\n        temp = '{0}({1}, key={2}, load={3})'\n        return temp.format(\n            self.__class__.__name__,\n            repr(list(self)),\n            repr(self._key),\n            repr(self._load)\n        )\n\n    def _check(self):\n        self._list._check()\n        assert len(self._set) == len(self._list)\n        _set = self._set\n        assert all(val in _set for val in self._list)\n"
  },
  {
    "path": "code/default/lib/noarch/subj_alt_name.py",
    "content": "\"\"\"NDG HTTPS Client package\n\nUse pyasn1 to provide support for parsing ASN.1 formatted subjectAltName\ncontent for SSL peer verification.  Code based on:\n\nhttp://stackoverflow.com/questions/5519958/how-do-i-parse-subjectaltname-extension-data-using-pyasn1\n\"\"\"\n__author__ = \"P J Kershaw\"\n__date__ = \"01/02/12\"\n__copyright__ = \"(C) 2012 Science and Technology Facilities Council\"\n__license__ = \"BSD - see LICENSE file in top-level directory\"\n__contact__ = \"Philip.Kershaw@stfc.ac.uk\"\n__revision__ = '$Id$'\ntry:\n    from pyasn1.type import univ, constraint, char, namedtype, tag\n    \nexcept ImportError as e:\n    import_error_msg = ('Error importing pyasn1, subjectAltName check for SSL '\n                        'peer verification will be disabled.  Import error '\n                        'is: %s' % e)\n    import warnings\n    warnings.warn(import_error_msg)\n    class Pyasn1ImportError(ImportError):\n        \"Raise for pyasn1 import error\"\n    raise Pyasn1ImportError(import_error_msg)\n    \n    \nMAX = 64\n\n\nclass DirectoryString(univ.Choice):\n    \"\"\"ASN.1 Directory string class\"\"\"\n    componentType = namedtype.NamedTypes(\n        namedtype.NamedType(\n            'teletexString', char.TeletexString().subtype(\n                subtypeSpec=constraint.ValueSizeConstraint(1, MAX))),\n        namedtype.NamedType(\n            'printableString', char.PrintableString().subtype(\n                subtypeSpec=constraint.ValueSizeConstraint(1, MAX))),\n        namedtype.NamedType(\n            'universalString', char.UniversalString().subtype(\n                subtypeSpec=constraint.ValueSizeConstraint(1, MAX))),\n        namedtype.NamedType(\n            'utf8String', char.UTF8String().subtype(\n                subtypeSpec=constraint.ValueSizeConstraint(1, MAX))),\n        namedtype.NamedType(\n            'bmpString', char.BMPString().subtype(\n                subtypeSpec=constraint.ValueSizeConstraint(1, MAX))),\n        namedtype.NamedType(\n            'ia5String', char.IA5String().subtype(\n                subtypeSpec=constraint.ValueSizeConstraint(1, MAX))),\n        )\n\n\nclass AttributeValue(DirectoryString):\n    \"\"\"ASN.1 Attribute value\"\"\"\n\n\nclass AttributeType(univ.ObjectIdentifier):\n    \"\"\"ASN.1 Attribute type\"\"\"\n\n\nclass AttributeTypeAndValue(univ.Sequence):\n    \"\"\"ASN.1 Attribute type and value class\"\"\"\n    componentType = namedtype.NamedTypes(\n        namedtype.NamedType('type', AttributeType()),\n        namedtype.NamedType('value', AttributeValue()),\n        )\n\n\nclass RelativeDistinguishedName(univ.SetOf):\n    '''ASN.1 Realtive distinguished name'''\n    componentType = AttributeTypeAndValue()\n\nclass RDNSequence(univ.SequenceOf):\n    '''ASN.1 RDN sequence class'''\n    componentType = RelativeDistinguishedName()\n\n\nclass Name(univ.Choice):\n    '''ASN.1 name class'''\n    componentType = namedtype.NamedTypes(\n        namedtype.NamedType('', RDNSequence()),\n        )\n\n\nclass Extension(univ.Sequence):\n    '''ASN.1 extension class'''\n    componentType = namedtype.NamedTypes(\n        namedtype.NamedType('extnID', univ.ObjectIdentifier()),\n        namedtype.DefaultedNamedType('critical', univ.Boolean('False')),\n        namedtype.NamedType('extnValue', univ.OctetString()),\n        )\n\n\nclass Extensions(univ.SequenceOf):\n    '''ASN.1 extensions class'''\n    componentType = Extension()\n    sizeSpec = univ.SequenceOf.sizeSpec + constraint.ValueSizeConstraint(1, MAX)\n\n\nclass AnotherName(univ.Sequence):\n    componentType = namedtype.NamedTypes(\n        namedtype.NamedType('type-id', univ.ObjectIdentifier()),\n        namedtype.NamedType('value', univ.Any().subtype(\n                            explicitTag=tag.Tag(tag.tagClassContext,\n                                                tag.tagFormatSimple, 0)))\n        )\n\n\nclass GeneralName(univ.Choice):\n    '''ASN.1 configuration for X.509 certificate subjectAltNames fields'''\n    componentType = namedtype.NamedTypes(\n        namedtype.NamedType('otherName', AnotherName().subtype(\n                            implicitTag=tag.Tag(tag.tagClassContext,\n                                                tag.tagFormatSimple, 0))),\n        namedtype.NamedType('rfc822Name', char.IA5String().subtype(\n                            implicitTag=tag.Tag(tag.tagClassContext,\n                                                tag.tagFormatSimple, 1))),\n        namedtype.NamedType('dNSName', char.IA5String().subtype(\n                            implicitTag=tag.Tag(tag.tagClassContext,\n                                                tag.tagFormatSimple, 2))),\n#        namedtype.NamedType('x400Address', ORAddress().subtype(\n#                            implicitTag=tag.Tag(tag.tagClassContext,\n#                                                tag.tagFormatSimple, 3))),\n        namedtype.NamedType('directoryName', Name().subtype(\n                            implicitTag=tag.Tag(tag.tagClassContext,\n                                                tag.tagFormatSimple, 4))),\n#        namedtype.NamedType('ediPartyName', EDIPartyName().subtype(\n#                            implicitTag=tag.Tag(tag.tagClassContext,\n#                                                tag.tagFormatSimple, 5))),\n        namedtype.NamedType('uniformResourceIdentifier', char.IA5String().subtype(\n                            implicitTag=tag.Tag(tag.tagClassContext,\n                                                tag.tagFormatSimple, 6))),\n        namedtype.NamedType('iPAddress', univ.OctetString().subtype(\n                            implicitTag=tag.Tag(tag.tagClassContext,\n                                                tag.tagFormatSimple, 7))),\n        namedtype.NamedType('registeredID', univ.ObjectIdentifier().subtype(\n                            implicitTag=tag.Tag(tag.tagClassContext,\n                                                tag.tagFormatSimple, 8))),\n        )\n\n\nclass GeneralNames(univ.SequenceOf):\n    '''Sequence of names for ASN.1 subjectAltNames settings'''\n    componentType = GeneralName()\n    sizeSpec = univ.SequenceOf.sizeSpec + constraint.ValueSizeConstraint(1, MAX)\n\n\nclass SubjectAltName(GeneralNames):\n    '''ASN.1 implementation for subjectAltNames support'''\n\n\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/__init__.py",
    "content": "# Author: Trevor Perrin\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"TLS Lite is a free python library that implements SSL and TLS. TLS Lite\nsupports RSA and SRP ciphersuites. TLS Lite is pure python, however it can use\nother libraries for faster crypto operations. TLS Lite integrates with several\nstdlib neworking libraries.\n\nAPI documentation is available in the 'docs' directory.\n\nIf you have questions or feedback, feel free to contact me.\n\nTo use, do::\n\n    from tlslite import TLSConnection, ...\n\nIf you want to import the most useful objects, the cleanest way is::\n\n    from tlslite.api import *\n\nThen use the :py:class:`TLSConnection` class with a socket.\n(Or, use one of the integration classes in :py:mod:`tlslite.integration`).\n\"\"\"\n\nfrom tlslite.api import *\nfrom tlslite.api import __version__ # Unsure why this is needed, but it is\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/api.py",
    "content": "# Author: Trevor Perrin\n# See the LICENSE file for legal information regarding use of this file.\n\n__version__ = \"0.8.0-alpha43\"\nfrom .constants import AlertLevel, AlertDescription, Fault\nfrom .errors import *\nfrom .checker import Checker\nfrom .handshakesettings import HandshakeSettings\nfrom .session import Session\nfrom .sessioncache import SessionCache\nfrom .tlsconnection import TLSConnection\nfrom .verifierdb import VerifierDB\nfrom .x509 import X509\nfrom .x509certchain import X509CertChain\n\nfrom .utils.cryptomath import m2cryptoLoaded, gmpyLoaded, \\\n                             pycryptoLoaded, prngName, GMPY2_LOADED\nfrom .utils.keyfactory import generateRSAKey, parsePEMKey, \\\n                             parseAsPublicKey, parsePrivateKey\nfrom .utils.tackwrapper import tackpyLoaded\nfrom .dh import parse as parseDH\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/basedb.py",
    "content": "# Authors: \n#   Trevor Perrin\n#   Martin von Loewis - python 3 port\n#\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Base class for SharedKeyDB and VerifierDB.\"\"\"\n\ntry:\n    import anydbm\nexcept ImportError:\n    # Python 3\n    import dbm as anydbm\nimport threading\nimport time\nimport logging\n\nclass BaseDB(object):\n    def __init__(self, filename, type):\n        self.type = type\n        self.filename = filename\n        if self.filename:\n            self.db = None\n        else:\n            self.db = {}\n        self.lock = threading.Lock()\n\n    def create(self):\n        \"\"\"\n        Create a new on-disk database.\n\n        :raises anydbm.error: If there's a problem creating the database.\n        \"\"\"\n        logger = logging.getLogger(__name__)\n\n        if self.filename:\n            logger.debug('server %s - create - will open db', time.time())\n            self.db = anydbm.open(self.filename, \"n\") #raises anydbm.error\n            logger.debug('server %s - create - setting type', time.time())\n            self.db[\"--Reserved--type\"] = self.type\n            logger.debug('server %s - create - syncing', time.time())\n            self.db.sync()\n            logger.debug('server %s - create - fun exit', time.time())\n        else:\n            logger.debug('server %s - create - using dict() as DB',\n                         time.time())\n            self.db = {}\n\n    def open(self):\n        \"\"\"\n        Open a pre-existing on-disk database.\n\n        :raises anydbm.error: If there's a problem opening the database.\n        :raises ValueError: If the database is not of the right type.\n        \"\"\"\n        if not self.filename:\n            raise ValueError(\"Can only open on-disk databases\")\n        self.db = anydbm.open(self.filename, \"w\") #raises anydbm.error\n        try:\n            if self.db[\"--Reserved--type\"] != self.type:\n                raise ValueError(\"Not a %s database\" % self.type)\n        except KeyError:\n            raise ValueError(\"Not a recognized database\")\n\n    def __getitem__(self, username):\n        if self.db == None:\n            raise AssertionError(\"DB not open\")\n\n        self.lock.acquire()\n        try:\n            valueStr = self.db[username]\n        finally:\n            self.lock.release()\n\n        return self._getItem(username, valueStr)\n\n    def __setitem__(self, username, value):\n        if self.db == None:\n            raise AssertionError(\"DB not open\")\n\n        valueStr = self._setItem(username, value)\n\n        self.lock.acquire()\n        try:\n            self.db[username] = valueStr\n            if self.filename:\n                self.db.sync()\n        finally:\n            self.lock.release()\n\n    def __delitem__(self, username):\n        if self.db == None:\n            raise AssertionError(\"DB not open\")\n\n        self.lock.acquire()\n        try:\n            del(self.db[username])\n            if self.filename:\n                self.db.sync()\n        finally:\n            self.lock.release()\n\n    def __contains__(self, username):\n        \"\"\"\n        Check if the database contains the specified username.\n\n        :param str username: The username to check for.\n\n        :rtype: bool\n        :returns: True if the database contains the username, False\n            otherwise.\n        \"\"\"\n        if self.db == None:\n            raise AssertionError(\"DB not open\")\n\n        self.lock.acquire()\n        try:\n            return username in self.db\n        finally:\n            self.lock.release()\n\n    def check(self, username, param):\n        value = self.__getitem__(username)\n        return self._checkItem(value, username, param)\n\n    def keys(self):\n        \"\"\"\n        Return a list of usernames in the database.\n\n        :rtype: list\n        :returns: The usernames in the database.\n        \"\"\"\n        if self.db == None:\n            raise AssertionError(\"DB not open\")\n\n        self.lock.acquire()\n        try:\n            usernames = self.db.keys()\n        finally:\n            self.lock.release()\n        usernames = [u for u in usernames if not u.startswith(\"--Reserved--\")]\n        return usernames\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/bufferedsocket.py",
    "content": "# Copyright (c) 2016, Hubert Kario\n#\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Wrapper around the socket.socket interface that provides buffering\"\"\"\n\nfrom collections import deque\n\n\nclass BufferedSocket(object):\n    \"\"\"\n    Socket that will buffer reads and writes to a real socket object\n\n    When buffer_writes is enabled, writes won't be passed to the real socket\n    until flush() is called.\n\n    Not multithread safe.\n\n    :vartype buffer_writes: boolean\n    :ivar buffer_writes: whether to buffer data writes, False by default\n    \"\"\"\n\n    def __init__(self, socket):\n        \"\"\"Associate socket with the object\"\"\"\n        self.socket = socket\n        self._write_queue = deque()\n        self.buffer_writes = False\n        self._read_buffer = bytearray()\n\n    def send(self, data):\n        \"\"\"Send data to the socket\"\"\"\n        if self.buffer_writes:\n            self._write_queue.append(data)\n            return len(data)\n        return self.socket.send(data)\n\n    def sendall(self, data):\n        \"\"\"Send data to the socket\"\"\"\n        if self.buffer_writes:\n            self._write_queue.append(data)\n            return None\n        return self.socket.sendall(data)\n\n    def flush(self):\n        \"\"\"Send all buffered data\"\"\"\n        buf = bytearray()\n        for i in self._write_queue:\n            buf += i\n        self._write_queue.clear()\n        if buf:\n            self.socket.sendall(buf)\n\n    def recv(self, bufsize):\n        \"\"\"Receive data from socket (socket emulation)\"\"\"\n        if not self._read_buffer:\n            self._read_buffer += self.socket.recv(max(4096, bufsize))\n        ret = self._read_buffer[:bufsize]\n        del self._read_buffer[:bufsize]\n        return ret\n\n    def getsockname(self):\n        \"\"\"Return the socket's own address (socket emulation).\"\"\"\n        return self.socket.getsockname()\n\n    def getpeername(self):\n        \"\"\"\n        Return the remote address to which the socket is connected\n\n        (socket emulation)\n        \"\"\"\n        return self.socket.getpeername()\n\n    def settimeout(self, value):\n        \"\"\"Set a timeout on blocking socket operations (socket emulation).\"\"\"\n        return self.socket.settimeout(value)\n\n    def gettimeout(self):\n        \"\"\"\n        Return the timeout associated with socket operations\n\n        (socket emulation)\n        \"\"\"\n        return self.socket.gettimeout()\n\n    def setsockopt(self, level, optname, value):\n        \"\"\"Set the value of the given socket option (socket emulation).\"\"\"\n        return self.socket.setsockopt(level, optname, value)\n\n    def shutdown(self, how):\n        \"\"\"Shutdown the underlying socket.\"\"\"\n        self.flush()\n        return self.socket.shutdown(how)\n\n    def close(self):\n        \"\"\"Close the underlying socket.\"\"\"\n        self.flush()\n        return self.socket.close()\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/checker.py",
    "content": "# Author: Trevor Perrin\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Class for post-handshake certificate checking.\"\"\"\n\nfrom .x509 import X509\nfrom .x509certchain import X509CertChain\nfrom .errors import *\n\n\nclass Checker(object):\n    \"\"\"\n    This class is passed to a handshake function to check the other\n    party's certificate chain.\n\n    If a handshake function completes successfully, but the Checker\n    judges the other party's certificate chain to be missing or\n    inadequate, a subclass of\n    :py:class:`tlslite.errors.TLSAuthenticationError`\n    will be raised.\n\n    Currently, the Checker can check an X.509 chain.\n    \"\"\"\n\n    def __init__(self,\n                 x509Fingerprint=None,\n                 checkResumedSession=False):\n        \"\"\"\n        Create a new Checker instance.\n\n        You must pass in one of these argument combinations:\n         - x509Fingerprint\n\n        :param str x509Fingerprint: A hex-encoded X.509 end-entity\n            fingerprint which the other party's end-entity certificate must\n            match.\n\n        :param bool checkResumedSession: If resumed sessions should be\n            checked.  This defaults to False, on the theory that if the\n            session was checked once, we don't need to bother\n            re-checking it.\n        \"\"\"\n\n        self.x509Fingerprint = x509Fingerprint\n        self.checkResumedSession = checkResumedSession\n\n    def __call__(self, connection):\n        \"\"\"Check a TLSConnection.\n\n        When a Checker is passed to a handshake function, this will\n        be called at the end of the function.\n\n        :param tlslite.tlsconnection.TLSConnection connection: The\n            TLSConnection to examine.\n\n        :raises tlslite.errors.TLSAuthenticationError: If the other\n            party's certificate chain is missing or bad.\n        \"\"\"\n        if not self.checkResumedSession and connection.resumed:\n            return\n\n        if self.x509Fingerprint:\n            if connection._client:\n                chain = connection.session.serverCertChain\n            else:\n                chain = connection.session.clientCertChain\n\n            if self.x509Fingerprint:\n                if isinstance(chain, X509CertChain):\n                    if self.x509Fingerprint:\n                        if chain.getFingerprint() != self.x509Fingerprint:\n                            raise TLSFingerprintError(\\\n                                \"X.509 fingerprint mismatch: %s, %s\" % \\\n                                (chain.getFingerprint(), self.x509Fingerprint))\n                elif chain:\n                    raise TLSAuthenticationTypeError()\n                else:\n                    raise TLSNoAuthenticationError()\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/constants.py",
    "content": "# Authors: \n#   Trevor Perrin\n#   Google - defining ClientCertificateType\n#   Google (adapted by Sam Rushing) - NPN support\n#   Dimitris Moraitis - Anon ciphersuites\n#   Dave Baggett (Arcode Corporation) - canonicalCipherName\n#   Yngve Pettersen (ported by Paul Sokolovsky) - TLS 1.2\n#\n# See the LICENSE file for legal information regarding use of this file.\n\nfrom .utils.compat import a2b_hex\n\n\"\"\"Constants used in various places.\"\"\"\n\n\n# protocol version number used for negotiating TLS 1.3 between implementations\n# of the draft specification\n# DEPRECATED!\nTLS_1_3_DRAFT = (3, 4)\n\n\n# ServerHello.random value meaning that the message is a HelloRetryRequest\nTLS_1_3_HRR = a2b_hex(\"CF21AD74E59A6111BE1D8C021E65B891\"\n                      \"C2A211167ABB8C5E079E09E2C8A8339C\")\n\n# last bytes of ServerHello.random to be used when negotiating TLS 1.1 or\n# earlier while supporting TLS 1.2 or greater\nTLS_1_1_DOWNGRADE_SENTINEL = a2b_hex(\"444F574E47524400\")\n\n# last bytes of ServerHello.random to be used when negotiating TLS 1.2\n# while supporting TLS 1.3 or greater\nTLS_1_2_DOWNGRADE_SENTINEL = a2b_hex(\"444F574E47524401\")\n\nRSA_PSS_OID = bytes(a2b_hex('06092a864886f70d01010a'))\n\n\nclass TLSEnum(object):\n    \"\"\"Base class for different enums of TLS IDs\"\"\"\n\n    @classmethod\n    def _recursiveVars(cls, klass):\n        \"\"\"Call vars recursively on base classes\"\"\"\n        fields = dict()\n        for basecls in klass.__bases__:\n            fields.update(cls._recursiveVars(basecls))\n        fields.update(dict(vars(klass)))\n        return fields\n\n    @classmethod\n    def toRepr(cls, value, blacklist=None):\n        \"\"\"\n        Convert numeric type to string representation\n\n        name if found, None otherwise\n        \"\"\"\n        fields = cls._recursiveVars(cls)\n        if blacklist is None:\n            blacklist = []\n        return next((key for key, val in fields.items() \\\n                    if key not in ('__weakref__', '__dict__', '__doc__',\n                                   '__module__') and \\\n                       key not in blacklist and \\\n                        val == value), None)\n\n    @classmethod\n    def toStr(cls, value, blacklist=None):\n        \"\"\"Convert numeric type to human-readable string if possible\"\"\"\n        ret = cls.toRepr(value, blacklist)\n        if ret is not None:\n            return ret\n        else:\n            return '{0}'.format(value)\n\n\nclass CertificateType(TLSEnum):\n    x509 = 0\n    openpgp = 1\n\n\nclass ClientCertificateType(TLSEnum):\n    rsa_sign = 1\n    dss_sign = 2\n    rsa_fixed_dh = 3\n    dss_fixed_dh = 4\n    ecdsa_sign = 64  # RFC 8422\n    rsa_fixed_ecdh = 65  # RFC 8422\n    ecdsa_fixed_ecdh = 66  # RFC 8422\n\n\nclass SSL2HandshakeType(TLSEnum):\n    \"\"\"SSL2 Handshake Protocol message types.\"\"\"\n\n    error = 0\n    client_hello = 1\n    client_master_key = 2\n    client_finished = 3\n    server_hello = 4\n    server_verify = 5\n    server_finished = 6\n    request_certificate = 7\n    client_certificate = 8\n\n\nclass SSL2ErrorDescription(TLSEnum):\n    \"\"\"SSL2 Handshake protocol error message descriptions\"\"\"\n\n    no_cipher = 0x0001\n    no_certificate = 0x0002\n    bad_certificate = 0x0004\n    unsupported_certificate_type = 0x0006\n\n\nclass HandshakeType(TLSEnum):\n    \"\"\"Message types in TLS Handshake protocol\"\"\"\n\n    hello_request = 0\n    client_hello = 1\n    server_hello = 2\n    new_session_ticket = 4\n    hello_retry_request = 6  # draft version of TLS 1.3\n    encrypted_extensions = 8\n    certificate = 11\n    server_key_exchange = 12\n    certificate_request = 13\n    server_hello_done = 14\n    certificate_verify = 15\n    client_key_exchange = 16\n    finished = 20\n    certificate_status = 22\n    key_update = 24  # TLS 1.3\n    compressed_certificate = 25  # TLS 1.3\n    next_protocol = 67\n    message_hash = 254  # TLS 1.3\n\n\nclass ContentType(TLSEnum):\n    \"\"\"TLS record layer content types of payloads\"\"\"\n\n    change_cipher_spec = 20\n    alert = 21\n    handshake = 22\n    application_data = 23\n    heartbeat = 24  # RFC 6520\n    all = (20, 21, 22, 23, 24)\n\n    @classmethod\n    def toRepr(cls, value, blacklist=None):\n        \"\"\"Convert numeric type to name representation\"\"\"\n        if blacklist is None:\n            blacklist = []\n        blacklist.append('all')\n        return super(ContentType, cls).toRepr(value, blacklist)\n\n\nclass ExtensionType(TLSEnum):\n    \"\"\"TLS Extension Type registry values\"\"\"\n\n    server_name = 0  # RFC 6066 / 4366\n    max_fragment_length = 1  # RFC 6066 / 4366\n    status_request = 5  # RFC 6066 / 4366\n    cert_type = 9  # RFC 6091\n    supported_groups = 10  # RFC 4492, RFC-ietf-tls-negotiated-ff-dhe-10\n    ec_point_formats = 11  # RFC 4492\n    srp = 12  # RFC 5054\n    signature_algorithms = 13  # RFC 5246\n    heartbeat = 15  # RFC 6520\n    alpn = 16  # RFC 7301\n    signed_certificate_timestamp = 18\n    client_hello_padding = 21  # RFC 7685\n    encrypt_then_mac = 22  # RFC 7366\n    extended_master_secret = 23  # RFC 7627\n    compress_certificate = 27  # RFC 8446\n    record_size_limit = 28  # RFC 8449\n    session_ticket = 35\n    extended_random = 40  # draft-rescorla-tls-extended-random-02\n    pre_shared_key = 41  # TLS 1.3\n    early_data = 42  # TLS 1.3\n    supported_versions = 43  # TLS 1.3\n    cookie = 44  # TLS 1.3\n    psk_key_exchange_modes = 45  # TLS 1.3\n    post_handshake_auth = 49  # TLS 1.3\n    signature_algorithms_cert = 50  # TLS 1.3\n    key_share = 51  # TLS 1.3\n    supports_npn = 13172\n    application_settings = 17513\n    tack = 0xF300\n    renegotiation_info = 0xff01  # RFC 5746\n\n\nclass HashAlgorithm(TLSEnum):\n    \"\"\"Hash algorithm IDs used in TLSv1.2\"\"\"\n\n    none = 0\n    md5 = 1\n    sha1 = 2\n    sha224 = 3\n    sha256 = 4\n    sha384 = 5\n    sha512 = 6\n    intrinsic = 8  # RFC 8422\n\n\nclass SignatureAlgorithm(TLSEnum):\n    \"\"\"Signing algorithms used in TLSv1.2\"\"\"\n\n    anonymous = 0\n    rsa = 1\n    dsa = 2\n    ecdsa = 3\n    ed25519 = 7  # RFC 8422\n    ed448 = 8  # RFC 8422\n\n\nclass SignatureScheme(TLSEnum):\n    \"\"\"\n    Signature scheme used for signalling supported signature algorithms.\n\n    This is the replacement for the HashAlgorithm and SignatureAlgorithm\n    lists. Introduced with TLSv1.3.\n    \"\"\"\n\n    rsa_pkcs1_sha1 = (2, 1)\n    rsa_pkcs1_sha224 = (3, 1)\n    rsa_pkcs1_sha256 = (4, 1)\n    rsa_pkcs1_sha384 = (5, 1)\n    rsa_pkcs1_sha512 = (6, 1)\n    ecdsa_sha1 = (2, 3)\n    ecdsa_sha224 = (3, 3)\n    ecdsa_secp256r1_sha256 = (4, 3)\n    ecdsa_secp384r1_sha384 = (5, 3)\n    ecdsa_secp521r1_sha512 = (6, 3)\n    rsa_pss_rsae_sha256 = (8, 4)\n    rsa_pss_rsae_sha384 = (8, 5)\n    rsa_pss_rsae_sha512 = (8, 6)\n    ed25519 = (8, 7)  # RFC 8422\n    ed448 = (8, 8)  # RFC 8422\n    rsa_pss_pss_sha256 = (8, 9)\n    rsa_pss_pss_sha384 = (8, 10)\n    rsa_pss_pss_sha512 = (8, 11)\n\n    # backwards compatibility (for TLS1.2)\n    rsa_pss_sha256 = (8, 4)\n    rsa_pss_sha384 = (8, 5)\n    rsa_pss_sha512 = (8, 6)\n\n    dsa_sha1 = (2, 2)\n    dsa_sha224 = (3, 2)\n    dsa_sha256 = (4, 2)\n    dsa_sha384 = (5, 2)\n    dsa_sha512 = (6, 2)\n\n    @classmethod\n    def toRepr(cls, value, blacklist=None):\n        \"\"\"Convert numeric type to name representation\"\"\"\n        if blacklist is None:\n            blacklist = []\n        blacklist += ['getKeyType', 'getPadding', 'getHash',\n                      'rsa_pss_sha256', 'rsa_pss_sha384', 'rsa_pss_sha512']\n\n        return super(SignatureScheme, cls).toRepr(value, blacklist)\n\n    @staticmethod\n    def getKeyType(scheme):\n        \"\"\"\n        Return the name of the signature algorithm used in scheme.\n\n        E.g. for \"rsa_pkcs1_sha1\" it returns \"rsa\"\n        \"\"\"\n        if scheme in (\"ed25519\", \"ed448\"):\n            return \"eddsa\"\n        try:\n            getattr(SignatureScheme, scheme)\n        except AttributeError:\n            raise ValueError(\"\\\"{0}\\\" scheme is unknown\".format(scheme))\n        vals = scheme.split('_', 4)\n        return vals[0]\n\n    @staticmethod\n    def getPadding(scheme):\n        \"\"\"Return the name of padding scheme used in signature scheme.\"\"\"\n        try:\n            getattr(SignatureScheme, scheme)\n        except AttributeError:\n            raise ValueError(\"\\\"{0}\\\" scheme is unknown\".format(scheme))\n        vals = scheme.split('_', 4)\n        assert len(vals) in (3, 4)\n        if len(vals) == 3:\n            kType, padding, _ = vals\n        else:\n            kType, padding, _, _ = vals\n        assert kType == 'rsa'\n        return padding\n\n    @staticmethod\n    def getHash(scheme):\n        \"\"\"Return the name of hash used in signature scheme.\"\"\"\n        # there is no explicit hash in the EDDSA, see RFC 8422\n        if scheme in (\"ed25519\", \"ed448\"):\n            return \"intrinsic\"\n        try:\n            getattr(SignatureScheme, scheme)\n        except AttributeError:\n            raise ValueError(\"\\\"{0}\\\" scheme is unknown\".format(scheme))\n        vals = scheme.split('_', 4)\n        assert len(vals) in (2, 3, 4)\n        if len(vals) == 2:\n            kType, hName = vals\n        elif len(vals) == 3:\n            kType, _, hName = vals\n        else:\n            kType, _, _, hName = vals\n        assert kType in ('rsa', 'ecdsa', 'dsa')\n        return hName\n\n\nclass AlgorithmOID(TLSEnum):\n    \"\"\"\n    Algorithm OIDs as defined in rfc5758(ecdsa),\n    rfc5754(rsa, sha), rfc3447(rss-pss).\n    The key is the DER encoded OID in hex and\n    the value is the algorithm id.\n    \"\"\"\n    oid = {}\n\n    oid[bytes(a2b_hex('06072a8648ce3d0401'))] = \\\n            SignatureScheme.ecdsa_sha1\n    oid[bytes(a2b_hex('06082a8648ce3d040301'))] = \\\n            SignatureScheme.ecdsa_sha224\n    oid[bytes(a2b_hex('06082a8648ce3d040302'))] = \\\n            SignatureScheme.ecdsa_secp256r1_sha256\n    oid[bytes(a2b_hex('06082a8648ce3d040303'))] = \\\n            SignatureScheme.ecdsa_secp384r1_sha384\n    oid[bytes(a2b_hex('06082a8648ce3d040304'))] = \\\n            SignatureScheme.ecdsa_secp521r1_sha512\n    oid[bytes(a2b_hex('06092a864886f70d010104'))] = \\\n            (HashAlgorithm.md5, SignatureAlgorithm.rsa)\n    oid[bytes(a2b_hex('06092a864886f70d010105'))] = \\\n            SignatureScheme.rsa_pkcs1_sha1\n    oid[bytes(a2b_hex('06092a864886f70d01010e'))] = \\\n            SignatureScheme.rsa_pkcs1_sha224\n    oid[bytes(a2b_hex('06092a864886f70d01010b'))] = \\\n            SignatureScheme.rsa_pkcs1_sha256\n    oid[bytes(a2b_hex('06092a864886f70d01010c'))] = \\\n            SignatureScheme.rsa_pkcs1_sha384\n    oid[bytes(a2b_hex('06092a864886f70d01010d'))] = \\\n            SignatureScheme.rsa_pkcs1_sha512\n    oid[bytes(a2b_hex('300b0609608648016503040201'))] = \\\n            SignatureScheme.rsa_pss_rsae_sha256\n    oid[bytes(a2b_hex('300b0609608648016503040202'))] = \\\n            SignatureScheme.rsa_pss_rsae_sha384\n    oid[bytes(a2b_hex('300b0609608648016503040203'))] = \\\n            SignatureScheme.rsa_pss_rsae_sha512\n    # for RSA-PSS an AlgorithmIdentifier with and without NULL parameters\n    # is valid. See RFC 4055 Section 2.1\n    oid[bytes(a2b_hex('300d06096086480165030402010500'))] = \\\n            SignatureScheme.rsa_pss_rsae_sha256\n    oid[bytes(a2b_hex('300d06096086480165030402020500'))] = \\\n            SignatureScheme.rsa_pss_rsae_sha384\n    oid[bytes(a2b_hex('300d06096086480165030402030500'))] = \\\n            SignatureScheme.rsa_pss_rsae_sha512\n    oid[bytes(a2b_hex('06072A8648CE380403'))] = \\\n            SignatureScheme.dsa_sha1\n    oid[bytes(a2b_hex('0609608648016503040301'))] = \\\n            SignatureScheme.dsa_sha224\n    oid[bytes(a2b_hex('0609608648016503040302'))] = \\\n            SignatureScheme.dsa_sha256\n    oid[bytes(a2b_hex('0609608648016503040303'))] = \\\n            SignatureScheme.dsa_sha384\n    oid[bytes(a2b_hex('0609608648016503040304'))] = \\\n            SignatureScheme.dsa_sha512\n    oid[bytes(a2b_hex('06032b6570'))] = \\\n            SignatureScheme.ed25519\n    oid[bytes(a2b_hex('06032b6571'))] = \\\n            SignatureScheme.ed448\n\n\nclass GroupName(TLSEnum):\n    \"\"\"Name of groups supported for (EC)DH key exchange\"\"\"\n\n    # RFC4492\n    sect163k1 = 1\n    sect163r1 = 2\n    sect163r2 = 3\n    sect193r1 = 4\n    sect193r2 = 5\n    sect233k1 = 6\n    sect233r1 = 7\n    sect239k1 = 8\n    sect283k1 = 9\n    sect283r1 = 10\n    sect409k1 = 11\n    sect409r1 = 12\n    sect571k1 = 13\n    sect571r1 = 14\n    secp160k1 = 15\n    secp160r1 = 16\n    secp160r2 = 17\n    secp192k1 = 18\n    secp192r1 = 19\n    secp224k1 = 20\n    secp224r1 = 21\n    secp256k1 = 22\n    secp256r1 = 23\n    secp384r1 = 24\n    secp521r1 = 25\n    allEC = list(range(1, 26))\n\n    # RFC7027\n    brainpoolP256r1 = 26\n    brainpoolP384r1 = 27\n    brainpoolP512r1 = 28\n    allEC.extend(list(range(26, 29)))\n\n    # draft-ietf-tls-rfc4492bis\n    x25519 = 29\n    x448 = 30\n    allEC.extend(list(range(29, 31)))\n\n    # RFC7919\n    ffdhe2048 = 256\n    ffdhe3072 = 257\n    ffdhe4096 = 258\n    ffdhe6144 = 259\n    ffdhe8192 = 260\n    allFF = list(range(256, 261))\n\n    all = allEC + allFF\n\n    @classmethod\n    def toRepr(cls, value, blacklist=None):\n        \"\"\"Convert numeric type to name representation\"\"\"\n        if blacklist is None:\n            blacklist = []\n        blacklist += ['all', 'allEC', 'allFF']\n        return super(GroupName, cls).toRepr(value, blacklist)\n\n\n# groups forbidden by RFC 8446 section B.3.1.4\nTLS_1_3_FORBIDDEN_GROUPS = frozenset().union(\n    range(1, 0x17),\n    range(0x1A, 0x1D),\n    (0xff01, 0xff02))\n\n\nclass ECPointFormat(TLSEnum):\n    \"\"\"Names and ID's of supported EC point formats.\"\"\"\n\n    uncompressed = 0\n    ansiX962_compressed_prime = 1\n    ansiX962_compressed_char2 = 2\n\n    all = [uncompressed,\n           ansiX962_compressed_prime,\n           ansiX962_compressed_char2]\n\n    @classmethod\n    def toRepr(cls, value, blacklist=None):\n        \"\"\"Convert numeric type to name representation.\"\"\"\n        if blacklist is None:\n            blacklist = []\n        blacklist.append('all')\n        return super(ECPointFormat, cls).toRepr(value, blacklist)\n\n\nclass ECCurveType(TLSEnum):\n    \"\"\"Types of ECC curves supported in TLS from RFC4492\"\"\"\n\n    explicit_prime = 1\n    explicit_char2 = 2\n    named_curve = 3\n\n\nclass NameType(TLSEnum):\n    \"\"\"Type of entries in Server Name Indication extension.\"\"\"\n\n    host_name = 0\n\n\nclass CertificateStatusType(TLSEnum):\n    \"\"\"Type of responses in the status_request and CertificateStatus msgs.\"\"\"\n\n    ocsp = 1\n\n\nclass HeartbeatMode(TLSEnum):\n    \"\"\"Types of heartbeat modes from RFC 6520\"\"\"\n\n    PEER_ALLOWED_TO_SEND = 1\n    PEER_NOT_ALLOWED_TO_SEND = 2\n\n\nclass HeartbeatMessageType(TLSEnum):\n    \"\"\"Types of heartbeat messages from RFC 6520\"\"\"\n\n    heartbeat_request = 1\n    heartbeat_response = 2\n\n\nclass KeyUpdateMessageType(TLSEnum):\n    \"\"\"Types of keyupdate messages from RFC 8446\"\"\"\n\n    update_not_requested = 0\n    update_requested = 1\n\n\nclass AlertLevel(TLSEnum):\n    \"\"\"Enumeration of TLS Alert protocol levels\"\"\"\n\n    warning = 1\n    fatal = 2\n\n\nclass AlertDescription(TLSEnum):\n    \"\"\"\n    :cvar bad_record_mac: A TLS record failed to decrypt properly.\n\n        If this occurs during a SRP handshake it most likely\n        indicates a bad password.  It may also indicate an implementation\n        error, or some tampering with the data in transit.\n\n        This alert will be signalled by the server if the SRP password is bad.\n        It\n        may also be signalled by the server if the SRP username is unknown to\n        the\n        server, but it doesn't wish to reveal that fact.\n\n\n    :cvar handshake_failure: A problem occurred while handshaking.\n\n        This typically indicates a lack of common ciphersuites between client\n        and\n        server, or some other disagreement (about SRP parameters or key sizes,\n        for example).\n\n    :cvar protocol_version: The other party's SSL/TLS version was unacceptable.\n\n        This indicates that the client and server couldn't agree on which\n        version\n        of SSL or TLS to use.\n\n    :cvar user_canceled: The handshake is being cancelled for some reason.\n    \"\"\"\n\n    close_notify = 0\n    unexpected_message = 10\n    bad_record_mac = 20\n    decryption_failed = 21\n    record_overflow = 22\n    decompression_failure = 30\n    handshake_failure = 40\n    no_certificate = 41 #SSLv3\n    bad_certificate = 42\n    unsupported_certificate = 43\n    certificate_revoked = 44\n    certificate_expired = 45\n    certificate_unknown = 46\n    illegal_parameter = 47\n    unknown_ca = 48\n    access_denied = 49\n    decode_error = 50\n    decrypt_error = 51\n    export_restriction = 60\n    protocol_version = 70\n    insufficient_security = 71\n    internal_error = 80\n    inappropriate_fallback = 86\n    user_canceled = 90\n    no_renegotiation = 100\n    missing_extension = 109\n    unsupported_extension = 110  # RFC 5246\n    certificate_unobtainable = 111  # RFC 6066\n    unrecognized_name = 112  # RFC 6066\n    bad_certificate_status_response = 113  # RFC 6066\n    bad_certificate_hash_value = 114  # RFC 6066\n    unknown_psk_identity = 115\n    certificate_required = 116  # RFC 8446\n    no_application_protocol = 120  # RFC 7301\n\n\nclass PskKeyExchangeMode(TLSEnum):\n    \"\"\"Values used in the PSK Key Exchange Modes extension.\"\"\"\n\n    psk_ke = 0\n    psk_dhe_ke = 1\n\n\nclass CipherSuite:\n\n    \"\"\"\n    Numeric values of ciphersuites and ciphersuite types\n\n    :cvar tripleDESSuites: ciphersuties which use 3DES symmetric cipher in CBC\n        mode\n    :cvar aes128Suites: ciphersuites which use AES symmetric cipher in CBC mode\n        with 128 bit key\n    :cvar aes256Suites: ciphersuites which use AES symmetric cipher in CBC mode\n        with 256 bit key\n    :cvar rc4Suites: ciphersuites which use RC4 symmetric cipher with 128 bit\n        key\n    :cvar shaSuites: ciphersuites which use SHA-1 HMAC integrity mechanism\n        and protocol default Pseudo Random Function\n    :cvar sha256Suites: ciphersuites which use SHA-256 HMAC integrity mechanism\n        and SHA-256 Pseudo Random Function\n    :cvar md5Suites: ciphersuites which use MD-5 HMAC integrity mechanism and\n        protocol default Pseudo Random Function\n    :cvar srpSuites: ciphersuites which use Secure Remote Password (SRP) key\n        exchange protocol\n    :cvar srpCertSuites: ciphersuites which use Secure Remote Password (SRP)\n        key exchange protocol with RSA server authentication\n    :cvar srpAllSuites: all SRP ciphersuites, pure SRP and with RSA based\n        server authentication\n    :cvar certSuites: ciphersuites which use RSA key exchange with RSA server\n        authentication\n    :cvar certAllSuites: ciphersuites which use RSA server authentication\n    :cvar anonSuites: ciphersuites which use anonymous Finite Field\n        Diffie-Hellman key exchange\n    :cvar ietfNames: dictionary with string names of the ciphersuites\n    \"\"\"\n\n    ietfNames = {}\n\n# the ciphesuite names come from IETF, we want to keep them\n#pylint: disable = invalid-name\n\n    # SSLv2 from draft-hickman-netscape-ssl-00.txt\n    SSL_CK_RC4_128_WITH_MD5 = 0x010080\n    ietfNames[0x010080] = 'SSL_CK_RC4_128_WITH_MD5'\n    SSL_CK_RC4_128_EXPORT40_WITH_MD5 = 0x020080\n    ietfNames[0x020080] = 'SSL_CK_RC4_128_EXPORT40_WITH_MD5'\n    SSL_CK_RC2_128_CBC_WITH_MD5 = 0x030080\n    ietfNames[0x030080] = 'SSL_CK_RC2_128_CBC_WITH_MD5'\n    SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5 = 0x040080\n    ietfNames[0x040080] = 'SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5'\n    SSL_CK_IDEA_128_CBC_WITH_MD5 = 0x050080\n    ietfNames[0x050080] = 'SSL_CK_IDEA_128_CBC_WITH_MD5'\n    SSL_CK_DES_64_CBC_WITH_MD5 = 0x060040\n    ietfNames[0x060040] = 'SSL_CK_DES_64_CBC_WITH_MD5'\n    SSL_CK_DES_192_EDE3_CBC_WITH_MD5 = 0x0700C0\n    ietfNames[0x0700C0] = 'SSL_CK_DES_192_EDE3_CBC_WITH_MD5'\n\n    #: SSL2 ciphersuites which use RC4 symmetric cipher\n    ssl2rc4 = []\n    ssl2rc4.append(SSL_CK_RC4_128_WITH_MD5)\n    ssl2rc4.append(SSL_CK_RC4_128_EXPORT40_WITH_MD5)\n\n    #: SSL2 ciphersuites which use RC2 symmetric cipher\n    ssl2rc2 = []\n    ssl2rc2.append(SSL_CK_RC2_128_CBC_WITH_MD5)\n    ssl2rc2.append(SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5)\n\n    #: SSL2 ciphersuites which use IDEA symmetric cipher\n    ssl2idea = [SSL_CK_IDEA_128_CBC_WITH_MD5]\n\n    #: SSL2 ciphersuites which use (single) DES symmetric cipher\n    ssl2des = [SSL_CK_DES_64_CBC_WITH_MD5]\n\n    #: SSL2 ciphersuites which use 3DES symmetric cipher\n    ssl2_3des = [SSL_CK_DES_192_EDE3_CBC_WITH_MD5]\n\n    #: SSL2 ciphersuites which encrypt only part (40 bits) of the key\n    ssl2export = []\n    ssl2export.append(SSL_CK_RC4_128_EXPORT40_WITH_MD5)\n    ssl2export.append(SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5)\n\n    #: SSL2 ciphersuties which use 128 bit key\n    ssl2_128Key = []\n    ssl2_128Key.append(SSL_CK_RC4_128_WITH_MD5)\n    ssl2_128Key.append(SSL_CK_RC4_128_EXPORT40_WITH_MD5)\n    ssl2_128Key.append(SSL_CK_RC2_128_CBC_WITH_MD5)\n    ssl2_128Key.append(SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5)\n    ssl2_128Key.append(SSL_CK_IDEA_128_CBC_WITH_MD5)\n\n    #: SSL2 ciphersuites which use 64 bit key\n    ssl2_64Key = [SSL_CK_DES_64_CBC_WITH_MD5]\n\n    #: SSL2 ciphersuites which use 192 bit key\n    ssl2_192Key = [SSL_CK_DES_192_EDE3_CBC_WITH_MD5]\n\n    #\n    # SSLv3 and TLS cipher suite definitions\n    #\n\n    # RFC 5246 - TLS v1.2 Protocol\n    TLS_RSA_WITH_NULL_MD5 = 0x0001\n    ietfNames[0x0001] = 'TLS_RSA_WITH_NULL_MD5'\n    TLS_RSA_WITH_NULL_SHA = 0x0002\n    ietfNames[0x0002] = 'TLS_RSA_WITH_NULL_SHA'\n    TLS_RSA_WITH_RC4_128_MD5 = 0x0004\n    ietfNames[0x0004] = 'TLS_RSA_WITH_RC4_128_MD5'\n    TLS_RSA_WITH_RC4_128_SHA = 0x0005\n    ietfNames[0x0005] = 'TLS_RSA_WITH_RC4_128_SHA'\n    TLS_RSA_WITH_3DES_EDE_CBC_SHA = 0x000A\n    ietfNames[0x000A] = 'TLS_RSA_WITH_3DES_EDE_CBC_SHA'\n    TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = 0x000D\n    ietfNames[0x000D] = 'TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA'\n    TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = 0x0013\n    ietfNames[0x0013] = 'TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA'\n    TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 0x0016\n    ietfNames[0x0016] = 'TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA'\n    TLS_DH_ANON_WITH_RC4_128_MD5 = 0x0018\n    ietfNames[0x0018] = 'TLS_DH_ANON_WITH_RC4_128_MD5'\n    TLS_DH_ANON_WITH_3DES_EDE_CBC_SHA = 0x001B\n    ietfNames[0x001B] = 'TLS_DH_ANON_WITH_3DES_EDE_CBC_SHA'\n    TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F\n    ietfNames[0x002F] = 'TLS_RSA_WITH_AES_128_CBC_SHA'\n    TLS_DH_DSS_WITH_AES_128_CBC_SHA = 0x0030\n    ietfNames[0x0030] = 'TLS_DH_DSS_WITH_AES_128_CBC_SHA'\n    TLS_DHE_DSS_WITH_AES_128_CBC_SHA = 0x0032\n    ietfNames[0x0032] = 'TLS_DHE_DSS_WITH_AES_128_CBC_SHA'\n    TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033\n    ietfNames[0x0033] = 'TLS_DHE_RSA_WITH_AES_128_CBC_SHA'\n    TLS_DH_ANON_WITH_AES_128_CBC_SHA = 0x0034\n    ietfNames[0x0034] = 'TLS_DH_ANON_WITH_AES_128_CBC_SHA'\n    TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035\n    ietfNames[0x0035] = 'TLS_RSA_WITH_AES_256_CBC_SHA'\n    TLS_DH_DSS_WITH_AES_256_CBC_SHA = 0x0036\n    ietfNames[0x0036] = 'TLS_DH_DSS_WITH_AES_256_CBC_SHA'\n    TLS_DHE_DSS_WITH_AES_256_CBC_SHA = 0x0038\n    ietfNames[0x0038] = 'TLS_DHE_DSS_WITH_AES_256_CBC_SHA'\n    TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039\n    ietfNames[0x0039] = 'TLS_DHE_RSA_WITH_AES_256_CBC_SHA'\n    TLS_DH_ANON_WITH_AES_256_CBC_SHA = 0x003A\n    ietfNames[0x003A] = 'TLS_DH_ANON_WITH_AES_256_CBC_SHA'\n    TLS_RSA_WITH_NULL_SHA256 = 0x003B\n    ietfNames[0x003B] = 'TLS_RSA_WITH_NULL_SHA256'\n    TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x003C\n    ietfNames[0x003C] = 'TLS_RSA_WITH_AES_128_CBC_SHA256'\n    TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x003D\n    ietfNames[0x003D] = 'TLS_RSA_WITH_AES_256_CBC_SHA256'\n    TLS_DH_DSS_WITH_AES_128_CBC_SHA256 = 0x003E\n    ietfNames[0x003E] = 'TLS_DH_DSS_WITH_AES_128_CBC_SHA256'\n    TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 = 0x0040\n    ietfNames[0x0040] = 'TLS_DHE_DSS_WITH_AES_128_CBC_SHA256'\n    TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x0067\n    ietfNames[0x0067] = 'TLS_DHE_RSA_WITH_AES_128_CBC_SHA256'\n    TLS_DH_DSS_WITH_AES_256_CBC_SHA256 = 0x0068\n    ietfNames[0x0068] = 'TLS_DH_DSS_WITH_AES_256_CBC_SHA256'\n    TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 = 0x006A\n    ietfNames[0x006A] = 'TLS_DHE_DSS_WITH_AES_256_CBC_SHA256'\n    TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x006B\n    ietfNames[0x006B] = 'TLS_DHE_RSA_WITH_AES_256_CBC_SHA256'\n    TLS_DH_ANON_WITH_AES_128_CBC_SHA256 = 0x006C\n    ietfNames[0x006C] = 'TLS_DH_ANON_WITH_AES_128_CBC_SHA256'\n    TLS_DH_ANON_WITH_AES_256_CBC_SHA256 = 0x006D\n    ietfNames[0x006D] = 'TLS_DH_ANON_WITH_AES_256_CBC_SHA256'\n\n    # RFC 5288 - AES-GCM ciphers for TLSv1.2\n    TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C\n    ietfNames[0x009C] = 'TLS_RSA_WITH_AES_128_GCM_SHA256'\n    TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x009D\n    ietfNames[0x009D] = 'TLS_RSA_WITH_AES_256_GCM_SHA384'\n    TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E\n    ietfNames[0x009E] = 'TLS_DHE_RSA_WITH_AES_128_GCM_SHA256'\n    TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = 0x009F\n    ietfNames[0x009F] = 'TLS_DHE_RSA_WITH_AES_256_GCM_SHA384'\n    TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 = 0x00A2\n    ietfNames[0x00A2] = 'TLS_DHE_DSS_WITH_AES_128_GCM_SHA256'\n    TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 = 0x00A3\n    ietfNames[0x00A3] = 'TLS_DHE_DSS_WITH_AES_256_GCM_SHA384'\n    TLS_DH_DSS_WITH_AES_128_GCM_SHA256 = 0x00A4\n    ietfNames[0x00A4] = 'TLS_DH_DSS_WITH_AES_128_GCM_SHA256'\n    TLS_DH_DSS_WITH_AES_256_GCM_SHA384 = 0x00A5\n    ietfNames[0x00A5] = 'TLS_DH_DSS_WITH_AES_256_GCM_SHA384'\n    TLS_DH_ANON_WITH_AES_128_GCM_SHA256 = 0x00A6\n    ietfNames[0x00A6] = 'TLS_DH_ANON_WITH_AES_128_GCM_SHA256'\n    TLS_DH_ANON_WITH_AES_256_GCM_SHA384 = 0x00A7\n    ietfNames[0x00A7] = 'TLS_DH_ANON_WITH_AES_256_GCM_SHA384'\n\n    # RFC 6655 - AES-CCM ciphers for TLSv1.2\n    TLS_RSA_WITH_AES_128_CCM = 0xC09C\n    ietfNames[0xC09C] = 'TLS_RSA_WITH_AES_128_CCM'\n    TLS_RSA_WITH_AES_256_CCM = 0xC09D\n    ietfNames[0xC09D] = 'TLS_RSA_WITH_AES_256_CCM'\n    TLS_DHE_RSA_WITH_AES_128_CCM = 0xC09E\n    ietfNames[0xC09E] = 'TLS_DHE_RSA_WITH_AES_128_CCM'\n    TLS_DHE_RSA_WITH_AES_256_CCM = 0xC09F\n    ietfNames[0xC09F] = 'TLS_DHE_RSA_WITH_AES_256_CCM'\n    TLS_RSA_WITH_AES_128_CCM_8 = 0xC0A0\n    ietfNames[0xC0A0] = 'TLS_RSA_WITH_AES_128_CCM_8'\n    TLS_RSA_WITH_AES_256_CCM_8 = 0xC0A1\n    ietfNames[0xC0A1] = 'TLS_RSA_WITH_AES_256_CCM_8'\n    TLS_DHE_RSA_WITH_AES_128_CCM_8 = 0xC0A2\n    ietfNames[0xC0A2] = 'TLS_DHE_RSA_WITH_AES_128_CCM_8'\n    TLS_DHE_RSA_WITH_AES_256_CCM_8 = 0xC0A3\n    ietfNames[0xC0A3] = 'TLS_DHE_RSA_WITH_AES_256_CCM_8'\n\n\n    # Weird pseudo-ciphersuite from RFC 5746\n    # Signals that \"secure renegotiation\" is supported\n    # We actually don't do any renegotiation, but this\n    # prevents renegotiation attacks\n    TLS_EMPTY_RENEGOTIATION_INFO_SCSV = 0x00FF\n    ietfNames[0x00FF] = 'TLS_EMPTY_RENEGOTIATION_INFO_SCSV'\n\n    # TLS 1.3 ciphersuites\n    TLS_AES_128_GCM_SHA256 = 0x1301\n    ietfNames[0x1301] = 'TLS_AES_128_GCM_SHA256'\n    TLS_AES_256_GCM_SHA384 = 0x1302\n    ietfNames[0x1302] = 'TLS_AES_256_GCM_SHA384'\n    TLS_CHACHA20_POLY1305_SHA256 = 0x1303\n    ietfNames[0x1303] = 'TLS_CHACHA20_POLY1305_SHA256'\n    TLS_AES_128_CCM_SHA256 = 0x1304\n    ietfNames[0x1304] = 'TLS_AES_128_CCM_SHA256'\n    TLS_AES_128_CCM_8_SHA256 = 0x1305\n    ietfNames[0x1305] = 'TLS_AES_128_CCM_8_SHA256'\n\n    # RFC 7507 - Fallback Signaling Cipher Suite Value for Preventing Protocol\n    # Downgrade Attacks\n    TLS_FALLBACK_SCSV = 0x5600\n    ietfNames[0x5600] = 'TLS_FALLBACK_SCSV'\n\n    # RFC 4492 - ECC Cipher Suites for TLS\n    # unsupported - no support for ECDSA certificates\n    TLS_ECDH_ECDSA_WITH_NULL_SHA = 0xC001\n    ietfNames[0xC001] = 'TLS_ECDH_ECDSA_WITH_NULL_SHA'\n    TLS_ECDH_ECDSA_WITH_RC4_128_SHA = 0xC002\n    ietfNames[0xC002] = 'TLS_ECDH_ECDSA_WITH_RC4_128_SHA'\n    TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA = 0xC003\n    ietfNames[0xC003] = 'TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA'\n    TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA = 0xC004\n    ietfNames[0xC004] = 'TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA'\n    TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA = 0xC005\n    ietfNames[0xC005] = 'TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA'\n    TLS_ECDHE_ECDSA_WITH_NULL_SHA = 0xC006\n    ietfNames[0xC006] = 'TLS_ECDHE_ECDSA_WITH_NULL_SHA'\n    TLS_ECDHE_ECDSA_WITH_RC4_128_SHA = 0xC007\n    ietfNames[0xC007] = 'TLS_ECDHE_ECDSA_WITH_RC4_128_SHA'\n    TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA = 0xC008\n    ietfNames[0xC008] = 'TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA'\n    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0xC009\n    ietfNames[0xC009] = 'TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA'\n    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xC00A\n    ietfNames[0xC00A] = 'TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA'\n    TLS_ECDH_RSA_WITH_NULL_SHA = 0xC00B\n    ietfNames[0xC00B] = 'TLS_ECDH_RSA_WITH_NULL_SHA'\n    TLS_ECDH_RSA_WITH_RC4_128_SHA = 0xC00C\n    ietfNames[0xC00C] = 'TLS_ECDH_RSA_WITH_RC4_128_SHA'\n    TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA = 0xC00D\n    ietfNames[0xC00D] = 'TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA'\n    TLS_ECDH_RSA_WITH_AES_128_CBC_SHA = 0xC00E\n    ietfNames[0xC00E] = 'TLS_ECDH_RSA_WITH_AES_128_CBC_SHA'\n    TLS_ECDH_RSA_WITH_AES_256_CBC_SHA = 0xC00F\n    ietfNames[0xC00F] = 'TLS_ECDH_RSA_WITH_AES_256_CBC_SHA'\n\n    # RFC 4492 - ECC Cipher Suites for TLS\n    TLS_ECDHE_RSA_WITH_NULL_SHA = 0xC010\n    ietfNames[0xC010] = 'TLS_ECDHE_RSA_WITH_NULL_SHA'\n    TLS_ECDHE_RSA_WITH_RC4_128_SHA = 0xC011\n    ietfNames[0xC011] = 'TLS_ECDHE_RSA_WITH_RC4_128_SHA'\n    TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA = 0xC012\n    ietfNames[0xC012] = 'TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA'\n    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC013\n    ietfNames[0xC013] = 'TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA'\n    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014\n    ietfNames[0xC014] = 'TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA'\n    TLS_ECDH_ANON_WITH_NULL_SHA = 0xC015\n    ietfNames[0xC015] = 'TLS_ECDH_ANON_WITH_NULL_SHA'\n    TLS_ECDH_ANON_WITH_RC4_128_SHA = 0xC016\n    ietfNames[0xC016] = 'TLS_ECDH_ANON_WITH_RC4_128_SHA'\n    TLS_ECDH_ANON_WITH_3DES_EDE_CBC_SHA = 0xC017\n    ietfNames[0xC017] = 'TLS_ECDH_ANON_WITH_3DES_EDE_CBC_SHA'\n    TLS_ECDH_ANON_WITH_AES_128_CBC_SHA = 0xC018\n    ietfNames[0xC018] = 'TLS_ECDH_ANON_WITH_AES_128_CBC_SHA'\n    TLS_ECDH_ANON_WITH_AES_256_CBC_SHA = 0xC019\n    ietfNames[0xC019] = 'TLS_ECDH_ANON_WITH_AES_256_CBC_SHA'\n\n    # RFC 5054 - Secure Remote Password (SRP) Protocol for TLS Authentication\n    TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA  = 0xC01A\n    ietfNames[0xC01A] = 'TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA'\n    TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA = 0xC01B\n    ietfNames[0xC01B] = 'TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA'\n    TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA = 0xC01C\n    ietfNames[0xC01C] = 'TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA'\n    TLS_SRP_SHA_WITH_AES_128_CBC_SHA = 0xC01D\n    ietfNames[0xC01D] = 'TLS_SRP_SHA_WITH_AES_128_CBC_SHA'\n    TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA = 0xC01E\n    ietfNames[0xC01E] = 'TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA'\n    TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA = 0xC01F\n    ietfNames[0xC01F] = 'TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA'\n    TLS_SRP_SHA_WITH_AES_256_CBC_SHA = 0xC020\n    ietfNames[0xC020] = 'TLS_SRP_SHA_WITH_AES_256_CBC_SHA'\n    TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA = 0xC021\n    ietfNames[0xC021] = 'TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA'\n    TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA = 0xC022\n    ietfNames[0xC022] = 'TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA'\n\n    # RFC 5289 - ECC Ciphers with SHA-256/SHA-384 HMAC and AES-GCM\n    # unsupported! - no support for ECDSA certificates\n    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC023\n    ietfNames[0xC023] = 'TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256'\n    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC024\n    ietfNames[0xC024] = 'TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384'\n    TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC025\n    ietfNames[0xC025] = 'TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256'\n    TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC026\n    ietfNames[0xC026] = 'TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384'\n\n    # RFC 5289 - ECC Ciphers with SHA-256/SHA-384 HMAC and AES-GCM\n    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xC027\n    ietfNames[0xC027] = 'TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256'\n    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 = 0xC028\n    ietfNames[0xC028] = 'TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384'\n\n    # RFC 5289 - ECC Ciphers with SHA-256/SHA-384 HMAC and AES-GCM\n    # unsupported\n    TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 = 0xC029\n    ietfNames[0xC029] = 'TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256'\n    TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 = 0xC02A\n    ietfNames[0xC02A] = 'TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384'\n    TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B\n    ietfNames[0xC02B] = 'TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256'\n    TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02C\n    ietfNames[0xC02C] = 'TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384'\n    TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02D\n    ietfNames[0xC02D] = 'TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256'\n    TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02E\n    ietfNames[0xC02E] = 'TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384'\n\n    # RFC 5289 - ECC Ciphers with SHA-256/SHA-384 HMAC and AES-GCM\n    TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F\n    ietfNames[0xC02F] = 'TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256'\n    TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xC030\n    ietfNames[0xC030] = 'TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384'\n\n    # RFC 5289 - ECC Ciphers with SHA-256/SHA-384 HMAC and AES-GCM\n    # unsupported\n    TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 = 0xC031\n    ietfNames[0xC031] = 'TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256'\n    TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 = 0xC032\n    ietfNames[0xC032] = 'TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384'\n\n    # draft-ietf-tls-chacha20-poly1305-00\n    # ChaCha20/Poly1305 based Cipher Suites for TLS1.2\n    TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_draft_00 = 0xCCA1\n    ietfNames[0xCCA1] = 'TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_draft_00'\n    TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_draft_00 = 0xCCA2\n    ietfNames[0xCCA2] = 'TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_draft_00'\n    TLS_DHE_RSA_WITH_CHACHA20_POLY1305_draft_00 = 0xCCA3\n    ietfNames[0xCCA3] = 'TLS_DHE_RSA_WITH_CHACHA20_POLY1305_draft_00'\n\n    # RFC 7905 - ChaCha20-Poly1305 Cipher Suites for TLS\n    TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA8\n    ietfNames[0xCCA8] = 'TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256'\n    TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA9\n    ietfNames[0xCCA9] = 'TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256'\n    TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAA\n    ietfNames[0xCCAA] = 'TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256'\n\n    # RFC 7251 - AES-CCM ECC Ciphers for TLS\n    TLS_ECDHE_ECDSA_WITH_AES_128_CCM = 0xC0AC\n    ietfNames[0xC0AC] = 'TLS_ECDHE_ECDSA_WITH_AES_128_CCM'\n    TLS_ECDHE_ECDSA_WITH_AES_256_CCM = 0xC0AD\n    ietfNames[0xC0AD] = 'TLS_ECDHE_ECDSA_WITH_AES_256_CCM'\n    TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 = 0xC0AE\n    ietfNames[0xC0AE] = 'TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8'\n    TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 = 0xC0AF\n    ietfNames[0xC0AF] = 'TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8'\n\n#pylint: enable = invalid-name\n    #\n    # Define cipher suite families below\n    #\n\n    #: 3DES CBC ciphers\n    tripleDESSuites = []\n    tripleDESSuites.append(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA)\n    tripleDESSuites.append(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA)  # unsupported\n    tripleDESSuites.append(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA)  # unsupported\n    tripleDESSuites.append(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA)\n    tripleDESSuites.append(TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA)\n    tripleDESSuites.append(TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA)\n    tripleDESSuites.append(TLS_RSA_WITH_3DES_EDE_CBC_SHA)\n    tripleDESSuites.append(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA)\n    tripleDESSuites.append(TLS_DH_ANON_WITH_3DES_EDE_CBC_SHA)\n    tripleDESSuites.append(TLS_ECDH_ANON_WITH_3DES_EDE_CBC_SHA)\n    tripleDESSuites.append(TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA)    # unsupported\n    tripleDESSuites.append(TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA)   # unsupported\n    tripleDESSuites.append(TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA)   # unsupp\n\n\n    #: AES-128 CBC ciphers\n    aes128Suites = []\n    aes128Suites.append(TLS_SRP_SHA_WITH_AES_128_CBC_SHA)\n    aes128Suites.append(TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA)\n    aes128Suites.append(TLS_RSA_WITH_AES_128_CBC_SHA)\n    aes128Suites.append(TLS_DHE_RSA_WITH_AES_128_CBC_SHA)\n    aes128Suites.append(TLS_DH_ANON_WITH_AES_128_CBC_SHA)\n    aes128Suites.append(TLS_RSA_WITH_AES_128_CBC_SHA256)\n    aes128Suites.append(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256)\n    aes128Suites.append(TLS_DH_ANON_WITH_AES_128_CBC_SHA256)\n    aes128Suites.append(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256)\n    aes128Suites.append(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA)\n    aes128Suites.append(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256)  # unsupported\n    aes128Suites.append(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA)  # unsupported\n    aes128Suites.append(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256)  # unsupported\n    aes128Suites.append(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA)  # unsupported\n    aes128Suites.append(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA)\n    aes128Suites.append(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256)\n    aes128Suites.append(TLS_ECDH_ANON_WITH_AES_128_CBC_SHA)\n    aes128Suites.append(TLS_DH_DSS_WITH_AES_128_CBC_SHA)    # unsupported\n    aes128Suites.append(TLS_DHE_DSS_WITH_AES_128_CBC_SHA)   # unsupported\n    aes128Suites.append(TLS_DH_DSS_WITH_AES_128_CBC_SHA256) # unsupported\n    aes128Suites.append(TLS_DHE_DSS_WITH_AES_128_CBC_SHA256)    # unsupported\n    aes128Suites.append(TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA)   # unsupported\n\n    #: AES-256 CBC ciphers\n    aes256Suites = []\n    aes256Suites.append(TLS_SRP_SHA_WITH_AES_256_CBC_SHA)\n    aes256Suites.append(TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA)\n    aes256Suites.append(TLS_RSA_WITH_AES_256_CBC_SHA)\n    aes256Suites.append(TLS_DH_ANON_WITH_AES_256_CBC_SHA)\n    aes256Suites.append(TLS_DHE_RSA_WITH_AES_256_CBC_SHA)\n    aes256Suites.append(TLS_RSA_WITH_AES_256_CBC_SHA256)\n    aes256Suites.append(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256)\n    aes256Suites.append(TLS_DH_ANON_WITH_AES_256_CBC_SHA256)\n    aes256Suites.append(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384)\n    aes256Suites.append(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA)\n    aes256Suites.append(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384)  # unsupported\n    aes256Suites.append(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA)  # unsupported\n    aes256Suites.append(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384)  # unsupported\n    aes256Suites.append(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA)  # unsupported\n    aes256Suites.append(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA)\n    aes256Suites.append(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384)\n    aes256Suites.append(TLS_ECDH_ANON_WITH_AES_256_CBC_SHA)\n    aes256Suites.append(TLS_DH_DSS_WITH_AES_256_CBC_SHA)    # unsupported\n    aes256Suites.append(TLS_DHE_DSS_WITH_AES_256_CBC_SHA)   # unsupported\n    aes256Suites.append(TLS_DH_DSS_WITH_AES_256_CBC_SHA256) # unsupported\n    aes256Suites.append(TLS_DHE_DSS_WITH_AES_256_CBC_SHA256)    # unsupported\n    aes256Suites.append(TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA)   # unsupported\n\n    #: AES-128 GCM ciphers\n    aes128GcmSuites = []\n    aes128GcmSuites.append(TLS_RSA_WITH_AES_128_GCM_SHA256)\n    aes128GcmSuites.append(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256)\n    aes128GcmSuites.append(TLS_DH_ANON_WITH_AES_128_GCM_SHA256)\n    aes128GcmSuites.append(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)\n    aes128GcmSuites.append(TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256)  # unsupp\n    aes128GcmSuites.append(TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256)  # unsupp\n    aes128GcmSuites.append(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256)\n    aes128GcmSuites.append(TLS_AES_128_GCM_SHA256)\n    aes128GcmSuites.append(TLS_DHE_DSS_WITH_AES_128_GCM_SHA256) # unsupported\n    aes128GcmSuites.append(TLS_DH_DSS_WITH_AES_128_GCM_SHA256)  # unsupported\n\n    #: AES-256-GCM ciphers (implicit SHA384, see sha384PrfSuites)\n    aes256GcmSuites = []\n    aes256GcmSuites.append(TLS_RSA_WITH_AES_256_GCM_SHA384)\n    aes256GcmSuites.append(TLS_DHE_RSA_WITH_AES_256_GCM_SHA384)\n    aes256GcmSuites.append(TLS_DH_ANON_WITH_AES_256_GCM_SHA384)\n    aes256GcmSuites.append(TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384)\n    aes256GcmSuites.append(TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384)  # unsupp\n    aes256GcmSuites.append(TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384)  # unsupported\n    aes256GcmSuites.append(TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384)\n    aes256GcmSuites.append(TLS_AES_256_GCM_SHA384)\n    aes256GcmSuites.append(TLS_DHE_DSS_WITH_AES_256_GCM_SHA384) # unsupported\n    aes256GcmSuites.append(TLS_DH_DSS_WITH_AES_256_GCM_SHA384)  # unsupported\n\n    #: AES-128 CCM_8 ciphers\n    aes128Ccm_8Suites = []\n    aes128Ccm_8Suites.append(TLS_RSA_WITH_AES_128_CCM_8)\n    aes128Ccm_8Suites.append(TLS_DHE_RSA_WITH_AES_128_CCM_8)\n    aes128Ccm_8Suites.append(TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8)\n    aes128Ccm_8Suites.append(TLS_AES_128_CCM_8_SHA256)\n\n    #: AES-128 CCM ciphers\n    aes128CcmSuites = []\n    aes128CcmSuites.append(TLS_RSA_WITH_AES_128_CCM)\n    aes128CcmSuites.append(TLS_DHE_RSA_WITH_AES_128_CCM)\n    aes128CcmSuites.append(TLS_ECDHE_ECDSA_WITH_AES_128_CCM)\n    aes128CcmSuites.append(TLS_AES_128_CCM_SHA256)\n\n    #: AES-256 CCM_8 ciphers\n    aes256Ccm_8Suites = []\n    aes256Ccm_8Suites.append(TLS_RSA_WITH_AES_256_CCM_8)\n    aes256Ccm_8Suites.append(TLS_DHE_RSA_WITH_AES_256_CCM_8)\n    aes256Ccm_8Suites.append(TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8)\n\n    # AES-256 CCM ciphers\n    aes256CcmSuites = []\n    aes256CcmSuites.append(TLS_RSA_WITH_AES_256_CCM)\n    aes256CcmSuites.append(TLS_DHE_RSA_WITH_AES_256_CCM)\n    aes256CcmSuites.append(TLS_ECDHE_ECDSA_WITH_AES_256_CCM)\n\n    #: CHACHA20 cipher, 00'th IETF draft (implicit POLY1305 authenticator)\n    chacha20draft00Suites = []\n    chacha20draft00Suites.append(TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_draft_00)\n    chacha20draft00Suites.append(\n        TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_draft_00)\n    chacha20draft00Suites.append(TLS_DHE_RSA_WITH_CHACHA20_POLY1305_draft_00)\n\n    #: CHACHA20 cipher (implicit POLY1305 authenticator, SHA256 PRF)\n    chacha20Suites = []\n    chacha20Suites.append(TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256)\n    chacha20Suites.append(TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256)\n    chacha20Suites.append(TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256)\n    chacha20Suites.append(TLS_CHACHA20_POLY1305_SHA256)\n\n    #: RC4 128 stream cipher\n    rc4Suites = []\n    rc4Suites.append(TLS_ECDHE_RSA_WITH_RC4_128_SHA)\n    rc4Suites.append(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA)\n    rc4Suites.append(TLS_ECDH_ECDSA_WITH_RC4_128_SHA)  # unsupported\n    rc4Suites.append(TLS_ECDH_RSA_WITH_RC4_128_SHA)  # unsupported\n    rc4Suites.append(TLS_DH_ANON_WITH_RC4_128_MD5)\n    rc4Suites.append(TLS_RSA_WITH_RC4_128_SHA)\n    rc4Suites.append(TLS_RSA_WITH_RC4_128_MD5)\n    rc4Suites.append(TLS_ECDH_ANON_WITH_RC4_128_SHA)\n\n    #: no encryption\n    nullSuites = []\n    nullSuites.append(TLS_RSA_WITH_NULL_MD5)\n    nullSuites.append(TLS_RSA_WITH_NULL_SHA)\n    nullSuites.append(TLS_RSA_WITH_NULL_SHA256)\n    nullSuites.append(TLS_ECDHE_ECDSA_WITH_NULL_SHA)\n    nullSuites.append(TLS_ECDH_ECDSA_WITH_NULL_SHA)  # unsupported\n    nullSuites.append(TLS_ECDH_RSA_WITH_NULL_SHA)  # unsupported\n    nullSuites.append(TLS_ECDHE_RSA_WITH_NULL_SHA)\n    nullSuites.append(TLS_ECDH_ANON_WITH_NULL_SHA)\n\n    #: SHA-1 HMAC, protocol default PRF\n    shaSuites = []\n    shaSuites.append(TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA)\n    shaSuites.append(TLS_SRP_SHA_WITH_AES_128_CBC_SHA)\n    shaSuites.append(TLS_SRP_SHA_WITH_AES_256_CBC_SHA)\n    shaSuites.append(TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA)\n    shaSuites.append(TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA)\n    shaSuites.append(TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA)\n    shaSuites.append(TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA) # unsupported\n    shaSuites.append(TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA)  # unsupported\n    shaSuites.append(TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA)  # unsupported\n    shaSuites.append(TLS_RSA_WITH_3DES_EDE_CBC_SHA)\n    shaSuites.append(TLS_RSA_WITH_AES_128_CBC_SHA)\n    shaSuites.append(TLS_RSA_WITH_AES_256_CBC_SHA)\n    shaSuites.append(TLS_RSA_WITH_RC4_128_SHA)\n    shaSuites.append(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA)\n    shaSuites.append(TLS_DHE_RSA_WITH_AES_128_CBC_SHA)\n    shaSuites.append(TLS_DHE_RSA_WITH_AES_256_CBC_SHA)\n    shaSuites.append(TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA) # unsupported\n    shaSuites.append(TLS_DHE_DSS_WITH_AES_128_CBC_SHA)  # unsupported\n    shaSuites.append(TLS_DHE_DSS_WITH_AES_256_CBC_SHA)  # unsupported\n    shaSuites.append(TLS_DH_ANON_WITH_AES_128_CBC_SHA)\n    shaSuites.append(TLS_DH_ANON_WITH_AES_256_CBC_SHA)\n    shaSuites.append(TLS_DH_ANON_WITH_3DES_EDE_CBC_SHA)\n    shaSuites.append(TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA)  # unsupported\n    shaSuites.append(TLS_DH_DSS_WITH_AES_128_CBC_SHA)   # unsupported\n    shaSuites.append(TLS_DH_DSS_WITH_AES_256_CBC_SHA)   # unsupported\n    shaSuites.append(TLS_RSA_WITH_NULL_SHA)\n    shaSuites.append(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA)\n    shaSuites.append(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA)\n    shaSuites.append(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA)\n    shaSuites.append(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA)\n    shaSuites.append(TLS_ECDHE_ECDSA_WITH_NULL_SHA)\n    shaSuites.append(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA)  # unsupported\n    shaSuites.append(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA)  # unsupported\n    shaSuites.append(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA)  # unsupported\n    shaSuites.append(TLS_ECDH_ECDSA_WITH_RC4_128_SHA)  # unsupported\n    shaSuites.append(TLS_ECDH_ECDSA_WITH_NULL_SHA)  # unsupported\n    shaSuites.append(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA)  # unsupported\n    shaSuites.append(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA)  # unsupported\n    shaSuites.append(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA)  # unsupported\n    shaSuites.append(TLS_ECDH_RSA_WITH_RC4_128_SHA)  # unsupported\n    shaSuites.append(TLS_ECDH_RSA_WITH_NULL_SHA)  # unsupported\n    shaSuites.append(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA)\n    shaSuites.append(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA)\n    shaSuites.append(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA)\n    shaSuites.append(TLS_ECDHE_RSA_WITH_RC4_128_SHA)\n    shaSuites.append(TLS_ECDHE_RSA_WITH_NULL_SHA)\n    shaSuites.append(TLS_ECDH_ANON_WITH_AES_256_CBC_SHA)\n    shaSuites.append(TLS_ECDH_ANON_WITH_AES_128_CBC_SHA)\n    shaSuites.append(TLS_ECDH_ANON_WITH_3DES_EDE_CBC_SHA)\n    shaSuites.append(TLS_ECDH_ANON_WITH_RC4_128_SHA)\n    shaSuites.append(TLS_ECDH_ANON_WITH_NULL_SHA)\n\n    #: SHA-256 HMAC, SHA-256 PRF\n    sha256Suites = []\n    sha256Suites.append(TLS_RSA_WITH_AES_128_CBC_SHA256)\n    sha256Suites.append(TLS_RSA_WITH_AES_256_CBC_SHA256)\n    sha256Suites.append(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256)\n    sha256Suites.append(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256)\n    sha256Suites.append(TLS_RSA_WITH_NULL_SHA256)\n    sha256Suites.append(TLS_DH_ANON_WITH_AES_128_CBC_SHA256)\n    sha256Suites.append(TLS_DH_ANON_WITH_AES_256_CBC_SHA256)\n    sha256Suites.append(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256)\n    sha256Suites.append(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256)  # unsupported\n    sha256Suites.append(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256)  # unsupported\n    sha256Suites.append(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256)\n\n    #: SHA-384 HMAC, SHA-384 PRF\n    sha384Suites = []\n    sha384Suites.append(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384)\n    sha384Suites.append(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384)  # unsupported\n    sha384Suites.append(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384)  # unsupported\n    sha384Suites.append(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384)\n    sha384Suites.append(TLS_DHE_DSS_WITH_AES_256_GCM_SHA384)    # unsupported\n    sha384Suites.append(TLS_DH_DSS_WITH_AES_256_GCM_SHA384) # unsupported\n\n    #: stream cipher construction\n    streamSuites = []\n    streamSuites.extend(rc4Suites)\n    streamSuites.extend(nullSuites)\n\n    #: AEAD integrity, any PRF\n    aeadSuites = []\n    aeadSuites.extend(aes128GcmSuites)\n    aeadSuites.extend(aes256GcmSuites)\n    aeadSuites.extend(aes128CcmSuites)\n    aeadSuites.extend(aes128Ccm_8Suites)\n    aeadSuites.extend(aes256CcmSuites)\n    aeadSuites.extend(aes256Ccm_8Suites)\n    aeadSuites.extend(chacha20Suites)\n    aeadSuites.extend(chacha20draft00Suites)\n\n    #: TLS1.2 with SHA384 PRF\n    sha384PrfSuites = []\n    sha384PrfSuites.extend(sha384Suites)\n    sha384PrfSuites.extend(aes256GcmSuites)\n\n    #: MD-5 HMAC, protocol default PRF\n    md5Suites = []\n    md5Suites.append(TLS_DH_ANON_WITH_RC4_128_MD5)\n    md5Suites.append(TLS_RSA_WITH_RC4_128_MD5)\n    md5Suites.append(TLS_RSA_WITH_NULL_MD5)\n\n    #: SSL3, TLS1.0, TLS1.1 and TLS1.2 compatible ciphers\n    ssl3Suites = []\n    ssl3Suites.extend(shaSuites)\n    ssl3Suites.extend(md5Suites)\n\n    #: TLS1.2 specific ciphersuites\n    tls12Suites = []\n    tls12Suites.extend(sha256Suites)\n    tls12Suites.extend(sha384Suites)\n    tls12Suites.extend(aeadSuites)\n\n    #: TLS1.3 specific ciphersuites\n    tls13Suites = []\n\n    # TLS 1.3 suites are not a superset of TLS 1.2 suites, but they\n    # use the same mechanism (AEAD), so we need to remove TLS 1.3 items\n    # from the TLS 1.2 list\n    tls13Suites.append(TLS_AES_256_GCM_SHA384)\n    tls12Suites.remove(TLS_AES_256_GCM_SHA384)\n    tls13Suites.append(TLS_AES_128_GCM_SHA256)\n    tls12Suites.remove(TLS_AES_128_GCM_SHA256)\n    tls13Suites.append(TLS_CHACHA20_POLY1305_SHA256)\n    tls12Suites.remove(TLS_CHACHA20_POLY1305_SHA256)\n    tls13Suites.append(TLS_AES_128_CCM_SHA256)\n    tls12Suites.remove(TLS_AES_128_CCM_SHA256)\n    tls13Suites.append(TLS_AES_128_CCM_8_SHA256)\n    tls12Suites.remove(TLS_AES_128_CCM_8_SHA256)\n\n    @staticmethod\n    def filterForVersion(suites, minVersion, maxVersion):\n        \"\"\"Return a copy of suites without ciphers incompatible with version\"\"\"\n        includeSuites = set([])\n        if (3, 0) <= minVersion <= (3, 3):\n            includeSuites.update(CipherSuite.ssl3Suites)\n        if maxVersion >= (3, 3) and minVersion <= (3, 3):\n            includeSuites.update(CipherSuite.tls12Suites)\n        if maxVersion > (3, 3):\n            includeSuites.update(CipherSuite.tls13Suites)\n        return [s for s in suites if s in includeSuites]\n\n    @staticmethod\n    def filter_for_certificate(suites, cert_chain):\n        \"\"\"Return a copy of suites without ciphers incompatible with the cert.\n        \"\"\"\n        includeSuites = set([])\n        includeSuites.update(CipherSuite.tls13Suites)\n        if cert_chain:\n            if cert_chain.x509List[0].certAlg in (\"rsa\", \"rsa-pss\"):\n                includeSuites.update(CipherSuite.certAllSuites)\n            if cert_chain.x509List[0].certAlg == \"rsa-pss\":\n                # suites in which RSA encryption is used can't be used with\n                # rsa-pss\n                includeSuites.symmetric_difference_update(\n                    CipherSuite.certSuites)\n            if cert_chain.x509List[0].certAlg in (\"ecdsa\", \"Ed25519\", \"Ed448\"):\n                includeSuites.update(CipherSuite.ecdheEcdsaSuites)\n            if cert_chain.x509List[0].certAlg == \"dsa\":\n                includeSuites.update(CipherSuite.dheDsaSuites)\n        else:\n            includeSuites.update(CipherSuite.srpSuites)\n            includeSuites.update(CipherSuite.anonSuites)\n            includeSuites.update(CipherSuite.ecdhAnonSuites)\n        return [s for s in suites if s in includeSuites]\n\n    @staticmethod\n    def _filterSuites(suites, settings, version=None):\n        if version is None:\n            version = settings.maxVersion\n        macNames = settings.macNames\n        cipherNames = settings.cipherNames\n        keyExchangeNames = settings.keyExchangeNames\n        macSuites = []\n        if \"sha\" in macNames:\n            macSuites += CipherSuite.shaSuites\n        if \"sha256\" in macNames and version >= (3, 3):\n            macSuites += CipherSuite.sha256Suites\n        if \"sha384\" in macNames and version >= (3, 3):\n            macSuites += CipherSuite.sha384Suites\n        if \"md5\" in macNames:\n            macSuites += CipherSuite.md5Suites\n        if \"aead\" in macNames and version >= (3, 3):\n            macSuites += CipherSuite.aeadSuites\n\n        cipherSuites = []\n        if \"chacha20-poly1305\" in cipherNames and version >= (3, 3):\n            cipherSuites += CipherSuite.chacha20Suites\n        if \"chacha20-poly1305_draft00\" in cipherNames and version >= (3, 3):\n            cipherSuites += CipherSuite.chacha20draft00Suites\n        if \"aes128gcm\" in cipherNames and version >= (3, 3):\n            cipherSuites += CipherSuite.aes128GcmSuites\n        if \"aes256gcm\" in cipherNames and version >= (3, 3):\n            cipherSuites += CipherSuite.aes256GcmSuites\n        if \"aes128ccm\" in cipherNames and version >= (3, 3):\n            cipherSuites += CipherSuite.aes128CcmSuites\n        if \"aes128ccm_8\" in cipherNames and version >= (3, 3):\n            cipherSuites += CipherSuite.aes128Ccm_8Suites\n        if \"aes256ccm\" in cipherNames and version >= (3, 3):\n            cipherSuites += CipherSuite.aes256CcmSuites\n        if \"aes256ccm_8\" in cipherNames and version >= (3, 3):\n            cipherSuites += CipherSuite.aes256Ccm_8Suites\n        if \"aes128\" in cipherNames:\n            cipherSuites += CipherSuite.aes128Suites\n        if \"aes256\" in cipherNames:\n            cipherSuites += CipherSuite.aes256Suites\n        if \"3des\" in cipherNames:\n            cipherSuites += CipherSuite.tripleDESSuites\n        if \"rc4\" in cipherNames:\n            cipherSuites += CipherSuite.rc4Suites\n        if \"null\" in cipherNames:\n            cipherSuites += CipherSuite.nullSuites\n\n        keyExchangeSuites = []\n        if version >= (3, 4):\n            keyExchangeSuites += CipherSuite.tls13Suites\n        if \"rsa\" in keyExchangeNames:\n            keyExchangeSuites += CipherSuite.certSuites\n        if \"dhe_rsa\" in keyExchangeNames:\n            keyExchangeSuites += CipherSuite.dheCertSuites\n        if \"dhe_dsa\" in keyExchangeNames:\n            keyExchangeSuites += CipherSuite.dheDsaSuites\n        if \"ecdhe_rsa\" in keyExchangeNames:\n            keyExchangeSuites += CipherSuite.ecdheCertSuites\n        if \"ecdhe_ecdsa\" in keyExchangeNames:\n            keyExchangeSuites += CipherSuite.ecdheEcdsaSuites\n        if \"srp_sha\" in keyExchangeNames:\n            keyExchangeSuites += CipherSuite.srpSuites\n        if \"srp_sha_rsa\" in keyExchangeNames:\n            keyExchangeSuites += CipherSuite.srpCertSuites\n        if \"dh_anon\" in keyExchangeNames:\n            keyExchangeSuites += CipherSuite.anonSuites\n        if \"ecdh_anon\" in keyExchangeNames:\n            keyExchangeSuites += CipherSuite.ecdhAnonSuites\n\n        return [s for s in suites if s in macSuites and\n                s in cipherSuites and s in keyExchangeSuites]\n\n    @classmethod\n    def getTLS13Suites(cls, settings, version=None):\n        \"\"\"Return cipher suites that are TLS 1.3 specific.\"\"\"\n        return cls._filterSuites(CipherSuite.tls13Suites, settings, version)\n\n    #: SRP key exchange, no certificate base authentication\n    srpSuites = []\n    srpSuites.append(TLS_SRP_SHA_WITH_AES_256_CBC_SHA)\n    srpSuites.append(TLS_SRP_SHA_WITH_AES_128_CBC_SHA)\n    srpSuites.append(TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA)\n\n    @classmethod\n    def getSrpSuites(cls, settings, version=None):\n        \"\"\"Return SRP cipher suites matching settings\"\"\"\n        return cls._filterSuites(CipherSuite.srpSuites, settings, version)\n\n    #: SRP key exchange, RSA authentication\n    srpCertSuites = []\n    srpCertSuites.append(TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA)\n    srpCertSuites.append(TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA)\n    srpCertSuites.append(TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA)\n\n    @classmethod\n    def getSrpCertSuites(cls, settings, version=None):\n        \"\"\"Return SRP cipher suites that use server certificates\"\"\"\n        return cls._filterSuites(CipherSuite.srpCertSuites, settings, version)\n\n    #: SRP key exchange, DSA authentication\n    srpDsaSuites = []\n    srpDsaSuites.append(TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA) # unsupported\n    srpDsaSuites.append(TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA)  # unsupported\n    srpDsaSuites.append(TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA)  # unsupported\n\n    @classmethod\n    def getSrpDsaSuites(cls, settings, version=None):\n        \"\"\"Return SRP DSA cipher suites that use server certificates\"\"\"\n        return cls._filterSuites(CipherSuite.srpCertSuites, settings, version)\n\n    #: All that use SRP key exchange\n    srpAllSuites = srpSuites + srpCertSuites\n\n    @classmethod\n    def getSrpAllSuites(cls, settings, version=None):\n        \"\"\"Return all SRP cipher suites matching settings\"\"\"\n        return cls._filterSuites(CipherSuite.srpAllSuites, settings, version)\n\n    #: RSA key exchange, RSA authentication\n    certSuites = []\n    certSuites.append(TLS_RSA_WITH_AES_256_GCM_SHA384)\n    certSuites.append(TLS_RSA_WITH_AES_128_GCM_SHA256)\n    certSuites.append(TLS_RSA_WITH_AES_256_CCM)\n    certSuites.append(TLS_RSA_WITH_AES_128_CCM)\n    certSuites.append(TLS_RSA_WITH_AES_256_CBC_SHA256)\n    certSuites.append(TLS_RSA_WITH_AES_128_CBC_SHA256)\n    certSuites.append(TLS_RSA_WITH_AES_256_CBC_SHA)\n    certSuites.append(TLS_RSA_WITH_AES_128_CBC_SHA)\n    certSuites.append(TLS_RSA_WITH_AES_256_CCM_8)\n    certSuites.append(TLS_RSA_WITH_AES_128_CCM_8)\n    certSuites.append(TLS_RSA_WITH_3DES_EDE_CBC_SHA)\n    certSuites.append(TLS_RSA_WITH_RC4_128_SHA)\n    certSuites.append(TLS_RSA_WITH_RC4_128_MD5)\n    certSuites.append(TLS_RSA_WITH_NULL_MD5)\n    certSuites.append(TLS_RSA_WITH_NULL_SHA)\n    certSuites.append(TLS_RSA_WITH_NULL_SHA256)\n\n    @classmethod\n    def getCertSuites(cls, settings, version=None):\n        \"\"\"Return ciphers with RSA authentication matching settings\"\"\"\n        return cls._filterSuites(CipherSuite.certSuites, settings, version)\n\n    #: FFDHE key exchange, RSA authentication\n    dheCertSuites = []\n    dheCertSuites.append(TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256)\n    dheCertSuites.append(TLS_DHE_RSA_WITH_CHACHA20_POLY1305_draft_00)\n    dheCertSuites.append(TLS_DHE_RSA_WITH_AES_256_GCM_SHA384)\n    dheCertSuites.append(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256)\n    dheCertSuites.append(TLS_DHE_RSA_WITH_AES_256_CCM)\n    dheCertSuites.append(TLS_DHE_RSA_WITH_AES_128_CCM)\n    dheCertSuites.append(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256)\n    dheCertSuites.append(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256)\n    dheCertSuites.append(TLS_DHE_RSA_WITH_AES_256_CBC_SHA)\n    dheCertSuites.append(TLS_DHE_RSA_WITH_AES_128_CBC_SHA)\n    dheCertSuites.append(TLS_DHE_RSA_WITH_AES_256_CCM_8)\n    dheCertSuites.append(TLS_DHE_RSA_WITH_AES_128_CCM_8)\n    dheCertSuites.append(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA)\n\n    @classmethod\n    def getDheCertSuites(cls, settings, version=None):\n        \"\"\"Provide authenticated DHE ciphersuites matching settings\"\"\"\n        return cls._filterSuites(CipherSuite.dheCertSuites, settings, version)\n\n    #: ECDHE key exchange, RSA authentication\n    ecdheCertSuites = []\n    ecdheCertSuites.append(TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256)\n    ecdheCertSuites.append(TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_draft_00)\n    ecdheCertSuites.append(TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384)\n    ecdheCertSuites.append(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256)\n    ecdheCertSuites.append(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384)\n    ecdheCertSuites.append(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256)\n    ecdheCertSuites.append(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA)\n    ecdheCertSuites.append(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA)\n    ecdheCertSuites.append(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA)\n    ecdheCertSuites.append(TLS_ECDHE_RSA_WITH_RC4_128_SHA)\n    ecdheCertSuites.append(TLS_ECDHE_RSA_WITH_NULL_SHA)\n\n    @classmethod\n    def getEcdheCertSuites(cls, settings, version=None):\n        \"\"\"Provide authenticated ECDHE ciphersuites matching settings\"\"\"\n        return cls._filterSuites(CipherSuite.ecdheCertSuites, settings, version)\n\n    #: RSA authentication\n    certAllSuites = srpCertSuites + certSuites + dheCertSuites + ecdheCertSuites\n\n    #: ECDHE key exchange, ECDSA authentication\n    ecdheEcdsaSuites = []\n    ecdheEcdsaSuites.append(TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256)\n    ecdheEcdsaSuites.append(TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_draft_00)\n    ecdheEcdsaSuites.append(TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384)\n    ecdheEcdsaSuites.append(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)\n    ecdheEcdsaSuites.append(TLS_ECDHE_ECDSA_WITH_AES_256_CCM)\n    ecdheEcdsaSuites.append(TLS_ECDHE_ECDSA_WITH_AES_128_CCM)\n    ecdheEcdsaSuites.append(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384)\n    ecdheEcdsaSuites.append(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256)\n    ecdheEcdsaSuites.append(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA)\n    ecdheEcdsaSuites.append(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA)\n    ecdheEcdsaSuites.append(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA)\n    ecdheEcdsaSuites.append(TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8)\n    ecdheEcdsaSuites.append(TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8)\n    ecdheEcdsaSuites.append(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA)\n    ecdheEcdsaSuites.append(TLS_ECDHE_ECDSA_WITH_NULL_SHA)\n\n    @classmethod\n    def getEcdsaSuites(cls, settings, version=None):\n        \"\"\"Provide ECDSA authenticated ciphersuites matching settings\"\"\"\n        return cls._filterSuites(CipherSuite.ecdheEcdsaSuites,\n                                 settings, version)\n\n    #: DHE key exchange, DSA authentication\n    dheDsaSuites = []\n    dheDsaSuites.append(TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA)\n    dheDsaSuites.append(TLS_DHE_DSS_WITH_AES_128_CBC_SHA)\n    dheDsaSuites.append(TLS_DHE_DSS_WITH_AES_256_CBC_SHA)\n    dheDsaSuites.append(TLS_DHE_DSS_WITH_AES_128_CBC_SHA256)\n    dheDsaSuites.append(TLS_DHE_DSS_WITH_AES_256_CBC_SHA256)\n    dheDsaSuites.append(TLS_DHE_DSS_WITH_AES_128_GCM_SHA256)\n    dheDsaSuites.append(TLS_DHE_DSS_WITH_AES_256_GCM_SHA384)\n\n    @classmethod\n    def getDheDsaSuites(cls, settings, version=None):\n        \"\"\"Provide DSA authenticated ciphersuites matching settings\"\"\"\n        return cls._filterSuites(CipherSuite.dheDsaSuites,\n                                 settings, version)\n\n    #: anon FFDHE key exchange\n    anonSuites = []\n    anonSuites.append(TLS_DH_ANON_WITH_AES_256_GCM_SHA384)\n    anonSuites.append(TLS_DH_ANON_WITH_AES_128_GCM_SHA256)\n    anonSuites.append(TLS_DH_ANON_WITH_AES_256_CBC_SHA256)\n    anonSuites.append(TLS_DH_ANON_WITH_AES_256_CBC_SHA)\n    anonSuites.append(TLS_DH_ANON_WITH_AES_128_CBC_SHA256)\n    anonSuites.append(TLS_DH_ANON_WITH_AES_128_CBC_SHA)\n    anonSuites.append(TLS_DH_ANON_WITH_3DES_EDE_CBC_SHA)\n    anonSuites.append(TLS_DH_ANON_WITH_RC4_128_MD5)\n\n    @classmethod\n    def getAnonSuites(cls, settings, version=None):\n        \"\"\"Provide anonymous DH ciphersuites matching settings\"\"\"\n        return cls._filterSuites(CipherSuite.anonSuites, settings, version)\n\n    dhAllSuites = dheCertSuites + anonSuites + dheDsaSuites\n\n    #: anon ECDHE key exchange\n    ecdhAnonSuites = []\n    ecdhAnonSuites.append(TLS_ECDH_ANON_WITH_AES_256_CBC_SHA)\n    ecdhAnonSuites.append(TLS_ECDH_ANON_WITH_AES_128_CBC_SHA)\n    ecdhAnonSuites.append(TLS_ECDH_ANON_WITH_3DES_EDE_CBC_SHA)\n    ecdhAnonSuites.append(TLS_ECDH_ANON_WITH_RC4_128_SHA)\n    ecdhAnonSuites.append(TLS_ECDH_ANON_WITH_NULL_SHA)\n\n    @classmethod\n    def getEcdhAnonSuites(cls, settings, version=None):\n        \"\"\"Provide anonymous ECDH ciphersuites matching settings\"\"\"\n        return cls._filterSuites(CipherSuite.ecdhAnonSuites, settings, version)\n\n    #: all ciphersuites which use ephemeral ECDH key exchange\n    ecdhAllSuites = ecdheEcdsaSuites + ecdheCertSuites + ecdhAnonSuites\n\n    @staticmethod\n    def canonicalCipherName(ciphersuite):\n        \"\"\"Return the canonical name of the cipher whose number is provided.\"\"\"\n        if ciphersuite in CipherSuite.aes128GcmSuites:\n            return \"aes128gcm\"\n        elif ciphersuite in CipherSuite.aes256GcmSuites:\n            return \"aes256gcm\"\n        elif ciphersuite in CipherSuite.aes128Ccm_8Suites:\n            return \"aes128ccm_8\"\n        elif ciphersuite in CipherSuite.aes128CcmSuites:\n            return \"aes128ccm\"\n        elif ciphersuite in CipherSuite.aes256CcmSuites:\n            return \"aes256ccm\"\n        elif ciphersuite in CipherSuite.aes256Ccm_8Suites:\n            return \"aes256ccm_8\"\n        elif ciphersuite in CipherSuite.aes128Suites:\n            return \"aes128\"\n        elif ciphersuite in CipherSuite.aes256Suites:\n            return \"aes256\"\n        elif ciphersuite in CipherSuite.rc4Suites:\n            return \"rc4\"\n        elif ciphersuite in CipherSuite.tripleDESSuites:\n            return \"3des\"\n        elif ciphersuite in CipherSuite.nullSuites:\n            return \"null\"\n        elif ciphersuite in CipherSuite.chacha20draft00Suites:\n            return \"chacha20-poly1305_draft00\"\n        elif ciphersuite in CipherSuite.chacha20Suites:\n            return \"chacha20-poly1305\"\n        else:\n            return None\n\n    @staticmethod\n    def canonicalMacName(ciphersuite):\n        \"\"\"Return the canonical name of the MAC whose number is provided.\"\"\"\n        if ciphersuite in CipherSuite.sha384Suites:\n            return \"sha384\"\n        elif ciphersuite in CipherSuite.sha256Suites:\n            return \"sha256\"\n        elif ciphersuite in CipherSuite.shaSuites:\n            return \"sha\"\n        elif ciphersuite in CipherSuite.md5Suites:\n            return \"md5\"\n        else:\n            return None\n\n\n# The following faults are induced as part of testing.  The faultAlerts\n# dictionary describes the allowed alerts that may be triggered by these\n# faults.\nclass Fault:\n    badUsername = 101\n    badPassword = 102\n    badA = 103\n    clientSrpFaults = list(range(101,104))\n\n    badVerifyMessage = 601\n    clientCertFaults = list(range(601,602))\n\n    badPremasterPadding = 501\n    shortPremasterSecret = 502\n    clientNoAuthFaults = list(range(501,503))\n\n    badB = 201\n    serverFaults = list(range(201,202))\n\n    badFinished = 300\n    badMAC = 301\n    badPadding = 302\n    genericFaults = list(range(300,303))\n\n    faultAlerts = {\\\n        badUsername: (AlertDescription.unknown_psk_identity, \\\n                      AlertDescription.bad_record_mac),\\\n        badPassword: (AlertDescription.bad_record_mac,),\\\n        badA: (AlertDescription.illegal_parameter,),\\\n        badPremasterPadding: (AlertDescription.bad_record_mac,),\\\n        shortPremasterSecret: (AlertDescription.bad_record_mac,),\\\n        badVerifyMessage: (AlertDescription.decrypt_error,),\\\n        badFinished: (AlertDescription.decrypt_error,),\\\n        badMAC: (AlertDescription.bad_record_mac,),\\\n        badPadding: (AlertDescription.bad_record_mac,)\n        }\n\n    faultNames = {\\\n        badUsername: \"bad username\",\\\n        badPassword: \"bad password\",\\\n        badA: \"bad A\",\\\n        badPremasterPadding: \"bad premaster padding\",\\\n        shortPremasterSecret: \"short premaster secret\",\\\n        badVerifyMessage: \"bad verify message\",\\\n        badFinished: \"bad finished message\",\\\n        badMAC: \"bad MAC\",\\\n        badPadding: \"bad padding\"\n        }\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/defragmenter.py",
    "content": "# Copyright (c) 2015, Hubert Kario\n#\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Helper package for handling fragmentation of messages.\"\"\"\n\nfrom __future__ import generators\n\nfrom .utils.codec import Parser\nfrom .utils.deprecations import deprecated_attrs, deprecated_params\n\n\n@deprecated_attrs({\"add_static_size\": \"addStaticSize\",\n                   \"add_dynamic_size\": \"addDynamicSize\",\n                   \"add_data\": \"addData\",\n                   \"get_message\": \"getMessage\",\n                   \"clear_buffers\": \"clearBuffers\"})\nclass Defragmenter(object):\n    \"\"\"\n    Class for demultiplexing TLS messages.\n\n    Since the messages can be interleaved and fragmented between each other\n    we need to cache not complete ones and return in order of urgency.\n\n    Supports messages with given size (like Alerts) or with a length header\n    in specific place (like Handshake messages).\n\n    :ivar priorities: order in which messages from given types should be\n        returned.\n    :ivar buffers: data buffers for message types\n    :ivar decoders: functions which check buffers if a message of given type\n        is complete\n    \"\"\"\n\n    def __init__(self):\n        \"\"\"Set up empty defregmenter\"\"\"\n        self.priorities = []\n        self.buffers = {}\n        self.decoders = {}\n\n    @deprecated_params({\"msg_type\": \"msgType\"})\n    def add_static_size(self, msg_type, size):\n        \"\"\"Add a message type which all messages are of same length\"\"\"\n        if msg_type in self.priorities:\n            raise ValueError(\"Message type already defined\")\n        if size < 1:\n            raise ValueError(\"Message size must be positive integer\")\n\n        self.priorities += [msg_type]\n\n        self.buffers[msg_type] = bytearray(0)\n        def size_handler(data):\n            \"\"\"\n            Size of message in parameter\n\n            If complete message is present in parameter returns its size,\n            None otherwise.\n            \"\"\"\n            if len(data) < size:\n                return None\n            else:\n                return size\n        self.decoders[msg_type] = size_handler\n\n    @deprecated_params({\"msg_type\": \"msgType\",\n                        \"size_offset\": \"sizeOffset\",\n                        \"size_of_size\": \"sizeOfSize\"})\n    def add_dynamic_size(self, msg_type, size_offset, size_of_size):\n        \"\"\"Add a message type which has a dynamic size set in a header\"\"\"\n        if msg_type in self.priorities:\n            raise ValueError(\"Message type already defined\")\n        if size_of_size < 1:\n            raise ValueError(\"Size of size must be positive integer\")\n        if size_offset < 0:\n            raise ValueError(\"Offset can't be negative\")\n\n        self.priorities += [msg_type]\n        self.buffers[msg_type] = bytearray(0)\n\n        def size_handler(data):\n            \"\"\"\n            Size of message in parameter\n\n            If complete message is present in parameter returns its size,\n            None otherwise.\n            \"\"\"\n            if len(data) < size_offset+size_of_size:\n                return None\n            else:\n                parser = Parser(data)\n                # skip the header\n                parser.skip_bytes(size_offset)\n\n                payload_length = parser.get(size_of_size)\n                if parser.getRemainingLength() < payload_length:\n                    # not enough bytes in buffer\n                    return None\n                return size_offset + size_of_size + payload_length\n\n        self.decoders[msg_type] = size_handler\n\n    @deprecated_params({\"msg_type\": \"msgType\"})\n    def add_data(self, msg_type, data):\n        \"\"\"Adds data to buffers\"\"\"\n        if msg_type not in self.priorities:\n            raise ValueError(\"Message type not defined\")\n\n        self.buffers[msg_type] += data\n\n    def get_message(self):\n        \"\"\"Extract the highest priority complete message from buffer\"\"\"\n        for msg_type in self.priorities:\n            buf = self.buffers[msg_type]\n            length = self.decoders[msg_type](buf)\n            if length is None:\n                continue\n\n            # extract message\n            data = buf[:length]\n            # remove it from buffer\n            del buf[:length]\n            return (msg_type, data)\n        return None\n\n    def clear_buffers(self):\n        \"\"\"Remove all data from buffers\"\"\"\n        for key in self.buffers.keys():\n            self.buffers[key] = bytearray(0)\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/dh.py",
    "content": "# Author:\n#    Hubert Kario\n\n\"\"\"Handling of Diffie-Hellman parameter files.\"\"\"\n\nfrom .utils.asn1parser import ASN1Parser\nfrom .utils.pem import dePem\nfrom .utils.cryptomath import bytesToNumber\n\n\ndef parseBinary(data):\n    \"\"\"\n    Parse DH parameters from ASN.1 DER encoded binary string.\n\n    :param bytes data: DH parameters\n    :rtype: tuple of int\n    \"\"\"\n    parser = ASN1Parser(data)\n\n    prime = parser.getChild(0)\n    gen = parser.getChild(1)\n\n    return (bytesToNumber(gen.value), bytesToNumber(prime.value))\n\n\ndef parse(data):\n    \"\"\"\n    Parses DH parameters from a binary string.\n\n    The string can either by PEM or DER encoded\n\n    :param bytes data: DH parameters\n    :rtype: tuple of int\n    :returns: generator and prime\n    \"\"\"\n    try:\n        return parseBinary(data)\n    except (SyntaxError, TypeError):\n        pass\n\n    binData = dePem(data, \"DH PARAMETERS\")\n    return parseBinary(binData)\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/errors.py",
    "content": "# Authors: \n#   Trevor Perrin\n#   Dave Baggett (Arcode Corporation) - Added TLSUnsupportedError.\n#\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Exception classes.\"\"\"\nimport socket\n\nfrom .constants import AlertDescription, AlertLevel\n\nclass BaseTLSException(Exception):\n    \"\"\"\n    Metaclass for TLS Lite exceptions.\n\n    Look to :py:class:`tlslite.errors.TLSError` for exceptions that should be\n    caught by tlslite\n    consumers\n    \"\"\"\n\n    pass\n\n\nclass EncryptionError(BaseTLSException):\n    \"\"\"Base class for exceptions thrown while encrypting.\"\"\"\n\n    pass\n\n\nclass TLSError(BaseTLSException):\n    \"\"\"Base class for all TLS Lite exceptions.\"\"\"\n\n    def __str__(self):\n        \"\"\"At least print out the Exception time for str(...).\"\"\"\n        return repr(self)\n\n\nclass TLSClosedConnectionError(TLSError, socket.error):\n    \"\"\"An attempt was made to use the connection after it was closed.\"\"\"\n\n    pass\n\n\nclass TLSAbruptCloseError(TLSError):\n    \"\"\"The socket was closed without a proper TLS shutdown.\n\n    The TLS specification mandates that an alert of some sort\n    must be sent before the underlying socket is closed.  If the socket\n    is closed without this, it could signify that an attacker is trying\n    to truncate the connection.  It could also signify a misbehaving\n    TLS implementation, or a random network failure.\n    \"\"\"\n\n    pass\n\n\nclass TLSAlert(TLSError):\n    \"\"\"A TLS alert has been signalled.\"\"\"\n\n    pass\n\n\nclass TLSLocalAlert(TLSAlert):\n    \"\"\"A TLS alert has been signalled by the local implementation.\n\n    :vartype description: int\n    :ivar description: Set to one of the constants in\n        :py:class:`tlslite.constants.AlertDescription`\n\n    :vartype level: int\n    :ivar level: Set to one of the constants in\n        :py:class:`tlslite.constants.AlertLevel`\n\n    :vartype message: str\n    :ivar message: Description of what went wrong.\n    \"\"\"\n\n    def __init__(self, alert, message=None):\n        self.description = alert.description\n        self.level = alert.level\n        self.message = message\n\n    def __str__(self):\n        alertStr = AlertDescription.toStr(self.description)\n        if self.message:\n            return alertStr + \": \" + self.message\n        else:\n            return alertStr\n\n\nclass TLSRemoteAlert(TLSAlert):\n    \"\"\"\n    A TLS alert has been signalled by the remote implementation.\n\n    :vartype description: int\n    :ivar description: Set to one of the constants in\n        :py:class:`tlslite.constants.AlertDescription`\n\n    :vartype level: int\n    :ivar level: Set to one of the constants in\n        :py:class:`tlslite.constants.AlertLevel`\n    \"\"\"\n\n    def __init__(self, alert):\n        self.description = alert.description\n        self.level = alert.level\n\n    def __str__(self):\n        alertStr = AlertDescription.toStr(self.description)\n        return alertStr\n\n\nclass TLSAuthenticationError(TLSError):\n    \"\"\"\n    The handshake succeeded, but the other party's authentication\n    was inadequate.\n\n    This exception will only be raised when a\n    :py:class:`tlslite.Checker.Checker` has been passed to a handshake\n    function.\n    The Checker will be invoked once the handshake completes, and if\n    the Checker objects to how the other party authenticated, a\n    subclass of this exception will be raised.\n    \"\"\"\n\n    pass\n\n\nclass TLSNoAuthenticationError(TLSAuthenticationError):\n    \"\"\"The Checker was expecting the other party to authenticate with a\n    certificate chain, but this did not occur.\"\"\"\n\n    pass\n\n\nclass TLSAuthenticationTypeError(TLSAuthenticationError):\n    \"\"\"The Checker was expecting the other party to authenticate with a\n    different type of certificate chain.\"\"\"\n\n    pass\n\n\nclass TLSFingerprintError(TLSAuthenticationError):\n    \"\"\"The Checker was expecting the other party to authenticate with a\n    certificate chain that matches a different fingerprint.\"\"\"\n\n    pass\n\n\nclass TLSAuthorizationError(TLSAuthenticationError):\n    \"\"\"The Checker was expecting the other party to authenticate with a\n    certificate chain that has a different authorization.\"\"\"\n\n    pass\n\n\nclass TLSValidationError(TLSAuthenticationError):\n    \"\"\"The Checker has determined that the other party's certificate\n    chain is invalid.\"\"\"\n\n    def __init__(self, msg, info=None):\n        # Include a dict containing info about this validation failure\n        TLSAuthenticationError.__init__(self, msg)\n        self.info = info\n\n\nclass TLSFaultError(TLSError):\n    \"\"\"The other party responded incorrectly to an induced fault.\n\n    This exception will only occur during fault testing, when a\n    :py:class:`tlslite.tlsconnection.TLSConnection`'s fault variable is\n    set to induce some sort of\n    faulty behavior, and the other party doesn't respond appropriately.\n    \"\"\"\n\n    pass\n\n\nclass TLSUnsupportedError(TLSError):\n    \"\"\"The implementation doesn't support the requested (or required)\n    capabilities.\"\"\"\n\n    pass\n\n\nclass TLSInternalError(TLSError):\n    \"\"\"The internal state of object is unexpected or invalid.\n\n    Caused by incorrect use of API.\n    \"\"\"\n\n    pass\n\n\nclass TLSProtocolException(BaseTLSException):\n    \"\"\"Exceptions used internally for handling errors in received messages\"\"\"\n\n    pass\n\n\nclass TLSIllegalParameterException(TLSProtocolException):\n    \"\"\"Parameters specified in message were incorrect or invalid\"\"\"\n\n    pass\n\n\nclass TLSDecodeError(TLSProtocolException):\n    \"\"\"The received message encoding does not match specification.\"\"\"\n\n    pass\n\n\nclass TLSUnexpectedMessage(TLSProtocolException):\n    \"\"\"\n    The received message was unexpected or parsing of Inner Plaintext\n    failed\n    \"\"\"\n\n    pass\n\n\nclass TLSRecordOverflow(TLSProtocolException):\n    \"\"\"The received record size was too big\"\"\"\n\n    pass\n\n\nclass TLSDecryptionFailed(TLSProtocolException):\n    \"\"\"Decryption of data was unsuccessful\"\"\"\n\n    pass\n\n\nclass TLSBadRecordMAC(TLSProtocolException):\n    \"\"\"Bad MAC (or padding in case of mac-then-encrypt)\"\"\"\n\n    pass\n\n\nclass TLSInsufficientSecurity(TLSProtocolException):\n    \"\"\"Parameters selected by user are too weak\"\"\"\n\n    pass\n\n\nclass TLSUnknownPSKIdentity(TLSProtocolException):\n    \"\"\"The PSK or SRP identity is unknown\"\"\"\n\n    pass\n\n\nclass TLSHandshakeFailure(TLSProtocolException):\n    \"\"\"Could not find acceptable set of handshake parameters\"\"\"\n\n    pass\n\n\nclass MaskTooLongError(EncryptionError):\n    \"\"\"The maskLen passed into function is too high\"\"\"\n\n    pass\n\n\nclass MessageTooLongError(EncryptionError):\n    \"\"\"The message passed into function is too long\"\"\"\n\n    pass\n\n\nclass EncodingError(EncryptionError):\n    \"\"\"An error appeared while encoding\"\"\"\n\n    pass\n\n\nclass InvalidSignature(EncryptionError):\n    \"\"\"Verification function found invalid signature\"\"\"\n\n    pass\n\n\nclass UnknownRSAType(EncryptionError):\n    \"\"\"Unknown RSA algorithm type passed\"\"\"\n\n    pass\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/extensions.py",
    "content": "# Copyright (c) 2014, 2015 Hubert Kario\n#\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\" Helper package for handling TLS extensions encountered in ClientHello\nand ServerHello messages.\n\"\"\"\n\nfrom __future__ import generators\nfrom collections import namedtuple\nfrom .utils.codec import Writer, Parser, DecodeError\nfrom .constants import NameType, ExtensionType, CertificateStatusType, \\\n        SignatureAlgorithm, HashAlgorithm, SignatureScheme, \\\n        PskKeyExchangeMode, CertificateType, GroupName, ECPointFormat, \\\n        HeartbeatMode\nfrom .errors import TLSInternalError\n\n\nclass TLSExtension(object):\n    \"\"\"\n    Base class for handling handshake protocol hello messages extensions.\n\n    This class handles the generic information about TLS extensions used by\n    both sides of connection in Client Hello and Server Hello messages.\n    See https://tools.ietf.org/html/rfc4366 for more info.\n\n    It is used as a base class for specific users and as a way to store\n    extensions that are not implemented in library.\n\n    To implement a new extension you will need to create a new class which\n    calls this class contructor (__init__), usually specifying just the\n    extType parameter. The other methods which need to be implemented are:\n    `extData`, `create`, `parse` and `__repr__`. If the parser can be used\n    for client and optionally server extensions, the extension constructor\n    should be added to `_universalExtensions`. Otherwise, when the client and\n    server extensions have completely different forms, you should add client\n    form to the `_universalExtensions` and the server form to\n    `_serverExtensions`. Since the server MUST NOT send extensions not\n    advertised by client, there are no purely server-side extensions. But\n    if the client side extension is just marked by presence and has no payload,\n    the client side (thus the `_universalExtensions` may be skipped, then\n    the `TLSExtension` class will be used for implementing it. See\n    end of the file for type-to-constructor bindings.\n\n    .. note:: Subclassing for the purpose of parsing extensions\n        is not an officially supported part of API (just as underscores in\n        their\n        names would indicate).\n\n    :vartype extType: int\n    :ivar extType: a 2^16-1 limited integer specifying the type of the\n        extension that it contains, e.g. 0 indicates server name extension\n\n    :vartype ~.extData: bytearray\n    :ivar ~.extData: a byte array containing the value of the extension as\n        to be written on the wire\n\n    :vartype serverType: boolean\n    :ivar serverType: indicates that the extension was parsed with ServerHello\n        specific parser, otherwise it used universal or ClientHello specific\n        parser\n\n    :vartype encExtType: boolean\n    :ivar encExtType: indicates that the extension should be the type from\n        Encrypted Extensions\n\n    :vartype _universalExtensions: dict\n    :cvar _universalExtensions: dictionary with concrete implementations of\n        specific TLS extensions where key is the numeric value of the extension\n        ID. Contains ClientHello version of extensions or universal\n        implementations\n\n    :vartype _serverExtensions: dict\n    :cvar _serverExtensions: dictionary with concrete implementations of\n        specific TLS extensions where key is the numeric value of the extension\n        ID. Includes only those extensions that require special handlers for\n        ServerHello versions.\n\n    :vartype _certificateExtensions: dict\n    :cvar _certificateExtensions: dictionary with concrete implementations of\n        specific TLS extensions where the key is the numeric value of the\n        type of the extension and the value is the class. Includes only\n        those extensions that require special handlers for Certificate\n        message.\n\n    :vartype _hrrExtensions: dict\n    :cvar _hrrExtensions: dictionary with concrete implementation of specific\n        TLS extensions where the key is the numeric type of the extension\n        and the value is the class. Includes only those extensions that require\n        special handlers for the Hello Retry Request message.\n    \"\"\"\n    # actual definition at the end of file, after definitions of all classes\n    _universalExtensions = {}\n    _serverExtensions = {}\n    # _encryptedExtensions = {}\n    _certificateExtensions = {}\n    _hrrExtensions = {}\n\n    def __init__(self, server=False, extType=None, encExt=False,\n                 cert=False, hrr=False):\n        \"\"\"\n        Creates a generic TLS extension.\n\n        You'll need to use :py:meth:`create` or :py:meth:`parse` methods to\n        create an extension\n        that is actually usable.\n\n        :param bool server: whether to select ClientHello or ServerHello\n            version\n            for parsing\n        :param int extType: type of extension encoded as an integer, to be used\n            by subclasses\n        :param bool encExt: whether to select the EncryptedExtensions type\n            for parsing\n        :param bool cert: whether to select the Certificate type\n            of extension for parsing\n        :param bool hrr: whether to select the Hello Retry Request type\n            of extension for parsing\n        \"\"\"\n        self.extType = extType\n        self._extData = bytearray(0)\n        self.serverType = server\n        self.encExtType = encExt\n        self.cert = cert\n        self.hrr = hrr\n\n    @property\n    def extData(self):\n        \"\"\"\n        Return the on the wire encoding of extension\n\n        Child classes need to override this property so that it returns just\n        the payload of an extension, that is, without the 4 byte generic header\n        common to all extension. In other words, without the extension ID and\n        overall extension length.\n\n        :rtype: bytearray\n        \"\"\"\n        return self._extData\n\n    def _oldCreate(self, extType, data):\n        \"\"\"Legacy handling of create method\"\"\"\n        self.extType = extType\n        self._extData = data\n\n    def _newCreate(self, data):\n        \"\"\"New format for create method\"\"\"\n        self._extData = data\n\n    def create(self, *args, **kwargs):\n        \"\"\"\n        Initializes a generic TLS extension.\n\n        The extension can carry arbitrary data and have arbitrary payload, can\n        be used in client hello or server hello messages.\n\n        The legacy calling method uses two arguments - the `extType` and\n        `data`.\n        If the new calling method is used, only one argument is passed in -\n        `data`.\n\n        Child classes need to override this method so that it is possible\n        to set values for all fields used by the extension.\n\n        :param int extType: if int: type of the extension encoded as an integer\n            between `0` and `2^16-1`\n        :param bytearray data: raw data representing extension on the wire\n        :rtype: TLSExtension\n        \"\"\"\n        # old style\n        if len(args) + len(kwargs) == 2:\n            self._oldCreate(*args, **kwargs)\n        # new style\n        elif len(args) + len(kwargs) == 1:\n            self._newCreate(*args, **kwargs)\n        else:\n            raise TypeError(\"Invalid number of arguments\")\n\n        return self\n\n    def write(self):\n        \"\"\"Returns encoded extension, as encoded on the wire\n\n        Note that child classes in general don't need to override this method.\n\n        :rtype: bytearray\n        :returns: An array of bytes formatted as is supposed to be written on\n           the wire, including the extension_type, length and the extension\n           data\n\n        :raises AssertionError: when the object was not initialized\n        \"\"\"\n        assert self.extType is not None\n\n        w = Writer()\n        w.addTwo(self.extType)\n        data = self.extData\n        w.addTwo(len(data))\n        w.bytes += data\n        return w.bytes\n\n    @staticmethod\n    def _parseExt(parser, extType, extLength, extList):\n        \"\"\"Parse a extension using a predefined constructor\"\"\"\n        ext = extList[extType]()\n        extParser = Parser(parser.getFixBytes(extLength))\n        ext = ext.parse(extParser)\n        return ext\n\n    def parse(self, p):\n        \"\"\"Parses extension from on the wire format\n\n        Child classes should override this method so that it parses the\n        extension from on the wire data. Note that child class parsers will\n        not receive the generic header of the extension, but just a parser\n        with the payload. In other words, the method should be the exact\n        reverse of the `extData` property.\n\n        :param tlslite.util.codec.Parser p:  data to be parsed\n\n        :raises DecodeError: when the size of the passed element doesn't match\n            the internal representation\n\n        :rtype: TLSExtension\n        \"\"\"\n        extType = p.get(2)\n        try:\n            extLength = p.get(2)\n\n            for handler_t, handlers in (\n                    (self.cert, self._certificateExtensions),\n                    # (self.encExtType, self._encryptedExtensions),\n                    (self.serverType, self._serverExtensions),\n                    (self.hrr, self._hrrExtensions),\n                    (True, self._universalExtensions)):\n                if handler_t and extType in handlers:\n                    return self._parseExt(p, extType, extLength, handlers)\n\n            # if there is no custom handler for the extension, just save the\n            # extension data as there are extensions which\n            # don't require specific handlers and indicate option by mere presence\n            # also, we need to be able to handle unrecognised extensions in\n            # ClientHello and CertificateRequest\n            self.extType = extType\n            self._extData = p.getFixBytes(extLength)\n            assert len(self._extData) == extLength\n        except DecodeError as exc:\n            raise DecodeError(\"Malformed extension (type: {0}): {1}\".format(\n                ExtensionType.toStr(extType), str(exc)))\n        return self\n\n    def __eq__(self, that):\n        \"\"\"Test if two TLS extensions are effectively the same\n\n        Will check if encoding them will result in the same on the wire\n        representation.\n\n        Will return False for every object that's not an extension.\n        \"\"\"\n        if hasattr(that, 'extType') and hasattr(that, 'extData'):\n            return self.extType == that.extType and \\\n                    self.extData == that.extData\n        return False\n\n    def __repr__(self):\n        \"\"\"Output human readable representation of object\n\n        Child classes should override this method to support more appropriate\n        string rendering of the extension.\n\n        :rtype: str\n        \"\"\"\n        return \"TLSExtension(extType={0!r}, extData={1!r},\"\\\n               \" serverType={2!r}, encExtType={3!r})\".format(self.extType,\n                                                             self.extData,\n                                                             self.serverType,\n                                                             self.encExtType)\n\n\nclass CustomNameExtension(TLSExtension):\n    \"\"\"\n    Abstract class for handling custom name for payload variable.\n\n    Used for handling arbitrary extensions that deal with a single value\n    in payload (either an opaque data, single value or single array).\n\n    Must be subclassed.\n    \"\"\"\n    def __init__(self, field_name, extType):\n        \"\"\"\n        Create instance of the class.\n\n        :param str field_name: name of the field to store the extension payload\n        :param int ext_type: numerical ID of the extension\n        \"\"\"\n        super(CustomNameExtension, self).__init__(extType=extType)\n        self._field_name = field_name\n        self._internal_value = None\n\n    @property\n    def extData(self):\n        \"\"\"\n        Return raw data encoding of the extension.\n\n        :rtype: bytearray\n        \"\"\"\n        raise NotImplementedError(\"Abstract class\")\n\n    def create(self, values):\n        \"\"\"\n        Set the list to specified values.\n\n        :param list values: list of values to save\n        \"\"\"\n        self._internal_value = values\n        return self\n\n    def parse(self, parser):\n        \"\"\"\n        Deserialise extension from on-the-wire data.\n\n        :param tlslite.utils.codec.Parser parser: data\n        :rtype: Extension\n        \"\"\"\n        raise NotImplementedError(\"Abstract class\")\n\n    def __getattr__(self, name):\n        \"\"\"Return the special field name value.\"\"\"\n        if name == '_field_name':\n            raise AttributeError(\n                \"type object '{0}' has no attribute '{1}'\"\n                .format(self.__class__.__name__, name))\n        if name == self._field_name:\n            return self._internal_value\n        raise AttributeError(\n            \"type object '{0}' has no attribute '{1}'\"\n            .format(self.__class__.__name__, name))\n\n    def __setattr__(self, name, value):\n        \"\"\"Set the special field value.\"\"\"\n        if hasattr(self, '_field_name') and name == self._field_name:\n            self._internal_value = value\n            return\n        super(CustomNameExtension, self).__setattr__(name, value)\n\n\nclass VarBytesExtension(CustomNameExtension):\n    \"\"\"\n    Abstract class for extension that deal with single byte array payload.\n\n    Extension for handling arbitrary extensions that comprise of just\n    a single bytearray of variable size.\n    \"\"\"\n\n    def __init__(self, field_name, length_length, ext_type):\n        \"\"\"\n        Crate instance of the class.\n\n        :param str field_name: name of the field to store the bytearray\n            that is the payload\n        :param int length_length: number of bytes needed to encode the length\n            field of the string\n        :param int ext_type: numerical ID of the extension\n        \"\"\"\n        super(VarBytesExtension, self).__init__(field_name, extType=ext_type)\n        self._length_length = length_length\n\n    @property\n    def extData(self):\n        \"\"\"\n        Return raw data encoding of the extension.\n\n        :rtype: bytearray\n        \"\"\"\n        if self._internal_value is None:\n            return bytearray(0)\n\n        writer = Writer()\n        writer.add_var_bytes(self._internal_value, self._length_length)\n        return writer.bytes\n\n    def parse(self, parser):\n        \"\"\"Deserialise extension from on-the-wire data.\n\n        :param tlslite.utils.codec.Parser parser: data\n        :rtype: TLSExtension\n        \"\"\"\n        if not parser.getRemainingLength():\n            self._internal_value = None\n            return self\n\n        self._internal_value = parser.getVarBytes(self._length_length)\n\n        if parser.getRemainingLength():\n            raise DecodeError(\"Extra data after extension payload\")\n\n        return self\n\n    def __repr__(self):\n        \"\"\"Return human readable representation of the extension.\"\"\"\n        if self._internal_value is not None:\n            return \"{0}(len({1})={2})\".format(self.__class__.__name__,\n                                              self._field_name,\n                                              len(self._internal_value))\n        return \"{0}({1}=None)\".format(self.__class__.__name__,\n                                      self._field_name)\n\n\nclass ListExtension(CustomNameExtension):\n    \"\"\"\n    Abstract class for extensions that deal with single list in payload.\n\n    Extension for handling arbitrary extensions comprising of just a list\n    of same-sized elementes inside an array\n    \"\"\"\n\n    def __init__(self, fieldName, extType, item_enum=None):\n        \"\"\"\n        Create instance of the class.\n\n        :param str fieldName: name of the field to store the list that is\n            the payload\n        :param int extType: numerical ID of the extension\n        :param class item_enum: TLSEnum class that defines the enum of the\n            items in the list\n        \"\"\"\n        super(ListExtension, self).__init__(fieldName, extType=extType)\n        self._item_enum = item_enum\n\n    def _list_to_repr(self):\n        \"\"\"Return human redable representation of the item list\"\"\"\n        if not self._internal_value or not self._item_enum:\n            return \"{0!r}\".format(self._internal_value)\n\n        return \"[{0}]\".format(\n            \", \".join(self._item_enum.toStr(i) for i in self._internal_value))\n\n    def __repr__(self):\n        \"\"\"Return human readable representation of the extension.\"\"\"\n        return \"{0}({1}={2})\".format(self.__class__.__name__,\n                                     self._field_name,\n                                     self._list_to_repr())\n\n\nclass VarListExtension(ListExtension):\n    \"\"\"\n    Abstract extension for handling extensions comprised of uniform value list.\n\n    Extension for handling arbitrary extensions comprising of just a list\n    of same-sized elementes inside an array\n    \"\"\"\n\n    def __init__(self, elemLength, lengthLength, fieldName, extType,\n                 item_enum=None):\n        \"\"\"Create handler for extension that has a list of items as payload.\n\n        :param int elemLength: number of bytes needed to encode single element\n        :param int lengthLength: number of bytes needed to encode length field\n        :param str fieldName: name of the field storing the list of elements\n        :param int extType: numerical ID of the extension encoded\n        :param class item_enum: TLSEnum class that defines entries in the list\n        \"\"\"\n        super(VarListExtension, self).__init__(fieldName, extType=extType,\n                                               item_enum=item_enum)\n        self._elemLength = elemLength\n        self._lengthLength = lengthLength\n\n    @property\n    def extData(self):\n        \"\"\"\n        Return raw data encoding of the extension.\n\n        :rtype: bytearray\n        \"\"\"\n        if self._internal_value is None:\n            return bytearray(0)\n\n        writer = Writer()\n        writer.addVarSeq(self._internal_value,\n                         self._elemLength,\n                         self._lengthLength)\n        return writer.bytes\n\n    def parse(self, parser):\n        \"\"\"\n        Deserialise extension from on-the-wire data.\n\n        :param tlslite.utils.codec.Parser parser: data\n        :rtype: Extension\n        \"\"\"\n        if parser.getRemainingLength() == 0:\n            self._internal_value = None\n            return self\n\n        self._internal_value = parser.getVarList(self._elemLength,\n                                                 self._lengthLength)\n\n        if parser.getRemainingLength():\n            raise DecodeError(\"Extra data after extension payload\")\n\n        return self\n\n\nclass VarSeqListExtension(ListExtension):\n    \"\"\"\n    Abstract extension for handling extensions comprised of tuple list.\n\n    Extension for handling arbitrary extensions comprising of a single list\n    of same-sized elements in same-sized tuples\n    \"\"\"\n\n    def __init__(self, elemLength, elemNum, lengthLength, fieldName, extType,\n                 item_enum=None):\n        \"\"\"\n        Create a handler for extension that has a list of tuples as payload.\n\n        :param int elemLength: number of bytes needed to encode single element\n            of a tuple\n        :param int elemNum: number of elements in a tuple\n        :param int lengthLength: number of bytes needed to encode overall\n            length of the list\n        :param str fieldName: name of the field storing the list of elements\n        :param int extType: numerical ID of the extension encoded\n        :param class item_enum: TLSEnum class that defines entries in the list\n        \"\"\"\n        super(VarSeqListExtension, self).__init__(fieldName, extType=extType,\n                                                  item_enum=item_enum)\n        self._elemLength = elemLength\n        self._elemNum = elemNum\n        self._lengthLength = lengthLength\n\n    @property\n    def extData(self):\n        \"\"\"\n        Return raw data encoding of the extension.\n\n        :rtype: bytearray\n        \"\"\"\n        if self._internal_value is None:\n            return bytearray(0)\n\n        writer = Writer()\n        writer.addVarTupleSeq(self._internal_value,\n                              self._elemLength,\n                              self._lengthLength)\n        return writer.bytes\n\n    def parse(self, parser):\n        \"\"\"\n        Deserialise extension from on-the-wire data.\n\n        :param tlslite.utils.codec.Parser parser: data\n        :rtype: Extension\n        \"\"\"\n        if parser.getRemainingLength() == 0:\n            self._internal_value = None\n            return self\n\n        self._internal_value = parser.getVarTupleList(self._elemLength,\n                                                      self._elemNum,\n                                                      self._lengthLength)\n        if parser.getRemainingLength():\n            raise DecodeError(\"Extra data after extension payload\")\n\n        return self\n\n\nclass IntExtension(CustomNameExtension):\n    \"\"\"\n    Abstract class for extensions that deal with single integer in payload.\n\n    Extension for handling arbitrary extensions that have a payload that is\n    a single integer of a given size (1, 2, ... bytes)\n    \"\"\"\n\n    def __init__(self, elem_length, field_name, ext_type, item_enum=None):\n        \"\"\"Create handler for extension that has a single integer as payload.\n\n        :param str field_name: name of the field that will store the value\n        :param int elem_length: size (in bytes) of the value in the extension\n        :param int ext_tyoe: numerical ID of the extension encoded\n        :param class item_enum: TLSEnum class that defines entries in the\n            extension\n        \"\"\"\n        super(IntExtension, self).__init__(field_name, extType=ext_type)\n        self._elem_length = elem_length\n        self._item_enum = item_enum\n\n    def _entry_to_repr(self):\n        \"\"\"Return human readable representation of the value.\"\"\"\n        if self._item_enum:\n            return self._item_enum.toStr(self._internal_value)\n        return str(self._internal_value)\n\n    def __repr__(self):\n        \"\"\"Return human readable representation of the extension.\"\"\"\n        return \"{0}({1}={2})\".format(self.__class__.__name__,\n                                     self._field_name,\n                                     self._entry_to_repr())\n\n    @property\n    def extData(self):\n        \"\"\"Return raw data encoding of the extension.\n\n        :rtype: bytearray\n        \"\"\"\n        if self._internal_value is None:\n            return bytearray(0)\n\n        writer = Writer()\n        writer.add(self._internal_value, self._elem_length)\n        return writer.bytes\n\n    def parse(self, parser):\n        \"\"\"\n        Deserialise extension from on-the-wire data.\n\n        :param tlslite.utils.codec.Parser parser: data\n        :rtype: Extension\n        \"\"\"\n        if parser.getRemainingLength() == 0:\n            self._internal_value = None\n            return self\n\n        self._internal_value = parser.get(self._elem_length)\n\n        if parser.getRemainingLength():\n            raise DecodeError(\"Extra data after extension payload\")\n\n        return self\n\n\nclass SNIExtension(TLSExtension):\n    \"\"\"\n    Class for handling Server Name Indication (server_name) extension from\n    RFC 4366.\n\n    Note that while usually the client does advertise just one name, it is\n    possible to provide a list of names, each of different type.\n    The type is a single byte value (represented by ints), the names are\n    opaque byte strings, in case of DNS host names (records of type 0) they\n    are UTF-8 encoded domain names (without the ending dot).\n\n    :vartype hostNames: tuple of bytearrays\n    :ivar hostNames: tuple of hostnames (server name records of type 0)\n        advertised in the extension. Note that it may not include all names\n        from client hello as the client can advertise other types. Also note\n        that while it's not possible to change the returned array in place, it\n        is possible to assign a new set of names. IOW, this won't work::\n\n           sni_extension.hostNames[0] = bytearray(b'example.com')\n\n        while this will work::\n\n           names = list(sni_extension.hostNames)\n           names[0] = bytearray(b'example.com')\n           sni_extension.hostNames = names\n\n\n    :vartype serverNames: list of :py:class:`ServerName`\n    :ivar serverNames: list of all names advertised in extension.\n        :py:class:`ServerName` is a namedtuple with two elements, the first\n        element (type) defines the type of the name (encoded as int)\n        while the other (name) is a bytearray that carries the value.\n        Known types are defined in :py:class:`tlslite.constants.NameType`.\n        The list will be empty if the on the wire extension had and empty\n        list while it will be None if the extension was empty.\n\n    :vartype extType: int\n    :ivar extType: numeric type of SNIExtension, i.e. 0\n\n    :vartype ~.extData: bytearray\n    :ivar ~.extData: raw representation of the extension\n    \"\"\"\n\n    ServerName = namedtuple('ServerName', 'name_type name')\n\n    def __init__(self):\n        \"\"\"\n        Create an instance of SNIExtension.\n\n        See also: :py:meth:`create` and :py:meth:`parse`.\n        \"\"\"\n        super(SNIExtension, self).__init__(extType=ExtensionType.server_name)\n        self.serverNames = None\n\n    def __repr__(self):\n        \"\"\"\n        Return programmer-readable representation of extension\n\n        :rtype: str\n        \"\"\"\n        return \"SNIExtension(serverNames={0!r})\".format(self.serverNames)\n\n    def create(self, hostname=None, hostNames=None, serverNames=None):\n        \"\"\"\n        Initializes an instance with provided hostname, host names or\n        raw server names.\n\n        Any of the parameters may be `None`, in that case the list inside the\n        extension won't be defined, if either `hostNames` or `serverNames` is\n        an empty list, then the extension will define a list of length 0.\n\n        If multiple parameters are specified at the same time, then the\n        resulting list of names will be concatenated in order of hostname,\n        hostNames and serverNames last.\n\n        :param bytearray hostname: raw UTF-8 encoding of the host name\n\n        :param list hostNames: list of raw UTF-8 encoded host names\n\n        :param list serverNames: pairs of name_type and name encoded as a\n            namedtuple\n\n        :rtype: SNIExtension\n        \"\"\"\n        if hostname is None and hostNames is None and serverNames is None:\n            self.serverNames = None\n            return self\n        else:\n            self.serverNames = []\n\n        if hostname:\n            self.serverNames += \\\n                [SNIExtension.ServerName(NameType.host_name, hostname)]\n\n        if hostNames:\n            self.serverNames += \\\n                [SNIExtension.ServerName(NameType.host_name, x) for x in\n                 hostNames]\n\n        if serverNames:\n            self.serverNames += serverNames\n\n        return self\n\n    @property\n    def hostNames(self):\n        \"\"\" Returns a simulated list of hostNames from the extension.\n\n        :rtype: tuple of bytearrays\n        \"\"\"\n        # because we can't simulate assignments to array elements we return\n        # an immutable type\n        if self.serverNames is None:\n            return tuple()\n        return tuple([x.name for x in self.serverNames if\n                      x.name_type == NameType.host_name])\n\n    @hostNames.setter\n    def hostNames(self, hostNames):\n        \"\"\" Removes all host names from the extension and replaces them by\n        names in `hostNames` parameter.\n\n        Newly added parameters will be added at the beginning of the list\n        of extensions.\n\n        :param iterable hostNames: host names (bytearrays) to replace the\n            old server names of type 0\n        \"\"\"\n\n        self.serverNames = \\\n            [SNIExtension.ServerName(NameType.host_name, x) for x in\n             hostNames] + \\\n            [x for x in self.serverNames if x.name_type != NameType.host_name]\n\n    @hostNames.deleter\n    def hostNames(self):\n        \"\"\"\n        Remove all host names from extension, leaves other name types\n        unmodified.\n        \"\"\"\n        self.serverNames = [x for x in self.serverNames if\n                            x.name_type != NameType.host_name]\n\n    @property\n    def extData(self):\n        \"\"\"\n        Raw encoding of extension data, without type and length header.\n\n        :rtype: bytearray\n        \"\"\"\n        if self.serverNames is None:\n            return bytearray(0)\n\n        w2 = Writer()\n        for server_name in self.serverNames:\n            w2.add(server_name.name_type, 1)\n            w2.add(len(server_name.name), 2)\n            w2.bytes += server_name.name\n\n        # note that when the array is empty we write it as array of length 0\n        w = Writer()\n        w.add(len(w2.bytes), 2)\n        w.bytes += w2.bytes\n        return w.bytes\n\n    def write(self):\n        \"\"\"\n        Returns encoded extension, as encoded on the wire\n\n        :rtype: bytearray\n        :returns: an array of bytes formatted as they are supposed to be\n            written\n            on the wire, including the type, length and extension data\n        \"\"\"\n\n        raw_data = self.extData\n\n        w = Writer()\n        w.add(self.extType, 2)\n        w.add(len(raw_data), 2)\n        w.bytes += raw_data\n\n        return w.bytes\n\n    def parse(self, p):\n        \"\"\"\n        Deserialise the extension from on-the-wire data\n\n        The parser should not include the type or length of extension!\n\n        :param tlslite.util.codec.Parser p: data to be parsed\n\n        :rtype: SNIExtension\n        :raises DecodeError: when the internal sizes don't match the attached\n            data\n        \"\"\"\n        if p.getRemainingLength() == 0:\n            return self\n\n        self.serverNames = []\n\n        p.startLengthCheck(2)\n        while not p.atLengthCheck():\n            sn_type = p.get(1)\n            sn_name = p.getVarBytes(2)\n            self.serverNames += [SNIExtension.ServerName(sn_type, sn_name)]\n        p.stopLengthCheck()\n\n        if p.getRemainingLength():\n            raise DecodeError(\"Extra data after extension payload\")\n\n        return self\n\n\nclass SupportedVersionsExtension(VarSeqListExtension):\n    \"\"\"\n    This class handles the SupportedVersion extensions used in TLS 1.3.\n\n    See draft-ietf-tls-tls13.\n\n    :vartype extType: int\n    :ivar extType: numeric type of the Supported Versions extension, i.e. 43\n\n    :vartype ~.extData: bytearray\n    :ivar ~.extData: raw representation of the extension data\n\n    :vartype versions: list of tuples\n    :ivar versions: list of supported protocol versions; each tuple has two\n        one byte long integers\n    \"\"\"\n\n    def __init__(self):\n        \"\"\"Create an instance of SupportedVersionsExtension.\"\"\"\n        super(SupportedVersionsExtension, self).__init__(\n            1, 2, 1,\n            \"versions\",\n            extType=ExtensionType.supported_versions)\n\n\nclass CompressCertificateExtension(VarSeqListExtension):\n    \"\"\"\n    This class handles the SupportedVersion extensions used in TLS 1.3.\n\n    See draft-ietf-tls-tls13.\n\n    :vartype extType: int\n    :ivar extType: numeric type of the Supported Versions extension, i.e. 43\n\n    :vartype ~.extData: bytearray\n    :ivar ~.extData: raw representation of the extension data\n\n    :vartype versions: list of tuples\n    :ivar versions: list of supported protocol versions; each tuple has two\n        one byte long integers\n    \"\"\"\n\n    def __init__(self):\n        \"\"\"Create an instance of SupportedVersionsExtension.\"\"\"\n        super(CompressCertificateExtension, self).__init__(\n            1, 2, 1,\n            \"algorithm\",\n            extType=ExtensionType.compress_certificate)\n\n\nclass SrvSupportedVersionsExtension(TLSExtension):\n    \"\"\"\n    Handling of SupportedVersion extension in SH and HRR in TLS 1.3.\n\n    See draft-ietf-tls-tls13.\n\n    :vartype extType: int\n    :ivar extType: numeric type of the Supported Versions extension, i.e. 43\n\n    :vartype ~.extData: bytearray\n    :ivar ~.extData: raw representation of the extension payload\n\n    :vartype ~.version: tuple\n    :ivar ~.version: version selected by the server\n    \"\"\"\n\n    def __init__(self):\n        super(SrvSupportedVersionsExtension, self).__init__(\n            extType=ExtensionType.supported_versions)\n        self.version = None\n\n    def __repr__(self):\n        \"\"\"\n        Return programmer-readable representation of the extension.\n\n        :rtype: str\n        \"\"\"\n        return \"SrvSupportedVersionsExtension(version={0})\".format(\n            self.version)\n\n    def create(self, version):\n        \"\"\"\n        Set the version supported by the server.\n\n        :param tuple version: Version selected by server.\n        :rtype: SrvSupportedVersionsExtension\n        \"\"\"\n        self.version = version\n        return self\n\n    @property\n    def extData(self):\n        \"\"\"\n        Raw encoding of extension data, without type and length header.\n\n        :rtype: bytearray\n        \"\"\"\n        if self.version is None:\n            return bytearray()\n\n        writer = Writer()\n        writer.addFixSeq(self.version, 1)\n        return writer.bytes\n\n    def parse(self, parser):\n        \"\"\"\n        Deserialise the extension from on-the-wire data.\n\n        The parser should not include the type or length of extension.\n\n        :param tlslite.util.codec.Parser parser: data to be parsed\n\n        :rtype: SrvSupportedVersionsExtension\n        \"\"\"\n        self.version = tuple(parser.getFixList(1, 2))\n\n        if parser.getRemainingLength():\n            raise DecodeError(\"Extra data after extension payload\")\n\n        return self\n\n\nclass ClientCertTypeExtension(VarListExtension):\n    \"\"\"\n    This class handles the (client variant of) Certificate Type extension\n\n    See RFC 6091.\n\n    :vartype extType: int\n    :ivar extType: numeric type of Certificate Type extension, i.e. 9\n\n    :vartype ~.extData: bytearray\n    :ivar ~.extData: raw representation of the extension data\n\n    :vartype certTypes: list of int\n    :ivar certTypes: list of certificate type identifiers (each one byte long)\n    \"\"\"\n\n    def __init__(self):\n        \"\"\"\n        Create an instance of ClientCertTypeExtension\n\n        See also: :py:meth:`create` and :py:meth:`parse`\n        \"\"\"\n        super(ClientCertTypeExtension, self).__init__(\n            1, 1, 'certTypes',\n            ExtensionType.cert_type,\n            CertificateType)\n\n\nclass ServerCertTypeExtension(IntExtension):\n    \"\"\"\n    This class handles the Certificate Type extension (variant sent by server)\n    defined in RFC 6091.\n\n    :vartype extType: int\n    :ivar extType: binary type of Certificate Type extension, i.e. 9\n\n    :vartype ~.extData: bytearray\n    :ivar ~.extData: raw representation of the extension data\n\n    :vartype cert_type: int\n    :ivar cert_type: the certificate type selected by server\n    \"\"\"\n\n    def __init__(self):\n        \"\"\"\n        Create an instance of ServerCertTypeExtension\n\n        See also: :py:meth:`create` and :py:meth:`parse`\n        \"\"\"\n        super(ServerCertTypeExtension, self).__init__(\n            1, 'cert_type', ext_type=ExtensionType.cert_type,\n            item_enum=CertificateType)\n        self.serverType = True\n\n    def parse(self, parser):\n        \"\"\"Parse the extension from on the wire format\n\n        :param Parser p: parser with data\n        \"\"\"\n        # generic code allows empty, this ext does not\n        if not parser.getRemainingLength():\n            raise DecodeError(\"Empty payload in extension\")\n        return super(ServerCertTypeExtension, self).parse(parser)\n\n\nclass SRPExtension(TLSExtension):\n    \"\"\"\n    This class handles the Secure Remote Password protocol TLS extension\n    defined in RFC 5054.\n\n    :vartype extType: int\n    :ivar extType: numeric type of SRPExtension, i.e. 12\n\n    :vartype ~.extData: bytearray\n    :ivar ~.extData: raw representation of extension data\n\n    :vartype identity: bytearray\n    :ivar identity: UTF-8 encoding of user name\n    \"\"\"\n\n    def __init__(self):\n        \"\"\"\n        Create an instance of SRPExtension\n\n        See also: :py:meth:`create` and :py:meth:`parse`\n        \"\"\"\n        super(SRPExtension, self).__init__(extType=ExtensionType.srp)\n\n        self.identity = None\n\n    def __repr__(self):\n        \"\"\"\n        Return programmer-centric description of extension\n\n        :rtype: str\n        \"\"\"\n        return \"SRPExtension(identity={0!r})\".format(self.identity)\n\n    @property\n    def extData(self):\n        \"\"\"\n        Return raw data encoding of the extension\n\n        :rtype: bytearray\n        \"\"\"\n\n        if self.identity is None:\n            return bytearray(0)\n\n        w = Writer()\n        w.add(len(self.identity), 1)\n        w.addFixSeq(self.identity, 1)\n\n        return w.bytes\n\n    def create(self, identity=None):\n        \"\"\" Create and instance of SRPExtension with specified protocols\n\n        :param bytearray identity: UTF-8 encoded identity (user name) to be\n            provided\n            to user. MUST be shorter than 2^8-1.\n\n        :raises ValueError: when the identity lenght is longer than 2^8-1\n        \"\"\"\n\n        if identity is None:\n            return self\n\n        if len(identity) >= 2**8:\n            raise ValueError()\n\n        self.identity = identity\n        return self\n\n    def parse(self, p):\n        \"\"\"\n        Parse the extension from on the wire format\n\n        :param Parser p: data to be parsed\n\n        :raises DecodeError: when the data is internally inconsistent\n\n        :rtype: SRPExtension\n        \"\"\"\n\n        self.identity = p.getVarBytes(1)\n\n        return self\n\n\nclass NPNExtension(TLSExtension):\n    \"\"\"\n    This class handles the unofficial Next Protocol Negotiation TLS extension.\n\n    :vartype protocols: list of bytearrays\n    :ivar protocols: list of protocol names supported by the server\n\n    :vartype extType: int\n    :ivar extType: numeric type of NPNExtension, i.e. 13172\n\n    :vartype ~.extData: bytearray\n    :ivar ~.extData: raw representation of extension data\n    \"\"\"\n\n    def __init__(self):\n        \"\"\"\n        Create an instance of NPNExtension\n\n        See also: :py:meth:`create` and :py:meth:`parse`\n        \"\"\"\n        super(NPNExtension, self).__init__(extType=ExtensionType.supports_npn)\n\n        self.protocols = None\n\n    def __repr__(self):\n        \"\"\"\n        Create programmer-readable version of representation\n\n        :rtype: str\n        \"\"\"\n        return \"NPNExtension(protocols={0!r})\".format(self.protocols)\n\n    @property\n    def extData(self):\n        \"\"\" Return the raw data encoding of the extension\n\n        :rtype: bytearray\n        \"\"\"\n        if self.protocols is None:\n            return bytearray(0)\n\n        w = Writer()\n        for prot in self.protocols:\n            w.add(len(prot), 1)\n            w.addFixSeq(prot, 1)\n\n        return w.bytes\n\n    def create(self, protocols=None):\n        \"\"\" Create an instance of NPNExtension with specified protocols\n\n        :param list protocols: list of protocol names that are supported\n        \"\"\"\n        self.protocols = protocols\n        return self\n\n    def parse(self, p):\n        \"\"\" Parse the extension from on the wire format\n\n        :param Parser p: data to be parsed\n\n        :raises DecodeError: when the size of the passed element doesn't match\n            the internal representation\n\n        :rtype: NPNExtension\n        \"\"\"\n        self.protocols = []\n\n        while p.getRemainingLength() > 0:\n            self.protocols += [p.getVarBytes(1)]\n\n        return self\n\n\nclass TACKExtension(TLSExtension):\n    \"\"\"\n    This class handles the server side TACK extension (see\n    draft-perrin-tls-tack-02).\n\n    :vartype tacks: list\n    :ivar tacks: list of TACK's supported by server\n\n    :vartype activation_flags: int\n    :ivar activation_flags: activation flags for the tacks\n    \"\"\"\n\n    class TACK(object):\n        \"\"\"\n        Implementation of the single TACK\n        \"\"\"\n        def __init__(self):\n            \"\"\"\n            Create a single TACK object\n            \"\"\"\n            self.public_key = bytearray(64)\n            self.min_generation = 0\n            self.generation = 0\n            self.expiration = 0\n            self.target_hash = bytearray(32)\n            self.signature = bytearray(64)\n\n        def __repr__(self):\n            \"\"\"\n            Return programmmer readable representation of TACK object\n\n            :rtype: str\n            \"\"\"\n            return \"TACK(public_key={0!r}, min_generation={1!r}, \"\\\n                   \"generation={2!r}, expiration={3!r}, target_hash={4!r}, \"\\\n                   \"signature={5!r})\"\\\n                   .format(self.public_key, self.min_generation,\n                           self.generation, self.expiration, self.target_hash,\n                           self.signature)\n\n        def create(self, public_key, min_generation, generation, expiration,\n                   target_hash, signature):\n            \"\"\"\n            Initialise the TACK with data\n            \"\"\"\n            self.public_key = public_key\n            self.min_generation = min_generation\n            self.generation = generation\n            self.expiration = expiration\n            self.target_hash = target_hash\n            self.signature = signature\n            return self\n\n        def write(self):\n            \"\"\"\n            Convert the TACK into on the wire format\n\n            :rtype: bytearray\n            \"\"\"\n            w = Writer()\n            if len(self.public_key) != 64:\n                raise TLSInternalError(\"Public_key must be 64 bytes long\")\n            w.bytes += self.public_key\n            w.add(self.min_generation, 1)\n            w.add(self.generation, 1)\n            w.add(self.expiration, 4)\n            if len(self.target_hash) != 32:\n                raise TLSInternalError(\"Target_hash must be 32 bytes long\")\n            w.bytes += self.target_hash\n            if len(self.signature) != 64:\n                raise TLSInternalError(\"Signature must be 64 bytes long\")\n            w.bytes += self.signature\n            return w.bytes\n\n        def parse(self, p):\n            \"\"\"\n            Parse the TACK from on the wire format\n\n            :param Parser p: data to be parsed\n\n            :rtype: TACK\n            :raises DecodeError: when the internal sizes don't match the\n                provided data\n            \"\"\"\n\n            self.public_key = p.getFixBytes(64)\n            self.min_generation = p.get(1)\n            self.generation = p.get(1)\n            self.expiration = p.get(4)\n            self.target_hash = p.getFixBytes(32)\n            self.signature = p.getFixBytes(64)\n            return self\n\n        def __eq__(self, other):\n            \"\"\"\n            Tests if the other object is equivalent to this TACK\n\n            Returns False for every object that's not a TACK\n            \"\"\"\n            if hasattr(other, 'public_key') and\\\n                    hasattr(other, 'min_generation') and\\\n                    hasattr(other, 'generation') and\\\n                    hasattr(other, 'expiration') and\\\n                    hasattr(other, 'target_hash') and\\\n                    hasattr(other, 'signature'):\n                if self.public_key == other.public_key and\\\n                   self.min_generation == other.min_generation and\\\n                   self.generation == other.generation and\\\n                   self.expiration == other.expiration and\\\n                   self.target_hash == other.target_hash and\\\n                   self.signature == other.signature:\n                    return True\n                else:\n                    return False\n            else:\n                return False\n\n    def __init__(self):\n        \"\"\"\n        Create an instance of TACKExtension\n\n        See also: :py:meth:`create` and :py:meth`parse`\n        \"\"\"\n        super(TACKExtension, self).__init__(extType=ExtensionType.tack)\n\n        self.tacks = []\n        self.activation_flags = 0\n\n    def __repr__(self):\n        \"\"\"\n        Create a programmer readable representation of TACK extension\n\n        :rtype: str\n        \"\"\"\n        return \"TACKExtension(activation_flags={0!r}, tacks={1!r})\"\\\n               .format(self.activation_flags, self.tacks)\n\n    @property\n    def extData(self):\n        \"\"\"\n        Return the raw data encoding of the extension\n\n        :rtype: bytearray\n        \"\"\"\n        w2 = Writer()\n        for t in self.tacks:\n            w2.bytes += t.write()\n\n        w = Writer()\n        w.add(len(w2.bytes), 2)\n        w.bytes += w2.bytes\n        w.add(self.activation_flags, 1)\n        return w.bytes\n\n    def create(self, tacks, activation_flags):\n        \"\"\"\n        Initialize the instance of TACKExtension\n\n        :rtype: TACKExtension\n        \"\"\"\n\n        self.tacks = tacks\n        self.activation_flags = activation_flags\n        return self\n\n    def parse(self, p):\n        \"\"\"\n        Parse the extension from on the wire format\n\n        :param Parser p: data to be parsed\n\n        :rtype: TACKExtension\n        \"\"\"\n        self.tacks = []\n\n        p.startLengthCheck(2)\n        while not p.atLengthCheck():\n            tack = TACKExtension.TACK().parse(p)\n            self.tacks += [tack]\n        p.stopLengthCheck()\n        self.activation_flags = p.get(1)\n\n        return self\n\n\nclass SupportedGroupsExtension(VarListExtension):\n    \"\"\"\n    Client side list of supported groups of (EC)DHE key exchage.\n\n    See RFC4492, RFC7027 and RFC-ietf-tls-negotiated-ff-dhe-10\n\n    :vartype groups: int\n    :ivar groups: list of groups that the client supports\n    \"\"\"\n\n    def __init__(self):\n        \"\"\"Create instance of class\"\"\"\n        super(SupportedGroupsExtension, self).__init__(\n            2, 2, 'groups',\n            ExtensionType.supported_groups,\n            GroupName)\n\n\nclass ECPointFormatsExtension(VarListExtension):\n    \"\"\"\n    Client side list of supported ECC point formats.\n\n    See RFC4492.\n\n    :vartype formats: list of int\n    :ivar formats: list of point formats supported by peer\n    \"\"\"\n\n    def __init__(self):\n        \"\"\"Create instance of class\"\"\"\n        super(ECPointFormatsExtension, self).__init__(\n            1, 1, 'formats',\n            ExtensionType.ec_point_formats,\n            ECPointFormat)\n\n\nclass _SigListExt(VarSeqListExtension):\n    \"\"\"\n    Common methods to SignatureAlgorithmsExtension and\n    SignatureAlgorithmsCertExtension.\n    \"\"\"\n\n    def _list_to_repr(self):\n        \"\"\"Return a text representation of sigalgs field.\n\n        Override the one from ListExtension to be able to handle legacy\n        signature algorithms.\n        \"\"\"\n        if self.sigalgs is None:\n            return \"None\"\n\n        values = []\n        for alg in self.sigalgs:\n            name = SignatureScheme.toRepr(alg)\n            if name is None:\n                name = \"({0}, {1})\".format(HashAlgorithm.toStr(alg[0]),\n                                           SignatureAlgorithm.toStr(alg[1]))\n            values.append(name)\n\n        return \"[{0}]\".format(\", \".join(values))\n\n\nclass SignatureAlgorithmsExtension(_SigListExt):\n    \"\"\"\n    Client side list of supported signature algorithms.\n\n    Should be used by server to select certificate and signing method for\n    Server Key Exchange messages. In practice used only for the latter.\n\n    See RFC5246.\n    \"\"\"\n\n    def __init__(self):\n        \"\"\"Create instance of class\"\"\"\n        super(SignatureAlgorithmsExtension, self).__init__(\n            1, 2, 2,\n            'sigalgs',\n            ExtensionType.signature_algorithms,\n            SignatureScheme)\n\n\nclass SignatureAlgorithmsCertExtension(_SigListExt):\n    \"\"\"\n    Client side list of supported signatures in certificates.\n\n    Should be used when the signatures supported in certificates and in TLS\n    messages differ.\n\n    See TLS1.3 RFC\n    \"\"\"\n\n    def __init__(self):\n        \"\"\"Create instance of class.\"\"\"\n        super(SignatureAlgorithmsCertExtension, self).__init__(\n            1, 2, 2,\n            'sigalgs',\n            ExtensionType.signature_algorithms_cert,\n            SignatureScheme)\n\n\nclass PaddingExtension(TLSExtension):\n    \"\"\"\n    ClientHello message padding with a desired size.\n\n    Can be used to pad ClientHello messages to a desired size\n    in order to avoid implementation bugs caused by certain\n    ClientHello sizes.\n\n    See RFC7685.\n    \"\"\"\n\n    def __init__(self):\n        \"\"\"Create instance of class.\"\"\"\n        extType = ExtensionType.client_hello_padding\n        super(PaddingExtension, self).__init__(extType=extType)\n        self.paddingData = bytearray(0)\n\n    @property\n    def extData(self):\n        \"\"\"\n        Return raw encoding of the extension.\n\n        :rtype: bytearray\n        \"\"\"\n        return self.paddingData\n\n    def create(self, size):\n        \"\"\"\n        Set the padding size and create null byte padding of defined size.\n\n        :param int size: required padding size in bytes\n        \"\"\"\n        self.paddingData = bytearray(size)\n        return self\n\n    def parse(self, p):\n        \"\"\"\n        Deserialise extension from on the wire data.\n\n        :param Parser p:  data to be parsed\n\n        :raises DecodeError: when the size of the passed element doesn't match\n            the internal representation\n\n        :rtype: TLSExtension\n        \"\"\"\n        self.paddingData = p.getFixBytes(p.getRemainingLength())\n        return self\n\n\nclass RenegotiationInfoExtension(VarBytesExtension):\n    \"\"\"\n    Client and Server Hello secure renegotiation extension from RFC 5746\n\n    Should have an empty renegotiated_connection field in case of initial\n    connection\n    \"\"\"\n\n    def __init__(self):\n        \"\"\"Create instance\"\"\"\n        extType = ExtensionType.renegotiation_info\n        super(RenegotiationInfoExtension, self).__init__(\n            'renegotiated_connection',\n            1,\n            extType)\n\n\nclass ALPNExtension(TLSExtension):\n    \"\"\"\n    Handling of Application Layer Protocol Negotiation extension from RFC 7301.\n\n    :vartype protocol_names: list of bytearrays\n    :ivar protocol_names: list of protocol names acceptable or selected by peer\n\n    :vartype extType: int\n    :ivar extType: numberic type of ALPNExtension, i.e. 16\n\n    :vartype ~.extData: bytearray\n    :var ~.extData: raw encoding of the extension data\n    \"\"\"\n\n    def __init__(self):\n        \"\"\"\n        Create instance of ALPNExtension\n\n        See also: :py:meth:`create` and :py:meth:`parse`\n        \"\"\"\n        super(ALPNExtension, self).__init__(extType=ExtensionType.alpn)\n\n        self.protocol_names = None\n\n    def __repr__(self):\n        \"\"\"\n        Create programmer-readable representation of object\n\n        :rtype: str\n        \"\"\"\n        return \"ALPNExtension(protocol_names={0!r})\"\\\n               .format(self.protocol_names)\n\n    @property\n    def extData(self):\n        \"\"\"\n        Return encoded payload of the extension\n\n        :rtype: bytearray\n        \"\"\"\n        if self.protocol_names is None:\n            return bytearray(0)\n\n        writer = Writer()\n        for prot in self.protocol_names:\n            writer.add(len(prot), 1)\n            writer.bytes += prot\n\n        writer2 = Writer()\n        writer2.add(len(writer.bytes), 2)\n        writer2.bytes += writer.bytes\n\n        return writer2.bytes\n\n    def create(self, protocol_names=None):\n        \"\"\"\n        Create an instance of ALPNExtension with specified protocols\n\n        :param list protocols: list of protocol names that are to be sent\n        \"\"\"\n        self.protocol_names = protocol_names\n        return self\n\n    def parse(self, parser):\n        \"\"\"\n        Parse the extension from on the wire format\n\n        :param Parser parser: data to be parsed as extension\n\n        :raises DecodeError: when the encoding of the extension is self\n            inconsistent\n\n        :rtype: ALPNExtension\n        \"\"\"\n        self.protocol_names = []\n        parser.startLengthCheck(2)\n        while not parser.atLengthCheck():\n            name_len = parser.get(1)\n            self.protocol_names.append(parser.getFixBytes(name_len))\n        parser.stopLengthCheck()\n        if parser.getRemainingLength() != 0:\n            raise DecodeError(\"Trailing data after protocol_name_list\")\n        return self\n\n\nclass ApplicationSettingsExtension(TLSExtension):\n    \"\"\"\n    Handling of Application Layer Protocol Negotiation extension from RFC 7301.\n\n    :vartype protocol_names: list of bytearrays\n    :ivar protocol_names: list of protocol names acceptable or selected by peer\n\n    :vartype extType: int\n    :ivar extType: numberic type of ALPNExtension, i.e. 16\n\n    :vartype ~.extData: bytearray\n    :var ~.extData: raw encoding of the extension data\n    \"\"\"\n\n    def __init__(self):\n        \"\"\"\n        Create instance of ALPNExtension\n\n        See also: :py:meth:`create` and :py:meth:`parse`\n        \"\"\"\n        super(ApplicationSettingsExtension, self).__init__(extType=ExtensionType.application_settings)\n\n        self.protocol_names = None\n\n    def __repr__(self):\n        \"\"\"\n        Create programmer-readable representation of object\n\n        :rtype: str\n        \"\"\"\n        return \"ALPNExtension(protocol_names={0!r})\"\\\n               .format(self.protocol_names)\n\n    @property\n    def extData(self):\n        \"\"\"\n        Return encoded payload of the extension\n\n        :rtype: bytearray\n        \"\"\"\n        if self.protocol_names is None:\n            return bytearray(0)\n\n        writer = Writer()\n        for prot in self.protocol_names:\n            writer.add(len(prot), 1)\n            writer.bytes += prot\n\n        writer2 = Writer()\n        writer2.add(len(writer.bytes), 2)\n        writer2.bytes += writer.bytes\n\n        return writer2.bytes\n\n    def create(self, protocol_names=None):\n        \"\"\"\n        Create an instance of ALPNExtension with specified protocols\n\n        :param list protocols: list of protocol names that are to be sent\n        \"\"\"\n        self.protocol_names = protocol_names\n        return self\n\n    def parse(self, parser):\n        \"\"\"\n        Parse the extension from on the wire format\n\n        :param Parser parser: data to be parsed as extension\n\n        :raises DecodeError: when the encoding of the extension is self\n            inconsistent\n\n        :rtype: ALPNExtension\n        \"\"\"\n        self.protocol_names = []\n        parser.startLengthCheck(2)\n        while not parser.atLengthCheck():\n            name_len = parser.get(1)\n            self.protocol_names.append(parser.getFixBytes(name_len))\n        parser.stopLengthCheck()\n        if parser.getRemainingLength() != 0:\n            raise DecodeError(\"Trailing data after protocol_name_list\")\n        return self\n\n\nclass StatusRequestExtension(TLSExtension):\n    \"\"\"\n    Handling of the Certificate Status Request extension from RFC 6066.\n\n    :vartype status_type: int\n    :ivar status_type: type of the status request\n\n    :vartype responder_id_list: list of bytearray\n    :ivar responder_id_list: list of DER encoded OCSP responder identifiers\n        that the client trusts\n\n    :vartype request_extensions: bytearray\n    :ivar request_extensions: DER encoded list of OCSP extensions, as defined\n        in RFC 2560\n    \"\"\"\n\n    def __init__(self):\n        \"\"\"Create instance of StatusRequestExtension.\"\"\"\n        super(StatusRequestExtension, self).__init__(\n            extType=ExtensionType.status_request)\n        self.status_type = None\n        self.responder_id_list = []\n        self.request_extensions = bytearray()\n\n    def __repr__(self):\n        \"\"\"\n        Create programmer-readable representation of object\n\n        :rtype: str\n        \"\"\"\n        return (\"StatusRequestExtension(status_type={0}, \"\n                \"responder_id_list={1!r}, \"\n                \"request_extensions={2!r})\").format(\n                    self.status_type, self.responder_id_list,\n                    self.request_extensions)\n\n    @property\n    def extData(self):\n        \"\"\"\n        Return encoded payload of the extension.\n\n        :rtype: bytearray\n        \"\"\"\n        if self.status_type is None:\n            return bytearray()\n\n        writer = Writer()\n        writer.add(self.status_type, 1)\n        writer2 = Writer()\n        for i in self.responder_id_list:\n            writer2.add(len(i), 2)\n            writer2.bytes += i\n        writer.add(len(writer2.bytes), 2)\n        writer.bytes += writer2.bytes\n        writer.add(len(self.request_extensions), 2)\n        writer.bytes += self.request_extensions\n\n        return writer.bytes\n\n    def create(self, status_type=CertificateStatusType.ocsp,\n               responder_id_list=tuple(),\n               request_extensions=b''):\n        \"\"\"\n        Create an instance of StatusRequestExtension with specified options.\n\n        :param int status_type: type of status returned\n\n        :param list responder_id_list: list of encoded OCSP responder\n            identifiers\n            that the client trusts\n\n        :param bytearray request_extensions: DER encoding of requested OCSP\n            extensions\n        \"\"\"\n        self.status_type = status_type\n        self.responder_id_list = list(responder_id_list)\n        self.request_extensions = bytearray(request_extensions)\n        return self\n\n    def parse(self, parser):\n        \"\"\"\n        Parse the extension from on the wire format.\n\n        :param Parser parser: data to be parsed as extension\n\n        :rtype: StatusRequestExtension\n        \"\"\"\n        # handling of server side message\n        if parser.getRemainingLength() == 0:\n            self.status_type = None\n            self.responder_id_list = []\n            self.request_extensions = bytearray()\n            return self\n\n        self.status_type = parser.get(1)\n        self.responder_id_list = []\n        parser.startLengthCheck(2)\n        while not parser.atLengthCheck():\n            self.responder_id_list.append(parser.getVarBytes(2))\n        parser.stopLengthCheck()\n        self.request_extensions = parser.getVarBytes(2)\n        if parser.getRemainingLength() != 0:\n            raise DecodeError(\"Trailing data after CertificateStatusRequest\")\n        return self\n\n\nclass CertificateStatusExtension(TLSExtension):\n    \"\"\"Handling of Certificate Status response as redefined in TLS1.3\"\"\"\n\n    def __init__(self):\n        \"\"\"Create instance of CertificateStatusExtension.\"\"\"\n        super(CertificateStatusExtension, self).__init__(\n            extType=ExtensionType.status_request)\n        self.status_type = None\n        self.response = None\n\n    def create(self, status_type, response):\n        \"\"\"Set values of the extension.\"\"\"\n        self.status_type = status_type\n        self.response = response\n        return self\n\n    def parse(self, parser):\n        \"\"\"Deserialise the data from on the wire representation.\"\"\"\n        self.status_type = parser.get(1)\n        if self.status_type == 1:\n            self.response = parser.getVarBytes(3)\n        else:\n            raise DecodeError(\"Unrecognised type\")\n        if parser.getRemainingLength():\n            raise DecodeError(\"Trailing data\")\n        return self\n\n    @property\n    def extData(self):\n        \"\"\"Serialise the object.\"\"\"\n        writer = Writer()\n        writer.add(self.status_type, 1)\n        writer.addVarSeq(self.response, 1, 3)\n\n        return writer.bytes\n\n\nclass KeyShareEntry(object):\n    \"\"\"Handler for of the item of the Key Share extension.\"\"\"\n\n    def __init__(self):\n        \"\"\"Initialise the object.\"\"\"\n        self.group = None\n        self.key_exchange = None\n        self.private = None\n\n    def create(self, group, key_exchange, private=None):\n        \"\"\"\n        Initialise the Key Share Entry from Key Share extension.\n\n        :param int group: ID of the key share\n        :param bytearray key_exchange: value of the key share\n        :param object private: private value for the given share (won't be\n            encoded during serialisation)\n        :rtype: KeyShareEntry\n        \"\"\"\n        self.group = group\n        self.key_exchange = key_exchange\n        self.private = private\n        return self\n\n    def parse(self, parser):\n        \"\"\"\n        Parse the value from on the wire format.\n\n        :param Parser parser: data to be parsed as extension\n\n        :rtype: KeyShareEntry\n        \"\"\"\n        self.group = parser.get(2)\n        self.key_exchange = parser.getVarBytes(2)\n        return self\n\n    def write(self, writer):\n        \"\"\"\n        Write the on the wire representation of the item to writer.\n\n        :param Writer writer: buffer to write the data to\n        \"\"\"\n        writer.addTwo(self.group)\n        writer.addTwo(len(self.key_exchange))\n        writer.bytes += self.key_exchange\n\n\nclass HeartbeatExtension(IntExtension):\n    \"\"\"\n    Heartbeat extension from RFC 6520\n\n    :type mode: int\n    :ivar mode: mode if peer is allowed or nor allowed to send responses\n    \"\"\"\n    def __init__(self):\n        super(HeartbeatExtension, self).__init__(\n            1, 'mode', ext_type=ExtensionType.heartbeat,\n            item_enum=HeartbeatMode)\n\n    def parse(self, parser):\n        \"\"\"Deserialise the extension from on the wire data.\"\"\"\n        # the generic class allows for missing values, it's not allowed here\n        if not parser.getRemainingLength():\n            raise DecodeError(\"Empty extension payload\")\n        return super(HeartbeatExtension, self).parse(parser)\n\n\nclass ClientKeyShareExtension(TLSExtension):\n    \"\"\"\n    Class for handling the Client Hello version of the Key Share extension.\n\n    Extension for sending the key shares to server\n    \"\"\"\n\n    def __init__(self):\n        \"\"\"Create instance of the object.\"\"\"\n        super(ClientKeyShareExtension, self).__init__(extType=ExtensionType.\n                                                      key_share)\n        self.client_shares = None\n\n    @property\n    def extData(self):\n        \"\"\"\n        Return the on the wire raw encoding of the extension\n\n        :rtype: bytearray\n        \"\"\"\n        shares = Writer()\n        for share in self.client_shares:\n            share.write(shares)\n\n        w = Writer()\n        w.addTwo(len(shares.bytes))\n        w.bytes += shares.bytes\n\n        return w.bytes\n\n    def create(self, client_shares):\n        \"\"\"Set the advertised client shares in the extension.\"\"\"\n        self.client_shares = client_shares\n        return self\n\n    def parse(self, parser):\n        \"\"\"\n        Parse the extension from on the wire format\n\n        :param Parser parser: data to be parsed\n\n        :raises DecodeError: when the data does not match the definition\n\n        :rtype: ClientKeyShareExtension\n        \"\"\"\n        if not parser.getRemainingLength():\n            self.client_shares = None\n            return self\n\n        self.client_shares = []\n        parser.startLengthCheck(2)\n\n        while not parser.atLengthCheck():\n            self.client_shares.append(KeyShareEntry().parse(parser))\n\n        parser.stopLengthCheck()\n\n        if parser.getRemainingLength():\n            raise DecodeError(\"Trailing data in client Key Share extension\")\n\n        return self\n\n\nclass ServerKeyShareExtension(TLSExtension):\n    \"\"\"\n    Class for handling the Server Hello variant of the Key Share extension.\n\n    Extension for sending the key shares to client\n    \"\"\"\n\n    def __init__(self):\n        \"\"\"Create instance of the object.\"\"\"\n        super(ServerKeyShareExtension, self).__init__(extType=ExtensionType.\n                                                      key_share,\n                                                      server=True)\n        self.server_share = None\n\n    def create(self, server_share):\n        \"\"\"Set the advertised server share in the extension.\"\"\"\n        self.server_share = server_share\n        return self\n\n    @property\n    def extData(self):\n        \"\"\"Serialise the payload of the extension\"\"\"\n        if self.server_share is None:\n            return bytearray(0)\n\n        w = Writer()\n        self.server_share.write(w)\n        return w.bytes\n\n    def parse(self, parser):\n        \"\"\"\n        Parse the extension from on the wire format.\n\n        :param Parser parser: data to be parsed\n\n        :rtype: ServerKeyShareExtension\n        \"\"\"\n        if not parser.getRemainingLength():\n            self.server_share = None\n            return self\n\n        self.server_share = KeyShareEntry().parse(parser)\n\n        if parser.getRemainingLength():\n            raise DecodeError(\"Trailing data in server Key Share extension\")\n\n        return self\n\n\nclass HRRKeyShareExtension(TLSExtension):\n    \"\"\"\n    Class for handling the Hello Retry Request variant of the Key Share ext.\n\n    Extension for notifying the client of the server selected group for\n    key exchange.\n    \"\"\"\n    def __init__(self):\n        \"\"\"Create instance of the object.\"\"\"\n        super(HRRKeyShareExtension, self).__init__(extType=ExtensionType.\n                                                   key_share,\n                                                   hrr=True)\n        self.selected_group = None\n\n    def create(self, selected_group):\n        \"\"\"Set the selected group in the extension.\"\"\"\n        self.selected_group = selected_group\n        return self\n\n    @property\n    def extData(self):\n        \"\"\"Serialise the payload of the extension.\"\"\"\n        if self.selected_group is None:\n            return bytearray(0)\n\n        w = Writer()\n        w.add(self.selected_group, 2)\n        return w.bytes\n\n    def parse(self, parser):\n        \"\"\"Parse the extension from on the wire format.\n\n        :param Parser parser: data to be parsed\n\n        :rtype: HRRKeyShareExtension\n        \"\"\"\n        self.selected_group = parser.get(2)\n\n        if parser.getRemainingLength():\n            raise DecodeError(\"Trailing data in HRR Key Share extension\")\n\n        return self\n\n\nclass PskIdentity(object):\n    \"\"\"Handling of PskIdentity from PreSharedKey Extension.\"\"\"\n    def __init__(self):\n        \"\"\"Create instance of class.\"\"\"\n        super(PskIdentity, self).__init__()\n        self.identity = None\n        self.obfuscated_ticket_age = None\n\n    def create(self, identity, obf_ticket_age):\n        \"\"\"Initialise instance.\"\"\"\n        self.identity = identity\n        self.obfuscated_ticket_age = obf_ticket_age\n        return self\n\n    def write(self):\n        \"\"\"Serialise the object.\"\"\"\n        writer = Writer()\n        writer.addTwo(len(self.identity))\n        writer.bytes += self.identity\n        writer.addFour(self.obfuscated_ticket_age)\n        return writer.bytes\n\n    def parse(self, parser):\n        \"\"\"Deserialize the object from bytearray.\"\"\"\n        self.identity = parser.getVarBytes(2)\n        self.obfuscated_ticket_age = parser.get(4)\n        return self\n\n\nclass PreSharedKeyExtension(TLSExtension):\n    \"\"\"\n    Class for handling Pre Shared Key negotiation.\n    \"\"\"\n    def __init__(self):\n        \"\"\"Create instance of class.\"\"\"\n        super(PreSharedKeyExtension, self).__init__(\n            extType=ExtensionType.pre_shared_key)\n        self.identities = None\n        self.binders = None\n\n    def create(self, identities, binders):\n        \"\"\"Set list of offered PSKs.\"\"\"\n        self.identities = identities\n        self.binders = binders\n        return self\n\n    @property\n    def extData(self):\n        \"\"\"Serialise the payload of the extension.\"\"\"\n        if self.identities is None:\n            return bytearray()\n\n        writer = Writer()\n\n        iden_writer = Writer()\n        for i in self.identities:\n            iden_writer.bytes += i.write()\n        writer.add(len(iden_writer.bytes), 2)\n        writer.bytes += iden_writer.bytes\n\n        binder_writer = Writer()\n        for i in self.binders:\n            binder_writer.add(len(i), 1)\n            binder_writer.bytes += i\n        writer.add(len(binder_writer.bytes), 2)\n        writer.bytes += binder_writer.bytes\n        return writer.bytes\n\n    def parse(self, parser):\n        \"\"\"Parse the extension from on the wire format.\"\"\"\n        if not parser.getRemainingLength():\n            self.identities = None\n            self.binders = None\n            return self\n\n        # PskIdentity identities<7..2^16-1>;\n        parser.startLengthCheck(2)\n        self.identities = []\n        while not parser.atLengthCheck():\n            self.identities.append(PskIdentity().parse(parser))\n        parser.stopLengthCheck()\n\n        # PskBinderEntry binders<33..2^16-1>;\n        parser.startLengthCheck(2)\n        self.binders = []\n        while not parser.atLengthCheck():\n            self.binders.append(parser.getVarBytes(1))\n        parser.stopLengthCheck()\n\n        if parser.getRemainingLength():\n            raise DecodeError(\"Trailing data after binders field\")\n        return self\n\n\nclass SrvPreSharedKeyExtension(IntExtension):\n    \"\"\"Handling of the Pre Shared Key extension from server.\"\"\"\n\n    def __init__(self):\n        \"\"\"Create instance of class.\"\"\"\n        super(SrvPreSharedKeyExtension, self).__init__(\n            2, 'selected', ext_type=ExtensionType.pre_shared_key)\n\n\nclass PskKeyExchangeModesExtension(VarListExtension):\n    \"\"\"Handling of the PSK Key Exchange Modes extension.\"\"\"\n\n    def __init__(self):\n        \"\"\"Create instance of class.\"\"\"\n        super(PskKeyExchangeModesExtension, self).__init__(\n            1, 1, 'modes',\n            ExtensionType.psk_key_exchange_modes,\n            PskKeyExchangeMode)\n\n\nclass CookieExtension(VarBytesExtension):\n    \"\"\"Handling of the TLS 1.3 cookie extension.\"\"\"\n\n    def __init__(self):\n        \"\"\"Create instance.\"\"\"\n        ext_type = ExtensionType.cookie\n        super(CookieExtension, self).__init__('cookie', 2, ext_type)\n\n\nclass RecordSizeLimitExtension(IntExtension):\n    \"\"\"Class for handling the record_size_limit extension from RFC 8449.\"\"\"\n\n    def __init__(self):\n        \"\"\"Create instance.\"\"\"\n        super(RecordSizeLimitExtension, self).__init__(\n            2, 'record_size_limit', ExtensionType.record_size_limit)\n\n\nTLSExtension._universalExtensions = \\\n    {\n        ExtensionType.server_name: SNIExtension,\n        ExtensionType.status_request: StatusRequestExtension,\n        ExtensionType.cert_type: ClientCertTypeExtension,\n        ExtensionType.supported_groups: SupportedGroupsExtension,\n        ExtensionType.ec_point_formats: ECPointFormatsExtension,\n        ExtensionType.srp: SRPExtension,\n        ExtensionType.signature_algorithms: SignatureAlgorithmsExtension,\n        ExtensionType.alpn: ALPNExtension,\n        ExtensionType.supports_npn: NPNExtension,\n        ExtensionType.client_hello_padding: PaddingExtension,\n        ExtensionType.renegotiation_info: RenegotiationInfoExtension,\n        ExtensionType.heartbeat: HeartbeatExtension,\n        ExtensionType.supported_versions: SupportedVersionsExtension,\n        ExtensionType.key_share: ClientKeyShareExtension,\n        ExtensionType.signature_algorithms_cert:\n            SignatureAlgorithmsCertExtension,\n        ExtensionType.pre_shared_key: PreSharedKeyExtension,\n        ExtensionType.psk_key_exchange_modes: PskKeyExchangeModesExtension,\n        ExtensionType.cookie: CookieExtension,\n        ExtensionType.record_size_limit: RecordSizeLimitExtension}\n\nTLSExtension._serverExtensions = \\\n    {\n        ExtensionType.cert_type: ServerCertTypeExtension,\n        ExtensionType.tack: TACKExtension,\n        ExtensionType.key_share: ServerKeyShareExtension,\n        ExtensionType.supported_versions: SrvSupportedVersionsExtension,\n        ExtensionType.pre_shared_key: SrvPreSharedKeyExtension}\n\nTLSExtension._certificateExtensions = \\\n    {\n        ExtensionType.status_request: CertificateStatusExtension}\n\nTLSExtension._hrrExtensions = \\\n    {\n        ExtensionType.key_share: HRRKeyShareExtension,\n        ExtensionType.supported_versions: SrvSupportedVersionsExtension}\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/handshakehashes.py",
    "content": "# Copyright (c) 2015, Hubert Kario\n#\n# See the LICENSE file for legal information regarding use of this file.\n\"\"\"Handling cryptographic hashes for handshake protocol\"\"\"\n\nfrom .utils.compat import compat26Str, compatHMAC\nfrom .utils.cryptomath import MD5, SHA1\nfrom .utils import tlshashlib as hashlib\n\nclass HandshakeHashes(object):\n\n    \"\"\"\n    Store and calculate necessary hashes for handshake protocol\n\n    Calculates message digests of messages exchanged in handshake protocol\n    of SSLv3 and TLS.\n    \"\"\"\n\n    def __init__(self):\n        \"\"\"Create instance\"\"\"\n        self._handshakeMD5 = hashlib.md5()\n        self._handshakeSHA = hashlib.sha1()\n        self._handshakeSHA224 = hashlib.sha224()\n        self._handshakeSHA256 = hashlib.sha256()\n        self._handshakeSHA384 = hashlib.sha384()\n        self._handshakeSHA512 = hashlib.sha512()\n        self._handshake_buffer = bytearray()\n\n    def update(self, data):\n        \"\"\"\n        Add `data` to hash input.\n\n        :param bytearray data: serialized TLS handshake message\n        \"\"\"\n        text = compat26Str(data)\n        self._handshakeMD5.update(text)\n        self._handshakeSHA.update(text)\n        self._handshakeSHA224.update(text)\n        self._handshakeSHA256.update(text)\n        self._handshakeSHA384.update(text)\n        self._handshakeSHA512.update(text)\n        self._handshake_buffer += text\n\n    def digest(self, digest=None):\n        \"\"\"\n        Calculate and return digest for the already consumed data.\n\n        Used for Finished and CertificateVerify messages.\n\n        :param str digest: name of digest to return\n        \"\"\"\n        if digest is None:\n            return self._handshakeMD5.digest() + self._handshakeSHA.digest()\n        elif digest == 'md5':\n            return self._handshakeMD5.digest()\n        elif digest == 'sha1':\n            return self._handshakeSHA.digest()\n        elif digest == 'sha224':\n            return self._handshakeSHA224.digest()\n        elif digest == 'sha256':\n            return self._handshakeSHA256.digest()\n        elif digest == 'sha384':\n            return self._handshakeSHA384.digest()\n        elif digest == 'sha512':\n            return self._handshakeSHA512.digest()\n        elif digest == \"intrinsic\":\n            return self._handshake_buffer\n        else:\n            raise ValueError(\"Unknown digest name\")\n\n    def digestSSL(self, masterSecret, label):\n        \"\"\"\n        Calculate and return digest for already consumed data (SSLv3 version)\n\n        Used for Finished and CertificateVerify messages.\n\n        :param bytearray masterSecret: value of the master secret\n        :param bytearray label: label to include in the calculation\n        \"\"\"\n        #pylint: disable=maybe-no-member\n        imacMD5 = self._handshakeMD5.copy()\n        imacSHA = self._handshakeSHA.copy()\n        #pylint: enable=maybe-no-member\n\n        # the below difference in input for MD5 and SHA-1 is why we can't reuse\n        # digest() method\n        imacMD5.update(compatHMAC(label + masterSecret + bytearray([0x36]*48)))\n        imacSHA.update(compatHMAC(label + masterSecret + bytearray([0x36]*40)))\n\n        md5Bytes = MD5(masterSecret + bytearray([0x5c]*48) + \\\n                         bytearray(imacMD5.digest()))\n        shaBytes = SHA1(masterSecret + bytearray([0x5c]*40) + \\\n                         bytearray(imacSHA.digest()))\n\n        return md5Bytes + shaBytes\n\n    #pylint: disable=protected-access, maybe-no-member\n    def copy(self):\n        \"\"\"\n        Copy object\n\n        Return a copy of the object with all the hashes in the same state\n        as the source object.\n\n        :rtype: HandshakeHashes\n        \"\"\"\n        other = HandshakeHashes()\n        other._handshakeMD5 = self._handshakeMD5.copy()\n        other._handshakeSHA = self._handshakeSHA.copy()\n        other._handshakeSHA224 = self._handshakeSHA224.copy()\n        other._handshakeSHA256 = self._handshakeSHA256.copy()\n        other._handshakeSHA384 = self._handshakeSHA384.copy()\n        other._handshakeSHA512 = self._handshakeSHA512.copy()\n        other._handshake_buffer = bytearray(self._handshake_buffer)\n        return other\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/handshakehelpers.py",
    "content": "# Authors:\n#   Karel Srot\n#\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Class with various handshake helpers.\"\"\"\n\nfrom .extensions import PaddingExtension, PreSharedKeyExtension\nfrom .utils.cryptomath import derive_secret, secureHMAC, HKDF_expand_label\nfrom .utils.constanttime import ct_compare_digest\nfrom .errors import TLSIllegalParameterException\n\n\nclass HandshakeHelpers(object):\n    \"\"\"\n    This class encapsulates helper functions to be used with a TLS handshake.\n    \"\"\"\n\n    @staticmethod\n    def alignClientHelloPadding(clientHello):\n        \"\"\"\n        Align ClientHello using the Padding extension to 512 bytes at least.\n\n        :param ClientHello clientHello: ClientHello to be aligned\n        \"\"\"\n        # Check clientHello size if padding extension should be added\n        # we want to add the extension even when using just SSLv3\n        # cut-off 4 bytes with the Hello header (ClientHello type + Length)\n        clientHelloLength = len(clientHello.write())\n        if 256 <= clientHelloLength <= 511:\n            if clientHello.extensions is None:\n                clientHello.extensions = []\n                # we need to recalculate the size after extension list addition\n                # results in extra 2 bytes, equals to\n                # clientHelloLength = len(clientHello.write()) - 4\n                clientHelloLength += 2\n            # we want to get 512 bytes in total, including the padding\n            # extension header (4B)\n            paddingExtensionInstance = PaddingExtension().create(\n                max(512 - clientHelloLength - 4, 0))\n            clientHello.extensions.append(paddingExtensionInstance)\n\n    @staticmethod\n    def _calc_binder(prf, psk, handshake_hash, external=True):\n        \"\"\"\n        Calculate the binder value for a given HandshakeHash (that includes\n        a truncated client hello already)\n        \"\"\"\n        assert prf in ('sha256', 'sha384')\n        key_len = 32 if prf == 'sha256' else 48\n\n        # HKDF-Extract(0, PSK)\n        early_secret = secureHMAC(bytearray(key_len), psk, prf)\n        if external:\n            binder_key = derive_secret(early_secret, b\"ext binder\", None, prf)\n        else:\n            binder_key = derive_secret(early_secret, b\"res binder\", None, prf)\n        finished_key = HKDF_expand_label(binder_key, b\"finished\", b\"\", key_len,\n                                         prf)\n        binder = secureHMAC(finished_key, handshake_hash.digest(prf), prf)\n        return binder\n\n    @staticmethod\n    def calc_res_binder_psk(iden, res_master_secret, tickets):\n        \"\"\"Calculate PSK associated with provided ticket identity.\"\"\"\n        ticket = [i for i in tickets if i.ticket == iden.identity][0]\n\n        ticket_hash = 'sha256' if len(res_master_secret) == 32 else 'sha384'\n\n        psk = HKDF_expand_label(res_master_secret, b\"resumption\",\n                                ticket.ticket_nonce, len(res_master_secret),\n                                ticket_hash)\n        return psk\n\n    @staticmethod\n    def update_binders(client_hello, handshake_hashes, psk_configs,\n                       tickets=None, res_master_secret=None):\n        \"\"\"\n        Sign the Client Hello using TLS 1.3 PSK binders.\n\n        note: the psk_configs should be in the same order as the ones in the\n        PreSharedKeyExtension extension (extra ones are ok)\n\n        :param client_hello: ClientHello to sign\n        :param handshake_hashes: hashes of messages exchanged so far\n        :param psk_configs: PSK identities and secrets\n        :param tickets: optional list of tickets received from server\n        :param bytearray res_master_secret: secret associated with the\n            tickets\n        \"\"\"\n        ext = client_hello.extensions[-1]\n        if not isinstance(ext, PreSharedKeyExtension):\n            raise ValueError(\"Last extension in client_hello must be \"\n                             \"PreSharedKeyExtension\")\n        if tickets and not res_master_secret:\n            raise ValueError(\"Tickets require setting res_master_secret\")\n\n        hh = handshake_hashes.copy()\n\n        hh.update(client_hello.psk_truncate())\n\n        configs_iter = iter(psk_configs)\n        ticket_idens = []\n        if tickets:\n            ticket_idens = [i.ticket for i in tickets]\n\n        for i, iden in enumerate(ext.identities):\n            # identities that are tickets don't carry PSK directly\n            if iden.identity in ticket_idens:\n                binder_hash = 'sha256' if len(res_master_secret) == 32 \\\n                    else 'sha384'\n                psk = HandshakeHelpers.calc_res_binder_psk(\n                    iden, res_master_secret, tickets)\n                external = False\n            else:\n                try:\n                    config = next(configs_iter)\n                    while config[0] != iden.identity:\n                        config = next(configs_iter)\n                except StopIteration:\n                    raise ValueError(\"psk_configs don't match the \"\n                                     \"PreSharedKeyExtension\")\n\n                binder_hash = config[2] if len(config) > 2 else 'sha256'\n                psk = config[1]\n                external = True\n\n            binder = HandshakeHelpers._calc_binder(binder_hash,\n                                                   psk,\n                                                   hh,\n                                                   external)\n\n            # replace the fake value with calculated one\n            ext.binders[i] = binder\n\n    @staticmethod\n    def verify_binder(client_hello, handshake_hashes, position, secret, prf,\n                      external=True):\n        \"\"\"Verify the PSK binder value in client hello.\n\n        :param client_hello: ClientHello to verify\n        :param handshake_hashes: hashes of messages exchanged so far\n        :param position: binder at which position should be verified\n        :param secret: the secret PSK\n        :param prf: name of the hash used as PRF\n        \"\"\"\n        ext = client_hello.extensions[-1]\n        if not isinstance(ext, PreSharedKeyExtension):\n            raise TLSIllegalParameterException(\n                \"Last extension in client_hello must be \"\n                \"PreSharedKeyExtension\")\n\n        hh = handshake_hashes.copy()\n        hh.update(client_hello.psk_truncate())\n\n        binder = HandshakeHelpers._calc_binder(prf,\n                                               secret,\n                                               hh,\n                                               external)\n\n        if not ct_compare_digest(binder, ext.binders[position]):\n            raise TLSIllegalParameterException(\"Binder does not verify\")\n\n        return True\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/handshakesettings.py",
    "content": "# Authors:\n#   Trevor Perrin\n#   Dave Baggett (Arcode Corporation) - cleanup handling of constants\n#   Yngve Pettersen (ported by Paul Sokolovsky) - TLS 1.2\n#\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Class for setting handshake parameters.\"\"\"\n\nfrom .constants import CertificateType\nfrom .utils import cryptomath\nfrom .utils import cipherfactory\nfrom .utils.compat import ecdsaAllCurves, int_types\n\nCIPHER_NAMES = [\"chacha20-poly1305\",\n                \"aes256gcm\", \"aes128gcm\",\n                \"aes256ccm\", \"aes128ccm\",\n                \"aes256\", \"aes128\",\n                \"3des\"]\nALL_CIPHER_NAMES = CIPHER_NAMES + [\"chacha20-poly1305_draft00\",\n                                   \"aes128ccm_8\", \"aes256ccm_8\",\n                                   \"rc4\", \"null\"]\n# Don't allow \"md5\" by default\nMAC_NAMES = [\"sha\", \"sha256\", \"sha384\", \"aead\"]\nALL_MAC_NAMES = MAC_NAMES + [\"md5\"]\nKEY_EXCHANGE_NAMES = [\"ecdhe_ecdsa\", \"rsa\", \"dhe_rsa\", \"ecdhe_rsa\", \"srp_sha\",\n                      \"srp_sha_rsa\", \"ecdh_anon\", \"dh_anon\", \"dhe_dsa\"]\nCIPHER_IMPLEMENTATIONS = [\"openssl\", \"pycrypto\", \"python\"]\nCERTIFICATE_TYPES = [\"x509\"]\nRSA_SIGNATURE_HASHES = [\"sha512\", \"sha384\", \"sha256\", \"sha224\", \"sha1\"]\nDSA_SIGNATURE_HASHES = [\"sha512\", \"sha384\", \"sha256\", \"sha224\", \"sha1\"]\nECDSA_SIGNATURE_HASHES = [\"sha512\", \"sha384\", \"sha256\", \"sha224\", \"sha1\"]\nALL_RSA_SIGNATURE_HASHES = RSA_SIGNATURE_HASHES + [\"md5\"]\nSIGNATURE_SCHEMES = [\"Ed25519\", \"Ed448\"]\nRSA_SCHEMES = [\"pss\", \"pkcs1\"]\n# while secp521r1 is the most secure, it's also much slower than the others\n# so place it as the last one\nCURVE_NAMES = [\"x25519\", \"x448\", \"secp384r1\", \"secp256r1\",\n               \"secp521r1\"]\nALL_CURVE_NAMES = CURVE_NAMES + [\"secp256k1\", \"brainpoolP512r1\",\n                                 \"brainpoolP384r1\", \"brainpoolP256r1\"]\nif ecdsaAllCurves:\n    ALL_CURVE_NAMES += [\"secp224r1\", \"secp192r1\"]\nALL_DH_GROUP_NAMES = [\"ffdhe2048\", \"ffdhe3072\", \"ffdhe4096\", \"ffdhe6144\",\n                      \"ffdhe8192\"]\nCURVE_ALIASES = {\"secp256r1\": ('NIST256p', 'prime256v1', 'P-256'),\n                 \"secp384r1\": ('NIST384p', 'P-384'),\n                 \"secp521r1\": ('NIST521p', 'P-521'),\n                 \"secp256k1\": ('SECP256k1',),\n                 \"secp192r1\": ('NIST192p', 'P-192'),\n                 \"secp224r1\": ('NIST224p', 'P-224'),\n                 \"brainpoolP256r1\": ('BRAINPOOLP256r1',),\n                 \"brainpoolP384r1\": ('BRAINPOOLP384r1',),\n                 \"brainpoolP512r1\": ('BRAINPOOLP512r1',)}\n# list of supported groups in TLS 1.3 as per RFC 8446, chapter 4.2.7. (excluding private use here)\nTLS13_PERMITTED_GROUPS = [\"secp256r1\", \"secp384r1\", \"secp521r1\",\n                          \"x25519\", \"x448\", \"ffdhe2048\",\n                          \"ffdhe3072\", \"ffdhe4096\", \"ffdhe6144\",\n                          \"ffdhe8192\"]\nKNOWN_VERSIONS = ((3, 0), (3, 1), (3, 2), (3, 3), (3, 4))\nTICKET_CIPHERS = [\"chacha20-poly1305\", \"aes256gcm\", \"aes128gcm\", \"aes128ccm\",\n                  \"aes128ccm_8\", \"aes256ccm\", \"aes256ccm_8\"]\nPSK_MODES = [\"psk_dhe_ke\", \"psk_ke\"]\n\n\nclass Keypair(object):\n    \"\"\"\n    Key, certificate and related data.\n\n    Stores also certificate associate data like OCSPs and transparency info.\n    TODO: add the above\n\n    First certificate in certificates needs to match key, remaining should\n    build a trust path to a root CA.\n\n    :vartype key: RSAKey or ECDSAKey\n    :ivar key: private key\n\n    :vartype certificates: list(X509)\n    :ivar certificates: the certificates to send to peer if the key is selected\n        for use. The first one MUST include the public key of the ``key``\n    \"\"\"\n    def __init__(self, key=None, certificates=tuple()):\n        self.key = key\n        self.certificates = certificates\n\n    def validate(self):\n        \"\"\"Sanity check the keypair.\"\"\"\n        if not self.key or not self.certificates:\n            raise ValueError(\"Key or certificate missing in Keypair\")\n\n\nclass VirtualHost(object):\n    \"\"\"\n    Configuration of keys and certs for a single virual server.\n\n    This class encapsulates keys and certificates for hosts specified by\n    server_name (SNI) and ALPN extensions.\n\n    TODO: support SRP as alternative to certificates\n    TODO: support PSK as alternative to certificates\n\n    :vartype keys: list(Keypair)\n    :ivar keys: List of certificates and keys to be used in this\n        virtual host. First keypair able to server ClientHello will be used.\n\n    :vartype hostnames: set(bytes)\n    :ivar hostnames: all the hostnames that server supports\n        please use :py:meth:`matches_hostname` to verify if the VirtualHost\n        can serve a request to a given hostname as that allows wildcard hosts\n        that always reply True.\n\n    :vartype trust_anchors: list(X509)\n    :ivar trust_anchors: list of CA certificates supported for client\n        certificate authentication, sent in CertificateRequest\n\n    :ivar list(bytes) app_protocols: all the application protocols that the\n        server supports (for ALPN)\n    \"\"\"\n\n    def __init__(self):\n        \"\"\"Set up default configuration.\"\"\"\n        self.keys = []\n        self.hostnames = set()\n        self.trust_anchors = []\n        self.app_protocols = []\n\n    def matches_hostname(self, hostname):\n        \"\"\"Checks if the virtual host can serve hostname\"\"\"\n        return hostname in self.hostnames\n\n    def validate(self):\n        \"\"\"Sanity check the settings\"\"\"\n        if not self.keys:\n            raise ValueError(\"Virtual host missing keys\")\n        for i in self.keys:\n            i.validate()\n\n\nclass HandshakeSettings(object):\n    \"\"\"\n    This class encapsulates various parameters that can be used with\n    a TLS handshake.\n\n    :vartype minKeySize: int\n    :ivar minKeySize: The minimum bit length for asymmetric keys.\n\n        If the other party tries to use SRP, RSA, DSA, or Diffie-Hellman\n        parameters smaller than this length, an alert will be\n        signalled.  The default is 1023.\n\n\n    :vartype maxKeySize: int\n    :ivar maxKeySize: The maximum bit length for asymmetric keys.\n\n        If the other party tries to use SRP, RSA, DSA, or Diffie-Hellman\n        parameters larger than this length, an alert will be signalled.\n        The default is 8193.\n\n    :vartype cipherNames: list(str)\n    :ivar cipherNames: The allowed ciphers.\n\n        The allowed values in this list are 'chacha20-poly1305', 'aes256gcm',\n        'aes128gcm', 'aes256', 'aes128', '3des', 'chacha20-poly1305_draft00',\n        'null' and\n        'rc4'.  If these settings are used with a client handshake, they\n        determine the order of the ciphersuites offered in the ClientHello\n        message.\n\n        If these settings are used with a server handshake, the server will\n        choose whichever ciphersuite matches the earliest entry in this\n        list.\n\n        The default value is list that excludes 'rc4', 'null' and\n        'chacha20-poly1305_draft00'.\n\n    :vartype macNames: list(str)\n    :ivar macNames: The allowed MAC algorithms.\n\n        The allowed values in this list are 'sha384', 'sha256', 'aead', 'sha'\n        and 'md5'.\n\n        The default value is list that excludes 'md5'.\n\n    :vartype certificateTypes: list(str)\n    :ivar certificateTypes: The allowed certificate types.\n\n        The only allowed certificate type is 'x509'.  This list is only used\n        with a\n        client handshake.  The client will advertise to the server which\n        certificate\n        types are supported, and will check that the server uses one of the\n        appropriate types.\n\n\n    :vartype minVersion: tuple\n    :ivar minVersion: The minimum allowed SSL/TLS version.\n\n        This variable can be set to (3, 0) for SSL 3.0, (3, 1) for TLS 1.0,\n        (3, 2) for\n        TLS 1.1, or (3, 3) for TLS 1.2.  If the other party wishes to use a\n        lower\n        version, a protocol_version alert will be signalled.  The default is\n        (3, 1).\n\n    :vartype maxVersion: tuple\n    :ivar maxVersion: The maximum allowed SSL/TLS version.\n\n        This variable can be set to (3, 0) for SSL 3.0, (3, 1) for TLS 1.0,\n        (3, 2) for TLS 1.1, or (3, 3) for TLS 1.2.  If the other party wishes\n        to use a\n        higher version, a protocol_version alert will be signalled.  The\n        default is (3, 3).\n\n        .. warning:: Some servers may (improperly) reject clients which offer\n            support\n            for TLS 1.1 or higher.  In this case, try lowering maxVersion to\n            (3, 1).\n\n    :vartype useExperimentalTackExtension: bool\n    :ivar useExperimentalTackExtension: Whether to enabled TACK support.\n\n        Note that TACK support is not standardized by IETF and uses a temporary\n        TLS Extension number, so should NOT be used in production software.\n\n    :vartype sendFallbackSCSV: bool\n    :ivar sendFallbackSCSV: Whether to, as a client, send FALLBACK_SCSV.\n\n    :vartype rsaSigHashes: list(str)\n    :ivar rsaSigHashes: List of hashes supported (and advertised as such) for\n        TLS 1.2 signatures over Server Key Exchange or Certificate Verify with\n        RSA signature algorithm.\n\n        The list is sorted from most wanted to least wanted algorithm.\n\n        The allowed hashes are: \"md5\", \"sha1\", \"sha224\", \"sha256\",\n        \"sha384\" and \"sha512\". The default list does not include md5.\n\n    :vartype dsaSigHashes: list(str)\n    :ivar dsaSigHashes: List of hashes supported (and advertised as such) for\n        TLS 1.2 signatures over Server Key Exchange or Certificate Verify with\n        DSA signature algorithm.\n\n        The list is sorted from most wanted to least wanted algorithm.\n\n        The allowed hashes are: \"sha1\", \"sha224\", \"sha256\",\n        \"sha384\" and \"sha512\".\n\n    :vartype ecdsaSigHashes: list(str)\n    :ivar ecdsaSigHashes: List of hashes supported (and advertised as such) for\n        TLS 1.2 signatures over Server Key Exchange or Certificate Verify with\n        ECDSA signature algorithm.\n\n        The list is sorted from most wanted to least wanted algorithm.\n\n        The allowed hashes are: \"sha1\", \"sha224\", \"sha256\",\n        \"sha384\" and \"sha512\".\n\n    \"vartype more_sig_schemes: list(str)\n    :ivar more_sig_schemes: List of additional signatures schemes (ones\n        that don't use RSA-PKCS#1 v1.5, RSA-PSS, DSA, or ECDSA) to advertise\n        as supported.\n        Currently supported are: \"Ed25519\", and \"Ed448\".\n\n    :vartype eccCurves: list(str)\n    :ivar eccCurves: List of named curves that are to be advertised as\n        supported in supported_groups extension.\n\n    :vartype useEncryptThenMAC: bool\n    :ivar useEncryptThenMAC: whether to support the encrypt then MAC extension\n        from RFC 7366. True by default.\n\n    :vartype useExtendedMasterSecret: bool\n    :ivar useExtendedMasterSecret: whether to support the extended master\n        secret calculation from RFC 7627. True by default.\n\n    :vartype requireExtendedMasterSecret: bool\n    :ivar requireExtendedMasterSecret: whether to require negotiation of\n        extended master secret calculation for successful connection. Requires\n        useExtendedMasterSecret to be set to true. False by default.\n\n    :vartype defaultCurve: str\n    :ivar defaultCurve: curve that will be used by server in case the client\n        did not advertise support for any curves. It does not have to be the\n        first curve for eccCurves and may be distinct from curves from that\n        list.\n\n    :vartype keyShares: list(str)\n    :ivar keyShares: list of TLS 1.3 key shares to include in Client Hello\n\n    :vartype padding_cb: func\n    :ivar padding_cb: Callback to function computing number of padding bytes\n        for TLS 1.3. Signature is cb_func(msg_size, content_type, max_size).\n\n    :vartype pskConfigs: list(tuple(bytearray, bytearray, bytearray))\n    :ivar pskConfigs: list of tuples, first element of the tuple is the\n        human readable, UTF-8 encoded, \"identity\" of the associated secret\n        (bytearray, can be empty for TLS 1.2 and earlier), second element is\n        the binary secret (bytearray), third is an optional parameter\n        specifying the PRF hash to be used in TLS 1.3 (``sha256`` or\n        ``sha384``)\n\n    :vartype ticketKeys: list(bytearray)\n    :ivar ticketKeys: keys to be used for encrypting and decrypting session\n        tickets. First entry is the encryption key for new tickets and the\n        default decryption key, subsequent entries are the fallback keys\n        allowing for key rollover. The keys need to be of size appropriate\n        for a selected cipher in ticketCipher, 32 bytes for 'aes256gcm' and\n        'chacha20-poly1305', 16 bytes for 'aes128-gcm'.\n        New keys should be generated regularly and replace old ones. Key use\n        time should generally not be longer than 24h and key life-time should\n        not be longer than 48h.\n        Leave empty to disable session ticket support on server side.\n\n    :vartype ticketCipher: str\n    :ivar ticketCipher: name of the cipher used for encrypting the session\n        tickets. 'aes256gcm' by default, 'aes128gcm' or 'chacha20-poly1305'\n        alternatively.\n\n    :vartype ticketLifetime: int\n    :ivar ticketLifetime: maximum allowed lifetime of ticket encryption key,\n        in seconds. 1 day by default\n\n    :vartype psk_modes: list(str)\n    :ivar psk_modes: acceptable modes for the PSK key exchange in TLS 1.3\n\n    :ivar int max_early_data: maximum number of bytes acceptable for 0-RTT\n        early_data processing. In other words, how many bytes will the server\n        try to process, but ignore, in case the Client Hello includes\n        early_data extension.\n\n    :vartype use_heartbeat_extension: bool\n    :ivar use_heartbeat_extension: whether to support heartbeat extension from\n        RFC 6520. True by default.\n\n    :vartype heartbeat_response_callback: func\n    :ivar heartbeat_response_callback: Callback to function when Heartbeat\n        response is received.\n\n    :vartype ~.record_size_limit: int\n    :ivar ~.record_size_limit: maximum size of records we are willing to process\n        (value advertised to the other side). It must not be larger than\n        2**14+1 (the maximum for TLS 1.3) and will be reduced to 2**14 if TLS\n        1.2 or lower is the highest enabled version. Must not be set to values\n        smaller than 64. Set to None to disable support for the extension.\n        See also: RFC 8449.\n\n    :vartype keyExchangeNames: list\n    :ivar keyExchangeNames: Enabled key exchange types for the connection,\n        influences selected cipher suites.\n    \"\"\"\n\n    def _init_key_settings(self):\n        \"\"\"Create default variables for key-related settings.\"\"\"\n        self.minKeySize = 1023\n        self.maxKeySize = 8193\n        self.rsaSigHashes = list(RSA_SIGNATURE_HASHES)\n        self.rsaSchemes = list(RSA_SCHEMES)\n        self.dsaSigHashes = list(DSA_SIGNATURE_HASHES)\n        self.virtual_hosts = []\n        # DH key settings\n        self.eccCurves = list(CURVE_NAMES)\n        self.dhParams = None\n        self.dhGroups = list(ALL_DH_GROUP_NAMES)\n        self.defaultCurve = \"secp256r1\"\n        self.keyShares = [\"secp256r1\", \"x25519\"]\n        self.padding_cb = None\n        self.use_heartbeat_extension = True\n        self.heartbeat_response_callback = None\n\n    def _init_misc_extensions(self):\n        \"\"\"Default variables for assorted extensions.\"\"\"\n        self.certificateTypes = list(CERTIFICATE_TYPES)\n        self.useExperimentalTackExtension = False\n        self.sendFallbackSCSV = False\n        self.useEncryptThenMAC = True\n        self.ecdsaSigHashes = list(ECDSA_SIGNATURE_HASHES)\n        self.more_sig_schemes = list(SIGNATURE_SCHEMES)\n        self.usePaddingExtension = True\n        self.useExtendedMasterSecret = True\n        self.requireExtendedMasterSecret = False\n        # PSKs\n        self.pskConfigs = []\n        self.psk_modes = list(PSK_MODES)\n        # session tickets\n        self.ticketKeys = []\n        self.ticketCipher = \"aes256gcm\"\n        self.ticketLifetime = 24 * 60 * 60\n        self.max_early_data = 2 ** 14 + 16  # full record + tag\n        # send two tickets so that client can quickly ramp up number of\n        # resumed connections (as tickets are single-use in TLS 1.3\n        self.ticket_count = 2\n        self.record_size_limit = 2**14 + 1  # TLS 1.3 includes content type\n\n    def __init__(self):\n        \"\"\"Initialise default values for settings.\"\"\"\n        self._init_key_settings()\n        self._init_misc_extensions()\n        self.minVersion = (3, 1)\n        self.maxVersion = (3, 4)\n        self.versions = [(3, 4), (3, 3), (3, 2), (3, 1)]\n        self.cipherNames = list(CIPHER_NAMES)\n        self.macNames = list(MAC_NAMES)\n        self.keyExchangeNames = list(KEY_EXCHANGE_NAMES)\n        self.cipherImplementations = list(CIPHER_IMPLEMENTATIONS)\n\n    @staticmethod\n    def _sanityCheckKeySizes(other):\n        \"\"\"Check if key size limits are sane\"\"\"\n        if other.minKeySize < 512:\n            raise ValueError(\"minKeySize too small\")\n        if other.minKeySize > 16384:\n            raise ValueError(\"minKeySize too large\")\n        if other.maxKeySize < 512:\n            raise ValueError(\"maxKeySize too small\")\n        if other.maxKeySize > 16384:\n            raise ValueError(\"maxKeySize too large\")\n        if other.maxKeySize < other.minKeySize:\n            raise ValueError(\"maxKeySize smaller than minKeySize\")\n        # check also keys of virtual hosts\n        for i in other.virtual_hosts:\n            i.validate()\n\n    @staticmethod\n    def _not_matching(values, sieve):\n        \"\"\"Return list of items from values that are not in sieve.\"\"\"\n        return [val for val in values if val not in sieve]\n\n    @staticmethod\n    def _sanityCheckCipherSettings(other):\n        \"\"\"Check if specified cipher settings are known.\"\"\"\n        not_matching = HandshakeSettings._not_matching\n        unknownCiph = not_matching(other.cipherNames, ALL_CIPHER_NAMES)\n        if unknownCiph:\n            raise ValueError(\"Unknown cipher name: {0}\".format(unknownCiph))\n\n        unknownMac = not_matching(other.macNames, ALL_MAC_NAMES)\n        if unknownMac:\n            raise ValueError(\"Unknown MAC name: {0}\".format(unknownMac))\n\n        unknownKex = not_matching(other.keyExchangeNames, KEY_EXCHANGE_NAMES)\n        if unknownKex:\n            raise ValueError(\"Unknown key exchange name: {0}\"\n                             .format(unknownKex))\n\n        unknownImpl = not_matching(other.cipherImplementations,\n                                   CIPHER_IMPLEMENTATIONS)\n        if unknownImpl:\n            raise ValueError(\"Unknown cipher implementation: {0}\"\n                             .format(unknownImpl))\n\n    @staticmethod\n    def _sanityCheckECDHSettings(other):\n        \"\"\"Check ECDHE settings if they are sane.\"\"\"\n        not_matching = HandshakeSettings._not_matching\n\n        unknownCurve = not_matching(other.eccCurves, ALL_CURVE_NAMES)\n        if unknownCurve:\n            raise ValueError(\"Unknown ECC Curve name: {0}\"\n                             .format(unknownCurve))\n\n        if other.defaultCurve not in ALL_CURVE_NAMES:\n            raise ValueError(\"Unknown default ECC Curve name: {0}\"\n                             .format(other.defaultCurve))\n\n        nonAdvertisedGroup = [val for val in other.keyShares\n                              if val not in other.eccCurves and\n                              val not in other.dhGroups]\n        if nonAdvertisedGroup:\n            raise ValueError(\"Key shares for not enabled groups specified: {0}\"\n                             .format(nonAdvertisedGroup))\n\n        unknownSigHash = not_matching(other.ecdsaSigHashes,\n                                      ECDSA_SIGNATURE_HASHES)\n        if unknownSigHash:\n            raise ValueError(\"Unknown ECDSA signature hash: '{0}'\".\\\n                             format(unknownSigHash))\n\n        unknownSigHash = not_matching(other.more_sig_schemes,\n                                      SIGNATURE_SCHEMES)\n        if unknownSigHash:\n            raise ValueError(\"Unkonwn more_sig_schemes specified: '{0}'\"\n                             .format(unknownSigHash))\n\n        unknownDHGroup = not_matching(other.dhGroups, ALL_DH_GROUP_NAMES)\n        if unknownDHGroup:\n            raise ValueError(\"Unknown FFDHE group name: '{0}'\"\n                             .format(unknownDHGroup))\n\n        # TLS 1.3 limits the allowed groups (RFC 8446,ch. 4.2.7.)\n        if other.maxVersion == (3, 4):\n            forbiddenGroup = HandshakeSettings._not_matching(other.eccCurves, TLS13_PERMITTED_GROUPS)\n            if forbiddenGroup:\n                raise ValueError(\"The following enabled groups are forbidden in TLS 1.3: {0}\"\n                                 .format(forbiddenGroup))\n\n    @staticmethod\n    def _sanityCheckDHSettings(other):\n        \"\"\"Check if (EC)DHE settings are sane.\"\"\"\n        not_matching = HandshakeSettings._not_matching\n\n        HandshakeSettings._sanityCheckECDHSettings(other)\n\n        unknownKeyShare = [val for val in other.keyShares\n                           if val not in ALL_DH_GROUP_NAMES and\n                           val not in ALL_CURVE_NAMES]\n        if unknownKeyShare:\n            raise ValueError(\"Unknown key share: '{0}'\"\n                             .format(unknownKeyShare))\n\n        if other.dhParams and (len(other.dhParams) != 2 or\n                               not isinstance(other.dhParams[0], int_types) or\n                               not isinstance(other.dhParams[1], int_types)):\n            raise ValueError(\"DH parameters need to be a tuple of integers\")\n\n    @staticmethod\n    def _sanityCheckPrimitivesNames(other):\n        \"\"\"Check if specified cryptographic primitive names are known\"\"\"\n        HandshakeSettings._sanityCheckCipherSettings(other)\n        HandshakeSettings._sanityCheckDHSettings(other)\n\n        not_matching = HandshakeSettings._not_matching\n\n        unknownType = not_matching(other.certificateTypes, CERTIFICATE_TYPES)\n        if unknownType:\n            raise ValueError(\"Unknown certificate type: {0}\"\n                             .format(unknownType))\n\n        unknownSigHash = not_matching(other.rsaSigHashes,\n                                      ALL_RSA_SIGNATURE_HASHES)\n        if unknownSigHash:\n            raise ValueError(\"Unknown RSA signature hash: '{0}'\"\n                             .format(unknownSigHash))\n\n        unknownRSAPad = not_matching(other.rsaSchemes, RSA_SCHEMES)\n        if unknownRSAPad:\n            raise ValueError(\"Unknown RSA padding mode: '{0}'\"\n                             .format(unknownRSAPad))\n\n        unknownSigHash = not_matching(other.dsaSigHashes,\n                                      DSA_SIGNATURE_HASHES)\n        if unknownSigHash:\n            raise ValueError(\"Unknown DSA signature hash: '{0}'\"\n                             .format(unknownSigHash))\n\n        if not other.rsaSigHashes and not other.ecdsaSigHashes and \\\n                not other.dsaSigHashes and not other.more_sig_schemes and \\\n                other.maxVersion >= (3, 3):\n            raise ValueError(\"TLS 1.2 requires signature algorithms to be set\")\n\n    @staticmethod\n    def _sanityCheckProtocolVersions(other):\n        \"\"\"Check if set protocol version are sane\"\"\"\n        if other.minVersion > other.maxVersion:\n            raise ValueError(\"Versions set incorrectly\")\n        if other.minVersion not in KNOWN_VERSIONS:\n            raise ValueError(\"minVersion set incorrectly\")\n        if other.maxVersion not in KNOWN_VERSIONS:\n            raise ValueError(\"maxVersion set incorrectly\")\n\n        if other.maxVersion < (3, 4):\n            other.versions = [i for i in other.versions if i < (3, 4)]\n\n    @staticmethod\n    def _sanityCheckEMSExtension(other):\n        \"\"\"Check if settings for EMS are sane.\"\"\"\n        if other.useExtendedMasterSecret not in (True, False):\n            raise ValueError(\"useExtendedMasterSecret must be True or False\")\n        if other.requireExtendedMasterSecret not in (True, False):\n            raise ValueError(\"requireExtendedMasterSecret must be True \"\n                             \"or False\")\n        if other.requireExtendedMasterSecret and \\\n                not other.useExtendedMasterSecret:\n            raise ValueError(\"requireExtendedMasterSecret requires \"\n                             \"useExtendedMasterSecret\")\n\n    @staticmethod\n    def _sanityCheckExtensions(other):\n        \"\"\"Check if set extension settings are sane\"\"\"\n        if other.useEncryptThenMAC not in (True, False):\n            raise ValueError(\"useEncryptThenMAC can only be True or False\")\n\n        if other.usePaddingExtension not in (True, False):\n            raise ValueError(\"usePaddingExtension must be True or False\")\n\n        if other.use_heartbeat_extension not in (True, False):\n            raise ValueError(\"use_heartbeat_extension must be True or False\")\n\n        if other.heartbeat_response_callback and not other.use_heartbeat_extension:\n            raise ValueError(\"heartbeat_response_callback requires \"\n                             \"use_heartbeat_extension\")\n\n        if other.record_size_limit is not None and \\\n                not 64 <= other.record_size_limit <= 2**14 + 1:\n            raise ValueError(\"record_size_limit cannot exceed 2**14+1 bytes\")\n\n        HandshakeSettings._sanityCheckEMSExtension(other)\n\n    @staticmethod\n    def _not_allowed_len(values, sieve):\n        \"\"\"Return True if length of any item in values is not in sieve.\"\"\"\n        sieve = set(sieve)\n        return any(len(i) not in sieve for i in values)\n\n    @staticmethod\n    def _sanityCheckPsks(other):\n        \"\"\"Check if the set PSKs are sane.\"\"\"\n        if HandshakeSettings._not_allowed_len(other.pskConfigs, [2, 3]):\n            raise ValueError(\"pskConfigs items must be a 2 or 3-element\"\n                             \"tuples\")\n\n        badHashes = [i[2] for i in other.pskConfigs if\n                     len(i) == 3 and i[2] not in set(['sha256', 'sha384'])]\n        if badHashes:\n            raise ValueError(\"pskConfigs include invalid hash specifications: \"\n                             \"{0}\".format(badHashes))\n\n        bad_psk_modes = [i for i in other.psk_modes if\n                         i not in PSK_MODES]\n        if bad_psk_modes:\n            raise ValueError(\"psk_modes includes invalid key exchange modes: \"\n                             \"{0}\".format(bad_psk_modes))\n\n    @staticmethod\n    def _sanityCheckTicketSettings(other):\n        \"\"\"Check if the session ticket settings are sane.\"\"\"\n        if other.ticketCipher not in TICKET_CIPHERS:\n            raise ValueError(\"Invalid cipher for session ticket encryption: \"\n                             \"{0}\".format(other.ticketCipher))\n\n        if HandshakeSettings._not_allowed_len(other.ticketKeys, [16, 32]):\n            raise ValueError(\"Session ticket encryption keys must be 16 or 32\"\n                             \"bytes long\")\n\n        if not 0 < other.ticketLifetime <= 7 * 24 * 60 * 60:\n            raise ValueError(\"Ticket lifetime must be a positive integer \"\n                             \"smaller or equal 604800 (7 days)\")\n\n        # while not ticket setting per-se, it is related to session tickets\n        if not 0 < other.max_early_data <= 2**64:\n            raise ValueError(\"max_early_data must be between 0 and 2GiB\")\n\n        if not 0 <= other.ticket_count < 2**16:\n            raise ValueError(\"Incorrect amount for number of new session \"\n                             \"tickets to send\")\n\n    def _copy_cipher_settings(self, other):\n        \"\"\"Copy values related to cipher selection.\"\"\"\n        other.cipherNames = self.cipherNames\n        other.macNames = self.macNames\n        other.keyExchangeNames = self.keyExchangeNames\n        other.cipherImplementations = self.cipherImplementations\n        other.minVersion = self.minVersion\n        other.maxVersion = self.maxVersion\n        other.versions = self.versions\n\n    def _copy_extension_settings(self, other):\n        \"\"\"Copy values of settings related to extensions.\"\"\"\n        other.useExtendedMasterSecret = self.useExtendedMasterSecret\n        other.requireExtendedMasterSecret = self.requireExtendedMasterSecret\n        other.useExperimentalTackExtension = self.useExperimentalTackExtension\n        other.sendFallbackSCSV = self.sendFallbackSCSV\n        other.useEncryptThenMAC = self.useEncryptThenMAC\n        other.usePaddingExtension = self.usePaddingExtension\n        # session tickets\n        other.padding_cb = self.padding_cb\n        other.ticketKeys = self.ticketKeys\n        other.ticketCipher = self.ticketCipher\n        other.ticketLifetime = self.ticketLifetime\n        other.max_early_data = self.max_early_data\n        other.ticket_count = self.ticket_count\n        other.record_size_limit = self.record_size_limit\n\n    @staticmethod\n    def _remove_all_matches(values, needle):\n        \"\"\"Remove all instances of needle from values.\"\"\"\n        values[:] = (i for i in values if i != needle)\n\n    def _sanity_check_ciphers(self, other):\n        \"\"\"Remove unsupported ciphers in current configuration.\"\"\"\n        if not cipherfactory.tripleDESPresent:\n            other.cipherNames = other.cipherNames[:]\n            self._remove_all_matches(other.cipherNames, \"3des\")\n\n        if not other.cipherNames:\n            raise ValueError(\"No supported ciphers\")\n\n    def _sanity_check_implementations(self, other):\n        \"\"\"Remove all backends that are not loaded.\"\"\"\n        if not cryptomath.m2cryptoLoaded:\n            self._remove_all_matches(other.cipherImplementations, \"openssl\")\n        if not cryptomath.pycryptoLoaded:\n            self._remove_all_matches(other.cipherImplementations, \"pycrypto\")\n\n        if not other.cipherImplementations:\n            raise ValueError(\"No supported cipher implementations\")\n\n    def _copy_key_settings(self, other):\n        \"\"\"Copy key-related settings.\"\"\"\n        other.minKeySize = self.minKeySize\n        other.maxKeySize = self.maxKeySize\n        other.certificateTypes = self.certificateTypes\n        other.rsaSigHashes = self.rsaSigHashes\n        other.rsaSchemes = self.rsaSchemes\n        other.dsaSigHashes = self.dsaSigHashes\n        other.ecdsaSigHashes = self.ecdsaSigHashes\n        other.more_sig_schemes = self.more_sig_schemes\n        other.virtual_hosts = self.virtual_hosts\n        # DH key params\n        other.eccCurves = self.eccCurves\n        other.dhParams = self.dhParams\n        other.dhGroups = self.dhGroups\n        other.defaultCurve = self.defaultCurve\n        other.keyShares = self.keyShares\n        other.use_heartbeat_extension = self.use_heartbeat_extension\n        other.heartbeat_response_callback = self.heartbeat_response_callback\n\n    def validate(self):\n        \"\"\"\n        Validate the settings, filter out unsupported ciphersuites and return\n        a copy of object. Does not modify the original object.\n\n        :rtype: HandshakeSettings\n        :returns: a self-consistent copy of settings\n        :raises ValueError: when settings are invalid, insecure or unsupported.\n        \"\"\"\n        other = HandshakeSettings()\n\n        self._copy_cipher_settings(other)\n        self._copy_extension_settings(other)\n        self._copy_key_settings(other)\n\n        other.pskConfigs = self.pskConfigs\n        other.psk_modes = self.psk_modes\n\n        if not other.certificateTypes:\n            raise ValueError(\"No supported certificate types\")\n\n        self._sanityCheckKeySizes(other)\n\n        self._sanityCheckPrimitivesNames(other)\n\n        self._sanityCheckProtocolVersions(other)\n\n        self._sanityCheckExtensions(other)\n\n        if other.maxVersion < (3, 3):\n            # No sha-2 and AEAD pre TLS 1.2\n            other.macNames = [e for e in self.macNames if\n                              e == \"sha\" or e == \"md5\"]\n\n        self._sanityCheckPsks(other)\n\n        self._sanityCheckTicketSettings(other)\n\n        self._sanity_check_implementations(other)\n        self._sanity_check_ciphers(other)\n\n        return other\n\n    def getCertificateTypes(self):\n        \"\"\"Get list of certificate types as IDs\"\"\"\n        ret = []\n        for ct in self.certificateTypes:\n            if ct == \"x509\":\n                ret.append(CertificateType.x509)\n            else:\n                raise AssertionError()\n        return ret\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/keyexchange.py",
    "content": "# Authors:\n#   Hubert Kario (2015)\n#\n# See the LICENSE file for legal information regarding use of this file.\n\"\"\"Handling of cryptographic operations for key exchange\"\"\"\n\nimport ecdsa\nfrom .mathtls import goodGroupParameters, makeK, makeU, makeX, \\\n        paramStrength, RFC7919_GROUPS, calc_key\nfrom .errors import TLSInsufficientSecurity, TLSUnknownPSKIdentity, \\\n        TLSIllegalParameterException, TLSDecryptionFailed, TLSInternalError, \\\n        TLSDecodeError\nfrom .messages import ServerKeyExchange, ClientKeyExchange, CertificateVerify\nfrom .constants import SignatureAlgorithm, HashAlgorithm, CipherSuite, \\\n        ExtensionType, GroupName, ECCurveType, SignatureScheme\nfrom .utils.ecc import decodeX962Point, encodeX962Point, getCurveByName, \\\n        getPointByteSize\nfrom .utils.rsakey import RSAKey\nfrom .utils.cryptomath import bytesToNumber, getRandomBytes, powMod, \\\n        numBits, numberToByteArray, divceil, numBytes, secureHash\nfrom .utils.lists import getFirstMatching\nfrom .utils import tlshashlib as hashlib\nfrom .utils.x25519 import x25519, x448, X25519_G, X448_G, X25519_ORDER_SIZE, \\\n        X448_ORDER_SIZE\nfrom .utils.compat import int_types\nfrom .utils.codec import DecodeError\n\n\nclass KeyExchange(object):\n    \"\"\"\n    Common API for calculating Premaster secret\n\n    NOT stable, will get moved from this file\n    \"\"\"\n\n    def __init__(self, cipherSuite, clientHello, serverHello, privateKey=None):\n        \"\"\"Initialize KeyExchange. privateKey is the signing private key\"\"\"\n        self.cipherSuite = cipherSuite\n        self.clientHello = clientHello\n        self.serverHello = serverHello\n        self.privateKey = privateKey\n\n    def makeServerKeyExchange(self, sigHash=None):\n        \"\"\"\n        Create a ServerKeyExchange object\n\n        Returns a ServerKeyExchange object for the server's initial leg in the\n        handshake. If the key exchange method does not send ServerKeyExchange\n        (e.g. RSA), it returns None.\n        \"\"\"\n        raise NotImplementedError()\n\n    def makeClientKeyExchange(self):\n        \"\"\"\n        Create a ClientKeyExchange object\n\n        Returns a ClientKeyExchange for the second flight from client in the\n        handshake.\n        \"\"\"\n        return ClientKeyExchange(self.cipherSuite,\n                                 self.serverHello.server_version)\n\n    def processClientKeyExchange(self, clientKeyExchange):\n        \"\"\"\n        Process ClientKeyExchange and return premaster secret\n\n        Processes the client's ClientKeyExchange message and returns the\n        premaster secret. Raises TLSLocalAlert on error.\n        \"\"\"\n        raise NotImplementedError()\n\n    def processServerKeyExchange(self, srvPublicKey,\n                                 serverKeyExchange):\n        \"\"\"Process the server KEX and return premaster secret\"\"\"\n        raise NotImplementedError()\n\n    def _tls12_sign_ecdsa_SKE(self, serverKeyExchange, sigHash=None):\n        try:\n            serverKeyExchange.hashAlg, serverKeyExchange.signAlg = \\\n                    getattr(SignatureScheme, sigHash)\n            hashName = SignatureScheme.getHash(sigHash)\n        except AttributeError:\n            serverKeyExchange.hashAlg = getattr(HashAlgorithm, sigHash)\n            serverKeyExchange.signAlg = SignatureAlgorithm.ecdsa\n            hashName = sigHash\n\n        hash_bytes = serverKeyExchange.hash(self.clientHello.random,\n                                            self.serverHello.random)\n\n        hash_bytes = hash_bytes[:self.privateKey.private_key.curve.baselen]\n\n        serverKeyExchange.signature = \\\n            self.privateKey.sign(hash_bytes, hashAlg=hashName)\n\n        if not serverKeyExchange.signature:\n            raise TLSInternalError(\"Empty signature\")\n\n        if not self.privateKey.verify(serverKeyExchange.signature,\n                                             hash_bytes,\n                                             ecdsa.util.sigdecode_der):\n            raise TLSInternalError(\"signature validation failure\")\n\n    def _tls12_sign_dsa_SKE(self, serverKeyExchange, sigHash=None):\n        \"\"\"Sign a TLSv1.2 SKE message.\"\"\"\n        try:\n            serverKeyExchange.hashAlg, serverKeyExchange.signAlg = \\\n                getattr(SignatureScheme, sigHash)\n\n        except AttributeError:\n            serverKeyExchange.signAlg = SignatureAlgorithm.dsa\n            serverKeyExchange.hashAlg = getattr(HashAlgorithm, sigHash)\n\n        hashBytes = serverKeyExchange.hash(self.clientHello.random,\n                                           self.serverHello.random)\n\n        serverKeyExchange.signature = \\\n            self.privateKey.sign(hashBytes)\n\n        if not serverKeyExchange.signature:\n            raise TLSInternalError(\"Empty signature\")\n\n        if not self.privateKey.verify(serverKeyExchange.signature,\n                                      hashBytes):\n            raise TLSInternalError(\"Server Key Exchange signature invalid\")\n\n    def _tls12_sign_eddsa_ske(self, server_key_exchange, sig_hash):\n        \"\"\"Sign a TLSv1.2 SKE message.\"\"\"\n        server_key_exchange.hashAlg, server_key_exchange.signAlg = \\\n                getattr(SignatureScheme, sig_hash)\n        pad_type = None\n        hash_name = None\n        salt_len = None\n\n        hash_bytes = server_key_exchange.hash(self.clientHello.random,\n                                              self.serverHello.random)\n\n        server_key_exchange.signature = \\\n            self.privateKey.hashAndSign(hash_bytes,\n                                        pad_type,\n                                        hash_name,\n                                        salt_len)\n\n        if not server_key_exchange.signature:\n            raise TLSInternalError(\"Empty signature\")\n\n        if not self.privateKey.hashAndVerify(\n                server_key_exchange.signature,\n                hash_bytes,\n                pad_type,\n                hash_name,\n                salt_len):\n            raise TLSInternalError(\"Server Key Exchange signature invalid\")\n\n    def _tls12_signSKE(self, serverKeyExchange, sigHash=None):\n        \"\"\"Sign a TLSv1.2 SKE message.\"\"\"\n        try:\n            serverKeyExchange.hashAlg, serverKeyExchange.signAlg = \\\n                    getattr(SignatureScheme, sigHash)\n            keyType = SignatureScheme.getKeyType(sigHash)\n            padType = SignatureScheme.getPadding(sigHash)\n            hashName = SignatureScheme.getHash(sigHash)\n            saltLen = getattr(hashlib, hashName)().digest_size\n        except AttributeError:\n            serverKeyExchange.signAlg = SignatureAlgorithm.rsa\n            serverKeyExchange.hashAlg = getattr(HashAlgorithm, sigHash)\n            keyType = 'rsa'\n            padType = 'pkcs1'\n            hashName = sigHash\n            saltLen = 0\n\n        assert keyType == 'rsa'\n\n        hashBytes = serverKeyExchange.hash(self.clientHello.random,\n                                           self.serverHello.random)\n\n        serverKeyExchange.signature = \\\n            self.privateKey.sign(hashBytes,\n                                 padding=padType,\n                                 hashAlg=hashName,\n                                 saltLen=saltLen)\n\n        if not serverKeyExchange.signature:\n            raise TLSInternalError(\"Empty signature\")\n\n        if not self.privateKey.verify(serverKeyExchange.signature,\n                                      hashBytes,\n                                      padding=padType,\n                                      hashAlg=hashName,\n                                      saltLen=saltLen):\n            raise TLSInternalError(\"Server Key Exchange signature invalid\")\n\n    def signServerKeyExchange(self, serverKeyExchange, sigHash=None):\n        \"\"\"\n        Sign a server key exchange using default or specified algorithm\n\n        :type sigHash: str\n        :param sigHash: name of the signature hash to be used for signing\n        \"\"\"\n        if self.serverHello.server_version < (3, 3):\n            if self.privateKey.key_type == \"ecdsa\":\n                serverKeyExchange.signAlg = SignatureAlgorithm.ecdsa\n            if self.privateKey.key_type == \"dsa\":\n                serverKeyExchange.signAlg = SignatureAlgorithm.dsa\n            hashBytes = serverKeyExchange.hash(self.clientHello.random,\n                                               self.serverHello.random)\n\n            serverKeyExchange.signature = self.privateKey.sign(hashBytes)\n\n            if not serverKeyExchange.signature:\n                raise TLSInternalError(\"Empty signature\")\n\n            if not self.privateKey.verify(serverKeyExchange.signature,\n                                          hashBytes):\n                raise TLSInternalError(\"Server Key Exchange signature invalid\")\n        else:\n            if self.privateKey.key_type == \"ecdsa\":\n                self._tls12_sign_ecdsa_SKE(serverKeyExchange, sigHash)\n            elif self.privateKey.key_type == \"dsa\":\n                self._tls12_sign_dsa_SKE(serverKeyExchange, sigHash)\n            elif self.privateKey.key_type in (\"Ed25519\", \"Ed448\"):\n                self._tls12_sign_eddsa_ske(serverKeyExchange, sigHash)\n            else:\n                self._tls12_signSKE(serverKeyExchange, sigHash)\n\n    @staticmethod\n    def _tls12_verify_ecdsa_SKE(serverKeyExchange, publicKey, clientRandom,\n                                serverRandom, validSigAlgs):\n        hashName = HashAlgorithm.toRepr(serverKeyExchange.hashAlg)\n        if not hashName:\n            raise TLSIllegalParameterException(\"Unknown hash algorithm\")\n\n        hashBytes = serverKeyExchange.hash(clientRandom, serverRandom)\n\n        hashBytes = hashBytes[:publicKey.public_key.curve.baselen]\n\n        if not publicKey.verify(serverKeyExchange.signature, hashBytes,\n                                padding=None,\n                                hashAlg=hashName,\n                                saltLen=None):\n            raise TLSDecryptionFailed(\"Server Key Exchange signature \"\n                                      \"invalid\")\n\n    @staticmethod\n    def _tls12_verify_eddsa_ske(server_key_exchange, public_key, client_random,\n                                server_random, valid_sig_algs):\n        \"\"\"Verify SeverKeyExchange messages with EdDSA signatures.\"\"\"\n        del valid_sig_algs\n        sig_bytes = server_key_exchange.signature\n        if not sig_bytes:\n            raise TLSIllegalParameterException(\"Empty signature\")\n\n        hash_bytes = server_key_exchange.hash(client_random, server_random)\n\n        if not public_key.hashAndVerify(sig_bytes,\n                                        hash_bytes):\n            raise TLSDecryptionFailed(\"Server Key Exchange signature invalid\")\n\n    @staticmethod\n    def _tls12_verify_dsa_SKE(serverKeyExchange, publicKey, clientRandom,\n                              serverRandom, validSigAlgs):\n\n        hashBytes = serverKeyExchange.hash(clientRandom, serverRandom)\n\n        if not publicKey.verify(serverKeyExchange.signature, hashBytes):\n            raise TLSDecryptionFailed(\"Server Key Exchange signature \"\n                                      \"invalid\")\n\n    @staticmethod\n    def _tls12_verify_SKE(serverKeyExchange, publicKey, clientRandom,\n                          serverRandom, validSigAlgs):\n        \"\"\"Verify TLSv1.2 version of SKE.\"\"\"\n        if (serverKeyExchange.hashAlg, serverKeyExchange.signAlg) not in \\\n                validSigAlgs:\n            raise TLSIllegalParameterException(\"Server selected \"\n                                               \"invalid signature \"\n                                               \"algorithm\")\n        if (serverKeyExchange.hashAlg, serverKeyExchange.signAlg) in (\n                SignatureScheme.ed25519, SignatureScheme.ed448):\n            return KeyExchange._tls12_verify_eddsa_ske(serverKeyExchange,\n                                                       publicKey,\n                                                       clientRandom,\n                                                       serverRandom,\n                                                       validSigAlgs)\n        if serverKeyExchange.signAlg == SignatureAlgorithm.ecdsa:\n            return KeyExchange._tls12_verify_ecdsa_SKE(serverKeyExchange,\n                                                       publicKey,\n                                                       clientRandom,\n                                                       serverRandom,\n                                                       validSigAlgs)\n\n        elif serverKeyExchange.signAlg == SignatureAlgorithm.dsa:\n            return KeyExchange._tls12_verify_dsa_SKE(serverKeyExchange,\n                                                     publicKey,\n                                                     clientRandom,\n                                                     serverRandom,\n                                                     validSigAlgs)\n\n        schemeID = (serverKeyExchange.hashAlg,\n                    serverKeyExchange.signAlg)\n        scheme = SignatureScheme.toRepr(schemeID)\n        if scheme is not None:\n            keyType = SignatureScheme.getKeyType(scheme)\n            padType = SignatureScheme.getPadding(scheme)\n            hashName = SignatureScheme.getHash(scheme)\n            saltLen = getattr(hashlib, hashName)().digest_size\n        else:\n            if serverKeyExchange.signAlg != SignatureAlgorithm.rsa:\n                raise TLSInternalError(\"non-RSA sigs are not supported\")\n            keyType = 'rsa'\n            padType = 'pkcs1'\n            saltLen = 0\n            hashName = HashAlgorithm.toRepr(serverKeyExchange.hashAlg)\n            if hashName is None:\n                msg = \"Unknown hash ID: {0}\"\\\n                        .format(serverKeyExchange.hashAlg)\n                raise TLSIllegalParameterException(msg)\n        assert keyType == 'rsa'\n\n        hashBytes = serverKeyExchange.hash(clientRandom, serverRandom)\n\n        sigBytes = serverKeyExchange.signature\n        if not sigBytes:\n            raise TLSIllegalParameterException(\"Empty signature\")\n\n        if not publicKey.verify(sigBytes, hashBytes,\n                                padding=padType,\n                                hashAlg=hashName,\n                                saltLen=saltLen):\n            raise TLSDecryptionFailed(\"Server Key Exchange signature \"\n                                      \"invalid\")\n\n    @staticmethod\n    def verifyServerKeyExchange(serverKeyExchange, publicKey, clientRandom,\n                                serverRandom, validSigAlgs):\n        \"\"\"Verify signature on the Server Key Exchange message\n\n        the only acceptable signature algorithms are specified by validSigAlgs\n        \"\"\"\n        if serverKeyExchange.version < (3, 3):\n            hashBytes = serverKeyExchange.hash(clientRandom, serverRandom)\n            sigBytes = serverKeyExchange.signature\n\n            if not sigBytes:\n                raise TLSIllegalParameterException(\"Empty signature\")\n\n            if not publicKey.verify(sigBytes, hashBytes):\n                raise TLSDecryptionFailed(\"Server Key Exchange signature \"\n                                          \"invalid\")\n        else:\n            KeyExchange._tls12_verify_SKE(serverKeyExchange, publicKey,\n                                          clientRandom, serverRandom,\n                                          validSigAlgs)\n\n    @staticmethod\n    def calcVerifyBytes(version, handshakeHashes, signatureAlg,\n                        premasterSecret, clientRandom, serverRandom,\n                        prf_name = None, peer_tag=b'client', key_type=\"rsa\"):\n        \"\"\"Calculate signed bytes for Certificate Verify\"\"\"\n        if version == (3, 0):\n            masterSecret = calc_key(version, premasterSecret,\n                                    0, b\"master secret\",\n                                    client_random=clientRandom,\n                                    server_random=serverRandom,\n                                    output_length=48)\n            verifyBytes = handshakeHashes.digestSSL(masterSecret, b\"\")\n        elif version in ((3, 1), (3, 2)):\n            if key_type != \"ecdsa\":\n                verifyBytes = handshakeHashes.digest()\n            else:\n                verifyBytes = handshakeHashes.digest(\"sha1\")\n        elif version == (3, 3):\n            if signatureAlg in (SignatureScheme.ed25519,\n                    SignatureScheme.ed448):\n                hashName = \"intrinsic\"\n                padding = None\n            elif signatureAlg[1] != SignatureAlgorithm.ecdsa:\n                scheme = SignatureScheme.toRepr(signatureAlg)\n                if scheme is None:\n                    hashName = HashAlgorithm.toRepr(signatureAlg[0])\n                    padding = 'pkcs1'\n                else:\n                    hashName = SignatureScheme.getHash(scheme)\n                    padding = SignatureScheme.getPadding(scheme)\n            else:\n                padding = None\n                hashName = HashAlgorithm.toRepr(signatureAlg[0])\n            verifyBytes = handshakeHashes.digest(hashName)\n            if padding == 'pkcs1':\n                verifyBytes = RSAKey.addPKCS1Prefix(verifyBytes, hashName)\n        elif version == (3, 4):\n            scheme = SignatureScheme.toRepr(signatureAlg)\n            if scheme:\n                hash_name = SignatureScheme.getHash(scheme)\n            else:\n                # handles negative test cases when we try to pass in\n                # schemes that are not supported in TLS1.3\n                hash_name = HashAlgorithm.toRepr(signatureAlg[0])\n            verifyBytes = bytearray(b'\\x20' * 64 +\n                                    b'TLS 1.3, ' + peer_tag +\n                                    b' CertificateVerify' +\n                                    b'\\x00') + \\\n                          handshakeHashes.digest(prf_name)\n            if hash_name != \"intrinsic\":\n                verifyBytes = secureHash(verifyBytes, hash_name)\n        else:\n            raise ValueError(\"Unsupported TLS version {0}\".format(version))\n        return verifyBytes\n\n    @staticmethod\n    def makeCertificateVerify(version, handshakeHashes, validSigAlgs,\n                              privateKey, certificateRequest, premasterSecret,\n                              clientRandom, serverRandom):\n        \"\"\"Create a Certificate Verify message\n\n        :param version: protocol version in use\n        :param handshakeHashes: the running hash of all handshake messages\n        :param validSigAlgs: acceptable signature algorithms for client side,\n            applicable only to TLSv1.2 (or later)\n        :param certificateRequest: the server provided Certificate Request\n            message\n        :param premasterSecret: the premaster secret, needed only for SSLv3\n        :param clientRandom: client provided random value, needed only for\n            SSLv3\n        :param serverRandom: server provided random value, needed only for\n            SSLv3\n        \"\"\"\n        signatureAlgorithm = None\n        if privateKey.key_type == \"ecdsa\" and version < (3, 3):\n            signatureAlgorithm = (HashAlgorithm.sha1, SignatureAlgorithm.ecdsa)\n        # in TLS 1.2 we must decide which algorithm to use for signing\n        if version == (3, 3):\n            serverSigAlgs = certificateRequest.supported_signature_algs\n            signatureAlgorithm = getFirstMatching(validSigAlgs, serverSigAlgs)\n            # if none acceptable, do a last resort:\n            if signatureAlgorithm is None:\n                signatureAlgorithm = validSigAlgs[0]\n        verifyBytes = KeyExchange.calcVerifyBytes(version, handshakeHashes,\n                                                  signatureAlgorithm,\n                                                  premasterSecret,\n                                                  clientRandom,\n                                                  serverRandom,\n                                                  key_type=privateKey.key_type)\n        if signatureAlgorithm and signatureAlgorithm in (\n                SignatureScheme.ed25519, SignatureScheme.ed448):\n            padding = None\n            hashName = \"intrinsic\"\n            saltLen = None\n            sig_func = privateKey.hashAndSign\n            ver_func = privateKey.hashAndVerify\n        elif signatureAlgorithm and \\\n                signatureAlgorithm[1] == SignatureAlgorithm.ecdsa:\n            padding = None\n            hashName = HashAlgorithm.toRepr(signatureAlgorithm[0])\n            saltLen = None\n            verifyBytes = verifyBytes[:privateKey.private_key.curve.baselen]\n            sig_func = privateKey.sign\n            ver_func = privateKey.verify\n        else:\n            scheme = SignatureScheme.toRepr(signatureAlgorithm)\n            # for pkcs1 signatures hash is used to add PKCS#1 prefix, but\n            # that was already done by calcVerifyBytes\n            hashName = None\n            saltLen = 0\n            if scheme is None:\n                padding = 'pkcs1'\n            else:\n                padding = SignatureScheme.getPadding(scheme)\n                if padding == 'pss':\n                    hashName = SignatureScheme.getHash(scheme)\n                    saltLen = getattr(hashlib, hashName)().digest_size\n            sig_func = privateKey.sign\n            ver_func = privateKey.verify\n\n        signedBytes = sig_func(verifyBytes,\n                               padding,\n                               hashName,\n                               saltLen)\n        if not ver_func(signedBytes, verifyBytes, padding, hashName,\n                        saltLen):\n            raise TLSInternalError(\"Certificate Verify signature invalid\")\n        certificateVerify = CertificateVerify(version)\n        certificateVerify.create(signedBytes, signatureAlgorithm)\n\n        return certificateVerify\n\n\nclass AuthenticatedKeyExchange(KeyExchange):\n    \"\"\"\n    Common methods for key exchanges that authenticate Server Key Exchange\n\n    Methods for signing Server Key Exchange message\n    \"\"\"\n\n    def makeServerKeyExchange(self, sigHash=None):\n        \"\"\"Prepare server side of key exchange with selected parameters\"\"\"\n        ske = super(AuthenticatedKeyExchange, self).makeServerKeyExchange()\n        self.signServerKeyExchange(ske, sigHash)\n        return ske\n\n\nclass RSAKeyExchange(KeyExchange):\n    \"\"\"\n    Handling of RSA key exchange\n\n    NOT stable API, do NOT use\n    \"\"\"\n\n    def __init__(self, cipherSuite, clientHello, serverHello, privateKey):\n        super(RSAKeyExchange, self).__init__(cipherSuite, clientHello,\n                                             serverHello, privateKey)\n        self.encPremasterSecret = None\n\n    def makeServerKeyExchange(self, sigHash=None):\n        \"\"\"Don't create a server key exchange for RSA key exchange\"\"\"\n        return None\n\n    def processClientKeyExchange(self, clientKeyExchange):\n        \"\"\"Decrypt client key exchange, return premaster secret\"\"\"\n        premasterSecret = self.privateKey.decrypt(\\\n            clientKeyExchange.encryptedPreMasterSecret)\n\n        # On decryption failure randomize premaster secret to avoid\n        # Bleichenbacher's \"million message\" attack\n        randomPreMasterSecret = getRandomBytes(48)\n        if not premasterSecret:\n            premasterSecret = randomPreMasterSecret\n        elif len(premasterSecret) != 48:\n            premasterSecret = randomPreMasterSecret\n        else:\n            versionCheck = (premasterSecret[0], premasterSecret[1])\n            if versionCheck != self.clientHello.client_version:\n                #Tolerate buggy IE clients\n                if versionCheck != self.serverHello.server_version:\n                    premasterSecret = randomPreMasterSecret\n        return premasterSecret\n\n    def processServerKeyExchange(self, srvPublicKey,\n                                 serverKeyExchange):\n        \"\"\"Generate premaster secret for server\"\"\"\n        del serverKeyExchange # not present in RSA key exchange\n        premasterSecret = getRandomBytes(48)\n        premasterSecret[0] = self.clientHello.client_version[0]\n        premasterSecret[1] = self.clientHello.client_version[1]\n\n        self.encPremasterSecret = srvPublicKey.encrypt(premasterSecret)\n        return premasterSecret\n\n    def makeClientKeyExchange(self):\n        \"\"\"Return a client key exchange with clients key share\"\"\"\n        clientKeyExchange = super(RSAKeyExchange, self).makeClientKeyExchange()\n        clientKeyExchange.createRSA(self.encPremasterSecret)\n        return clientKeyExchange\n\n\nclass ADHKeyExchange(KeyExchange):\n    \"\"\"\n    Handling of anonymous Diffie-Hellman Key exchange\n\n    FFDHE without signing serverKeyExchange useful for anonymous DH\n    \"\"\"\n\n    def __init__(self, cipherSuite, clientHello, serverHello,\n                 dhParams=None, dhGroups=None):\n        super(ADHKeyExchange, self).__init__(cipherSuite, clientHello,\n                                             serverHello)\n#pylint: enable = invalid-name\n        self.dh_Xs = None\n        self.dh_Yc = None\n        if dhParams:\n            self.dh_g, self.dh_p = dhParams\n        else:\n            # 2048-bit MODP Group (RFC 5054, group 3)\n            self.dh_g, self.dh_p = goodGroupParameters[2]\n        self.dhGroups = dhGroups\n\n    def makeServerKeyExchange(self):\n        \"\"\"\n        Prepare server side of anonymous key exchange with selected parameters\n        \"\"\"\n        # Check for RFC 7919 support\n        ext = self.clientHello.getExtension(ExtensionType.supported_groups)\n        if ext and self.dhGroups:\n            commonGroup = getFirstMatching(ext.groups, self.dhGroups)\n            if commonGroup:\n                self.dh_g, self.dh_p = RFC7919_GROUPS[commonGroup - 256]\n            elif getFirstMatching(ext.groups, range(256, 512)):\n                raise TLSInternalError(\"DHE key exchange attempted despite no \"\n                                       \"overlap between supported groups\")\n\n        # for TLS < 1.3 we need special algorithm to select params (see above)\n        # so do not pass in the group, if we selected one\n        kex = FFDHKeyExchange(None, self.serverHello.server_version,\n                              self.dh_g, self.dh_p)\n        self.dh_Xs = kex.get_random_private_key()\n        dh_Ys = kex.calc_public_value(self.dh_Xs)\n\n        version = self.serverHello.server_version\n        serverKeyExchange = ServerKeyExchange(self.cipherSuite, version)\n        serverKeyExchange.createDH(self.dh_p, self.dh_g, dh_Ys)\n        # No sign for anonymous ServerKeyExchange.\n        return serverKeyExchange\n\n    def processClientKeyExchange(self, clientKeyExchange):\n        \"\"\"Use client provided parameters to establish premaster secret\"\"\"\n        dh_Yc = clientKeyExchange.dh_Yc\n\n        kex = FFDHKeyExchange(None, self.serverHello.server_version,\n                              self.dh_g, self.dh_p)\n        return kex.calc_shared_key(self.dh_Xs, dh_Yc)\n\n    def processServerKeyExchange(self, srvPublicKey, serverKeyExchange):\n        \"\"\"Process the server key exchange, return premaster secret.\"\"\"\n        del srvPublicKey\n        dh_p = serverKeyExchange.dh_p\n        # TODO make the minimum changeable\n        if dh_p < 2**1023:\n            raise TLSInsufficientSecurity(\"DH prime too small\")\n        dh_g = serverKeyExchange.dh_g\n        dh_Ys = serverKeyExchange.dh_Ys\n\n        kex = FFDHKeyExchange(None, self.serverHello.server_version,\n                              dh_g, dh_p)\n\n        dh_Xc = kex.get_random_private_key()\n        self.dh_Yc = kex.calc_public_value(dh_Xc)\n        return kex.calc_shared_key(dh_Xc, dh_Ys)\n\n    def makeClientKeyExchange(self):\n        \"\"\"Create client key share for the key exchange\"\"\"\n        cke = super(ADHKeyExchange, self).makeClientKeyExchange()\n        cke.createDH(self.dh_Yc)\n        return cke\n\n\n# the DHE_RSA part comes from IETF ciphersuite names, we want to keep it\n#pylint: disable = invalid-name\nclass DHE_RSAKeyExchange(AuthenticatedKeyExchange, ADHKeyExchange):\n    \"\"\"\n    Handling of authenticated ephemeral Diffe-Hellman Key exchange.\n    \"\"\"\n\n    def __init__(self, cipherSuite, clientHello, serverHello, privateKey,\n                 dhParams=None, dhGroups=None):\n        \"\"\"\n        Create helper object for Diffie-Hellamn key exchange.\n\n        :param dhParams: Diffie-Hellman parameters that will be used by\n            server. First element of the tuple is the generator, the second\n            is the prime. If not specified it will use a secure set (currently\n            a 2048-bit safe prime).\n        :type dhParams: 2-element tuple of int\n        \"\"\"\n        super(DHE_RSAKeyExchange, self).__init__(cipherSuite, clientHello,\n                                                 serverHello, dhParams,\n                                                 dhGroups)\n#pylint: enable = invalid-name\n        self.privateKey = privateKey\n\n\nclass AECDHKeyExchange(KeyExchange):\n    \"\"\"\n    Handling of anonymous Eliptic curve Diffie-Hellman Key exchange\n\n    ECDHE without signing serverKeyExchange useful for anonymous ECDH\n    \"\"\"\n\n    def __init__(self, cipherSuite, clientHello, serverHello, acceptedCurves,\n                 defaultCurve=GroupName.secp256r1):\n        super(AECDHKeyExchange, self).__init__(cipherSuite, clientHello,\n                                               serverHello)\n        self.ecdhXs = None\n        self.acceptedCurves = acceptedCurves\n        self.group_id = None\n        self.ecdhYc = None\n        self.defaultCurve = defaultCurve\n\n    def makeServerKeyExchange(self, sigHash=None):\n        \"\"\"Create AECDHE version of Server Key Exchange\"\"\"\n        #Get client supported groups\n        client_curves = self.clientHello.getExtension(\n                ExtensionType.supported_groups)\n        if client_curves is None:\n            # in case there is no extension, we can pick any curve,\n            # use the configured one\n            client_curves = [self.defaultCurve]\n        elif not client_curves.groups:\n            # extension should have been validated before\n            raise TLSInternalError(\"Can't do ECDHE with no client curves\")\n        else:\n            client_curves = client_curves.groups\n\n        #Pick first client preferred group we support\n        self.group_id = getFirstMatching(client_curves, self.acceptedCurves)\n        if self.group_id is None:\n            raise TLSInsufficientSecurity(\"No mutual groups\")\n\n        kex = ECDHKeyExchange(self.group_id, self.serverHello.server_version)\n        self.ecdhXs = kex.get_random_private_key()\n        ecdhYs = kex.calc_public_value(self.ecdhXs)\n\n        version = self.serverHello.server_version\n        serverKeyExchange = ServerKeyExchange(self.cipherSuite, version)\n        serverKeyExchange.createECDH(ECCurveType.named_curve,\n                                     named_curve=self.group_id,\n                                     point=ecdhYs)\n        # No sign for anonymous ServerKeyExchange\n        return serverKeyExchange\n\n    def processClientKeyExchange(self, clientKeyExchange):\n        \"\"\"Calculate premaster secret from previously generated SKE and CKE\"\"\"\n        ecdhYc = clientKeyExchange.ecdh_Yc\n\n        if not ecdhYc:\n            raise TLSDecodeError(\"No key share\")\n\n        kex = ECDHKeyExchange(self.group_id, self.serverHello.server_version)\n        return kex.calc_shared_key(self.ecdhXs, ecdhYc)\n\n    def processServerKeyExchange(self, srvPublicKey, serverKeyExchange):\n        \"\"\"Process the server key exchange, return premaster secret\"\"\"\n        del srvPublicKey\n\n        if serverKeyExchange.curve_type != ECCurveType.named_curve \\\n            or serverKeyExchange.named_curve not in self.acceptedCurves:\n            raise TLSIllegalParameterException(\"Server picked curve we \"\n                                               \"didn't advertise\")\n\n        ecdh_Ys = serverKeyExchange.ecdh_Ys\n        if not ecdh_Ys:\n            raise TLSDecodeError(\"Empty server key share\")\n\n        kex = ECDHKeyExchange(serverKeyExchange.named_curve,\n                              self.serverHello.server_version)\n        ecdhXc = kex.get_random_private_key()\n        self.ecdhYc = kex.calc_public_value(ecdhXc)\n        return kex.calc_shared_key(ecdhXc, ecdh_Ys)\n\n    def makeClientKeyExchange(self):\n        \"\"\"Make client key exchange for ECDHE\"\"\"\n        cke = super(AECDHKeyExchange, self).makeClientKeyExchange()\n        cke.createECDH(self.ecdhYc)\n        return cke\n\n\n# The ECDHE_RSA part comes from the IETF names of ciphersuites, so we want to\n# keep it\n#pylint: disable = invalid-name\nclass ECDHE_RSAKeyExchange(AuthenticatedKeyExchange, AECDHKeyExchange):\n    \"\"\"Helper class for conducting ECDHE key exchange\"\"\"\n\n    def __init__(self, cipherSuite, clientHello, serverHello, privateKey,\n                 acceptedCurves, defaultCurve=GroupName.secp256r1):\n        super(ECDHE_RSAKeyExchange, self).__init__(cipherSuite, clientHello,\n                                                   serverHello,\n                                                   acceptedCurves,\n                                                   defaultCurve)\n#pylint: enable = invalid-name\n        self.privateKey = privateKey\n\n\nclass SRPKeyExchange(KeyExchange):\n    \"\"\"Helper class for conducting SRP key exchange\"\"\"\n\n    def __init__(self, cipherSuite, clientHello, serverHello, privateKey,\n                 verifierDB, srpUsername=None, password=None, settings=None):\n        \"\"\"Link Key Exchange options with verifierDB for SRP\"\"\"\n        super(SRPKeyExchange, self).__init__(cipherSuite, clientHello,\n                                             serverHello, privateKey)\n        self.N = None\n        self.v = None\n        self.b = None\n        self.B = None\n        self.verifierDB = verifierDB\n        self.A = None\n        self.srpUsername = srpUsername\n        self.password = password\n        self.settings = settings\n        if srpUsername is not None and not isinstance(srpUsername, bytearray):\n            raise TypeError(\"srpUsername must be a bytearray object\")\n        if password is not None and not isinstance(password, bytearray):\n            raise TypeError(\"password must be a bytearray object\")\n\n    def makeServerKeyExchange(self, sigHash=None):\n        \"\"\"Create SRP version of Server Key Exchange\"\"\"\n        srpUsername = bytes(self.clientHello.srp_username)\n        #Get parameters from username\n        try:\n            entry = self.verifierDB[srpUsername]\n        except KeyError:\n            raise TLSUnknownPSKIdentity(\"Unknown identity\")\n        (self.N, g, s, self.v) = entry\n\n        #Calculate server's ephemeral DH values (b, B)\n        self.b = bytesToNumber(getRandomBytes(32))\n        k = makeK(self.N, g)\n        self.B = (powMod(g, self.b, self.N) + (k * self.v)) % self.N\n\n        #Create ServerKeyExchange, signing it if necessary\n        serverKeyExchange = ServerKeyExchange(self.cipherSuite,\n                                              self.serverHello.server_version)\n        serverKeyExchange.createSRP(self.N, g, s, self.B)\n        if self.cipherSuite in CipherSuite.srpCertSuites:\n            self.signServerKeyExchange(serverKeyExchange, sigHash)\n        return serverKeyExchange\n\n    def processClientKeyExchange(self, clientKeyExchange):\n        \"\"\"Calculate premaster secret from Client Key Exchange and sent SKE\"\"\"\n        A = clientKeyExchange.srp_A\n        if A % self.N == 0:\n            raise TLSIllegalParameterException(\"Invalid SRP A value\")\n\n        #Calculate u\n        u = makeU(self.N, A, self.B)\n\n        #Calculate premaster secret\n        S = powMod((A * powMod(self.v, u, self.N)) % self.N, self.b, self.N)\n        return numberToByteArray(S)\n\n    def processServerKeyExchange(self, srvPublicKey, serverKeyExchange):\n        \"\"\"Calculate premaster secret from ServerKeyExchange\"\"\"\n        del srvPublicKey # irrelevant for SRP\n        N = serverKeyExchange.srp_N\n        g = serverKeyExchange.srp_g\n        s = serverKeyExchange.srp_s\n        B = serverKeyExchange.srp_B\n\n        if (g, N) not in goodGroupParameters:\n            raise TLSInsufficientSecurity(\"Unknown group parameters\")\n        if numBits(N) < self.settings.minKeySize:\n            raise TLSInsufficientSecurity(\"N value is too small: {0}\".\\\n                                          format(numBits(N)))\n        if numBits(N) > self.settings.maxKeySize:\n            raise TLSInsufficientSecurity(\"N value is too large: {0}\".\\\n                                          format(numBits(N)))\n        if B % N == 0:\n            raise TLSIllegalParameterException(\"Suspicious B value\")\n\n        #Client ephemeral value\n        a = bytesToNumber(getRandomBytes(32))\n        self.A = powMod(g, a, N)\n\n        #Calculate client's static DH values (x, v)\n        x = makeX(s, self.srpUsername, self.password)\n        v = powMod(g, x, N)\n\n        #Calculate u\n        u = makeU(N, self.A, B)\n\n        #Calculate premaster secret\n        k = makeK(N, g)\n        S = powMod((B - (k*v)) % N, a+(u*x), N)\n        return numberToByteArray(S)\n\n    def makeClientKeyExchange(self):\n        \"\"\"Create ClientKeyExchange\"\"\"\n        cke = super(SRPKeyExchange, self).makeClientKeyExchange()\n        cke.createSRP(self.A)\n        return cke\n\n\nclass RawDHKeyExchange(object):\n    \"\"\"\n    Abstract class for performing Diffe-Hellman key exchange.\n\n    Provides a shared API for X25519, ECDHE and FFDHE key exchange.\n    \"\"\"\n\n    def __init__(self, group, version):\n        \"\"\"\n        Set the parameters of the key exchange\n\n        Sets group on which the KEX will take part and protocol version used.\n        \"\"\"\n        self.group = group\n        self.version = version\n\n    def get_random_private_key(self):\n        \"\"\"\n        Generate a random value suitable for use as the private value of KEX.\n        \"\"\"\n        raise NotImplementedError(\"Abstract class\")\n\n    def calc_public_value(self, private):\n        \"\"\"Calculate the public value from the provided private value.\"\"\"\n        raise NotImplementedError(\"Abstract class\")\n\n    def calc_shared_key(self, private, peer_share):\n        \"\"\"Calcualte the shared key given our private and remote share value\"\"\"\n        raise NotImplementedError(\"Abstract class\")\n\n\nclass FFDHKeyExchange(RawDHKeyExchange):\n    \"\"\"Implemenation of the Finite Field Diffie-Hellman key exchange.\"\"\"\n\n    def __init__(self, group, version, generator=None, prime=None):\n        super(FFDHKeyExchange, self).__init__(group, version)\n        if prime and group:\n            raise ValueError(\"Can't set the RFC7919 group and custom params\"\n                             \" at the same time\")\n        if group:\n            self.generator, self.prime = RFC7919_GROUPS[group-256]\n        else:\n            self.prime = prime\n            self.generator = generator\n\n        if not 1 < self.generator < self.prime:\n            raise TLSIllegalParameterException(\"Invalid DH generator\")\n\n    def get_random_private_key(self):\n        \"\"\"\n        Return a random private value for the prime used.\n\n        :rtype: int\n        \"\"\"\n        # Per RFC 3526, Section 1, the exponent should have double the entropy\n        # of the strength of the group.\n        needed_bytes = divceil(paramStrength(self.prime) * 2, 8)\n        return bytesToNumber(getRandomBytes(needed_bytes))\n\n    def calc_public_value(self, private):\n        \"\"\"\n        Calculate the public value for given private value.\n\n        :rtype: int\n        \"\"\"\n        dh_Y = powMod(self.generator, private, self.prime)\n        if dh_Y in (1, self.prime - 1):\n            raise TLSIllegalParameterException(\"Small subgroup capture\")\n        if self.version < (3, 4):\n            return dh_Y\n        else:\n            return numberToByteArray(dh_Y, numBytes(self.prime))\n\n    def _normalise_peer_share(self, peer_share):\n        \"\"\"Convert the peer_share to number if necessary.\"\"\"\n        if isinstance(peer_share, (int_types)):\n            return peer_share\n\n        if numBytes(self.prime) != len(peer_share):\n            raise TLSIllegalParameterException(\n                \"Key share does not match FFDH prime\")\n        return bytesToNumber(peer_share)\n\n    def calc_shared_key(self, private, peer_share):\n        \"\"\"Calculate the shared key.\"\"\"\n        peer_share = self._normalise_peer_share(peer_share)\n        # First half of RFC 2631, Section 2.1.5. Validate the client's public\n        # key.\n        # use of safe primes also means that the p-1 is invalid\n        if not 2 <= peer_share < self.prime - 1:\n            raise TLSIllegalParameterException(\"Invalid peer key share\")\n\n        S = powMod(peer_share, private, self.prime)\n        if S in (1, self.prime - 1):\n            raise TLSIllegalParameterException(\"Small subgroup capture\")\n        if self.version < (3, 4):\n            return numberToByteArray(S)\n        else:\n            return numberToByteArray(S, numBytes(self.prime))\n\n\nclass ECDHKeyExchange(RawDHKeyExchange):\n    \"\"\"Implementation of the Elliptic Curve Diffie-Hellman key exchange.\"\"\"\n\n    _x_groups = set((GroupName.x25519, GroupName.x448))\n\n    @staticmethod\n    def _non_zero_check(value):\n        \"\"\"\n        Verify using constant time operation that the bytearray is not zero\n\n        :raises TLSIllegalParameterException: if the value is all zero\n        \"\"\"\n        summa = 0\n        for i in value:\n            summa |= i\n        if summa == 0:\n            raise TLSIllegalParameterException(\"Invalid key share\")\n\n    def __init__(self, group, version):\n        super(ECDHKeyExchange, self).__init__(group, version)\n\n    def get_random_private_key(self):\n        \"\"\"Return random private key value for the selected curve.\"\"\"\n        if self.group in self._x_groups:\n            if self.group == GroupName.x25519:\n                return getRandomBytes(X25519_ORDER_SIZE)\n            else:\n                return getRandomBytes(X448_ORDER_SIZE)\n        else:\n            curve = getCurveByName(GroupName.toStr(self.group))\n            return ecdsa.util.randrange(curve.generator.order())\n\n    def _get_fun_gen_size(self):\n        \"\"\"Return the function and generator for X25519/X448 KEX.\"\"\"\n        if self.group == GroupName.x25519:\n            return x25519, bytearray(X25519_G), X25519_ORDER_SIZE\n        else:\n            return x448, bytearray(X448_G), X448_ORDER_SIZE\n\n    def calc_public_value(self, private):\n        \"\"\"Calculate public value for given private key.\"\"\"\n        if self.group in self._x_groups:\n            fun, generator, _ = self._get_fun_gen_size()\n            return fun(private, generator)\n        else:\n            curve = getCurveByName(GroupName.toStr(self.group))\n            return encodeX962Point(curve.generator * private)\n\n    def calc_shared_key(self, private, peer_share):\n        \"\"\"Calculate the shared key,\"\"\"\n        if self.group in self._x_groups:\n            fun, _, size = self._get_fun_gen_size()\n            if len(peer_share) != size:\n                raise TLSIllegalParameterException(\"Invalid key share\")\n            S = fun(private, peer_share)\n            self._non_zero_check(S)\n            return S\n        else:\n            curve = getCurveByName(GroupName.toRepr(self.group))\n            try:\n                ecdhYc = decodeX962Point(peer_share,\n                                         curve)\n            except (AssertionError, DecodeError):\n                raise TLSIllegalParameterException(\"Invalid ECC point\")\n\n            S = ecdhYc * private\n\n            return numberToByteArray(S.x(), getPointByteSize(ecdhYc))\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/mathtls.py",
    "content": "# Authors: \n#   Trevor Perrin\n#   Dave Baggett (Arcode Corporation) - MD5 support for MAC_SSL\n#   Yngve Pettersen (ported by Paul Sokolovsky) - TLS 1.2\n#   Hubert Kario - SHA384 PRF\n#\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Miscellaneous helper functions.\"\"\"\n\nfrom .utils.compat import *\nfrom .utils.cryptomath import *\nfrom .constants import CipherSuite\nfrom .utils import tlshashlib as hashlib\nfrom .utils import tlshmac as hmac\nfrom .utils.deprecations import deprecated_method\n\n\nFFDHE_PARAMETERS = {}\n\"\"\"\nListing of all well known FFDH parameters.\n\nPlease note that this dictionary includes all groups that are well-known\n(i.e. named), irrespective if their use is recommended or not.\n\nYou should use RFC7919_GROUPS for well-known secure groups.\n\"\"\"\n\n\n# RFC 2409 section 6.1, First Oakley Group, 768 bit MODP\nRFC2409_GROUP1 = (\n    2,\n    int(remove_whitespace(\"\"\"\n         FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1\n         29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD\n         EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245\n         E485B576 625E7EC6 F44C42E9 A63A3620 FFFFFFFF FFFFFFFF\"\"\"), 16))\nFFDHE_PARAMETERS[\"RFC2409 group 1\"] = RFC2409_GROUP1\n\n\n# RFC 2409 section 6.2, Second Oakley Group, 1024 bit MODP\nRFC2409_GROUP2 = (\n    2,\n    int(remove_whitespace(\"\"\"\n         FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1\n         29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD\n         EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245\n         E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED\n         EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381\n         FFFFFFFF FFFFFFFF\"\"\"), 16))\nFFDHE_PARAMETERS[\"RFC2409 group 2\"] = RFC2409_GROUP2\n\n\n# RFC 3526 section 2, 1536 bit MODP\nRFC3526_GROUP5 = (\n    2,\n    int(remove_whitespace(\"\"\"\n      FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1\n      29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD\n      EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245\n      E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED\n      EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D\n      C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F\n      83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D\n      670C354E 4ABC9804 F1746C08 CA237327 FFFFFFFF FFFFFFFF\"\"\"), 16))\nFFDHE_PARAMETERS[\"RFC3526 group 5\"] = RFC3526_GROUP5\n\n\n# RFC 3526 section 3, 2048 bit MODP\nRFC3526_GROUP14 = (\n    2,\n    int(remove_whitespace(\"\"\"\n      FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1\n      29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD\n      EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245\n      E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED\n      EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D\n      C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F\n      83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D\n      670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B\n      E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9\n      DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510\n      15728E5A 8AACAA68 FFFFFFFF FFFFFFFF\"\"\"), 16))\nFFDHE_PARAMETERS[\"RFC3526 group 14\"] = RFC3526_GROUP14\n\n\n# RFC 3526 section 4, 3072 bit MODP\nRFC3526_GROUP15 = (\n    2,\n    int(remove_whitespace(\"\"\"\n      FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1\n      29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD\n      EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245\n      E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED\n      EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D\n      C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F\n      83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D\n      670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B\n      E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9\n      DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510\n      15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64\n      ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7\n      ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B\n      F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C\n      BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31\n      43DB5BFC E0FD108E 4B82D120 A93AD2CA FFFFFFFF FFFFFFFF\"\"\"), 16))\nFFDHE_PARAMETERS[\"RFC3526 group 15\"] = RFC3526_GROUP15\n\n\n# RFC 3526 section 5, 4096 bit MODP\nRFC3526_GROUP16 = (\n    2,\n    int(remove_whitespace(\"\"\"\n      FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1\n      29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD\n      EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245\n      E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED\n      EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D\n      C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F\n      83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D\n      670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B\n      E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9\n      DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510\n      15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64\n      ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7\n      ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B\n      F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C\n      BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31\n      43DB5BFC E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7\n      88719A10 BDBA5B26 99C32718 6AF4E23C 1A946834 B6150BDA\n      2583E9CA 2AD44CE8 DBBBC2DB 04DE8EF9 2E8EFC14 1FBECAA6\n      287C5947 4E6BC05D 99B2964F A090C3A2 233BA186 515BE7ED\n      1F612970 CEE2D7AF B81BDD76 2170481C D0069127 D5B05AA9\n      93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34063199\n      FFFFFFFF FFFFFFFF\"\"\"), 16))\nFFDHE_PARAMETERS[\"RFC3526 group 16\"] = RFC3526_GROUP16\n\n\n# RFC 3526 section 6, 6144 bit MODP\nRFC3526_GROUP17 = (\n    2,\n    int(remove_whitespace(\"\"\"\n   FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 29024E08\n   8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD EF9519B3 CD3A431B\n   302B0A6D F25F1437 4FE1356D 6D51C245 E485B576 625E7EC6 F44C42E9\n   A637ED6B 0BFF5CB6 F406B7ED EE386BFB 5A899FA5 AE9F2411 7C4B1FE6\n   49286651 ECE45B3D C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8\n   FD24CF5F 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D\n   670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B E39E772C\n   180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9 DE2BCBF6 95581718\n   3995497C EA956AE5 15D22618 98FA0510 15728E5A 8AAAC42D AD33170D\n   04507A33 A85521AB DF1CBA64 ECFB8504 58DBEF0A 8AEA7157 5D060C7D\n   B3970F85 A6E1E4C7 ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226\n   1AD2EE6B F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C\n   BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31 43DB5BFC\n   E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7 88719A10 BDBA5B26\n   99C32718 6AF4E23C 1A946834 B6150BDA 2583E9CA 2AD44CE8 DBBBC2DB\n   04DE8EF9 2E8EFC14 1FBECAA6 287C5947 4E6BC05D 99B2964F A090C3A2\n   233BA186 515BE7ED 1F612970 CEE2D7AF B81BDD76 2170481C D0069127\n   D5B05AA9 93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34028492\n   36C3FAB4 D27C7026 C1D4DCB2 602646DE C9751E76 3DBA37BD F8FF9406\n   AD9E530E E5DB382F 413001AE B06A53ED 9027D831 179727B0 865A8918\n   DA3EDBEB CF9B14ED 44CE6CBA CED4BB1B DB7F1447 E6CC254B 33205151\n   2BD7AF42 6FB8F401 378CD2BF 5983CA01 C64B92EC F032EA15 D1721D03\n   F482D7CE 6E74FEF6 D55E702F 46980C82 B5A84031 900B1C9E 59E7C97F\n   BEC7E8F3 23A97A7E 36CC88BE 0F1D45B7 FF585AC5 4BD407B2 2B4154AA\n   CC8F6D7E BF48E1D8 14CC5ED2 0F8037E0 A79715EE F29BE328 06A1D58B\n   B7C5DA76 F550AA3D 8A1FBFF0 EB19CCB1 A313D55C DA56C9EC 2EF29632\n   387FE8D7 6E3C0468 043E8F66 3F4860EE 12BF2D5B 0B7474D6 E694F91E\n   6DCC4024 FFFFFFFF FFFFFFFF\"\"\"), 16))\nFFDHE_PARAMETERS[\"RFC3526 group 17\"] = RFC3526_GROUP17\n\n\n# RFC 3526 section 7, 8192 bit MODP\nRFC3526_GROUP18 = (\n    2,\n    int(remove_whitespace(\"\"\"\n      FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1\n      29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD\n      EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245\n      E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED\n      EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D\n      C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F\n      83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D\n      670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B\n      E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9\n      DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510\n      15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64\n      ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7\n      ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B\n      F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C\n      BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31\n      43DB5BFC E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7\n      88719A10 BDBA5B26 99C32718 6AF4E23C 1A946834 B6150BDA\n      2583E9CA 2AD44CE8 DBBBC2DB 04DE8EF9 2E8EFC14 1FBECAA6\n      287C5947 4E6BC05D 99B2964F A090C3A2 233BA186 515BE7ED\n      1F612970 CEE2D7AF B81BDD76 2170481C D0069127 D5B05AA9\n      93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34028492\n      36C3FAB4 D27C7026 C1D4DCB2 602646DE C9751E76 3DBA37BD\n      F8FF9406 AD9E530E E5DB382F 413001AE B06A53ED 9027D831\n      179727B0 865A8918 DA3EDBEB CF9B14ED 44CE6CBA CED4BB1B\n      DB7F1447 E6CC254B 33205151 2BD7AF42 6FB8F401 378CD2BF\n      5983CA01 C64B92EC F032EA15 D1721D03 F482D7CE 6E74FEF6\n      D55E702F 46980C82 B5A84031 900B1C9E 59E7C97F BEC7E8F3\n      23A97A7E 36CC88BE 0F1D45B7 FF585AC5 4BD407B2 2B4154AA\n      CC8F6D7E BF48E1D8 14CC5ED2 0F8037E0 A79715EE F29BE328\n      06A1D58B B7C5DA76 F550AA3D 8A1FBFF0 EB19CCB1 A313D55C\n      DA56C9EC 2EF29632 387FE8D7 6E3C0468 043E8F66 3F4860EE\n      12BF2D5B 0B7474D6 E694F91E 6DBE1159 74A3926F 12FEE5E4\n      38777CB6 A932DF8C D8BEC4D0 73B931BA 3BC832B6 8D9DD300\n      741FA7BF 8AFC47ED 2576F693 6BA42466 3AAB639C 5AE4F568\n      3423B474 2BF1C978 238F16CB E39D652D E3FDB8BE FC848AD9\n      22222E04 A4037C07 13EB57A8 1A23F0C7 3473FC64 6CEA306B\n      4BCBC886 2F8385DD FA9D4B7F A2C087E8 79683303 ED5BDD3A\n      062B3CF5 B3A278A6 6D2A13F8 3F44F82D DF310EE0 74AB6A36\n      4597E899 A0255DC1 64F31CC5 0846851D F9AB4819 5DED7EA1\n      B1D510BD 7EE74D73 FAF36BC3 1ECFA268 359046F4 EB879F92\n      4009438B 481C6CD7 889A002E D5EE382B C9190DA6 FC026E47\n      9558E447 5677E9AA 9E3050E2 765694DF C81F56E8 80B96E71\n      60C980DD 98EDD3DF FFFFFFFF FFFFFFFF\"\"\"), 16))\nFFDHE_PARAMETERS[\"RFC3526 group 18\"] = RFC3526_GROUP18\n\n\n# 1024, 1536, 2048, 3072, 4096, 6144, and 8192 bit groups from RFC 5054\n# Formatted as in the RFC\ngoodGroupParameters = [\n    # RFC 5054, 1, 1024-bit Group\n    (2, int(remove_whitespace(\n        \"\"\"\n          EEAF0AB9 ADB38DD6 9C33F80A FA8FC5E8 60726187 75FF3C0B 9EA2314C\n          9C256576 D674DF74 96EA81D3 383B4813 D692C6E0 E0D5D8E2 50B98BE4\n          8E495C1D 6089DAD1 5DC7D7B4 6154D6B6 CE8EF4AD 69B15D49 82559B29\n          7BCF1885 C529F566 660E57EC 68EDBC3C 05726CC0 2FD4CBF4 976EAA9A\n          FD5138FE 8376435B 9FC61D2F C0EB06E3\"\"\"), 16)),\n    # RFC 5054, 2, 1536-bit Group\n    (2, int(remove_whitespace(\n        \"\"\"\n          9DEF3CAF B939277A B1F12A86 17A47BBB DBA51DF4 99AC4C80 BEEEA961\n          4B19CC4D 5F4F5F55 6E27CBDE 51C6A94B E4607A29 1558903B A0D0F843\n          80B655BB 9A22E8DC DF028A7C EC67F0D0 8134B1C8 B9798914 9B609E0B\n          E3BAB63D 47548381 DBC5B1FC 764E3F4B 53DD9DA1 158BFD3E 2B9C8CF5\n          6EDF0195 39349627 DB2FD53D 24B7C486 65772E43 7D6C7F8C E442734A\n          F7CCB7AE 837C264A E3A9BEB8 7F8A2FE9 B8B5292E 5A021FFF 5E91479E\n          8CE7A28C 2442C6F3 15180F93 499A234D CF76E3FE D135F9BB\"\"\"), 16)),\n    # RFC 5054, 3, 2048-bit Group\n    (2, int(remove_whitespace(\n        \"\"\"\n          AC6BDB41 324A9A9B F166DE5E 1389582F AF72B665 1987EE07 FC319294\n          3DB56050 A37329CB B4A099ED 8193E075 7767A13D D52312AB 4B03310D\n          CD7F48A9 DA04FD50 E8083969 EDB767B0 CF609517 9A163AB3 661A05FB\n          D5FAAAE8 2918A996 2F0B93B8 55F97993 EC975EEA A80D740A DBF4FF74\n          7359D041 D5C33EA7 1D281E44 6B14773B CA97B43A 23FB8016 76BD207A\n          436C6481 F1D2B907 8717461A 5B9D32E6 88F87748 544523B5 24B0D57D\n          5EA77A27 75D2ECFA 032CFBDB F52FB378 61602790 04E57AE6 AF874E73\n          03CE5329 9CCC041C 7BC308D8 2A5698F3 A8D0C382 71AE35F8 E9DBFBB6\n          94B5C803 D89F7AE4 35DE236D 525F5475 9B65E372 FCD68EF2 0FA7111F\n          9E4AFF73\"\"\"), 16)),\n    # RFC 5054, 4, 3072-bit Group\n    (5, int(remove_whitespace(\n        \"\"\"\n          FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 29024E08\n          8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD EF9519B3 CD3A431B\n          302B0A6D F25F1437 4FE1356D 6D51C245 E485B576 625E7EC6 F44C42E9\n          A637ED6B 0BFF5CB6 F406B7ED EE386BFB 5A899FA5 AE9F2411 7C4B1FE6\n          49286651 ECE45B3D C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8\n          FD24CF5F 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D\n          670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B E39E772C\n          180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9 DE2BCBF6 95581718\n          3995497C EA956AE5 15D22618 98FA0510 15728E5A 8AAAC42D AD33170D\n          04507A33 A85521AB DF1CBA64 ECFB8504 58DBEF0A 8AEA7157 5D060C7D\n          B3970F85 A6E1E4C7 ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226\n          1AD2EE6B F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C\n          BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31 43DB5BFC\n          E0FD108E 4B82D120 A93AD2CA FFFFFFFF FFFFFFFF\"\"\"), 16)),\n    # RFC 5054, 5, 4096-bit Group\n    (5, int(remove_whitespace(\n        \"\"\"\n          FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 29024E08\n          8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD EF9519B3 CD3A431B\n          302B0A6D F25F1437 4FE1356D 6D51C245 E485B576 625E7EC6 F44C42E9\n          A637ED6B 0BFF5CB6 F406B7ED EE386BFB 5A899FA5 AE9F2411 7C4B1FE6\n          49286651 ECE45B3D C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8\n          FD24CF5F 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D\n          670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B E39E772C\n          180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9 DE2BCBF6 95581718\n          3995497C EA956AE5 15D22618 98FA0510 15728E5A 8AAAC42D AD33170D\n          04507A33 A85521AB DF1CBA64 ECFB8504 58DBEF0A 8AEA7157 5D060C7D\n          B3970F85 A6E1E4C7 ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226\n          1AD2EE6B F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C\n          BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31 43DB5BFC\n          E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7 88719A10 BDBA5B26\n          99C32718 6AF4E23C 1A946834 B6150BDA 2583E9CA 2AD44CE8 DBBBC2DB\n          04DE8EF9 2E8EFC14 1FBECAA6 287C5947 4E6BC05D 99B2964F A090C3A2\n          233BA186 515BE7ED 1F612970 CEE2D7AF B81BDD76 2170481C D0069127\n          D5B05AA9 93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34063199\n          FFFFFFFF FFFFFFFF\"\"\"), 16)),\n    # RFC 5054, 6, 6144-bit Group\n    (5, int(remove_whitespace(\n        \"\"\"\n          FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 29024E08\n          8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD EF9519B3 CD3A431B\n          302B0A6D F25F1437 4FE1356D 6D51C245 E485B576 625E7EC6 F44C42E9\n          A637ED6B 0BFF5CB6 F406B7ED EE386BFB 5A899FA5 AE9F2411 7C4B1FE6\n          49286651 ECE45B3D C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8\n          FD24CF5F 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D\n          670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B E39E772C\n          180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9 DE2BCBF6 95581718\n          3995497C EA956AE5 15D22618 98FA0510 15728E5A 8AAAC42D AD33170D\n          04507A33 A85521AB DF1CBA64 ECFB8504 58DBEF0A 8AEA7157 5D060C7D\n          B3970F85 A6E1E4C7 ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226\n          1AD2EE6B F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C\n          BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31 43DB5BFC\n          E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7 88719A10 BDBA5B26\n          99C32718 6AF4E23C 1A946834 B6150BDA 2583E9CA 2AD44CE8 DBBBC2DB\n          04DE8EF9 2E8EFC14 1FBECAA6 287C5947 4E6BC05D 99B2964F A090C3A2\n          233BA186 515BE7ED 1F612970 CEE2D7AF B81BDD76 2170481C D0069127\n          D5B05AA9 93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34028492\n          36C3FAB4 D27C7026 C1D4DCB2 602646DE C9751E76 3DBA37BD F8FF9406\n          AD9E530E E5DB382F 413001AE B06A53ED 9027D831 179727B0 865A8918\n          DA3EDBEB CF9B14ED 44CE6CBA CED4BB1B DB7F1447 E6CC254B 33205151\n          2BD7AF42 6FB8F401 378CD2BF 5983CA01 C64B92EC F032EA15 D1721D03\n          F482D7CE 6E74FEF6 D55E702F 46980C82 B5A84031 900B1C9E 59E7C97F\n          BEC7E8F3 23A97A7E 36CC88BE 0F1D45B7 FF585AC5 4BD407B2 2B4154AA\n          CC8F6D7E BF48E1D8 14CC5ED2 0F8037E0 A79715EE F29BE328 06A1D58B\n          B7C5DA76 F550AA3D 8A1FBFF0 EB19CCB1 A313D55C DA56C9EC 2EF29632\n          387FE8D7 6E3C0468 043E8F66 3F4860EE 12BF2D5B 0B7474D6 E694F91E\n          6DCC4024 FFFFFFFF FFFFFFFF\"\"\"), 16)),\n    # RFC 5054, 7, 8192-bit Group\n    (19, int(remove_whitespace(\n        \"\"\"\n          FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 29024E08\n          8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD EF9519B3 CD3A431B\n          302B0A6D F25F1437 4FE1356D 6D51C245 E485B576 625E7EC6 F44C42E9\n          A637ED6B 0BFF5CB6 F406B7ED EE386BFB 5A899FA5 AE9F2411 7C4B1FE6\n          49286651 ECE45B3D C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8\n          FD24CF5F 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D\n          670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B E39E772C\n          180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9 DE2BCBF6 95581718\n          3995497C EA956AE5 15D22618 98FA0510 15728E5A 8AAAC42D AD33170D\n          04507A33 A85521AB DF1CBA64 ECFB8504 58DBEF0A 8AEA7157 5D060C7D\n          B3970F85 A6E1E4C7 ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226\n          1AD2EE6B F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C\n          BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31 43DB5BFC\n          E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7 88719A10 BDBA5B26\n          99C32718 6AF4E23C 1A946834 B6150BDA 2583E9CA 2AD44CE8 DBBBC2DB\n          04DE8EF9 2E8EFC14 1FBECAA6 287C5947 4E6BC05D 99B2964F A090C3A2\n          233BA186 515BE7ED 1F612970 CEE2D7AF B81BDD76 2170481C D0069127\n          D5B05AA9 93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34028492\n          36C3FAB4 D27C7026 C1D4DCB2 602646DE C9751E76 3DBA37BD F8FF9406\n          AD9E530E E5DB382F 413001AE B06A53ED 9027D831 179727B0 865A8918\n          DA3EDBEB CF9B14ED 44CE6CBA CED4BB1B DB7F1447 E6CC254B 33205151\n          2BD7AF42 6FB8F401 378CD2BF 5983CA01 C64B92EC F032EA15 D1721D03\n          F482D7CE 6E74FEF6 D55E702F 46980C82 B5A84031 900B1C9E 59E7C97F\n          BEC7E8F3 23A97A7E 36CC88BE 0F1D45B7 FF585AC5 4BD407B2 2B4154AA\n          CC8F6D7E BF48E1D8 14CC5ED2 0F8037E0 A79715EE F29BE328 06A1D58B\n          B7C5DA76 F550AA3D 8A1FBFF0 EB19CCB1 A313D55C DA56C9EC 2EF29632\n          387FE8D7 6E3C0468 043E8F66 3F4860EE 12BF2D5B 0B7474D6 E694F91E\n          6DBE1159 74A3926F 12FEE5E4 38777CB6 A932DF8C D8BEC4D0 73B931BA\n          3BC832B6 8D9DD300 741FA7BF 8AFC47ED 2576F693 6BA42466 3AAB639C\n          5AE4F568 3423B474 2BF1C978 238F16CB E39D652D E3FDB8BE FC848AD9\n          22222E04 A4037C07 13EB57A8 1A23F0C7 3473FC64 6CEA306B 4BCBC886\n          2F8385DD FA9D4B7F A2C087E8 79683303 ED5BDD3A 062B3CF5 B3A278A6\n          6D2A13F8 3F44F82D DF310EE0 74AB6A36 4597E899 A0255DC1 64F31CC5\n          0846851D F9AB4819 5DED7EA1 B1D510BD 7EE74D73 FAF36BC3 1ECFA268\n          359046F4 EB879F92 4009438B 481C6CD7 889A002E D5EE382B C9190DA6\n          FC026E47 9558E447 5677E9AA 9E3050E2 765694DF C81F56E8 80B96E71\n          60C980DD 98EDD3DF FFFFFFFF FFFFFFFF\"\"\"), 16))]\n\n\nfor num, group in enumerate(goodGroupParameters, 1):\n    FFDHE_PARAMETERS[\"RFC5054 group {0}\".format(num)] = group\n\n\n# old versions of tlslite had an incorrect generator for 3072 bit group\n# from RFC 5054. Since the group is a safe prime, the generator of \"2\" is\n# cryptographically safe, so we don't have reason to reject connections\n# from old tlslite, so add the old invalid value to the \"known good\" list\ngoodGroupParameters.append((2, goodGroupParameters[3][1]))\n# we had a bad generator for group 7 (8192 bit) - 5 - while it needs to be 19\n# same as above, any generator but 1 and p-1 are ok, cryptographically speaking\ngoodGroupParameters.append((5, goodGroupParameters[6][1]))\n\n\n# INSECURE groups from RFC 5114, do NOT use\n# RFC 5114, section 2.1, 1024 bit MODP with 160-bit Prime Order Subgroup\nRFC5114_GROUP22 = (\n    int(remove_whitespace(\"\"\"\n       A4D1CBD5 C3FD3412 6765A442 EFB99905 F8104DD2 58AC507F\n       D6406CFF 14266D31 266FEA1E 5C41564B 777E690F 5504F213\n       160217B4 B01B886A 5E91547F 9E2749F4 D7FBD7D3 B9A92EE1\n       909D0D22 63F80A76 A6A24C08 7A091F53 1DBF0A01 69B6A28A\n       D662A4D1 8E73AFA3 2D779D59 18D08BC8 858F4DCE F97C2A24\n       855E6EEB 22B3B2E5\"\"\"), 16),\n    int(remove_whitespace(\"\"\"\n       B10B8F96 A080E01D DE92DE5E AE5D54EC 52C99FBC FB06A3C6\n       9A6A9DCA 52D23B61 6073E286 75A23D18 9838EF1E 2EE652C0\n       13ECB4AE A9061123 24975C3C D49B83BF ACCBDD7D 90C4BD70\n       98488E9C 219A7372 4EFFD6FA E5644738 FAA31A4F F55BCCC0\n       A151AF5F 0DC8B4BD 45BF37DF 365C1A65 E68CFDA7 6D4DA708\n       DF1FB2BC 2E4A4371\"\"\"), 16))\nFFDHE_PARAMETERS[\"RFC5114 group 22\"] = RFC5114_GROUP22\n\n\n# RFC 5114, section 2.2, 2048 bit MODP with 224-bit Prime Order Subgroup\n# INSECURE, do not use\nRFC5114_GROUP23 = (\n    int(remove_whitespace(\"\"\"\n        AC4032EF 4F2D9AE3 9DF30B5C 8FFDAC50 6CDEBE7B 89998CAF\n        74866A08 CFE4FFE3 A6824A4E 10B9A6F0 DD921F01 A70C4AFA\n        AB739D77 00C29F52 C57DB17C 620A8652 BE5E9001 A8D66AD7\n        C1766910 1999024A F4D02727 5AC1348B B8A762D0 521BC98A\n        E2471504 22EA1ED4 09939D54 DA7460CD B5F6C6B2 50717CBE\n        F180EB34 118E98D1 19529A45 D6F83456 6E3025E3 16A330EF\n        BB77A86F 0C1AB15B 051AE3D4 28C8F8AC B70A8137 150B8EEB\n        10E183ED D19963DD D9E263E4 770589EF 6AA21E7F 5F2FF381\n        B539CCE3 409D13CD 566AFBB4 8D6C0191 81E1BCFE 94B30269\n        EDFE72FE 9B6AA4BD 7B5A0F1C 71CFFF4C 19C418E1 F6EC0179\n        81BC087F 2A7065B3 84B890D3 191F2BFA\"\"\"), 16),\n    int(remove_whitespace(\"\"\"\n        AD107E1E 9123A9D0 D660FAA7 9559C51F A20D64E5 683B9FD1\n        B54B1597 B61D0A75 E6FA141D F95A56DB AF9A3C40 7BA1DF15\n        EB3D688A 309C180E 1DE6B85A 1274A0A6 6D3F8152 AD6AC212\n        9037C9ED EFDA4DF8 D91E8FEF 55B7394B 7AD5B7D0 B6C12207\n        C9F98D11 ED34DBF6 C6BA0B2C 8BBC27BE 6A00E0A0 B9C49708\n        B3BF8A31 70918836 81286130 BC8985DB 1602E714 415D9330\n        278273C7 DE31EFDC 7310F712 1FD5A074 15987D9A DC0A486D\n        CDF93ACC 44328387 315D75E1 98C641A4 80CD86A1 B9E587E8\n        BE60E69C C928B2B9 C52172E4 13042E9B 23F10B0E 16E79763\n        C9B53DCF 4BA80A29 E3FB73C1 6B8E75B9 7EF363E2 FFA31F71\n        CF9DE538 4E71B81C 0AC4DFFE 0C10E64F\"\"\"), 16))\nFFDHE_PARAMETERS[\"RFC5114 group 23\"] = RFC5114_GROUP23\n\n\n# RFC 5114, section 2.3, 2048 bit MODP with 256-bit Prime Order Subgroup\n# INSECURE, do not use\nRFC5114_GROUP24 = (\n    int(remove_whitespace(\"\"\"\n       3FB32C9B 73134D0B 2E775066 60EDBD48 4CA7B18F 21EF2054\n       07F4793A 1A0BA125 10DBC150 77BE463F FF4FED4A AC0BB555\n       BE3A6C1B 0C6B47B1 BC3773BF 7E8C6F62 901228F8 C28CBB18\n       A55AE313 41000A65 0196F931 C77A57F2 DDF463E5 E9EC144B\n       777DE62A AAB8A862 8AC376D2 82D6ED38 64E67982 428EBC83\n       1D14348F 6F2F9193 B5045AF2 767164E1 DFC967C1 FB3F2E55\n       A4BD1BFF E83B9C80 D052B985 D182EA0A DB2A3B73 13D3FE14\n       C8484B1E 052588B9 B7D2BBD2 DF016199 ECD06E15 57CD0915\n       B3353BBB 64E0EC37 7FD02837 0DF92B52 C7891428 CDC67EB6\n       184B523D 1DB246C3 2F630784 90F00EF8 D647D148 D4795451\n       5E2327CF EF98C582 664B4C0F 6CC41659\"\"\"), 16),\n    int(remove_whitespace(\"\"\"\n       87A8E61D B4B6663C FFBBD19C 65195999 8CEEF608 660DD0F2\n       5D2CEED4 435E3B00 E00DF8F1 D61957D4 FAF7DF45 61B2AA30\n       16C3D911 34096FAA 3BF4296D 830E9A7C 209E0C64 97517ABD\n       5A8A9D30 6BCF67ED 91F9E672 5B4758C0 22E0B1EF 4275BF7B\n       6C5BFC11 D45F9088 B941F54E B1E59BB8 BC39A0BF 12307F5C\n       4FDB70C5 81B23F76 B63ACAE1 CAA6B790 2D525267 35488A0E\n       F13C6D9A 51BFA4AB 3AD83477 96524D8E F6A167B5 A41825D9\n       67E144E5 14056425 1CCACB83 E6B486F6 B3CA3F79 71506026\n       C0B857F6 89962856 DED4010A BD0BE621 C3A3960A 54E710C3\n       75F26375 D7014103 A4B54330 C198AF12 6116D227 6E11715F\n       693877FA D7EF09CA DB094AE9 1E1A1597\"\"\"), 16))\nFFDHE_PARAMETERS[\"RFC5114 group 24\"] = RFC5114_GROUP24\n\n\nRFC7919_GROUPS = []\n\"\"\"\nAll DH parameters specified in RFC 7919.\n\nThose are the parameters recommended for use in TLS.\n\"\"\"\n\n\n# RFC 7919 ffdhe2048 bit group\nFFDHE2048 = (\n    2,\n    int(remove_whitespace(\"\"\"\n    FFFFFFFF FFFFFFFF ADF85458 A2BB4A9A AFDC5620 273D3CF1\n    D8B9C583 CE2D3695 A9E13641 146433FB CC939DCE 249B3EF9\n    7D2FE363 630C75D8 F681B202 AEC4617A D3DF1ED5 D5FD6561\n    2433F51F 5F066ED0 85636555 3DED1AF3 B557135E 7F57C935\n    984F0C70 E0E68B77 E2A689DA F3EFE872 1DF158A1 36ADE735\n    30ACCA4F 483A797A BC0AB182 B324FB61 D108A94B B2C8E3FB\n    B96ADAB7 60D7F468 1D4F42A3 DE394DF4 AE56EDE7 6372BB19\n    0B07A7C8 EE0A6D70 9E02FCE1 CDF7E2EC C03404CD 28342F61\n    9172FE9C E98583FF 8E4F1232 EEF28183 C3FE3B1B 4C6FAD73\n    3BB5FCBC 2EC22005 C58EF183 7D1683B2 C6F34A26 C1B2EFFA\n    886B4238 61285C97 FFFFFFFF FFFFFFFF\"\"\"), 16))\ngoodGroupParameters.append(FFDHE2048)\nRFC7919_GROUPS.append(FFDHE2048)\nFFDHE_PARAMETERS[\"RFC7919 ffdhe2048\"] = FFDHE2048\n\n\n# RFC 7919 ffdhe3072 bit group\nFFDHE3072 = (\n    2,\n    int(remove_whitespace(\"\"\"\n    FFFFFFFF FFFFFFFF ADF85458 A2BB4A9A AFDC5620 273D3CF1\n    D8B9C583 CE2D3695 A9E13641 146433FB CC939DCE 249B3EF9\n    7D2FE363 630C75D8 F681B202 AEC4617A D3DF1ED5 D5FD6561\n    2433F51F 5F066ED0 85636555 3DED1AF3 B557135E 7F57C935\n    984F0C70 E0E68B77 E2A689DA F3EFE872 1DF158A1 36ADE735\n    30ACCA4F 483A797A BC0AB182 B324FB61 D108A94B B2C8E3FB\n    B96ADAB7 60D7F468 1D4F42A3 DE394DF4 AE56EDE7 6372BB19\n    0B07A7C8 EE0A6D70 9E02FCE1 CDF7E2EC C03404CD 28342F61\n    9172FE9C E98583FF 8E4F1232 EEF28183 C3FE3B1B 4C6FAD73\n    3BB5FCBC 2EC22005 C58EF183 7D1683B2 C6F34A26 C1B2EFFA\n    886B4238 611FCFDC DE355B3B 6519035B BC34F4DE F99C0238\n    61B46FC9 D6E6C907 7AD91D26 91F7F7EE 598CB0FA C186D91C\n    AEFE1309 85139270 B4130C93 BC437944 F4FD4452 E2D74DD3\n    64F2E21E 71F54BFF 5CAE82AB 9C9DF69E E86D2BC5 22363A0D\n    ABC52197 9B0DEADA 1DBF9A42 D5C4484E 0ABCD06B FA53DDEF\n    3C1B20EE 3FD59D7C 25E41D2B 66C62E37 FFFFFFFF FFFFFFFF\"\"\"), 16))\ngoodGroupParameters.append(FFDHE3072)\nRFC7919_GROUPS.append(FFDHE3072)\nFFDHE_PARAMETERS[\"RFC7919 ffdhe3072\"] = FFDHE3072\n\n\n# RFC 7919 ffdhe4096 bit group\nFFDHE4096 = (\n    2,\n    int(remove_whitespace(\"\"\"\n    FFFFFFFF FFFFFFFF ADF85458 A2BB4A9A AFDC5620 273D3CF1\n    D8B9C583 CE2D3695 A9E13641 146433FB CC939DCE 249B3EF9\n    7D2FE363 630C75D8 F681B202 AEC4617A D3DF1ED5 D5FD6561\n    2433F51F 5F066ED0 85636555 3DED1AF3 B557135E 7F57C935\n    984F0C70 E0E68B77 E2A689DA F3EFE872 1DF158A1 36ADE735\n    30ACCA4F 483A797A BC0AB182 B324FB61 D108A94B B2C8E3FB\n    B96ADAB7 60D7F468 1D4F42A3 DE394DF4 AE56EDE7 6372BB19\n    0B07A7C8 EE0A6D70 9E02FCE1 CDF7E2EC C03404CD 28342F61\n    9172FE9C E98583FF 8E4F1232 EEF28183 C3FE3B1B 4C6FAD73\n    3BB5FCBC 2EC22005 C58EF183 7D1683B2 C6F34A26 C1B2EFFA\n    886B4238 611FCFDC DE355B3B 6519035B BC34F4DE F99C0238\n    61B46FC9 D6E6C907 7AD91D26 91F7F7EE 598CB0FA C186D91C\n    AEFE1309 85139270 B4130C93 BC437944 F4FD4452 E2D74DD3\n    64F2E21E 71F54BFF 5CAE82AB 9C9DF69E E86D2BC5 22363A0D\n    ABC52197 9B0DEADA 1DBF9A42 D5C4484E 0ABCD06B FA53DDEF\n    3C1B20EE 3FD59D7C 25E41D2B 669E1EF1 6E6F52C3 164DF4FB\n    7930E9E4 E58857B6 AC7D5F42 D69F6D18 7763CF1D 55034004\n    87F55BA5 7E31CC7A 7135C886 EFB4318A ED6A1E01 2D9E6832\n    A907600A 918130C4 6DC778F9 71AD0038 092999A3 33CB8B7A\n    1A1DB93D 7140003C 2A4ECEA9 F98D0ACC 0A8291CD CEC97DCF\n    8EC9B55A 7F88A46B 4DB5A851 F44182E1 C68A007E 5E655F6A\n    FFFFFFFF FFFFFFFF\"\"\"), 16))\ngoodGroupParameters.append(FFDHE4096)\nRFC7919_GROUPS.append(FFDHE4096)\nFFDHE_PARAMETERS[\"RFC7919 ffdhe4096\"] = FFDHE4096\n\n\n# RFC 7919 ffdhe6144 bit group\nFFDHE6144 = (\n    2,\n    int(remove_whitespace(\"\"\"\n    FFFFFFFF FFFFFFFF ADF85458 A2BB4A9A AFDC5620 273D3CF1\n    D8B9C583 CE2D3695 A9E13641 146433FB CC939DCE 249B3EF9\n    7D2FE363 630C75D8 F681B202 AEC4617A D3DF1ED5 D5FD6561\n    2433F51F 5F066ED0 85636555 3DED1AF3 B557135E 7F57C935\n    984F0C70 E0E68B77 E2A689DA F3EFE872 1DF158A1 36ADE735\n    30ACCA4F 483A797A BC0AB182 B324FB61 D108A94B B2C8E3FB\n    B96ADAB7 60D7F468 1D4F42A3 DE394DF4 AE56EDE7 6372BB19\n    0B07A7C8 EE0A6D70 9E02FCE1 CDF7E2EC C03404CD 28342F61\n    9172FE9C E98583FF 8E4F1232 EEF28183 C3FE3B1B 4C6FAD73\n    3BB5FCBC 2EC22005 C58EF183 7D1683B2 C6F34A26 C1B2EFFA\n    886B4238 611FCFDC DE355B3B 6519035B BC34F4DE F99C0238\n    61B46FC9 D6E6C907 7AD91D26 91F7F7EE 598CB0FA C186D91C\n    AEFE1309 85139270 B4130C93 BC437944 F4FD4452 E2D74DD3\n    64F2E21E 71F54BFF 5CAE82AB 9C9DF69E E86D2BC5 22363A0D\n    ABC52197 9B0DEADA 1DBF9A42 D5C4484E 0ABCD06B FA53DDEF\n    3C1B20EE 3FD59D7C 25E41D2B 669E1EF1 6E6F52C3 164DF4FB\n    7930E9E4 E58857B6 AC7D5F42 D69F6D18 7763CF1D 55034004\n    87F55BA5 7E31CC7A 7135C886 EFB4318A ED6A1E01 2D9E6832\n    A907600A 918130C4 6DC778F9 71AD0038 092999A3 33CB8B7A\n    1A1DB93D 7140003C 2A4ECEA9 F98D0ACC 0A8291CD CEC97DCF\n    8EC9B55A 7F88A46B 4DB5A851 F44182E1 C68A007E 5E0DD902\n    0BFD64B6 45036C7A 4E677D2C 38532A3A 23BA4442 CAF53EA6\n    3BB45432 9B7624C8 917BDD64 B1C0FD4C B38E8C33 4C701C3A\n    CDAD0657 FCCFEC71 9B1F5C3E 4E46041F 388147FB 4CFDB477\n    A52471F7 A9A96910 B855322E DB6340D8 A00EF092 350511E3\n    0ABEC1FF F9E3A26E 7FB29F8C 183023C3 587E38DA 0077D9B4\n    763E4E4B 94B2BBC1 94C6651E 77CAF992 EEAAC023 2A281BF6\n    B3A739C1 22611682 0AE8DB58 47A67CBE F9C9091B 462D538C\n    D72B0374 6AE77F5E 62292C31 1562A846 505DC82D B854338A\n    E49F5235 C95B9117 8CCF2DD5 CACEF403 EC9D1810 C6272B04\n    5B3B71F9 DC6B80D6 3FDD4A8E 9ADB1E69 62A69526 D43161C1\n    A41D570D 7938DAD4 A40E329C D0E40E65 FFFFFFFF FFFFFFFF\"\"\"), 16))\ngoodGroupParameters.append(FFDHE6144)\nRFC7919_GROUPS.append(FFDHE6144)\nFFDHE_PARAMETERS[\"RFC7919 ffdhe6144\"] = FFDHE6144\n\n\n# RFC 7919 ffdhe8192 bit group\nFFDHE8192 = (\n    2,\n    int(remove_whitespace(\"\"\"\n    FFFFFFFF FFFFFFFF ADF85458 A2BB4A9A AFDC5620 273D3CF1\n    D8B9C583 CE2D3695 A9E13641 146433FB CC939DCE 249B3EF9\n    7D2FE363 630C75D8 F681B202 AEC4617A D3DF1ED5 D5FD6561\n    2433F51F 5F066ED0 85636555 3DED1AF3 B557135E 7F57C935\n    984F0C70 E0E68B77 E2A689DA F3EFE872 1DF158A1 36ADE735\n    30ACCA4F 483A797A BC0AB182 B324FB61 D108A94B B2C8E3FB\n    B96ADAB7 60D7F468 1D4F42A3 DE394DF4 AE56EDE7 6372BB19\n    0B07A7C8 EE0A6D70 9E02FCE1 CDF7E2EC C03404CD 28342F61\n    9172FE9C E98583FF 8E4F1232 EEF28183 C3FE3B1B 4C6FAD73\n    3BB5FCBC 2EC22005 C58EF183 7D1683B2 C6F34A26 C1B2EFFA\n    886B4238 611FCFDC DE355B3B 6519035B BC34F4DE F99C0238\n    61B46FC9 D6E6C907 7AD91D26 91F7F7EE 598CB0FA C186D91C\n    AEFE1309 85139270 B4130C93 BC437944 F4FD4452 E2D74DD3\n    64F2E21E 71F54BFF 5CAE82AB 9C9DF69E E86D2BC5 22363A0D\n    ABC52197 9B0DEADA 1DBF9A42 D5C4484E 0ABCD06B FA53DDEF\n    3C1B20EE 3FD59D7C 25E41D2B 669E1EF1 6E6F52C3 164DF4FB\n    7930E9E4 E58857B6 AC7D5F42 D69F6D18 7763CF1D 55034004\n    87F55BA5 7E31CC7A 7135C886 EFB4318A ED6A1E01 2D9E6832\n    A907600A 918130C4 6DC778F9 71AD0038 092999A3 33CB8B7A\n    1A1DB93D 7140003C 2A4ECEA9 F98D0ACC 0A8291CD CEC97DCF\n    8EC9B55A 7F88A46B 4DB5A851 F44182E1 C68A007E 5E0DD902\n    0BFD64B6 45036C7A 4E677D2C 38532A3A 23BA4442 CAF53EA6\n    3BB45432 9B7624C8 917BDD64 B1C0FD4C B38E8C33 4C701C3A\n    CDAD0657 FCCFEC71 9B1F5C3E 4E46041F 388147FB 4CFDB477\n    A52471F7 A9A96910 B855322E DB6340D8 A00EF092 350511E3\n    0ABEC1FF F9E3A26E 7FB29F8C 183023C3 587E38DA 0077D9B4\n    763E4E4B 94B2BBC1 94C6651E 77CAF992 EEAAC023 2A281BF6\n    B3A739C1 22611682 0AE8DB58 47A67CBE F9C9091B 462D538C\n    D72B0374 6AE77F5E 62292C31 1562A846 505DC82D B854338A\n    E49F5235 C95B9117 8CCF2DD5 CACEF403 EC9D1810 C6272B04\n    5B3B71F9 DC6B80D6 3FDD4A8E 9ADB1E69 62A69526 D43161C1\n    A41D570D 7938DAD4 A40E329C CFF46AAA 36AD004C F600C838\n    1E425A31 D951AE64 FDB23FCE C9509D43 687FEB69 EDD1CC5E\n    0B8CC3BD F64B10EF 86B63142 A3AB8829 555B2F74 7C932665\n    CB2C0F1C C01BD702 29388839 D2AF05E4 54504AC7 8B758282\n    2846C0BA 35C35F5C 59160CC0 46FD8251 541FC68C 9C86B022\n    BB709987 6A460E74 51A8A931 09703FEE 1C217E6C 3826E52C\n    51AA691E 0E423CFC 99E9E316 50C1217B 624816CD AD9A95F9\n    D5B80194 88D9C0A0 A1FE3075 A577E231 83F81D4A 3F2FA457\n    1EFC8CE0 BA8A4FE8 B6855DFE 72B0A66E DED2FBAB FBE58A30\n    FAFABE1C 5D71A87E 2F741EF8 C1FE86FE A6BBFDE5 30677F0D\n    97D11D49 F7A8443D 0822E506 A9F4614E 011E2A94 838FF88C\n    D68C8BB7 C5C6424C FFFFFFFF FFFFFFFF\"\"\"), 16))\ngoodGroupParameters.append(FFDHE8192)\nRFC7919_GROUPS.append(FFDHE8192)\nFFDHE_PARAMETERS[\"RFC7919 ffdhe8192\"] = FFDHE8192\n\n\ndef paramStrength(param):\n    \"\"\"\n    Return level of security for DH, DSA and RSA parameters.\n\n    Provide the approximate level of security for algorithms based on finite\n    field (DSA, DH) or integer factorisation cryptography (RSA) when provided\n    with the prime defining the field or the modulus of the public key.\n\n    :param param: prime or modulus\n    :type param: int\n    \"\"\"\n    size = numBits(param)\n    if size < 512:\n        return 48\n    elif size < 768:\n        return 56\n    elif size < 816:\n        return 64\n    elif size < 1023:\n        return 72\n    elif size < 1535:\n        return 80  # NIST SP 800-57\n    elif size < 2047:\n        return 88  # rounded RFC 3526\n    elif size < 3071:\n        return 112  # NIST SP 800-57\n    elif size < 4095:\n        return 128  # NIST SP 800-57\n    elif size < 6144:\n        return 152  # rounded RFC 3526\n    elif size < 7679:\n        return 168  # rounded RFC 3526\n    elif size < 15359:\n        return 192  # NIST SP 800-57\n    else:\n        return 256  # NIST SP 800-57\n\n\ndef P_hash(mac_name, secret, seed, length):\n    \"\"\"Internal method for calculation the PRF in TLS.\"\"\"\n    ret = bytearray(length)\n    seed = compatHMAC(seed)\n    A = seed\n    index = 0\n    mac = hmac.HMAC(compatHMAC(secret), digestmod=mac_name)\n    while index < length:\n        a_fun = mac.copy()\n        a_fun.update(A)\n        A = a_fun.digest()\n        out_fun = mac.copy()\n        out_fun.update(A)\n        out_fun.update(seed)\n        output = out_fun.digest()\n\n        how_many = min(length - index, len(output))\n        ret[index:index+how_many] = output[:how_many]\n        index += how_many\n    return ret\n\n\ndef PRF(secret, label, seed, length):\n    #Split the secret into left and right halves\n    # which may share a byte if len is odd\n    S1 = secret[ : int(math.ceil(len(secret)/2.0))]\n    S2 = secret[ int(math.floor(len(secret)/2.0)) : ]\n\n    #Run the left half through P_MD5 and the right half through P_SHA1\n    p_md5 = P_hash(\"md5\", S1, label + seed, length)\n    p_sha1 = P_hash(\"sha1\", S2, label + seed, length)\n\n    #XOR the output values and return the result\n    for x in range(length):\n        p_md5[x] ^= p_sha1[x]\n    return p_md5\n\ndef PRF_1_2(secret, label, seed, length):\n    \"\"\"Pseudo Random Function for TLS1.2 ciphers that use SHA256\"\"\"\n    return P_hash(\"sha256\", secret, label + seed, length)\n\ndef PRF_1_2_SHA384(secret, label, seed, length):\n    \"\"\"Pseudo Random Function for TLS1.2 ciphers that use SHA384\"\"\"\n    return P_hash(\"sha384\", secret, label + seed, length)\n\ndef PRF_SSL(secret, seed, length):\n    bytes = bytearray(length)\n    index = 0\n    for x in range(26):\n        A = bytearray([ord('A')+x] * (x+1)) # 'A', 'BB', 'CCC', etc..\n        input = secret + SHA1(A + secret + seed)\n        output = MD5(input)\n        for c in output:\n            if index >= length:\n                return bytes\n            bytes[index] = c\n            index += 1\n    return bytes\n\n@deprecated_method(\"Please use calc_key function instead.\")\ndef calcExtendedMasterSecret(version, cipherSuite, premasterSecret,\n                             handshakeHashes):\n    \"\"\"Derive Extended Master Secret from premaster and handshake msgs\"\"\"\n    assert version in ((3, 1), (3, 2), (3, 3))\n    if version in ((3, 1), (3, 2)):\n        masterSecret = PRF(premasterSecret, b\"extended master secret\",\n                           handshakeHashes.digest('md5') +\n                           handshakeHashes.digest('sha1'),\n                           48)\n    else:\n        if cipherSuite in CipherSuite.sha384PrfSuites:\n            masterSecret = PRF_1_2_SHA384(premasterSecret,\n                                          b\"extended master secret\",\n                                          handshakeHashes.digest('sha384'),\n                                          48)\n        else:\n            masterSecret = PRF_1_2(premasterSecret,\n                                   b\"extended master secret\",\n                                   handshakeHashes.digest('sha256'),\n                                   48)\n    return masterSecret\n\n\n@deprecated_method(\"Please use calc_key function instead.\")\ndef calcMasterSecret(version, cipherSuite, premasterSecret, clientRandom,\n                     serverRandom):\n    \"\"\"Derive Master Secret from premaster secret and random values\"\"\"\n    if version == (3,0):\n        masterSecret = PRF_SSL(premasterSecret,\n                            clientRandom + serverRandom, 48)\n    elif version in ((3,1), (3,2)):\n        masterSecret = PRF(premasterSecret, b\"master secret\",\n                            clientRandom + serverRandom, 48)\n    elif version == (3,3):\n        if cipherSuite in CipherSuite.sha384PrfSuites:\n            masterSecret = PRF_1_2_SHA384(premasterSecret,\n                                          b\"master secret\",\n                                          clientRandom + serverRandom,\n                                          48)\n        else:\n            masterSecret = PRF_1_2(premasterSecret,\n                                   b\"master secret\",\n                                   clientRandom + serverRandom,\n                                   48)\n    else:\n        raise AssertionError()\n    return masterSecret\n\n@deprecated_method(\"Please use calc_key function instead.\")\ndef calcFinished(version, masterSecret, cipherSuite, handshakeHashes,\n                 isClient):\n    \"\"\"Calculate the Handshake protocol Finished value\n\n    :param version: TLS protocol version tuple\n    :param masterSecret: negotiated master secret of the connection\n    :param cipherSuite: negotiated cipher suite of the connection,\n    :param handshakeHashes: running hash of the handshake messages\n    :param isClient: whether the calculation should be performed for message\n        sent by client (True) or by server (False) side of connection\n    \"\"\"\n    assert version in ((3, 0), (3, 1), (3, 2), (3, 3))\n    if version == (3,0):\n        if isClient:\n            senderStr = b\"\\x43\\x4C\\x4E\\x54\"\n        else:\n            senderStr = b\"\\x53\\x52\\x56\\x52\"\n\n        verifyData = handshakeHashes.digestSSL(masterSecret, senderStr)\n    else:\n        if isClient:\n            label = b\"client finished\"\n        else:\n            label = b\"server finished\"\n\n        if version in ((3,1), (3,2)):\n            handshakeHash = handshakeHashes.digest()\n            verifyData = PRF(masterSecret, label, handshakeHash, 12)\n        else: # version == (3,3):\n            if cipherSuite in CipherSuite.sha384PrfSuites:\n                handshakeHash = handshakeHashes.digest('sha384')\n                verifyData = PRF_1_2_SHA384(masterSecret, label,\n                                            handshakeHash, 12)\n            else:\n                handshakeHash = handshakeHashes.digest('sha256')\n                verifyData = PRF_1_2(masterSecret, label, handshakeHash, 12)\n\n    return verifyData\n\ndef calc_key(version, secret, cipher_suite, label, handshake_hashes=None,\n            client_random=None, server_random=None, output_length=None):\n    \"\"\"\n    Method for calculating different keys depending on input.\n    It can be used to calculate finished value, master secret,\n    extended master secret or key expansion.\n\n    :param version: TLS protocol version\n    :type version: tuple(int, int)\n    :param bytearray secret: master secret or premasterSecret which will be\n        used in the PRF.\n    :param int cipher_suite: Negotiated cipher suite of the connection.\n    :param bytes label: label for the key you want to calculate\n        (ex. 'master secret', 'extended master secret', etc).\n    :param handshake_hashes: running hash of the handshake messages\n        needed for calculating extended master secret or finished value.\n    :type handshake_hashes: ~tlslite.handshakehashes.HandshakeHashes\n    :param bytearray client_random: client random needed for calculating\n        master secret or key expansion.\n    :param bytearray server_random: server random needed for calculating\n        master secret or key expansion.\n    :param int output_length: Number of bytes to output.\n    \"\"\"\n\n\n    # SSL3 calculations.\n    if version == (3, 0):\n        # Calculating Finished value, either for message sent\n        # by server or by client\n        if label == b\"client finished\":\n            senderStr = b\"\\x43\\x4C\\x4E\\x54\"\n            return handshake_hashes.digestSSL(secret, senderStr)\n        elif label == b\"server finished\":\n            senderStr = b\"\\x53\\x52\\x56\\x52\"\n            return handshake_hashes.digestSSL(secret, senderStr)\n        else:\n            assert label in [b\"key expansion\", b\"master secret\"]\n            func = PRF_SSL\n\n    # TLS1.0 or TLS1.1 calculations.\n    elif version in ((3, 1), (3, 2)):\n        func = PRF\n        # Seed needed for calculating extended master secret\n        if label == b\"extended master secret\":\n            seed = handshake_hashes.digest('md5') + \\\n                   handshake_hashes.digest('sha1')\n        # Seed needed for calculating Finished value\n        elif label in [b\"server finished\", b\"client finished\"]:\n            seed = handshake_hashes.digest()\n        else:\n            assert label in [b\"key expansion\", b\"master secret\"]\n\n    # TLS1.2 calculations.\n    else:\n        assert version == (3, 3)\n        if cipher_suite in CipherSuite.sha384PrfSuites:\n            func = PRF_1_2_SHA384\n            # Seed needed for calculating Finished value or extended master\n            # secret\n            if label in [b\"extended master secret\", b\"server finished\",\n                    b\"client finished\"]:\n                seed = handshake_hashes.digest('sha384')\n            else:\n                assert label in [b\"key expansion\", b\"master secret\"]\n        else:\n            # Same as above, just using sha256\n            func = PRF_1_2\n            if label in [b\"extended master secret\", b\"server finished\",\n                    b\"client finished\"]:\n                seed = handshake_hashes.digest('sha256')\n            else:\n                assert label in [b\"key expansion\", b\"master secret\"]\n\n    # Seed needed for calculating key expansion or master secret\n    if label == b\"key expansion\":\n        seed = server_random + client_random\n    if label == b\"master secret\":\n        seed = client_random + server_random\n\n    if func == PRF_SSL:\n        return func(secret, seed, output_length)\n    return func(secret, label, seed, output_length)\n\ndef makeX(salt, username, password):\n    if len(username)>=256:\n        raise ValueError(\"username too long\")\n    if len(salt)>=256:\n        raise ValueError(\"salt too long\")\n    innerHashResult = SHA1(username + bytearray(b\":\") + password)\n    outerHashResult = SHA1(salt + innerHashResult)\n    return bytesToNumber(outerHashResult)\n\n#This function is used by VerifierDB.makeVerifier\ndef makeVerifier(username, password, bits):\n    bitsIndex = {1024:0, 1536:1, 2048:2, 3072:3, 4096:4, 6144:5, 8192:6}[bits]\n    g,N = goodGroupParameters[bitsIndex]\n    salt = getRandomBytes(16)\n    x = makeX(salt, username, password)\n    verifier = powMod(g, x, N)\n    return N, g, salt, verifier\n\ndef PAD(n, x):\n    nLength = len(numberToByteArray(n))\n    b = numberToByteArray(x)\n    if len(b) < nLength:\n        b = (b\"\\0\" * (nLength-len(b))) + b\n    return b\n\ndef makeU(N, A, B):\n  return bytesToNumber(SHA1(PAD(N, A) + PAD(N, B)))\n\ndef makeK(N, g):\n  return bytesToNumber(SHA1(numberToByteArray(N) + PAD(N, g)))\n\ndef createHMAC(k, digestmod=hashlib.sha1):\n    h = hmac.HMAC(k, digestmod=digestmod)\n    if not hasattr(h, 'block_size'):\n        h.block_size = digestmod().block_size\n    assert h.block_size == digestmod().block_size\n    return h\n\ndef createMAC_SSL(k, digestmod=None):\n    mac = MAC_SSL()\n    mac.create(k, digestmod=digestmod)\n    return mac\n\n\nclass MAC_SSL(object):\n    def create(self, k, digestmod=None):\n        self.digestmod = digestmod or hashlib.sha1\n        self.block_size = self.digestmod().block_size\n        # Repeat pad bytes 48 times for MD5; 40 times for other hash functions.\n        self.digest_size = 16 if (self.digestmod is hashlib.md5) else 20\n        repeat = 40 if self.digest_size == 20 else 48\n        opad = b\"\\x5C\" * repeat\n        ipad = b\"\\x36\" * repeat\n\n        self.ohash = self.digestmod(k + opad)\n        self.ihash = self.digestmod(k + ipad)\n\n    def update(self, m):\n        self.ihash.update(m)\n\n    def copy(self):\n        new = MAC_SSL()\n        new.ihash = self.ihash.copy()\n        new.ohash = self.ohash.copy()\n        new.digestmod = self.digestmod\n        new.digest_size = self.digest_size\n        new.block_size = self.block_size\n        return new\n\n    def digest(self):\n        ohash2 = self.ohash.copy()\n        ohash2.update(self.ihash.digest())\n        return bytearray(ohash2.digest())\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/messages.py",
    "content": "# Authors:\n#   Trevor Perrin\n#   Google - handling CertificateRequest.certificate_types\n#   Google (adapted by Sam Rushing and Marcelo Fernandez) - NPN support\n#   Dimitris Moraitis - Anon ciphersuites\n#   Yngve Pettersen (ported by Paul Sokolovsky) - TLS 1.2\n#   Hubert Kario - 'extensions' cleanup\n#\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Classes representing TLS messages.\"\"\"\n\nimport brotli\n\nfrom .utils.compat import *\nfrom .utils.cryptomath import *\nfrom .errors import *\nfrom .utils.codec import *\nfrom .constants import *\nfrom .x509 import X509\nfrom .x509certchain import X509CertChain\nfrom .utils.tackwrapper import *\nfrom .utils.deprecations import deprecated_attrs, deprecated_params\nfrom .extensions import *\nfrom .utils.format_output import none_as_unknown\n\n\nclass RecordHeader(object):\n    \"\"\"Generic interface to SSLv2 and SSLv3 (and later) record headers.\"\"\"\n\n    def __init__(self, ssl2):\n        \"\"\"Define instance variables.\"\"\"\n        self.type = 0\n        self.version = (0, 0)\n        self.length = 0\n        self.ssl2 = ssl2\n\n\nclass RecordHeader3(RecordHeader):\n    \"\"\"SSLv3 (and later) TLS record header.\"\"\"\n\n    def __init__(self):\n        \"\"\"Define a SSLv3 style class.\"\"\"\n        super(RecordHeader3, self).__init__(ssl2=False)\n\n    def create(self, version, type, length):\n        \"\"\"Set object values for writing (serialisation).\"\"\"\n        self.type = type\n        self.version = version\n        self.length = length\n        return self\n\n    def write(self):\n        \"\"\"Serialise object to bytearray.\"\"\"\n        writer = Writer()\n        writer.add(self.type, 1)\n        writer.add(self.version[0], 1)\n        writer.add(self.version[1], 1)\n        writer.add(self.length, 2)\n        return writer.bytes\n\n    def parse(self, parser):\n        \"\"\"Deserialise object from Parser.\"\"\"\n        self.type = parser.get(1)\n        self.version = (parser.get(1), parser.get(1))\n        self.length = parser.get(2)\n        self.ssl2 = False\n        return self\n\n    @property\n    def typeName(self):\n        matching = [x[0] for x in ContentType.__dict__.items()\n                    if x[1] == self.type]\n        if len(matching) == 0:\n            return \"unknown(\" + str(self.type) + \")\"\n        else:\n            return str(matching[0])\n\n    def __str__(self):\n        return \"SSLv3 record,version({0[0]}.{0[1]}),\"\\\n                \"content type({1}),length({2})\".format(self.version,\n                                                       self.typeName,\n                                                       self.length)\n\n    def __repr__(self):\n        return \"RecordHeader3(type={0}, version=({1[0]}.{1[1]}), length={2})\".\\\n                format(self.type, self.version, self.length)\n\n\nclass RecordHeader2(RecordHeader):\n    \"\"\"\n    SSLv2 record header.\n\n    :vartype padding: int\n    :ivar padding: number of bytes added at end of message to make it multiple\n        of block cipher size\n    :vartype securityEscape: boolean\n    :ivar securityEscape: whether the record contains a security escape message\n    \"\"\"\n\n    def __init__(self):\n        \"\"\"Define a SSLv2 style class.\"\"\"\n        super(RecordHeader2, self).__init__(ssl2=True)\n        self.padding = 0\n        self.securityEscape = False\n\n    def parse(self, parser):\n        \"\"\"Deserialise object from Parser.\"\"\"\n        firstByte = parser.get(1)\n        secondByte = parser.get(1)\n        if firstByte & 0x80:\n            self.length = ((firstByte & 0x7f) << 8) | secondByte\n        else:\n            self.length = ((firstByte & 0x3f) << 8) | secondByte\n            self.securityEscape = firstByte & 0x40 != 0\n            self.padding = parser.get(1)\n\n        self.type = ContentType.handshake\n        self.version = (2, 0)\n        return self\n\n    def create(self, length, padding=0, securityEscape=False):\n        \"\"\"Set object's values.\"\"\"\n        self.length = length\n        self.padding = padding\n        self.securityEscape = securityEscape\n        return self\n\n    def write(self):\n        \"\"\"Serialise object to bytearray.\"\"\"\n        writer = Writer()\n\n        shortHeader = not (self.padding or self.securityEscape)\n\n        if ((shortHeader and self.length >= 0x8000) or\n                (not shortHeader and self.length >= 0x4000)):\n            raise ValueError(\"length too large\")\n\n        firstByte = 0\n        if shortHeader:\n            firstByte |= 0x80\n        if self.securityEscape:\n            firstByte |= 0x40\n        firstByte |= self.length >> 8\n        secondByte = self.length & 0xff\n\n        writer.add(firstByte, 1)\n        writer.add(secondByte, 1)\n        if not shortHeader:\n            writer.add(self.padding, 1)\n\n        return writer.bytes\n\n\nclass Message(object):\n    \"\"\"Generic TLS message.\"\"\"\n\n    def __init__(self, contentType, data):\n        \"\"\"\n        Initialize object with specified contentType and data.\n\n        :type contentType: int\n        :param contentType: TLS record layer content type of associated data\n        :type data: bytearray\n        :param data: data\n        \"\"\"\n        self.contentType = contentType\n        self.data = data\n\n    def write(self):\n        \"\"\"Return serialised object data.\"\"\"\n        return self.data\n\n\nclass Alert(object):\n    def __init__(self):\n        self.contentType = ContentType.alert\n        self.level = 0\n        self.description = 0\n\n    def create(self, description, level=AlertLevel.fatal):\n        self.level = level\n        self.description = description\n        return self\n\n    def parse(self, p):\n        p.setLengthCheck(2)\n        self.level = p.get(1)\n        self.description = p.get(1)\n        p.stopLengthCheck()\n        return self\n\n    def write(self):\n        w = Writer()\n        w.add(self.level, 1)\n        w.add(self.description, 1)\n        return w.bytes\n\n    @property\n    def levelName(self):\n        return none_as_unknown(AlertLevel.toRepr(self.level),\n                             self.level)\n\n    @property\n    def descriptionName(self):\n        return none_as_unknown(AlertDescription.toRepr(self.description),\n                             self.description)\n\n    def __str__(self):\n        return \"Alert, level:{0}, description:{1}\".format(self.levelName,\n                                                          self.descriptionName)\n\n    def __repr__(self):\n        return \"Alert(level={0}, description={1})\".format(self.level,\n                                                          self.description)\n\n\nclass HandshakeMsg(object):\n    def __init__(self, handshakeType):\n        self.contentType = ContentType.handshake\n        self.handshakeType = handshakeType\n\n    def __eq__(self, other):\n        \"\"\"Check if other object represents the same data as this object.\"\"\"\n        if hasattr(self, \"write\") and hasattr(other, \"write\"):\n            return self.write() == other.write()\n        else:\n            return False\n\n    def __ne__(self, other):\n        \"\"\"Check if other object represents different data as this object.\"\"\"\n        return not self.__eq__(other)\n\n    def postWrite(self, w):\n        headerWriter = Writer()\n        headerWriter.add(self.handshakeType, 1)\n        headerWriter.add(len(w.bytes), 3)\n        return headerWriter.bytes + w.bytes\n\n\nclass HelloMessage(HandshakeMsg):\n    \"\"\"\n    Class for sharing code between :py:class:`ClientHello` and\n    :py:class:`ServerHello`.\n    \"\"\"\n\n    def __init__(self, *args, **kwargs):\n        \"\"\"Initialize object.\"\"\"\n        super(HelloMessage, self).__init__(*args, **kwargs)\n        self.extensions = None\n\n    def getExtension(self, extType):\n        \"\"\"\n        Return extension of given type if present, None otherwise.\n\n        :rtype: ~tlslite.extensions.TLSExtension\n        :raises TLSInternalError: when there are multiple extensions of the\n            same type\n        \"\"\"\n        if self.extensions is None:\n            return None\n\n        exts = [ext for ext in self.extensions if ext.extType == extType]\n        if len(exts) > 1:\n            raise TLSInternalError(\n                \"Multiple extensions of the same type present\")\n        elif len(exts) == 1:\n            return exts[0]\n        else:\n            return None\n\n    def addExtension(self, ext):\n        \"\"\"\n        Add extension to internal list of extensions.\n\n        :type ext: TLSExtension\n        :param ext: extension object to add to list\n        \"\"\"\n        if self.extensions is None:\n            self.extensions = []\n\n        self.extensions.append(ext)\n\n    def _addExt(self, extType):\n        \"\"\"Add en empty extension of given type, if not already present\"\"\"\n        ext = self.getExtension(extType)\n        if ext is None:\n            ext = TLSExtension(extType=extType).create(bytearray(0))\n            self.addExtension(ext)\n\n    def _removeExt(self, extType):\n        \"\"\"Remove extension of given type\"\"\"\n        if self.extensions is not None:\n            self.extensions[:] = (i for i in self.extensions\n                                  if i.extType != extType)\n\n\n    def _addOrRemoveExt(self, extType, add):\n        \"\"\"\n        Remove or add an empty extension of given type.\n\n        :type extType: int\n        :param extType: numeric id of extension to add or remove\n        :type add: boolean\n        :param add: whether to add (True) or remove (False) the extension\n        \"\"\"\n        if add:\n            self._addExt(extType)\n        else:\n            self._removeExt(extType)\n\n\nclass ClientHello(HelloMessage):\n    \"\"\"\n    Class for handling the ClientHello SSLv2/SSLv3/TLS message.\n\n    :vartype certificate_types: list\n    :ivar certificate_types: list of supported certificate types\n        (deprecated)\n    :vartype srp_username: bytearray\n    :ivar srp_username: name of the user in SRP extension (deprecated)\n\n    :vartype ~.supports_npn: boolean\n    :ivar ~.supports_npn: NPN extension presence (deprecated)\n\n    :vartype ~.tack: boolean\n    :ivar ~.tack: TACK extension presence (deprecated)\n\n    :vartype ~.server_name: bytearray\n    :ivar ~.server_name: first host_name (type 0) present in SNI extension\n        (deprecated)\n\n    :vartype extensions: list of :py:class:`TLSExtension`\n    :ivar extensions: list of TLS extensions parsed from wire or to send, see\n        :py:class:`TLSExtension` and child classes for exact examples\n    \"\"\"\n\n    def __init__(self, ssl2=False):\n        super(ClientHello, self).__init__(HandshakeType.client_hello)\n        self.ssl2 = ssl2\n        self.client_version = (0, 0)\n        self.random = bytearray(32)\n        self.session_id = bytearray(0)\n        self.cipher_suites = []         # a list of 16-bit values\n        self.compression_methods = []   # a list of 8-bit values\n\n    def __str__(self):\n        \"\"\"\n        Return human readable representation of Client Hello.\n\n        :rtype: str\n        \"\"\"\n        if self.session_id.count(bytearray(b'\\x00')) == len(self.session_id)\\\n                and len(self.session_id) != 0:\n            session = \"bytearray(b'\\\\x00'*{0})\".format(len(self.session_id))\n        else:\n            session = repr(self.session_id)\n        ret = \"client_hello,version({0[0]}.{0[1]}),random(...),\"\\\n              \"session ID({1!s}),cipher suites({2!r}),\"\\\n              \"compression methods({3!r})\".format(\n                  self.client_version, session,\n                  self.cipher_suites, self.compression_methods)\n\n        if self.extensions is not None:\n            ret += \",extensions({0!r})\".format(self.extensions)\n\n        return ret\n\n    def __repr__(self):\n        \"\"\"\n        Return machine readable representation of Client Hello.\n\n        :rtype: str\n        \"\"\"\n        return \"ClientHello(ssl2={0}, client_version=({1[0]}.{1[1]}), \"\\\n               \"random={2!r}, session_id={3!r}, cipher_suites={4!r}, \"\\\n               \"compression_methods={5}, extensions={6})\".format(\n                   self.ssl2, self.client_version, self.random,\n                   self.session_id, self.cipher_suites,\n                   self.compression_methods, self.extensions)\n\n    @property\n    def certificate_types(self):\n        \"\"\"\n        Return the list of certificate types supported.\n\n        .. deprecated:: 0.5\n            use extensions field to get the extension for inspection\n        \"\"\"\n        cert_type = self.getExtension(ExtensionType.cert_type)\n        if cert_type is None:\n            # XXX backwards compatibility: TLSConnection\n            # depends on a default value of this property\n            return [CertificateType.x509]\n        else:\n            return cert_type.certTypes\n\n    @certificate_types.setter\n    def certificate_types(self, val):\n        \"\"\"\n        Set list of supported certificate types.\n\n        Sets the list of supported types to list given in :py:obj:`val` if the\n        cert_type extension is present. Creates the extension and places it\n        last in the list otherwise.\n\n        :type val: list\n        :param val: list of supported certificate types by client encoded as\n            single byte integers\n        \"\"\"\n        cert_type = self.getExtension(ExtensionType.cert_type)\n\n        if cert_type is None:\n            ext = ClientCertTypeExtension().create(val)\n            self.addExtension(ext)\n        else:\n            cert_type.certTypes = val\n\n    @property\n    def srp_username(self):\n        \"\"\"\n        Return username for the SRP.\n\n        .. deprecated:: 0.5\n            use extensions field to get the extension for inspection\n        \"\"\"\n        srp_ext = self.getExtension(ExtensionType.srp)\n\n        if srp_ext is None:\n            return None\n        else:\n            return srp_ext.identity\n\n    @srp_username.setter\n    def srp_username(self, name):\n        \"\"\"\n        Set the username for SRP.\n\n        :type name: bytearray\n        :param name: UTF-8 encoded username\n        \"\"\"\n        srp_ext = self.getExtension(ExtensionType.srp)\n\n        if srp_ext is None:\n            ext = SRPExtension().create(name)\n            self.addExtension(ext)\n        else:\n            srp_ext.identity = name\n\n    @property\n    def tack(self):\n        \"\"\"\n        Return whether the client supports TACK.\n\n        .. deprecated:: 0.5\n            use extensions field to get the extension for inspection\n\n        :rtype: boolean\n        \"\"\"\n        return self.getExtension(ExtensionType.tack) is not None\n\n    @tack.setter\n    def tack(self, present):\n        \"\"\"\n        Create or delete the TACK extension.\n\n        :type present: boolean\n        :param present: True will create extension while False will remove\n            extension from client hello\n        \"\"\"\n        self._addOrRemoveExt(ExtensionType.tack, present)\n\n    @property\n    def supports_npn(self):\n        \"\"\"\n        Return whether client supports NPN extension.\n\n        .. deprecated:: 0.5\n            use extensions field to get the extension for inspection\n\n        :rtype: boolean\n        \"\"\"\n        return self.getExtension(ExtensionType.supports_npn) is not None\n\n    @supports_npn.setter\n    def supports_npn(self, present):\n        \"\"\"\n        Create or delete the NPN extension.\n\n        :type present: boolean\n        :param present: selects whatever to create or remove the extension\n            from list of supported ones\n        \"\"\"\n        self._addOrRemoveExt(ExtensionType.supports_npn, present)\n\n    @property\n    def server_name(self):\n        \"\"\"\n        Return first host_name present in SNI extension.\n\n        .. deprecated:: 0.5\n            use extensions field to get the extension for inspection\n\n        :rtype: bytearray\n        \"\"\"\n        sni_ext = self.getExtension(ExtensionType.server_name)\n        if sni_ext is None:\n            return bytearray(0)\n        else:\n            if len(sni_ext.hostNames) > 0:\n                return sni_ext.hostNames[0]\n            else:\n                return bytearray(0)\n\n    @server_name.setter\n    def server_name(self, hostname):\n        \"\"\"\n        Set the first host_name present in SNI extension.\n\n        :type hostname: bytearray\n        :param hostname: name of the host_name to set\n        \"\"\"\n        sni_ext = self.getExtension(ExtensionType.server_name)\n        # if sni_ext is None:\n        #     sni_ext = SNIExtension().create(hostname)\n        #     self.addExtension(sni_ext)\n        # else:\n        #     names = list(sni_ext.hostNames)\n        #     names[0] = hostname\n        #     sni_ext.hostNames = names\n\n    def create(self, version, random, session_id, cipher_suites,\n               certificate_types=None, srpUsername=None,\n               tack=False, supports_npn=None, serverName=None,\n               extensions=None):\n        \"\"\"\n        Create a ClientHello message for sending.\n\n        :type version: tuple\n        :param version: the highest supported TLS version encoded as two int\n            tuple\n\n        :type random: bytearray\n        :param random: client provided random value, in old versions of TLS\n            (before 1.2) the first 32 bits should include system time, also\n            used as the \"challenge\" field in SSLv2\n\n        :type session_id: bytearray\n        :param session_id: ID of session, set when doing session resumption\n\n        :type cipher_suites: list\n        :param cipher_suites: list of ciphersuites advertised as supported\n\n        :type certificate_types: list\n        :param certificate_types: list of supported certificate types, uses\n            TLS extension for signalling, as such requires TLS1.0 to work\n\n        :type srpUsername: bytearray\n        :param srpUsername: utf-8 encoded username for SRP, TLS extension\n\n        :type tack: boolean\n        :param tack: whatever to advertise support for TACK, TLS extension\n\n        :type supports_npn: boolean\n        :param supports_npn: whatever to advertise support for NPN, TLS\n            extension\n\n        :type serverName: bytearray\n        :param serverName: the hostname to request in server name indication\n            extension, TLS extension. Note that SNI allows to set multiple\n            hostnames and values that are not hostnames, use\n            :py:class:`~.extensions.SNIExtension`\n            together with :py:obj:`extensions` to use it.\n\n        :type extensions: list of :py:class:`~.extensions.TLSExtension`\n        :param extensions: list of extensions to advertise\n        \"\"\"\n        self.client_version = version\n        self.random = random\n        self.session_id = session_id\n        self.cipher_suites = cipher_suites\n        self.compression_methods = [0]\n        if extensions is not None:\n            self.extensions = extensions\n        if certificate_types is not None:\n            self.certificate_types = certificate_types\n        if srpUsername is not None:\n            if not isinstance(srpUsername, bytearray):\n                raise TypeError(\"srpUsername must be a bytearray object\")\n            self.srp_username = srpUsername\n        self.tack = tack\n        if supports_npn is not None:\n            self.supports_npn = supports_npn\n        # if serverName is not None:\n        #     self.server_name = bytearray(serverName, \"utf-8\")\n        return self\n\n    def parse(self, p):\n        \"\"\"Deserialise object from on the wire data.\"\"\"\n        if self.ssl2:\n            self.client_version = (p.get(1), p.get(1))\n            cipherSpecsLength = p.get(2)\n            sessionIDLength = p.get(2)\n            randomLength = p.get(2)\n            p.setLengthCheck(cipherSpecsLength +\n                             sessionIDLength +\n                             randomLength)\n            self.cipher_suites = p.getFixList(3, cipherSpecsLength//3)\n            self.session_id = p.getFixBytes(sessionIDLength)\n            self.random = p.getFixBytes(randomLength)\n            if len(self.random) < 32:\n                zeroBytes = 32-len(self.random)\n                self.random = bytearray(zeroBytes) + self.random\n            self.compression_methods = [0]  # Fake this value\n            p.stopLengthCheck()\n        else:\n            p.startLengthCheck(3)\n            self.client_version = (p.get(1), p.get(1))\n            self.random = p.getFixBytes(32)\n            self.session_id = p.getVarBytes(1)\n            self.cipher_suites = p.getVarList(2, 2)\n            self.compression_methods = p.getVarList(1, 1)\n            if not p.atLengthCheck():\n                self.extensions = []\n                totalExtLength = p.get(2)\n                p2 = Parser(p.getFixBytes(totalExtLength))\n                while p2.getRemainingLength() > 0:\n                    ext = TLSExtension().parse(p2)\n                    self.extensions += [ext]\n            p.stopLengthCheck()\n        return self\n\n    def _writeSSL2(self):\n        \"\"\"Serialise SSLv2 object to on the wire data.\"\"\"\n        writer = Writer()\n        writer.add(self.handshakeType, 1)\n        writer.add(self.client_version[0], 1)\n        writer.add(self.client_version[1], 1)\n\n        ciphersWriter = Writer()\n        ciphersWriter.addFixSeq(self.cipher_suites, 3)\n\n        writer.add(len(ciphersWriter.bytes), 2)\n        writer.add(len(self.session_id), 2)\n        writer.add(len(self.random), 2)\n\n        writer.bytes += ciphersWriter.bytes\n        writer.bytes += self.session_id\n        writer.bytes += self.random\n\n        # postWrite() is necessary only for SSLv3/TLS\n        return writer.bytes\n\n    def _write(self):\n        \"\"\"Serialise SSLv3 or TLS object to on the wire data.\"\"\"\n        w = Writer()\n        w.add(self.client_version[0], 1)\n        w.add(self.client_version[1], 1)\n        w.bytes += self.random\n        w.addVarSeq(self.session_id, 1, 1)\n        w.addVarSeq(self.cipher_suites, 2, 2)\n        w.addVarSeq(self.compression_methods, 1, 1)\n\n        if self.extensions is not None:\n            w2 = Writer()\n            for ext in self.extensions:\n                w2.bytes += ext.write()\n\n            w.add(len(w2.bytes), 2)\n            w.bytes += w2.bytes\n        return self.postWrite(w)\n\n    def psk_truncate(self):\n        \"\"\"Return a truncated encoding of message without binders.\n\n        In TLS 1.3, with PSK exchange, the ClientHello message is signed\n        by the binders in it. Return the part that is symmetrically signed\n        by those binders.\n\n        See \"PSK Binder\" in draft-ietf-tls-tls13-23.\n\n        :rtype: bytearray\n        \"\"\"\n        ext = self.extensions[-1]\n        if not isinstance(ext, PreSharedKeyExtension):\n            raise ValueError(\"Last extension must be the pre_shared_key \"\n                             \"extension\")\n        bts = self.write()\n        # every binder has 1 byte long header and the list of them\n        # has a 2 byte header\n        length = sum(len(i) + 1 for i in ext.binders) + 2\n\n        return bts[:-length]\n\n\n    def write(self):\n        \"\"\"Serialise object to on the wire data.\"\"\"\n        if self.ssl2:\n            return self._writeSSL2()\n        else:\n            return self._write()\n\n\nclass HelloRequest(HandshakeMsg):\n    \"\"\"\n    Handling of Hello Request messages.\n    \"\"\"\n\n    def __init__(self):\n        super(HelloRequest, self).__init__(HandshakeType.hello_request)\n\n    def create(self):\n        return self\n\n    def write(self):\n        return self.postWrite(Writer())\n\n    def parse(self, parser):\n        # verify that the message is empty (the buffer will just contain\n        # the length from header)\n        parser.startLengthCheck(3)\n        parser.stopLengthCheck()\n        return self\n\n\nclass ServerHello(HelloMessage):\n    \"\"\"\n    Handling of Server Hello messages.\n\n    :vartype server_version: tuple\n    :ivar server_version: protocol version encoded as two int tuple\n\n    :vartype random: bytearray\n    :ivar random: server random value\n\n    :vartype session_id: bytearray\n    :ivar session_id: session identifier for resumption\n\n    :vartype cipher_suite: int\n    :ivar cipher_suite: server selected cipher_suite\n\n    :vartype compression_method: int\n    :ivar compression_method: server selected compression method\n\n    :vartype next_protos: list of bytearray\n    :ivar next_protos: list of advertised protocols in NPN extension\n\n    :vartype next_protos_advertised: list of bytearray\n    :ivar next_protos_advertised: list of protocols advertised in NPN extension\n\n    :vartype certificate_type: int\n    :ivar certificate_type: certificate type selected by server\n\n    :vartype extensions: list\n    :ivar extensions: list of TLS extensions present in server_hello message,\n        see :py:class:`~.extensions.TLSExtension` and child classes for exact\n        examples\n    \"\"\"\n\n    def __init__(self):\n        \"\"\"Initialise ServerHello object.\"\"\"\n        super(ServerHello, self).__init__(HandshakeType.server_hello)\n        self.server_version = (0, 0)\n        self.random = bytearray(32)\n        self.session_id = bytearray(0)\n        self.cipher_suite = 0\n        self.compression_method = 0\n        self._tack_ext = None\n\n    def __str__(self):\n        base = \"server_hello,length({0}),version({1[0]}.{1[1]}),random(...),\"\\\n                \"session ID({2!r}),cipher({3:#x}),compression method({4})\"\\\n                .format(len(self.write())-4, self.server_version,\n                        self.session_id, self.cipher_suite,\n                        self.compression_method)\n\n        if self.extensions is None:\n            return base\n\n        ret = \",extensions[\"\n        ret += \",\".join(repr(x) for x in self.extensions)\n        ret += \"]\"\n        return base + ret\n\n    def __repr__(self):\n        return \"ServerHello(server_version=({0[0]}, {0[1]}), random={1!r}, \"\\\n                \"session_id={2!r}, cipher_suite={3}, compression_method={4}, \"\\\n                \"_tack_ext={5}, extensions={6!r})\".format(\n                    self.server_version, self.random, self.session_id,\n                    self.cipher_suite, self.compression_method, self._tack_ext,\n                    self.extensions)\n\n    @property\n    def tackExt(self):\n        \"\"\"Return the TACK extension.\"\"\"\n        if self._tack_ext is None:\n            ext = self.getExtension(ExtensionType.tack)\n            if ext is None or not tackpyLoaded:\n                return None\n            else:\n                self._tack_ext = TackExtension(ext.extData)\n        return self._tack_ext\n\n    @tackExt.setter\n    def tackExt(self, val):\n        \"\"\"Set the TACK extension.\"\"\"\n        self._tack_ext = val\n        # makes sure that extensions are included in the on the wire encoding\n        if val is not None:\n            if self.extensions is None:\n                self.extensions = []\n\n    @property\n    def certificate_type(self):\n        \"\"\"\n        Return the certificate type selected by server.\n\n        :rtype: int\n        \"\"\"\n        cert_type = self.getExtension(ExtensionType.cert_type)\n        if cert_type is None:\n            # XXX backwards compatibility, TLSConnection expects the default\n            # value to be that\n            return CertificateType.x509\n        return cert_type.cert_type\n\n    @certificate_type.setter\n    def certificate_type(self, val):\n        \"\"\"\n        Set the certificate type supported.\n\n        :type val: int\n        :param val: type of certificate\n        \"\"\"\n        if val == CertificateType.x509 or val is None:\n            # XXX backwards compatibility, x509 value should not be sent\n            self._removeExt(ExtensionType.cert_type)\n            return\n\n        cert_type = self.getExtension(ExtensionType.cert_type)\n        if cert_type is None:\n            ext = ServerCertTypeExtension().create(val)\n            self.addExtension(ext)\n        else:\n            cert_type.cert_type = val\n\n    @property\n    def next_protos(self):\n        \"\"\"\n        Return the advertised protocols in NPN extension.\n\n        :rtype: list of bytearrays\n        \"\"\"\n        npn_ext = self.getExtension(ExtensionType.supports_npn)\n\n        if npn_ext is None:\n            return None\n        else:\n            return npn_ext.protocols\n\n    @next_protos.setter\n    def next_protos(self, val):\n        \"\"\"\n        Set the advertised protocols in NPN extension.\n\n        :type val: list\n        :param val: list of protocols to advertise as UTF-8 encoded names\n        \"\"\"\n        if val is None:\n            # XXX: do not send empty extension\n            self._removeExt(ExtensionType.supports_npn)\n            return\n        else:\n            # convinience function, make sure the values are properly encoded\n            val = [bytearray(x) for x in val]\n\n        npn_ext = self.getExtension(ExtensionType.supports_npn)\n\n        if npn_ext is None:\n            ext = NPNExtension().create(val)\n            self.addExtension(ext)\n        else:\n            npn_ext.protocols = val\n\n    @property\n    def next_protos_advertised(self):\n        \"\"\"\n        Return the advertised protocols in NPN extension.\n\n        :rtype: list of bytearrays\n        \"\"\"\n        return self.next_protos\n\n    @next_protos_advertised.setter\n    def next_protos_advertised(self, val):\n        \"\"\"\n        Set the advertised protocols in NPN extension.\n\n        :type val: list\n        :param val: list of protocols to advertise as UTF-8 encoded names\n        \"\"\"\n        self.next_protos = val\n\n    def create(self, version, random, session_id, cipher_suite,\n               certificate_type=None, tackExt=None,\n               next_protos_advertised=None,\n               extensions=None):\n        \"\"\"Initialize the object for deserialisation.\"\"\"\n        self.extensions = extensions\n        self.server_version = version\n        self.random = random\n        self.session_id = session_id\n        self.cipher_suite = cipher_suite\n        self.certificate_type = certificate_type\n        self.compression_method = 0\n        if tackExt is not None:\n            self.tackExt = tackExt\n        self.next_protos_advertised = next_protos_advertised\n        return self\n\n    def parse(self, p):\n        p.startLengthCheck(3)\n        self.server_version = (p.get(1), p.get(1))\n        self.random = p.getFixBytes(32)\n        self.session_id = p.getVarBytes(1)\n        self.cipher_suite = p.get(2)\n        self.compression_method = p.get(1)\n        if not p.atLengthCheck():\n            self.extensions = []\n            totalExtLength = p.get(2)\n            p2 = Parser(p.getFixBytes(totalExtLength))\n            while p2.getRemainingLength() > 0:\n                if self.random == TLS_1_3_HRR:\n                    ext = TLSExtension(hrr=True).parse(p2)\n                else:\n                    ext = TLSExtension(server=True).parse(p2)\n                self.extensions += [ext]\n        p.stopLengthCheck()\n        return self\n\n    def write(self):\n        w = Writer()\n        w.add(self.server_version[0], 1)\n        w.add(self.server_version[1], 1)\n        w.bytes += self.random\n        w.addVarSeq(self.session_id, 1, 1)\n        w.add(self.cipher_suite, 2)\n        w.add(self.compression_method, 1)\n\n        if self.extensions is not None:\n            w2 = Writer()\n            for ext in self.extensions:\n                w2.bytes += ext.write()\n\n            if self.tackExt:\n                b = self.tackExt.serialize()\n                w2.add(ExtensionType.tack, 2)\n                w2.add(len(b), 2)\n                w2.bytes += b\n\n            w.add(len(w2.bytes), 2)\n            w.bytes += w2.bytes\n        return self.postWrite(w)\n\n\nclass ServerHello2(HandshakeMsg):\n    \"\"\"\n    SERVER-HELLO message from SSLv2.\n\n    :vartype session_id_hit: int\n    :ivar session_id_hit: non zero if the client provided session ID was\n        matched in server's session cache\n\n    :vartype certificate_type: int\n    :ivar certificate_type: type of certificate sent\n\n    :vartype server_version: tuple of ints\n    :ivar server_version: protocol version selected by server\n\n    :vartype certificate: bytearray\n    :ivar certificate: certificate sent by server\n\n    :vartype ciphers: array of int\n    :ivar ciphers: list of ciphers supported by server\n\n    :vartype session_id: bytearray\n    :ivar session_id: idendifier of negotiated session\n    \"\"\"\n\n    def __init__(self):\n        super(ServerHello2, self).__init__(SSL2HandshakeType.server_hello)\n        self.session_id_hit = 0\n        self.certificate_type = 0\n        self.server_version = (0, 0)\n        self.certificate = bytearray(0)\n        self.ciphers = []\n        self.session_id = bytearray(0)\n\n    def create(self, session_id_hit, certificate_type, server_version,\n               certificate, ciphers, session_id):\n        \"\"\"Initialize fields of the SERVER-HELLO message.\"\"\"\n        self.session_id_hit = session_id_hit\n        self.certificate_type = certificate_type\n        self.server_version = server_version\n        self.certificate = certificate\n        self.ciphers = ciphers\n        self.session_id = session_id\n        return self\n\n    def write(self):\n        \"\"\"Serialise object to on the wire data.\"\"\"\n        writer = Writer()\n        writer.add(self.handshakeType, 1)\n        writer.add(self.session_id_hit, 1)\n        writer.add(self.certificate_type, 1)\n        if len(self.server_version) != 2:\n            raise ValueError(\"server version must be a 2-element tuple\")\n        writer.addFixSeq(self.server_version, 1)\n        writer.add(len(self.certificate), 2)\n\n        ciphersWriter = Writer()\n        ciphersWriter.addFixSeq(self.ciphers, 3)\n\n        writer.add(len(ciphersWriter.bytes), 2)\n        writer.add(len(self.session_id), 2)\n\n        writer.bytes += self.certificate\n        writer.bytes += ciphersWriter.bytes\n        writer.bytes += self.session_id\n\n        # postWrite() is necessary only for SSLv3/TLS\n        return writer.bytes\n\n    def parse(self, parser):\n        \"\"\"Deserialise object from on the wire data.\"\"\"\n        self.session_id_hit = parser.get(1)\n        self.certificate_type = parser.get(1)\n        self.server_version = (parser.get(1), parser.get(1))\n        certificateLength = parser.get(2)\n        ciphersLength = parser.get(2)\n        sessionIDLength = parser.get(2)\n        parser.setLengthCheck(certificateLength +\n                              ciphersLength +\n                              sessionIDLength)\n        self.certificate = parser.getFixBytes(certificateLength)\n        self.ciphers = parser.getFixList(3, ciphersLength // 3)\n        self.session_id = parser.getFixBytes(sessionIDLength)\n        parser.stopLengthCheck()\n        return self\n\n\nclass CertificateEntry(object):\n    \"\"\"\n    Object storing a single certificate from TLS 1.3.\n\n    Stores a certificate (or possibly a raw public key) together with\n    associated extensions\n    \"\"\"\n\n    def __init__(self, certificateType):\n        \"\"\"Initialise the object for given certificate type.\"\"\"\n        self.certificateType = certificateType\n        self.certificate = None\n        self.extensions = None\n\n    def create(self, certificate, extensions):\n        \"\"\"Set all values of the certificate entry.\"\"\"\n        self.certificate = certificate\n        self.extensions = extensions\n        return self\n\n    def write(self):\n        \"\"\"Serialise the object.\"\"\"\n        writer = Writer()\n        if self.certificateType == CertificateType.x509:\n            writer.addVarSeq(self.certificate.writeBytes(), 1, 3)\n        else:\n            raise ValueError(\"Set certificate type ({0}) unsupported\"\n                             .format(self.certificateType))\n\n        if self.extensions is not None:\n            writer2 = Writer()\n            for ext in self.extensions:\n                writer2.bytes += ext.write()\n            writer.addVarSeq(writer2.bytes, 1, 2)\n\n        return writer.bytes\n\n    def parse(self, parser):\n        \"\"\"Deserialise the object from on the wire data.\"\"\"\n        if self.certificateType == CertificateType.x509:\n            certBytes = parser.getVarBytes(3)\n            x509 = X509()\n            x509.parseBinary(certBytes)\n            self.certificate = x509\n        else:\n            raise ValueError(\"Set certificate type ({0}) unsupported\"\n                             .format(self.certificateType))\n\n        self.extensions = []\n        parser.startLengthCheck(2)\n        while not parser.atLengthCheck():\n            ext = TLSExtension(cert=True).parse(parser)\n            self.extensions.append(ext)\n        parser.stopLengthCheck()\n        return self\n\n    def __repr__(self):\n        return \"CertificateEntry(certificate={0!r}, extensions={1!r})\".format(\n                self.certificate, self.extensions)\n\n\n@deprecated_attrs({\"cert_chain\": \"certChain\"})\nclass Certificate(HandshakeMsg):\n    def __init__(self, certificateType, version=(3, 2)):\n        HandshakeMsg.__init__(self, HandshakeType.certificate)\n        self.certificateType = certificateType\n        self._cert_chain = None\n        self.version = version\n        self.certificate_list = []\n        self.certificate_request_context = None\n\n    @property\n    def cert_chain(self):\n        \"\"\"Getter for the cert_chain property.\"\"\"\n        if self._cert_chain:\n            return self._cert_chain\n        elif self.certificate_list:\n            return X509CertChain([i.certificate\n                                  for i in self.certificate_list])\n        else:\n            return None\n\n    @cert_chain.setter\n    def cert_chain(self, cert_chain):\n        \"\"\"Setter for the cert_chain property.\"\"\"\n        if isinstance(cert_chain, X509CertChain):\n            self._cert_chain = cert_chain\n            self.certificate_list = [CertificateEntry(self.certificateType)\n                                     .create(i, []) for i\n                                     in cert_chain.x509List]\n        elif cert_chain is None:\n            self.certificate_list = []\n        else:\n            self.certificate_list = cert_chain\n\n    @deprecated_params({\"cert_chain\": \"certChain\"})\n    def create(self, cert_chain, context=b''):\n        \"\"\"Initialise fields of the class.\"\"\"\n        self.cert_chain = cert_chain\n        self.certificate_request_context = context\n        return self\n\n    def _parse_certificate_list(self, parser):\n        self.certificate_list = []\n        while parser.getRemainingLength():\n            entry = CertificateEntry(self.certificateType)\n            self.certificate_list.append(entry.parse(parser))\n\n    def _parse_tls13(self, parser):\n        parser.startLengthCheck(3)\n        self.certificate_request_context = parser.getVarBytes(1)\n        self._parse_certificate_list(Parser(parser.getVarBytes(3)))\n        parser.stopLengthCheck()\n        return self\n\n    def _parse_tls12(self, p):\n        p.startLengthCheck(3)\n        if self.certificateType == CertificateType.x509:\n            chainLength = p.get(3)\n            index = 0\n            certificate_list = []\n            while index != chainLength:\n                certBytes = p.getVarBytes(3)\n                if not certBytes:\n                    raise DecodeError(\"Client certificate is empty\")\n                x509 = X509()\n                try:\n                    x509.parseBinary(certBytes)\n                except SyntaxError:\n                    raise BadCertificateError(\"Certificate could not be parsed\")\n                certificate_list.append(x509)\n                index += len(certBytes)+3\n            if certificate_list:\n                self._cert_chain = X509CertChain(certificate_list)\n        else:\n            raise AssertionError()\n\n        p.stopLengthCheck()\n        return self\n\n    def parse(self, p):\n        if self.version <= (3, 3):\n            return self._parse_tls12(p)\n        else:\n            return self._parse_tls13(p)\n\n    def _write_tls13(self):\n        w = Writer()\n        w.addVarSeq(self.certificate_request_context, 1, 1)\n        w2 = Writer()\n        for entry in self.certificate_list:\n            w2.bytes += entry.write()\n        w.addVarSeq(w2.bytes, 1, 3)\n        return w\n\n    def _write_tls12(self):\n        w = Writer()\n        if self.certificateType == CertificateType.x509:\n            chainLength = 0\n            if self._cert_chain:\n                certificate_list = self._cert_chain.x509List\n            else:\n                certificate_list = []\n            # determine length\n            for cert in certificate_list:\n                bytes = cert.writeBytes()\n                chainLength += len(bytes)+3\n            # add bytes\n            w.add(chainLength, 3)\n            for cert in certificate_list:\n                bytes = cert.writeBytes()\n                w.addVarSeq(bytes, 1, 3)\n        else:\n            raise AssertionError()\n        return w\n\n    def write(self):\n        if self.version <= (3, 3):\n            writer = self._write_tls12()\n        else:\n            writer = self._write_tls13()\n        return self.postWrite(writer)\n\n    def __repr__(self):\n        if self.version <= (3, 3):\n            return \"Certificate(cert_chain={0!r})\"\\\n                   .format(self.cert_chain.x509List)\n        return \"Certificate(request_context={0!r}, \"\\\n               \"certificate_list={1!r})\"\\\n               .format(self.certificate_request_context,\n                       self.certificate_list)\n\n\nclass CompressedCertificate(Certificate):\n    def __init__(self, certificateType, version=(3, 2)):\n        HandshakeMsg.__init__(self, HandshakeType.compressed_certificate)\n        self.certificateType = certificateType\n        self._cert_chain = None\n        self.version = version\n        self.certificate_list = []\n        self.certificate_request_context = None\n\n    def parse(self, p):\n        if self.version <= (3, 3):\n            raise AssertionError()\n\n        return self._parse_compress(p)\n\n    def _parse_compress(self, parser):\n        parser.startLengthCheck(3)\n        CertificateCompressionAlgorithm = bytes_to_int(parser.getFixBytes(2), \"big\")\n        if CertificateCompressionAlgorithm != 2:\n            raise AssertionError()\n\n        uncompressed_length = bytes_to_int(parser.getFixBytes(3), \"big\")\n        compressed_length = bytes_to_int(parser.getFixBytes(3), \"big\")\n        compressed_content = parser.getFixBytes(compressed_length)\n        parser.stopLengthCheck()\n\n        compressed_content = bytes(compressed_content)\n        decompressed_content = brotli.decompress(compressed_content)\n        if len(decompressed_content) != uncompressed_length:\n            raise AssertionError()\n\n        p2 = Parser(decompressed_content)\n        self._parse_tls13(p2)\n        return self\n\n    def _parse_tls13(self, parser):\n        self.certificate_request_context = parser.getVarBytes(1)\n        self._parse_certificate_list(Parser(parser.getVarBytes(3)))\n        return self\n\n\nclass CertificateRequest(HelloMessage):\n    def __init__(self, version):\n        super(CertificateRequest, self).__init__(\n                HandshakeType.certificate_request)\n        self.certificate_types = []\n        self.certificate_authorities = []\n        self.version = version\n        self.certificate_request_context = b''\n        self.extensions = None\n\n    @property\n    def supported_signature_algs(self):\n        \"\"\"\n        Returns the list of supported algorithms.\n\n        We store the list in an extension even for TLS < 1.3\n        Extensions are used/valid only for TLS 1.3 but they are a good\n        unified storage mechanism for all versions.\n        \"\"\"\n        ext = self.getExtension(ExtensionType.signature_algorithms)\n        if ext:\n            return ext.sigalgs\n        return None\n\n    @supported_signature_algs.setter\n    def supported_signature_algs(self, val):\n        self._removeExt(ExtensionType.signature_algorithms)\n        if val is not None:\n            ext = SignatureAlgorithmsExtension().create(val)\n            self.addExtension(ext)\n\n    def create(self, certificate_types=None, certificate_authorities=None,\n               sig_algs=None, context=b'', extensions=None):\n        \"\"\"\n            Creates a Certificate Request message.\n            For TLS 1.3 only the context and extensions parameters should be\n            provided, the others are ignored.\n            For TLS versions below 1.3 instead only the first three parameters\n            are considered.\n        \"\"\"\n        self.certificate_types = certificate_types\n        self.certificate_authorities = certificate_authorities\n        self.certificate_request_context = context\n        self.extensions = extensions\n        # do this after setting extensions, or it will be overwritten\n        if sig_algs is not None:\n            self.supported_signature_algs = sig_algs\n        return self\n\n    def _parse_tls13(self, parser):\n        parser.startLengthCheck(3)\n        self.certificate_request_context = parser.getVarBytes(1)\n        if not parser.getRemainingLength():\n            raise SyntaxError(\"No list of extensions\")\n        else:\n            self.extensions = []\n            sub_parser = Parser(parser.getVarBytes(2))\n            while sub_parser.getRemainingLength():\n                # We care only for universal extensions so far\n                ext = TLSExtension().parse(sub_parser)\n                self.extensions.append(ext)\n\n        parser.stopLengthCheck()\n        return self\n\n    def _parse_tls12(self, p):\n        p.startLengthCheck(3)\n        self.certificate_types = p.getVarList(1, 1)\n        if self.version == (3, 3):\n            self.supported_signature_algs = p.getVarTupleList(1, 2, 2)\n        ca_list_length = p.get(2)\n        index = 0\n        self.certificate_authorities = []\n        while index != ca_list_length:\n            ca_bytes = p.getVarBytes(2)\n            self.certificate_authorities.append(ca_bytes)\n            index += len(ca_bytes)+2\n        p.stopLengthCheck()\n        return self\n\n    def parse(self, parser):\n        if self.version <= (3, 3):\n            return self._parse_tls12(parser)\n        return self._parse_tls13(parser)\n\n    def _write_tls13(self):\n        writer = Writer()\n        writer.addVarSeq(self.certificate_request_context, 1, 1)\n        sub_writer = Writer()\n        for ext in self.extensions or []:\n            sub_writer.bytes += ext.write()\n        writer.addVarSeq(sub_writer.bytes, 1, 2)\n        return writer\n\n    def _write_tls12(self):\n        w = Writer()\n        w.addVarSeq(self.certificate_types, 1, 1)\n        if self.version >= (3, 3):\n            w.addVarTupleSeq(self.supported_signature_algs, 1, 2)\n        caLength = 0\n        # determine length\n        for ca_dn in self.certificate_authorities:\n            caLength += len(ca_dn)+2\n        w.add(caLength, 2)\n        # add bytes\n        for ca_dn in self.certificate_authorities:\n            w.addVarSeq(ca_dn, 1, 2)\n        return w\n\n    def write(self):\n        if self.version <= (3, 3):\n            writer = self._write_tls12()\n        else:\n            writer = self._write_tls13()\n        return self.postWrite(writer)\n\n\nclass ServerKeyExchange(HandshakeMsg):\n    \"\"\"\n    Handling TLS Handshake protocol Server Key Exchange messages.\n\n    :vartype cipherSuite: int\n    :cvar cipherSuite: id of ciphersuite selected in Server Hello message\n    :vartype srp_N: int\n    :cvar srp_N: SRP protocol prime\n    :vartype srp_N_len: int\n    :cvar srp_N_len: length of srp_N in bytes\n    :vartype srp_g: int\n    :cvar srp_g: SRP protocol generator\n    :vartype srp_g_len: int\n    :cvar srp_g_len: length of srp_g in bytes\n    :vartype srp_s: bytearray\n    :cvar srp_s: SRP protocol salt value\n    :vartype srp_B: int\n    :cvar srp_B: SRP protocol server public value\n    :vartype srp_B_len: int\n    :cvar srp_B_len: length of srp_B in bytes\n    :vartype dh_p: int\n    :cvar dh_p: FFDHE protocol prime\n    :vartype dh_p_len: int\n    :cvar dh_p_len: length of dh_p in bytes\n    :vartype dh_g: int\n    :cvar dh_g: FFDHE protocol generator\n    :vartype dh_g_len: int\n    :cvar dh_g_len: length of dh_g in bytes\n    :vartype dh_Ys: int\n    :cvar dh_Ys: FFDH protocol server key share\n    :vartype dh_Ys_len: int\n    :cvar dh_Ys_len: length of dh_Ys in bytes\n    :vartype curve_type: int\n    :cvar curve_type: Type of curve used (explicit, named, etc.)\n    :vartype named_curve: int\n    :cvar named_curve: TLS ID of named curve\n    :vartype ecdh_Ys: bytearray\n    :cvar ecdh_Ys: ECDH protocol encoded point key share\n    :vartype signature: bytearray\n    :cvar signature: signature performed over the parameters by server\n    :vartype hashAlg: int\n    :cvar hashAlg: id of hash algorithm used for signature\n    :vartype signAlg: int\n    :cvar signAlg: id of signature algorithm used for signature\n    \"\"\"\n\n    def __init__(self, cipherSuite, version):\n        \"\"\"\n        Initialise Server Key Exchange for reading or writing.\n\n        :type cipherSuite: int\n        :param cipherSuite: id of ciphersuite selected by server\n        \"\"\"\n        HandshakeMsg.__init__(self, HandshakeType.server_key_exchange)\n        self.cipherSuite = cipherSuite\n        self.version = version\n        self.srp_N = 0\n        self.srp_N_len = None\n        self.srp_g = 0\n        self.srp_g_len = None\n        self.srp_s = bytearray(0)\n        self.srp_B = 0\n        self.srp_B_len = None\n        # Anon DH params:\n        self.dh_p = 0\n        self.dh_p_len = None\n        self.dh_g = 0\n        self.dh_g_len = None\n        self.dh_Ys = 0\n        self.dh_Ys_len = None\n        # EC settings\n        self.curve_type = None\n        self.named_curve = None\n        self.ecdh_Ys = bytearray(0)\n        # signature for certificate authenticated ciphersuites\n        self.signature = bytearray(0)\n        # signature hash algorithm and signing algorithm for TLSv1.2\n        self.hashAlg = 0\n        self.signAlg = 0\n\n    def __repr__(self):\n        ret = \"ServerKeyExchange(cipherSuite=CipherSuite.{0}, version={1}\"\\\n              \"\".format(CipherSuite.ietfNames[self.cipherSuite], self.version)\n\n        if self.srp_N != 0:\n            ret += \", srp_N={0}, srp_g={1}, srp_s={2!r}, srp_B={3}\".format(\n                self.srp_N, self.srp_g, self.srp_s, self.srp_B)\n        if self.dh_p != 0:\n            ret += \", dh_p={0}, dh_g={1}, dh_Ys={2}\".format(\n                self.dh_p, self.dh_g, self.dh_Ys)\n        if self.signAlg != 0:\n            ret += \", hashAlg={0}, signAlg={1}\".format(\n                self.hashAlg, self.signAlg)\n        if self.signature != bytearray(0):\n            ret += \", signature={0!r}\".format(self.signature)\n        ret += \")\"\n\n        return ret\n\n    def createSRP(self, srp_N, srp_g, srp_s, srp_B):\n        \"\"\"Set SRP protocol parameters.\"\"\"\n        self.srp_N = srp_N\n        self.srp_N_len = None\n        self.srp_g = srp_g\n        self.srp_g_len = None\n        self.srp_s = srp_s\n        self.srp_B = srp_B\n        self.srp_B_len = None\n        return self\n\n    def createDH(self, dh_p, dh_g, dh_Ys):\n        \"\"\"Set FFDH protocol parameters.\"\"\"\n        self.dh_p = dh_p\n        self.dh_p_len = None\n        self.dh_g = dh_g\n        self.dh_g_len = None\n        self.dh_Ys = dh_Ys\n        self.dh_Ys_len = None\n        return self\n\n    def createECDH(self, curve_type, named_curve=None, point=None):\n        \"\"\"Set ECDH protocol parameters.\"\"\"\n        self.curve_type = curve_type\n        self.named_curve = named_curve\n        self.ecdh_Ys = point\n        return self\n\n    def parse(self, parser):\n        \"\"\"\n        Deserialise message from :py:class:`Parser`.\n\n        :type parser: Parser\n        :param parser: parser to read data from\n        \"\"\"\n        parser.startLengthCheck(3)\n        if self.cipherSuite in CipherSuite.srpAllSuites:\n            self.srp_N_len = parser.get(2)\n            self.srp_N = bytesToNumber(parser.getFixBytes(self.srp_N_len))\n            self.srp_g_len = parser.get(2)\n            self.srp_g = bytesToNumber(parser.getFixBytes(self.srp_g_len))\n            self.srp_s = parser.getVarBytes(1)\n            self.srp_B_len = parser.get(2)\n            self.srp_B = bytesToNumber(parser.getFixBytes(self.srp_B_len))\n        elif self.cipherSuite in CipherSuite.dhAllSuites:\n            self.dh_p_len = parser.get(2)\n            self.dh_p = bytesToNumber(parser.getFixBytes(self.dh_p_len))\n            self.dh_g_len = parser.get(2)\n            self.dh_g = bytesToNumber(parser.getFixBytes(self.dh_g_len))\n            self.dh_Ys_len = parser.get(2)\n            self.dh_Ys = bytesToNumber(parser.getFixBytes(self.dh_Ys_len))\n        elif self.cipherSuite in CipherSuite.ecdhAllSuites:\n            self.curve_type = parser.get(1)\n            # only named curves supported\n            assert self.curve_type == 3\n            self.named_curve = parser.get(2)\n            self.ecdh_Ys = parser.getVarBytes(1)\n        else:\n            raise AssertionError()\n\n        if self.cipherSuite in CipherSuite.certAllSuites or\\\n                self.cipherSuite in CipherSuite.ecdheEcdsaSuites or\\\n                self.cipherSuite in CipherSuite.dheDsaSuites:\n            if self.version == (3, 3):\n                self.hashAlg = parser.get(1)\n                self.signAlg = parser.get(1)\n            self.signature = parser.getVarBytes(2)\n\n        parser.stopLengthCheck()\n        return self\n\n    def writeParams(self):\n        \"\"\"\n        Serialise the key exchange parameters.\n\n        :rtype: bytearray\n        \"\"\"\n        writer = Writer()\n        if self.cipherSuite in CipherSuite.srpAllSuites:\n            writer.addVarSeq(numberToByteArray(self.srp_N, self.srp_N_len),\n                             1, 2)\n            writer.addVarSeq(numberToByteArray(self.srp_g, self.srp_g_len),\n                             1, 2)\n            writer.addVarSeq(self.srp_s, 1, 1)\n            writer.addVarSeq(numberToByteArray(self.srp_B, self.srp_B_len),\n                             1, 2)\n        elif self.cipherSuite in CipherSuite.dhAllSuites:\n            writer.addVarSeq(numberToByteArray(self.dh_p, self.dh_p_len),\n                             1, 2)\n            writer.addVarSeq(numberToByteArray(self.dh_g, self.dh_g_len),\n                             1, 2)\n            writer.addVarSeq(numberToByteArray(self.dh_Ys, self.dh_Ys_len),\n                             1, 2)\n        elif self.cipherSuite in CipherSuite.ecdhAllSuites:\n            writer.add(self.curve_type, 1)\n            assert self.curve_type == 3\n            writer.add(self.named_curve, 2)\n            writer.addVarSeq(self.ecdh_Ys, 1, 1)\n        else:\n            assert(False)\n        return writer.bytes\n\n    def write(self):\n        \"\"\"\n        Serialise complete message.\n\n        :rtype: bytearray\n        \"\"\"\n        writer = Writer()\n        writer.bytes += self.writeParams()\n        if self.cipherSuite in CipherSuite.certAllSuites or \\\n                self.cipherSuite in CipherSuite.ecdheEcdsaSuites or \\\n                self.cipherSuite in CipherSuite.dheDsaSuites:\n            if self.version >= (3, 3):\n                assert self.hashAlg != 0 and self.signAlg != 0\n                writer.add(self.hashAlg, 1)\n                writer.add(self.signAlg, 1)\n            writer.addVarSeq(self.signature, 1, 2)\n        return self.postWrite(writer)\n\n    def hash(self, clientRandom, serverRandom):\n        \"\"\"\n        Calculate hash of parameters to sign.\n\n        :rtype: bytearray\n        \"\"\"\n        bytesToHash = clientRandom + serverRandom + self.writeParams()\n        if self.version >= (3, 3):\n            sigScheme = SignatureScheme.toRepr((self.hashAlg, self.signAlg))\n            if sigScheme is None:\n                hashAlg = HashAlgorithm.toRepr(self.hashAlg)\n                if hashAlg is None:\n                    raise AssertionError(\"Unknown hash algorithm: {0}\".\n                                         format(self.hashAlg))\n            else:\n                hashAlg = SignatureScheme.getHash(sigScheme)\n            if hashAlg == \"intrinsic\":\n                return bytesToHash\n            return secureHash(bytesToHash, hashAlg)\n        # DSA and ECDSA ciphers in TLS 1.1 and earlier sign the messages using\n        # SHA-1 only\n        if self.cipherSuite in CipherSuite.ecdheEcdsaSuites or\\\n                self.cipherSuite in CipherSuite.dheDsaSuites:\n            return SHA1(bytesToHash)\n        return MD5(bytesToHash) + SHA1(bytesToHash)\n\n\nclass ServerHelloDone(HandshakeMsg):\n    def __init__(self):\n        HandshakeMsg.__init__(self, HandshakeType.server_hello_done)\n\n    def create(self):\n        return self\n\n    def parse(self, p):\n        p.startLengthCheck(3)\n        p.stopLengthCheck()\n        return self\n\n    def write(self):\n        w = Writer()\n        return self.postWrite(w)\n\n    def __repr__(self):\n        \"\"\"Human readable representation of object.\"\"\"\n        return \"ServerHelloDone()\"\n\n\nclass ClientKeyExchange(HandshakeMsg):\n    \"\"\"\n    Handling of TLS Handshake protocol ClientKeyExchange message.\n\n    :vartype cipherSuite: int\n    :ivar cipherSuite: the cipher suite id used for the connection\n    :vartype ~.version: tuple(int, int)\n    :ivar ~.version: TLS protocol version used for the connection\n    :vartype srp_A: int\n    :ivar srp_A: SRP protocol client answer value\n    :vartype dh_Yc: int\n    :ivar dh_Yc: client Finite Field Diffie-Hellman protocol key share\n    :vartype ecdh_Yc: bytearray\n    :ivar ecdh_Yc: encoded curve coordinates\n    :vartype encryptedPreMasterSecret: bytearray\n    :ivar encryptedPreMasterSecret: client selected PremMaster secret encrypted\n        with server public key (from certificate)\n    \"\"\"\n\n    def __init__(self, cipherSuite, version=None):\n        \"\"\"\n        Initialise ClientKeyExchange for reading or writing.\n\n        :type cipherSuite: int\n        :param cipherSuite: id of the ciphersuite selected by server\n        :type version: tuple(int, int)\n        :param version: protocol version selected by server\n        \"\"\"\n        HandshakeMsg.__init__(self, HandshakeType.client_key_exchange)\n        self.cipherSuite = cipherSuite\n        self.version = version\n        self.srp_A = 0\n        self.dh_Yc = 0\n        self.ecdh_Yc = bytearray(0)\n        self.encryptedPreMasterSecret = bytearray(0)\n\n    def createSRP(self, srp_A):\n        \"\"\"\n        Set the SRP client answer.\n\n        returns self\n\n        :type srp_A: int\n        :param srp_A: client SRP answer\n        :rtype: ClientKeyExchange\n        \"\"\"\n        self.srp_A = srp_A\n        return self\n\n    def createRSA(self, encryptedPreMasterSecret):\n        \"\"\"\n        Set the encrypted PreMaster Secret.\n\n        returns self\n\n        :type encryptedPreMasterSecret: bytearray\n        :rtype: ClientKeyExchange\n        \"\"\"\n        self.encryptedPreMasterSecret = encryptedPreMasterSecret\n        return self\n\n    def createDH(self, dh_Yc):\n        \"\"\"\n        Set the client FFDH key share.\n\n        returns self\n\n        :type dh_Yc: int\n        :rtype: ClientKeyExchange\n        \"\"\"\n        self.dh_Yc = dh_Yc\n        return self\n\n    def createECDH(self, ecdh_Yc):\n        \"\"\"\n        Set the client ECDH key share.\n\n        returns self\n\n        :type ecdh_Yc: bytearray\n        :rtype: ClientKeyExchange\n        \"\"\"\n        self.ecdh_Yc = ecdh_Yc\n        return self\n\n    def parse(self, parser):\n        \"\"\"\n        Deserialise the message from :py:class:`Parser`,\n\n        returns self\n\n        :type parser: Parser\n        :rtype: ClientKeyExchange\n        \"\"\"\n        parser.startLengthCheck(3)\n        if self.cipherSuite in CipherSuite.srpAllSuites:\n            self.srp_A = bytesToNumber(parser.getVarBytes(2))\n        elif self.cipherSuite in CipherSuite.certSuites:\n            if self.version in ((3, 1), (3, 2), (3, 3)):\n                self.encryptedPreMasterSecret = parser.getVarBytes(2)\n            elif self.version == (3, 0):\n                self.encryptedPreMasterSecret = \\\n                    parser.getFixBytes(parser.getRemainingLength())\n            else:\n                raise AssertionError()\n        elif self.cipherSuite in CipherSuite.dhAllSuites:\n            self.dh_Yc = bytesToNumber(parser.getVarBytes(2))\n        elif self.cipherSuite in CipherSuite.ecdhAllSuites:\n            self.ecdh_Yc = parser.getVarBytes(1)\n        else:\n            raise AssertionError()\n        parser.stopLengthCheck()\n        return self\n\n    def write(self):\n        \"\"\"\n        Serialise the object.\n\n        :rtype: bytearray\n        \"\"\"\n        w = Writer()\n        if self.cipherSuite in CipherSuite.srpAllSuites:\n            w.addVarSeq(numberToByteArray(self.srp_A), 1, 2)\n        elif self.cipherSuite in CipherSuite.certSuites:\n            if self.version in ((3, 1), (3, 2), (3, 3)):\n                w.addVarSeq(self.encryptedPreMasterSecret, 1, 2)\n            elif self.version == (3, 0):\n                w.bytes += self.encryptedPreMasterSecret\n            else:\n                raise AssertionError()\n        elif self.cipherSuite in CipherSuite.dhAllSuites:\n            w.addVarSeq(numberToByteArray(self.dh_Yc), 1, 2)\n        elif self.cipherSuite in CipherSuite.ecdhAllSuites:\n            w.addVarSeq(self.ecdh_Yc, 1, 1)\n        else:\n            raise AssertionError()\n        return self.postWrite(w)\n\n\nclass ClientMasterKey(HandshakeMsg):\n    \"\"\"\n    Handling of SSLv2 CLIENT-MASTER-KEY message.\n\n    :vartype cipher: int\n    :ivar cipher: negotiated cipher\n\n    :vartype clear_key: bytearray\n    :ivar clear_key: the part of master secret key that is sent in clear for\n        export cipher suites\n\n    :vartype encrypted_key: bytearray\n    :ivar encrypted_key: (part of) master secret encrypted using server key\n\n    :vartype key_argument: bytearray\n    :ivar key_argument: additional key argument for block ciphers\n    \"\"\"\n\n    def __init__(self):\n        super(ClientMasterKey,\n              self).__init__(SSL2HandshakeType.client_master_key)\n        self.cipher = 0\n        self.clear_key = bytearray(0)\n        self.encrypted_key = bytearray(0)\n        self.key_argument = bytearray(0)\n\n    def create(self, cipher, clear_key, encrypted_key, key_argument):\n        \"\"\"Set values of the CLIENT-MASTER-KEY object.\"\"\"\n        self.cipher = cipher\n        self.clear_key = clear_key\n        self.encrypted_key = encrypted_key\n        self.key_argument = key_argument\n        return self\n\n    def write(self):\n        \"\"\"Serialise the object to on the wire data.\"\"\"\n        writer = Writer()\n        writer.add(self.handshakeType, 1)\n        writer.add(self.cipher, 3)\n        writer.add(len(self.clear_key), 2)\n        writer.add(len(self.encrypted_key), 2)\n        writer.add(len(self.key_argument), 2)\n        writer.bytes += self.clear_key\n        writer.bytes += self.encrypted_key\n        writer.bytes += self.key_argument\n        return writer.bytes\n\n    def parse(self, parser):\n        \"\"\"Deserialise object from on the wire data.\"\"\"\n        self.cipher = parser.get(3)\n        clear_key_length = parser.get(2)\n        encrypted_key_length = parser.get(2)\n        key_argument_length = parser.get(2)\n        parser.setLengthCheck(clear_key_length +\n                              encrypted_key_length +\n                              key_argument_length)\n        self.clear_key = parser.getFixBytes(clear_key_length)\n        self.encrypted_key = parser.getFixBytes(encrypted_key_length)\n        self.key_argument = parser.getFixBytes(key_argument_length)\n        parser.stopLengthCheck()\n        return self\n\n\nclass CertificateVerify(HandshakeMsg):\n    \"\"\"Serializer for TLS handshake protocol Certificate Verify message.\"\"\"\n\n    def __init__(self, version):\n        \"\"\"\n        Create message.\n\n        :param version: TLS protocol version in use\n        \"\"\"\n        HandshakeMsg.__init__(self, HandshakeType.certificate_verify)\n        self.version = version\n        self.signatureAlgorithm = None\n        self.signature = bytearray(0)\n\n    def create(self, signature, signatureAlgorithm=None):\n        \"\"\"\n        Provide data for serialisation of message.\n\n        :param signature: signature carried in the message\n        :param signatureAlgorithm: signature algorithm used to make the\n            signature (TLSv1.2 only)\n        \"\"\"\n        self.signatureAlgorithm = signatureAlgorithm\n        self.signature = signature\n        return self\n\n    def parse(self, parser):\n        \"\"\"\n        Deserialize message from parser.\n\n        :param parser: parser with data to read\n        \"\"\"\n        parser.startLengthCheck(3)\n        if self.version >= (3, 3):\n            self.signatureAlgorithm = (parser.get(1), parser.get(1))\n        self.signature = parser.getVarBytes(2)\n        parser.stopLengthCheck()\n        return self\n\n    def write(self):\n        \"\"\"\n        Serialize the data to bytearray.\n\n        :rtype: bytearray\n        \"\"\"\n        writer = Writer()\n        if self.version >= (3, 3):\n            writer.add(self.signatureAlgorithm[0], 1)\n            writer.add(self.signatureAlgorithm[1], 1)\n        writer.addVarSeq(self.signature, 1, 2)\n        return self.postWrite(writer)\n\n\nclass ChangeCipherSpec(object):\n    def __init__(self):\n        self.contentType = ContentType.change_cipher_spec\n        self.type = 1\n\n    def create(self):\n        self.type = 1\n        return self\n\n    def parse(self, p):\n        p.setLengthCheck(1)\n        self.type = p.get(1)\n        p.stopLengthCheck()\n        return self\n\n    def write(self):\n        w = Writer()\n        w.add(self.type, 1)\n        return w.bytes\n\n\nclass NextProtocol(HandshakeMsg):\n    def __init__(self):\n        HandshakeMsg.__init__(self, HandshakeType.next_protocol)\n        self.next_proto = None\n\n    def create(self, next_proto):\n        self.next_proto = next_proto\n        return self\n\n    def parse(self, p):\n        p.startLengthCheck(3)\n        self.next_proto = p.getVarBytes(1)\n        _ = p.getVarBytes(1)\n        p.stopLengthCheck()\n        return self\n\n    def write(self, trial=False):\n        w = Writer()\n        w.addVarSeq(self.next_proto, 1, 1)\n        paddingLen = 32 - ((len(self.next_proto) + 2) % 32)\n        w.addVarSeq(bytearray(paddingLen), 1, 1)\n        return self.postWrite(w)\n\n\nclass Finished(HandshakeMsg):\n    def __init__(self, version, hash_length=None):\n        HandshakeMsg.__init__(self, HandshakeType.finished)\n        self.version = version\n        self.verify_data = bytearray(0)\n        self.hash_length = hash_length\n\n    def create(self, verify_data):\n        self.verify_data = verify_data\n        return self\n\n    def parse(self, p):\n        p.startLengthCheck(3)\n        if self.version == (3, 0):\n            self.verify_data = p.getFixBytes(36)\n        elif self.version in ((3, 1), (3, 2), (3, 3)):\n            self.verify_data = p.getFixBytes(12)\n        elif self.version > (3, 3):\n            self.verify_data = p.getFixBytes(self.hash_length)\n        else:\n            raise AssertionError()\n        p.stopLengthCheck()\n        return self\n\n    def write(self):\n        w = Writer()\n        w.bytes += self.verify_data\n        return self.postWrite(w)\n\n\nclass EncryptedExtensions(HelloMessage):\n    \"\"\"Handling of the TLS1.3 Encrypted Extensions message.\"\"\"\n\n    def __init__(self):\n        super(EncryptedExtensions, self).__init__(\n                HandshakeType.encrypted_extensions)\n\n    def create(self, extensions):\n        \"\"\"Set the extensions in the message.\"\"\"\n        self.extensions = extensions\n        return self\n\n    def parse(self, parser):\n        \"\"\"Parse the extensions from on the wire data.\"\"\"\n        parser.startLengthCheck(3)\n\n        if not parser.getRemainingLength():\n            raise SyntaxError(\"No list of extensions\")\n        else:\n            self.extensions = []\n            p2 = Parser(parser.getVarBytes(2))\n            while p2.getRemainingLength():\n                self.extensions.append(TLSExtension(encExt=True).parse(p2))\n\n        parser.stopLengthCheck()\n        return self\n\n    def write(self):\n        \"\"\"\n        Serialise the message to on the wire data.\n\n        :rtype: bytearray\n        \"\"\"\n        w = Writer()\n        w2 = Writer()\n        for ext in self.extensions:\n            w2.bytes += ext.write()\n\n        w.add(len(w2.bytes), 2)\n        w.bytes += w2.bytes\n\n        return self.postWrite(w)\n\n\nclass NewSessionTicket(HelloMessage):\n    \"\"\"Handling of the TLS1.3 New Session Ticket message.\"\"\"\n\n    def __init__(self):\n        \"\"\"Create New Session Ticket object.\"\"\"\n        super(NewSessionTicket, self).__init__(HandshakeType\n                                               .new_session_ticket)\n        self.ticket_lifetime = 0\n        self.ticket_age_add = 0\n        self.ticket_nonce = bytearray(0)\n        self.ticket = bytearray(0)\n        self.extensions = []\n        # time at which the ticket was received, not sent on the wire\n        # in seconds in Unix Epoch\n        self.time = None\n\n    def create(self, ticket_lifetime, ticket_age_add, ticket_nonce, ticket,\n               extensions):\n        \"\"\"Initialise a New Session Ticket.\"\"\"\n        self.ticket_lifetime = ticket_lifetime\n        self.ticket_age_add = ticket_age_add\n        self.ticket_nonce = ticket_nonce\n        self.ticket = ticket\n        self.extensions = extensions\n        return self\n\n    def write(self):\n        \"\"\"\n        Serialise the message to on the wire data.\n\n        :rtype: bytearray\n        \"\"\"\n        w = Writer()\n        w.add(self.ticket_lifetime, 4)\n        w.add(self.ticket_age_add, 4)\n        w.addVarSeq(self.ticket_nonce, 1, 1)\n        w.addVarSeq(self.ticket, 1, 2)\n        w2 = Writer()\n        for ext in self.extensions:\n            w2.bytes += ext.write()\n        w.add(len(w2.bytes), 2)\n        w.bytes += w2.bytes\n\n        return self.postWrite(w)\n\n    def parse(self, parser):\n        \"\"\"Parse the object from on the wire data.\"\"\"\n        parser.startLengthCheck(3)\n\n        self.ticket_lifetime = parser.get(4)\n        self.ticket_age_add = parser.get(4)\n        self.ticket_nonce = parser.getVarBytes(1)\n        self.ticket = parser.getVarBytes(2)\n        self.extensions = []\n        ext_parser = Parser(parser.getVarBytes(2))\n        while ext_parser.getRemainingLength():\n            self.extensions.append(TLSExtension().parse(ext_parser))\n\n        parser.stopLengthCheck()\n        return self\n\n\nclass SessionTicketPayload(object):\n    \"\"\"Serialisation and deserialisation of server state for resumption.\n\n    This is the internal (meant to be encrypted) representation of server\n    state that is set to client in the NewSessionTicket message.\n\n    :ivar int ~.version: implementation detail for forward compatibility\n    :ivar bytearray master_secret: master secret for TLS 1.2-, resumption\n        master secret for TLS 1.3\n\n    :ivar tuple protocol_version: version of protocol that was previously\n        negotiated in this session\n\n    :ivar int cipher_suite: numerical ID of ciphersuite that was negotiated\n        previously\n\n    :ivar bytearray nonce: nonce for TLS 1.3 KDF\n\n    :ivar int creation_time: Unix time in seconds when was the ticket created\n    :ivar X509CertChain client_cert_chain: Client X509 Certificate Chain\n    \"\"\"\n\n    def __init__(self):\n        \"\"\"Create instance of the object.\"\"\"\n        self.version = 0\n        self.master_secret = bytearray()\n        self.protocol_version = bytearray()\n        self.cipher_suite = 0\n        self.creation_time = 0\n        self.nonce = bytearray()\n        self._cert_chain = None\n\n    @property\n    def client_cert_chain(self):\n        \"\"\"Getter for the client_cert_chain property.\"\"\"\n        if self._cert_chain:\n            return X509CertChain([i.certificate\n                                  for i in self._cert_chain])\n        return None\n\n    @client_cert_chain.setter\n    def client_cert_chain(self, client_cert_chain):\n        \"\"\"Setter for the cert_chain property.\"\"\"\n        self._cert_chain = [CertificateEntry(CertificateType.x509)\n                            .create(i, []) for i in client_cert_chain.x509List]\n\n    def create(self, master_secret, protocol_version, cipher_suite,\n               creation_time, nonce=bytearray(), client_cert_chain=None):\n        \"\"\"Initialise the object with cryptographic data.\"\"\"\n        self.master_secret = master_secret\n        self.protocol_version = protocol_version\n        self.cipher_suite = cipher_suite\n        self.creation_time = creation_time\n        self.nonce = nonce\n        if client_cert_chain:\n            self.version = 1\n            self.client_cert_chain = client_cert_chain\n        return self\n\n    def _parse_cert_chain(self, parser):\n        self._cert_chain = []\n        while parser.getRemainingLength():\n            entry = CertificateEntry(CertificateType.x509)\n            self._cert_chain.append(entry.parse(parser))\n\n    def parse(self, parser):\n        self.version = parser.get(2)\n        if self.version > 1:\n            raise ValueError(\"Unrecognised version number\")\n        self.master_secret = parser.getVarBytes(2)\n        self.protocol_version = (parser.get(1), parser.get(1))\n        self.cipher_suite = parser.get(2)\n        self.nonce = parser.getVarBytes(1)\n        self.creation_time = parser.get(8)\n        if self.version == 1:\n            self._parse_cert_chain(Parser(parser.getVarBytes(3)))\n        if parser.getRemainingLength():\n            raise ValueError(\"Malformed ticket\")\n        return self\n\n    def write(self):\n        writer = Writer()\n        writer.addTwo(self.version)\n        writer.addTwo(len(self.master_secret))\n        writer.bytes += self.master_secret\n        writer.addOne(self.protocol_version[0])\n        writer.addOne(self.protocol_version[1])\n        writer.addTwo(self.cipher_suite)\n        writer.addOne(len(self.nonce))\n        writer.bytes += self.nonce\n        writer.add(self.creation_time, 8)\n        if self.version == 1:\n            wcert = Writer()\n            for entry in self._cert_chain:\n                wcert.bytes += entry.write()\n            writer.addVarSeq(wcert.bytes, 1, 3)\n        return writer.bytes\n\n\nclass SSL2Finished(HandshakeMsg):\n    \"\"\"Handling of the SSL2 FINISHED messages.\"\"\"\n\n    def __init__(self, msg_type):\n        super(SSL2Finished, self).__init__(msg_type)\n        self.verify_data = bytearray(0)\n\n    def create(self, verify_data):\n        \"\"\"Set the message payload.\"\"\"\n        self.verify_data = verify_data\n        return self\n\n    def parse(self, parser):\n        \"\"\"Deserialise the message from on the wire data.\"\"\"\n        self.verify_data = parser.getFixBytes(parser.getRemainingLength())\n        return self\n\n    def write(self):\n        \"\"\"Serialise the message to on the wire data.\"\"\"\n        writer = Writer()\n        writer.add(self.handshakeType, 1)\n        writer.bytes += self.verify_data\n        # does not use postWrite() as it's a SSLv2 message\n        return writer.bytes\n\n\nclass ClientFinished(SSL2Finished):\n    \"\"\"\n    Handling of SSLv2 CLIENT-FINISHED message.\n\n    :vartype verify_data: bytearray\n    :ivar verify_data: payload of the message, should be the CONNECTION-ID\n    \"\"\"\n\n    def __init__(self):\n        super(ClientFinished, self).__init__(SSL2HandshakeType.client_finished)\n\n\nclass ServerFinished(SSL2Finished):\n    \"\"\"\n    Handling of SSLv2 SERVER-FINISHED message.\n\n    :vartype verify_data: bytearray\n    :ivar verify_data: payload of the message, should be SESSION-ID\n    \"\"\"\n\n    def __init__(self):\n        super(ServerFinished, self).__init__(SSL2HandshakeType.server_finished)\n\n\nclass CertificateStatus(HandshakeMsg):\n    \"\"\"\n    Handling of the CertificateStatus message from RFC 6066.\n\n    Handling of the handshake protocol message that includes the OCSP staple.\n\n    :vartype status_type: int\n    :ivar status_type: type of response returned\n\n    :vartype ocsp: bytearray\n    :ivar ocsp: OCSPResponse from RFC 2560\n    \"\"\"\n\n    def __init__(self):\n        \"\"\"Create the objet, set its type.\"\"\"\n        super(CertificateStatus, self).__init__(\n                HandshakeType.certificate_status)\n        self.status_type = None\n        self.ocsp = bytearray()\n\n    def create(self, status_type, ocsp):\n        \"\"\"Set up message payload.\"\"\"\n        self.status_type = status_type\n        self.ocsp = ocsp\n        return self\n\n    def parse(self, parser):\n        \"\"\"Deserialise the message from one the wire data.\"\"\"\n        parser.startLengthCheck(3)\n        self.status_type = parser.get(1)\n        self.ocsp = parser.getVarBytes(3)\n        parser.stopLengthCheck()\n        return self\n\n    def write(self):\n        \"\"\"Serialise the message.\"\"\"\n        writer = Writer()\n        writer.add(self.status_type, 1)\n        writer.add(len(self.ocsp), 3)\n        writer.bytes += self.ocsp\n        return self.postWrite(writer)\n\n\nclass ApplicationData(object):\n    def __init__(self):\n        self.contentType = ContentType.application_data\n        self.bytes = bytearray(0)\n\n    def create(self, bytes):\n        self.bytes = bytes\n        return self\n\n    def splitFirstByte(self):\n        newMsg = ApplicationData().create(self.bytes[:1])\n        self.bytes = self.bytes[1:]\n        return newMsg\n\n    def parse(self, p):\n        self.bytes = p.bytes\n        return self\n\n    def write(self):\n        return self.bytes\n\n\nclass Heartbeat(object):\n    \"\"\"\n    Handling Heartbeat messages from RFC 6520\n\n    :type message_type: int\n    :ivar message_type: type of message (response or request)\n\n    :type payload: bytearray\n    :ivar payload: payload\n\n    :type padding: bytearray\n    :ivar padding: random padding of selected length\n    \"\"\"\n\n    def __init__(self):\n        self.contentType = ContentType.heartbeat\n        self.message_type = 0\n        self.payload = bytearray(0)\n        self.padding = bytearray(0)\n\n    def create(self, message_type, payload, padding_length):\n        \"\"\"Create heartbeat request or response with selected parameters\"\"\"\n        self.message_type = message_type\n        self.payload = payload\n        self.padding = getRandomBytes(padding_length)\n        return self\n\n    def create_response(self):\n        \"\"\"Creates heartbeat response based on request.\"\"\"\n        heartbeat_response = Heartbeat().create(\n            HeartbeatMessageType.heartbeat_response,\n            self.payload,\n            16)\n        return heartbeat_response\n\n    def parse(self, p):\n        \"\"\"\n        Deserialize heartbeat message from parser.\n\n        We are reading only message type and payload, ignoring\n        leftover bytes (padding).\n        \"\"\"\n        self.message_type = p.get(1)\n        self.payload = p.getVarBytes(2)\n        self.padding = p.getFixBytes(p.getRemainingLength())\n        return self\n\n    def write(self):\n        \"\"\"Serialise heartbeat message.\"\"\"\n        w = Writer()\n        w.add(self.message_type, 1)\n        w.add(len(self.payload), 2)\n        w.bytes += self.payload\n        w.bytes += self.padding\n        return w.bytes\n\n    @property\n    def _message_type(self):\n        \"\"\"Format heartbeat message to human readable representation.\"\"\"\n        return none_as_unknown(HeartbeatMessageType.toRepr(self.message_type),\n                               self.message_type)\n\n    def __str__(self):\n        \"\"\"Return human readable representation of heartbeat message.\"\"\"\n        return \"heartbeat {0}\".format(self._message_type)\n\n\nclass KeyUpdate(HandshakeMsg):\n    \"\"\"\n    Handling KeyUpdate message from RFC 8446\n\n    :vartype message_type: int\n    :ivar message_type: type of message (update_not_requested or\n                                         update_requested)\n    \"\"\"\n\n    def __init__(self):\n        super(KeyUpdate, self).__init__(HandshakeType.key_update)\n        self.message_type = 0\n\n    def create(self, message_type):\n        \"\"\"Create KeyUpdate message with selected parameter.\"\"\"\n        self.message_type = message_type\n        return self\n\n    def parse(self, p):\n        \"\"\"Deserialize keyupdate message from parser.\"\"\"\n        p.startLengthCheck(3)\n        self.message_type = p.get(1)\n        p.stopLengthCheck()\n        return self\n\n    def write(self):\n        \"\"\"Serialise keyupdate message.\"\"\"\n        writer = Writer()\n        writer.add(self.message_type, 1)\n        return self.postWrite(writer)\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/messagesocket.py",
    "content": "# vim: set fileencoding=utf8\n#\n# Copyright © 2015, Hubert Kario\n#\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Wrapper of TLS RecordLayer providing message-level abstraction\"\"\"\n\nfrom .recordlayer import RecordLayer\nfrom .constants import ContentType\nfrom .messages import RecordHeader3, Message\nfrom .utils.codec import Parser\n\nclass MessageSocket(RecordLayer):\n\n    \"\"\"TLS Record Layer socket that provides Message level abstraction\n\n    Because the record layer has a hard size limit on sent messages, they need\n    to be fragmented before sending. Similarly, a single record layer record\n    can include multiple handshake protocol messages (very common with\n    ServerHello, Certificate and ServerHelloDone), as such, the user of\n    RecordLayer needs to fragment those records into multiple messages.\n    Unfortunately, fragmentation of messages requires some degree of\n    knowledge about the messages passed and as such is outside scope of pure\n    record layer implementation.\n\n    This class tries to provide a useful abstraction for handling Handshake\n    protocol messages.\n\n    :vartype recordSize: int\n    :ivar recordSize: maximum size of records sent through socket. Messages\n        bigger than this size will be fragmented to smaller chunks. Setting it\n        to higher value than the default 2^14 will make the implementation\n        non RFC compliant and likely not interoperable with other peers.\n\n    :vartype defragmenter: Defragmenter\n    :ivar defragmenter: defragmenter used for read records\n\n    :vartype unfragmentedDataTypes: tuple\n    :ivar unfragmentedDataTypes: data types which will be passed as-read,\n        TLS application_data and heartbeat by default\n    \"\"\"\n\n    def __init__(self, sock, defragmenter):\n        \"\"\"Apply TLS Record Layer abstraction to raw network socket.\n\n        :type sock: socket.socket\n        :param sock: network socket to wrap\n        :type defragmenter: Defragmenter\n        :param defragmenter: defragmenter to apply on the records read\n        \"\"\"\n        super(MessageSocket, self).__init__(sock)\n\n        self.defragmenter = defragmenter\n        self.unfragmentedDataTypes = (ContentType.application_data,\n                                      ContentType.heartbeat)\n        self._lastRecordVersion = (0, 0)\n\n        self._sendBuffer = bytearray(0)\n        self._sendBufferType = None\n\n        self.recordSize = 2**14\n\n    def recvMessage(self):\n        \"\"\"\n        Read next message in queue\n\n        will return a 0 or 1 if the read is blocking, a tuple of\n        :py:class:`RecordHeader3` and :py:class:`Parser` in case a message was\n        received.\n\n        :rtype: generator\n        \"\"\"\n        while True:\n            while True:\n                ret = self.defragmenter.get_message()\n                if ret is None:\n                    break\n                header = RecordHeader3().create(self._lastRecordVersion,\n                                                ret[0],\n                                                0)\n                yield header, Parser(ret[1])\n\n            for ret in self.recvRecord():\n                if ret in (0, 1):\n                    yield ret\n                else:\n                    break\n\n            header, parser = ret\n            if header.type in self.unfragmentedDataTypes:\n                yield ret\n            # TODO probably needs a bit better handling...\n            if header.ssl2:\n                yield ret\n\n            self.defragmenter.add_data(header.type, parser.bytes)\n            self._lastRecordVersion = header.version\n\n    def recvMessageBlocking(self):\n        \"\"\"Blocking variant of :py:meth:`recvMessage`.\"\"\"\n        for res in self.recvMessage():\n            if res in (0, 1):\n                pass\n            else:\n                return res\n\n    def flush(self):\n        \"\"\"\n        Empty the queue of messages to write\n\n        Will fragment the messages and write them in as little records as\n        possible.\n\n        :rtype: generator\n        \"\"\"\n        while len(self._sendBuffer) > 0:\n            recordPayload = self._sendBuffer[:self.recordSize]\n            self._sendBuffer = self._sendBuffer[self.recordSize:]\n            msg = Message(self._sendBufferType, recordPayload)\n            for res in self.sendRecord(msg):\n                yield res\n\n        assert len(self._sendBuffer) == 0\n        self._sendBufferType = None\n\n    def flushBlocking(self):\n        \"\"\"Blocking variant of :py:meth:`flush`.\"\"\"\n        for _ in self.flush():\n            pass\n\n    def queueMessage(self, msg):\n        \"\"\"\n        Queue message for sending\n\n        If the message is of same type as messages in queue, the message is\n        just added to queue.\n\n        If the message is of different type as messages in queue, the queue is\n        flushed and then the message is queued.\n\n        :rtype: generator\n        \"\"\"\n        if self._sendBufferType is None:\n            self._sendBufferType = msg.contentType\n\n        if msg.contentType == self._sendBufferType:\n            self._sendBuffer += msg.write()\n            return\n\n        for res in self.flush():\n            yield res\n\n        assert self._sendBufferType is None\n        self._sendBufferType = msg.contentType\n        self._sendBuffer += msg.write()\n\n    def queueMessageBlocking(self, msg):\n        \"\"\"Blocking variant of :py:meth:`queueMessage`.\"\"\"\n        for _ in self.queueMessage(msg):\n            pass\n\n    def sendMessage(self, msg):\n        \"\"\"\n        Fragment and send a message.\n\n        If a messages already of same type reside in queue, the message if\n        first added to it and then the queue is flushed.\n\n        If the message is of different type than the queue, the queue is\n        flushed, the message is added to queue and the queue is flushed again.\n\n        Use the sendRecord() message if you want to send a message outside\n        the queue, or a message of zero size.\n\n        :rtype: generator\n        \"\"\"\n        for res in self.queueMessage(msg):\n            yield res\n\n        for res in self.flush():\n            yield res\n\n    def sendMessageBlocking(self, msg):\n        \"\"\"Blocking variant of :py:meth:`sendMessage`.\"\"\"\n        for _ in self.sendMessage(msg):\n            pass\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/ocsp.py",
    "content": "\"\"\"Class for handling primary OCSP responses\"\"\"\n\nfrom .utils.asn1parser import ASN1Parser\nfrom .utils.cryptomath import bytesToNumber, numBytes, secureHash\nfrom .x509 import X509\nfrom .signed import SignedObject\nfrom .errors import TLSIllegalParameterException\n\nclass OCSPRespStatus(object):\n    \"\"\" OCSP response status codes (RFC 2560) \"\"\"\n    successful = 0\n    malformedRequest = 1\n    internalError = 2\n    tryLater = 3    # 4 is not used to match RFC2560 specification\n    sigRequired = 5\n    unauthorized = 6\n\n\nclass CertStatus(object):\n    \"\"\" Certificate status in an OCSP response \"\"\"\n    good, revoked, unknown = range(3)\n\n\nclass SingleResponse(object):\n    \"\"\" This class represents SingleResponse ASN1 type (defined in RFC2560) \"\"\"\n    def __init__(self, value):\n        self.value = value\n        self.cert_hash_alg = None\n        self.cert_issuer_name_hash = None\n        self.cert_issuer_key_hash = None\n        self.cert_serial_num = None\n        self.cert_status = None\n        self.this_update = None\n        self.next_update = None\n        self.parse(value)\n\n    _hash_algs_OIDs = {\n        tuple([0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x2, 0x5]): 'md5',\n        tuple([0x2b, 0xe, 0x3, 0x2, 0x1a]): 'sha1',\n        tuple([0x60, 0x86, 0x48, 0x1, 0x65, 0x3, 0x4, 0x2, 0x4]): 'sha224',\n        tuple([0x60, 0x86, 0x48, 0x1, 0x65, 0x3, 0x4, 0x2, 0x1]): 'sha256',\n        tuple([0x60, 0x86, 0x48, 0x1, 0x65, 0x3, 0x4, 0x2, 0x2]): 'sha384',\n        tuple([0x60, 0x86, 0x48, 0x1, 0x65, 0x3, 0x4, 0x2, 0x3]): 'sha512'\n    }\n\n    def parse(self, value):\n        cert_id = value.getChild(0)\n        self.cert_hash_alg = cert_id.getChild(0).getChild(0).value\n        self.cert_issuer_name_hash = cert_id.getChild(1).value\n        self.cert_issuer_key_hash = cert_id.getChild(2).value\n        self.cert_serial_num = bytesToNumber(cert_id.getChild(3).value)\n        self.cert_status = value.getChild(1).value\n        self.this_update = value.getChild(2).value\n        # next_update is optional\n        try:\n            fld = value.getChild(3)\n            if fld.type.tag_id == 0:\n                self.next_update = fld.value\n        except SyntaxError:\n            self.next_update = None\n\n    def verify_cert_match(self, server_cert, issuer_cert):\n        # extact subject public key\n        issuer_key = issuer_cert.subject_public_key\n\n        # extract issuer DN\n        issuer_name = issuer_cert.subject\n\n        try:\n            alg = self._hash_algs_OIDs[tuple(self.cert_hash_alg)]\n        except KeyError as e:\n            raise TLSIllegalParameterException(\"Unknown hash algorithm: {0}\".format(\n                            list(self.cert_hash_alg)))\n\n        # hash issuer key\n        hashed_key = secureHash(issuer_key, alg)\n        if hashed_key != self.cert_issuer_key_hash:\n            raise ValueError(\"Could not verify certificate public key\")\n\n        # hash issuer name\n        hashed_name = secureHash(issuer_name, alg)\n        if hashed_name != self.cert_issuer_name_hash:\n            raise ValueError(\"Could not verify certificate DN\")\n\n        # serial number\n        if server_cert.serial_number != self.cert_serial_num:\n            raise ValueError(\"Could not verify certificate serial number\")\n        return True\n\n\nclass OCSPResponse(SignedObject):\n    \"\"\" This class represents an OCSP response. \"\"\"\n    def __init__(self, value):\n        super(OCSPResponse, self).__init__()\n        self.bytes = None\n        self.resp_status = None\n        self.resp_type = None\n        self.version = None\n        self.resp_id = None\n        self.produced_at = None\n        self.responses = []\n        self.certs = []\n        self.parse(value)\n\n    def parse(self, value):\n        \"\"\"\n        Parse a DER-encoded OCSP response.\n\n        :type value: stream of bytes\n        :param value: An DER-encoded OCSP response\n        \"\"\"\n        self.bytes = bytearray(value)\n        parser = ASN1Parser(self.bytes)\n        resp_status = parser.getChild(0)\n        self.resp_status = resp_status.value[0]\n        # if the response status is not successsful, abort parsing other fields\n        if self.resp_status != OCSPRespStatus.successful:\n            return self\n        resp_bytes = parser.getChild(1).getChild(0)\n        self.resp_type = resp_bytes.getChild(0).value\n        response = resp_bytes.getChild(1)\n        # check if response is id-pkix-ocsp-basic\n        if list(self.resp_type) != [43, 6, 1, 5, 5, 7, 48, 1, 1]:\n            raise SyntaxError()\n        basic_resp = response.getChild(0)\n        # parsing tbsResponseData fields\n        self._tbsdataparse(basic_resp.getChild(0))\n        self.tbs_data = basic_resp.getChildBytes(0)\n        self.signature_alg = basic_resp.getChild(1).getChild(0).value\n        self.signature = basic_resp.getChild(2).value\n        # test if certs field is present\n        if basic_resp.getChildCount() > 3:\n            certs = basic_resp.getChild(3)\n            cnt = certs.getChildCount()\n            for i in range(cnt):\n                certificate = X509()\n                certificate.parseBinary(certs.getChild(i).value)\n                self.certs.append(certificate)\n        return self\n\n    def _tbsdataparse(self, value):\n        \"\"\"\n        Parse to be signed data,\n\n        :type value: stream of bytes\n        :param value: TBS data\n        \"\"\"\n        # test if version is ommited\n        field = value.getChild(0)\n        cnt = 0\n        if field.type.tag_id == 0:\n            # version is not omitted\n            cnt += 1\n            self.version = field.value\n        else:\n            self.version = 1\n        self.resp_id = value.getChild(cnt).value\n        self.produced_at = value.getChild(cnt+1).value\n        responses = value.getChild(cnt+2)\n        resp_cnt = responses.getChildCount()\n        for i in range(resp_cnt):\n            resp = responses.getChild(i)\n            parsed_resp = SingleResponse(resp)\n            self.responses.append(parsed_resp)\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/recordlayer.py",
    "content": "# Copyright (c) 2014, Hubert Kario\n#\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Implementation of the TLS Record Layer protocol\"\"\"\n\nimport socket\nimport errno\nimport copy\ntry:\n    # in python 3 the native zip() returns iterator\n    from itertools import izip\nexcept ImportError:\n    izip = zip\ntry:\n    # in python 3 the native range() returns an object/iterator\n    xrange\nexcept NameError:\n    xrange = range\n\nfrom .utils import tlshashlib as hashlib\nfrom .constants import ContentType, CipherSuite\nfrom .messages import RecordHeader3, RecordHeader2, Message\nfrom .utils.cipherfactory import createAESCCM, createAESCCM_8, createAESGCM,\\\n        createAES, createRC4, createTripleDES, createCHACHA20\nfrom .utils.codec import Parser, Writer\nfrom .utils.compat import compatHMAC\nfrom .utils.cryptomath import getRandomBytes, MD5, HKDF_expand_label\nfrom .utils.constanttime import ct_compare_digest, ct_check_cbc_mac_and_pad\nfrom .errors import TLSRecordOverflow, TLSIllegalParameterException,\\\n        TLSAbruptCloseError, TLSDecryptionFailed, TLSBadRecordMAC, \\\n        TLSUnexpectedMessage\nfrom .mathtls import createMAC_SSL, createHMAC, calc_key\n\nclass RecordSocket(object):\n    \"\"\"\n    Socket wrapper for reading and writing TLS Records.\n\n    :ivar sock: wrapped socket\n    :ivar ~.version: version for the records to be encoded on the wire\n    :ivar tls13record: flag to indicate that TLS 1.3 specific record limits\n        should be used for received records\n    :ivar int recv_record_limit: negotiated maximum size of record plaintext\n        size\n    \"\"\"\n\n    def __init__(self, sock):\n        \"\"\"\n        Assign socket to wrapper\n\n        :type sock: socket.socket\n        \"\"\"\n        self.sock = sock\n        self.version = (0, 0)\n        self.tls13record = False\n        self.recv_record_limit = 2**14\n\n    def _sockSendAll(self, data):\n        \"\"\"\n        Send all data through socket\n\n        :type data: bytearray\n        :param data: data to send\n        :raises socket.error: when write to socket failed\n        \"\"\"\n        while 1:\n            try:\n                bytesSent = self.sock.send(data)\n            except socket.error as why:\n                if why.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):\n                    yield 1\n                    continue\n                raise\n\n            if bytesSent == len(data):\n                return\n            data = data[bytesSent:]\n            yield 1\n\n    def send(self, msg, padding=0):\n        \"\"\"\n        Send the message through socket.\n\n        :type msg: bytearray\n        :param msg: TLS message to send\n        :type padding: int\n        :param padding: amount of padding to specify for SSLv2\n        :raises socket.error: when write to socket failed\n        \"\"\"\n        data = msg.write()\n\n        if self.version in ((2, 0), (0, 2)):\n            header = RecordHeader2().create(len(data),\n                                            padding)\n        else:\n            header = RecordHeader3().create(self.version,\n                                            msg.contentType,\n                                            len(data))\n\n        data = header.write() + data\n\n        for result in self._sockSendAll(data):\n            yield result\n\n    def _sockRecvAll(self, length):\n        \"\"\"\n        Read exactly the amount of bytes specified in L{length} from raw socket.\n\n        :rtype: generator\n        :returns: generator that will return 0 or 1 in case the socket is non\n            blocking and would block and bytearray in case the read finished\n        :raises TLSAbruptCloseError: when the socket closed\n        \"\"\"\n        buf = bytearray(0)\n\n        if length == 0:\n            yield buf\n\n        while True:\n            try:\n                socketBytes = self.sock.recv(length - len(buf))\n            except socket.error as why:\n                if why.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):\n                    yield 0\n                    continue\n                else:\n                    raise\n\n            #if the connection closed, raise socket error\n            if len(socketBytes) == 0:\n                raise TLSAbruptCloseError()\n\n            buf += bytearray(socketBytes)\n            if len(buf) == length:\n                yield buf\n\n    def _recvHeader(self):\n        \"\"\"Read a single record header from socket\"\"\"\n        #Read the next record header\n        buf = bytearray(0)\n        ssl2 = False\n\n        result = None\n        for result in self._sockRecvAll(1):\n            if result in (0, 1):\n                yield result\n            else: break\n        assert result is not None\n\n        buf += result\n\n        if buf[0] in ContentType.all:\n            ssl2 = False\n            # SSLv3 record layer header is 5 bytes long, we already read 1\n            result = None\n            for result in self._sockRecvAll(4):\n                if result in (0, 1):\n                    yield result\n                else: break\n            assert result is not None\n            buf += result\n        else:\n            # if header has no pading the header is 2 bytes long, 3 otherwise\n            # at the same time we already read 1 byte\n            ssl2 = True\n            if buf[0] & 0x80:\n                readLen = 1\n            else:\n                readLen = 2\n            result = None\n            for result in self._sockRecvAll(readLen):\n                if result in (0, 1):\n                    yield result\n                else: break\n            assert result is not None\n            buf += result\n\n\n        #Parse the record header\n        if ssl2:\n            record = RecordHeader2().parse(Parser(buf))\n            # padding can't be longer than overall length and if it is present\n            # the overall size must be a multiple of cipher block size\n            if ((record.padding > record.length) or\n                    (record.padding and record.length % 8)):\n                raise TLSIllegalParameterException(\\\n                        \"Malformed record layer header\")\n        else:\n            record = RecordHeader3().parse(Parser(buf))\n\n        yield record\n\n    def recv(self):\n        \"\"\"\n        Read a single record from socket, handle SSLv2 and SSLv3 record layer\n\n        :rtype: generator\n        :returns: generator that returns 0 or 1 in case the read would be\n            blocking or a tuple containing record header (object) and record\n            data (bytearray) read from socket\n        :raises socket.error: In case of network error\n        :raises TLSAbruptCloseError: When the socket was closed on the other\n            side in middle of record receiving\n        :raises TLSRecordOverflow: When the received record was longer than\n            allowed by TLS\n        :raises TLSIllegalParameterException: When the record header was\n            malformed\n        \"\"\"\n        record = None\n        for record in self._recvHeader():\n            if record in (0, 1):\n                yield record\n            else: break\n        assert record is not None\n\n        #Check the record header fields\n        # 18432 = 2**14 (default record size limit) + 1024 (maximum compression\n        # overhead) + 1024 (maximum encryption overhead)\n        if record.length > self.recv_record_limit + 1024 + 1024:\n            raise TLSRecordOverflow()\n        if self.tls13record and record.length > self.recv_record_limit + 256:\n            raise TLSRecordOverflow()\n\n        #Read the record contents\n        buf = bytearray(0)\n\n        result = None\n        for result in self._sockRecvAll(record.length):\n            if result in (0, 1):\n                yield result\n            else: break\n        assert result is not None\n\n        buf += result\n\n        yield (record, buf)\n\n\nclass ConnectionState(object):\n\n    \"\"\"Preserve the connection state for reading and writing data to records\"\"\"\n\n    def __init__(self):\n        \"\"\"Create an instance with empty encryption and MACing contexts\"\"\"\n        self.macContext = None\n        self.encContext = None\n        self.fixedNonce = None\n        self.seqnum = 0\n        self.encryptThenMAC = False\n\n    def getSeqNumBytes(self):\n        \"\"\"Return encoded sequence number and increment it.\"\"\"\n        writer = Writer()\n        writer.add(self.seqnum, 8)\n        self.seqnum += 1\n        return writer.bytes\n\n    def __copy__(self):\n        \"\"\"Return a copy of the object.\"\"\"\n        ret = ConnectionState()\n        ret.macContext = copy.copy(self.macContext)\n        ret.encContext = copy.copy(self.encContext)\n        ret.fixedNonce = self.fixedNonce\n        ret.seqnum = self.seqnum\n        ret.encryptThenMAC = self.encryptThenMAC\n        return ret\n\n\nclass RecordLayer(object):\n\n    \"\"\"\n    Implementation of TLS record layer protocol\n\n    :ivar ~.version: the TLS version to use (tuple encoded as on the wire)\n    :ivar sock: underlying socket\n    :ivar client: whether the connection should use encryption\n    :ivar handshake_finished: used in SSL2, True if handshake protocol is over\n    :ivar tls13record: if True, the record layer will use the TLS 1.3 version\n        and content type hiding\n    :ivar bool early_data_ok: if True, it's ok to ignore undecryptable records\n        up to the size of max_early_data (sum of payloads)\n    :ivar int max_early_data: maximum number of bytes that will be processed\n        before aborting the connection on data that can not be validated,\n        works only if early_data_ok is set to True\n    :ivar callable padding_cb: callback used for calculating the size of\n        padding to add in TLSv1.3 records\n    :ivar int send_record_limit: hint provided to padding callback to not\n        generate records larger than the receiving size expects\n    :ivar int recv_record_limit: negotiated size of records we are willing to\n        accept, TLSRecordOverflow will be raised when records with larger\n        plaintext size are received (in TLS 1.3 padding is included in this\n        size but encrypted content type is not)\n    \"\"\"\n\n    def __init__(self, sock):\n        self.sock = sock\n        self._recordSocket = RecordSocket(sock)\n        self._version = (0, 0)\n        self._tls13record = False\n\n        self.client = True\n\n        self._writeState = ConnectionState()\n        self._readState = ConnectionState()\n        self._pendingWriteState = ConnectionState()\n        self._pendingReadState = ConnectionState()\n        self.fixedIVBlock = None\n\n        self.handshake_finished = False\n\n        self.padding_cb = None\n\n        self._early_data_ok = False\n        self.max_early_data = 0\n        self._early_data_processed = 0\n        self.send_record_limit = 2**14\n\n    @property\n    def recv_record_limit(self):\n        \"\"\"Maximum record size that is permitted for receiving.\"\"\"\n        return self._recordSocket.recv_record_limit\n\n    @recv_record_limit.setter\n    def recv_record_limit(self, value):\n        self._recordSocket.recv_record_limit = value\n\n    @property\n    def early_data_ok(self):\n        \"\"\"\n        Set or get the state of early data acceptability.\n\n        If processing of the early_data records is to suceed, even if the\n        encryption is not correct, set this property to True. It will be\n        automatically reset to False as soon as a decryptable record is\n        processed.\n\n        Use max_early_data to set the limit of the total size of records\n        that will be processed like this.\n        \"\"\"\n        return self._early_data_ok\n\n    @early_data_ok.setter\n    def early_data_ok(self, val):\n        self._early_data_processed = 0\n        self._early_data_ok = val\n\n    @property\n    def encryptThenMAC(self):\n        \"\"\"\n        Set or get the setting of Encrypt Then MAC mechanism.\n\n        set the encrypt-then-MAC mechanism for record\n        integrity for next parameter change (after CCS),\n        gets current state\n        \"\"\"\n        return self._writeState.encryptThenMAC\n\n    @encryptThenMAC.setter\n    def encryptThenMAC(self, value):\n        self._pendingWriteState.encryptThenMAC = value\n        self._pendingReadState.encryptThenMAC = value\n\n    @property\n    def blockSize(self):\n        \"\"\"Return the size of block used by current symmetric cipher (R/O)\"\"\"\n        return self._writeState.encContext.block_size\n\n    @property\n    def tls13record(self):\n        \"\"\"Return the value of the tls13record state.\"\"\"\n        return self._tls13record\n\n    @tls13record.setter\n    def tls13record(self, val):\n        \"\"\"Change the record layer to TLS1.3-like operation, if applicable.\"\"\"\n        self._tls13record = val\n        self._recordSocket.tls13record = val\n        self._handle_tls13_record()\n\n    def _is_tls13_plus(self):\n        \"\"\"Returns True if we're doing real TLS 1.3.\"\"\"\n        return self._version > (3, 3) and self._tls13record\n\n    def _handle_tls13_record(self):\n        \"\"\"Make sure that the version and tls13record setting is consistent.\"\"\"\n        if self._is_tls13_plus():\n            # in TLS 1.3 all records need to be sent with the generic version\n            # which is the same as TLS 1.2\n            self._recordSocket.version = (3, 3)\n        else:\n            self._recordSocket.version = self._version\n\n    @property\n    def version(self):\n        \"\"\"Return the TLS version used by record layer\"\"\"\n        return self._version\n\n    @version.setter\n    def version(self, val):\n        \"\"\"Set the TLS version used by record layer\"\"\"\n        self._version = val\n        self._handle_tls13_record()\n\n    def getCipherName(self):\n        \"\"\"\n        Return the name of the bulk cipher used by this connection\n\n        :rtype: str\n        :returns: The name of the cipher, like 'aes128', 'rc4', etc.\n        \"\"\"\n        if self._writeState.encContext is None:\n            return None\n        return self._writeState.encContext.name\n\n    def getCipherImplementation(self):\n        \"\"\"\n        Return the name of the implementation used for the connection\n\n        'python' for tlslite internal implementation, 'openssl' for M2crypto\n        and 'pycrypto' for pycrypto\n        :rtype: str\n        :returns: Name of cipher implementation used, None if not initialised\n        \"\"\"\n        if self._writeState.encContext is None:\n            return None\n        return self._writeState.encContext.implementation\n\n    def shutdown(self):\n        \"\"\"Clear read and write states\"\"\"\n        self._writeState = ConnectionState()\n        self._readState = ConnectionState()\n        self._pendingWriteState = ConnectionState()\n        self._pendingReadState = ConnectionState()\n\n    def isCBCMode(self):\n        \"\"\"Returns true if cipher uses CBC mode\"\"\"\n        if self._writeState and self._writeState.encContext and \\\n                self._writeState.encContext.isBlockCipher:\n            return True\n        else:\n            return False\n    #\n    # sending messages\n    #\n\n    def addPadding(self, data):\n        \"\"\"Add padding to data so that it is multiple of block size\"\"\"\n        currentLength = len(data)\n        blockLength = self.blockSize\n        paddingLength = blockLength - 1 - (currentLength % blockLength)\n\n        paddingBytes = bytearray([paddingLength] * (paddingLength+1))\n        data += paddingBytes\n        return data\n\n    def calculateMAC(self, mac, seqnumBytes, contentType, data):\n        \"\"\"Calculate the SSL/TLS version of a MAC\"\"\"\n        mac.update(compatHMAC(seqnumBytes))\n        mac.update(compatHMAC(bytearray([contentType])))\n        assert self.version in ((3, 0), (3, 1), (3, 2), (3, 3))\n        if self.version != (3, 0):\n            mac.update(compatHMAC(bytearray([self.version[0]])))\n            mac.update(compatHMAC(bytearray([self.version[1]])))\n        mac.update(compatHMAC(bytearray([len(data)//256])))\n        mac.update(compatHMAC(bytearray([len(data)%256])))\n        mac.update(compatHMAC(data))\n        return bytearray(mac.digest())\n\n    def _macThenEncrypt(self, data, contentType):\n        \"\"\"MAC, pad then encrypt data\"\"\"\n        if self._writeState.macContext:\n            seqnumBytes = self._writeState.getSeqNumBytes()\n            mac = self._writeState.macContext.copy()\n            macBytes = self.calculateMAC(mac, seqnumBytes, contentType, data)\n            data += macBytes\n\n        #Encrypt for Block or Stream Cipher\n        if self._writeState.encContext:\n            #Add padding (for Block Cipher):\n            if self._writeState.encContext.isBlockCipher:\n\n                #Add TLS 1.1 fixed block\n                if self.version >= (3, 2):\n                    data = self.fixedIVBlock + data\n\n                data = self.addPadding(data)\n\n            #Encrypt\n            data = self._writeState.encContext.encrypt(data)\n\n        return data\n\n    def _encryptThenMAC(self, buf, contentType):\n        \"\"\"Pad, encrypt and then MAC the data\"\"\"\n        if self._writeState.encContext:\n            # add IV for TLS1.1+\n            if self.version >= (3, 2):\n                buf = self.fixedIVBlock + buf\n\n            buf = self.addPadding(buf)\n\n            buf = self._writeState.encContext.encrypt(buf)\n\n        # add MAC\n        if self._writeState.macContext:\n            seqnumBytes = self._writeState.getSeqNumBytes()\n            mac = self._writeState.macContext.copy()\n\n            # append MAC\n            macBytes = self.calculateMAC(mac, seqnumBytes, contentType, buf)\n            buf += macBytes\n\n        return buf\n\n    def _getNonce(self, state, seqnum):\n        \"\"\"Calculate a nonce for a given enc/dec context\"\"\"\n        # ChaCha is using the draft-TLS1.3-like nonce derivation\n        if (state.encContext.name == \"chacha20-poly1305\" and\n                len(state.fixedNonce) == 12) or self._is_tls13_plus():\n            # 4 byte nonce is used by the draft cipher\n            pad = bytearray(len(state.fixedNonce) - len(seqnum))\n            nonce = bytearray(i ^ j for i, j in zip(pad + seqnum,\n                                                    state.fixedNonce))\n        else:\n            nonce = state.fixedNonce + seqnum\n        return nonce\n\n\n    def _encryptThenSeal(self, buf, contentType):\n        \"\"\"Encrypt with AEAD cipher\"\"\"\n        #Assemble the authenticated data.\n        seqNumBytes = self._writeState.getSeqNumBytes()\n        if not self._is_tls13_plus():\n            authData = seqNumBytes + bytearray([contentType,\n                                                self.version[0],\n                                                self.version[1],\n                                                len(buf)//256,\n                                                len(buf)%256])\n        else:  # TLS 1.3\n            out_len = len(buf) + self._writeState.encContext.tagLength\n            # this is just recreated Record Layer header\n            authData = bytearray([contentType,\n                                  self._recordSocket.version[0],\n                                  self._recordSocket.version[1],\n                                  out_len // 256, out_len % 256])\n\n        nonce = self._getNonce(self._writeState, seqNumBytes)\n\n        assert len(nonce) == self._writeState.encContext.nonceLength\n\n        buf = self._writeState.encContext.seal(nonce, buf, authData)\n\n        #AES-GCM, has an explicit variable nonce.\n        if \"aes\" in self._writeState.encContext.name and \\\n                not self._is_tls13_plus():\n            buf = seqNumBytes + buf\n\n        return buf\n\n    def _ssl2Encrypt(self, data):\n        \"\"\"Encrypt in SSL2 mode\"\"\"\n        # in SSLv2 sequence numbers are incremented for plaintext records too\n        seqnumBytes = self._writeState.getSeqNumBytes()\n\n        if (self._writeState.encContext and\n                self._writeState.encContext.isBlockCipher):\n            plaintext_len = len(data)\n            data = self.addPadding(data)\n            padding = len(data) - plaintext_len\n        else:\n            padding = 0\n\n        if self._writeState.macContext:\n            mac = self._writeState.macContext.copy()\n            mac.update(compatHMAC(data))\n            mac.update(compatHMAC(seqnumBytes[-4:]))\n\n            data = bytearray(mac.digest()) + data\n\n        if self._writeState.encContext:\n            data = self._writeState.encContext.encrypt(data)\n\n        return data, padding\n\n    def sendRecord(self, msg):\n        \"\"\"\n        Encrypt, MAC and send arbitrary message as-is through socket.\n\n        Note that if the message was not fragmented to below 2**14 bytes\n        it will be rejected by the other connection side.\n\n        :param msg: TLS message to send\n        :type msg: ApplicationData, HandshakeMessage, etc.\n        \"\"\"\n        data = msg.write()\n        contentType = msg.contentType\n\n        # TLS 1.3 hides the content type of messages\n        # but CCS is always not encrypted\n        if self._is_tls13_plus() and self._writeState.encContext and \\\n                contentType != ContentType.change_cipher_spec:\n            data += bytearray([contentType])\n            if self.padding_cb:\n                max_padding = self.send_record_limit - len(data) - 1\n                # add number of zero bytes specified by padding_cb()\n                data += bytearray(self.padding_cb(len(data),\n                                                  contentType,\n                                                  max_padding))\n            # in TLS 1.3 contentType is ignored by _encryptThenSeal\n            contentType = ContentType.application_data\n\n        padding = 0\n        if self.version in ((0, 2), (2, 0)):\n            data, padding = self._ssl2Encrypt(data)\n        elif self.version > (3, 3) and \\\n                contentType == ContentType.change_cipher_spec:\n            # TLS 1.3 does not encrypt CCS messages\n            pass\n        elif self._writeState.encContext and \\\n                self._writeState.encContext.isAEAD:\n            data = self._encryptThenSeal(data, contentType)\n        elif self._writeState.encryptThenMAC:\n            data = self._encryptThenMAC(data, contentType)\n        else:\n            data = self._macThenEncrypt(data, contentType)\n\n        encryptedMessage = Message(contentType, data)\n\n        for result in self._recordSocket.send(encryptedMessage, padding):\n            yield result\n\n    #\n    # receiving messages\n    #\n\n    def _decryptStreamThenMAC(self, recordType, data):\n        \"\"\"Decrypt a stream cipher and check MAC\"\"\"\n        if self._readState.encContext:\n            assert self.version in ((3, 0), (3, 1), (3, 2), (3, 3))\n\n            data = self._readState.encContext.decrypt(data)\n\n        if self._readState.macContext:\n            #Check MAC\n            macGood = True\n            macLength = self._readState.macContext.digest_size\n            endLength = macLength\n            if endLength > len(data):\n                macGood = False\n            else:\n                #Read MAC\n                startIndex = len(data) - endLength\n                endIndex = startIndex + macLength\n                checkBytes = data[startIndex : endIndex]\n\n                #Calculate MAC\n                seqnumBytes = self._readState.getSeqNumBytes()\n                data = data[:-endLength]\n                mac = self._readState.macContext.copy()\n                macBytes = self.calculateMAC(mac, seqnumBytes, recordType,\n                                             data)\n\n                #Compare MACs\n                if not ct_compare_digest(macBytes, checkBytes):\n                    macGood = False\n\n            if not macGood:\n                raise TLSBadRecordMAC()\n\n        return data\n\n\n    def _decryptThenMAC(self, recordType, data):\n        \"\"\"Decrypt data, check padding and MAC\"\"\"\n        if self._readState.encContext:\n            assert self.version in ((3, 0), (3, 1), (3, 2), (3, 3))\n            assert self._readState.encContext.isBlockCipher\n            assert self._readState.macContext\n\n            #\n            # decrypt the record\n            #\n            blockLength = self._readState.encContext.block_size\n            if len(data) % blockLength != 0:\n                raise TLSDecryptionFailed()\n            data = self._readState.encContext.decrypt(data)\n            if self.version >= (3, 2): #For TLS 1.1, remove explicit IV\n                data = data[self._readState.encContext.block_size : ]\n\n            #\n            # check padding and MAC\n            #\n            seqnumBytes = self._readState.getSeqNumBytes()\n\n            if not ct_check_cbc_mac_and_pad(\n                    data,\n                    self._readState.macContext,\n                    seqnumBytes,\n                    recordType,\n                    self.version,\n                    self._readState.encContext.block_size):\n                raise TLSBadRecordMAC()\n\n            #\n            # strip padding and MAC\n            #\n\n            endLength = data[-1] + 1 + self._readState.macContext.digest_size\n\n            data = data[:-endLength]\n\n        return data\n\n    def _macThenDecrypt(self, recordType, buf):\n        \"\"\"\n        Check MAC of data, then decrypt and remove padding\n\n        :raises TLSBadRecordMAC: when the mac value is invalid\n        :raises TLSDecryptionFailed: when the data to decrypt has invalid size\n        \"\"\"\n        if self._readState.macContext:\n            macLength = self._readState.macContext.digest_size\n            if len(buf) < macLength:\n                raise TLSBadRecordMAC(\"Truncated data\")\n\n            checkBytes = buf[-macLength:]\n            buf = buf[:-macLength]\n\n            seqnumBytes = self._readState.getSeqNumBytes()\n            mac = self._readState.macContext.copy()\n\n            macBytes = self.calculateMAC(mac, seqnumBytes, recordType, buf)\n\n            if not ct_compare_digest(macBytes, checkBytes):\n                raise TLSBadRecordMAC(\"MAC mismatch\")\n\n        if self._readState.encContext:\n            blockLength = self._readState.encContext.block_size\n            if len(buf) % blockLength != 0:\n                raise TLSDecryptionFailed(\"data length not multiple of \"\\\n                                          \"block size\")\n\n            buf = self._readState.encContext.decrypt(buf)\n\n            # remove explicit IV\n            if self.version >= (3, 2):\n                buf = buf[blockLength:]\n\n            if len(buf) == 0:\n                raise TLSBadRecordMAC(\"No data left after IV removal\")\n\n            # check padding\n            paddingLength = buf[-1]\n            if paddingLength + 1 > len(buf):\n                raise TLSBadRecordMAC(\"Invalid padding length\")\n\n            paddingGood = True\n            totalPaddingLength = paddingLength+1\n            if self.version != (3, 0):\n                paddingBytes = buf[-totalPaddingLength:-1]\n                for byte in paddingBytes:\n                    if byte != paddingLength:\n                        paddingGood = False\n\n            if not paddingGood:\n                raise TLSBadRecordMAC(\"Invalid padding byte values\")\n\n            # remove padding\n            buf = buf[:-totalPaddingLength]\n\n        return buf\n\n    def _decryptAndUnseal(self, header, buf):\n        \"\"\"Decrypt AEAD encrypted data\"\"\"\n        seqnumBytes = self._readState.getSeqNumBytes()\n        # AES-GCM has an explicit variable nonce in TLS 1.2\n        if \"aes\" in self._readState.encContext.name and \\\n                not self._is_tls13_plus():\n            explicitNonceLength = 8\n            if explicitNonceLength > len(buf):\n                #Publicly invalid.\n                raise TLSBadRecordMAC(\"Truncated nonce\")\n            nonce = self._readState.fixedNonce + buf[:explicitNonceLength]\n            buf = buf[8:]\n        else:\n            # for TLS 1.3 and Chacha20 in TLS 1.2 share nonce generation\n            # algorithm\n            nonce = self._getNonce(self._readState, seqnumBytes)\n\n        if self._readState.encContext.tagLength > len(buf):\n            #Publicly invalid.\n            raise TLSBadRecordMAC(\"Truncated tag\")\n\n        if not self._is_tls13_plus():\n            plaintextLen = len(buf) - self._readState.encContext.tagLength\n            authData = seqnumBytes + bytearray([header.type, self.version[0],\n                                                self.version[1],\n                                                plaintextLen//256,\n                                                plaintextLen%256])\n        else:  # TLS 1.3\n            # enforce the checks for encrypted records\n            if header.type != ContentType.application_data:\n                raise TLSUnexpectedMessage(\n                    \"Invalid ContentType for encrypted record: {0}\"\n                    .format(ContentType.toStr(header.type)))\n            if header.version != (3, 3):\n                raise TLSIllegalParameterException(\n                    \"Unexpected version in encrypted record: {0}\"\n                    .format(header.version))\n            if header.length != len(buf):\n                raise TLSBadRecordMAC(\"Length mismatch\")\n            authData = header.write()\n\n        buf = self._readState.encContext.open(nonce, buf, authData)\n        if buf is None:\n            raise TLSBadRecordMAC(\"Invalid tag, decryption failure\")\n        return buf\n\n    def _decryptSSL2(self, data, padding):\n        \"\"\"Decrypt SSL2 encrypted data\"\"\"\n        # sequence numbers are incremented for plaintext records too\n        seqnumBytes = self._readState.getSeqNumBytes()\n\n        #\n        # decrypt\n        #\n        if self._readState.encContext:\n            if self._readState.encContext.isBlockCipher:\n                blockLength = self._readState.encContext.block_size\n                if len(data) % blockLength:\n                    raise TLSDecryptionFailed()\n            data = self._readState.encContext.decrypt(data)\n\n        #\n        # strip and check MAC\n        #\n        if self._readState.macContext:\n            macBytes = data[:16]\n            data = data[16:]\n\n            mac = self._readState.macContext.copy()\n            mac.update(compatHMAC(data))\n            mac.update(compatHMAC(seqnumBytes[-4:]))\n            calcMac = bytearray(mac.digest())\n            if macBytes != calcMac:\n                raise TLSBadRecordMAC()\n\n        #\n        # strip padding\n        #\n        if padding:\n            data = data[:-padding]\n        return data\n\n    @staticmethod\n    def _tls13_de_pad(data):\n        \"\"\"\n        Remove the padding and extract content type from TLSInnerPlaintext.\n\n        :param bytearray data: decrypted plaintext TLS 1.3 record payload\n            (the serialised TLSInnerPlaintext data structure)\n\n        :rtype: tuple\n        \"\"\"\n        # the padding is at the end and the first non-zero byte is the\n        # padding\n        # could be reversed(enumerate(data)), if that worked at all\n        # could be reversed(list(enumerate(data))), if that didn't double\n        # memory usage\n        for pos, value in izip(reversed(xrange(len(data))), reversed(data)):\n            if value != 0:\n                break\n        else:\n            raise TLSUnexpectedMessage(\"Malformed record layer inner plaintext\"\n                                       \" - content type missing\")\n\n        return data[:pos], value\n\n    def recvRecord(self):\n        \"\"\"\n        Read, decrypt and check integrity of a single record\n\n        :rtype: tuple\n        :returns: message header and decrypted message payload\n        :raises TLSDecryptionFailed: when decryption of data failed\n        :raises TLSBadRecordMAC: when record has bad MAC or padding\n        :raises socket.error: when reading from socket was unsuccessful\n        :raises TLSRecordOverflow: when the received record was longer than\n            allowed by negotiated version of TLS\n        \"\"\"\n        while True:\n            result = None\n            for result in self._recordSocket.recv():\n                if result in (0, 1):\n                    yield result\n                else: break\n            assert result is not None\n\n            (header, data) = result\n            # as trying decryption increments sequence number, we need to\n            # keep the old one (we do copy of the whole object in case\n            # some cipher has an internal state itself)\n            read_state_copy = None\n            if self.early_data_ok:\n                # do the copy only when needed\n                read_state_copy = copy.copy(self._readState)\n\n            try:\n                if isinstance(header, RecordHeader2):\n                    data = self._decryptSSL2(data, header.padding)\n                    if self.handshake_finished:\n                        header.type = ContentType.application_data\n                # in TLS 1.3, the other party may send an unprotected CCS\n                # message at any point in connection\n                elif self._is_tls13_plus() and \\\n                        header.type == ContentType.change_cipher_spec:\n                    pass\n                elif self._readState and \\\n                    self._readState.encContext and \\\n                    self._readState.encContext.isAEAD:\n                    data = self._decryptAndUnseal(header, data)\n                elif self._readState and self._readState.encryptThenMAC:\n                    data = self._macThenDecrypt(header.type, data)\n                elif self._readState and \\\n                        self._readState.encContext and \\\n                        self._readState.encContext.isBlockCipher:\n                    data = self._decryptThenMAC(header.type, data)\n                else:\n                    data = self._decryptStreamThenMAC(header.type, data)\n                # if we don't have an encryption context established\n                # and early data is ok, that means we have received\n                # encrypted record in case the type of record is\n                # application_data (from TLS 1.3)\n                if not self._readState.encContext \\\n                        and not self._readState.macContext \\\n                        and self.early_data_ok and \\\n                        header.type == ContentType.application_data:\n                    raise TLSBadRecordMAC(\"early data received\")\n            except TLSBadRecordMAC:\n                if self.early_data_ok and (\n                        self._early_data_processed + len(data)\n                        < self.max_early_data):\n                    # ignore exception, retry reading\n                    self._early_data_processed += len(data)\n                    # reload state for decryption\n                    self._readState = read_state_copy\n                    continue\n                raise\n            # as soon as we're able to decrypt messages again, we must\n            # start checking the MACs\n            self.early_data_ok = False\n\n            # TLS 1.3 encrypts the type, CCS is not encrypted\n            if self._is_tls13_plus() and self._readState and \\\n                    self._readState.encContext and\\\n                    header.type != ContentType.change_cipher_spec:\n                # check if plaintext is not too big, RFC 8446, section 5.4\n                if len(data) > self.recv_record_limit + 1:\n                    raise TLSRecordOverflow()\n                data, contentType = self._tls13_de_pad(data)\n                header = RecordHeader3().create((3, 4), contentType, len(data))\n\n            # RFC 5246, section 6.2.1\n            if len(data) > self.recv_record_limit:\n                raise TLSRecordOverflow()\n\n            yield (header, Parser(data))\n\n    #\n    # cryptography state methods\n    #\n\n    def changeWriteState(self):\n        \"\"\"\n        Change the cipher state to the pending one for write operations.\n\n        This should be done only once after a call to\n        :py:meth:`calcPendingStates` was\n        performed and directly after sending a :py:class:`ChangeCipherSpec`\n        message.\n        \"\"\"\n        if self.version in ((0, 2), (2, 0)):\n            # in SSLv2 sequence numbers carry over from plaintext to encrypted\n            # context\n            self._pendingWriteState.seqnum = self._writeState.seqnum\n        self._writeState = self._pendingWriteState\n        self._pendingWriteState = ConnectionState()\n\n    def changeReadState(self):\n        \"\"\"\n        Change the cipher state to the pending one for read operations.\n\n        This should be done only once after a call to\n        :py:meth:`calcPendingStates` was\n        performed and directly after receiving a :py:class:`ChangeCipherSpec`\n        message.\n        \"\"\"\n        if self.version in ((0, 2), (2, 0)):\n            # in SSLv2 sequence numbers carry over from plaintext to encrypted\n            # context\n            self._pendingReadState.seqnum = self._readState.seqnum\n        self._readState = self._pendingReadState\n        self._pendingReadState = ConnectionState()\n\n    @staticmethod\n    def _getCipherSettings(cipherSuite):\n        \"\"\"Get the settings for cipher suite used\"\"\"\n        if cipherSuite in CipherSuite.aes256GcmSuites:\n            keyLength = 32\n            ivLength = 4\n            createCipherFunc = createAESGCM\n        elif cipherSuite in CipherSuite.aes128GcmSuites:\n            keyLength = 16\n            ivLength = 4\n            createCipherFunc = createAESGCM\n        elif cipherSuite in CipherSuite.aes256Ccm_8Suites:\n            keyLength = 32\n            ivLength = 4\n            createCipherFunc = createAESCCM_8\n        elif cipherSuite in CipherSuite.aes256CcmSuites:\n            keyLength = 32\n            ivLength = 4\n            createCipherFunc = createAESCCM\n        elif cipherSuite in CipherSuite.aes128Ccm_8Suites:\n            keyLength = 16\n            ivLength = 4\n            createCipherFunc = createAESCCM_8\n        elif cipherSuite in CipherSuite.aes128CcmSuites:\n            keyLength = 16\n            ivLength = 4\n            createCipherFunc = createAESCCM\n        elif cipherSuite in CipherSuite.chacha20Suites:\n            keyLength = 32\n            ivLength = 12\n            createCipherFunc = createCHACHA20\n        elif cipherSuite in CipherSuite.chacha20draft00Suites:\n            keyLength = 32\n            ivLength = 4\n            createCipherFunc = createCHACHA20\n        elif cipherSuite in CipherSuite.aes128Suites:\n            keyLength = 16\n            ivLength = 16\n            createCipherFunc = createAES\n        elif cipherSuite in CipherSuite.aes256Suites:\n            keyLength = 32\n            ivLength = 16\n            createCipherFunc = createAES\n        elif cipherSuite in CipherSuite.rc4Suites:\n            keyLength = 16\n            ivLength = 0\n            createCipherFunc = createRC4\n        elif cipherSuite in CipherSuite.tripleDESSuites:\n            keyLength = 24\n            ivLength = 8\n            createCipherFunc = createTripleDES\n        elif cipherSuite in CipherSuite.nullSuites:\n            keyLength = 0\n            ivLength = 0\n            createCipherFunc = None\n        else:\n            raise AssertionError()\n\n        return (keyLength, ivLength, createCipherFunc)\n\n    @staticmethod\n    def _getMacSettings(cipherSuite):\n        \"\"\"Get settings for HMAC used\"\"\"\n        if cipherSuite in CipherSuite.aeadSuites:\n            macLength = 0\n            digestmod = None\n        elif cipherSuite in CipherSuite.shaSuites:\n            macLength = 20\n            digestmod = hashlib.sha1\n        elif cipherSuite in CipherSuite.sha256Suites:\n            macLength = 32\n            digestmod = hashlib.sha256\n        elif cipherSuite in CipherSuite.sha384Suites:\n            macLength = 48\n            digestmod = hashlib.sha384\n        elif cipherSuite in CipherSuite.md5Suites:\n            macLength = 16\n            digestmod = hashlib.md5\n        else:\n            raise AssertionError()\n\n        return macLength, digestmod\n\n    @staticmethod\n    def _getHMACMethod(version):\n        \"\"\"Get the HMAC method\"\"\"\n        assert version in ((3, 0), (3, 1), (3, 2), (3, 3))\n        if version == (3, 0):\n            createMACFunc = createMAC_SSL\n        elif version in ((3, 1), (3, 2), (3, 3)):\n            createMACFunc = createHMAC\n\n        return createMACFunc\n\n    def calcSSL2PendingStates(self, cipherSuite, masterSecret, clientRandom,\n                              serverRandom, implementations):\n        \"\"\"\n        Create the keys for encryption and decryption in SSLv2\n\n        While we could reuse calcPendingStates(), we need to provide the\n        key-arg data for the server that needs to be passed up to handshake\n        protocol.\n        \"\"\"\n        if cipherSuite in CipherSuite.ssl2_128Key:\n            key_length = 16\n        elif cipherSuite in CipherSuite.ssl2_192Key:\n            key_length = 24\n        elif cipherSuite in CipherSuite.ssl2_64Key:\n            key_length = 8\n        else:\n            raise ValueError(\"Unknown cipher specified\")\n\n        key_material = bytearray(key_length * 2)\n        md5_output_size = 16\n        for i, pos in enumerate(range(0, key_length * 2, md5_output_size)):\n            key_material[pos:pos+md5_output_size] = MD5(\\\n                    masterSecret +\n                    bytearray(str(i), \"ascii\") +\n                    clientRandom + serverRandom)\n\n        serverWriteKey = key_material[:key_length]\n        clientWriteKey = key_material[key_length:]\n\n        # specification draft says that DES key should not use the\n        # incrementing label but all implementations use it anyway\n        #elif cipherSuite in CipherSuite.ssl2_64Key:\n        #    key_material = MD5(masterSecret + clientRandom + serverRandom)\n        #    serverWriteKey = key_material[0:8]\n        #    clientWriteKey = key_material[8:16]\n\n        # RC4 cannot use initialisation vector\n        if cipherSuite not in CipherSuite.ssl2rc4:\n            iv = getRandomBytes(8)\n        else:\n            iv = bytearray(0)\n\n        clientPendingState = ConnectionState()\n        serverPendingState = ConnectionState()\n\n        # MAC\n        clientPendingState.macContext = hashlib.md5()\n        clientPendingState.macContext.update(compatHMAC(clientWriteKey))\n        serverPendingState.macContext = hashlib.md5()\n        serverPendingState.macContext.update(compatHMAC(serverWriteKey))\n\n        # ciphers\n        if cipherSuite in CipherSuite.ssl2rc4:\n            cipherMethod = createRC4\n        elif cipherSuite in CipherSuite.ssl2_3des:\n            cipherMethod = createTripleDES\n        else:\n            raise NotImplementedError(\"Unknown cipher\")\n\n        clientPendingState.encContext = cipherMethod(clientWriteKey, iv,\n                                                     implementations)\n        serverPendingState.encContext = cipherMethod(serverWriteKey, iv,\n                                                     implementations)\n\n        # Assign new connection states to pending states\n        if self.client:\n            self._pendingWriteState = clientPendingState\n            self._pendingReadState = serverPendingState\n        else:\n            self._pendingWriteState = serverPendingState\n            self._pendingReadState = clientPendingState\n\n        return iv\n\n    def calcPendingStates(self, cipherSuite, masterSecret, clientRandom,\n                          serverRandom, implementations):\n        \"\"\"Create pending states for encryption and decryption.\"\"\"\n        keyLength, ivLength, createCipherFunc = \\\n                self._getCipherSettings(cipherSuite)\n\n        macLength, digestmod = self._getMacSettings(cipherSuite)\n\n        if not digestmod:\n            createMACFunc = None\n        else:\n            createMACFunc = self._getHMACMethod(self.version)\n\n        outputLength = (macLength*2) + (keyLength*2) + (ivLength*2)\n\n        #Calculate Keying Material from Master Secret\n        keyBlock = calc_key(self.version, masterSecret, cipherSuite,\n                            b\"key expansion\", client_random=clientRandom,\n                            server_random=serverRandom,\n                            output_length=outputLength)\n\n        #Slice up Keying Material\n        clientPendingState = ConnectionState()\n        serverPendingState = ConnectionState()\n        parser = Parser(keyBlock)\n        clientMACBlock = parser.getFixBytes(macLength)\n        serverMACBlock = parser.getFixBytes(macLength)\n        clientKeyBlock = parser.getFixBytes(keyLength)\n        serverKeyBlock = parser.getFixBytes(keyLength)\n        clientIVBlock = parser.getFixBytes(ivLength)\n        serverIVBlock = parser.getFixBytes(ivLength)\n\n        if digestmod:\n            # Legacy cipher\n            clientPendingState.macContext = createMACFunc(\n                compatHMAC(clientMACBlock), digestmod=digestmod)\n            serverPendingState.macContext = createMACFunc(\n                compatHMAC(serverMACBlock), digestmod=digestmod)\n            if createCipherFunc is not None:\n                clientPendingState.encContext = \\\n                                            createCipherFunc(clientKeyBlock,\n                                                             clientIVBlock,\n                                                             implementations)\n                serverPendingState.encContext = \\\n                                            createCipherFunc(serverKeyBlock,\n                                                             serverIVBlock,\n                                                             implementations)\n        else:\n            # AEAD\n            clientPendingState.macContext = None\n            serverPendingState.macContext = None\n            clientPendingState.encContext = createCipherFunc(clientKeyBlock,\n                                                             implementations)\n            serverPendingState.encContext = createCipherFunc(serverKeyBlock,\n                                                             implementations)\n            clientPendingState.fixedNonce = clientIVBlock\n            serverPendingState.fixedNonce = serverIVBlock\n\n        #Assign new connection states to pending states\n        if self.client:\n            clientPendingState.encryptThenMAC = \\\n                    self._pendingWriteState.encryptThenMAC\n            self._pendingWriteState = clientPendingState\n            serverPendingState.encryptThenMAC = \\\n                    self._pendingReadState.encryptThenMAC\n            self._pendingReadState = serverPendingState\n        else:\n            serverPendingState.encryptThenMAC = \\\n                    self._pendingWriteState.encryptThenMAC\n            self._pendingWriteState = serverPendingState\n            clientPendingState.encryptThenMAC = \\\n                    self._pendingReadState.encryptThenMAC\n            self._pendingReadState = clientPendingState\n\n        if self.version >= (3, 2) and ivLength:\n            #Choose fixedIVBlock for TLS 1.1 (this is encrypted with the CBC\n            #residue to create the IV for each sent block)\n            self.fixedIVBlock = getRandomBytes(ivLength)\n\n    def calcTLS1_3PendingState(self, cipherSuite, cl_traffic_secret,\n                               sr_traffic_secret,\n                               implementations):\n        \"\"\"\n        Create pending state for encryption in TLS 1.3.\n\n        :param int cipherSuite: cipher suite that will be used for encrypting\n            and decrypting data\n        :param bytearray cl_traffic_secret: Client Traffic Secret, either\n            handshake secret or application data secret\n        :param bytearray sr_traffic_secret: Server Traffic Secret, either\n            handshake secret or application data secret\n        :param list implementations: list of names of implementations that\n            are permitted for the connection\n        \"\"\"\n        prf_name = 'sha384' if cipherSuite \\\n                   in CipherSuite.sha384PrfSuites \\\n                   else 'sha256'\n\n        key_length, iv_length, cipher_func = \\\n            self._getCipherSettings(cipherSuite)\n        iv_length = 12\n\n        clientPendingState = ConnectionState()\n        serverPendingState = ConnectionState()\n\n        clientPendingState.macContext = None\n        clientPendingState.encContext = \\\n            cipher_func(HKDF_expand_label(cl_traffic_secret,\n                                          b\"key\", b\"\",\n                                          key_length,\n                                          prf_name),\n                        implementations)\n        clientPendingState.fixedNonce = HKDF_expand_label(cl_traffic_secret,\n                                                          b\"iv\", b\"\",\n                                                          iv_length,\n                                                          prf_name)\n\n        serverPendingState.macContext = None\n        serverPendingState.encContext = \\\n            cipher_func(HKDF_expand_label(sr_traffic_secret,\n                                          b\"key\", b\"\",\n                                          key_length,\n                                          prf_name),\n                        implementations)\n        serverPendingState.fixedNonce = HKDF_expand_label(sr_traffic_secret,\n                                                          b\"iv\", b\"\",\n                                                          iv_length,\n                                                          prf_name)\n\n        if self.client:\n            self._pendingWriteState = clientPendingState\n            self._pendingReadState = serverPendingState\n        else:\n            self._pendingWriteState = serverPendingState\n            self._pendingReadState = clientPendingState\n\n    def _calcTLS1_3KeyUpdate(self, cipherSuite, app_secret):\n        prf_name, prf_length = ('sha384', 48) if cipherSuite \\\n                                in CipherSuite.sha384PrfSuites \\\n                                else ('sha256', 32)\n        key_length, iv_length, cipher_func = \\\n            self._getCipherSettings(cipherSuite)\n        iv_length = 12\n\n        new_app_secret = HKDF_expand_label(app_secret,\n                                           b\"traffic upd\", b\"\",\n                                           prf_length,\n                                           prf_name)\n        new_state = ConnectionState()\n        new_state.macContext = None\n        new_state.encContext = \\\n            cipher_func(HKDF_expand_label(new_app_secret,\n                                          b\"key\", b\"\",\n                                          key_length,\n                                          prf_name),\n                        None)\n        new_state.fixedNonce = HKDF_expand_label(new_app_secret,\n                                                 b\"iv\", b\"\",\n                                                 iv_length,\n                                                 prf_name)\n        return new_app_secret, new_state\n\n    def calcTLS1_3KeyUpdate_sender(self, cipherSuite, cl_app_secret,\n                                   sr_app_secret):\n        if self.client:\n            new_sr_app_secret, server_state = self._calcTLS1_3KeyUpdate(\n                cipherSuite, sr_app_secret)\n            self._readState = server_state\n            return cl_app_secret, new_sr_app_secret\n        else:\n            new_cl_app_secret, client_state = self._calcTLS1_3KeyUpdate(\n                cipherSuite, cl_app_secret)\n            self._readState = client_state\n            return new_cl_app_secret, sr_app_secret\n\n    def calcTLS1_3KeyUpdate_reciever(self, cipherSuite, cl_app_secret,\n                                     sr_app_secret):\n        if self.client:\n            new_cl_app_secret, client_state = self._calcTLS1_3KeyUpdate(\n                cipherSuite, cl_app_secret)\n            self._writeState = client_state\n            return new_cl_app_secret, sr_app_secret\n        else:\n            new_sr_app_secret, server_state = self._calcTLS1_3KeyUpdate(\n                cipherSuite, sr_app_secret)\n            self._writeState = server_state\n            return cl_app_secret, new_sr_app_secret\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/session.py",
    "content": "# Authors: \n#   Trevor Perrin\n#   Dave Baggett (Arcode Corporation) - canonicalCipherName\n#\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Class representing a TLS session.\"\"\"\n\nfrom .utils.compat import *\nfrom .mathtls import *\nfrom .constants import *\n\nclass Session(object):\n    \"\"\"\n    This class represents a TLS session.\n\n    TLS distinguishes between connections and sessions.  A new\n    handshake creates both a connection and a session.  Data is\n    transmitted over the connection.\n\n    The session contains a more permanent record of the handshake.  The\n    session can be inspected to determine handshake results.  The\n    session can also be used to create a new connection through\n    \"session resumption\". If the client and server both support this,\n    they can create a new connection based on an old session without\n    the overhead of a full handshake.\n\n    The session for a :py:class:`~tlslite.tlsconnection.TLSConnection` can be\n    retrieved from the connection's 'session' attribute.\n\n    :vartype srpUsername: str\n    :ivar srpUsername: The client's SRP username (or None).\n\n    :vartype clientCertChain: ~tlslite.x509certchain.X509CertChain\n    :ivar clientCertChain: The client's certificate chain (or None).\n\n    :vartype serverCertChain: ~tlslite.x509certchain.X509CertChain\n    :ivar serverCertChain: The server's certificate chain (or None).\n\n    :vartype tackExt: tack.structures.TackExtension.TackExtension\n    :ivar tackExt: The server's TackExtension (or None).\n\n    :vartype tackInHelloExt: bool\n    :ivar tackInHelloExt: True if a TACK was presented via TLS Extension.\n\n    :vartype ~.encryptThenMAC: bool\n    :ivar ~.encryptThenMAC: True if connection uses CBC cipher in\n        encrypt-then-MAC mode\n\n    :vartype appProto: bytearray\n    :ivar appProto: name of the negotiated application level protocol, None\n        if not negotiated\n\n    :vartype cl_app_secret: bytearray\n    :ivar cl_app_secret: key used for deriving keys used by client to encrypt\n        and protect data in TLS 1.3\n\n    :vartype sr_app_secret: bytearray\n    :ivar sr_app_secret: key used for deriving keys used by server to encrypt\n        and protect data in TLS 1.3\n\n    :vartype exporterMasterSecret: bytearray\n    :ivar exporterMasterSecret: master secret used for TLS Exporter in TLS1.3\n\n    :vartype resumptionMasterSecret: bytearray\n    :ivar resumptionMasterSecret: master secret used for session resumption in\n        TLS 1.3\n\n    :vartype tickets: list\n    :ivar tickets: list of tickets received from the server\n    \"\"\"\n\n    def __init__(self):\n        self.masterSecret = bytearray(0)\n        self.sessionID = bytearray(0)\n        self.cipherSuite = 0\n        self.srpUsername = \"\"\n        self.clientCertChain = None\n        self.serverCertChain = None\n        self.tackExt = None\n        self.tackInHelloExt = False\n        self.serverName = \"\"\n        self.resumable = False\n        self.encryptThenMAC = False\n        self.extendedMasterSecret = False\n        self.appProto = bytearray(0)\n        self.cl_app_secret = bytearray(0)\n        self.sr_app_secret = bytearray(0)\n        self.exporterMasterSecret = bytearray(0)\n        self.resumptionMasterSecret = bytearray(0)\n        self.tickets = None\n\n    def create(self, masterSecret, sessionID, cipherSuite,\n               srpUsername, clientCertChain, serverCertChain,\n               tackExt, tackInHelloExt, serverName, resumable=True,\n               encryptThenMAC=False, extendedMasterSecret=False,\n               appProto=bytearray(0), cl_app_secret=bytearray(0),\n               sr_app_secret=bytearray(0), exporterMasterSecret=bytearray(0),\n               resumptionMasterSecret=bytearray(0), tickets=None):\n        self.masterSecret = masterSecret\n        self.sessionID = sessionID\n        self.cipherSuite = cipherSuite\n        self.srpUsername = srpUsername\n        self.clientCertChain = clientCertChain\n        self.serverCertChain = serverCertChain\n        self.tackExt = tackExt\n        self.tackInHelloExt = tackInHelloExt  \n        self.serverName = serverName\n        self.resumable = resumable\n        self.encryptThenMAC = encryptThenMAC\n        self.extendedMasterSecret = extendedMasterSecret\n        self.appProto = appProto\n        self.cl_app_secret = cl_app_secret\n        self.sr_app_secret = sr_app_secret\n        self.exporterMasterSecret = exporterMasterSecret\n        self.resumptionMasterSecret = resumptionMasterSecret\n        # NOTE we need a reference copy not a copy of object here!\n        self.tickets = tickets\n\n    def _clone(self):\n        other = Session()\n        other.masterSecret = self.masterSecret\n        other.sessionID = self.sessionID\n        other.cipherSuite = self.cipherSuite\n        other.srpUsername = self.srpUsername\n        other.clientCertChain = self.clientCertChain\n        other.serverCertChain = self.serverCertChain\n        other.tackExt = self.tackExt\n        other.tackInHelloExt = self.tackInHelloExt\n        other.serverName = self.serverName\n        other.resumable = self.resumable\n        other.encryptThenMAC = self.encryptThenMAC\n        other.extendedMasterSecret = self.extendedMasterSecret\n        other.appProto = self.appProto\n        other.cl_app_secret = self.cl_app_secret\n        other.sr_app_secret = self.sr_app_secret\n        other.exporterMasterSecret = self.exporterMasterSecret\n        other.resumptionMasterSecret = self.resumptionMasterSecret\n        other.tickets = self.tickets\n        return other\n\n    def valid(self):\n        \"\"\"If this session can be used for session resumption.\n\n        :rtype: bool\n        :returns: If this session can be used for session resumption.\n        \"\"\"\n        # TODO add checks for tickets received from server (freshness etc.)\n        return self.resumable and (self.sessionID or self.tickets)\n\n    def _setResumable(self, boolean):\n        #Only let it be set to True if the sessionID is non-null\n        if (not boolean) or (boolean and self.sessionID):\n            self.resumable = boolean\n\n    def getTackId(self):\n        if self.tackExt and self.tackExt.tack:\n            return self.tackExt.tack.getTackId()\n        else:\n            return None\n        \n    def getBreakSigs(self):\n        if self.tackExt and self.tackExt.break_sigs:\n            return self.tackExt.break_sigs\n        else:\n            return None\n\n    def getCipherName(self):\n        \"\"\"Get the name of the cipher used with this connection.\n\n        :rtype: str\n        :returns: The name of the cipher used with this connection.\n        \"\"\"\n        return CipherSuite.canonicalCipherName(self.cipherSuite)\n        \n    def getMacName(self):\n        \"\"\"Get the name of the HMAC hash algo used with this connection.\n\n        :rtype: str\n        :returns: The name of the HMAC hash algo used with this connection.\n        \"\"\"\n        return CipherSuite.canonicalMacName(self.cipherSuite)\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/sessioncache.py",
    "content": "# Authors: \n#   Trevor Perrin\n#   Martin von Loewis - python 3 port\n#   Mirko Dziadzka - bugfix\n#\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Class for caching TLS sessions.\"\"\"\n\nimport threading\nimport time\n\nclass SessionCache(object):\n    \"\"\"This class is used by the server to cache TLS sessions.\n\n    Caching sessions allows the client to use TLS session resumption\n    and avoid the expense of a full handshake.  To use this class,\n    simply pass a SessionCache instance into the server handshake\n    function.\n\n    This class is thread-safe.\n    \"\"\"\n\n    #References to these instances\n    #are also held by the caller, who may change the 'resumable'\n    #flag, so the SessionCache must return the same instances\n    #it was passed in.\n\n    def __init__(self, maxEntries=10000, maxAge=14400):\n        \"\"\"Create a new SessionCache.\n\n        :type maxEntries: int\n        :param maxEntries: The maximum size of the cache.  When this\n            limit is reached, the oldest sessions will be deleted as\n            necessary to make room for new ones.  The default is 10000.\n\n        :type maxAge: int\n        :param maxAge:  The number of seconds before a session expires\n            from the cache.  The default is 14400 (i.e. 4 hours).\"\"\"\n\n        self.lock = threading.Lock()\n\n        # Maps sessionIDs to sessions\n        self.entriesDict = {}\n\n        #Circular list of (sessionID, timestamp) pairs\n        self.entriesList = [(None,None)] * maxEntries\n\n        self.firstIndex = 0\n        self.lastIndex = 0\n        self.maxAge = maxAge\n\n    def __getitem__(self, sessionID):\n        self.lock.acquire()\n        try:\n            self._purge() #Delete old items, so we're assured of a new one\n            session = self.entriesDict[bytes(sessionID)]\n\n            #When we add sessions they're resumable, but it's possible\n            #for the session to be invalidated later on (if a fatal alert\n            #is returned), so we have to check for resumability before\n            #returning the session.\n\n            if session.valid():\n                return session\n            else:\n                raise KeyError()\n        finally:\n            self.lock.release()\n\n\n    def __setitem__(self, sessionID, session):\n        self.lock.acquire()\n        try:\n            #Add the new element\n            self.entriesDict[bytes(sessionID)] = session\n            self.entriesList[self.lastIndex] = (bytes(sessionID), time.time())\n            self.lastIndex = (self.lastIndex+1) % len(self.entriesList)\n\n            #If the cache is full, we delete the oldest element to make an\n            #empty space\n            if self.lastIndex == self.firstIndex:\n                del(self.entriesDict[self.entriesList[self.firstIndex][0]])\n                self.firstIndex = (self.firstIndex+1) % len(self.entriesList)\n        finally:\n            self.lock.release()\n\n    #Delete expired items\n    def _purge(self):\n        currentTime = time.time()\n\n        #Search through the circular list, deleting expired elements until\n        #we reach a non-expired element.  Since elements in list are\n        #ordered in time, we can break once we reach the first non-expired\n        #element\n        index = self.firstIndex\n        while index != self.lastIndex:\n            if currentTime - self.entriesList[index][1] > self.maxAge:\n                del(self.entriesDict[self.entriesList[index][0]])\n                index = (index+1) % len(self.entriesList)\n            else:\n                break\n        self.firstIndex = index\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/signed.py",
    "content": "\"\"\"Base class that represents any signed object\"\"\"\n\nfrom .utils.cryptomath import numBytes\n\nRSA_SIGNATURE_HASHES = [\"sha512\", \"sha384\", \"sha256\", \"sha224\", \"sha1\"]\nALL_RSA_SIGNATURE_HASHES = RSA_SIGNATURE_HASHES + [\"md5\"]\nRSA_SCHEMES = [\"pss\", \"pkcs1\"]\n\n\nclass SignatureSettings(object):\n    def __init__(self, min_key_size=None, max_key_size=None,\n                 rsa_sig_hashes=None, rsa_schemes=None):\n        \"\"\"Create default variables for key-related settings.\"\"\"\n        self.min_key_size = min_key_size or 1023\n        self.max_key_size = max_key_size or 8193\n        self.rsa_sig_hashes = rsa_sig_hashes or list(RSA_SIGNATURE_HASHES)\n        self.rsa_schemes = rsa_schemes or list(RSA_SCHEMES)\n\n    def _copy_settings(self, other):\n        other.min_key_size = self.min_key_size\n        other.max_key_size = self.max_key_size\n        other.rsa_sig_hashes = self.rsa_sig_hashes\n        other.rsa_schemes = self.rsa_schemes\n\n    @staticmethod\n    def _sanityCheckKeySizes(other):\n        if other.min_key_size < 512:\n            raise ValueError(\"min_key_size too small\")\n        if other.min_key_size > 16384:\n            raise ValueError(\"min_key_size too large\")\n        if other.max_key_size < 512:\n            raise ValueError(\"max_key_size too small\")\n        if other.max_key_size > 16384:\n            raise ValueError(\"max_key_size too large\")\n        if other.max_key_size < other.min_key_size:\n            raise ValueError(\"max_key_size smaller than min_key_size\")\n\n    @staticmethod\n    def _sanityCheckSignatureAlgs(other):\n        not_allowed = [alg for alg in other.rsa_sig_hashes\n                       if alg not in ALL_RSA_SIGNATURE_HASHES]\n        if len(not_allowed) > 0:\n            raise ValueError(\"Following signature algorithms are not allowed: \"\n                             \"{0}\".format(\", \".join(not_allowed)))\n\n    def validate(self):\n        other = SignatureSettings()\n        self._copy_settings(other)\n        self._sanityCheckKeySizes(other)\n        self._sanityCheckSignatureAlgs(other)\n        return other\n\n\nclass SignedObject(object):\n    def __init__(self):\n        self.tbs_data = None\n        self.signature = None\n        self.signature_alg = None\n\n    _hash_algs_OIDs = {\n        tuple([0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0x4]): 'md5',\n        tuple([0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0x5]): 'sha1',\n        tuple([0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0xe]): 'sha224',\n        tuple([0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0xc]): 'sha384',\n        tuple([0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0xb]): 'sha256',\n        tuple([0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0xd]): 'sha512'\n    }\n\n    def verify_signature(self, publicKey, settings=None):\n        \"\"\" Verify signature in a reponse\"\"\"\n        offset = 0\n        settings = settings or SignatureSettings()\n\n        # workaround as some signature encodings could be zero left-padded\n        if (self.signature[0] == 0 and\n                numBytes(publicKey.n) + 1 == len(self.signature)):\n            offset = 1\n\n        alg = self._hash_algs_OIDs[tuple(self.signature_alg)]\n        if alg not in settings.rsa_sig_hashes:\n            raise ValueError(\"Invalid signature algorithm: {0}\".format(alg))\n        verified = publicKey.hashAndVerify(self.signature[offset:],\n                                           self.tbs_data, hAlg=alg)\n        if not verified:\n            raise ValueError(\"Signature could not be verified for {0}\"\n                             .format(alg))\n        return True\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/tlsconnection.py",
    "content": "# Authors:\n#   Trevor Perrin\n#   Google - added reqCAs parameter\n#   Google (adapted by Sam Rushing and Marcelo Fernandez) - NPN support\n#   Google - FALLBACK_SCSV\n#   Dimitris Moraitis - Anon ciphersuites\n#   Martin von Loewis - python 3 port\n#   Yngve Pettersen (ported by Paul Sokolovsky) - TLS 1.2\n#   Hubert Kario - complete refactoring of key exchange methods, addition\n#          of ECDH support\n#\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"\nMAIN CLASS FOR TLS LITE (START HERE!).\n\"\"\"\n\nfrom __future__ import division\n\nimport random\nimport time\nimport socket\nfrom itertools import chain\nfrom .utils.compat import formatExceptionTrace\nfrom .tlsrecordlayer import TLSRecordLayer\nfrom .session import Session\nfrom .constants import *\nfrom .utils.cryptomath import derive_secret, getRandomBytes, HKDF_expand_label\nfrom .utils.dns_utils import is_valid_hostname\nfrom .utils.lists import getFirstMatching\nfrom .errors import *\nfrom .messages import *\nfrom .mathtls import *\nfrom .handshakesettings import HandshakeSettings, KNOWN_VERSIONS, CURVE_ALIASES\nfrom .handshakehashes import HandshakeHashes\nfrom .utils.tackwrapper import *\nfrom .utils.deprecations import deprecated_params\nfrom .keyexchange import KeyExchange, RSAKeyExchange, DHE_RSAKeyExchange, \\\n        ECDHE_RSAKeyExchange, SRPKeyExchange, ADHKeyExchange, \\\n        AECDHKeyExchange, FFDHKeyExchange, ECDHKeyExchange\nfrom .handshakehelpers import HandshakeHelpers\nfrom .utils.cipherfactory import createAESCCM, createAESCCM_8, \\\n        createAESGCM, createCHACHA20\n\nclass TLSConnection(TLSRecordLayer):\n    \"\"\"\n    This class wraps a socket and provides TLS handshaking and data transfer.\n\n    To use this class, create a new instance, passing a connected\n    socket into the constructor.  Then call some handshake function.\n    If the handshake completes without raising an exception, then a TLS\n    connection has been negotiated.  You can transfer data over this\n    connection as if it were a socket.\n\n    This class provides both synchronous and asynchronous versions of\n    its key functions.  The synchronous versions should be used when\n    writing single-or multi-threaded code using blocking sockets.  The\n    asynchronous versions should be used when performing asynchronous,\n    event-based I/O with non-blocking sockets.\n\n    Asynchronous I/O is a complicated subject; typically, you should\n    not use the asynchronous functions directly, but should use some\n    framework like asyncore or Twisted which TLS Lite integrates with\n    (see\n    :py:class:`~.integration.tlsasyncdispatchermixin.TLSAsyncDispatcherMixIn`).\n    \"\"\"\n\n    def __init__(self, sock):\n        \"\"\"Create a new TLSConnection instance.\n\n        :param sock: The socket data will be transmitted on.  The\n            socket should already be connected.  It may be in blocking or\n            non-blocking mode.\n\n        :type sock: socket.socket\n        \"\"\"\n        TLSRecordLayer.__init__(self, sock)\n        self.serverSigAlg = None\n        self.ecdhCurve = None\n        self.dhGroupSize = None\n        self.extendedMasterSecret = False\n        self._clientRandom = bytearray(0)\n        self._serverRandom = bytearray(0)\n        self.next_proto = None\n        # whether the CCS was already sent in the connection (for hello retry)\n        self._ccs_sent = False\n        # if and how big is the limit on records peer is willing to accept\n        # used only for TLS 1.2 and earlier\n        self._peer_record_size_limit = None\n        self._pha_supported = False\n\n    def keyingMaterialExporter(self, label, length=20):\n        \"\"\"Return keying material as described in RFC 5705\n\n        :type label: bytearray\n        :param label: label to be provided for the exporter\n\n        :type length: int\n        :param length: number of bytes of the keying material to export\n        \"\"\"\n        if label in (b'server finished', b'client finished',\n                     b'master secret', b'key expansion'):\n            raise ValueError(\"Forbidden label value\")\n        if self.version < (3, 1):\n            raise ValueError(\"Supported only in TLSv1.0 and later\")\n        elif self.version < (3, 3):\n            return PRF(self.session.masterSecret, label,\n                       self._clientRandom + self._serverRandom,\n                       length)\n        elif self.version == (3, 3):\n            if self.session.cipherSuite in CipherSuite.sha384PrfSuites:\n                return PRF_1_2_SHA384(self.session.masterSecret, label,\n                                      self._clientRandom + self._serverRandom,\n                                      length)\n            else:\n                return PRF_1_2(self.session.masterSecret, label,\n                               self._clientRandom + self._serverRandom,\n                               length)\n        elif self.version == (3, 4):\n            prf = 'sha256'\n            if self.session.cipherSuite in CipherSuite.sha384PrfSuites:\n                prf = 'sha384'\n            secret = derive_secret(self.session.exporterMasterSecret, label,\n                                   None, prf)\n            ctxhash = secureHash(bytearray(b''), prf)\n            return HKDF_expand_label(secret, b\"exporter\", ctxhash, length, prf)\n        else:\n            raise AssertionError(\"Unknown protocol version\")\n\n    #*********************************************************\n    # Client Handshake Functions\n    #*********************************************************\n\n    @deprecated_params({\"async_\": \"async\"},\n                       \"'{old_name}' is a keyword in Python 3.7, use\"\n                       \"'{new_name}'\")\n    def handshakeClientAnonymous(self, session=None, settings=None,\n                                 checker=None, serverName=None,\n                                 async_=False):\n        \"\"\"Perform an anonymous handshake in the role of client.\n\n        This function performs an SSL or TLS handshake using an\n        anonymous Diffie Hellman ciphersuite.\n\n        Like any handshake function, this can be called on a closed\n        TLS connection, or on a TLS connection that is already open.\n        If called on an open connection it performs a re-handshake.\n\n        If the function completes without raising an exception, the\n        TLS connection will be open and available for data transfer.\n\n        If an exception is raised, the connection will have been\n        automatically closed (if it was ever open).\n\n        :type session: ~tlslite.session.Session\n        :param session: A TLS session to attempt to resume.  If the\n            resumption does not succeed, a full handshake will be\n            performed.\n\n        :type settings: ~tlslite.handshakesettings.HandshakeSettings\n        :param settings: Various settings which can be used to control\n            the ciphersuites, certificate types, and SSL/TLS versions\n            offered by the client.\n\n        :type checker: ~tlslite.checker.Checker\n        :param checker: A Checker instance.  This instance will be\n            invoked to examine the other party's authentication\n            credentials, if the handshake completes succesfully.\n\n        :type serverName: string\n        :param serverName: The ServerNameIndication TLS Extension.\n\n        :type async_: bool\n        :param async_: If False, this function will block until the\n            handshake is completed.  If True, this function will return a\n            generator.  Successive invocations of the generator will\n            return 0 if it is waiting to read from the socket, 1 if it is\n            waiting to write to the socket, or will raise StopIteration if\n            the handshake operation is completed.\n\n        :rtype: None or an iterable\n        :returns: If 'async_' is True, a generator object will be\n            returned.\n\n        :raises socket.error: If a socket error occurs.\n        :raises tlslite.errors.TLSAbruptCloseError: If the socket is closed\n            without a preceding alert.\n        :raises tlslite.errors.TLSAlert: If a TLS alert is signalled.\n        :raises tlslite.errors.TLSAuthenticationError: If the checker\n            doesn't like the other party's authentication credentials.\n        \"\"\"\n        handshaker = self._handshakeClientAsync(anonParams=(True),\n                                                session=session,\n                                                settings=settings,\n                                                checker=checker,\n                                                serverName=serverName)\n        if async_:\n            return handshaker\n        for result in handshaker:\n            pass\n\n    @deprecated_params({\"async_\": \"async\"},\n                       \"'{old_name}' is a keyword in Python 3.7, use\"\n                       \"'{new_name}'\")\n    def handshakeClientSRP(self, username, password, session=None,\n                           settings=None, checker=None,\n                           reqTack=True, serverName=None,\n                           async_=False):\n        \"\"\"Perform an SRP handshake in the role of client.\n\n        This function performs a TLS/SRP handshake.  SRP mutually\n        authenticates both parties to each other using only a\n        username and password.  This function may also perform a\n        combined SRP and server-certificate handshake, if the server\n        chooses to authenticate itself with a certificate chain in\n        addition to doing SRP.\n\n        If the function completes without raising an exception, the\n        TLS connection will be open and available for data transfer.\n\n        If an exception is raised, the connection will have been\n        automatically closed (if it was ever open).\n\n        :type username: bytearray\n        :param username: The SRP username.\n\n        :type password: bytearray\n        :param password: The SRP password.\n\n        :type session: ~tlslite.session.Session\n        :param session: A TLS session to attempt to resume.  This\n            session must be an SRP session performed with the same username\n            and password as were passed in.  If the resumption does not\n            succeed, a full SRP handshake will be performed.\n\n        :type settings: ~tlslite.handshakesettings.HandshakeSettings\n        :param settings: Various settings which can be used to control\n            the ciphersuites, certificate types, and SSL/TLS versions\n            offered by the client.\n\n        :type checker: ~tlslite.checker.Checker\n        :param checker: A Checker instance.  This instance will be\n            invoked to examine the other party's authentication\n            credentials, if the handshake completes succesfully.\n\n        :type reqTack: bool\n        :param reqTack: Whether or not to send a \"tack\" TLS Extension,\n            requesting the server return a TackExtension if it has one.\n\n        :type serverName: string\n        :param serverName: The ServerNameIndication TLS Extension.\n\n        :type async_: bool\n        :param async_: If False, this function will block until the\n            handshake is completed.  If True, this function will return a\n            generator.  Successive invocations of the generator will\n            return 0 if it is waiting to read from the socket, 1 if it is\n            waiting to write to the socket, or will raise StopIteration if\n            the handshake operation is completed.\n\n        :rtype: None or an iterable\n        :returns: If 'async_' is True, a generator object will be\n            returned.\n\n        :raises socket.error: If a socket error occurs.\n        :raises tlslite.errors.TLSAbruptCloseError: If the socket is closed\n            without a preceding alert.\n        :raises tlslite.errors.TLSAlert: If a TLS alert is signalled.\n        :raises tlslite.errors.TLSAuthenticationError: If the checker\n            doesn't like the other party's authentication credentials.\n        \"\"\"\n        # TODO add deprecation warning\n        if isinstance(username, str):\n            username = bytearray(username, 'utf-8')\n        if isinstance(password, str):\n            password = bytearray(password, 'utf-8')\n        handshaker = self._handshakeClientAsync(srpParams=(username, password),\n                        session=session, settings=settings, checker=checker,\n                        reqTack=reqTack, serverName=serverName)\n        # The handshaker is a Python Generator which executes the handshake.\n        # It allows the handshake to be run in a \"piecewise\", asynchronous\n        # fashion, returning 1 when it is waiting to able to write, 0 when\n        # it is waiting to read.\n        #\n        # If 'async_' is True, the generator is returned to the caller,\n        # otherwise it is executed to completion here.\n        if async_:\n            return handshaker\n        for result in handshaker:\n            pass\n\n    @deprecated_params({\"async_\": \"async\"},\n                       \"'{old_name}' is a keyword in Python 3.7, use\"\n                       \"'{new_name}'\")\n    def handshakeClientCert(self, certChain=None, privateKey=None,\n                            session=None, settings=None, checker=None,\n                            nextProtos=None, reqTack=True, serverName=None,\n                            async_=False, alpn=None):\n        \"\"\"Perform a certificate-based handshake in the role of client.\n\n        This function performs an SSL or TLS handshake.  The server\n        will authenticate itself using an X.509 certificate\n        chain.  If the handshake succeeds, the server's certificate\n        chain will be stored in the session's serverCertChain attribute.\n        Unless a checker object is passed in, this function does no\n        validation or checking of the server's certificate chain.\n\n        If the server requests client authentication, the\n        client will send the passed-in certificate chain, and use the\n        passed-in private key to authenticate itself.  If no\n        certificate chain and private key were passed in, the client\n        will attempt to proceed without client authentication.  The\n        server may or may not allow this.\n\n        If the function completes without raising an exception, the\n        TLS connection will be open and available for data transfer.\n\n        If an exception is raised, the connection will have been\n        automatically closed (if it was ever open).\n\n        :type certChain: ~tlslite.x509certchain.X509CertChain\n        :param certChain: The certificate chain to be used if the\n            server requests client authentication.\n\n        :type privateKey: ~tlslite.utils.rsakey.RSAKey\n        :param privateKey: The private key to be used if the server\n            requests client authentication.\n\n        :type session: ~tlslite.session.Session\n        :param session: A TLS session to attempt to resume.  If the\n            resumption does not succeed, a full handshake will be\n            performed.\n\n        :type settings: ~tlslite.handshakesettings.HandshakeSettings\n        :param settings: Various settings which can be used to control\n            the ciphersuites, certificate types, and SSL/TLS versions\n            offered by the client.\n\n        :type checker: ~tlslite.checker.Checker\n        :param checker: A Checker instance.  This instance will be\n            invoked to examine the other party's authentication\n            credentials, if the handshake completes succesfully.\n\n        :type nextProtos: list of str\n        :param nextProtos: A list of upper layer protocols ordered by\n            preference, to use in the Next-Protocol Negotiation Extension.\n\n        :type reqTack: bool\n        :param reqTack: Whether or not to send a \"tack\" TLS Extension,\n            requesting the server return a TackExtension if it has one.\n\n        :type serverName: string\n        :param serverName: The ServerNameIndication TLS Extension.\n\n        :type async_: bool\n        :param async_: If False, this function will block until the\n            handshake is completed.  If True, this function will return a\n            generator.  Successive invocations of the generator will\n            return 0 if it is waiting to read from the socket, 1 if it is\n            waiting to write to the socket, or will raise StopIteration if\n            the handshake operation is completed.\n\n        :type alpn: list of bytearrays\n        :param alpn: protocol names to advertise to server as supported by\n            client in the Application Layer Protocol Negotiation extension.\n            Example items in the array include b'http/1.1' or b'h2'.\n\n        :rtype: None or an iterable\n        :returns: If 'async_' is True, a generator object will be\n            returned.\n\n        :raises socket.error: If a socket error occurs.\n        :raises tlslite.errors.TLSAbruptCloseError: If the socket is closed\n            without a preceding alert.\n        :raises tlslite.errors.TLSAlert: If a TLS alert is signalled.\n        :raises tlslite.errors.TLSAuthenticationError: If the checker\n            doesn't like the other party's authentication credentials.\n        \"\"\"\n        handshaker = \\\n                self._handshakeClientAsync(certParams=(certChain, privateKey),\n                                           session=session, settings=settings,\n                                           checker=checker,\n                                           serverName=serverName,\n                                           nextProtos=nextProtos,\n                                           reqTack=reqTack,\n                                           alpn=alpn)\n        # The handshaker is a Python Generator which executes the handshake.\n        # It allows the handshake to be run in a \"piecewise\", asynchronous\n        # fashion, returning 1 when it is waiting to able to write, 0 when\n        # it is waiting to read.\n        #\n        # If 'async_' is True, the generator is returned to the caller,\n        # otherwise it is executed to completion here.\n        if async_:\n            return handshaker\n        for result in handshaker:\n            pass\n\n\n    def _handshakeClientAsync(self, srpParams=(), certParams=(), anonParams=(),\n                              session=None, settings=None, checker=None,\n                              nextProtos=None, serverName=None, reqTack=True,\n                              alpn=None):\n\n        handshaker = self._handshakeClientAsyncHelper(srpParams=srpParams,\n                certParams=certParams,\n                anonParams=anonParams,\n                session=session,\n                settings=settings,\n                serverName=serverName,\n                nextProtos=nextProtos,\n                reqTack=reqTack,\n                alpn=alpn)\n        for result in self._handshakeWrapperAsync(handshaker, checker):\n            yield result\n\n\n    def _handshakeClientAsyncHelper(self, srpParams, certParams, anonParams,\n                               session, settings, serverName, nextProtos,\n                               reqTack, alpn):\n\n        self._handshakeStart(client=True)\n\n        #Unpack parameters\n        srpUsername = None      # srpParams[0]\n        password = None         # srpParams[1]\n        clientCertChain = None  # certParams[0]\n        privateKey = None       # certParams[1]\n\n        # Allow only one of (srpParams, certParams, anonParams)\n        if srpParams:\n            assert(not certParams)\n            assert(not anonParams)\n            srpUsername, password = srpParams\n        if certParams:\n            assert(not srpParams)\n            assert(not anonParams)\n            clientCertChain, privateKey = certParams\n        if anonParams:\n            assert(not srpParams)\n            assert(not certParams)\n\n        #Validate parameters\n        if srpUsername and not password:\n            raise ValueError(\"Caller passed a username but no password\")\n        if password and not srpUsername:\n            raise ValueError(\"Caller passed a password but no username\")\n        if clientCertChain and not privateKey:\n            raise ValueError(\"Caller passed a cert_chain but no privateKey\")\n        if privateKey and not clientCertChain:\n            raise ValueError(\"Caller passed a privateKey but no cert_chain\")\n        if reqTack:\n            if not tackpyLoaded:\n                reqTack = False\n            if not settings or not settings.useExperimentalTackExtension:\n                reqTack = False\n        if nextProtos is not None:\n            if len(nextProtos) == 0:\n                raise ValueError(\"Caller passed no nextProtos\")\n        if alpn is not None and not alpn:\n            raise ValueError(\"Caller passed empty alpn list\")\n        # reject invalid hostnames but accept empty/None ones\n        if serverName and not is_valid_hostname(serverName):\n            raise ValueError(\"Caller provided invalid server host name: {0}\"\n                             .format(serverName))\n\n        # Validates the settings and filters out any unsupported ciphers\n        # or crypto libraries that were requested\n        if not settings:\n            settings = HandshakeSettings()\n        settings = settings.validate()\n        self.sock.padding_cb = settings.padding_cb\n\n        if clientCertChain:\n            if not isinstance(clientCertChain, X509CertChain):\n                raise ValueError(\"Unrecognized certificate type\")\n            if \"x509\" not in settings.certificateTypes:\n                raise ValueError(\"Client certificate doesn't match \"\\\n                                 \"Handshake Settings\")\n\n        if session:\n            # session.valid() ensures session is resumable and has\n            # non-empty sessionID\n            if not session.valid():\n                session = None #ignore non-resumable sessions...\n            elif session.resumable:\n                if session.srpUsername != srpUsername:\n                    raise ValueError(\"Session username doesn't match\")\n                if session.serverName != serverName:\n                    raise ValueError(\"Session servername doesn't match\")\n\n        #Add Faults to parameters\n        if srpUsername and self.fault == Fault.badUsername:\n            srpUsername += bytearray(b\"GARBAGE\")\n        if password and self.fault == Fault.badPassword:\n            password += bytearray(b\"GARBAGE\")\n\n        # Tentatively set the client's record version.\n        # We'll use this for the ClientHello, and if an error occurs\n        # parsing the Server Hello, we'll use this version for the response\n        # in TLS 1.3 it always needs to be set to TLS 1.0\n        self.version = \\\n            (3, 1) if settings.maxVersion > (3, 3) else settings.maxVersion\n\n        # OK Start sending messages!\n        # *****************************\n\n        # Send the ClientHello.\n        for result in self._clientSendClientHello(settings, session,\n                                        srpUsername, srpParams, certParams,\n                                        anonParams, serverName, nextProtos,\n                                        reqTack, alpn):\n            if result in (0,1): yield result\n            else: break\n        clientHello = result\n\n        #Get the ServerHello.\n        for result in self._clientGetServerHello(settings, session,\n                                                 clientHello):\n            if result in (0,1): yield result\n            else: break\n        serverHello = result\n        cipherSuite = serverHello.cipher_suite\n\n        # Check the serverHello.random  if it includes the downgrade protection\n        # values as described in RFC8446 section 4.1.3\n\n        # For TLS1.3\n        if (settings.maxVersion > (3, 3) and self.version <= (3, 3)) and \\\n                (serverHello.random[-8:] == TLS_1_2_DOWNGRADE_SENTINEL or\n                 serverHello.random[-8:] == TLS_1_1_DOWNGRADE_SENTINEL):\n            for result in self._sendError(AlertDescription.illegal_parameter,\n                                          \"Connection terminated because \"\n                                          \"of downgrade protection.\"):\n                yield result\n\n        # For TLS1.2\n        if settings.maxVersion == (3, 3) and self.version < (3, 3) and \\\n                serverHello.random[-8:] == TLS_1_1_DOWNGRADE_SENTINEL:\n            for result in self._sendError(AlertDescription.illegal_parameter,\n                                          \"Connection terminated because \"\n                                          \"of downgrade protection.\"):\n                yield result\n\n        # if we're doing tls1.3, use the new code as the negotiation is much\n        # different\n        ext = serverHello.getExtension(ExtensionType.supported_versions)\n        if ext and ext.version > (3, 3):\n            for result in self._clientTLS13Handshake(settings, session,\n                                                     clientHello,\n                                                     clientCertChain,\n                                                     privateKey,\n                                                     serverHello):\n                if result in (0, 1):\n                    yield result\n                else:\n                    break\n            if result in [\"finished\", \"resumed_and_finished\"]:\n                self._handshakeDone(resumed=(result == \"resumed_and_finished\"))\n                self._serverRandom = serverHello.random\n                self._clientRandom = clientHello.random\n                return\n            else:\n                raise Exception(\"unexpected return\")\n\n        # Choose a matching Next Protocol from server list against ours\n        # (string or None)\n        nextProto = self._clientSelectNextProto(nextProtos, serverHello)\n\n        # Check if server selected encrypt-then-MAC\n        if serverHello.getExtension(ExtensionType.encrypt_then_mac):\n            self._recordLayer.encryptThenMAC = True\n\n        if serverHello.getExtension(ExtensionType.extended_master_secret):\n            self.extendedMasterSecret = True\n\n        #If the server elected to resume the session, it is handled here.\n        for result in self._clientResume(session, serverHello,\n                        clientHello.random,\n                        settings.cipherImplementations,\n                        nextProto, settings):\n            if result in (0,1): yield result\n            else: break\n        if result == \"resumed_and_finished\":\n            self._handshakeDone(resumed=True)\n            self._serverRandom = serverHello.random\n            self._clientRandom = clientHello.random\n            # alpn protocol is independent of resumption and renegotiation\n            # and needs to be negotiated every time\n            alpnExt = serverHello.getExtension(ExtensionType.alpn)\n            if alpnExt:\n                session.appProto = alpnExt.protocol_names[0]\n            return\n\n        #If the server selected an SRP ciphersuite, the client finishes\n        #reading the post-ServerHello messages, then derives a\n        #premasterSecret and sends a corresponding ClientKeyExchange.\n        if cipherSuite in CipherSuite.srpAllSuites:\n            keyExchange = SRPKeyExchange(cipherSuite, clientHello,\n                                         serverHello, None, None,\n                                         srpUsername=srpUsername,\n                                         password=password,\n                                         settings=settings)\n\n        #If the server selected an anonymous ciphersuite, the client\n        #finishes reading the post-ServerHello messages.\n        elif cipherSuite in CipherSuite.dhAllSuites:\n            keyExchange = DHE_RSAKeyExchange(cipherSuite, clientHello,\n                                             serverHello, None)\n\n        elif cipherSuite in CipherSuite.ecdhAllSuites:\n            acceptedCurves = self._curveNamesToList(settings)\n            keyExchange = ECDHE_RSAKeyExchange(cipherSuite, clientHello,\n                                               serverHello, None,\n                                               acceptedCurves)\n\n        #If the server selected a certificate-based RSA ciphersuite,\n        #the client finishes reading the post-ServerHello messages. If\n        #a CertificateRequest message was sent, the client responds with\n        #a Certificate message containing its certificate chain (if any),\n        #and also produces a CertificateVerify message that signs the\n        #ClientKeyExchange.\n        else:\n            keyExchange = RSAKeyExchange(cipherSuite, clientHello,\n                                         serverHello, None)\n\n        # we'll send few messages here, send them in single TCP packet\n        self.sock.buffer_writes = True\n        for result in self._clientKeyExchange(settings, cipherSuite,\n                                              clientCertChain,\n                                              privateKey,\n                                              serverHello.certificate_type,\n                                              serverHello.tackExt,\n                                              clientHello.random,\n                                              serverHello.random,\n                                              keyExchange):\n            if result in (0, 1):\n                yield result\n            else: break\n        (premasterSecret, serverCertChain, clientCertChain,\n         tackExt) = result\n\n        #After having previously sent a ClientKeyExchange, the client now\n        #initiates an exchange of Finished messages.\n        # socket buffering is turned off in _clientFinished\n        for result in self._clientFinished(premasterSecret,\n                            clientHello.random,\n                            serverHello.random,\n                            cipherSuite, settings.cipherImplementations,\n                            nextProto, settings):\n                if result in (0,1): yield result\n                else: break\n        masterSecret = result\n\n        # check if an application layer protocol was negotiated\n        alpnProto = None\n        alpnExt = serverHello.getExtension(ExtensionType.alpn)\n        if alpnExt:\n            alpnProto = alpnExt.protocol_names[0]\n\n        # Create the session object which is used for resumptions\n        self.session = Session()\n        self.session.create(masterSecret, serverHello.session_id, cipherSuite,\n                            srpUsername, clientCertChain, serverCertChain,\n                            tackExt, (serverHello.tackExt is not None),\n                            serverName,\n                            encryptThenMAC=self._recordLayer.encryptThenMAC,\n                            extendedMasterSecret=self.extendedMasterSecret,\n                            appProto=alpnProto,\n                            # NOTE it must be a reference not a copy\n                            tickets=self.tickets)\n        self._handshakeDone(resumed=False)\n        self._serverRandom = serverHello.random\n        self._clientRandom = clientHello.random\n\n    @staticmethod\n    def _get_GREASE_version():\n        n = random.randint(1, 10)\n        ns = n * 16 + 10\n        value = (ns, ns)\n        return value\n\n    @staticmethod\n    def _get_GREASE():\n        values = [0x1a1a, 0x2a2a, 0x3a3a, 0x4a4a, 0x5a5a, 0x6a6a, 0x7a7a, 0x8a8a, 0x9a9a, 0xaaaa, 0xbaba]\n        return random.choice(values)\n\n    def _clientSendClientHello(self, settings, session, srpUsername,\n                                srpParams, certParams, anonParams,\n                                serverName, nextProtos, reqTack, alpn):\n        #Initialize acceptable ciphersuites\n        # cipherSuites = [CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV]\n        # if srpParams:\n        #     cipherSuites += CipherSuite.getSrpAllSuites(settings)\n        # elif certParams:\n        #     cipherSuites += CipherSuite.getTLS13Suites(settings)\n        #     cipherSuites += CipherSuite.getEcdsaSuites(settings)\n        #     cipherSuites += CipherSuite.getEcdheCertSuites(settings)\n        #     cipherSuites += CipherSuite.getDheCertSuites(settings)\n        #     cipherSuites += CipherSuite.getCertSuites(settings)\n        #     cipherSuites += CipherSuite.getDheDsaSuites(settings)\n        # elif anonParams:\n        #     cipherSuites += CipherSuite.getEcdhAnonSuites(settings)\n        #     cipherSuites += CipherSuite.getAnonSuites(settings)\n        # else:\n        #     assert False\n\n        cipherSuites = [\n            self._get_GREASE(),\n            CipherSuite.TLS_AES_128_GCM_SHA256,  # 1301\n            CipherSuite.TLS_AES_256_GCM_SHA384,  # 1302\n            CipherSuite.TLS_CHACHA20_POLY1305_SHA256,  # 1303\n            CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,  # C02B\n            CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,  # C02F\n            CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,  # C02C\n            CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,  # C030\n            CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,  # cca9\n            CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,  # cca8\n            CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,  # c013\n            CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,  # c014\n            CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256,  # 009c\n            CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384,  # 009d\n            CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA,  # 002f\n            CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA,  # 0035\n        ]\n\n        #Add any SCSVs. These are not real cipher suites, but signaling\n        #values which reuse the cipher suite field in the ClientHello.\n        wireCipherSuites = list(cipherSuites)\n        if settings.sendFallbackSCSV:\n            wireCipherSuites.append(CipherSuite.TLS_FALLBACK_SCSV)\n\n        #Initialize acceptable certificate types\n        certificateTypes = None  # settings.getCertificateTypes()\n\n        extensions = []\n        extensions.append(TLSExtension().\\\n                          create(self._get_GREASE(),\n                                 bytearray(0)))\n\n        if serverName:\n            serverName = bytearray(serverName, \"utf-8\")\n            sni_ext = SNIExtension().create(serverName)\n            extensions.append(sni_ext)\n\n        extensions.append(TLSExtension().create(ExtensionType.extended_master_secret, bytearray(0)))\n\n        extensions.append(TLSExtension().create(ExtensionType.renegotiation_info, bytearray(1)))\n\n        groups = [self._get_GREASE(), 0x001d, 0x0017, 0x0018]\n        extensions.append(SupportedGroupsExtension().create(groups))\n\n        extensions.append(ECPointFormatsExtension().create([ECPointFormat.uncompressed]))\n\n        extensions.append(TLSExtension().create(ExtensionType.session_ticket, bytearray(0)))\n\n        extensions.append(ALPNExtension().create(alpn))\n\n        extensions.append(StatusRequestExtension().create())\n\n        # In TLS1.2 advertise support for additional signature types\n        # sigList = self._sigHashesToList(settings)\n        # assert len(sigList) > 0\n        sigList = [\n            (4, 3),\n            (8, 4),\n            (4, 1),\n            (5, 3),\n            (8, 5),\n            (5, 1),\n            (8, 6),\n            (6, 1),\n        ]\n        extensions.append(SignatureAlgorithmsExtension().create(sigList))\n\n        extensions.append(TLSExtension().create(ExtensionType.signed_certificate_timestamp, bytearray(0)))\n\n        shares = []\n        grease_key_share = KeyShareEntry().create(self._get_GREASE(), bytearray(1))\n        shares.append(grease_key_share)\n        for group_name in [\"x25519\"]:\n            group_id = getattr(GroupName, group_name)\n            key_share = self._genKeyShareEntry(group_id, (3, 4))\n\n            shares.append(key_share)\n        # if TLS 1.3 is enabled, key_share must always be sent\n        # (unless only static PSK is used)\n        extensions.append(ClientKeyShareExtension().create(shares))\n\n        # add info on types of PSKs supported (also used for\n        # NewSessionTicket so send basically always)\n        psk_modes = [\"psk_dhe_ke\",]\n        ext = PskKeyExchangeModesExtension().create([getattr(PskKeyExchangeMode, i) for i in psk_modes])\n        extensions.append(ext)\n\n        versions = [self._get_GREASE_version(), (3, 4), (3, 3)]\n        extensions.append(SupportedVersionsExtension().create(versions))\n\n        algorithms = [\n            (0, 2)  # brotli\n        ]\n        extensions.append(CompressCertificateExtension().create(algorithms))\n\n        alpn = [bytearray(b\"h2\")]\n        extensions.append(ApplicationSettingsExtension().create(alpn))\n\n        GREASE_ID = self._get_GREASE()\n        extensions.append(TLSExtension().create(GREASE_ID, bytearray(1)))\n\n        # when TLS 1.3 advertised, add key shares, set fake session_id\n        # shares = None\n        session_id = getRandomBytes(32)\n\n        # don't send empty list of extensions or extensions in SSLv3\n        if not extensions or settings.maxVersion == (3, 0):\n            extensions = None\n\n        sent_version = min(settings.maxVersion, (3, 3))\n\n        #Either send ClientHello (with a resumable session)...\n        # if session and session.sessionID:\n        #     #If it's resumable, then its\n        #     #ciphersuite must be one of the acceptable ciphersuites\n        #     if session.cipherSuite not in cipherSuites:\n        #         raise ValueError(\"Session's cipher suite not consistent \"\\\n        #                          \"with parameters\")\n        #     else:\n        #         clientHello = ClientHello()\n        #         clientHello.create(sent_version, getRandomBytes(32),\n        #                            session.sessionID, wireCipherSuites,\n        #                            certificateTypes,\n        #                            session.srpUsername,\n        #                            reqTack, nextProtos is not None,\n        #                            session.serverName,\n        #                            extensions=extensions)\n        #\n        # #Or send ClientHello (without)\n        # else:\n        clientHello = ClientHello()\n        clientHello.create(sent_version, getRandomBytes(32),\n                           session_id, wireCipherSuites,\n                           certificateTypes,\n                           srpUsername,\n                           reqTack, nextProtos is not None,\n                           serverName,\n                           extensions=extensions)\n\n        # Check if padding extension should be added\n        # we want to add extensions even when using just SSLv3\n        if settings.usePaddingExtension:\n            HandshakeHelpers.alignClientHelloPadding(clientHello)\n\n        # because TLS 1.3 PSK is sent in ClientHello and signs the ClientHello\n        # we need to send it as the last extension\n        if (settings.pskConfigs or (session and session.tickets)) \\\n                and settings.maxVersion >= (3, 4):\n            ext = PreSharedKeyExtension()\n            idens = []\n            binders = []\n            # if we have a previous session, include it in PSKs too\n            if session and session.tickets:\n                now = time.time()\n                # clean the list from obsolete ones\n                # RFC says that the tickets MUST NOT be cached longer than\n                # 7 days\n                session.tickets[:] = (i for i in session.tickets if\n                                      i.time + i.ticket_lifetime > now and\n                                      i.time + 7 * 24 * 60 * 60 > now)\n                if session.tickets:\n                    ticket = session.tickets[0]\n\n                    # ticket.time is in seconds while the obfuscated time\n                    # is in ms\n                    ticket_time = int(\n                        time.time() * 1000 -\n                        ticket.time * 1000 +\n                        ticket.ticket_age_add) % 2**32\n                    idens.append(PskIdentity().create(ticket.ticket,\n                                                      ticket_time))\n                    binder_len = 48 if session.cipherSuite in \\\n                        CipherSuite.sha384PrfSuites else 32\n                    binders.append(bytearray(binder_len))\n            for psk in settings.pskConfigs:\n                # skip PSKs with no identities as they're TLS1.3 incompatible\n                if not psk[0]:\n                    continue\n                idens.append(PskIdentity().create(psk[0], 0))\n                psk_hash = psk[2] if len(psk) > 2 else 'sha256'\n                assert psk_hash in set(['sha256', 'sha384'])\n                # create fake binder values to create correct length fields\n                binders.append(bytearray(32 if psk_hash == 'sha256' else 48))\n\n            if idens:\n                ext.create(idens, binders)\n                clientHello.extensions.append(ext)\n\n                # for HRR case we'll need 1st CH and HRR in handshake hashes,\n                # so pass them in, truncated CH will be added by the helpers to\n                # the copy of the hashes\n                HandshakeHelpers.update_binders(clientHello,\n                                                self._handshake_hash,\n                                                settings.pskConfigs,\n                                                session.tickets if session\n                                                else None,\n                                                session.resumptionMasterSecret\n                                                if session else None)\n\n        for result in self._sendMsg(clientHello):\n            yield result\n        yield clientHello\n\n    def _clientGetServerHello(self, settings, session, clientHello):\n        client_hello_hash = self._handshake_hash.copy()\n        for result in self._getMsg(ContentType.handshake,\n                                   HandshakeType.server_hello):\n            if result in (0,1): yield result\n            else: break\n\n        hello_retry = None\n        ext = result.getExtension(ExtensionType.supported_versions)\n        if result.random == TLS_1_3_HRR and ext and ext.version > (3, 3):\n            self.version = ext.version\n            hello_retry = result\n\n            # create synthetic handshake hash\n            prf_name, prf_size = self._getPRFParams(hello_retry.cipher_suite)\n\n            self._handshake_hash = HandshakeHashes()\n            writer = Writer()\n            writer.add(HandshakeType.message_hash, 1)\n            writer.addVarSeq(client_hello_hash.digest(prf_name), 1, 3)\n            self._handshake_hash.update(writer.bytes)\n            self._handshake_hash.update(hello_retry.write())\n\n            # check if all extensions in the HRR were present in client hello\n            ch_ext_types = set(i.extType for i in clientHello.extensions)\n            ch_ext_types.add(ExtensionType.cookie)\n\n            bad_ext = next((i for i in hello_retry.extensions\n                            if i.extType not in ch_ext_types), None)\n            if bad_ext:\n                bad_ext = ExtensionType.toStr(bad_ext)\n                for result in self._sendError(AlertDescription\n                                              .unsupported_extension,\n                                              (\"Unexpected extension in HRR: \"\n                                               \"{0}\").format(bad_ext)):\n                    yield result\n\n            # handle cookie extension\n            cookie = hello_retry.getExtension(ExtensionType.cookie)\n            if cookie:\n                clientHello.addExtension(cookie)\n\n            # handle key share extension\n            sr_key_share_ext = hello_retry.getExtension(ExtensionType\n                                                        .key_share)\n            if sr_key_share_ext:\n                group_id = sr_key_share_ext.selected_group\n                # check if group selected by server is valid\n                groups_ext = clientHello.getExtension(ExtensionType\n                                                      .supported_groups)\n                if group_id not in groups_ext.groups:\n                    for result in self._sendError(AlertDescription\n                                                  .illegal_parameter,\n                                                  \"Server selected group we \"\n                                                  \"did not advertise\"):\n                        yield result\n\n                cl_key_share_ext = clientHello.getExtension(ExtensionType\n                                                            .key_share)\n                # check if the server didn't ask for a group we already sent\n                if next((entry for entry in cl_key_share_ext.client_shares\n                         if entry.group == group_id), None):\n                    for result in self._sendError(AlertDescription\n                                                  .illegal_parameter,\n                                                  \"Server selected group we \"\n                                                  \"did sent the key share \"\n                                                  \"for\"):\n                        yield result\n\n                key_share = self._genKeyShareEntry(group_id, (3, 4))\n\n                # old key shares need to be removed\n                cl_key_share_ext.client_shares = [key_share]\n\n            if not cookie and not sr_key_share_ext:\n                # HRR did not result in change to Client Hello\n                for result in self._sendError(AlertDescription.\n                                              illegal_parameter,\n                                              \"Received HRR did not cause \"\n                                              \"update to Client Hello\"):\n                    yield result\n\n            if clientHello.session_id != hello_retry.session_id:\n                for result in self._sendError(\n                        AlertDescription.illegal_parameter,\n                        \"Received HRR session_id does not match the one in \"\n                        \"ClientHello\"):\n                    yield result\n\n            ext = clientHello.getExtension(ExtensionType.pre_shared_key)\n            if ext:\n                # move the extension to end (in case extension like cookie was\n                # added\n                clientHello.extensions.remove(ext)\n                clientHello.extensions.append(ext)\n                HandshakeHelpers.update_binders(clientHello,\n                                                self._handshake_hash,\n                                                settings.pskConfigs,\n                                                session.tickets if session\n                                                else None,\n                                                session.resumptionMasterSecret\n                                                if session else None)\n\n            # resend the client hello with performed changes\n            msgs = []\n            if clientHello.session_id:\n                ccs = ChangeCipherSpec().create()\n                msgs.append(ccs)\n            msgs.append(clientHello)\n            for result in self._sendMsgs(msgs):\n                yield result\n            self._ccs_sent = True\n\n            # retry getting server hello\n            for result in self._getMsg(ContentType.handshake,\n                                       HandshakeType.server_hello):\n                if result in (0, 1):\n                    yield result\n                else:\n                    break\n\n        serverHello = result\n\n        #Get the server version.  Do this before anything else, so any\n        #error alerts will use the server's version\n        real_version = serverHello.server_version\n        if serverHello.server_version >= (3, 3):\n            ext = serverHello.getExtension(ExtensionType.supported_versions)\n            if ext:\n                real_version = ext.version\n        self.version = real_version\n\n        #Check ServerHello\n        if hello_retry and \\\n                hello_retry.cipher_suite != serverHello.cipher_suite:\n            for result in self._sendError(AlertDescription.illegal_parameter,\n                                          \"server selected different cipher \"\n                                          \"in HRR and Server Hello\"):\n                yield result\n        if real_version < settings.minVersion:\n            for result in self._sendError(\n                    AlertDescription.protocol_version,\n                    \"Too old version: {0} (min: {1})\"\n                    .format(real_version, settings.minVersion)):\n                yield result\n        if real_version > settings.maxVersion and \\\n                real_version not in settings.versions:\n            for result in self._sendError(\n                    AlertDescription.protocol_version,\n                    \"Too new version: {0} (max: {1})\"\n                    .format(real_version, settings.maxVersion)):\n                yield result\n        if real_version > (3, 3) and \\\n                serverHello.session_id != clientHello.session_id:\n            for result in self._sendError(\n                    AlertDescription.illegal_parameter,\n                    \"Received ServerHello session_id does not match the one \"\n                    \"in ClientHello\"):\n                yield result\n        cipherSuites = CipherSuite.filterForVersion(clientHello.cipher_suites,\n                                                    minVersion=real_version,\n                                                    maxVersion=real_version)\n        if serverHello.cipher_suite not in cipherSuites:\n            for result in self._sendError(\\\n                AlertDescription.illegal_parameter,\n                \"Server responded with incorrect ciphersuite\"):\n                yield result\n        if serverHello.certificate_type not in clientHello.certificate_types:\n            for result in self._sendError(\\\n                AlertDescription.illegal_parameter,\n                \"Server responded with incorrect certificate type\"):\n                yield result\n        if serverHello.compression_method != 0:\n            for result in self._sendError(\\\n                AlertDescription.illegal_parameter,\n                \"Server responded with incorrect compression method\"):\n                yield result\n        if serverHello.tackExt:            \n            if not clientHello.tack:\n                for result in self._sendError(\\\n                    AlertDescription.illegal_parameter,\n                    \"Server responded with unrequested Tack Extension\"):\n                    yield result\n            if not serverHello.tackExt.verifySignatures():\n                for result in self._sendError(\\\n                    AlertDescription.decrypt_error,\n                    \"TackExtension contains an invalid signature\"):\n                    yield result\n        if serverHello.next_protos and not clientHello.supports_npn:\n            for result in self._sendError(\\\n                AlertDescription.illegal_parameter,\n                \"Server responded with unrequested NPN Extension\"):\n                yield result\n        if not serverHello.getExtension(ExtensionType.extended_master_secret)\\\n            and settings.requireExtendedMasterSecret:\n            for result in self._sendError(\n                    AlertDescription.insufficient_security,\n                    \"Negotiation of Extended master Secret failed\"):\n                yield result\n        alpnExt = serverHello.getExtension(ExtensionType.alpn)\n        if alpnExt:\n            if not alpnExt.protocol_names or \\\n                    len(alpnExt.protocol_names) != 1:\n                for result in self._sendError(\n                        AlertDescription.illegal_parameter,\n                        \"Server responded with invalid ALPN extension\"):\n                    yield result\n            clntAlpnExt = clientHello.getExtension(ExtensionType.alpn)\n            if not clntAlpnExt:\n                for result in self._sendError(\n                        AlertDescription.unsupported_extension,\n                        \"Server sent ALPN extension without one in \"\n                        \"client hello\"):\n                    yield result\n            if alpnExt.protocol_names[0] not in clntAlpnExt.protocol_names:\n                for result in self._sendError(\n                        AlertDescription.illegal_parameter,\n                        \"Server selected ALPN protocol we did not advertise\"):\n                    yield result\n        heartbeat_ext = serverHello.getExtension(ExtensionType.heartbeat)\n        if heartbeat_ext:\n            if not settings.use_heartbeat_extension:\n                for result in self._sendError(\n                        AlertDescription.unsupported_extension,\n                        \"Server sent Heartbeat extension without one in \"\n                        \"client hello\"):\n                    yield result\n            if heartbeat_ext.mode == HeartbeatMode.PEER_ALLOWED_TO_SEND and \\\n                    settings.heartbeat_response_callback:\n                self.heartbeat_can_send = True\n                self.heartbeat_response_callback = settings.\\\n                    heartbeat_response_callback\n            elif heartbeat_ext.mode == HeartbeatMode.\\\n                    PEER_NOT_ALLOWED_TO_SEND or not settings.\\\n                    heartbeat_response_callback:\n                self.heartbeat_can_send = False\n            else:\n                for result in self._sendError(\n                        AlertDescription.illegal_parameter,\n                        \"Server responded with invalid Heartbeat extension\"):\n                    yield result\n            self.heartbeat_supported = True\n        size_limit_ext = serverHello.getExtension(\n            ExtensionType.record_size_limit)\n        if size_limit_ext:\n            if size_limit_ext.record_size_limit is None:\n                for result in self._sendError(\n                        AlertDescription.decode_error,\n                        \"Malformed record_size_limit extension\"):\n                    yield result\n            # if we got the extension in ServerHello it means we're doing\n            # TLS 1.2 so the max value for extension is 2^14\n            if not 64 <= size_limit_ext.record_size_limit <= 2**14:\n                for result in self._sendError(\n                        AlertDescription.illegal_parameter,\n                        \"Server responed with invalid value in \"\n                        \"record_size_limit extension\"):\n                    yield result\n            self._peer_record_size_limit = size_limit_ext.record_size_limit\n        yield serverHello\n\n    @staticmethod\n    def _getKEX(group, version):\n        \"\"\"Get object for performing key exchange.\"\"\"\n        if group in GroupName.allFF:\n            return FFDHKeyExchange(group, version)\n        return ECDHKeyExchange(group, version)\n\n    @classmethod\n    def _genKeyShareEntry(cls, group, version):\n        \"\"\"Generate KeyShareEntry object from randomly selected private value.\n        \"\"\"\n        kex = cls._getKEX(group, version)\n        private = kex.get_random_private_key()\n        share = kex.calc_public_value(private)\n        return KeyShareEntry().create(group, share, private)\n\n    @staticmethod\n    def _getPRFParams(cipher_suite):\n        \"\"\"Return name of hash used for PRF and the hash output size.\"\"\"\n        if cipher_suite in CipherSuite.sha384PrfSuites:\n            return 'sha384', 48\n        return 'sha256', 32\n\n    def _clientTLS13Handshake(self, settings, session, clientHello,\n                              clientCertChain, privateKey, serverHello):\n        \"\"\"Perform TLS 1.3 handshake as a client.\"\"\"\n        prfName, prf_size = self._getPRFParams(serverHello.cipher_suite)\n\n        # we have client and server hello in TLS 1.3 so we have the necessary\n        # key shares to derive the handshake receive key\n        sr_kex = serverHello.getExtension(ExtensionType.key_share)\n        sr_psk = serverHello.getExtension(ExtensionType.pre_shared_key)\n        if not sr_kex and not sr_psk:\n            raise TLSIllegalParameterException(\"Server did not select PSK nor \"\n                                               \"an (EC)DH group\")\n        if sr_kex:\n            sr_kex = sr_kex.server_share\n            self.ecdhCurve = sr_kex.group\n            cl_key_share_ex = clientHello.getExtension(ExtensionType.key_share)\n            cl_kex = next((i for i in cl_key_share_ex.client_shares\n                           if i.group == sr_kex.group), None)\n            if cl_kex is None:\n                raise TLSIllegalParameterException(\"Server selected not \"\n                                                   \"advertised group.\")\n            kex = self._getKEX(sr_kex.group, self.version)\n\n            shared_sec = kex.calc_shared_key(cl_kex.private,\n                                             sr_kex.key_exchange)\n        else:\n            shared_sec = bytearray(prf_size)\n\n        # if server agreed to perform resumption, find the matching secret key\n        resuming = False\n        if sr_psk:\n            clPSK = clientHello.getExtension(ExtensionType.pre_shared_key)\n            ident = clPSK.identities[sr_psk.selected]\n            psk = [i[1] for i in settings.pskConfigs if i[0] == ident.identity]\n            if psk:\n                psk = psk[0]\n            else:\n                resuming = True\n                psk = HandshakeHelpers.calc_res_binder_psk(\n                    ident, session.resumptionMasterSecret,\n                    session.tickets)\n        else:\n            psk = bytearray(prf_size)\n\n        secret = bytearray(prf_size)\n        # Early Secret\n        secret = secureHMAC(secret, psk, prfName)\n\n        # Handshake Secret\n        secret = derive_secret(secret, bytearray(b'derived'),\n                               None, prfName)\n        secret = secureHMAC(secret, shared_sec, prfName)\n\n        sr_handshake_traffic_secret = derive_secret(secret,\n                                                    bytearray(b's hs traffic'),\n                                                    self._handshake_hash,\n                                                    prfName)\n        cl_handshake_traffic_secret = derive_secret(secret,\n                                                    bytearray(b'c hs traffic'),\n                                                    self._handshake_hash,\n                                                    prfName)\n\n        # prepare for reading encrypted messages\n        self._recordLayer.calcTLS1_3PendingState(\n            serverHello.cipher_suite,\n            cl_handshake_traffic_secret,\n            sr_handshake_traffic_secret,\n            settings.cipherImplementations)\n\n        self._changeReadState()\n\n        for result in self._getMsg(ContentType.handshake,\n                                   HandshakeType.encrypted_extensions):\n            if result in (0, 1):\n                yield result\n            else:\n                break\n        encrypted_extensions = result\n        assert isinstance(encrypted_extensions, EncryptedExtensions)\n\n        size_limit_ext = encrypted_extensions.getExtension(\n            ExtensionType.record_size_limit)\n        if size_limit_ext and not settings.record_size_limit:\n            for result in self._sendError(\n                    AlertDescription.illegal_parameter,\n                    \"Server sent record_size_limit extension despite us not \"\n                    \"advertising it\"):\n                yield result\n        if size_limit_ext:\n            if size_limit_ext.record_size_limit is None:\n                for result in self._sendError(\n                        AlertDescription.decode_error,\n                        \"Malformed record_size_limit extension\"):\n                    yield result\n            if not 64 <= size_limit_ext.record_size_limit <= 2**14+1:\n                for result in self._sendError(\n                        AlertDescription.illegal_parameter,\n                        \"Invalid valid in record_size_limit extension\"):\n                    yield result\n            # the record layer code expects a limit that excludes content type\n            # from the value while extension is defined including it\n            self._send_record_limit = size_limit_ext.record_size_limit - 1\n            self._recv_record_limit = min(2**14, settings.record_size_limit - 1)\n\n        # if we negotiated PSK then Certificate is not sent\n        certificate_request = None\n        certificate = None\n        if not sr_psk:\n            for result in self._getMsg(ContentType.handshake,\n                                       (HandshakeType.certificate_request,\n                                        HandshakeType.certificate,\n                                        HandshakeType.compressed_certificate),\n                                       CertificateType.x509):\n                if result in (0, 1):\n                    yield result\n                else:\n                    break\n\n            if isinstance(result, CertificateRequest):\n                certificate_request = result\n\n                # we got CertificateRequest so now we'll get Certificate\n                for result in self._getMsg(ContentType.handshake,\n                                           HandshakeType.certificate,\n                                           CertificateType.x509):\n                    if result in (0, 1):\n                        yield result\n                    else:\n                        break\n\n            certificate = result\n            assert isinstance(certificate, Certificate)\n\n            srv_cert_verify_hh = self._handshake_hash.copy()\n\n            for result in self._getMsg(ContentType.handshake,\n                                       HandshakeType.certificate_verify):\n                if result in (0, 1):\n                    yield result\n                else:\n                    break\n            certificate_verify = result\n            assert isinstance(certificate_verify, CertificateVerify)\n\n            signature_scheme = certificate_verify.signatureAlgorithm\n            self.serverSigAlg = signature_scheme\n\n            signature_context = KeyExchange.calcVerifyBytes((3, 4),\n                                                            srv_cert_verify_hh,\n                                                            signature_scheme,\n                                                            None, None, None,\n                                                            prfName, b'server')\n\n            for result in self._clientGetKeyFromChain(certificate, settings):\n                if result in (0, 1):\n                    yield result\n                else:\n                    break\n            publicKey, serverCertChain, tackExt = result\n\n            if signature_scheme in (SignatureScheme.ed25519,\n                                    SignatureScheme.ed448):\n                pad_type = None\n                hash_name = \"intrinsic\"\n                salt_len = None\n                method = publicKey.hashAndVerify\n            elif signature_scheme[1] == SignatureAlgorithm.ecdsa:\n                pad_type = None\n                hash_name = HashAlgorithm.toRepr(signature_scheme[0])\n                matching_hash = self._curve_name_to_hash_name(\n                    publicKey.curve_name)\n                if hash_name != matching_hash:\n                    raise TLSIllegalParameterException(\n                        \"server selected signature method invalid for the \"\n                        \"certificate it presented (curve mismatch)\")\n\n                salt_len = None\n                method = publicKey.verify\n            else:\n                scheme = SignatureScheme.toRepr(signature_scheme)\n                pad_type = SignatureScheme.getPadding(scheme)\n                hash_name = SignatureScheme.getHash(scheme)\n                salt_len = getattr(hashlib, hash_name)().digest_size\n                method = publicKey.verify\n\n            if not method(certificate_verify.signature,\n                          signature_context,\n                          pad_type,\n                          hash_name,\n                          salt_len):\n                raise TLSDecryptionFailed(\"server Certificate Verify \"\n                                          \"signature \"\n                                          \"verification failed\")\n\n        transcript_hash = self._handshake_hash.digest(prfName)\n\n        for result in self._getMsg(ContentType.handshake,\n                                   HandshakeType.finished,\n                                   prf_size):\n            if result in (0, 1):\n                yield result\n            else:\n                break\n        finished = result\n\n        server_finish_hs = self._handshake_hash.copy()\n\n        assert isinstance(finished, Finished)\n\n        finished_key = HKDF_expand_label(sr_handshake_traffic_secret,\n                                         b\"finished\", b'', prf_size, prfName)\n        verify_data = secureHMAC(finished_key, transcript_hash, prfName)\n\n        if finished.verify_data != verify_data:\n            raise TLSDecryptionFailed(\"Finished value is not valid\")\n\n        # now send client set of messages\n        self._changeWriteState()\n\n        # Master secret\n        secret = derive_secret(secret, bytearray(b'derived'), None, prfName)\n        secret = secureHMAC(secret, bytearray(prf_size), prfName)\n\n        cl_app_traffic = derive_secret(secret, bytearray(b'c ap traffic'),\n                                       server_finish_hs, prfName)\n        sr_app_traffic = derive_secret(secret, bytearray(b's ap traffic'),\n                                       server_finish_hs, prfName)\n\n        if certificate_request:\n            client_certificate = Certificate(serverHello.certificate_type,\n                                             self.version)\n            if clientCertChain:\n                # Check to make sure we have the same type of certificates the\n                # server requested\n                if serverHello.certificate_type == CertificateType.x509 \\\n                    and not isinstance(clientCertChain, X509CertChain):\n                    for result in self._sendError(\n                            AlertDescription.handshake_failure,\n                            \"Client certificate is of wrong type\"):\n                        yield result\n\n            client_certificate.create(clientCertChain)\n            # we need to send the message even if we don't have a certificate\n            for result in self._sendMsg(client_certificate):\n                yield result\n\n            if clientCertChain and privateKey:\n                valid_sig_algs = certificate_request.supported_signature_algs\n                if not valid_sig_algs:\n                    for result in self._sendError(\n                            AlertDescription.missing_extension,\n                            \"No Signature Algorithms found\"):\n                        yield result\n\n                availSigAlgs = self._sigHashesToList(settings, privateKey,\n                                                     clientCertChain,\n                                                     version=(3, 4))\n                signature_scheme = getFirstMatching(availSigAlgs,\n                                                    valid_sig_algs)\n                scheme = SignatureScheme.toRepr(signature_scheme)\n                signature_scheme = getattr(SignatureScheme, scheme)\n\n                signature_context = \\\n                    KeyExchange.calcVerifyBytes((3, 4), self._handshake_hash,\n                                                signature_scheme, None, None,\n                                                None, prfName, b'client')\n\n                if signature_scheme in (SignatureScheme.ed25519,\n                        SignatureScheme.ed448):\n                    pad_type = None\n                    hash_name = \"intrinsic\"\n                    salt_len = None\n                    sig_func = privateKey.hashAndSign\n                    ver_func = privateKey.hashAndVerify\n                elif signature_scheme[1] == SignatureAlgorithm.ecdsa:\n                    pad_type = None\n                    hash_name = HashAlgorithm.toRepr(signature_scheme[0])\n                    salt_len = None\n                    sig_func = privateKey.sign\n                    ver_func = privateKey.verify\n                else:\n                    pad_type = SignatureScheme.getPadding(scheme)\n                    hash_name = SignatureScheme.getHash(scheme)\n                    salt_len = getattr(hashlib, hash_name)().digest_size\n                    sig_func = privateKey.sign\n                    ver_func = privateKey.verify\n\n                signature = sig_func(signature_context,\n                                     pad_type,\n                                     hash_name,\n                                     salt_len)\n                if not ver_func(signature, signature_context,\n                                pad_type,\n                                hash_name,\n                                salt_len):\n                    for result in self._sendError(\n                            AlertDescription.internal_error,\n                            \"Certificate Verify signature failed\"):\n                        yield result\n\n                certificate_verify = CertificateVerify(self.version)\n                certificate_verify.create(signature, signature_scheme)\n\n                for result in self._sendMsg(certificate_verify):\n                    yield result\n\n        # Do after client cert and verify messages has been sent.\n        exporter_master_secret = derive_secret(secret,\n                                               bytearray(b'exp master'),\n                                               self._handshake_hash, prfName)\n\n        self._recordLayer.calcTLS1_3PendingState(\n            serverHello.cipher_suite,\n            cl_app_traffic,\n            sr_app_traffic,\n            settings.cipherImplementations)\n        # be ready to process alert messages from the server, which\n        # MUST be encrypted with ap traffic secret when they are sent after\n        # Finished\n        self._changeReadState()\n\n        cl_finished_key = HKDF_expand_label(cl_handshake_traffic_secret,\n                                            b\"finished\", b'',\n                                            prf_size, prfName)\n        cl_verify_data = secureHMAC(\n            cl_finished_key,\n            self._handshake_hash.digest(prfName),\n            prfName)\n\n        cl_finished = Finished(self.version, prf_size)\n        cl_finished.create(cl_verify_data)\n\n        if not self._ccs_sent and clientHello.session_id:\n            ccs = ChangeCipherSpec().create()\n            msgs = [ccs, cl_finished]\n        else:\n            msgs = [cl_finished]\n\n        for result in self._sendMsgs(msgs):\n            yield result\n\n        # CCS messages are not allowed in post handshake authentication\n        self._middlebox_compat_mode = False\n\n        # fully switch to application data\n        self._changeWriteState()\n\n        self._first_handshake_hashes = self._handshake_hash.copy()\n\n        resumption_master_secret = derive_secret(secret,\n                                                 bytearray(b'res master'),\n                                                 self._handshake_hash, prfName)\n\n        self.session = Session()\n        self.extendedMasterSecret = True\n\n        serverName = None\n        if clientHello.server_name:\n            serverName = clientHello.server_name.decode(\"utf-8\")\n\n        appProto = None\n        alpnExt = encrypted_extensions.getExtension(ExtensionType.alpn)\n        if alpnExt:\n            appProto = alpnExt.protocol_names[0]\n\n        heartbeat_ext = encrypted_extensions.getExtension(ExtensionType.heartbeat)\n        if heartbeat_ext:\n            if not settings.use_heartbeat_extension:\n                for result in self._sendError(\n                        AlertDescription.unsupported_extension,\n                        \"Server sent Heartbeat extension without one in \"\n                        \"client hello\"):\n                    yield result\n            if heartbeat_ext.mode == HeartbeatMode.PEER_ALLOWED_TO_SEND and \\\n                    settings.heartbeat_response_callback:\n                self.heartbeat_can_send = True\n                self.heartbeat_response_callback = settings.\\\n                    heartbeat_response_callback\n            elif heartbeat_ext.mode == HeartbeatMode.\\\n                    PEER_NOT_ALLOWED_TO_SEND or not settings.\\\n                    heartbeat_response_callback:\n                self.heartbeat_can_send = False\n            else:\n                for result in self._sendError(\n                        AlertDescription.illegal_parameter,\n                        \"Server responded with invalid Heartbeat extension\"):\n                    yield result\n            self.heartbeat_supported = True\n\n        self.session.create(secret,\n                            bytearray(b''),  # no session_id in TLS 1.3\n                            serverHello.cipher_suite,\n                            None,  # no SRP\n                            clientCertChain,\n                            certificate.cert_chain if certificate else None,\n                            None,  # no TACK\n                            False,  # no TACK in hello\n                            serverName,\n                            encryptThenMAC=False,  # all ciphers are AEAD\n                            extendedMasterSecret=True,  # all TLS1.3 are EMS\n                            appProto=appProto,\n                            cl_app_secret=cl_app_traffic,\n                            sr_app_secret=sr_app_traffic,\n                            exporterMasterSecret=exporter_master_secret,\n                            resumptionMasterSecret=resumption_master_secret,\n                            # NOTE it must be a reference, not a copy!\n                            tickets=self.tickets)\n\n        yield \"finished\" if not resuming else \"resumed_and_finished\"\n\n    def _clientSelectNextProto(self, nextProtos, serverHello):\n        # nextProtos is None or non-empty list of strings\n        # serverHello.next_protos is None or possibly-empty list of strings\n        #\n        # !!! We assume the client may have specified nextProtos as a list of\n        # strings so we convert them to bytearrays (it's awkward to require\n        # the user to specify a list of bytearrays or \"bytes\", and in \n        # Python 2.6 bytes() is just an alias for str() anyways...\n        if nextProtos is not None and serverHello.next_protos is not None:\n            for p in nextProtos:\n                if bytearray(p) in serverHello.next_protos:\n                    return bytearray(p)\n            else:\n                # If the client doesn't support any of server's protocols,\n                # or the server doesn't advertise any (next_protos == [])\n                # the client SHOULD select the first protocol it supports.\n                return bytearray(nextProtos[0])\n        return None\n \n    def _clientResume(self, session, serverHello, clientRandom, \n                      cipherImplementations, nextProto, settings):\n        #If the server agrees to resume\n        if session and session.sessionID and \\\n            serverHello.session_id == session.sessionID:\n\n            if serverHello.cipher_suite != session.cipherSuite:\n                for result in self._sendError(\\\n                    AlertDescription.illegal_parameter,\\\n                    \"Server's ciphersuite doesn't match session\"):\n                    yield result\n\n            #Calculate pending connection states\n            self._calcPendingStates(session.cipherSuite,\n                                    session.masterSecret,\n                                    clientRandom, serverHello.random,\n                                    cipherImplementations)\n\n            #Exchange ChangeCipherSpec and Finished messages\n            for result in self._getFinished(session.masterSecret,\n                                            session.cipherSuite):\n                yield result\n            # buffer writes so that CCS and Finished go out in one TCP packet\n            self.sock.buffer_writes = True\n            for result in self._sendFinished(session.masterSecret,\n                                             session.cipherSuite,\n                                             nextProto,\n                                             settings=settings):\n                yield result\n            self.sock.flush()\n            self.sock.buffer_writes = False\n\n            #Set the session for this connection\n            self.session = session\n            yield \"resumed_and_finished\"\n\n    def _clientKeyExchange(self, settings, cipherSuite,\n                           clientCertChain, privateKey,\n                           certificateType,\n                           tackExt, clientRandom, serverRandom,\n                           keyExchange):\n        \"\"\"Perform the client side of key exchange\"\"\"\n        # if server chose cipher suite with authentication, get the certificate\n        if cipherSuite in CipherSuite.certAllSuites or \\\n                cipherSuite in CipherSuite.ecdheEcdsaSuites or \\\n                cipherSuite in CipherSuite.dheDsaSuites:\n            for result in self._getMsg(ContentType.handshake,\n                                       HandshakeType.certificate,\n                                       certificateType):\n                if result in (0, 1):\n                    yield result\n                else: break\n            serverCertificate = result\n        else:\n            serverCertificate = None\n        # if server chose RSA key exchange, we need to skip SKE message\n        if cipherSuite not in CipherSuite.certSuites:\n            for result in self._getMsg(ContentType.handshake,\n                                       HandshakeType.server_key_exchange,\n                                       cipherSuite):\n                if result in (0, 1):\n                    yield result\n                else: break\n            serverKeyExchange = result\n        else:\n            serverKeyExchange = None\n\n        for result in self._getMsg(ContentType.handshake,\n                                   (HandshakeType.certificate_request,\n                                    HandshakeType.server_hello_done)):\n            if result in (0, 1):\n                yield result\n            else: break\n\n        certificateRequest = None\n        if isinstance(result, CertificateRequest):\n            certificateRequest = result\n\n            #abort if Certificate Request with inappropriate ciphersuite\n            if cipherSuite not in CipherSuite.certAllSuites \\\n                and cipherSuite not in CipherSuite.ecdheEcdsaSuites \\\n                and CipherSuite not in CipherSuite.dheDsaSuites\\\n                or cipherSuite in CipherSuite.srpAllSuites:\n                for result in self._sendError(\\\n                        AlertDescription.unexpected_message,\n                        \"Certificate Request with incompatible cipher suite\"):\n                    yield result\n\n            # we got CertificateRequest so now we'll get ServerHelloDone\n            for result in self._getMsg(ContentType.handshake,\n                                       HandshakeType.server_hello_done):\n                if result in (0, 1):\n                    yield result\n                else: break\n        serverHelloDone = result\n\n        serverCertChain = None\n        publicKey = None\n        if cipherSuite in CipherSuite.certAllSuites or \\\n                cipherSuite in CipherSuite.ecdheEcdsaSuites or \\\n                cipherSuite in CipherSuite.dheDsaSuites:\n            # get the certificate\n            for result in self._clientGetKeyFromChain(serverCertificate,\n                                                      settings,\n                                                      tackExt):\n                if result in (0, 1):\n                    yield result\n                else: break\n            publicKey, serverCertChain, tackExt = result\n\n            #Check the server's signature, if the server chose an authenticated\n            # PFS-enabled ciphersuite\n\n            if serverKeyExchange:\n                valid_sig_algs = \\\n                    self._sigHashesToList(settings,\n                                          certList=serverCertChain)\n                try:\n                    KeyExchange.verifyServerKeyExchange(serverKeyExchange,\n                                                        publicKey,\n                                                        clientRandom,\n                                                        serverRandom,\n                                                        valid_sig_algs)\n                except TLSIllegalParameterException:\n                    for result in self._sendError(AlertDescription.\\\n                                                  illegal_parameter):\n                        yield result\n                except TLSDecryptionFailed:\n                    for result in self._sendError(\\\n                            AlertDescription.decrypt_error):\n                        yield result\n\n        if serverKeyExchange:\n            # store key exchange metadata for user applications\n            if self.version >= (3, 3) \\\n                    and (cipherSuite in CipherSuite.certAllSuites or\n                         cipherSuite in CipherSuite.ecdheEcdsaSuites) \\\n                    and cipherSuite not in CipherSuite.certSuites:\n                self.serverSigAlg = (serverKeyExchange.hashAlg,\n                                     serverKeyExchange.signAlg)\n\n            if cipherSuite in CipherSuite.dhAllSuites:\n                self.dhGroupSize = numBits(serverKeyExchange.dh_p)\n            if cipherSuite in CipherSuite.ecdhAllSuites:\n                self.ecdhCurve = serverKeyExchange.named_curve\n\n        #Send Certificate if we were asked for it\n        if certificateRequest:\n\n            # if a peer doesn't advertise support for any algorithm in TLSv1.2,\n            # support for SHA1+RSA can be assumed\n            if self.version == (3, 3)\\\n                and not [sig for sig in \\\n                         certificateRequest.supported_signature_algs\\\n                         if sig[1] == SignatureAlgorithm.rsa]:\n                for result in self._sendError(\\\n                        AlertDescription.handshake_failure,\n                        \"Server doesn't accept any sigalgs we support: \" +\n                        str(certificateRequest.supported_signature_algs)):\n                    yield result\n            clientCertificate = Certificate(certificateType)\n\n            if clientCertChain:\n                #Check to make sure we have the same type of\n                #certificates the server requested\n                if certificateType == CertificateType.x509 \\\n                    and not isinstance(clientCertChain, X509CertChain):\n                    for result in self._sendError(\\\n                            AlertDescription.handshake_failure,\n                            \"Client certificate is of wrong type\"):\n                        yield result\n\n                clientCertificate.create(clientCertChain)\n            # we need to send the message even if we don't have a certificate\n            for result in self._sendMsg(clientCertificate):\n                yield result\n        else:\n            #Server didn't ask for cer, zeroise so session doesn't store them\n            privateKey = None\n            clientCertChain = None\n\n        try:\n            ske = serverKeyExchange\n            premasterSecret = keyExchange.processServerKeyExchange(publicKey,\n                                                                   ske)\n        except TLSInsufficientSecurity as e:\n            for result in self._sendError(\\\n                    AlertDescription.insufficient_security, e):\n                yield result\n        except TLSIllegalParameterException as e:\n            for result in self._sendError(\\\n                    AlertDescription.illegal_parameter, e):\n                yield result\n\n        clientKeyExchange = keyExchange.makeClientKeyExchange()\n\n        #Send ClientKeyExchange\n        for result in self._sendMsg(clientKeyExchange):\n            yield result\n\n        # the Extended Master Secret calculation uses the same handshake\n        # hashes as the Certificate Verify calculation so we need to\n        # make a copy of it\n        self._certificate_verify_handshake_hash = self._handshake_hash.copy()\n\n        #if client auth was requested and we have a private key, send a\n        #CertificateVerify\n        if certificateRequest and privateKey:\n            valid_sig_algs = self._sigHashesToList(settings, privateKey,\n                                                   clientCertChain)\n            try:\n                certificateVerify = KeyExchange.makeCertificateVerify(\n                    self.version,\n                    self._certificate_verify_handshake_hash,\n                    valid_sig_algs,\n                    privateKey,\n                    certificateRequest,\n                    premasterSecret,\n                    clientRandom,\n                    serverRandom)\n            except TLSInternalError as exception:\n                for result in self._sendError(\n                        AlertDescription.internal_error, exception):\n                    yield result\n            for result in self._sendMsg(certificateVerify):\n                yield result\n\n        yield (premasterSecret, serverCertChain, clientCertChain, tackExt)\n\n    def _clientFinished(self, premasterSecret, clientRandom, serverRandom,\n                        cipherSuite, cipherImplementations, nextProto,\n                        settings):\n        if self.extendedMasterSecret:\n            cvhh = self._certificate_verify_handshake_hash\n            # in case of session resumption, or when the handshake doesn't\n            # use the certificate authentication, the hashes are the same\n            if not cvhh:\n                cvhh = self._handshake_hash\n            masterSecret = calc_key(self.version, premasterSecret,\n                                    cipherSuite, b\"extended master secret\",\n                                    handshake_hashes=cvhh,\n                                    output_length=48)\n        else:\n            masterSecret = calc_key(self.version, premasterSecret,\n                                    cipherSuite, b\"master secret\",\n                                    client_random=clientRandom,\n                                    server_random=serverRandom,\n                                    output_length=48)\n        self._calcPendingStates(cipherSuite, masterSecret, \n                                clientRandom, serverRandom, \n                                cipherImplementations)\n\n        #Exchange ChangeCipherSpec and Finished messages\n        for result in self._sendFinished(masterSecret, cipherSuite, nextProto,\n                settings=settings):\n            yield result\n        self.sock.flush()\n        self.sock.buffer_writes = False\n        for result in self._getFinished(masterSecret,\n                                        cipherSuite,\n                                        nextProto=nextProto):\n            yield result\n        yield masterSecret\n\n    def _check_certchain_with_settings(self, cert_chain, settings):\n        \"\"\"\n        Verify that the key parameters match enabled ones.\n\n        Checks if the certificate key size matches the minimum and maximum\n        sizes set or that it uses curves enabled in settings\n        \"\"\"\n        #Get and check public key from the cert chain\n        publicKey = cert_chain.getEndEntityPublicKey()\n        cert_type = cert_chain.x509List[0].certAlg\n        if cert_type == \"ecdsa\":\n            curve_name = publicKey.curve_name\n            for name, aliases in CURVE_ALIASES.items():\n                if curve_name in aliases:\n                    curve_name = name\n                    break\n\n            if self.version <= (3, 3) and curve_name not in settings.eccCurves:\n                for result in self._sendError(\n                        AlertDescription.handshake_failure,\n                        \"Peer sent certificate with curve we did not \"\n                        \"advertise support for: {0}\".format(curve_name)):\n                    yield result\n            if self.version >= (3, 4):\n                if curve_name not in ('secp256r1', 'secp384r1', 'secp521r1'):\n                    for result in self._sendError(\n                            AlertDescription.illegal_parameter,\n                            \"Peer sent certificate with curve not supported \"\n                            \"in TLS 1.3: {0}\".format(curve_name)):\n                        yield result\n                if curve_name == 'secp256r1':\n                    sig_alg_for_curve = 'sha256'\n                elif curve_name == 'secp384r1':\n                    sig_alg_for_curve = 'sha384'\n                else:\n                    assert curve_name == 'secp521r1'\n                    sig_alg_for_curve = 'sha512'\n                if sig_alg_for_curve not in settings.ecdsaSigHashes:\n                    for result in self._sendError(\n                            AlertDescription.illegal_parameter,\n                            \"Peer selected certificate with ECDSA curve we \"\n                            \"did not advertise support for: {0}\"\n                            .format(curve_name)):\n                        yield result\n        elif cert_type in (\"Ed25519\", \"Ed448\"):\n            if self.version < (3, 3):\n                for result in self._sendError(\n                        AlertDescription.illegal_parameter,\n                        \"Peer sent certificate incompatible with negotiated \"\n                        \"TLS version\"):\n                    yield result\n            if cert_type not in settings.more_sig_schemes:\n                for result in self._sendError(\n                        AlertDescription.handshake_failure,\n                        \"Peer sent certificate we did not advertise support \"\n                        \"for: {0}\".format(cert_type)):\n                    yield result\n\n        else:\n            # for RSA and DSA keys\n            if len(publicKey) < settings.minKeySize:\n                for result in self._sendError(\n                        AlertDescription.handshake_failure,\n                        \"Other party's public key too small: %d\" %\n                        len(publicKey)):\n                    yield result\n            if len(publicKey) > settings.maxKeySize:\n                for result in self._sendError(\n                        AlertDescription.handshake_failure,\n                        \"Other party's public key too large: %d\" %\n                        len(publicKey)):\n                    yield result\n        yield publicKey\n\n    def _clientGetKeyFromChain(self, certificate, settings, tack_ext=None):\n        #Get and check cert chain from the Certificate message\n        cert_chain = certificate.cert_chain\n        if not cert_chain or cert_chain.getNumCerts() == 0:\n            for result in self._sendError(\n                    AlertDescription.illegal_parameter,\n                    \"Other party sent a Certificate message without \"\\\n                    \"certificates\"):\n                yield result\n\n        for result in self._check_certchain_with_settings(\n                cert_chain,\n                settings):\n            if result in (0, 1):\n                yield result\n            else: break\n        public_key = result\n\n        # If there's no TLS Extension, look for a TACK cert\n        if tackpyLoaded:\n            if not tack_ext:\n                tack_ext = cert_chain.getTackExt()\n         \n            # If there's a TACK (whether via TLS or TACK Cert), check that it\n            # matches the cert chain   \n            if tack_ext and tack_ext.tacks:\n                for tack in tack_ext.tacks:\n                    if not cert_chain.checkTack(tack):\n                        for result in self._sendError(  \n                                AlertDescription.illegal_parameter,\n                                \"Other party's TACK doesn't match their public key\"):\n                                yield result\n\n        yield public_key, cert_chain, tack_ext\n\n\n    #*********************************************************\n    # Server Handshake Functions\n    #*********************************************************\n\n\n    def handshakeServer(self, verifierDB=None,\n                        certChain=None, privateKey=None, reqCert=False,\n                        sessionCache=None, settings=None, checker=None,\n                        reqCAs = None, \n                        tacks=None, activationFlags=0,\n                        nextProtos=None, anon=False, alpn=None, sni=None):\n        \"\"\"Perform a handshake in the role of server.\n\n        This function performs an SSL or TLS handshake.  Depending on\n        the arguments and the behavior of the client, this function can\n        perform an SRP, or certificate-based handshake.  It\n        can also perform a combined SRP and server-certificate\n        handshake.\n\n        Like any handshake function, this can be called on a closed\n        TLS connection, or on a TLS connection that is already open.\n        If called on an open connection it performs a re-handshake.\n        This function does not send a Hello Request message before\n        performing the handshake, so if re-handshaking is required,\n        the server must signal the client to begin the re-handshake\n        through some other means.\n\n        If the function completes without raising an exception, the\n        TLS connection will be open and available for data transfer.\n\n        If an exception is raised, the connection will have been\n        automatically closed (if it was ever open).\n\n        :type verifierDB: ~tlslite.verifierdb.VerifierDB\n        :param verifierDB: A database of SRP password verifiers\n            associated with usernames.  If the client performs an SRP\n            handshake, the session's srpUsername attribute will be set.\n\n        :type certChain: ~tlslite.x509certchain.X509CertChain\n        :param certChain: The certificate chain to be used if the\n            client requests server certificate authentication and no virtual\n            host defined in HandshakeSettings matches ClientHello.\n\n        :type privateKey: ~tlslite.utils.rsakey.RSAKey\n        :param privateKey: The private key to be used if the client\n            requests server certificate authentication and no virtual host\n            defined in HandshakeSettings matches ClientHello.\n\n        :type reqCert: bool\n        :param reqCert: Whether to request client certificate\n            authentication.  This only applies if the client chooses server\n            certificate authentication; if the client chooses SRP\n            authentication, this will be ignored.  If the client\n            performs a client certificate authentication, the sessions's\n            clientCertChain attribute will be set.\n\n        :type sessionCache: ~tlslite.sessioncache.SessionCache\n        :param sessionCache: An in-memory cache of resumable sessions.\n            The client can resume sessions from this cache.  Alternatively,\n            if the client performs a full handshake, a new session will be\n            added to the cache.\n\n        :type settings: ~tlslite.handshakesettings.HandshakeSettings\n        :param settings: Various settings which can be used to control\n            the ciphersuites and SSL/TLS version chosen by the server.\n\n        :type checker: ~tlslite.checker.Checker\n        :param checker: A Checker instance.  This instance will be\n            invoked to examine the other party's authentication\n            credentials, if the handshake completes succesfully.\n\n        :type reqCAs: list of bytearray\n        :param reqCAs: A collection of DER-encoded DistinguishedNames that\n            will be sent along with a certificate request to help client pick\n            a certificates. This does not affect verification.\n\n        :type nextProtos: list of str\n        :param nextProtos: A list of upper layer protocols to expose to the\n            clients through the Next-Protocol Negotiation Extension,\n            if they support it. Deprecated, use the `virtual_hosts` in\n            HandshakeSettings.\n\n        :type alpn: list of bytearray\n        :param alpn: names of application layer protocols supported.\n            Note that it will be used instead of NPN if both were advertised by\n            client. Deprecated, use the `virtual_hosts` in HandshakeSettings.\n\n        :type sni: bytearray\n        :param sni: expected virtual name hostname. Deprecated, use the\n            `virtual_hosts` in HandshakeSettings.\n\n        :raises socket.error: If a socket error occurs.\n        :raises tlslite.errors.TLSAbruptCloseError: If the socket is closed\n            without a preceding alert.\n        :raises tlslite.errors.TLSAlert: If a TLS alert is signalled.\n        :raises tlslite.errors.TLSAuthenticationError: If the checker\n            doesn't like the other party's authentication credentials.\n        \"\"\"\n        for result in self.handshakeServerAsync(verifierDB,\n                certChain, privateKey, reqCert, sessionCache, settings,\n                checker, reqCAs,\n                tacks=tacks, activationFlags=activationFlags,\n                nextProtos=nextProtos, anon=anon, alpn=alpn, sni=sni):\n            pass\n\n\n    def handshakeServerAsync(self, verifierDB=None,\n                             certChain=None, privateKey=None, reqCert=False,\n                             sessionCache=None, settings=None, checker=None,\n                             reqCAs=None, \n                             tacks=None, activationFlags=0,\n                             nextProtos=None, anon=False, alpn=None, sni=None\n                             ):\n        \"\"\"Start a server handshake operation on the TLS connection.\n\n        This function returns a generator which behaves similarly to\n        handshakeServer().  Successive invocations of the generator\n        will return 0 if it is waiting to read from the socket, 1 if it is\n        waiting to write to the socket, or it will raise StopIteration\n        if the handshake operation is complete.\n\n        :rtype: iterable\n        :returns: A generator; see above for details.\n        \"\"\"\n        handshaker = self._handshakeServerAsyncHelper(\\\n            verifierDB=verifierDB, cert_chain=certChain,\n            privateKey=privateKey, reqCert=reqCert,\n            sessionCache=sessionCache, settings=settings, \n            reqCAs=reqCAs, \n            tacks=tacks, activationFlags=activationFlags, \n            nextProtos=nextProtos, anon=anon, alpn=alpn, sni=sni)\n        for result in self._handshakeWrapperAsync(handshaker, checker):\n            yield result\n\n\n    def _handshakeServerAsyncHelper(self, verifierDB,\n                             cert_chain, privateKey, reqCert, sessionCache,\n                             settings, reqCAs, \n                             tacks, activationFlags, \n                             nextProtos, anon, alpn, sni):\n\n        self._handshakeStart(client=False)\n\n        if not settings:\n            settings = HandshakeSettings()\n        settings = settings.validate()\n\n        if (not verifierDB) and (not cert_chain) and not anon and \\\n                not settings.pskConfigs and not settings.virtual_hosts:\n            raise ValueError(\"Caller passed no authentication credentials\")\n        if cert_chain and not privateKey:\n            raise ValueError(\"Caller passed a cert_chain but no privateKey\")\n        if privateKey and not cert_chain:\n            raise ValueError(\"Caller passed a privateKey but no cert_chain\")\n        if reqCAs and not reqCert:\n            raise ValueError(\"Caller passed reqCAs but not reqCert\")            \n        if cert_chain and not isinstance(cert_chain, X509CertChain):\n            raise ValueError(\"Unrecognized certificate type\")\n        if activationFlags and not tacks:\n            raise ValueError(\"Nonzero activationFlags requires tacks\")\n        if tacks:\n            if not tackpyLoaded:\n                raise ValueError(\"tackpy is not loaded\")\n            if not settings.useExperimentalTackExtension:\n                raise ValueError(\"useExperimentalTackExtension not enabled\")\n        if alpn is not None and not alpn:\n            raise ValueError(\"Empty list of ALPN protocols\")\n\n        self.sock.padding_cb = settings.padding_cb\n\n        # OK Start exchanging messages\n        # ******************************\n        \n        # Handle ClientHello and resumption\n        for result in self._serverGetClientHello(settings, privateKey,\n                                                 cert_chain,\n                                                 verifierDB, sessionCache,\n                                                 anon, alpn, sni):\n            if result in (0,1): yield result\n            elif result == None:\n                self._handshakeDone(resumed=True)                \n                return # Handshake was resumed, we're done \n            else: break\n        (clientHello, version, cipherSuite, sig_scheme, privateKey,\n            cert_chain) = result\n\n        # in TLS 1.3 the handshake is completely different\n        # (extensions go into different messages, format of messages is\n        # different, etc.)\n        if version > (3, 3):\n            for result in self._serverTLS13Handshake(settings, clientHello,\n                                                     cipherSuite,\n                                                     privateKey, cert_chain,\n                                                     version, sig_scheme,\n                                                     alpn, reqCert):\n                if result in (0, 1):\n                    yield result\n                else:\n                    break\n            if result == \"finished\":\n                self._handshakeDone(resumed=False)\n            return\n\n        #If not a resumption...\n\n        # Create the ServerHello message\n        if sessionCache:\n            sessionID = getRandomBytes(32)\n        else:\n            sessionID = bytearray(0)\n        \n        if not clientHello.supports_npn:\n            nextProtos = None\n\n        alpnExt = clientHello.getExtension(ExtensionType.alpn)\n        if alpnExt and alpn:\n            # if there's ALPN, don't do NPN\n            nextProtos = None\n\n        # If not doing a certificate-based suite, discard the TACK\n        if not cipherSuite in CipherSuite.certAllSuites and \\\n                not cipherSuite in CipherSuite.ecdheEcdsaSuites:\n            tacks = None\n\n        # Prepare a TACK Extension if requested\n        if clientHello.tack:\n            tackExt = TackExtension.create(tacks, activationFlags)\n        else:\n            tackExt = None\n\n        extensions = []\n        # Prepare other extensions if requested\n        if settings.useEncryptThenMAC and \\\n                clientHello.getExtension(ExtensionType.encrypt_then_mac) and \\\n                cipherSuite not in CipherSuite.streamSuites and \\\n                cipherSuite not in CipherSuite.aeadSuites:\n            extensions.append(TLSExtension().create(ExtensionType.\n                                                    encrypt_then_mac,\n                                                    bytearray(0)))\n            self._recordLayer.encryptThenMAC = True\n\n        if settings.useExtendedMasterSecret:\n            if clientHello.getExtension(ExtensionType.extended_master_secret):\n                extensions.append(TLSExtension().create(ExtensionType.\n                                                        extended_master_secret,\n                                                        bytearray(0)))\n                self.extendedMasterSecret = True\n            elif settings.requireExtendedMasterSecret:\n                for result in self._sendError(\n                        AlertDescription.insufficient_security,\n                        \"Failed to negotiate Extended Master Secret\"):\n                    yield result\n\n        selectedALPN = None\n        if alpnExt and alpn:\n            for protoName in alpnExt.protocol_names:\n                if protoName in alpn:\n                    selectedALPN = protoName\n                    ext = ALPNExtension().create([protoName])\n                    extensions.append(ext)\n                    break\n            else:\n                for result in self._sendError(\n                        AlertDescription.no_application_protocol,\n                        \"No mutually supported application layer protocols\"):\n                    yield result\n        # notify client that we understood its renegotiation info extension\n        # or SCSV\n        secureRenego = False\n        renegoExt = clientHello.getExtension(ExtensionType.renegotiation_info)\n        if renegoExt:\n            if renegoExt.renegotiated_connection:\n                for result in self._sendError(\n                        AlertDescription.handshake_failure,\n                        \"Non empty renegotiation info extension in \"\n                        \"initial Client Hello\"):\n                    yield result\n            secureRenego = True\n        elif CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV in \\\n                clientHello.cipher_suites:\n            secureRenego = True\n        if secureRenego:\n            extensions.append(RenegotiationInfoExtension()\n                              .create(bytearray(0)))\n\n        # tell the client what point formats we support\n        if clientHello.getExtension(ExtensionType.ec_point_formats):\n            # even though the selected cipher may not use ECC, client may want\n            # to send a CA certificate with ECDSA...\n            extensions.append(ECPointFormatsExtension().create(\n                [ECPointFormat.uncompressed]))\n\n        # if client sent Heartbeat extension\n        if clientHello.getExtension(ExtensionType.heartbeat):\n            # and we want to accept it\n            if settings.use_heartbeat_extension:\n                extensions.append(HeartbeatExtension().create(\n                    HeartbeatMode.PEER_ALLOWED_TO_SEND))\n\n        if clientHello.getExtension(ExtensionType.record_size_limit) and \\\n                settings.record_size_limit:\n            # in TLS 1.2 and earlier we can select at most 2^14B records\n            extensions.append(RecordSizeLimitExtension().create(\n                min(2**14, settings.record_size_limit)))\n\n\n        # don't send empty list of extensions\n        if not extensions:\n            extensions = None\n\n        serverHello = ServerHello()\n        # RFC 8446, section 4.1.3\n        random = getRandomBytes(32)\n        if version == (3, 3) and settings.maxVersion > (3, 3):\n            random[-8:] = TLS_1_2_DOWNGRADE_SENTINEL\n        if version < (3, 3) and settings.maxVersion >= (3, 3):\n            random[-8:] = TLS_1_1_DOWNGRADE_SENTINEL\n        serverHello.create(self.version, random, sessionID,\n                           cipherSuite, CertificateType.x509, tackExt,\n                           nextProtos, extensions=extensions)\n\n        # Perform the SRP key exchange\n        clientCertChain = None\n        if cipherSuite in CipherSuite.srpAllSuites:\n            for result in self._serverSRPKeyExchange(clientHello, serverHello,\n                                                     verifierDB, cipherSuite,\n                                                     privateKey, cert_chain,\n                                                     settings):\n                if result in (0, 1):\n                    yield result\n                else: break\n            premasterSecret, privateKey, cert_chain = result\n\n        # Perform a certificate-based key exchange\n        elif (cipherSuite in CipherSuite.certSuites or\n              cipherSuite in CipherSuite.dheCertSuites or\n              cipherSuite in CipherSuite.dheDsaSuites or\n              cipherSuite in CipherSuite.ecdheCertSuites or\n              cipherSuite in CipherSuite.ecdheEcdsaSuites):\n            try:\n                sig_hash_alg, cert_chain, privateKey = \\\n                    self._pickServerKeyExchangeSig(settings,\n                                                   clientHello,\n                                                   cert_chain,\n                                                   privateKey)\n            except TLSHandshakeFailure as alert:\n                for result in self._sendError(\n                        AlertDescription.handshake_failure,\n                        str(alert)):\n                    yield result\n\n            if cipherSuite in CipherSuite.certSuites:\n                keyExchange = RSAKeyExchange(cipherSuite,\n                                             clientHello,\n                                             serverHello,\n                                             privateKey)\n            elif cipherSuite in CipherSuite.dheCertSuites or \\\n                    cipherSuite in CipherSuite.dheDsaSuites:\n                dhGroups = self._groupNamesToList(settings)\n                keyExchange = DHE_RSAKeyExchange(cipherSuite,\n                                                 clientHello,\n                                                 serverHello,\n                                                 privateKey,\n                                                 settings.dhParams,\n                                                 dhGroups)\n            elif cipherSuite in CipherSuite.ecdheCertSuites or \\\n                    cipherSuite in CipherSuite.ecdheEcdsaSuites:\n                acceptedCurves = self._curveNamesToList(settings)\n                defaultCurve = getattr(GroupName, settings.defaultCurve)\n                keyExchange = ECDHE_RSAKeyExchange(cipherSuite,\n                                                   clientHello,\n                                                   serverHello,\n                                                   privateKey,\n                                                   acceptedCurves,\n                                                   defaultCurve)\n            else:\n                assert(False)\n            for result in self._serverCertKeyExchange(clientHello, serverHello,\n                                        sig_hash_alg, cert_chain, keyExchange,\n                                        reqCert, reqCAs, cipherSuite,\n                                        settings):\n                if result in (0,1): yield result\n                else: break\n            (premasterSecret, clientCertChain) = result\n\n        # Perform anonymous Diffie Hellman key exchange\n        elif (cipherSuite in CipherSuite.anonSuites or\n              cipherSuite in CipherSuite.ecdhAnonSuites):\n            if cipherSuite in CipherSuite.anonSuites:\n                dhGroups = self._groupNamesToList(settings)\n                keyExchange = ADHKeyExchange(cipherSuite, clientHello,\n                                             serverHello, settings.dhParams,\n                                             dhGroups)\n            else:\n                acceptedCurves = self._curveNamesToList(settings)\n                defaultCurve = getattr(GroupName, settings.defaultCurve)\n                keyExchange = AECDHKeyExchange(cipherSuite, clientHello,\n                                               serverHello, acceptedCurves,\n                                               defaultCurve)\n            for result in self._serverAnonKeyExchange(serverHello, keyExchange,\n                                                      cipherSuite):\n                if result in (0,1): yield result\n                else: break\n            premasterSecret = result\n\n        else:\n            assert(False)\n                        \n        # Exchange Finished messages      \n        for result in self._serverFinished(premasterSecret, \n                                clientHello.random, serverHello.random,\n                                cipherSuite, settings.cipherImplementations,\n                                nextProtos, settings):\n                if result in (0,1): yield result\n                else: break\n        masterSecret = result\n\n        #Create the session object\n        self.session = Session()\n        if cipherSuite in CipherSuite.certAllSuites or \\\n                cipherSuite in CipherSuite.ecdheEcdsaSuites:\n            serverCertChain = cert_chain\n        else:\n            serverCertChain = None\n        srpUsername = None\n        serverName = None\n        if clientHello.srp_username:\n            srpUsername = clientHello.srp_username.decode(\"utf-8\")\n        if clientHello.server_name:\n            serverName = clientHello.server_name.decode(\"utf-8\")\n        self.session.create(masterSecret, serverHello.session_id, cipherSuite,\n                            srpUsername, clientCertChain, serverCertChain,\n                            tackExt, (serverHello.tackExt is not None),\n                            serverName,\n                            encryptThenMAC=self._recordLayer.encryptThenMAC,\n                            extendedMasterSecret=self.extendedMasterSecret,\n                            appProto=selectedALPN,\n                            # NOTE it must be a reference, not a copy!\n                            tickets=self.tickets)\n\n        #Add the session object to the session cache\n        if sessionCache and sessionID:\n            sessionCache[sessionID] = self.session\n\n        self._handshakeDone(resumed=False)\n        self._serverRandom = serverHello.random\n        self._clientRandom = clientHello.random\n\n    def request_post_handshake_auth(self, settings=None):\n        \"\"\"\n        Request Post-handshake Authentication from client.\n\n        The PHA process is asynchronous, and client may send some data before\n        its certificates are added to Session object. Calling this generator\n        will only request for the new identity of client, it will not wait for\n        it.\n        \"\"\"\n        if self.version != (3, 4):\n            raise ValueError(\"PHA is supported only in TLS 1.3\")\n        if self._client:\n            raise ValueError(\"PHA can only be requested by server\")\n        if not self._pha_supported:\n            raise ValueError(\"PHA not supported by client\")\n\n        settings = settings or HandshakeSettings()\n        settings = settings.validate()\n\n        valid_sig_algs = self._sigHashesToList(settings)\n        if not valid_sig_algs:\n            raise ValueError(\"No signature algorithms enabled in \"\n                             \"HandshakeSettings\")\n\n        context = bytes(getRandomBytes(32))\n\n        certificate_request = CertificateRequest(self.version)\n        certificate_request.create(context=context, sig_algs=valid_sig_algs)\n\n        self._cert_requests[context] = certificate_request\n\n        for result in self._sendMsg(certificate_request):\n            yield result\n\n    @staticmethod\n    def _derive_key_iv(nonce, user_key, settings):\n        \"\"\"Derive the IV and key for session ticket encryption.\"\"\"\n        if settings.ticketCipher == \"aes128gcm\":\n            prf_name = \"sha256\"\n            prf_size = 32\n        else:\n            prf_name = \"sha384\"\n            prf_size = 48\n\n        # mix the nonce with the key set by user\n        secret = bytearray(prf_size)\n        secret = secureHMAC(secret, nonce, prf_name)\n        secret = derive_secret(secret, bytearray(b'derived'), None, prf_name)\n        secret = secureHMAC(secret, user_key, prf_name)\n\n        ticket_secret = derive_secret(secret,\n                                      bytearray(b'SessionTicket secret'),\n                                      None, prf_name)\n\n        key = HKDF_expand_label(ticket_secret, b\"key\", b\"\", len(user_key),\n                                prf_name)\n        # all AEADs use 12 byte long IV\n        iv = HKDF_expand_label(ticket_secret, b\"iv\", b\"\", 12, prf_name)\n        return key, iv\n\n    def _serverSendTickets(self, settings):\n        \"\"\"Send session tickets to client.\"\"\"\n        if not settings.ticketKeys:\n            return\n\n        for _ in range(settings.ticket_count):\n            # prepare the ticket\n            ticket = SessionTicketPayload()\n            ticket.create(self.session.resumptionMasterSecret,\n                          self.version,\n                          self.session.cipherSuite,\n                          int(time.time()),\n                          getRandomBytes(len(settings.ticketKeys[0])),\n                          client_cert_chain=self.session.clientCertChain)\n\n            # encrypt the ticket\n\n            # generate keys for the encryption\n            nonce = getRandomBytes(32)\n            key, iv = self._derive_key_iv(nonce, settings.ticketKeys[0],\n                                          settings)\n\n            if settings.ticketCipher in (\"aes128gcm\", \"aes256gcm\"):\n                cipher = createAESGCM(key,\n                                      settings.cipherImplementations)\n            elif settings.ticketCipher in (\"aes128ccm\", \"aes256ccm\"):\n                cipher = createAESCCM(key, settings.cipherImplementations)\n            elif settings.ticketCipher in (\"aes128ccm_8\", \"aes256ccm_8\"):\n                cipher = createAESCCM_8(key, settings.cipherImplementations)\n            else:\n                assert settings.ticketCipher == \"chacha20-poly1305\"\n                cipher = createCHACHA20(key,\n                                        settings.cipherImplementations)\n\n            encrypted_ticket = cipher.seal(iv, ticket.write(), b'')\n\n            # encapsulate the ticket and send to client\n            new_ticket = NewSessionTicket()\n            new_ticket.create(settings.ticketLifetime,\n                              getRandomNumber(1, 8**4),\n                              ticket.nonce,\n                              nonce + encrypted_ticket,\n                              [])\n            self._queue_message(new_ticket)\n\n        # send tickets to client\n        if settings.ticket_count:\n            for result in self._queue_flush():\n                yield result\n\n    def _tryDecrypt(self, settings, identity):\n        if not settings.ticketKeys:\n            return None, None\n\n        if len(identity.identity) < 33:\n            # too small for an encrypted ticket\n            return None, None\n\n        nonce, encrypted_ticket = identity.identity[:32], identity.identity[32:]\n        for user_key in settings.ticketKeys:\n            key, iv = self._derive_key_iv(nonce, user_key, settings)\n            if settings.ticketCipher in (\"aes128gcm\", \"aes256gcm\"):\n                cipher = createAESGCM(key, settings.cipherImplementations)\n            elif settings.ticketCipher in (\"aes128ccm\", \"aes256ccm\"):\n                cipher = createAESCCM(key, settings.cipherImplementations)\n            elif settings.ticketCipher in (\"aes128ccm_8\", \"aes256ccm_8\"):\n                cipher = createAESCCM_8(key, settings.cipherImplementations)\n            else:\n                assert settings.ticketCipher == \"chacha20-poly1305\"\n                cipher = createCHACHA20(key, settings.cipherImplementations)\n\n            ticket = cipher.open(iv, encrypted_ticket, b'')\n            if not ticket:\n                continue\n\n            parser = Parser(ticket)\n            try:\n                ticket = SessionTicketPayload().parse(parser)\n            except ValueError:\n                continue\n\n            prf = 'sha384' if ticket.cipher_suite \\\n                in CipherSuite.sha384PrfSuites else 'sha256'\n\n            new_sess_ticket = NewSessionTicket()\n            new_sess_ticket.ticket_nonce = ticket.nonce\n            new_sess_ticket.ticket = identity.identity\n\n            psk = HandshakeHelpers.calc_res_binder_psk(identity,\n                                                       ticket.master_secret,\n                                                       [new_sess_ticket])\n\n            return ((identity.identity, psk, prf), ticket)\n\n        # no keys\n        return None, None\n\n    def _serverTLS13Handshake(self, settings, clientHello, cipherSuite,\n                              privateKey, serverCertChain, version, scheme,\n                              srv_alpns, reqCert):\n        \"\"\"Perform a TLS 1.3 handshake\"\"\"\n        prf_name, prf_size = self._getPRFParams(cipherSuite)\n\n        secret = bytearray(prf_size)\n\n        share = clientHello.getExtension(ExtensionType.key_share)\n        if share:\n            share_ids = [i.group for i in share.client_shares]\n            for group_name in chain(settings.keyShares, settings.eccCurves,\n                                    settings.dhGroups):\n                selected_group = getattr(GroupName, group_name)\n                if selected_group in share_ids:\n                    cl_key_share = next(i for i in share.client_shares\n                                        if i.group == selected_group)\n                    break\n            else:\n                for result in self._sendError(AlertDescription.internal_error,\n                                              \"HRR did not work?!\"):\n                    yield result\n\n        psk = None\n        selected_psk = None\n        resumed_client_cert_chain = None\n        psks = clientHello.getExtension(ExtensionType.pre_shared_key)\n        psk_types = clientHello.getExtension(\n            ExtensionType.psk_key_exchange_modes)\n        if psks and (PskKeyExchangeMode.psk_dhe_ke in psk_types.modes or\n                     PskKeyExchangeMode.psk_ke in psk_types.modes) and \\\n                (settings.pskConfigs or settings.ticketKeys):\n            for i, ident in enumerate(psks.identities):\n                ticket = None\n                external = True\n                match = [j for j in settings.pskConfigs\n                         if j[0] == ident.identity]\n                if not match:\n                    (match, ticket) = self._tryDecrypt(settings, ident)\n                    external = False\n                    if not match:\n                        continue\n                    match = [match]\n\n                # check if PSK can be used with selected cipher suite\n                psk_hash = match[0][2] if len(match[0]) > 2 else 'sha256'\n                if psk_hash != prf_name:\n                    continue\n\n                psk = match[0][1]\n                selected_psk = i\n                if ticket:\n                    resumed_client_cert_chain = ticket.client_cert_chain\n                try:\n                    HandshakeHelpers.verify_binder(\n                        clientHello,\n                        self._pre_client_hello_handshake_hash,\n                        selected_psk,\n                        psk,\n                        psk_hash,\n                        external)\n                except TLSIllegalParameterException as e:\n                    for result in self._sendError(\n                            AlertDescription.illegal_parameter,\n                            str(e)):\n                        yield result\n                break\n\n        sh_extensions = []\n\n        # we need to gen key share either when we selected psk_dhe_ke or\n        # regular certificate authenticated key exchange (the default)\n        if (psk and\n                PskKeyExchangeMode.psk_dhe_ke in psk_types.modes and\n                \"psk_dhe_ke\" in settings.psk_modes) or\\\n                (psk is None and privateKey):\n            self.ecdhCurve = selected_group\n            kex = self._getKEX(selected_group, version)\n            key_share = self._genKeyShareEntry(selected_group, version)\n\n            try:\n                shared_sec = kex.calc_shared_key(key_share.private,\n                                                 cl_key_share.key_exchange)\n            except TLSIllegalParameterException as alert:\n                for result in self._sendError(\n                        AlertDescription.illegal_parameter,\n                        str(alert)):\n                    yield result\n\n            sh_extensions.append(ServerKeyShareExtension().create(key_share))\n        elif (psk is not None and\n              PskKeyExchangeMode.psk_ke in psk_types.modes and\n              \"psk_ke\" in settings.psk_modes):\n            shared_sec = bytearray(prf_size)\n        else:\n            for result in self._sendError(\n                    AlertDescription.handshake_failure,\n                    \"Could not find acceptable PSK identity nor certificate\"):\n                yield result\n\n        if psk is None:\n            psk = bytearray(prf_size)\n\n        sh_extensions.append(SrvSupportedVersionsExtension().create(version))\n        if selected_psk is not None:\n            sh_extensions.append(SrvPreSharedKeyExtension()\n                                 .create(selected_psk))\n\n        serverHello = ServerHello()\n        # in TLS1.3 the version selected is sent in extension, (3, 3) is\n        # just dummy value to workaround broken middleboxes\n        serverHello.create((3, 3), getRandomBytes(32),\n                           clientHello.session_id,\n                           cipherSuite, extensions=sh_extensions)\n\n        msgs = []\n        msgs.append(serverHello)\n        if not self._ccs_sent and clientHello.session_id:\n            ccs = ChangeCipherSpec().create()\n            msgs.append(ccs)\n        for result in self._sendMsgs(msgs):\n            yield result\n\n        # Early secret\n        secret = secureHMAC(secret, psk, prf_name)\n\n        # Handshake Secret\n        secret = derive_secret(secret, bytearray(b'derived'), None, prf_name)\n        secret = secureHMAC(secret, shared_sec, prf_name)\n\n        sr_handshake_traffic_secret = derive_secret(secret,\n                                                    bytearray(b's hs traffic'),\n                                                    self._handshake_hash,\n                                                    prf_name)\n        cl_handshake_traffic_secret = derive_secret(secret,\n                                                    bytearray(b'c hs traffic'),\n                                                    self._handshake_hash,\n                                                    prf_name)\n        self.version = version\n        self._recordLayer.calcTLS1_3PendingState(\n            cipherSuite,\n            cl_handshake_traffic_secret,\n            sr_handshake_traffic_secret,\n            settings.cipherImplementations)\n\n        self._changeWriteState()\n\n        ee_extensions = []\n\n        if clientHello.getExtension(ExtensionType.record_size_limit) and \\\n                settings.record_size_limit:\n            ee_extensions.append(RecordSizeLimitExtension().create(\n                min(2**14+1, settings.record_size_limit)))\n\n        # a bit of a hack to detect if the HRR was sent\n        # as that means that original key share didn't match what we wanted\n        # send the client updated list of shares we support,\n        # preferred ones first\n        if clientHello.getExtension(ExtensionType.cookie):\n            ext = SupportedGroupsExtension()\n            groups = [getattr(GroupName, i) for i in settings.keyShares]\n            groups += [getattr(GroupName, i) for i in settings.eccCurves\n                       if getattr(GroupName, i) not in groups]\n            groups += [getattr(GroupName, i) for i in settings.dhGroups\n                       if getattr(GroupName, i) not in groups]\n            if groups:\n                ext.create(groups)\n                ee_extensions.append(ext)\n\n        alpn_ext = clientHello.getExtension(ExtensionType.alpn)\n        if alpn_ext:\n            # error handling was done when receiving ClientHello\n            matched = [i for i in alpn_ext.protocol_names if i in srv_alpns]\n            if matched:\n                ext = ALPNExtension().create([matched[0]])\n                ee_extensions.append(ext)\n\n        if clientHello.getExtension(ExtensionType.heartbeat):\n            if settings.use_heartbeat_extension:\n                ee_extensions.append(HeartbeatExtension().create(\n                    HeartbeatMode.PEER_ALLOWED_TO_SEND))\n\n        encryptedExtensions = EncryptedExtensions().create(ee_extensions)\n        self._queue_message(encryptedExtensions)\n\n        if selected_psk is None:\n\n            # optionally send the client a certificate request\n            if reqCert:\n\n                # the context SHALL be zero length except in post-handshake\n                ctx = b''\n\n                # Get list of valid Signing Algorithms\n                # we don't support DSA for client certificates yet\n                cr_settings = settings.validate()\n                cr_settings.dsaSigHashes = []\n                valid_sig_algs = self._sigHashesToList(cr_settings)\n                assert valid_sig_algs\n\n                certificate_request = CertificateRequest(self.version)\n                certificate_request.create(context=ctx, sig_algs=valid_sig_algs)\n                self._queue_message(certificate_request)\n\n            certificate = Certificate(CertificateType.x509, self.version)\n            certificate.create(serverCertChain, bytearray())\n            self._queue_message(certificate)\n\n            certificate_verify = CertificateVerify(self.version)\n\n            signature_scheme = getattr(SignatureScheme, scheme)\n\n            signature_context = \\\n                KeyExchange.calcVerifyBytes((3, 4), self._handshake_hash,\n                                            signature_scheme, None, None, None,\n                                            prf_name, b'server')\n\n            if signature_scheme in (SignatureScheme.ed25519,\n                    SignatureScheme.ed448):\n                hashName = \"intrinsic\"\n                padType = None\n                saltLen = None\n                sig_func = privateKey.hashAndSign\n                ver_func = privateKey.hashAndVerify\n            elif signature_scheme[1] == SignatureAlgorithm.ecdsa:\n                hashName = HashAlgorithm.toRepr(signature_scheme[0])\n                padType = None\n                saltLen = None\n                sig_func = privateKey.sign\n                ver_func = privateKey.verify\n            else:\n                padType = SignatureScheme.getPadding(scheme)\n                hashName = SignatureScheme.getHash(scheme)\n                saltLen = getattr(hashlib, hashName)().digest_size\n                sig_func = privateKey.sign\n                ver_func = privateKey.verify\n\n            signature = sig_func(signature_context,\n                                 padType,\n                                 hashName,\n                                 saltLen)\n            if not ver_func(signature, signature_context,\n                            padType,\n                            hashName,\n                            saltLen):\n                for result in self._sendError(\n                        AlertDescription.internal_error,\n                        \"Certificate Verify signature failed\"):\n                    yield result\n            certificate_verify.create(signature, signature_scheme)\n\n            self._queue_message(certificate_verify)\n\n        finished_key = HKDF_expand_label(sr_handshake_traffic_secret,\n                                         b\"finished\", b'', prf_size, prf_name)\n        verify_data = secureHMAC(finished_key,\n                                 self._handshake_hash.digest(prf_name),\n                                 prf_name)\n\n        finished = Finished(self.version, prf_size).create(verify_data)\n\n        self._queue_message(finished)\n        for result in self._queue_flush():\n            yield result\n\n        self._changeReadState()\n\n        # Master secret\n        secret = derive_secret(secret, bytearray(b'derived'), None, prf_name)\n        secret = secureHMAC(secret, bytearray(prf_size), prf_name)\n\n        cl_app_traffic = derive_secret(secret, bytearray(b'c ap traffic'),\n                                       self._handshake_hash, prf_name)\n        sr_app_traffic = derive_secret(secret, bytearray(b's ap traffic'),\n                                       self._handshake_hash, prf_name)\n        self._recordLayer.calcTLS1_3PendingState(serverHello.cipher_suite,\n                                                 cl_app_traffic,\n                                                 sr_app_traffic,\n                                                 settings\n                                                 .cipherImplementations)\n\n        # all the messages sent by the server after the Finished message\n        # MUST be encrypted with ap traffic secret, even if they regard\n        # problems in processing client Certificate, CertificateVerify or\n        # Finished messages\n        self._changeWriteState()\n\n        client_cert_chain = None\n        #Get [Certificate,] (if was requested)\n        if reqCert and selected_psk is None:\n            for result in self._getMsg(ContentType.handshake,\n                                       HandshakeType.certificate,\n                                       CertificateType.x509):\n                if result in (0, 1):\n                    yield result\n                else:\n                    break\n            client_certificate = result\n            assert isinstance(client_certificate, Certificate)\n            client_cert_chain = client_certificate.cert_chain\n\n        #Get and check CertificateVerify, if relevant\n        cli_cert_verify_hh = self._handshake_hash.copy()\n        if client_cert_chain and client_cert_chain.getNumCerts():\n            for result in self._getMsg(ContentType.handshake,\n                                       HandshakeType.certificate_verify):\n                if result in (0, 1):\n                    yield result\n                else: break\n            certificate_verify = result\n            assert isinstance(certificate_verify, CertificateVerify)\n\n            signature_scheme = certificate_verify.signatureAlgorithm\n\n            valid_sig_algs = self._sigHashesToList(settings,\n                                                   certList=client_cert_chain,\n                                                   version=(3, 4))\n            if signature_scheme not in valid_sig_algs:\n                for result in self._sendError(\n                        AlertDescription.illegal_parameter,\n                        \"Invalid signature on Certificate Verify\"):\n                    yield result\n\n            signature_context = \\\n                KeyExchange.calcVerifyBytes((3, 4), cli_cert_verify_hh,\n                                            signature_scheme, None, None, None,\n                                            prf_name, b'client')\n\n            public_key = client_cert_chain.getEndEntityPublicKey()\n\n            if signature_scheme in (SignatureScheme.ed25519,\n                    SignatureScheme.ed448):\n                hash_name = \"intrinsic\"\n                pad_type = None\n                salt_len = None\n                ver_func = public_key.hashAndVerify\n            elif signature_scheme[1] == SignatureAlgorithm.ecdsa:\n                hash_name = HashAlgorithm.toRepr(signature_scheme[0])\n                pad_type = None\n                salt_len = None\n                ver_func = public_key.verify\n            else:\n                scheme = SignatureScheme.toRepr(signature_scheme)\n                pad_type = SignatureScheme.getPadding(scheme)\n                hash_name = SignatureScheme.getHash(scheme)\n                salt_len = getattr(hashlib, hash_name)().digest_size\n                ver_func = public_key.verify\n\n            if not ver_func(certificate_verify.signature,\n                            signature_context,\n                            pad_type,\n                            hash_name,\n                            salt_len):\n                for result in self._sendError(\n                        AlertDescription.decrypt_error,\n                        \"signature verification failed\"):\n                    yield result\n\n        # as both exporter and resumption master secrets include handshake\n        # transcript, we need to derive them early\n        exporter_master_secret = derive_secret(secret,\n                                               bytearray(b'exp master'),\n                                               self._handshake_hash,\n                                               prf_name)\n\n        # verify Finished of client\n        cl_finished_key = HKDF_expand_label(cl_handshake_traffic_secret,\n                                            b\"finished\", b'',\n                                            prf_size, prf_name)\n        cl_verify_data = secureHMAC(cl_finished_key,\n                                    self._handshake_hash.digest(prf_name),\n                                    prf_name)\n        for result in self._getMsg(ContentType.handshake,\n                                   HandshakeType.finished,\n                                   prf_size):\n            if result in (0, 1):\n                yield result\n            else:\n                break\n        cl_finished = result\n        assert isinstance(cl_finished, Finished)\n        if cl_finished.verify_data != cl_verify_data:\n            for result in self._sendError(\n                    AlertDescription.decrypt_error,\n                    \"Finished value is not valid\"):\n                yield result\n\n        # disallow CCS messages after handshake\n        self._middlebox_compat_mode = False\n\n        resumption_master_secret = derive_secret(secret,\n                                                 bytearray(b'res master'),\n                                                 self._handshake_hash,\n                                                 prf_name)\n\n        self._first_handshake_hashes = self._handshake_hash.copy()\n\n        self.session = Session()\n        self.extendedMasterSecret = True\n        server_name = None\n        if clientHello.server_name:\n            server_name = clientHello.server_name.decode('utf-8')\n\n        app_proto = None\n        alpnExt = encryptedExtensions.getExtension(ExtensionType.alpn)\n        if alpnExt:\n            app_proto = alpnExt.protocol_names[0]\n\n        if not client_cert_chain and resumed_client_cert_chain:\n            client_cert_chain = resumed_client_cert_chain\n\n        self.session.create(secret,\n                            bytearray(b''),  # no session_id\n                            serverHello.cipher_suite,\n                            bytearray(b''),  # no SRP\n                            client_cert_chain,\n                            serverCertChain,\n                            None,\n                            False,\n                            server_name,\n                            encryptThenMAC=False,\n                            extendedMasterSecret=True,\n                            appProto=app_proto,\n                            cl_app_secret=cl_app_traffic,\n                            sr_app_secret=sr_app_traffic,\n                            exporterMasterSecret=exporter_master_secret,\n                            resumptionMasterSecret=resumption_master_secret,\n                            # NOTE it must be a reference, not a copy\n                            tickets=self.tickets)\n\n        # switch to application_traffic_secret for client packets\n        self._changeReadState()\n\n        for result in self._serverSendTickets(settings):\n            yield result\n\n        yield \"finished\"\n\n    def _serverGetClientHello(self, settings, private_key, cert_chain,\n                              verifierDB,\n                              sessionCache, anon, alpn, sni):\n        # Tentatively set version to most-desirable version, so if an error\n        # occurs parsing the ClientHello, this will be the version we'll use\n        # for the error alert\n        # If TLS 1.3 is enabled, use the \"compatible\" TLS 1.2 version\n        self.version = min(settings.maxVersion, (3, 3))\n\n        self._pre_client_hello_handshake_hash = self._handshake_hash.copy()\n        #Get ClientHello\n        for result in self._getMsg(ContentType.handshake,\n                                   HandshakeType.client_hello):\n            if result in (0,1): yield result\n            else: break\n        clientHello = result\n\n        # check if the ClientHello and its extensions are well-formed\n\n        #If client's version is too low, reject it\n        real_version = clientHello.client_version\n        if real_version >= (3, 3):\n            ext = clientHello.getExtension(ExtensionType.supported_versions)\n            if ext:\n                for v in ext.versions:\n                    if v in KNOWN_VERSIONS and v > real_version:\n                        real_version = v\n        if real_version < settings.minVersion:\n            self.version = settings.minVersion\n            for result in self._sendError(\\\n                  AlertDescription.protocol_version,\n                  \"Too old version: %s\" % str(clientHello.client_version)):\n                yield result\n\n        # there MUST be at least one value in both of those\n        if not clientHello.cipher_suites or \\\n                not clientHello.compression_methods:\n            for result in self._sendError(\n                    AlertDescription.decode_error,\n                    \"Malformed Client Hello message\"):\n                yield result\n\n        # client hello MUST advertise uncompressed method\n        if 0 not in clientHello.compression_methods:\n            for result in self._sendError(\n                    AlertDescription.illegal_parameter,\n                    \"Client Hello missing uncompressed method\"):\n                yield result\n\n        # the list of signatures methods is defined as <2..2^16-2>, which\n        # means it can't be empty, but it's only applicable to TLSv1.2 protocol\n        ext = clientHello.getExtension(ExtensionType.signature_algorithms)\n        if clientHello.client_version >= (3, 3) and ext and not ext.sigalgs:\n            for result in self._sendError(\n                    AlertDescription.decode_error,\n                    \"Malformed signature_algorithms extension\"):\n                yield result\n\n        # Sanity check the ALPN extension\n        alpnExt = clientHello.getExtension(ExtensionType.alpn)\n        if alpnExt:\n            if not alpnExt.protocol_names:\n                for result in self._sendError(\n                        AlertDescription.decode_error,\n                        \"Client sent empty list of ALPN names\"):\n                    yield result\n            for protocolName in alpnExt.protocol_names:\n                if not protocolName:\n                    for result in self._sendError(\n                            AlertDescription.decode_error,\n                            \"Client sent empty name in ALPN extension\"):\n                        yield result\n\n        # Sanity check the SNI extension\n        sniExt = clientHello.getExtension(ExtensionType.server_name)\n        # check if extension is well formed\n        if sniExt and (not sniExt.extData or not sniExt.serverNames):\n            for result in self._sendError(\n                    AlertDescription.decode_error,\n                    \"Recevived SNI extension is malformed\"):\n                yield result\n        if sniExt and sniExt.hostNames:\n            # RFC 6066 limitation\n            if len(sniExt.hostNames) > 1:\n                for result in self._sendError(\n                        AlertDescription.illegal_parameter,\n                        \"Client sent multiple host names in SNI extension\"):\n                    yield result\n            if not sniExt.hostNames[0]:\n                for result in self._sendError(\n                        AlertDescription.decode_error,\n                        \"Received SNI extension is malformed\"):\n                    yield result\n            try:\n                name = sniExt.hostNames[0].decode('ascii', 'strict')\n            except UnicodeDecodeError:\n                for result in self._sendError(\n                        AlertDescription.illegal_parameter,\n                        \"Host name in SNI is not valid ASCII\"):\n                    yield result\n            if not is_valid_hostname(name):\n                for result in self._sendError(\n                        AlertDescription.illegal_parameter,\n                        \"Host name in SNI is not valid DNS name\"):\n                    yield result\n\n        # sanity check the EMS extension\n        emsExt = clientHello.getExtension(ExtensionType.extended_master_secret)\n        if emsExt and emsExt.extData:\n            for result in self._sendError(\n                    AlertDescription.decode_error,\n                    \"Non empty payload of the Extended \"\n                    \"Master Secret extension\"):\n                yield result\n\n        # sanity check the TLS 1.3 extensions\n        ver_ext = clientHello.getExtension(ExtensionType.supported_versions)\n        if ver_ext and (3, 4) in ver_ext.versions:\n            psk = clientHello.getExtension(ExtensionType.pre_shared_key)\n            psk_modes = clientHello.getExtension(\n                ExtensionType.psk_key_exchange_modes)\n            key_share = clientHello.getExtension(ExtensionType.key_share)\n            sup_groups = clientHello.getExtension(\n                ExtensionType.supported_groups)\n\n            pha = clientHello.getExtension(ExtensionType.post_handshake_auth)\n            if pha:\n                if pha.extData:\n                    for result in self._sendError(\n                            AlertDescription.decode_error,\n                            \"Invalid encoding of post_handshake_auth extension\"\n                            ):\n                        yield result\n                self._pha_supported = True\n\n            key_exchange = None\n\n            if psk_modes:\n                if not psk_modes.modes:\n                    for result in self._sendError(\n                            AlertDescription.decode_error,\n                            \"Empty psk_key_exchange_modes extension\"):\n                        yield result\n            # psk_ke\n            if psk:\n                if not psk.identities:\n                    for result in self._sendError(\n                            AlertDescription.decode_error,\n                            \"No identities in PSK extension\"):\n                        yield result\n                if not psk.binders:\n                    for result in self._sendError(\n                            AlertDescription.decode_error,\n                            \"No binders in PSK extension\"):\n                        yield result\n                if len(psk.identities) != len(psk.binders):\n                    for result in self._sendError(\n                            AlertDescription.illegal_parameter,\n                            \"Number of identities does not match number of \"\n                            \"binders in PSK extension\"):\n                        yield result\n                if any(not i.identity for i in psk.identities):\n                    for result in self._sendError(\n                            AlertDescription.decoder_error,\n                            \"Empty identity in PSK extension\"):\n                        yield result\n                if any(not i for i in psk.binders):\n                    for result in self._sendError(\n                            AlertDescription.decoder_error,\n                            \"Empty binder in PSK extension\"):\n                        yield result\n                if psk is not clientHello.extensions[-1]:\n                    for result in self._sendError(\n                            AlertDescription.illegal_parameter,\n                            \"PSK extension not last in client hello\"):\n                        yield result\n                if not psk_modes:\n                    for result in self._sendError(\n                            AlertDescription.missing_extension,\n                            \"PSK extension without psk_key_exchange_modes \"\n                            \"extension\"):\n                        yield result\n\n                if PskKeyExchangeMode.psk_dhe_ke not in psk_modes.modes:\n                    key_exchange = \"psk_ke\"\n            # cert\n            if not key_exchange:\n                if not sup_groups:\n                    for result in self._sendError(\n                            AlertDescription.missing_extension,\n                            \"Missing supported_groups extension\"):\n                        yield result\n                if not key_share:\n                    for result in self._sendError(\n                            AlertDescription.missing_extension,\n                            \"Missing key_share extension\"):\n                        yield result\n\n                if not sup_groups.groups:\n                    for result in self._sendError(\n                            AlertDescription.decode_error,\n                            \"Empty supported_groups extension\"):\n                        yield result\n                if key_share.client_shares is None:\n                    for result in self._sendError(\n                            AlertDescription.decode_error,\n                            \"Empty key_share extension\"):\n                        yield result\n\n                # check supported_groups\n                if TLS_1_3_FORBIDDEN_GROUPS.intersection(sup_groups.groups):\n                    for result in self._sendError(\n                            AlertDescription.illegal_parameter,\n                            \"Client advertised in TLS 1.3 Client Hello a key \"\n                            \"exchange group forbidden in TLS 1.3\"):\n                        yield result\n\n                # Check key_share\n                mismatch = next((i for i in key_share.client_shares\n                                 if i.group not in sup_groups.groups), None)\n                if mismatch:\n                    for result in self._sendError(\n                            AlertDescription.illegal_parameter,\n                            \"Client sent key share for \"\n                            \"group it did not advertise \"\n                            \"support for: {0}\"\n                            .format(GroupName.toStr(mismatch))):\n                        yield result\n\n                key_share_ids = [i.group for i in key_share.client_shares]\n                if len(set(key_share_ids)) != len(key_share_ids):\n                    for result in self._sendError(\n                            AlertDescription.illegal_parameter,\n                            \"Client sent multiple key shares for the same \"\n                            \"group\"):\n                        yield result\n\n                group_ids = sup_groups.groups\n                diff = set(group_ids) - set(key_share_ids)\n                if key_share_ids != [i for i in group_ids if i not in diff]:\n                    for result in self._sendError(\n                            AlertDescription.illegal_parameter,\n                            \"Client sent key shares in different order than \"\n                            \"the advertised groups.\"):\n                        yield result\n\n                sig_algs = clientHello.getExtension(\n                    ExtensionType.signature_algorithms)\n                if (not psk_modes or not psk) and sig_algs:\n                    key_exchange = \"cert\"\n\n            # psk_dhe_ke\n            if not key_exchange and psk:\n                key_exchange = \"psk_dhe_ke\"\n\n            if not key_exchange:\n                for result in self._sendError(\n                        AlertDescription.missing_extension,\n                        \"Missing extension\"):\n                    yield result\n\n            early_data = clientHello.getExtension(ExtensionType.early_data)\n            if early_data:\n                if early_data.extData:\n                    for result in self._sendError(\n                            AlertDescription.decode_error,\n                            \"malformed early_data extension\"):\n                        yield result\n                if not psk:\n                    for result in self._sendError(\n                            AlertDescription.illegal_parameter,\n                            \"early_data without PSK extension\"):\n                        yield result\n                # if early data comes from version we don't support, client\n                # MUST (section D.3 draft 28) abort the connection so we\n                # enable early data tolerance only when versions match\n                self._recordLayer.max_early_data = settings.max_early_data\n                self._recordLayer.early_data_ok = True\n\n        # negotiate the protocol version for the connection\n        high_ver = None\n        if ver_ext:\n            high_ver = getFirstMatching(settings.versions,\n                                        ver_ext.versions)\n            if not high_ver:\n                for result in self._sendError(\n                        AlertDescription.protocol_version,\n                        \"supported_versions did not include version we \"\n                        \"support\"):\n                    yield result\n        if high_ver:\n            # when we selected TLS 1.3, we cannot set the record layer to\n            # it as well as that also switches it to a mode where the\n            # content type is encrypted\n            # use the backwards compatible TLS 1.2 version instead\n            self.version = min((3, 3), high_ver)\n            version = high_ver\n        elif clientHello.client_version > settings.maxVersion:\n            # in TLS 1.3 the version is negotiatied with extension,\n            # but the settings use the (3, 4) as the max version\n            self.version = min(settings.maxVersion, (3, 3))\n            version = self.version\n        else:\n            #Set the version to the client's version\n            self.version = min(clientHello.client_version, (3, 3))\n            version = self.version\n\n        #Detect if the client performed an inappropriate fallback.\n        if version < settings.maxVersion and \\\n                CipherSuite.TLS_FALLBACK_SCSV in clientHello.cipher_suites:\n            for result in self._sendError(\n                    AlertDescription.inappropriate_fallback):\n                yield result\n\n        # TODO when TLS 1.3 is final, check the client hello random for\n        # downgrade too\n\n        # start negotiating the parameters of the connection\n\n        sni_ext = clientHello.getExtension(ExtensionType.server_name)\n        if sni_ext:\n            name = sni_ext.hostNames[0].decode('ascii', 'strict')\n            # warn the client if the name didn't match the expected value\n            if sni and sni != name:\n                alert = Alert().create(AlertDescription.unrecognized_name,\n                                       AlertLevel.warning)\n                for result in self._sendMsg(alert):\n                    yield result\n\n        #Check if there's intersection between supported curves by client and\n        #server\n        clientGroups = clientHello.getExtension(ExtensionType.supported_groups)\n        # in case the client didn't advertise any curves, we can pick any so\n        # enable ECDHE\n        ecGroupIntersect = True\n        # if there is no extension, then enable DHE\n        ffGroupIntersect = True\n        if clientGroups is not None:\n            clientGroups = clientGroups.groups\n            if not clientGroups:\n                for result in self._sendError(\n                        AlertDescription.decode_error,\n                        \"Received malformed supported_groups extension\"):\n                    yield result\n            serverGroups = self._curveNamesToList(settings)\n            ecGroupIntersect = getFirstMatching(clientGroups, serverGroups)\n            # RFC 7919 groups\n            serverGroups = self._groupNamesToList(settings)\n            ffGroupIntersect = getFirstMatching(clientGroups, serverGroups)\n            # if there is no overlap, but there are no FFDHE groups listed,\n            # allow DHE, prohibit otherwise\n            if not ffGroupIntersect:\n                if clientGroups and \\\n                        any(i for i in clientGroups if i in range(256, 512)):\n                    ffGroupIntersect = False\n                else:\n                    ffGroupIntersect = True\n\n        # Check and save clients heartbeat extension mode\n        heartbeat_ext = clientHello.getExtension(ExtensionType.heartbeat)\n        if heartbeat_ext:\n            if heartbeat_ext.mode == HeartbeatMode.PEER_ALLOWED_TO_SEND:\n                if settings.heartbeat_response_callback:\n                    self.heartbeat_can_send = True\n                    self.heartbeat_response_callback = settings.\\\n                        heartbeat_response_callback\n            elif heartbeat_ext.mode == HeartbeatMode.PEER_NOT_ALLOWED_TO_SEND:\n                self.heartbeat_can_send = False\n            else:\n                for result in self._sendError(\n                        AlertDescription.illegal_parameter,\n                        \"Received invalid value in Heartbeat extension\"):\n                    yield result\n            self.heartbeat_supported = True\n            self.heartbeat_can_receive = True\n\n        size_limit_ext = clientHello.getExtension(\n            ExtensionType.record_size_limit)\n        if size_limit_ext:\n            if size_limit_ext.record_size_limit is None:\n                for result in self._sendError(\n                        AlertDescription.decode_error,\n                        \"Malformed record_size_limit extension\"):\n                    yield result\n            if not 64 <= size_limit_ext.record_size_limit:\n                for result in self._sendError(\n                        AlertDescription.illegal_parameter,\n                        \"Invalid value in record_size_limit extension\"):\n                    yield result\n            if settings.record_size_limit:\n                # in TLS 1.3 handshake is encrypted so we need to switch\n                # to sending smaller messages right away\n                if version >= (3, 4):\n                    # the client can send bigger values because it may\n                    # know protocol versions or extensions we don't know about\n                    # (but we need to still clamp it to protocol limit)\n                    self._send_record_limit = min(\n                        2**14, size_limit_ext.record_size_limit - 1)\n                    # the record layer excludes content type, extension doesn't\n                    # thus the \"-1)\n                    self._recv_record_limit = min(2**14,\n                        settings.record_size_limit - 1)\n                else:\n                    # but in TLS 1.2 and earlier we need to postpone it till\n                    # handling of Finished\n                    self._peer_record_size_limit = min(\n                        2**14, size_limit_ext.record_size_limit)\n\n        #Now that the version is known, limit to only the ciphers available to\n        #that version and client capabilities.\n        cipherSuites = []\n        if verifierDB:\n            if cert_chain:\n                cipherSuites += \\\n                    CipherSuite.getSrpCertSuites(settings, version)\n            cipherSuites += CipherSuite.getSrpSuites(settings, version)\n        elif cert_chain:\n            if ecGroupIntersect or ffGroupIntersect:\n                cipherSuites += CipherSuite.getTLS13Suites(settings,\n                                                           version)\n            if ecGroupIntersect:\n                cipherSuites += CipherSuite.getEcdsaSuites(settings, version)\n                cipherSuites += CipherSuite.getEcdheCertSuites(settings,\n                                                               version)\n            if ffGroupIntersect:\n                cipherSuites += CipherSuite.getDheCertSuites(settings,\n                                                             version)\n                cipherSuites += CipherSuite.getDheDsaSuites(settings,\n                                                            version)\n            cipherSuites += CipherSuite.getCertSuites(settings, version)\n        elif anon:\n            cipherSuites += CipherSuite.getAnonSuites(settings, version)\n            cipherSuites += CipherSuite.getEcdhAnonSuites(settings,\n                                                          version)\n        elif settings.pskConfigs:\n            cipherSuites += CipherSuite.getTLS13Suites(settings,\n                                                       version)\n        else:\n            assert False\n        cipherSuites = CipherSuite.filterForVersion(cipherSuites,\n                                                    minVersion=version,\n                                                    maxVersion=version)\n\n        #If resumption was requested and we have a session cache...\n        if clientHello.session_id and sessionCache:\n            session = None\n\n            # Check if the session there is good enough and consistent with\n            # new Client Hello\n            try:\n                session = sessionCache[clientHello.session_id]\n                if not session.resumable:\n                    raise AssertionError()\n                # Check if we are willing to use that old cipher still\n                if session.cipherSuite not in cipherSuites:\n                    session = None\n                    raise KeyError()\n                # Check for consistency with ClientHello\n                # see RFC 5246 section 7.4.1.2, description of\n                # cipher_suites\n                if session.cipherSuite not in clientHello.cipher_suites:\n                    for result in self._sendError(\n                            AlertDescription.illegal_parameter):\n                        yield result\n                if clientHello.srp_username:\n                    if not session.srpUsername or \\\n                            clientHello.srp_username != \\\n                            bytearray(session.srpUsername, \"utf-8\"):\n                        for result in self._sendError(\n                                AlertDescription.handshake_failure):\n                            yield result\n                if clientHello.server_name:\n                    if not session.serverName or \\\n                            clientHello.server_name != \\\n                            bytearray(session.serverName, \"utf-8\"):\n                        for result in self._sendError(\n                                AlertDescription.handshake_failure):\n                            yield result\n                if session.encryptThenMAC and \\\n                        not clientHello.getExtension(\n                                ExtensionType.encrypt_then_mac):\n                    for result in self._sendError(\n                            AlertDescription.illegal_parameter):\n                        yield result\n                # if old session used EMS, new connection MUST use EMS\n                if session.extendedMasterSecret and \\\n                        not clientHello.getExtension(\n                                ExtensionType.extended_master_secret):\n                    # RFC 7627, section 5.2 explicitly requires\n                    # handshake_failure\n                    for result in self._sendError(\n                            AlertDescription.handshake_failure):\n                        yield result\n                # if old session didn't use EMS but new connection\n                # advertises EMS, create a new session\n                elif not session.extendedMasterSecret and \\\n                        clientHello.getExtension(\n                                ExtensionType.extended_master_secret):\n                    session = None\n            except KeyError:\n                pass\n\n            #If a session is found..\n            if session:\n                #Send ServerHello\n                extensions = []\n                if session.encryptThenMAC:\n                    self._recordLayer.encryptThenMAC = True\n                    mte = TLSExtension().create(ExtensionType.encrypt_then_mac,\n                                                bytearray(0))\n                    extensions.append(mte)\n                if session.extendedMasterSecret:\n                    ems = TLSExtension().create(ExtensionType.\n                                                extended_master_secret,\n                                                bytearray(0))\n                    extensions.append(ems)\n                secureRenego = False\n                renegoExt = clientHello.\\\n                    getExtension(ExtensionType.renegotiation_info)\n                if renegoExt:\n                    if renegoExt.renegotiated_connection:\n                        for result in self._sendError(\n                                AlertDescription.handshake_failure):\n                            yield result\n                    secureRenego = True\n                elif CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV in \\\n                        clientHello.cipher_suites:\n                    secureRenego = True\n                if secureRenego:\n                    extensions.append(RenegotiationInfoExtension()\n                                      .create(bytearray(0)))\n                selectedALPN = None\n                if alpn:\n                    alpnExt = clientHello.getExtension(ExtensionType.alpn)\n                    if alpnExt:\n                        for protocolName in alpnExt.protocol_names:\n                            if protocolName in alpn:\n                                ext = ALPNExtension().create([protocolName])\n                                extensions.append(ext)\n                                selectedALPN = protocolName\n                                break\n                        else:\n                            for result in self._sendError(\n                                    AlertDescription.no_application_protocol,\n                                    \"No commonly supported application layer\"\n                                    \"protocol supported\"):\n                                yield result\n\n                heartbeat_ext = clientHello.getExtension(\n                    ExtensionType.heartbeat)\n                if heartbeat_ext:\n                    if heartbeat_ext.mode == HeartbeatMode.PEER_ALLOWED_TO_SEND:\n                        self.heartbeat_can_send = True\n                    elif heartbeat_ext.mode == \\\n                            HeartbeatMode.PEER_NOT_ALLOWED_TO_SEND:\n                        self.heartbeat_can_send = False\n                    else:\n                        for result in self._sendError(\n                                AlertDescription.illegal_parameter,\n                                \"Client sent invalid Heartbeat extension\"):\n                            yield result\n                    heartbeat = HeartbeatExtension().create(\n                        HeartbeatMode.PEER_ALLOWED_TO_SEND)\n                    self.heartbeat_can_receive = True\n                    self.heartbeat_supported = True\n                    extensions.append(heartbeat)\n                record_limit = clientHello.getExtension(\n                    ExtensionType.record_size_limit)\n                if record_limit and settings.record_size_limit:\n                    extensions.append(RecordSizeLimitExtension().create(\n                        min(2**14, settings.record_size_limit)))\n\n                # don't send empty extensions\n                if not extensions:\n                    extensions = None\n                serverHello = ServerHello()\n                serverHello.create(version, getRandomBytes(32),\n                                   session.sessionID, session.cipherSuite,\n                                   CertificateType.x509, None, None,\n                                   extensions=extensions)\n                for result in self._sendMsg(serverHello):\n                    yield result\n\n                #Calculate pending connection states\n                self._calcPendingStates(session.cipherSuite, \n                                        session.masterSecret,\n                                        clientHello.random, \n                                        serverHello.random,\n                                        settings.cipherImplementations)\n\n                #Exchange ChangeCipherSpec and Finished messages\n                for result in self._sendFinished(session.masterSecret,\n                                                 session.cipherSuite,\n                                                 settings=settings):\n                    yield result\n                for result in self._getFinished(session.masterSecret,\n                                                session.cipherSuite):\n                    yield result\n\n                #Set the session\n                self.session = session\n                self._clientRandom = clientHello.random\n                self._serverRandom = serverHello.random\n                self.session.appProto = selectedALPN\n                yield None # Handshake done!\n\n        #Calculate the first cipher suite intersection.\n        #This is the 'privileged' ciphersuite.  We'll use it if we're\n        #doing a new negotiation.  In fact,\n        #the only time we won't use it is if we're resuming a\n        #session, in which case we use the ciphersuite from the session.\n        #\n        #Given the current ciphersuite ordering, this means we prefer SRP\n        #over non-SRP.\n\n        try:\n            cipherSuite, sig_scheme, cert_chain, private_key = \\\n                    self._server_select_certificate(settings, clientHello,\n                                                    cipherSuites, cert_chain,\n                                                    private_key, version)\n        except TLSHandshakeFailure as err:\n            for result in self._sendError(\n                    AlertDescription.handshake_failure,\n                    str(err)):\n                yield result\n        except TLSInsufficientSecurity as err:\n            for result in self._sendError(\n                    AlertDescription.insufficient_security,\n                    str(err)):\n                yield result\n        except TLSIllegalParameterException as err:\n            for result in self._sendError(\n                    AlertDescription.illegal_parameter,\n                    str(err)):\n                yield result\n\n        #If an RSA suite is chosen, check for certificate type intersection\n        if (cipherSuite in CipherSuite.certAllSuites or\n            cipherSuite in CipherSuite.ecdheEcdsaSuites) \\\n                    and CertificateType.x509 \\\n                    not in clientHello.certificate_types:\n            for result in self._sendError(\\\n                    AlertDescription.handshake_failure,\n                    \"the client doesn't support my certificate type\"):\n                yield result\n\n        # when we have selected TLS 1.3, check if we don't have to ask for\n        # a new client hello\n        if version > (3, 3):\n            self.version = version\n            hrr_ext = []\n\n            # check if we have good key share\n            share = clientHello.getExtension(ExtensionType.key_share)\n            if share:\n                share_ids = [i.group for i in share.client_shares]\n                acceptable_ids = [getattr(GroupName, i) for i in\n                                  chain(settings.keyShares, settings.eccCurves,\n                                        settings.dhGroups)]\n                for selected_group in acceptable_ids:\n                    if selected_group in share_ids:\n                        cl_key_share = next(i for i in share.client_shares\n                                            if i.group == selected_group)\n                        break\n                else:\n                    # if no key share is acceptable, pick one of the supported\n                    # groups that we support\n                    supported = clientHello.getExtension(ExtensionType\n                                                         .supported_groups)\n                    supported_ids = supported.groups\n                    selected_group = next((i for i in acceptable_ids\n                                           if i in supported_ids), None)\n                    if not selected_group:\n                        for result in self._sendError(AlertDescription\n                                                      .handshake_failure,\n                                                      \"No acceptable group \"\n                                                      \"advertised by client\"):\n                            yield result\n                    hrr_ks = HRRKeyShareExtension().create(selected_group)\n                    hrr_ext.append(hrr_ks)\n\n            if hrr_ext:\n                cookie = TLSExtension(extType=ExtensionType.cookie)\n                cookie = cookie.create(bytearray(b'\\x00\\x20') +\n                                       getRandomBytes(32))\n                hrr_ext.append(cookie)\n\n            if hrr_ext:\n                clientHello1 = clientHello\n\n                # create synthetic handshake hash of the first Client Hello\n                prf_name, prf_size = self._getPRFParams(cipherSuite)\n\n                client_hello_hash = self._handshake_hash.digest(prf_name)\n                self._handshake_hash = HandshakeHashes()\n                writer = Writer()\n                writer.add(HandshakeType.message_hash, 1)\n                writer.addVarSeq(client_hello_hash, 1, 3)\n                self._handshake_hash.update(writer.bytes)\n\n                # send the version that was really selected\n                vers = SrvSupportedVersionsExtension().create(version)\n                hrr_ext.append(vers)\n\n                # send the HRR\n                hrr = ServerHello()\n                # version is hardcoded in TLS 1.3, and real version\n                # is sent as extension\n                hrr.create((3, 3), TLS_1_3_HRR, clientHello.session_id,\n                           cipherSuite, extensions=hrr_ext)\n\n                msgs = [hrr]\n                if clientHello.session_id:\n                    ccs = ChangeCipherSpec().create()\n                    msgs.append(ccs)\n                for result in self._sendMsgs(msgs):\n                    yield result\n                self._ccs_sent = True\n\n                # copy for calculating PSK binders\n                self._pre_client_hello_handshake_hash = \\\n                    self._handshake_hash.copy()\n\n                for result in self._getMsg(ContentType.handshake,\n                                           HandshakeType.client_hello):\n                    if result in (0, 1):\n                        yield result\n                    else:\n                        break\n                clientHello = result\n\n                # verify that the new key share is present\n                ext = clientHello.getExtension(ExtensionType.key_share)\n                if not ext:\n                    for result in self._sendError(AlertDescription\n                                                  .missing_extension,\n                                                  \"Key share missing in \"\n                                                  \"Client Hello\"):\n                        yield result\n\n                # here we're assuming that the HRR was sent because of\n                # missing key share, that may not always be the case\n                if len(ext.client_shares) != 1:\n                    for result in self._sendError(AlertDescription\n                                                  .illegal_parameter,\n                                                  \"Multiple key shares in \"\n                                                  \"second Client Hello\"):\n                        yield result\n                if ext.client_shares[0].group != selected_group:\n                    for result in self._sendError(AlertDescription\n                                                  .illegal_parameter,\n                                                  \"Client key share does not \"\n                                                  \"match Hello Retry Request\"):\n                        yield result\n\n                # here we're assuming no 0-RTT and possibly no session\n                # resumption\n                # verify that new client hello is like the old client hello\n                # with the exception of changes requested in HRR\n                old_ext = clientHello1.getExtension(ExtensionType.key_share)\n                new_ext = clientHello.getExtension(ExtensionType.key_share)\n                old_ext.client_shares = new_ext.client_shares\n\n                # TODO when 0-RTT supported, remove early_data from old hello\n\n                if cookie:\n                    # insert the extension at the same place in the old hello\n                    # as it is in the new hello so that later binary compare\n                    # works\n                    for i, ext in enumerate(clientHello.extensions):\n                        if ext.extType == ExtensionType.cookie:\n                            if ext.extData != cookie.extData:\n                                eType = AlertDescription.illegal_parameter\n                                eText = \"Malformed cookie extension\"\n                                for result in self._sendError(eType, eText):\n                                    yield result\n                            clientHello1.extensions.insert(i, ext)\n                            break\n                    else:\n                        for result in self._sendError(AlertDescription\n                                                      .missing_extension,\n                                                      \"Second client hello \"\n                                                      \"does not contain \"\n                                                      \"cookie extension\"):\n                            yield result\n\n                # also padding extension may change\n                old_ext = clientHello1.getExtension(\n                    ExtensionType.client_hello_padding)\n                new_ext = clientHello.getExtension(\n                    ExtensionType.client_hello_padding)\n                if old_ext != new_ext:\n                    if old_ext is None and new_ext:\n                        for i, ext in enumerate(clientHello.extensions):\n                            if ext.extType == \\\n                                    ExtensionType.client_hello_padding:\n                                clientHello1.extensions.insert(i, ext)\n                                break\n                    elif old_ext and new_ext is None:\n                        # extension was removed, so remove it here too\n                        clientHello1.extensions[:] = \\\n                            (i for i in clientHello1.extensions\n                             if i.extType !=\n                             ExtensionType.client_hello_padding)\n                    else:\n                        old_ext.paddingData = new_ext.paddingData\n\n                # PSKs not compatible with cipher suite MAY\n                # be removed, but must have updated obfuscated ticket age\n                # and binders\n                old_ext = clientHello1.getExtension(\n                    ExtensionType.pre_shared_key)\n                new_ext = clientHello.getExtension(\n                    ExtensionType.pre_shared_key)\n                if new_ext and old_ext:\n                    clientHello1.extensions[-1] = new_ext\n                    if clientHello.extensions[-1] is not new_ext:\n                        for result in self._sendError(\n                                AlertDescription.illegal_parameter,\n                                \"PSK extension not last in client hello\"):\n                            yield result\n                # early_data extension MUST be dropped\n                old_ext = clientHello1.getExtension(ExtensionType.early_data)\n                if old_ext:\n                    clientHello1.extensions.remove(old_ext)\n\n                if clientHello1 != clientHello:\n                    for result in self._sendError(AlertDescription\n                                                  .illegal_parameter,\n                                                  \"Old Client Hello does not \"\n                                                  \"match the updated Client \"\n                                                  \"Hello\"):\n                        yield result\n\n        # If resumption was not requested, or\n        # we have no session cache, or\n        # the client's session_id was not found in cache:\n#pylint: disable = undefined-loop-variable\n        yield (clientHello, version, cipherSuite, sig_scheme, private_key,\n               cert_chain)\n#pylint: enable = undefined-loop-variable\n\n    def _serverSRPKeyExchange(self, clientHello, serverHello, verifierDB,\n                              cipherSuite, privateKey, serverCertChain,\n                              settings):\n        \"\"\"Perform the server side of SRP key exchange\"\"\"\n        try:\n            sigHash, serverCertChain, privateKey = \\\n                self._pickServerKeyExchangeSig(settings, clientHello,\n                                               serverCertChain,\n                                               privateKey)\n        except TLSHandshakeFailure as alert:\n            for result in self._sendError(\n                    AlertDescription.handshake_failure,\n                    str(alert)):\n                yield result\n\n        keyExchange = SRPKeyExchange(cipherSuite,\n                                     clientHello,\n                                     serverHello,\n                                     privateKey,\n                                     verifierDB)\n\n        #Create ServerKeyExchange, signing it if necessary\n        try:\n            serverKeyExchange = keyExchange.makeServerKeyExchange(sigHash)\n        except TLSUnknownPSKIdentity:\n            for result in self._sendError(\n                    AlertDescription.unknown_psk_identity):\n                yield result\n        except TLSInsufficientSecurity:\n            for result in self._sendError(\n                    AlertDescription.insufficient_security):\n                yield result\n\n        #Send ServerHello[, Certificate], ServerKeyExchange,\n        #ServerHelloDone\n        msgs = []\n        msgs.append(serverHello)\n        if cipherSuite in CipherSuite.srpCertSuites:\n            certificateMsg = Certificate(CertificateType.x509)\n            certificateMsg.create(serverCertChain)\n            msgs.append(certificateMsg)\n        msgs.append(serverKeyExchange)\n        msgs.append(ServerHelloDone())\n        for result in self._sendMsgs(msgs):\n            yield result\n\n        #Get and check ClientKeyExchange\n        for result in self._getMsg(ContentType.handshake,\n                                  HandshakeType.client_key_exchange,\n                                  cipherSuite):\n            if result in (0,1): yield result\n            else: break\n        try:\n            premasterSecret = keyExchange.processClientKeyExchange(result)\n        except TLSIllegalParameterException:\n            for result in self._sendError(AlertDescription.illegal_parameter,\n                                          \"Suspicious A value\"):\n                yield result\n        except TLSDecodeError as alert:\n            for result in self._sendError(AlertDescription.decode_error,\n                                          str(alert)):\n                yield result\n\n        yield premasterSecret, privateKey, serverCertChain\n\n    def _server_select_certificate(self, settings, client_hello,\n                                   cipher_suites, cert_chain,\n                                   private_key, version):\n        \"\"\"\n        This method makes the decision on which certificate/key pair,\n        signature algorithm and cipher to use based on the certificate.\n        \"\"\"\n\n        last_cert = False\n        possible_certs = []\n\n        # Get client groups\n        client_groups = client_hello. \\\n                getExtension(ExtensionType.supported_groups)\n        if client_groups is not None:\n            client_groups = client_groups.groups\n\n        # If client did send signature_algorithms_cert use it,\n        # otherwise fallback to signature_algorithms.\n        # Client can also decide not to send sigalg extension\n        client_sigalgs = \\\n                client_hello. \\\n                getExtension(ExtensionType.signature_algorithms_cert)\n        if client_sigalgs is not None:\n            client_sigalgs = \\\n                    client_hello. \\\n                    getExtension(ExtensionType.signature_algorithms_cert). \\\n                    sigalgs\n        else:\n            client_sigalgs = \\\n                    client_hello. \\\n                    getExtension(ExtensionType.signature_algorithms)\n            if client_sigalgs is not None:\n                client_sigalgs = \\\n                        client_hello. \\\n                        getExtension(ExtensionType.signature_algorithms). \\\n                        sigalgs\n            else:\n                client_sigalgs = []\n\n        # Get all the certificates we can offer\n        alt_certs = ((X509CertChain(i.certificates), i.key) for vh in\n                     settings.virtual_hosts for i in vh.keys)\n        certs = [(cert, key)\n                 for cert, key in chain([(cert_chain, private_key)], alt_certs)]\n\n        for cert, key in certs:\n\n            # Check if this is the last (cert, key) pair we have to check\n            if (cert, key) == certs[-1]:\n                last_cert = True\n\n            # Mandatory checks. If any one of these checks fail, the certificate\n            # is not usuable.\n            try:\n                # Find a suitable ciphersuite based on the certificate\n                ciphers = CipherSuite.filter_for_certificate(cipher_suites, cert)\n                for cipher in ciphers:\n                    if cipher in client_hello.cipher_suites:\n                        break\n                else:\n                    if client_groups and \\\n                        any(i in range(256, 512) for i in client_groups) and \\\n                        any(i in CipherSuite.dhAllSuites\n                            for i in client_hello.cipher_suites):\n                            raise TLSInsufficientSecurity(\n                                    \"FFDHE groups not acceptable and no other common \"\n                                    \"ciphers\")\n                    raise TLSHandshakeFailure(\"No mutual ciphersuite\")\n\n                # Find a signature algorithm based on the certificate\n                try:\n                    sig_scheme, _, _ = \\\n                        self._pickServerKeyExchangeSig(settings,\n                                                       client_hello,\n                                                       cert,\n                                                       key,\n                                                       version,\n                                                       False)\n                except TLSHandshakeFailure:\n                    raise TLSHandshakeFailure(\n                        \"No common signature algorithms\")\n\n                # If the certificate is ECDSA, we must check curve compatibility\n                if cert and cert.x509List[0].certAlg == 'ecdsa' and \\\n                        client_groups and client_sigalgs:\n                    public_key = cert.getEndEntityPublicKey()\n                    curve = public_key.curve_name\n                    for name, aliases in CURVE_ALIASES.items():\n                        if curve in aliases:\n                            curve = getattr(GroupName, name)\n                            break\n\n                    if version <= (3, 3) and curve not in client_groups:\n                        raise TLSHandshakeFailure(\n                            \"The curve in the public key is not \"\n                            \"supported by the client: {0}\" \\\n                                    .format(GroupName.toRepr(curve)))\n\n                    if version >= (3, 4):\n                        if GroupName.toRepr(curve) not in \\\n                                ('secp256r1', 'secp384r1', 'secp521r1'):\n                            raise TLSIllegalParameterException(\n                                    \"Curve in public key is not supported \"\n                                    \"in TLS1.3\")\n\n                # If all mandatory checks passed add\n                # this as possible certificate we can use.\n                possible_certs.append((cipher, sig_scheme, cert, key))\n\n            except Exception:\n                if last_cert and not possible_certs:\n                    raise\n                continue\n\n            # Non-mandatory checks, if these fail the certificate is still usable\n            # but we should try to find one that passes all the checks\n\n            # Check if every certificate(except the self-signed root CA)\n            # in the certificate chain is signed with a signature algorithm\n            # supported by the client.\n            if cert:\n                cert_chain_ok = True\n                for i in range(len(cert.x509List)):\n                    if cert.x509List[i].issuer != cert.x509List[i].subject:\n                        if cert.x509List[i].sigalg not in client_sigalgs:\n                            cert_chain_ok = False\n                            break\n                if not cert_chain_ok:\n                    if not last_cert:\n                        continue\n                    break\n\n            # If all mandatory and non-mandatory checks passed\n            # return the (cert, key) pair, cipher and sig_scheme\n            return cipher, sig_scheme, cert, key\n\n        # If we can't find cert that passed all the checks, return the first usable one.\n        return possible_certs[0]\n\n\n    def _serverCertKeyExchange(self, clientHello, serverHello, sigHashAlg,\n                                serverCertChain, keyExchange,\n                                reqCert, reqCAs, cipherSuite,\n                                settings):\n        #Send ServerHello, Certificate[, ServerKeyExchange]\n        #[, CertificateRequest], ServerHelloDone\n        msgs = []\n\n        # If we verify a client cert chain, return it\n        clientCertChain = None\n\n        msgs.append(serverHello)\n        msgs.append(Certificate(CertificateType.x509).create(serverCertChain))\n        try:\n            serverKeyExchange = keyExchange.makeServerKeyExchange(sigHashAlg)\n        except TLSInternalError as alert:\n            for result in self._sendError(\n                    AlertDescription.internal_error,\n                    str(alert)):\n                yield result\n        except TLSInsufficientSecurity as alert:\n            for result in self._sendError(\n                    AlertDescription.insufficient_security,\n                    str(alert)):\n                yield result\n        if serverKeyExchange is not None:\n            msgs.append(serverKeyExchange)\n        if reqCert:\n            certificateRequest = CertificateRequest(self.version)\n            if not reqCAs:\n                reqCAs = []\n            cr_settings = settings.validate()\n            # we don't support DSA in client certificates yet\n            cr_settings.dsaSigHashes = []\n            valid_sig_algs = self._sigHashesToList(cr_settings)\n            certificateRequest.create([ClientCertificateType.rsa_sign,\n                                       ClientCertificateType.ecdsa_sign],\n                                      reqCAs,\n                                      valid_sig_algs)\n            msgs.append(certificateRequest)\n        msgs.append(ServerHelloDone())\n        for result in self._sendMsgs(msgs):\n            yield result\n\n        #Get [Certificate,] (if was requested)\n        if reqCert:\n            if self.version == (3,0):\n                for result in self._getMsg((ContentType.handshake,\n                                           ContentType.alert),\n                                           HandshakeType.certificate,\n                                           CertificateType.x509):\n                    if result in (0,1): yield result\n                    else: break\n                msg = result\n\n                if isinstance(msg, Alert):\n                    #If it's not a no_certificate alert, re-raise\n                    alert = msg\n                    if alert.description != \\\n                            AlertDescription.no_certificate:\n                        self._shutdown(False)\n                        raise TLSRemoteAlert(alert)\n                elif isinstance(msg, Certificate):\n                    clientCertificate = msg\n                    if clientCertificate.cert_chain and \\\n                            clientCertificate.cert_chain.getNumCerts() != 0:\n                        clientCertChain = clientCertificate.cert_chain\n                else:\n                    raise AssertionError()\n            elif self.version in ((3,1), (3,2), (3,3)):\n                for result in self._getMsg(ContentType.handshake,\n                                          HandshakeType.certificate,\n                                          CertificateType.x509):\n                    if result in (0,1): yield result\n                    else: break\n                clientCertificate = result\n                if clientCertificate.cert_chain and \\\n                        clientCertificate.cert_chain.getNumCerts() != 0:\n                    clientCertChain = clientCertificate.cert_chain\n            else:\n                raise AssertionError()\n\n        #Get ClientKeyExchange\n        for result in self._getMsg(ContentType.handshake,\n                                  HandshakeType.client_key_exchange,\n                                  cipherSuite):\n            if result in (0,1): yield result\n            else: break\n        clientKeyExchange = result\n\n        #Process ClientKeyExchange\n        try:\n            premasterSecret = \\\n                keyExchange.processClientKeyExchange(clientKeyExchange)\n        except TLSIllegalParameterException as alert:\n            for result in self._sendError(AlertDescription.illegal_parameter,\n                                          str(alert)):\n                yield result\n        except TLSDecodeError as alert:\n            for result in self._sendError(AlertDescription.decode_error,\n                                          str(alert)):\n                yield result\n\n        #Get and check CertificateVerify, if relevant\n        self._certificate_verify_handshake_hash = self._handshake_hash.copy()\n        if clientCertChain:\n            for result in self._getMsg(ContentType.handshake,\n                                       HandshakeType.certificate_verify):\n                if result in (0, 1):\n                    yield result\n                else: break\n            certificateVerify = result\n            signatureAlgorithm = None\n            if self.version == (3, 3):\n                valid_sig_algs = \\\n                    self._sigHashesToList(settings,\n                                          certList=clientCertChain)\n                if certificateVerify.signatureAlgorithm not in valid_sig_algs:\n                    for result in self._sendError(\n                            AlertDescription.illegal_parameter,\n                            \"Invalid signature algorithm in Certificate \"\n                            \"Verify\"):\n                        yield result\n                signatureAlgorithm = certificateVerify.signatureAlgorithm\n            if not signatureAlgorithm and \\\n                    clientCertChain.x509List[0].certAlg == \"ecdsa\":\n                signatureAlgorithm = (HashAlgorithm.sha1,\n                                      SignatureAlgorithm.ecdsa)\n\n            cvhh = self._certificate_verify_handshake_hash\n            verify_bytes = KeyExchange.calcVerifyBytes(\n                self.version,\n                cvhh,\n                signatureAlgorithm,\n                premasterSecret,\n                clientHello.random,\n                serverHello.random,\n                key_type=clientCertChain.x509List[0].certAlg)\n\n            for result in self._check_certchain_with_settings(\n                    clientCertChain,\n                    settings):\n                if result in (0, 1):\n                    yield result\n                else: break\n            public_key = result\n\n            if signatureAlgorithm and signatureAlgorithm in (\n                    SignatureScheme.ed25519, SignatureScheme.ed448):\n                hash_name = \"intrinsic\"\n                salt_len = None\n                padding = None\n                ver_func = public_key.hashAndVerify\n            elif not signatureAlgorithm or \\\n                    signatureAlgorithm[1] != SignatureAlgorithm.ecdsa:\n                scheme = SignatureScheme.toRepr(signatureAlgorithm)\n                # for pkcs1 signatures hash is used to add PKCS#1 prefix, but\n                # that was already done by calcVerifyBytes\n                hash_name = None\n                salt_len = 0\n                if scheme is None:\n                    padding = 'pkcs1'\n                else:\n                    padding = SignatureScheme.getPadding(scheme)\n                    if padding == 'pss':\n                        hash_name = SignatureScheme.getHash(scheme)\n                        salt_len = getattr(hashlib, hash_name)().digest_size\n                ver_func = public_key.verify\n            else:\n                hash_name = HashAlgorithm.toStr(signatureAlgorithm[0])\n                verify_bytes = verify_bytes[\n                    :public_key.public_key.curve.baselen]\n                padding = None\n                salt_len = None\n                ver_func = public_key.verify\n\n            if not ver_func(certificateVerify.signature,\n                            verify_bytes,\n                            padding,\n                            hash_name,\n                            salt_len):\n                for result in self._sendError(\n                        AlertDescription.decrypt_error,\n                        \"Signature failed to verify\"):\n                    yield result\n        yield (premasterSecret, clientCertChain)\n\n\n    def _serverAnonKeyExchange(self, serverHello, keyExchange, cipherSuite):\n\n        # Create ServerKeyExchange\n        serverKeyExchange = keyExchange.makeServerKeyExchange()\n\n        # Send ServerHello[, Certificate], ServerKeyExchange,\n        # ServerHelloDone\n        msgs = []\n        msgs.append(serverHello)\n        msgs.append(serverKeyExchange)\n        msgs.append(ServerHelloDone())\n        for result in self._sendMsgs(msgs):\n            yield result\n\n        # Get and check ClientKeyExchange\n        for result in self._getMsg(ContentType.handshake,\n                                   HandshakeType.client_key_exchange,\n                                   cipherSuite):\n            if result in (0,1):\n                yield result\n            else:\n                break\n        cke = result\n        try:\n            premasterSecret = keyExchange.processClientKeyExchange(cke)\n        except TLSIllegalParameterException as alert:\n            for result in self._sendError(AlertDescription.illegal_parameter,\n                                          str(alert)):\n                yield result\n        except TLSDecodeError as alert:\n            for result in self._sendError(AlertDescription.decode_error,\n                                          str(alert)):\n                yield result\n\n        yield premasterSecret\n\n\n    def _serverFinished(self,  premasterSecret, clientRandom, serverRandom,\n                        cipherSuite, cipherImplementations, nextProtos,\n                        settings):\n        if self.extendedMasterSecret:\n            cvhh = self._certificate_verify_handshake_hash\n            # in case of resumption or lack of certificate authentication,\n            # the CVHH won't be initialised, but then it would also be equal\n            # to regular handshake hash\n            if not cvhh:\n                cvhh = self._handshake_hash\n            masterSecret = calc_key(self.version, premasterSecret,\n                                    cipherSuite, b\"extended master secret\",\n                                    handshake_hashes=cvhh,\n                                    output_length=48)\n        else:\n            masterSecret = calc_key(self.version, premasterSecret,\n                                    cipherSuite, b\"master secret\",\n                                    client_random=clientRandom,\n                                    server_random=serverRandom,\n                                    output_length=48)\n\n        #Calculate pending connection states\n        self._calcPendingStates(cipherSuite, masterSecret, \n                                clientRandom, serverRandom,\n                                cipherImplementations)\n\n        #Exchange ChangeCipherSpec and Finished messages\n        for result in self._getFinished(masterSecret,\n                                        cipherSuite,\n                                   expect_next_protocol=nextProtos is not None):\n            yield result\n\n        for result in self._sendFinished(masterSecret, cipherSuite,\n                settings=settings):\n            yield result\n        \n        yield masterSecret        \n\n\n    #*********************************************************\n    # Shared Handshake Functions\n    #*********************************************************\n\n\n    def _sendFinished(self, masterSecret, cipherSuite=None, nextProto=None,\n            settings=None):\n        # send the CCS and Finished in single TCP packet\n        self.sock.buffer_writes = True\n        #Send ChangeCipherSpec\n        for result in self._sendMsg(ChangeCipherSpec()):\n            yield result\n\n        #Switch to pending write state\n        self._changeWriteState()\n\n        if self._peer_record_size_limit:\n            self._send_record_limit = self._peer_record_size_limit\n            # this is TLS 1.2 and earlier method, so the real limit may be\n            # lower that what's in the settings\n            self._recv_record_limit = min(2**14, settings.record_size_limit)\n\n        if nextProto is not None:\n            nextProtoMsg = NextProtocol().create(nextProto)\n            for result in self._sendMsg(nextProtoMsg):\n                yield result\n\n        #Figure out the correct label to use\n        if self._client:\n            label = b\"client finished\"\n        else:\n            label = b\"server finished\"\n        #Calculate verification data\n        verifyData = calc_key(self.version, masterSecret,\n                              cipherSuite, label,\n                              handshake_hashes=self._handshake_hash,\n                              output_length=12)\n        if self.fault == Fault.badFinished:\n            verifyData[0] = (verifyData[0]+1)%256\n\n        #Send Finished message under new state\n        finished = Finished(self.version).create(verifyData)\n        for result in self._sendMsg(finished):\n            yield result\n        self.sock.flush()\n        self.sock.buffer_writes = False\n\n    def _getFinished(self, masterSecret, cipherSuite=None,\n                     expect_next_protocol=False, nextProto=None):\n        #Get and check ChangeCipherSpec\n        for result in self._getMsg( (ContentType.change_cipher_spec, ContentType.handshake)):\n            if result in (0,1):\n                yield result\n        changeCipherSpec = result\n\n        if changeCipherSpec.type != 1:\n            for result in self._sendError(AlertDescription.illegal_parameter,\n                                         \"ChangeCipherSpec type incorrect\"):\n                yield result\n\n        #Switch to pending read state\n        self._changeReadState()\n\n        #Server Finish - Are we waiting for a next protocol echo? \n        if expect_next_protocol:\n            for result in self._getMsg(ContentType.handshake, HandshakeType.next_protocol):\n                if result in (0,1):\n                    yield result\n            if result is None:\n                for result in self._sendError(AlertDescription.unexpected_message,\n                                             \"Didn't get NextProtocol message\"):\n                    yield result\n\n            self.next_proto = result.next_proto\n        else:\n            self.next_proto = None\n\n        #Client Finish - Only set the next_protocol selected in the connection\n        if nextProto:\n            self.next_proto = nextProto\n\n        #Figure out which label to use.\n        if self._client:\n            label = b\"server finished\"\n        else:\n            label = b\"client finished\"\n\n        #Calculate verification data\n        verifyData = calc_key(self.version, masterSecret,\n                              cipherSuite, label,\n                              handshake_hashes=self._handshake_hash,\n                              output_length=12)\n\n        #Get and check Finished message under new state\n        for result in self._getMsg(ContentType.handshake,\n                                  HandshakeType.finished):\n            if result in (0,1):\n                yield result\n        finished = result\n        if finished.verify_data != verifyData:\n            for result in self._sendError(AlertDescription.decrypt_error,\n                                         \"Finished message is incorrect\"):\n                yield result\n\n    def _handshakeWrapperAsync(self, handshaker, checker):\n        try:\n            for result in handshaker:\n                yield result\n            if checker:\n                try:\n                    checker(self)\n                except TLSAuthenticationError:\n                    alert = Alert().create(AlertDescription.close_notify,\n                                           AlertLevel.fatal)\n                    for result in self._sendMsg(alert):\n                        yield result\n                    raise\n        except GeneratorExit:\n            raise\n        except TLSAlert as alert:\n            if not self.fault:\n                raise\n            if alert.description not in Fault.faultAlerts[self.fault]:\n                raise TLSFaultError(str(alert))\n            else:\n                pass\n        except:\n            self._shutdown(False)\n            raise\n\n    @staticmethod\n    def _pickServerKeyExchangeSig(settings, clientHello, certList=None,\n                                  private_key=None,\n                                  version=(3, 3), check_alt=True):\n        \"\"\"Pick a hash that matches most closely the supported ones\"\"\"\n        hashAndAlgsExt = clientHello.getExtension(\n            ExtensionType.signature_algorithms)\n\n        if version > (3, 3):\n            if not hashAndAlgsExt:\n                # the error checking was done before hand, likely we're\n                # doing PSK key exchange\n                return None, certList, private_key\n\n        if hashAndAlgsExt is None or hashAndAlgsExt.sigalgs is None:\n            # RFC 5246 states that if there are no hashes advertised,\n            # sha1 should be picked\n            return \"sha1\", certList, private_key\n\n        if check_alt:\n            alt_certs = ((X509CertChain(i.certificates), i.key) for vh in\n                         settings.virtual_hosts for i in vh.keys)\n        else:\n            alt_certs = ()\n\n        for certs, key in chain([(certList, private_key)], alt_certs):\n            supported = TLSConnection._sigHashesToList(settings,\n                                                       certList=certs,\n                                                       version=version)\n\n            for schemeID in supported:\n                if schemeID in hashAndAlgsExt.sigalgs:\n                    name = SignatureScheme.toRepr(schemeID)\n                    if not name and schemeID[1] in (SignatureAlgorithm.rsa,\n                                                    SignatureAlgorithm.ecdsa,\n                                                    SignatureAlgorithm.dsa):\n                        name = HashAlgorithm.toRepr(schemeID[0])\n\n                    if name:\n                        return name, certs, key\n\n        # if no match, we must abort per RFC 5246\n        raise TLSHandshakeFailure(\"No common signature algorithms\")\n\n    @staticmethod\n    def _sigHashesToList(settings, privateKey=None, certList=None,\n                         version=(3, 3)):\n        \"\"\"Convert list of valid signature hashes to array of tuples\"\"\"\n        certType = None\n        publicKey = None\n        if certList and certList.x509List:\n            certType = certList.x509List[0].certAlg\n            publicKey = certList.x509List[0].publicKey\n\n        sigAlgs = []\n\n        if not certType or certType == \"Ed25519\" or certType == \"Ed448\":\n            for sig_scheme in settings.more_sig_schemes:\n                if version < (3, 3):\n                    # EdDSA is supported only in TLS 1.2 and 1.3\n                    continue\n                if certType and sig_scheme != certType:\n                    continue\n                sigAlgs.append(getattr(SignatureScheme, sig_scheme.lower()))\n\n        if not certType or certType == \"ecdsa\":\n            for hashName in settings.ecdsaSigHashes:\n                # only SHA256, SHA384 and SHA512 are allowed in TLS 1.3\n                if version > (3, 3) and hashName in (\"sha1\", \"sha224\"):\n                    continue\n\n                # in TLS 1.3 ECDSA key curve is bound to hash\n                if publicKey and version > (3, 3):\n                    curve = publicKey.curve_name\n                    matching_hash = TLSConnection._curve_name_to_hash_name(\n                        curve)\n                    if hashName != matching_hash:\n                        continue\n\n                sigAlgs.append((getattr(HashAlgorithm, hashName),\n                                SignatureAlgorithm.ecdsa))\n\n        if not certType or certType == \"dsa\":\n            for hashName in settings.dsaSigHashes:\n                if version > (3, 3):\n                    continue\n\n                sigAlgs.append((getattr(HashAlgorithm, hashName),\n                                SignatureAlgorithm.dsa))\n\n        if not certType or certType in (\"rsa\", \"rsa-pss\"):\n            for schemeName in settings.rsaSchemes:\n                # pkcs#1 v1.5 signatures are not allowed in TLS 1.3\n                if version > (3, 3) and schemeName == \"pkcs1\":\n                    continue\n\n                for hashName in settings.rsaSigHashes:\n                    # rsa-pss certificates can't be used to make PKCS#1 v1.5\n                    # signatures\n                    if certType == \"rsa-pss\" and schemeName == \"pkcs1\":\n                        continue\n                    try:\n                        # 1024 bit keys are too small to create valid\n                        # rsa-pss-SHA512 signatures\n                        if schemeName == 'pss' and hashName == 'sha512'\\\n                                and privateKey and privateKey.n < 2**2047:\n                            continue\n                        # advertise support for both rsaEncryption and RSA-PSS OID\n                        # key type\n                        if certType != 'rsa-pss':\n                            sigAlgs.append(getattr(SignatureScheme,\n                                                   \"rsa_{0}_rsae_{1}\"\n                                                   .format(schemeName, hashName)))\n                        if certType != 'rsa':\n                            sigAlgs.append(getattr(SignatureScheme,\n                                                   \"rsa_{0}_pss_{1}\"\n                                                   .format(schemeName, hashName)))\n                    except AttributeError:\n                        if schemeName == 'pkcs1':\n                            sigAlgs.append((getattr(HashAlgorithm, hashName),\n                                            SignatureAlgorithm.rsa))\n                        continue\n        return sigAlgs\n\n    @staticmethod\n    def _curveNamesToList(settings):\n        \"\"\"Convert list of acceptable curves to array identifiers\"\"\"\n        return [getattr(GroupName, val) for val in settings.eccCurves]\n\n    @staticmethod\n    def _groupNamesToList(settings):\n        \"\"\"Convert list of acceptable ff groups to TLS identifiers.\"\"\"\n        return [getattr(GroupName, val) for val in settings.dhGroups]\n\n    @staticmethod\n    def _curve_name_to_hash_name(curve_name):\n        \"\"\"Returns the matching hash for a given curve name, for TLS 1.3\n\n        expects the python-ecdsa curve names as parameter\n        \"\"\"\n        if curve_name == \"NIST256p\":\n            return \"sha256\"\n        if curve_name == \"NIST384p\":\n            return \"sha384\"\n        if curve_name == \"NIST521p\":\n            return \"sha512\"\n        raise TLSIllegalParameterException(\n            \"Curve {0} is not supported in TLS 1.3\".format(curve_name))\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/tlsrecordlayer.py",
    "content": "# Authors: \n#   Trevor Perrin\n#   Google (adapted by Sam Rushing) - NPN support\n#   Google - minimal padding\n#   Martin von Loewis - python 3 port\n#   Yngve Pettersen (ported by Paul Sokolovsky) - TLS 1.2\n#   Hubert Kario\n#\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Helper class for TLSConnection.\"\"\"\nfrom __future__ import generators\n\nimport io\nimport time\nimport socket\n\nfrom .utils.compat import *\nfrom .utils.cryptomath import *\nfrom .utils.codec import Parser, BadCertificateError\nfrom .utils.lists import to_str_delimiter, getFirstMatching\nfrom .errors import *\nfrom .messages import *\nfrom .mathtls import *\nfrom .constants import *\nfrom .recordlayer import RecordLayer\nfrom .defragmenter import Defragmenter\nfrom .handshakehashes import HandshakeHashes\nfrom .bufferedsocket import BufferedSocket\nfrom .handshakesettings import HandshakeSettings\nfrom .keyexchange import KeyExchange\n\nclass TLSRecordLayer(object):\n    \"\"\"\n    This class handles data transmission for a TLS connection.\n\n    Its only subclass is :py:class:`~tlslite.tlsconnection.TLSConnection`.\n    We've\n    separated the code in this class from TLSConnection to make things\n    more readable.\n\n\n    :vartype sock: socket.socket\n    :ivar sock: The underlying socket object.\n\n    :vartype session: ~tlslite.Session.Session\n    :ivar session: The session corresponding to this connection.\n        Due to TLS session resumption, multiple connections can correspond\n        to the same underlying session.\n\n    :vartype ~.version: tuple\n    :ivar ~.version: The TLS version being used for this connection.\n        (3,0) means SSL 3.0, and (3,1) means TLS 1.0.\n\n    :vartype closed: bool\n    :ivar closed: If this connection is closed.\n\n    :vartype resumed: bool\n    :ivar resumed: If this connection is based on a resumed session.\n\n    :vartype allegedSrpUsername: str or None\n    :ivar allegedSrpUsername:  This is set to the SRP username\n        asserted by the client, whether the handshake succeeded or not.\n        If the handshake fails, this can be inspected to determine\n        if a guessing attack is in progress against a particular user\n        account.\n\n    :vartype closeSocket: bool\n    :ivar closeSocket: If the socket should be closed when the\n        connection is closed, defaults to True (writable).\n\n        If you set this to True, TLS Lite will assume the responsibility of\n        closing the socket when the TLS Connection is shutdown (either\n        through an error or through the user calling close()).  The default\n        is False.\n\n    :vartype ignoreAbruptClose: bool\n    :ivar ignoreAbruptClose: If an abrupt close of the socket should\n        raise an error (writable).\n\n        If you set this to True, TLS Lite will not raise a\n        :py:class:`~tlslite.errors.TLSAbruptCloseError` exception if the\n        underlying\n        socket is unexpectedly closed.  Such an unexpected closure could be\n        caused by an attacker.  However, it also occurs with some incorrect\n        TLS implementations.\n\n        You should set this to True only if you're not worried about an\n        attacker truncating the connection, and only if necessary to avoid\n        spurious errors.  The default is False.\n\n    :vartype ~.encryptThenMAC: bool\n    :ivar ~.encryptThenMAC: Whether the connection uses the encrypt-then-MAC\n        construct for CBC cipher suites, will be False also if connection uses\n        RC4 or AEAD.\n\n    :vartype recordSize: int\n    :ivar recordSize: maximum size of data to be sent in a single record layer\n        message. Note that after encryption is established (generally after\n        handshake protocol has finished) the actual amount of data written to\n        network socket will be larger because of the record layer header,\n        padding\n        or encryption overhead. It can be set to low value (so that there is no\n        fragmentation on Ethernet, IP and TCP level) at the beginning of\n        connection to reduce latency and set to protocol max (2**14) to\n        maximise\n        throughput after sending the first few kiB of data. If negotiated,\n        record_size_limit extension may limit it though, causing reading of the\n        variable to return lower value that was initially set.\n        See also: HandshakeSettings.record_size_limit.\n\n    :vartype tickets: list of bytearray\n    :ivar tickets: list of session tickets received from server, oldest first.\n\n    :vartype client_cert_required: bool\n    :ivar client_cert_required: Set to True to make the post-handshake\n        authentication fail when client doesn't provide a certificate in\n        response\n    \"\"\"\n\n    def __init__(self, sock):\n        sock = BufferedSocket(sock)\n        self.sock = sock\n        self._recordLayer = RecordLayer(sock)\n\n        #My session object (Session instance; read-only)\n        self.session = None\n\n        #Buffers for processing messages\n        self._defragmenter = Defragmenter()\n        self._defragmenter.add_static_size(ContentType.change_cipher_spec, 1)\n        self._defragmenter.add_static_size(ContentType.alert, 2)\n        self._defragmenter.add_dynamic_size(ContentType.handshake, 1, 3)\n        self.clearReadBuffer()\n        self.clearWriteBuffer()\n\n        #Handshake digests\n        self._handshake_hash = HandshakeHashes()\n        # Handshake digest used for Certificate Verify signature and\n        # also for EMS calculation, in practice, it excludes\n        # CertificateVerify and all following messages (Finished)\n        self._certificate_verify_handshake_hash = None\n        # for PSK binders we need to be able to calculate the hash of all\n        # echanged messages and a _truncated_ ClientHello message so we\n        # need a copy of those hashes before CH was received\n        self._pre_client_hello_handshake_hash = None\n\n        #Is the connection open?\n        self.closed = True #read-only\n        self._refCount = 0 #Used to trigger closure\n\n        #Is this a resumed session?\n        self.resumed = False #read-only\n\n        #What username did the client claim in his handshake?\n        self.allegedSrpUsername = None\n\n        #On a call to close(), do we close the socket? (writeable)\n        self.closeSocket = True\n\n        #If the socket is abruptly closed, do we ignore it\n        #and pretend the connection was shut down properly? (writeable)\n        self.ignoreAbruptClose = False\n\n        #Fault we will induce, for testing purposes\n        self.fault = None\n\n        # Temporarily limit the size of outgoing records to following size\n        self._user_record_limit = 16384  # 2**14\n\n        # NewSessionTickets received from server\n        self.tickets = []\n\n        # Indicator for heartbeat extension mode, if we can receive\n        # heartbeat requests\n        self.heartbeat_can_receive = False\n\n        # Indicator for heartbeat extension mode, if we can send\n        # heartbeat requests\n        self.heartbeat_can_send = False\n\n        # Indicator, that both sides want use heartbeat extension\n        self.heartbeat_supported = False\n\n        # Callback function for handling responses to heartbeat requests\n        # we sent\n        self.heartbeat_response_callback = None\n\n        self._buffer_content_type = None\n        self._buffer = bytearray()\n\n        # tuple with list of certificates and the private key that will be\n        # used for post handshake authentication in TLS 1.3\n        self._client_keypair = None\n\n        # dictionary with CertificateRequest messages we (as a server) have\n        # sent, the keys are the \"certificate request context\" from the\n        # messages (which are the values)\n        self._cert_requests = {}\n\n        # boolean to control if PHA needs to be aborted when the client\n        # doesn't provide a certificate\n        self.client_cert_required = False\n\n        # boolean to control if ChangeCipherSpec in TLS1.3 is allowed or not\n        # we start with True, as peers MUST always processe the messages\n        # before the handshake is done, only then we disable it (for PHA)\n        self._middlebox_compat_mode = True\n\n    @property\n    def _send_record_limit(self):\n        \"\"\"Maximum size of payload that can be sent.\"\"\"\n        return self._recordLayer.send_record_limit\n\n    @_send_record_limit.setter\n    def _send_record_limit(self, value):\n        \"\"\"Maximum size of payload that can be sent.\"\"\"\n        self._recordLayer.send_record_limit = value\n\n    @property\n    def _recv_record_limit(self):\n        \"\"\"Maximum size of payload that can be received.\"\"\"\n        return self._recordLayer.recv_record_limit\n\n    @_recv_record_limit.setter\n    def _recv_record_limit(self, value):\n        \"\"\"Maximum size of payload that can be received.\"\"\"\n        self._recordLayer.recv_record_limit = value\n\n    @property\n    def recordSize(self):\n        \"\"\"Maximum size of the records that will be sent out.\"\"\"\n        return min(self._user_record_limit, self._send_record_limit)\n\n    @recordSize.setter\n    def recordSize(self, value):\n        \"\"\"Size to automatically fragment records to.\"\"\"\n        self._user_record_limit = value\n\n    @property\n    def _client(self):\n        \"\"\"Boolean stating if the endpoint acts as a client\"\"\"\n        return self._recordLayer.client\n\n    @_client.setter\n    def _client(self, value):\n        \"\"\"Set the endpoint to act as a client or not\"\"\"\n        self._recordLayer.client = value\n\n    @property\n    def version(self):\n        \"\"\"Get the SSL protocol version of connection\"\"\"\n        return self._recordLayer.version\n\n    @version.setter\n    def version(self, value):\n        \"\"\"\n        Set the SSL protocol version of connection\n\n        The setter is a public method only for backwards compatibility.\n        Don't use it! See at HandshakeSettings for options to set desired\n        protocol version.\n        \"\"\"\n        self._recordLayer.version = value\n        if value > (3, 3):\n            self._recordLayer.tls13record = True\n\n    @property\n    def encryptThenMAC(self):\n        \"\"\"Whether the connection uses Encrypt Then MAC (RFC 7366)\"\"\"\n        return self._recordLayer.encryptThenMAC\n\n    def clearReadBuffer(self):\n        self._readBuffer = b''\n\n    def clearWriteBuffer(self):\n        self._send_writer = None\n\n\n    #*********************************************************\n    # Public Functions START\n    #*********************************************************\n\n    def read(self, max=None, min=1):\n        \"\"\"Read some data from the TLS connection.\n\n        This function will block until at least 'min' bytes are\n        available (or the connection is closed).\n\n        If an exception is raised, the connection will have been\n        automatically closed.\n\n        :type max: int\n        :param max: The maximum number of bytes to return.\n\n        :type min: int\n        :param min: The minimum number of bytes to return\n\n        :rtype: str\n        :returns: A string of no more than 'max' bytes, and no fewer\n            than 'min' (unless the connection has been closed, in which\n            case fewer than 'min' bytes may be returned).\n\n        :raises socket.error: If a socket error occurs.\n        :raises tlslite.errors.TLSAbruptCloseError: If the socket is closed\n            without a preceding alert.\n        :raises tlslite.errors.TLSAlert: If a TLS alert is signalled.\n        \"\"\"\n        for result in self.readAsync(max, min):\n            pass\n        return result\n\n    def readAsync(self, max=None, min=1):\n        \"\"\"Start a read operation on the TLS connection.\n\n        This function returns a generator which behaves similarly to\n        read().  Successive invocations of the generator will return 0\n        if it is waiting to read from the socket, 1 if it is waiting\n        to write to the socket, or a string if the read operation has\n        completed.\n\n        :rtype: iterable\n        :returns: A generator; see above for details.\n        \"\"\"\n        constructor_type = None\n        if self.version > (3, 3):\n            allowedTypes = (ContentType.application_data,\n                            ContentType.handshake)\n            if self._client_keypair:\n                allowedHsTypes = (HandshakeType.new_session_ticket,\n                                  HandshakeType.key_update,\n                                  HandshakeType.certificate_request)\n            elif self._cert_requests:\n                allowedHsTypes = (HandshakeType.new_session_ticket,\n                                  HandshakeType.key_update,\n                                  HandshakeType.certificate)\n                constructor_type = CertificateType.x509\n            else:\n                allowedHsTypes = (HandshakeType.new_session_ticket,\n                                  HandshakeType.key_update)\n        else:\n            allowedTypes = ContentType.application_data\n            allowedHsTypes = None\n        try:\n            try_once = True\n            # perform a read even if we were asked to read 0 bytes, but only\n            # if the buffer is empty; this is used to trigger\n            # processing of NST, KeyUpdate and PHA\n            while (len(self._readBuffer) < min or\n                    (not self._readBuffer and try_once)) \\\n                    and not self.closed:\n                try_once = False\n                try:\n                    for result in self._getMsg(allowedTypes,\n                                               allowedHsTypes,\n                                               constructor_type):\n                        if result in (0, 1):\n                            yield result\n                    if isinstance(result, NewSessionTicket):\n                        result.time = time.time()\n                        self.tickets.append(result)\n                    elif isinstance(result, KeyUpdate):\n                        for result in self._handle_keyupdate_request(result):\n                            yield result\n                        # KeyUpdate messages are not solicited, while call with\n                        # min==0 are done to perform PHA\n                        try_once = True\n                    elif isinstance(result, Certificate):\n                        for result in self._handle_srv_pha(result):\n                            yield result\n                    elif isinstance(result, CertificateRequest):\n                        for result in self._handle_pha(result):\n                            yield result\n                    else:\n                        assert isinstance(result, ApplicationData)\n                        applicationData = result\n                        self._readBuffer += applicationData.write()\n                except TLSRemoteAlert as alert:\n                    if alert.description != AlertDescription.close_notify:\n                        raise\n                except TLSAbruptCloseError:\n                    if not self.ignoreAbruptClose:\n                        raise\n                    else:\n                        self._shutdown(True)\n\n            if max == None:\n                max = len(self._readBuffer)\n\n            returnBytes = self._readBuffer[:max]\n            self._readBuffer = self._readBuffer[max:]\n            yield bytes(returnBytes)\n        except GeneratorExit:\n            raise\n        except:\n            self._shutdown(False)\n            raise\n\n    def unread(self, b):\n        \"\"\"Add bytes to the front of the socket read buffer for future\n        reading. Be careful using this in the context of select(...): if you\n        unread the last data from a socket, that won't wake up selected waiters,\n        and those waiters may hang forever.\n        \"\"\"\n        self._readBuffer = b + self._readBuffer\n\n    def write(self, s):\n        \"\"\"Write some data to the TLS connection.\n\n        This function will block until all the data has been sent.\n\n        If an exception is raised, the connection will have been\n        automatically closed.\n\n        :type s: str\n        :param s: The data to transmit to the other party.\n\n        :raises socket.error: If a socket error occurs.\n        \"\"\"\n        for result in self.writeAsync(s):\n            pass\n\n    def writeAsync(self, s):\n        \"\"\"Start a write operation on the TLS connection.\n\n        This function returns a generator which behaves similarly to\n        write().  Successive invocations of the generator will return\n        1 if it is waiting to write to the socket, or will raise\n        StopIteration if the write operation has completed.\n\n        :rtype: iterable\n        :returns: A generator; see above for details.\n        \"\"\"\n        try:\n            if self.closed:\n                raise TLSClosedConnectionError(\"attempt to write to closed connection\")\n\n            applicationData = ApplicationData().create(bytearray(s))\n            for result in self._sendMsg(applicationData, \\\n                                        randomizeFirstBlock=True):\n                yield result\n        except GeneratorExit:\n            raise\n        except Exception:\n            # Don't invalidate the session on write failure if abrupt closes are\n            # okay.\n            self._shutdown(self.ignoreAbruptClose)\n            raise\n\n    def close(self):\n        \"\"\"Close the TLS connection.\n\n        This function will block until it has exchanged close_notify\n        alerts with the other party.  After doing so, it will shut down the\n        TLS connection.  Further attempts to read through this connection\n        will return \"\".  Further attempts to write through this connection\n        will raise ValueError.\n\n        If makefile() has been called on this connection, the connection\n        will be not be closed until the connection object and all file\n        objects have been closed.\n\n        Even if an exception is raised, the connection will have been\n        closed.\n\n        :raises socket.error: If a socket error occurs.\n        :raises tlslite.errors.TLSAbruptCloseError: If the socket is closed\n            without a preceding alert.\n        :raises tlslite.errors.TLSAlert: If a TLS alert is signalled.\n        \"\"\"\n        if not self.closed:\n            for result in self._decrefAsync():\n                pass\n\n    # Python 3 callback\n    _decref_socketios = close\n\n    def closeAsync(self):\n        \"\"\"Start a close operation on the TLS connection.\n\n        This function returns a generator which behaves similarly to\n        close().  Successive invocations of the generator will return 0\n        if it is waiting to read from the socket, 1 if it is waiting\n        to write to the socket, or will raise StopIteration if the\n        close operation has completed.\n\n        :rtype: iterable\n        :returns: A generator; see above for details.\n        \"\"\"\n        if not self.closed:\n            for result in self._decrefAsync():\n                yield result\n\n    def _decrefAsync(self):\n        self._refCount -= 1\n        if self._refCount == 0 and not self.closed:\n            try:\n                for result in self._sendMsg(Alert().create(\\\n                        AlertDescription.close_notify, AlertLevel.warning)):\n                    yield result\n                alert = None\n                # By default close the socket, since it's been observed\n                # that some other libraries will not respond to the \n                # close_notify alert, thus leaving us hanging if we're\n                # expecting it\n                if self.closeSocket:\n                    self._shutdown(True)\n                else:\n                    while not alert:\n                        for result in self._getMsg((ContentType.alert, \\\n                                                  ContentType.application_data)):\n                            if result in (0,1):\n                                yield result\n                        if result.contentType == ContentType.alert:\n                            alert = result\n                    if alert.description == AlertDescription.close_notify:\n                        self._shutdown(True)\n                    else:\n                        raise TLSRemoteAlert(alert)\n            except (socket.error, TLSAbruptCloseError):\n                #If the other side closes the socket, that's okay\n                self._shutdown(True)\n            except GeneratorExit:\n                raise\n            except:\n                self._shutdown(False)\n                raise\n\n    def getVersionName(self):\n        \"\"\"Get the name of this TLS version.\n\n        :rtype: str\n        :returns: The name of the TLS version used with this connection.\n            Either None, 'SSL 3.0', 'TLS 1.0', 'TLS 1.1', 'TLS 1.2' or\n            'TLS 1.3'.\n        \"\"\"\n        ver = {(3, 0): \"SSL 3.0\",\n               (3, 1): \"TLS 1.0\",\n               (3, 2): \"TLS 1.1\",\n               (3, 3): \"TLS 1.2\",\n               (3, 4): \"TLS 1.3\"}\n        return ver.get(self.version)\n\n    def getCipherName(self):\n        \"\"\"Get the name of the cipher used with this connection.\n\n        :rtype: str\n        :returns: The name of the cipher used with this connection.\n            Either 'aes128', 'aes256', 'rc4', or '3des'.\n        \"\"\"\n        return self._recordLayer.getCipherName()\n\n    def getCipherImplementation(self):\n        \"\"\"Get the name of the cipher implementation used with\n        this connection.\n\n        :rtype: str\n        :returns: The name of the cipher implementation used with\n            this connection.  Either 'python', 'openssl', or 'pycrypto'.\n        \"\"\"\n        return self._recordLayer.getCipherImplementation()\n\n    #Emulate a socket, somewhat -\n    def send(self, s):\n        \"\"\"Send data to the TLS connection (socket emulation).\n\n        :raises socket.error: If a socket error occurs.\n        \"\"\"\n        self.write(s)\n        return len(s)\n\n    def sendall(self, s):\n        \"\"\"Send data to the TLS connection (socket emulation).\n\n        :raises socket.error: If a socket error occurs.\n        \"\"\"\n        self.write(s)\n\n    def recv(self, bufsize):\n        \"\"\"Get some data from the TLS connection (socket emulation).\n\n        :raises socket.error: If a socket error occurs.\n        :raises tlslite.errors.TLSAbruptCloseError: If the socket is closed\n            without a preceding alert.\n        :raises tlslite.errors.TLSAlert: If a TLS alert is signalled.\n        \"\"\"\n        return self.read(bufsize)\n\n    def recv_into(self, b):\n        # XXX doc string\n        data = self.read(len(b))\n        if not data:\n            return None\n        b[:len(data)] = data\n        return len(data)\n\n    # while the SocketIO and _fileobject in socket is private we really need\n    # to use it as it's what the real socket does internally\n\n    # pylint: disable=no-member,protected-access\n    def makefile(self, mode='r', bufsize=-1):\n        \"\"\"Create a file object for the TLS connection (socket emulation).\n\n        :rtype: socket._fileobject\n        \"\"\"\n        self._refCount += 1\n        # So, it is pretty fragile to be using Python internal objects\n        # like this, but it is probably the best/easiest way to provide\n        # matching behavior for socket emulation purposes.  The 'close'\n        # argument is nice, its apparently a recent addition to this\n        # class, so that when fileobject.close() gets called, it will\n        # close() us, causing the refcount to be decremented (decrefAsync).\n        #\n        # If this is the last close() on the outstanding fileobjects / \n        # TLSConnection, then the \"actual\" close alerts will be sent,\n        # socket closed, etc.\n\n        # for writes, we MUST buffer otherwise the lengths of headers leak\n        # through record layer boundaries\n        if 'w' in mode and bufsize <= 0:\n            bufsize = 2**14\n\n        if sys.version_info < (3,):\n            return socket._fileobject(self, mode, bufsize, close=True)\n        else:\n            if 'w' in mode:\n                return io.BufferedWriter(socket.SocketIO(self, mode), bufsize)\n            else:\n                return socket.SocketIO(self, mode)\n    # pylint: enable=no-member,protected-access\n\n    def getsockname(self):\n        \"\"\"Return the socket's own address (socket emulation).\"\"\"\n        return self.sock.getsockname()\n\n    def getpeername(self):\n        \"\"\"Return the remote address to which the socket is connected\n        (socket emulation).\"\"\"\n        return self.sock.getpeername()\n\n    def settimeout(self, value):\n        \"\"\"Set a timeout on blocking socket operations (socket emulation).\"\"\"\n        return self.sock.settimeout(value)\n\n    def gettimeout(self):\n        \"\"\"Return the timeout associated with socket operations (socket\n        emulation).\"\"\"\n        return self.sock.gettimeout()\n\n    def setsockopt(self, level, optname, value):\n        \"\"\"Set the value of the given socket option (socket emulation).\"\"\"\n        return self.sock.setsockopt(level, optname, value)\n\n    def shutdown(self, how):\n        \"\"\"Shutdown the underlying socket.\"\"\"\n        return self.sock.shutdown(how)\n    \t\n    def fileno(self):\n        \"\"\"Not implement in TLS Lite.\"\"\"\n        raise NotImplementedError()\n    \t\n\n     #*********************************************************\n     # Public Functions END\n     #*********************************************************\n\n    def _handle_pha(self, cert_request):\n        cert, p_key = self._client_keypair\n\n        handshake_context = self._first_handshake_hashes.copy()\n        handshake_context.update(cert_request.write())\n\n        prf_name = 'sha256'\n        prf_size = 32\n        if self.session.cipherSuite in CipherSuite.sha384PrfSuites:\n            prf_name = 'sha384'\n            prf_size = 48\n\n        msgs = []\n        msgs.append(Certificate(CertificateType.x509, self.version)\n                    .create(cert, cert_request.certificate_request_context))\n        handshake_context.update(msgs[0].write())\n        if cert.x509List and p_key:\n            # sign the CertificateVerify only when we have a private key to do\n            # that\n            valid_sig_algs = cert_request.supported_signature_algs\n            if not valid_sig_algs:\n                for result in self._sendError(\n                        AlertDescription.missing_extension,\n                        \"No signature algorithms found in CertificateRequest\"):\n                    yield result\n            avail_sig_algs = self._sigHashesToList(HandshakeSettings(), p_key,\n                                                   cert, version=(3, 4))\n            sig_scheme = getFirstMatching(avail_sig_algs, valid_sig_algs)\n            scheme = SignatureScheme.toRepr(sig_scheme)\n            sig_scheme = getattr(SignatureScheme, scheme)\n\n            signature_context = \\\n                KeyExchange.calcVerifyBytes((3, 4),\n                                            handshake_context,\n                                            sig_scheme, None, None, None,\n                                            prf_name, b'client')\n\n            if sig_scheme in (SignatureScheme.ed25519, SignatureScheme.ed448):\n                pad_type = None\n                hash_name = \"intrinsic\"\n                salt_len = None\n                sig_func = p_key.hashAndSign\n                ver_func = p_key.hashAndVerify\n            elif sig_scheme[1] == SignatureAlgorithm.ecdsa:\n                pad_type = None\n                hash_name = HashAlgorithm.toRepr(sig_scheme[0])\n                salt_len = None\n                sig_func = p_key.sign\n                ver_func = p_key.verify\n            else:\n                pad_type = SignatureScheme.getPadding(scheme)\n                hash_name = SignatureScheme.getHash(scheme)\n                salt_len = getattr(hashlib, hash_name)().digest_size\n                sig_func = p_key.sign\n                ver_func = p_key.verify\n\n            signature = sig_func(signature_context,\n                                 pad_type,\n                                 hash_name,\n                                 salt_len)\n            if not ver_func(signature, signature_context,\n                            pad_type,\n                            hash_name,\n                            salt_len):\n                for result in self._sendError(\n                        AlertDescription.internal_error,\n                        \"Certificate Verify signature failed\"):\n                    yield result\n            certificate_verify = CertificateVerify(self.version)\n            certificate_verify.create(signature, sig_scheme)\n\n            msgs.append(certificate_verify)\n            handshake_context.update(certificate_verify.write())\n\n        finished_key = HKDF_expand_label(self.session.cl_app_secret,\n                                         b\"finished\", b\"\",\n                                         prf_size, prf_name)\n        verify_data = secureHMAC(finished_key,\n                                 handshake_context.digest(prf_name),\n                                 prf_name)\n\n        finished = Finished((3, 4), prf_size)\n        finished.create(verify_data)\n        msgs.append(finished)\n\n        for result in self._sendMsgs(msgs):\n            yield result\n\n    def _handle_srv_pha(self, cert):\n        \"\"\"Process the post-handshake authentication from client.\"\"\"\n        prf_name = 'sha256'\n        prf_size = 32\n        if self.session.cipherSuite in CipherSuite.sha384PrfSuites:\n            prf_name = 'sha384'\n            prf_size = 48\n\n        cr_context = cert.certificate_request_context\n        if not cr_context:\n            for result in self._sendError(\n                    AlertDescription.illegal_parameter,\n                    \"Certificate Request context missing in Certificate \"\n                    \"message from client\"):\n                yield result\n\n        try:\n            cr = self._cert_requests.pop(bytes(cr_context))\n        except KeyError:\n            for result in self._sendError(\n                    AlertDescription.illegal_parameter,\n                    \"Certificiate Request context is incorrect or was already \"\n                    \"handled previously\"):\n                yield result\n\n        # TODO: verify that the extensions used by client were sent by us in\n        # CertificateReuest\n\n        handshake_context = self._first_handshake_hashes.copy()\n        handshake_context.update(cr.write())\n        handshake_context.update(cert.write())\n\n        if cert.cert_chain:\n            for result in self._getMsg(ContentType.handshake,\n                                       HandshakeType.certificate_verify):\n                if result in (0, 1):\n                    yield result\n                else:\n                    break\n            assert isinstance(result, CertificateVerify)\n            cert_verify = result\n\n            valid_sig_algs = cr.supported_signature_algs\n            if cert_verify.signatureAlgorithm not in valid_sig_algs:\n                for result in self._sendError(\n                        AlertDescription.illegal_parameter,\n                        \"Client selected signature algorithm we didn't \"\n                        \"advertise\"):\n                    yield result\n            avail_sig_algs = self._sigHashesToList(HandshakeSettings(), None,\n                                                   cert.cert_chain,\n                                                   version=(3, 4))\n            if cert_verify.signatureAlgorithm not in avail_sig_algs:\n                for result in self._sendError(\n                        AlertDescription.illegal_parameter,\n                        \"Client selected signature algorithm not consistent \"\n                        \"with public key in its certificate\"):\n                    yield result\n            scheme = SignatureScheme.toRepr(cert_verify.signatureAlgorithm)\n            sig_scheme = getattr(SignatureScheme, scheme)\n\n            signature_context = \\\n                KeyExchange.calcVerifyBytes((3, 4),\n                                            handshake_context,\n                                            sig_scheme, None, None, None,\n                                            prf_name, b'client')\n\n            if sig_scheme in (SignatureScheme.ed25519, SignatureScheme.ed448):\n                pad_type = None\n                hash_name = \"intrinsic\"\n                salt_len = None\n                ver_func = cert.cert_chain.getEndEntityPublicKey().hashAndVerify\n            elif sig_scheme[1] == SignatureAlgorithm.ecdsa:\n                pad_type = None\n                hash_name = HashAlgorithm.toRepr(sig_scheme[0])\n                salt_len = None\n                ver_func = cert.cert_chain.getEndEntityPublicKey().verify\n            else:\n                pad_type = SignatureScheme.getPadding(scheme)\n                hash_name = SignatureScheme.getHash(scheme)\n                salt_len = getattr(hashlib, hash_name)().digest_size\n                ver_func = cert.cert_chain.getEndEntityPublicKey().verify\n\n            if not ver_func(\n                    cert_verify.signature, signature_context, pad_type,\n                    hash_name, salt_len):\n                for result in self._sendError(\n                        AlertDescription.decrypt_error,\n                        \"Signature verification failed\"):\n                    yield result\n            handshake_context.update(cert_verify.write())\n        elif self.client_cert_required:\n            for result in self._sendError(\n                    AlertDescription.certificate_required,\n                    \"Client did not provide a certificate in post-handshake \"\n                    \"authentication\"):\n                yield result\n\n        finished_key = HKDF_expand_label(self.session.cl_app_secret,\n                                         b'finished', b'',\n                                         prf_size, prf_name)\n        verify_data = secureHMAC(finished_key,\n                                 handshake_context.digest(prf_name),\n                                 prf_name)\n\n        for result in self._getMsg(ContentType.handshake,\n                                   HandshakeType.finished,\n                                   prf_size):\n            if result in (0, 1):\n                yield result\n            else:\n                break\n        assert isinstance(result, Finished)\n\n        finished = result\n\n        if finished.verify_data != verify_data:\n            for result in self._sendError(\n                    AlertDescription.decrypt_error,\n                    \"Invalid Finished verify_data from client\"):\n                yield result\n\n        self.session.clientCertChain = cert.cert_chain\n\n    def _shutdown(self, resumable):\n        self._recordLayer.shutdown()\n        self.version = (0,0)\n        self.closed = True\n        if self.closeSocket:\n            self.sock.close()\n\n        #Even if resumable is False, we'll never toggle this on\n        if not resumable and self.session:\n            self.session.resumable = False\n\n\n    def _sendError(self, alertDescription, errorStr=None):\n        # make sure that the message goes out\n        self.sock.flush()\n        self.sock.buffer_writes = False\n        alert = Alert().create(alertDescription, AlertLevel.fatal)\n        for result in self._sendMsg(alert):\n            yield result\n        self._shutdown(False)\n        raise TLSLocalAlert(alert, errorStr)\n\n    def _sendMsgs(self, msgs):\n        # send messages together in a single TCP write\n        self.sock.buffer_writes = True\n        randomizeFirstBlock = True\n        for msg in msgs:\n            for result in self._sendMsg(msg, randomizeFirstBlock):\n                yield result\n            randomizeFirstBlock = True\n        self.sock.flush()\n        self.sock.buffer_writes = False\n\n    def _sendMsg(self, msg, randomizeFirstBlock=True, update_hashes=True):\n        \"\"\"Fragment and send message through socket\"\"\"\n        #Whenever we're connected and asked to send an app data message,\n        #we first send the first byte of the message.  This prevents\n        #an attacker from launching a chosen-plaintext attack based on\n        #knowing the next IV (a la BEAST).\n        if randomizeFirstBlock and self.version <= (3, 1) \\\n                and self._recordLayer.isCBCMode() \\\n                and msg.contentType == ContentType.application_data:\n            msgFirstByte = msg.splitFirstByte()\n            for result in self._sendMsgThroughSocket(msgFirstByte):\n                yield result\n            if len(msg.write()) == 0:\n                return\n\n        buf = msg.write()\n        contentType = msg.contentType\n        #Update handshake hashes\n        if update_hashes and contentType == ContentType.handshake:\n            self._handshake_hash.update(buf)\n\n        #Fragment big messages\n        while len(buf) > self.recordSize:\n            newB = buf[:self.recordSize]\n            buf = buf[self.recordSize:]\n\n            msgFragment = Message(contentType, newB)\n            for result in self._sendMsgThroughSocket(msgFragment):\n                yield result\n\n        msgFragment = Message(contentType, buf)\n        for result in self._sendMsgThroughSocket(msgFragment):\n            yield result\n\n    def _queue_message(self, msg):\n        \"\"\"Just queue message for sending, for record layer coalescing.\"\"\"\n        if self._buffer_content_type is not None and \\\n                self._buffer_content_type != msg.contentType:\n            raise ValueError(\"Queuing of wrong message types\")\n        if self._buffer_content_type is None:\n            self._buffer_content_type = msg.contentType\n\n        serialised_msg = msg.write()\n        self._buffer += serialised_msg\n        if msg.contentType == ContentType.handshake:\n            self._handshake_hash.update(serialised_msg)\n\n    def _queue_flush(self):\n        \"\"\"Send the queued messages.\"\"\"\n        msg = Message(self._buffer_content_type, self._buffer)\n        for result in self._sendMsg(msg, update_hashes=False):\n            yield result\n        self._buffer_content_type = None\n        self._buffer = bytearray()\n\n    def _sendMsgThroughSocket(self, msg):\n        \"\"\"Send message, handle errors\"\"\"\n\n        try:\n            for result in self._recordLayer.sendRecord(msg):\n                if result in (0, 1):\n                    yield result\n        except socket.error:\n            # The socket was unexpectedly closed.  The tricky part\n            # is that there may be an alert sent by the other party\n            # sitting in the read buffer.  So, if we get here after\n            # handshaking, we will just raise the error and let the\n            # caller read more data if it would like, thus stumbling\n            # upon the error.\n            #\n            # However, if we get here DURING handshaking, we take\n            # it upon ourselves to see if the next message is an\n            # Alert.\n            if msg.contentType == ContentType.handshake:\n\n                # See if there's an alert record\n                # Could raise socket.error or TLSAbruptCloseError\n                for result in self._getNextRecord():\n                    if result in (0, 1):\n                        yield result\n                    else:\n                        break\n\n                # Closes the socket\n                self._shutdown(False)\n\n                # If we got an alert, raise it\n                recordHeader, p = result\n                if recordHeader.type == ContentType.alert:\n                    alert = Alert().parse(p)\n                    raise TLSRemoteAlert(alert)\n            else:\n                # If we got some other message who know what\n                # the remote side is doing, just go ahead and\n                # raise the socket.error\n                raise\n\n    def _getMsg(self, expectedType, secondaryType=None, constructorType=None):\n        try:\n            if not isinstance(expectedType, tuple):\n                expectedType = (expectedType,)\n\n            #Spin in a loop, until we've got a non-empty record of a type we\n            #expect.  The loop will be repeated if:\n            #  - we receive a renegotiation attempt; we send no_renegotiation,\n            #    then try again\n            #  - we receive an empty application-data fragment; we try again\n            while 1:\n                for result in self._getNextRecord():\n                    if result in (0,1):\n                        yield result\n                    else:\n                        break\n                recordHeader, p = result\n\n                # if this is a CCS message in TLS 1.3, sanity check and\n                # continue\n                if self.version > (3, 3) and \\\n                        ContentType.handshake in expectedType and \\\n                        self._middlebox_compat_mode and \\\n                        recordHeader.type == ContentType.change_cipher_spec:\n                    ccs = ChangeCipherSpec().parse(p)\n                    if ccs.type != 1:\n                        for result in self._sendError(\n                                AlertDescription.unexpected_message,\n                                \"Invalid CCS message received\"):\n                            yield result\n                    # ignore the message\n                    continue\n\n                #If we received an unexpected record type...\n                if recordHeader.type not in expectedType:\n\n                    #If we received an alert...\n                    if recordHeader.type == ContentType.alert:\n                        alert = Alert().parse(p)\n\n                        #We either received a fatal error, a warning, or a\n                        #close_notify.  In any case, we're going to close the\n                        #connection.  In the latter two cases we respond with\n                        #a close_notify, but ignore any socket errors, since\n                        #the other side might have already closed the socket.\n                        if alert.level == AlertLevel.warning or \\\n                           alert.description == AlertDescription.close_notify:\n\n                            #If the sendMsg() call fails because the socket has\n                            #already been closed, we will be forgiving and not\n                            #report the error nor invalidate the \"resumability\"\n                            #of the session.\n                            try:\n                                alertMsg = Alert()\n                                alertMsg.create(AlertDescription.close_notify,\n                                                AlertLevel.warning)\n                                for result in self._sendMsg(alertMsg):\n                                    yield result\n                            except socket.error:\n                                pass\n\n                            if alert.description == \\\n                                   AlertDescription.close_notify:\n                                self._shutdown(True)\n                            elif alert.level == AlertLevel.warning:\n                                self._shutdown(False)\n\n                        else: #Fatal alert:\n                            self._shutdown(False)\n\n                        #Raise the alert as an exception\n                        raise TLSRemoteAlert(alert)\n\n                    #If we received a renegotiation attempt...\n                    if recordHeader.type == ContentType.handshake:\n                        subType = p.get(1)\n                        reneg = False\n                        if self._client:\n                            if subType == HandshakeType.hello_request:\n                                reneg = True\n                        else:\n                            if subType == HandshakeType.client_hello:\n                                reneg = True\n                        # Send no_renegotiation if we're not negotiating\n                        # a connection now, then try again\n                        if reneg and self.session:\n                            alertMsg = Alert()\n                            alertMsg.create(AlertDescription.no_renegotiation,\n                                            AlertLevel.warning)\n                            for result in self._sendMsg(alertMsg):\n                                yield result\n                            continue\n\n                    # If we received a heartbeat request and heartbeat\n                    # extension was negotiated\n                    if recordHeader.type == ContentType.heartbeat and \\\n                            self.heartbeat_supported:\n                        try:\n                            heartbeat_message = Heartbeat().parse(p)\n                            # If we received heartbeat request, then we\n                            # response with response create from request\n                            if heartbeat_message.message_type == \\\n                                    HeartbeatMessageType.heartbeat_request:\n                                if not self.heartbeat_can_receive:\n                                    for result in self._sendError(\n                                            AlertDescription.\n                                            unexpected_message,\n                                            \"Received heartbeat_request to \"\n                                            \"peer_not_allowed_to_send mode\"):\n                                        yield result\n                                if len(heartbeat_message.padding) < 16:\n                                    # per RFC, silently ignore if the message\n                                    # is malformed\n                                    continue\n                                heartbeat_response = heartbeat_message.\\\n                                    create_response()\n                                for result in self._sendMsg(\n                                        heartbeat_response):\n                                    yield result\n                            # If we received heartbeat response, then we\n                            # check, if its payload is same as payload of\n                            # request we sent\n                            elif heartbeat_message.message_type == \\\n                                    HeartbeatMessageType.heartbeat_response \\\n                                    and self.heartbeat_response_callback:\n                                self.heartbeat_response_callback(\n                                    heartbeat_message)\n                        except (socket.error, SyntaxError):\n                            pass\n                        continue\n\n                    #Otherwise: this is an unexpected record, but neither an\n                    #alert nor renegotiation\n                    for result in self._sendError(\\\n                            AlertDescription.unexpected_message,\n                            \"received type=%d\" % recordHeader.type):\n                        yield result\n\n                #If this is an empty application-data fragment, try again\n                if recordHeader.type == ContentType.application_data:\n                    if p.index == len(p.bytes):\n                        continue\n\n                break\n\n            #Parse based on content_type\n            if recordHeader.type == ContentType.change_cipher_spec:\n                yield ChangeCipherSpec().parse(p)\n            elif recordHeader.type == ContentType.alert:\n                yield Alert().parse(p)\n            elif recordHeader.type == ContentType.application_data:\n                yield ApplicationData().parse(p)\n            elif recordHeader.type == ContentType.handshake:\n                #Convert secondaryType to tuple, if it isn't already\n                if not isinstance(secondaryType, tuple):\n                    secondaryType = (secondaryType,)\n\n                #If it's a handshake message, check handshake header\n                if recordHeader.ssl2:\n                    subType = p.get(1)\n                    if subType != HandshakeType.client_hello:\n                        for result in self._sendError(\\\n                                AlertDescription.unexpected_message,\n                                \"Can only handle SSLv2 ClientHello messages\"):\n                            yield result\n                    if HandshakeType.client_hello not in secondaryType:\n                        for result in self._sendError(\\\n                                AlertDescription.unexpected_message):\n                            yield result\n                    subType = HandshakeType.client_hello\n                else:\n                    subType = p.get(1)\n                    if subType not in secondaryType:\n                        exp = to_str_delimiter(HandshakeType.toStr(i) for i in\n                                               secondaryType)\n                        rec = HandshakeType.toStr(subType)\n                        for result in self._sendError(AlertDescription\n                                                      .unexpected_message,\n                                                      \"Expecting {0}, got {1}\"\n                                                      .format(exp, rec)):\n                            yield result\n\n                #Update handshake hashes\n                self._handshake_hash.update(p.bytes)\n\n                #Parse based on handshake type\n                if subType == HandshakeType.client_hello:\n                    yield ClientHello(recordHeader.ssl2).parse(p)\n                elif subType == HandshakeType.server_hello:\n                    yield ServerHello().parse(p)\n                elif subType == HandshakeType.certificate:\n                    yield Certificate(constructorType, self.version).parse(p)\n                elif subType == HandshakeType.compressed_certificate:\n                    yield CompressedCertificate(constructorType, self.version).parse(p)\n                elif subType == HandshakeType.certificate_request:\n                    yield CertificateRequest(self.version).parse(p)\n                elif subType == HandshakeType.certificate_verify:\n                    yield CertificateVerify(self.version).parse(p)\n                elif subType == HandshakeType.server_key_exchange:\n                    yield ServerKeyExchange(constructorType,\n                                            self.version).parse(p)\n                elif subType == HandshakeType.server_hello_done:\n                    yield ServerHelloDone().parse(p)\n                elif subType == HandshakeType.client_key_exchange:\n                    yield ClientKeyExchange(constructorType, \\\n                                            self.version).parse(p)\n                elif subType == HandshakeType.finished:\n                    yield Finished(self.version, constructorType).parse(p)\n                elif subType == HandshakeType.next_protocol:\n                    yield NextProtocol().parse(p)\n                elif subType == HandshakeType.encrypted_extensions:\n                    yield EncryptedExtensions().parse(p)\n                elif subType == HandshakeType.new_session_ticket:\n                    yield NewSessionTicket().parse(p)\n                elif subType == HandshakeType.key_update:\n                    yield KeyUpdate().parse(p)\n                else:\n                    raise AssertionError()\n\n        #If an exception was raised by a Parser or Message instance:\n        except BadCertificateError as e:\n            for result in self._sendError(AlertDescription.bad_certificate,\n                                          formatExceptionTrace(e)):\n                yield result\n        except SyntaxError as e:\n            for result in self._sendError(AlertDescription.decode_error,\n                                          formatExceptionTrace(e)):\n                yield result\n\n    #Returns next record or next handshake message\n    def _getNextRecord(self):\n        \"\"\"read next message from socket, defragment message\"\"\"\n\n        while True:\n            # support for fragmentation\n            # (RFC 5246 Section 6.2.1)\n            # Because the Record Layer is completely separate from the messages\n            # that traverse it, it should handle both application data and\n            # hadshake data in the same way. For that we buffer the handshake\n            # messages until they are completely read.\n            # This makes it possible to handle both handshake data not aligned\n            # to record boundary as well as handshakes longer than single\n            # record.\n            while True:\n                # empty message buffer\n                ret = self._defragmenter.get_message()\n                if ret is None:\n                    break\n                header = RecordHeader3().create(self.version, ret[0], 0)\n                yield header, Parser(ret[1])\n\n            # CCS can be sent before early_data but processing it will\n            # remove the flag from record layer, so reset it\n            early_data_ok = self._recordLayer.early_data_ok\n\n            # when the message buffer is empty, read next record from socket\n            for result in self._getNextRecordFromSocket():\n                if result in (0, 1):\n                    yield result\n                else:\n                    break\n\n            header, parser = result\n\n            # application data (and CCS in TLS1.3) isn't made out of messages,\n            # pass it through\n            if header.type == ContentType.application_data or \\\n                    (self.version > (3, 3) and\n                     header.type == ContentType.change_cipher_spec):\n                # CCS doesn't change the status of undecryptable\n                # records\n                if header.type == ContentType.change_cipher_spec:\n                    self._recordLayer.early_data_ok = early_data_ok\n                yield (header, parser)\n            # heartbeat message isn't made out of messages, too\n            elif header.type == ContentType.heartbeat:\n                yield (header, parser)\n            # If it's an SSLv2 ClientHello, we can return it as well, since\n            # it's the only ssl2 type we support\n            elif header.ssl2:\n                yield (header, parser)\n            else:\n                # other types need to be put into buffers\n                self._defragmenter.add_data(header.type, parser.bytes)\n\n    def _getNextRecordFromSocket(self):\n        \"\"\"Read a record, handle errors\"\"\"\n\n        try:\n            # otherwise... read the next record\n            for result in self._recordLayer.recvRecord():\n                if result in (0, 1):\n                    yield result\n                else:\n                    break\n        except TLSUnexpectedMessage:\n            for result in self._sendError(AlertDescription.unexpected_message):\n                yield result\n        except TLSRecordOverflow:\n            for result in self._sendError(AlertDescription.record_overflow):\n                yield result\n        except TLSIllegalParameterException:\n            for result in self._sendError(AlertDescription.illegal_parameter):\n                yield result\n        except TLSDecryptionFailed:\n            for result in self._sendError(\n                    AlertDescription.decryption_failed,\n                    \"Encrypted data not a multiple of blocksize\"):\n                yield result\n        except TLSBadRecordMAC:\n            for result in self._sendError(\n                    AlertDescription.bad_record_mac,\n                    \"MAC failure (or padding failure)\"):\n                yield result\n\n        header, parser = result\n\n        # RFC5246 section 6.2.1: Implementations MUST NOT send\n        # zero-length fragments of content types other than Application\n        # Data.\n        if header.type != ContentType.application_data \\\n                and parser.getRemainingLength() == 0:\n            for result in self._sendError(\n                    AlertDescription.unexpected_message,\n                    \"Received empty non-application data record\"):\n                yield result\n\n        if header.type not in ContentType.all:\n            for result in self._sendError(\\\n                    AlertDescription.unexpected_message, \\\n                    \"Received record with unknown ContentType\"):\n                yield result\n\n        yield (header, parser)\n\n    def _handshakeStart(self, client):\n        if not self.closed:\n            raise ValueError(\"Renegotiation disallowed for security reasons\")\n        self._client = client\n        self._handshake_hash = HandshakeHashes()\n        self._certificate_verify_handshake_hash = None\n        self._pre_client_hello_handshake_hash = None\n        self._defragmenter.clear_buffers()\n        self.allegedSrpUsername = None\n        self._refCount = 1\n\n    def _handshakeDone(self, resumed):\n        self.resumed = resumed\n        self.closed = False\n\n    def _calcPendingStates(self, cipherSuite, masterSecret,\n                           clientRandom, serverRandom, implementations):\n        self._recordLayer.calcPendingStates(cipherSuite, masterSecret,\n                                            clientRandom, serverRandom,\n                                            implementations)\n\n    def _changeWriteState(self):\n        self._recordLayer.changeWriteState()\n\n    def _changeReadState(self):\n        self._recordLayer.changeReadState()\n\n    def write_heartbeat(self, payload, padding_length):\n        \"\"\"Start a write operation of heartbeat_request.\n\n        :type payload: bytes\n        :param payload: Payload, that we want send in request and\n                        get at response.\n\n        :type padding_length: int\n        :param padding_length: Length of padding.\n\n        :raise socket.error: If a socket error occurs.\n        \"\"\"\n        if self.closed:\n            raise TLSClosedConnectionError(\n                \"attempt to write to closed connection\")\n        if not self.heartbeat_supported or not self.heartbeat_can_send:\n            raise TLSInternalError(\"attempt to send Heartbeat request when \"\n                                   \"we cant send it to other side\")\n        heartbeat_request = Heartbeat().create(\n            HeartbeatMessageType.heartbeat_request, payload, padding_length)\n\n        for result in self._sendMsg(heartbeat_request,\n                                    randomizeFirstBlock=False):\n            yield result\n\n    def send_heartbeat_request(self, payload, padding_length):\n        \"\"\"Synchronous version of write_heartbeat function.\n\n        :type payload: bytes\n        :param payload: Payload, that we want send in request and\n             get at response.\n\n        :type padding_length: int\n        :param padding_length: Length of padding.\n\n        :raise socket.error: If a socket error occurs.\n        \"\"\"\n        for _ in self.write_heartbeat(payload, padding_length):\n            pass\n\n    def _handle_keyupdate_request(self, request):\n        \"\"\"Process the KeyUpdate request.\n\n        :type request: KeyUpdate\n        :param request: Recieved KeyUpdate message.\n        \"\"\"\n        if request.message_type == KeyUpdateMessageType.update_not_requested or\\\n                request.message_type == KeyUpdateMessageType.update_requested:\n            self.session.cl_app_secret, self.session.sr_app_secret = self._recordLayer.\\\n                calcTLS1_3KeyUpdate_sender(\n                    self.session.cipherSuite,\n                    self.session.cl_app_secret,\n                    self.session.sr_app_secret)\n            if request.message_type == KeyUpdateMessageType.update_requested:\n                for result in self.send_keyupdate_request(\n                        KeyUpdateMessageType.update_not_requested):\n                    yield result\n        else:\n            for result in self._sendError(\n                    AlertDescription.illegal_parameter,\n                    \"Received KeyUpdate request with unknown message_type\"):\n                yield result\n\n    def send_keyupdate_request(self, message_type):\n        \"\"\"Send a KeyUpdate message.\n\n        :type payload: int\n        :param payload: Type of KeyUpdate message.\n\n        :raise socket.error: If a socket error occurs.\n        \"\"\"\n        if self.closed:\n            raise TLSClosedConnectionError(\n                \"attempt to write to closed connection\")\n        if self.version != (3, 4):\n            raise TLSIllegalParameterException(\"KeyUpdate is a TLS 1.3 specific\"\n                                               \" feature\")\n\n        keyupdate_request = KeyUpdate().create(message_type)\n        for result in self._sendMsg(keyupdate_request):\n            yield result\n        self.session.cl_app_secret, self.session.sr_app_secret = \\\n            self._recordLayer.calcTLS1_3KeyUpdate_reciever(\n                    self.session.cipherSuite,\n                    self.session.cl_app_secret,\n                    self.session.sr_app_secret)\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/__init__.py",
    "content": "# Author: Trevor Perrin\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Toolkit for crypto and other stuff.\"\"\"\n\n__all__ = [\"aes\",\n           \"asn1parser\",\n           \"cipherfactory\",\n           \"codec\",\n           \"cryptomath\",\n           \"datefuncs\",\n           \"compat\",\n           \"keyfactory\",\n           \"openssl_aes\",\n           \"openssl_rc4\",\n           \"openssl_rsakey\",\n           \"openssl_tripledes\",\n           \"pycrypto_aes\",\n           \"pycrypto_rc4\",\n           \"pycrypto_rsakey\",\n           \"pycrypto_tripledes\",\n           \"python_aes\",\n           \"python_rc4\",\n           \"python_rsakey\",\n           \"python_ecdsakey\",\n           \"python_eddsakey\",\n           \"python_dsakey\",\n           \"rc4\",\n           \"rijndael\",\n           \"rsakey\",\n           \"tackpywrapper\",\n           \"tripledes\"]\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/aes.py",
    "content": "# Author: Trevor Perrin\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Abstract class for AES.\"\"\"\n\nclass AES(object):\n    def __init__(self, key, mode, IV, implementation):\n        if len(key) not in (16, 24, 32):\n            raise AssertionError()\n        if mode not in [2, 6]:\n            raise AssertionError()\n        if mode == 2:\n            if len(IV) != 16:\n                raise AssertionError()\n        if mode == 6:\n            if len(IV) > 16:\n                raise AssertionError()\n        self.isBlockCipher = True\n        self.isAEAD = False\n        self.block_size = 16\n        self.implementation = implementation\n        if len(key)==16:\n            self.name = \"aes128\"\n        elif len(key)==24:\n            self.name = \"aes192\"\n        elif len(key)==32:\n            self.name = \"aes256\"\n        else:\n            raise AssertionError()\n\n    #CBC-Mode encryption, returns ciphertext\n    #WARNING: *MAY* modify the input as well\n    def encrypt(self, plaintext):\n        assert(len(plaintext) % 16 == 0)\n\n    #CBC-Mode decryption, returns plaintext\n    #WARNING: *MAY* modify the input as well\n    def decrypt(self, ciphertext):\n        assert(len(ciphertext) % 16 == 0)\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/aesccm.py",
    "content": "# Copyright (c) 2019 Ivan Nikolchev\n#\n# See the LICENSE file for legal information regarding use of this file.\n#\n\nfrom __future__ import division\nfrom tlslite.utils.cryptomath import numberToByteArray\nfrom tlslite.utils import python_aes\n\n\nclass AESCCM(object):\n    # AES-CCM implementation per RFC3610\n\n    def __init__(self, key, implementation, rawAesEncrypt, tag_length=16):\n        self.isBlockCipher = False\n        self.isAEAD = True\n        self.key = key\n        self.tagLength = tag_length\n        self.nonceLength = 12\n        self.implementation = implementation\n\n        if len(self.key) == 16 and self.tagLength == 8:\n            self.name = \"aes128ccm_8\"\n        elif len(self.key) == 16 and self.tagLength == 16:\n            self.name = \"aes128ccm\"\n        elif len(self.key) == 32 and self.tagLength == 8:\n            self.name = \"aes256ccm_8\"\n        else:\n            assert len(self.key) == 32 and self.tagLength == 16\n            self.name = \"aes256ccm\"\n\n        self._ctr = python_aes.new(self.key, 6, bytearray(b'\\x00' * 16))\n        self._cbc = python_aes.new(self.key, 2, bytearray(b'\\x00' * 16))\n\n\n    def _cbcmac_calc(self, nonce, aad, msg):\n        L = 15 - len(nonce)\n        mac_data = bytearray()\n\n        # Flags constructed as in section 2.2 in the rfc\n        flags = 64 * (len(aad) > 0)\n        flags += 8 * ((self.tagLength - 2) // 2)\n        flags += 1 * (L - 1)\n\n        # Construct B_0\n        b_0 = bytearray([flags]) + nonce + numberToByteArray(len(msg), L)\n\n        aad_len_encoded = bytearray()\n        if len(aad) > 0:\n            if len(aad) < (2 ** 16 - 2 ** 8):\n                oct_size = 2\n            elif len(aad) < (2 ** 32):\n                oct_size = 4\n                aad_len_encoded = b'\\xFF\\xFE'\n            else:\n                oct_size = 8\n                aad_len_encoded = b'\\xFF\\xFF'\n\n            aad_len_encoded += numberToByteArray(len(aad), oct_size)\n\n        # Construct the bytearray that goes into the MAC\n        mac_data += b_0\n        mac_data += aad_len_encoded\n        mac_data += aad\n\n        # We need to pad with zeroes before and after msg blocks are added\n        self._pad_with_zeroes(mac_data, 16)\n        if msg != b'':\n            mac_data += msg\n            self._pad_with_zeroes(mac_data, 16)\n\n        # The mac data is now constructed and\n        # we need to run in through AES-CBC with 0 IV\n\n        self._cbc.IV = bytearray(b'\\x00' * 16)\n        cbcmac = self._cbc.encrypt(mac_data)\n\n        # If the tagLength has default value 16, we return\n        # the whole last block. Otherwise we return only\n        # the first tagLength bytes from the last block\n        if self.tagLength == 16:\n            t = cbcmac[-16:]\n        else:\n            t = cbcmac[-16:-(16-self.tagLength)]\n        return t\n\n    def seal(self, nonce, msg, aad):\n\n        if len(nonce) != 12:\n            raise ValueError(\"Bad nonce length\")\n\n        L = 15 - len(nonce)\n\n        # We construct the key stream blocks.\n        # S_0 is not used for encrypting the message, it is only used\n        # to compute the authentication value.\n        # S_1..S_n are used to encrypt the message.\n\n        flags = L - 1\n        s_0 = bytearray([flags]) + nonce + numberToByteArray(0, L)\n\n        mac = self._cbcmac_calc(nonce, aad, msg)\n        self._ctr.counter = s_0\n        if self.tagLength == 16:\n            auth_value = self._ctr.encrypt(mac)\n        else:\n            assert self.tagLength == 8\n            self._pad_with_zeroes(mac, 16)\n            auth_value = self._ctr.encrypt(mac)[:8]\n        enc_msg = self._ctr.encrypt(msg)\n\n        ciphertext = enc_msg + auth_value\n        return ciphertext\n\n    def open(self, nonce, ciphertext, aad):\n\n        if len(nonce) != 12:\n            raise ValueError(\"Bad nonce length\")\n        if self.tagLength == 16 and len(ciphertext) < 16:\n            return None\n        if self.tagLength == 8 and len(ciphertext) < 8:\n            return None\n\n        L = 15 - len(nonce)\n        flags = L - 1\n\n        # Same construction as in seal function\n\n        s_0 = bytearray([flags]) + nonce + numberToByteArray(0, L)\n\n        auth_value = ciphertext[-self.tagLength:]\n\n        # We decrypt the auth value\n        self._ctr.counter = s_0\n        if self.tagLength == 16:\n            received_mac = self._ctr.decrypt(auth_value)\n        else:\n            assert self.tagLength == 8\n            self._pad_with_zeroes(auth_value, 16)\n            received_mac = self._ctr.decrypt(auth_value)[:8]\n        msg = self._ctr.decrypt(ciphertext)\n        msg = msg[:-self.tagLength]\n        computed_mac = self._cbcmac_calc(nonce, aad, msg)\n\n\n        # Compare the mac vlaue is the same as the one we computed\n        if received_mac != computed_mac:\n            return None\n        return msg\n\n    @staticmethod\n    def _pad_with_zeroes(data, size):\n        if len(data) % size != 0:\n            zeroes_to_add = size - (len(data) % size)\n            data += b'\\x00' * zeroes_to_add\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/aesgcm.py",
    "content": "# Author: Google\n# See the LICENSE file for legal information regarding use of this file.\n\n# GCM derived from Go's implementation in crypto/cipher.\n#\n# https://golang.org/src/crypto/cipher/gcm.go\n\n# GCM works over elements of the field GF(2^128), each of which is a 128-bit\n# polynomial. Throughout this implementation, polynomials are represented as\n# Python integers with the low-order terms at the most significant bits. So a\n# 128-bit polynomial is an integer from 0 to 2^128-1 with the most significant\n# bit representing the x^0 term and the least significant bit representing the\n# x^127 term. This bit reversal also applies to polynomials used as indices in a\n# look-up table.\n\nfrom __future__ import division\nfrom tlslite.utils import python_aes\nfrom .constanttime import ct_compare_digest\nfrom .cryptomath import bytesToNumber, numberToByteArray\n\nclass AESGCM(object):\n    \"\"\"\n    AES-GCM implementation. Note: this implementation does not attempt\n    to be side-channel resistant. It's also rather slow.\n    \"\"\"\n\n    def __init__(self, key, implementation, rawAesEncrypt):\n        self.isBlockCipher = False\n        self.isAEAD = True\n        self.nonceLength = 12\n        self.tagLength = 16\n        self.implementation = implementation\n        if len(key) == 16:\n            self.name = \"aes128gcm\"\n        elif len(key) == 32:\n            self.name = \"aes256gcm\"\n        else:\n            raise AssertionError()\n        self.key = key\n\n        self._rawAesEncrypt = rawAesEncrypt\n        self._ctr = python_aes.new(self.key, 6, bytearray(b'\\x00' * 16))\n\n        # The GCM key is AES(0).\n        h = bytesToNumber(self._rawAesEncrypt(bytearray(16)))\n\n        # Pre-compute all 4-bit multiples of h. Note that bits are reversed\n        # because our polynomial representation places low-order terms at the\n        # most significant bit. Thus x^0 * h = h is at index 0b1000 = 8 and\n        # x^1 * h is at index 0b0100 = 4.\n        self._productTable = [0] * 16\n        self._productTable[self._reverseBits(1)] = h\n        for i in range(2, 16, 2):\n            self._productTable[self._reverseBits(i)] = \\\n                self._gcmShift(self._productTable[self._reverseBits(i//2)])\n            self._productTable[self._reverseBits(i+1)] = \\\n                self._gcmAdd(self._productTable[self._reverseBits(i)], h)\n\n\n    def _auth(self, ciphertext, ad, tagMask):\n        y = 0\n        y = self._update(y, ad)\n        y = self._update(y, ciphertext)\n        y ^= (len(ad) << (3 + 64)) | (len(ciphertext) << 3)\n        y = self._mul(y)\n        y ^= bytesToNumber(tagMask)\n        return numberToByteArray(y, 16)\n\n    def _update(self, y, data):\n        for i in range(0, len(data) // 16):\n            y ^= bytesToNumber(data[16*i:16*i+16])\n            y = self._mul(y)\n        extra = len(data) % 16\n        if extra != 0:\n            block = bytearray(16)\n            block[:extra] = data[-extra:]\n            y ^= bytesToNumber(block)\n            y = self._mul(y)\n        return y\n\n    def _mul(self, y):\n        \"\"\" Returns y*H, where H is the GCM key. \"\"\"\n        ret = 0\n        # Multiply H by y 4 bits at a time, starting with the highest power\n        # terms.\n        for i in range(0, 128, 4):\n            # Multiply by x^4. The reduction for the top four terms is\n            # precomputed.\n            retHigh = ret & 0xf\n            ret >>= 4\n            ret ^= (AESGCM._gcmReductionTable[retHigh] << (128-16))\n\n            # Add in y' * H where y' are the next four terms of y, shifted down\n            # to the x^0..x^4. This is one of the pre-computed multiples of\n            # H. The multiplication by x^4 shifts them back into place.\n            ret ^= self._productTable[y & 0xf]\n            y >>= 4\n        assert y == 0\n        return ret\n\n    def seal(self, nonce, plaintext, data):\n        \"\"\"\n        Encrypts and authenticates plaintext using nonce and data. Returns the\n        ciphertext, consisting of the encrypted plaintext and tag concatenated.\n        \"\"\"\n\n        if len(nonce) != 12:\n            raise ValueError(\"Bad nonce length\")\n\n        # The initial counter value is the nonce, followed by a 32-bit counter\n        # that starts at 1. It's used to compute the tag mask.\n        counter = bytearray(16)\n        counter[:12] = nonce\n        counter[-1] = 1\n        tagMask = self._rawAesEncrypt(counter)\n\n        # The counter starts at 2 for the actual encryption.\n        counter[-1] = 2\n        self._ctr.counter = counter\n        ciphertext = self._ctr.encrypt(plaintext)\n\n        tag = self._auth(ciphertext, data, tagMask)\n\n        return ciphertext + tag\n\n    def open(self, nonce, ciphertext, data):\n        \"\"\"\n        Decrypts and authenticates ciphertext using nonce and data. If the\n        tag is valid, the plaintext is returned. If the tag is invalid,\n        returns None.\n        \"\"\"\n\n        if len(nonce) != 12:\n            raise ValueError(\"Bad nonce length\")\n        if len(ciphertext) < 16:\n            return None\n\n        tag = ciphertext[-16:]\n        ciphertext = ciphertext[:-16]\n\n        # The initial counter value is the nonce, followed by a 32-bit counter\n        # that starts at 1. It's used to compute the tag mask.\n        counter = bytearray(16)\n        counter[:12] = nonce\n        counter[-1] = 1\n        tagMask = self._rawAesEncrypt(counter)\n\n        if not ct_compare_digest(tag, self._auth(ciphertext, data, tagMask)):\n            return None\n\n        # The counter starts at 2 for the actual decryption.\n        counter[-1] = 2\n        self._ctr.counter = counter\n        return self._ctr.decrypt(ciphertext)\n\n    @staticmethod\n    def _reverseBits(i):\n        assert i < 16\n        i = ((i << 2) & 0xc) | ((i >> 2) & 0x3)\n        i = ((i << 1) & 0xa) | ((i >> 1) & 0x5)\n        return i\n\n    @staticmethod\n    def _gcmAdd(x, y):\n        return x ^ y\n\n    @staticmethod\n    def _gcmShift(x):\n        # Multiplying by x is a right shift, due to bit order.\n        highTermSet = x & 1\n        x >>= 1\n        if highTermSet:\n            # The x^127 term was shifted up to x^128, so subtract a 1+x+x^2+x^7\n            # term. This is 0b11100001 or 0xe1 when represented as an 8-bit\n            # polynomial.\n            x ^= 0xe1 << (128-8)\n        return x\n\n    @staticmethod\n    def _inc32(counter):\n        for i in range(len(counter)-1, len(counter)-5, -1):\n            counter[i] = (counter[i] + 1) % 256\n            if counter[i] != 0:\n                break\n        return counter\n\n    # _gcmReductionTable[i] is i * (1+x+x^2+x^7) for all 4-bit polynomials i. The\n    # result is stored as a 16-bit polynomial. This is used in the reduction step to\n    # multiply elements of GF(2^128) by x^4.\n    _gcmReductionTable = [\n        0x0000, 0x1c20, 0x3840, 0x2460, 0x7080, 0x6ca0, 0x48c0, 0x54e0,\n        0xe100, 0xfd20, 0xd940, 0xc560, 0x9180, 0x8da0, 0xa9c0, 0xb5e0,\n    ]\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/asn1parser.py",
    "content": "# Author: Trevor Perrin\n# Patch from Google adding getChildBytes()\n#\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Abstract Syntax Notation One (ASN.1) parsing\"\"\"\n\nfrom .codec import Parser\n\n\nclass ASN1Type(object):\n    \"\"\"\n    Class that represents the ASN.1 type bit octet.\n    Consists of a class (universal(0), application(1), context-specific(2)\n    or private(3)), boolean value that indicates if a type is constructed or\n    primitive and the ASN1 type itself.\n\n    :vartype bytes: bytearray\n    :ivar field: bit octet\n\n    :vartype tagClass: int\n    :ivar tagClass: type's class\n\n    :vartype isPrimitive: int\n    :ivar isPrimitive: equals to 0 if the type is primitive, 1 if not\n\n    :vartype tagId: int\n    :ivar tagId: ANS1 tag number\n    \"\"\"\n\n    def __init__(self, tag_class, is_primitive, tag_id):\n        self.tag_class = tag_class\n        self.is_primitive = is_primitive\n        self.tag_id = tag_id\n\n\nclass ASN1Parser(object):\n    \"\"\"\n    Parser and storage of ASN.1 DER encoded objects.\n\n    :vartype length: int\n    :ivar length: length of the value of the tag\n    :vartype value: bytearray\n    :ivar value: literal value of the tag\n    \"\"\"\n\n    def __init__(self, bytes):\n        \"\"\"Create an object from bytes.\n\n        :type bytes: bytearray\n        :param bytes: DER encoded ASN.1 object\n        \"\"\"\n        p = Parser(bytes)\n\n        # Get Type\n        self.type = self._parse_type(p)\n\n        #Get Length\n        self.length = self._getASN1Length(p)\n\n        #Get Value\n        self.value = p.getFixBytes(self.length)\n\n    def getChild(self, which):\n        \"\"\"\n        Return n-th child assuming that the object is a SEQUENCE.\n\n        :type which: int\n        :param which: ordinal of the child to return\n\n        :rtype: ASN1Parser\n        :returns: decoded child object\n        \"\"\"\n        return ASN1Parser(self.getChildBytes(which))\n\n    def getChildCount(self):\n        \"\"\"\n        Return number of children, assuming that the object is a SEQUENCE.\n\n        :rtype: int\n        :returns: number of children in the object\n        \"\"\"\n        p = Parser(self.value)\n        count = 0\n        while True:\n            if p.getRemainingLength() == 0:\n                break\n            p.skip_bytes(1)  # skip Type\n            length = self._getASN1Length(p)\n            p.skip_bytes(length)  # skip value\n            count += 1\n        return count\n\n    def getChildBytes(self, which):\n        \"\"\"\n        Return raw encoding of n-th child, assume self is a SEQUENCE\n\n        :type which: int\n        :param which: ordinal of the child to return\n\n        :rtype: bytearray\n        :returns: raw child object\n        \"\"\"\n        p = Parser(self.value)\n        for _ in range(which+1):\n            markIndex = p.index\n            p.skip_bytes(1)  # skip Type\n            length = self._getASN1Length(p)\n            p.skip_bytes(length)\n        return p.bytes[markIndex : p.index]\n\n    @staticmethod\n    def _getASN1Length(p):\n        \"\"\"Decode the ASN.1 DER length field\"\"\"\n        firstLength = p.get(1)\n        if firstLength <= 127:\n            return firstLength\n        else:\n            lengthLength = firstLength & 0x7F\n            return p.get(lengthLength)\n\n    @staticmethod\n    def _parse_type(parser):\n        \"\"\"Decode the ASN.1 DER type field\"\"\"\n        header = parser.get(1)\n        tag_class = (header & 0xc0) >> 6\n        tag_is_primitive = (header & 0x20) >> 5\n        tag_id = header & 0x1f\n\n        if tag_id == 0x1f:\n            tag_id = 0\n            while True:\n                value = parser.get(1)\n                tag_id += value & 0x7f\n                if not value & 0x80:\n                    break\n                tag_id <<= 7\n\n        asn1type = ASN1Type(tag_class, tag_is_primitive, tag_id)\n        return asn1type\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/chacha.py",
    "content": "# Copyright (c) 2015, Hubert Kario\n#\n# See the LICENSE file for legal information regarding use of this file.\n\"\"\"Pure Python implementation of ChaCha cipher\n\nImplementation that follows RFC 7539 closely.\n\"\"\"\n\nfrom __future__ import division\nfrom .compat import compat26Str\nimport copy\nimport struct\ntry:\n    # in Python 3 the native zip returns iterator\n    from itertools import izip\nexcept ImportError:\n    izip = zip\n\nclass ChaCha(object):\n\n    \"\"\"Pure python implementation of ChaCha cipher\"\"\"\n\n    constants = [0x61707865, 0x3320646e, 0x79622d32, 0x6b206574]\n\n    @staticmethod\n    def rotl32(v, c):\n        \"\"\"Rotate left a 32 bit integer v by c bits\"\"\"\n        return ((v << c) & 0xffffffff) | (v >> (32 - c))\n\n    @staticmethod\n    def quarter_round(x, a, b, c, d):\n        \"\"\"Perform a ChaCha quarter round\"\"\"\n        xa = x[a]\n        xb = x[b]\n        xc = x[c]\n        xd = x[d]\n\n        xa = (xa + xb) & 0xffffffff\n        xd = xd ^ xa\n        xd = ((xd << 16) & 0xffffffff | (xd >> 16))\n\n        xc = (xc + xd) & 0xffffffff\n        xb = xb ^ xc\n        xb = ((xb << 12) & 0xffffffff | (xb >> 20))\n\n        xa = (xa + xb) & 0xffffffff\n        xd = xd ^ xa\n        xd = ((xd << 8) & 0xffffffff | (xd >> 24))\n\n        xc = (xc + xd) & 0xffffffff\n        xb = xb ^ xc\n        xb = ((xb << 7) & 0xffffffff | (xb >> 25))\n\n        x[a] = xa\n        x[b] = xb\n        x[c] = xc\n        x[d] = xd\n\n    _round_mixup_box = [(0, 4, 8, 12),\n                        (1, 5, 9, 13),\n                        (2, 6, 10, 14),\n                        (3, 7, 11, 15),\n                        (0, 5, 10, 15),\n                        (1, 6, 11, 12),\n                        (2, 7, 8, 13),\n                        (3, 4, 9, 14)]\n\n    @classmethod\n    def double_round(cls, x):\n        \"\"\"Perform two rounds of ChaCha cipher\"\"\"\n        for a, b, c, d in cls._round_mixup_box:\n            xa = x[a]\n            xb = x[b]\n            xc = x[c]\n            xd = x[d]\n\n            xa = (xa + xb) & 0xffffffff\n            xd = xd ^ xa\n            xd = ((xd << 16) & 0xffffffff | (xd >> 16))\n\n            xc = (xc + xd) & 0xffffffff\n            xb = xb ^ xc\n            xb = ((xb << 12) & 0xffffffff | (xb >> 20))\n\n            xa = (xa + xb) & 0xffffffff\n            xd = xd ^ xa\n            xd = ((xd << 8) & 0xffffffff | (xd >> 24))\n\n            xc = (xc + xd) & 0xffffffff\n            xb = xb ^ xc\n            xb = ((xb << 7) & 0xffffffff | (xb >> 25))\n\n            x[a] = xa\n            x[b] = xb\n            x[c] = xc\n            x[d] = xd\n\n    @staticmethod\n    def chacha_block(key, counter, nonce, rounds):\n        \"\"\"Generate a state of a single block\"\"\"\n        state = ChaCha.constants + key + [counter] + nonce\n\n        working_state = state[:]\n        dbl_round = ChaCha.double_round\n        for _ in range(0, rounds // 2):\n            dbl_round(working_state)\n\n        return [(st + wrkSt) & 0xffffffff for st, wrkSt\n                in izip(state, working_state)]\n\n    @staticmethod\n    def word_to_bytearray(state):\n        \"\"\"Convert state to little endian bytestream\"\"\"\n        return bytearray(struct.pack('<LLLLLLLLLLLLLLLL', *state))\n\n    @staticmethod\n    def _bytearray_to_words(data):\n        \"\"\"Convert a bytearray to array of word sized ints\"\"\"\n        ret = []\n        for i in range(0, len(data)//4):\n            ret.extend(struct.unpack('<L',\n                                     compat26Str(data[i*4:(i+1)*4])))\n        return ret\n\n    def __init__(self, key, nonce, counter=0, rounds=20):\n        \"\"\"Set the initial state for the ChaCha cipher\"\"\"\n        if len(key) != 32:\n            raise ValueError(\"Key must be 256 bit long\")\n        if len(nonce) != 12:\n            raise ValueError(\"Nonce must be 96 bit long\")\n        self.key = []\n        self.nonce = []\n        self.counter = counter\n        self.rounds = rounds\n\n        # convert bytearray key and nonce to little endian 32 bit unsigned ints\n        self.key = ChaCha._bytearray_to_words(key)\n        self.nonce = ChaCha._bytearray_to_words(nonce)\n\n    def encrypt(self, plaintext):\n        \"\"\"Encrypt the data\"\"\"\n        encrypted_message = bytearray()\n        for i, block in enumerate(plaintext[i:i+64] for i\n                                  in range(0, len(plaintext), 64)):\n            key_stream = ChaCha.chacha_block(self.key,\n                                             self.counter + i,\n                                             self.nonce,\n                                             self.rounds)\n            key_stream = ChaCha.word_to_bytearray(key_stream)\n            encrypted_message += bytearray(x ^ y for x, y\n                                           in izip(key_stream, block))\n\n        return encrypted_message\n\n    def decrypt(self, ciphertext):\n        \"\"\"Decrypt the data\"\"\"\n        return self.encrypt(ciphertext)\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/chacha20_poly1305.py",
    "content": "# Copyright (c) 2015, Hubert Kario\n#\n# See the LICENSE file for legal information regarding use of this file.\n\"\"\"Pure Python implementation of ChaCha20/Poly1305 AEAD cipher\n\nImplementation that follows RFC 7539 and draft-ietf-tls-chacha20-poly1305-00\n\"\"\"\n\nfrom __future__ import division\nfrom .constanttime import ct_compare_digest\nfrom .chacha import ChaCha\nfrom .poly1305 import Poly1305\nimport struct\n\nclass CHACHA20_POLY1305(object):\n\n    \"\"\"Pure python implementation of ChaCha20/Poly1305 AEAD cipher\"\"\"\n\n    def __init__(self, key, implementation):\n        \"\"\"Set the initial state for the ChaCha20 AEAD\"\"\"\n        if len(key) != 32:\n            raise ValueError(\"Key must be 256 bit long\")\n        if implementation != \"python\":\n            raise ValueError(\"Implementations other then python unsupported\")\n\n        self.isBlockCipher = False\n        self.isAEAD = True\n        self.nonceLength = 12\n        self.tagLength = 16\n        self.implementation = implementation\n        self.name = \"chacha20-poly1305\"\n        self.key = key\n\n    @staticmethod\n    def poly1305_key_gen(key, nonce):\n        \"\"\"Generate the key for the Poly1305 authenticator\"\"\"\n        poly = ChaCha(key, nonce)\n        return poly.encrypt(bytearray(32))\n\n    @staticmethod\n    def pad16(data):\n        \"\"\"Return padding for the Associated Authenticated Data\"\"\"\n        if len(data) % 16 == 0:\n            return bytearray(0)\n        else:\n            return bytearray(16-(len(data)%16))\n\n    def seal(self, nonce, plaintext, data):\n        \"\"\"\n        Encrypts and authenticates plaintext using nonce and data. Returns the\n        ciphertext, consisting of the encrypted plaintext and tag concatenated.\n        \"\"\"\n        if len(nonce) != 12:\n            raise ValueError(\"Nonce must be 96 bit large\")\n\n        otk = self.poly1305_key_gen(self.key, nonce)\n\n        ciphertext = ChaCha(self.key, nonce, counter=1).encrypt(plaintext)\n\n        mac_data = data + self.pad16(data)\n        mac_data += ciphertext + self.pad16(ciphertext)\n        mac_data += struct.pack('<Q', len(data))\n        mac_data += struct.pack('<Q', len(ciphertext))\n        tag = Poly1305(otk).create_tag(mac_data)\n\n        return ciphertext + tag\n\n    def open(self, nonce, ciphertext, data):\n        \"\"\"\n        Decrypts and authenticates ciphertext using nonce and data. If the\n        tag is valid, the plaintext is returned. If the tag is invalid,\n        returns None.\n        \"\"\"\n        if len(nonce) != 12:\n            raise ValueError(\"Nonce must be 96 bit long\")\n\n        if len(ciphertext) < 16:\n            return None\n\n        expected_tag = ciphertext[-16:]\n        ciphertext = ciphertext[:-16]\n\n        otk = self.poly1305_key_gen(self.key, nonce)\n\n        mac_data = data + self.pad16(data)\n        mac_data += ciphertext + self.pad16(ciphertext)\n        mac_data += struct.pack('<Q', len(data))\n        mac_data += struct.pack('<Q', len(ciphertext))\n        tag = Poly1305(otk).create_tag(mac_data)\n\n        if not ct_compare_digest(tag, expected_tag):\n            return None\n\n        return ChaCha(self.key, nonce, counter=1).decrypt(ciphertext)\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/cipherfactory.py",
    "content": "# Author: Trevor Perrin\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Factory functions for symmetric cryptography.\"\"\"\n\nimport os\n\nfrom tlslite.utils import python_aes\nfrom tlslite.utils import python_aesgcm\nfrom tlslite.utils import python_aesccm\nfrom tlslite.utils import python_chacha20_poly1305\nfrom tlslite.utils import python_rc4\nfrom tlslite.utils import python_tripledes\nfrom tlslite.utils import openssl_aesccm\nfrom tlslite.utils import openssl_aesgcm\n\nfrom tlslite.utils import cryptomath\n\ntripleDESPresent = True\n\"\"\"Inform if the 3DES algorithm is supported.\"\"\"\n\nif cryptomath.m2cryptoLoaded:\n    from tlslite.utils import openssl_aes\n    from tlslite.utils import openssl_rc4\n    from tlslite.utils import openssl_tripledes\n\nif cryptomath.pycryptoLoaded:\n    from tlslite.utils import pycrypto_aes\n    from tlslite.utils import pycrypto_aesgcm\n    from tlslite.utils import pycrypto_rc4\n    from tlslite.utils import pycrypto_tripledes\n\n# **************************************************************************\n# Factory Functions for AES\n# **************************************************************************\n\ndef createAES(key, IV, implList=None):\n    \"\"\"Create a new AES object.\n\n    :type key: str\n    :param key: A 16, 24, or 32 byte string.\n\n    :type IV: str\n    :param IV: A 16 byte string\n\n    :rtype: tlslite.utils.AES\n    :returns: An AES object.\n    \"\"\"\n    if implList is None:\n        implList = [\"openssl\", \"pycrypto\", \"python\"]\n\n    for impl in implList:\n        if impl == \"openssl\" and cryptomath.m2cryptoLoaded:\n            return openssl_aes.new(key, 2, IV)\n        elif impl == \"pycrypto\" and cryptomath.pycryptoLoaded:\n            return pycrypto_aes.new(key, 2, IV)\n        elif impl == \"python\":\n                return python_aes.new(key, 2, IV)\n    raise NotImplementedError()\n\ndef createAESCTR(key, IV, implList=None):\n    \"\"\"Create a new AESCTR object.\n\n    :type key: str\n    :param key: A 16, 24, or 32 byte string.\n\n    :type IV: str\n    :param IV: A 8 or 12 byte string\n\n    :rtype: tlslite.utils.AES\n    :returns: An AES object.\n    \"\"\"\n    if implList is None:\n        implList = [\"python\"]\n\n    for impl in implList:\n        if impl == \"python\":\n            return python_aes.new(key, 6, IV)\n    raise NotImplementedError()\n\ndef createAESGCM(key, implList=None):\n    \"\"\"Create a new AESGCM object.\n\n    :type key: bytearray\n    :param key: A 16 or 32 byte byte array.\n\n    :rtype: tlslite.utils.AESGCM\n    :returns: An AESGCM object.\n    \"\"\"\n    if implList is None:\n        implList = [\"openssl\", \"pycrypto\", \"python\"]\n\n    for impl in implList:\n        if impl == \"openssl\" and cryptomath.m2cryptoLoaded:\n            return openssl_aesgcm.new(key)\n        if impl == \"pycrypto\" and cryptomath.pycryptoLoaded:\n            return pycrypto_aesgcm.new(key)\n        if impl == \"python\":\n            return python_aesgcm.new(key)\n    raise NotImplementedError()\n\ndef createAESCCM(key, implList=None):\n    \"\"\" Create a new AESCCM object.\n\n    :type key: bytearray\n    :param key: A 16 or 32 byte byte array to serve as key.\n\n    :rtype: tlslite.utils.AESCCM\n    :returns: An AESCCM object.\n    \"\"\"\n\n    if implList is None:\n        implList = [\"openssl\", \"python\"]\n\n    for impl in implList:\n        if impl == \"openssl\" and cryptomath.m2cryptoLoaded:\n            return openssl_aesccm.new(key)\n        if impl == \"python\":\n            return python_aesccm.new(key)\n\n    raise NotImplementedError()\n\ndef createAESCCM_8(key, implList=None):\n    \"\"\" Create a new AESCCM object with truncated tag.\n\n    :type key: bytearray\n    :param key: A 16 or 32 byte byte array to serve as key.\n\n    :rtype: tlslite.utils.AESCCM\n    :returns: An AESCCM object.\n    \"\"\"\n\n    if implList is None:\n        implList = [\"openssl\", \"python\"]\n\n    for impl in implList:\n        if impl == \"openssl\" and cryptomath.m2cryptoLoaded:\n            return openssl_aesccm.new(key, 8)\n        if impl == \"python\":\n            return python_aesccm.new(key, 8)\n\n    raise NotImplementedError()\n\ndef createCHACHA20(key, implList=None):\n    \"\"\"Create a new CHACHA20_POLY1305 object.\n\n    :type key: bytearray\n    :param key: a 32 byte array to serve as key\n\n    :rtype: tlslite.utils.CHACHA20_POLY1305\n    :returns: A ChaCha20/Poly1305 object\n    \"\"\"\n    if implList is None:\n        implList = [\"python\"]\n\n    for impl in implList:\n        if impl == \"python\":\n            return python_chacha20_poly1305.new(key)\n    raise NotImplementedError()\n\ndef createRC4(key, IV, implList=None):\n    \"\"\"Create a new RC4 object.\n\n    :type key: str\n    :param key: A 16 to 32 byte string.\n\n    :type IV: object\n    :param IV: Ignored, whatever it is.\n\n    :rtype: tlslite.utils.RC4\n    :returns: An RC4 object.\n    \"\"\"\n    if implList is None:\n        implList = [\"openssl\", \"pycrypto\", \"python\"]\n\n    if len(IV) != 0:\n        raise AssertionError()\n    for impl in implList:\n        if impl == \"openssl\" and cryptomath.m2cryptoLoaded:\n            return openssl_rc4.new(key)\n        elif impl == \"pycrypto\" and cryptomath.pycryptoLoaded:\n            return pycrypto_rc4.new(key)\n        elif impl == \"python\":\n            return python_rc4.new(key)\n    raise NotImplementedError()\n\n#Create a new TripleDES instance\ndef createTripleDES(key, IV, implList=None):\n    \"\"\"Create a new 3DES object.\n\n    :type key: str\n    :param key: A 24 byte string.\n\n    :type IV: str\n    :param IV: An 8 byte string\n\n    :rtype: tlslite.utils.TripleDES\n    :returns: A 3DES object.\n    \"\"\"\n    if implList is None:\n        implList = [\"openssl\", \"pycrypto\", \"python\"]\n\n    for impl in implList:\n        if impl == \"openssl\" and cryptomath.m2cryptoLoaded:\n            return openssl_tripledes.new(key, 2, IV)\n        elif impl == \"pycrypto\" and cryptomath.pycryptoLoaded:\n            return pycrypto_tripledes.new(key, 2, IV)\n        elif impl == \"python\":\n            return python_tripledes.new(key, IV)\n    raise NotImplementedError()\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/codec.py",
    "content": "# Author: Trevor Perrin\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Classes for reading/writing binary data (such as TLS records).\"\"\"\n\nfrom __future__ import division\n\nimport sys\nimport struct\nfrom struct import pack\nfrom .compat import bytes_to_int\n\n\nclass DecodeError(SyntaxError):\n    \"\"\"Exception raised in case of decoding errors.\"\"\"\n    pass\n\n\nclass BadCertificateError(SyntaxError):\n    \"\"\"Exception raised in case of bad certificate.\"\"\"\n    pass\n\n\nclass Writer(object):\n    \"\"\"Serialisation helper for complex byte-based structures.\"\"\"\n\n    def __init__(self):\n        \"\"\"Initialise the serializer with no data.\"\"\"\n        self.bytes = bytearray(0)\n\n    def addOne(self, val):\n        \"\"\"Add a single-byte wide element to buffer, see add().\"\"\"\n        self.bytes.append(val)\n\n    if sys.version_info < (2, 7):\n        # struct.pack on Python2.6 does not raise exception if the value\n        # is larger than can fit inside the specified size\n        def addTwo(self, val):\n            \"\"\"Add a double-byte wide element to buffer, see add().\"\"\"\n            if not 0 <= val <= 0xffff:\n                raise ValueError(\"Can't represent value in specified length\")\n            self.bytes += pack('>H', val)\n\n        def addThree(self, val):\n            \"\"\"Add a three-byte wide element to buffer, see add().\"\"\"\n            if not 0 <= val <= 0xffffff:\n                raise ValueError(\"Can't represent value in specified length\")\n            self.bytes += pack('>BH', val >> 16, val & 0xffff)\n\n        def addFour(self, val):\n            \"\"\"Add a four-byte wide element to buffer, see add().\"\"\"\n            if not 0 <= val <= 0xffffffff:\n                raise ValueError(\"Can't represent value in specified length\")\n            self.bytes += pack('>I', val)\n    else:\n        def addTwo(self, val):\n            \"\"\"Add a double-byte wide element to buffer, see add().\"\"\"\n            try:\n                self.bytes += pack('>H', val)\n            except struct.error:\n                raise ValueError(\"Can't represent value in specified length\")\n\n        def addThree(self, val):\n            \"\"\"Add a three-byte wide element to buffer, see add().\"\"\"\n            try:\n                self.bytes += pack('>BH', val >> 16, val & 0xffff)\n            except struct.error:\n                raise ValueError(\"Can't represent value in specified length\")\n\n        def addFour(self, val):\n            \"\"\"Add a four-byte wide element to buffer, see add().\"\"\"\n            try:\n                self.bytes += pack('>I', val)\n            except struct.error:\n                raise ValueError(\"Can't represent value in specified length\")\n\n    if sys.version_info >= (3, 0):\n        # the method is called thousands of times, so it's better to extern\n        # the version info check\n        def add(self, x, length):\n            \"\"\"\n            Add a single positive integer value x, encode it in length bytes\n\n            Encode positive integer x in big-endian format using length bytes,\n            add to the internal buffer.\n\n            :type x: int\n            :param x: value to encode\n\n            :type length: int\n            :param length: number of bytes to use for encoding the value\n            \"\"\"\n            try:\n                self.bytes += x.to_bytes(length, 'big')\n            except OverflowError:\n                raise ValueError(\"Can't represent value in specified length\")\n    else:\n        _addMethods = {1: addOne, 2: addTwo, 3: addThree, 4: addFour}\n\n        def add(self, x, length):\n            \"\"\"\n            Add a single positive integer value x, encode it in length bytes\n\n            Encode positive iteger x in big-endian format using length bytes,\n            add to the internal buffer.\n\n            :type x: int\n            :param x: value to encode\n\n            :type length: int\n            :param length: number of bytes to use for encoding the value\n            \"\"\"\n            try:\n                self._addMethods[length](self, x)\n            except KeyError:\n                self.bytes += bytearray(length)\n                newIndex = len(self.bytes) - 1\n                for i in range(newIndex, newIndex - length, -1):\n                    self.bytes[i] = x & 0xFF\n                    x >>= 8\n                if x != 0:\n                    raise ValueError(\"Can't represent value in specified \"\n                                     \"length\")\n\n    def addFixSeq(self, seq, length):\n        \"\"\"\n        Add a list of items, encode every item in length bytes\n\n        Uses the unbounded iterable seq to produce items, each of\n        which is then encoded to length bytes\n\n        :type seq: iterable of int\n        :param seq: list of positive integers to encode\n\n        :type length: int\n        :param length: number of bytes to which encode every element\n        \"\"\"\n        for e in seq:\n            self.add(e, length)\n\n    if sys.version_info < (2, 7):\n        # struct.pack on Python2.6 does not raise exception if the value\n        # is larger than can fit inside the specified size\n        def _addVarSeqTwo(self, seq):\n            \"\"\"Helper method for addVarSeq\"\"\"\n            if not all(0 <= i <= 0xffff for i in seq):\n                raise ValueError(\"Can't represent value in specified \"\n                                 \"length\")\n            self.bytes += pack('>' + 'H' * len(seq), *seq)\n\n        def addVarSeq(self, seq, length, lengthLength):\n            \"\"\"\n            Add a bounded list of same-sized values\n\n            Create a list of specific length with all items being of the same\n            size\n\n            :type seq: list of int\n            :param seq: list of positive integers to encode\n\n            :type length: int\n            :param length: amount of bytes in which to encode every item\n\n            :type lengthLength: int\n            :param lengthLength: amount of bytes in which to encode the overall\n                length of the array\n            \"\"\"\n            self.add(len(seq)*length, lengthLength)\n            if length == 1:\n                self.bytes.extend(seq)\n            elif length == 2:\n                self._addVarSeqTwo(seq)\n            else:\n                for i in seq:\n                    self.add(i, length)\n    else:\n        def addVarSeq(self, seq, length, lengthLength):\n            \"\"\"\n            Add a bounded list of same-sized values\n\n            Create a list of specific length with all items being of the same\n            size\n\n            :type seq: list of int\n            :param seq: list of positive integers to encode\n\n            :type length: int\n            :param length: amount of bytes in which to encode every item\n\n            :type lengthLength: int\n            :param lengthLength: amount of bytes in which to encode the overall\n                length of the array\n            \"\"\"\n            seqLen = len(seq)\n            self.add(seqLen*length, lengthLength)\n            if length == 1:\n                self.bytes.extend(seq)\n            elif length == 2:\n                try:\n                    self.bytes += pack('>' + 'H' * seqLen, *seq)\n                except struct.error:\n                    raise ValueError(\"Can't represent value in specified \"\n                                     \"length\")\n            else:\n                for i in seq:\n                    self.add(i, length)\n\n    def addVarTupleSeq(self, seq, length, lengthLength):\n        \"\"\"\n        Add a variable length list of same-sized element tuples.\n\n        Note that all tuples must have the same size.\n\n        Inverse of Parser.getVarTupleList()\n\n        :type seq: enumerable\n        :param seq: list of tuples\n\n        :type length: int\n        :param length: length of single element in tuple\n\n        :type lengthLength: int\n        :param lengthLength: length in bytes of overall length field\n        \"\"\"\n        if not seq:\n            self.add(0, lengthLength)\n        else:\n            startPos = len(self.bytes)\n            dataLength = len(seq) * len(seq[0]) * length\n            self.add(dataLength, lengthLength)\n            # since at the time of writing, all the calls encode single byte\n            # elements, and it's very easy to speed up that case, give it\n            # special case\n            if length == 1:\n                for elemTuple in seq:\n                    self.bytes.extend(elemTuple)\n            else:\n                for elemTuple in seq:\n                    self.addFixSeq(elemTuple, length)\n            if startPos + dataLength + lengthLength != len(self.bytes):\n                raise ValueError(\"Tuples of different lengths\")\n\n    def add_var_bytes(self, data, length_length):\n        \"\"\"\n        Add a variable length array of bytes.\n\n        Inverse of Parser.getVarBytes()\n\n        :type data: bytes\n        :param data: bytes to add to the buffer\n\n        :param int length_length: size of the field to represent the length\n            of the data string\n        \"\"\"\n        length = len(data)\n        self.add(length, length_length)\n        self.bytes += data\n\n\nclass Parser(object):\n    \"\"\"\n    Parser for TLV and LV byte-based encodings.\n\n    Parser that can handle arbitrary byte-based encodings usually employed in\n    Type-Length-Value or Length-Value binary encoding protocols like ASN.1\n    or TLS\n\n    Note: if the raw bytes don't match expected values (like trying to\n    read a 4-byte integer from a 2-byte buffer), most methods will raise a\n    DecodeError exception.\n\n    TODO: don't use an exception used by language parser to indicate errors\n    in application code.\n\n    :vartype bytes: bytearray\n    :ivar bytes: data to be interpreted (buffer)\n\n    :vartype index: int\n    :ivar index: current position in the buffer\n\n    :vartype lengthCheck: int\n    :ivar lengthCheck: size of struct being parsed\n\n    :vartype indexCheck: int\n    :ivar indexCheck: position at which the structure begins in buffer\n    \"\"\"\n\n    def __init__(self, bytes):\n        \"\"\"\n        Bind raw bytes with parser.\n\n        :type bytes: bytearray\n        :param bytes: bytes to be parsed/interpreted\n        \"\"\"\n        self.bytes = bytes\n        self.index = 0\n        self.indexCheck = 0\n        self.lengthCheck = 0\n\n    def get(self, length):\n        \"\"\"\n        Read a single big-endian integer value encoded in 'length' bytes.\n\n        :type length: int\n        :param length: number of bytes in which the value is encoded in\n\n        :rtype: int\n        \"\"\"\n        ret = self.getFixBytes(length)\n        return bytes_to_int(ret, 'big')\n\n    def getFixBytes(self, lengthBytes):\n        \"\"\"\n        Read a string of bytes encoded in 'lengthBytes' bytes.\n\n        :type lengthBytes: int\n        :param lengthBytes: number of bytes to return\n\n        :rtype: bytearray\n        \"\"\"\n        end = self.index + lengthBytes\n        if end > len(self.bytes):\n            raise DecodeError(\"Read past end of buffer\")\n        ret = self.bytes[self.index : end]\n        self.index += lengthBytes\n        return ret\n\n    def skip_bytes(self, length):\n        \"\"\"Move the internal pointer ahead length bytes.\"\"\"\n        if self.index + length > len(self.bytes):\n            raise DecodeError(\"Read past end of buffer\")\n        self.index += length\n\n    def getVarBytes(self, lengthLength):\n        \"\"\"\n        Read a variable length string with a fixed length.\n\n        see Writer.add_var_bytes() for an inverse of this method\n\n        :type lengthLength: int\n        :param lengthLength: number of bytes in which the length of the string\n            is encoded in\n\n        :rtype: bytearray\n        \"\"\"\n        lengthBytes = self.get(lengthLength)\n        return self.getFixBytes(lengthBytes)\n\n    def getFixList(self, length, lengthList):\n        \"\"\"\n        Read a list of static length with same-sized ints.\n\n        :type length: int\n        :param length: size in bytes of a single element in list\n\n        :type lengthList: int\n        :param lengthList: number of elements in list\n\n        :rtype: list of int\n        \"\"\"\n        l = [0] * lengthList\n        for x in range(lengthList):\n            l[x] = self.get(length)\n        return l\n\n    def getVarList(self, length, lengthLength):\n        \"\"\"\n        Read a variable length list of same-sized integers.\n\n        :type length: int\n        :param length: size in bytes of a single element\n\n        :type lengthLength: int\n        :param lengthLength: size of the encoded length of the list\n\n        :rtype: list of int\n        \"\"\"\n        lengthList = self.get(lengthLength)\n        if lengthList % length != 0:\n            raise DecodeError(\"Encoded length not a multiple of element \"\n                              \"length\")\n        lengthList = lengthList // length\n        l = [0] * lengthList\n        for x in range(lengthList):\n            l[x] = self.get(length)\n        return l\n\n    def getVarTupleList(self, elemLength, elemNum, lengthLength):\n        \"\"\"\n        Read a variable length list of same sized tuples.\n\n        :type elemLength: int\n        :param elemLength: length in bytes of single tuple element\n\n        :type elemNum: int\n        :param elemNum: number of elements in tuple\n\n        :type lengthLength: int\n        :param lengthLength: length in bytes of the list length variable\n\n        :rtype: list of tuple of int\n        \"\"\"\n        lengthList = self.get(lengthLength)\n        if lengthList % (elemLength * elemNum) != 0:\n            raise DecodeError(\"Encoded length not a multiple of element \"\n                              \"length\")\n        tupleCount = lengthList // (elemLength * elemNum)\n        tupleList = []\n        for _ in range(tupleCount):\n            currentTuple = []\n            for _ in range(elemNum):\n                currentTuple.append(self.get(elemLength))\n            tupleList.append(tuple(currentTuple))\n        return tupleList\n\n    def startLengthCheck(self, lengthLength):\n        \"\"\"\n        Read length of struct and start a length check for parsing.\n\n        :type lengthLength: int\n        :param lengthLength: number of bytes in which the length is encoded\n        \"\"\"\n        self.lengthCheck = self.get(lengthLength)\n        self.indexCheck = self.index\n\n    def setLengthCheck(self, length):\n        \"\"\"\n        Set length of struct and start a length check for parsing.\n\n        :type length: int\n        :param length: expected size of parsed struct in bytes\n        \"\"\"\n        self.lengthCheck = length\n        self.indexCheck = self.index\n\n    def stopLengthCheck(self):\n        \"\"\"\n        Stop struct parsing, verify that no under- or overflow occurred.\n\n        In case the expected length was mismatched with actual length of\n        processed data, raises an exception.\n        \"\"\"\n        if (self.index - self.indexCheck) != self.lengthCheck:\n            raise DecodeError(\"Under- or over-flow while reading buffer\")\n\n    def atLengthCheck(self):\n        \"\"\"\n        Check if there is data in structure left for parsing.\n\n        Returns True if the whole structure was parsed, False if there is\n        some data left.\n\n        Will raise an exception if overflow occured (amount of data read was\n        greater than expected size)\n        \"\"\"\n        if (self.index - self.indexCheck) < self.lengthCheck:\n            return False\n        elif (self.index - self.indexCheck) == self.lengthCheck:\n            return True\n        else:\n            raise DecodeError(\"Read past end of buffer\")\n\n    def getRemainingLength(self):\n        \"\"\"Return amount of data remaining in struct being parsed.\"\"\"\n        return len(self.bytes) - self.index\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/compat.py",
    "content": "# Author: Trevor Perrin\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Miscellaneous functions to mask Python version differences.\"\"\"\n\nimport sys\nimport re\nimport os\nimport platform\nimport math\nimport binascii\nimport traceback\nimport time\nimport ecdsa\n\nif sys.version_info >= (3,0):\n\n    def compat26Str(x): return x\n\n    # Python 3.3 requires bytes instead of bytearrays for HMAC\n    # So, python 2.6 requires strings, python 3 requires 'bytes',\n    # and python 2.7 and 3.5 can handle bytearrays...\n    # pylint: disable=invalid-name\n    # we need to keep compatHMAC and `x` for API compatibility\n    if sys.version_info < (3, 4):\n        def compatHMAC(x):\n            \"\"\"Convert bytes-like input to format acceptable for HMAC.\"\"\"\n            return bytes(x)\n    else:\n        def compatHMAC(x):\n            \"\"\"Convert bytes-like input to format acceptable for HMAC.\"\"\"\n            return x\n    # pylint: enable=invalid-name\n\n    def compatAscii2Bytes(val):\n        \"\"\"Convert ASCII string to bytes.\"\"\"\n        if isinstance(val, str):\n            return bytes(val, 'ascii')\n        return val\n\n    def compat_b2a(val):\n        \"\"\"Convert an ASCII bytes string to string.\"\"\"\n        return str(val, 'ascii')\n\n    def raw_input(s):\n        return input(s)\n    \n    # So, the python3 binascii module deals with bytearrays, and python2\n    # deals with strings...  I would rather deal with the \"a\" part as\n    # strings, and the \"b\" part as bytearrays, regardless of python version,\n    # so...\n    def a2b_hex(s):\n        try:\n            b = bytearray(binascii.a2b_hex(bytearray(s, \"ascii\")))\n        except Exception as e:\n            raise SyntaxError(\"base16 error: %s\" % e) \n        return b  \n\n    def a2b_base64(s):\n        try:\n            if isinstance(s, str):\n                s = bytearray(s, \"ascii\")\n            b = bytearray(binascii.a2b_base64(s))\n        except Exception as e:\n            raise SyntaxError(\"base64 error: %s\" % e)\n        return b\n\n    def b2a_hex(b):\n        return binascii.b2a_hex(b).decode(\"ascii\")    \n            \n    def b2a_base64(b):\n        return binascii.b2a_base64(b).decode(\"ascii\") \n\n    def readStdinBinary():\n        return sys.stdin.buffer.read()        \n\n    def compatLong(num):\n        return int(num)\n\n    int_types = tuple([int])\n\n    def formatExceptionTrace(e):\n        \"\"\"Return exception information formatted as string\"\"\"\n        return str(e)\n\n    def time_stamp():\n        \"\"\"Returns system time as a float\"\"\"\n        if sys.version_info >= (3, 3):\n            return time.perf_counter()\n        return time.clock()\n\n    def remove_whitespace(text):\n        \"\"\"Removes all whitespace from passed in string\"\"\"\n        return re.sub(r\"\\s+\", \"\", text, flags=re.UNICODE)\n\n    # pylint: disable=invalid-name\n    # pylint is stupid here and deson't notice it's a function, not\n    # constant\n    bytes_to_int = int.from_bytes\n    # pylint: enable=invalid-name\n\n    def bit_length(val):\n        \"\"\"Return number of bits necessary to represent an integer.\"\"\"\n        return val.bit_length()\n\n    def int_to_bytes(val, length=None, byteorder=\"big\"):\n        \"\"\"Return number converted to bytes\"\"\"\n        if length is None:\n            length = byte_length(val)\n        # for gmpy we need to convert back to native int\n        if type(val) != int:\n            val = int(val)\n        return bytearray(val.to_bytes(length=length, byteorder=byteorder))\n\nelse:\n    # Python 2.6 requires strings instead of bytearrays in a couple places,\n    # so we define this function so it does the conversion if needed.\n    # same thing with very old 2.7 versions\n    # or on Jython\n    if sys.version_info < (2, 7) or sys.version_info < (2, 7, 4) \\\n            or platform.system() == 'Java':\n        def compat26Str(x): return str(x)\n\n        def remove_whitespace(text):\n            \"\"\"Removes all whitespace from passed in string\"\"\"\n            return re.sub(r\"\\s+\", \"\", text)\n\n        def bit_length(val):\n            \"\"\"Return number of bits necessary to represent an integer.\"\"\"\n            if val == 0:\n                return 0\n            return len(bin(val))-2\n    else:\n        def compat26Str(x): return x\n\n        def remove_whitespace(text):\n            \"\"\"Removes all whitespace from passed in string\"\"\"\n            return re.sub(r\"\\s+\", \"\", text, flags=re.UNICODE)\n\n        def bit_length(val):\n            \"\"\"Return number of bits necessary to represent an integer.\"\"\"\n            return val.bit_length()\n\n    def compatAscii2Bytes(val):\n        \"\"\"Convert ASCII string to bytes.\"\"\"\n        return val\n\n    def compat_b2a(val):\n        \"\"\"Convert an ASCII bytes string to string.\"\"\"\n        return str(val)\n\n    # So, python 2.6 requires strings, python 3 requires 'bytes',\n    # and python 2.7 can handle bytearrays...     \n    def compatHMAC(x): return compat26Str(x)\n\n    def a2b_hex(s):\n        try:\n            b = bytearray(binascii.a2b_hex(s))\n        except Exception as e:\n            raise SyntaxError(\"base16 error: %s\" % e)\n        return b\n\n    def a2b_base64(s):\n        try:\n            b = bytearray(binascii.a2b_base64(s))\n        except Exception as e:\n            raise SyntaxError(\"base64 error: %s\" % e)\n        return b\n        \n    def b2a_hex(b):\n        return binascii.b2a_hex(compat26Str(b))\n        \n    def b2a_base64(b):\n        return binascii.b2a_base64(compat26Str(b))\n\n    def compatLong(num):\n        return long(num)\n\n    int_types = (int, long)\n\n    # pylint on Python3 goes nuts for the sys dereferences...\n\n    #pylint: disable=no-member\n    def formatExceptionTrace(e):\n        \"\"\"Return exception information formatted as string\"\"\"\n        newStr = \"\".join(traceback.format_exception(sys.exc_type,\n                                                    sys.exc_value,\n                                                    sys.exc_traceback))\n        return newStr\n    #pylint: enable=no-member\n\n    def time_stamp():\n        \"\"\"Returns system time as a float\"\"\"\n        return time.clock()\n\n    def bytes_to_int(val, byteorder):\n        \"\"\"Convert bytes to an int.\"\"\"\n        if not val:\n            return 0\n        if byteorder == \"big\":\n            return int(b2a_hex(val), 16)\n        if byteorder == \"little\":\n            return int(b2a_hex(val[::-1]), 16)\n        raise ValueError(\"Only 'big' and 'little' endian supported\")\n\n    def int_to_bytes(val, length=None, byteorder=\"big\"):\n        \"\"\"Return number converted to bytes\"\"\"\n        if length is None:\n            length = byte_length(val)\n        if byteorder == \"big\":\n            return bytearray((val >> i) & 0xff\n                             for i in reversed(range(0, length*8, 8)))\n        if byteorder == \"little\":\n            return bytearray((val >> i) & 0xff\n                             for i in range(0, length*8, 8))\n        raise ValueError(\"Only 'big' or 'little' endian supported\")\n\n\ndef byte_length(val):\n    \"\"\"Return number of bytes necessary to represent an integer.\"\"\"\n    length = bit_length(val)\n    return (length + 7) // 8\n\n\ntry:\n    # Fedora and Red Hat Enterprise Linux versions have small curves removed\n    getattr(ecdsa, 'NIST192p')\nexcept AttributeError:\n    ecdsaAllCurves = False\nelse:\n    ecdsaAllCurves = True\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/constanttime.py",
    "content": "# Copyright (c) 2015, Hubert Kario\n#\n# See the LICENSE file for legal information regarding use of this file.\n\"\"\"Various constant time functions for processing sensitive data\"\"\"\n\nfrom __future__ import division\n\nfrom .compat import compatHMAC\nimport hmac\n\ndef ct_lt_u32(val_a, val_b):\n    \"\"\"\n    Returns 1 if val_a < val_b, 0 otherwise. Constant time.\n\n    :type val_a: int\n    :type val_b: int\n    :param val_a: an unsigned integer representable as a 32 bit value\n    :param val_b: an unsigned integer representable as a 32 bit value\n    :rtype: int\n    \"\"\"\n    val_a &= 0xffffffff\n    val_b &= 0xffffffff\n\n    return (val_a^((val_a^val_b)|(((val_a-val_b)&0xffffffff)^val_b)))>>31\n\n\ndef ct_gt_u32(val_a, val_b):\n    \"\"\"\n    Return 1 if val_a > val_b, 0 otherwise. Constant time.\n\n    :type val_a: int\n    :type val_b: int\n    :param val_a: an unsigned integer representable as a 32 bit value\n    :param val_b: an unsigned integer representable as a 32 bit value\n    :rtype: int\n    \"\"\"\n    return ct_lt_u32(val_b, val_a)\n\n\ndef ct_le_u32(val_a, val_b):\n    \"\"\"\n    Return 1 if val_a <= val_b, 0 otherwise. Constant time.\n\n    :type val_a: int\n    :type val_b: int\n    :param val_a: an unsigned integer representable as a 32 bit value\n    :param val_b: an unsigned integer representable as a 32 bit value\n    :rtype: int\n    \"\"\"\n    return 1 ^ ct_gt_u32(val_a, val_b)\n\n\ndef ct_lsb_prop_u8(val):\n    \"\"\"Propagate LSB to all 8 bits of the returned int. Constant time.\"\"\"\n    val &= 0x01\n    val |= val << 1\n    val |= val << 2\n    val |= val << 4\n    return val\n\n\ndef ct_lsb_prop_u16(val):\n    \"\"\"Propagate LSB to all 16 bits of the returned int. Constant time.\"\"\"\n    val &= 0x01\n    val |= val << 1\n    val |= val << 2\n    val |= val << 4\n    val |= val << 8\n    return val\n\n\ndef ct_isnonzero_u32(val):\n    \"\"\"\n    Returns 1 if val is != 0, 0 otherwise. Constant time.\n\n    :type val: int\n    :param val: an unsigned integer representable as a 32 bit value\n    :rtype: int\n    \"\"\"\n    val &= 0xffffffff\n    return (val|(-val&0xffffffff)) >> 31\n\n\ndef ct_neq_u32(val_a, val_b):\n    \"\"\"\n    Return 1 if val_a != val_b, 0 otherwise. Constant time.\n\n    :type val_a: int\n    :type val_b: int\n    :param val_a: an unsigned integer representable as a 32 bit value\n    :param val_b: an unsigned integer representable as a 32 bit value\n    :rtype: int\n    \"\"\"\n    val_a &= 0xffffffff\n    val_b &= 0xffffffff\n\n    return (((val_a-val_b)&0xffffffff) | ((val_b-val_a)&0xffffffff)) >> 31\n\ndef ct_eq_u32(val_a, val_b):\n    \"\"\"\n    Return 1 if val_a == val_b, 0 otherwise. Constant time.\n\n    :type val_a: int\n    :type val_b: int\n    :param val_a: an unsigned integer representable as a 32 bit value\n    :param val_b: an unsigned integer representable as a 32 bit value\n    :rtype: int\n    \"\"\"\n    return 1 ^ ct_neq_u32(val_a, val_b)\n\ndef ct_check_cbc_mac_and_pad(data, mac, seqnumBytes, contentType, version,\n                             block_size=16):\n    \"\"\"\n    Check CBC cipher HMAC and padding. Close to constant time.\n\n    :type data: bytearray\n    :param data: data with HMAC value to test and padding\n\n    :type mac: hashlib mac\n    :param mac: empty HMAC, initialised with a key\n\n    :type seqnumBytes: bytearray\n    :param seqnumBytes: TLS sequence number, used as input to HMAC\n\n    :type contentType: int\n    :param contentType: a single byte, used as input to HMAC\n\n    :type version: tuple of int\n    :param version: a tuple of two ints, used as input to HMAC and to guide\n        checking of padding\n\n    :rtype: boolean\n    :returns: True if MAC and pad is ok, False otherwise\n    \"\"\"\n    assert version in ((3, 0), (3, 1), (3, 2), (3, 3))\n\n    data_len = len(data)\n    if mac.digest_size + 1 > data_len: # data_len is public\n        return False\n\n    # 0 - OK\n    result = 0x00\n\n    #\n    # check padding\n    #\n    pad_length = data[data_len-1]\n    pad_start = data_len - pad_length - 1\n    pad_start = max(0, pad_start)\n\n    if version == (3, 0): # version is public\n        # in SSLv3 we can only check if pad is not longer than the cipher\n        # block size\n\n        # subtract 1 for the pad length byte\n        mask = ct_lsb_prop_u8(ct_lt_u32(block_size, pad_length))\n        result |= mask\n    else:\n        start_pos = max(0, data_len - 256)\n        for i in range(start_pos, data_len):\n            # if pad_start < i: mask = 0xff; else: mask = 0x00\n            mask = ct_lsb_prop_u8(ct_le_u32(pad_start, i))\n            # if data[i] != pad_length and \"inside_pad\": result = False\n            result |= (data[i] ^ pad_length) & mask\n\n    #\n    # check MAC\n    #\n\n    # real place where mac starts and data ends\n    mac_start = pad_start - mac.digest_size\n    mac_start = max(0, mac_start)\n\n    # place to start processing\n    start_pos = max(0, data_len - (256 + mac.digest_size)) // mac.block_size\n    start_pos *= mac.block_size\n\n    # add start data\n    data_mac = mac.copy()\n    data_mac.update(compatHMAC(seqnumBytes))\n    data_mac.update(compatHMAC(bytearray([contentType])))\n    if version != (3, 0): # version is public\n        data_mac.update(compatHMAC(bytearray([version[0]])))\n        data_mac.update(compatHMAC(bytearray([version[1]])))\n    data_mac.update(compatHMAC(bytearray([mac_start >> 8])))\n    data_mac.update(compatHMAC(bytearray([mac_start & 0xff])))\n    data_mac.update(compatHMAC(data[:start_pos]))\n\n    # don't check past the array end (already checked to be >= zero)\n    end_pos = data_len - mac.digest_size\n\n    # calculate all possible\n    for i in range(start_pos, end_pos): # constant for given overall length\n        cur_mac = data_mac.copy()\n        cur_mac.update(compatHMAC(data[start_pos:i]))\n        mac_compare = bytearray(cur_mac.digest())\n        # compare the hash for real only if it's the place where mac is\n        # supposed to be\n        mask = ct_lsb_prop_u8(ct_eq_u32(i, mac_start))\n        for j in range(0, mac.digest_size): # digest_size is public\n            result |= (data[i+j] ^ mac_compare[j]) & mask\n\n    # return python boolean\n    return result == 0\n\nif hasattr(hmac, 'compare_digest'):\n    ct_compare_digest = hmac.compare_digest\nelse:\n    def ct_compare_digest(val_a, val_b):\n        \"\"\"Compares if string like objects are equal. Constant time.\"\"\"\n        if len(val_a) != len(val_b):\n            return False\n\n        result = 0\n        for x, y in zip(val_a, val_b):\n            result |= x ^ y\n\n        return result == 0\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/cryptomath.py",
    "content": "# Authors: \n#   Trevor Perrin\n#   Martin von Loewis - python 3 port\n#   Yngve Pettersen (ported by Paul Sokolovsky) - TLS 1.2\n#\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"cryptomath module\n\nThis module has basic math/crypto code.\"\"\"\nfrom __future__ import print_function\nimport os\nimport math\nimport base64\nimport binascii\n\nfrom .compat import compat26Str, compatHMAC, compatLong, \\\n        bytes_to_int, int_to_bytes, bit_length, byte_length\nfrom .codec import Writer\n\nfrom . import tlshashlib as hashlib\nfrom . import tlshmac as hmac\n\n\n# **************************************************************************\n# Load Optional Modules\n# **************************************************************************\n\n# Try to load M2Crypto/OpenSSL\n# pylint: disable=invalid-name\ntry:\n    from M2Crypto import m2\n    m2cryptoLoaded = True\n    M2CRYPTO_AES_CTR = False\n    if hasattr(m2, 'aes_192_ctr'):\n        M2CRYPTO_AES_CTR = True\n\n    try:\n        with open('/proc/sys/crypto/fips_enabled', 'r') as fipsFile:\n            if '1' in fipsFile.read():\n                m2cryptoLoaded = False\n    except (IOError, OSError):\n        # looks like we're running in container, likely not FIPS mode\n        m2cryptoLoaded = True\n\n    # If AES-CBC is not available, don't use m2crypto\n    if not hasattr(m2, 'aes_192_cbc'):\n        m2cryptoLoaded = False\n\nexcept ImportError:\n    m2cryptoLoaded = False\n# pylint: enable=invalid-name\n\n#Try to load GMPY\ntry:\n    import gmpy\n    gmpy.mpz\n    gmpyLoaded = True\nexcept ImportError:\n    gmpyLoaded = False\n\n\n# Try to load GMPY2\ntry:\n    from gmpy2 import powmod\n    GMPY2_LOADED = True\nexcept ImportError:\n    GMPY2_LOADED = False\n\n\n# Use the faster mpz\nif GMPY2_LOADED:\n    from gmpy2 import mpz\nelif gmpyLoaded:\n    from gmpy import mpz\n\n\n#Try to load pycrypto\n# pylint: disable=invalid-name\ntry:\n    import Crypto.Cipher.AES\n    # check if we're not using pycryptodome\n    try:\n        # pycrypto defaults to ECB when just key is provided\n        # pycryptodome requires specifying the mode of operation\n        Crypto.Cipher.AES.AESCipher(b'2' * (128//8))\n        pycryptoLoaded = True\n    except AttributeError:\n        pycryptoLoaded = False\nexcept ImportError:\n    pycryptoLoaded = False\n# pylint: enable=invalid-name\n\n\n# **************************************************************************\n# PRNG Functions\n# **************************************************************************\n\n# Check that os.urandom works\nimport zlib\nassert len(zlib.compress(os.urandom(1000))) > 900\n\ndef getRandomBytes(howMany):\n    b = bytearray(os.urandom(howMany))\n    assert(len(b) == howMany)\n    return b\n\nprngName = \"os.urandom\"\n\n# **************************************************************************\n# Simple hash functions\n# **************************************************************************\n\ndef MD5(b):\n    \"\"\"Return a MD5 digest of data\"\"\"\n    return secureHash(b, 'md5')\n\ndef SHA1(b):\n    \"\"\"Return a SHA1 digest of data\"\"\"\n    return secureHash(b, 'sha1')\n\ndef secureHash(data, algorithm):\n    \"\"\"Return a digest of `data` using `algorithm`\"\"\"\n    hashInstance = hashlib.new(algorithm)\n    hashInstance.update(compat26Str(data))\n    return bytearray(hashInstance.digest())\n\ndef secureHMAC(k, b, algorithm):\n    \"\"\"Return a HMAC using `b` and `k` using `algorithm`\"\"\"\n    k = compatHMAC(k)\n    b = compatHMAC(b)\n    return bytearray(hmac.new(k, b, getattr(hashlib, algorithm)).digest())\n\ndef HMAC_MD5(k, b):\n    return secureHMAC(k, b, 'md5')\n\ndef HMAC_SHA1(k, b):\n    return secureHMAC(k, b, 'sha1')\n\ndef HMAC_SHA256(k, b):\n    return secureHMAC(k, b, 'sha256')\n\ndef HMAC_SHA384(k, b):\n    return secureHMAC(k, b, 'sha384')\n\ndef HKDF_expand(PRK, info, L, algorithm):\n    N = divceil(L, getattr(hashlib, algorithm)().digest_size)\n    T = bytearray()\n    Titer = bytearray()\n    for x in range(1, N+2):\n        T += Titer\n        Titer = secureHMAC(PRK, Titer + info + bytearray([x]), algorithm)\n    return T[:L]\n\ndef HKDF_expand_label(secret, label, hashValue, length, algorithm):\n    \"\"\"\n    TLS1.3 key derivation function (HKDF-Expand-Label).\n\n    :param bytearray secret: the key from which to derive the keying material\n    :param bytearray label: label used to differentiate the keying materials\n    :param bytearray hashValue: bytes used to \"salt\" the produced keying\n        material\n    :param int length: number of bytes to produce\n    :param str algorithm: name of the secure hash algorithm used as the\n        basis of the HKDF\n    :rtype: bytearray\n    \"\"\"\n    hkdfLabel = Writer()\n    hkdfLabel.addTwo(length)\n    hkdfLabel.addVarSeq(bytearray(b\"tls13 \") + label, 1, 1)\n    hkdfLabel.addVarSeq(hashValue, 1, 1)\n\n    return HKDF_expand(secret, hkdfLabel.bytes, length, algorithm)\n\ndef derive_secret(secret, label, handshake_hashes, algorithm):\n    \"\"\"\n    TLS1.3 key derivation function (Derive-Secret).\n\n    :param bytearray secret: secret key used to derive the keying material\n    :param bytearray label: label used to differentiate they keying materials\n    :param HandshakeHashes handshake_hashes: hashes of the handshake messages\n        or `None` if no handshake transcript is to be used for derivation of\n        keying material\n    :param str algorithm: name of the secure hash algorithm used as the\n        basis of the HKDF algorithm - governs how much keying material will\n        be generated\n    :rtype: bytearray\n    \"\"\"\n    if handshake_hashes is None:\n        hs_hash = secureHash(bytearray(b''), algorithm)\n    else:\n        hs_hash = handshake_hashes.digest(algorithm)\n    return HKDF_expand_label(secret, label, hs_hash,\n                             getattr(hashlib, algorithm)().digest_size,\n                             algorithm)\n\n# **************************************************************************\n# Converter Functions\n# **************************************************************************\n\ndef bytesToNumber(b, endian=\"big\"):\n    \"\"\"\n    Convert a number stored in bytearray to an integer.\n\n    By default assumes big-endian encoding of the number.\n    \"\"\"\n    return bytes_to_int(b, endian)\n\n\ndef numberToByteArray(n, howManyBytes=None, endian=\"big\"):\n    \"\"\"\n    Convert an integer into a bytearray, zero-pad to howManyBytes.\n\n    The returned bytearray may be smaller than howManyBytes, but will\n    not be larger.  The returned bytearray will contain a big- or little-endian\n    encoding of the input integer (n). Big endian encoding is used by default.\n    \"\"\"\n    if howManyBytes is not None:\n        length = byte_length(n)\n        if howManyBytes < length:\n            ret = int_to_bytes(n, length, endian)\n            if endian == \"big\":\n                return ret[length-howManyBytes:length]\n            return ret[:howManyBytes]\n    return int_to_bytes(n, howManyBytes, endian)\n\n\ndef mpiToNumber(mpi):\n    \"\"\"Convert a MPI (OpenSSL bignum string) to an integer.\"\"\"\n    byte = bytearray(mpi)\n    if byte[4] & 0x80:\n        raise ValueError(\"Input must be a positive integer\")\n    return bytesToNumber(byte[4:])\n\n\ndef numberToMPI(n):\n    b = numberToByteArray(n)\n    ext = 0\n    #If the high-order bit is going to be set,\n    #add an extra byte of zeros\n    if (numBits(n) & 0x7)==0:\n        ext = 1\n    length = numBytes(n) + ext\n    b = bytearray(4+ext) + b\n    b[0] = (length >> 24) & 0xFF\n    b[1] = (length >> 16) & 0xFF\n    b[2] = (length >> 8) & 0xFF\n    b[3] = length & 0xFF\n    return bytes(b)\n\n\n# **************************************************************************\n# Misc. Utility Functions\n# **************************************************************************\n\n\n# pylint: disable=invalid-name\n# pylint recognises them as constants, not function names, also\n# we can't change their names without API change\nnumBits = bit_length\n\n\nnumBytes = byte_length\n# pylint: enable=invalid-name\n\n\n# **************************************************************************\n# Big Number Math\n# **************************************************************************\n\ndef getRandomNumber(low, high):\n    assert low < high\n    howManyBits = numBits(high)\n    howManyBytes = numBytes(high)\n    lastBits = howManyBits % 8\n    while 1:\n        bytes = getRandomBytes(howManyBytes)\n        if lastBits:\n            bytes[0] = bytes[0] % (1 << lastBits)\n        n = bytesToNumber(bytes)\n        if n >= low and n < high:\n            return n\n\ndef gcd(a,b):\n    a, b = max(a,b), min(a,b)\n    while b:\n        a, b = b, a % b\n    return a\n\ndef lcm(a, b):\n    return (a * b) // gcd(a, b)\n\n# pylint: disable=invalid-name\n# disable pylint check as the (a, b) are part of the API\nif GMPY2_LOADED:\n    def invMod(a, b):\n        \"\"\"Return inverse of a mod b, zero if none.\"\"\"\n        if a == 0:\n            return 0\n        return powmod(a, -1, b)\nelse:\n    # Use Extended Euclidean Algorithm\n    def invMod(a, b):\n        \"\"\"Return inverse of a mod b, zero if none.\"\"\"\n        c, d = a, b\n        uc, ud = 1, 0\n        while c != 0:\n            q = d // c\n            c, d = d-(q*c), c\n            uc, ud = ud - (q * uc), uc\n        if d == 1:\n            return ud % b\n        return 0\n# pylint: enable=invalid-name\n\n\nif gmpyLoaded or GMPY2_LOADED:\n    def powMod(base, power, modulus):\n        base = mpz(base)\n        power = mpz(power)\n        modulus = mpz(modulus)\n        result = pow(base, power, modulus)\n        return compatLong(result)\nelse:\n    powMod = pow\n\n\ndef divceil(divident, divisor):\n    \"\"\"Integer division with rounding up\"\"\"\n    quot, r = divmod(divident, divisor)\n    return quot + int(bool(r))\n\n\n#Pre-calculate a sieve of the ~100 primes < 1000:\ndef makeSieve(n):\n    sieve = list(range(n))\n    for count in range(2, int(math.sqrt(n))+1):\n        if sieve[count] == 0:\n            continue\n        x = sieve[count] * 2\n        while x < len(sieve):\n            sieve[x] = 0\n            x += sieve[count]\n    sieve = [x for x in sieve[2:] if x]\n    return sieve\n\ndef isPrime(n, iterations=5, display=False, sieve=makeSieve(1000)):\n    #Trial division with sieve\n    for x in sieve:\n        if x >= n: return True\n        if n % x == 0: return False\n    #Passed trial division, proceed to Rabin-Miller\n    #Rabin-Miller implemented per Ferguson & Schneier\n    #Compute s, t for Rabin-Miller\n    if display: print(\"*\", end=' ')\n    s, t = n-1, 0\n    while s % 2 == 0:\n        s, t = s//2, t+1\n    #Repeat Rabin-Miller x times\n    a = 2 #Use 2 as a base for first iteration speedup, per HAC\n    for count in range(iterations):\n        v = powMod(a, s, n)\n        if v==1:\n            continue\n        i = 0\n        while v != n-1:\n            if i == t-1:\n                return False\n            else:\n                v, i = powMod(v, 2, n), i+1\n        a = getRandomNumber(2, n)\n    return True\n\n\ndef getRandomPrime(bits, display=False):\n    \"\"\"\n    Generate a random prime number of a given size.\n\n    the number will be 'bits' bits long (i.e. generated number will be\n    larger than `(2^(bits-1) * 3 ) / 2` but smaller than 2^bits.\n    \"\"\"\n    assert bits >= 10\n    #The 1.5 ensures the 2 MSBs are set\n    #Thus, when used for p,q in RSA, n will have its MSB set\n    #\n    #Since 30 is lcm(2,3,5), we'll set our test numbers to\n    #29 % 30 and keep them there\n    low = ((2 ** (bits-1)) * 3) // 2\n    high = 2 ** bits - 30\n    while True:\n        if display:\n            print(\".\", end=' ')\n        cand_p = getRandomNumber(low, high)\n        # make odd\n        if cand_p % 2 == 0:\n            cand_p += 1\n        if isPrime(cand_p, display=display):\n            return cand_p\n\n\n#Unused at the moment...\ndef getRandomSafePrime(bits, display=False):\n    \"\"\"Generate a random safe prime.\n\n    Will generate a prime `bits` bits long (see getRandomPrime) such that\n    the (p-1)/2 will also be prime.\n    \"\"\"\n    assert bits >= 10\n    #The 1.5 ensures the 2 MSBs are set\n    #Thus, when used for p,q in RSA, n will have its MSB set\n    #\n    #Since 30 is lcm(2,3,5), we'll set our test numbers to\n    #29 % 30 and keep them there\n    low = (2 ** (bits-2)) * 3//2\n    high = (2 ** (bits-1)) - 30\n    q = getRandomNumber(low, high)\n    q += 29 - (q % 30)\n    while 1:\n        if display: print(\".\", end=' ')\n        q += 30\n        if (q >= high):\n            q = getRandomNumber(low, high)\n            q += 29 - (q % 30)\n        #Ideas from Tom Wu's SRP code\n        #Do trial division on p and q before Rabin-Miller\n        if isPrime(q, 0, display=display):\n            p = (2 * q) + 1\n            if isPrime(p, display=display):\n                if isPrime(q, display=display):\n                    return p\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/datefuncs.py",
    "content": "# Author: Trevor Perrin\n# See the LICENSE file for legal information regarding use of this file.\n\nimport os\n\n#Functions for manipulating datetime objects\n#CCYY-MM-DDThh:mm:ssZ\ndef parseDateClass(s):\n    year, month, day = s.split(\"-\")\n    day, tail = day[:2], day[2:]\n    hour, minute, second = tail[1:].split(\":\")\n    second = second[:2]\n    year, month, day = int(year), int(month), int(day)\n    hour, minute, second = int(hour), int(minute), int(second)\n    return createDateClass(year, month, day, hour, minute, second)\n\n\nif os.name != \"java\":\n    from datetime import datetime, timedelta\n\n    #Helper functions for working with a date/time class\n    def createDateClass(year, month, day, hour, minute, second):\n        return datetime(year, month, day, hour, minute, second)\n\n    def printDateClass(d):\n        #Split off fractional seconds, append 'Z'\n        return d.isoformat().split(\".\")[0]+\"Z\"\n\n    def getNow():\n        return datetime.utcnow()\n\n    def getHoursFromNow(hours):\n        return datetime.utcnow() + timedelta(hours=hours)\n\n    def getMinutesFromNow(minutes):\n        return datetime.utcnow() + timedelta(minutes=minutes)\n\n    def isDateClassExpired(d):\n        return d < datetime.utcnow()\n\n    def isDateClassBefore(d1, d2):\n        return d1 < d2\n\nelse:\n    #Jython 2.1 is missing lots of python 2.3 stuff,\n    #which we have to emulate here:\n    import java\n    import jarray\n\n    def createDateClass(year, month, day, hour, minute, second):\n        c = java.util.Calendar.getInstance()\n        c.setTimeZone(java.util.TimeZone.getTimeZone(\"UTC\"))\n        c.set(year, month-1, day, hour, minute, second)\n        return c\n\n    def printDateClass(d):\n        return \"%04d-%02d-%02dT%02d:%02d:%02dZ\" % \\\n        (d.get(d.YEAR), d.get(d.MONTH)+1, d.get(d.DATE), \\\n        d.get(d.HOUR_OF_DAY), d.get(d.MINUTE), d.get(d.SECOND))\n\n    def getNow():\n        c = java.util.Calendar.getInstance()\n        c.setTimeZone(java.util.TimeZone.getTimeZone(\"UTC\"))\n        c.get(c.HOUR) #force refresh?\n        return c\n\n    def getHoursFromNow(hours):\n        d = getNow()\n        d.add(d.HOUR, hours)\n        return d\n\n    def isDateClassExpired(d):\n        n = getNow()\n        return d.before(n)\n\n    def isDateClassBefore(d1, d2):\n        return d1.before(d2)\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/deprecations.py",
    "content": "# Copyright (c) 2018 Hubert Kario\n#\n# See the LICENSE file for legal information regarding use of this file.\n\"\"\"Methods for deprecating old names for arguments or attributes.\"\"\"\nimport warnings\nimport inspect\nfrom functools import wraps\n\n\ndef deprecated_class_name(old_name,\n                          warn=\"Class name '{old_name}' is deprecated, \"\n                          \"please use '{new_name}'\"):\n    \"\"\"\n    Class decorator to deprecate a use of class.\n\n    :param str old_name: the deprecated name that will be registered, but\n       will raise warnings if used.\n\n    :param str warn: DeprecationWarning format string for informing the\n       user what is the current class name, uses 'old_name' for the deprecated\n       keyword name and the 'new_name' for the current one.\n       Example: \"Old name: {old_nam}, use '{new_name}' instead\".\n    \"\"\"\n    def _wrap(obj):\n        assert callable(obj)\n\n        def _warn():\n            warnings.warn(warn.format(old_name=old_name,\n                                      new_name=obj.__name__),\n                          DeprecationWarning,\n                          stacklevel=3)\n\n        def _wrap_with_warn(func, is_inspect):\n            @wraps(func)\n            def _func(*args, **kwargs):\n                if is_inspect:\n                    # XXX: If use another name to call,\n                    # you will not get the warning.\n                    # we do this instead of subclassing or metaclass as\n                    # we want to isinstance(new_name(), old_name) and\n                    # isinstance(old_name(), new_name) to work\n                    frame = inspect.currentframe().f_back\n                    code = inspect.getframeinfo(frame).code_context\n                    if [line for line in code\n                            if '{0}('.format(old_name) in line]:\n                        _warn()\n                else:\n                    _warn()\n                return func(*args, **kwargs)\n            return _func\n\n        # Make old name available.\n        frame = inspect.currentframe().f_back\n        if old_name in frame.f_globals:\n            raise NameError(\"Name '{0}' already in use.\".format(old_name))\n\n        if inspect.isclass(obj):\n            obj.__init__ = _wrap_with_warn(obj.__init__, True)\n            placeholder = obj\n        else:\n            placeholder = _wrap_with_warn(obj, False)\n\n        frame.f_globals[old_name] = placeholder\n\n        return obj\n    return _wrap\n\n\ndef deprecated_params(names, warn=\"Param name '{old_name}' is deprecated, \"\n                                  \"please use '{new_name}'\"):\n    \"\"\"Decorator to translate obsolete names and warn about their use.\n\n    :param dict names: dictionary with pairs of new_name: old_name\n        that will be used for translating obsolete param names to new names\n\n    :param str warn: DeprecationWarning format string for informing the user\n        what is the current parameter name, uses 'old_name' for the\n        deprecated keyword name and 'new_name' for the current one.\n        Example: \"Old name: {old_name}, use {new_name} instead\".\n    \"\"\"\n    def decorator(func):\n        @wraps(func)\n        def wrapper(*args, **kwargs):\n            for new_name, old_name in names.items():\n                if old_name in kwargs:\n                    if new_name in kwargs:\n                        raise TypeError(\"got multiple values for keyword \"\n                                        \"argument '{0}'\".format(new_name))\n                    warnings.warn(warn.format(old_name=old_name,\n                                              new_name=new_name),\n                                  DeprecationWarning,\n                                  stacklevel=2)\n                    kwargs[new_name] = kwargs.pop(old_name)\n            return func(*args, **kwargs)\n        return wrapper\n    return decorator\n\n\ndef deprecated_instance_attrs(names,\n                              warn=\"Attribute '{old_name}' is deprecated, \"\n                                   \"please use '{new_name}'\"):\n    \"\"\"Decorator to deprecate class instance attributes.\n\n    Translates all names in `names` to use new names and emits warnings\n    if the translation was necessary. Does apply only to instance variables\n    and attributes (won't modify behaviour of class variables, static methods,\n    etc.\n\n    :param dict names: dictionary with paris of new_name: old_name that will\n        be used to translate the calls\n    :param str warn: DeprecationWarning format string for informing the user\n        what is the current parameter name, uses 'old_name' for the\n        deprecated keyword name and 'new_name' for the current one.\n        Example: \"Old name: {old_name}, use {new_name} instead\".\n    \"\"\"\n    # reverse the dict as we're looking for old attributes, not new ones\n    names = dict((j, i) for i, j in names.items())\n\n    def decorator(clazz):\n        def getx(self, name, __old_getx=getattr(clazz, \"__getattr__\", None)):\n            if name in names:\n                warnings.warn(warn.format(old_name=name,\n                                          new_name=names[name]),\n                              DeprecationWarning,\n                              stacklevel=2)\n                return getattr(self, names[name])\n            if __old_getx:\n                if hasattr(__old_getx, \"__func__\"):\n                    return __old_getx.__func__(self, name)\n                return __old_getx(self, name)\n            raise AttributeError(\"'{0}' object has no attribute '{1}'\"\n                                 .format(clazz.__name__, name))\n\n        getx.__name__ = \"__getattr__\"\n        clazz.__getattr__ = getx\n\n        def setx(self, name, value, __old_setx=getattr(clazz, \"__setattr__\")):\n            if name in names:\n                warnings.warn(warn.format(old_name=name,\n                                          new_name=names[name]),\n                              DeprecationWarning,\n                              stacklevel=2)\n                setattr(self, names[name], value)\n            else:\n                __old_setx(self, name, value)\n\n        setx.__name__ = \"__setattr__\"\n        clazz.__setattr__ = setx\n\n        def delx(self, name, __old_delx=getattr(clazz, \"__delattr__\")):\n            if name in names:\n                warnings.warn(warn.format(old_name=name,\n                                          new_name=names[name]),\n                              DeprecationWarning,\n                              stacklevel=2)\n                delattr(self, names[name])\n            else:\n                __old_delx(self, name)\n\n        delx.__name__ = \"__delattr__\"\n        clazz.__delattr__ = delx\n\n        return clazz\n    return decorator\n\n\ndef deprecated_attrs(names, warn=\"Attribute '{old_name}' is deprecated, \"\n                                 \"please use '{new_name}'\"):\n    \"\"\"Decorator to deprecate all specified attributes in class.\n\n    Translates all names in `names` to use new names and emits warnings\n    if the translation was necessary.\n\n    Note: uses metaclass magic so is incompatible with other metaclass uses\n\n    :param dict names: dictionary with paris of new_name: old_name that will\n        be used to translate the calls\n    :param str warn: DeprecationWarning format string for informing the user\n        what is the current parameter name, uses 'old_name' for the\n        deprecated keyword name and 'new_name' for the current one.\n        Example: \"Old name: {old_name}, use {new_name} instead\".\n    \"\"\"\n    # prepare metaclass for handling all the class methods, class variables\n    # and static methods (as they don't go through instance's __getattr__)\n    class DeprecatedProps(type):\n        pass\n\n    metaclass = deprecated_instance_attrs(names, warn)(DeprecatedProps)\n\n    def wrapper(cls):\n        cls = deprecated_instance_attrs(names, warn)(cls)\n\n        # apply metaclass\n        orig_vars = cls.__dict__.copy()\n        slots = orig_vars.get('__slots__')\n        if slots is not None:\n            if isinstance(slots, str):\n                slots = [slots]\n            for slots_var in slots:\n                orig_vars.pop(slots_var)\n        orig_vars.pop('__dict__', None)\n        orig_vars.pop('__weakref__', None)\n        return metaclass(cls.__name__, cls.__bases__, orig_vars)\n    return wrapper\n\ndef deprecated_method(message):\n    \"\"\"Decorator for deprecating methods.\n\n    :param ste message: The message you want to display.\n    \"\"\"\n    def decorator(func):\n        @wraps(func)\n        def wrapper(*args, **kwargs):\n            warnings.warn(\"{0} is a deprecated method. {1}\".format(func.__name__, message),\n                          DeprecationWarning, stacklevel=2)\n            return func(*args, **kwargs)\n        return wrapper\n    return decorator\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/dns_utils.py",
    "content": "# Copyright (c) 2017 Hubert Kario\n#\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Utilities for handling DNS hostnames\"\"\"\n\nimport re\n\n\ndef is_valid_hostname(hostname):\n    \"\"\"\n    Check if the parameter is a valid hostname.\n\n    :type hostname: str or bytearray\n    :param hostname: string to check\n    :rtype: boolean\n    \"\"\"\n    try:\n        if not isinstance(hostname, str):\n            hostname = hostname.decode('ascii', 'strict')\n    except UnicodeDecodeError:\n        return False\n    if hostname[-1] == \".\":\n        # strip exactly one dot from the right, if present\n        hostname = hostname[:-1]\n    # the maximum length of the domain name is 255 bytes, but because they\n    # are encoded as labels (which is a length byte and an up to 63 character\n    # ascii string), you change the dots to the length bytes, but the\n    # host element of the FQDN doesn't start with a dot and the name doesn't\n    # end with a dot (specification of a root label), we need to subtract 2\n    # bytes from the 255 byte maximum when looking at dot-deliminated FQDN\n    # with the trailing dot removed\n    # see RFC 1035\n    if len(hostname) > 253:\n        return False\n\n    # must not be all-numeric, so that it can't be confused with an ip-address\n    if re.match(r\"[\\d.]+$\", hostname):\n        return False\n\n    allowed = re.compile(r\"(?!-)[A-Z\\d-]{1,63}(?<!-)$\", re.IGNORECASE)\n    return all(allowed.match(x) for x in hostname.split(\".\"))\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/dsakey.py",
    "content": "\"\"\"Abstract class for DSA.\"\"\"\n\nclass DSAKey(object):\n    \"\"\"This is an abstract base class for DSA keys.\n\n    Particular implementations of DSA keys, such as\n    :py:class:`~.python_dsakey.Python_DSAKey`\n    ... more coming\n    inherit from this.\n\n    To create or parse an DSA key, don't use one of these classes\n    directly.  Instead, use the factory functions in\n    :py:class:`~tlslite.utils.keyfactory`.\n    \"\"\"\n\n    def __init__(self, p, q, g, x, y):\n        \"\"\"Create a new DSA key.\n        :type p: int\n        :param p: domain parameter, prime num defining Gaolis Field\n        :type q: int\n        :param q: domain parameter, prime factor of p-1\n        :type g: int\n        :param g: domain parameter, generator of q-order cyclic group GP(p)\n        :type x: int\n        :param x: private key\n        :type y: int\n        :param y: public key\n        \"\"\"\n        raise NotImplementedError()\n\n    def __len__(self):\n        \"\"\"Return the size of the order of the curve of this key, in bits.\n\n        :rtype: int\n        \"\"\"\n        raise NotImplementedError()\n\n    def hasPrivateKey(self):\n        \"\"\"Return whether or not this key has a private component.\n\n        :rtype: bool\n        \"\"\"\n        raise NotImplementedError()\n\n    def hashAndSign(self, data, hAlg):\n        \"\"\"Hash and sign the passed-in bytes.\n\n        This requires the key to have a private component and\n        global parameters. It performs a signature on the passed-in data\n        with selected hash algorithm.\n\n        :type data: str\n        :param data: The data which will be hashed and signed.\n\n        :type hAlg: str\n        :param hAlg: The hash algorithm that will be used to hash data\n\n        :rtype: bytearray\n        :returns: An DSA signature on the passed-in data.\n        \"\"\"\n        raise NotImplementedError()\n\n    def sign(self, data):\n        raise NotImplementedError()\n\n    def hashAndVerify(self, signature, data, hAlg=\"sha1\"):\n        \"\"\"Hash and verify the passed-in bytes with signature.\n\n        :type signature: ASN1 bytearray\n        :param signature: the r, s dsa signature\n\n        :type data: str\n        :param data: The data which will be hashed and verified.\n\n        :type hAlg: str\n        :param hAlg: The hash algorithm that will be used to hash data\n\n        :rtype: bool\n        :returns: return True if verification is OK.\n        \"\"\"\n        raise NotImplementedError()\n\n    @staticmethod\n    def generate(L, N):\n        \"\"\"Generate new key given by bit lengths L, N.\n\n        :type L: int\n        :param L: length of parameter p in bits\n\n        :type N: int\n        :param N: length of parameter q in bits\n\n        :rtype: DSAkey\n        :returns: DSAkey(domain parameters, private key, public key)\n        \"\"\"\n        raise NotImplementedError()\n\n    @staticmethod\n    def generate_qp(L, N):\n        \"\"\"Generate new (p, q) given by bit lengths L, N.\n\n        :type L: int\n        :param L: length of parameter p in bits\n\n        :type N: int\n        :param N: length of parameter q in bits\n\n        :rtype: (int, int)\n        :returns: new p and q key parameters\n        \"\"\"\n        raise NotImplementedError()\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/ecc.py",
    "content": "# Copyright (c) 2015, Hubert Kario\n#\n# See the LICENSE file for legal information regarding use of this file.\n\"\"\"Methods for dealing with ECC points\"\"\"\n\nfrom .codec import Parser, Writer, DecodeError\nfrom .cryptomath import bytesToNumber, numberToByteArray, numBytes\nfrom .compat import ecdsaAllCurves\nimport ecdsa\n\n\ndef decodeX962Point(data, curve=ecdsa.NIST256p):\n    \"\"\"Decode a point from a X9.62 encoding\"\"\"\n    parser = Parser(data)\n    encFormat = parser.get(1)\n    if encFormat != 4:\n        raise DecodeError(\"Not an uncompressed point encoding\")\n    bytelength = getPointByteSize(curve)\n    xCoord = bytesToNumber(parser.getFixBytes(bytelength))\n    yCoord = bytesToNumber(parser.getFixBytes(bytelength))\n    if parser.getRemainingLength():\n        raise DecodeError(\"Invalid length of point encoding for curve\")\n    return ecdsa.ellipticcurve.Point(curve.curve, xCoord, yCoord)\n\n\ndef encodeX962Point(point):\n    \"\"\"Encode a point in X9.62 format\"\"\"\n    bytelength = numBytes(point.curve().p())\n    writer = Writer()\n    writer.add(4, 1)\n    writer.bytes += numberToByteArray(point.x(), bytelength)\n    writer.bytes += numberToByteArray(point.y(), bytelength)\n    return writer.bytes\n\ndef getCurveByName(curveName):\n    \"\"\"Return curve identified by curveName\"\"\"\n    curveMap = {'secp256r1':ecdsa.NIST256p,\n                'secp384r1':ecdsa.NIST384p,\n                'secp521r1':ecdsa.NIST521p,\n                'secp256k1':ecdsa.SECP256k1,\n                'brainpoolP256r1': ecdsa.BRAINPOOLP256r1,\n                'brainpoolP384r1': ecdsa.BRAINPOOLP384r1,\n                'brainpoolP512r1': ecdsa.BRAINPOOLP512r1}\n    if ecdsaAllCurves:\n        curveMap['secp224r1'] = ecdsa.NIST224p\n        curveMap['secp192r1'] = ecdsa.NIST192p\n\n    if curveName in curveMap:\n        return curveMap[curveName]\n    else:\n        raise ValueError(\"Curve of name '{0}' unknown\".format(curveName))\n\ndef getPointByteSize(point):\n    \"\"\"Convert the point or curve bit size to bytes\"\"\"\n    curveMap = {ecdsa.NIST256p.curve: 256//8,\n                ecdsa.NIST384p.curve: 384//8,\n                ecdsa.NIST521p.curve: (521+7)//8,\n                ecdsa.SECP256k1.curve: 256//8,\n                ecdsa.BRAINPOOLP256r1.curve: 256//8,\n                ecdsa.BRAINPOOLP384r1.curve: 384//8,\n                ecdsa.BRAINPOOLP512r1.curve: 512//8}\n    if ecdsaAllCurves:\n        curveMap[ecdsa.NIST224p.curve] = 224//8\n        curveMap[ecdsa.NIST192p.curve] = 192//8\n\n    if hasattr(point, 'curve'):\n        if callable(point.curve):\n            return curveMap[point.curve()]\n        else:\n            return curveMap[point.curve]\n    raise ValueError(\"Parameter must be a curve or point on curve\")\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/ecdsakey.py",
    "content": "# Author: Stanislav Zidek\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Abstract class for ECDSA.\"\"\"\n\nfrom .cryptomath import secureHash\n\n\nclass ECDSAKey(object):\n    \"\"\"This is an abstract base class for ECDSA keys.\n\n    Particular implementations of ECDSA keys, such as\n    :py:class:`~.python_ecdsakey.Python_ECDSAKey`\n    ... more coming\n    inherit from this.\n\n    To create or parse an ECDSA key, don't use one of these classes\n    directly.  Instead, use the factory functions in\n    :py:class:`~tlslite.utils.keyfactory`.\n    \"\"\"\n\n    def __init__(self, public_key, private_key):\n        \"\"\"Create a new ECDSA key.\n\n        If public_key or private_key are passed in, the new key\n        will be initialized.\n\n        :param public_key: ECDSA public key.\n\n        :param private_key: ECDSA private key.\n        \"\"\"\n        raise NotImplementedError()\n\n    def __len__(self):\n        \"\"\"Return the size of the order of the curve of this key, in bits.\n\n        :rtype: int\n        \"\"\"\n        raise NotImplementedError()\n\n    def hasPrivateKey(self):\n        \"\"\"Return whether or not this key has a private component.\n\n        :rtype: bool\n        \"\"\"\n        raise NotImplementedError()\n\n    def _sign(self, data, hash_alg):\n        raise NotImplementedError()\n\n    def _hashAndSign(self, data, hAlg):\n        raise NotImplementedError()\n\n    def _verify(self, signature, hash_bytes):\n        raise NotImplementedError()\n\n    def hashAndSign(self, bytes, rsaScheme=None, hAlg='sha1', sLen=None):\n        \"\"\"Hash and sign the passed-in bytes.\n\n        This requires the key to have a private component. It performs\n        a signature on the passed-in data with selected hash algorithm.\n\n        :type bytes: bytes-like object\n        :param bytes: The value which will be hashed and signed.\n\n        :type rsaScheme: str\n        :param rsaScheme: Ignored, present for API compatibility with RSA\n\n        :type hAlg: str\n        :param hAlg: The hash algorithm that will be used to hash data\n\n        :type sLen: int\n        :param sLen: Ignored, present for API compatibility with RSA\n\n        :rtype: bytearray\n        :returns: An ECDSA signature on the passed-in data.\n        \"\"\"\n        hAlg = hAlg.lower()\n        hashBytes = secureHash(bytearray(bytes), hAlg)\n        return self.sign(hashBytes, padding=rsaScheme, hashAlg=hAlg,\n                         saltLen=sLen)\n\n    def hashAndVerify(self, sigBytes, bytes, rsaScheme=None, hAlg='sha1',\n                      sLen=None):\n        \"\"\"Hash and verify the passed-in bytes with the signature.\n\n        This verifies an ECDSA signature on the passed-in data\n        with selected hash algorithm.\n\n        :type sigBytes: bytearray\n        :param sigBytes: An ECDSA signature, DER encoded.\n\n        :type bytes: str or bytearray\n        :param bytes: The value which will be hashed and verified.\n\n        :type rsaScheme: str\n        :param rsaScheme: Ignored, present for API compatibility with RSA\n\n        :type hAlg: str\n        :param hAlg: The hash algorithm that will be used\n\n        :type sLen: int\n        :param sLen: Ignored, present for API compatibility with RSA\n\n        :rtype: bool\n        :returns: Whether the signature matches the passed-in data.\n        \"\"\"\n        hAlg = hAlg.lower()\n\n        hashBytes = secureHash(bytearray(bytes), hAlg)\n        return self.verify(sigBytes, hashBytes, rsaScheme, hAlg, sLen)\n\n    def sign(self, bytes, padding=None, hashAlg=\"sha1\", saltLen=None):\n        \"\"\"Sign the passed-in bytes.\n\n        This requires the key to have a private component.  It performs\n        an ECDSA signature on the passed-in data.\n\n        :type bytes: bytearray\n        :param bytes: The value which will be signed (generally a binary\n            encoding of hash output.\n\n        :type padding: str\n        :param padding: Ignored, present for API compatibility with RSA\n\n        :type hashAlg: str\n        :param hashAlg: name of hash that was used for calculating the bytes\n\n        :type saltLen: int\n        :param saltLen: Ignored, present for API compatibility with RSA\n\n        :rtype: bytearray\n        :returns: An ECDSA signature on the passed-in data.\n        \"\"\"\n        sigBytes = self._sign(bytes, hashAlg)\n        return sigBytes\n\n    def verify(self, sigBytes, bytes, padding=None, hashAlg=None,\n               saltLen=None):\n        \"\"\"Verify the passed-in bytes with the signature.\n\n        This verifies a PKCS1 signature on the passed-in data.\n\n        :type sigBytes: bytearray\n        :param sigBytes: A PKCS1 signature.\n\n        :type bytes: bytearray\n        :param bytes: The value which will be verified.\n\n        :type padding: str\n        :param padding: Ignored, present for API compatibility with RSA\n\n        :rtype: bool\n        :returns: Whether the signature matches the passed-in data.\n        \"\"\"\n        return self._verify(sigBytes, bytes)\n\n    def acceptsPassword(self):\n        \"\"\"Return True if the write() method accepts a password for use\n        in encrypting the private key.\n\n        :rtype: bool\n        \"\"\"\n        raise NotImplementedError()\n\n    def write(self, password=None):\n        \"\"\"Return a string containing the key.\n\n        :rtype: str\n        :returns: A string describing the key, in whichever format (PEM)\n            is native to the implementation.\n        \"\"\"\n        raise NotImplementedError()\n\n    @staticmethod\n    def generate(bits):\n        \"\"\"Generate a new key with the specified curve.\n\n        :rtype: ~tlslite.utils.ECDSAKey.ECDSAKey\n        \"\"\"\n        raise NotImplementedError()\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/eddsakey.py",
    "content": "# Author: Hubert Kario\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Abstract class for EdDSA.\"\"\"\n\n\nclass EdDSAKey(object):\n    \"\"\"This is an abstract base class for EdDSA keys.\n\n    Particular implementations of EdDSA keys, such as\n    :py:class:`~.python_eddsakey.Python_EdDSAKey`\n    ... more coming\n    inherit from this.\n\n    To create or parse an EdDSA key, don't use one of these classes\n    directly.  Instead, use the factory functions in\n    :py:class:`~tlslite.utils.keyfactory`.\n    \"\"\"\n    def __len__(self):\n        \"\"\"Return the size of the order of the curve of this key, in bits.\n\n        :rtype: int\n        \"\"\"\n        raise NotImplementedError()\n\n    def hasPrivateKey(self):\n        \"\"\"Return whether or not this key has a private component.\n\n        :rtype: bool\n        \"\"\"\n        raise NotImplementedError()\n\n    def _hashAndSign(self, data):\n        raise NotImplementedError()\n\n    def _hashAndVerify(self, signature, data):\n        raise NotImplementedError()\n\n    def hashAndSign(self, data, rsaScheme=None, hAlg=None, sLen=None):\n        \"\"\"Hash and sign the passed-in bytes.\n\n        This requires the key to have a private component. It performs\n        a signature on the passed-in data with selected hash algorithm.\n\n        :type bytes: bytes-like object\n        :param bytes: The value which will be hashed and signed.\n\n        :type rsaScheme: str\n        :param rsaScheme: Ignored, present for API compatibility with RSA\n\n        :type hAlg: str\n        :param hAlg: Ignored, present for API compatibility with RSA/ECDSA\n\n        :type sLen: int\n        :param sLen: Ignored, present for API compatibility with RSA\n\n        :rtype: bytearray\n        :returns: An EdDSA signature on the passed-in data.\n        \"\"\"\n        return self._hashAndSign(data)\n\n    def hashAndVerify(self, sig_bytes, data, rsaScheme=None, hAlg=None,\n                      sLen=None):\n        \"\"\"Hash and verify the passed-in bytes with the signature.\n\n        This verifies an EdDSA signature on the passed-in data\n        with the implicit hash algorithm.\n\n        :type sigBytes: bytearray\n        :param sigBytes: An EdDSA signature\n\n        :type bytes: str or bytearray\n        :param bytes: The value which will be hashed and verified.\n\n        :type rsaScheme: str\n        :param rsaScheme: Ignored, present for API compatibility with RSA\n\n        :type hAlg: str\n        :param hAlg: Ignored, present for API compatibility with RSA\n\n        :type sLen: int\n        :param sLen: Ignored, present for API compatibility with RSA\n\n        :rtype: bool\n        :returns: Whether the signature matches the passed-in data.\n        \"\"\"\n        return self._hashAndVerify(sig_bytes, data)\n\n    @staticmethod\n    def sign(self, bytes, padding=None, hashAlg=\"sha1\", saltLen=None):\n        \"\"\"Sign the passed-in bytes.\n\n        Note: this method is unsupported for EdDSA keys, as pre-hash\n        signatures are unsupported. Use hashAndSign to perform the\n        Pure EdDSA signature creation.\n\n        :type bytes: bytearray\n        :param bytes: Ignored\n\n        :type padding: str\n        :param padding: Ignored\n\n        :type hashAlg: str\n        :param hashAlg: Ignored\n\n        :type saltLen: int\n        :param saltLen: Ignored\n        \"\"\"\n        raise TypeError(\"Only Pure EdDSA signatures are supported, use \"\n                        \"hashAndSign() instead.\")\n\n    @staticmethod\n    def verify(self, sigBytes, bytes, padding=None, hashAlg=None,\n               saltLen=None):\n        \"\"\"Verify the passed-in bytes with the signature.\n\n        Note: this method is unsupported for EdDSA keys, as pre-hash\n        signatures are unsupported. Use hashAndVerify to perform the\n        Pure EdDSA verification.\n\n        :type sigBytes: bytearray\n        :param sigBytes: Ignored\n\n        :type bytes: bytearray\n        :param bytes: Ignored\n\n        :type padding: str\n        :param padding: Ignored\n        \"\"\"\n        raise TypeError(\"Only Pure EdDSA signatures are supported, use \"\n                        \"hashAndVerify() instead.\")\n\n    def acceptsPassword(self):\n        \"\"\"Return True if the write() method accepts a password for use\n        in encrypting the private key.\n\n        :rtype: bool\n        \"\"\"\n        raise NotImplementedError()\n\n    def write(self, password=None):\n        \"\"\"Return a string containing the key.\n\n        :rtype: str\n        :returns: A string describing the key, in whichever format (PEM)\n            is native to the implementation.\n        \"\"\"\n        raise NotImplementedError()\n\n    @staticmethod\n    def generate(bits):\n        \"\"\"Generate a new key with the specified curve.\n\n        :rtype: ~tlslite.utils.EdDSAKey.EdDSAKey\n        \"\"\"\n        raise NotImplementedError()\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/format_output.py",
    "content": "# Author: Milan Lysonek\n#\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Helper functions for output formatting\"\"\"\n\n\ndef none_as_unknown(text, number):\n    \"\"\"\n    Return text if text isn't None or empty, otherwise return 'unknown(number)'\n\n    :type text: str\n    :param text: string, that we want format\n    :type number: int\n    :param number: number used in text\n    \"\"\"\n    if not text:\n        text = \"unknown({0})\".format(number)\n    return text\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/keyfactory.py",
    "content": "# Author: Trevor Perrin\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Factory functions for asymmetric cryptography.\"\"\"\n\nfrom .compat import *\n\nfrom .rsakey import RSAKey\nfrom .python_rsakey import Python_RSAKey\nfrom .python_ecdsakey import Python_ECDSAKey\nfrom .python_dsakey import Python_DSAKey\nfrom .python_eddsakey import Python_EdDSAKey\nfrom tlslite.utils import cryptomath\n\nif cryptomath.m2cryptoLoaded:\n    from .openssl_rsakey import OpenSSL_RSAKey\n\nif cryptomath.pycryptoLoaded:\n    from .pycrypto_rsakey import PyCrypto_RSAKey\n\n# **************************************************************************\n# Factory Functions for RSA Keys\n# **************************************************************************\n\ndef generateRSAKey(bits, implementations=[\"openssl\", \"python\"]):\n    \"\"\"Generate an RSA key with the specified bit length.\n\n    :type bits: int\n    :param bits: Desired bit length of the new key's modulus.\n\n    :rtype: ~tlslite.utils.rsakey.RSAKey\n    :returns: A new RSA private key.\n    \"\"\"\n    for implementation in implementations:\n        if implementation == \"openssl\" and cryptomath.m2cryptoLoaded:\n            return OpenSSL_RSAKey.generate(bits)\n        elif implementation == \"python\":\n            return Python_RSAKey.generate(bits)\n    raise ValueError(\"No acceptable implementations\")\n\n#Parse as an OpenSSL or Python key\ndef parsePEMKey(s, private=False, public=False, passwordCallback=None,\n                implementations=[\"openssl\", \"python\"]):\n    \"\"\"Parse a PEM-format key.\n\n    The PEM format is used by OpenSSL and other tools.  The\n    format is typically used to store both the public and private\n    components of a key.  For example::\n\n       -----BEGIN RSA PRIVATE KEY-----\n        MIICXQIBAAKBgQDYscuoMzsGmW0pAYsmyHltxB2TdwHS0dImfjCMfaSDkfLdZY5+\n        dOWORVns9etWnr194mSGA1F0Pls/VJW8+cX9+3vtJV8zSdANPYUoQf0TP7VlJxkH\n        dSRkUbEoz5bAAs/+970uos7n7iXQIni+3erUTdYEk2iWnMBjTljfgbK/dQIDAQAB\n        AoGAJHoJZk75aKr7DSQNYIHuruOMdv5ZeDuJvKERWxTrVJqE32/xBKh42/IgqRrc\n        esBN9ZregRCd7YtxoL+EVUNWaJNVx2mNmezEznrc9zhcYUrgeaVdFO2yBF1889zO\n        gCOVwrO8uDgeyj6IKa25H6c1N13ih/o7ZzEgWbGG+ylU1yECQQDv4ZSJ4EjSh/Fl\n        aHdz3wbBa/HKGTjC8iRy476Cyg2Fm8MZUe9Yy3udOrb5ZnS2MTpIXt5AF3h2TfYV\n        VoFXIorjAkEA50FcJmzT8sNMrPaV8vn+9W2Lu4U7C+K/O2g1iXMaZms5PC5zV5aV\n        CKXZWUX1fq2RaOzlbQrpgiolhXpeh8FjxwJBAOFHzSQfSsTNfttp3KUpU0LbiVvv\n        i+spVSnA0O4rq79KpVNmK44Mq67hsW1P11QzrzTAQ6GVaUBRv0YS061td1kCQHnP\n        wtN2tboFR6lABkJDjxoGRvlSt4SOPr7zKGgrWjeiuTZLHXSAnCY+/hr5L9Q3ZwXG\n        6x6iBdgLjVIe4BZQNtcCQQDXGv/gWinCNTN3MPWfTW/RGzuMYVmyBFais0/VrgdH\n        h1dLpztmpQqfyH/zrBXQ9qL/zR4ojS6XYneO/U18WpEe\n        -----END RSA PRIVATE KEY-----\n\n    To generate a key like this with OpenSSL, run::\n\n        openssl genrsa 2048 > key.pem\n\n    This format also supports password-encrypted private keys.  TLS\n    Lite can only handle password-encrypted private keys when OpenSSL\n    and M2Crypto are installed.  In this case, passwordCallback will be\n    invoked to query the user for the password.\n\n    :type s: str\n    :param s: A string containing a PEM-encoded public or private key.\n\n    :type private: bool\n    :param private: If True, a :py:class:`SyntaxError` will be raised if the\n        private key component is not present.\n\n    :type public: bool\n    :param public: If True, the private key component (if present) will\n        be discarded, so this function will always return a public key.\n\n    :type passwordCallback: callable\n    :param passwordCallback: This function will be called, with no\n        arguments, if the PEM-encoded private key is password-encrypted.\n        The callback should return the password string.  If the password is\n        incorrect, SyntaxError will be raised.  If no callback is passed\n        and the key is password-encrypted, a prompt will be displayed at\n        the console.\n\n    :rtype: ~tlslite.utils.rsakey.RSAKey\n    :returns: An RSA key.\n\n    :raises SyntaxError: If the key is not properly formatted.\n    \"\"\"\n    # as old versions of openssl can't handle RSA-PSS or ECDSA keys, first\n    # try to detect what kind of key it is (we ignore errors as the python\n    # code can't handle encrypted key files while m2crypto/openssl can)\n    key_type = \"rsa\"\n    try:\n        key = Python_RSAKey.parsePEM(s)\n        key_type = key.key_type\n        del key\n    except Exception:\n        pass\n\n    for implementation in implementations:\n        if implementation == \"openssl\" and cryptomath.m2cryptoLoaded \\\n                and key_type == \"rsa\":\n            key = OpenSSL_RSAKey.parse(s, passwordCallback)\n            break\n        elif implementation == \"python\":\n            key = Python_RSAKey.parsePEM(s)\n            break\n    else:\n        raise ValueError(\"No acceptable implementations\")\n\n    return _parseKeyHelper(key, private, public)\n\n\ndef _parseKeyHelper(key, private, public):\n    if private and not key.hasPrivateKey():\n        raise SyntaxError(\"Not a private key!\")\n\n    if public:\n        return _createPublicKey(key)\n\n    if private:\n        if cryptomath.m2cryptoLoaded:\n            if type(key) == Python_RSAKey:\n                return _createPrivateKey(key)\n            assert type(key) in (OpenSSL_RSAKey, Python_ECDSAKey,\n                Python_DSAKey, Python_EdDSAKey), type(key)\n            return key\n        elif hasattr(key, \"d\"):\n            return _createPrivateKey(key)\n    return key\n\n\ndef parseAsPublicKey(s):\n    \"\"\"Parse a PEM-formatted public key.\n\n    :type s: str\n    :param s: A string containing a PEM-encoded public or private key.\n\n    :rtype: ~tlslite.utils.rsakey.RSAKey\n    :returns: An RSA public key.\n\n    :raises SyntaxError: If the key is not properly formatted.\n    \"\"\"\n    return parsePEMKey(s, public=True)\n\ndef parsePrivateKey(s):\n    \"\"\"Parse a PEM-formatted private key.\n\n    :type s: str\n    :param s: A string containing a PEM-encoded private key.\n\n    :rtype: ~tlslite.utils.rsakey.RSAKey\n    :returns: An RSA private key.\n\n    :raises SyntaxError: If the key is not properly formatted.\n    \"\"\"\n    return parsePEMKey(s, private=True)\n\ndef _createPublicKey(key):\n    \"\"\"\n    Create a new public key.  Discard any private component,\n    and return the most efficient key possible.\n    \"\"\"\n    if not isinstance(key, RSAKey):\n        raise AssertionError()\n    return _createPublicRSAKey(key.n, key.e, key.key_type)\n\ndef _createPrivateKey(key):\n    \"\"\"\n    Create a new private key.  Return the most efficient key possible.\n    \"\"\"\n    if not isinstance(key, RSAKey):\n        raise AssertionError()\n    if not key.hasPrivateKey():\n        raise AssertionError()\n    return _createPrivateRSAKey(key.n, key.e, key.d, key.p, key.q, key.dP,\n                                key.dQ, key.qInv, key.key_type)\n\n# n, e, d, etc. are the names used in mathematical proofs for the variables\n# so using so short names makes it actually more readable\n# pylint: disable=invalid-name\ndef _createPublicRSAKey(n, e, key_type,\n                        implementations=(\"openssl\", \"pycrypto\", \"python\")):\n    for implementation in implementations:\n        if implementation == \"openssl\" and cryptomath.m2cryptoLoaded:\n            return OpenSSL_RSAKey(n, e, key_type=key_type)\n        elif implementation == \"pycrypto\" and cryptomath.pycryptoLoaded:\n            return PyCrypto_RSAKey(n, e, key_type=key_type)\n        elif implementation == \"python\":\n            return Python_RSAKey(n, e, key_type=key_type)\n    raise ValueError(\"No acceptable implementations\")\n\ndef _createPrivateRSAKey(n, e, d, p, q, dP, dQ, qInv, key_type,\n                         implementations=(\"pycrypto\", \"python\")):\n    for implementation in implementations:\n        if implementation == \"pycrypto\" and cryptomath.pycryptoLoaded:\n            return PyCrypto_RSAKey(n, e, d, p, q, dP, dQ, qInv,\n                                   key_type=key_type)\n        elif implementation == \"python\":\n            return Python_RSAKey(n, e, d, p, q, dP, dQ, qInv,\n                                 key_type=key_type)\n    raise ValueError(\"No acceptable implementations\")\n# pylint: enable=invalid-name\n\n\ndef _create_public_ecdsa_key(point_x, point_y, curve_name,\n                             implementations=(\"python\",)):\n    \"\"\"\n    Convert public key parameters into concrete implementation of verifier.\n\n    The public key in ECDSA is a point on elliptic curve, so it consists of\n    two integers that identify the point and the name of the curve on which\n    it needs to lie on.\n\n    :type point_x: int\n    :param point_x: the 'x' coordinate of the point\n    :type point_y: int\n    :param point_y: the 'y' coordinate of the point\n    :type curve_name: str\n    :param curve_name: well known name of the curve (e.g. 'NIST256p' or\n        'SECP256k1')\n    :type implementations: iterable of str\n    :param implementations: list of implementations that can be used as the\n        concrete implementation of the verifying key (only 'python' is\n        supported currently)\n    \"\"\"\n    for impl in implementations:\n        if impl == \"python\":\n            return Python_ECDSAKey(point_x, point_y, curve_name)\n    raise ValueError(\"No acceptable implementation\")\n\n\ndef _create_public_eddsa_key(public_key,\n                             implementations=(\"python\",)):\n    \"\"\"\n    Convert the python-ecdsa public key into concrete implementation of\n    verifier.\n    \"\"\"\n    for impl in implementations:\n        if impl == \"python\":\n            return Python_EdDSAKey(public_key)\n    raise ValueError(\"No acceptable implementation\")\n\n\ndef _create_public_dsa_key(p, q, g, y,\n                           implementations=(\"python\",)):\n    \"\"\"\n    Convert public key parameters into concrete implementation of verifier.\n\n    The public key in DSA consists of four integers.\n\n    :type p: int\n    :param p: domain parameter, prime num defining Gaolis Field\n    :type q: int\n    :param q: domain parameter, prime factor of p-1\n    :type g: int\n    :param g: domain parameter, generator of q-order cyclic group GP(p)\n    :type y: int\n    :param y: public key\n    :type implementations: iterable of str\n    :param implementations: list of implementations that can be used as the\n        concrete implementation of the verifying key (only 'python' is\n        supported currently)\n    \"\"\"\n    for impl in implementations:\n        if impl == \"python\":\n            return Python_DSAKey(p=p, q=q, g=g, y=y)\n    raise ValueError(\"No acceptable implementation\")\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/lists.py",
    "content": "# Authors:\n#   Hubert Kario (2016)\n#\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Helper functions for handling lists\"\"\"\n\nfrom itertools import chain\n\n\ndef getFirstMatching(values, matches):\n    \"\"\"\n    Return the first element in :py:obj:`values` that is also in\n    :py:obj:`matches`.\n\n    Return None if values is None, empty or no element in values is also in\n    matches.\n\n    :type values: collections.abc.Iterable\n    :param values: list of items to look through, can be None\n    :type matches: collections.abc.Container\n    :param matches: list of items to check against\n    \"\"\"\n    assert matches is not None\n    if not values:\n        return None\n    return next((i for i in values if i in matches), None)\n\n\ndef to_str_delimiter(values, delim=\", \", last_delim=\" or \"):\n    \"\"\"\n    Format the list as a human readable string.\n\n    Will format the list as a human readable enumeration, separated by commas\n    (changable with `delim`) with last value separated with \"or\" (changable\n    with `last_delim`).\n\n    :type values: collections.abc.Iterable\n    :param values: list of items to concatenate\n    :type delim: str\n    :param delim: primary delimiter for objects, comma by default\n    :type last_delim: str\n    :param last_delim: delimiter for last object in list\n    :rtype: str\n    \"\"\"\n    # we need to slice the iterator, so we need a copy\n    values = list(values)\n    return delim.join(chain((str(i) for i in values[:-2]),\n                            [last_delim.join(str(i) for i in values[-2:])]))\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/openssl_aes.py",
    "content": "# Author: Trevor Perrin\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"OpenSSL/M2Crypto AES implementation.\"\"\"\n\nfrom .cryptomath import *\nfrom .aes import *\nfrom .python_aes import Python_AES_CTR\n\nif m2cryptoLoaded:\n\n    def new(key, mode, IV):\n        # IV argument name is a part of the interface\n        # pylint: disable=invalid-name\n        \"\"\"\n        Try using AES CTR from m2crpyto,\n        if it is not available fall back to the\n        python implementation.\n        \"\"\"\n        if mode == 2:\n            return OpenSSL_AES(key, mode, IV)\n        elif mode == 6:\n            if M2CRYPTO_AES_CTR:\n                return OpenSSL_CTR(key, mode, IV)\n            return Python_AES_CTR(key, mode, IV)\n        else:\n            raise NotImplementedError()\n\n\n    class OpenSSL_AES(AES):\n\n        def __init__(self, key, mode, IV):\n            # IV argument/field names are a part of the interface\n            # pylint: disable=invalid-name\n            AES.__init__(self, key, mode, IV, \"openssl\")\n            self._IV, self._key = IV, key\n            self._context = None\n            self._encrypt = None\n\n        @property\n        def IV(self):\n            return self._IV\n\n        @IV.setter\n        def IV(self, iv):\n            if self._context is not None:\n                m2.cipher_ctx_free(self._context)\n            self._IV = iv\n            self._init_context()\n\n        def _init_context(self, encrypt=True):\n            if len(self._key) == 16:\n                cipherType = m2.aes_128_cbc()\n            if len(self._key) == 24:\n                cipherType = m2.aes_192_cbc()\n            if len(self._key) == 32:\n                cipherType = m2.aes_256_cbc()\n            self._context = m2.cipher_ctx_new()\n            m2.cipher_init(self._context, cipherType, self._key, self._IV,\n                           int(encrypt))\n            m2.cipher_set_padding(self._context, 0)\n            self._encrypt = encrypt\n\n        def encrypt(self, plaintext):\n            if self._context is None:\n                self._init_context(encrypt=True)\n            else:\n                assert self._encrypt, '.encrypt() not allowed after .decrypt()'\n            AES.encrypt(self, plaintext)\n            ciphertext = m2.cipher_update(self._context, plaintext)\n            return bytearray(ciphertext)\n\n        def decrypt(self, ciphertext):\n            if self._context is None:\n                self._init_context(encrypt=False)\n            else:\n                assert not self._encrypt, \\\n                       '.decrypt() not allowed after .encrypt()'\n            AES.decrypt(self, ciphertext)\n            plaintext = m2.cipher_update(self._context, ciphertext)\n            return bytearray(plaintext)\n\n        def __del__(self):\n            if self._context is not None:\n                m2.cipher_ctx_free(self._context)\n\n\n    class OpenSSL_CTR(AES):\n\n        def __init__(self, key, mode, IV):\n            # IV argument/field names are a part of the interface\n            # pylint: disable=invalid-name\n            AES.__init__(self, key, mode, IV, \"openssl\")\n            self._IV = IV\n            self.key = key\n            self._context = None\n            self._encrypt = None\n            if len(key) not in (16, 24, 32):\n                raise AssertionError()\n\n        @property\n        def counter(self):\n            return self._IV\n\n        @counter.setter\n        def counter(self, ctr):\n            if self._context is not None:\n                m2.cipher_ctx_free(self._context)\n            self._IV = ctr\n            self._init_context()\n\n        def _init_context(self, encrypt=True):\n            if len(self.key) == 16:\n                cipherType = m2.aes_128_ctr()\n            if len(self.key) == 24:\n                cipherType = m2.aes_192_ctr()\n            if len(self.key) == 32:\n                cipherType = m2.aes_256_ctr()\n            self._context = m2.cipher_ctx_new()\n            m2.cipher_init(self._context, cipherType, self.key, self._IV,\n                           int(encrypt))\n            m2.cipher_set_padding(self._context, 0)\n            self._encrypt = encrypt\n\n        def encrypt(self, plaintext):\n            ciphertext = m2.cipher_update(self._context, plaintext)\n            return bytearray(ciphertext)\n\n        def decrypt(self, ciphertext):\n            plaintext = m2.cipher_update(self._context, ciphertext)\n            return bytearray(plaintext)\n\n        def __del__(self):\n            if self._context is not None:\n                m2.cipher_ctx_free(self._context)\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/openssl_aesccm.py",
    "content": "# Author: Ivan Nikolchev\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"AESCCM with CTR and CBC from m2crypto\"\"\"\n\nfrom tlslite.utils.cryptomath import m2cryptoLoaded\nfrom tlslite.utils.aesccm import AESCCM\nfrom tlslite.utils import openssl_aes\n\n\nif m2cryptoLoaded:\n    def new(key, tagLength=16):\n        return OPENSSL_AESCCM(key, \"openssl\", bytearray(16), tagLength)\n\n\nclass OPENSSL_AESCCM(AESCCM):\n    def __init__(self, key, implementation, rawAesEncrypt, tagLength):\n        super(OPENSSL_AESCCM, self).__init__(key, implementation, rawAesEncrypt, tagLength)\n\n        self._ctr = openssl_aes.new(key, 6, bytearray(b'\\x00' * 16))\n        self._cbc = openssl_aes.new(key, 2, bytearray(b'\\x00' * 16))\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/openssl_aesgcm.py",
    "content": "# Author: Ivan Nikolchev\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"AESGCM with CTR from m2crypto\"\"\"\n\nfrom tlslite.utils.cryptomath import m2cryptoLoaded\nfrom tlslite.utils.aesgcm import AESGCM\nfrom tlslite.utils import openssl_aes\nfrom tlslite.utils.rijndael import Rijndael\n\nif m2cryptoLoaded:\n    def new(key):\n        return OPENSSL_AESGCM(key, \"openssl\", Rijndael(key, 16).encrypt)\n\n\nclass OPENSSL_AESGCM(AESGCM):\n    def __init__(self, key, implementation, rawAesEncrypt):\n        super(OPENSSL_AESGCM, self).__init__(key, implementation, rawAesEncrypt)\n\n        self._ctr = openssl_aes.new(key, 6, bytearray(b'\\x00' * 16))\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/openssl_rc4.py",
    "content": "# Author: Trevor Perrin\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"OpenSSL/M2Crypto RC4 implementation.\"\"\"\n\nfrom .cryptomath import *\nfrom .rc4 import RC4\n\nif m2cryptoLoaded:\n\n    def new(key):\n        return OpenSSL_RC4(key)\n\n    class OpenSSL_RC4(RC4):\n\n        def __init__(self, key):\n            RC4.__init__(self, key, \"openssl\")\n            self.rc4 = m2.rc4_new()\n            m2.rc4_set_key(self.rc4, key)\n\n        def __del__(self):\n            m2.rc4_free(self.rc4)\n\n        def encrypt(self, plaintext):\n            return bytearray(m2.rc4_update(self.rc4, plaintext))\n\n        def decrypt(self, ciphertext):\n            return bytearray(self.encrypt(ciphertext))\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/openssl_rsakey.py",
    "content": "# Author: Trevor Perrin\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"OpenSSL/M2Crypto RSA implementation.\"\"\"\n\nfrom .cryptomath import *\n\nfrom .rsakey import *\nfrom .python_rsakey import Python_RSAKey\nfrom .compat import compatAscii2Bytes, compat_b2a\n\n#copied from M2Crypto.util.py, so when we load the local copy of m2\n#we can still use it\ndef password_callback(v, prompt1='Enter private key passphrase:',\n                           prompt2='Verify passphrase:'):\n    from getpass import getpass\n    while 1:\n        try:\n            p1=getpass(prompt1)\n            if v:\n                p2=getpass(prompt2)\n                if p1==p2:\n                    break\n            else:\n                break\n        except KeyboardInterrupt:\n            return None\n    return p1\n\n\nif m2cryptoLoaded:\n    import M2Crypto\n\n    class OpenSSL_RSAKey(RSAKey):\n        def __init__(self, n=0, e=0, key_type=\"rsa\"):\n            self.rsa = None\n            self._hasPrivateKey = False\n            if (n and not e) or (e and not n):\n                raise AssertionError()\n            if n and e:\n                self.rsa = m2.rsa_new()\n                m2.rsa_set_n(self.rsa, numberToMPI(n))\n                m2.rsa_set_e(self.rsa, numberToMPI(e))\n            self.key_type = key_type\n\n        def __del__(self):\n            if self.rsa:\n                m2.rsa_free(self.rsa)\n\n        def __getattr__(self, name):\n            if name == 'e':\n                if not self.rsa:\n                    return 0\n                return mpiToNumber(m2.rsa_get_e(self.rsa))\n            elif name == 'n':\n                if not self.rsa:\n                    return 0\n                return mpiToNumber(m2.rsa_get_n(self.rsa))\n            else:\n                raise AttributeError\n\n        def hasPrivateKey(self):\n            return self._hasPrivateKey\n\n        def _rawPrivateKeyOp(self, message):\n            data = numberToByteArray(message, numBytes(self.n))\n            string = m2.rsa_private_encrypt(self.rsa, bytes(data),\n                                            m2.no_padding)\n            ciphertext = bytesToNumber(bytearray(string))\n            return ciphertext\n\n        def _raw_private_key_op_bytes(self, message):\n            return self._call_m2crypto(\n                m2.rsa_private_encrypt, message,\n                \"Bad parameters to private key operation\")\n\n        def _rawPublicKeyOp(self, ciphertext):\n            data = numberToByteArray(ciphertext, numBytes(self.n))\n            string = m2.rsa_public_decrypt(self.rsa, bytes(data),\n                                           m2.no_padding)\n            message = bytesToNumber(bytearray(string))\n            return message\n\n        def _call_m2crypto(self, method, param, err_msg):\n            try:\n                return bytearray(method(self.rsa, bytes(param), m2.no_padding))\n            except M2Crypto.RSA.RSAError:\n                raise ValueError(err_msg)\n\n        def _raw_public_key_op_bytes(self, ciphertext):\n            return self._call_m2crypto(\n                m2.rsa_public_decrypt, ciphertext,\n                \"Bad parameters to public key operation\")\n\n        def acceptsPassword(self): return True\n\n        def write(self, password=None):\n            bio = m2.bio_new(m2.bio_s_mem())\n            if self._hasPrivateKey:\n                if password:\n                    def f(v): return password\n                    m2.rsa_write_key(self.rsa, bio, m2.des_ede_cbc(), f)\n                else:\n                    def f(): pass\n                    m2.rsa_write_key_no_cipher(self.rsa, bio, f)\n            else:\n                if password:\n                    raise AssertionError()\n                m2.rsa_write_pub_key(self.rsa, bio)\n            s = m2.bio_read(bio, m2.bio_ctrl_pending(bio))\n            m2.bio_free(bio)\n            return s\n\n        @staticmethod\n        def generate(bits, key_type=\"rsa\"):\n            key = OpenSSL_RSAKey()\n            def f():pass\n            key.rsa = m2.rsa_generate_key(bits, 3, f)\n            key._hasPrivateKey = True\n            key.key_type = key_type\n            b64_key = compat_b2a(key.write())\n            py_key = Python_RSAKey.parsePEM(b64_key)\n            key.d = py_key.d\n            return key\n\n        @staticmethod\n        def parse(s, passwordCallback=None):\n            # Skip forward to the first PEM header\n            start = s.find(\"-----BEGIN \")\n            if start == -1:\n                raise SyntaxError()\n            s = s[start:]            \n            if s.startswith(\"-----BEGIN \"):\n                if passwordCallback==None:\n                    callback = password_callback\n                else:\n                    def f(v, prompt1=None, prompt2=None):\n                        return passwordCallback()\n                    callback = f\n                bio = m2.bio_new(m2.bio_s_mem())\n                try:\n                    m2.bio_write(bio, compatAscii2Bytes(s))\n                    key = OpenSSL_RSAKey()\n                    # parse SSLay format PEM file\n                    if s.startswith(\"-----BEGIN RSA PRIVATE KEY-----\"):\n                        def f():pass\n                        key.rsa = m2.rsa_read_key(bio, callback)\n                        if key.rsa == None:\n                            raise SyntaxError()\n                        key._hasPrivateKey = True\n                    # parse a standard PKCS#8 PEM file\n                    elif s.startswith(\"-----BEGIN PRIVATE KEY-----\"):\n                        def f():pass\n                        key.rsa = m2.pkey_read_pem(bio, callback)\n                        # the below code assumes RSA key while PKCS#8 files\n                        # (and by extension the EVP_PKEY structure) can be\n                        # also DSA or EC, thus the double check against None\n                        # (first if the file was properly loaded and second\n                        # if the file actually has a RSA key in it)\n                        # tlslite doesn't support DSA or EC so it's useless\n                        # to handle them in a different way\n                        if key.rsa == None:\n                            raise SyntaxError()\n                        key.rsa = m2.pkey_get1_rsa(key.rsa)\n                        if key.rsa == None:\n                            raise SyntaxError()\n                        key._hasPrivateKey = True\n                    elif s.startswith(\"-----BEGIN PUBLIC KEY-----\"):\n                        key.rsa = m2.rsa_read_pub_key(bio)\n                        if key.rsa == None:\n                            raise SyntaxError()\n                        key._hasPrivateKey = False\n                    else:\n                        raise SyntaxError()\n                    if key._hasPrivateKey:\n                        b64_key = compat_b2a(key.write())\n                        py_key = Python_RSAKey.parsePEM(b64_key)\n                        key.d = py_key.d\n                    return key\n                finally:\n                    m2.bio_free(bio)\n            else:\n                raise SyntaxError()\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/openssl_tripledes.py",
    "content": "# Author: Trevor Perrin\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"OpenSSL/M2Crypto 3DES implementation.\"\"\"\n\nfrom .cryptomath import *\nfrom .tripledes import *\n\nif m2cryptoLoaded:\n\n    def new(key, mode, IV):\n        return OpenSSL_TripleDES(key, mode, IV)\n\n    class OpenSSL_TripleDES(TripleDES):\n\n        def __init__(self, key, mode, IV):\n            TripleDES.__init__(self, key, mode, IV, \"openssl\")\n            self._IV, self._key = IV, key\n            self._context = None\n            self._encrypt = None\n\n        def _init_context(self, encrypt=True):\n            cipherType = m2.des_ede3_cbc()\n            self._context = m2.cipher_ctx_new()\n            m2.cipher_init(self._context, cipherType, self._key, self._IV,\n                           int(encrypt))\n            m2.cipher_set_padding(self._context, 0)\n            self._encrypt = encrypt\n\n        def encrypt(self, plaintext):\n            if self._context is None:\n                self._init_context(encrypt=True)\n            else:\n                assert self._encrypt, '.encrypt() not allowed after .decrypt()'\n            TripleDES.encrypt(self, plaintext)\n            ciphertext = m2.cipher_update(self._context, plaintext)\n            return bytearray(ciphertext)\n\n        def decrypt(self, ciphertext):\n            if self._context is None:\n                self._init_context(encrypt=False)\n            else:\n                assert not self._encrypt, \\\n                       '.decrypt() not allowed after .encrypt()'\n            TripleDES.decrypt(self, ciphertext)\n            plaintext = m2.cipher_update(self._context, ciphertext)\n            return bytearray(plaintext)\n\n        def __del__(self):\n            if self._context is not None:\n                m2.cipher_ctx_free(self._context)\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/pem.py",
    "content": "# Author: Trevor Perrin\n# See the LICENSE file for legal information regarding use of this file.\n\nfrom .compat import *\nimport binascii\n\n#This code is shared with tackpy (somewhat), so I'd rather make minimal\n#changes, and preserve the use of a2b_base64 throughout.\n\ndef dePem(s, name):\n    \"\"\"Decode a PEM string into a bytearray of its payload.\n    \n    The input must contain an appropriate PEM prefix and postfix\n    based on the input name string, e.g. for name=\"CERTIFICATE\"::\n\n      -----BEGIN CERTIFICATE-----\n      MIIBXDCCAUSgAwIBAgIBADANBgkqhkiG9w0BAQUFADAPMQ0wCwYDVQQDEwRUQUNL\n      ...\n      KoZIhvcNAQEFBQADAwA5kw==\n      -----END CERTIFICATE-----\n\n    The first such PEM block in the input will be found, and its\n    payload will be base64 decoded and returned.\n    \"\"\"\n    prefix  = \"-----BEGIN %s-----\" % name\n    postfix = \"-----END %s-----\" % name    \n    start = s.find(prefix)\n    if start == -1:\n        raise SyntaxError(\"Missing PEM prefix\")\n    end = s.find(postfix, start+len(prefix))\n    if end == -1:\n        raise SyntaxError(\"Missing PEM postfix\")\n    s = s[start+len(\"-----BEGIN %s-----\" % name) : end]\n    retBytes = a2b_base64(s) # May raise SyntaxError\n    return retBytes\n    \ndef dePemList(s, name):\n    \"\"\"Decode a sequence of PEM blocks into a list of bytearrays.\n\n    The input must contain any number of PEM blocks, each with the appropriate\n    PEM prefix and postfix based on the input name string, e.g. for\n    name=\"TACK BREAK SIG\".  Arbitrary text can appear between and before and\n    after the PEM blocks.  For example::\n\n        Created by TACK.py 0.9.3 Created at 2012-02-01T00:30:10Z\n        -----BEGIN TACK BREAK SIG-----\n        ATKhrz5C6JHJW8BF5fLVrnQss6JnWVyEaC0p89LNhKPswvcC9/s6+vWLd9snYTUv\n        YMEBdw69PUP8JB4AdqA3K6Ap0Fgd9SSTOECeAKOUAym8zcYaXUwpk0+WuPYa7Zmm\n        SkbOlK4ywqt+amhWbg9txSGUwFO5tWUHT3QrnRlE/e3PeNFXLx5Bckg=\n        -----END TACK BREAK SIG-----\n        Created by TACK.py 0.9.3 Created at 2012-02-01T00:30:11Z\n        -----BEGIN TACK BREAK SIG-----\n        ATKhrz5C6JHJW8BF5fLVrnQss6JnWVyEaC0p89LNhKPswvcC9/s6+vWLd9snYTUv\n        YMEBdw69PUP8JB4AdqA3K6BVCWfcjN36lx6JwxmZQncS6sww7DecFO/qjSePCxwM\n        +kdDqX/9/183nmjx6bf0ewhPXkA0nVXsDYZaydN8rJU1GaMlnjcIYxY=\n        -----END TACK BREAK SIG-----\n    \n    All such PEM blocks will be found, decoded, and return in an ordered list\n    of bytearrays, which may have zero elements if not PEM blocks are found.\n    \"\"\"\n    bList = []\n    prefix  = \"-----BEGIN %s-----\" % name\n    postfix = \"-----END %s-----\" % name\n    while 1:\n        start = s.find(prefix)\n        if start == -1:\n            return bList\n        end = s.find(postfix, start+len(prefix))\n        if end == -1:\n            raise SyntaxError(\"Missing PEM postfix\")\n        s2 = s[start+len(prefix) : end]\n        retBytes = a2b_base64(s2) # May raise SyntaxError\n        bList.append(retBytes)\n        s = s[end+len(postfix) : ]\n\ndef pem(b, name):\n    \"\"\"Encode a payload bytearray into a PEM string.\n    \n    The input will be base64 encoded, then wrapped in a PEM prefix/postfix\n    based on the name string, e.g. for name=\"CERTIFICATE\"::\n    \n        -----BEGIN CERTIFICATE-----\n        MIIBXDCCAUSgAwIBAgIBADANBgkqhkiG9w0BAQUFADAPMQ0wCwYDVQQDEwRUQUNL\n        ...\n        KoZIhvcNAQEFBQADAwA5kw==\n        -----END CERTIFICATE-----\n    \"\"\"\n    s1 = b2a_base64(b)[:-1] # remove terminating \\n\n    s2 = \"\"\n    while s1:\n        s2 += s1[:64] + \"\\n\"\n        s1 = s1[64:]\n    s = (\"-----BEGIN %s-----\\n\" % name) + s2 + \\\n        (\"-----END %s-----\\n\" % name)     \n    return s\n\ndef pemSniff(inStr, name):\n    searchStr = \"-----BEGIN %s-----\" % name\n    return searchStr in inStr\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/poly1305.py",
    "content": "# Copyright (c) 2015, Hubert Kario\n#\n# See the LICENSE file for legal information regarding use of this file.\n\"\"\"Implementation of Poly1305 authenticator for RFC 7539\"\"\"\n\nfrom .cryptomath import divceil\n\nclass Poly1305(object):\n\n    \"\"\"Poly1305 authenticator\"\"\"\n\n    P = 0x3fffffffffffffffffffffffffffffffb # 2^130-5\n\n    @staticmethod\n    def le_bytes_to_num(data):\n        \"\"\"Convert a number from little endian byte format\"\"\"\n        ret = 0\n        for i in range(len(data) - 1, -1, -1):\n            ret <<= 8\n            ret += data[i]\n        return ret\n\n    @staticmethod\n    def num_to_16_le_bytes(num):\n        \"\"\"Convert number to 16 bytes in little endian format\"\"\"\n        ret = [0]*16\n        for i, _ in enumerate(ret):\n            ret[i] = num & 0xff\n            num >>= 8\n        return bytearray(ret)\n\n    def __init__(self, key):\n        \"\"\"Set the authenticator key\"\"\"\n        if len(key) != 32:\n            raise ValueError(\"Key must be 256 bit long\")\n        self.acc = 0\n        self.r = self.le_bytes_to_num(key[0:16])\n        self.r &= 0x0ffffffc0ffffffc0ffffffc0fffffff\n        self.s = self.le_bytes_to_num(key[16:32])\n\n    def create_tag(self, data):\n        \"\"\"Calculate authentication tag for data\"\"\"\n        for i in range(0, divceil(len(data), 16)):\n            n = self.le_bytes_to_num(data[i*16:(i+1)*16] + b'\\x01')\n            self.acc += n\n            self.acc = (self.r * self.acc) % self.P\n        self.acc += self.s\n        return self.num_to_16_le_bytes(self.acc)\n\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/pycrypto_aes.py",
    "content": "# Author: Trevor Perrin\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"PyCrypto AES implementation.\"\"\"\n\nfrom .cryptomath import *\nfrom .aes import *\n\nif pycryptoLoaded:\n    import Crypto.Cipher.AES\n\n    def new(key, mode, IV):\n        return PyCrypto_AES(key, mode, IV)\n\n    class PyCrypto_AES(AES):\n\n        def __init__(self, key, mode, IV):\n            AES.__init__(self, key, mode, IV, \"pycrypto\")\n            key = bytes(key)\n            IV = bytes(IV)\n            self.context = Crypto.Cipher.AES.new(key, mode, IV)\n\n        def encrypt(self, plaintext):\n            plaintext = bytes(plaintext)\n            return bytearray(self.context.encrypt(plaintext))\n\n        def decrypt(self, ciphertext):\n            ciphertext = bytes(ciphertext)\n            return bytearray(self.context.decrypt(ciphertext))\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/pycrypto_aesgcm.py",
    "content": "# Author: Google\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"PyCrypto AES-GCM implementation.\"\"\"\n\nfrom .cryptomath import *\nfrom .aesgcm import AESGCM\n\nif pycryptoLoaded:\n    import Crypto.Cipher.AES\n\n    def new(key):\n        cipher = Crypto.Cipher.AES.new(bytes(key))\n        def encrypt(plaintext):\n            return bytearray(cipher.encrypt(bytes(plaintext)))\n        return AESGCM(key, \"pycrypto\", encrypt)\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/pycrypto_rc4.py",
    "content": "# Author: Trevor Perrin\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"PyCrypto RC4 implementation.\"\"\"\n\nfrom .cryptomath import *\nfrom .rc4 import *\n\nif pycryptoLoaded:\n    import Crypto.Cipher.ARC4\n\n    def new(key):\n        return PyCrypto_RC4(key)\n\n    class PyCrypto_RC4(RC4):\n\n        def __init__(self, key):\n            RC4.__init__(self, key, \"pycrypto\")\n            key = bytes(key)\n            self.context = Crypto.Cipher.ARC4.new(key)\n\n        def encrypt(self, plaintext):\n            plaintext = bytes(plaintext)\n            return bytearray(self.context.encrypt(plaintext))\n\n        def decrypt(self, ciphertext):\n            ciphertext = bytes(ciphertext)\n            return bytearray(self.context.decrypt(ciphertext))"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/pycrypto_rsakey.py",
    "content": "# Author: Trevor Perrin\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"PyCrypto RSA implementation.\"\"\"\n\nfrom __future__ import print_function\nimport sys\n\nfrom .cryptomath import *\n\nfrom .rsakey import *\nfrom .python_rsakey import Python_RSAKey\nfrom .compat import compatLong\n\nif pycryptoLoaded:\n\n    from Crypto.PublicKey import RSA\n\n    class PyCrypto_RSAKey(RSAKey):\n        def __init__(self, n=0, e=0, d=0, p=0, q=0, dP=0, dQ=0, qInv=0,\n                     key_type=\"rsa\"):\n            del dP, dQ, qInv  # pycrypto calculates them by its own\n            if not d:\n                self.rsa = RSA.construct((compatLong(n), compatLong(e)))\n            else:\n                self.rsa = RSA.construct((compatLong(n), compatLong(e),\n                                          compatLong(d), compatLong(p),\n                                          compatLong(q)))\n            self.key_type = key_type\n\n        def __getattr__(self, name):\n            return getattr(self.rsa, name)\n\n        def hasPrivateKey(self):\n            return self.rsa.has_private()\n\n        def _rawPrivateKeyOp(self, message):\n            try:\n                return self.rsa.decrypt((compatLong(message),))\n            except ValueError as e:\n                print(\"rsa: {0!r}\".format(self.rsa), file=sys.stderr)\n                values = []\n                for name in [\"n\", \"e\", \"d\", \"p\", \"q\", \"dP\", \"dQ\", \"qInv\"]:\n                    values.append(\"{0}: {1}\".format(name,\n                                                    getattr(self, name, None)))\n                print(\", \".join(values), file=sys.stderr)\n                print(\"message: {0}\".format(message), file=sys.stderr)\n                raise\n\n\n        def _rawPublicKeyOp(self, ciphertext):\n            try:\n                return self.rsa.encrypt(compatLong(ciphertext), None)[0]\n            except ValueError as e:\n                print(\"rsa: {0!r}\".format(self.rsa), file=sys.stderr)\n                values = []\n                for name in [\"n\", \"e\", \"d\", \"p\", \"q\", \"dP\", \"dQ\", \"qInv\"]:\n                    values.append(\"{0}: {1}\".format(name,\n                                                    getattr(self, name, None)))\n                print(\", \".join(values), file=sys.stderr)\n                print(\"ciphertext: {0}\".format(ciphertext), file=sys.stderr)\n                raise\n\n        @staticmethod\n        def generate(bits, key_type=\"rsa\"):\n            key = PyCrypto_RSAKey()\n            def f(numBytes):\n                return bytes(getRandomBytes(numBytes))\n            key.rsa = RSA.generate(bits, f)\n            key.key_type = key_type\n            return key\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/pycrypto_tripledes.py",
    "content": "# Author: Trevor Perrin\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"PyCrypto 3DES implementation.\"\"\"\n\nfrom .cryptomath import *\nfrom .tripledes import *\n\nif pycryptoLoaded:\n    import Crypto.Cipher.DES3\n\n    def new(key, mode, IV):\n        return PyCrypto_TripleDES(key, mode, IV)\n\n    class PyCrypto_TripleDES(TripleDES):\n\n        def __init__(self, key, mode, IV):\n            TripleDES.__init__(self, key, mode, IV, \"pycrypto\")\n            key = bytes(key)\n            IV = bytes(IV)\n            self.context = Crypto.Cipher.DES3.new(key, mode, IV)\n\n        def encrypt(self, plaintext):\n            plaintext = bytes(plaintext)\n            return bytearray(self.context.encrypt(plaintext))\n\n        def decrypt(self, ciphertext):\n            ciphertext = bytes(ciphertext)\n            return bytearray(self.context.decrypt(ciphertext))"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/python_aes.py",
    "content": "# Author: Trevor Perrin\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Pure-Python AES implementation.\"\"\"\n\nfrom .aes import AES\nfrom .rijndael import Rijndael\nfrom .cryptomath import bytesToNumber, numberToByteArray\n\n__all__ = ['new', 'Python_AES']\n\n\ndef new(key, mode, IV):\n    # IV argument name is a part of the interface\n    # pylint: disable=invalid-name\n    if mode == 2:\n        return Python_AES(key, mode, IV)\n    elif mode == 6:\n        return Python_AES_CTR(key, mode, IV)\n    else:\n        raise NotImplementedError()\n\n\nclass Python_AES(AES):\n    def __init__(self, key, mode, IV):\n        # IV argument/field names are a part of the interface\n        # pylint: disable=invalid-name\n        key, IV = bytearray(key), bytearray(IV)\n        super(Python_AES, self).__init__(key, mode, IV, \"python\")\n        self.rijndael = Rijndael(key, 16)\n        self.IV = IV\n\n    def encrypt(self, plaintext):\n        super(Python_AES, self).encrypt(plaintext)\n\n        plaintextBytes = bytearray(plaintext)\n        chainBytes = self.IV[:]\n\n        #CBC Mode: For each block...\n        for x in range(len(plaintextBytes)//16):\n\n            #XOR with the chaining block\n            blockBytes = plaintextBytes[x*16 : (x*16)+16]\n            for y in range(16):\n                blockBytes[y] ^= chainBytes[y]\n\n            #Encrypt it\n            encryptedBytes = self.rijndael.encrypt(blockBytes)\n\n            #Overwrite the input with the output\n            for y in range(16):\n                plaintextBytes[(x*16)+y] = encryptedBytes[y]\n\n            #Set the next chaining block\n            chainBytes = encryptedBytes\n\n        self.IV = chainBytes[:]\n        return plaintextBytes\n\n    def decrypt(self, ciphertext):\n        super(Python_AES, self).decrypt(ciphertext)\n\n        ciphertextBytes = ciphertext[:]\n        chainBytes = self.IV[:]\n\n        #CBC Mode: For each block...\n        for x in range(len(ciphertextBytes)//16):\n\n            #Decrypt it\n            blockBytes = ciphertextBytes[x*16 : (x*16)+16]\n            decryptedBytes = self.rijndael.decrypt(blockBytes)\n\n            #XOR with the chaining block and overwrite the input with output\n            for y in range(16):\n                decryptedBytes[y] ^= chainBytes[y]\n                ciphertextBytes[(x*16)+y] = decryptedBytes[y]\n\n            #Set the next chaining block\n            chainBytes = blockBytes\n\n        self.IV = chainBytes[:]\n        return ciphertextBytes\n\n\nclass Python_AES_CTR(AES):\n    def __init__(self, key, mode, IV):\n        super(Python_AES_CTR, self).__init__(key, mode, IV, \"python\")\n        self.rijndael = Rijndael(key, 16)\n        self.IV = IV\n        self._counter_bytes = 16 - len(self.IV)\n        self._counter = self.IV + bytearray(b'\\x00' * self._counter_bytes)\n\n    @property\n    def counter(self):\n        return self._counter\n\n    @counter.setter\n    def counter(self, ctr):\n        self._counter = ctr\n\n    def _counter_update(self):\n        counter_int = bytesToNumber(self._counter) + 1\n        self._counter = numberToByteArray(counter_int, 16)\n        if self._counter_bytes > 0 and \\\n                self._counter[-self._counter_bytes:] == \\\n                bytearray(b'\\xff' * self._counter_bytes):\n            raise OverflowError(\"CTR counter overflowed\")\n\n    def encrypt(self, plaintext):\n\n        mask = bytearray()\n        while len(mask) < len(plaintext):\n            mask += self.rijndael.encrypt(self._counter)\n            self._counter_update()\n        inp_bytes = bytearray(i ^ j for i, j in zip(plaintext, mask))\n        return inp_bytes\n\n    def decrypt(self, ciphertext):\n        return self.encrypt(ciphertext)\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/python_aesccm.py",
    "content": "# Author: Ivan Nikolchev\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\" Pure Python AES-CCM implementation.\"\"\"\n\nfrom tlslite.utils.aesccm import AESCCM\n\ndef new(key, tagLength=16):\n    return AESCCM(key, \"python\", bytearray(16), tagLength)\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/python_aesgcm.py",
    "content": "# Author: Google\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Pure-Python AES-GCM implementation.\"\"\"\n\nfrom .aesgcm import AESGCM\nfrom .rijndael import Rijndael\n\n\ndef new(key):\n    return AESGCM(key, \"python\", Rijndael(key, 16).encrypt)\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/python_chacha20_poly1305.py",
    "content": "# Author: Hubert Kario (c) 2015\n#\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Pure-Python ChaCha20/Poly1305 implementation.\"\"\"\n\nfrom .chacha20_poly1305 import CHACHA20_POLY1305\n\ndef new(key):\n    \"\"\"Return an AEAD cipher implementation\"\"\"\n    return CHACHA20_POLY1305(key, \"python\")\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/python_dsakey.py",
    "content": "# Author: Frantisek Krenzelok\n\"\"\"Pure-Python RSA implementation.\"\"\"\nfrom ecdsa.der import encode_sequence, encode_integer,  \\\n    remove_sequence, remove_integer\n\nfrom .cryptomath import getRandomNumber, getRandomPrime,    \\\n    powMod, numBits, bytesToNumber, invMod,   \\\n    secureHash, GMPY2_LOADED, gmpyLoaded\n\nfrom .compat import compatHMAC\n\nif GMPY2_LOADED:\n    from gmpy2 import mpz\nelif gmpyLoaded:\n    from gmpy import mpz\n\nfrom .dsakey import DSAKey\n\nclass Python_DSAKey(DSAKey):\n    \"\"\"\n    Concrete implementaion of DSA object.\n    for func docstring see tlslite/dsakey.py\n    \"\"\"\n    def __init__(self, p=0, q=0, g=0, x=0, y=0):\n        if gmpyLoaded or GMPY2_LOADED:\n            p = mpz(p)\n            q = mpz(q)\n            g = mpz(g)\n            x = mpz(x)\n            y = mpz(y)\n        self.p = p\n        self.q = q\n        self.g = g\n        self.private_key = x\n        self.public_key = y\n        self.key_type = \"dsa\"\n\n        if p and q and p < q:\n            raise ValueError(\"q is greater than p\")\n\n    def __len__(self):\n        return numBits(self.p)\n\n    def hasPrivateKey(self):\n        return bool(self.private_key)\n\n    @staticmethod\n    def generate(L, N):\n        assert (L, N) in [(1024, 160), (2048, 224), (2048, 256), (3072, 256)]\n        key = Python_DSAKey()\n        (q, p) = Python_DSAKey.generate_qp(L, N)\n\n        index = getRandomNumber(1, (p-1))\n        g = powMod(index, int((p-1)/q), p)\n        x = getRandomNumber(1, q-1)\n        y = powMod(g, x, p)\n        if gmpyLoaded or GMPY2_LOADED:\n            p = mpz(p)\n            q = mpz(q)\n            g = mpz(g)\n            x = mpz(x)\n            y = mpz(y)\n        key.q = q\n        key.p = p\n        key.g = g\n        key.private_key = x\n        key.public_key = y\n        return key\n\n    @staticmethod\n    def generate_qp(L, N):\n        assert (L, N) in [(1024, 160), (2048, 224), (2048, 256), (3072, 256)]\n\n        q = int(getRandomPrime(N))\n        while True:\n            p = int(getRandomPrime(L))\n            if (p-1) % q:\n                break\n        return (q, p)\n\n    def hashAndSign(self, data, hAlg=\"sha1\"):\n        hashData = (secureHash(bytearray(data), hAlg))\n        return self.sign(hashData)\n\n    def sign(self, data):\n        N = numBits(self.q)\n        digest_len = len(data) * 8\n        digest = bytesToNumber(data)\n        if N < digest_len:\n            digest >>= digest_len - N\n\n        k = getRandomNumber(1, (self.q-1))\n        r = powMod(self.g, k, self.p) % self.q\n        s = invMod(k, self.q) * (digest + self.private_key * r) % self.q\n\n        return encode_sequence(encode_integer(r), encode_integer(s))\n\n    def verify(self, signature, hashData):\n        N = numBits(self.q)\n        digest_len = len(hashData) * 8\n        digest = bytesToNumber(hashData)\n\n        if N < digest_len:\n            digest >>= digest_len - N\n\n        signature = compatHMAC(signature)\n\n        # get r, s keys\n        if not signature:\n            return False\n        body, rest = remove_sequence(signature)\n        if rest:\n            return False\n        r, rest = remove_integer(body)\n        s, rest = remove_integer(rest)\n        if rest:\n            return False\n\n        if gmpyLoaded or GMPY2_LOADED:\n            r = mpz(r)\n            s = mpz(s)\n\n        # check the signature\n        if 0 < r < self.q and 0 < s < self.q:\n            w = invMod(s, self.q)\n            u1 = (digest * w) % self.q\n            u2 = (r * w) % self.q\n            v = ((powMod(self.g, u1, self.p) *  \\\n                    powMod(self.public_key, u2, self.p)) % self.p) % self.q\n            return r == v\n        return False\n\n    def hashAndVerify(self, signature, data, hAlg=\"sha1\"):\n        digest = secureHash(bytearray(data), hAlg)\n        return self.verify(signature, digest)\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/python_ecdsakey.py",
    "content": "# Author Hubert Kario, copyright 2019\n\nfrom .ecdsakey import ECDSAKey\nfrom ecdsa.curves import curves\nfrom ecdsa.util import sigencode_der, sigdecode_der\nfrom ecdsa.keys import VerifyingKey, SigningKey, BadSignatureError\nfrom ecdsa.ellipticcurve import Point\nfrom ecdsa.der import UnexpectedDER\nfrom . import tlshashlib\nfrom .cryptomath import numBits\nfrom .compat import compatHMAC\n\nclass Python_ECDSAKey(ECDSAKey):\n    \"\"\"\n    Concrete implementation of ECDSA object backed by python-ecdsa.\n\n    Object that uses the common, abstract API of asymmetric keys\n    that uses the python-ecdsa library for the cryptographic operations.\n\n    :vartype public_key: VerifyingKey\n    :ivar public_key: python-ecdsa object for veryfying ECDSA signatures, if\n        `private_key` is set, it should match it (should be able to verify\n        signatures created by it)\n\n    :vartype private_key: SigningKey\n    :ivar private_key: python-ecdsa object for creating ECDSA signatures\n\n    :vartype key_type: str\n    :ivar key_type: type of assymetric algorithm used by the keys - for this\n        objects it is always 'ecdsa'\n    \"\"\"\n\n    def __init__(self, x, y, curve_name, secret_multiplier=None):\n        if not curve_name:\n            raise ValueError(\"curve_name must be specified\")\n        self.curve_name = curve_name\n\n        for c in curves:\n            if c.name == curve_name or c.openssl_name == curve_name:\n                curve = c\n                break\n        else:\n            raise ValueError(\"Curve '{0}' not supported by python-ecdsa\"\n                             .format(curve_name))\n\n        self.private_key = None\n        self.public_key = None\n        self.key_type = \"ecdsa\"\n\n        if secret_multiplier:\n            self.private_key = SigningKey.from_secret_exponent(\n                secret_multiplier, curve)\n\n        if x and y:\n            point = Point(curve.curve, x, y)\n            self.public_key = VerifyingKey.from_public_point(point, curve)\n\n        if not self.public_key:\n            self.public_key = self.private_key.get_verifying_key()\n\n    def __len__(self):\n        return numBits(self.public_key.curve.order)\n\n    def hasPrivateKey(self):\n        return bool(self.private_key)\n\n    def acceptsPassword(self):\n        return False\n\n    @staticmethod\n    def generate(bits):\n        raise NotImplementedError()\n\n    def _sign(self, data, hAlg):\n        func = getattr(tlshashlib, hAlg)\n\n        return self.private_key.\\\n            sign_digest_deterministic(compatHMAC(data),\n                                      hashfunc=func,\n                                      sigencode=sigencode_der)\n\n    def _hashAndSign(self, data, hAlg):\n        return self.private_key.sign_deterministic(compatHMAC(data),\n                                                   hash=getattr(tlshashlib,\n                                                                hAlg),\n                                                   sigencode=sigencode_der)\n\n    def _verify(self, signature, hash_bytes):\n        try:\n            return self.public_key.verify_digest(compatHMAC(signature),\n                                                 compatHMAC(hash_bytes),\n                                                 sigdecode_der)\n        # https://github.com/warner/python-ecdsa/issues/114\n        except (BadSignatureError, UnexpectedDER, IndexError, AssertionError):\n            return False\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/python_eddsakey.py",
    "content": "# Author Hubert Kario, copyright 2021\n\nfrom .eddsakey import EdDSAKey\nfrom ecdsa.keys import BadSignatureError\nfrom ecdsa.der import UnexpectedDER\nfrom .cryptomath import numBits\nfrom .compat import compatHMAC\n\n\nclass Python_EdDSAKey(EdDSAKey):\n    \"\"\"\n    Concrete implementation of EdDSA object backed by python-ecdsa.\n\n    Object that uses the common, abstract API of asymmetric keys\n    that uses the python-ecdsa library for the cryptographic operations.\n\n    :vartype public_key: VerifyingKey\n    :ivar public_key: python-ecdsa object for veryfying EdDSA signatures, if\n        `private_key` is set, it should match it (should be able to verify\n        signatures created by it)\n\n    :vartype private_key: SigningKey\n    :ivar private_key: python-ecdsa object for creating EdDSA signatures\n\n    :vartype key_type: str\n    :ivar key_type: type of assymetric algorithm used by the keys - for this\n        objects it is either \"Ed25519\" or \"Ed448\"\n    \"\"\"\n\n    def __init__(self, public_key, private_key=None):\n        if not public_key and not private_key:\n            raise ValueError(\"at least one key must be provided\")\n        if not public_key:\n            public_key = private_key.verifying_key\n\n        self.curve_name = public_key.curve.name\n\n        self.private_key = private_key\n        self.public_key = public_key\n        self.key_type = self.curve_name\n\n    def __len__(self):\n        return numBits(self.public_key.curve.order)\n\n    def hasPrivateKey(self):\n        return bool(self.private_key)\n\n    def acceptsPassword(self):\n        return False\n\n    @staticmethod\n    def generate(bits):\n        raise NotImplementedError()\n\n    def _hashAndSign(self, data):\n        return self.private_key.sign_deterministic(compatHMAC(data))\n\n    def _hashAndVerify(self, signature, data):\n        try:\n            return self.public_key.verify(compatHMAC(signature),\n                                          compatHMAC(data))\n        # https://github.com/warner/python-ecdsa/issues/114\n        except (BadSignatureError, UnexpectedDER, IndexError, AssertionError):\n            return False\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/python_key.py",
    "content": "\n\nfrom .python_rsakey import Python_RSAKey\nfrom .python_ecdsakey import Python_ECDSAKey\nfrom .python_dsakey import Python_DSAKey\nfrom .python_eddsakey import Python_EdDSAKey\nfrom .pem import dePem, pemSniff\nfrom .asn1parser import ASN1Parser\nfrom .cryptomath import bytesToNumber\nfrom .compat import compatHMAC\nfrom ecdsa.curves import NIST256p, NIST384p, NIST521p\nfrom ecdsa.keys import SigningKey, VerifyingKey\n\nclass Python_Key(object):\n    \"\"\"\n    Generic methods for parsing private keys from files.\n\n    Handles both RSA and ECDSA keys, irrespective of file format.\n    \"\"\"\n\n    @staticmethod\n    def parsePEM(s, passwordCallback=None):\n        \"\"\"Parse a string containing a PEM-encoded <privateKey>.\"\"\"\n\n        if pemSniff(s, \"PRIVATE KEY\"):\n            bytes = dePem(s, \"PRIVATE KEY\")\n            return Python_Key._parse_pkcs8(bytes)\n        elif pemSniff(s, \"RSA PRIVATE KEY\"):\n            bytes = dePem(s, \"RSA PRIVATE KEY\")\n            return Python_Key._parse_ssleay(bytes, \"rsa\")\n        elif pemSniff(s, \"DSA PRIVATE KEY\"):\n            bytes = dePem(s, \"DSA PRIVATE KEY\")\n            return Python_Key._parse_dsa_ssleay(bytes)\n        elif pemSniff(s, \"EC PRIVATE KEY\"):\n            bytes = dePem(s, \"EC PRIVATE KEY\")\n            return Python_Key._parse_ecc_ssleay(bytes)\n        elif pemSniff(s, \"PUBLIC KEY\"):\n            bytes = dePem(s, \"PUBLIC KEY\")\n            return Python_Key._parse_public_key(bytes)\n        else:\n            raise SyntaxError(\"Not a PEM private key file\")\n\n    @staticmethod\n    def _parse_public_key(bytes):\n        # public keys are encoded as the subject_public_key_info objects\n        spk_info = ASN1Parser(bytes)\n\n        # first element of the SEQUENCE is the AlgorithmIdentifier\n        alg_id = spk_info.getChild(0)\n\n        # AlgId has two elements, the OID of the algorithm and parameters\n        # parameters generally have to be NULL, with exception of RSA-PSS\n\n        alg_oid = alg_id.getChild(0)\n\n        if list(alg_oid.value) == [42, 134, 72, 134, 247, 13, 1, 1, 1]:\n            key_type = \"rsa\"\n        elif list(alg_oid.value) == [42, 134, 72, 206, 56, 4, 1]:\n            key_type = \"dsa\"\n        else:\n            raise SyntaxError(\"Only RSA or DSA Public keys supported\")\n\n        if key_type == \"rsa\":\n            subject_public_key = ASN1Parser(\n                ASN1Parser(spk_info.getChildBytes(1)).value[1:])\n\n            modulus = subject_public_key.getChild(0)\n            exponent = subject_public_key.getChild(1)\n\n            n = bytesToNumber(modulus.value)\n            e = bytesToNumber(exponent.value)\n\n            return Python_RSAKey(n, e, key_type=\"rsa\")\n\n        elif key_type == \"dsa\":\n            # public key\n            subject_public_key = ASN1Parser(\n                ASN1Parser(spk_info.getChildBytes(1)).value[1:])\n\n            public_key = bytesToNumber(subject_public_key.value)\n\n            # domain parameters\n            domain = alg_id.getChild(1)\n\n            p = bytesToNumber(domain.getChild(0).value)\n            q = bytesToNumber(domain.getChild(1).value)\n            g = bytesToNumber(domain.getChild(2).value)\n\n            return Python_DSAKey(p, q, g, y=public_key)\n\n    @staticmethod\n    def _parse_pkcs8(bytes):\n        parser = ASN1Parser(bytes)\n\n        # first element in PrivateKeyInfo is an INTEGER\n        version = parser.getChild(0).value\n        if bytesToNumber(version) != 0:\n            raise SyntaxError(\"Unrecognized PKCS8 version\")\n\n        # second element in PrivateKeyInfo is a SEQUENCE of type\n        # AlgorithmIdentifier\n        alg_ident = parser.getChild(1)\n        seq_len = alg_ident.getChildCount()\n        # first item of AlgorithmIdentifier is an OBJECT (OID)\n        oid = alg_ident.getChild(0)\n        if list(oid.value) == [42, 134, 72, 134, 247, 13, 1, 1, 1]:\n            key_type = \"rsa\"\n        elif list(oid.value) == [42, 134, 72, 134, 247, 13, 1, 1, 10]:\n            key_type = \"rsa-pss\"\n        elif list(oid.value) == [42, 134, 72, 206, 56, 4, 1]:\n            key_type = \"dsa\"\n        elif list(oid.value) == [42, 134, 72, 206, 61, 2, 1]:\n            key_type = \"ecdsa\"\n        elif list(oid.value) == [43, 101, 112]:\n            key_type = \"Ed25519\"\n        elif list(oid.value) == [43, 101, 113]:\n            key_type = \"Ed448\"\n        else:\n            raise SyntaxError(\"Unrecognized AlgorithmIdentifier: {0}\"\n                              .format(list(oid.value)))\n        # second item of AlgorithmIdentifier are parameters (defined by\n        # above algorithm)\n        if key_type == \"rsa\":\n            if seq_len != 2:\n                raise SyntaxError(\"Missing parameters for RSA algorithm ID\")\n            parameters = alg_ident.getChild(1)\n            if parameters.value != bytearray(0):\n                raise SyntaxError(\"RSA parameters are not NULL\")\n        if key_type == \"dsa\":\n            if seq_len != 2:\n                raise SyntaxError(\"Invalid encoding of algorithm identifier\")\n            parameters = alg_ident.getChild(1)\n            if parameters.value == bytearray(0):\n                parameters = None\n        elif key_type == \"ecdsa\":\n            if seq_len != 2:\n                raise SyntaxError(\"Invalid encoding of algorithm identifier\")\n            curveID = alg_ident.getChild(1)\n            if list(curveID.value) == [42, 134, 72, 206, 61, 3, 1, 7]:\n                curve = NIST256p\n            elif list(curveID.value) == [43, 129, 4, 0, 34]:\n                curve = NIST384p\n            elif list(curveID.value) == [43, 129, 4, 0, 35]:\n                curve = NIST521p\n            else:\n                raise SyntaxError(\"Unknown curve\")\n        else:  # rsa-pss\n            pass  # ignore parameters - don't apply restrictions\n\n        if seq_len > 2:\n            raise SyntaxError(\"Invalid encoding of AlgorithmIdentifier\")\n\n        #Get the privateKey\n        private_key_parser = parser.getChild(2)\n\n        #Adjust for OCTET STRING encapsulation\n        private_key_parser = ASN1Parser(private_key_parser.value)\n\n        if key_type in (\"Ed25519\", \"Ed448\"):\n            return Python_Key._parse_eddsa_private_key(bytes)\n        if key_type == \"ecdsa\":\n            return Python_Key._parse_ecdsa_private_key(private_key_parser,\n                                                       curve)\n        elif key_type == \"dsa\":\n            return Python_Key._parse_dsa_private_key(private_key_parser, parameters)\n        else:\n            return Python_Key._parse_asn1_private_key(private_key_parser,\n                                                      key_type)\n\n    @staticmethod\n    def _parse_ssleay(data, key_type=\"rsa\"):\n        \"\"\"\n        Parse binary structure of the old SSLeay file format used by OpenSSL.\n\n        For RSA keys.\n        \"\"\"\n        private_key_parser = ASN1Parser(data)\n        # \"rsa\" type as old format doesn't support rsa-pss parameters\n        return Python_Key._parse_asn1_private_key(private_key_parser, key_type)\n\n    @staticmethod\n    def _parse_dsa_ssleay(data):\n        \"\"\"\n        Parse binary structure of the old SSLeay file format used by OpenSSL.\n\n        For DSA keys.\n        \"\"\"\n        private_key_parser = ASN1Parser(data)\n        return Python_Key._parse_dsa_private_key(private_key_parser)\n\n    @staticmethod\n    def _parse_ecc_ssleay(data):\n        \"\"\"\n        Parse binary structure of the old SSLeay file format used by OpenSSL.\n\n        For ECDSA keys.\n        \"\"\"\n        private_key = SigningKey.from_der(compatHMAC(data))\n        secret_mult = private_key.privkey.secret_multiplier\n        return Python_ECDSAKey(None, None, private_key.curve.name,\n                               secret_mult)\n\n    @staticmethod\n    def _parse_ecdsa_private_key(private, curve):\n        ver = private.getChild(0)\n        if ver.value != b'\\x01':\n            raise SyntaxError(\"Unexpected EC key version\")\n        private_key = private.getChild(1)\n        public_key = private.getChild(2)\n        # first two bytes are the ASN.1 custom type and the length of payload\n        # while the latter two bytes are just specification of the public\n        # key encoding (uncompressed)\n        # TODO: update ecdsa lib to be able to parse PKCS#8 files\n        if curve is not NIST521p:\n            if list(public_key.value[:1]) != [3] or \\\n                    list(public_key.value[2:4]) != [0, 4]:\n                raise SyntaxError(\"Invalid or unsupported encoding of public key\")\n\n            pub_key = VerifyingKey.from_string(\n                    compatHMAC(public_key.value[4:]),\n                    curve)\n        else:\n            if list(public_key.value[:3]) != [3, 129, 134] or \\\n                    list(public_key.value[3:5]) != [0, 4]:\n                raise SyntaxError(\"Invalid or unsupported encoding of public key\")\n\n            pub_key = VerifyingKey.from_string(\n                    compatHMAC(public_key.value[5:]),\n                    curve)\n        pub_x = pub_key.pubkey.point.x()\n        pub_y = pub_key.pubkey.point.y()\n        priv_key = SigningKey.from_string(compatHMAC(private_key.value),\n                                          curve)\n        mult = priv_key.privkey.secret_multiplier\n        return Python_ECDSAKey(pub_x, pub_y, curve.name, mult)\n\n    @staticmethod\n    def _parse_eddsa_private_key(data):\n        \"\"\"Parse a DER encoded EdDSA key.\"\"\"\n        priv_key = SigningKey.from_der(data)\n        return Python_EdDSAKey(priv_key.verifying_key, private_key=priv_key)\n\n    @staticmethod\n    def _parse_asn1_private_key(private_key_parser, key_type):\n        version = private_key_parser.getChild(0).value[0]\n        if version != 0:\n            raise SyntaxError(\"Unrecognized RSAPrivateKey version\")\n        n = bytesToNumber(private_key_parser.getChild(1).value)\n        e = bytesToNumber(private_key_parser.getChild(2).value)\n        d = bytesToNumber(private_key_parser.getChild(3).value)\n        p = bytesToNumber(private_key_parser.getChild(4).value)\n        q = bytesToNumber(private_key_parser.getChild(5).value)\n        dP = bytesToNumber(private_key_parser.getChild(6).value)\n        dQ = bytesToNumber(private_key_parser.getChild(7).value)\n        qInv = bytesToNumber(private_key_parser.getChild(8).value)\n        return Python_RSAKey(n, e, d, p, q, dP, dQ, qInv, key_type)\n\n\n    @staticmethod\n    def _parse_dsa_private_key(private_key_parser, domain_parameters=None):\n        if domain_parameters:\n            p = bytesToNumber(domain_parameters.getChild(0).value)\n            q = bytesToNumber(domain_parameters.getChild(1).value)\n            g = bytesToNumber(domain_parameters.getChild(2).value)\n            x = bytesToNumber(private_key_parser.value)\n            return Python_DSAKey(p, q, g, x)\n        p = bytesToNumber(private_key_parser.getChild(1).value)\n        q = bytesToNumber(private_key_parser.getChild(2).value)\n        g = bytesToNumber(private_key_parser.getChild(3).value)\n        y = bytesToNumber(private_key_parser.getChild(4).value)\n        x = bytesToNumber(private_key_parser.getChild(5).value)\n        return Python_DSAKey(p, q, g, x, y)\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/python_rc4.py",
    "content": "# Author: Trevor Perrin\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Pure-Python RC4 implementation.\"\"\"\n\nfrom .rc4 import RC4\nfrom .cryptomath import *\n\ndef new(key):\n    return Python_RC4(key)\n\nclass Python_RC4(RC4):\n    def __init__(self, keyBytes):\n        RC4.__init__(self, keyBytes, \"python\")\n        S = [i for i in range(256)]\n        j = 0\n        for i in range(256):\n            j = (j + S[i] + keyBytes[i % len(keyBytes)]) % 256\n            S[i], S[j] = S[j], S[i]\n\n        self.S = S\n        self.i = 0\n        self.j = 0\n\n    def encrypt(self, plaintextBytes):\n        ciphertextBytes = plaintextBytes[:]\n        S = self.S\n        i = self.i\n        j = self.j\n        for x in range(len(ciphertextBytes)):\n            i = (i + 1) % 256\n            j = (j + S[i]) % 256\n            S[i], S[j] = S[j], S[i]\n            t = (S[i] + S[j]) % 256\n            ciphertextBytes[x] ^= S[t]\n        self.i = i\n        self.j = j\n        return ciphertextBytes\n\n    def decrypt(self, ciphertext):\n        return self.encrypt(ciphertext)\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/python_rsakey.py",
    "content": "# Author: Trevor Perrin\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Pure-Python RSA implementation.\"\"\"\nimport threading\nfrom .cryptomath import *\nfrom .rsakey import *\nfrom .pem import *\nfrom .deprecations import deprecated_params\nif GMPY2_LOADED:\n    from gmpy2 import mpz\nelif gmpyLoaded:\n    from gmpy import mpz\n\nclass Python_RSAKey(RSAKey):\n    def __init__(self, n=0, e=0, d=0, p=0, q=0, dP=0, dQ=0, qInv=0,\n                 key_type=\"rsa\"):\n        \"\"\"Initialise key directly from integers.\n\n        see also generate() and parsePEM().\"\"\"\n        if (n and not e) or (e and not n):\n            raise AssertionError()\n        if gmpyLoaded or GMPY2_LOADED:\n            n = mpz(n)\n            e = mpz(e)\n            d = mpz(d)\n            p = mpz(p)\n            q = mpz(q)\n            dP = mpz(dP)\n            dQ = mpz(dQ)\n            qInv = mpz(qInv)\n        self.n = n\n        self.e = e\n        if p and not q or not p and q:\n            raise ValueError(\"p and q must be set or left unset together\")\n        if not d and p and q:\n            t = lcm(p - 1, q - 1)\n            d = invMod(e, t)\n        self.d = d\n        self.p = p\n        self.q = q\n        if not dP and p:\n            dP = d % (p - 1)\n        self.dP = dP\n        if not dQ and q:\n            dQ = d % (q - 1)\n        self.dQ = dQ\n        if not qInv:\n            qInv = invMod(q, p)\n        self.qInv = qInv\n        self.blinder = 0\n        self.unblinder = 0\n        self._lock = threading.Lock()\n        self.key_type = key_type\n\n    def hasPrivateKey(self):\n        \"\"\"\n        Does the key has the associated private key (True) or is it only\n        the public part (False).\n        \"\"\"\n        return self.d != 0\n\n    def _rawPrivateKeyOp(self, message):\n        n = self.n\n        with self._lock:\n            # Create blinding values, on the first pass:\n            if not self.blinder:\n                self.unblinder = getRandomNumber(2, n)\n                self.blinder = powMod(invMod(self.unblinder, n), self.e,\n                                      n)\n            unblinder = self.unblinder\n            blinder = self.blinder\n\n            # Update blinding values\n            self.blinder = (blinder * blinder) % n\n            self.unblinder = (unblinder * unblinder) % n\n\n        # Blind the input\n        message = (message * blinder) % n\n\n        # Perform the RSA operation\n        cipher = self._rawPrivateKeyOpHelper(message)\n\n        # Unblind the output\n        cipher = (cipher * unblinder) % n\n\n        # Return the output\n        return cipher\n\n    def _rawPrivateKeyOpHelper(self, m):\n        #Non-CRT version\n        #c = pow(m, self.d, self.n)\n\n        #CRT version  (~3x faster).\n        p, q = self.p, self.q\n        s1 = pow(m, self.dP, p)\n        s2 = pow(m, self.dQ, q)\n        h = ((s1 - s2) * self.qInv) % p\n        c = s2 + q * h\n        return c\n\n    def _rawPublicKeyOp(self, ciphertext):\n        msg = pow(ciphertext, self.e, self.n)\n        return msg\n\n    def acceptsPassword(self):\n        \"\"\"Does it support encrypted key files.\"\"\"\n        return False\n\n    @staticmethod\n    def generate(bits, key_type=\"rsa\"):\n        \"\"\"Generate a private key with modulus 'bits' bit big.\n\n        key_type can be \"rsa\" for a universal rsaEncryption key or\n        \"rsa-pss\" for a key that can be used only for RSASSA-PSS.\"\"\"\n        # p, q, and t are standard names for the variables in RSA, so\n        # ignore the fact those are one character long variable names\n        # pylint: disable=invalid-name\n        key = Python_RSAKey()\n        while True:\n            p = getRandomPrime(bits//2, False)\n            q = getRandomPrime(bits//2, False)\n            if gmpyLoaded or GMPY2_LOADED:\n                p = mpz(p)\n                q = mpz(q)\n            t = lcm(p-1, q-1)\n            # since we need to calculate inverse of 65537 mod t, they\n            # must be relatively prime (coprime)\n            if gcd(t, 65537) == 1:\n                break\n        key.n = p * q\n        if gmpyLoaded or GMPY2_LOADED:\n            key.e = mpz(65537)\n        else:\n            key.e = 65537\n        key.d = invMod(key.e, t)\n        key.p = p\n        key.q = q\n        key.dP = key.d % (p-1)\n        key.dQ = key.d % (q-1)\n        key.qInv = invMod(q, p)\n        key.key_type = key_type\n        # pylint: enable=invalid-name\n        return key\n\n    @staticmethod\n    @deprecated_params({\"data\": \"s\", \"password_callback\": \"passwordCallback\"})\n    def parsePEM(data, password_callback=None):\n        \"\"\"Parse a string containing a PEM-encoded <privateKey>.\"\"\"\n        from .python_key import Python_Key\n        return Python_Key.parsePEM(data, password_callback)\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/python_tripledes.py",
    "content": "#################################################\n#               Documentation                   #\n#################################################\n\n# Author:   Todd Whiteman\n# Date:     16th March, 2009\n# Verion:   2.0.0\n# License:  Public Domain - free to do as you wish\n# Homepage: http://twhiteman.netfirms.com/Des.html\n#\n# Modified by: Adam Varga, 2018\n#\n# A pure python implementation of the DES and Triple DES\n# encryption algorithms using CBC mode. Triple DES class is\n# implemented by utilising the DES base. Triple DES is\n# DES-EDE3 with a 24 byte key, or DES-EDE2 with a 16 byte key.\n\n\"\"\"\nClass initialization\n--------------------\npyDes.Des(key, iv)\npyDes.Python_TripleDES(key, iv)\n\nkey -> Bytes containing the encryption key. 8 bytes for DES, 16 or 24 bytes\n       for Triple DES\niv  -> Initialization Vector in bytes. Length must be 8 bytes.\n\"\"\"\n\nimport sys\nimport warnings\n\n# PY_VER is used to handle Python2 and Python3 differences.\nPY_VER = sys.version_info\n\n\ndef new(key, iv):\n    \"\"\"Operate this 3DES cipher.\"\"\"\n\n    return Python_TripleDES(key, iv)\n\n\nclass _baseDes(object):\n    \"\"\"The base class shared by DES and triple DES.\"\"\"\n\n    def __init__(self, iv):\n        self.iv = iv\n\n    def _guard_against_unicode(self, data):\n        \"\"\"Check the data for valid datatype and return them.\n\n        Only accept byte strings or ascii unicode values.\n        Otherwise there is no way to correctly decode the data into bytes.\n        \"\"\"\n\n        if PY_VER < (3, ):\n            if isinstance(data, unicode):\n                raise ValueError(\"Only bytes, bytearray or memoryview \"\n                                 \"objects of them should be passed, \"\n                                 \"not Unicode strings\")\n        else:\n            if isinstance(data, str):\n                warnings.warn(\"Only bytes, bytearray or memoryview \"\n                              \"objects of them should be passed\",\n                              DeprecationWarning,\n                              stacklevel=3)\n                # Only accept ascii unicode values.\n                try:\n                    return data.encode('ascii')\n                except UnicodeEncodeError:\n                    raise ValueError(\"The Unicode string shouldn't be passed\")\n        return data\n\n#############################################\n#                   DES                     #\n#############################################\n\n\nclass Des(_baseDes):\n    \"\"\"DES encryption/decryption class.\n\n    Supports CBC (Cypher Block Chaining) mode.\n    \"\"\"\n\n    # Permutation and translation tables for DES\n    __pc1 = [56, 48, 40, 32, 24, 16, 8,\n             0, 57, 49, 41, 33, 25, 17,\n             9, 1, 58, 50, 42, 34, 26,\n             18, 10, 2, 59, 51, 43, 35,\n             62, 54, 46, 38, 30, 22, 14,\n             6, 61, 53, 45, 37, 29, 21,\n             13, 5, 60, 52, 44, 36, 28,\n             20, 12, 4, 27, 19, 11, 3]\n\n    # Number left rotations of pc1\n    __left_rotations = [1, 1, 2, 2, 2, 2, 2, 2,\n                        1, 2, 2, 2, 2, 2, 2, 1]\n\n    # Permuted choice key (table 2)\n    __pc2 = [13, 16, 10, 23, 0, 4,\n             2, 27, 14, 5, 20, 9,\n             22, 18, 11, 3, 25, 7,\n             15, 6, 26, 19, 12, 1,\n             40, 51, 30, 36, 46, 54,\n             29, 39, 50, 44, 32, 47,\n             43, 48, 38, 55, 33, 52,\n             45, 41, 49, 35, 28, 31]\n\n    # Initial permutation IP\n    __ip = [57, 49, 41, 33, 25, 17, 9, 1,\n            59, 51, 43, 35, 27, 19, 11, 3,\n            61, 53, 45, 37, 29, 21, 13, 5,\n            63, 55, 47, 39, 31, 23, 15, 7,\n            56, 48, 40, 32, 24, 16, 8, 0,\n            58, 50, 42, 34, 26, 18, 10, 2,\n            60, 52, 44, 36, 28, 20, 12, 4,\n            62, 54, 46, 38, 30, 22, 14, 6]\n\n    # Expansion table for turning 32 bit blocks into 48 bits\n    __expansion_table = [31, 0, 1, 2, 3, 4,\n                         3, 4, 5, 6, 7, 8,\n                         7, 8, 9, 10, 11, 12,\n                         11, 12, 13, 14, 15, 16,\n                         15, 16, 17, 18, 19, 20,\n                         19, 20, 21, 22, 23, 24,\n                         23, 24, 25, 26, 27, 28,\n                         27, 28, 29, 30, 31, 0]\n\n    # The (in)famous S-boxes\n    __sbox = [  # S1\n              [14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,\n               0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,\n               4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,\n               15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13],\n\n              # S2\n              [15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,\n               3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,\n               0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,\n               13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9],\n\n              # S3\n              [10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,\n               13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,\n               13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,\n               1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12],\n\n              # S4\n              [7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,\n               13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,\n               10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,\n               3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14],\n\n              # S5\n              [2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,\n               14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,\n               4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,\n               11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3],\n\n              # S6\n              [12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,\n               10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,\n               9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,\n               4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13],\n\n              # S7\n              [4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,\n               13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,\n               1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,\n               6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12],\n\n              # S8\n              [13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,\n               1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,\n               7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,\n               2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11], ]\n\n    # 32-bit permutation function P used on the output of the S-boxes\n    __p = [15, 6, 19, 20, 28, 11,\n           27, 16, 0, 14, 22, 25,\n           4, 17, 30, 9, 1, 7,\n           23, 13, 31, 26, 2, 8,\n           18, 12, 29, 5, 21, 10,\n           3, 24]\n\n    # Final permutation IP^-1\n    __fp = [39, 7, 47, 15, 55, 23, 63, 31,\n            38, 6, 46, 14, 54, 22, 62, 30,\n            37, 5, 45, 13, 53, 21, 61, 29,\n            36, 4, 44, 12, 52, 20, 60, 28,\n            35, 3, 43, 11, 51, 19, 59, 27,\n            34, 2, 42, 10, 50, 18, 58, 26,\n            33, 1, 41, 9, 49, 17, 57, 25,\n            32, 0, 40, 8, 48, 16, 56, 24]\n\n    # Type of crypting being done\n    ENCRYPT = 0x00\n    DECRYPT = 0x01\n\n    # Initialisation\n    def __init__(self, key, iv=None):\n        # Sanity checking of arguments\n        if len(key) != 8:\n            raise ValueError(\"Invalid DES key size. Key must be exactly \"\n                             \"8 bytes long\")\n        super(Des, self).__init__(iv)\n\n        self.key_size = 8\n        self._l = []\n        self._r = []\n        self._kn = [[0] * 48] * 16  # 16 48-bit keys (K1 - K16)\n        self._final = []\n\n        self.set_key(key)\n\n    def set_key(self, key):\n        \"\"\"Set the crypting key for this object. Must be 8 bytes.\"\"\"\n\n        self.key = key\n        self.__create_sub_keys()\n\n    def __string_to_bitlist(self, data):\n        \"\"\"Turn the string data into a list of bits (1, 0)'s.\"\"\"\n\n        if PY_VER < (3, ):\n            # Turn the strings into integers. Python 3 uses a bytes\n            # class, which already has this behaviour\n            if not isinstance(data, bytearray):\n                data = [ord(c) for c in data]\n        len_data = len(data) * 8\n        result = [0] * len_data\n        pos = 0\n        for ch in data:\n            i = 7\n            while i >= 0:\n                if ch & (1 << i) != 0:\n                    result[pos] = 1\n                else:\n                    result[pos] = 0\n                pos += 1\n                i -= 1\n        return result\n\n    def __bitlist_to_string(self, data):\n        \"\"\"Turn the data as list of bits into a string.\"\"\"\n\n        result = []\n        pos = 0\n        c = 0\n        while pos < len(data):\n            c += data[pos] << (7 - (pos % 8))\n            if (pos % 8) == 7:\n                result.append(c)\n                c = 0\n            pos += 1\n\n        if PY_VER < (3, ):\n            return ''.join([chr(c) for c in result])\n        else:\n            return bytes(result)\n\n    def __permutate(self, table, block):\n        \"\"\"Permutate this block with the specified table.\"\"\"\n        return [block[x] for x in table]\n\n    def __create_sub_keys(self):\n        \"\"\"Transform the secret key for data processing.\n\n        Create the 16 subkeys k[1] to k[16] from the given key.\n        \"\"\"\n        key = self.__permutate(Des.__pc1,\n                               self.__string_to_bitlist(self.key))\n        # Split into Left and Right sections\n        self._l = key[:28]\n        self._r = key[28:]\n        for i in range(16):\n            # Perform circular left shifts\n            for _ in range(Des.__left_rotations[i]):\n                self._l.append(self._l[0])\n                del self._l[0]\n                self._r.append(self._r[0])\n                del self._r[0]\n\n            # Create one of the 16 subkeys through pc2 permutation\n            self._kn[i] = self.__permutate(Des.__pc2, self._l + self._r)\n\n    def __des_crypt(self, block, crypt_type):\n        \"\"\"Crypt the block of data through DES bit-manipulation.\"\"\"\n\n        block = self.__permutate(Des.__ip, block)\n        self._l = block[:32]\n        self._r = block[32:]\n\n        # Encryption starts from _kn[1] through to _kn[16]\n        if crypt_type == Des.ENCRYPT:\n            iteration = 0\n            iteration_adjustment = 1\n        # Decryption starts from _kn[16] down to _kn[1]\n        else:\n            iteration = 15\n            iteration_adjustment = -1\n\n        for _ in range(16):\n            # Make a copy of _r[i-1], this will later become _l[i]\n            temp_r = self._r[:]\n\n            # Permutate _r[i - 1] to start creating _r[i]\n            self._r = self.__permutate(Des.__expansion_table, self._r)\n\n            # Exclusive or _r[i - 1] with k[i], create b[1] to b[8] whilst here\n            self._r = [x ^ y for x, y in zip(self._r, self._kn[iteration])]\n            b = [self._r[:6], self._r[6:12], self._r[12:18], self._r[18:24],\n                 self._r[24:30], self._r[30:36], self._r[36:42], self._r[42:]]\n\n            # Permutate b[1] to b[8] using the S-Boxes\n            bn = [0] * 32\n            pos = 0\n            for j in range(8):\n                # Work out the offsets\n                m = (b[j][0] << 1) + b[j][5]\n                n = (b[j][1] << 3) + (b[j][2] << 2) + (b[j][3] << 1) + b[j][4]\n\n                # Find the permutation value\n                v = Des.__sbox[j][(m << 4) + n]\n\n                # Turn value into bits, add it to result: bn\n                bn[pos] = (v & 8) >> 3\n                bn[pos + 1] = (v & 4) >> 2\n                bn[pos + 2] = (v & 2) >> 1\n                bn[pos + 3] = v & 1\n\n                pos += 4\n\n            # Permutate the concatination of b[1] to b[8] (bn)\n            self._r = self.__permutate(Des.__p, bn)\n\n            # Xor with _l[i - 1]\n            self._r = [x ^ y for x, y in zip(self._r, self._l)]\n            self._l = temp_r\n\n            iteration += iteration_adjustment\n\n        # Final permutation of _r[16]_l[16]\n        self._final = self.__permutate(Des.__fp, self._r + self._l)\n        return self._final\n\n    def crypt(self, data, crypt_type):\n        \"\"\"Crypt the data in blocks, running it through des_crypt().\"\"\"\n\n        iv = self.__string_to_bitlist(self.iv)\n\n        # Split the data into blocks, crypting each one seperately\n        i = 0\n        result = []\n        while i < len(data):\n            # Test code for caching encryption results\n            block = self.__string_to_bitlist(data[i:i+8])\n\n            # Xor with iv if using CBC mode\n            if crypt_type == Des.ENCRYPT:\n                block = [x ^ y for x, y in zip(block, iv)]\n\n            processed_block = self.__des_crypt(block, crypt_type)\n\n            if crypt_type == Des.DECRYPT:\n                processed_block = [x ^ y for x, y in zip(processed_block, iv)]\n                iv = block\n            else:\n                iv = processed_block\n\n            # Add the resulting crypted block to our list\n            result.append(self.__bitlist_to_string(processed_block))\n            i += 8\n\n        # Return the full crypted string\n        return b''.join(result)\n\n#############################################\n#               Triple DES                  #\n#############################################\n\n\nclass Python_TripleDES(_baseDes):\n    \"\"\"Triple DES encryption/decrytpion class.\n\n    This algorithm uses the DES-EDE3 (when a 24 byte key is supplied) or\n    the DES-EDE2 (when a 16 byte key is supplied) encryption methods.\n    Supports CBC (Cypher Block Chaining) mode.\n    \"\"\"\n    def __init__(self, key, iv=None):\n        self.block_size = 8\n        if iv:\n            if len(iv) != self.block_size:\n                raise ValueError(\"Invalid Initialization Vector (iv) must be\"\n                                 \" {0} bytes long\".format(self.block_size))\n            iv = self._guard_against_unicode(iv)\n        else:\n            raise ValueError(\"Initialization Vector (iv) must be supplied\")\n\n        super(Python_TripleDES, self).__init__(iv)\n\n        # Will set crypting key for this object. Either 16/24 bytes long.\n        self.key_size = len(key)\n        if self.key_size not in (16, 24):\n            raise ValueError(\"Invalid triple DES key size. \"\n                             \"Key must be either 16 or 24 bytes long\")\n        key = self._guard_against_unicode(key)\n\n        self.__key1 = Des(key[:8], self.iv)\n        self.__key2 = Des(key[8:16], self.iv)\n        if self.key_size == 16:\n            self.__key3 = Des(key[:8], self.iv)\n        else:\n            self.__key3 = Des(key[16:], self.iv)\n\n        self.isAEAD = False\n        self.isBlockCipher = True\n        self.name = \"3des\"\n        self.implementation = \"python\"\n\n        self.__key1.iv = self.iv\n        self.__key2.iv = self.iv\n        self.__key3.iv = self.iv\n\n    def encrypt(self, data):\n        \"\"\"Encrypt data and return bytes.\n\n        data : bytes to be encrypted\n\n        The data must be a multiple of 8 bytes and will be encrypted\n        with the already specified key.\n        \"\"\"\n\n        ENCRYPT = Des.ENCRYPT\n        DECRYPT = Des.DECRYPT\n\n        if not data:\n            return bytearray(b'')\n\n        data = self._guard_against_unicode(data)\n        if len(data) % self.block_size:\n            raise ValueError(\"Invalid data length, must be a multiple \"\n                             \"of {0} bytes\".format(self.block_size))\n\n        i = 0\n        result = []\n        while i < len(data):\n            block = self.__key1.crypt(data[i:i+8], ENCRYPT)\n            block = self.__key2.crypt(block, DECRYPT)\n            block = self.__key3.crypt(block, ENCRYPT)\n            self.__key1.iv = block\n            self.__key2.iv = block\n            self.__key3.iv = block\n            result.append(block)\n            i += 8\n\n        return bytearray(b''.join(result))\n\n    def decrypt(self, data):\n        \"\"\"Decrypt data and return bytes.\n\n        data : bytes to be encrypted\n\n        The data must be a multiple of 8 bytes and will be decrypted\n        with the already specified key.\n        \"\"\"\n        ENCRYPT = Des.ENCRYPT\n        DECRYPT = Des.DECRYPT\n\n        if not data:\n            return bytearray(b'')\n\n        data = self._guard_against_unicode(data)\n        if len(data) % self.block_size:\n            raise ValueError(\"Invalid data length, must be a multiple \"\n                             \"of {0} bytes\".format(self.block_size))\n\n        i = 0\n        result = []\n        while i < len(data):\n            iv = data[i:i+8]\n            block = self.__key3.crypt(iv, DECRYPT)\n            block = self.__key2.crypt(block, ENCRYPT)\n            block = self.__key1.crypt(block, DECRYPT)\n            self.__key1.iv = iv\n            self.__key2.iv = iv\n            self.__key3.iv = iv\n            result.append(block)\n            i += 8\n        data = b''.join(result)\n\n        return bytearray(data)\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/rc4.py",
    "content": "# Author: Trevor Perrin\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Abstract class for RC4.\"\"\"\n\n\nclass RC4(object):\n    def __init__(self, keyBytes, implementation):\n        if len(keyBytes) < 16 or len(keyBytes) > 256:\n            raise ValueError()\n        self.isBlockCipher = False\n        self.isAEAD = False\n        self.name = \"rc4\"\n        self.implementation = implementation\n\n    def encrypt(self, plaintext):\n        raise NotImplementedError()\n\n    def decrypt(self, ciphertext):\n        raise NotImplementedError()\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/rijndael.py",
    "content": "# Authors:\n#   Bram Cohen\n#   Trevor Perrin - various changes\n#\n# See the LICENSE file for legal information regarding use of this file.\n# Also see Bram Cohen's statement below\n\n\"\"\"\nA pure python (slow) implementation of rijndael with a decent interface\n\nTo include -\n\nfrom rijndael import Rijndael\n\nTo do a key setup -\n\nr = Rijndael(key, block_size = 16)\n\nkey must be a string of length 16, 24, or 32\nblocksize must be 16, 24, or 32. Default is 16\n\nTo use -\n\nciphertext = r.encrypt(plaintext)\nplaintext = r.decrypt(ciphertext)\n\nIf any strings are of the wrong length a ValueError is thrown\n\"\"\"\n\nfrom .deprecations import deprecated_class_name\n\n# ported from the Java reference code by Bram Cohen, bram@gawth.com, April 2001\n# this code is public domain, unless someone makes\n# an intellectual property claim against the reference\n# code, in which case it can be made public domain by\n# deleting all the comments and renaming all the variables\n\nshifts = [[[0, 0], [1, 3], [2, 2], [3, 1]],\n          [[0, 0], [1, 5], [2, 4], [3, 3]],\n          [[0, 0], [1, 7], [3, 5], [4, 4]]]\n\n# [keysize][block_size]\nnum_rounds = {16: {16: 10, 24: 12, 32: 14},\n              24: {16: 12, 24: 12, 32: 14},\n              32: {16: 14, 24: 14, 32: 14}}\n\n# see unit_tests/test_tlslite_utils_rijndael.py for algorithm used to\n# calculate S, Si, T, U and rcon arrays\n\n# S box\nS = (99, 124, 119, 123, 242, 107, 111, 197,\n     48, 1, 103, 43, 254, 215, 171, 118,\n     202, 130, 201, 125, 250, 89, 71, 240,\n     173, 212, 162, 175, 156, 164, 114, 192,\n     183, 253, 147, 38, 54, 63, 247, 204,\n     52, 165, 229, 241, 113, 216, 49, 21,\n     4, 199, 35, 195, 24, 150, 5, 154,\n     7, 18, 128, 226, 235, 39, 178, 117,\n     9, 131, 44, 26, 27, 110, 90, 160,\n     82, 59, 214, 179, 41, 227, 47, 132,\n     83, 209, 0, 237, 32, 252, 177, 91,\n     106, 203, 190, 57, 74, 76, 88, 207,\n     208, 239, 170, 251, 67, 77, 51, 133,\n     69, 249, 2, 127, 80, 60, 159, 168,\n     81, 163, 64, 143, 146, 157, 56, 245,\n     188, 182, 218, 33, 16, 255, 243, 210,\n     205, 12, 19, 236, 95, 151, 68, 23,\n     196, 167, 126, 61, 100, 93, 25, 115,\n     96, 129, 79, 220, 34, 42, 144, 136,\n     70, 238, 184, 20, 222, 94, 11, 219,\n     224, 50, 58, 10, 73, 6, 36, 92,\n     194, 211, 172, 98, 145, 149, 228, 121,\n     231, 200, 55, 109, 141, 213, 78, 169,\n     108, 86, 244, 234, 101, 122, 174, 8,\n     186, 120, 37, 46, 28, 166, 180, 198,\n     232, 221, 116, 31, 75, 189, 139, 138,\n     112, 62, 181, 102, 72, 3, 246, 14,\n     97, 53, 87, 185, 134, 193, 29, 158,\n     225, 248, 152, 17, 105, 217, 142, 148,\n     155, 30, 135, 233, 206, 85, 40, 223,\n     140, 161, 137, 13, 191, 230, 66, 104,\n     65, 153, 45, 15, 176, 84, 187, 22)\n\n# inverse of S box\nSi = (82, 9, 106, 213, 48, 54, 165, 56,\n      191, 64, 163, 158, 129, 243, 215, 251,\n      124, 227, 57, 130, 155, 47, 255, 135,\n      52, 142, 67, 68, 196, 222, 233, 203,\n      84, 123, 148, 50, 166, 194, 35, 61,\n      238, 76, 149, 11, 66, 250, 195, 78,\n      8, 46, 161, 102, 40, 217, 36, 178,\n      118, 91, 162, 73, 109, 139, 209, 37,\n      114, 248, 246, 100, 134, 104, 152, 22,\n      212, 164, 92, 204, 93, 101, 182, 146,\n      108, 112, 72, 80, 253, 237, 185, 218,\n      94, 21, 70, 87, 167, 141, 157, 132,\n      144, 216, 171, 0, 140, 188, 211, 10,\n      247, 228, 88, 5, 184, 179, 69, 6,\n      208, 44, 30, 143, 202, 63, 15, 2,\n      193, 175, 189, 3, 1, 19, 138, 107,\n      58, 145, 17, 65, 79, 103, 220, 234,\n      151, 242, 207, 206, 240, 180, 230, 115,\n      150, 172, 116, 34, 231, 173, 53, 133,\n      226, 249, 55, 232, 28, 117, 223, 110,\n      71, 241, 26, 113, 29, 41, 197, 137,\n      111, 183, 98, 14, 170, 24, 190, 27,\n      252, 86, 62, 75, 198, 210, 121, 32,\n      154, 219, 192, 254, 120, 205, 90, 244,\n      31, 221, 168, 51, 136, 7, 199, 49,\n      177, 18, 16, 89, 39, 128, 236, 95,\n      96, 81, 127, 169, 25, 181, 74, 13,\n      45, 229, 122, 159, 147, 201, 156, 239,\n      160, 224, 59, 77, 174, 42, 245, 176,\n      200, 235, 187, 60, 131, 83, 153, 97,\n      23, 43, 4, 126, 186, 119, 214, 38,\n      225, 105, 20, 99, 85, 33, 12, 125)\n\nT1 = (0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d,\n      0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,\n      0x60303050, 0x2010103, 0xce6767a9, 0x562b2b7d,\n      0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,\n      0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87,\n      0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,\n      0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea,\n      0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,\n      0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a,\n      0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f,\n      0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108,\n      0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,\n      0x804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e,\n      0x30181828, 0x379696a1, 0xa05050f, 0x2f9a9ab5,\n      0xe070709, 0x24121236, 0x1b80809b, 0xdfe2e23d,\n      0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,\n      0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e,\n      0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,\n      0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce,\n      0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,\n      0xa65353f5, 0xb9d1d168, 0x0, 0xc1eded2c,\n      0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed,\n      0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b,\n      0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,\n      0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16,\n      0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594,\n      0x8a4545cf, 0xe9f9f910, 0x4020206, 0xfe7f7f81,\n      0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,\n      0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x58f8f8a,\n      0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,\n      0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163,\n      0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,\n      0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f,\n      0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739,\n      0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47,\n      0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,\n      0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f,\n      0x44222266, 0x542a2a7e, 0x3b9090ab, 0xb888883,\n      0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c,\n      0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,\n      0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e,\n      0x924949db, 0xc06060a, 0x4824246c, 0xb85c5ce4,\n      0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6,\n      0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,\n      0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7,\n      0x18d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0,\n      0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25,\n      0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,\n      0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72,\n      0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651,\n      0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21,\n      0x964b4bdd, 0x61bdbddc, 0xd8b8b86, 0xf8a8a85,\n      0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa,\n      0x904848d8, 0x6030305, 0xf7f6f601, 0x1c0e0e12,\n      0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0,\n      0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,\n      0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133,\n      0xd26969bb, 0xa9d9d970, 0x78e8e89, 0x339494a7,\n      0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920,\n      0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,\n      0x38c8c8f, 0x59a1a1f8, 0x9898980, 0x1a0d0d17,\n      0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8,\n      0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11,\n      0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a)\n\nT2 = (0xa5c66363, 0x84f87c7c, 0x99ee7777, 0x8df67b7b,\n      0xdfff2f2, 0xbdd66b6b, 0xb1de6f6f, 0x5491c5c5,\n      0x50603030, 0x3020101, 0xa9ce6767, 0x7d562b2b,\n      0x19e7fefe, 0x62b5d7d7, 0xe64dabab, 0x9aec7676,\n      0x458fcaca, 0x9d1f8282, 0x4089c9c9, 0x87fa7d7d,\n      0x15effafa, 0xebb25959, 0xc98e4747, 0xbfbf0f0,\n      0xec41adad, 0x67b3d4d4, 0xfd5fa2a2, 0xea45afaf,\n      0xbf239c9c, 0xf753a4a4, 0x96e47272, 0x5b9bc0c0,\n      0xc275b7b7, 0x1ce1fdfd, 0xae3d9393, 0x6a4c2626,\n      0x5a6c3636, 0x417e3f3f, 0x2f5f7f7, 0x4f83cccc,\n      0x5c683434, 0xf451a5a5, 0x34d1e5e5, 0x8f9f1f1,\n      0x93e27171, 0x73abd8d8, 0x53623131, 0x3f2a1515,\n      0xc080404, 0x5295c7c7, 0x65462323, 0x5e9dc3c3,\n      0x28301818, 0xa1379696, 0xf0a0505, 0xb52f9a9a,\n      0x90e0707, 0x36241212, 0x9b1b8080, 0x3ddfe2e2,\n      0x26cdebeb, 0x694e2727, 0xcd7fb2b2, 0x9fea7575,\n      0x1b120909, 0x9e1d8383, 0x74582c2c, 0x2e341a1a,\n      0x2d361b1b, 0xb2dc6e6e, 0xeeb45a5a, 0xfb5ba0a0,\n      0xf6a45252, 0x4d763b3b, 0x61b7d6d6, 0xce7db3b3,\n      0x7b522929, 0x3edde3e3, 0x715e2f2f, 0x97138484,\n      0xf5a65353, 0x68b9d1d1, 0x0, 0x2cc1eded,\n      0x60402020, 0x1fe3fcfc, 0xc879b1b1, 0xedb65b5b,\n      0xbed46a6a, 0x468dcbcb, 0xd967bebe, 0x4b723939,\n      0xde944a4a, 0xd4984c4c, 0xe8b05858, 0x4a85cfcf,\n      0x6bbbd0d0, 0x2ac5efef, 0xe54faaaa, 0x16edfbfb,\n      0xc5864343, 0xd79a4d4d, 0x55663333, 0x94118585,\n      0xcf8a4545, 0x10e9f9f9, 0x6040202, 0x81fe7f7f,\n      0xf0a05050, 0x44783c3c, 0xba259f9f, 0xe34ba8a8,\n      0xf3a25151, 0xfe5da3a3, 0xc0804040, 0x8a058f8f,\n      0xad3f9292, 0xbc219d9d, 0x48703838, 0x4f1f5f5,\n      0xdf63bcbc, 0xc177b6b6, 0x75afdada, 0x63422121,\n      0x30201010, 0x1ae5ffff, 0xefdf3f3, 0x6dbfd2d2,\n      0x4c81cdcd, 0x14180c0c, 0x35261313, 0x2fc3ecec,\n      0xe1be5f5f, 0xa2359797, 0xcc884444, 0x392e1717,\n      0x5793c4c4, 0xf255a7a7, 0x82fc7e7e, 0x477a3d3d,\n      0xacc86464, 0xe7ba5d5d, 0x2b321919, 0x95e67373,\n      0xa0c06060, 0x98198181, 0xd19e4f4f, 0x7fa3dcdc,\n      0x66442222, 0x7e542a2a, 0xab3b9090, 0x830b8888,\n      0xca8c4646, 0x29c7eeee, 0xd36bb8b8, 0x3c281414,\n      0x79a7dede, 0xe2bc5e5e, 0x1d160b0b, 0x76addbdb,\n      0x3bdbe0e0, 0x56643232, 0x4e743a3a, 0x1e140a0a,\n      0xdb924949, 0xa0c0606, 0x6c482424, 0xe4b85c5c,\n      0x5d9fc2c2, 0x6ebdd3d3, 0xef43acac, 0xa6c46262,\n      0xa8399191, 0xa4319595, 0x37d3e4e4, 0x8bf27979,\n      0x32d5e7e7, 0x438bc8c8, 0x596e3737, 0xb7da6d6d,\n      0x8c018d8d, 0x64b1d5d5, 0xd29c4e4e, 0xe049a9a9,\n      0xb4d86c6c, 0xfaac5656, 0x7f3f4f4, 0x25cfeaea,\n      0xafca6565, 0x8ef47a7a, 0xe947aeae, 0x18100808,\n      0xd56fbaba, 0x88f07878, 0x6f4a2525, 0x725c2e2e,\n      0x24381c1c, 0xf157a6a6, 0xc773b4b4, 0x5197c6c6,\n      0x23cbe8e8, 0x7ca1dddd, 0x9ce87474, 0x213e1f1f,\n      0xdd964b4b, 0xdc61bdbd, 0x860d8b8b, 0x850f8a8a,\n      0x90e07070, 0x427c3e3e, 0xc471b5b5, 0xaacc6666,\n      0xd8904848, 0x5060303, 0x1f7f6f6, 0x121c0e0e,\n      0xa3c26161, 0x5f6a3535, 0xf9ae5757, 0xd069b9b9,\n      0x91178686, 0x5899c1c1, 0x273a1d1d, 0xb9279e9e,\n      0x38d9e1e1, 0x13ebf8f8, 0xb32b9898, 0x33221111,\n      0xbbd26969, 0x70a9d9d9, 0x89078e8e, 0xa7339494,\n      0xb62d9b9b, 0x223c1e1e, 0x92158787, 0x20c9e9e9,\n      0x4987cece, 0xffaa5555, 0x78502828, 0x7aa5dfdf,\n      0x8f038c8c, 0xf859a1a1, 0x80098989, 0x171a0d0d,\n      0xda65bfbf, 0x31d7e6e6, 0xc6844242, 0xb8d06868,\n      0xc3824141, 0xb0299999, 0x775a2d2d, 0x111e0f0f,\n      0xcb7bb0b0, 0xfca85454, 0xd66dbbbb, 0x3a2c1616)\n\nT3 = (0x63a5c663, 0x7c84f87c, 0x7799ee77, 0x7b8df67b,\n      0xf20dfff2, 0x6bbdd66b, 0x6fb1de6f, 0xc55491c5,\n      0x30506030, 0x1030201, 0x67a9ce67, 0x2b7d562b,\n      0xfe19e7fe, 0xd762b5d7, 0xabe64dab, 0x769aec76,\n      0xca458fca, 0x829d1f82, 0xc94089c9, 0x7d87fa7d,\n      0xfa15effa, 0x59ebb259, 0x47c98e47, 0xf00bfbf0,\n      0xadec41ad, 0xd467b3d4, 0xa2fd5fa2, 0xafea45af,\n      0x9cbf239c, 0xa4f753a4, 0x7296e472, 0xc05b9bc0,\n      0xb7c275b7, 0xfd1ce1fd, 0x93ae3d93, 0x266a4c26,\n      0x365a6c36, 0x3f417e3f, 0xf702f5f7, 0xcc4f83cc,\n      0x345c6834, 0xa5f451a5, 0xe534d1e5, 0xf108f9f1,\n      0x7193e271, 0xd873abd8, 0x31536231, 0x153f2a15,\n      0x40c0804, 0xc75295c7, 0x23654623, 0xc35e9dc3,\n      0x18283018, 0x96a13796, 0x50f0a05, 0x9ab52f9a,\n      0x7090e07, 0x12362412, 0x809b1b80, 0xe23ddfe2,\n      0xeb26cdeb, 0x27694e27, 0xb2cd7fb2, 0x759fea75,\n      0x91b1209, 0x839e1d83, 0x2c74582c, 0x1a2e341a,\n      0x1b2d361b, 0x6eb2dc6e, 0x5aeeb45a, 0xa0fb5ba0,\n      0x52f6a452, 0x3b4d763b, 0xd661b7d6, 0xb3ce7db3,\n      0x297b5229, 0xe33edde3, 0x2f715e2f, 0x84971384,\n      0x53f5a653, 0xd168b9d1, 0x0, 0xed2cc1ed,\n      0x20604020, 0xfc1fe3fc, 0xb1c879b1, 0x5bedb65b,\n      0x6abed46a, 0xcb468dcb, 0xbed967be, 0x394b7239,\n      0x4ade944a, 0x4cd4984c, 0x58e8b058, 0xcf4a85cf,\n      0xd06bbbd0, 0xef2ac5ef, 0xaae54faa, 0xfb16edfb,\n      0x43c58643, 0x4dd79a4d, 0x33556633, 0x85941185,\n      0x45cf8a45, 0xf910e9f9, 0x2060402, 0x7f81fe7f,\n      0x50f0a050, 0x3c44783c, 0x9fba259f, 0xa8e34ba8,\n      0x51f3a251, 0xa3fe5da3, 0x40c08040, 0x8f8a058f,\n      0x92ad3f92, 0x9dbc219d, 0x38487038, 0xf504f1f5,\n      0xbcdf63bc, 0xb6c177b6, 0xda75afda, 0x21634221,\n      0x10302010, 0xff1ae5ff, 0xf30efdf3, 0xd26dbfd2,\n      0xcd4c81cd, 0xc14180c, 0x13352613, 0xec2fc3ec,\n      0x5fe1be5f, 0x97a23597, 0x44cc8844, 0x17392e17,\n      0xc45793c4, 0xa7f255a7, 0x7e82fc7e, 0x3d477a3d,\n      0x64acc864, 0x5de7ba5d, 0x192b3219, 0x7395e673,\n      0x60a0c060, 0x81981981, 0x4fd19e4f, 0xdc7fa3dc,\n      0x22664422, 0x2a7e542a, 0x90ab3b90, 0x88830b88,\n      0x46ca8c46, 0xee29c7ee, 0xb8d36bb8, 0x143c2814,\n      0xde79a7de, 0x5ee2bc5e, 0xb1d160b, 0xdb76addb,\n      0xe03bdbe0, 0x32566432, 0x3a4e743a, 0xa1e140a,\n      0x49db9249, 0x60a0c06, 0x246c4824, 0x5ce4b85c,\n      0xc25d9fc2, 0xd36ebdd3, 0xacef43ac, 0x62a6c462,\n      0x91a83991, 0x95a43195, 0xe437d3e4, 0x798bf279,\n      0xe732d5e7, 0xc8438bc8, 0x37596e37, 0x6db7da6d,\n      0x8d8c018d, 0xd564b1d5, 0x4ed29c4e, 0xa9e049a9,\n      0x6cb4d86c, 0x56faac56, 0xf407f3f4, 0xea25cfea,\n      0x65afca65, 0x7a8ef47a, 0xaee947ae, 0x8181008,\n      0xbad56fba, 0x7888f078, 0x256f4a25, 0x2e725c2e,\n      0x1c24381c, 0xa6f157a6, 0xb4c773b4, 0xc65197c6,\n      0xe823cbe8, 0xdd7ca1dd, 0x749ce874, 0x1f213e1f,\n      0x4bdd964b, 0xbddc61bd, 0x8b860d8b, 0x8a850f8a,\n      0x7090e070, 0x3e427c3e, 0xb5c471b5, 0x66aacc66,\n      0x48d89048, 0x3050603, 0xf601f7f6, 0xe121c0e,\n      0x61a3c261, 0x355f6a35, 0x57f9ae57, 0xb9d069b9,\n      0x86911786, 0xc15899c1, 0x1d273a1d, 0x9eb9279e,\n      0xe138d9e1, 0xf813ebf8, 0x98b32b98, 0x11332211,\n      0x69bbd269, 0xd970a9d9, 0x8e89078e, 0x94a73394,\n      0x9bb62d9b, 0x1e223c1e, 0x87921587, 0xe920c9e9,\n      0xce4987ce, 0x55ffaa55, 0x28785028, 0xdf7aa5df,\n      0x8c8f038c, 0xa1f859a1, 0x89800989, 0xd171a0d,\n      0xbfda65bf, 0xe631d7e6, 0x42c68442, 0x68b8d068,\n      0x41c38241, 0x99b02999, 0x2d775a2d, 0xf111e0f,\n      0xb0cb7bb0, 0x54fca854, 0xbbd66dbb, 0x163a2c16)\n\nT4 = (0x6363a5c6, 0x7c7c84f8, 0x777799ee, 0x7b7b8df6,\n      0xf2f20dff, 0x6b6bbdd6, 0x6f6fb1de, 0xc5c55491,\n      0x30305060, 0x1010302, 0x6767a9ce, 0x2b2b7d56,\n      0xfefe19e7, 0xd7d762b5, 0xababe64d, 0x76769aec,\n      0xcaca458f, 0x82829d1f, 0xc9c94089, 0x7d7d87fa,\n      0xfafa15ef, 0x5959ebb2, 0x4747c98e, 0xf0f00bfb,\n      0xadadec41, 0xd4d467b3, 0xa2a2fd5f, 0xafafea45,\n      0x9c9cbf23, 0xa4a4f753, 0x727296e4, 0xc0c05b9b,\n      0xb7b7c275, 0xfdfd1ce1, 0x9393ae3d, 0x26266a4c,\n      0x36365a6c, 0x3f3f417e, 0xf7f702f5, 0xcccc4f83,\n      0x34345c68, 0xa5a5f451, 0xe5e534d1, 0xf1f108f9,\n      0x717193e2, 0xd8d873ab, 0x31315362, 0x15153f2a,\n      0x4040c08, 0xc7c75295, 0x23236546, 0xc3c35e9d,\n      0x18182830, 0x9696a137, 0x5050f0a, 0x9a9ab52f,\n      0x707090e, 0x12123624, 0x80809b1b, 0xe2e23ddf,\n      0xebeb26cd, 0x2727694e, 0xb2b2cd7f, 0x75759fea,\n      0x9091b12, 0x83839e1d, 0x2c2c7458, 0x1a1a2e34,\n      0x1b1b2d36, 0x6e6eb2dc, 0x5a5aeeb4, 0xa0a0fb5b,\n      0x5252f6a4, 0x3b3b4d76, 0xd6d661b7, 0xb3b3ce7d,\n      0x29297b52, 0xe3e33edd, 0x2f2f715e, 0x84849713,\n      0x5353f5a6, 0xd1d168b9, 0x0, 0xeded2cc1,\n      0x20206040, 0xfcfc1fe3, 0xb1b1c879, 0x5b5bedb6,\n      0x6a6abed4, 0xcbcb468d, 0xbebed967, 0x39394b72,\n      0x4a4ade94, 0x4c4cd498, 0x5858e8b0, 0xcfcf4a85,\n      0xd0d06bbb, 0xefef2ac5, 0xaaaae54f, 0xfbfb16ed,\n      0x4343c586, 0x4d4dd79a, 0x33335566, 0x85859411,\n      0x4545cf8a, 0xf9f910e9, 0x2020604, 0x7f7f81fe,\n      0x5050f0a0, 0x3c3c4478, 0x9f9fba25, 0xa8a8e34b,\n      0x5151f3a2, 0xa3a3fe5d, 0x4040c080, 0x8f8f8a05,\n      0x9292ad3f, 0x9d9dbc21, 0x38384870, 0xf5f504f1,\n      0xbcbcdf63, 0xb6b6c177, 0xdada75af, 0x21216342,\n      0x10103020, 0xffff1ae5, 0xf3f30efd, 0xd2d26dbf,\n      0xcdcd4c81, 0xc0c1418, 0x13133526, 0xecec2fc3,\n      0x5f5fe1be, 0x9797a235, 0x4444cc88, 0x1717392e,\n      0xc4c45793, 0xa7a7f255, 0x7e7e82fc, 0x3d3d477a,\n      0x6464acc8, 0x5d5de7ba, 0x19192b32, 0x737395e6,\n      0x6060a0c0, 0x81819819, 0x4f4fd19e, 0xdcdc7fa3,\n      0x22226644, 0x2a2a7e54, 0x9090ab3b, 0x8888830b,\n      0x4646ca8c, 0xeeee29c7, 0xb8b8d36b, 0x14143c28,\n      0xdede79a7, 0x5e5ee2bc, 0xb0b1d16, 0xdbdb76ad,\n      0xe0e03bdb, 0x32325664, 0x3a3a4e74, 0xa0a1e14,\n      0x4949db92, 0x6060a0c, 0x24246c48, 0x5c5ce4b8,\n      0xc2c25d9f, 0xd3d36ebd, 0xacacef43, 0x6262a6c4,\n      0x9191a839, 0x9595a431, 0xe4e437d3, 0x79798bf2,\n      0xe7e732d5, 0xc8c8438b, 0x3737596e, 0x6d6db7da,\n      0x8d8d8c01, 0xd5d564b1, 0x4e4ed29c, 0xa9a9e049,\n      0x6c6cb4d8, 0x5656faac, 0xf4f407f3, 0xeaea25cf,\n      0x6565afca, 0x7a7a8ef4, 0xaeaee947, 0x8081810,\n      0xbabad56f, 0x787888f0, 0x25256f4a, 0x2e2e725c,\n      0x1c1c2438, 0xa6a6f157, 0xb4b4c773, 0xc6c65197,\n      0xe8e823cb, 0xdddd7ca1, 0x74749ce8, 0x1f1f213e,\n      0x4b4bdd96, 0xbdbddc61, 0x8b8b860d, 0x8a8a850f,\n      0x707090e0, 0x3e3e427c, 0xb5b5c471, 0x6666aacc,\n      0x4848d890, 0x3030506, 0xf6f601f7, 0xe0e121c,\n      0x6161a3c2, 0x35355f6a, 0x5757f9ae, 0xb9b9d069,\n      0x86869117, 0xc1c15899, 0x1d1d273a, 0x9e9eb927,\n      0xe1e138d9, 0xf8f813eb, 0x9898b32b, 0x11113322,\n      0x6969bbd2, 0xd9d970a9, 0x8e8e8907, 0x9494a733,\n      0x9b9bb62d, 0x1e1e223c, 0x87879215, 0xe9e920c9,\n      0xcece4987, 0x5555ffaa, 0x28287850, 0xdfdf7aa5,\n      0x8c8c8f03, 0xa1a1f859, 0x89898009, 0xd0d171a,\n      0xbfbfda65, 0xe6e631d7, 0x4242c684, 0x6868b8d0,\n      0x4141c382, 0x9999b029, 0x2d2d775a, 0xf0f111e,\n      0xb0b0cb7b, 0x5454fca8, 0xbbbbd66d, 0x16163a2c)\n\nT5 = (0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96,\n      0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393,\n      0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25,\n      0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,\n      0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1,\n      0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,\n      0x38f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da,\n      0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,\n      0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd,\n      0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4,\n      0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45,\n      0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,\n      0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7,\n      0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a,\n      0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5,\n      0x302887f2, 0x23bfa5b2, 0x2036aba, 0xed16825c,\n      0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1,\n      0x65daf4cd, 0x605bed5, 0xd134621f, 0xc4a6fe8a,\n      0x342e539d, 0xa2f355a0, 0x58ae132, 0xa4f6eb75,\n      0xb83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,\n      0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46,\n      0x91548db5, 0x71c45d05, 0x406d46f, 0x605015ff,\n      0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77,\n      0xb0e842bd, 0x7898b88, 0xe7195b38, 0x79c8eedb,\n      0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x0,\n      0x9808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e,\n      0xfd0efffb, 0xf853856, 0x3daed51e, 0x362d3927,\n      0xa0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,\n      0xc0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e,\n      0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,\n      0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d,\n      0xe090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,\n      0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd,\n      0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34,\n      0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163,\n      0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,\n      0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d,\n      0x1d9e2f4b, 0xdcb230f3, 0xd8652ec, 0x77c1e3d0,\n      0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422,\n      0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,\n      0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36,\n      0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,\n      0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662,\n      0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,\n      0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3,\n      0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b,\n      0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8,\n      0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,\n      0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6,\n      0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0,\n      0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815,\n      0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,\n      0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df,\n      0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,\n      0x9d5eea04, 0x18c355d, 0xfa877473, 0xfb0b412e,\n      0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,\n      0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89,\n      0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c,\n      0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf,\n      0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,\n      0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f,\n      0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541,\n      0x39a80171, 0x80cb3de, 0xd8b4e49c, 0x6456c190,\n      0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742)\n\nT6 = (0x5051f4a7, 0x537e4165, 0xc31a17a4, 0x963a275e,\n      0xcb3bab6b, 0xf11f9d45, 0xabacfa58, 0x934be303,\n      0x552030fa, 0xf6ad766d, 0x9188cc76, 0x25f5024c,\n      0xfc4fe5d7, 0xd7c52acb, 0x80263544, 0x8fb562a3,\n      0x49deb15a, 0x6725ba1b, 0x9845ea0e, 0xe15dfec0,\n      0x2c32f75, 0x12814cf0, 0xa38d4697, 0xc66bd3f9,\n      0xe7038f5f, 0x9515929c, 0xebbf6d7a, 0xda955259,\n      0x2dd4be83, 0xd3587421, 0x2949e069, 0x448ec9c8,\n      0x6a75c289, 0x78f48e79, 0x6b99583e, 0xdd27b971,\n      0xb6bee14f, 0x17f088ad, 0x66c920ac, 0xb47dce3a,\n      0x1863df4a, 0x82e51a31, 0x60975133, 0x4562537f,\n      0xe0b16477, 0x84bb6bae, 0x1cfe81a0, 0x94f9082b,\n      0x58704868, 0x198f45fd, 0x8794de6c, 0xb7527bf8,\n      0x23ab73d3, 0xe2724b02, 0x57e31f8f, 0x2a6655ab,\n      0x7b2eb28, 0x32fb5c2, 0x9a86c57b, 0xa5d33708,\n      0xf2302887, 0xb223bfa5, 0xba02036a, 0x5ced1682,\n      0x2b8acf1c, 0x92a779b4, 0xf0f307f2, 0xa14e69e2,\n      0xcd65daf4, 0xd50605be, 0x1fd13462, 0x8ac4a6fe,\n      0x9d342e53, 0xa0a2f355, 0x32058ae1, 0x75a4f6eb,\n      0x390b83ec, 0xaa4060ef, 0x65e719f, 0x51bd6e10,\n      0xf93e218a, 0x3d96dd06, 0xaedd3e05, 0x464de6bd,\n      0xb591548d, 0x571c45d, 0x6f0406d4, 0xff605015,\n      0x241998fb, 0x97d6bde9, 0xcc894043, 0x7767d99e,\n      0xbdb0e842, 0x8807898b, 0x38e7195b, 0xdb79c8ee,\n      0x47a17c0a, 0xe97c420f, 0xc9f8841e, 0x0,\n      0x83098086, 0x48322bed, 0xac1e1170, 0x4e6c5a72,\n      0xfbfd0eff, 0x560f8538, 0x1e3daed5, 0x27362d39,\n      0x640a0fd9, 0x21685ca6, 0xd19b5b54, 0x3a24362e,\n      0xb10c0a67, 0xf9357e7, 0xd2b4ee96, 0x9e1b9b91,\n      0x4f80c0c5, 0xa261dc20, 0x695a774b, 0x161c121a,\n      0xae293ba, 0xe5c0a02a, 0x433c22e0, 0x1d121b17,\n      0xb0e090d, 0xadf28bc7, 0xb92db6a8, 0xc8141ea9,\n      0x8557f119, 0x4caf7507, 0xbbee99dd, 0xfda37f60,\n      0x9ff70126, 0xbc5c72f5, 0xc544663b, 0x345bfb7e,\n      0x768b4329, 0xdccb23c6, 0x68b6edfc, 0x63b8e4f1,\n      0xcad731dc, 0x10426385, 0x40139722, 0x2084c611,\n      0x7d854a24, 0xf8d2bb3d, 0x11aef932, 0x6dc729a1,\n      0x4b1d9e2f, 0xf3dcb230, 0xec0d8652, 0xd077c1e3,\n      0x6c2bb316, 0x99a970b9, 0xfa119448, 0x2247e964,\n      0xc4a8fc8c, 0x1aa0f03f, 0xd8567d2c, 0xef223390,\n      0xc787494e, 0xc1d938d1, 0xfe8ccaa2, 0x3698d40b,\n      0xcfa6f581, 0x28a57ade, 0x26dab78e, 0xa43fadbf,\n      0xe42c3a9d, 0xd507892, 0x9b6a5fcc, 0x62547e46,\n      0xc2f68d13, 0xe890d8b8, 0x5e2e39f7, 0xf582c3af,\n      0xbe9f5d80, 0x7c69d093, 0xa96fd52d, 0xb3cf2512,\n      0x3bc8ac99, 0xa710187d, 0x6ee89c63, 0x7bdb3bbb,\n      0x9cd2678, 0xf46e5918, 0x1ec9ab7, 0xa8834f9a,\n      0x65e6956e, 0x7eaaffe6, 0x821bccf, 0xe6ef15e8,\n      0xd9bae79b, 0xce4a6f36, 0xd4ea9f09, 0xd629b07c,\n      0xaf31a4b2, 0x312a3f23, 0x30c6a594, 0xc035a266,\n      0x37744ebc, 0xa6fc82ca, 0xb0e090d0, 0x1533a7d8,\n      0x4af10498, 0xf741ecda, 0xe7fcd50, 0x2f1791f6,\n      0x8d764dd6, 0x4d43efb0, 0x54ccaa4d, 0xdfe49604,\n      0xe39ed1b5, 0x1b4c6a88, 0xb8c12c1f, 0x7f466551,\n      0x49d5eea, 0x5d018c35, 0x73fa8774, 0x2efb0b41,\n      0x5ab3671d, 0x5292dbd2, 0x33e91056, 0x136dd647,\n      0x8c9ad761, 0x7a37a10c, 0x8e59f814, 0x89eb133c,\n      0xeecea927, 0x35b761c9, 0xede11ce5, 0x3c7a47b1,\n      0x599cd2df, 0x3f55f273, 0x791814ce, 0xbf73c737,\n      0xea53f7cd, 0x5b5ffdaa, 0x14df3d6f, 0x867844db,\n      0x81caaff3, 0x3eb968c4, 0x2c382434, 0x5fc2a340,\n      0x72161dc3, 0xcbce225, 0x8b283c49, 0x41ff0d95,\n      0x7139a801, 0xde080cb3, 0x9cd8b4e4, 0x906456c1,\n      0x617bcb84, 0x70d532b6, 0x74486c5c, 0x42d0b857)\n\nT7 = (0xa75051f4, 0x65537e41, 0xa4c31a17, 0x5e963a27,\n      0x6bcb3bab, 0x45f11f9d, 0x58abacfa, 0x3934be3,\n      0xfa552030, 0x6df6ad76, 0x769188cc, 0x4c25f502,\n      0xd7fc4fe5, 0xcbd7c52a, 0x44802635, 0xa38fb562,\n      0x5a49deb1, 0x1b6725ba, 0xe9845ea, 0xc0e15dfe,\n      0x7502c32f, 0xf012814c, 0x97a38d46, 0xf9c66bd3,\n      0x5fe7038f, 0x9c951592, 0x7aebbf6d, 0x59da9552,\n      0x832dd4be, 0x21d35874, 0x692949e0, 0xc8448ec9,\n      0x896a75c2, 0x7978f48e, 0x3e6b9958, 0x71dd27b9,\n      0x4fb6bee1, 0xad17f088, 0xac66c920, 0x3ab47dce,\n      0x4a1863df, 0x3182e51a, 0x33609751, 0x7f456253,\n      0x77e0b164, 0xae84bb6b, 0xa01cfe81, 0x2b94f908,\n      0x68587048, 0xfd198f45, 0x6c8794de, 0xf8b7527b,\n      0xd323ab73, 0x2e2724b, 0x8f57e31f, 0xab2a6655,\n      0x2807b2eb, 0xc2032fb5, 0x7b9a86c5, 0x8a5d337,\n      0x87f23028, 0xa5b223bf, 0x6aba0203, 0x825ced16,\n      0x1c2b8acf, 0xb492a779, 0xf2f0f307, 0xe2a14e69,\n      0xf4cd65da, 0xbed50605, 0x621fd134, 0xfe8ac4a6,\n      0x539d342e, 0x55a0a2f3, 0xe132058a, 0xeb75a4f6,\n      0xec390b83, 0xefaa4060, 0x9f065e71, 0x1051bd6e,\n      0x8af93e21, 0x63d96dd, 0x5aedd3e, 0xbd464de6,\n      0x8db59154, 0x5d0571c4, 0xd46f0406, 0x15ff6050,\n      0xfb241998, 0xe997d6bd, 0x43cc8940, 0x9e7767d9,\n      0x42bdb0e8, 0x8b880789, 0x5b38e719, 0xeedb79c8,\n      0xa47a17c, 0xfe97c42, 0x1ec9f884, 0x0,\n      0x86830980, 0xed48322b, 0x70ac1e11, 0x724e6c5a,\n      0xfffbfd0e, 0x38560f85, 0xd51e3dae, 0x3927362d,\n      0xd9640a0f, 0xa621685c, 0x54d19b5b, 0x2e3a2436,\n      0x67b10c0a, 0xe70f9357, 0x96d2b4ee, 0x919e1b9b,\n      0xc54f80c0, 0x20a261dc, 0x4b695a77, 0x1a161c12,\n      0xba0ae293, 0x2ae5c0a0, 0xe0433c22, 0x171d121b,\n      0xd0b0e09, 0xc7adf28b, 0xa8b92db6, 0xa9c8141e,\n      0x198557f1, 0x74caf75, 0xddbbee99, 0x60fda37f,\n      0x269ff701, 0xf5bc5c72, 0x3bc54466, 0x7e345bfb,\n      0x29768b43, 0xc6dccb23, 0xfc68b6ed, 0xf163b8e4,\n      0xdccad731, 0x85104263, 0x22401397, 0x112084c6,\n      0x247d854a, 0x3df8d2bb, 0x3211aef9, 0xa16dc729,\n      0x2f4b1d9e, 0x30f3dcb2, 0x52ec0d86, 0xe3d077c1,\n      0x166c2bb3, 0xb999a970, 0x48fa1194, 0x642247e9,\n      0x8cc4a8fc, 0x3f1aa0f0, 0x2cd8567d, 0x90ef2233,\n      0x4ec78749, 0xd1c1d938, 0xa2fe8cca, 0xb3698d4,\n      0x81cfa6f5, 0xde28a57a, 0x8e26dab7, 0xbfa43fad,\n      0x9de42c3a, 0x920d5078, 0xcc9b6a5f, 0x4662547e,\n      0x13c2f68d, 0xb8e890d8, 0xf75e2e39, 0xaff582c3,\n      0x80be9f5d, 0x937c69d0, 0x2da96fd5, 0x12b3cf25,\n      0x993bc8ac, 0x7da71018, 0x636ee89c, 0xbb7bdb3b,\n      0x7809cd26, 0x18f46e59, 0xb701ec9a, 0x9aa8834f,\n      0x6e65e695, 0xe67eaaff, 0xcf0821bc, 0xe8e6ef15,\n      0x9bd9bae7, 0x36ce4a6f, 0x9d4ea9f, 0x7cd629b0,\n      0xb2af31a4, 0x23312a3f, 0x9430c6a5, 0x66c035a2,\n      0xbc37744e, 0xcaa6fc82, 0xd0b0e090, 0xd81533a7,\n      0x984af104, 0xdaf741ec, 0x500e7fcd, 0xf62f1791,\n      0xd68d764d, 0xb04d43ef, 0x4d54ccaa, 0x4dfe496,\n      0xb5e39ed1, 0x881b4c6a, 0x1fb8c12c, 0x517f4665,\n      0xea049d5e, 0x355d018c, 0x7473fa87, 0x412efb0b,\n      0x1d5ab367, 0xd25292db, 0x5633e910, 0x47136dd6,\n      0x618c9ad7, 0xc7a37a1, 0x148e59f8, 0x3c89eb13,\n      0x27eecea9, 0xc935b761, 0xe5ede11c, 0xb13c7a47,\n      0xdf599cd2, 0x733f55f2, 0xce791814, 0x37bf73c7,\n      0xcdea53f7, 0xaa5b5ffd, 0x6f14df3d, 0xdb867844,\n      0xf381caaf, 0xc43eb968, 0x342c3824, 0x405fc2a3,\n      0xc372161d, 0x250cbce2, 0x498b283c, 0x9541ff0d,\n      0x17139a8, 0xb3de080c, 0xe49cd8b4, 0xc1906456,\n      0x84617bcb, 0xb670d532, 0x5c74486c, 0x5742d0b8)\n\nT8 = (0xf4a75051, 0x4165537e, 0x17a4c31a, 0x275e963a,\n      0xab6bcb3b, 0x9d45f11f, 0xfa58abac, 0xe303934b,\n      0x30fa5520, 0x766df6ad, 0xcc769188, 0x24c25f5,\n      0xe5d7fc4f, 0x2acbd7c5, 0x35448026, 0x62a38fb5,\n      0xb15a49de, 0xba1b6725, 0xea0e9845, 0xfec0e15d,\n      0x2f7502c3, 0x4cf01281, 0x4697a38d, 0xd3f9c66b,\n      0x8f5fe703, 0x929c9515, 0x6d7aebbf, 0x5259da95,\n      0xbe832dd4, 0x7421d358, 0xe0692949, 0xc9c8448e,\n      0xc2896a75, 0x8e7978f4, 0x583e6b99, 0xb971dd27,\n      0xe14fb6be, 0x88ad17f0, 0x20ac66c9, 0xce3ab47d,\n      0xdf4a1863, 0x1a3182e5, 0x51336097, 0x537f4562,\n      0x6477e0b1, 0x6bae84bb, 0x81a01cfe, 0x82b94f9,\n      0x48685870, 0x45fd198f, 0xde6c8794, 0x7bf8b752,\n      0x73d323ab, 0x4b02e272, 0x1f8f57e3, 0x55ab2a66,\n      0xeb2807b2, 0xb5c2032f, 0xc57b9a86, 0x3708a5d3,\n      0x2887f230, 0xbfa5b223, 0x36aba02, 0x16825ced,\n      0xcf1c2b8a, 0x79b492a7, 0x7f2f0f3, 0x69e2a14e,\n      0xdaf4cd65, 0x5bed506, 0x34621fd1, 0xa6fe8ac4,\n      0x2e539d34, 0xf355a0a2, 0x8ae13205, 0xf6eb75a4,\n      0x83ec390b, 0x60efaa40, 0x719f065e, 0x6e1051bd,\n      0x218af93e, 0xdd063d96, 0x3e05aedd, 0xe6bd464d,\n      0x548db591, 0xc45d0571, 0x6d46f04, 0x5015ff60,\n      0x98fb2419, 0xbde997d6, 0x4043cc89, 0xd99e7767,\n      0xe842bdb0, 0x898b8807, 0x195b38e7, 0xc8eedb79,\n      0x7c0a47a1, 0x420fe97c, 0x841ec9f8, 0x0,\n      0x80868309, 0x2bed4832, 0x1170ac1e, 0x5a724e6c,\n      0xefffbfd, 0x8538560f, 0xaed51e3d, 0x2d392736,\n      0xfd9640a, 0x5ca62168, 0x5b54d19b, 0x362e3a24,\n      0xa67b10c, 0x57e70f93, 0xee96d2b4, 0x9b919e1b,\n      0xc0c54f80, 0xdc20a261, 0x774b695a, 0x121a161c,\n      0x93ba0ae2, 0xa02ae5c0, 0x22e0433c, 0x1b171d12,\n      0x90d0b0e, 0x8bc7adf2, 0xb6a8b92d, 0x1ea9c814,\n      0xf1198557, 0x75074caf, 0x99ddbbee, 0x7f60fda3,\n      0x1269ff7, 0x72f5bc5c, 0x663bc544, 0xfb7e345b,\n      0x4329768b, 0x23c6dccb, 0xedfc68b6, 0xe4f163b8,\n      0x31dccad7, 0x63851042, 0x97224013, 0xc6112084,\n      0x4a247d85, 0xbb3df8d2, 0xf93211ae, 0x29a16dc7,\n      0x9e2f4b1d, 0xb230f3dc, 0x8652ec0d, 0xc1e3d077,\n      0xb3166c2b, 0x70b999a9, 0x9448fa11, 0xe9642247,\n      0xfc8cc4a8, 0xf03f1aa0, 0x7d2cd856, 0x3390ef22,\n      0x494ec787, 0x38d1c1d9, 0xcaa2fe8c, 0xd40b3698,\n      0xf581cfa6, 0x7ade28a5, 0xb78e26da, 0xadbfa43f,\n      0x3a9de42c, 0x78920d50, 0x5fcc9b6a, 0x7e466254,\n      0x8d13c2f6, 0xd8b8e890, 0x39f75e2e, 0xc3aff582,\n      0x5d80be9f, 0xd0937c69, 0xd52da96f, 0x2512b3cf,\n      0xac993bc8, 0x187da710, 0x9c636ee8, 0x3bbb7bdb,\n      0x267809cd, 0x5918f46e, 0x9ab701ec, 0x4f9aa883,\n      0x956e65e6, 0xffe67eaa, 0xbccf0821, 0x15e8e6ef,\n      0xe79bd9ba, 0x6f36ce4a, 0x9f09d4ea, 0xb07cd629,\n      0xa4b2af31, 0x3f23312a, 0xa59430c6, 0xa266c035,\n      0x4ebc3774, 0x82caa6fc, 0x90d0b0e0, 0xa7d81533,\n      0x4984af1, 0xecdaf741, 0xcd500e7f, 0x91f62f17,\n      0x4dd68d76, 0xefb04d43, 0xaa4d54cc, 0x9604dfe4,\n      0xd1b5e39e, 0x6a881b4c, 0x2c1fb8c1, 0x65517f46,\n      0x5eea049d, 0x8c355d01, 0x877473fa, 0xb412efb,\n      0x671d5ab3, 0xdbd25292, 0x105633e9, 0xd647136d,\n      0xd7618c9a, 0xa10c7a37, 0xf8148e59, 0x133c89eb,\n      0xa927eece, 0x61c935b7, 0x1ce5ede1, 0x47b13c7a,\n      0xd2df599c, 0xf2733f55, 0x14ce7918, 0xc737bf73,\n      0xf7cdea53, 0xfdaa5b5f, 0x3d6f14df, 0x44db8678,\n      0xaff381ca, 0x68c43eb9, 0x24342c38, 0xa3405fc2,\n      0x1dc37216, 0xe2250cbc, 0x3c498b28, 0xd9541ff,\n      0xa8017139, 0xcb3de08, 0xb4e49cd8, 0x56c19064,\n      0xcb84617b, 0x32b670d5, 0x6c5c7448, 0xb85742d0)\n\nU1 = (0x0, 0xe090d0b, 0x1c121a16, 0x121b171d,\n      0x3824342c, 0x362d3927, 0x24362e3a, 0x2a3f2331,\n      0x70486858, 0x7e416553, 0x6c5a724e, 0x62537f45,\n      0x486c5c74, 0x4665517f, 0x547e4662, 0x5a774b69,\n      0xe090d0b0, 0xee99ddbb, 0xfc82caa6, 0xf28bc7ad,\n      0xd8b4e49c, 0xd6bde997, 0xc4a6fe8a, 0xcaaff381,\n      0x90d8b8e8, 0x9ed1b5e3, 0x8ccaa2fe, 0x82c3aff5,\n      0xa8fc8cc4, 0xa6f581cf, 0xb4ee96d2, 0xbae79bd9,\n      0xdb3bbb7b, 0xd532b670, 0xc729a16d, 0xc920ac66,\n      0xe31f8f57, 0xed16825c, 0xff0d9541, 0xf104984a,\n      0xab73d323, 0xa57ade28, 0xb761c935, 0xb968c43e,\n      0x9357e70f, 0x9d5eea04, 0x8f45fd19, 0x814cf012,\n      0x3bab6bcb, 0x35a266c0, 0x27b971dd, 0x29b07cd6,\n      0x38f5fe7, 0xd8652ec, 0x1f9d45f1, 0x119448fa,\n      0x4be30393, 0x45ea0e98, 0x57f11985, 0x59f8148e,\n      0x73c737bf, 0x7dce3ab4, 0x6fd52da9, 0x61dc20a2,\n      0xad766df6, 0xa37f60fd, 0xb16477e0, 0xbf6d7aeb,\n      0x955259da, 0x9b5b54d1, 0x894043cc, 0x87494ec7,\n      0xdd3e05ae, 0xd33708a5, 0xc12c1fb8, 0xcf2512b3,\n      0xe51a3182, 0xeb133c89, 0xf9082b94, 0xf701269f,\n      0x4de6bd46, 0x43efb04d, 0x51f4a750, 0x5ffdaa5b,\n      0x75c2896a, 0x7bcb8461, 0x69d0937c, 0x67d99e77,\n      0x3daed51e, 0x33a7d815, 0x21bccf08, 0x2fb5c203,\n      0x58ae132, 0xb83ec39, 0x1998fb24, 0x1791f62f,\n      0x764dd68d, 0x7844db86, 0x6a5fcc9b, 0x6456c190,\n      0x4e69e2a1, 0x4060efaa, 0x527bf8b7, 0x5c72f5bc,\n      0x605bed5, 0x80cb3de, 0x1a17a4c3, 0x141ea9c8,\n      0x3e218af9, 0x302887f2, 0x223390ef, 0x2c3a9de4,\n      0x96dd063d, 0x98d40b36, 0x8acf1c2b, 0x84c61120,\n      0xaef93211, 0xa0f03f1a, 0xb2eb2807, 0xbce2250c,\n      0xe6956e65, 0xe89c636e, 0xfa877473, 0xf48e7978,\n      0xdeb15a49, 0xd0b85742, 0xc2a3405f, 0xccaa4d54,\n      0x41ecdaf7, 0x4fe5d7fc, 0x5dfec0e1, 0x53f7cdea,\n      0x79c8eedb, 0x77c1e3d0, 0x65daf4cd, 0x6bd3f9c6,\n      0x31a4b2af, 0x3fadbfa4, 0x2db6a8b9, 0x23bfa5b2,\n      0x9808683, 0x7898b88, 0x15929c95, 0x1b9b919e,\n      0xa17c0a47, 0xaf75074c, 0xbd6e1051, 0xb3671d5a,\n      0x99583e6b, 0x97513360, 0x854a247d, 0x8b432976,\n      0xd134621f, 0xdf3d6f14, 0xcd267809, 0xc32f7502,\n      0xe9105633, 0xe7195b38, 0xf5024c25, 0xfb0b412e,\n      0x9ad7618c, 0x94de6c87, 0x86c57b9a, 0x88cc7691,\n      0xa2f355a0, 0xacfa58ab, 0xbee14fb6, 0xb0e842bd,\n      0xea9f09d4, 0xe49604df, 0xf68d13c2, 0xf8841ec9,\n      0xd2bb3df8, 0xdcb230f3, 0xcea927ee, 0xc0a02ae5,\n      0x7a47b13c, 0x744ebc37, 0x6655ab2a, 0x685ca621,\n      0x42638510, 0x4c6a881b, 0x5e719f06, 0x5078920d,\n      0xa0fd964, 0x406d46f, 0x161dc372, 0x1814ce79,\n      0x322bed48, 0x3c22e043, 0x2e39f75e, 0x2030fa55,\n      0xec9ab701, 0xe293ba0a, 0xf088ad17, 0xfe81a01c,\n      0xd4be832d, 0xdab78e26, 0xc8ac993b, 0xc6a59430,\n      0x9cd2df59, 0x92dbd252, 0x80c0c54f, 0x8ec9c844,\n      0xa4f6eb75, 0xaaffe67e, 0xb8e4f163, 0xb6edfc68,\n      0xc0a67b1, 0x2036aba, 0x10187da7, 0x1e1170ac,\n      0x342e539d, 0x3a275e96, 0x283c498b, 0x26354480,\n      0x7c420fe9, 0x724b02e2, 0x605015ff, 0x6e5918f4,\n      0x44663bc5, 0x4a6f36ce, 0x587421d3, 0x567d2cd8,\n      0x37a10c7a, 0x39a80171, 0x2bb3166c, 0x25ba1b67,\n      0xf853856, 0x18c355d, 0x13972240, 0x1d9e2f4b,\n      0x47e96422, 0x49e06929, 0x5bfb7e34, 0x55f2733f,\n      0x7fcd500e, 0x71c45d05, 0x63df4a18, 0x6dd64713,\n      0xd731dcca, 0xd938d1c1, 0xcb23c6dc, 0xc52acbd7,\n      0xef15e8e6, 0xe11ce5ed, 0xf307f2f0, 0xfd0efffb,\n      0xa779b492, 0xa970b999, 0xbb6bae84, 0xb562a38f,\n      0x9f5d80be, 0x91548db5, 0x834f9aa8, 0x8d4697a3)\n\nU2 = (0x0, 0xb0e090d, 0x161c121a, 0x1d121b17,\n      0x2c382434, 0x27362d39, 0x3a24362e, 0x312a3f23,\n      0x58704868, 0x537e4165, 0x4e6c5a72, 0x4562537f,\n      0x74486c5c, 0x7f466551, 0x62547e46, 0x695a774b,\n      0xb0e090d0, 0xbbee99dd, 0xa6fc82ca, 0xadf28bc7,\n      0x9cd8b4e4, 0x97d6bde9, 0x8ac4a6fe, 0x81caaff3,\n      0xe890d8b8, 0xe39ed1b5, 0xfe8ccaa2, 0xf582c3af,\n      0xc4a8fc8c, 0xcfa6f581, 0xd2b4ee96, 0xd9bae79b,\n      0x7bdb3bbb, 0x70d532b6, 0x6dc729a1, 0x66c920ac,\n      0x57e31f8f, 0x5ced1682, 0x41ff0d95, 0x4af10498,\n      0x23ab73d3, 0x28a57ade, 0x35b761c9, 0x3eb968c4,\n      0xf9357e7, 0x49d5eea, 0x198f45fd, 0x12814cf0,\n      0xcb3bab6b, 0xc035a266, 0xdd27b971, 0xd629b07c,\n      0xe7038f5f, 0xec0d8652, 0xf11f9d45, 0xfa119448,\n      0x934be303, 0x9845ea0e, 0x8557f119, 0x8e59f814,\n      0xbf73c737, 0xb47dce3a, 0xa96fd52d, 0xa261dc20,\n      0xf6ad766d, 0xfda37f60, 0xe0b16477, 0xebbf6d7a,\n      0xda955259, 0xd19b5b54, 0xcc894043, 0xc787494e,\n      0xaedd3e05, 0xa5d33708, 0xb8c12c1f, 0xb3cf2512,\n      0x82e51a31, 0x89eb133c, 0x94f9082b, 0x9ff70126,\n      0x464de6bd, 0x4d43efb0, 0x5051f4a7, 0x5b5ffdaa,\n      0x6a75c289, 0x617bcb84, 0x7c69d093, 0x7767d99e,\n      0x1e3daed5, 0x1533a7d8, 0x821bccf, 0x32fb5c2,\n      0x32058ae1, 0x390b83ec, 0x241998fb, 0x2f1791f6,\n      0x8d764dd6, 0x867844db, 0x9b6a5fcc, 0x906456c1,\n      0xa14e69e2, 0xaa4060ef, 0xb7527bf8, 0xbc5c72f5,\n      0xd50605be, 0xde080cb3, 0xc31a17a4, 0xc8141ea9,\n      0xf93e218a, 0xf2302887, 0xef223390, 0xe42c3a9d,\n      0x3d96dd06, 0x3698d40b, 0x2b8acf1c, 0x2084c611,\n      0x11aef932, 0x1aa0f03f, 0x7b2eb28, 0xcbce225,\n      0x65e6956e, 0x6ee89c63, 0x73fa8774, 0x78f48e79,\n      0x49deb15a, 0x42d0b857, 0x5fc2a340, 0x54ccaa4d,\n      0xf741ecda, 0xfc4fe5d7, 0xe15dfec0, 0xea53f7cd,\n      0xdb79c8ee, 0xd077c1e3, 0xcd65daf4, 0xc66bd3f9,\n      0xaf31a4b2, 0xa43fadbf, 0xb92db6a8, 0xb223bfa5,\n      0x83098086, 0x8807898b, 0x9515929c, 0x9e1b9b91,\n      0x47a17c0a, 0x4caf7507, 0x51bd6e10, 0x5ab3671d,\n      0x6b99583e, 0x60975133, 0x7d854a24, 0x768b4329,\n      0x1fd13462, 0x14df3d6f, 0x9cd2678, 0x2c32f75,\n      0x33e91056, 0x38e7195b, 0x25f5024c, 0x2efb0b41,\n      0x8c9ad761, 0x8794de6c, 0x9a86c57b, 0x9188cc76,\n      0xa0a2f355, 0xabacfa58, 0xb6bee14f, 0xbdb0e842,\n      0xd4ea9f09, 0xdfe49604, 0xc2f68d13, 0xc9f8841e,\n      0xf8d2bb3d, 0xf3dcb230, 0xeecea927, 0xe5c0a02a,\n      0x3c7a47b1, 0x37744ebc, 0x2a6655ab, 0x21685ca6,\n      0x10426385, 0x1b4c6a88, 0x65e719f, 0xd507892,\n      0x640a0fd9, 0x6f0406d4, 0x72161dc3, 0x791814ce,\n      0x48322bed, 0x433c22e0, 0x5e2e39f7, 0x552030fa,\n      0x1ec9ab7, 0xae293ba, 0x17f088ad, 0x1cfe81a0,\n      0x2dd4be83, 0x26dab78e, 0x3bc8ac99, 0x30c6a594,\n      0x599cd2df, 0x5292dbd2, 0x4f80c0c5, 0x448ec9c8,\n      0x75a4f6eb, 0x7eaaffe6, 0x63b8e4f1, 0x68b6edfc,\n      0xb10c0a67, 0xba02036a, 0xa710187d, 0xac1e1170,\n      0x9d342e53, 0x963a275e, 0x8b283c49, 0x80263544,\n      0xe97c420f, 0xe2724b02, 0xff605015, 0xf46e5918,\n      0xc544663b, 0xce4a6f36, 0xd3587421, 0xd8567d2c,\n      0x7a37a10c, 0x7139a801, 0x6c2bb316, 0x6725ba1b,\n      0x560f8538, 0x5d018c35, 0x40139722, 0x4b1d9e2f,\n      0x2247e964, 0x2949e069, 0x345bfb7e, 0x3f55f273,\n      0xe7fcd50, 0x571c45d, 0x1863df4a, 0x136dd647,\n      0xcad731dc, 0xc1d938d1, 0xdccb23c6, 0xd7c52acb,\n      0xe6ef15e8, 0xede11ce5, 0xf0f307f2, 0xfbfd0eff,\n      0x92a779b4, 0x99a970b9, 0x84bb6bae, 0x8fb562a3,\n      0xbe9f5d80, 0xb591548d, 0xa8834f9a, 0xa38d4697)\n\nU3 = (0x0, 0xd0b0e09, 0x1a161c12, 0x171d121b,\n      0x342c3824, 0x3927362d, 0x2e3a2436, 0x23312a3f,\n      0x68587048, 0x65537e41, 0x724e6c5a, 0x7f456253,\n      0x5c74486c, 0x517f4665, 0x4662547e, 0x4b695a77,\n      0xd0b0e090, 0xddbbee99, 0xcaa6fc82, 0xc7adf28b,\n      0xe49cd8b4, 0xe997d6bd, 0xfe8ac4a6, 0xf381caaf,\n      0xb8e890d8, 0xb5e39ed1, 0xa2fe8cca, 0xaff582c3,\n      0x8cc4a8fc, 0x81cfa6f5, 0x96d2b4ee, 0x9bd9bae7,\n      0xbb7bdb3b, 0xb670d532, 0xa16dc729, 0xac66c920,\n      0x8f57e31f, 0x825ced16, 0x9541ff0d, 0x984af104,\n      0xd323ab73, 0xde28a57a, 0xc935b761, 0xc43eb968,\n      0xe70f9357, 0xea049d5e, 0xfd198f45, 0xf012814c,\n      0x6bcb3bab, 0x66c035a2, 0x71dd27b9, 0x7cd629b0,\n      0x5fe7038f, 0x52ec0d86, 0x45f11f9d, 0x48fa1194,\n      0x3934be3, 0xe9845ea, 0x198557f1, 0x148e59f8,\n      0x37bf73c7, 0x3ab47dce, 0x2da96fd5, 0x20a261dc,\n      0x6df6ad76, 0x60fda37f, 0x77e0b164, 0x7aebbf6d,\n      0x59da9552, 0x54d19b5b, 0x43cc8940, 0x4ec78749,\n      0x5aedd3e, 0x8a5d337, 0x1fb8c12c, 0x12b3cf25,\n      0x3182e51a, 0x3c89eb13, 0x2b94f908, 0x269ff701,\n      0xbd464de6, 0xb04d43ef, 0xa75051f4, 0xaa5b5ffd,\n      0x896a75c2, 0x84617bcb, 0x937c69d0, 0x9e7767d9,\n      0xd51e3dae, 0xd81533a7, 0xcf0821bc, 0xc2032fb5,\n      0xe132058a, 0xec390b83, 0xfb241998, 0xf62f1791,\n      0xd68d764d, 0xdb867844, 0xcc9b6a5f, 0xc1906456,\n      0xe2a14e69, 0xefaa4060, 0xf8b7527b, 0xf5bc5c72,\n      0xbed50605, 0xb3de080c, 0xa4c31a17, 0xa9c8141e,\n      0x8af93e21, 0x87f23028, 0x90ef2233, 0x9de42c3a,\n      0x63d96dd, 0xb3698d4, 0x1c2b8acf, 0x112084c6,\n      0x3211aef9, 0x3f1aa0f0, 0x2807b2eb, 0x250cbce2,\n      0x6e65e695, 0x636ee89c, 0x7473fa87, 0x7978f48e,\n      0x5a49deb1, 0x5742d0b8, 0x405fc2a3, 0x4d54ccaa,\n      0xdaf741ec, 0xd7fc4fe5, 0xc0e15dfe, 0xcdea53f7,\n      0xeedb79c8, 0xe3d077c1, 0xf4cd65da, 0xf9c66bd3,\n      0xb2af31a4, 0xbfa43fad, 0xa8b92db6, 0xa5b223bf,\n      0x86830980, 0x8b880789, 0x9c951592, 0x919e1b9b,\n      0xa47a17c, 0x74caf75, 0x1051bd6e, 0x1d5ab367,\n      0x3e6b9958, 0x33609751, 0x247d854a, 0x29768b43,\n      0x621fd134, 0x6f14df3d, 0x7809cd26, 0x7502c32f,\n      0x5633e910, 0x5b38e719, 0x4c25f502, 0x412efb0b,\n      0x618c9ad7, 0x6c8794de, 0x7b9a86c5, 0x769188cc,\n      0x55a0a2f3, 0x58abacfa, 0x4fb6bee1, 0x42bdb0e8,\n      0x9d4ea9f, 0x4dfe496, 0x13c2f68d, 0x1ec9f884,\n      0x3df8d2bb, 0x30f3dcb2, 0x27eecea9, 0x2ae5c0a0,\n      0xb13c7a47, 0xbc37744e, 0xab2a6655, 0xa621685c,\n      0x85104263, 0x881b4c6a, 0x9f065e71, 0x920d5078,\n      0xd9640a0f, 0xd46f0406, 0xc372161d, 0xce791814,\n      0xed48322b, 0xe0433c22, 0xf75e2e39, 0xfa552030,\n      0xb701ec9a, 0xba0ae293, 0xad17f088, 0xa01cfe81,\n      0x832dd4be, 0x8e26dab7, 0x993bc8ac, 0x9430c6a5,\n      0xdf599cd2, 0xd25292db, 0xc54f80c0, 0xc8448ec9,\n      0xeb75a4f6, 0xe67eaaff, 0xf163b8e4, 0xfc68b6ed,\n      0x67b10c0a, 0x6aba0203, 0x7da71018, 0x70ac1e11,\n      0x539d342e, 0x5e963a27, 0x498b283c, 0x44802635,\n      0xfe97c42, 0x2e2724b, 0x15ff6050, 0x18f46e59,\n      0x3bc54466, 0x36ce4a6f, 0x21d35874, 0x2cd8567d,\n      0xc7a37a1, 0x17139a8, 0x166c2bb3, 0x1b6725ba,\n      0x38560f85, 0x355d018c, 0x22401397, 0x2f4b1d9e,\n      0x642247e9, 0x692949e0, 0x7e345bfb, 0x733f55f2,\n      0x500e7fcd, 0x5d0571c4, 0x4a1863df, 0x47136dd6,\n      0xdccad731, 0xd1c1d938, 0xc6dccb23, 0xcbd7c52a,\n      0xe8e6ef15, 0xe5ede11c, 0xf2f0f307, 0xfffbfd0e,\n      0xb492a779, 0xb999a970, 0xae84bb6b, 0xa38fb562,\n      0x80be9f5d, 0x8db59154, 0x9aa8834f, 0x97a38d46)\n\nU4 = (0x0, 0x90d0b0e, 0x121a161c, 0x1b171d12,\n      0x24342c38, 0x2d392736, 0x362e3a24, 0x3f23312a,\n      0x48685870, 0x4165537e, 0x5a724e6c, 0x537f4562,\n      0x6c5c7448, 0x65517f46, 0x7e466254, 0x774b695a,\n      0x90d0b0e0, 0x99ddbbee, 0x82caa6fc, 0x8bc7adf2,\n      0xb4e49cd8, 0xbde997d6, 0xa6fe8ac4, 0xaff381ca,\n      0xd8b8e890, 0xd1b5e39e, 0xcaa2fe8c, 0xc3aff582,\n      0xfc8cc4a8, 0xf581cfa6, 0xee96d2b4, 0xe79bd9ba,\n      0x3bbb7bdb, 0x32b670d5, 0x29a16dc7, 0x20ac66c9,\n      0x1f8f57e3, 0x16825ced, 0xd9541ff, 0x4984af1,\n      0x73d323ab, 0x7ade28a5, 0x61c935b7, 0x68c43eb9,\n      0x57e70f93, 0x5eea049d, 0x45fd198f, 0x4cf01281,\n      0xab6bcb3b, 0xa266c035, 0xb971dd27, 0xb07cd629,\n      0x8f5fe703, 0x8652ec0d, 0x9d45f11f, 0x9448fa11,\n      0xe303934b, 0xea0e9845, 0xf1198557, 0xf8148e59,\n      0xc737bf73, 0xce3ab47d, 0xd52da96f, 0xdc20a261,\n      0x766df6ad, 0x7f60fda3, 0x6477e0b1, 0x6d7aebbf,\n      0x5259da95, 0x5b54d19b, 0x4043cc89, 0x494ec787,\n      0x3e05aedd, 0x3708a5d3, 0x2c1fb8c1, 0x2512b3cf,\n      0x1a3182e5, 0x133c89eb, 0x82b94f9, 0x1269ff7,\n      0xe6bd464d, 0xefb04d43, 0xf4a75051, 0xfdaa5b5f,\n      0xc2896a75, 0xcb84617b, 0xd0937c69, 0xd99e7767,\n      0xaed51e3d, 0xa7d81533, 0xbccf0821, 0xb5c2032f,\n      0x8ae13205, 0x83ec390b, 0x98fb2419, 0x91f62f17,\n      0x4dd68d76, 0x44db8678, 0x5fcc9b6a, 0x56c19064,\n      0x69e2a14e, 0x60efaa40, 0x7bf8b752, 0x72f5bc5c,\n      0x5bed506, 0xcb3de08, 0x17a4c31a, 0x1ea9c814,\n      0x218af93e, 0x2887f230, 0x3390ef22, 0x3a9de42c,\n      0xdd063d96, 0xd40b3698, 0xcf1c2b8a, 0xc6112084,\n      0xf93211ae, 0xf03f1aa0, 0xeb2807b2, 0xe2250cbc,\n      0x956e65e6, 0x9c636ee8, 0x877473fa, 0x8e7978f4,\n      0xb15a49de, 0xb85742d0, 0xa3405fc2, 0xaa4d54cc,\n      0xecdaf741, 0xe5d7fc4f, 0xfec0e15d, 0xf7cdea53,\n      0xc8eedb79, 0xc1e3d077, 0xdaf4cd65, 0xd3f9c66b,\n      0xa4b2af31, 0xadbfa43f, 0xb6a8b92d, 0xbfa5b223,\n      0x80868309, 0x898b8807, 0x929c9515, 0x9b919e1b,\n      0x7c0a47a1, 0x75074caf, 0x6e1051bd, 0x671d5ab3,\n      0x583e6b99, 0x51336097, 0x4a247d85, 0x4329768b,\n      0x34621fd1, 0x3d6f14df, 0x267809cd, 0x2f7502c3,\n      0x105633e9, 0x195b38e7, 0x24c25f5, 0xb412efb,\n      0xd7618c9a, 0xde6c8794, 0xc57b9a86, 0xcc769188,\n      0xf355a0a2, 0xfa58abac, 0xe14fb6be, 0xe842bdb0,\n      0x9f09d4ea, 0x9604dfe4, 0x8d13c2f6, 0x841ec9f8,\n      0xbb3df8d2, 0xb230f3dc, 0xa927eece, 0xa02ae5c0,\n      0x47b13c7a, 0x4ebc3774, 0x55ab2a66, 0x5ca62168,\n      0x63851042, 0x6a881b4c, 0x719f065e, 0x78920d50,\n      0xfd9640a, 0x6d46f04, 0x1dc37216, 0x14ce7918,\n      0x2bed4832, 0x22e0433c, 0x39f75e2e, 0x30fa5520,\n      0x9ab701ec, 0x93ba0ae2, 0x88ad17f0, 0x81a01cfe,\n      0xbe832dd4, 0xb78e26da, 0xac993bc8, 0xa59430c6,\n      0xd2df599c, 0xdbd25292, 0xc0c54f80, 0xc9c8448e,\n      0xf6eb75a4, 0xffe67eaa, 0xe4f163b8, 0xedfc68b6,\n      0xa67b10c, 0x36aba02, 0x187da710, 0x1170ac1e,\n      0x2e539d34, 0x275e963a, 0x3c498b28, 0x35448026,\n      0x420fe97c, 0x4b02e272, 0x5015ff60, 0x5918f46e,\n      0x663bc544, 0x6f36ce4a, 0x7421d358, 0x7d2cd856,\n      0xa10c7a37, 0xa8017139, 0xb3166c2b, 0xba1b6725,\n      0x8538560f, 0x8c355d01, 0x97224013, 0x9e2f4b1d,\n      0xe9642247, 0xe0692949, 0xfb7e345b, 0xf2733f55,\n      0xcd500e7f, 0xc45d0571, 0xdf4a1863, 0xd647136d,\n      0x31dccad7, 0x38d1c1d9, 0x23c6dccb, 0x2acbd7c5,\n      0x15e8e6ef, 0x1ce5ede1, 0x7f2f0f3, 0xefffbfd,\n      0x79b492a7, 0x70b999a9, 0x6bae84bb, 0x62a38fb5,\n      0x5d80be9f, 0x548db591, 0x4f9aa883, 0x4697a38d)\n\nrcon = (0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80,\n        0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f,\n        0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4,\n        0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91)\n\n@deprecated_class_name('rijndael')\nclass Rijndael(object):\n    \"\"\"\n    Implementation of the AES (formely known as Rijndael) block cipher.\n\n    Supports key sizes of 128, 192 and 256 bits as well as the non\n    standard block sizes of 192 and 256 bits (the standard 128 bit block\n    size is the default).\n\n    Note: this is a pure python stright-forward implementation thus it is\n    vulnerable against majority, if not all possible side channel attacks.\n\n    Can process data just one block at a time, does not perform block\n    cipher chaining or plaintext padding.\n\n    :ival int block_size: the size of the encrypted blocks, in bytes\n    :ival list Ke: key schedule for encryption\n    :ival list Kd: key schedule for decryption\n    \"\"\"\n    def __init__(self, key, block_size = 16):\n        \"\"\"Initialise the object, derive keys for encryption and decryption.\"\"\"\n        if block_size != 16 and block_size != 24 and block_size != 32:\n            raise ValueError('Invalid block size: ' + str(block_size))\n        if len(key) != 16 and len(key) != 24 and len(key) != 32:\n            raise ValueError('Invalid key size: ' + str(len(key)))\n        self.block_size = block_size\n\n        ROUNDS = num_rounds[len(key)][block_size]\n        BC = block_size // 4\n        # encryption round keys\n        Ke = [[0] * BC for i in range(ROUNDS + 1)]\n        # decryption round keys\n        Kd = [[0] * BC for i in range(ROUNDS + 1)]\n        ROUND_KEY_COUNT = (ROUNDS + 1) * BC\n        KC = len(key) // 4\n\n        # copy user material bytes into temporary ints\n        tk = []\n        for i in range(0, KC):\n            tk.append((key[i * 4] << 24) | (key[i * 4 + 1] << 16) |\n                (key[i * 4 + 2] << 8) | key[i * 4 + 3])\n\n        # copy values into round key arrays\n        t = 0\n        j = 0\n        while j < KC and t < ROUND_KEY_COUNT:\n            Ke[t // BC][t % BC] = tk[j]\n            Kd[ROUNDS - (t // BC)][t % BC] = tk[j]\n            j += 1\n            t += 1\n        tt = 0\n        rconpointer = 0\n        while t < ROUND_KEY_COUNT:\n            # extrapolate using phi (the round key evolution function)\n            tt = tk[KC - 1]\n            tk[0] ^= (S[(tt >> 16) & 0xFF] & 0xFF) << 24 ^  \\\n                     (S[(tt >>  8) & 0xFF] & 0xFF) << 16 ^  \\\n                     (S[ tt        & 0xFF] & 0xFF) <<  8 ^  \\\n                     (S[(tt >> 24) & 0xFF] & 0xFF)       ^  \\\n                     (rcon[rconpointer]    & 0xFF) << 24\n            rconpointer += 1\n            if KC != 8:\n                for i in range(1, KC):\n                    tk[i] ^= tk[i-1]\n            else:\n                for i in range(1, KC // 2):\n                    tk[i] ^= tk[i-1]\n                tt = tk[KC // 2 - 1]\n                tk[KC // 2] ^= (S[ tt        & 0xFF] & 0xFF)       ^ \\\n                              (S[(tt >>  8) & 0xFF] & 0xFF) <<  8 ^ \\\n                              (S[(tt >> 16) & 0xFF] & 0xFF) << 16 ^ \\\n                              (S[(tt >> 24) & 0xFF] & 0xFF) << 24\n                for i in range(KC // 2 + 1, KC):\n                    tk[i] ^= tk[i-1]\n            # copy values into round key arrays\n            j = 0\n            while j < KC and t < ROUND_KEY_COUNT:\n                Ke[t // BC][t % BC] = tk[j]\n                Kd[ROUNDS - (t // BC)][t % BC] = tk[j]\n                j += 1\n                t += 1\n        # inverse MixColumn where needed\n        for r in range(1, ROUNDS):\n            for j in range(BC):\n                tt = Kd[r][j]\n                Kd[r][j] = U1[(tt >> 24) & 0xFF] ^ \\\n                           U2[(tt >> 16) & 0xFF] ^ \\\n                           U3[(tt >>  8) & 0xFF] ^ \\\n                           U4[ tt        & 0xFF]\n        self.Ke = Ke\n        self.Kd = Kd\n\n    def encrypt(self, plaintext):\n        \"\"\"Encrypt a single block of plaintext.\"\"\"\n        if len(plaintext) != self.block_size:\n            raise ValueError('wrong block length, expected {0} got {1}'\n                             .format(self.block_size, len(plaintext)))\n        Ke = self.Ke\n\n        BC = self.block_size // 4\n        ROUNDS = len(Ke) - 1\n        if BC == 4:\n            SC = 0\n        elif BC == 6:\n            SC = 1\n        else:\n            SC = 2\n        s1 = shifts[SC][1][0]\n        s2 = shifts[SC][2][0]\n        s3 = shifts[SC][3][0]\n        a = [0] * BC\n        # temporary work array\n        t = []\n        # plaintext to ints + key\n        for i in range(BC):\n            t.append((plaintext[i * 4    ] << 24 |\n                      plaintext[i * 4 + 1] << 16 |\n                      plaintext[i * 4 + 2] <<  8 |\n                      plaintext[i * 4 + 3]        ) ^ Ke[0][i])\n        # apply round transforms\n        for r in range(1, ROUNDS):\n            for i in range(BC):\n                a[i] = (T1[(t[ i           ] >> 24) & 0xFF] ^\n                        T2[(t[(i + s1) % BC] >> 16) & 0xFF] ^\n                        T3[(t[(i + s2) % BC] >>  8) & 0xFF] ^\n                        T4[ t[(i + s3) % BC]        & 0xFF]  ) ^ Ke[r][i]\n            t = a[:]\n        # last round is special\n        result = []\n        for i in range(BC):\n            tt = Ke[ROUNDS][i]\n            result.append((S[(t[ i         ] >> 24) & 0xFF] ^ (tt>>24)) & 0xFF)\n            result.append((S[(t[(i+s1) % BC] >> 16) & 0xFF] ^ (tt>>16)) & 0xFF)\n            result.append((S[(t[(i+s2) % BC] >>  8) & 0xFF] ^ (tt>> 8)) & 0xFF)\n            result.append((S[ t[(i+s3) % BC]        & 0xFF] ^  tt     ) & 0xFF)\n        return bytearray(result)\n\n    def decrypt(self, ciphertext):\n        \"\"\"Decrypt a block of ciphertext.\"\"\"\n        if len(ciphertext) != self.block_size:\n            raise ValueError('wrong block length, expected {0} got {1}'\n                             .format(self.block_size, len(ciphertext)))\n        Kd = self.Kd\n\n        BC = self.block_size // 4\n        ROUNDS = len(Kd) - 1\n        if BC == 4:\n            SC = 0\n        elif BC == 6:\n            SC = 1\n        else:\n            SC = 2\n        s1 = shifts[SC][1][1]\n        s2 = shifts[SC][2][1]\n        s3 = shifts[SC][3][1]\n        a = [0] * BC\n        # temporary work array\n        t = [0] * BC\n        # ciphertext to ints + key\n        for i in range(BC):\n            t[i] = (ciphertext[i * 4    ] << 24 |\n                    ciphertext[i * 4 + 1] << 16 |\n                    ciphertext[i * 4 + 2] <<  8 |\n                    ciphertext[i * 4 + 3]        ) ^ Kd[0][i]\n        # apply round transforms\n        for r in range(1, ROUNDS):\n            for i in range(BC):\n                a[i] = (T5[(t[ i           ] >> 24) & 0xFF] ^\n                        T6[(t[(i + s1) % BC] >> 16) & 0xFF] ^\n                        T7[(t[(i + s2) % BC] >>  8) & 0xFF] ^\n                        T8[ t[(i + s3) % BC]        & 0xFF]  ) ^ Kd[r][i]\n            t = a[:]\n        # last round is special\n        result = []\n        for i in range(BC):\n            tt = Kd[ROUNDS][i]\n            result.append((Si[(t[ i         ] >> 24) & 0xFF] ^ (tt>>24)) &0xFF)\n            result.append((Si[(t[(i+s1) % BC] >> 16) & 0xFF] ^ (tt>>16)) &0xFF)\n            result.append((Si[(t[(i+s2) % BC] >>  8) & 0xFF] ^ (tt>> 8)) &0xFF)\n            result.append((Si[ t[(i+s3) % BC]        & 0xFF] ^  tt     ) &0xFF)\n        return bytearray(result)\n\ndef encrypt(key, block):\n    return Rijndael(key, len(block)).encrypt(block)\n\ndef decrypt(key, block):\n    return Rijndael(key, len(block)).decrypt(block)\n\ndef test():\n    def t(kl, bl):\n        b = 'b' * bl\n        r = Rijndael('a' * kl, bl)\n        assert r.decrypt(r.encrypt(b)) == b\n    t(16, 16)\n    t(16, 24)\n    t(16, 32)\n    t(24, 16)\n    t(24, 24)\n    t(24, 32)\n    t(32, 16)\n    t(32, 24)\n    t(32, 32)\n\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/rsakey.py",
    "content": "# Author: Trevor Perrin\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Abstract class for RSA.\"\"\"\n\nfrom .cryptomath import *\nfrom . import tlshashlib as hashlib\nfrom ..errors import MaskTooLongError, MessageTooLongError, EncodingError, \\\n    InvalidSignature, UnknownRSAType\nfrom .constanttime import ct_isnonzero_u32, ct_neq_u32, ct_lsb_prop_u8, \\\n    ct_lsb_prop_u16, ct_lt_u32\n\n\nclass RSAKey(object):\n    \"\"\"This is an abstract base class for RSA keys.\n\n    Particular implementations of RSA keys, such as\n    :py:class:`~.openssl_rsakey.OpenSSL_RSAKey`,\n    :py:class:`~.python_rsakey.Python_RSAKey`, and\n    :py:class:`~.pycrypto_rsakey.PyCrypto_RSAKey`,\n    inherit from this.\n\n    To create or parse an RSA key, don't use one of these classes\n    directly.  Instead, use the factory functions in\n    :py:class:`~tlslite.utils.keyfactory`.\n    \"\"\"\n\n    def __init__(self, n=0, e=0, key_type=\"rsa\"):\n        \"\"\"Create a new RSA key.\n\n        If n and e are passed in, the new key will be initialized.\n\n        :type n: int\n        :param n: RSA modulus.\n\n        :type e: int\n        :param e: RSA public exponent.\n\n        :type key_type: str\n        :param key_type: type of the RSA key, \"rsa\" for rsaEncryption\n            (universal, able to perform all operations) or \"rsa-pss\" for a\n            RSASSA-PSS key (able to perform only RSA-PSS signature verification\n            and creation)\n        \"\"\"\n        # pylint: disable=invalid-name\n        self.n = n\n        self.e = e\n        # pylint: enable=invalid-name\n        self.key_type = key_type\n        self._key_hash = None\n        raise NotImplementedError()\n\n    def __len__(self):\n        \"\"\"Return the length of this key in bits.\n\n        :rtype: int\n        \"\"\"\n        return numBits(self.n)\n\n    def hasPrivateKey(self):\n        \"\"\"Return whether or not this key has a private component.\n\n        :rtype: bool\n        \"\"\"\n        raise NotImplementedError()\n\n    def hashAndSign(self, bytes, rsaScheme='PKCS1', hAlg='sha1', sLen=0):\n        \"\"\"Hash and sign the passed-in bytes.\n\n        This requires the key to have a private component.  It performs\n        a PKCS1 or PSS signature on the passed-in data with selected hash\n        algorithm.\n\n        :type bytes: bytes-like object\n        :param bytes: The value which will be hashed and signed.\n\n        :type rsaScheme: str\n        :param rsaScheme: The type of RSA scheme that will be applied,\n                          \"PKCS1\" for RSASSA-PKCS#1 v1.5 signature and \"PSS\"\n                          for RSASSA-PSS with MGF1 signature method\n\n        :type hAlg: str\n        :param hAlg: The hash algorithm that will be used\n\n        :type sLen: int\n        :param sLen: The length of intended salt value, applicable only\n                     for RSASSA-PSS signatures\n\n        :rtype: bytearray\n        :returns: A PKCS1 or PSS signature on the passed-in data.\n        \"\"\"\n        rsaScheme = rsaScheme.lower()\n        hAlg = hAlg.lower()\n        hashBytes = secureHash(bytearray(bytes), hAlg)\n        return self.sign(hashBytes, padding=rsaScheme, hashAlg=hAlg,\n                         saltLen=sLen)\n\n    def hashAndVerify(self, sigBytes, bytes, rsaScheme='PKCS1', hAlg='sha1',\n                      sLen=0):\n        \"\"\"Hash and verify the passed-in bytes with the signature.\n\n        This verifies a PKCS1 or PSS signature on the passed-in data\n        with selected hash algorithm.\n\n        :type sigBytes: bytes-like object\n        :param sigBytes: A PKCS1 or PSS signature.\n\n        :type bytes: bytes-like object\n        :param bytes: The value which will be hashed and verified.\n\n        :type rsaScheme: str\n        :param rsaScheme: The type of RSA scheme that will be applied,\n                          \"PKCS1\" for RSASSA-PKCS#1 v1.5 signature and \"PSS\"\n                          for RSASSA-PSS with MGF1 signature method\n\n        :type hAlg: str\n        :param hAlg: The hash algorithm that will be used\n\n        :type sLen: int\n        :param sLen: The length of intended salt value, applicable only\n                     for RSASSA-PSS signatures\n\n        :rtype: bool\n        :returns: Whether the signature matches the passed-in data.\n        \"\"\"\n        rsaScheme = rsaScheme.lower()\n        hAlg = hAlg.lower()\n\n        hashBytes = secureHash(bytearray(bytes), hAlg)\n        return self.verify(sigBytes, hashBytes, rsaScheme, hAlg, sLen)\n\n    def MGF1(self, mgfSeed, maskLen, hAlg):\n        \"\"\"Generate mask from passed-in seed.\n\n        This generates mask based on passed-in seed and output maskLen.\n\n        :type mgfSeed: bytearray\n        :param mgfSeed: Seed from which mask will be generated.\n\n        :type maskLen: int\n        :param maskLen: Wished length of the mask, in octets\n\n        :rtype: bytearray\n        :returns: Mask\n        \"\"\"\n        hashLen = getattr(hashlib, hAlg)().digest_size\n        if maskLen > (2 ** 32) * hashLen:\n            raise MaskTooLongError(\"Incorrect parameter maskLen\")\n        T = bytearray()\n        end = divceil(maskLen, hashLen)\n        for x in range(0, end):\n            C = numberToByteArray(x, 4)\n            T += secureHash(mgfSeed + C, hAlg)\n        return T[:maskLen]\n\n    def EMSA_PSS_encode(self, mHash, emBits, hAlg, sLen=0):\n        \"\"\"Encode the passed in message\n\n        This encodes the message using selected hash algorithm\n\n        :type mHash: bytearray\n        :param mHash: Hash of message to be encoded\n\n        :type emBits: int\n        :param emBits: maximal length of returned EM\n\n        :type hAlg: str\n        :param hAlg: hash algorithm to be used\n\n        :type sLen: int\n        :param sLen: length of salt\"\"\"\n        hashLen = getattr(hashlib, hAlg)().digest_size\n        emLen = divceil(emBits, 8)\n        if emLen < hashLen + sLen + 2:\n            raise EncodingError(\"The ending limit too short for \" +\n                                \"selected hash and salt length\")\n        salt = getRandomBytes(sLen)\n        M2 = bytearray(8) + mHash + salt\n        H = secureHash(M2, hAlg)\n        PS = bytearray(emLen - sLen - hashLen - 2)\n        DB = PS + bytearray(b'\\x01') + salt\n        dbMask = self.MGF1(H, emLen - hashLen - 1, hAlg)\n        maskedDB = bytearray(i ^ j for i, j in zip(DB, dbMask))\n        mLen = emLen*8 - emBits\n        mask = (1 << 8 - mLen) - 1\n        maskedDB[0] &= mask\n        EM = maskedDB + H + bytearray(b'\\xbc')\n        return EM\n\n    def RSASSA_PSS_sign(self, mHash, hAlg, sLen=0):\n        \"\"\"\"Sign the passed in message\n\n        This signs the message using selected hash algorithm\n\n        :type mHash: bytes-like object\n        :param mHash: Hash of message to be signed\n\n        :type hAlg: str\n        :param hAlg: hash algorithm to be used\n\n        :type sLen: int\n        :param sLen: length of salt\"\"\"\n        EM = self.EMSA_PSS_encode(mHash, numBits(self.n) - 1, hAlg, sLen)\n        try:\n            ret = self._raw_private_key_op_bytes(EM)\n        except ValueError:\n            raise MessageTooLongError(\"Encode output too long\")\n        return ret\n\n    def EMSA_PSS_verify(self, mHash, EM, emBits, hAlg, sLen=0):\n        \"\"\"Verify signature in passed in encoded message\n\n        This verifies the signature in encoded message\n\n        :type mHash: bytes-like object\n        :param mHash: Hash of the original not signed message\n\n        :type EM: bytes-like object\n        :param EM: Encoded message\n\n        :type emBits: int\n        :param emBits: Length of the encoded message in bits\n\n        :type hAlg: str\n        :param hAlg: hash algorithm to be used\n\n        :type sLen: int\n        :param sLen: Length of salt\n        \"\"\"\n        hashLen = getattr(hashlib, hAlg)().digest_size\n        emLen = divceil(emBits, 8)\n        if emLen < hashLen + sLen + 2:\n            raise InvalidSignature(\"Invalid signature\")\n        if EM[-1] != 0xbc:\n            raise InvalidSignature(\"Invalid signature\")\n        maskedDB = EM[0:emLen - hashLen - 1]\n        H = EM[emLen - hashLen - 1:emLen - hashLen - 1 + hashLen]\n        DBHelpMask = 1 << 8 - (8*emLen - emBits)\n        DBHelpMask -= 1\n        DBHelpMask = (~DBHelpMask) & 0xff\n        if maskedDB[0] & DBHelpMask != 0:\n            raise InvalidSignature(\"Invalid signature\")\n        dbMask = self.MGF1(H, emLen - hashLen - 1, hAlg)\n        DB = bytearray(i ^ j for i, j in zip(maskedDB, dbMask))\n        mLen = emLen*8 - emBits\n        mask = (1 << 8 - mLen) - 1\n        DB[0] &= mask\n        if any(x != 0 for x in DB[0:emLen - hashLen - sLen - 2]):\n            raise InvalidSignature(\"Invalid signature\")\n        if DB[emLen - hashLen - sLen - 2] != 0x01:\n            raise InvalidSignature(\"Invalid signature\")\n        if sLen != 0:\n            salt = DB[-sLen:]\n        else:\n            salt = bytearray()\n        newM = bytearray(8) + mHash + salt\n        newH = secureHash(newM, hAlg)\n        if H == newH:\n            return True\n        else:\n            raise InvalidSignature(\"Invalid signature\")\n\n    def RSASSA_PSS_verify(self, mHash, S, hAlg, sLen=0):\n        \"\"\"Verify the signature in passed in message\n\n        This verifies the signature in the signed message\n\n        :type mHash: bytes-like object\n        :param mHash: Hash of original message\n\n        :type S: bytes-like object\n        :param S: Signed message\n\n        :type hAlg: str\n        :param hAlg: Hash algorithm to be used\n\n        :type sLen: int\n        :param sLen: Length of salt\n        \"\"\"\n        try:\n            EM = self._raw_public_key_op_bytes(S)\n        except ValueError:\n            raise InvalidSignature(\"Invalid signature\")\n        result = self.EMSA_PSS_verify(mHash, EM, numBits(self.n) - 1,\n                                      hAlg, sLen)\n        if result:\n            return True\n        else:\n            raise InvalidSignature(\"Invalid signature\")\n\n    def _raw_pkcs1_sign(self, bytes):\n        \"\"\"Perform signature on raw data, add PKCS#1 padding.\"\"\"\n        if not self.hasPrivateKey():\n            raise AssertionError()\n        paddedBytes = self._addPKCS1Padding(bytes, 1)\n        return self._raw_private_key_op_bytes(paddedBytes)\n\n    def sign(self, bytes, padding='pkcs1', hashAlg=None, saltLen=None):\n        \"\"\"Sign the passed-in bytes.\n\n        This requires the key to have a private component.  It performs\n        a PKCS1 signature on the passed-in data.\n\n        :type bytes: bytes-like object\n        :param bytes: The value which will be signed.\n\n        :type padding: str\n        :param padding: name of the rsa padding mode to use, supported:\n            \"pkcs1\" for RSASSA-PKCS1_1_5 and \"pss\" for RSASSA-PSS.\n\n        :type hashAlg: str\n        :param hashAlg: name of hash to be encoded using the PKCS#1 prefix\n            for \"pkcs1\" padding or the hash used for MGF1 in \"pss\". Parameter\n            is mandatory for \"pss\" padding.\n\n        :type saltLen: int\n        :param saltLen: length of salt used for the PSS padding. Default\n            is the length of the hash output used.\n\n        :rtype: bytearray\n        :returns: A PKCS1 signature on the passed-in data.\n        \"\"\"\n        padding = padding.lower()\n        if padding == 'pkcs1':\n            if hashAlg is not None:\n                bytes = self.addPKCS1Prefix(bytes, hashAlg)\n            sigBytes = self._raw_pkcs1_sign(bytes)\n        elif padding == \"pss\":\n            sigBytes = self.RSASSA_PSS_sign(bytes, hashAlg, saltLen)\n        else:\n            raise UnknownRSAType(\"Unknown RSA algorithm type\")\n        return sigBytes\n\n    def _raw_pkcs1_verify(self, sigBytes, bytes):\n        \"\"\"Perform verification operation on raw PKCS#1 padded signature\"\"\"\n        try:\n            checkBytes = self._raw_public_key_op_bytes(sigBytes)\n        except ValueError:\n            return False\n        paddedBytes = self._addPKCS1Padding(bytes, 1)\n        return checkBytes == paddedBytes\n\n    def verify(self, sigBytes, bytes, padding='pkcs1', hashAlg=None,\n               saltLen=None):\n        \"\"\"Verify the passed-in bytes with the signature.\n\n        This verifies a PKCS1 signature on the passed-in data.\n\n        :type sigBytes: bytes-like object\n        :param sigBytes: A PKCS1 signature.\n\n        :type bytes: bytes-like object\n        :param bytes: The value which will be verified.\n\n        :rtype: bool\n        :returns: Whether the signature matches the passed-in data.\n        \"\"\"\n        if padding == \"pkcs1\" and self.key_type == \"rsa-pss\":\n            return False\n        if padding == \"pkcs1\" and hashAlg == 'sha1':\n            # Try it with/without the embedded NULL\n            prefixedHashBytes1 = self.addPKCS1SHA1Prefix(bytes, False)\n            prefixedHashBytes2 = self.addPKCS1SHA1Prefix(bytes, True)\n            result1 = self._raw_pkcs1_verify(sigBytes, prefixedHashBytes1)\n            result2 = self._raw_pkcs1_verify(sigBytes, prefixedHashBytes2)\n            return (result1 or result2)\n        elif padding == 'pkcs1':\n            if hashAlg is not None:\n                bytes = self.addPKCS1Prefix(bytes, hashAlg)\n            res = self._raw_pkcs1_verify(sigBytes, bytes)\n            return res\n        elif padding == \"pss\":\n            try:\n                res = self.RSASSA_PSS_verify(bytes, sigBytes, hashAlg, saltLen)\n            except InvalidSignature:\n                res = False\n            return res\n        else:\n            raise UnknownRSAType(\"Unknown RSA algorithm type\")\n\n    def encrypt(self, bytes):\n        \"\"\"Encrypt the passed-in bytes.\n\n        This performs PKCS1 encryption of the passed-in data.\n\n        :type bytes: bytes-like object\n        :param bytes: The value which will be encrypted.\n\n        :rtype: bytearray\n        :returns: A PKCS1 encryption of the passed-in data.\n        \"\"\"\n        paddedBytes = self._addPKCS1Padding(bytes, 2)\n        return self._raw_public_key_op_bytes(paddedBytes)\n\n    def _dec_prf(self, key, label, out_len):\n        \"\"\"PRF for deterministic implicit rejection in the RSA decryption.\n\n        :param bytes key: key to use for derivation\n        :param bytes label: name of the keystream generated\n        :param int out_len: length of output, in bits\n        :rtype: bytes\n        :returns: a random bytestring\n        \"\"\"\n        out = bytearray()\n\n        if out_len % 8 != 0:\n            raise ValueError(\"only multiples of 8 supported as output size\")\n\n        iterator = 0\n        while len(out) < out_len // 8:\n            out += secureHMAC(\n                key,\n                numberToByteArray(iterator, 2) + label +\n                numberToByteArray(out_len, 2),\n                \"sha256\")\n            iterator += 1\n\n        return out[:out_len//8]\n\n    def decrypt(self, encBytes):\n        \"\"\"Decrypt the passed-in bytes.\n\n        This requires the key to have a private component.  It performs\n        PKCS#1 v1.5 decryption operation of the passed-in data.\n\n        Note: as a workaround against Bleichenbacher-like attacks, it will\n        return a deterministically selected random message in case the padding\n        checks failed. It returns an error (None) only in case the ciphertext\n        is of incorrect length or encodes an integer bigger than the modulus\n        of the key (i.e. it's publically invalid).\n\n        :type encBytes: bytes-like object\n        :param encBytes: The value which will be decrypted.\n\n        :rtype: bytearray or None\n        :returns: A PKCS#1 v1.5 decryption of the passed-in data or None if\n            the provided data is not properly formatted. Note: encrypting\n            an empty string is correct, so it may return an empty bytearray\n            for some ciphertexts.\n        \"\"\"\n        if not self.hasPrivateKey():\n            raise AssertionError()\n        if self.key_type != \"rsa\":\n            raise ValueError(\"Decryption requires RSA key, \\\"{0}\\\" present\"\n                             .format(self.key_type))\n        try:\n            dec_bytes = self._raw_private_key_op_bytes(encBytes)\n        except ValueError:\n            # _raw_private_key_op_bytes fails only when encBytes >= self.n,\n            # or when len(encBytes) != numBytes(self.n) and that's public\n            # information, so we don't have to handle it\n            # in sidechannel secure way\n            return None\n\n        ###################\n        # here be dragons #\n        ###################\n        # While the code is written as-if it was side-channel secure, in\n        # practice, because of cPython implementation details IT IS NOT\n        # see:\n        # https://securitypitfalls.wordpress.com/2018/08/03/constant-time-compare-in-python/\n\n        n = self.n\n\n        # maximum length we can return is reduced by the mandatory prefix:\n        # (0x00 0x02), 8 bytes of padding, so this is the position of the\n        # null separator byte, as counted from the last position\n        max_sep_offset = numBytes(n) - 10\n\n        # the private exponent (d) doesn't change so `_key_hash` doesn't\n        # change, calculate it only once\n        if not hasattr(self, '_key_hash') or not self._key_hash:\n            self._key_hash = secureHash(numberToByteArray(self.d, numBytes(n)),\n                                        \"sha256\")\n\n        kdk = secureHMAC(self._key_hash, encBytes, \"sha256\")\n\n        # we need 128 2-byte numbers, encoded as the number of bits\n        length_randoms = self._dec_prf(kdk, b\"length\", 128 * 2 * 8)\n\n        message_random = self._dec_prf(kdk, b\"message\", numBytes(n) * 8)\n\n        # select the last length that's not too large to return\n        synth_length = 0\n        length_rand_iter = iter(length_randoms)\n        length_mask = (1 << numBits(max_sep_offset)) - 1\n        for high, low in zip(length_rand_iter, length_rand_iter):\n            # interpret the two bytes from the PRF output as 16-bit big-endian\n            # integer\n            len_candidate = (high << 8) + low\n            len_candidate &= length_mask\n            # equivalent to:\n            # if len_candidate < max_sep_offset:\n            #    synth_length = len_candidate\n            mask = ct_lt_u32(len_candidate, max_sep_offset)\n            mask = ct_lsb_prop_u16(mask)\n            synth_length = synth_length & (0xffff ^ mask) \\\n                | len_candidate & mask\n\n        synth_msg_start = numBytes(n) - synth_length\n\n        error_detected = 0\n\n        # enumerate over all decrypted bytes\n        em_bytes = enumerate(dec_bytes)\n        # first check if first two bytes specify PKCS#1 v1.5 encryption padding\n        _, val = next(em_bytes)\n        error_detected |= ct_isnonzero_u32(val)\n        _, val = next(em_bytes)\n        error_detected |= ct_neq_u32(val, 0x02)\n        # then look for for the null separator byte among the padding bytes\n        # but inspect all decrypted bytes, even if we already find the\n        # separator earlier\n        msg_start = 0\n        for pos, val in em_bytes:\n            # padding must be at least 8 bytes long, fail if any of the first\n            # 8 bytes of it are zero\n            # equivalent to:\n            # if pos < 10 and not val:\n            #     error_detected = 0x01\n            error_detected |= ct_lt_u32(pos, 10) & (1 ^ ct_isnonzero_u32(val))\n\n            # update the msg_start only once; when it's 0\n            # (pos+1) because we want to skip the null separator\n            # equivalent to:\n            # if pos >= 10 and not msg_start and not val:\n            #     msg_start = pos+1\n            mask = (1 ^ ct_lt_u32(pos, 10)) & (1 ^ ct_isnonzero_u32(val)) \\\n                & (1 ^ ct_isnonzero_u32(msg_start))\n            mask = ct_lsb_prop_u16(mask)\n            msg_start = msg_start & (0xffff ^ mask) | (pos+1) & mask\n\n        # if separator wasn't found, it's an error\n        # equivalent to:\n        # if not msg_start:\n        #     error_detected = 0x01\n        error_detected |= 1 ^ ct_isnonzero_u32(msg_start)\n\n        # equivalent to:\n        # if error_detected:\n        #     ret_msg_start = synth_msg_start\n        # else:\n        #     ret_msg_start = msg_start\n        mask = ct_lsb_prop_u16(error_detected)\n        ret_msg_start = msg_start & (0xffff ^ mask) | synth_msg_start & mask\n\n        # as at this point the length doesn't leak the information if the\n        # padding was correct or not, we don't have to worry about the\n        # length of the returned value (and thus the size of the buffer we\n        # pass to the caller); but we still need to read both buffers\n        # to ensure that the memory access patern is preserved (that both\n        # buffers are accessed, not just the one we return)\n\n        # equivalent to:\n        # if error_detected:\n        #     return message_random[ret_msg_start:]\n        # else:\n        #     return dec_bytes[ret_msg_start:]\n        mask = ct_lsb_prop_u8(error_detected)\n        not_mask = 0xff ^ mask\n        ret = bytearray(\n            x & not_mask | y & mask for x, y in\n            zip(dec_bytes[ret_msg_start:], message_random[ret_msg_start:]))\n\n        return ret\n\n    def _rawPrivateKeyOp(self, message):\n        raise NotImplementedError()\n\n    def _rawPublicKeyOp(self, ciphertext):\n        raise NotImplementedError()\n\n    def _raw_private_key_op_bytes(self, message):\n        n = self.n\n        if len(message) != numBytes(n):\n            raise ValueError(\"Message has incorrect length for the key size\")\n        m_int = bytesToNumber(message)\n        if m_int >= n:\n            raise ValueError(\"Provided message value exceeds modulus\")\n        dec_int = self._rawPrivateKeyOp(m_int)\n        return numberToByteArray(dec_int, numBytes(n))\n\n    def _raw_public_key_op_bytes(self, ciphertext):\n        n = self.n\n        if len(ciphertext) != numBytes(n):\n            raise ValueError(\"Message has incorrect length for the key size\")\n        c_int = bytesToNumber(ciphertext)\n        if c_int >= n:\n            raise ValueError(\"Provided message value exceeds modulus\")\n        enc_int = self._rawPublicKeyOp(c_int)\n        return numberToByteArray(enc_int, numBytes(n))\n\n    def acceptsPassword(self):\n        \"\"\"Return True if the write() method accepts a password for use\n        in encrypting the private key.\n\n        :rtype: bool\n        \"\"\"\n        raise NotImplementedError()\n\n    def write(self, password=None):\n        \"\"\"Return a string containing the key.\n\n        :rtype: str\n        :returns: A string describing the key, in whichever format (PEM)\n            is native to the implementation.\n        \"\"\"\n        raise NotImplementedError()\n\n    @staticmethod\n    def generate(bits, key_type=\"rsa\"):\n        \"\"\"Generate a new key with the specified bit length.\n\n        :rtype: ~tlslite.utils.RSAKey.RSAKey\n        \"\"\"\n        raise NotImplementedError()\n\n\n    # **************************************************************************\n    # Helper Functions for RSA Keys\n    # **************************************************************************\n\n    @classmethod\n    def addPKCS1SHA1Prefix(cls, hashBytes, withNULL=True):\n        \"\"\"Add PKCS#1 v1.5 algorithm identifier prefix to SHA1 hash bytes\"\"\"\n        # There is a long history of confusion over whether the SHA1 \n        # algorithmIdentifier should be encoded with a NULL parameter or \n        # with the parameter omitted.  While the original intention was \n        # apparently to omit it, many toolkits went the other way.  TLS 1.2\n        # specifies the NULL should be included, and this behavior is also\n        # mandated in recent versions of PKCS #1, and is what tlslite has\n        # always implemented.  Anyways, verification code should probably \n        # accept both.\n        if not withNULL:\n            prefixBytes = bytearray([0x30, 0x1f, 0x30, 0x07, 0x06, 0x05, 0x2b,\n                                     0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14])\n        else:\n            prefixBytes = cls._pkcs1Prefixes['sha1']\n        prefixedBytes = prefixBytes + hashBytes\n        return prefixedBytes\n\n    _pkcs1Prefixes = {'md5' : bytearray([0x30, 0x20, 0x30, 0x0c, 0x06, 0x08,\n                                         0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,\n                                         0x02, 0x05, 0x05, 0x00, 0x04, 0x10]),\n                      'sha1' : bytearray([0x30, 0x21, 0x30, 0x09, 0x06, 0x05,\n                                          0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05,\n                                          0x00, 0x04, 0x14]),\n                      'sha224' : bytearray([0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09,\n                                            0x60, 0x86, 0x48, 0x01, 0x65, 0x03,\n                                            0x04, 0x02, 0x04, 0x05, 0x00, 0x04,\n                                            0x1c]),\n                      'sha256' : bytearray([0x30, 0x31, 0x30, 0x0d, 0x06, 0x09,\n                                            0x60, 0x86, 0x48, 0x01, 0x65, 0x03,\n                                            0x04, 0x02, 0x01, 0x05, 0x00, 0x04,\n                                            0x20]),\n                      'sha384' : bytearray([0x30, 0x41, 0x30, 0x0d, 0x06, 0x09,\n                                            0x60, 0x86, 0x48, 0x01, 0x65, 0x03,\n                                            0x04, 0x02, 0x02, 0x05, 0x00, 0x04,\n                                            0x30]),\n                      'sha512' : bytearray([0x30, 0x51, 0x30, 0x0d, 0x06, 0x09,\n                                            0x60, 0x86, 0x48, 0x01, 0x65, 0x03,\n                                            0x04, 0x02, 0x03, 0x05, 0x00, 0x04,\n                                            0x40])}\n\n    @classmethod\n    def addPKCS1Prefix(cls, data, hashName):\n        \"\"\"Add the PKCS#1 v1.5 algorithm identifier prefix to hash bytes\"\"\"\n        hashName = hashName.lower()\n        assert hashName in cls._pkcs1Prefixes\n        prefixBytes = cls._pkcs1Prefixes[hashName]\n        return prefixBytes + data\n\n    def _addPKCS1Padding(self, bytes, blockType):\n        padLength = (numBytes(self.n) - (len(bytes)+3))\n        if blockType == 1: #Signature padding\n            pad = [0xFF] * padLength\n        elif blockType == 2: #Encryption padding\n            pad = bytearray(0)\n            while len(pad) < padLength:\n                padBytes = getRandomBytes(padLength * 2)\n                pad = [b for b in padBytes if b]\n                pad = pad[:padLength]\n        else:\n            raise AssertionError()\n\n        padding = bytearray([0,blockType] + pad + [0])\n        return padding + bytes\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/tackwrapper.py",
    "content": "# Author: Trevor Perrin\n# See the LICENSE file for legal information regarding use of this file.\n\ntry:\n    from tack.structures.Tack import Tack\n    from tack.structures.TackExtension import TackExtension\n    from tack.tls.TlsCertificate import TlsCertificate\n    \n    tackpyLoaded = True\nexcept ImportError:\n    tackpyLoaded = False\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/tlshashlib.py",
    "content": "# Author: Hubert Kario (c) 2015\n# see LICENCE file for legal information regarding use of this file\n\n\"\"\"hashlib that handles FIPS mode.\"\"\"\n\n# Because we are extending the hashlib module, we need to import all its\n# fields to suppport the same uses\n# pylint: disable=unused-wildcard-import, wildcard-import\nfrom hashlib import *\n# pylint: enable=unused-wildcard-import, wildcard-import\nimport hashlib\n\n\ndef _fipsFunction(func, *args, **kwargs):\n    \"\"\"Make hash function support FIPS mode.\"\"\"\n    try:\n        return func(*args, **kwargs)\n    except ValueError:\n        return func(*args, usedforsecurity=False, **kwargs)\n\n\n# redefining the function is exactly what we intend to do\n# pylint: disable=function-redefined\ndef md5(*args, **kwargs):\n    \"\"\"MD5 constructor that works in FIPS mode.\"\"\"\n    return _fipsFunction(hashlib.md5, *args, **kwargs)\n\n\ndef new(*args, **kwargs):\n    \"\"\"General constructor that works in FIPS mode.\"\"\"\n    return _fipsFunction(hashlib.new, *args, **kwargs)\n# pylint: enable=function-redefined\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/tlshmac.py",
    "content": "# Author: Hubert Kario (c) 2019\n# see LICENCE file for legal information regarding use of this file\n\n\"\"\"\nHMAC module that works in FIPS mode.\n\nNote that this makes this code FIPS non-compliant!\n\"\"\"\n\n# Because we are extending the hashlib module, we need to import all its\n# fields to suppport the same uses\nfrom . import tlshashlib\nfrom .compat import compatHMAC\ntry:\n    from hmac import compare_digest\n    __all__ = [\"new\", \"compare_digest\", \"HMAC\"]\nexcept ImportError:\n    __all__ = [\"new\", \"HMAC\"]\n\ntry:\n    from hmac import HMAC, new\n    # if we can calculate HMAC on MD5, then use the built-in HMAC\n    # implementation\n    _val = HMAC(b'some key', b'msg', 'md5')\n    _val.digest()\n    del _val\nexcept Exception:\n    # fallback only when MD5 doesn't work\n    class HMAC(object):\n        \"\"\"Hacked version of HMAC that works in FIPS mode even with MD5.\"\"\"\n\n        def __init__(self, key, msg=None, digestmod=None):\n            \"\"\"\n            Initialise the HMAC and hash first portion of data.\n\n            msg: data to hash\n            digestmod: name of hash or object that be used as a hash and be cloned\n            \"\"\"\n            self.key = key\n            if digestmod is None:\n                digestmod = 'md5'\n            if callable(digestmod):\n                digestmod = digestmod()\n            if not hasattr(digestmod, 'digest_size'):\n                digestmod = tlshashlib.new(digestmod)\n            self.block_size = digestmod.block_size\n            self.digest_size = digestmod.digest_size\n            self.digestmod = digestmod\n            if len(key) > self.block_size:\n                k_hash = digestmod.copy()\n                k_hash.update(compatHMAC(key))\n                key = k_hash.digest()\n            if len(key) < self.block_size:\n                key = key + b'\\x00' * (self.block_size - len(key))\n            key = bytearray(key)\n            ipad = bytearray(b'\\x36' * self.block_size)\n            opad = bytearray(b'\\x5c' * self.block_size)\n            i_key = bytearray(i ^ j for i, j in zip(key, ipad))\n            self._o_key = bytearray(i ^ j for i, j in zip(key, opad))\n            self._context = digestmod.copy()\n            self._context.update(compatHMAC(i_key))\n            if msg:\n                self._context.update(compatHMAC(msg))\n\n        def update(self, msg):\n            self._context.update(compatHMAC(msg))\n\n        def digest(self):\n            i_digest = self._context.digest()\n            o_hash = self.digestmod.copy()\n            o_hash.update(compatHMAC(self._o_key))\n            o_hash.update(compatHMAC(i_digest))\n            return o_hash.digest()\n\n        def copy(self):\n            new = HMAC.__new__(HMAC)\n            new.key = self.key\n            new.digestmod = self.digestmod\n            new.block_size = self.block_size\n            new.digest_size = self.digest_size\n            new._o_key = self._o_key\n            new._context = self._context.copy()\n            return new\n\n\n    def new(*args, **kwargs):\n        \"\"\"General constructor that works in FIPS mode.\"\"\"\n        return HMAC(*args, **kwargs)\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/tripledes.py",
    "content": "# Author: Trevor Perrin\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Abstract class for 3DES.\"\"\"\n\nclass TripleDES(object):\n    def __init__(self, key, mode, IV, implementation):\n        if len(key) != 24:\n            raise ValueError()\n        if mode != 2:\n            raise ValueError()\n        if len(IV) != 8:\n            raise ValueError()\n        self.isBlockCipher = True\n        self.isAEAD = False\n        self.block_size = 8\n        self.implementation = implementation\n        self.name = \"3des\"\n\n    #CBC-Mode encryption, returns ciphertext\n    #WARNING: *MAY* modify the input as well\n    def encrypt(self, plaintext):\n        assert(len(plaintext) % 8 == 0)\n\n    #CBC-Mode decryption, returns plaintext\n    #WARNING: *MAY* modify the input as well\n    def decrypt(self, ciphertext):\n        assert(len(ciphertext) % 8 == 0)\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/utils/x25519.py",
    "content": "# Authors:\n#   Hubert Kario (2017)\n#\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Handling X25519 and X448 curve based key agreement protocol.\"\"\"\n\nfrom .cryptomath import bytesToNumber, numberToByteArray, divceil\n# the names of the variables come directly from RFC 7748 so changing them\n# would make the code harder to audit/compare\n# pylint: disable=invalid-name\n\n\ndef decodeUCoordinate(u, bits):\n    \"\"\"Function to decode the public U coordinate of X25519-family curves.\"\"\"\n    if bits not in (255, 448):\n        raise ValueError(\"Invalid number of expected bits\")\n    if bits % 8:\n        u[-1] &= (1 << (bits % 8)) - 1\n    return bytesToNumber(u, endian=\"little\")\n\n\ndef decodeScalar22519(k):\n    \"\"\"Function to decode the private K parameter of the x25519 function.\"\"\"\n    k[0] &= 248\n    k[31] &= 127\n    k[31] |= 64\n    return bytesToNumber(k, endian=\"little\")\n\n\ndef decodeScalar448(k):\n    \"\"\"Function to decode the private K parameter of the X448 function.\"\"\"\n    k[0] &= 252\n    k[55] |= 128\n    return bytesToNumber(k, endian=\"little\")\n\n\ndef cswap(swap, x_2, x_3):\n    \"\"\"Conditional swap function.\"\"\"\n    if swap:\n        return x_3, x_2\n    else:\n        return x_2, x_3\n\n\nX25519_G = numberToByteArray(9, 32, endian=\"little\")\n\n\nX25519_ORDER_SIZE = 32\n\n\ndef x25519(k, u):\n    \"\"\"\n    Perform point multiplication on X25519 curve.\n\n    :type k: bytearray\n    :param k: random secret value (multiplier), should be 32 byte long\n\n    :type u: bytearray\n    :param u: curve generator or the other party key share\n\n    :rtype: bytearray\n    \"\"\"\n    bits = 255\n    k = decodeScalar22519(k)\n    u = decodeUCoordinate(u, bits)\n\n    a24 = 121665\n    p = 2**255 - 19\n\n    return _x25519_generic(k, u, bits, a24, p)\n\n\nX448_G = numberToByteArray(5, 56, endian=\"little\")\n\n\nX448_ORDER_SIZE = 56\n\n\ndef x448(k, u):\n    \"\"\"\n    Perform point multiplication on X448 curve.\n\n    :type k: bytearray\n    :param k: random secret value (multiplier), should be 56 bytes long\n\n    :type u: bytearray\n    :param u: curve generator or the other party key share\n\n    :rtype: bytearray\n    \"\"\"\n    bits = 448\n    k = decodeScalar448(k)\n    u = decodeUCoordinate(u, bits)\n\n    a24 = 39081\n    p = 2**448 - 2**224 - 1\n\n    return _x25519_generic(k, u, bits, a24, p)\n\n\ndef _x25519_generic(k, u, bits, a24, p):\n    \"\"\"Generic Montgomery ladder implementation of the x25519 algorithm.\"\"\"\n    x_1 = u\n    x_2 = 1\n    z_2 = 0\n    x_3 = u\n    z_3 = 1\n    swap = 0\n\n    for t in range(bits-1, -1, -1):\n        k_t = (k >> t) & 1\n        swap ^= k_t\n        x_2, x_3 = cswap(swap, x_2, x_3)\n        z_2, z_3 = cswap(swap, z_2, z_3)\n        swap = k_t\n\n        A = (x_2 + z_2) % p\n        AA = pow(A, 2, p)\n        B = (x_2 - z_2) % p\n        BB = pow(B, 2, p)\n        E = (AA - BB) % p\n        C = (x_3 + z_3) % p\n        D = (x_3 - z_3) % p\n        DA = (D * A) % p\n        CB = (C * B) % p\n        x_3 = pow(DA + CB, 2, p)\n        z_3 = (x_1 * pow(DA - CB, 2, p)) % p\n        x_2 = (AA * BB) % p\n        z_2 = (E * (AA + a24 * E)) % p\n\n    x_2, x_3 = cswap(swap, x_2, x_3)\n    z_2, z_3 = cswap(swap, z_2, z_3)\n    ret = (x_2 * pow(z_2, p - 2, p)) % p\n    return numberToByteArray(ret, divceil(bits, 8), endian=\"little\")\n# pylint: enable=invalid-name\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/verifierdb.py",
    "content": "# Author: Trevor Perrin\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Class for storing SRP password verifiers.\"\"\"\n\nfrom .utils.cryptomath import *\nfrom .utils.compat import *\nfrom tlslite import mathtls\nfrom .basedb import BaseDB\n\nclass VerifierDB(BaseDB):\n    \"\"\"This class represent an in-memory or on-disk database of SRP\n    password verifiers.\n\n    A VerifierDB can be passed to a server handshake to authenticate\n    a client based on one of the verifiers.\n\n    This class is thread-safe.\n    \"\"\"\n    def __init__(self, filename=None):\n        \"\"\"Create a new VerifierDB instance.\n\n        :type filename: str\n        :param filename: Filename for an on-disk database, or None for\n            an in-memory database.  If the filename already exists, follow\n            this with a call to open().  To create a new on-disk database,\n            follow this with a call to create().\n        \"\"\"\n        BaseDB.__init__(self, filename, b\"verifier\")\n\n    def _getItem(self, username, valueStr):\n        (N, g, salt, verifier) = valueStr.split(b\" \")\n        N = bytesToNumber(a2b_base64(N))\n        g = bytesToNumber(a2b_base64(g))\n        salt = a2b_base64(salt)\n        verifier = bytesToNumber(a2b_base64(verifier))\n        return (N, g, salt, verifier)\n\n    def __setitem__(self, username, verifierEntry):\n        \"\"\"Add a verifier entry to the database.\n\n        :type username: str\n        :param username: The username to associate the verifier with.\n            Must be less than 256 characters in length.  Must not already\n            be in the database.\n\n        :type verifierEntry: tuple\n        :param verifierEntry: The verifier entry to add.  Use\n            :py:meth:`~tlslite.verifierdb.VerifierDB.makeVerifier` to create a\n            verifier entry.\n        \"\"\"\n        BaseDB.__setitem__(self, username, verifierEntry)\n\n\n    def _setItem(self, username, value):\n        if len(username)>=256:\n            raise ValueError(\"username too long\")\n        N, g, salt, verifier = value\n        N = b2a_base64(numberToByteArray(N)).encode(\"ascii\")\n        g = b2a_base64(numberToByteArray(g)).encode(\"ascii\")\n        salt = b2a_base64(salt).encode(\"ascii\")\n        verifier = b2a_base64(numberToByteArray(verifier)).encode(\"ascii\")\n        valueStr = b\" \".join((N, g, salt, verifier))\n        return valueStr\n\n    def _checkItem(self, value, username, param):\n        (N, g, salt, verifier) = value\n        x = mathtls.makeX(salt, username, param)\n        v = powMod(g, x, N)\n        return (verifier == v)\n\n    @staticmethod\n    def makeVerifier(username, password, bits):\n        \"\"\"Create a verifier entry which can be stored in a VerifierDB.\n\n        :type username: str\n        :param username: The username for this verifier.  Must be less\n            than 256 characters in length.\n\n        :type password: str\n        :param password: The password for this verifier.\n\n        :type bits: int\n        :param bits: This values specifies which SRP group parameters\n            to use.  It must be one of (1024, 1536, 2048, 3072, 4096, 6144,\n            8192).  Larger values are more secure but slower.  2048 is a\n            good compromise between safety and speed.\n\n        :rtype: tuple\n        :returns: A tuple which may be stored in a VerifierDB.\n        \"\"\"\n        if isinstance(username, str):\n            usernameBytes = bytearray(username, \"utf-8\")\n        else:\n            usernameBytes = bytearray(username)\n        if isinstance(password, str):\n            passwordBytes = bytearray(password, \"utf-8\")\n        else:\n            passwordBytes = bytearray(password)\n        return mathtls.makeVerifier(usernameBytes, passwordBytes, bits)\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/x509.py",
    "content": "# Authors:\n#   Trevor Perrin\n#   Google - parsing subject field\n#\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Class representing an X.509 certificate.\"\"\"\n\nfrom ecdsa.keys import VerifyingKey\n\nfrom .utils.asn1parser import ASN1Parser\nfrom .utils.cryptomath import *\nfrom .utils.keyfactory import _createPublicRSAKey, _create_public_ecdsa_key, \\\n    _create_public_dsa_key, _create_public_eddsa_key\nfrom .utils.pem import *\nfrom .utils.compat import compatHMAC, b2a_hex\nfrom .constants import AlgorithmOID, RSA_PSS_OID\n\n\nclass X509(object):\n    \"\"\"\n    This class represents an X.509 certificate.\n\n    :vartype bytes: bytearray\n    :ivar bytes: The DER-encoded ASN.1 certificate\n\n    :vartype publicKey: ~tlslite.utils.rsakey.RSAKey\n    :ivar publicKey: The subject public key from the certificate.\n\n    :vartype subject: bytearray\n    :ivar subject: The DER-encoded ASN.1 subject distinguished name.\n\n    :vartype certAlg: str\n    :ivar certAlg: algorithm of the public key, \"rsa\" for RSASSA-PKCS#1 v1.5,\n        \"rsa-pss\" for RSASSA-PSS, \"ecdsa\" for ECDSA\n    \"\"\"\n\n    def __init__(self):\n        \"\"\"Create empty certificate object.\"\"\"\n        self.bytes = bytearray(0)\n        self.serial_number = None\n        self.subject_public_key = None\n        self.publicKey = None\n        self.subject = None\n        self.certAlg = None\n        self.sigalg = None\n        self.issuer = None\n\n    def __hash__(self):\n        \"\"\"Calculate hash of object.\"\"\"\n        return hash(bytes(self.bytes))\n\n    def __eq__(self, other):\n        \"\"\"Compare other object for equality.\"\"\"\n        if not hasattr(other, \"bytes\"):\n            return NotImplemented\n        return self.bytes == other.bytes\n\n    def __ne__(self, other):\n        \"\"\"Compare with other object for inequality.\"\"\"\n        if not hasattr(other, \"bytes\"):\n            return NotImplemented\n        return not self == other\n\n    def parse(self, s):\n        \"\"\"\n        Parse a PEM-encoded X.509 certificate.\n\n        :type s: str\n        :param s: A PEM-encoded X.509 certificate (i.e. a base64-encoded\n            certificate wrapped with \"-----BEGIN CERTIFICATE-----\" and\n            \"-----END CERTIFICATE-----\" tags).\n        \"\"\"\n        bytes = dePem(s, \"CERTIFICATE\")\n        self.parseBinary(bytes)\n        return self\n\n    def parseBinary(self, cert_bytes):\n        \"\"\"\n        Parse a DER-encoded X.509 certificate.\n\n        :type bytes: L{str} (in python2) or L{bytearray} of unsigned bytes\n        :param bytes: A DER-encoded X.509 certificate.\n        \"\"\"\n        self.bytes = bytearray(cert_bytes)\n        parser = ASN1Parser(self.bytes)\n\n        # Get the SignatureAlgorithm\n        signature_algorithm_identifier = parser.getChild(1)\n        self.sigalg = bytes(signature_algorithm_identifier.getChildBytes(0))\n\n        # Finally get the (hash, signature) pair coresponding to it\n        # If it is rsa-pss we need to check the aditional parameters field\n        # to extract the hash algorithm\n        if self.sigalg == RSA_PSS_OID:\n            sigalg_hash = signature_algorithm_identifier.getChild(1)\n            sigalg_hash = bytes(sigalg_hash.getChild(0).value)\n            self.sigalg = AlgorithmOID.oid[sigalg_hash]\n        else:\n            self.sigalg = AlgorithmOID.oid[self.sigalg]\n\n        # Get the tbsCertificate\n        tbs_certificate = parser.getChild(0)\n        # Is the optional version field present?\n        # This determines which index the key is at.\n        if tbs_certificate.value[0] == 0xA0:\n            serial_number_index = 1\n            subject_public_key_info_index = 6\n        else:\n            serial_number_index = 0\n            subject_public_key_info_index = 5\n\n        # Get serial number\n        self.serial_number = bytesToNumber(tbs_certificate.getChild(serial_number_index).value)\n\n        # Get the issuer\n        self.issuer = tbs_certificate.getChildBytes(\n            subject_public_key_info_index - 3)\n\n        # Get the subject\n        self.subject = tbs_certificate.getChildBytes(\n            subject_public_key_info_index - 1)\n\n        # Get the subjectPublicKeyInfo\n        subject_public_key_info = tbs_certificate.getChild(\n            subject_public_key_info_index)\n\n        # Get the AlgorithmIdentifier\n        alg_identifier = subject_public_key_info.getChild(0)\n        alg_identifier_len = alg_identifier.getChildCount()\n\n        # first item of AlgorithmIdentifier is the algorithm\n        alg = alg_identifier.getChild(0)\n        alg_oid = alg.value\n        if list(alg_oid) == [42, 134, 72, 134, 247, 13, 1, 1, 1]:\n            self.certAlg = \"rsa\"\n        elif list(alg_oid) == [42, 134, 72, 134, 247, 13, 1, 1, 10]:\n            self.certAlg = \"rsa-pss\"\n        elif list(alg_oid) == [42, 134, 72, 206, 56, 4, 1]:\n            self.certAlg = \"dsa\"\n        elif list(alg_oid) == [42, 134, 72, 206, 61, 2, 1]:\n            self.certAlg = \"ecdsa\"\n        elif list(alg_oid) == [43, 101, 112]:\n            self.certAlg = \"Ed25519\"\n        elif list(alg_oid) == [43, 101, 113]:\n            self.certAlg = \"Ed448\"\n        else:\n            raise SyntaxError(\"Unrecognized AlgorithmIdentifier\")\n\n        # for RSA the parameters of AlgorithmIdentifier shuld be a NULL\n        if self.certAlg == \"rsa\":\n            if alg_identifier_len != 2:\n                raise SyntaxError(\"Missing parameters in AlgorithmIdentifier\")\n            params = alg_identifier.getChild(1)\n            if params.value != bytearray(0):\n                raise SyntaxError(\"Unexpected non-NULL parameters in \"\n                                  \"AlgorithmIdentifier\")\n        elif self.certAlg == \"ecdsa\":\n            self._ecdsa_pubkey_parsing(\n                tbs_certificate.getChildBytes(subject_public_key_info_index))\n            return\n        elif self.certAlg == \"dsa\":\n            self._dsa_pubkey_parsing(subject_public_key_info)\n            return\n        elif self.certAlg == \"Ed25519\" or self.certAlg == \"Ed448\":\n            self._eddsa_pubkey_parsing(\n                tbs_certificate.getChildBytes(subject_public_key_info_index))\n            return\n        else:  # rsa-pss\n            pass  # ignore parameters, if any - don't apply key restrictions\n\n        self._rsa_pubkey_parsing(subject_public_key_info)\n\n    def _eddsa_pubkey_parsing(self, subject_public_key_info):\n        \"\"\"\n        Convert the raw DER encoded EdDSA parameters into public key object.\n\n        :param subject_public_key_info: bytes like object with the DER encoded\n            public key in it\n        \"\"\"\n        try:\n            # python ecdsa knows how to parse curve OIDs so re-use that\n            # code\n            public_key = VerifyingKey.from_der(compatHMAC(\n                subject_public_key_info))\n        except Exception:\n            raise SyntaxError(\"Malformed or unsupported public key in \"\n                              \"certificate\")\n        self.publicKey = _create_public_eddsa_key(public_key)\n\n    def _rsa_pubkey_parsing(self, subject_public_key_info):\n        \"\"\"\n        Parse the RSA public key from the certificate.\n\n        :param subject_public_key_info: ASN1Parser object with subject\n            public key info of X.509 certificate\n        \"\"\"\n\n        # Get the subjectPublicKey\n        subject_public_key = subject_public_key_info.getChild(1)\n        self.subject_public_key = subject_public_key_info.getChildBytes(1)\n        self.subject_public_key = ASN1Parser(self.subject_public_key).value[1:]\n\n        # Adjust for BIT STRING encapsulation\n        if subject_public_key.value[0]:\n            raise SyntaxError()\n        subject_public_key = ASN1Parser(subject_public_key.value[1:])\n\n        # Get the modulus and exponent\n        modulus = subject_public_key.getChild(0)\n        public_exponent = subject_public_key.getChild(1)\n\n        # Decode them into numbers\n        # pylint: disable=invalid-name\n        # 'n' and 'e' are the universally used parameters in RSA algorithm\n        # definition\n        n = bytesToNumber(modulus.value)\n        e = bytesToNumber(public_exponent.value)\n\n        # Create a public key instance\n        self.publicKey = _createPublicRSAKey(n, e, self.certAlg)\n        # pylint: enable=invalid-name\n\n    def _ecdsa_pubkey_parsing(self, subject_public_key_info):\n        \"\"\"\n        Convert the raw DER encoded ECDSA parameters into public key object\n\n        :param subject_public_key_info: bytes like object with DER encoded\n            public key in it\n        \"\"\"\n        try:\n            # python ecdsa knows how to parse curve OIDs so re-use that\n            # code\n            public_key = VerifyingKey.from_der(compatHMAC(\n                subject_public_key_info))\n        except Exception:\n            raise SyntaxError(\"Malformed or unsupported public key in \"\n                              \"certificate\")\n        x = public_key.pubkey.point.x()\n        y = public_key.pubkey.point.y()\n        curve_name = public_key.curve.name\n        self.publicKey = _create_public_ecdsa_key(x, y, curve_name)\n\n    def _dsa_pubkey_parsing(self, subject_public_key_info):\n        \"\"\"\n        Convert the raw DER encoded DSA parameters into public key object\n\n        :param subject_public_key_info: bytes like object with DER encoded\n          global parameters and public key in it\n        \"\"\"\n        global_parameters = (subject_public_key_info.getChild(0)).getChild(1)\n        # Get the subjectPublicKey\n        public_key = subject_public_key_info.getChild(1)\n\n        # Adjust for BIT STRING encapsulation and get hex value\n        if public_key.value[0]:\n            raise SyntaxError()\n        y = ASN1Parser(public_key.value[1:])\n\n        # Get the {A, p, q}\n        p = global_parameters.getChild(0)\n        q = global_parameters.getChild(1)\n        g = global_parameters.getChild(2)\n\n        # Decode them into numbers\n        y = bytesToNumber(y.value)\n        p = bytesToNumber(p.value)\n        q = bytesToNumber(q.value)\n        g = bytesToNumber(g.value)\n\n        # Create a public key instance\n        self.publicKey = _create_public_dsa_key(p, q, g, y)\n\n    def getFingerprint(self):\n        \"\"\"\n        Get the hex-encoded fingerprint of this certificate.\n\n        :rtype: str\n        :returns: A hex-encoded fingerprint.\n        \"\"\"\n        return b2a_hex(SHA1(self.bytes))\n\n    def writeBytes(self):\n        \"\"\"Serialise object to a DER encoded string.\"\"\"\n        return self.bytes\n\n\n"
  },
  {
    "path": "code/default/lib/noarch/tlslite/x509certchain.py",
    "content": "# Author: Trevor Perrin\n# See the LICENSE file for legal information regarding use of this file.\n\n\"\"\"Class representing an X.509 certificate chain.\"\"\"\n\nfrom .utils import cryptomath\nfrom .utils.tackwrapper import *\nfrom .utils.pem import *\nfrom .x509 import X509\n\nclass X509CertChain(object):\n    \"\"\"This class represents a chain of X.509 certificates.\n\n    :vartype x509List: list\n    :ivar x509List: A list of :py:class:`tlslite.x509.X509` instances,\n        starting with the end-entity certificate and with every\n        subsequent certificate certifying the previous.\n    \"\"\"\n\n    def __init__(self, x509List=None):\n        \"\"\"Create a new X509CertChain.\n\n        :type x509List: list\n        :param x509List: A list of :py:class:`tlslite.x509.X509` instances,\n            starting with the end-entity certificate and with every\n            subsequent certificate certifying the previous.\n        \"\"\"\n        if x509List:\n            self.x509List = x509List\n        else:\n            self.x509List = []\n\n    def __hash__(self):\n        \"\"\"Return hash of the object.\"\"\"\n        return hash(tuple(self.x509List))\n\n    def __eq__(self, other):\n        \"\"\"Compare objects with each-other.\"\"\"\n        if not hasattr(other, \"x509List\"):\n            return NotImplemented\n        return self.x509List == other.x509List\n\n    def __ne__(self, other):\n        \"\"\"Compare object for inequality.\"\"\"\n        if not hasattr(other, \"x509List\"):\n            return NotImplemented\n        return self.x509List != other.x509List\n\n    def parsePemList(self, s):\n        \"\"\"Parse a string containing a sequence of PEM certs.\n\n        Raise a SyntaxError if input is malformed.\n        \"\"\"\n        x509List = []\n        bList = dePemList(s, \"CERTIFICATE\")\n        for b in bList:\n            x509 = X509()\n            x509.parseBinary(b)\n            x509List.append(x509)\n        self.x509List = x509List\n\n    def getNumCerts(self):\n        \"\"\"Get the number of certificates in this chain.\n\n        :rtype: int\n        \"\"\"\n        return len(self.x509List)\n\n    def getEndEntityPublicKey(self):\n        \"\"\"Get the public key from the end-entity certificate.\n\n        :rtype: ~tlslite.utils.rsakey.RSAKey`\n        \"\"\"\n        if self.getNumCerts() == 0:\n            raise AssertionError()\n        return self.x509List[0].publicKey\n\n    def getFingerprint(self):\n        \"\"\"Get the hex-encoded fingerprint of the end-entity certificate.\n\n        :rtype: str\n        :returns: A hex-encoded fingerprint.\n        \"\"\"\n        if self.getNumCerts() == 0:\n            raise AssertionError()\n        return self.x509List[0].getFingerprint()\n\n    def checkTack(self, tack):\n        if self.x509List:\n            tlsCert = TlsCertificate(self.x509List[0].bytes)\n            if tlsCert.matches(tack):\n                return True\n        return False\n        \n    def getTackExt(self):\n        \"\"\"Get the TACK and/or Break Sigs from a TACK Cert in the chain.\"\"\"\n        tackExt = None\n        # Search list in backwards order\n        for x509 in self.x509List[::-1]:\n            tlsCert = TlsCertificate(x509.bytes)\n            if tlsCert.tackExt:\n                if tackExt:\n                    raise SyntaxError(\"Multiple TACK Extensions\")\n                else:\n                    tackExt = tlsCert.tackExt\n        return tackExt\n                \n"
  },
  {
    "path": "code/default/lib/noarch/utils.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nimport re\nimport os\nimport threading\nfrom functools import reduce\nfrom six import string_types\n\nipv4_pattern = re.compile(br'^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$')\n\nipv6_pattern = re.compile(br\"\"\"\n        ^\n        \\s*                         # Leading whitespace\n        (?!.*::.*::)                # Only a single whildcard allowed\n        (?:(?!:)|:(?=:))            # Colon iff it would be part of a wildcard\n        (?:                         # Repeat 6 times:\n            [0-9a-f]{0,4}           #   A group of at most four hexadecimal digits\n            (?:(?<=::)|(?<!::):)    #   Colon unless preceeded by wildcard\n        ){6}                        #\n        (?:                         # Either\n            [0-9a-f]{0,4}           #   Another group\n            (?:(?<=::)|(?<!::):)    #   Colon unless preceeded by wildcard\n            [0-9a-f]{0,4}           #   Last group\n            (?: (?<=::)             #   Colon iff preceeded by exacly one colon\n             |  (?<!:)              #\n             |  (?<=:) (?<!::) :    #\n             )                      # OR\n         |                          #   A v4 address with NO leading zeros\n            (?:25[0-4]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)\n            (?: \\.\n                (?:25[0-4]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)\n            ){3}\n        )\n        \\s*                         # Trailing whitespace\n        $\n    \"\"\", re.VERBOSE | re.IGNORECASE | re.DOTALL)\n\n\ndef check_ip_valid4(ip):\n    \"\"\"检查ipv4地址的合法性\"\"\"\n    ip = to_bytes(ip)\n    ret = ipv4_pattern.match(ip)\n    if ret is not None:\n        \"each item range: [0,255]\"\n        for item in ret.groups():\n            if int(item) > 255:\n                return 0\n        return 1\n    else:\n        return 0\n\n\ndef check_ip_valid6(ip):\n    \"\"\"Copied from http://stackoverflow.com/a/319293/2755602\"\"\"\n    ip = to_bytes(ip)\n\n    return ipv6_pattern.match(ip) is not None\n\n\ndef check_ip_valid(ip):\n    ip = to_bytes(ip)\n    if b'.' in ip:\n        return check_ip_valid4(ip)\n    else:\n        return check_ip_valid6(ip)\n\n\ndef get_ip_port(ip_str, port=443):\n    ip_str = to_bytes(ip_str)\n    if b\".\" in ip_str:\n        # ipv4\n        if b\":\" in ip_str:\n            # format is ip:port\n            ps = ip_str.split(b\":\")\n            ip = ps[0]\n            port = ps[1]\n        else:\n            # format is ip\n            ip = ip_str\n    else:\n        # ipv6\n        if b\"[\" in ip_str:\n            # format: [ab01:12:23:34::1]\n            # format: [ab01:12:23:34::1]:23\n\n            p1 = ip_str.find(b\"[\")\n            p2 = ip_str.find(b\"]\")\n            ip = ip_str[p1 + 1:p2]\n            port_str = ip_str[p2 + 1:]\n            if len(port_str) > 0:\n                port = port_str[1:]\n        else:\n            ip = ip_str\n\n    return ip, int(port)\n\n\ndef get_ip_str(ip, port=443):\n    ip = to_str(ip)\n    if \":\" in ip:\n        ip = \"[\" + ip + \"]\"\n    ip_str = ip + \":\" + str(port)\n    return ip_str\n\n\ndomain_allowed = re.compile(\"(?!-)[A-Z\\\\d-]{1,63}(?<!-)$\")\n\n\ndef check_domain_valid(hostname):\n    if len(hostname) > 255:\n        return False\n    if hostname.endswith(\".\"):\n        hostname = hostname[:-1]\n\n    return all(domain_allowed.match(x) for x in hostname.split(\".\"))\n\n\ndef str2hex(data):\n    data = to_bytes(data)\n    return data.hex(':')\n\n\ndef get_ip_maskc(ip_str):\n    head = \".\".join(ip_str.split(\".\")[:-1])\n    return head + \".0\"\n\n\ndef split_ip(strline):\n    \"\"\"从每组地址中分离出起始IP以及结束IP\"\"\"\n    begin = \"\"\n    end = \"\"\n    if \"-\" in strline:\n        num_regions = strline.split(\".\")\n        if len(num_regions) == 4:\n            \"xxx.xxx.xxx-xxx.xxx-xxx\"\n            begin = ''\n            end = ''\n            for region in num_regions:\n                if '-' in region:\n                    s, e = region.split('-')\n                    begin += '.' + s\n                    end += '.' + e\n                else:\n                    begin += '.' + region\n                    end += '.' + region\n            begin = begin[1:]\n            end = end[1:]\n\n        else:\n            \"xxx.xxx.xxx.xxx-xxx.xxx.xxx.xxx\"\n            begin, end = strline.split(\"-\")\n            if 1 <= len(end) <= 3:\n                prefix = begin[0:begin.rfind(\".\")]\n                end = prefix + \".\" + end\n\n    elif strline.endswith(\".\"):\n        \"xxx.xxx.xxx.\"\n        begin = strline + \"0\"\n        end = strline + \"255\"\n    elif \"/\" in strline:\n        \"xxx.xxx.xxx.xxx/xx\"\n        (ip, bits) = strline.split(\"/\")\n        if check_ip_valid4(ip) and (0 <= int(bits) <= 32):\n            orgip = ip_string_to_num(ip)\n            end_bits = (1 << (32 - int(bits))) - 1\n            begin_bits = 0xFFFFFFFF ^ end_bits\n            begin = ip_num_to_string(orgip & begin_bits)\n            end = ip_num_to_string(orgip | end_bits)\n    else:\n        \"xxx.xxx.xxx.xxx\"\n        begin = strline\n        end = strline\n\n    return begin, end\n\n\ndef generate_random_lowercase(n):\n    min_lc = ord(b'a')\n    len_lc = 26\n    ba = bytearray(os.urandom(n))\n    for i, b in enumerate(ba):\n        ba[i] = min_lc + b % len_lc  # convert 0..255 to 97..122\n    # sys.stdout.buffer.write(ba)\n    return ba\n\n\nclass SimpleCondition(object):\n    def __init__(self):\n        self.lock = threading.Condition()\n\n    def notify(self):\n        self.lock.acquire()\n        self.lock.notify()\n        self.lock.release()\n\n    def wait(self, timeout=None):\n        self.lock.acquire()\n        self.lock.wait(timeout)\n        self.lock.release()\n\n\ndef split_domain(host):\n    host = to_bytes(host)\n    hl = host.split(b\".\")\n    return hl[0], b\".\".join(hl[1:])\n\n\ndef ip_string_to_num(s):\n    \"\"\"Convert dotted IPv4 address to integer.\"\"\"\n    return reduce(lambda a, b: a << 8 | b, list(map(int, s.split(\".\"))))\n\n\ndef ip_num_to_string(ip):\n    \"\"\"Convert 32-bit integer to dotted IPv4 address.\"\"\"\n    return \".\".join([str(ip >> n & 0xFF) for n in [24, 16, 8, 0]])\n\n\nprivate_ipv4_range = [\n    (\"10.0.0.0\", \"10.255.255.255\"),\n    (\"127.0.0.0\", \"127.255.255.255\"),\n    (\"169.254.0.0\", \"169.254.255.255\"),\n    (\"172.16.0.0\", \"172.31.255.255\"),\n    (\"192.168.0.0\", \"192.168.255.255\")\n]\n\nprivate_ipv6_range = [\n    (\"::1\", \"::1\"),\n    (\"fc00::\", \"fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff\")\n]\n\nprivate_ipv4_range_bin = []\nfor b, e in private_ipv4_range:\n    bb = ip_string_to_num(b)\n    ee = ip_string_to_num(e)\n    private_ipv4_range_bin.append((bb, ee))\n\n\ndef is_private_ip(ip):\n    ip = to_str(ip)\n    try:\n        if \".\" in ip:\n            ip_bin = ip_string_to_num(ip)\n            for b, e in private_ipv4_range_bin:\n                if b <= ip_bin <= e:\n                    return True\n            return False\n        else:\n            if ip == \"::1\":\n                return True\n\n            fi = ip.find(\":\")\n            if fi != 4:\n                return False\n\n            be = ip[0:2]\n            if be in [\"fc\", \"fd\"]:\n                return True\n            else:\n                return False\n    except Exception as e:\n        # print((\"is_private_ip(%s), except:%r\", ip, e))\n        return False\n\n\nimport string\n\nprintable = set(string.printable)\n\n\ndef get_printable(s):\n    return [x for x in s if x in printable]\n\n\ndef compare_version(version, reference_version):\n    try:\n        p = re.compile(r'([0-9]+)\\.([0-9]+)\\.([0-9]+)')\n        m1 = p.match(version)\n        m2 = p.match(reference_version)\n        v1 = list(map(int, list(map(m1.group, [1, 2, 3]))))\n        v2 = list(map(int, list(map(m2.group, [1, 2, 3]))))\n\n        if v1 > v2:\n            return 1\n        elif v1 < v2:\n            return -1\n        else:\n            return 0\n    except Exception as e:\n        print(\"older_or_equal fail: %s, %s\" % (version, reference_version))\n        raise e\n\n\ndef map_with_parameter(function, datas, args):\n    l = []\n    for data in datas:\n        d_out = function(data, args)\n        l.append(d_out)\n    return l\n\n\ndef to_bytes(data, coding='utf-8'):\n    if isinstance(data, bytes):\n        return data\n    if isinstance(data, string_types):\n        return data.encode(coding)\n    if isinstance(data, dict):\n        return dict(map_with_parameter(to_bytes, data.items(), coding))\n    if isinstance(data, tuple):\n        return tuple(map_with_parameter(to_bytes, data, coding))\n    if isinstance(data, list):\n        return list(map_with_parameter(to_bytes, data, coding))\n    if isinstance(data, int):\n        return to_bytes(str(data))\n    if data is None:\n        return data\n    return bytes(data)\n\n\ndef to_str(data, coding='utf-8'):\n    if isinstance(data, string_types):\n        return data\n    if isinstance(data, bytes):\n        return data.decode(coding)\n    if isinstance(data, bytearray):\n        return data.decode(coding)\n    if isinstance(data, dict):\n        return dict(map_with_parameter(to_str, data.items(), coding))\n    if isinstance(data, tuple):\n        return tuple(map_with_parameter(to_str, data, coding))\n    if isinstance(data, list):\n        return list(map_with_parameter(to_str, data, coding))\n    if isinstance(data, int):\n        return str(data)\n    if data is None:\n        return data\n    return str(data)\n\n\ndef bytes2str_only(data, coding='utf-8'):\n    if isinstance(data, bytes):\n        return data.decode(coding)\n    if isinstance(data, dict):\n        return dict(map_with_parameter(bytes2str_only, data.items(), coding))\n    if isinstance(data, tuple):\n        return tuple(map_with_parameter(bytes2str_only, data, coding))\n    if isinstance(data, list):\n        return list(map_with_parameter(bytes2str_only, data, coding))\n    else:\n        return data\n\n\ndef merge_two_dict(x, y):\n    \"\"\"Given two dictionaries, merge them into a new dict as a shallow copy.\"\"\"\n    z = x.copy()\n    z.update(y)\n    return z\n\n\nif __name__ == '__main__':\n    # print(get_ip_port(\"1.2.3.4\", 443))\n    # print(get_ip_port(\"1.2.3.4:8443\", 443))\n    print((get_ip_port(\"[face:ab1:11::0]\", 443)))\n    print((get_ip_port(\"ab01::1\", 443)))\n    print((get_ip_port(\"[ab01:55::1]:8444\", 443)))\n"
  },
  {
    "path": "code/default/lib/noarch/xconfig.py",
    "content": "\nimport time\nimport json\nimport os\nimport xlog\n\n\nclass Config(object):\n    def __init__(self, config_path):\n        self.last_load_time = time.time()\n        self.default_config = {}\n        self.file_config = {}\n        self.config_path = config_path\n        self.set_default()\n\n    def set_default(self):\n        pass\n\n    def check_change(self):\n        if os.path.getmtime(self.config_path) > self.last_load_time:\n            self.load()\n            xlog.info(\"reload config %s\", self.config_path)\n\n    def load(self):\n        self.last_load_time = time.time()\n        if os.path.isfile(self.config_path):\n            with open(self.config_path, 'r', encoding='utf-8') as f:\n                content = f.read()\n                content = content.strip()\n                content = content.replace(\"\\r\", \"\")\n                content = content.replace(\"\\n\", \"\")\n                content = content.replace(\",}\", \"}\")\n                try:\n                    self.file_config = json.loads(content)\n                except Exception as e:\n                    xlog.warn(\"Loading config:%s content:%s fail:%r\", self.config_path, content, e)\n                    self.file_config = {}\n\n        for var_name in self.default_config:\n            if self.file_config and var_name in self.file_config:\n                setattr(self, var_name, self.file_config[var_name])\n            else:\n                setattr(self, var_name, self.default_config[var_name])\n\n    # only save var not same with default\n    def save(self):\n        for var_name in self.default_config:\n            if getattr(self, var_name, None) == self.default_config[var_name]:\n                if var_name in self.file_config:\n                    del self.file_config[var_name]\n            else:\n                self.file_config[var_name] = getattr(self, var_name)\n\n        with open(self.config_path, \"w\", encoding='utf-8') as f:\n            f.write(json.dumps(self.file_config, indent=2, ensure_ascii=False))\n\n    def set_var(self, var_name, default_value):\n        self.default_config[var_name] = default_value\n"
  },
  {
    "path": "code/default/lib/noarch/xlog.py",
    "content": "import os\nimport sys\nimport time\nfrom datetime import datetime\nimport traceback\nimport threading\nimport json\nimport shutil\nfrom os.path import join\n\nfrom six import string_types\n\nimport utils\n\nCRITICAL = 50\nFATAL = CRITICAL\nERROR = 40\nWARNING = 30\nWARN = WARNING\nINFO = 20\nDEBUG = 10\nNOTSET = 0\n\n# full_log set by server, upload full log for debug (maybe next time start session), remove old log file on reset log\nfull_log = False\n\n# keep log set by UI, keep all logs, never delete old log, also upload log to server.\n\n\nclass Logger():\n    def __init__(self, name, buffer_size=0, file_name=None, roll_num=1,\n                 log_path=None, save_start_log=0, save_warning_log=False):\n        self.name = str(name)\n        self.file_max_size = 1024 * 1024\n        self.buffer_lock = threading.RLock()\n        self.buffer = {}  # id => line\n        self.buffer_size = buffer_size\n        self.last_no = 0\n        self.min_level = NOTSET\n        self.log_fd = None\n        self.set_color()\n        self.roll_num = roll_num\n        if file_name:\n            self.set_file(file_name)\n\n        self.log_path = log_path\n        self.save_start_log = save_start_log\n        self.save_warning_log = save_warning_log\n        self.start_log_num = 0\n        if log_path and save_start_log:\n            now = datetime.now()\n            time_str = now.strftime(\"%Y-%m-%d_%H-%M-%S\")\n            self.log_fn = os.path.join(log_path, \"start_log_%s_%s.log\" % (name, time_str))\n            self.start_log = open(self.log_fn, \"w\")\n        else:\n            self.start_log = None\n\n        if log_path and os.path.exists(join(log_path, \"keep_log.txt\")):\n            self.info(\"keep log\")\n            self.keep_log = True\n        else:\n            self.keep_log = False\n\n        if log_path and save_warning_log:\n            self.warning_log_fn = os.path.join(log_path, \"%s_warning.log\" % (name))\n            self.warning_log = open(self.warning_log_fn, \"a\")\n        else:\n            self.warning_log_fn = None\n            self.warning_log = None\n\n    def set_buffer(self, buffer_size):\n        with self.buffer_lock:\n            self.buffer_size = buffer_size\n            buffer_len = len(self.buffer)\n            if buffer_len > self.buffer_size:\n                for i in range(self.last_no - buffer_len, self.last_no - self.buffer_size):\n                    try:\n                        del self.buffer[i]\n                    except:\n                        pass\n\n    def reset_log_files(self):\n        if not (self.keep_log or full_log):\n            if self.start_log:\n                self.start_log.close()\n                self.start_log = None\n\n            if self.warning_log:\n                self.warning_log.close()\n                self.warning_log = None\n\n        if self.log_path and not self.keep_log:\n            for filename in os.listdir(self.log_path):\n                fp = os.path.join(self.log_path, filename)\n                if not filename.endswith(\".log\") or fp == self.log_fn or not filename.startswith(\"start_log_%s\" % self.name):\n                    continue\n\n                try:\n                    os.remove(fp)\n                except:\n                    pass\n\n        if self.warning_log_fn and not self.keep_log:\n            self.warning_log = open(self.warning_log_fn, \"a\")\n\n    def keep_logs(self):\n        self.keep_log = True\n        # self.debug(\"keep log for %s\", self.name)\n        if not self.log_path:\n            return\n\n        with open(join(self.log_path, \"keep_log.txt\"), \"w\") as fd:\n            fd.write(\" \")\n\n        if not self.start_log:\n            now = datetime.now()\n            time_str = now.strftime(\"%Y-%m-%d_%H-%M-%S\")\n            log_fn = os.path.join(self.log_path, \"start_log_%s_%s.log\" % (self.name, time_str))\n            self.start_log = open(log_fn, \"w\")\n\n    def setLevel(self, level):\n        if level == \"DEBUG\":\n            self.min_level = DEBUG\n        elif level == \"INFO\":\n            self.min_level = INFO\n        elif level == \"WARN\":\n            self.min_level = WARN\n        elif level == \"ERROR\":\n            self.min_level = ERROR\n        elif level == \"FATAL\":\n            self.min_level = FATAL\n        else:\n            print((\"log level not support:%s\", level))\n\n    def set_color(self):\n        self.err_color = None\n        self.warn_color = None\n        self.debug_color = None\n        self.reset_color = None\n        self.set_console_color = lambda x: None\n        if hasattr(sys.stderr, 'isatty') and sys.stderr.isatty():\n            if os.name == 'nt':\n                self.err_color = 0x04\n                self.warn_color = 0x06\n                self.debug_color = 0x002\n                self.reset_color = 0x07\n\n                import ctypes\n                SetConsoleTextAttribute = ctypes.windll.kernel32.SetConsoleTextAttribute\n                GetStdHandle = ctypes.windll.kernel32.GetStdHandle\n                self.set_console_color = lambda color: SetConsoleTextAttribute(GetStdHandle(-11), color)\n\n            elif os.name == 'posix':\n                self.err_color = '\\033[31m'\n                self.warn_color = '\\033[33m'\n                self.debug_color = '\\033[32m'\n                self.reset_color = '\\033[0m'\n\n                self.set_console_color = lambda color: sys.stderr.write(color)\n\n    def set_file(self, file_name):\n        self.log_filename = file_name\n        if os.path.isfile(file_name):\n            self.file_size = os.path.getsize(file_name)\n            if self.file_size > self.file_max_size:\n                self.roll_log()\n                self.file_size = 0\n        else:\n            self.file_size = 0\n\n        self.log_fd = open(file_name, \"a+\")\n\n    def roll_log(self):\n        for i in range(self.roll_num, 1, -1):\n            new_name = \"%s.%d\" % (self.log_filename, i)\n            old_name = \"%s.%d\" % (self.log_filename, i - 1)\n            if not os.path.isfile(old_name):\n                continue\n\n            # self.info(\"roll_log %s -> %s\", old_name, new_name)\n            shutil.move(old_name, new_name)\n\n        shutil.move(self.log_filename, self.log_filename + \".1\")\n\n    def log(self, level, console_color, html_color, fmt, *args, **kwargs):\n        args = utils.bytes2str_only(args)\n        now = datetime.now()\n        time_str = now.strftime(\"%Y-%m-%d %H:%M:%S.%f\")[:23]\n        string = '%s - [%s] %s\\n' % (time_str, level, fmt % args)\n        self.buffer_lock.acquire()\n        try:\n            try:\n                console_string = '%s [%s][%s] %s\\n' % (time_str, self.name, level, fmt % args)\n\n                self.set_console_color(console_color)\n                sys.stderr.write(console_string)\n                self.set_console_color(self.reset_color)\n            except:\n                pass\n\n            if self.log_fd:\n                self.log_fd.write(string)\n                try:\n                    self.log_fd.flush()\n                except:\n                    pass\n\n                self.file_size += len(string)\n                if self.file_size > self.file_max_size:\n                    self.log_fd.close()\n                    self.log_fd = None\n                    self.roll_log()\n                    self.log_fd = open(self.log_filename, \"w\")\n                    self.file_size = 0\n\n            if self.start_log:\n                self.start_log.write(string)\n                try:\n                    self.start_log.flush()\n                except:\n                    pass\n                self.start_log_num += 1\n\n                if self.start_log_num > self.save_start_log and not self.keep_log and not full_log:\n                    self.start_log.close()\n                    self.start_log = None\n\n            if self.warning_log and level in [\"WARN\", \"WARNING\", \"ERROR\", \"CRITICAL\"]:\n                self.warning_log.write(string)\n                try:\n                    self.warning_log.flush()\n                except:\n                    pass\n\n            if self.buffer_size:\n                self.last_no += 1\n                self.buffer[self.last_no] = string\n                buffer_len = len(self.buffer)\n                if buffer_len > self.buffer_size:\n                    del self.buffer[self.last_no - self.buffer_size]\n        except Exception as e:\n            string = '%s - [%s]LOG_EXCEPT: %s, Except:%s<br> %s' % \\\n                     (time.ctime()[4:-5], level, fmt % args, e, traceback.format_exc())\n            self.last_no += 1\n            self.buffer[self.last_no] = string\n            buffer_len = len(self.buffer)\n            if buffer_len > self.buffer_size:\n                del self.buffer[self.last_no - self.buffer_size]\n        finally:\n            self.buffer_lock.release()\n\n    def debug(self, fmt, *args, **kwargs):\n        if self.min_level > DEBUG:\n            return\n        self.log('DEBUG', self.debug_color, '21610b', fmt, *args, **kwargs)\n\n    def info(self, fmt, *args, **kwargs):\n        if self.min_level > INFO:\n            return\n        self.log('INFO', self.reset_color, '000000', fmt, *args)\n\n    def warning(self, fmt, *args, **kwargs):\n        if self.min_level > WARN:\n            return\n        self.log('WARNING', self.warn_color, 'FF8000', fmt, *args, **kwargs)\n\n    def warn(self, fmt, *args, **kwargs):\n        self.warning(fmt, *args, **kwargs)\n\n    def error(self, fmt, *args, **kwargs):\n        if self.min_level > ERROR:\n            return\n        self.log('ERROR', self.err_color, 'FE2E2E', fmt, *args, **kwargs)\n\n    def exception(self, fmt, *args, **kwargs):\n        self.error(fmt, *args, **kwargs)\n        self.error(\"Except stack:%s\", traceback.format_exc(), **kwargs)\n\n    def critical(self, fmt, *args, **kwargs):\n        if self.min_level > CRITICAL:\n            return\n        self.log('CRITICAL', self.err_color, 'D7DF01', fmt, *args, **kwargs)\n\n    # =================================================================\n    def get_last_lines(self, max_lines):\n        self.buffer_lock.acquire()\n        buffer_len = len(self.buffer)\n        if buffer_len > max_lines:\n            first_no = self.last_no - max_lines\n        else:\n            first_no = self.last_no - buffer_len + 1\n\n        jd = {}\n        if buffer_len > 0:\n            for i in range(first_no, self.last_no + 1):\n                jd[i] = utils.to_str(self.buffer[i])\n        self.buffer_lock.release()\n        return json.dumps(jd)\n\n    def get_new_lines(self, from_no):\n        self.buffer_lock.acquire()\n        jd = {}\n        first_no = self.last_no - len(self.buffer) + 1\n        if from_no < first_no:\n            from_no = first_no\n\n        if self.last_no >= from_no:\n            for i in range(from_no, self.last_no + 1):\n                jd[i] = utils.to_str(self.buffer[i])\n        self.buffer_lock.release()\n        return json.dumps(jd)\n\n\nclass null():\n    @staticmethod\n    def debug(fmt, *args, **kwargs):\n        pass\n\n    @staticmethod\n    def info(fmt, *args, **kwargs):\n        pass\n\n    @staticmethod\n    def warn(fmt, *args, **kwargs):\n        pass\n\n    @staticmethod\n    def exception(fmt, *args, **kwargs):\n        pass\n\n\nloggerDict = {}\n\n\ndef getLogger(name=None, buffer_size=0, file_name=None, roll_num=1,\n              log_path=None, save_start_log=0, save_warning_log=False):\n    global loggerDict, default_log\n    if name is None:\n        for n in loggerDict:\n            name = n\n            break\n    if name is None:\n        name = u\"default\"\n\n    if not isinstance(name, string_types):\n        raise TypeError('A logger name must be string or Unicode')\n    if isinstance(name, bytes):\n        name = name.decode('utf-8')\n\n    if name in loggerDict:\n        return loggerDict[name]\n    else:\n        logger_instance = Logger(name, buffer_size, file_name, roll_num, log_path, save_start_log, save_warning_log)\n        loggerDict[name] = logger_instance\n        default_log = logger_instance\n        return logger_instance\n\n\ndef reset_log_files():\n    for name, log in loggerDict.items():\n        log.reset_log_files()\n\n\ndef keep_log(temp=False):\n    global full_log\n    if temp:\n        full_log = True\n    else:\n        for name, log in loggerDict.items():\n            log.keep_logs()\n\n\ndefault_log = getLogger()\n\n\ndef debug(fmt, *args, **kwargs):\n    default_log.debug(fmt, *args, **kwargs)\n\n\ndef info(fmt, *args, **kwargs):\n    default_log.info(fmt, *args, **kwargs)\n\n\ndef warning(fmt, *args, **kwargs):\n    default_log.warnin(fmt, *args, **kwargs)\n\n\ndef warn(fmt, *args, **kwargs):\n    default_log.warn(fmt, *args, **kwargs)\n\n\ndef error(fmt, *args, **kwargs):\n    default_log.error(fmt, *args, **kwargs)\n\n\ndef exception(fmt, *args, **kwargs):\n    error(fmt, *args, **kwargs)\n    error(\"Except stack:%s\", traceback.format_exc(), **kwargs)\n\n\ndef critical(fmt, *args, **kwargs):\n    default_log.critical(fmt, *args, **kwargs)\n"
  },
  {
    "path": "code/default/lib/noarch/xstruct.py",
    "content": "from struct import pack\nfrom struct import unpack as origin_unpack\n\n\nneed_convert = False\n\n\ndef unpack(format, data):\n    global need_convert\n\n    if need_convert and isinstance(data, memoryview):\n        data = data.tobytes()\n\n    try:\n        return origin_unpack(format, data)\n    except:\n        need_convert = True\n\n        data = data.tobytes()\n        return origin_unpack(format, data)"
  },
  {
    "path": "code/default/lib/noarch/xx_six.py",
    "content": "from six import PY2\n\n\nif PY2:\n  class BlockingIOError(Exception):\n      pass\n\n\n  class BrokenPipeError(Exception):\n      pass\n\n\n  class ConnectionError(Exception):\n      pass\n\n\n  class ConnectionResetError(Exception):\n      pass\n\n\n  class ConnectionAbortedError(Exception):\n      pass\nelse:\n    BlockingIOError = BlockingIOError\n    BrokenPipeError = BrokenPipeError\n    ConnectionError = ConnectionError\n    ConnectionResetError = ConnectionResetError\n    ConnectionAbortedError = ConnectionAbortedError\n"
  },
  {
    "path": "code/default/lib/tests/stress_boringssl.py",
    "content": "import sys\nimport os\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nlocal_path = os.path.abspath(os.path.join(current_path, os.pardir))\nroot_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))\npython_path = root_path\n\nsys.path.append(root_path)\nsys.path.append(local_path)\n\nnoarch_lib = os.path.abspath(os.path.join(python_path, 'lib', 'noarch'))\nsys.path.append(noarch_lib)\n\nif sys.platform == \"win32\":\n    win32_lib = os.path.abspath(os.path.join(python_path, 'lib', 'win32'))\n    sys.path.append(win32_lib)\nelif sys.platform.startswith(\"linux\"):\n    linux_lib = os.path.abspath(os.path.join(python_path, 'lib', 'linux'))\n    sys.path.append(linux_lib)\nelif sys.platform == \"darwin\":\n    darwin_lib = os.path.abspath(os.path.join(python_path, 'lib', 'darwin'))\n    sys.path.append(darwin_lib)\n    extra_lib = \"/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python\"\n    sys.path.append(extra_lib)\n\nimport env_info\nimport xlog\nlogger = xlog.getLogger(\"stress\")\n\nfrom front_base.openssl_wrap import SSLContext\nfrom front_base.connect_creator import ConnectCreator\nfrom front_base.check_ip import CheckIp\n\n\nfrom x_tunnel.local.tls_relay_front.front import front\nfrom x_tunnel.local.tls_relay_front.config import Config\nfrom x_tunnel.local.tls_relay_front.host_manager import HostManager\n\nmodule_data_path = os.path.join(env_info.data_path, 'x_tunnel')\n\n\ndef round():\n    ip = \"127.0.0.1\"\n    top_domain = \"agentnobody.pics\"\n    wait_time = 0\n\n    config_path = os.path.join(module_data_path, \"tls_relay.json\")\n    config = Config(config_path)\n\n    openssl_context = SSLContext(logger)\n\n    host_fn = os.path.join(module_data_path, \"tls_host.json\")\n    host_manager = HostManager(host_fn)\n    connect_creator = ConnectCreator(logger, config, openssl_context, host_manager)\n    check_ip = CheckIp(logger, config, connect_creator)\n\n    res = check_ip.check_ip(ip, sni=top_domain, host=top_domain, wait_time=wait_time)\n    logger.info(\"res: %s\", res)\n    front.stop()\n\n\ndef loop():\n    while True:\n        round()\n        # time.sleep(1)\n\n\nloop()\n\n"
  },
  {
    "path": "code/default/lib/tests/stress_boringssl2.py",
    "content": "\nimport socket\n\nfrom boringssl import lib as bssl, ffi\n\n\nclass SSLConnection(object):\n    BIO_CLOSE = 1\n\n    def __init__(self, context, sock, ip_str=None, sni=None, on_close=None):\n        self._context = context\n        self._sock = sock\n        # self.ip_str = utils.to_bytes(ip_str)\n        self.sni = sni\n        self._makefile_refs = 0\n        self._on_close = on_close\n        self.peer_cert = None\n        self.socket_closed = False\n        self.timeout = self._sock.gettimeout() or 0.1\n        self.running = True\n        self._connection = None\n        self.wrap()\n\n    def wrap(self):\n        fn = self._sock.fileno()\n        bio = bssl.BIO_new_socket(fn, self.BIO_CLOSE)\n\n        self._connection = bssl.SSL_new(self._context.ctx)\n\n        bssl.SSL_set_tlsext_host_name(self._connection, self.sni)\n\n        bssl.SSL_set_bio(self._connection, bio, bio)\n\n        if self._context.enable_h2:\n            proto = b\"h2\"\n            setting = b\"h2\"\n            ret = bssl.SSL_add_application_settings(self._connection,\n                                                    proto, len(proto),\n                                                    setting, len(setting))\n            # print(ret)\n\n        ret = bssl.SSL_connect(self._connection)\n\n    def send(self, data):\n        bssl.SSL_write(self._connection, data, len(data))\n\n    def recv(self, size):\n        buf = bytes(size)\n        n = bssl.SSL_read(self._connection, buf, size)\n        if n <= 0:\n            return None\n\n        dat = buf[:n]\n        return dat\n\n    def close(self):\n        print(\"close\")\n        bssl.SSL_shutdown(self._connection)\n        bssl.SSL_free(self._connection)\n        self._connection = None\n\n    def __del__(self):\n        self.close()\n\n\nclass SSLContext(object):\n    def __init__(self, enable_h2=True):\n        method = bssl.TLS_method()\n        self.ctx = bssl.SSL_CTX_new(method)\n        self.enable_h2 = enable_h2\n        bssl.SSL_CTX_set_grease_enabled(self.ctx, 1)\n\n        cmd = b\"ALL:!aPSK:!ECDSA+SHA1:!3DES\"\n        bssl.SSL_CTX_set_cipher_list(self.ctx, cmd)\n\n        if enable_h2:\n            alpn = b\"\"\n            for proto in [b\"h2\", b\"http/1.1\"]:\n                proto_len = len(proto)\n                alpn += proto_len.to_bytes(1, 'big') + proto\n            bssl.SSL_CTX_set_alpn_protos(self.ctx, alpn, len(alpn))\n        bssl.SSL_CTX_enable_ocsp_stapling(self.ctx)\n        bssl.SSL_CTX_enable_signed_cert_timestamps(self.ctx)\n\n        #SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PSS_RSAE_SHA256,\n        #SSL_SIGN_RSA_PKCS1_SHA256,       SSL_SIGN_ECDSA_SECP384R1_SHA384,\n        #SSL_SIGN_RSA_PSS_RSAE_SHA384,    SSL_SIGN_RSA_PKCS1_SHA384,\n        #SSL_SIGN_RSA_PSS_RSAE_SHA512,    SSL_SIGN_RSA_PKCS1_SHA512,\n        algs = [0x0403, 0x0804, 0x0401, 0x0503, 0x0805, 0x0501, 0x0806, 0x0601]\n        algs_buf = ffi.new(\"uint16_t[%s]\" % (len(algs)))\n        i = 0\n        for alg in algs:\n            algs_buf[i] = alg\n            i += 1\n        cdata_ptr = ffi.cast(\"uint16_t *\", algs_buf)\n        bssl.SSL_CTX_set_verify_algorithm_prefs(self.ctx, cdata_ptr, len(algs))\n\n        bssl.SSL_CTX_set_min_proto_version(self.ctx, 0x0303)\n\n        bssl.SetCompression(self.ctx)\n\n\ndef round():\n    ip = \"127.0.0.1\"\n    host = \"agentnobody.pics\"\n    sock = socket.socket(socket.AF_INET if ':' not in ip else socket.AF_INET6)\n    sock.settimeout(3)\n    try:\n        sock.connect((ip, 443))\n    except Exception as e:\n        print(\"connnect fail\")\n        return\n\n    context = SSLContext(enable_h2=False)\n    connection = SSLConnection(context, sock, sni=host.encode(\"utf-8\"))\n    sock.setblocking(True)\n    # connection.settimeout(10)\n    print(\"connected\")\n\n    connection.send(b\"GET / HTTP/1.0\\r\\n\")\n    connection.send(b\"Host: %s\\r\\n\" % host.encode(\"utf-8\"))\n    connection.send(b\"User-Agent: curl\\r\\n\")\n    connection.send(b\"Accept: */*\\r\\n\")\n    connection.send(b\"\\r\\n\")\n\n    while True:\n        try:\n            r = connection.recv(10240)\n            if not r:\n                break\n            print(r.decode(\"utf-8\"))\n        except socket.timeout:\n            break\n        except Exception as e:\n            break\n\n\ndef loop():\n    while True:\n        round()\n\n\nloop()\n"
  },
  {
    "path": "code/default/lib/tests/test_http_client.py",
    "content": "import os\nimport unittest\nimport time\nimport utils\nimport json\nimport simple_http_client\nimport tempfile\n\n\nclass HttpClientTest(unittest.TestCase):\n    def test_get(self):\n        client = simple_http_client.Client(timeout=10)\n        url = \"https://raw.githubusercontent.com/XX-net/XX-Net/master/code/default/x_tunnel/local/cloudflare_front/front_domains.json\"\n        res = client.request(\"GET\", url)\n        self.assertEqual(res.status, 200)\n        content = utils.to_str(res.text)\n        data = json.loads(content)\n        print(data)\n\n    def test_get2(self):\n        url = \"https://raw.githubusercontent.com/XX-net/XX-Net/master/code/default/update_v5.txt\"\n\n        client = simple_http_client.Client(timeout=10)\n        res = client.request(\"GET\", url)\n        self.assertEqual(res.status, 200)\n        content = utils.to_str(res.text)\n        print(content)\n\n    def test_get_fail(self):\n        headers = {\"connection\": \"close\"}\n        res = simple_http_client.request(\"GET\", \"http://127.0.0.1:2515/ping\", headers=headers, timeout=0.5)\n        self.assertIsNone(res)\n\n    def test_get_bulk(self):\n        timeout = 5\n        client = simple_http_client.Client(timeout=timeout)\n        url = \"https://raw.githubusercontent.com/XX-net/XX-Net/master/code/default/update_v5.txt\"\n\n        start_time = time.time()\n        req = client.request(\"GET\", url, read_payload=False)\n        self.assertIsNotNone(req)\n\n        tp = tempfile.gettempdir()\n        filename = os.path.join(tp, \"v5.txt\")\n        if req.chunked:\n            downloaded = 0\n            with open(filename, 'wb') as fp:\n                while True:\n                    time_left = timeout - (time.time() - start_time)\n                    if time_left < 0:\n                        raise Exception(\"time out\")\n\n                    dat = req.read(timeout=time_left)\n                    if not dat:\n                        break\n\n                    fp.write(dat)\n                    downloaded += len(dat)\n\n            return True\n        else:\n            file_size = int(req.getheader(b'Content-Length', 0))\n\n            left = file_size\n            downloaded = 0\n            with open(filename, 'wb') as fp:\n                while True:\n                    chunk_len = min(65536, left)\n                    if not chunk_len:\n                        break\n\n                    chunk = req.read(chunk_len)\n                    if not chunk:\n                        break\n                    fp.write(chunk)\n                    downloaded += len(chunk)\n                    left -= len(chunk)\n"
  },
  {
    "path": "code/default/lib/tests/test_http_server.py",
    "content": "import unittest\nimport utils\nimport simple_http_client\nimport simple_http_server\n\n\nclass HttpClientTest(unittest.TestCase):\n    def test_get(self):\n        server = simple_http_server.HTTPServer(('', 8880), simple_http_server.TestHttpServer, \".\")\n        server.start()\n\n        client = simple_http_client.Client(timeout=5)\n        url = \"http://localhost:8880/test\"\n        res = client.request(\"GET\", url)\n        self.assertEqual(res.status, 200)\n        content = utils.to_str(res.text)\n        print(content)\n\n        server.shutdown()\n"
  },
  {
    "path": "code/default/lib/tests/test_queue.py",
    "content": "import time\nimport threading\nfrom unittest import TestCase\n# from simple_queue import Queue\nfrom  queue import Queue\n\n\nclass TestSimpleQueue(TestCase):\n\n    @staticmethod\n    def pub(q, x):\n        time.sleep(2)\n        print(\"put x\")\n        q.put(x)\n\n    def test_basic(self):\n        q1 = Queue()\n        q1.put(\"a\")\n        v = q1.get()\n        self.assertEqual(v, \"a\")\n\n        threading.Thread(target=self.pub, args=(q1, \"b\")).start()\n        v = q1.get(5)\n        self.assertEqual(v, \"b\")\n"
  },
  {
    "path": "code/default/lib/tests/test_utils.py",
    "content": "import unittest\n\nimport utils\nimport re\n\ndef split_the_ip(ip_str):\n    # ips = utils.to_str(ip_str).split(\":\")[0:-1]\n    # ip = \":\".join(ips)\n\n    ip_pattern = r'(?P<ip>(\\d{1,3}\\.){3}\\d{1,3}|(\\[[0-9a-fA-F:]+\\])):(?P<port>\\d+)'\n\n    match = re.match(ip_pattern, ip_str)\n    ip_address = match.group('ip')\n    if '[' in ip_address:\n        ip_address = ip_address[1:-1]\n    port = match.group('port')\n    return ip_address\n\n\nclass TestIP(unittest.TestCase):\n    def test_check_ipv4(self):\n        host = 'bat-bing-com.a-0001.a-msedge.net.'\n        res = utils.check_ip_valid4(host)\n        self.assertFalse(res)\n\n    def test_private_ip(self):\n        ip = 'bat-bing-com.a-0001.a-msedge.net.'\n        res = utils.is_private_ip(ip)\n        self.assertFalse(res)\n\n    def test_merge_dict(self):\n        x = {'a': 1, 'b': 2}\n        y = {'b': 3, 'c': 4}\n        z = utils.merge_two_dict(x, y)\n        self.assertEqual(z, {\n            'a': 1,\n            'b': 3,\n            'c': 4\n        })\n\n    def test_memory(self):\n        buf = bytearray(8)\n        mv = memoryview(buf)\n        mv3 = mv[3:]\n        print(len(mv3))\n\n    def test_split_ip(self):\n        ip_pattern = r'(?P<ip>(\\d{1,3}\\.){3}\\d{1,3}|(\\[[0-9a-fA-F:]+\\])):(?P<port>\\d+)'\n\n        ip_port_str_1 = \"127.0.0.1:8080\"\n        # Extract the IP address and port from the IPv4 string\n        match = re.match(ip_pattern, ip_port_str_1)\n        ip_address = match.group('ip')\n        port = match.group('port')\n        self.assertEqual(ip_address, \"127.0.0.1\")\n\n        ip_port_str_1 = \"[fffe:3465:efab::23fe]:8080\"\n        # Extract the IP address and port from the IPv4 string\n        match = re.match(ip_pattern, ip_port_str_1)\n        ip_address = match.group('ip')\n        if '[' in ip_address:\n            ip_address = ip_address[1:-1]\n        port = match.group('port')\n        self.assertEqual(ip_address, \"fffe:3465:efab::23fe\")\n\n    def test_split_ip_fun(self):\n        self.assertEqual(split_the_ip(\"127.0.0.1:8080\"), \"127.0.0.1\")\n        self.assertEqual(split_the_ip(\"[fffe:3465:efab::23fe]:8080\"), \"fffe:3465:efab::23fe\")\n\n    def test_utils_get_ip(self):\n        ip, port = utils.get_ip_port(\"2400:8901::f03c:93ff:fe49:5c21\")\n        ip = utils.to_str(ip)\n        self.assertEqual(ip, \"2400:8901::f03c:93ff:fe49:5c21\")\n"
  },
  {
    "path": "code/default/lib/win32/systray/__init__.py",
    "content": "# infi.systray\n\nfrom .traybar import SysTrayIcon\n"
  },
  {
    "path": "code/default/lib/win32/systray/traybar.py",
    "content": "import os\r\nfrom .win32_adapter import *\r\nimport threading\r\nimport uuid\r\n\r\n\r\nclass SysTrayIcon(object):\r\n    QUIT = 'QUIT'\r\n    SPECIAL_ACTIONS = [QUIT]\r\n\r\n    FIRST_ID = 1023\r\n\r\n    def __init__(self,\r\n                 icon,\r\n                 hover_text,\r\n                 menu_options=None,\r\n                 on_quit=None,\r\n                 default_menu_index=None,\r\n                 window_class_name=None,\r\n                 left_click=None,\r\n                 right_click=None):\r\n\r\n        self._icon = icon\r\n        self._hover_text = hover_text\r\n        self._on_quit = on_quit\r\n        if left_click:\r\n            self._left_click = left_click\r\n        if right_click:\r\n            self._right_click = right_click\r\n\r\n        self._set_menu_options(menu_options)\r\n\r\n        window_class_name = window_class_name or (\"SysTrayIconPy-%s\" % (str(uuid.uuid4())))\r\n\r\n        self._default_menu_index = (default_menu_index or 0)\r\n        self._window_class_name = convert_to_ascii(window_class_name)\r\n        self._message_dict = {RegisterWindowMessage(\"TaskbarCreated\"): self._restart,\r\n                              WM_DESTROY: self._destroy,\r\n                              WM_CLOSE: self._destroy,\r\n                              WM_COMMAND: self._command,\r\n                              WM_USER+20: self._notify}\r\n        self._notify_id = None\r\n        self._message_loop_thread = None\r\n        self._hwnd = None\r\n        self._hicon = 0\r\n        self._hinst = None\r\n        self._window_class = None\r\n        self._menu = None\r\n        self._register_class()\r\n\r\n    def _set_menu_options(self, menu_options):\r\n        self._menu_actions_by_id = set()\r\n\r\n        menu_options = menu_options or ()\r\n        self._menu_options = self._add_ids_to_menu_options(list(menu_options))\r\n        self._menu_actions_by_id = dict(self._menu_actions_by_id)\r\n\r\n    def _add_ids_to_menu_options(self, menu_options):\r\n        self._next_action_id = SysTrayIcon.FIRST_ID\r\n        result = []\r\n        for menu_option in menu_options:\r\n            option_text, option_icon, option_action, fState = menu_option\r\n            if callable(option_action) or option_action in SysTrayIcon.SPECIAL_ACTIONS:\r\n                self._menu_actions_by_id.add((self._next_action_id, option_action))\r\n                result.append(menu_option + (self._next_action_id,))\r\n            elif non_string_iterable(option_action):\r\n                result.append((option_text,\r\n                               option_icon,\r\n                               self._add_ids_to_menu_options(option_action),\r\n                               self._next_action_id))\r\n            else:\r\n                raise Exception('Unknown item', option_text, option_icon, option_action)\r\n            self._next_action_id += 1\r\n        return result\r\n\r\n    def WndProc(self, hwnd, msg, wparam, lparam):\r\n        hwnd = HANDLE(hwnd)\r\n        wparam = WPARAM(wparam)\r\n        lparam = LPARAM(lparam)\r\n        #print msg\r\n        if msg in self._message_dict:\r\n            self._message_dict[msg](hwnd, msg, wparam.value, lparam.value)\r\n        return DefWindowProc(hwnd, msg, wparam, lparam)\r\n\r\n    def _register_class(self):\r\n        # Register the Window class.\r\n        self._window_class = WNDCLASS()\r\n        self._hinst = self._window_class.hInstance = GetModuleHandle(None)\r\n        self._window_class.lpszClassName = self._window_class_name\r\n        self._window_class.style = CS_VREDRAW | CS_HREDRAW\r\n        self._window_class.hCursor = LoadCursor(0, IDC_ARROW)\r\n        self._window_class.hbrBackground = COLOR_WINDOW\r\n        self._window_class.lpfnWndProc = LPFN_WNDPROC(self.WndProc)\r\n        RegisterClass(ctypes.byref(self._window_class))\r\n\r\n    def _create_window(self):\r\n        style = WS_OVERLAPPED | WS_SYSMENU\r\n        self._hwnd = CreateWindowEx(0, self._window_class_name,\r\n                                      self._window_class_name,\r\n                                      style,\r\n                                      0,\r\n                                      0,\r\n                                      CW_USEDEFAULT,\r\n                                      CW_USEDEFAULT,\r\n                                      0,\r\n                                      0,\r\n                                      self._hinst,\r\n                                      None)\r\n        UpdateWindow(self._hwnd)\r\n        self._refresh_icon(recreate=True)\r\n\r\n    def _message_loop_func(self):\r\n        self._create_window()\r\n        PumpMessages()\r\n\r\n    def start(self):\r\n        if self._hwnd:\r\n            return      # already started\r\n        self._message_loop_thread = threading.Thread(target=self._message_loop_func, name=\"win32_systray\")\r\n        self._message_loop_thread.daemon = True\r\n        self._message_loop_thread.start()\r\n\r\n    def shutdown(self):\r\n        if not self._hwnd:\r\n            return      # not started\r\n        PostMessage(self._hwnd, WM_CLOSE, 0, 0)\r\n        self._message_loop_thread.join()\r\n\r\n    def update(self, icon=None, hover_text=None, menu=None):\r\n        \"\"\" update icon image and/or hover text \"\"\"\r\n        if icon:\r\n            self._icon = icon\r\n        if hover_text:\r\n            self._hover_text = hover_text\r\n        if menu:\r\n            self._set_menu_options(menu)\r\n            self._menu = CreatePopupMenu()\r\n            self._create_menu(self._menu, self._menu_options)\r\n        self._refresh_icon()\r\n\r\n\r\n    def _load_icon(self):\r\n        # release previous icon, if a custom one was loaded\r\n        # note: it's important *not* to release the icon if we loaded the default system icon (with\r\n        # the LoadIcon function) - this is why we assign self._hicon only if it was loaded using LoadImage\r\n        # TODO don't reload if not necessary\r\n        if self._hicon != 0:\r\n            DestroyIcon(self._hicon)\r\n            self._hicon = 0\r\n        hicon = 0\r\n        # Try and find a custom icon\r\n        if self._icon is not None and os.path.isfile(self._icon):\r\n            icon_flags = LR_LOADFROMFILE | LR_DEFAULTSIZE\r\n            icon = convert_to_ascii(self._icon)\r\n            hicon = self._hicon = LoadImage(0, icon, IMAGE_ICON, 0, 0, icon_flags)\r\n        if hicon == 0:\r\n            # Can't find icon file - using default\r\n            hicon = LoadIcon(0, IDI_APPLICATION)\r\n        return hicon\r\n\r\n    def _refresh_icon(self, recreate=False):\r\n        if self._hwnd is None:\r\n            return\r\n        hicon = self._load_icon()\r\n        if self._notify_id and not recreate:\r\n            message = NIM_MODIFY\r\n        else:\r\n            message = NIM_ADD\r\n        self._notify_id = NotifyData(self._hwnd,\r\n                          0,\r\n                          NIF_ICON | NIF_MESSAGE | NIF_TIP,\r\n                          WM_USER+20,\r\n                          hicon,\r\n                          self._hover_text)\r\n        Shell_NotifyIcon(message, ctypes.byref(self._notify_id))\r\n\r\n    def _restart(self, hwnd, msg, wparam, lparam):\r\n        self._refresh_icon(recreate=True)\r\n\r\n    def _destroy(self, hwnd, msg, wparam, lparam):\r\n        if self._on_quit:\r\n            self._on_quit(self)\r\n        nid = NotifyData(self._hwnd, 0)\r\n        Shell_NotifyIcon(NIM_DELETE, ctypes.byref(nid))\r\n        PostQuitMessage(0)  # Terminate the app.\r\n        # TODO * release self._menu with DestroyMenu and reset the memeber\r\n        #      * release self._hicon with DestoryIcon and reset the member\r\n        #      * release loaded menu icons (loaded in _load_menu_icon) with DeleteObject\r\n        #        (we don't keep those objects anywhere now)\r\n        self._hwnd = None\r\n        self._notify_id = None\r\n\r\n    def _notify(self, hwnd, msg, wparam, lparam):\r\n        #print lparam\r\n        if lparam == WM_LBUTTONDBLCLK:\r\n            self._execute_menu_option(self._default_menu_index + SysTrayIcon.FIRST_ID)\r\n        elif lparam == WM_RBUTTONUP:\r\n            self._right_click()\r\n        elif lparam == WM_LBUTTONUP:\r\n            self._left_click()\r\n        return True\r\n\r\n    def _left_click(self):\r\n        pass\r\n    def _right_click(self):\r\n        self._show_menu()\r\n\r\n    def _show_menu(self):\r\n        if self._menu is None:\r\n            self._menu = CreatePopupMenu()\r\n            self._create_menu(self._menu, self._menu_options)\r\n            #SetMenuDefaultItem(self._menu, 1000, 0)\r\n\r\n        pos = POINT()\r\n        GetCursorPos(ctypes.byref(pos))\r\n        # See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/menus_0hdi.asp\r\n        SetForegroundWindow(self._hwnd)\r\n        TrackPopupMenu(self._menu,\r\n                       TPM_LEFTALIGN,\r\n                       pos.x,\r\n                       pos.y,\r\n                       0,\r\n                       self._hwnd,\r\n                       None)\r\n        PostMessage(self._hwnd, WM_NULL, 0, 0)\r\n\r\n    def _create_menu(self, menu, menu_options):\r\n        for option_text, option_icon, option_action, fState, option_id in menu_options[::-1]:\r\n            if option_icon:\r\n                option_icon = self._load_menu_icon(option_icon)\r\n            if option_id in self._menu_actions_by_id:\r\n                item = PackMENUITEMINFO(text=option_text,\r\n                                        hbmpItem=option_icon,\r\n                                        wID=option_id,\r\n                                        fState=fState)\r\n            else:\r\n                submenu = CreatePopupMenu()\r\n                self._create_menu(submenu, option_action)\r\n                item = PackMENUITEMINFO(text=option_text,\r\n                                        hbmpItem=option_icon,\r\n                                        hSubMenu=submenu)\r\n            InsertMenuItem(menu, 0, 1,  ctypes.byref(item))\r\n\r\n    def _load_menu_icon(self, icon):\r\n        icon = convert_to_ascii(icon)\r\n        # First load the icon.\r\n        ico_x = GetSystemMetrics(SM_CXSMICON)\r\n        ico_y = GetSystemMetrics(SM_CYSMICON)\r\n        hicon = LoadImage(0, icon, IMAGE_ICON, ico_x, ico_y, LR_LOADFROMFILE)\r\n\r\n        hdcBitmap = CreateCompatibleDC(None)\r\n        hdcScreen = GetDC(None)\r\n        hbm = CreateCompatibleBitmap(hdcScreen, ico_x, ico_y)\r\n        hbmOld = SelectObject(hdcBitmap, hbm)\r\n        # Fill the background.\r\n        brush = GetSysColorBrush(COLOR_MENU)\r\n        FillRect(hdcBitmap, ctypes.byref(RECT(0, 0, 16, 16)), brush)\r\n        # draw the icon\r\n        DrawIconEx(hdcBitmap, 0, 0, hicon, ico_x, ico_y, 0, 0, DI_NORMAL)\r\n        SelectObject(hdcBitmap, hbmOld)\r\n\r\n        # No need to free the brush\r\n        DeleteDC(hdcBitmap)\r\n        DestroyIcon(hicon)\r\n\r\n        return hbm\r\n\r\n    def _command(self, hwnd, msg, wparam, lparam):\r\n        id = LOWORD(wparam)\r\n        self._execute_menu_option(id)\r\n\r\n    def _execute_menu_option(self, id):\r\n        menu_action = self._menu_actions_by_id[id]\r\n        if menu_action == SysTrayIcon.QUIT:\r\n            DestroyWindow(self._hwnd)\r\n        else:\r\n            menu_action(self)\r\n\r\ndef non_string_iterable(obj):\r\n    try:\r\n        iter(obj)\r\n    except TypeError:\r\n        return False\r\n    else:\r\n        return not isinstance(obj, str)\r\n"
  },
  {
    "path": "code/default/lib/win32/systray/win32_adapter.py",
    "content": "import ctypes\r\nimport locale\r\n\r\nRegisterWindowMessage = ctypes.windll.user32.RegisterWindowMessageA\r\nLoadCursor = ctypes.windll.user32.LoadCursorA\r\nLoadIcon = ctypes.windll.user32.LoadIconA\r\nLoadImage = ctypes.windll.user32.LoadImageA\r\nRegisterClass = ctypes.windll.user32.RegisterClassA\r\nCreateWindowEx = ctypes.windll.user32.CreateWindowExA\r\nUpdateWindow = ctypes.windll.user32.UpdateWindow\r\nDefWindowProc = ctypes.windll.user32.DefWindowProcA\r\nGetSystemMetrics = ctypes.windll.user32.GetSystemMetrics\r\nInsertMenuItem = ctypes.windll.user32.InsertMenuItemA\r\nPostMessage = ctypes.windll.user32.PostMessageA\r\nPostQuitMessage = ctypes.windll.user32.PostQuitMessage\r\nSetMenuDefaultItem = ctypes.windll.user32.SetMenuDefaultItem\r\nGetCursorPos = ctypes.windll.user32.GetCursorPos\r\nSetForegroundWindow = ctypes.windll.user32.SetForegroundWindow\r\nTrackPopupMenu = ctypes.windll.user32.TrackPopupMenu\r\nCreatePopupMenu = ctypes.windll.user32.CreatePopupMenu\r\nCreateCompatibleDC = ctypes.windll.gdi32.CreateCompatibleDC\r\nGetDC = ctypes.windll.user32.GetDC\r\nCreateCompatibleBitmap = ctypes.windll.gdi32.CreateCompatibleBitmap\r\nGetSysColorBrush = ctypes.windll.user32.GetSysColorBrush\r\nFillRect = ctypes.windll.user32.FillRect\r\nDrawIconEx = ctypes.windll.user32.DrawIconEx\r\nSelectObject = ctypes.windll.gdi32.SelectObject\r\nDeleteDC = ctypes.windll.gdi32.DeleteDC\r\nDestroyWindow = ctypes.windll.user32.DestroyWindow\r\nGetModuleHandle = ctypes.windll.kernel32.GetModuleHandleA\r\nGetMessage = ctypes.windll.user32.GetMessageA\r\nTranslateMessage = ctypes.windll.user32.TranslateMessage\r\nDispatchMessage = ctypes.windll.user32.DispatchMessageA\r\nShell_NotifyIcon = ctypes.windll.shell32.Shell_NotifyIcon\r\nDestroyIcon = ctypes.windll.user32.DestroyIcon\r\n\r\nNIM_ADD = 0\r\nNIM_MODIFY = 1\r\nNIM_DELETE = 2\r\nNIF_ICON = 2\r\nNIF_MESSAGE = 1\r\nNIF_TIP = 4\r\nMIIM_ID = 2\r\nMIIM_SUBMENU = 4\r\nMIIM_STRING = 64\r\nMIIM_BITMAP = 128\r\nWM_DESTROY = 2\r\nWM_CLOSE = 16\r\nWM_COMMAND = 273\r\nWM_USER = 1024\r\nWM_LBUTTONDBLCLK = 515\r\nWM_RBUTTONUP = 517\r\nWM_LBUTTONUP = 514\r\nWM_NULL = 0\r\nCS_VREDRAW = 1\r\nCS_HREDRAW = 2\r\nIDC_ARROW = 32512\r\nCOLOR_WINDOW = 5\r\nWS_OVERLAPPED = 0\r\nWS_SYSMENU = 524288\r\nCW_USEDEFAULT = -2147483648\r\nLR_LOADFROMFILE = 16\r\nLR_DEFAULTSIZE = 64\r\nIMAGE_ICON = 1\r\nIDI_APPLICATION = 32512\r\nTPM_LEFTALIGN = 0\r\nSM_CXSMICON = 49\r\nSM_CYSMICON = 50\r\nCOLOR_MENU = 4\r\nDI_NORMAL = 3\r\n\r\nclass fState:\r\n    MFS_DEFAULT = 0x1000\r\n    MFS_ENABLED = 0\r\n    MFS_DISABLED = 0x3\r\n    MFS_CHECKED = 0x8\r\n    MFS_HILITE = 0x80\r\n\r\n# WPARAM is defined as UINT_PTR (unsigned type)\r\n# LPARAM is defined as LONG_PTR (signed type)\r\nif ctypes.sizeof(ctypes.c_long) == ctypes.sizeof(ctypes.c_void_p):\r\n    WPARAM = ctypes.c_ulong\r\n    LPARAM = ctypes.c_long\r\n    LRESULT = ctypes.c_long\r\nelif ctypes.sizeof(ctypes.c_longlong) == ctypes.sizeof(ctypes.c_void_p):\r\n    WPARAM = ctypes.c_ulonglong\r\n    LPARAM = ctypes.c_longlong\r\n    LRESULT = ctypes.c_longlong\r\nHANDLE = ctypes.c_void_p\r\n\r\n\r\nSZTIP_MAX_LENGTH = 128\r\nLOCALE_ENCODING = locale.getpreferredencoding()\r\n\r\n\r\ndef convert_to_ascii(s):\r\n    \"\"\"\r\n    Encode text items for system locale. If encoding fails, fall back to ASCII.\r\n    \"\"\"\r\n    try:\r\n        return s.encode(LOCALE_ENCODING, 'ignore')\r\n    except (AttributeError, UnicodeDecodeError):\r\n        return s.decode('ascii', 'ignore').encode(LOCALE_ENCODING)\r\n\r\nLPFN_WNDPROC = ctypes.CFUNCTYPE(LRESULT, HANDLE, ctypes.c_uint, WPARAM, LPARAM)\r\nclass WNDCLASS(ctypes.Structure):\r\n    _fields_ = [(\"style\", ctypes.c_uint),\r\n                (\"lpfnWndProc\", LPFN_WNDPROC),\r\n                (\"cbClsExtra\", ctypes.c_int),\r\n                (\"cbWndExtra\", ctypes.c_int),\r\n                (\"hInstance\", HANDLE),\r\n                (\"hIcon\", HANDLE),\r\n                (\"hCursor\", HANDLE),\r\n                (\"hbrBackground\", HANDLE),\r\n                (\"lpszMenuName\", ctypes.c_char_p),\r\n                (\"lpszClassName\", ctypes.c_char_p),\r\n               ]\r\n\r\nclass POINT(ctypes.Structure):\r\n    _fields_ = [('x', ctypes.c_long), ('y', ctypes.c_long)]\r\n\r\nclass RECT(ctypes.Structure):\r\n    _fields_ = [('left', ctypes.c_long), ('top', ctypes.c_long),\r\n                ('right', ctypes.c_long), ('bottom', ctypes.c_long)]\r\n\r\nclass MENUITEMINFO(ctypes.Structure):\r\n    _fields_ = [(\"cbSize\", ctypes.c_uint),\r\n                (\"fMask\", ctypes.c_uint),\r\n                (\"fType\", ctypes.c_uint),\r\n                (\"fState\", ctypes.c_uint),\r\n                (\"wID\", ctypes.c_uint),\r\n                (\"hSubMenu\", HANDLE),\r\n                (\"hbmpChecked\", HANDLE),\r\n                (\"hbmpUnchecked\", HANDLE),\r\n                (\"dwItemData\", ctypes.c_void_p),\r\n                (\"dwTypeData\", ctypes.c_char_p),\r\n                (\"cch\", ctypes.c_uint),\r\n                (\"hbmpItem\", HANDLE),\r\n               ]\r\n\r\nclass MSG(ctypes.Structure):\r\n    _fields_ = [(\"hwnd\", HANDLE),\r\n                (\"message\", ctypes.c_uint),\r\n                (\"wParam\", WPARAM),\r\n                (\"lParam\", LPARAM),\r\n                (\"time\", ctypes.c_ulong),\r\n                (\"pt\", POINT),\r\n               ]\r\n\r\nclass NOTIFYICONDATA(ctypes.Structure):\r\n    _fields_ = [(\"cbSize\", ctypes.c_uint),\r\n                (\"hWnd\", HANDLE),\r\n                (\"uID\", ctypes.c_uint),\r\n                (\"uFlags\", ctypes.c_uint),\r\n                (\"uCallbackMessage\", ctypes.c_uint),\r\n                (\"hIcon\", HANDLE),\r\n                (\"szTip\", ctypes.c_char * 64),\r\n                (\"dwState\", ctypes.c_uint),\r\n                (\"dwStateMask\", ctypes.c_uint),\r\n                (\"szInfo\", ctypes.c_char * 256),\r\n                (\"uTimeout\", ctypes.c_uint),\r\n                (\"szInfoTitle\", ctypes.c_char * 64),\r\n                (\"dwInfoFlags\", ctypes.c_uint),\r\n                (\"guidItem\", ctypes.c_char * 16),\r\n                (\"hBalloonIcon\", HANDLE),\r\n               ]\r\n\r\ndef PackMENUITEMINFO(text=None, hbmpItem=None, wID=None, hSubMenu=None, fState=fState.MFS_ENABLED):\r\n    res = MENUITEMINFO()\r\n    res.cbSize = ctypes.sizeof(res)\r\n    res.fMask = 1\r\n\r\n\r\n    res.fState  = fState\r\n    if hbmpItem is not None:\r\n        res.fMask |= MIIM_BITMAP\r\n        res.hbmpItem = hbmpItem\r\n    if wID is not None:\r\n        res.fMask |= MIIM_ID\r\n        res.wID = wID\r\n    if text is not None:\r\n        text = convert_to_ascii(text)\r\n        res.fMask |= MIIM_STRING\r\n        res.dwTypeData = text\r\n    if hSubMenu is not None:\r\n        res.fMask |= MIIM_SUBMENU\r\n        res.hSubMenu = hSubMenu\r\n    return res\r\n\r\ndef LOWORD(w):\r\n    return w & 0xFFFF\r\n\r\ndef PumpMessages():\r\n    msg = MSG()\r\n    while GetMessage(ctypes.byref(msg), None, 0, 0) > 0:\r\n        TranslateMessage(ctypes.byref(msg))\r\n        DispatchMessage(ctypes.byref(msg))\r\n\r\ndef NotifyData(hWnd=0, uID=0, uFlags=0, uCallbackMessage=0, hIcon=0, szTip=\"\"):\r\n    szTip = convert_to_ascii(szTip)\r\n    res = NOTIFYICONDATA()\r\n    res.cbSize = ctypes.sizeof(res)\r\n    res.hWnd = hWnd\r\n    res.uID = uID\r\n    res.uFlags = uFlags\r\n    res.uCallbackMessage = uCallbackMessage\r\n    res.hIcon = hIcon\r\n    res.szTip = szTip\r\n    return res\r\n"
  },
  {
    "path": "code/default/lib/win32/win32_proxy_manager.py",
    "content": "import winreg as winreg\nfrom ctypes import *\nfrom ctypes.wintypes import *\n\nLPWSTR = POINTER(WCHAR)\nHINTERNET = LPVOID\n\nINTERNET_OPTION_REFRESH = 37\nINTERNET_OPTION_SETTINGS_CHANGED = 39\nINTERNET_OPTION_PER_CONNECTION_OPTION = 75\nINTERNET_PER_CONN_FLAGS = 1\nINTERNET_PER_CONN_PROXY_SERVER = 2\nINTERNET_PER_CONN_PROXY_BYPASS = 3\nINTERNET_PER_CONN_AUTOCONFIG_URL = 4\nINTERNET_PER_CONN_AUTODISCOVERY_FLAGS = 5\n\nPROXY_TYPE_DIRECT = 1\nPROXY_TYPE_PROXY = 2\nPROXY_TYPE_AUTO_PROXY_URL = 4\n\nCONN_PATH = r'Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Connections'\nCONNECTIONS = winreg.OpenKey(winreg.HKEY_CURRENT_USER, CONN_PATH, 0, winreg.KEY_QUERY_VALUE)\n\nclass INTERNET_PER_CONN_OPTION(Structure):\n    class Value(Union):\n        _fields_ = [\n            ('dwValue', DWORD),\n            ('pszValue', LPWSTR),\n            ('ftValue', FILETIME),\n        ]\n\n    _fields_ = [\n        ('dwOption', DWORD),\n        ('Value', Value),\n    ]\n\nclass INTERNET_PER_CONN_OPTION_LIST(Structure):\n    _fields_ = [\n        ('dwSize', DWORD),\n        ('pszConnection', LPWSTR),\n        ('dwOptionCount', DWORD),\n        ('dwOptionError', DWORD),\n        ('pOptions', POINTER(INTERNET_PER_CONN_OPTION)),\n    ]\n\nInternetSetOption = windll.wininet.InternetSetOptionW\nInternetSetOption.argtypes = [HINTERNET, DWORD, LPVOID, DWORD]\nInternetSetOption.restype  = BOOL\n\ndef disable_proxy():\n    _,values_num,_ = winreg.QueryInfoKey(CONNECTIONS)\n    for i in range(0, values_num):\n        try:\n            key, value,_ = winreg.EnumValue(CONNECTIONS, i)\n        except:\n            break\n\n        List = INTERNET_PER_CONN_OPTION_LIST()\n        Option = (INTERNET_PER_CONN_OPTION * 1)()\n        nSize = c_ulong(sizeof(INTERNET_PER_CONN_OPTION_LIST))\n\n        Option[0].dwOption = INTERNET_PER_CONN_FLAGS\n        Option[0].Value.dwValue = PROXY_TYPE_DIRECT\n\n        List.dwSize = sizeof(INTERNET_PER_CONN_OPTION_LIST)\n        List.pszConnection = create_unicode_buffer(key)\n        List.dwOptionCount = 1\n        List.dwOptionError = 0\n        List.pOptions = Option\n\n        InternetSetOption(None, INTERNET_OPTION_PER_CONNECTION_OPTION, byref(List), nSize)\n\n    InternetSetOption(None, INTERNET_OPTION_SETTINGS_CHANGED, None, 0)\n    InternetSetOption(None, INTERNET_OPTION_REFRESH, None, 0)\n\ndef set_proxy_auto(proxy_addr, conn_name='DefaultConnectionSettings'):\n    setting = create_unicode_buffer(proxy_addr)\n\n    List = INTERNET_PER_CONN_OPTION_LIST()\n    Option = (INTERNET_PER_CONN_OPTION * 3)()\n    nSize = c_ulong(sizeof(INTERNET_PER_CONN_OPTION_LIST))\n\n    Option[0].dwOption = INTERNET_PER_CONN_FLAGS\n    Option[0].Value.dwValue = PROXY_TYPE_DIRECT | PROXY_TYPE_AUTO_PROXY_URL\n    Option[1].dwOption = INTERNET_PER_CONN_AUTOCONFIG_URL\n    Option[1].Value.pszValue = setting\n    Option[2].dwOption = INTERNET_PER_CONN_PROXY_BYPASS\n    Option[2].Value.pszValue = create_unicode_buffer(\"localhost;127.*;10.*;172.16.*;172.17.*;172.18.*;172.19.*;172.20.*;172.21.*;172.22.*;172.23.*;172.24.*;172.25.*;172.26.*;172.27.*;172.28.*;172.29.*;172.30.*;172.31.*;172.32.*;192.168.*\")\n\n    List.dwSize = sizeof(INTERNET_PER_CONN_OPTION_LIST)\n    List.pszConnection = create_unicode_buffer(conn_name)\n    List.dwOptionCount = 3\n    List.dwOptionError = 0\n    List.pOptions = Option\n\n    InternetSetOption(None, INTERNET_OPTION_PER_CONNECTION_OPTION, byref(List), nSize)\n    InternetSetOption(None, INTERNET_OPTION_SETTINGS_CHANGED, None, 0)\n    InternetSetOption(None, INTERNET_OPTION_REFRESH, None, 0)\n\ndef set_proxy_server(proxy_addr, conn_name='DefaultConnectionSettings'):\n    setting = create_unicode_buffer(proxy_addr)\n\n    List = INTERNET_PER_CONN_OPTION_LIST()\n    Option = (INTERNET_PER_CONN_OPTION * 3)()\n    nSize = c_ulong(sizeof(INTERNET_PER_CONN_OPTION_LIST))\n\n    Option[0].dwOption = INTERNET_PER_CONN_FLAGS\n    Option[0].Value.dwValue = PROXY_TYPE_DIRECT | PROXY_TYPE_PROXY\n    Option[1].dwOption = INTERNET_PER_CONN_PROXY_SERVER\n    Option[1].Value.pszValue = setting\n    Option[2].dwOption = INTERNET_PER_CONN_PROXY_BYPASS\n    Option[2].Value.pszValue = create_unicode_buffer(\"localhost;127.*;10.*;172.16.*;172.17.*;172.18.*;172.19.*;172.20.*;172.21.*;172.22.*;172.23.*;172.24.*;172.25.*;172.26.*;172.27.*;172.28.*;172.29.*;172.30.*;172.31.*;172.32.*;192.168.*\")\n\n    List.dwSize = sizeof(INTERNET_PER_CONN_OPTION_LIST)\n    List.pszConnection = create_unicode_buffer(conn_name)\n    List.dwOptionCount = 3\n    List.dwOptionError = 0\n    List.pOptions = Option\n\n    InternetSetOption(None, INTERNET_OPTION_PER_CONNECTION_OPTION, byref(List), nSize)\n    InternetSetOption(None, INTERNET_OPTION_SETTINGS_CHANGED, None, 0)\n    InternetSetOption(None, INTERNET_OPTION_REFRESH, None, 0)\n\ndef set_proxy(proxy_addr):\n    _,values_num,_ = winreg.QueryInfoKey(CONNECTIONS)\n    if values_num:\n        for i in range(0, values_num):\n            try:\n                key,value,_ = winreg.EnumValue(CONNECTIONS, i)\n            except:\n                break\n\n            if '://' in proxy_addr:\n                set_proxy_auto(proxy_addr, key)\n            else:\n                set_proxy_server(proxy_addr, key)\n\nif __name__ == \"__main__\":\n    set_proxy(\"127.0.0.1:8087\")\n"
  },
  {
    "path": "code/default/lib/win32/win32elevate.py",
    "content": "'''\nCopyright (c) 2013 by JustAMan at GitHub\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\nThis file provides the ability to re-elevate the rights of running Python script to\nAdministrative ones allowing console of elevated process to remain user-interactive.\nYou should use elevateAdminRights() at the very possible start point of your scripts because\nit will re-launch your script from the very beginning.\n'''\n\nimport os\nimport sys\nimport subprocess\n\nimport ctypes\nfrom ctypes.wintypes import HANDLE, BOOL, DWORD, HWND, HINSTANCE, HKEY\nfrom ctypes import c_ulong, c_char_p, c_int, c_void_p\n\nimport utils\n\nPHANDLE = ctypes.POINTER(HANDLE)\nPDWORD = ctypes.POINTER(DWORD)\n\nGetCurrentProcess = ctypes.windll.kernel32.GetCurrentProcess\nGetCurrentProcess.argtypes = ()\nGetCurrentProcess.restype = HANDLE\n\nOpenProcessToken = ctypes.windll.kernel32.OpenProcessToken\nOpenProcessToken.argtypes = (HANDLE, DWORD, PHANDLE)\nOpenProcessToken.restype = BOOL\n\nCloseHandle = ctypes.windll.kernel32.CloseHandle\nCloseHandle.argtypes = (HANDLE, )\nCloseHandle.restype = BOOL\n\nGetTokenInformation = ctypes.windll.Advapi32.GetTokenInformation\nGetTokenInformation.argtypes = (HANDLE, ctypes.c_int, ctypes.c_void_p, DWORD, PDWORD)\nGetTokenInformation.restype = BOOL\n\nTOKEN_READ = 0x20008\nTokenElevation = 0x14\n\n\nclass ShellExecuteInfo(ctypes.Structure):\n    _fields_ = [('cbSize', DWORD),\n                ('fMask', c_ulong),\n                ('hwnd', HWND),\n                ('lpVerb', c_char_p),\n                ('lpFile', c_char_p),\n                ('lpParameters', c_char_p),\n                ('lpDirectory', c_char_p),\n                ('nShow', c_int),\n                ('hInstApp', HINSTANCE),\n                ('lpIDList', c_void_p),\n                ('lpClass', c_char_p),\n                ('hKeyClass', HKEY),\n                ('dwHotKey', DWORD),\n                ('hIcon', HANDLE),\n                ('hProcess', HANDLE)]\n\n    def __init__(self, **kw):\n        ctypes.Structure.__init__(self)\n        self.cbSize = ctypes.sizeof(self)\n        for fieldName, fieldValue in kw.items():\n            if isinstance(fieldValue, str):\n                fieldValue = utils.to_bytes(fieldValue)\n            setattr(self, fieldName, fieldValue)\n\n\nPShellExecuteInfo = ctypes.POINTER(ShellExecuteInfo)\n\nShellExecuteEx = ctypes.windll.Shell32.ShellExecuteExA\nShellExecuteEx.argtypes = (PShellExecuteInfo, )\nShellExecuteEx.restype = BOOL\n\nWaitForSingleObject = ctypes.windll.kernel32.WaitForSingleObject\nWaitForSingleObject.argtypes = (HANDLE, DWORD)\nWaitForSingleObject.restype = DWORD\n\nSW_HIDE = 0\nSW_SHOW = 5\nSEE_MASK_NOCLOSEPROCESS = 0x00000040\nINFINITE = -1\n\nELEVATE_MARKER = 'win32elevate_marker_parameter'\n\nFreeConsole = ctypes.windll.kernel32.FreeConsole\nFreeConsole.argtypes = ()\nFreeConsole.restype = BOOL\n\nAttachConsole = ctypes.windll.kernel32.AttachConsole\nAttachConsole.argtypes = (DWORD, )\nAttachConsole.restype = BOOL\n\nATTACH_PARENT_PROCESS = -1\n\nsysargv = [os.path.abspath(sys.argv[0])] + sys.argv[1:]\n\ndef areAdminRightsElevated():\n    '''\n    Tells you whether current script already has Administrative rights.\n    '''\n    pid = GetCurrentProcess()\n    processToken = HANDLE()\n    if not OpenProcessToken(pid, TOKEN_READ, ctypes.byref(processToken)):\n        raise ctypes.WinError()\n    try:\n        elevated, elevatedSize = DWORD(), DWORD()\n        if not GetTokenInformation(processToken, TokenElevation, ctypes.byref(elevated),\n                                   ctypes.sizeof(elevated), ctypes.byref(elevatedSize)):\n            raise ctypes.WinError()\n        return bool(elevated)\n    finally:\n        CloseHandle(processToken)\n\ndef waitAndCloseHandle(processHandle):\n    '''\n    Waits till spawned process finishes and closes the handle for it\n    '''\n    WaitForSingleObject(processHandle, INFINITE)\n    CloseHandle(processHandle)\n\ndef elevateAdminRights(waitAndClose=True, reattachConsole=True):\n    '''\n    This will re-run current Python script requesting to elevate administrative rights.\n    If waitAndClose is True the process that called elevateAdminRights() will wait till elevated\n    process exits and then will quit.\n    If waitAndClose is False this function returns None for elevated process and process handle\n    for parent process (like POSIX os.fork).\n    If reattachConsole is False console of elevated process won't be attached to parent process\n    so you won't see any output of it.\n    '''\n    if not areAdminRightsElevated():\n        # this is host process that doesn't have administrative rights\n        params = subprocess.list2cmdline(sysargv + [ELEVATE_MARKER])\n        executeInfo = ShellExecuteInfo(fMask=SEE_MASK_NOCLOSEPROCESS, hwnd=None, lpVerb='runas',\n                                       lpFile=sys.executable, lpParameters=params,\n                                       lpDirectory=None,\n                                       nShow=SW_HIDE if reattachConsole else SW_SHOW)\n        if reattachConsole and not all(stream.isatty() for stream in (sys.stdin, sys.stdout,\n                                                                      sys.stderr)):\n            # TODO: some streams were redirected, we need to manually work them\n            # currently just raise an exception\n            raise NotImplementedError(\"win32elevate doesn't support elevating scripts with \"\n                                      \"redirected input or output\")\n\n        if not ShellExecuteEx(ctypes.byref(executeInfo)):\n            raise ctypes.WinError()\n        if waitAndClose:\n            waitAndCloseHandle(executeInfo.hProcess)\n            sys.exit(0)\n        else:\n            return executeInfo.hProcess\n    else:\n        # This is elevated process, either it is launched by host process or user manually\n        # elevated the rights for this script. We check it by examining last parameter\n        if sys.argv[-1] == ELEVATE_MARKER:\n            # this is script-elevated process, remove the marker\n            del sys.argv[-1]\n            if reattachConsole:\n                # Now attach our elevated console to parent's console.\n                # first we free our own console\n                if not FreeConsole():\n                    raise ctypes.WinError()\n                # then we attach to parent process console\n                if not AttachConsole(ATTACH_PARENT_PROCESS):\n                    raise ctypes.WinError()\n\n        # indicate we're already running with administrative rights, see docstring\n        return None\n\ndef elevateAdminRun(args=sysargv, executable=sys.executable,\n                    waitAndClose=False, reattachConsole=True):\n    if (waitAndClose or\n        reattachConsole and\n        not all(stream.isatty() for stream in (sys.stdin, sys.stdout,sys.stderr))):\n        # Don't attached to parent process when waitAndClose is \"True\"\n        # TODO: some streams were redirected, we need to manually work them\n        # currently just don't attached to parent process\n        reattachConsole = False\n    if args is not None and not isinstance(args, bytes):\n        args = subprocess.list2cmdline(args)\n    executeInfo = ShellExecuteInfo(fMask=SEE_MASK_NOCLOSEPROCESS, hwnd=None,\n                                   lpVerb='' if areAdminRightsElevated() else b'runas',\n                                   lpFile=executable, lpParameters=args,\n                                   lpDirectory=None,\n                                   nShow=SW_HIDE if reattachConsole else SW_SHOW)\n\n    if not ShellExecuteEx(ctypes.byref(executeInfo)):\n        raise ctypes.WinError()\n    if waitAndClose:\n        waitAndCloseHandle(executeInfo.hProcess)\n    else:\n        return executeInfo.hProcess\n\nif __name__ == '__main__':\n    elevateAdminRights(reattachConsole=False)\n    sys.exit(1)"
  },
  {
    "path": "code/default/lib/win32/win_inet_pton.py",
    "content": "# This software released into the public domain. Anyone is free to copy,\n# modify, publish, use, compile, sell, or distribute this software,\n# either in source code form or as a compiled binary, for any purpose,\n# commercial or non-commercial, and by any means.\n\nimport socket\nimport ctypes\nimport os\n\nimport utils\n\nclass sockaddr(ctypes.Structure):\n    _fields_ = [(\"sa_family\", ctypes.c_short),\n                (\"__pad1\", ctypes.c_ushort),\n                (\"ipv4_addr\", ctypes.c_byte * 4),\n                (\"ipv6_addr\", ctypes.c_byte * 16),\n                (\"__pad2\", ctypes.c_ulong)]\n\nif hasattr(ctypes, 'windll'):\n    WSAStringToAddressA = ctypes.windll.ws2_32.WSAStringToAddressA\n    WSAAddressToStringA = ctypes.windll.ws2_32.WSAAddressToStringA\nelse:\n    def not_windows():\n        raise SystemError(\n            \"Invalid platform. ctypes.windll must be available.\"\n        )\n    WSAStringToAddressA = not_windows\n    WSAAddressToStringA = not_windows\n\n\ndef inet_pton(address_family, ip_string):\n    addr = sockaddr()\n    addr.sa_family = address_family\n    addr_size = ctypes.c_int(ctypes.sizeof(addr))\n\n    ip_string = utils.to_bytes(ip_string)\n\n    if WSAStringToAddressA(\n            ip_string,\n            address_family,\n            None,\n            ctypes.byref(addr),\n            ctypes.byref(addr_size)\n    ) != 0:\n        raise socket.error(ctypes.FormatError())\n\n    if address_family == socket.AF_INET:\n        return ctypes.string_at(addr.ipv4_addr, 4)\n    if address_family == socket.AF_INET6:\n        return ctypes.string_at(addr.ipv6_addr, 16)\n\n    raise socket.error('unknown address family')\n\n\ndef inet_ntop(address_family, packed_ip):\n    addr = sockaddr()\n    addr.sa_family = address_family\n    addr_size = ctypes.c_int(ctypes.sizeof(addr))\n    ip_string = ctypes.create_string_buffer(128)\n    ip_string_size = ctypes.c_int(ctypes.sizeof(ip_string))\n\n    if address_family == socket.AF_INET:\n        if len(packed_ip) != ctypes.sizeof(addr.ipv4_addr):\n            raise socket.error('packed IP wrong length for inet_ntoa')\n        ctypes.memmove(addr.ipv4_addr, packed_ip, 4)\n    elif address_family == socket.AF_INET6:\n        if len(packed_ip) != ctypes.sizeof(addr.ipv6_addr):\n            raise socket.error('packed IP wrong length for inet_ntoa')\n        ctypes.memmove(addr.ipv6_addr, packed_ip, 16)\n    else:\n        raise socket.error('unknown address family')\n\n    if WSAAddressToStringA(\n            ctypes.byref(addr),\n            addr_size,\n            None,\n            ip_string,\n            ctypes.byref(ip_string_size)\n    ) != 0:\n        raise socket.error(ctypes.FormatError())\n\n    return ip_string[:ip_string_size.value - 1]\n\n# Adding our two functions to the socket library\nif os.name == 'nt':\n    socket.inet_pton = inet_pton\n    socket.inet_ntop = inet_ntop\n"
  },
  {
    "path": "code/default/smart_router/README.md",
    "content": "\n\n\nHow to make linux allow non-root user listen on 53 port:\n`sudo setcap 'cap_net_bind_service=+ep' /usr/bin/python3.7`\n\nNotice:\nsetcap is in the debian package libcap2-bin\nat least a 2.6.24 kernel\n\n\n\n\n"
  },
  {
    "path": "code/default/smart_router/__init__.py",
    "content": "__all__ = [\"local\"]"
  },
  {
    "path": "code/default/smart_router/babel.config",
    "content": "# Extraction from Python source files\n#[python: **.py]\n\n# Extraction from HTML and YAML templates\n[jinja2: **/web_ui/**.html]\n[jinja2: **/web_ui/**.yaml]\n\nencoding = utf-8\n"
  },
  {
    "path": "code/default/smart_router/lang/fa_IR/LC_MESSAGES/messages.po",
    "content": "\nmsgid \"General\"\nmsgstr \"عمومی\"\n\nmsgid \"Rules\"\nmsgstr \"قاعده\"\n\nmsgid \"Cache\"\nmsgstr \"مخازن\"\n\nmsgid \"Smart Router Configuration\"\nmsgstr \"پیکربندی روتر هوشمند\"\n\nmsgid \"Clean Cache\"\nmsgstr \"حافظه پنهان\"\n\nmsgid \"Domain Cache\"\nmsgstr \"حافظه نهان\"\n\nmsgid \"IP Cache\"\nmsgstr \"حافظه نهان\"\n\nmsgid \"Clean Cache successfully.\"\nmsgstr \"حافظه پنهان را با موفقیت تمیز کنید.\"\n\nmsgid \"Country\"\nmsgstr \"کشور\"\n\nmsgid \"China\"\nmsgstr \"چین\"\n\nmsgid \"Other\"\nmsgstr \"دیگر\"\n\nmsgid \"Route Policy\"\nmsgstr \"خط مشی مسیر\"\n\nmsgid \"Black->GAEProxy\"\nmsgstr \"سیاه-> gaeproxy\"\n\nmsgid \"Black->X-Tunnel\"\nmsgstr \"سیاه-> x-tunnel\"\n\nmsgid \"All Smart-Router\"\nmsgstr \"همه روتر هوشمند\"\n\nmsgid \"All->X-Tunnel\"\nmsgstr \"All-> X-Tunnel\"\n\nmsgid \"Auto-Try Direct\"\nmsgstr \"کارگردانی مستقیم\"\n\nmsgid \"Use IPv6 preferentially when Auto-Try Direct\"\nmsgstr \"هنگام مستقیم کار خودکار از IPv6 استفاده کنید\"\n\nmsgid \"Auto-Try GAEProxy\"\nmsgstr \"گای پروکسی\"\n\nmsgid \"Enable Fake CA\"\nmsgstr \"CA جعلی را فعال کنید\"\n\nmsgid \"Block Advertisement\"\nmsgstr \"تبلیغات مسدود\"\n\nmsgid \"Settings saved successfully.\"\nmsgstr \"تنظیمات با موفقیت ذخیره شد.\"\n\nmsgid \"https://github.com/XX-net/XX-Net/wiki/SmartRouter_rules_en\"\nmsgstr \"\"\n\nmsgid \"Help documents\"\nmsgstr \"به اسناد کمک کنید\"\n\nmsgid \"Direct List\"\nmsgstr \"لیست مستقیم\"\n\nmsgid \"GAEProxy List\"\nmsgstr \"لیست\"\n\nmsgid \"X-Tunnel List\"\nmsgstr \"لیست تونل ایکس\"\n\nmsgid \"Redirect HTTPS\"\nmsgstr \"تغییر مسیر HTTPS\"\n\nmsgid \"Advertisement Black List\"\nmsgstr \"لیست سیاه تبلیغات\"\n\nmsgid \"Submit\"\nmsgstr \"ارسال\"\n\nmsgid \"Smart Router Log\"\nmsgstr \"ورود به سیستم روتر هوشمند\"\n\nmsgid \"Log\"\nmsgstr \"ورود به سیستم\"\n\nmsgid \"Configuration\"\nmsgstr \"پیکربندی\"\n\nmsgid \"Smart Router\"\nmsgstr \"روتر هوشمند\"\n"
  },
  {
    "path": "code/default/smart_router/lang/ru_RU/LC_MESSAGES/messages.po",
    "content": "#\nmsgid \"\"\nmsgstr \"\"\n\nmsgid \"General\"\nmsgstr \"Общий\"\n\nmsgid \"Rules\"\nmsgstr \"Правила\"\n\nmsgid \"Cache\"\nmsgstr \"Кеш\"\n\nmsgid \"Smart Router Configuration\"\nmsgstr \"Умный маршрутизатор конфигурация\"\n\nmsgid \"Clean Cache\"\nmsgstr \"Чистый кеш\"\n\nmsgid \"Domain Cache\"\nmsgstr \"Доменный кеш\"\n\nmsgid \"IP Cache\"\nmsgstr \"Ip cache\"\n\nmsgid \"Clean Cache successfully.\"\nmsgstr \"Чистый кэш успешно.\"\n\nmsgid \"Country\"\nmsgstr \"Страна\"\n\nmsgid \"China\"\nmsgstr \"Китай\"\n\nmsgid \"Other\"\nmsgstr \"Другой\"\n\nmsgid \"Route Policy\"\nmsgstr \"Политика маршрута\"\n\nmsgid \"Black->GAEProxy\"\nmsgstr \"Black-> GaeProxy\"\n\nmsgid \"Black->X-Tunnel\"\nmsgstr \"Черный-> X-Tunnel\"\n\nmsgid \"All Smart-Router\"\nmsgstr \"Весь интеллектуальный маршрут\"\n\nmsgid \"All->X-Tunnel\"\nmsgstr \"All-> X-Tunnel\"\n\nmsgid \"Auto-Try Direct\"\nmsgstr \"Auto-Cetr Direct\"\n\nmsgid \"Use IPv6 preferentially when Auto-Try Direct\"\nmsgstr \"Используйте IPv6 преимущественно, когда Auto-Ctry Direct\"\n\nmsgid \"Auto-Try GAEProxy\"\nmsgstr \"Auto-tore GaeProxy\"\n\nmsgid \"Enable Fake CA\"\nmsgstr \"Включить поддельный ок\"\n\nmsgid \"Block Advertisement\"\nmsgstr \"Блок рекламы\"\n\nmsgid \"Settings saved successfully.\"\nmsgstr \"Настройки успешно сохранились.\"\n\nmsgid \"https://github.com/XX-net/XX-Net/wiki/SmartRouter_rules_en\"\nmsgstr \"\"\n\nmsgid \"Help documents\"\nmsgstr \"Помогите документы\"\n\nmsgid \"Direct List\"\nmsgstr \"Прямой список\"\n\nmsgid \"GAEProxy List\"\nmsgstr \"Список GaeProxy\"\n\nmsgid \"X-Tunnel List\"\nmsgstr \"Список X-Tunnel\"\n\nmsgid \"Redirect HTTPS\"\nmsgstr \"Перенаправить https\"\n\nmsgid \"Advertisement Black List\"\nmsgstr \"Реклама черного списка\"\n\nmsgid \"Submit\"\nmsgstr \"Представлять на рассмотрение\"\n\nmsgid \"Smart Router Log\"\nmsgstr \"Умный маршрутизатор журнал\"\n\nmsgid \"Log\"\nmsgstr \"Бревно\"\n\nmsgid \"Configuration\"\nmsgstr \"Конфигурация\"\n\nmsgid \"Smart Router\"\nmsgstr \"Умный маршрутизатор\"\n"
  },
  {
    "path": "code/default/smart_router/lang/zh_CN/LC_MESSAGES/messages.po",
    "content": "\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: PROJECT VERSION\\n\"\n\"Report-Msgid-Bugs-To: xxnet.dev@gmail.com\\n\"\n\"POT-Creation-Date: 2022-03-01 03:45-0500\\n\"\n\"PO-Revision-Date: 2017-12-29 12:00+0800\\n\"\n\"Last-Translator: Emphasia@github\\n\"\n\"Language: zh_Hans_CN\\n\"\n\"Language-Team: zh_Hans_CN <LL@li.org>\\n\"\n\"Plural-Forms: nplurals=2; plural=(n != 1)\\n\"\n\"MIME-Version: 1.0\\n\"\n\"Content-Type: text/plain; charset=utf-8\\n\"\n\"Content-Transfer-Encoding: 8bit\\n\"\n\"Generated-By: Babel 2.9.1\\n\"\n\nmsgid \"General\"\nmsgstr \"通用\"\n\nmsgid \"Rules\"\nmsgstr \"规则\"\n\nmsgid \"Cache\"\nmsgstr \"缓存\"\n\nmsgid \"Smart Router Configuration\"\nmsgstr \"Smart Router 配置\"\n\nmsgid \"Clean Cache\"\nmsgstr \"清空缓存\"\n\nmsgid \"Domain Cache\"\nmsgstr \"域名缓存\"\n\nmsgid \"IP Cache\"\nmsgstr \"IP缓存\"\n\nmsgid \"Clean Cache successfully.\"\nmsgstr \"成功清空缓存。\"\n\nmsgid \"Country\"\nmsgstr \"国家\"\n\nmsgid \"China\"\nmsgstr \"中国\"\n\nmsgid \"Other\"\nmsgstr \"其他\"\n\nmsgid \"Route Policy\"\nmsgstr \"路由策略\"\n\nmsgid \"Black->GAEProxy\"\nmsgstr \"黑名单->GAEProxy\"\n\nmsgid \"Black->X-Tunnel\"\nmsgstr \"黑名单->X-Tunnel\"\n\nmsgid \"All Smart-Router\"\nmsgstr \"全部->Smart-Router\"\n\nmsgid \"All->X-Tunnel\"\nmsgstr \"全部->X-Tunnel\"\n\nmsgid \"Auto-Try Direct\"\nmsgstr \"自动尝试直连\"\n\nmsgid \"Use IPv6 preferentially when Auto-Try Direct\"\nmsgstr \"自动尝试直连时优先使用 IPv6\"\n\nmsgid \"Auto-Try GAEProxy\"\nmsgstr \"自动尝试 GAEProxy\"\n\nmsgid \"Enable Fake CA\"\nmsgstr \"允许替换证书\"\n\nmsgid \"Block Advertisement\"\nmsgstr \"阻止广告\"\n\nmsgid \"Settings saved successfully.\"\nmsgstr \"设置保存成功。\"\n\nmsgid \"https://github.com/XX-net/XX-Net/wiki/SmartRouter_rules_en\"\nmsgstr \"https://github.com/XX-net/XX-Net/wiki/SmartRouter_rules_cn\"\n\nmsgid \"Help documents\"\nmsgstr \"帮助文档\"\n\nmsgid \"Direct List\"\nmsgstr \"直连\"\n\nmsgid \"GAEProxy List\"\nmsgstr \"走 GAE代理\"\n\nmsgid \"X-Tunnel List\"\nmsgstr \"走X-Tunnel\"\n\nmsgid \"Redirect HTTPS\"\nmsgstr \"重定向到 HTTPS\"\n\nmsgid \"Advertisement Black List\"\nmsgstr \"广告黑名单\"\n\nmsgid \"Submit\"\nmsgstr \"提交\"\n\nmsgid \"Smart Router Log\"\nmsgstr \"智能路由日志\"\n\nmsgid \"Log\"\nmsgstr \"日志\"\n\nmsgid \"Configuration\"\nmsgstr \"设置\"\n\nmsgid \"Smart Router\"\nmsgstr \"智能路由\"\n"
  },
  {
    "path": "code/default/smart_router/local/__init__.py",
    "content": "import os\nimport sys\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nlauncher_path = os.path.abspath( os.path.join(current_path, os.pardir, os.pardir, \"launcher\"))\n\nroot_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))\n\nimport env_info\ndata_path = os.path.join(env_info.data_path, \"smart_router\")\n\nif launcher_path not in sys.path:\n    sys.path.append(launcher_path)\n\n\nif not os.path.isdir(data_path):\n    os.mkdir(data_path)\n\nfrom xlog import getLogger\nxlog = getLogger(\"smart_router\", log_path=data_path, save_start_log=200, save_warning_log=True)\nxlog.set_buffer(100)\n\nimport xconfig\nimport simple_http_server\n\ntry:\n    from module_init import proc_handler\nexcept:\n    xlog.info(\"launcher not running\")\n    proc_handler = None\n\n\nfrom . import apis\nfrom . import global_var as g\nfrom . import dns_server\nfrom . import dns_query\nfrom . import host_records\nfrom . import user_rules\nfrom . import proxy_handler\nfrom . import web_control\nfrom . import connect_manager\nfrom . import pac_server\nfrom . import pipe_socks\nfrom . import ip_region\nfrom . import gfwlist\n\nready = False\n\n\ndef is_ready():\n    global ready\n    return ready\n\n\ndef load_config():\n    global g\n\n    config_path = os.path.join(data_path, 'config.json')\n    config = xconfig.Config(config_path)\n\n    config.set_var(\"PROXY_ENABLE\", 0)\n    config.set_var(\"PROXY_TYPE\", \"HTTP\")\n    config.set_var(\"PROXY_HOST\", \"\")\n    config.set_var(\"PROXY_PORT\", 0)\n    config.set_var(\"PROXY_USER\", \"\")\n    config.set_var(\"PROXY_PASSWD\", \"\")\n\n    config.set_var(\"dns_bind_ip\", \"127.0.0.1\")\n    config.set_var(\"dns_port\", 53)\n    config.set_var(\"dns_backup_port\", 8053)\n    config.set_var(\"udp_relay_port\", 8086)\n\n    config.set_var(\"proxy_bind_ip\", \"127.0.0.1\")\n    config.set_var(\"proxy_port\", 8086)\n\n    config.set_var(\"dns_cache_size\", 200)\n    config.set_var(\"pip_cache_size\", 32*1024)\n    config.set_var(\"ip_cache_size\", 1000)\n    config.set_var(\"dns_ttl\", 60*30)\n    config.set_var(\"direct_split_SNI\", 1)\n\n    config.set_var(\"pac_policy\", \"smart-router\")\n    config.set_var(\"country_code\", \"CN\")\n    config.set_var(\"auto_direct\", 1)\n    config.set_var(\"auto_direct6\", 0)\n    config.set_var(\"auto_gae\", 1)\n    config.set_var(\"enable_fake_ca\", 1)\n    config.set_var(\"bypass_speedtest\", 1)\n    config.set_var(\"block_advertisement\", 0)\n\n    config.set_var(\"log_debug\", 0)\n\n    config.load()\n    if config.PROXY_ENABLE:\n        xlog.info(\"use LAN proxy:%s://%s:%d/\", config.PROXY_TYPE,\n                  config.PROXY_HOST, config.PROXY_PORT)\n\n    g.config = config\n\n\ndef start(args):\n    global proc_handler, ready, g\n\n    if not proc_handler:\n        return False\n\n    if \"gae_proxy\" in proc_handler:\n        g.gae_proxy = proc_handler[\"gae_proxy\"][\"imp\"].local\n        g.gae_proxy_listen_port = g.gae_proxy.config.config.listen_port\n    else:\n        g.gae_proxy = None\n        xlog.debug(\"gae_proxy not running\")\n\n    if \"x_tunnel\" in proc_handler:\n        g.x_tunnel = proc_handler[\"x_tunnel\"][\"imp\"].local\n        g.x_tunnel_socks_port = g.x_tunnel.global_var.config.socks_port\n    else:\n        xlog.debug(\"x_tunnel not running\")\n\n    load_config()\n    g.gfwlist = gfwlist.GfwList()\n    g.ip_region = ip_region.IpRegion()\n\n    g.domain_cache = host_records.DomainRecords(os.path.join(data_path, \"domain_records.txt\"),\n                                                capacity=g.config.dns_cache_size, ttl=g.config.dns_ttl)\n    g.ip_cache = host_records.IpRecord(os.path.join(data_path, \"ip_records.txt\"),\n                                       capacity=g.config.ip_cache_size)\n\n    g.user_rules = user_rules.Config()\n\n    connect_manager.load_proxy_config()\n    g.connect_manager = connect_manager.ConnectManager()\n    g.pipe_socks = pipe_socks.PipeSocks(g.config.pip_cache_size)\n    g.pipe_socks.run()\n\n    allow_remote = args.get(\"allow_remote\", 0)\n\n    listen_ips = g.config.proxy_bind_ip\n    if isinstance(listen_ips, str):\n        listen_ips = [listen_ips]\n    else:\n        listen_ips = list(listen_ips)\n\n    if allow_remote and (\"0.0.0.0\" not in listen_ips or \"::\" not in listen_ips):\n        listen_ips = [(\"0.0.0.0\")]\n    addresses = [(listen_ip, g.config.proxy_port) for listen_ip in listen_ips]\n\n    g.proxy_server = simple_http_server.HTTPServer(addresses,\n                                                   proxy_handler.ProxyServer,\n                                                   logger=xlog,\n                                                   check_listen_interval=60)\n    g.proxy_server.start()\n    xlog.info(\"Proxy server listen:%s:%d.\", listen_ips, g.config.proxy_port)\n\n    listen_ips = g.config.dns_bind_ip\n    if isinstance(listen_ips, str):\n        listen_ips = [listen_ips]\n    else:\n        listen_ips = list(listen_ips)\n    if allow_remote and (\"0.0.0.0\" not in listen_ips or \"::\" not in listen_ips):\n        listen_ips.append(\"0.0.0.0\")\n\n    g.local_ips = dns_query.get_local_ips()\n    g.dns_query = dns_query.CombineDnsQuery()\n\n    g.dns_srv = dns_server.DnsServer(\n        bind_ip=listen_ips, port=g.config.dns_port,\n        backup_port=g.config.dns_backup_port,\n        ttl=g.config.dns_ttl)\n    g.dns_srv.start()\n    xlog.debug(\"DNS server port %d\", g.dns_srv.listen_port)\n\n    ready = True\n\n\ndef stop():\n    global ready\n\n    g.domain_cache.save(True)\n    g.ip_cache.save(True)\n\n    g.connect_manager.stop()\n    g.pipe_socks.stop()\n    g.dns_query.stop()\n\n    g.dns_srv.stop()\n    g.proxy_server.shutdown()\n    ready = False\n"
  },
  {
    "path": "code/default/smart_router/local/advertisement_list.txt",
    "content": "51.la\naduu.cn\nduomeng\nwaps.cn\noadz.com\nadwo.com\nimmob.cn\ntanx.com\nyoumi.net\nadjust.io\nacs86.com\nmsg.71.am\nkejet.net\nadnxs.com\nadcome.cn\nadview.cn\nintely.cn\nadxmi.com\nwiyun.com\nirs01.com\nadjust.com\nunion.6.cn\nallyes.com\nguomob.com\nmmstat.com\nadzerk.net\nunimhk.com\n892155.com\np.l.qq.com\nfa.163.com\nsimba.6.cn\noptaim.com\ng1.163.com\ninmobi.com\nanquan.org\nmediav.com\nuyunad.com\ncmcore.com\nappads.com\nshrek.6.cn\nadchina.com\ndc.letv.com\nipinyou.com\ns.mgwcn.com\nclickzs.com\nsd.domob.cn\nsax.sina.cn\nadsmogo.org\nunlitui.com\nmobclix.com\nreachmax.cn\ng.uusee.com\nadwhirl.com\nguohead.com\nvamaker.com\ns.xnjpg.com\nwrating.com\nsegment.com\npv.sohu.com\n99click.com\nmadmini.com\natm.sina.com\nuc.biquge.cc\nhm.baidu.com\nla.fsjsp.com\nst.vq.ku6.cn\nark.letv.com\nzhiziyun.com\nsmartmad.com\nadinfuse.com\nafp.qiyi.com\nimg1.126.net\noptimix.asia\nnumber1cp.cn\nbobo.163.com\nmiaozhen.com\nfounseezb.cn\nn-st.vip.com\napplovin.com\nwqmobile.com\nrtb.behe.com\nbiddingx.com\nrcd.iqiyi.com\nadgeo.163.com\nt11.baidu.com\napplifier.com\nmtj.baidu.com\nr.l.youku.com\np.l.youku.com\nbiz.weibo.com\natm.youku.com\nistage.com.cn\nwooboo.com.cn\np.l.ykimg.com\nsitemeter.com\ntaiyuanjiu.cn\nresponsys.net\nt12.baidu.com\npop.uusee.com\nt10.baidu.com\nic.snssdk.com\nads.yahoo.com\npos.baidu.com\nres.limei.com\ngame.weibo.cn\nde.as.pptv.com\ncbjs.baidu.com\nads.flurry.com\napi.segment.io\nlvip.youku.com\ngug.ku6cdn.com\nad.m.iqiyi.com\ngog9.qzdfc.com\nlocalytics.com\nstat.youku.com\npagechoice.net\nhmma.baidu.com\ngame.weibo.com\nstat.tudou.com\nlives.l.qq.com\njssd.55156.com\ncpro.baidu.com\nm.aty.sohu.com\nad.sina.com.cn\nchartboost.com\nsponsorpay.com\nfen.dkdlsj.com\nstatic.ku6.com\nquantserve.com\ncc.xtgreat.com\nwxxx.mwnyr.com\ncupid.qiyi.com\nc.biz.weibo.com\nserving-sys.com\nm.game.weibo.cn\nnstat.tudou.com\nc.yes.youku.com\nunion.baidu.com\ncoremetrics.com\nswitchadhub.com\npq.stat.ku6.com\nlstat.youku.com\ncpro2.baidu.com\nn.mark.letv.com\nadmaster.com.cn\np-log.ykimg.com\nentry.baidu.com\ngb.corp.163.com\nclicktracks.com\nsax.sina.com.cn\nstats.tudou.com\ncupid.iqiyi.com\nadvertising.com\nzc.biz.weibo.com\nthoughtleadr.com\natanx.alicdn.com\nt.cr-nielsen.com\nagn.aty.sohu.com\nmobads.baidu.com\neclick.baidu.com\ntaob.bjjlcfw.com\niwstat.tudou.com\nprom.gome.com.cn\nadlog.flurry.com\nucstat.baidu.com\nadplay.tudou.com\nlog.cmbchina.com\nrlogs.youdao.com\napi.instabug.com\nalitui.weibo.com\nasimgs.pplive.cn\nwanproxy.127.net\nspcode.baidu.com\ndcads.sina.com.cn\ntjs.sjs.sinajs.cn\nnsclick.baidu.com\nres.cocounion.com\nsmartadserver.com\nactives.youku.com\ntraffic.uusee.com\ng.doubleclick.net\nlogstat.t.sfht.com\nmatch.rtbidder.net\nkwflvcdn.000dn.com\npay.mobile.sina.cn\nlogger.baofeng.com\npics.taobaocdn.com\nshow.re.taobao.com\nzymo.mps.weibo.com\nbeacon.tingyun.com\nbeacon.sina.com.cn\noptimizelyapis.com\nifacelog.iqiyi.com\ns.alitui.weibo.com\nnewspush.sinajs.cn\nd.dsp.imageter.com\nimageplus.baidu.com\nad.api.3g.tudou.com\nad.api.3g.youku.com\nadcontrol.tudou.com\nstrip.taobaocdn.com\npagead.l.google.com\nadm.leju.sina.com.cn\nc.wcpt.biz.weibo.com\npromote.biz.weibo.cn\nadimg.mobile.sina.cn\nwbapp.mobile.sina.cn\ntns.simba.taobao.com\ngoogleadservices.com\nsdkapp.mobile.sina.cn\ntrends.mobile.sina.cn\noimagea2.ydstatic.com\nmobads-logs.baidu.com\nstatic.g.ppstream.com\nwbclick.mobile.sina.cn\nota.pay.mobile.sina.cn\nstatic.tieba.baidu.com\nstatic.lstat.youku.com\nstuff.cdn.biddingx.com\nsdkclick.mobile.sina.cn\nwbpctips.mobile.sina.cn\ninit.icloud-analysis.com\nstatic.flv.uuzuonline.com\nzhihu-analytics.zhihu.com\n\n"
  },
  {
    "path": "code/default/smart_router/local/apis.py",
    "content": "\nfrom . import global_var as g\nfrom . import connect_manager\nfrom xlog import getLogger\nxlog = getLogger(\"smart_router\")\n\n\ndef set_proxy(args):\n    xlog.info(\"set_proxy:%s\", args)\n\n    g.config.PROXY_ENABLE = args[\"enable\"]\n    g.config.PROXY_TYPE = args[\"type\"]\n    g.config.PROXY_HOST = args[\"host\"]\n    try:\n        g.config.PROXY_PORT = int(args[\"port\"])\n    except:\n        g.config.PROXY_PORT = 0\n\n        g.config.PROXY_USER = args[\"user\"]\n    g.config.PROXY_PASSWD = args[\"passwd\"]\n\n    g.config.save()\n\n    connect_manager.load_proxy_config()\n\n\ndef set_bind_ip(args):\n    xlog.info(\"set_bind_ip:%s\", args)\n\n    g.config.proxy_bind_ip = args[\"ip\"]\n    g.config.dns_bind_ip = args[\"ip\"]\n    g.config.save()\n"
  },
  {
    "path": "code/default/smart_router/local/cacert-get-iprange.pem",
    "content": "# DigiCert SHA2 High Assurance Server CA\n-----BEGIN CERTIFICATE-----\nMIIEsTCCA5mgAwIBAgIQBOHnpNxc8vNtwCtCuF0VnzANBgkqhkiG9w0BAQsFADBs\nMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\nd3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j\nZSBFViBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoXDTI4MTAyMjEyMDAwMFowcDEL\nMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3\nLmRpZ2ljZXJ0LmNvbTEvMC0GA1UEAxMmRGlnaUNlcnQgU0hBMiBIaWdoIEFzc3Vy\nYW5jZSBTZXJ2ZXIgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC2\n4C/CJAbIbQRf1+8KZAayfSImZRauQkCbztyfn3YHPsMwVYcZuU+UDlqUH1VWtMIC\nKq/QmO4LQNfE0DtyyBSe75CxEamu0si4QzrZCwvV1ZX1QK/IHe1NnF9Xt4ZQaJn1\nitrSxwUfqJfJ3KSxgoQtxq2lnMcZgqaFD15EWCo3j/018QsIJzJa9buLnqS9UdAn\n4t07QjOjBSjEuyjMmqwrIw14xnvmXnG3Sj4I+4G3FhahnSMSTeXXkgisdaScus0X\nsh5ENWV/UyU50RwKmmMbGZJ0aAo3wsJSSMs5WqK24V3B3aAguCGikyZvFEohQcft\nbZvySC/zA/WiaJJTL17jAgMBAAGjggFJMIIBRTASBgNVHRMBAf8ECDAGAQH/AgEA\nMA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw\nNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2Vy\ndC5jb20wSwYDVR0fBEQwQjBAoD6gPIY6aHR0cDovL2NybDQuZGlnaWNlcnQuY29t\nL0RpZ2lDZXJ0SGlnaEFzc3VyYW5jZUVWUm9vdENBLmNybDA9BgNVHSAENjA0MDIG\nBFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQ\nUzAdBgNVHQ4EFgQUUWj/kK8CB3U8zNllZGKiErhZcjswHwYDVR0jBBgwFoAUsT7D\naQP4v0cB1JgmGggC72NkK8MwDQYJKoZIhvcNAQELBQADggEBABiKlYkD5m3fXPwd\naOpKj4PWUS+Na0QWnqxj9dJubISZi6qBcYRb7TROsLd5kinMLYBq8I4g4Xmk/gNH\nE+r1hspZcX30BJZr01lYPf7TMSVcGDiEo+afgv2MW5gxTs14nhr9hctJqvIni5ly\n/D6q1UEL2tU2ob8cbkdJf17ZSHwD2f2LSaCYJkJA69aSEaRkCldUxPUd1gJea6zu\nxICaEnL6VpPX/78whQYwvwt/Tv9XBZ0k7YXDK/umdaisLRbvfXknsuvCnQsH6qqF\n0wGjIChBWUMo0oHjqvbsezt3tkBigAVBRQHvFwY+3sAzm2fTYS5yh+Rp/BIAV0Ae\ncPUeybQ=\n-----END CERTIFICATE-----\n\n# DigiCert High Assurance EV Root CA\n-----BEGIN CERTIFICATE-----\nMIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs\nMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\nd3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j\nZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL\nMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3\nLmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug\nRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm\n+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW\nPNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM\nxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB\nIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3\nhzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg\nEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF\nMAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA\nFLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec\nnzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z\neM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF\nhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2\nYzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe\nvEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep\n+OkuE6N36B9K\n-----END CERTIFICATE-----\n"
  },
  {
    "path": "code/default/smart_router/local/cloudflare_cert.pem",
    "content": "##\n## Bundle of CA Root Certificates\n##\n## Certificate data from Mozilla downloaded on: Wed Sep  3 03:12:03 2014\n##\n## This is a bundle of X.509 certificates of public Certificate Authorities\n## (CA). These were automatically extracted from Mozilla's root certificates\n## file (certdata.txt).  This file can be found in the mozilla source tree:\n## http://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt\n##\n## It contains the certificates in PEM format and therefore\n## can be directly used with curl / libcurl / php_curl, or with\n## an Apache+mod_ssl webserver for SSL client authentication.\n## Just configure this file as the SSLCACertificateFile.\n##\n## Conversion done with mk-ca-bundle.pl verison 1.22.\n## SHA1: c4540021427a6fa29e5f50db9f12d48c97d33889\n##\nAddTrust_External_Root.crt\n==============================\n-----BEGIN CERTIFICATE-----\nMIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU\nMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs\nIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290\nMB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux\nFDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h\nbCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v\ndDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt\nH7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9\nuMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX\nmk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX\na0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN\nE0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0\nWicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD\nVR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0\nJvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU\ncnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx\nIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN\nAQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH\nYINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5\n6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC\nNr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX\nc4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a\nmnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=\n-----END CERTIFICATE-----\n\n\nCOMODO Certification Authority\n==============================\n-----BEGIN CERTIFICATE-----\nMIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB\ngTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G\nA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV\nBAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw\nMDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl\nYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P\nRE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0\naG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3\nUcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI\n2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8\nQ5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp\n+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+\nDT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O\nnKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW\n/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g\nPKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u\nQXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY\nSdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv\nIC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/\nRxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4\nzJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd\nBA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB\nZQ==\n-----END CERTIFICATE-----\n\nCOMODO_ECC_Certification_Authority\n===================================\n-----BEGIN CERTIFICATE-----\nMIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL\nMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE\nBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT\nIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw\nMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy\nZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N\nT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv\nbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR\nFtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J\ncfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW\nBBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/\nBAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm\nfQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv\nGDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY=\n-----END CERTIFICATE-----\n\nDigiCert_High_Assurance_EV_Root_CA\n===================================\n-----BEGIN CERTIFICATE-----\nMIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs\nMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\nd3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j\nZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL\nMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3\nLmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug\nRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm\n+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW\nPNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM\nxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB\nIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3\nhzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg\nEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF\nMAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA\nFLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec\nnzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z\neM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF\nhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2\nYzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe\nvEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep\n+OkuE6N36B9K\n-----END CERTIFICATE-----\n\n## DigiCert SHA2 High Assurance Server CA\n-----BEGIN CERTIFICATE-----\nMIIEsTCCA5mgAwIBAgIQBOHnpNxc8vNtwCtCuF0VnzANBgkqhkiG9w0BAQsFADBs\nMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\nd3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j\nZSBFViBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoXDTI4MTAyMjEyMDAwMFowcDEL\nMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3\nLmRpZ2ljZXJ0LmNvbTEvMC0GA1UEAxMmRGlnaUNlcnQgU0hBMiBIaWdoIEFzc3Vy\nYW5jZSBTZXJ2ZXIgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC2\n4C/CJAbIbQRf1+8KZAayfSImZRauQkCbztyfn3YHPsMwVYcZuU+UDlqUH1VWtMIC\nKq/QmO4LQNfE0DtyyBSe75CxEamu0si4QzrZCwvV1ZX1QK/IHe1NnF9Xt4ZQaJn1\nitrSxwUfqJfJ3KSxgoQtxq2lnMcZgqaFD15EWCo3j/018QsIJzJa9buLnqS9UdAn\n4t07QjOjBSjEuyjMmqwrIw14xnvmXnG3Sj4I+4G3FhahnSMSTeXXkgisdaScus0X\nsh5ENWV/UyU50RwKmmMbGZJ0aAo3wsJSSMs5WqK24V3B3aAguCGikyZvFEohQcft\nbZvySC/zA/WiaJJTL17jAgMBAAGjggFJMIIBRTASBgNVHRMBAf8ECDAGAQH/AgEA\nMA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw\nNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2Vy\ndC5jb20wSwYDVR0fBEQwQjBAoD6gPIY6aHR0cDovL2NybDQuZGlnaWNlcnQuY29t\nL0RpZ2lDZXJ0SGlnaEFzc3VyYW5jZUVWUm9vdENBLmNybDA9BgNVHSAENjA0MDIG\nBFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQ\nUzAdBgNVHQ4EFgQUUWj/kK8CB3U8zNllZGKiErhZcjswHwYDVR0jBBgwFoAUsT7D\naQP4v0cB1JgmGggC72NkK8MwDQYJKoZIhvcNAQELBQADggEBABiKlYkD5m3fXPwd\naOpKj4PWUS+Na0QWnqxj9dJubISZi6qBcYRb7TROsLd5kinMLYBq8I4g4Xmk/gNH\nE+r1hspZcX30BJZr01lYPf7TMSVcGDiEo+afgv2MW5gxTs14nhr9hctJqvIni5ly\n/D6q1UEL2tU2ob8cbkdJf17ZSHwD2f2LSaCYJkJA69aSEaRkCldUxPUd1gJea6zu\nxICaEnL6VpPX/78whQYwvwt/Tv9XBZ0k7YXDK/umdaisLRbvfXknsuvCnQsH6qqF\n0wGjIChBWUMo0oHjqvbsezt3tkBigAVBRQHvFwY+3sAzm2fTYS5yh+Rp/BIAV0Ae\ncPUeybQ=\n-----END CERTIFICATE-----\n\n## Baltimore_CyberTrust_Root\n-----BEGIN CERTIFICATE-----\nMIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ\nRTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD\nVQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX\nDTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y\nZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy\nVHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr\nmD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr\nIZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK\nmpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu\nXmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy\ndc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye\njl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1\nBE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3\nDQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92\n9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx\njkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0\nEpn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz\nksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS\nR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp\n-----END CERTIFICATE-----\n\n"
  },
  {
    "path": "code/default/smart_router/local/cn_ipv4_range.txt",
    "content": "1.0.1.0 256\n1.0.2.0 512\n1.0.8.0 2048\n1.0.32.0 8192\n1.1.0.0 256\n1.1.2.0 512\n1.1.4.0 1024\n1.1.8.0 256\n1.1.9.0 256\n1.1.10.0 512\n1.1.12.0 1024\n1.1.16.0 4096\n1.1.32.0 8192\n1.2.0.0 512\n1.2.2.0 256\n1.2.4.0 256\n1.2.5.0 256\n1.2.6.0 512\n1.2.8.0 256\n1.2.9.0 256\n1.2.10.0 512\n1.2.12.0 1024\n1.2.16.0 4096\n1.2.32.0 8192\n1.2.64.0 16384\n1.3.0.0 65536\n1.4.1.0 256\n1.4.2.0 512\n1.4.4.0 256\n1.4.5.0 256\n1.4.6.0 512\n1.4.8.0 2048\n1.4.16.0 4096\n1.4.32.0 8192\n1.4.64.0 16384\n1.8.0.0 65536\n1.10.0.0 2048\n1.10.8.0 512\n1.10.11.0 256\n1.10.12.0 1024\n1.10.16.0 4096\n1.10.32.0 8192\n1.10.64.0 16384\n1.12.0.0 262144\n1.24.0.0 524288\n1.45.0.0 65536\n1.48.0.0 131072\n1.50.0.0 65536\n1.51.0.0 65536\n1.56.0.0 524288\n1.68.0.0 262144\n1.80.0.0 524288\n1.88.0.0 262144\n1.92.0.0 131072\n1.94.0.0 131072\n1.116.0.0 131072\n1.118.0.0 65536\n1.119.0.0 32768\n1.119.128.0 32768\n1.180.0.0 262144\n1.184.0.0 131072\n1.188.0.0 262144\n1.192.0.0 524288\n1.202.0.0 131072\n1.204.0.0 262144\n14.0.0.0 2048\n14.0.12.0 1024\n14.1.0.0 1024\n14.1.24.0 1024\n14.1.96.0 1024\n14.1.108.0 1024\n14.16.0.0 1048576\n14.102.128.0 1024\n14.102.156.0 1024\n14.102.180.0 1024\n14.103.0.0 65536\n14.104.0.0 524288\n14.112.0.0 1048576\n14.130.0.0 131072\n14.134.0.0 131072\n14.144.0.0 1048576\n14.192.60.0 1024\n14.192.76.0 1024\n14.196.0.0 131072\n14.204.0.0 131072\n14.208.0.0 1048576\n27.0.128.0 1024\n27.0.132.0 1024\n27.0.160.0 1024\n27.0.164.0 1024\n27.0.188.0 1024\n27.0.204.0 1024\n27.0.208.0 1024\n27.0.212.0 1024\n27.8.0.0 524288\n27.16.0.0 1048576\n27.34.232.0 2048\n27.36.0.0 262144\n27.40.0.0 524288\n27.50.40.0 2048\n27.50.128.0 32768\n27.54.72.0 2048\n27.54.152.0 2048\n27.54.192.0 16384\n27.98.208.0 4096\n27.98.224.0 8192\n27.99.128.0 32768\n27.103.0.0 65536\n27.106.128.0 16384\n27.106.204.0 1024\n27.109.32.0 8192\n27.109.124.0 1024\n27.112.0.0 16384\n27.112.80.0 4096\n27.112.112.0 1024\n27.112.116.0 1024\n27.113.128.0 16384\n27.115.0.0 32768\n27.116.44.0 1024\n27.121.72.0 2048\n27.121.120.0 2048\n27.128.0.0 131072\n27.131.220.0 1024\n27.144.0.0 65536\n27.148.0.0 262144\n27.152.0.0 524288\n27.184.0.0 524288\n27.192.0.0 2097152\n27.224.0.0 262144\n36.0.0.0 1024\n36.0.8.0 2048\n36.0.16.0 4096\n36.0.32.0 8192\n36.0.64.0 16384\n36.0.128.0 32768\n36.1.0.0 65536\n36.4.0.0 262144\n36.16.0.0 1048576\n36.32.0.0 262144\n36.36.0.0 65536\n36.37.0.0 8192\n36.37.36.0 512\n36.37.39.0 256\n36.37.40.0 2048\n36.37.48.0 4096\n36.40.0.0 524288\n36.48.0.0 131072\n36.50.226.0 512\n36.50.254.0 512\n36.51.0.0 65536\n36.56.0.0 524288\n36.96.0.0 2097152\n36.128.0.0 4194304\n36.192.0.0 2097152\n36.248.0.0 262144\n36.254.0.0 65536\n36.255.116.0 1024\n36.255.128.0 1024\n36.255.164.0 1024\n36.255.172.0 1024\n36.255.176.0 1024\n39.0.0.0 256\n39.0.2.0 512\n39.0.4.0 1024\n39.0.8.0 2048\n39.0.16.0 4096\n39.0.32.0 8192\n39.0.64.0 16384\n39.0.128.0 32768\n39.64.0.0 2097152\n39.96.0.0 524288\n39.104.0.0 262144\n39.108.0.0 65536\n39.128.0.0 4194304\n40.72.0.0 131072\n40.125.128.0 32768\n40.126.64.0 16384\n42.0.0.0 1024\n42.0.8.0 2048\n42.0.16.0 2048\n42.0.24.0 1024\n42.0.32.0 8192\n42.0.128.0 32768\n42.1.0.0 8192\n42.1.32.0 4096\n42.1.48.0 2048\n42.1.56.0 1024\n42.1.128.0 32768\n42.4.0.0 262144\n42.48.0.0 131072\n42.50.0.0 65536\n42.51.0.0 65536\n42.52.0.0 262144\n42.56.0.0 262144\n42.62.0.0 32768\n42.62.128.0 8192\n42.62.160.0 4096\n42.62.180.0 1024\n42.62.184.0 2048\n42.63.0.0 65536\n42.80.0.0 131072\n42.83.64.0 4096\n42.83.80.0 1024\n42.83.88.0 2048\n42.83.96.0 8192\n42.83.128.0 32768\n42.84.0.0 262144\n42.88.0.0 524288\n42.96.64.0 8192\n42.96.96.0 2048\n42.96.108.0 1024\n42.96.112.0 4096\n42.96.128.0 32768\n42.97.0.0 65536\n42.99.0.0 16384\n42.99.64.0 8192\n42.99.96.0 4096\n42.99.112.0 1024\n42.99.120.0 2048\n42.100.0.0 262144\n42.120.0.0 131072\n42.122.0.0 65536\n42.123.0.0 8192\n42.123.36.0 1024\n42.123.40.0 2048\n42.123.48.0 4096\n42.123.64.0 16384\n42.123.128.0 32768\n42.128.0.0 1048576\n42.156.0.0 8192\n42.156.36.0 1024\n42.156.40.0 2048\n42.156.48.0 4096\n42.156.64.0 16384\n42.156.128.0 32768\n42.157.0.0 65536\n42.158.0.0 65536\n42.159.0.0 65536\n42.160.0.0 1048576\n42.176.0.0 524288\n42.184.0.0 131072\n42.186.0.0 65536\n42.187.0.0 16384\n42.187.64.0 8192\n42.187.96.0 4096\n42.187.112.0 2048\n42.187.120.0 1024\n42.187.128.0 32768\n42.192.0.0 131072\n42.194.0.0 2048\n42.194.8.0 1024\n42.194.12.0 1024\n42.194.16.0 4096\n42.194.32.0 8192\n42.194.64.0 16384\n42.194.128.0 32768\n42.195.0.0 65536\n42.196.0.0 262144\n42.201.0.0 32768\n42.202.0.0 131072\n42.204.0.0 262144\n42.208.0.0 1048576\n42.224.0.0 1048576\n42.240.0.0 32768\n42.240.128.0 32768\n42.242.0.0 131072\n42.244.0.0 262144\n42.248.0.0 524288\n43.136.0.0 524288\n43.144.0.0 524288\n43.176.0.0 1048576\n43.192.0.0 131072\n43.194.0.0 65536\n43.195.0.0 65536\n43.196.0.0 131072\n43.224.12.0 1024\n43.224.24.0 1024\n43.224.44.0 1024\n43.224.52.0 1024\n43.224.56.0 1024\n43.224.64.0 1024\n43.224.68.0 1024\n43.224.72.0 1024\n43.224.80.0 1024\n43.224.100.0 1024\n43.224.144.0 1024\n43.224.160.0 1024\n43.224.176.0 1024\n43.224.184.0 1024\n43.224.200.0 1024\n43.224.204.0 1024\n43.224.208.0 1024\n43.224.212.0 1024\n43.224.216.0 1024\n43.224.240.0 1024\n43.225.76.0 1024\n43.225.84.0 1024\n43.225.120.0 1024\n43.225.172.0 1024\n43.225.180.0 1024\n43.225.208.0 1024\n43.225.216.0 1024\n43.225.220.0 1024\n43.225.224.0 1024\n43.225.228.0 1024\n43.225.232.0 1024\n43.225.236.0 1024\n43.225.240.0 1024\n43.225.244.0 1024\n43.225.252.0 1024\n43.226.32.0 1024\n43.226.36.0 1024\n43.226.40.0 1024\n43.226.44.0 1024\n43.226.48.0 1024\n43.226.52.0 1024\n43.226.56.0 1024\n43.226.60.0 1024\n43.226.64.0 1024\n43.226.68.0 1024\n43.226.72.0 1024\n43.226.76.0 1024\n43.226.80.0 1024\n43.226.84.0 1024\n43.226.88.0 1024\n43.226.92.0 1024\n43.226.96.0 1024\n43.226.100.0 1024\n43.226.104.0 1024\n43.226.108.0 1024\n43.226.112.0 1024\n43.226.116.0 1024\n43.226.120.0 1024\n43.226.128.0 1024\n43.226.132.0 1024\n43.226.136.0 1024\n43.226.140.0 1024\n43.226.144.0 1024\n43.226.148.0 1024\n43.226.152.0 1024\n43.226.156.0 1024\n43.226.160.0 1024\n43.226.164.0 1024\n43.226.168.0 1024\n43.226.172.0 1024\n43.226.176.0 1024\n43.226.180.0 1024\n43.226.184.0 1024\n43.226.188.0 1024\n43.226.192.0 1024\n43.226.196.0 1024\n43.226.200.0 1024\n43.226.204.0 1024\n43.226.208.0 1024\n43.226.212.0 1024\n43.226.236.0 1024\n43.226.240.0 1024\n43.226.244.0 1024\n43.226.248.0 1024\n43.226.252.0 1024\n43.227.0.0 1024\n43.227.4.0 1024\n43.227.8.0 1024\n43.227.32.0 1024\n43.227.36.0 1024\n43.227.40.0 1024\n43.227.44.0 1024\n43.227.48.0 1024\n43.227.52.0 1024\n43.227.56.0 1024\n43.227.60.0 1024\n43.227.64.0 1024\n43.227.68.0 1024\n43.227.72.0 1024\n43.227.76.0 1024\n43.227.80.0 1024\n43.227.84.0 1024\n43.227.88.0 1024\n43.227.92.0 1024\n43.227.96.0 1024\n43.227.100.0 1024\n43.227.104.0 1024\n43.227.136.0 1024\n43.227.140.0 1024\n43.227.144.0 1024\n43.227.152.0 1024\n43.227.156.0 1024\n43.227.160.0 1024\n43.227.164.0 1024\n43.227.168.0 1024\n43.227.172.0 1024\n43.227.176.0 1024\n43.227.180.0 1024\n43.227.188.0 1024\n43.227.192.0 1024\n43.227.196.0 1024\n43.227.200.0 1024\n43.227.204.0 1024\n43.227.208.0 1024\n43.227.212.0 1024\n43.227.216.0 1024\n43.227.220.0 1024\n43.227.232.0 1024\n43.227.248.0 1024\n43.227.252.0 1024\n43.228.0.0 1024\n43.228.4.0 1024\n43.228.8.0 1024\n43.228.12.0 1024\n43.228.16.0 1024\n43.228.20.0 1024\n43.228.24.0 1024\n43.228.28.0 1024\n43.228.32.0 1024\n43.228.36.0 1024\n43.228.40.0 1024\n43.228.44.0 1024\n43.228.48.0 1024\n43.228.52.0 1024\n43.228.56.0 1024\n43.228.60.0 1024\n43.228.64.0 1024\n43.228.68.0 1024\n43.228.76.0 1024\n43.228.100.0 1024\n43.228.116.0 1024\n43.228.120.0 1024\n43.228.132.0 1024\n43.228.136.0 1024\n43.228.148.0 1024\n43.228.152.0 1024\n43.228.188.0 1024\n43.228.204.0 1024\n43.228.240.0 1024\n43.229.40.0 1024\n43.229.48.0 1024\n43.229.56.0 1024\n43.229.96.0 1024\n43.229.136.0 1024\n43.229.140.0 1024\n43.229.144.0 1024\n43.229.168.0 1024\n43.229.172.0 1024\n43.229.176.0 1024\n43.229.180.0 1024\n43.229.184.0 1024\n43.229.188.0 1024\n43.229.192.0 1024\n43.229.196.0 1024\n43.229.216.0 1024\n43.229.220.0 1024\n43.229.232.0 1024\n43.229.236.0 1024\n43.230.20.0 1024\n43.230.32.0 1024\n43.230.68.0 1024\n43.230.72.0 1024\n43.230.84.0 1024\n43.230.124.0 1024\n43.230.136.0 1024\n43.230.220.0 1024\n43.230.224.0 1024\n43.230.228.0 1024\n43.230.232.0 1024\n43.230.236.0 1024\n43.230.240.0 1024\n43.230.244.0 1024\n43.230.248.0 1024\n43.230.252.0 1024\n43.231.32.0 1024\n43.231.36.0 1024\n43.231.40.0 1024\n43.231.44.0 1024\n43.231.80.0 1024\n43.231.84.0 1024\n43.231.88.0 1024\n43.231.92.0 1024\n43.231.96.0 1024\n43.231.100.0 1024\n43.231.104.0 1024\n43.231.108.0 1024\n43.231.136.0 1024\n43.231.140.0 1024\n43.231.144.0 1024\n43.231.148.0 1024\n43.231.152.0 1024\n43.231.156.0 1024\n43.231.160.0 1024\n43.231.164.0 1024\n43.231.168.0 1024\n43.231.172.0 1024\n43.231.176.0 1024\n43.231.180.0 1024\n43.236.0.0 1024\n43.236.4.0 1024\n43.236.8.0 1024\n43.236.12.0 1024\n43.236.16.0 1024\n43.236.20.0 1024\n43.236.24.0 1024\n43.236.28.0 1024\n43.236.32.0 1024\n43.236.36.0 1024\n43.236.40.0 1024\n43.236.44.0 1024\n43.236.48.0 1024\n43.236.52.0 1024\n43.236.56.0 1024\n43.236.60.0 1024\n43.236.64.0 1024\n43.236.68.0 1024\n43.236.72.0 1024\n43.236.76.0 1024\n43.236.80.0 1024\n43.236.84.0 1024\n43.236.88.0 1024\n43.236.92.0 1024\n43.236.96.0 1024\n43.236.100.0 1024\n43.236.104.0 1024\n43.236.108.0 1024\n43.236.112.0 1024\n43.236.116.0 1024\n43.236.120.0 1024\n43.236.124.0 1024\n43.236.128.0 1024\n43.236.132.0 1024\n43.236.136.0 1024\n43.236.140.0 1024\n43.236.144.0 1024\n43.236.148.0 1024\n43.236.152.0 1024\n43.236.156.0 1024\n43.236.160.0 1024\n43.236.164.0 1024\n43.236.168.0 1024\n43.236.172.0 1024\n43.236.176.0 1024\n43.236.180.0 1024\n43.236.184.0 1024\n43.236.188.0 1024\n43.236.192.0 1024\n43.236.196.0 1024\n43.236.200.0 1024\n43.236.204.0 1024\n43.236.208.0 1024\n43.236.212.0 1024\n43.236.216.0 1024\n43.236.220.0 1024\n43.236.224.0 1024\n43.236.228.0 1024\n43.236.232.0 1024\n43.236.236.0 1024\n43.236.240.0 1024\n43.236.244.0 1024\n43.236.248.0 1024\n43.236.252.0 1024\n43.237.0.0 1024\n43.237.4.0 1024\n43.237.8.0 1024\n43.237.12.0 1024\n43.237.16.0 1024\n43.237.20.0 1024\n43.237.24.0 1024\n43.237.28.0 1024\n43.237.32.0 1024\n43.237.36.0 1024\n43.237.40.0 1024\n43.237.44.0 1024\n43.237.48.0 1024\n43.237.52.0 1024\n43.237.56.0 1024\n43.237.60.0 1024\n43.237.64.0 1024\n43.237.68.0 1024\n43.237.72.0 1024\n43.237.76.0 1024\n43.237.80.0 1024\n43.237.84.0 1024\n43.237.88.0 1024\n43.237.92.0 1024\n43.237.96.0 1024\n43.237.100.0 1024\n43.237.104.0 1024\n43.237.108.0 1024\n43.237.112.0 1024\n43.237.116.0 1024\n43.237.120.0 1024\n43.237.124.0 1024\n43.237.128.0 1024\n43.237.132.0 1024\n43.237.136.0 1024\n43.237.140.0 1024\n43.237.144.0 1024\n43.237.148.0 1024\n43.237.152.0 1024\n43.237.156.0 1024\n43.237.160.0 1024\n43.237.164.0 1024\n43.237.168.0 1024\n43.237.172.0 1024\n43.237.176.0 1024\n43.237.180.0 1024\n43.237.184.0 1024\n43.237.188.0 1024\n43.237.192.0 1024\n43.237.200.0 1024\n43.237.204.0 1024\n43.237.208.0 1024\n43.237.212.0 1024\n43.237.216.0 1024\n43.237.220.0 1024\n43.237.224.0 1024\n43.237.228.0 1024\n43.237.232.0 1024\n43.237.236.0 1024\n43.237.240.0 1024\n43.237.244.0 1024\n43.237.248.0 1024\n43.237.252.0 1024\n43.238.0.0 1024\n43.238.4.0 1024\n43.238.8.0 1024\n43.238.12.0 1024\n43.238.16.0 1024\n43.238.20.0 1024\n43.238.24.0 1024\n43.238.28.0 1024\n43.238.32.0 1024\n43.238.36.0 1024\n43.238.40.0 1024\n43.238.44.0 1024\n43.238.48.0 1024\n43.238.52.0 1024\n43.238.56.0 1024\n43.238.60.0 1024\n43.238.64.0 1024\n43.238.68.0 1024\n43.238.72.0 1024\n43.238.76.0 1024\n43.238.80.0 1024\n43.238.84.0 1024\n43.238.88.0 1024\n43.238.92.0 1024\n43.238.96.0 1024\n43.238.100.0 1024\n43.238.104.0 1024\n43.238.108.0 1024\n43.238.112.0 1024\n43.238.116.0 1024\n43.238.120.0 1024\n43.238.124.0 1024\n43.238.128.0 1024\n43.238.132.0 1024\n43.238.136.0 1024\n43.238.140.0 1024\n43.238.144.0 1024\n43.238.148.0 1024\n43.238.152.0 1024\n43.238.156.0 1024\n43.238.160.0 1024\n43.238.164.0 1024\n43.238.168.0 1024\n43.238.172.0 1024\n43.238.176.0 1024\n43.238.180.0 1024\n43.238.184.0 1024\n43.238.188.0 1024\n43.238.192.0 1024\n43.238.196.0 1024\n43.238.200.0 1024\n43.238.204.0 1024\n43.238.208.0 1024\n43.238.212.0 1024\n43.238.216.0 1024\n43.238.220.0 1024\n43.238.224.0 1024\n43.238.228.0 1024\n43.238.232.0 1024\n43.238.236.0 1024\n43.238.240.0 1024\n43.238.244.0 1024\n43.238.248.0 1024\n43.238.252.0 1024\n43.239.0.0 1024\n43.239.4.0 1024\n43.239.8.0 2048\n43.239.16.0 1024\n43.239.20.0 1024\n43.239.24.0 1024\n43.239.28.0 1024\n43.239.32.0 1024\n43.239.36.0 1024\n43.239.40.0 1024\n43.239.44.0 1024\n43.239.48.0 1024\n43.239.116.0 1024\n43.239.120.0 1024\n43.239.172.0 1024\n43.239.176.0 1024\n43.240.0.0 1024\n43.240.56.0 1024\n43.240.60.0 1024\n43.240.68.0 1024\n43.240.72.0 1024\n43.240.76.0 1024\n43.240.84.0 1024\n43.240.124.0 1024\n43.240.128.0 1024\n43.240.132.0 1024\n43.240.136.0 1024\n43.240.144.0 1024\n43.240.156.0 1024\n43.240.160.0 1024\n43.240.164.0 1024\n43.240.168.0 1024\n43.240.172.0 1024\n43.240.176.0 1024\n43.240.180.0 1024\n43.240.184.0 1024\n43.240.188.0 1024\n43.240.192.0 1024\n43.240.196.0 1024\n43.240.200.0 1024\n43.240.204.0 1024\n43.240.208.0 1024\n43.240.212.0 1024\n43.240.216.0 1024\n43.240.220.0 1024\n43.240.240.0 1024\n43.240.244.0 1024\n43.240.248.0 1024\n43.240.252.0 1024\n43.241.0.0 1024\n43.241.4.0 1024\n43.241.8.0 1024\n43.241.12.0 1024\n43.241.16.0 1024\n43.241.20.0 1024\n43.241.48.0 1024\n43.241.76.0 1024\n43.241.80.0 1024\n43.241.84.0 1024\n43.241.88.0 1024\n43.241.92.0 1024\n43.241.112.0 1024\n43.241.168.0 1024\n43.241.172.0 1024\n43.241.176.0 1024\n43.241.180.0 1024\n43.241.184.0 1024\n43.241.208.0 1024\n43.241.212.0 1024\n43.241.216.0 1024\n43.241.220.0 1024\n43.241.224.0 1024\n43.241.228.0 1024\n43.241.232.0 1024\n43.241.236.0 1024\n43.241.240.0 1024\n43.241.248.0 1024\n43.241.252.0 1024\n43.242.8.0 1024\n43.242.12.0 1024\n43.242.16.0 2048\n43.242.24.0 1024\n43.242.28.0 1024\n43.242.44.0 1024\n43.242.48.0 1024\n43.242.52.0 1024\n43.242.56.0 1024\n43.242.60.0 1024\n43.242.64.0 1024\n43.242.72.0 1024\n43.242.76.0 1024\n43.242.80.0 1024\n43.242.84.0 1024\n43.242.88.0 1024\n43.242.92.0 1024\n43.242.96.0 1024\n43.242.144.0 1024\n43.242.148.0 1024\n43.242.152.0 1024\n43.242.156.0 1024\n43.242.160.0 1024\n43.242.164.0 1024\n43.242.168.0 1024\n43.242.180.0 1024\n43.242.188.0 1024\n43.242.192.0 1024\n43.242.196.0 1024\n43.242.204.0 1024\n43.242.216.0 1024\n43.242.220.0 1024\n43.242.252.0 1024\n43.243.4.0 1024\n43.243.8.0 1024\n43.243.12.0 1024\n43.243.16.0 1024\n43.243.88.0 1024\n43.243.128.0 1024\n43.243.136.0 1024\n43.243.144.0 1024\n43.243.148.0 1024\n43.243.156.0 1024\n43.243.180.0 1024\n43.243.228.0 1024\n43.243.232.0 1024\n43.243.244.0 1024\n43.246.0.0 1024\n43.246.4.0 1024\n43.246.8.0 1024\n43.246.12.0 1024\n43.246.16.0 1024\n43.246.20.0 1024\n43.246.24.0 1024\n43.246.28.0 1024\n43.246.32.0 1024\n43.246.36.0 1024\n43.246.40.0 1024\n43.246.44.0 1024\n43.246.48.0 1024\n43.246.52.0 1024\n43.246.56.0 1024\n43.246.60.0 1024\n43.246.64.0 1024\n43.246.68.0 1024\n43.246.72.0 1024\n43.246.76.0 1024\n43.246.80.0 1024\n43.246.84.0 1024\n43.246.88.0 1024\n43.246.92.0 1024\n43.246.96.0 1024\n43.246.112.0 1024\n43.246.228.0 1024\n43.247.4.0 1024\n43.247.8.0 1024\n43.247.44.0 1024\n43.247.48.0 1024\n43.247.68.0 1024\n43.247.76.0 1024\n43.247.84.0 1024\n43.247.88.0 1024\n43.247.92.0 1024\n43.247.96.0 1024\n43.247.100.0 1024\n43.247.108.0 1024\n43.247.112.0 1024\n43.247.148.0 1024\n43.247.152.0 1024\n43.247.176.0 1024\n43.247.180.0 1024\n43.247.184.0 1024\n43.247.188.0 1024\n43.247.196.0 1024\n43.247.200.0 1024\n43.247.204.0 1024\n43.247.208.0 1024\n43.247.212.0 1024\n43.247.216.0 1024\n43.247.220.0 1024\n43.247.224.0 1024\n43.247.228.0 1024\n43.247.232.0 1024\n43.247.236.0 1024\n43.247.240.0 1024\n43.247.244.0 1024\n43.247.248.0 1024\n43.247.252.0 1024\n43.248.0.0 1024\n43.248.4.0 1024\n43.248.20.0 1024\n43.248.28.0 1024\n43.248.48.0 1024\n43.248.76.0 1024\n43.248.80.0 1024\n43.248.84.0 1024\n43.248.88.0 1024\n43.248.92.0 1024\n43.248.96.0 1024\n43.248.100.0 1024\n43.248.104.0 1024\n43.248.108.0 1024\n43.248.112.0 1024\n43.248.116.0 1024\n43.248.120.0 1024\n43.248.124.0 1024\n43.248.128.0 1024\n43.248.132.0 1024\n43.248.136.0 1024\n43.248.140.0 1024\n43.248.144.0 1024\n43.248.148.0 1024\n43.248.176.0 1024\n43.248.180.0 1024\n43.248.184.0 1024\n43.248.188.0 1024\n43.248.192.0 1024\n43.248.196.0 1024\n43.248.200.0 1024\n43.248.204.0 1024\n43.248.208.0 1024\n43.248.228.0 1024\n43.248.232.0 1024\n43.248.244.0 1024\n43.249.4.0 1024\n43.249.8.0 1024\n43.249.120.0 1024\n43.249.132.0 1024\n43.249.136.0 1024\n43.249.144.0 1024\n43.249.148.0 1024\n43.249.152.0 1024\n43.249.156.0 1024\n43.249.160.0 1024\n43.249.164.0 1024\n43.249.168.0 1024\n43.249.192.0 1024\n43.249.236.0 1024\n43.250.4.0 1024\n43.250.12.0 1024\n43.250.16.0 1024\n43.250.20.0 1024\n43.250.28.0 1024\n43.250.32.0 1024\n43.250.36.0 1024\n43.250.72.0 1024\n43.250.96.0 1024\n43.250.100.0 1024\n43.250.104.0 1024\n43.250.108.0 1024\n43.250.112.0 1024\n43.250.116.0 1024\n43.250.128.0 1024\n43.250.144.0 1024\n43.250.148.0 1024\n43.250.160.0 1024\n43.250.168.0 1024\n43.250.172.0 1024\n43.250.176.0 1024\n43.250.180.0 512\n43.250.200.0 1024\n43.250.212.0 1024\n43.250.216.0 1024\n43.250.220.0 1024\n43.250.236.0 1024\n43.250.244.0 1024\n43.251.4.0 1024\n43.251.8.0 1024\n43.251.36.0 1024\n43.251.100.0 1024\n43.251.116.0 1024\n43.251.192.0 1024\n43.251.232.0 1024\n43.251.236.0 1024\n43.251.244.0 1024\n43.252.48.0 1024\n43.252.56.0 1024\n43.254.0.0 1024\n43.254.4.0 1024\n43.254.8.0 1024\n43.254.24.0 1024\n43.254.36.0 1024\n43.254.44.0 1024\n43.254.52.0 1024\n43.254.64.0 1024\n43.254.72.0 1024\n43.254.84.0 1024\n43.254.88.0 1024\n43.254.92.0 1024\n43.254.100.0 1024\n43.254.104.0 1024\n43.254.112.0 1024\n43.254.116.0 1024\n43.254.128.0 1024\n43.254.136.0 1024\n43.254.140.0 1024\n43.254.144.0 1024\n43.254.148.0 1024\n43.254.152.0 1024\n43.254.156.0 1024\n43.254.168.0 1024\n43.254.172.0 1024\n43.254.180.0 1024\n43.254.184.0 1024\n43.254.188.0 1024\n43.254.192.0 1024\n43.254.196.0 1024\n43.254.200.0 1024\n43.254.208.0 1024\n43.254.220.0 1024\n43.254.224.0 1024\n43.254.228.0 1024\n43.254.232.0 1024\n43.254.236.0 1024\n43.254.240.0 1024\n43.254.248.0 1024\n43.254.252.0 1024\n43.255.0.0 1024\n43.255.4.0 1024\n43.255.8.0 1024\n43.255.16.0 1024\n43.255.48.0 1024\n43.255.64.0 1024\n43.255.68.0 1024\n43.255.72.0 1024\n43.255.76.0 1024\n43.255.84.0 1024\n43.255.96.0 1024\n43.255.144.0 1024\n43.255.176.0 1024\n43.255.184.0 1024\n43.255.192.0 1024\n43.255.200.0 1024\n43.255.204.0 1024\n43.255.208.0 1024\n43.255.212.0 1024\n43.255.224.0 1024\n43.255.228.0 1024\n43.255.232.0 1024\n43.255.244.0 1024\n45.40.192.0 16384\n45.65.16.0 1024\n45.65.20.0 1024\n45.65.24.0 1024\n45.65.28.0 1024\n45.112.132.0 1024\n45.112.188.0 1024\n45.112.208.0 1024\n45.112.212.0 1024\n45.112.216.0 1024\n45.112.220.0 1024\n45.112.228.0 1024\n45.112.232.0 1024\n45.112.236.0 1024\n45.113.12.0 1024\n45.113.16.0 1024\n45.113.20.0 1024\n45.113.24.0 1024\n45.113.28.0 1024\n45.113.40.0 1024\n45.113.52.0 1024\n45.113.56.0 1024\n45.113.72.0 1024\n45.113.144.0 1024\n45.113.148.0 1024\n45.113.168.0 1024\n45.113.176.0 1024\n45.113.184.0 1024\n45.113.200.0 1024\n45.113.204.0 1024\n45.113.208.0 1024\n45.113.212.0 1024\n45.113.216.0 1024\n45.113.220.0 1024\n45.113.240.0 1024\n45.113.252.0 1024\n45.114.0.0 1024\n45.114.32.0 1024\n45.114.40.0 1024\n45.114.52.0 1024\n45.114.96.0 1024\n45.114.124.0 1024\n45.114.136.0 1024\n45.114.196.0 1024\n45.114.200.0 1024\n45.114.228.0 1024\n45.114.252.0 1024\n45.115.44.0 1024\n45.115.100.0 1024\n45.115.120.0 1024\n45.115.132.0 1024\n45.115.144.0 1024\n45.115.156.0 1024\n45.115.164.0 1024\n45.115.200.0 1024\n45.115.212.0 1024\n45.115.228.0 1024\n45.115.236.0 1024\n45.115.244.0 1024\n45.115.248.0 1024\n45.116.16.0 1024\n45.116.24.0 1024\n45.116.32.0 1024\n45.116.36.0 1024\n45.116.52.0 1024\n45.116.96.0 1024\n45.116.100.0 1024\n45.116.140.0 1024\n45.116.152.0 1024\n45.116.208.0 1024\n45.117.8.0 1024\n45.117.20.0 1024\n45.117.68.0 1024\n45.117.124.0 1024\n45.117.252.0 1024\n45.119.52.0 1024\n45.119.60.0 1024\n45.119.64.0 1024\n45.119.68.0 1024\n45.119.72.0 1024\n45.119.104.0 1024\n45.119.116.0 1024\n45.119.232.0 1024\n45.120.100.0 1024\n45.120.140.0 1024\n45.120.164.0 1024\n45.120.240.0 1024\n45.121.52.0 1024\n45.121.64.0 1024\n45.121.68.0 1024\n45.121.72.0 1024\n45.121.92.0 1024\n45.121.96.0 1024\n45.121.172.0 1024\n45.121.176.0 1024\n45.121.212.0 1024\n45.121.240.0 1024\n45.121.244.0 1024\n45.121.248.0 1024\n45.121.252.0 1024\n45.122.0.0 1024\n45.122.4.0 1024\n45.122.8.0 1024\n45.122.12.0 1024\n45.122.16.0 1024\n45.122.20.0 1024\n45.122.24.0 1024\n45.122.28.0 1024\n45.122.32.0 1024\n45.122.36.0 1024\n45.122.40.0 1024\n45.122.60.0 1024\n45.122.64.0 1024\n45.122.68.0 1024\n45.122.72.0 1024\n45.122.76.0 1024\n45.122.80.0 1024\n45.122.84.0 1024\n45.122.88.0 1024\n45.122.92.0 1024\n45.122.96.0 2048\n45.122.104.0 1024\n45.122.108.0 1024\n45.122.112.0 1024\n45.122.116.0 1024\n45.122.160.0 1024\n45.122.164.0 1024\n45.122.168.0 1024\n45.122.172.0 1024\n45.122.176.0 1024\n45.122.180.0 1024\n45.122.184.0 1024\n45.122.188.0 1024\n45.122.192.0 1024\n45.122.196.0 1024\n45.122.200.0 1024\n45.122.204.0 1024\n45.122.208.0 1024\n45.122.212.0 1024\n45.122.216.0 1024\n45.123.28.0 1024\n45.123.32.0 1024\n45.123.36.0 1024\n45.123.44.0 1024\n45.123.48.0 1024\n45.123.52.0 1024\n45.123.56.0 1024\n45.123.60.0 1024\n45.123.64.0 1024\n45.123.68.0 1024\n45.123.72.0 1024\n45.123.76.0 1024\n45.123.80.0 1024\n45.123.84.0 1024\n45.123.88.0 1024\n45.123.120.0 1024\n45.123.128.0 1024\n45.123.132.0 1024\n45.123.136.0 1024\n45.123.148.0 1024\n45.123.152.0 1024\n45.123.156.0 1024\n45.123.164.0 1024\n45.123.168.0 1024\n45.123.172.0 1024\n45.123.176.0 1024\n45.123.180.0 1024\n45.123.184.0 1024\n45.123.204.0 1024\n45.123.212.0 1024\n45.123.224.0 1024\n45.123.228.0 1024\n45.123.232.0 1024\n45.123.236.0 1024\n45.123.240.0 1024\n45.123.244.0 1024\n45.123.248.0 1024\n45.123.252.0 1024\n45.124.0.0 1024\n45.124.20.0 1024\n45.124.28.0 1024\n45.124.32.0 1024\n45.124.36.0 1024\n45.124.44.0 1024\n45.124.68.0 1024\n45.124.76.0 1024\n45.124.80.0 1024\n45.124.100.0 1024\n45.124.124.0 1024\n45.124.172.0 1024\n45.124.176.0 1024\n45.124.208.0 1024\n45.124.248.0 1024\n45.125.16.0 1024\n45.125.24.0 1024\n45.125.44.0 1024\n45.125.52.0 1024\n45.125.56.0 1024\n45.125.76.0 1024\n45.125.80.0 1024\n45.125.84.0 1024\n45.125.88.0 1024\n45.125.92.0 1024\n45.125.96.0 1024\n45.125.100.0 1024\n45.125.136.0 1024\n45.126.48.0 1024\n45.126.52.0 1024\n45.126.100.0 1024\n45.126.108.0 1024\n45.126.112.0 1024\n45.126.116.0 1024\n45.126.120.0 1024\n45.126.212.0 1024\n45.126.220.0 1024\n45.127.8.0 1024\n45.127.12.0 1024\n45.127.128.0 1024\n45.127.144.0 1024\n45.127.148.0 1024\n45.127.156.0 1024\n45.127.216.0 1024\n45.248.8.0 1024\n45.248.80.0 1024\n45.248.84.0 1024\n45.248.88.0 1024\n45.248.96.0 1024\n45.248.100.0 1024\n45.248.104.0 1024\n45.248.108.0 1024\n45.248.128.0 1024\n45.248.132.0 1024\n45.248.204.0 1024\n45.248.208.0 1024\n45.248.212.0 1024\n45.248.216.0 1024\n45.248.220.0 1024\n45.248.224.0 1024\n45.248.228.0 1024\n45.248.232.0 1024\n45.248.236.0 1024\n45.248.240.0 1024\n45.248.244.0 1024\n45.248.248.0 1024\n45.248.252.0 1024\n45.249.0.0 1024\n45.249.4.0 1024\n45.249.12.0 1024\n45.249.16.0 1024\n45.249.20.0 1024\n45.249.24.0 1024\n45.249.28.0 1024\n45.249.32.0 1024\n45.249.36.0 1024\n45.249.112.0 1024\n45.249.188.0 1024\n45.249.192.0 1024\n45.249.196.0 1024\n45.249.200.0 1024\n45.249.204.0 1024\n45.249.208.0 1024\n45.249.212.0 1024\n45.250.12.0 1024\n45.250.16.0 1024\n45.250.28.0 1024\n45.250.32.0 1024\n45.250.36.0 1024\n45.250.40.0 1024\n45.250.76.0 1024\n45.250.80.0 1024\n45.250.84.0 1024\n45.250.88.0 1024\n45.250.92.0 1024\n45.250.96.0 1024\n45.250.104.0 1024\n45.250.108.0 1024\n45.250.112.0 1024\n45.250.116.0 1024\n45.250.120.0 1024\n45.250.124.0 1024\n45.250.128.0 1024\n45.250.132.0 1024\n45.250.136.0 1024\n45.250.140.0 1024\n45.250.144.0 1024\n45.250.148.0 1024\n45.250.152.0 1024\n45.250.164.0 1024\n45.250.180.0 1024\n45.250.184.0 1024\n45.250.188.0 1024\n45.250.192.0 1024\n45.251.0.0 1024\n45.251.8.0 1024\n45.251.16.0 1024\n45.251.20.0 1024\n45.251.52.0 1024\n45.251.84.0 1024\n45.251.88.0 1024\n45.251.92.0 1024\n45.251.96.0 1024\n45.251.100.0 1024\n45.251.120.0 1024\n45.251.124.0 1024\n45.251.136.0 1024\n45.251.140.0 1024\n45.251.144.0 1024\n45.251.148.0 1024\n45.251.152.0 1024\n45.251.156.0 1024\n45.251.160.0 1024\n45.251.164.0 1024\n45.251.168.0 1024\n45.251.172.0 1024\n45.251.176.0 1024\n45.251.180.0 1024\n45.251.184.0 1024\n45.251.188.0 1024\n45.251.192.0 1024\n45.251.196.0 1024\n45.251.200.0 1024\n45.251.204.0 1024\n45.251.208.0 1024\n45.251.212.0 1024\n45.251.216.0 1024\n45.251.220.0 1024\n45.251.224.0 1024\n45.251.240.0 1024\n45.252.0.0 1024\n45.252.4.0 1024\n45.252.8.0 1024\n45.252.12.0 1024\n45.252.16.0 1024\n45.252.20.0 1024\n45.252.24.0 1024\n45.252.28.0 1024\n45.252.32.0 1024\n45.252.36.0 1024\n45.252.40.0 1024\n45.252.44.0 1024\n45.252.48.0 1024\n45.252.84.0 1024\n45.252.88.0 1024\n45.252.92.0 1024\n45.252.96.0 1024\n45.252.100.0 1024\n45.252.104.0 1024\n45.252.108.0 1024\n45.252.112.0 1024\n45.252.116.0 1024\n45.252.120.0 1024\n45.252.124.0 1024\n45.252.128.0 1024\n45.252.132.0 1024\n45.252.136.0 1024\n45.252.140.0 1024\n45.252.144.0 1024\n45.252.148.0 1024\n45.252.152.0 1024\n45.252.156.0 1024\n45.252.160.0 1024\n45.252.164.0 1024\n45.252.168.0 1024\n45.252.172.0 1024\n45.252.176.0 1024\n45.252.192.0 1024\n45.252.196.0 1024\n45.252.200.0 1024\n45.252.204.0 1024\n45.252.208.0 1024\n45.252.212.0 1024\n45.252.216.0 1024\n45.252.220.0 1024\n45.252.224.0 1024\n45.252.228.0 1024\n45.252.232.0 1024\n45.253.0.0 1024\n45.253.4.0 1024\n45.253.8.0 1024\n45.253.12.0 1024\n45.253.16.0 1024\n45.253.20.0 1024\n45.253.24.0 1024\n45.253.28.0 1024\n45.253.32.0 1024\n45.253.36.0 1024\n45.253.40.0 1024\n45.253.44.0 1024\n45.253.48.0 1024\n45.253.52.0 1024\n45.253.56.0 1024\n45.253.60.0 1024\n45.253.64.0 1024\n45.253.68.0 1024\n45.253.72.0 1024\n45.253.76.0 1024\n45.253.80.0 1024\n45.253.84.0 1024\n45.253.92.0 1024\n45.253.96.0 1024\n45.253.100.0 1024\n45.253.104.0 1024\n45.253.108.0 1024\n45.253.112.0 1024\n45.253.116.0 1024\n45.253.120.0 1024\n45.253.132.0 1024\n45.253.136.0 1024\n45.253.140.0 1024\n45.253.144.0 1024\n45.253.148.0 1024\n45.253.152.0 1024\n45.253.156.0 1024\n45.253.160.0 1024\n45.253.164.0 1024\n45.253.168.0 1024\n45.253.172.0 1024\n45.253.176.0 1024\n45.253.180.0 1024\n45.253.184.0 1024\n45.253.188.0 1024\n45.253.192.0 1024\n45.253.196.0 1024\n45.253.200.0 1024\n45.253.204.0 1024\n45.253.208.0 1024\n45.253.212.0 1024\n45.253.216.0 1024\n45.253.220.0 1024\n45.253.224.0 1024\n45.253.228.0 1024\n45.253.232.0 1024\n45.253.236.0 1024\n45.253.240.0 1024\n45.253.244.0 1024\n45.254.0.0 1024\n45.254.4.0 1024\n45.254.8.0 1024\n45.254.12.0 1024\n45.254.16.0 1024\n45.254.20.0 1024\n45.254.24.0 1024\n45.254.28.0 1024\n45.254.40.0 1024\n45.254.48.0 1024\n45.254.52.0 1024\n45.254.56.0 1024\n45.254.60.0 1024\n45.254.64.0 1024\n45.254.68.0 1024\n45.254.72.0 1024\n45.254.76.0 1024\n45.254.80.0 1024\n45.254.84.0 1024\n45.254.88.0 1024\n45.254.92.0 1024\n45.254.96.0 1024\n45.254.100.0 1024\n45.254.104.0 1024\n45.254.108.0 1024\n45.254.112.0 1024\n45.254.116.0 1024\n45.254.120.0 1024\n45.254.124.0 1024\n45.254.128.0 1024\n45.254.132.0 1024\n45.254.136.0 1024\n45.254.140.0 1024\n45.254.144.0 1024\n45.254.148.0 1024\n45.254.152.0 1024\n45.254.156.0 1024\n45.254.160.0 1024\n45.254.164.0 1024\n45.254.168.0 1024\n45.254.172.0 1024\n45.254.176.0 1024\n45.254.180.0 1024\n45.254.184.0 1024\n45.254.188.0 1024\n45.254.192.0 1024\n45.254.196.0 1024\n45.254.200.0 1024\n45.254.204.0 1024\n45.254.208.0 1024\n45.254.212.0 1024\n45.254.216.0 1024\n45.254.220.0 1024\n45.254.224.0 1024\n45.254.228.0 1024\n45.254.236.0 1024\n45.254.240.0 1024\n45.254.248.0 1024\n45.255.0.0 1024\n45.255.4.0 1024\n45.255.8.0 1024\n45.255.12.0 1024\n45.255.16.0 1024\n45.255.20.0 1024\n45.255.24.0 1024\n45.255.28.0 1024\n45.255.32.0 1024\n45.255.36.0 1024\n45.255.40.0 1024\n45.255.44.0 1024\n45.255.48.0 1024\n45.255.52.0 1024\n45.255.56.0 1024\n45.255.60.0 1024\n45.255.64.0 1024\n45.255.68.0 1024\n45.255.72.0 1024\n45.255.76.0 1024\n45.255.80.0 1024\n45.255.84.0 1024\n45.255.88.0 1024\n45.255.92.0 1024\n45.255.96.0 1024\n45.255.100.0 1024\n45.255.104.0 1024\n45.255.108.0 1024\n45.255.112.0 1024\n45.255.116.0 1024\n45.255.120.0 1024\n45.255.124.0 1024\n45.255.132.0 1024\n45.255.136.0 1024\n45.255.140.0 1024\n45.255.144.0 1024\n45.255.148.0 1024\n45.255.152.0 1024\n45.255.156.0 1024\n45.255.160.0 1024\n45.255.164.0 1024\n45.255.168.0 1024\n45.255.172.0 1024\n45.255.176.0 1024\n45.255.180.0 1024\n45.255.184.0 1024\n45.255.188.0 1024\n45.255.192.0 1024\n45.255.196.0 1024\n45.255.200.0 1024\n45.255.204.0 1024\n45.255.208.0 1024\n45.255.212.0 1024\n45.255.216.0 1024\n45.255.220.0 1024\n45.255.224.0 1024\n45.255.228.0 1024\n45.255.232.0 1024\n45.255.236.0 1024\n45.255.240.0 1024\n45.255.244.0 1024\n45.255.248.0 1024\n47.92.0.0 262144\n47.96.0.0 2097152\n49.4.0.0 262144\n49.51.0.0 65536\n49.52.0.0 262144\n49.64.0.0 2097152\n49.112.0.0 524288\n49.120.0.0 262144\n49.128.0.0 256\n49.128.2.0 512\n49.128.4.0 1024\n49.140.0.0 131072\n49.152.0.0 262144\n49.208.0.0 131072\n49.210.0.0 131072\n49.220.0.0 262144\n49.232.0.0 262144\n49.239.0.0 16384\n49.239.192.0 16384\n49.246.224.0 8192\n52.80.0.0 131072\n52.82.0.0 131072\n52.130.0.0 131072\n54.222.0.0 131072\n57.176.0.0 131072\n58.14.0.0 131072\n58.16.0.0 65536\n58.17.0.0 32768\n58.17.128.0 32768\n58.18.0.0 65536\n58.19.0.0 65536\n58.20.0.0 65536\n58.21.0.0 65536\n58.22.0.0 131072\n58.24.0.0 131072\n58.30.0.0 131072\n58.32.0.0 524288\n58.40.0.0 131072\n58.42.0.0 65536\n58.43.0.0 65536\n58.44.0.0 262144\n58.48.0.0 524288\n58.56.0.0 131072\n58.58.0.0 65536\n58.59.0.0 32768\n58.59.128.0 32768\n58.60.0.0 262144\n58.65.232.0 2048\n58.66.0.0 131072\n58.68.128.0 32768\n58.82.0.0 32768\n58.83.0.0 32768\n58.83.128.0 32768\n58.87.64.0 16384\n58.99.128.0 32768\n58.100.0.0 131072\n58.116.0.0 262144\n58.128.0.0 524288\n58.144.0.0 65536\n58.154.0.0 131072\n58.192.0.0 131072\n58.194.0.0 131072\n58.196.0.0 131072\n58.198.0.0 131072\n58.200.0.0 524288\n58.208.0.0 1048576\n58.240.0.0 131072\n58.242.0.0 131072\n58.244.0.0 131072\n58.246.0.0 131072\n58.248.0.0 524288\n59.32.0.0 524288\n59.40.0.0 131072\n59.42.0.0 65536\n59.43.0.0 65536\n59.44.0.0 262144\n59.48.0.0 65536\n59.49.0.0 32768\n59.49.128.0 32768\n59.50.0.0 65536\n59.51.0.0 32768\n59.51.128.0 32768\n59.52.0.0 262144\n59.56.0.0 262144\n59.60.0.0 131072\n59.62.0.0 131072\n59.64.0.0 262144\n59.68.0.0 262144\n59.72.0.0 131072\n59.74.0.0 131072\n59.76.0.0 65536\n59.77.0.0 65536\n59.78.0.0 131072\n59.80.0.0 131072\n59.82.0.0 131072\n59.107.0.0 32768\n59.107.128.0 32768\n59.108.0.0 131072\n59.110.0.0 131072\n59.151.0.0 32768\n59.152.16.0 1024\n59.152.20.0 1024\n59.152.24.0 1024\n59.152.28.0 1024\n59.152.32.0 1024\n59.152.36.0 1024\n59.152.64.0 1024\n59.152.68.0 1024\n59.152.72.0 1024\n59.152.76.0 1024\n59.152.112.0 1024\n59.152.116.0 1024\n59.153.4.0 1024\n59.153.32.0 1024\n59.153.60.0 1024\n59.153.64.0 1024\n59.153.68.0 1024\n59.153.72.0 1024\n59.153.92.0 1024\n59.153.116.0 1024\n59.153.136.0 1024\n59.153.152.0 1024\n59.153.164.0 1024\n59.153.168.0 1024\n59.153.172.0 1024\n59.153.176.0 1024\n59.153.180.0 1024\n59.153.184.0 1024\n59.153.188.0 1024\n59.153.192.0 1024\n59.155.0.0 65536\n59.172.0.0 131072\n59.174.0.0 131072\n59.191.0.0 32768\n59.192.0.0 4194304\n60.0.0.0 524288\n60.8.0.0 131072\n60.10.0.0 65536\n60.11.0.0 65536\n60.12.0.0 65536\n60.13.0.0 16384\n60.13.64.0 16384\n60.13.128.0 32768\n60.14.0.0 131072\n60.16.0.0 524288\n60.24.0.0 262144\n60.28.0.0 131072\n60.30.0.0 65536\n60.31.0.0 65536\n60.55.0.0 65536\n60.63.0.0 65536\n60.160.0.0 131072\n60.162.0.0 131072\n60.164.0.0 131072\n60.166.0.0 131072\n60.168.0.0 524288\n60.176.0.0 1048576\n60.194.0.0 131072\n60.200.0.0 262144\n60.204.0.0 65536\n60.205.0.0 65536\n60.206.0.0 131072\n60.208.0.0 524288\n60.216.0.0 131072\n60.218.0.0 131072\n60.220.0.0 262144\n60.232.0.0 131072\n60.235.0.0 65536\n60.245.128.0 32768\n60.247.0.0 65536\n60.252.0.0 65536\n60.253.128.0 32768\n60.255.0.0 65536\n61.4.80.0 1024\n61.4.84.0 1024\n61.4.88.0 2048\n61.4.176.0 4096\n61.8.160.0 4096\n61.14.212.0 1024\n61.14.216.0 1024\n61.14.220.0 1024\n61.14.240.0 1024\n61.14.244.0 1024\n61.28.0.0 4096\n61.28.16.0 4096\n61.28.32.0 8192\n61.28.64.0 16384\n61.29.128.0 16384\n61.29.192.0 8192\n61.29.224.0 4096\n61.29.240.0 1024\n61.29.248.0 1024\n61.45.128.0 16384\n61.45.224.0 4096\n61.47.128.0 16384\n61.48.0.0 262144\n61.52.0.0 131072\n61.54.0.0 65536\n61.55.0.0 65536\n61.87.192.0 16384\n61.128.0.0 131072\n61.130.0.0 131072\n61.132.0.0 65536\n61.133.0.0 32768\n61.133.128.0 32768\n61.134.0.0 16384\n61.134.64.0 8192\n61.134.96.0 8192\n61.134.128.0 16384\n61.134.192.0 16384\n61.135.0.0 65536\n61.136.0.0 16384\n61.136.64.0 16384\n61.136.128.0 32768\n61.137.0.0 32768\n61.137.128.0 32768\n61.138.0.0 16384\n61.138.64.0 16384\n61.138.128.0 16384\n61.138.192.0 16384\n61.139.0.0 32768\n61.139.128.0 16384\n61.139.192.0 16384\n61.140.0.0 262144\n61.144.0.0 262144\n61.148.0.0 131072\n61.150.0.0 131072\n61.152.0.0 65536\n61.153.0.0 65536\n61.154.0.0 131072\n61.156.0.0 65536\n61.157.0.0 65536\n61.158.0.0 32768\n61.158.128.0 32768\n61.159.0.0 16384\n61.159.64.0 16384\n61.159.128.0 32768\n61.160.0.0 65536\n61.161.0.0 16384\n61.161.64.0 16384\n61.161.128.0 32768\n61.162.0.0 65536\n61.163.0.0 65536\n61.164.0.0 65536\n61.165.0.0 65536\n61.166.0.0 65536\n61.167.0.0 65536\n61.168.0.0 65536\n61.169.0.0 65536\n61.170.0.0 131072\n61.172.0.0 262144\n61.176.0.0 65536\n61.177.0.0 65536\n61.178.0.0 65536\n61.179.0.0 65536\n61.180.0.0 32768\n61.180.128.0 32768\n61.181.0.0 65536\n61.182.0.0 65536\n61.183.0.0 65536\n61.184.0.0 262144\n61.188.0.0 65536\n61.189.0.0 32768\n61.189.128.0 32768\n61.190.0.0 131072\n61.232.0.0 262144\n61.236.0.0 131072\n61.240.0.0 262144\n62.234.0.0 65536\n68.79.0.0 16384\n69.230.192.0 16384\n69.231.128.0 16384\n69.234.192.0 16384\n69.235.128.0 16384\n71.131.192.0 16384\n71.132.0.0 16384\n71.136.64.0 16384\n71.137.0.0 16384\n81.68.0.0 262144\n82.156.0.0 131072\n94.191.0.0 32768\n101.0.0.0 1024\n101.1.0.0 1024\n101.2.172.0 1024\n101.4.0.0 262144\n101.16.0.0 1048576\n101.33.128.0 32768\n101.34.0.0 131072\n101.36.0.0 16384\n101.36.64.0 8192\n101.36.128.0 32768\n101.37.0.0 65536\n101.38.0.0 131072\n101.40.0.0 131072\n101.42.0.0 131072\n101.48.0.0 131072\n101.50.8.0 1024\n101.50.12.0 1024\n101.50.56.0 1024\n101.52.0.0 65536\n101.53.100.0 1024\n101.54.0.0 65536\n101.55.224.0 2048\n101.64.0.0 524288\n101.72.0.0 262144\n101.76.0.0 131072\n101.78.0.0 1024\n101.78.32.0 8192\n101.80.0.0 1048576\n101.96.0.0 2048\n101.96.8.0 1024\n101.96.16.0 4096\n101.96.128.0 32768\n101.99.96.0 8192\n101.101.64.0 8192\n101.101.100.0 256\n101.101.102.0 512\n101.101.104.0 2048\n101.101.112.0 4096\n101.102.64.0 8192\n101.102.100.0 512\n101.102.102.0 256\n101.102.104.0 2048\n101.102.112.0 4096\n101.104.0.0 262144\n101.110.64.0 8192\n101.110.96.0 4096\n101.110.116.0 1024\n101.110.120.0 2048\n101.120.0.0 262144\n101.124.0.0 131072\n101.126.0.0 65536\n101.128.0.0 1024\n101.128.8.0 2048\n101.128.16.0 4096\n101.128.32.0 8192\n101.129.0.0 65536\n101.130.0.0 131072\n101.132.0.0 262144\n101.144.0.0 1048576\n101.192.0.0 262144\n101.196.0.0 65536\n101.197.0.0 65536\n101.198.0.0 131072\n101.200.0.0 131072\n101.203.128.0 8192\n101.203.160.0 2048\n101.203.172.0 1024\n101.203.176.0 4096\n101.204.0.0 262144\n101.224.0.0 524288\n101.232.0.0 131072\n101.234.64.0 2048\n101.234.76.0 1024\n101.234.80.0 4096\n101.234.96.0 8192\n101.236.0.0 262144\n101.240.0.0 262144\n101.244.0.0 65536\n101.245.0.0 65536\n101.246.0.0 131072\n101.248.0.0 131072\n101.251.0.0 1024\n101.251.8.0 2048\n101.251.16.0 4096\n101.251.32.0 8192\n101.251.64.0 16384\n101.251.128.0 32768\n101.252.0.0 131072\n101.254.0.0 65536\n103.1.8.0 1024\n103.1.20.0 1024\n103.1.24.0 1024\n103.1.72.0 1024\n103.1.88.0 1024\n103.1.168.0 1024\n103.2.108.0 1024\n103.2.156.0 1024\n103.2.164.0 1024\n103.2.188.0 512\n103.2.200.0 1024\n103.2.204.0 1024\n103.2.208.0 1024\n103.2.212.0 1024\n103.3.84.0 1024\n103.3.88.0 1024\n103.3.92.0 1024\n103.3.96.0 1024\n103.3.100.0 1024\n103.3.104.0 1024\n103.3.108.0 1024\n103.3.112.0 1024\n103.3.116.0 1024\n103.3.120.0 1024\n103.3.124.0 1024\n103.3.128.0 1024\n103.3.132.0 1024\n103.3.136.0 1024\n103.3.140.0 1024\n103.3.148.0 1024\n103.3.152.0 1024\n103.3.156.0 1024\n103.4.56.0 1024\n103.4.168.0 1024\n103.4.184.0 1024\n103.4.224.0 1024\n103.5.36.0 1024\n103.5.52.0 1024\n103.5.56.0 1024\n103.5.152.0 1024\n103.5.168.0 1024\n103.5.192.0 1024\n103.5.252.0 1024\n103.6.76.0 1024\n103.6.108.0 1024\n103.6.220.0 1024\n103.6.228.0 1024\n103.7.28.0 1024\n103.7.140.0 1024\n103.7.212.0 1024\n103.7.216.0 1024\n103.7.220.0 1024\n103.8.0.0 1024\n103.8.4.0 1024\n103.8.8.0 1024\n103.8.32.0 1024\n103.8.52.0 1024\n103.8.68.0 1024\n103.8.108.0 1024\n103.8.156.0 1024\n103.8.200.0 1024\n103.8.204.0 1024\n103.8.220.0 1024\n103.9.8.0 1024\n103.9.24.0 1024\n103.9.108.0 1024\n103.9.152.0 1024\n103.9.248.0 1024\n103.9.252.0 1024\n103.10.0.0 1024\n103.10.16.0 1024\n103.10.84.0 1024\n103.10.140.0 1024\n103.11.16.0 1024\n103.11.168.0 1024\n103.11.180.0 1024\n103.12.32.0 1024\n103.12.68.0 512\n103.12.92.0 1024\n103.12.98.0 512\n103.12.136.0 1024\n103.12.184.0 1024\n103.12.232.0 1024\n103.13.12.0 1024\n103.13.124.0 1024\n103.13.144.0 1024\n103.13.196.0 1024\n103.13.220.0 1024\n103.13.244.0 1024\n103.14.84.0 1024\n103.14.100.0 1024\n103.14.132.0 1024\n103.14.136.0 1024\n103.14.156.0 1024\n103.14.240.0 1024\n103.15.4.0 1024\n103.15.8.0 1024\n103.15.16.0 1024\n103.15.96.0 1024\n103.15.200.0 1024\n103.16.52.0 1024\n103.16.80.0 1024\n103.16.84.0 1024\n103.16.88.0 1024\n103.16.108.0 1024\n103.16.124.0 1024\n103.17.40.0 1024\n103.17.64.0 1024\n103.17.120.0 1024\n103.17.136.0 1024\n103.17.160.0 1024\n103.17.204.0 1024\n103.17.228.0 1024\n103.18.186.0 512\n103.18.192.0 1024\n103.18.206.0 512\n103.18.208.0 1024\n103.18.212.0 1024\n103.18.224.0 1024\n103.19.12.0 1024\n103.19.40.0 1024\n103.19.44.0 1024\n103.19.50.0 512\n103.19.64.0 1024\n103.19.68.0 1024\n103.19.72.0 1024\n103.19.232.0 1024\n103.20.12.0 1024\n103.20.32.0 1024\n103.20.44.0 1024\n103.20.68.0 1024\n103.20.112.0 1024\n103.20.128.0 1024\n103.20.160.0 1024\n103.20.248.0 1024\n103.21.98.0 512\n103.21.102.0 512\n103.21.112.0 1024\n103.21.116.0 1024\n103.21.136.0 1024\n103.21.140.0 1024\n103.21.176.0 1024\n103.21.208.0 1024\n103.21.240.0 1024\n103.22.0.0 1024\n103.22.4.0 1024\n103.22.8.0 1024\n103.22.12.0 1024\n103.22.16.0 1024\n103.22.20.0 1024\n103.22.24.0 1024\n103.22.28.0 1024\n103.22.32.0 1024\n103.22.36.0 1024\n103.22.40.0 1024\n103.22.44.0 1024\n103.22.48.0 1024\n103.22.52.0 1024\n103.22.56.0 1024\n103.22.60.0 1024\n103.22.64.0 1024\n103.22.68.0 1024\n103.22.72.0 1024\n103.22.76.0 1024\n103.22.80.0 1024\n103.22.84.0 1024\n103.22.88.0 1024\n103.22.92.0 1024\n103.22.100.0 1024\n103.22.104.0 1024\n103.22.108.0 1024\n103.22.112.0 1024\n103.22.116.0 1024\n103.22.120.0 1024\n103.22.124.0 1024\n103.22.188.0 1024\n103.22.228.0 1024\n103.22.252.0 1024\n103.23.8.0 1024\n103.23.56.0 1024\n103.23.160.0 1024\n103.23.164.0 1024\n103.23.176.0 1024\n103.23.228.0 1024\n103.24.24.0 1024\n103.24.116.0 1024\n103.24.128.0 1024\n103.24.144.0 1024\n103.24.176.0 1024\n103.24.184.0 1024\n103.24.220.0 1024\n103.24.228.0 1024\n103.24.252.0 1024\n103.25.8.0 512\n103.25.20.0 1024\n103.25.24.0 1024\n103.25.28.0 1024\n103.25.32.0 1024\n103.25.36.0 1024\n103.25.40.0 1024\n103.25.48.0 1024\n103.25.64.0 1024\n103.25.68.0 1024\n103.25.148.0 1024\n103.25.156.0 1024\n103.25.216.0 1024\n103.26.0.0 1024\n103.26.64.0 1024\n103.26.76.0 1024\n103.26.132.0 1024\n103.26.156.0 1024\n103.26.160.0 1024\n103.26.228.0 1024\n103.26.240.0 1024\n103.27.4.0 1024\n103.27.12.0 1024\n103.27.24.0 1024\n103.27.56.0 1024\n103.27.96.0 1024\n103.27.184.0 1024\n103.27.208.0 1024\n103.27.212.0 1024\n103.27.240.0 1024\n103.28.4.0 1024\n103.28.8.0 1024\n103.28.184.0 1024\n103.28.204.0 1024\n103.28.212.0 1024\n103.29.16.0 1024\n103.29.24.0 512\n103.29.29.0 256\n103.29.128.0 1024\n103.29.132.0 1024\n103.29.136.0 1024\n103.29.236.0 512\n103.30.20.0 1024\n103.30.96.0 1024\n103.30.104.0 512\n103.30.106.0 512\n103.30.148.0 1024\n103.30.200.0 1024\n103.30.228.0 1024\n103.30.236.0 1024\n103.31.0.0 1024\n103.31.48.0 1024\n103.31.52.0 1024\n103.31.56.0 1024\n103.31.60.0 1024\n103.31.64.0 1024\n103.31.68.0 1024\n103.31.148.0 1024\n103.31.160.0 1024\n103.31.168.0 1024\n103.31.200.0 1024\n103.31.236.0 1024\n103.31.242.0 512\n103.32.0.0 1024\n103.32.4.0 1024\n103.32.8.0 1024\n103.32.12.0 1024\n103.32.16.0 1024\n103.32.20.0 1024\n103.32.24.0 1024\n103.32.28.0 1024\n103.32.32.0 1024\n103.32.36.0 1024\n103.32.40.0 1024\n103.32.44.0 1024\n103.32.48.0 1024\n103.32.52.0 1024\n103.32.56.0 1024\n103.32.60.0 1024\n103.32.64.0 1024\n103.32.68.0 1024\n103.32.72.0 1024\n103.32.76.0 1024\n103.32.80.0 1024\n103.32.84.0 1024\n103.32.88.0 1024\n103.32.92.0 1024\n103.32.96.0 1024\n103.32.100.0 1024\n103.32.104.0 1024\n103.32.108.0 1024\n103.32.112.0 1024\n103.32.116.0 1024\n103.32.120.0 1024\n103.32.124.0 1024\n103.32.128.0 1024\n103.32.132.0 1024\n103.32.136.0 1024\n103.32.140.0 1024\n103.32.144.0 1024\n103.32.148.0 1024\n103.32.152.0 1024\n103.32.156.0 1024\n103.32.160.0 1024\n103.32.164.0 1024\n103.32.168.0 1024\n103.32.172.0 1024\n103.32.176.0 1024\n103.32.180.0 1024\n103.32.184.0 1024\n103.32.188.0 1024\n103.32.192.0 1024\n103.32.196.0 1024\n103.32.200.0 1024\n103.32.204.0 1024\n103.32.208.0 1024\n103.32.212.0 1024\n103.32.216.0 1024\n103.32.220.0 1024\n103.32.224.0 1024\n103.32.228.0 1024\n103.32.232.0 1024\n103.32.236.0 1024\n103.32.240.0 1024\n103.32.244.0 1024\n103.32.248.0 1024\n103.32.252.0 1024\n103.33.0.0 1024\n103.33.4.0 1024\n103.33.8.0 1024\n103.33.12.0 1024\n103.33.16.0 1024\n103.33.20.0 1024\n103.33.24.0 1024\n103.33.28.0 1024\n103.33.32.0 1024\n103.33.36.0 1024\n103.33.40.0 1024\n103.33.44.0 1024\n103.33.48.0 1024\n103.33.52.0 1024\n103.33.56.0 1024\n103.33.60.0 1024\n103.33.64.0 1024\n103.33.68.0 1024\n103.33.72.0 1024\n103.33.76.0 1024\n103.33.80.0 1024\n103.33.84.0 1024\n103.33.88.0 1024\n103.33.92.0 1024\n103.33.96.0 1024\n103.33.100.0 1024\n103.33.104.0 1024\n103.33.108.0 1024\n103.33.112.0 1024\n103.33.116.0 1024\n103.33.120.0 1024\n103.33.124.0 1024\n103.33.128.0 1024\n103.33.132.0 1024\n103.33.136.0 1024\n103.33.140.0 1024\n103.33.144.0 1024\n103.33.148.0 1024\n103.33.152.0 1024\n103.33.156.0 1024\n103.33.160.0 1024\n103.33.164.0 1024\n103.33.168.0 1024\n103.33.172.0 1024\n103.33.176.0 1024\n103.33.180.0 1024\n103.33.184.0 1024\n103.33.188.0 1024\n103.33.192.0 1024\n103.33.196.0 1024\n103.33.200.0 1024\n103.33.204.0 1024\n103.33.208.0 1024\n103.33.212.0 1024\n103.33.216.0 1024\n103.33.220.0 1024\n103.33.224.0 1024\n103.33.228.0 1024\n103.33.232.0 1024\n103.33.236.0 1024\n103.33.240.0 1024\n103.33.244.0 1024\n103.33.248.0 1024\n103.33.252.0 1024\n103.34.0.0 1024\n103.34.4.0 1024\n103.34.8.0 1024\n103.34.12.0 1024\n103.34.16.0 1024\n103.34.20.0 1024\n103.34.24.0 1024\n103.34.28.0 1024\n103.34.32.0 1024\n103.34.36.0 1024\n103.34.40.0 1024\n103.34.44.0 1024\n103.34.48.0 1024\n103.34.52.0 1024\n103.34.56.0 1024\n103.34.60.0 1024\n103.34.64.0 1024\n103.34.68.0 1024\n103.34.72.0 1024\n103.34.76.0 1024\n103.34.80.0 1024\n103.34.84.0 1024\n103.34.88.0 1024\n103.34.92.0 1024\n103.34.96.0 1024\n103.34.100.0 1024\n103.34.104.0 1024\n103.34.108.0 1024\n103.34.112.0 1024\n103.34.116.0 1024\n103.34.120.0 1024\n103.34.124.0 1024\n103.34.128.0 1024\n103.34.132.0 1024\n103.34.136.0 1024\n103.34.140.0 1024\n103.34.144.0 1024\n103.34.148.0 1024\n103.34.152.0 1024\n103.34.156.0 1024\n103.34.160.0 1024\n103.34.164.0 1024\n103.34.168.0 1024\n103.34.172.0 1024\n103.34.176.0 1024\n103.34.180.0 1024\n103.34.184.0 1024\n103.34.188.0 1024\n103.34.192.0 1024\n103.34.196.0 1024\n103.34.200.0 1024\n103.34.204.0 1024\n103.34.208.0 1024\n103.34.212.0 1024\n103.34.216.0 1024\n103.34.220.0 1024\n103.34.224.0 1024\n103.34.228.0 1024\n103.34.232.0 1024\n103.34.236.0 1024\n103.34.240.0 1024\n103.34.244.0 1024\n103.34.248.0 1024\n103.34.252.0 1024\n103.35.0.0 1024\n103.35.4.0 1024\n103.35.8.0 1024\n103.35.12.0 1024\n103.35.16.0 1024\n103.35.20.0 1024\n103.35.24.0 1024\n103.35.28.0 1024\n103.35.32.0 1024\n103.35.36.0 1024\n103.35.40.0 1024\n103.35.44.0 1024\n103.35.48.0 1024\n103.35.104.0 1024\n103.35.116.0 1024\n103.35.180.0 1024\n103.35.220.0 1024\n103.36.28.0 1024\n103.36.36.0 1024\n103.36.56.0 1024\n103.36.60.0 1024\n103.36.64.0 1024\n103.36.72.0 1024\n103.36.96.0 1024\n103.36.132.0 1024\n103.36.136.0 1024\n103.36.160.0 1024\n103.36.164.0 1024\n103.36.168.0 1024\n103.36.172.0 1024\n103.36.176.0 1024\n103.36.180.0 1024\n103.36.184.0 1024\n103.36.188.0 1024\n103.36.192.0 1024\n103.36.196.0 1024\n103.36.200.0 1024\n103.36.204.0 1024\n103.36.208.0 1024\n103.36.212.0 1024\n103.36.216.0 1024\n103.36.220.0 1024\n103.36.224.0 1024\n103.36.228.0 1024\n103.36.232.0 1024\n103.36.236.0 1024\n103.36.240.0 1024\n103.36.244.0 1024\n103.37.12.0 1024\n103.37.16.0 1024\n103.37.24.0 1024\n103.37.44.0 1024\n103.37.52.0 1024\n103.37.56.0 1024\n103.37.72.0 1024\n103.37.100.0 1024\n103.37.104.0 1024\n103.37.136.0 1024\n103.37.140.0 1024\n103.37.144.0 1024\n103.37.148.0 1024\n103.37.152.0 1024\n103.37.156.0 1024\n103.37.160.0 1024\n103.37.164.0 1024\n103.37.172.0 1024\n103.37.176.0 1024\n103.37.188.0 1024\n103.37.208.0 1024\n103.37.212.0 1024\n103.37.216.0 2048\n103.37.248.0 1024\n103.37.252.0 1024\n103.38.0.0 1024\n103.38.32.0 1024\n103.38.40.0 1024\n103.38.44.0 1024\n103.38.56.0 1024\n103.38.76.0 1024\n103.38.84.0 1024\n103.38.92.0 1024\n103.38.96.0 1024\n103.38.116.0 1024\n103.38.132.0 1024\n103.38.140.0 1024\n103.38.224.0 1024\n103.38.228.0 1024\n103.38.232.0 1024\n103.39.64.0 1024\n103.39.88.0 1024\n103.39.100.0 1024\n103.39.104.0 1024\n103.39.160.0 1024\n103.39.164.0 1024\n103.39.168.0 1024\n103.39.172.0 1024\n103.39.176.0 1024\n103.39.180.0 1024\n103.39.184.0 1024\n103.39.188.0 1024\n103.39.200.0 1024\n103.39.204.0 1024\n103.39.208.0 1024\n103.39.212.0 1024\n103.39.216.0 1024\n103.39.220.0 1024\n103.39.224.0 1024\n103.39.228.0 1024\n103.39.232.0 1024\n103.40.12.0 1024\n103.40.16.0 1024\n103.40.20.0 1024\n103.40.24.0 1024\n103.40.28.0 1024\n103.40.32.0 1024\n103.40.36.0 1024\n103.40.40.0 1024\n103.40.44.0 1024\n103.40.88.0 1024\n103.40.100.0 1024\n103.40.158.0 512\n103.40.174.0 512\n103.40.192.0 1024\n103.40.212.0 1024\n103.40.220.0 1024\n103.40.228.0 1024\n103.40.232.0 1024\n103.40.236.0 1024\n103.40.240.0 1024\n103.40.244.0 1024\n103.40.248.0 1024\n103.40.252.0 1024\n103.41.0.0 1024\n103.41.16.0 1024\n103.41.52.0 1024\n103.41.116.0 1024\n103.41.140.0 1024\n103.41.148.0 1024\n103.41.152.0 1024\n103.41.160.0 1024\n103.41.164.0 1024\n103.41.220.0 1024\n103.41.224.0 1024\n103.41.228.0 1024\n103.41.232.0 1024\n103.42.8.0 1024\n103.42.24.0 1024\n103.42.28.0 1024\n103.42.32.0 1024\n103.42.64.0 1024\n103.42.68.0 1024\n103.42.76.0 1024\n103.42.104.0 1024\n103.42.180.0 1024\n103.42.232.0 1024\n103.43.16.0 1024\n103.43.84.0 1024\n103.43.96.0 1024\n103.43.100.0 1024\n103.43.104.0 1024\n103.43.124.0 1024\n103.43.132.0 1024\n103.43.184.0 1024\n103.43.192.0 1024\n103.43.196.0 1024\n103.43.208.0 1024\n103.43.220.0 1024\n103.43.224.0 1024\n103.43.240.0 1024\n103.44.56.0 1024\n103.44.80.0 1024\n103.44.120.0 1024\n103.44.124.0 1024\n103.44.132.0 1024\n103.44.144.0 1024\n103.44.168.0 1024\n103.44.176.0 1024\n103.44.180.0 1024\n103.44.184.0 1024\n103.44.188.0 1024\n103.44.192.0 1024\n103.44.196.0 1024\n103.44.200.0 1024\n103.44.204.0 1024\n103.44.224.0 1024\n103.44.236.0 1024\n103.44.240.0 1024\n103.44.244.0 1024\n103.44.248.0 1024\n103.44.252.0 1024\n103.45.0.0 1024\n103.45.4.0 1024\n103.45.8.0 1024\n103.45.12.0 1024\n103.45.16.0 1024\n103.45.20.0 1024\n103.45.24.0 1024\n103.45.28.0 1024\n103.45.32.0 1024\n103.45.36.0 1024\n103.45.40.0 1024\n103.45.44.0 1024\n103.45.48.0 1024\n103.45.52.0 1024\n103.45.56.0 1024\n103.45.60.0 1024\n103.45.72.0 1024\n103.45.76.0 1024\n103.45.80.0 1024\n103.45.84.0 1024\n103.45.88.0 1024\n103.45.92.0 1024\n103.45.96.0 1024\n103.45.100.0 1024\n103.45.104.0 1024\n103.45.108.0 1024\n103.45.112.0 1024\n103.45.116.0 1024\n103.45.120.0 1024\n103.45.124.0 1024\n103.45.128.0 1024\n103.45.132.0 1024\n103.45.136.0 1024\n103.45.140.0 1024\n103.45.144.0 1024\n103.45.148.0 1024\n103.45.152.0 1024\n103.45.156.0 1024\n103.45.160.0 1024\n103.45.164.0 1024\n103.45.168.0 1024\n103.45.172.0 1024\n103.45.176.0 1024\n103.45.180.0 1024\n103.45.184.0 1024\n103.45.188.0 1024\n103.45.192.0 1024\n103.45.196.0 1024\n103.45.200.0 1024\n103.45.204.0 1024\n103.45.208.0 1024\n103.45.212.0 1024\n103.45.216.0 1024\n103.45.220.0 1024\n103.45.224.0 1024\n103.45.248.0 1024\n103.46.0.0 1024\n103.46.12.0 1024\n103.46.16.0 1024\n103.46.20.0 1024\n103.46.24.0 1024\n103.46.28.0 1024\n103.46.32.0 1024\n103.46.36.0 1024\n103.46.40.0 1024\n103.46.44.0 1024\n103.46.48.0 1024\n103.46.52.0 1024\n103.46.56.0 1024\n103.46.60.0 1024\n103.46.64.0 1024\n103.46.68.0 1024\n103.46.72.0 1024\n103.46.76.0 1024\n103.46.80.0 1024\n103.46.84.0 1024\n103.46.88.0 1024\n103.46.92.0 1024\n103.46.96.0 1024\n103.46.100.0 1024\n103.46.104.0 1024\n103.46.108.0 1024\n103.46.112.0 1024\n103.46.116.0 1024\n103.46.120.0 1024\n103.46.124.0 1024\n103.46.128.0 1024\n103.46.132.0 1024\n103.46.136.0 1024\n103.46.152.0 1024\n103.46.156.0 1024\n103.46.160.0 1024\n103.46.164.0 1024\n103.46.168.0 1024\n103.46.172.0 1024\n103.46.176.0 1024\n103.46.180.0 1024\n103.46.244.0 1024\n103.46.248.0 1024\n103.47.4.0 1024\n103.47.20.0 1024\n103.47.36.0 1024\n103.47.40.0 1024\n103.47.48.0 1024\n103.47.80.0 1024\n103.47.96.0 1024\n103.47.108.0 1024\n103.47.116.0 1024\n103.47.120.0 1024\n103.47.136.0 1024\n103.47.140.0 1024\n103.47.212.0 1024\n103.48.52.0 1024\n103.48.92.0 1024\n103.48.148.0 1024\n103.48.152.0 1024\n103.48.156.0 1024\n103.48.202.0 512\n103.48.216.0 1024\n103.48.220.0 1024\n103.48.224.0 1024\n103.48.228.0 1024\n103.48.232.0 1024\n103.48.236.0 1024\n103.48.240.0 1024\n103.48.244.0 1024\n103.49.12.0 1024\n103.49.20.0 1024\n103.49.72.0 1024\n103.49.76.0 1024\n103.49.96.0 1024\n103.49.108.0 1024\n103.49.128.0 1024\n103.49.176.0 1024\n103.49.180.0 1024\n103.49.196.0 1024\n103.50.36.0 1024\n103.50.44.0 1024\n103.50.48.0 1024\n103.50.52.0 1024\n103.50.56.0 1024\n103.50.60.0 1024\n103.50.64.0 1024\n103.50.68.0 1024\n103.50.72.0 1024\n103.50.108.0 1024\n103.50.112.0 1024\n103.50.116.0 1024\n103.50.120.0 1024\n103.50.124.0 1024\n103.50.132.0 1024\n103.50.136.0 1024\n103.50.140.0 1024\n103.50.172.0 1024\n103.50.176.0 1024\n103.50.180.0 1024\n103.50.184.0 1024\n103.50.188.0 1024\n103.50.192.0 1024\n103.50.196.0 1024\n103.50.200.0 1024\n103.50.220.0 1024\n103.50.224.0 1024\n103.50.228.0 1024\n103.50.232.0 1024\n103.50.236.0 1024\n103.50.240.0 1024\n103.50.244.0 1024\n103.50.248.0 1024\n103.52.40.0 1024\n103.52.72.0 1024\n103.52.76.0 1024\n103.52.80.0 1024\n103.52.84.0 1024\n103.52.96.0 1024\n103.52.100.0 1024\n103.52.104.0 1024\n103.52.160.0 1024\n103.52.164.0 1024\n103.52.172.0 1024\n103.52.176.0 1024\n103.52.184.0 1024\n103.52.196.0 1024\n103.53.64.0 1024\n103.53.68.0 1024\n103.53.92.0 1024\n103.53.100.0 1024\n103.53.124.0 1024\n103.53.128.0 1024\n103.53.132.0 1024\n103.53.136.0 1024\n103.53.140.0 1024\n103.53.144.0 1024\n103.53.180.0 1024\n103.53.204.0 1024\n103.53.208.0 1024\n103.53.212.0 1024\n103.53.236.0 1024\n103.53.248.0 1024\n103.54.8.0 1024\n103.54.48.0 1024\n103.54.160.0 1024\n103.54.164.0 1024\n103.54.212.0 1024\n103.54.240.0 1024\n103.55.80.0 1024\n103.55.120.0 1024\n103.55.152.0 1024\n103.55.172.0 1024\n103.55.204.0 1024\n103.55.208.0 1024\n103.55.228.0 1024\n103.55.236.0 1024\n103.56.8.0 1024\n103.56.16.0 1024\n103.56.20.0 1024\n103.56.32.0 1024\n103.56.56.0 1024\n103.56.60.0 1024\n103.56.72.0 1024\n103.56.76.0 1024\n103.56.94.0 512\n103.56.100.0 1024\n103.56.104.0 1024\n103.56.140.0 1024\n103.56.152.0 1024\n103.56.184.0 1024\n103.56.200.0 1024\n103.57.12.0 1024\n103.57.52.0 1024\n103.57.56.0 1024\n103.57.76.0 1024\n103.57.136.0 1024\n103.57.196.0 1024\n103.58.24.0 1024\n103.59.76.0 1024\n103.59.100.0 1024\n103.59.112.0 1024\n103.59.116.0 1024\n103.59.120.0 1024\n103.59.124.0 1024\n103.59.128.0 1024\n103.59.148.0 1024\n103.59.164.0 1024\n103.59.168.0 512\n103.60.32.0 1024\n103.60.44.0 1024\n103.60.164.0 1024\n103.60.228.0 1024\n103.60.236.0 1024\n103.61.60.0 1024\n103.61.104.0 1024\n103.61.140.0 1024\n103.61.152.0 1024\n103.61.156.0 1024\n103.61.160.0 1024\n103.61.172.0 1024\n103.61.176.0 1024\n103.61.188.0 1024\n103.62.24.0 1024\n103.62.52.0 1024\n103.62.72.0 1024\n103.62.76.0 1024\n103.62.80.0 1024\n103.62.84.0 1024\n103.62.88.0 1024\n103.62.96.0 1024\n103.62.100.0 1024\n103.62.104.0 1024\n103.62.108.0 1024\n103.62.112.0 1024\n103.62.116.0 1024\n103.62.120.0 1024\n103.62.124.0 1024\n103.62.128.0 1024\n103.62.132.0 1024\n103.62.156.0 1024\n103.62.160.0 1024\n103.62.164.0 1024\n103.62.168.0 1024\n103.62.172.0 1024\n103.62.176.0 1024\n103.62.180.0 1024\n103.62.184.0 1024\n103.62.188.0 1024\n103.62.192.0 1024\n103.62.204.0 1024\n103.62.208.0 1024\n103.62.212.0 1024\n103.62.216.0 1024\n103.62.220.0 1024\n103.62.224.0 1024\n103.63.32.0 1024\n103.63.36.0 1024\n103.63.40.0 1024\n103.63.44.0 1024\n103.63.48.0 1024\n103.63.52.0 1024\n103.63.56.0 1024\n103.63.60.0 1024\n103.63.64.0 1024\n103.63.68.0 1024\n103.63.72.0 1024\n103.63.76.0 1024\n103.63.80.0 1024\n103.63.84.0 1024\n103.63.88.0 1024\n103.63.140.0 1024\n103.63.144.0 1024\n103.63.152.0 1024\n103.63.160.0 1024\n103.63.164.0 1024\n103.63.168.0 1024\n103.63.172.0 1024\n103.63.176.0 1024\n103.63.180.0 1024\n103.63.184.0 1024\n103.63.192.0 1024\n103.63.196.0 1024\n103.63.200.0 1024\n103.63.204.0 1024\n103.63.208.0 1024\n103.63.240.0 1024\n103.63.244.0 1024\n103.63.248.0 1024\n103.63.252.0 1024\n103.64.0.0 1024\n103.64.4.0 1024\n103.64.24.0 1024\n103.64.28.0 1024\n103.64.32.0 1024\n103.64.36.0 1024\n103.64.40.0 1024\n103.64.44.0 1024\n103.64.48.0 1024\n103.64.52.0 1024\n103.64.56.0 1024\n103.64.60.0 1024\n103.64.64.0 1024\n103.64.68.0 1024\n103.64.72.0 1024\n103.64.76.0 1024\n103.64.80.0 1024\n103.64.84.0 1024\n103.64.88.0 1024\n103.64.92.0 1024\n103.64.96.0 1024\n103.64.100.0 1024\n103.64.104.0 1024\n103.64.108.0 1024\n103.64.112.0 1024\n103.64.116.0 1024\n103.64.120.0 1024\n103.64.124.0 1024\n103.64.140.0 1024\n103.64.144.0 1024\n103.64.152.0 1024\n103.64.156.0 1024\n103.64.160.0 1024\n103.64.164.0 1024\n103.64.168.0 1024\n103.64.172.0 1024\n103.64.176.0 1024\n103.64.180.0 1024\n103.64.184.0 1024\n103.64.188.0 1024\n103.64.192.0 1024\n103.64.196.0 1024\n103.64.200.0 1024\n103.64.204.0 1024\n103.64.208.0 1024\n103.64.212.0 1024\n103.64.216.0 1024\n103.64.220.0 1024\n103.64.224.0 1024\n103.64.228.0 1024\n103.64.232.0 1024\n103.64.236.0 1024\n103.64.240.0 1024\n103.64.244.0 1024\n103.64.248.0 1024\n103.64.252.0 1024\n103.65.0.0 1024\n103.65.4.0 1024\n103.65.8.0 1024\n103.65.12.0 1024\n103.65.16.0 1024\n103.65.36.0 1024\n103.65.40.0 1024\n103.65.48.0 1024\n103.65.52.0 1024\n103.65.56.0 1024\n103.65.60.0 1024\n103.65.64.0 1024\n103.65.68.0 1024\n103.65.72.0 1024\n103.65.76.0 1024\n103.65.80.0 1024\n103.65.84.0 1024\n103.65.88.0 1024\n103.65.92.0 1024\n103.65.100.0 1024\n103.65.104.0 1024\n103.65.108.0 1024\n103.65.112.0 1024\n103.65.144.0 1024\n103.65.148.0 1024\n103.65.152.0 1024\n103.65.156.0 1024\n103.65.160.0 1024\n103.65.164.0 1024\n103.65.168.0 1024\n103.65.172.0 1024\n103.65.204.0 512\n103.65.206.0 512\n103.65.224.0 512\n103.66.32.0 1024\n103.66.40.0 1024\n103.66.92.0 1024\n103.66.108.0 1024\n103.66.200.0 1024\n103.66.216.0 1024\n103.66.240.0 1024\n103.66.244.0 1024\n103.66.248.0 1024\n103.66.252.0 1024\n103.67.0.0 1024\n103.67.4.0 1024\n103.67.8.0 1024\n103.67.52.0 512\n103.67.100.0 1024\n103.67.104.0 1024\n103.67.108.0 1024\n103.67.112.0 1024\n103.67.116.0 1024\n103.67.120.0 1024\n103.67.124.0 1024\n103.67.128.0 1024\n103.67.132.0 1024\n103.67.136.0 1024\n103.67.140.0 1024\n103.67.144.0 1024\n103.67.148.0 1024\n103.67.172.0 1024\n103.67.192.0 1024\n103.67.212.0 1024\n103.67.252.0 1024\n103.68.64.0 1024\n103.68.88.0 1024\n103.68.100.0 1024\n103.68.128.0 1024\n103.68.192.0 1024\n103.69.16.0 1024\n103.69.62.0 512\n103.69.116.0 1024\n103.69.132.0 1024\n103.69.152.0 1024\n103.70.8.0 1024\n103.70.14.0 512\n103.70.148.0 1024\n103.70.220.0 1024\n103.70.224.0 1024\n103.70.236.0 1024\n103.70.252.0 1024\n103.71.0.0 1024\n103.71.48.0 1024\n103.71.68.0 1024\n103.71.72.0 1024\n103.71.80.0 1024\n103.71.84.0 1024\n103.71.88.0 1024\n103.71.120.0 1024\n103.71.124.0 1024\n103.71.128.0 1024\n103.71.144.0 1024\n103.71.196.0 1024\n103.71.200.0 1024\n103.71.232.0 1024\n103.72.12.0 1024\n103.72.16.0 1024\n103.72.20.0 1024\n103.72.24.0 1024\n103.72.28.0 1024\n103.72.32.0 1024\n103.72.36.0 1024\n103.72.40.0 1024\n103.72.44.0 1024\n103.72.48.0 1024\n103.72.52.0 1024\n103.72.112.0 1024\n103.72.116.0 1024\n103.72.120.0 1024\n103.72.124.0 1024\n103.72.128.0 1024\n103.72.132.0 1024\n103.72.148.0 1024\n103.72.172.0 1024\n103.72.180.0 1024\n103.72.224.0 1024\n103.72.228.0 1024\n103.72.232.0 1024\n103.72.236.0 1024\n103.72.240.0 1024\n103.72.244.0 1024\n103.72.248.0 1024\n103.72.252.0 1024\n103.73.0.0 1024\n103.73.4.0 1024\n103.73.8.0 1024\n103.73.12.0 1024\n103.73.16.0 1024\n103.73.20.0 1024\n103.73.24.0 1024\n103.73.28.0 1024\n103.73.48.0 1024\n103.73.116.0 1024\n103.73.120.0 1024\n103.73.128.0 1024\n103.73.132.0 1024\n103.73.136.0 1024\n103.73.140.0 1024\n103.73.144.0 1024\n103.73.168.0 1024\n103.73.176.0 1024\n103.73.204.0 1024\n103.73.208.0 1024\n103.73.240.0 1024\n103.73.244.0 1024\n103.73.248.0 1024\n103.74.24.0 1024\n103.74.28.0 1024\n103.74.32.0 1024\n103.74.36.0 1024\n103.74.40.0 1024\n103.74.44.0 1024\n103.74.48.0 1024\n103.74.56.0 1024\n103.74.60.0 1024\n103.74.80.0 1024\n103.74.124.0 1024\n103.74.148.0 1024\n103.74.152.0 1024\n103.74.156.0 1024\n103.74.204.0 1024\n103.74.232.0 1024\n103.75.82.0 512\n103.75.88.0 1024\n103.75.92.0 1024\n103.75.104.0 1024\n103.75.108.0 1024\n103.75.112.0 1024\n103.75.120.0 1024\n103.75.128.0 1024\n103.75.144.0 1024\n103.75.152.0 1024\n103.75.236.0 256\n103.76.60.0 1024\n103.76.64.0 1024\n103.76.68.0 1024\n103.76.72.0 1024\n103.76.92.0 1024\n103.76.216.0 1024\n103.76.220.0 1024\n103.76.224.0 1024\n103.77.28.0 1024\n103.77.52.0 1024\n103.77.56.0 1024\n103.77.72.0 1024\n103.77.88.0 1024\n103.77.92.0 1024\n103.77.132.0 1024\n103.77.148.0 1024\n103.77.220.0 1024\n103.78.56.0 1024\n103.78.60.0 1024\n103.78.64.0 1024\n103.78.68.0 1024\n103.78.124.0 1024\n103.78.172.0 1024\n103.78.176.0 1024\n103.78.196.0 1024\n103.78.228.0 1024\n103.79.24.0 1024\n103.79.28.0 1024\n103.79.36.0 1024\n103.79.40.0 1024\n103.79.44.0 1024\n103.79.52.0 1024\n103.79.56.0 1024\n103.79.60.0 1024\n103.79.64.0 1024\n103.79.68.0 1024\n103.79.80.0 1024\n103.79.84.0 1024\n103.79.136.0 1024\n103.79.188.0 1024\n103.79.192.0 1024\n103.79.196.0 1024\n103.79.200.0 1024\n103.79.204.0 1024\n103.79.208.0 1024\n103.79.212.0 1024\n103.79.228.0 512\n103.79.240.0 1024\n103.80.28.0 1024\n103.80.44.0 1024\n103.80.72.0 1024\n103.80.176.0 1024\n103.80.180.0 1024\n103.80.184.0 1024\n103.80.192.0 1024\n103.80.200.0 1024\n103.80.232.0 1024\n103.81.4.0 1024\n103.81.8.0 1024\n103.81.16.0 1024\n103.81.20.0 1024\n103.81.44.0 1024\n103.81.48.0 1024\n103.81.96.0 1024\n103.81.120.0 1024\n103.81.148.0 1024\n103.81.164.0 1024\n103.81.168.0 1024\n103.81.183.0 256\n103.81.184.0 1024\n103.81.200.0 1024\n103.81.232.0 1024\n103.82.52.0 1024\n103.82.60.0 1024\n103.82.68.0 1024\n103.82.84.0 1024\n103.82.104.0 1024\n103.82.224.0 1024\n103.82.236.0 1024\n103.83.44.0 1024\n103.83.52.0 1024\n103.83.60.0 1024\n103.83.64.0 1024\n103.83.72.0 1024\n103.83.112.0 1024\n103.83.120.0 1024\n103.83.180.0 1024\n103.84.0.0 1024\n103.84.12.0 1024\n103.84.16.0 1024\n103.84.20.0 1024\n103.84.24.0 1024\n103.84.28.0 1024\n103.84.48.0 1024\n103.84.64.0 1024\n103.84.72.0 1024\n103.84.136.0 1024\n103.84.170.0 512\n103.84.204.0 512\n103.85.20.0 1024\n103.85.24.0 1024\n103.85.44.0 1024\n103.85.48.0 1024\n103.85.84.0 1024\n103.85.136.0 1024\n103.85.144.0 1024\n103.85.164.0 1024\n103.85.168.0 1024\n103.85.172.0 1024\n103.85.176.0 1024\n103.85.186.0 512\n103.85.224.0 1024\n103.86.28.0 1024\n103.86.32.0 1024\n103.86.60.0 1024\n103.86.80.0 1024\n103.86.84.0 1024\n103.86.204.0 1024\n103.86.208.0 1024\n103.86.212.0 1024\n103.86.216.0 1024\n103.86.220.0 1024\n103.86.224.0 1024\n103.86.228.0 1024\n103.86.232.0 1024\n103.86.236.0 1024\n103.86.240.0 1024\n103.86.244.0 1024\n103.86.248.0 1024\n103.86.252.0 1024\n103.87.0.0 1024\n103.87.4.0 1024\n103.87.20.0 1024\n103.87.32.0 1024\n103.87.72.0 1024\n103.87.96.0 1024\n103.87.132.0 1024\n103.87.180.0 1024\n103.87.224.0 1024\n103.88.4.0 1024\n103.88.8.0 1024\n103.88.12.0 1024\n103.88.16.0 1024\n103.88.20.0 1024\n103.88.32.0 1024\n103.88.36.0 1024\n103.88.60.0 1024\n103.88.64.0 1024\n103.88.72.0 1024\n103.88.96.0 1024\n103.88.164.0 1024\n103.88.212.0 1024\n103.89.28.0 1024\n103.89.96.0 1024\n103.89.100.0 1024\n103.89.104.0 1024\n103.89.108.0 1024\n103.89.112.0 1024\n103.89.116.0 1024\n103.89.148.0 1024\n103.89.172.0 1024\n103.89.184.0 1024\n103.89.188.0 1024\n103.89.192.0 1024\n103.89.196.0 1024\n103.89.200.0 1024\n103.89.204.0 1024\n103.89.208.0 1024\n103.89.212.0 1024\n103.89.216.0 1024\n103.89.220.0 1024\n103.89.224.0 1024\n103.89.228.0 1024\n103.90.52.0 1024\n103.90.92.0 1024\n103.90.100.0 1024\n103.90.104.0 1024\n103.90.108.0 1024\n103.90.112.0 1024\n103.90.116.0 1024\n103.90.120.0 1024\n103.90.124.0 1024\n103.90.128.0 1024\n103.90.132.0 1024\n103.90.152.0 1024\n103.90.168.0 1024\n103.90.173.0 256\n103.90.176.0 1024\n103.90.188.0 1024\n103.90.192.0 1024\n103.91.36.0 1024\n103.91.40.0 1024\n103.91.108.0 1024\n103.91.112.0 512\n103.91.138.0 512\n103.91.152.0 1024\n103.91.176.0 1024\n103.91.200.0 1024\n103.91.208.0 1024\n103.91.212.0 1024\n103.91.236.0 1024\n103.91.252.0 1024\n103.92.0.0 1024\n103.92.4.0 1024\n103.92.8.0 1024\n103.92.12.0 1024\n103.92.48.0 1024\n103.92.52.0 1024\n103.92.56.0 1024\n103.92.60.0 1024\n103.92.64.0 1024\n103.92.68.0 1024\n103.92.72.0 1024\n103.92.76.0 1024\n103.92.80.0 1024\n103.92.86.0 256\n103.92.88.0 1024\n103.92.108.0 1024\n103.92.124.0 1024\n103.92.132.0 1024\n103.92.156.0 1024\n103.92.164.0 1024\n103.92.168.0 1024\n103.92.172.0 1024\n103.92.176.0 1024\n103.92.180.0 1024\n103.92.184.0 1024\n103.92.188.0 1024\n103.92.192.0 1024\n103.92.236.0 1024\n103.92.240.0 1024\n103.92.244.0 1024\n103.92.248.0 1024\n103.92.252.0 1024\n103.93.0.0 1024\n103.93.4.0 1024\n103.93.28.0 1024\n103.93.84.0 1024\n103.93.142.0 512\n103.93.152.0 1024\n103.93.180.0 1024\n103.93.204.0 1024\n103.94.12.0 1024\n103.94.20.0 1024\n103.94.28.0 1024\n103.94.32.0 1024\n103.94.36.0 1024\n103.94.40.0 1024\n103.94.44.0 1024\n103.94.72.0 1024\n103.94.88.0 1024\n103.94.116.0 1024\n103.94.160.0 1024\n103.94.200.0 1024\n103.95.52.0 1024\n103.95.68.0 1024\n103.95.88.0 1024\n103.95.92.0 1024\n103.95.128.0 1024\n103.95.136.0 1024\n103.95.140.0 1024\n103.95.144.0 1024\n103.95.152.0 1024\n103.95.216.0 1024\n103.95.220.0 1024\n103.95.224.0 1024\n103.95.236.0 1024\n103.95.240.0 1024\n103.95.244.0 1024\n103.95.248.0 1024\n103.95.252.0 1024\n103.96.0.0 1024\n103.96.8.0 1024\n103.96.124.0 1024\n103.96.136.0 1024\n103.96.140.0 256\n103.96.152.0 1024\n103.96.156.0 1024\n103.96.160.0 1024\n103.96.164.0 1024\n103.96.168.0 1024\n103.96.172.0 1024\n103.96.176.0 1024\n103.96.180.0 1024\n103.96.184.0 1024\n103.96.188.0 1024\n103.96.192.0 1024\n103.96.196.0 1024\n103.96.200.0 1024\n103.96.204.0 1024\n103.96.208.0 1024\n103.96.212.0 1024\n103.96.216.0 1024\n103.96.224.0 512\n103.97.8.0 1024\n103.97.12.0 1024\n103.97.16.0 4096\n103.97.32.0 1024\n103.97.36.0 1024\n103.97.40.0 1024\n103.97.56.0 1024\n103.97.60.0 1024\n103.97.64.0 1024\n103.97.68.0 1024\n103.97.72.0 1024\n103.97.80.0 1024\n103.97.112.0 1024\n103.97.116.0 1024\n103.97.128.0 1024\n103.97.144.0 1024\n103.97.148.0 1024\n103.97.188.0 1024\n103.97.192.0 1024\n103.97.228.0 512\n103.98.0.0 512\n103.98.28.0 512\n103.98.40.0 1024\n103.98.44.0 1024\n103.98.48.0 1024\n103.98.56.0 1024\n103.98.80.0 1024\n103.98.88.0 1024\n103.98.92.0 1024\n103.98.96.0 1024\n103.98.100.0 1024\n103.98.124.0 1024\n103.98.136.0 1024\n103.98.140.0 1024\n103.98.144.0 1024\n103.98.164.0 1024\n103.98.168.0 1024\n103.98.180.0 1024\n103.98.196.0 1024\n103.98.216.0 1024\n103.98.220.0 1024\n103.98.224.0 1024\n103.98.228.0 1024\n103.98.232.0 1024\n103.98.240.0 1024\n103.98.244.0 1024\n103.98.248.0 1024\n103.98.252.0 1024\n103.99.40.0 512\n103.99.52.0 1024\n103.99.56.0 1024\n103.99.60.0 1024\n103.99.76.0 1024\n103.99.104.0 1024\n103.99.116.0 1024\n103.99.120.0 1024\n103.99.152.0 1024\n103.99.220.0 1024\n103.99.232.0 1024\n103.99.236.0 1024\n103.100.0.0 1024\n103.100.32.0 1024\n103.100.40.0 1024\n103.100.48.0 1024\n103.100.52.0 1024\n103.100.56.0 1024\n103.100.60.0 1024\n103.100.64.0 1024\n103.100.68.0 1024\n103.100.88.0 1024\n103.100.116.0 1024\n103.100.144.0 1024\n103.100.236.0 1024\n103.100.240.0 1024\n103.100.248.0 1024\n103.100.252.0 1024\n103.101.4.0 1024\n103.101.8.0 1024\n103.101.12.0 1024\n103.101.28.0 1024\n103.101.60.0 1024\n103.101.120.0 1024\n103.101.124.0 1024\n103.101.144.0 1024\n103.101.148.0 1024\n103.101.180.0 1024\n103.101.184.0 1024\n103.102.76.0 1024\n103.102.80.0 1024\n103.102.168.0 1024\n103.102.172.0 1024\n103.102.180.0 1024\n103.102.184.0 1024\n103.102.188.0 1024\n103.102.192.0 1024\n103.102.196.0 1024\n103.102.200.0 1024\n103.102.208.0 1024\n103.102.212.0 1024\n103.103.12.0 1024\n103.103.16.0 1024\n103.103.36.0 1024\n103.103.72.0 1024\n103.103.176.0 1024\n103.103.188.0 1024\n103.103.200.0 1024\n103.103.204.0 1024\n103.103.220.0 1024\n103.103.224.0 2048\n103.103.232.0 1024\n103.103.248.0 2048\n103.104.0.0 2048\n103.104.36.0 1024\n103.104.40.0 1024\n103.104.64.0 1024\n103.104.104.0 1024\n103.104.152.0 1024\n103.104.168.0 1024\n103.104.188.0 1024\n103.104.198.0 512\n103.104.252.0 1024\n103.105.0.0 1024\n103.105.4.0 1024\n103.105.12.0 1024\n103.105.16.0 1024\n103.105.23.0 256\n103.105.60.0 1024\n103.105.116.0 1024\n103.105.132.0 1024\n103.105.180.0 1024\n103.105.184.0 1024\n103.105.200.0 1024\n103.105.204.0 1024\n103.105.220.0 1024\n103.106.36.0 1024\n103.106.40.0 1024\n103.106.44.0 1024\n103.106.60.0 1024\n103.106.68.0 1024\n103.106.96.0 1024\n103.106.120.0 1024\n103.106.128.0 1024\n103.106.132.0 1024\n103.106.160.0 1024\n103.106.196.0 1024\n103.106.202.0 512\n103.106.212.0 1024\n103.106.244.0 1024\n103.106.252.0 1024\n103.107.0.0 1024\n103.107.28.0 1024\n103.107.32.0 1024\n103.107.44.0 1024\n103.107.72.0 1024\n103.107.108.0 1024\n103.107.164.0 1024\n103.107.168.0 1024\n103.107.188.0 1024\n103.107.192.0 1024\n103.107.208.0 1024\n103.107.212.0 1024\n103.107.216.0 1024\n103.107.220.0 1024\n103.108.52.0 1024\n103.108.160.0 1024\n103.108.164.0 1024\n103.108.184.0 512\n103.108.192.0 1024\n103.108.196.0 1024\n103.108.208.0 1024\n103.108.212.0 1024\n103.108.224.0 1024\n103.108.244.0 1024\n103.109.20.0 1024\n103.109.48.0 1024\n103.109.88.0 1024\n103.109.106.0 512\n103.109.248.0 1024\n103.110.92.0 1024\n103.110.116.0 1024\n103.110.132.0 1024\n103.110.136.0 1024\n103.110.152.0 1024\n103.110.156.0 1024\n103.110.188.0 1024\n103.110.204.0 1024\n103.111.64.0 1024\n103.111.172.0 1024\n103.111.252.0 1024\n103.112.28.0 1024\n103.112.68.0 1024\n103.112.72.0 1024\n103.112.88.0 1024\n103.112.92.0 1024\n103.112.96.0 1024\n103.112.108.0 1024\n103.112.112.0 1024\n103.112.116.0 1024\n103.112.140.0 1024\n103.112.172.0 1024\n103.112.184.0 1024\n103.113.4.0 1024\n103.113.92.0 1024\n103.113.144.0 1024\n103.113.220.0 1024\n103.113.232.0 1024\n103.113.236.0 1024\n103.114.4.0 1024\n103.114.28.0 1024\n103.114.68.0 1024\n103.114.72.0 1024\n103.114.100.0 1024\n103.114.132.0 1024\n103.114.148.0 1024\n103.114.156.0 1024\n103.114.176.0 1024\n103.114.212.0 1024\n103.114.236.0 1024\n103.114.240.0 1024\n103.115.16.0 1024\n103.115.40.0 1024\n103.115.44.0 1024\n103.115.48.0 1024\n103.115.52.0 1024\n103.115.56.0 1024\n103.115.60.0 1024\n103.115.64.0 1024\n103.115.68.0 1024\n103.115.92.0 1024\n103.115.120.0 1024\n103.115.148.0 1024\n103.115.248.0 1024\n103.116.40.0 1024\n103.116.64.0 1024\n103.116.72.0 1024\n103.116.76.0 1024\n103.116.92.0 1024\n103.116.120.0 1024\n103.116.128.0 1024\n103.116.132.0 512\n103.116.138.0 512\n103.116.148.0 1024\n103.116.184.0 1024\n103.116.206.0 512\n103.116.220.0 1024\n103.116.224.0 1024\n103.116.228.0 1024\n103.117.16.0 1024\n103.117.72.0 1024\n103.117.88.0 1024\n103.117.136.0 1024\n103.117.188.0 1024\n103.117.220.0 1024\n103.118.52.0 1024\n103.118.56.0 1024\n103.118.60.0 1024\n103.118.64.0 1024\n103.118.68.0 1024\n103.118.72.0 1024\n103.118.88.0 1024\n103.118.173.0 256\n103.118.192.0 1024\n103.118.196.0 1024\n103.118.200.0 1024\n103.118.204.0 1024\n103.118.208.0 1024\n103.118.212.0 1024\n103.118.216.0 1024\n103.118.220.0 1024\n103.118.240.0 1024\n103.118.244.0 1024\n103.118.248.0 1024\n103.118.252.0 1024\n103.119.0.0 1024\n103.119.12.0 1024\n103.119.16.0 1024\n103.119.28.0 1024\n103.119.104.0 1024\n103.119.115.0 256\n103.119.156.0 1024\n103.119.180.0 1024\n103.119.200.0 1024\n103.119.224.0 1024\n103.120.52.0 1024\n103.120.72.0 1024\n103.120.88.0 1024\n103.120.96.0 1024\n103.120.100.0 1024\n103.120.140.0 1024\n103.120.196.0 1024\n103.120.224.0 1024\n103.121.52.0 1024\n103.121.92.0 1024\n103.121.160.0 1024\n103.121.164.0 1024\n103.121.250.0 256\n103.121.252.0 1024\n103.122.48.0 1024\n103.122.176.0 1024\n103.122.192.0 1024\n103.122.240.0 1024\n103.123.4.0 1024\n103.123.56.0 1024\n103.123.88.0 1024\n103.123.92.0 1024\n103.123.116.0 1024\n103.123.160.0 1024\n103.123.176.0 1024\n103.123.200.0 1024\n103.123.204.0 1024\n103.123.208.0 1024\n103.123.212.0 1024\n103.124.24.0 1024\n103.124.48.0 1024\n103.124.64.0 1024\n103.124.212.0 1024\n103.124.216.0 1024\n103.125.20.0 1024\n103.125.44.0 1024\n103.125.132.0 1024\n103.125.164.0 1024\n103.125.196.0 1024\n103.125.236.0 1024\n103.125.248.0 1024\n103.126.0.0 1024\n103.126.16.0 1024\n103.126.44.0 1024\n103.126.100.0 1024\n103.126.124.0 1024\n103.126.128.0 1024\n103.126.132.0 1024\n103.126.208.0 1024\n103.129.52.0 1024\n103.130.132.0 1024\n103.130.152.0 256\n103.130.160.0 1024\n103.130.228.0 1024\n103.131.20.0 1024\n103.131.36.0 1024\n103.131.138.0 512\n103.131.152.0 1024\n103.131.168.0 1024\n103.131.176.0 1024\n103.131.224.0 1024\n103.131.228.0 1024\n103.131.240.0 1024\n103.132.22.0 512\n103.132.60.0 1024\n103.132.64.0 1024\n103.132.68.0 1024\n103.132.72.0 1024\n103.132.76.0 1024\n103.132.80.0 1024\n103.132.104.0 1024\n103.132.108.0 1024\n103.132.112.0 1024\n103.132.116.0 1024\n103.132.120.0 1024\n103.132.160.0 1024\n103.132.164.0 1024\n103.132.188.0 1024\n103.132.208.0 1024\n103.132.212.0 1024\n103.132.234.0 512\n103.133.12.0 1024\n103.133.40.0 1024\n103.133.128.0 1024\n103.133.136.0 1024\n103.133.176.0 1024\n103.133.232.0 1024\n103.134.12.0 256\n103.134.196.0 1024\n103.134.232.0 512\n103.135.80.0 1024\n103.135.124.0 1024\n103.135.148.0 1024\n103.135.156.0 1024\n103.135.160.0 1024\n103.135.164.0 1024\n103.135.176.0 1024\n103.135.184.0 1024\n103.135.192.0 1024\n103.135.196.0 1024\n103.135.236.0 1024\n103.136.128.0 1024\n103.136.232.0 1024\n103.137.58.0 512\n103.137.60.0 256\n103.137.76.0 1024\n103.137.136.0 512\n103.137.180.0 1024\n103.137.236.0 1024\n103.138.2.0 512\n103.138.12.0 512\n103.138.80.0 1024\n103.138.134.0 512\n103.138.156.0 512\n103.138.208.0 512\n103.138.220.0 512\n103.138.246.0 512\n103.138.248.0 512\n103.139.0.0 512\n103.139.2.0 512\n103.139.22.0 512\n103.139.92.0 512\n103.139.113.0 256\n103.139.134.0 512\n103.139.136.0 512\n103.139.172.0 512\n103.139.204.0 512\n103.139.212.0 512\n103.140.8.0 512\n103.140.14.0 512\n103.140.70.0 512\n103.140.126.0 512\n103.140.140.0 512\n103.140.144.0 512\n103.140.152.0 512\n103.140.192.0 512\n103.140.228.0 512\n103.141.10.0 512\n103.141.58.0 512\n103.141.128.0 512\n103.141.186.0 512\n103.141.242.0 512\n103.142.28.0 512\n103.142.58.0 512\n103.142.82.0 512\n103.142.96.0 512\n103.142.102.0 512\n103.142.122.0 512\n103.142.128.0 512\n103.142.140.0 512\n103.142.154.0 512\n103.142.156.0 512\n103.142.172.0 512\n103.142.180.0 512\n103.142.186.0 512\n103.142.190.0 512\n103.142.220.0 512\n103.142.230.0 256\n103.142.234.0 512\n103.142.238.0 512\n103.142.248.0 512\n103.143.16.0 512\n103.143.18.0 512\n103.143.31.0 256\n103.143.74.0 512\n103.143.120.0 512\n103.143.124.0 512\n103.143.132.0 512\n103.143.134.0 512\n103.143.174.0 512\n103.143.228.0 512\n103.144.40.0 512\n103.144.52.0 512\n103.144.66.0 512\n103.144.70.0 512\n103.144.72.0 512\n103.144.108.0 512\n103.144.136.0 512\n103.144.148.0 512\n103.144.158.0 512\n103.144.240.0 512\n103.145.38.0 512\n103.145.40.0 512\n103.145.42.0 512\n103.145.60.0 512\n103.145.72.0 512\n103.145.80.0 512\n103.145.86.0 512\n103.145.92.0 512\n103.145.94.0 512\n103.145.98.0 512\n103.145.106.0 512\n103.145.122.0 512\n103.145.188.0 512\n103.145.190.0 512\n103.146.72.0 512\n103.146.90.0 512\n103.146.124.0 512\n103.146.126.0 512\n103.146.138.0 512\n103.146.230.0 512\n103.146.236.0 512\n103.146.252.0 512\n103.147.12.0 512\n103.147.124.0 512\n103.147.198.0 512\n103.147.206.0 512\n103.148.174.0 512\n103.149.6.0 512\n103.149.17.0 256\n103.149.44.0 512\n103.149.110.0 512\n103.149.132.0 512\n103.149.144.0 512\n103.149.156.0 512\n103.149.181.0 256\n103.149.210.0 512\n103.149.214.0 512\n103.149.220.0 512\n103.149.242.0 512\n103.149.244.0 512\n103.149.246.0 512\n103.149.248.0 512\n103.150.10.0 512\n103.150.24.0 512\n103.150.66.0 512\n103.150.72.0 512\n103.150.122.0 512\n103.150.126.0 512\n103.150.128.0 512\n103.150.130.0 512\n103.150.146.0 512\n103.150.164.0 512\n103.150.172.0 512\n103.150.180.0 512\n103.150.200.0 512\n103.150.210.0 512\n103.150.214.0 512\n103.150.216.0 512\n103.150.244.0 512\n103.151.4.0 512\n103.151.44.0 512\n103.151.138.0 512\n103.151.142.0 512\n103.151.148.0 512\n103.151.150.0 512\n103.151.158.0 512\n103.151.178.0 512\n103.151.206.0 512\n103.151.216.0 512\n103.151.228.0 512\n103.152.14.0 512\n103.152.24.0 512\n103.152.28.0 512\n103.152.30.0 512\n103.152.56.0 512\n103.152.76.0 512\n103.152.98.0 512\n103.152.112.0 512\n103.152.120.0 512\n103.152.122.0 512\n103.152.132.0 512\n103.152.152.0 512\n103.152.168.0 512\n103.152.170.0 512\n103.152.186.0 512\n103.152.190.0 512\n103.152.192.0 512\n103.152.200.0 512\n103.152.208.0 512\n103.152.224.0 512\n103.152.226.0 512\n103.152.246.0 512\n103.152.250.0 512\n103.153.4.0 512\n103.153.36.0 512\n103.153.100.0 512\n103.153.114.0 512\n103.153.122.0 512\n103.153.128.0 512\n103.153.132.0 512\n103.153.138.0 512\n103.153.146.0 512\n103.153.160.0 512\n103.154.18.0 512\n103.154.30.0 512\n103.154.32.0 512\n103.154.40.0 512\n103.154.66.0 512\n103.154.162.0 512\n103.154.164.0 512\n103.154.168.0 512\n103.154.242.0 512\n103.155.14.0 512\n103.155.16.0 512\n103.155.34.0 512\n103.155.48.0 512\n103.155.76.0 512\n103.155.100.0 512\n103.155.110.0 512\n103.155.120.0 512\n103.155.214.0 512\n103.155.248.0 512\n103.156.28.0 512\n103.156.68.0 512\n103.156.78.0 512\n103.156.104.0 512\n103.156.158.0 512\n103.156.174.0 512\n103.156.186.0 512\n103.156.228.0 512\n103.157.30.0 512\n103.157.138.0 512\n103.157.174.0 512\n103.157.212.0 512\n103.157.234.0 512\n103.157.254.0 512\n103.158.0.0 512\n103.158.8.0 512\n103.158.16.0 512\n103.158.74.0 512\n103.158.190.0 512\n103.158.200.0 512\n103.158.224.0 512\n103.159.80.0 512\n103.159.122.0 512\n103.159.124.0 512\n103.159.134.0 512\n103.159.142.0 512\n103.160.32.0 512\n103.160.34.0 512\n103.160.112.0 512\n103.160.114.0 512\n103.160.244.0 512\n103.160.254.0 512\n103.161.14.0 512\n103.161.102.0 512\n103.161.138.0 512\n103.161.208.0 512\n103.161.220.0 512\n103.161.254.0 512\n103.162.10.0 512\n103.162.32.0 512\n103.162.116.0 512\n103.163.28.0 512\n103.163.32.0 512\n103.163.46.0 512\n103.163.74.0 512\n103.163.180.0 512\n103.164.4.0 512\n103.164.32.0 512\n103.164.40.0 512\n103.164.42.0 512\n103.164.64.0 512\n103.164.76.0 512\n103.164.178.0 512\n103.165.44.0 512\n103.165.52.0 512\n103.165.82.0 512\n103.165.110.0 512\n103.166.20.0 512\n103.166.50.0 512\n103.166.52.0 512\n103.166.54.0 512\n103.166.84.0 512\n103.166.138.0 512\n103.166.242.0 512\n103.167.0.0 512\n103.167.36.0 512\n103.167.100.0 512\n103.168.98.0 512\n103.168.170.0 512\n103.169.50.0 512\n103.169.62.0 512\n103.169.108.0 512\n103.169.162.0 512\n103.169.202.0 512\n103.169.216.0 512\n103.170.4.0 512\n103.170.72.0 512\n103.170.134.0 512\n103.170.210.0 512\n103.170.212.0 512\n103.171.32.0 512\n103.171.166.0 512\n103.171.214.0 512\n103.172.32.0 512\n103.172.160.0 512\n103.172.191.0 256\n103.173.102.0 512\n103.173.182.0 512\n103.173.184.0 512\n103.174.94.0 512\n103.175.14.0 512\n103.175.98.0 512\n103.175.114.0 512\n103.175.118.0 512\n103.176.52.0 512\n103.176.222.0 512\n103.176.244.0 512\n103.177.28.0 512\n103.177.44.0 512\n103.177.70.0 512\n103.177.136.0 512\n103.177.162.0 512\n103.178.56.0 512\n103.178.240.0 512\n103.179.76.0 512\n103.179.78.0 512\n103.180.108.0 512\n103.180.226.0 512\n103.181.164.0 512\n103.181.234.0 512\n103.183.26.0 512\n103.183.66.0 512\n103.183.122.0 512\n103.183.124.0 512\n103.184.44.0 512\n103.184.46.0 512\n103.184.60.0 512\n103.185.78.0 512\n103.185.80.0 512\n103.185.228.0 512\n103.186.4.0 512\n103.186.108.0 512\n103.186.112.0 512\n103.186.136.0 512\n103.186.158.0 512\n103.186.162.0 512\n103.186.228.0 512\n103.189.92.0 512\n103.189.140.0 512\n103.189.152.0 512\n103.189.154.0 512\n103.190.20.0 512\n103.190.71.0 256\n103.190.104.0 512\n103.190.116.0 512\n103.190.118.0 512\n103.190.122.0 512\n103.191.102.0 512\n103.191.242.0 512\n103.192.0.0 1024\n103.192.4.0 1024\n103.192.8.0 1024\n103.192.12.0 1024\n103.192.16.0 1024\n103.192.20.0 1024\n103.192.24.0 1024\n103.192.28.0 1024\n103.192.48.0 1024\n103.192.52.0 1024\n103.192.56.0 1024\n103.192.84.0 1024\n103.192.88.0 1024\n103.192.92.0 1024\n103.192.96.0 1024\n103.192.100.0 1024\n103.192.104.0 1024\n103.192.108.0 1024\n103.192.112.0 1024\n103.192.128.0 1024\n103.192.132.0 1024\n103.192.136.0 1024\n103.192.140.0 1024\n103.192.144.0 1024\n103.192.164.0 1024\n103.192.188.0 1024\n103.192.208.0 1024\n103.192.212.0 1024\n103.192.216.0 1024\n103.192.252.0 1024\n103.193.40.0 1024\n103.193.44.0 1024\n103.193.120.0 1024\n103.193.140.0 1024\n103.193.160.0 1024\n103.193.188.0 1024\n103.193.192.0 1024\n103.193.212.0 1024\n103.193.216.0 1024\n103.193.220.0 1024\n103.193.224.0 1024\n103.193.228.0 1024\n103.193.232.0 1024\n103.193.236.0 1024\n103.194.16.0 1024\n103.195.104.0 1024\n103.195.112.0 1024\n103.195.148.0 1024\n103.195.152.0 1024\n103.195.160.0 1024\n103.196.64.0 1024\n103.196.72.0 1024\n103.196.88.0 1024\n103.196.92.0 1024\n103.196.96.0 1024\n103.196.168.0 1024\n103.196.204.0 1024\n103.197.0.0 1024\n103.197.180.0 1024\n103.197.228.0 1024\n103.198.20.0 1024\n103.198.60.0 1024\n103.198.64.0 1024\n103.198.72.0 1024\n103.198.124.0 1024\n103.198.156.0 1024\n103.198.180.0 1024\n103.198.196.0 1024\n103.198.216.0 1024\n103.198.220.0 1024\n103.198.224.0 1024\n103.198.228.0 1024\n103.198.232.0 1024\n103.198.236.0 1024\n103.198.240.0 1024\n103.198.244.0 1024\n103.199.164.0 1024\n103.199.196.0 1024\n103.199.228.0 1024\n103.199.248.0 1024\n103.199.252.0 1024\n103.200.52.0 1024\n103.200.64.0 1024\n103.200.68.0 1024\n103.200.136.0 1024\n103.200.140.0 1024\n103.200.144.0 1024\n103.200.148.0 1024\n103.200.152.0 1024\n103.200.156.0 1024\n103.200.160.0 1024\n103.200.164.0 1024\n103.200.168.0 1024\n103.200.172.0 1024\n103.200.176.0 1024\n103.200.180.0 1024\n103.200.184.0 1024\n103.200.188.0 1024\n103.200.192.0 1024\n103.200.220.0 1024\n103.200.224.0 1024\n103.200.228.0 1024\n103.200.232.0 1024\n103.200.236.0 1024\n103.200.240.0 1024\n103.200.244.0 1024\n103.200.248.0 1024\n103.200.252.0 1024\n103.201.0.0 1024\n103.201.4.0 1024\n103.201.8.0 1024\n103.201.12.0 1024\n103.201.16.0 1024\n103.201.20.0 1024\n103.201.28.0 1024\n103.201.32.0 1024\n103.201.36.0 1024\n103.201.40.0 1024\n103.201.44.0 1024\n103.201.48.0 1024\n103.201.52.0 1024\n103.201.56.0 1024\n103.201.60.0 1024\n103.201.64.0 1024\n103.201.76.0 1024\n103.201.80.0 1024\n103.201.84.0 1024\n103.201.88.0 1024\n103.201.92.0 1024\n103.201.96.0 1024\n103.201.100.0 1024\n103.201.104.0 1024\n103.201.108.0 1024\n103.201.112.0 1024\n103.201.116.0 1024\n103.201.120.0 1024\n103.201.152.0 1024\n103.201.156.0 1024\n103.201.160.0 1024\n103.201.164.0 1024\n103.201.168.0 1024\n103.201.172.0 1024\n103.201.176.0 1024\n103.201.180.0 1024\n103.201.184.0 1024\n103.201.188.0 1024\n103.201.192.0 1024\n103.201.196.0 1024\n103.201.200.0 1024\n103.201.204.0 1024\n103.201.208.0 1024\n103.201.212.0 1024\n103.201.216.0 1024\n103.201.220.0 1024\n103.201.224.0 1024\n103.201.228.0 1024\n103.201.232.0 1024\n103.201.236.0 1024\n103.201.240.0 1024\n103.201.244.0 1024\n103.201.248.0 1024\n103.201.252.0 1024\n103.202.0.0 1024\n103.202.4.0 1024\n103.202.8.0 1024\n103.202.12.0 1024\n103.202.16.0 1024\n103.202.20.0 1024\n103.202.24.0 1024\n103.202.28.0 1024\n103.202.32.0 1024\n103.202.36.0 1024\n103.202.40.0 1024\n103.202.44.0 1024\n103.202.56.0 1024\n103.202.60.0 1024\n103.202.64.0 1024\n103.202.68.0 1024\n103.202.72.0 1024\n103.202.76.0 1024\n103.202.80.0 1024\n103.202.84.0 1024\n103.202.88.0 1024\n103.202.92.0 1024\n103.202.96.0 1024\n103.202.100.0 1024\n103.202.104.0 1024\n103.202.108.0 1024\n103.202.112.0 1024\n103.202.116.0 1024\n103.202.120.0 1024\n103.202.124.0 1024\n103.202.128.0 1024\n103.202.132.0 1024\n103.202.136.0 1024\n103.202.140.0 1024\n103.202.144.0 1024\n103.202.152.0 1024\n103.202.156.0 1024\n103.202.160.0 1024\n103.202.164.0 1024\n103.202.168.0 1024\n103.202.172.0 1024\n103.202.176.0 1024\n103.202.180.0 1024\n103.202.184.0 1024\n103.202.188.0 1024\n103.202.192.0 1024\n103.202.196.0 1024\n103.202.200.0 2048\n103.202.212.0 1024\n103.202.228.0 1024\n103.202.236.0 1024\n103.202.240.0 1024\n103.202.244.0 1024\n103.202.248.0 1024\n103.202.252.0 1024\n103.203.0.0 1024\n103.203.4.0 1024\n103.203.8.0 1024\n103.203.12.0 1024\n103.203.16.0 1024\n103.203.20.0 1024\n103.203.24.0 1024\n103.203.28.0 1024\n103.203.32.0 1024\n103.203.56.0 1024\n103.203.96.0 1024\n103.203.100.0 1024\n103.203.104.0 1024\n103.203.108.0 1024\n103.203.112.0 1024\n103.203.116.0 1024\n103.203.120.0 1024\n103.203.124.0 1024\n103.203.128.0 1024\n103.203.140.0 1024\n103.203.164.0 1024\n103.203.168.0 1024\n103.203.192.0 1024\n103.203.200.0 1024\n103.203.212.0 1024\n103.203.216.0 1024\n103.204.24.0 1024\n103.204.72.0 1024\n103.204.88.0 1024\n103.204.112.0 1024\n103.204.136.0 1024\n103.204.140.0 1024\n103.204.144.0 1024\n103.204.148.0 1024\n103.204.152.0 1024\n103.204.196.0 1024\n103.204.216.0 512\n103.204.232.0 1024\n103.204.236.0 1024\n103.205.4.0 1024\n103.205.8.0 1024\n103.205.40.0 1024\n103.205.44.0 1024\n103.205.52.0 1024\n103.205.108.0 1024\n103.205.116.0 1024\n103.205.120.0 1024\n103.205.136.0 1024\n103.205.162.0 256\n103.205.188.0 1024\n103.205.192.0 1024\n103.205.196.0 1024\n103.205.200.0 1024\n103.205.236.0 1024\n103.205.248.0 1024\n103.205.252.0 1024\n103.206.0.0 1024\n103.206.44.0 1024\n103.206.148.0 1024\n103.207.48.0 1024\n103.207.104.0 1024\n103.207.184.0 1024\n103.207.188.0 1024\n103.207.192.0 1024\n103.207.196.0 1024\n103.207.200.0 1024\n103.207.204.0 1024\n103.207.208.0 1024\n103.207.212.0 1024\n103.207.220.0 1024\n103.207.228.0 1024\n103.207.232.0 1024\n103.208.12.0 1024\n103.208.16.0 1024\n103.208.28.0 1024\n103.208.40.0 1024\n103.208.44.0 1024\n103.208.48.0 1024\n103.209.112.0 1024\n103.209.136.0 1024\n103.209.200.0 1024\n103.209.208.0 1024\n103.209.216.0 1024\n103.210.96.0 1024\n103.210.156.0 1024\n103.210.160.0 1024\n103.210.164.0 1024\n103.210.168.0 1024\n103.210.172.0 1024\n103.210.176.0 1024\n103.210.180.0 1024\n103.210.184.0 1024\n103.210.188.0 1024\n103.210.216.0 1024\n103.211.44.0 1024\n103.211.96.0 1024\n103.211.156.0 1024\n103.211.164.0 1024\n103.211.194.0 512\n103.211.220.0 1024\n103.211.224.0 1024\n103.211.248.0 1024\n103.212.0.0 1024\n103.212.4.0 1024\n103.212.8.0 1024\n103.212.12.0 1024\n103.212.44.0 1024\n103.212.48.0 1024\n103.212.84.0 1024\n103.212.100.0 1024\n103.212.108.0 1024\n103.212.148.0 1024\n103.212.164.0 1024\n103.212.196.0 1024\n103.212.200.0 1024\n103.212.228.0 1024\n103.212.252.0 1024\n103.213.40.0 1024\n103.213.44.0 1024\n103.213.48.0 1024\n103.213.52.0 1024\n103.213.56.0 1024\n103.213.60.0 1024\n103.213.64.0 1024\n103.213.68.0 1024\n103.213.72.0 1024\n103.213.76.0 1024\n103.213.80.0 1024\n103.213.84.0 1024\n103.213.88.0 1024\n103.213.92.0 1024\n103.213.96.0 1024\n103.213.132.0 1024\n103.213.136.0 1024\n103.213.140.0 1024\n103.213.144.0 1024\n103.213.148.0 1024\n103.213.152.0 1024\n103.213.156.0 1024\n103.213.160.0 1024\n103.213.164.0 1024\n103.213.168.0 1024\n103.213.172.0 1024\n103.213.176.0 1024\n103.213.180.0 1024\n103.213.184.0 1024\n103.213.188.0 1024\n103.213.196.0 512\n103.213.198.0 512\n103.213.226.0 512\n103.213.232.0 512\n103.214.48.0 1024\n103.214.84.0 1024\n103.214.212.0 1024\n103.214.240.0 1024\n103.214.244.0 1024\n103.215.28.0 1024\n103.215.32.0 1024\n103.215.36.0 1024\n103.215.44.0 1024\n103.215.48.0 1024\n103.215.100.0 1024\n103.215.108.0 1024\n103.215.116.0 1024\n103.215.120.0 1024\n103.215.140.0 1024\n103.216.4.0 1024\n103.216.8.0 1024\n103.216.12.0 1024\n103.216.16.0 1024\n103.216.20.0 1024\n103.216.24.0 1024\n103.216.28.0 1024\n103.216.32.0 1024\n103.216.36.0 1024\n103.216.40.0 1024\n103.216.44.0 1024\n103.216.64.0 1024\n103.216.108.0 1024\n103.216.136.0 1024\n103.216.152.0 1024\n103.216.156.0 512\n103.216.224.0 1024\n103.216.228.0 1024\n103.216.240.0 1024\n103.216.244.0 1024\n103.216.248.0 1024\n103.216.252.0 1024\n103.217.0.0 1024\n103.217.4.0 1024\n103.217.8.0 1024\n103.217.12.0 1024\n103.217.16.0 1024\n103.217.20.0 1024\n103.217.24.0 1024\n103.217.28.0 1024\n103.217.32.0 1024\n103.217.36.0 1024\n103.217.40.0 1024\n103.217.44.0 1024\n103.217.48.0 1024\n103.217.52.0 1024\n103.217.56.0 1024\n103.217.60.0 1024\n103.217.168.0 1024\n103.217.180.0 1024\n103.217.184.0 1024\n103.217.188.0 1024\n103.217.192.0 1024\n103.217.196.0 1024\n103.217.200.0 1024\n103.217.204.0 1024\n103.218.8.0 1024\n103.218.12.0 1024\n103.218.16.0 1024\n103.218.20.0 1024\n103.218.28.0 1024\n103.218.32.0 1024\n103.218.36.0 1024\n103.218.40.0 1024\n103.218.44.0 1024\n103.218.48.0 1024\n103.218.52.0 1024\n103.218.56.0 1024\n103.218.60.0 1024\n103.218.64.0 1024\n103.218.68.0 1024\n103.218.72.0 1024\n103.218.76.0 1024\n103.218.80.0 1024\n103.218.84.0 1024\n103.218.88.0 1024\n103.218.92.0 1024\n103.218.178.0 512\n103.218.192.0 1024\n103.218.196.0 1024\n103.218.200.0 1024\n103.218.204.0 1024\n103.218.208.0 1024\n103.218.212.0 1024\n103.218.216.0 1024\n103.219.24.0 1024\n103.219.28.0 1024\n103.219.32.0 1024\n103.219.36.0 1024\n103.219.64.0 1024\n103.219.84.0 1024\n103.219.88.0 1024\n103.219.92.0 1024\n103.219.96.0 1024\n103.219.100.0 1024\n103.219.176.0 1024\n103.219.184.0 1024\n103.220.48.0 1024\n103.220.52.0 1024\n103.220.56.0 1024\n103.220.60.0 1024\n103.220.64.0 1024\n103.220.92.0 1024\n103.220.96.0 1024\n103.220.100.0 1024\n103.220.104.0 1024\n103.220.108.0 1024\n103.220.116.0 1024\n103.220.120.0 1024\n103.220.124.0 1024\n103.220.128.0 1024\n103.220.132.0 1024\n103.220.136.0 1024\n103.220.140.0 1024\n103.220.144.0 1024\n103.220.148.0 1024\n103.220.152.0 1024\n103.220.160.0 1024\n103.220.164.0 1024\n103.220.168.0 1024\n103.220.172.0 1024\n103.220.176.0 1024\n103.220.180.0 1024\n103.220.184.0 1024\n103.220.188.0 1024\n103.220.192.0 1024\n103.220.196.0 1024\n103.220.200.0 1024\n103.220.240.0 1024\n103.220.244.0 1024\n103.220.248.0 1024\n103.220.252.0 1024\n103.221.0.0 1024\n103.221.4.0 1024\n103.221.8.0 1024\n103.221.12.0 1024\n103.221.16.0 1024\n103.221.20.0 1024\n103.221.24.0 1024\n103.221.28.0 1024\n103.221.32.0 1024\n103.221.36.0 1024\n103.221.40.0 1024\n103.221.44.0 1024\n103.221.48.0 1024\n103.221.88.0 1024\n103.221.92.0 1024\n103.221.96.0 1024\n103.221.100.0 1024\n103.221.104.0 1024\n103.221.108.0 1024\n103.221.112.0 1024\n103.221.116.0 1024\n103.221.120.0 1024\n103.221.124.0 1024\n103.221.128.0 1024\n103.221.132.0 1024\n103.221.136.0 1024\n103.221.140.0 1024\n103.221.144.0 1024\n103.221.148.0 1024\n103.221.152.0 1024\n103.221.156.0 1024\n103.221.160.0 1024\n103.221.164.0 1024\n103.221.168.0 1024\n103.221.172.0 1024\n103.221.176.0 1024\n103.221.180.0 1024\n103.221.184.0 1024\n103.221.188.0 1024\n103.221.192.0 1024\n103.221.196.0 1024\n103.221.200.0 1024\n103.221.204.0 1024\n103.222.0.0 1024\n103.222.4.0 1024\n103.222.8.0 1024\n103.222.12.0 1024\n103.222.16.0 1024\n103.222.24.0 1024\n103.222.28.0 1024\n103.222.32.0 1024\n103.222.36.0 1024\n103.222.40.0 1024\n103.222.44.0 1024\n103.222.48.0 1024\n103.222.52.0 1024\n103.222.56.0 1024\n103.222.60.0 1024\n103.222.64.0 1024\n103.222.68.0 1024\n103.222.72.0 1024\n103.222.76.0 1024\n103.222.80.0 1024\n103.222.84.0 1024\n103.222.88.0 1024\n103.222.92.0 1024\n103.222.96.0 1024\n103.222.100.0 1024\n103.222.104.0 1024\n103.222.108.0 1024\n103.222.112.0 1024\n103.222.116.0 1024\n103.222.120.0 1024\n103.222.124.0 1024\n103.222.128.0 1024\n103.222.132.0 1024\n103.222.136.0 1024\n103.222.140.0 1024\n103.222.144.0 1024\n103.222.148.0 1024\n103.222.152.0 1024\n103.222.156.0 1024\n103.222.160.0 1024\n103.222.164.0 1024\n103.222.168.0 1024\n103.222.172.0 1024\n103.222.176.0 1024\n103.222.180.0 1024\n103.222.184.0 1024\n103.222.188.0 1024\n103.222.192.0 1024\n103.222.196.0 1024\n103.222.200.0 1024\n103.222.204.0 1024\n103.222.208.0 1024\n103.222.212.0 1024\n103.222.216.0 1024\n103.222.220.0 1024\n103.222.224.0 1024\n103.222.228.0 1024\n103.222.232.0 1024\n103.222.240.0 1024\n103.222.244.0 1024\n103.223.16.0 1024\n103.223.20.0 1024\n103.223.24.0 1024\n103.223.28.0 1024\n103.223.32.0 1024\n103.223.36.0 1024\n103.223.40.0 1024\n103.223.44.0 1024\n103.223.48.0 1024\n103.223.52.0 1024\n103.223.56.0 1024\n103.223.60.0 1024\n103.223.64.0 1024\n103.223.68.0 1024\n103.223.72.0 1024\n103.223.76.0 1024\n103.223.80.0 1024\n103.223.84.0 1024\n103.223.88.0 1024\n103.223.92.0 1024\n103.223.96.0 1024\n103.223.100.0 1024\n103.223.104.0 1024\n103.223.108.0 1024\n103.223.112.0 1024\n103.223.116.0 1024\n103.223.120.0 1024\n103.223.124.0 1024\n103.223.128.0 1024\n103.223.132.0 1024\n103.223.140.0 1024\n103.223.144.0 1024\n103.223.148.0 1024\n103.223.152.0 1024\n103.223.156.0 1024\n103.223.160.0 1024\n103.223.164.0 1024\n103.223.168.0 1024\n103.223.172.0 1024\n103.223.176.0 1024\n103.223.180.0 1024\n103.223.188.0 1024\n103.223.192.0 1024\n103.223.196.0 1024\n103.223.200.0 1024\n103.223.204.0 1024\n103.223.208.0 1024\n103.223.212.0 1024\n103.223.216.0 1024\n103.223.220.0 1024\n103.223.224.0 1024\n103.223.228.0 1024\n103.223.232.0 1024\n103.223.236.0 1024\n103.223.240.0 1024\n103.223.244.0 1024\n103.223.248.0 1024\n103.223.252.0 1024\n103.224.0.0 1024\n103.224.40.0 1024\n103.224.44.0 1024\n103.224.60.0 1024\n103.224.80.0 1024\n103.224.220.0 1024\n103.224.224.0 1024\n103.224.228.0 1024\n103.224.232.0 1024\n103.225.18.0 256\n103.225.84.0 1024\n103.226.16.0 1024\n103.226.40.0 1024\n103.226.56.0 1024\n103.226.60.0 1024\n103.226.80.0 1024\n103.226.116.0 512\n103.226.132.0 1024\n103.226.156.0 1024\n103.226.180.0 1024\n103.226.196.0 1024\n103.227.48.0 1024\n103.227.72.0 1024\n103.227.76.0 1024\n103.227.80.0 1024\n103.227.100.0 1024\n103.227.120.0 1024\n103.227.132.0 1024\n103.227.136.0 1024\n103.227.196.0 1024\n103.227.204.0 1024\n103.227.212.0 1024\n103.227.228.0 1024\n103.228.12.0 1024\n103.228.88.0 1024\n103.228.136.0 1024\n103.228.160.0 1024\n103.228.176.0 1024\n103.228.204.0 1024\n103.228.208.0 1024\n103.228.228.0 1024\n103.228.232.0 1024\n103.229.20.0 1024\n103.229.60.0 1024\n103.229.136.0 1024\n103.229.148.0 1024\n103.229.172.0 1024\n103.229.212.0 1024\n103.229.216.0 1024\n103.229.220.0 1024\n103.229.228.0 1024\n103.229.236.0 1024\n103.229.240.0 1024\n103.230.0.0 1024\n103.230.28.0 1024\n103.230.44.0 1024\n103.230.96.0 1024\n103.230.110.0 512\n103.230.128.0 512\n103.230.196.0 1024\n103.230.200.0 1024\n103.230.204.0 1024\n103.230.212.0 1024\n103.230.236.0 1024\n103.231.16.0 1024\n103.231.20.0 1024\n103.231.64.0 1024\n103.231.68.0 1024\n103.231.180.0 1024\n103.231.184.0 1024\n103.231.244.0 1024\n103.232.4.0 1024\n103.232.144.0 1024\n103.232.166.0 512\n103.232.188.0 1024\n103.232.212.0 1024\n103.233.4.0 1024\n103.233.44.0 1024\n103.233.52.0 1024\n103.233.104.0 1024\n103.233.128.0 1024\n103.233.136.0 1024\n103.233.162.0 512\n103.233.178.0 512\n103.233.228.0 1024\n103.234.0.0 1024\n103.234.20.0 1024\n103.234.56.0 1024\n103.234.128.0 1024\n103.234.172.0 1024\n103.234.180.0 1024\n103.234.244.0 1024\n103.235.48.0 1024\n103.235.56.0 1024\n103.235.60.0 1024\n103.235.80.0 1024\n103.235.84.0 1024\n103.235.100.0 1024\n103.235.128.0 1024\n103.235.132.0 1024\n103.235.136.0 1024\n103.235.140.0 1024\n103.235.144.0 1024\n103.235.148.0 1024\n103.235.184.0 1024\n103.235.192.0 1024\n103.235.200.0 1024\n103.235.220.0 1024\n103.235.224.0 1024\n103.235.228.0 1024\n103.235.232.0 1024\n103.235.236.0 1024\n103.235.240.0 1024\n103.235.244.0 1024\n103.235.248.0 1024\n103.235.252.0 1024\n103.236.0.0 1024\n103.236.4.0 1024\n103.236.8.0 1024\n103.236.12.0 1024\n103.236.16.0 1024\n103.236.20.0 1024\n103.236.24.0 1024\n103.236.28.0 1024\n103.236.32.0 1024\n103.236.36.0 1024\n103.236.40.0 1024\n103.236.44.0 1024\n103.236.48.0 1024\n103.236.52.0 1024\n103.236.56.0 1024\n103.236.60.0 1024\n103.236.64.0 1024\n103.236.68.0 1024\n103.236.72.0 1024\n103.236.76.0 1024\n103.236.80.0 1024\n103.236.84.0 1024\n103.236.88.0 1024\n103.236.92.0 1024\n103.236.96.0 1024\n103.236.116.0 512\n103.236.120.0 1024\n103.236.184.0 1024\n103.236.220.0 1024\n103.236.232.0 1024\n103.236.240.0 1024\n103.236.244.0 1024\n103.236.248.0 1024\n103.236.252.0 1024\n103.237.0.0 1024\n103.237.4.0 1024\n103.237.8.0 1024\n103.237.12.0 1024\n103.237.24.0 1024\n103.237.28.0 1024\n103.237.68.0 1024\n103.237.88.0 1024\n103.237.92.0 512\n103.237.152.0 1024\n103.237.176.0 1024\n103.237.180.0 1024\n103.237.184.0 1024\n103.237.188.0 1024\n103.237.192.0 1024\n103.237.196.0 1024\n103.237.200.0 1024\n103.237.204.0 1024\n103.237.208.0 1024\n103.237.212.0 1024\n103.237.216.0 1024\n103.237.220.0 1024\n103.237.224.0 1024\n103.237.228.0 1024\n103.237.232.0 1024\n103.237.236.0 1024\n103.237.240.0 1024\n103.237.244.0 1024\n103.237.248.0 1024\n103.237.252.0 1024\n103.238.0.0 1024\n103.238.4.0 1024\n103.238.16.0 1024\n103.238.20.0 1024\n103.238.24.0 1024\n103.238.28.0 1024\n103.238.32.0 1024\n103.238.36.0 1024\n103.238.40.0 1024\n103.238.44.0 1024\n103.238.48.0 1024\n103.238.52.0 1024\n103.238.56.0 1024\n103.238.88.0 1024\n103.238.92.0 1024\n103.238.96.0 1024\n103.238.132.0 1024\n103.238.140.0 1024\n103.238.144.0 1024\n103.238.152.0 512\n103.238.160.0 1024\n103.238.164.0 1024\n103.238.168.0 1024\n103.238.172.0 1024\n103.238.176.0 1024\n103.238.180.0 1024\n103.238.184.0 1024\n103.238.188.0 1024\n103.238.196.0 1024\n103.238.204.0 1024\n103.238.252.0 1024\n103.239.0.0 1024\n103.239.44.0 1024\n103.239.68.0 1024\n103.239.152.0 1024\n103.239.156.0 1024\n103.239.180.0 1024\n103.239.184.0 1024\n103.239.192.0 1024\n103.239.196.0 1024\n103.239.204.0 1024\n103.239.208.0 1024\n103.239.224.0 1024\n103.239.244.0 1024\n103.240.16.0 1024\n103.240.36.0 1024\n103.240.42.0 512\n103.240.72.0 1024\n103.240.84.0 1024\n103.240.124.0 1024\n103.240.172.0 1024\n103.240.188.0 1024\n103.240.200.0 512\n103.240.202.0 512\n103.240.244.0 1024\n103.241.12.0 1024\n103.241.72.0 1024\n103.241.92.0 1024\n103.241.96.0 1024\n103.241.160.0 1024\n103.241.172.0 512\n103.241.184.0 1024\n103.241.188.0 1024\n103.241.220.0 1024\n103.242.64.0 1024\n103.242.128.0 1024\n103.242.132.0 1024\n103.242.160.0 1024\n103.242.168.0 1024\n103.242.172.0 1024\n103.242.176.0 1024\n103.242.200.0 1024\n103.242.212.0 1024\n103.242.220.0 1024\n103.242.240.0 1024\n103.243.136.0 1024\n103.243.252.0 1024\n103.244.16.0 1024\n103.244.26.0 512\n103.244.58.0 512\n103.244.60.0 1024\n103.244.64.0 1024\n103.244.68.0 1024\n103.244.72.0 1024\n103.244.76.0 1024\n103.244.80.0 1024\n103.244.84.0 1024\n103.244.116.0 1024\n103.244.164.0 1024\n103.244.232.0 1024\n103.244.252.0 1024\n103.245.23.0 256\n103.245.24.0 512\n103.245.52.0 1024\n103.245.60.0 1024\n103.245.80.0 1024\n103.245.124.0 1024\n103.245.128.0 1024\n103.246.8.0 1024\n103.246.12.0 1024\n103.246.120.0 1024\n103.246.124.0 1024\n103.246.132.0 1024\n103.246.152.0 1024\n103.246.156.0 1024\n103.247.168.0 1024\n103.247.172.0 1024\n103.247.176.0 1024\n103.247.191.0 256\n103.247.200.0 1024\n103.247.212.0 1024\n103.248.0.0 512\n103.248.64.0 1024\n103.248.100.0 1024\n103.248.124.0 1024\n103.248.152.0 1024\n103.248.168.0 1024\n103.248.192.0 1024\n103.248.212.0 1024\n103.248.224.0 1024\n103.249.8.0 1024\n103.249.12.0 1024\n103.249.52.0 1024\n103.249.104.0 1024\n103.249.128.0 1024\n103.249.136.0 1024\n103.249.144.0 1024\n103.249.164.0 1024\n103.249.168.0 1024\n103.249.172.0 1024\n103.249.176.0 1024\n103.249.188.0 1024\n103.249.192.0 1024\n103.249.244.0 1024\n103.249.252.0 1024\n103.250.32.0 1024\n103.250.104.0 1024\n103.250.124.0 1024\n103.250.180.0 1024\n103.250.192.0 1024\n103.250.216.0 1024\n103.250.224.0 1024\n103.250.236.0 1024\n103.250.248.0 1024\n103.250.252.0 1024\n103.251.32.0 1024\n103.251.84.0 1024\n103.251.96.0 1024\n103.251.124.0 1024\n103.251.128.0 1024\n103.251.160.0 1024\n103.251.192.0 1024\n103.251.204.0 1024\n103.251.240.0 1024\n103.252.28.0 1024\n103.252.36.0 1024\n103.252.64.0 1024\n103.252.96.0 1024\n103.252.104.0 1024\n103.252.172.0 1024\n103.252.204.0 1024\n103.252.208.0 1024\n103.252.232.0 1024\n103.252.248.0 1024\n103.253.4.0 1024\n103.253.60.0 1024\n103.253.204.0 1024\n103.253.220.0 1024\n103.253.224.0 1024\n103.253.232.0 1024\n103.254.8.0 1024\n103.254.20.0 1024\n103.254.64.0 1024\n103.254.68.0 1024\n103.254.72.0 1024\n103.254.76.0 1024\n103.254.112.0 1024\n103.254.176.0 1024\n103.254.188.0 1024\n103.254.196.0 256\n103.254.220.0 1024\n103.255.56.0 1024\n103.255.68.0 1024\n103.255.88.0 1024\n103.255.92.0 1024\n103.255.136.0 1024\n103.255.140.0 1024\n103.255.184.0 1024\n103.255.200.0 1024\n103.255.208.0 512\n103.255.212.0 1024\n103.255.228.0 1024\n106.0.0.0 256\n106.0.2.0 512\n106.0.4.0 1024\n106.0.8.0 2048\n106.0.16.0 4096\n106.0.44.0 1024\n106.0.64.0 16384\n106.2.0.0 131072\n106.4.0.0 262144\n106.8.0.0 131072\n106.11.0.0 65536\n106.12.0.0 262144\n106.16.0.0 1048576\n106.32.0.0 1048576\n106.48.0.0 131072\n106.50.0.0 65536\n106.52.0.0 262144\n106.56.0.0 524288\n106.74.0.0 65536\n106.75.0.0 65536\n106.80.0.0 1048576\n106.108.0.0 262144\n106.112.0.0 524288\n106.120.0.0 524288\n106.224.0.0 1048576\n109.244.0.0 65536\n110.6.0.0 131072\n110.16.0.0 262144\n110.34.40.0 1024\n110.34.44.0 1024\n110.40.0.0 262144\n110.44.12.0 1024\n110.44.144.0 4096\n110.48.0.0 65536\n110.51.0.0 65536\n110.52.0.0 131072\n110.56.0.0 524288\n110.64.0.0 131072\n110.72.0.0 131072\n110.75.0.0 32768\n110.75.128.0 8192\n110.75.160.0 8192\n110.75.192.0 16384\n110.76.0.0 8192\n110.76.32.0 8192\n110.76.132.0 1024\n110.76.156.0 1024\n110.76.184.0 1024\n110.76.192.0 16384\n110.77.0.0 32768\n110.80.0.0 524288\n110.88.0.0 262144\n110.92.68.0 1024\n110.93.32.0 8192\n110.94.0.0 131072\n110.96.0.0 2097152\n110.152.0.0 262144\n110.156.0.0 131072\n110.165.32.0 8192\n110.166.0.0 131072\n110.172.192.0 16384\n110.173.0.0 8192\n110.173.32.0 4096\n110.173.64.0 8192\n110.173.96.0 8192\n110.173.192.0 8192\n110.176.0.0 524288\n110.184.0.0 524288\n110.192.0.0 2097152\n110.228.0.0 262144\n110.232.32.0 8192\n110.236.0.0 131072\n110.240.0.0 1048576\n111.0.0.0 4194304\n111.66.0.0 65536\n111.67.192.0 4096\n111.68.64.0 8192\n111.72.0.0 524288\n111.85.0.0 65536\n111.91.192.0 8192\n111.92.240.0 1024\n111.92.248.0 1024\n111.92.252.0 1024\n111.112.0.0 131072\n111.114.0.0 131072\n111.116.0.0 131072\n111.118.200.0 2048\n111.119.64.0 16384\n111.119.128.0 8192\n111.120.0.0 262144\n111.124.0.0 65536\n111.126.0.0 131072\n111.128.0.0 2097152\n111.160.0.0 524288\n111.170.0.0 65536\n111.172.0.0 262144\n111.176.0.0 524288\n111.186.0.0 131072\n111.192.0.0 1048576\n111.208.0.0 262144\n111.212.0.0 262144\n111.221.28.0 256\n111.221.128.0 32768\n111.222.0.0 65536\n111.223.4.0 1024\n111.223.8.0 1024\n111.223.12.0 1024\n111.223.16.0 1024\n111.223.240.0 1024\n111.223.248.0 1024\n111.224.0.0 262144\n111.228.0.0 262144\n111.235.96.0 8192\n111.235.156.0 1024\n111.235.160.0 8192\n112.0.0.0 4194304\n112.64.0.0 131072\n112.66.0.0 131072\n112.73.0.0 65536\n112.74.0.0 131072\n112.80.0.0 524288\n112.88.0.0 524288\n112.96.0.0 131072\n112.98.0.0 131072\n112.100.0.0 262144\n112.109.128.0 32768\n112.111.0.0 65536\n112.112.0.0 262144\n112.116.0.0 131072\n112.122.0.0 131072\n112.124.0.0 262144\n112.128.0.0 262144\n112.132.0.0 65536\n112.137.48.0 2048\n112.192.0.0 262144\n112.224.0.0 2097152\n113.0.0.0 524288\n113.8.0.0 131072\n113.11.192.0 8192\n113.12.0.0 262144\n113.16.0.0 131072\n113.18.0.0 65536\n113.21.232.0 1024\n113.21.236.0 1024\n113.24.0.0 262144\n113.31.0.0 65536\n113.44.0.0 262144\n113.48.0.0 262144\n113.52.160.0 8192\n113.52.228.0 1024\n113.54.0.0 131072\n113.56.0.0 131072\n113.58.0.0 65536\n113.59.0.0 32768\n113.59.224.0 1024\n113.62.0.0 131072\n113.64.0.0 2097152\n113.96.0.0 1048576\n113.112.0.0 524288\n113.120.0.0 524288\n113.128.0.0 131072\n113.130.96.0 4096\n113.130.112.0 2048\n113.132.0.0 262144\n113.136.0.0 524288\n113.192.40.0 512\n113.192.56.0 512\n113.194.0.0 131072\n113.197.100.0 1024\n113.200.0.0 131072\n113.202.0.0 65536\n113.204.0.0 262144\n113.208.96.0 8192\n113.208.128.0 32768\n113.209.0.0 65536\n113.212.0.0 16384\n113.212.88.0 1024\n113.212.100.0 1024\n113.212.184.0 2048\n113.213.0.0 32768\n113.214.0.0 131072\n113.218.0.0 131072\n113.220.0.0 262144\n113.224.0.0 1048576\n113.240.0.0 524288\n113.248.0.0 262144\n114.28.0.0 65536\n114.31.64.0 1024\n114.31.68.0 1024\n114.54.0.0 131072\n114.60.0.0 262144\n114.64.0.0 262144\n114.68.0.0 65536\n114.79.64.0 16384\n114.80.0.0 1048576\n114.96.0.0 524288\n114.104.0.0 262144\n114.110.0.0 4096\n114.110.64.0 16384\n114.111.0.0 8192\n114.111.160.0 8192\n114.112.0.0 262144\n114.116.0.0 65536\n114.117.0.0 32768\n114.117.128.0 32768\n114.118.0.0 65536\n114.119.0.0 32768\n114.119.192.0 2048\n114.119.200.0 1024\n114.119.204.0 1024\n114.119.208.0 4096\n114.119.224.0 8192\n114.132.0.0 65536\n114.134.184.0 1024\n114.134.188.0 512\n114.135.0.0 65536\n114.138.0.0 131072\n114.141.64.0 2048\n114.141.80.0 1024\n114.141.84.0 1024\n114.141.128.0 16384\n114.142.136.0 2048\n114.196.0.0 131072\n114.198.248.0 2048\n114.208.0.0 262144\n114.212.0.0 131072\n114.214.0.0 65536\n114.215.0.0 65536\n114.216.0.0 524288\n114.224.0.0 1048576\n114.240.0.0 1048576\n115.24.0.0 262144\n115.28.0.0 131072\n115.31.64.0 1024\n115.31.68.0 1024\n115.31.72.0 1024\n115.31.76.0 1024\n115.32.0.0 262144\n115.42.56.0 1024\n115.44.0.0 131072\n115.46.0.0 65536\n115.47.0.0 65536\n115.48.0.0 1048576\n115.69.64.0 4096\n115.84.0.0 16384\n115.84.192.0 8192\n115.85.192.0 16384\n115.100.0.0 262144\n115.104.0.0 262144\n115.120.0.0 262144\n115.124.16.0 4096\n115.148.0.0 262144\n115.152.0.0 131072\n115.154.0.0 131072\n115.156.0.0 131072\n115.158.0.0 65536\n115.159.0.0 65536\n115.166.64.0 8192\n115.168.0.0 262144\n115.172.0.0 262144\n115.180.0.0 131072\n115.182.0.0 65536\n115.183.0.0 65536\n115.187.0.0 1024\n115.187.4.0 1024\n115.187.8.0 1024\n115.187.12.0 1024\n115.190.0.0 131072\n115.192.0.0 2097152\n115.224.0.0 1048576\n116.0.8.0 2048\n116.0.24.0 2048\n116.1.0.0 65536\n116.2.0.0 131072\n116.4.0.0 262144\n116.8.0.0 262144\n116.13.0.0 65536\n116.16.0.0 1048576\n116.50.0.0 4096\n116.52.0.0 262144\n116.56.0.0 131072\n116.58.128.0 4096\n116.58.208.0 4096\n116.60.0.0 262144\n116.66.0.0 32768\n116.66.176.0 1024\n116.68.136.0 1024\n116.68.140.0 1024\n116.68.176.0 1024\n116.68.180.0 1024\n116.69.0.0 65536\n116.70.0.0 32768\n116.76.0.0 131072\n116.78.0.0 131072\n116.85.0.0 65536\n116.89.144.0 4096\n116.89.240.0 1024\n116.90.80.0 4096\n116.90.184.0 2048\n116.95.0.0 65536\n116.112.0.0 262144\n116.116.0.0 131072\n116.128.0.0 4194304\n116.192.0.0 65536\n116.193.16.0 4096\n116.193.32.0 8192\n116.193.152.0 1024\n116.193.164.0 1024\n116.193.176.0 2048\n116.194.0.0 131072\n116.196.0.0 32768\n116.196.128.0 16384\n116.196.192.0 16384\n116.197.160.0 1024\n116.197.164.0 1024\n116.198.0.0 65536\n116.199.0.0 32768\n116.199.128.0 8192\n116.204.0.0 32768\n116.204.132.0 1024\n116.204.216.0 1024\n116.205.0.0 65536\n116.207.0.0 65536\n116.208.0.0 262144\n116.212.160.0 4096\n116.213.44.0 1024\n116.213.64.0 16384\n116.213.128.0 32768\n116.214.32.0 8192\n116.214.64.0 4096\n116.214.128.0 32768\n116.215.0.0 65536\n116.216.0.0 262144\n116.224.0.0 1048576\n116.242.0.0 131072\n116.244.0.0 131072\n116.246.0.0 131072\n116.248.0.0 131072\n116.251.64.0 16384\n116.252.0.0 131072\n116.254.104.0 1024\n116.254.108.0 1024\n116.254.128.0 32768\n116.255.128.0 32768\n117.8.0.0 524288\n117.21.0.0 65536\n117.22.0.0 131072\n117.24.0.0 524288\n117.32.0.0 524288\n117.40.0.0 262144\n117.44.0.0 131072\n117.48.0.0 262144\n117.53.48.0 4096\n117.53.176.0 4096\n117.57.0.0 65536\n117.58.0.0 32768\n117.59.0.0 65536\n117.60.0.0 262144\n117.64.0.0 524288\n117.72.0.0 131072\n117.74.64.0 4096\n117.74.80.0 4096\n117.74.128.0 32768\n117.75.0.0 65536\n117.76.0.0 262144\n117.80.0.0 1048576\n117.100.0.0 131072\n117.103.16.0 4096\n117.103.40.0 2048\n117.103.72.0 2048\n117.103.128.0 4096\n117.104.168.0 2048\n117.106.0.0 131072\n117.112.0.0 524288\n117.120.64.0 16384\n117.120.128.0 32768\n117.121.0.0 32768\n117.121.128.0 16384\n117.121.192.0 2048\n117.122.128.0 32768\n117.124.0.0 262144\n117.128.0.0 4194304\n118.24.0.0 131072\n118.26.0.0 8192\n118.26.32.0 1024\n118.26.40.0 2048\n118.26.48.0 2048\n118.26.56.0 2048\n118.26.64.0 8192\n118.26.96.0 2048\n118.26.112.0 2048\n118.26.120.0 2048\n118.26.128.0 1024\n118.26.133.0 256\n118.26.134.0 512\n118.26.136.0 2048\n118.26.160.0 4096\n118.26.188.0 1024\n118.26.192.0 16384\n118.28.0.0 131072\n118.30.0.0 65536\n118.31.0.0 65536\n118.64.0.0 131072\n118.66.0.0 65536\n118.67.112.0 4096\n118.72.0.0 524288\n118.80.0.0 131072\n118.84.0.0 131072\n118.88.32.0 8192\n118.88.64.0 16384\n118.88.128.0 32768\n118.89.0.0 65536\n118.91.240.0 4096\n118.102.16.0 4096\n118.102.32.0 2048\n118.103.164.0 1024\n118.103.168.0 1024\n118.103.172.0 1024\n118.103.176.0 1024\n118.112.0.0 524288\n118.120.0.0 262144\n118.124.0.0 131072\n118.126.0.0 65536\n118.127.128.0 8192\n118.132.0.0 262144\n118.144.0.0 262144\n118.178.0.0 65536\n118.180.0.0 262144\n118.184.0.0 32768\n118.184.128.0 32768\n118.186.0.0 131072\n118.188.0.0 65536\n118.190.0.0 65536\n118.191.0.0 2048\n118.191.8.0 1024\n118.191.12.0 256\n118.191.16.0 2048\n118.191.64.0 4096\n118.191.80.0 1024\n118.191.128.0 8192\n118.191.176.0 4096\n118.191.192.0 4096\n118.191.208.0 256\n118.191.216.0 1024\n118.191.223.0 256\n118.191.224.0 256\n118.191.240.0 4096\n118.192.0.0 65536\n118.193.0.0 2048\n118.193.8.0 2048\n118.193.48.0 2048\n118.193.96.0 8192\n118.193.128.0 32768\n118.194.0.0 32768\n118.194.128.0 16384\n118.194.192.0 8192\n118.194.224.0 1024\n118.194.240.0 2048\n118.195.0.0 32768\n118.195.128.0 32768\n118.196.0.0 262144\n118.202.0.0 131072\n118.204.0.0 262144\n118.212.0.0 65536\n118.213.0.0 65536\n118.215.192.0 16384\n118.224.0.0 262144\n118.228.0.0 131072\n118.230.0.0 65536\n118.239.0.0 65536\n118.242.0.0 65536\n118.244.0.0 262144\n118.248.0.0 524288\n119.0.0.0 131072\n119.2.0.0 8192\n119.2.128.0 32768\n119.3.0.0 65536\n119.4.0.0 262144\n119.10.0.0 32768\n119.15.136.0 2048\n119.16.0.0 65536\n119.18.192.0 4096\n119.18.208.0 2048\n119.18.224.0 4096\n119.18.240.0 4096\n119.19.0.0 65536\n119.20.0.0 262144\n119.27.64.0 16384\n119.27.128.0 8192\n119.27.160.0 8192\n119.27.192.0 16384\n119.28.0.0 131072\n119.30.48.0 4096\n119.31.192.0 8192\n119.32.0.0 262144\n119.36.0.0 65536\n119.37.0.0 32768\n119.37.128.0 16384\n119.37.192.0 16384\n119.38.0.0 32768\n119.38.128.0 16384\n119.38.192.0 4096\n119.38.208.0 4096\n119.38.224.0 8192\n119.39.0.0 65536\n119.40.0.0 16384\n119.40.64.0 4096\n119.40.128.0 32768\n119.41.0.0 65536\n119.42.0.0 8192\n119.42.128.0 2048\n119.42.136.0 2048\n119.42.224.0 8192\n119.44.0.0 131072\n119.48.0.0 524288\n119.57.0.0 65536\n119.58.0.0 65536\n119.59.128.0 32768\n119.60.0.0 65536\n119.61.0.0 65536\n119.62.0.0 65536\n119.63.32.0 8192\n119.75.208.0 4096\n119.78.0.0 131072\n119.80.0.0 65536\n119.82.208.0 4096\n119.84.0.0 262144\n119.88.0.0 262144\n119.96.0.0 524288\n119.108.0.0 131072\n119.112.0.0 524288\n119.120.0.0 524288\n119.128.0.0 1048576\n119.144.0.0 262144\n119.148.160.0 4096\n119.148.176.0 4096\n119.151.192.0 16384\n119.160.200.0 2048\n119.161.120.0 1024\n119.161.124.0 1024\n119.161.128.0 32768\n119.162.0.0 131072\n119.164.0.0 262144\n119.176.0.0 1048576\n119.232.0.0 65536\n119.233.0.0 32768\n119.233.128.0 32768\n119.235.128.0 16384\n119.248.0.0 262144\n119.252.96.0 2048\n119.252.240.0 4096\n119.253.0.0 65536\n119.254.0.0 131072\n120.0.0.0 1048576\n120.24.0.0 262144\n120.30.0.0 65536\n120.31.0.0 65536\n120.32.0.0 524288\n120.40.0.0 262144\n120.44.0.0 131072\n120.46.0.0 65536\n120.47.0.0 65536\n120.48.0.0 131072\n120.52.0.0 65536\n120.53.0.0 65536\n120.54.0.0 131072\n120.64.0.0 262144\n120.68.0.0 262144\n120.72.32.0 8192\n120.72.128.0 32768\n120.76.0.0 262144\n120.80.0.0 524288\n120.88.8.0 2048\n120.90.0.0 131072\n120.92.0.0 65536\n120.94.0.0 65536\n120.95.0.0 65536\n120.128.0.0 262144\n120.132.0.0 32768\n120.132.128.0 32768\n120.133.0.0 65536\n120.134.0.0 131072\n120.136.16.0 1024\n120.136.20.0 1024\n120.136.128.0 16384\n120.137.0.0 32768\n120.143.128.0 8192\n120.192.0.0 4194304\n121.0.8.0 2048\n121.0.16.0 4096\n121.4.0.0 131072\n121.8.0.0 524288\n121.16.0.0 524288\n121.24.0.0 262144\n121.28.0.0 131072\n121.30.0.0 65536\n121.31.0.0 65536\n121.32.0.0 262144\n121.36.0.0 65536\n121.37.0.0 65536\n121.38.0.0 131072\n121.40.0.0 262144\n121.46.0.0 16384\n121.46.76.0 1024\n121.46.128.0 32768\n121.47.0.0 65536\n121.48.0.0 131072\n121.50.8.0 2048\n121.51.0.0 65536\n121.52.160.0 8192\n121.52.208.0 4096\n121.52.224.0 8192\n121.54.176.0 2048\n121.54.188.0 1024\n121.55.0.0 16384\n121.56.0.0 131072\n121.58.0.0 32768\n121.58.136.0 2048\n121.58.144.0 4096\n121.58.160.0 2048\n121.59.0.0 65536\n121.60.0.0 262144\n121.68.0.0 262144\n121.76.0.0 131072\n121.79.128.0 16384\n121.89.0.0 65536\n121.91.104.0 2048\n121.100.128.0 32768\n121.101.0.0 16384\n121.101.208.0 4096\n121.192.0.0 65536\n121.193.0.0 65536\n121.194.0.0 131072\n121.196.0.0 262144\n121.200.192.0 2048\n121.201.0.0 65536\n121.204.0.0 262144\n121.224.0.0 1048576\n121.248.0.0 262144\n121.255.0.0 65536\n122.0.64.0 16384\n122.0.128.0 32768\n122.4.0.0 262144\n122.8.0.0 32768\n122.8.192.0 16384\n122.9.0.0 65536\n122.10.128.0 1024\n122.10.132.0 512\n122.10.136.0 512\n122.10.164.0 1024\n122.10.168.0 2048\n122.10.176.0 4096\n122.10.192.0 1024\n122.10.200.0 2048\n122.10.208.0 2048\n122.10.216.0 1024\n122.10.228.0 1024\n122.10.232.0 2048\n122.10.240.0 1024\n122.11.0.0 32768\n122.12.0.0 65536\n122.13.0.0 65536\n122.14.0.0 32768\n122.14.128.0 16384\n122.14.192.0 16384\n122.48.0.0 65536\n122.49.0.0 16384\n122.51.0.0 65536\n122.64.0.0 2097152\n122.96.0.0 131072\n122.102.0.0 4096\n122.102.64.0 4096\n122.102.80.0 4096\n122.112.0.0 16384\n122.112.64.0 16384\n122.112.128.0 32768\n122.113.0.0 65536\n122.114.0.0 65536\n122.115.0.0 32768\n122.115.128.0 8192\n122.115.160.0 8192\n122.115.192.0 8192\n122.115.224.0 8192\n122.119.0.0 65536\n122.128.100.0 1024\n122.128.120.0 2048\n122.136.0.0 524288\n122.144.128.0 32768\n122.152.192.0 16384\n122.156.0.0 262144\n122.188.0.0 262144\n122.192.0.0 262144\n122.198.0.0 65536\n122.200.40.0 1024\n122.200.44.0 1024\n122.200.64.0 16384\n122.201.48.0 4096\n122.204.0.0 262144\n122.224.0.0 1048576\n122.240.0.0 524288\n122.248.24.0 2048\n122.248.48.0 4096\n122.255.64.0 2048\n123.0.128.0 16384\n123.4.0.0 262144\n123.8.0.0 524288\n123.49.128.0 32768\n123.50.160.0 8192\n123.52.0.0 262144\n123.56.0.0 131072\n123.58.0.0 4096\n123.58.16.0 4096\n123.58.32.0 8192\n123.58.64.0 8192\n123.58.96.0 8192\n123.58.128.0 16384\n123.58.224.0 4096\n123.58.240.0 4096\n123.59.0.0 65536\n123.60.0.0 65536\n123.61.0.0 65536\n123.62.0.0 65536\n123.64.0.0 2097152\n123.96.0.0 131072\n123.98.0.0 32768\n123.99.128.0 32768\n123.100.0.0 8192\n123.101.0.0 65536\n123.103.0.0 32768\n123.108.88.0 512\n123.108.128.0 4096\n123.108.208.0 4096\n123.112.0.0 1048576\n123.128.0.0 524288\n123.136.80.0 4096\n123.137.0.0 65536\n123.138.0.0 131072\n123.144.0.0 262144\n123.148.0.0 65536\n123.149.0.0 65536\n123.150.0.0 131072\n123.152.0.0 524288\n123.160.0.0 262144\n123.164.0.0 262144\n123.168.0.0 262144\n123.172.0.0 131072\n123.174.0.0 131072\n123.176.60.0 1024\n123.176.80.0 4096\n123.177.0.0 65536\n123.178.0.0 131072\n123.180.0.0 262144\n123.184.0.0 262144\n123.188.0.0 262144\n123.196.0.0 131072\n123.199.128.0 32768\n123.206.0.0 131072\n123.232.0.0 262144\n123.242.0.0 32768\n123.242.192.0 1024\n123.242.196.0 1024\n123.244.0.0 262144\n123.249.0.0 65536\n123.253.240.0 1024\n123.254.96.0 1024\n123.254.100.0 1024\n124.6.64.0 16384\n124.14.0.0 131072\n124.16.0.0 131072\n124.20.0.0 65536\n124.21.0.0 4096\n124.21.16.0 4096\n124.21.32.0 8192\n124.21.64.0 16384\n124.21.128.0 32768\n124.22.0.0 131072\n124.28.192.0 16384\n124.29.0.0 32768\n124.31.0.0 65536\n124.40.112.0 4096\n124.40.128.0 16384\n124.40.192.0 8192\n124.40.240.0 1024\n124.42.0.0 32768\n124.42.128.0 32768\n124.47.0.0 16384\n124.64.0.0 131072\n124.66.0.0 32768\n124.67.0.0 65536\n124.68.0.0 131072\n124.70.0.0 131072\n124.72.0.0 65536\n124.73.0.0 65536\n124.74.0.0 131072\n124.76.0.0 262144\n124.88.0.0 65536\n124.89.0.0 32768\n124.89.128.0 32768\n124.90.0.0 131072\n124.92.0.0 262144\n124.108.8.0 2048\n124.108.40.0 2048\n124.109.96.0 2048\n124.112.0.0 131072\n124.114.0.0 131072\n124.116.0.0 65536\n124.117.0.0 65536\n124.118.0.0 131072\n124.126.0.0 131072\n124.128.0.0 524288\n124.147.128.0 32768\n124.150.137.0 256\n124.151.0.0 65536\n124.152.0.0 65536\n124.160.0.0 65536\n124.161.0.0 65536\n124.162.0.0 65536\n124.163.0.0 65536\n124.164.0.0 262144\n124.172.0.0 131072\n124.174.0.0 131072\n124.192.0.0 131072\n124.196.0.0 65536\n124.200.0.0 524288\n124.220.0.0 262144\n124.224.0.0 65536\n124.225.0.0 65536\n124.226.0.0 131072\n124.228.0.0 262144\n124.232.0.0 131072\n124.234.0.0 131072\n124.236.0.0 262144\n124.240.0.0 32768\n124.240.128.0 16384\n124.242.0.0 65536\n124.243.192.0 16384\n124.248.0.0 32768\n124.249.0.0 65536\n124.250.0.0 131072\n124.254.0.0 16384\n125.31.192.0 16384\n125.32.0.0 65536\n125.33.0.0 65536\n125.34.0.0 65536\n125.35.0.0 32768\n125.35.128.0 32768\n125.36.0.0 262144\n125.40.0.0 524288\n125.58.128.0 32768\n125.61.128.0 32768\n125.62.0.0 16384\n125.64.0.0 524288\n125.72.0.0 65536\n125.73.0.0 65536\n125.74.0.0 131072\n125.76.0.0 32768\n125.76.128.0 32768\n125.77.0.0 65536\n125.78.0.0 131072\n125.80.0.0 524288\n125.88.0.0 524288\n125.96.0.0 131072\n125.98.0.0 65536\n125.104.0.0 524288\n125.112.0.0 1048576\n125.169.0.0 65536\n125.171.0.0 65536\n125.208.0.0 16384\n125.210.0.0 65536\n125.211.0.0 65536\n125.213.0.0 32768\n125.214.96.0 8192\n125.215.0.0 16384\n125.216.0.0 131072\n125.218.0.0 65536\n125.219.0.0 65536\n125.220.0.0 131072\n125.222.0.0 131072\n125.254.128.0 16384\n125.254.192.0 16384\n128.108.0.0 65536\n129.28.0.0 65536\n129.204.0.0 65536\n129.211.0.0 65536\n132.232.0.0 65536\n134.175.0.0 65536\n137.59.59.0 256\n137.59.88.0 1024\n139.5.56.0 1024\n139.5.60.0 1024\n139.5.80.0 1024\n139.5.92.0 1024\n139.5.108.0 1024\n139.5.128.0 1024\n139.5.160.0 1024\n139.5.192.0 1024\n139.5.204.0 1024\n139.5.212.0 1024\n139.5.244.0 1024\n139.9.0.0 65536\n139.129.0.0 65536\n139.148.0.0 65536\n139.155.0.0 65536\n139.159.0.0 65536\n139.170.0.0 65536\n139.176.0.0 65536\n139.183.0.0 65536\n139.186.0.0 65536\n139.189.0.0 65536\n139.196.0.0 262144\n139.200.0.0 524288\n139.208.0.0 524288\n139.217.0.0 65536\n139.219.0.0 65536\n139.220.0.0 131072\n139.224.0.0 65536\n139.226.0.0 131072\n140.75.0.0 65536\n140.143.0.0 65536\n140.179.0.0 65536\n140.205.0.0 65536\n140.206.0.0 131072\n140.210.0.0 32768\n140.210.128.0 32768\n140.224.0.0 65536\n140.237.0.0 65536\n140.240.0.0 65536\n140.243.0.0 65536\n140.246.0.0 65536\n140.249.0.0 65536\n140.250.0.0 65536\n140.255.0.0 65536\n142.70.0.0 65536\n142.86.0.0 65536\n143.64.0.0 65536\n144.0.0.0 65536\n144.7.0.0 65536\n144.12.0.0 65536\n144.48.64.0 1024\n144.48.88.0 1024\n144.48.156.0 1024\n144.48.180.0 1024\n144.48.184.0 1024\n144.48.204.0 1024\n144.48.208.0 1024\n144.48.212.0 1024\n144.48.220.0 1024\n144.48.252.0 1024\n144.52.0.0 65536\n144.123.0.0 65536\n144.255.0.0 65536\n146.56.192.0 16384\n146.196.56.0 1024\n146.196.68.0 1024\n146.196.72.0 1024\n146.196.92.0 1024\n146.196.112.0 1024\n146.196.116.0 1024\n146.196.124.0 1024\n148.70.0.0 65536\n149.41.0.0 65536\n150.0.0.0 65536\n150.115.0.0 65536\n150.121.0.0 65536\n150.122.0.0 65536\n150.129.136.0 1024\n150.129.192.0 1024\n150.129.252.0 1024\n150.138.0.0 131072\n150.158.0.0 65536\n150.223.0.0 65536\n150.242.0.0 1024\n150.242.4.0 1024\n150.242.8.0 1024\n150.242.28.0 1024\n150.242.44.0 1024\n150.242.48.0 1024\n150.242.52.0 1024\n150.242.56.0 1024\n150.242.76.0 1024\n150.242.80.0 1024\n150.242.92.0 1024\n150.242.96.0 1024\n150.242.112.0 1024\n150.242.116.0 1024\n150.242.120.0 1024\n150.242.152.0 1024\n150.242.156.0 1024\n150.242.160.0 1024\n150.242.164.0 1024\n150.242.168.0 1024\n150.242.184.0 1024\n150.242.188.0 1024\n150.242.192.0 1024\n150.242.212.0 1024\n150.242.224.0 1024\n150.242.232.0 1024\n150.242.236.0 1024\n150.242.240.0 1024\n150.242.244.0 1024\n150.242.248.0 1024\n150.248.0.0 65536\n150.255.0.0 65536\n152.104.128.0 32768\n152.136.0.0 65536\n153.0.0.0 65536\n153.3.0.0 65536\n153.34.0.0 131072\n153.36.0.0 131072\n153.99.0.0 65536\n153.101.0.0 65536\n153.118.0.0 131072\n154.8.128.0 32768\n157.0.0.0 65536\n157.10.34.0 512\n157.10.36.0 512\n157.10.112.0 512\n157.10.118.0 512\n157.10.130.0 512\n157.10.218.0 512\n157.10.220.0 512\n157.10.246.0 512\n157.15.74.0 512\n157.15.94.0 512\n157.15.100.0 512\n157.15.102.0 512\n157.15.104.0 512\n157.15.200.0 512\n157.18.0.0 65536\n157.61.0.0 65536\n157.119.8.0 1024\n157.119.12.0 1024\n157.119.16.0 1024\n157.119.28.0 1024\n157.119.132.0 1024\n157.119.136.0 1024\n157.119.140.0 1024\n157.119.144.0 1024\n157.119.148.0 1024\n157.119.152.0 1024\n157.119.156.0 1024\n157.119.160.0 1024\n157.119.164.0 1024\n157.119.172.0 1024\n157.119.192.0 1024\n157.119.196.0 1024\n157.119.240.0 1024\n157.119.252.0 1024\n157.122.0.0 65536\n157.148.0.0 65536\n157.156.0.0 65536\n157.255.0.0 65536\n158.60.0.0 65536\n158.79.0.0 65536\n159.27.0.0 65536\n159.75.0.0 65536\n159.226.0.0 65536\n160.19.208.0 1024\n160.19.212.0 1024\n160.19.216.0 1024\n160.20.48.0 1024\n160.202.60.0 1024\n160.202.148.0 1024\n160.202.152.0 1024\n160.202.168.0 1024\n160.202.212.0 1024\n160.202.216.0 1024\n160.202.220.0 1024\n160.202.224.0 1024\n160.202.228.0 1024\n160.202.232.0 1024\n160.202.236.0 1024\n160.202.240.0 1024\n160.202.244.0 1024\n160.202.248.0 1024\n160.202.252.0 1024\n161.120.0.0 65536\n161.189.0.0 65536\n161.207.0.0 65536\n162.14.0.0 65536\n162.105.0.0 65536\n163.0.0.0 65536\n163.47.4.0 1024\n163.53.0.0 1024\n163.53.4.0 1024\n163.53.8.0 1024\n163.53.12.0 1024\n163.53.36.0 1024\n163.53.40.0 1024\n163.53.44.0 1024\n163.53.48.0 1024\n163.53.52.0 1024\n163.53.56.0 1024\n163.53.60.0 1024\n163.53.64.0 1024\n163.53.88.0 1024\n163.53.92.0 1024\n163.53.96.0 1024\n163.53.100.0 1024\n163.53.104.0 1024\n163.53.108.0 1024\n163.53.112.0 1024\n163.53.116.0 1024\n163.53.120.0 1024\n163.53.124.0 1024\n163.53.128.0 1024\n163.53.132.0 1024\n163.53.136.0 1024\n163.53.160.0 1024\n163.53.164.0 1024\n163.53.168.0 1024\n163.53.172.0 1024\n163.53.188.0 1024\n163.53.240.0 1024\n163.125.0.0 65536\n163.142.0.0 65536\n163.177.0.0 65536\n163.179.0.0 65536\n163.204.0.0 65536\n163.228.0.0 65536\n164.52.0.0 32768\n166.111.0.0 65536\n167.139.0.0 65536\n167.189.0.0 65536\n167.220.244.0 1024\n168.160.0.0 65536\n170.179.0.0 65536\n171.8.0.0 524288\n171.34.0.0 131072\n171.36.0.0 262144\n171.40.0.0 524288\n171.80.0.0 262144\n171.84.0.0 262144\n171.88.0.0 524288\n171.104.0.0 524288\n171.112.0.0 262144\n171.116.0.0 262144\n171.120.0.0 524288\n171.208.0.0 1048576\n172.81.192.0 16384\n175.0.0.0 1048576\n175.16.0.0 524288\n175.24.0.0 65536\n175.25.0.0 65536\n175.26.0.0 65536\n175.27.0.0 65536\n175.30.0.0 131072\n175.42.0.0 131072\n175.44.0.0 65536\n175.46.0.0 131072\n175.48.0.0 1048576\n175.64.0.0 2097152\n175.102.0.0 65536\n175.106.128.0 32768\n175.111.144.0 1024\n175.111.148.0 1024\n175.111.152.0 1024\n175.111.156.0 1024\n175.111.160.0 1024\n175.111.164.0 1024\n175.111.168.0 1024\n175.111.172.0 1024\n175.111.184.0 1024\n175.146.0.0 131072\n175.148.0.0 262144\n175.152.0.0 262144\n175.158.96.0 1024\n175.160.0.0 1048576\n175.176.156.0 1024\n175.176.176.0 1024\n175.176.188.0 1024\n175.178.0.0 65536\n175.184.128.0 16384\n175.185.0.0 65536\n175.186.0.0 131072\n175.188.0.0 262144\n180.76.0.0 65536\n180.77.0.0 65536\n180.78.0.0 131072\n180.84.0.0 131072\n180.86.0.0 65536\n180.88.0.0 262144\n180.94.56.0 2048\n180.94.96.0 4096\n180.94.120.0 1024\n180.94.124.0 1024\n180.95.128.0 32768\n180.96.0.0 2097152\n180.129.128.0 32768\n180.130.0.0 65536\n180.136.0.0 524288\n180.148.16.0 2048\n180.148.152.0 2048\n180.148.216.0 2048\n180.148.224.0 8192\n180.149.128.0 8192\n180.149.236.0 1024\n180.150.160.0 8192\n180.152.0.0 524288\n180.160.0.0 1048576\n180.178.112.0 1024\n180.178.116.0 1024\n180.178.192.0 16384\n180.184.0.0 131072\n180.186.0.0 65536\n180.187.0.0 65536\n180.188.0.0 32768\n180.189.148.0 1024\n180.200.252.0 1024\n180.201.0.0 65536\n180.202.0.0 131072\n180.208.0.0 131072\n180.210.212.0 1024\n180.210.224.0 8192\n180.212.0.0 131072\n180.222.224.0 8192\n180.223.0.0 65536\n180.233.0.0 16384\n180.233.64.0 8192\n180.233.144.0 1024\n180.235.64.0 8192\n180.235.112.0 1024\n182.16.144.0 1024\n182.16.148.0 1024\n182.16.192.0 8192\n182.18.0.0 32768\n182.23.184.0 2048\n182.23.200.0 2048\n182.32.0.0 1048576\n182.48.96.0 8192\n182.49.0.0 65536\n182.50.0.0 4096\n182.50.112.0 4096\n182.51.0.0 65536\n182.54.0.0 32768\n182.54.244.0 1024\n182.61.0.0 65536\n182.80.0.0 262144\n182.84.0.0 262144\n182.88.0.0 262144\n182.92.0.0 65536\n182.96.0.0 1048576\n182.112.0.0 1048576\n182.128.0.0 1048576\n182.144.0.0 524288\n182.157.0.0 65536\n182.160.64.0 8192\n182.174.0.0 131072\n182.200.0.0 524288\n182.236.128.0 32768\n182.237.24.0 1024\n182.237.28.0 1024\n182.238.0.0 65536\n182.239.0.0 8192\n182.240.0.0 524288\n182.254.0.0 65536\n182.255.60.0 1024\n183.0.0.0 4194304\n183.64.0.0 524288\n183.78.160.0 1024\n183.78.164.0 1024\n183.78.180.0 1024\n183.81.172.0 1024\n183.81.180.0 1024\n183.84.0.0 131072\n183.91.128.0 1024\n183.91.136.0 2048\n183.91.144.0 4096\n183.92.0.0 262144\n183.128.0.0 2097152\n183.160.0.0 524288\n183.168.0.0 131072\n183.170.0.0 65536\n183.172.0.0 262144\n183.182.0.0 8192\n183.184.0.0 524288\n183.192.0.0 4194304\n185.203.36.0 1024\n188.131.128.0 32768\n192.51.188.0 256\n192.55.46.0 512\n192.55.68.0 1024\n192.102.204.0 1024\n192.124.154.0 256\n192.140.128.0 1024\n192.140.132.0 1024\n192.140.136.0 1024\n192.140.156.0 1024\n192.140.160.0 1024\n192.140.164.0 1024\n192.140.168.0 1024\n192.140.172.0 1024\n192.140.176.0 1024\n192.140.180.0 1024\n192.140.184.0 1024\n192.140.188.0 1024\n192.140.192.0 1024\n192.140.196.0 1024\n192.140.200.0 1024\n192.140.204.0 1024\n192.140.208.0 1024\n192.140.212.0 1024\n192.144.128.0 32768\n192.197.113.0 256\n193.112.0.0 65536\n198.175.100.0 1024\n199.212.57.0 256\n202.0.100.0 512\n202.0.122.0 512\n202.0.176.0 1024\n202.3.128.0 512\n202.4.128.0 8192\n202.4.252.0 1024\n202.5.208.0 1024\n202.5.212.0 1024\n202.5.216.0 1024\n202.6.6.0 512\n202.6.66.0 512\n202.6.72.0 512\n202.6.87.0 256\n202.6.88.0 512\n202.6.92.0 512\n202.6.103.0 256\n202.6.108.0 256\n202.6.110.0 512\n202.6.114.0 256\n202.6.176.0 4096\n202.8.0.0 256\n202.8.2.0 512\n202.8.4.0 512\n202.8.12.0 256\n202.8.24.0 256\n202.8.77.0 256\n202.8.120.0 1024\n202.8.128.0 8192\n202.8.192.0 4096\n202.9.32.0 256\n202.9.34.0 512\n202.9.48.0 512\n202.9.51.0 256\n202.9.52.0 512\n202.9.54.0 256\n202.9.57.0 256\n202.9.58.0 512\n202.10.64.0 4096\n202.10.112.0 1024\n202.10.116.0 1024\n202.10.120.0 1024\n202.10.124.0 1024\n202.12.1.0 256\n202.12.2.0 256\n202.12.17.0 256\n202.12.18.0 256\n202.12.72.0 256\n202.12.84.0 512\n202.12.96.0 256\n202.12.98.0 512\n202.12.106.0 256\n202.12.111.0 256\n202.12.116.0 256\n202.14.64.0 512\n202.14.69.0 256\n202.14.73.0 256\n202.14.74.0 512\n202.14.76.0 256\n202.14.78.0 512\n202.14.88.0 256\n202.14.97.0 256\n202.14.104.0 512\n202.14.108.0 512\n202.14.111.0 256\n202.14.114.0 512\n202.14.118.0 512\n202.14.124.0 512\n202.14.127.0 256\n202.14.129.0 256\n202.14.135.0 256\n202.14.136.0 256\n202.14.149.0 256\n202.14.151.0 256\n202.14.157.0 256\n202.14.158.0 512\n202.14.169.0 256\n202.14.170.0 512\n202.14.172.0 1024\n202.14.176.0 256\n202.14.184.0 512\n202.14.208.0 512\n202.14.213.0 256\n202.14.219.0 256\n202.14.220.0 256\n202.14.222.0 512\n202.14.225.0 256\n202.14.226.0 512\n202.14.231.0 256\n202.14.235.0 256\n202.14.236.0 512\n202.14.238.0 256\n202.14.239.0 256\n202.14.246.0 256\n202.14.251.0 256\n202.20.66.0 256\n202.20.79.0 256\n202.20.87.0 256\n202.20.88.0 512\n202.20.90.0 256\n202.20.94.0 512\n202.20.114.0 256\n202.20.117.0 256\n202.20.120.0 256\n202.20.125.0 256\n202.20.126.0 256\n202.20.127.0 256\n202.21.48.0 1024\n202.21.52.0 1024\n202.21.56.0 1024\n202.21.60.0 1024\n202.21.131.0 256\n202.21.132.0 256\n202.21.141.0 256\n202.21.142.0 256\n202.21.147.0 256\n202.21.148.0 256\n202.21.150.0 512\n202.21.152.0 512\n202.21.154.0 256\n202.21.156.0 256\n202.22.248.0 1024\n202.22.252.0 1024\n202.27.12.0 256\n202.27.14.0 256\n202.27.136.0 512\n202.36.226.0 256\n202.38.0.0 512\n202.38.2.0 512\n202.38.8.0 2048\n202.38.48.0 4096\n202.38.64.0 8192\n202.38.96.0 8192\n202.38.128.0 512\n202.38.130.0 512\n202.38.132.0 512\n202.38.134.0 256\n202.38.135.0 256\n202.38.136.0 512\n202.38.140.0 512\n202.38.142.0 512\n202.38.146.0 512\n202.38.149.0 256\n202.38.150.0 512\n202.38.152.0 512\n202.38.154.0 512\n202.38.156.0 256\n202.38.158.0 512\n202.38.164.0 1024\n202.38.168.0 512\n202.38.170.0 256\n202.38.176.0 512\n202.38.184.0 2048\n202.38.192.0 16384\n202.40.4.0 512\n202.40.7.0 256\n202.40.15.0 256\n202.40.135.0 256\n202.40.136.0 256\n202.40.140.0 256\n202.40.143.0 256\n202.40.144.0 512\n202.40.150.0 256\n202.40.155.0 256\n202.40.156.0 256\n202.40.158.0 512\n202.40.162.0 256\n202.41.8.0 512\n202.41.11.0 256\n202.41.12.0 512\n202.41.128.0 256\n202.41.130.0 512\n202.41.152.0 2048\n202.41.192.0 256\n202.41.196.0 1024\n202.41.200.0 1024\n202.41.240.0 4096\n202.43.76.0 1024\n202.43.144.0 4096\n202.44.16.0 4096\n202.44.48.0 1024\n202.44.67.0 256\n202.44.74.0 256\n202.44.97.0 256\n202.44.129.0 256\n202.44.132.0 512\n202.44.146.0 512\n202.45.0.0 512\n202.45.2.0 256\n202.45.15.0 256\n202.45.16.0 4096\n202.46.16.0 512\n202.46.18.0 256\n202.46.20.0 512\n202.46.32.0 8192\n202.46.128.0 256\n202.46.224.0 4096\n202.47.82.0 512\n202.47.96.0 1024\n202.47.100.0 1024\n202.47.104.0 1024\n202.47.108.0 1024\n202.47.126.0 256\n202.47.128.0 256\n202.47.130.0 512\n202.52.33.0 256\n202.52.34.0 256\n202.52.47.0 256\n202.52.143.0 256\n202.53.140.0 256\n202.53.143.0 256\n202.57.192.0 1024\n202.57.196.0 1024\n202.57.200.0 1024\n202.57.204.0 1024\n202.57.212.0 1024\n202.57.216.0 1024\n202.57.240.0 4096\n202.58.0.0 256\n202.58.104.0 1024\n202.58.112.0 1024\n202.59.0.0 256\n202.59.1.0 256\n202.59.212.0 1024\n202.59.236.0 256\n202.59.240.0 256\n202.60.48.0 2048\n202.60.96.0 2048\n202.60.112.0 4096\n202.60.132.0 1024\n202.60.136.0 2048\n202.60.144.0 4096\n202.61.68.0 1024\n202.61.76.0 1024\n202.61.88.0 1024\n202.61.123.0 256\n202.61.127.0 256\n202.62.112.0 1024\n202.62.248.0 1024\n202.62.252.0 256\n202.62.255.0 256\n202.63.80.0 256\n202.63.81.0 256\n202.63.82.0 512\n202.63.84.0 1024\n202.63.88.0 2048\n202.63.160.0 8192\n202.63.248.0 1024\n202.63.253.0 256\n202.65.0.0 2048\n202.65.8.0 512\n202.65.96.0 1024\n202.65.100.0 1024\n202.65.104.0 1024\n202.65.108.0 1024\n202.66.168.0 1024\n202.67.0.0 1024\n202.69.4.0 1024\n202.69.16.0 4096\n202.70.0.0 8192\n202.70.96.0 4096\n202.70.192.0 4096\n202.71.32.0 1024\n202.71.36.0 1024\n202.71.40.0 1024\n202.71.44.0 1024\n202.72.40.0 2048\n202.72.80.0 4096\n202.72.112.0 1024\n202.72.116.0 1024\n202.72.120.0 1024\n202.72.124.0 1024\n202.73.128.0 1024\n202.73.240.0 1024\n202.73.244.0 1024\n202.73.248.0 1024\n202.73.252.0 1024\n202.74.8.0 2048\n202.74.36.0 256\n202.74.42.0 256\n202.74.52.0 256\n202.74.80.0 4096\n202.74.254.0 512\n202.75.208.0 4096\n202.75.252.0 1024\n202.76.252.0 1024\n202.77.80.0 2048\n202.77.92.0 1024\n202.78.8.0 2048\n202.79.224.0 2048\n202.79.248.0 1024\n202.80.192.0 2048\n202.80.200.0 2048\n202.81.0.0 1024\n202.81.176.0 1024\n202.81.180.0 1024\n202.81.184.0 1024\n202.81.188.0 1024\n202.83.252.0 1024\n202.84.0.0 1024\n202.84.4.0 1024\n202.84.8.0 2048\n202.84.16.0 512\n202.84.22.0 256\n202.84.24.0 2048\n202.85.208.0 4096\n202.86.249.0 256\n202.86.252.0 1024\n202.87.80.0 4096\n202.88.32.0 1024\n202.89.8.0 2048\n202.89.96.0 1024\n202.89.108.0 1024\n202.89.119.0 256\n202.89.232.0 2048\n202.90.16.0 1024\n202.90.20.0 1024\n202.90.24.0 1024\n202.90.28.0 1024\n202.90.37.0 256\n202.90.96.0 1024\n202.90.100.0 1024\n202.90.104.0 1024\n202.90.108.0 1024\n202.90.112.0 4096\n202.90.193.0 256\n202.90.196.0 256\n202.90.205.0 256\n202.90.224.0 2048\n202.90.232.0 2048\n202.91.0.0 1024\n202.91.96.0 4096\n202.91.176.0 4096\n202.91.224.0 8192\n202.92.8.0 2048\n202.92.48.0 4096\n202.92.252.0 1024\n202.93.252.0 1024\n202.94.74.0 256\n202.94.81.0 256\n202.94.92.0 1024\n202.95.240.0 2048\n202.96.0.0 16384\n202.96.64.0 2048\n202.96.72.0 2048\n202.96.80.0 4096\n202.96.96.0 2048\n202.96.104.0 2048\n202.96.112.0 4096\n202.96.128.0 2048\n202.96.136.0 2048\n202.96.144.0 4096\n202.96.160.0 2048\n202.96.168.0 2048\n202.96.176.0 4096\n202.96.192.0 2048\n202.96.200.0 2048\n202.96.208.0 4096\n202.96.224.0 2048\n202.96.232.0 2048\n202.96.240.0 4096\n202.97.0.0 2048\n202.97.8.0 2048\n202.97.16.0 4096\n202.97.32.0 8192\n202.97.64.0 8192\n202.97.96.0 4096\n202.97.112.0 4096\n202.97.128.0 16384\n202.97.192.0 8192\n202.97.224.0 2048\n202.97.232.0 2048\n202.97.240.0 4096\n202.98.0.0 2048\n202.98.8.0 2048\n202.98.16.0 4096\n202.98.32.0 2048\n202.98.40.0 2048\n202.98.48.0 4096\n202.98.64.0 8192\n202.98.96.0 2048\n202.98.104.0 2048\n202.98.112.0 4096\n202.98.128.0 8192\n202.98.160.0 2048\n202.98.168.0 2048\n202.98.176.0 4096\n202.98.192.0 2048\n202.98.200.0 2048\n202.98.208.0 4096\n202.98.224.0 2048\n202.98.232.0 2048\n202.98.240.0 4096\n202.99.0.0 16384\n202.99.64.0 8192\n202.99.96.0 2048\n202.99.104.0 2048\n202.99.112.0 4096\n202.99.128.0 8192\n202.99.160.0 2048\n202.99.168.0 2048\n202.99.176.0 4096\n202.99.192.0 2048\n202.99.200.0 2048\n202.99.208.0 4096\n202.99.224.0 2048\n202.99.232.0 2048\n202.99.240.0 4096\n202.100.0.0 2048\n202.100.8.0 2048\n202.100.16.0 4096\n202.100.32.0 8192\n202.100.64.0 2048\n202.100.72.0 2048\n202.100.80.0 4096\n202.100.96.0 2048\n202.100.104.0 2048\n202.100.112.0 4096\n202.100.128.0 2048\n202.100.136.0 2048\n202.100.144.0 4096\n202.100.160.0 2048\n202.100.168.0 2048\n202.100.176.0 4096\n202.100.192.0 2048\n202.100.200.0 2048\n202.100.208.0 4096\n202.100.224.0 8192\n202.101.0.0 16384\n202.101.64.0 8192\n202.101.96.0 8192\n202.101.128.0 16384\n202.101.192.0 8192\n202.101.224.0 2048\n202.101.232.0 2048\n202.101.240.0 4096\n202.102.0.0 8192\n202.102.32.0 8192\n202.102.64.0 16384\n202.102.128.0 2048\n202.102.136.0 2048\n202.102.144.0 4096\n202.102.160.0 8192\n202.102.192.0 2048\n202.102.200.0 2048\n202.102.208.0 4096\n202.102.224.0 2048\n202.102.232.0 2048\n202.102.240.0 4096\n202.103.0.0 2048\n202.103.8.0 2048\n202.103.16.0 4096\n202.103.32.0 8192\n202.103.64.0 8192\n202.103.96.0 2048\n202.103.104.0 2048\n202.103.112.0 4096\n202.103.128.0 16384\n202.103.192.0 8192\n202.103.224.0 2048\n202.103.232.0 2048\n202.103.240.0 4096\n202.104.0.0 131072\n202.106.0.0 65536\n202.107.0.0 32768\n202.107.128.0 32768\n202.108.0.0 65536\n202.109.0.0 65536\n202.110.0.0 16384\n202.110.64.0 16384\n202.110.128.0 16384\n202.110.192.0 16384\n202.111.0.0 32768\n202.111.128.0 8192\n202.111.160.0 8192\n202.111.192.0 16384\n202.112.0.0 65536\n202.113.0.0 4096\n202.113.16.0 4096\n202.113.32.0 8192\n202.113.64.0 16384\n202.113.128.0 16384\n202.113.192.0 8192\n202.113.224.0 4096\n202.113.240.0 4096\n202.114.0.0 8192\n202.114.32.0 8192\n202.114.64.0 16384\n202.114.128.0 32768\n202.115.0.0 8192\n202.115.32.0 8192\n202.115.64.0 16384\n202.115.128.0 32768\n202.116.0.0 8192\n202.116.32.0 4096\n202.116.48.0 4096\n202.116.64.0 8192\n202.116.96.0 8192\n202.116.128.0 32768\n202.117.0.0 16384\n202.117.64.0 16384\n202.117.128.0 32768\n202.118.0.0 8192\n202.118.32.0 8192\n202.118.64.0 16384\n202.118.128.0 32768\n202.119.0.0 8192\n202.119.32.0 8192\n202.119.64.0 4096\n202.119.80.0 4096\n202.119.96.0 8192\n202.119.128.0 32768\n202.120.0.0 16384\n202.120.64.0 16384\n202.120.128.0 32768\n202.121.0.0 65536\n202.122.0.0 2048\n202.122.32.0 2048\n202.122.64.0 8192\n202.122.112.0 2048\n202.122.120.0 2048\n202.122.132.0 256\n202.123.96.0 4096\n202.123.116.0 1024\n202.123.120.0 1024\n202.124.16.0 2048\n202.124.24.0 1024\n202.125.107.0 256\n202.125.109.0 256\n202.125.112.0 4096\n202.125.176.0 4096\n202.127.0.0 512\n202.127.2.0 256\n202.127.3.0 256\n202.127.4.0 256\n202.127.5.0 256\n202.127.6.0 512\n202.127.12.0 1024\n202.127.16.0 4096\n202.127.40.0 2048\n202.127.48.0 4096\n202.127.112.0 4096\n202.127.128.0 4096\n202.127.144.0 4096\n202.127.192.0 512\n202.127.194.0 512\n202.127.196.0 1024\n202.127.200.0 2048\n202.127.212.0 1024\n202.127.216.0 2048\n202.127.224.0 8192\n202.129.208.0 256\n202.130.0.0 8192\n202.130.39.0 256\n202.130.224.0 8192\n202.131.16.0 2048\n202.131.48.0 4096\n202.131.208.0 4096\n202.133.32.0 4096\n202.134.58.0 256\n202.134.128.0 4096\n202.134.208.0 1024\n202.134.212.0 1024\n202.134.216.0 1024\n202.134.220.0 1024\n202.136.48.0 4096\n202.136.208.0 4096\n202.136.224.0 4096\n202.136.248.0 1024\n202.137.231.0 256\n202.140.140.0 1024\n202.140.144.0 1024\n202.140.148.0 1024\n202.140.152.0 1024\n202.140.156.0 1024\n202.141.160.0 8192\n202.142.16.0 4096\n202.143.4.0 1024\n202.143.16.0 4096\n202.143.32.0 4096\n202.143.56.0 2048\n202.143.100.0 1024\n202.143.104.0 1024\n202.144.196.0 1024\n202.146.160.0 4096\n202.146.184.0 512\n202.146.186.0 256\n202.146.188.0 1024\n202.146.196.0 1024\n202.146.200.0 2048\n202.147.144.0 4096\n202.148.32.0 4096\n202.148.64.0 8192\n202.148.96.0 8192\n202.149.32.0 8192\n202.149.160.0 8192\n202.149.224.0 8192\n202.150.16.0 4096\n202.150.32.0 4096\n202.150.56.0 1024\n202.150.192.0 4096\n202.150.224.0 8192\n202.151.0.0 1024\n202.151.33.0 256\n202.151.128.0 8192\n202.152.176.0 4096\n202.153.0.0 1024\n202.153.7.0 256\n202.153.48.0 4096\n202.157.192.0 8192\n202.158.160.0 8192\n202.158.242.0 256\n202.160.140.0 1024\n202.160.156.0 1024\n202.160.176.0 4096\n202.162.67.0 256\n202.162.75.0 256\n202.164.0.0 4096\n202.164.96.0 8192\n202.165.176.0 4096\n202.165.208.0 4096\n202.165.239.0 256\n202.165.240.0 512\n202.165.243.0 256\n202.165.245.0 256\n202.165.251.0 256\n202.165.252.0 1024\n202.166.224.0 8192\n202.168.80.0 1024\n202.168.128.0 1024\n202.168.132.0 1024\n202.168.136.0 1024\n202.168.140.0 1024\n202.168.160.0 4096\n202.168.176.0 4096\n202.170.128.0 8192\n202.170.216.0 2048\n202.170.224.0 8192\n202.171.216.0 2048\n202.171.232.0 256\n202.171.235.0 256\n202.172.0.0 1024\n202.172.7.0 256\n202.173.0.0 1024\n202.173.6.0 256\n202.173.8.0 2048\n202.173.112.0 1024\n202.173.224.0 8192\n202.174.64.0 4096\n202.174.124.0 1024\n202.176.224.0 8192\n202.179.160.0 1024\n202.179.164.0 1024\n202.179.168.0 1024\n202.179.172.0 1024\n202.179.240.0 4096\n202.180.128.0 8192\n202.180.208.0 2048\n202.181.8.0 1024\n202.181.28.0 1024\n202.181.112.0 4096\n202.182.32.0 4096\n202.182.192.0 8192\n202.189.0.0 16384\n202.189.80.0 4096\n202.189.184.0 2048\n202.191.0.0 256\n202.191.68.0 1024\n202.191.72.0 2048\n202.191.80.0 4096\n202.192.0.0 524288\n202.200.0.0 262144\n202.204.0.0 262144\n203.0.4.0 1024\n203.0.10.0 512\n203.0.18.0 256\n203.0.24.0 256\n203.0.42.0 512\n203.0.45.0 256\n203.0.46.0 512\n203.0.81.0 256\n203.0.82.0 512\n203.0.90.0 512\n203.0.96.0 512\n203.0.104.0 2048\n203.0.114.0 512\n203.0.122.0 256\n203.0.128.0 256\n203.0.130.0 512\n203.0.132.0 1024\n203.0.137.0 256\n203.0.142.0 256\n203.0.144.0 256\n203.0.146.0 256\n203.0.148.0 256\n203.0.150.0 512\n203.0.152.0 256\n203.0.177.0 256\n203.0.224.0 256\n203.1.4.0 1024\n203.1.18.0 256\n203.1.26.0 512\n203.1.65.0 256\n203.1.66.0 512\n203.1.70.0 512\n203.1.76.0 512\n203.1.90.0 256\n203.1.97.0 256\n203.1.98.0 512\n203.1.100.0 1024\n203.1.108.0 256\n203.1.253.0 256\n203.1.254.0 256\n203.2.64.0 2048\n203.2.73.0 256\n203.2.112.0 2048\n203.2.126.0 512\n203.2.140.0 256\n203.2.150.0 256\n203.2.152.0 1024\n203.2.156.0 512\n203.2.160.0 2048\n203.2.180.0 512\n203.2.196.0 512\n203.2.209.0 256\n203.2.214.0 512\n203.2.226.0 512\n203.2.229.0 256\n203.2.236.0 512\n203.3.68.0 256\n203.3.72.0 512\n203.3.75.0 256\n203.3.80.0 2048\n203.3.96.0 1024\n203.3.105.0 256\n203.3.112.0 2048\n203.3.120.0 256\n203.3.123.0 256\n203.3.135.0 256\n203.3.139.0 256\n203.3.143.0 256\n203.4.132.0 512\n203.4.134.0 256\n203.4.151.0 256\n203.4.152.0 1024\n203.4.174.0 512\n203.4.180.0 256\n203.4.186.0 256\n203.4.205.0 256\n203.4.208.0 1024\n203.4.227.0 256\n203.4.230.0 512\n203.5.4.0 512\n203.5.7.0 256\n203.5.8.0 512\n203.5.11.0 256\n203.5.21.0 256\n203.5.22.0 256\n203.5.44.0 256\n203.5.46.0 512\n203.5.52.0 1024\n203.5.56.0 512\n203.5.60.0 512\n203.5.114.0 512\n203.5.118.0 256\n203.5.120.0 256\n203.5.172.0 256\n203.5.180.0 512\n203.5.182.0 256\n203.5.185.0 256\n203.5.186.0 256\n203.5.188.0 512\n203.5.190.0 256\n203.5.195.0 256\n203.5.214.0 512\n203.5.218.0 512\n203.6.131.0 256\n203.6.136.0 256\n203.6.138.0 512\n203.6.142.0 256\n203.6.150.0 512\n203.6.157.0 256\n203.6.159.0 256\n203.6.224.0 4096\n203.6.248.0 512\n203.7.129.0 256\n203.7.138.0 512\n203.7.147.0 256\n203.7.150.0 512\n203.7.158.0 256\n203.7.192.0 512\n203.7.200.0 256\n203.8.0.0 256\n203.8.8.0 256\n203.8.23.0 256\n203.8.70.0 256\n203.8.82.0 256\n203.8.86.0 512\n203.8.91.0 256\n203.8.110.0 512\n203.8.115.0 256\n203.8.166.0 512\n203.8.169.0 256\n203.8.173.0 256\n203.8.184.0 256\n203.8.186.0 512\n203.8.190.0 512\n203.8.192.0 256\n203.8.197.0 256\n203.8.198.0 512\n203.8.203.0 256\n203.8.209.0 256\n203.8.210.0 512\n203.8.212.0 1024\n203.8.217.0 256\n203.8.220.0 256\n203.9.32.0 256\n203.9.36.0 512\n203.9.57.0 256\n203.9.63.0 256\n203.9.65.0 256\n203.9.70.0 512\n203.9.72.0 256\n203.9.75.0 256\n203.9.76.0 512\n203.9.96.0 1024\n203.9.100.0 512\n203.9.108.0 256\n203.9.158.0 256\n203.10.34.0 256\n203.10.56.0 256\n203.10.74.0 512\n203.10.84.0 1024\n203.10.88.0 256\n203.10.95.0 256\n203.10.125.0 256\n203.11.70.0 256\n203.11.76.0 1024\n203.11.82.0 256\n203.11.84.0 1024\n203.11.100.0 1024\n203.11.109.0 256\n203.11.117.0 256\n203.11.122.0 256\n203.11.126.0 256\n203.11.136.0 1024\n203.11.141.0 256\n203.11.142.0 512\n203.11.180.0 1024\n203.11.208.0 1024\n203.12.16.0 256\n203.12.19.0 256\n203.12.24.0 256\n203.12.57.0 256\n203.12.65.0 256\n203.12.66.0 256\n203.12.70.0 512\n203.12.87.0 256\n203.12.100.0 512\n203.12.103.0 256\n203.12.114.0 256\n203.12.118.0 256\n203.12.130.0 256\n203.12.137.0 256\n203.12.196.0 1024\n203.12.211.0 256\n203.12.219.0 256\n203.12.226.0 256\n203.12.240.0 1024\n203.13.18.0 256\n203.13.24.0 256\n203.13.44.0 512\n203.13.88.0 512\n203.13.92.0 1024\n203.13.173.0 256\n203.13.224.0 512\n203.13.227.0 256\n203.13.233.0 256\n203.14.24.0 1024\n203.14.33.0 256\n203.14.56.0 256\n203.14.61.0 256\n203.14.62.0 256\n203.14.104.0 256\n203.14.114.0 512\n203.14.118.0 256\n203.14.162.0 256\n203.14.192.0 256\n203.14.194.0 512\n203.14.214.0 256\n203.14.231.0 256\n203.14.246.0 256\n203.15.0.0 4096\n203.15.20.0 512\n203.15.22.0 256\n203.15.87.0 256\n203.15.88.0 512\n203.15.105.0 256\n203.15.112.0 2048\n203.15.130.0 512\n203.15.149.0 256\n203.15.151.0 256\n203.15.156.0 1024\n203.15.174.0 256\n203.15.227.0 256\n203.15.232.0 2048\n203.15.240.0 512\n203.15.246.0 256\n203.16.10.0 256\n203.16.12.0 512\n203.16.16.0 2048\n203.16.27.0 256\n203.16.38.0 256\n203.16.49.0 256\n203.16.50.0 512\n203.16.58.0 256\n203.16.63.0 256\n203.16.133.0 256\n203.16.161.0 256\n203.16.162.0 256\n203.16.186.0 512\n203.16.228.0 256\n203.16.238.0 256\n203.16.240.0 256\n203.16.245.0 256\n203.17.2.0 256\n203.17.18.0 256\n203.17.28.0 256\n203.17.39.0 256\n203.17.56.0 256\n203.17.74.0 512\n203.17.88.0 512\n203.17.136.0 256\n203.17.164.0 256\n203.17.187.0 256\n203.17.190.0 512\n203.17.231.0 256\n203.17.233.0 256\n203.17.248.0 256\n203.17.249.0 256\n203.17.255.0 256\n203.18.2.0 512\n203.18.4.0 256\n203.18.7.0 256\n203.18.31.0 256\n203.18.37.0 256\n203.18.48.0 512\n203.18.52.0 256\n203.18.72.0 1024\n203.18.80.0 512\n203.18.87.0 256\n203.18.100.0 512\n203.18.105.0 256\n203.18.107.0 256\n203.18.110.0 256\n203.18.129.0 256\n203.18.131.0 256\n203.18.132.0 512\n203.18.144.0 256\n203.18.153.0 256\n203.18.199.0 256\n203.18.208.0 256\n203.18.211.0 256\n203.18.215.0 256\n203.19.1.0 256\n203.19.18.0 256\n203.19.24.0 256\n203.19.30.0 256\n203.19.32.0 2048\n203.19.41.0 256\n203.19.44.0 512\n203.19.46.0 256\n203.19.58.0 256\n203.19.60.0 512\n203.19.64.0 256\n203.19.68.0 256\n203.19.72.0 256\n203.19.101.0 256\n203.19.111.0 256\n203.19.131.0 256\n203.19.133.0 256\n203.19.144.0 256\n203.19.147.0 256\n203.19.149.0 256\n203.19.156.0 256\n203.19.176.0 256\n203.19.178.0 512\n203.19.208.0 256\n203.19.228.0 1024\n203.19.233.0 256\n203.19.242.0 256\n203.19.248.0 512\n203.19.255.0 256\n203.20.17.0 256\n203.20.40.0 512\n203.20.44.0 256\n203.20.48.0 256\n203.20.61.0 256\n203.20.65.0 256\n203.20.84.0 512\n203.20.89.0 256\n203.20.106.0 512\n203.20.115.0 256\n203.20.117.0 256\n203.20.118.0 512\n203.20.122.0 256\n203.20.126.0 512\n203.20.135.0 256\n203.20.136.0 2048\n203.20.150.0 256\n203.20.230.0 256\n203.20.232.0 256\n203.20.236.0 256\n203.21.0.0 512\n203.21.2.0 256\n203.21.8.0 256\n203.21.10.0 256\n203.21.18.0 256\n203.21.33.0 256\n203.21.34.0 256\n203.21.41.0 256\n203.21.44.0 256\n203.21.68.0 256\n203.21.82.0 256\n203.21.96.0 1024\n203.21.124.0 256\n203.21.136.0 512\n203.21.145.0 256\n203.21.206.0 256\n203.22.24.0 256\n203.22.28.0 512\n203.22.31.0 256\n203.22.68.0 256\n203.22.76.0 256\n203.22.78.0 256\n203.22.84.0 256\n203.22.87.0 256\n203.22.92.0 1024\n203.22.99.0 256\n203.22.106.0 256\n203.22.122.0 512\n203.22.131.0 256\n203.22.163.0 256\n203.22.166.0 256\n203.22.170.0 256\n203.22.176.0 2048\n203.22.194.0 256\n203.22.242.0 512\n203.22.245.0 256\n203.22.246.0 256\n203.22.252.0 512\n203.23.0.0 256\n203.23.47.0 256\n203.23.61.0 256\n203.23.62.0 512\n203.23.73.0 256\n203.23.85.0 256\n203.23.92.0 1024\n203.23.98.0 256\n203.23.107.0 256\n203.23.112.0 256\n203.23.130.0 256\n203.23.140.0 512\n203.23.172.0 256\n203.23.182.0 256\n203.23.186.0 512\n203.23.192.0 256\n203.23.197.0 256\n203.23.198.0 256\n203.23.204.0 1024\n203.23.224.0 256\n203.23.226.0 512\n203.23.228.0 1024\n203.23.249.0 256\n203.23.251.0 256\n203.24.13.0 256\n203.24.18.0 256\n203.24.27.0 256\n203.24.43.0 256\n203.24.56.0 256\n203.24.58.0 256\n203.24.67.0 256\n203.24.74.0 256\n203.24.79.0 256\n203.24.80.0 512\n203.24.84.0 512\n203.24.86.0 256\n203.24.90.0 256\n203.24.111.0 256\n203.24.112.0 256\n203.24.116.0 256\n203.24.122.0 512\n203.24.145.0 256\n203.24.152.0 512\n203.24.157.0 256\n203.24.161.0 256\n203.24.167.0 256\n203.24.186.0 512\n203.24.199.0 256\n203.24.202.0 256\n203.24.212.0 512\n203.24.217.0 256\n203.24.219.0 256\n203.24.244.0 256\n203.25.19.0 256\n203.25.20.0 512\n203.25.46.0 256\n203.25.48.0 2048\n203.25.64.0 512\n203.25.91.0 256\n203.25.99.0 256\n203.25.100.0 256\n203.25.106.0 256\n203.25.131.0 256\n203.25.135.0 256\n203.25.138.0 256\n203.25.147.0 256\n203.25.153.0 256\n203.25.154.0 512\n203.25.164.0 256\n203.25.166.0 256\n203.25.174.0 512\n203.25.180.0 256\n203.25.182.0 256\n203.25.191.0 256\n203.25.199.0 256\n203.25.200.0 256\n203.25.202.0 512\n203.25.208.0 4096\n203.25.229.0 256\n203.25.235.0 256\n203.25.236.0 256\n203.25.242.0 256\n203.26.12.0 256\n203.26.34.0 256\n203.26.49.0 256\n203.26.50.0 256\n203.26.55.0 256\n203.26.56.0 512\n203.26.60.0 256\n203.26.65.0 256\n203.26.68.0 256\n203.26.76.0 256\n203.26.80.0 256\n203.26.84.0 256\n203.26.97.0 256\n203.26.102.0 512\n203.26.115.0 256\n203.26.116.0 256\n203.26.129.0 256\n203.26.143.0 256\n203.26.144.0 256\n203.26.148.0 512\n203.26.154.0 256\n203.26.158.0 512\n203.26.170.0 256\n203.26.173.0 256\n203.26.176.0 256\n203.26.185.0 256\n203.26.202.0 512\n203.26.210.0 256\n203.26.214.0 256\n203.26.222.0 256\n203.26.224.0 256\n203.26.228.0 256\n203.26.232.0 256\n203.27.0.0 256\n203.27.10.0 256\n203.27.15.0 256\n203.27.16.0 256\n203.27.20.0 256\n203.27.22.0 512\n203.27.40.0 256\n203.27.45.0 256\n203.27.53.0 256\n203.27.65.0 256\n203.27.66.0 256\n203.27.81.0 256\n203.27.88.0 256\n203.27.102.0 256\n203.27.109.0 256\n203.27.117.0 256\n203.27.121.0 256\n203.27.122.0 512\n203.27.125.0 256\n203.27.200.0 256\n203.27.202.0 256\n203.27.233.0 256\n203.27.241.0 256\n203.27.250.0 256\n203.28.10.0 256\n203.28.12.0 256\n203.28.33.0 256\n203.28.34.0 512\n203.28.43.0 256\n203.28.44.0 256\n203.28.54.0 256\n203.28.56.0 256\n203.28.73.0 256\n203.28.74.0 256\n203.28.76.0 256\n203.28.86.0 256\n203.28.88.0 256\n203.28.112.0 256\n203.28.131.0 256\n203.28.136.0 256\n203.28.140.0 256\n203.28.145.0 256\n203.28.165.0 256\n203.28.169.0 256\n203.28.170.0 256\n203.28.178.0 512\n203.28.185.0 256\n203.28.187.0 256\n203.28.196.0 256\n203.28.226.0 512\n203.28.239.0 256\n203.29.2.0 256\n203.29.8.0 512\n203.29.13.0 256\n203.29.14.0 256\n203.29.28.0 256\n203.29.46.0 256\n203.29.57.0 256\n203.29.61.0 256\n203.29.63.0 256\n203.29.69.0 256\n203.29.73.0 256\n203.29.81.0 256\n203.29.90.0 256\n203.29.95.0 256\n203.29.100.0 256\n203.29.103.0 256\n203.29.112.0 256\n203.29.120.0 1024\n203.29.182.0 512\n203.29.187.0 256\n203.29.189.0 256\n203.29.190.0 256\n203.29.205.0 256\n203.29.210.0 256\n203.29.217.0 256\n203.29.227.0 256\n203.29.231.0 256\n203.29.233.0 256\n203.29.234.0 256\n203.29.248.0 256\n203.29.254.0 512\n203.30.16.0 512\n203.30.25.0 256\n203.30.27.0 256\n203.30.29.0 256\n203.30.66.0 256\n203.30.81.0 256\n203.30.87.0 256\n203.30.111.0 256\n203.30.121.0 256\n203.30.123.0 256\n203.30.152.0 256\n203.30.156.0 256\n203.30.162.0 256\n203.30.173.0 256\n203.30.175.0 256\n203.30.187.0 256\n203.30.194.0 256\n203.30.217.0 256\n203.30.220.0 256\n203.30.222.0 256\n203.30.232.0 512\n203.30.235.0 256\n203.30.240.0 512\n203.30.246.0 256\n203.30.250.0 512\n203.31.45.0 256\n203.31.46.0 256\n203.31.49.0 256\n203.31.51.0 256\n203.31.54.0 512\n203.31.69.0 256\n203.31.72.0 256\n203.31.80.0 256\n203.31.85.0 256\n203.31.97.0 256\n203.31.105.0 256\n203.31.106.0 256\n203.31.108.0 512\n203.31.124.0 256\n203.31.162.0 256\n203.31.174.0 256\n203.31.177.0 256\n203.31.181.0 256\n203.31.187.0 256\n203.31.189.0 256\n203.31.204.0 256\n203.31.220.0 256\n203.31.222.0 512\n203.31.225.0 256\n203.31.229.0 256\n203.31.248.0 512\n203.31.253.0 256\n203.32.20.0 256\n203.32.48.0 512\n203.32.56.0 256\n203.32.60.0 256\n203.32.62.0 256\n203.32.68.0 512\n203.32.76.0 256\n203.32.81.0 256\n203.32.84.0 512\n203.32.95.0 256\n203.32.102.0 256\n203.32.105.0 256\n203.32.130.0 256\n203.32.133.0 256\n203.32.140.0 256\n203.32.152.0 256\n203.32.186.0 512\n203.32.192.0 256\n203.32.196.0 256\n203.32.203.0 256\n203.32.204.0 512\n203.32.212.0 256\n203.33.4.0 256\n203.33.7.0 256\n203.33.8.0 2048\n203.33.21.0 256\n203.33.26.0 256\n203.33.32.0 256\n203.33.63.0 256\n203.33.64.0 256\n203.33.67.0 256\n203.33.68.0 256\n203.33.73.0 256\n203.33.79.0 256\n203.33.100.0 256\n203.33.122.0 256\n203.33.129.0 256\n203.33.131.0 256\n203.33.145.0 256\n203.33.156.0 256\n203.33.158.0 512\n203.33.174.0 256\n203.33.185.0 256\n203.33.200.0 256\n203.33.202.0 512\n203.33.204.0 256\n203.33.206.0 512\n203.33.214.0 512\n203.33.224.0 512\n203.33.226.0 256\n203.33.233.0 256\n203.33.243.0 256\n203.33.250.0 256\n203.34.4.0 256\n203.34.21.0 256\n203.34.27.0 256\n203.34.39.0 256\n203.34.48.0 512\n203.34.54.0 256\n203.34.56.0 512\n203.34.67.0 256\n203.34.69.0 256\n203.34.76.0 256\n203.34.92.0 256\n203.34.106.0 256\n203.34.113.0 256\n203.34.147.0 256\n203.34.150.0 256\n203.34.152.0 512\n203.34.161.0 256\n203.34.162.0 256\n203.34.187.0 256\n203.34.192.0 2048\n203.34.204.0 1024\n203.34.232.0 256\n203.34.240.0 256\n203.34.242.0 256\n203.34.245.0 256\n203.34.251.0 256\n203.55.2.0 512\n203.55.4.0 256\n203.55.10.0 256\n203.55.13.0 256\n203.55.22.0 256\n203.55.30.0 256\n203.55.93.0 256\n203.55.101.0 256\n203.55.109.0 256\n203.55.110.0 256\n203.55.116.0 512\n203.55.119.0 256\n203.55.128.0 512\n203.55.146.0 512\n203.55.192.0 256\n203.55.196.0 256\n203.55.218.0 512\n203.55.221.0 256\n203.55.224.0 256\n203.56.1.0 256\n203.56.4.0 256\n203.56.12.0 256\n203.56.24.0 256\n203.56.38.0 256\n203.56.40.0 256\n203.56.46.0 256\n203.56.48.0 2048\n203.56.68.0 512\n203.56.82.0 512\n203.56.84.0 512\n203.56.95.0 256\n203.56.110.0 256\n203.56.121.0 256\n203.56.161.0 256\n203.56.169.0 256\n203.56.172.0 512\n203.56.175.0 256\n203.56.183.0 256\n203.56.185.0 256\n203.56.187.0 256\n203.56.192.0 256\n203.56.198.0 256\n203.56.201.0 256\n203.56.208.0 512\n203.56.210.0 256\n203.56.214.0 256\n203.56.216.0 256\n203.56.227.0 256\n203.56.228.0 256\n203.56.231.0 256\n203.56.232.0 256\n203.56.240.0 256\n203.56.252.0 256\n203.56.254.0 256\n203.57.5.0 256\n203.57.6.0 256\n203.57.12.0 512\n203.57.28.0 256\n203.57.39.0 256\n203.57.46.0 256\n203.57.58.0 256\n203.57.61.0 256\n203.57.66.0 256\n203.57.69.0 256\n203.57.70.0 512\n203.57.73.0 256\n203.57.90.0 256\n203.57.101.0 256\n203.57.109.0 256\n203.57.123.0 256\n203.57.157.0 256\n203.57.200.0 256\n203.57.202.0 256\n203.57.206.0 256\n203.57.222.0 256\n203.57.224.0 4096\n203.57.246.0 512\n203.57.249.0 256\n203.57.253.0 256\n203.57.254.0 512\n203.62.2.0 256\n203.62.131.0 256\n203.62.139.0 256\n203.62.161.0 256\n203.62.197.0 256\n203.62.228.0 1024\n203.62.234.0 256\n203.62.246.0 256\n203.76.160.0 1024\n203.76.168.0 1024\n203.76.208.0 1024\n203.76.212.0 1024\n203.76.216.0 1024\n203.76.240.0 1024\n203.76.244.0 1024\n203.77.180.0 1024\n203.78.48.0 4096\n203.78.156.0 1024\n203.79.0.0 4096\n203.79.32.0 4096\n203.80.4.0 512\n203.80.32.0 4096\n203.80.57.0 256\n203.80.129.0 256\n203.80.132.0 1024\n203.80.136.0 2048\n203.80.144.0 4096\n203.81.0.0 2048\n203.81.16.0 4096\n203.81.244.0 1024\n203.82.0.0 512\n203.82.16.0 2048\n203.82.112.0 1024\n203.82.116.0 1024\n203.82.120.0 1024\n203.82.124.0 1024\n203.82.224.0 1024\n203.82.228.0 1024\n203.82.232.0 1024\n203.82.236.0 1024\n203.83.0.0 1024\n203.83.8.0 1024\n203.83.12.0 1024\n203.83.56.0 2048\n203.83.224.0 4096\n203.86.0.0 8192\n203.86.32.0 8192\n203.86.64.0 4096\n203.86.80.0 4096\n203.86.96.0 8192\n203.86.250.0 256\n203.86.254.0 512\n203.88.32.0 8192\n203.88.192.0 8192\n203.89.8.0 2048\n203.89.100.0 1024\n203.89.133.0 256\n203.89.136.0 1024\n203.89.144.0 256\n203.90.8.0 1024\n203.90.12.0 1024\n203.90.128.0 8192\n203.90.160.0 8192\n203.90.192.0 8192\n203.91.32.0 8192\n203.91.96.0 4096\n203.91.120.0 2048\n203.92.0.0 1024\n203.92.6.0 256\n203.92.160.0 8192\n203.93.0.0 1024\n203.93.4.0 1024\n203.93.8.0 256\n203.93.9.0 256\n203.93.10.0 512\n203.93.12.0 1024\n203.93.16.0 4096\n203.93.32.0 8192\n203.93.64.0 16384\n203.93.128.0 2048\n203.93.136.0 1024\n203.93.140.0 256\n203.93.141.0 256\n203.93.142.0 512\n203.93.144.0 4096\n203.93.160.0 8192\n203.93.192.0 16384\n203.94.0.0 1024\n203.94.4.0 1024\n203.94.8.0 2048\n203.94.16.0 4096\n203.95.0.0 2048\n203.95.96.0 4096\n203.95.112.0 4096\n203.95.128.0 16384\n203.95.200.0 1024\n203.95.204.0 1024\n203.95.208.0 1024\n203.95.224.0 8192\n203.99.8.0 2048\n203.99.16.0 4096\n203.99.80.0 4096\n203.100.32.0 4096\n203.100.48.0 2048\n203.100.58.0 256\n203.100.60.0 256\n203.100.63.0 256\n203.100.80.0 4096\n203.100.96.0 8192\n203.100.192.0 4096\n203.104.32.0 4096\n203.105.96.0 8192\n203.105.128.0 8192\n203.107.0.0 32768\n203.110.160.0 8192\n203.110.208.0 4096\n203.110.232.0 512\n203.110.234.0 256\n203.114.80.0 1024\n203.114.84.0 1024\n203.114.88.0 1024\n203.114.92.0 1024\n203.114.244.0 1024\n203.118.192.0 8192\n203.118.241.0 256\n203.118.248.0 1024\n203.119.24.0 2048\n203.119.32.0 1024\n203.119.80.0 1024\n203.119.85.0 256\n203.119.113.0 256\n203.119.114.0 512\n203.119.116.0 1024\n203.119.120.0 2048\n203.119.128.0 32768\n203.123.58.0 256\n203.128.32.0 8192\n203.128.96.0 8192\n203.128.224.0 2048\n203.129.8.0 2048\n203.130.32.0 8192\n203.132.32.0 8192\n203.134.240.0 2048\n203.135.96.0 4096\n203.135.112.0 4096\n203.135.160.0 4096\n203.142.219.0 256\n203.142.224.0 8192\n203.144.96.0 8192\n203.145.0.0 8192\n203.148.0.0 16384\n203.148.64.0 4096\n203.148.80.0 1024\n203.148.86.0 512\n203.149.92.0 1024\n203.152.64.0 8192\n203.152.128.0 8192\n203.153.0.0 1024\n203.156.192.0 16384\n203.158.16.0 2048\n203.160.52.0 1024\n203.160.104.0 2048\n203.160.129.0 256\n203.160.192.0 8192\n203.161.0.0 1024\n203.161.180.0 256\n203.161.183.0 256\n203.161.192.0 8192\n203.166.160.0 8192\n203.167.28.0 1024\n203.168.0.0 8192\n203.170.58.0 512\n203.171.0.0 1024\n203.171.208.0 256\n203.171.224.0 4096\n203.174.4.0 256\n203.174.6.0 256\n203.174.7.0 256\n203.174.96.0 8192\n203.175.128.0 8192\n203.175.192.0 16384\n203.176.0.0 16384\n203.176.64.0 8192\n203.176.168.0 2048\n203.184.80.0 4096\n203.185.189.0 256\n203.187.160.0 8192\n203.189.0.0 512\n203.189.6.0 512\n203.189.112.0 1024\n203.189.192.0 8192\n203.189.240.0 1024\n203.190.96.0 4096\n203.190.249.0 256\n203.191.0.0 512\n203.191.2.0 256\n203.191.5.0 256\n203.191.7.0 256\n203.191.16.0 4096\n203.191.64.0 16384\n203.191.133.0 256\n203.191.144.0 2048\n203.191.152.0 2048\n203.192.0.0 8192\n203.193.224.0 8192\n203.194.120.0 2048\n203.195.64.0 8192\n203.195.112.0 2048\n203.195.128.0 32768\n203.196.0.0 2048\n203.196.8.0 2048\n203.196.28.0 1024\n203.201.181.0 256\n203.201.182.0 256\n203.202.236.0 1024\n203.205.64.0 8192\n203.205.128.0 32768\n203.207.64.0 4096\n203.207.80.0 2048\n203.207.88.0 1024\n203.207.92.0 1024\n203.207.96.0 4096\n203.207.112.0 4096\n203.207.128.0 16384\n203.207.192.0 2048\n203.207.200.0 2048\n203.207.208.0 4096\n203.207.224.0 8192\n203.208.32.0 8192\n203.209.224.0 8192\n203.212.0.0 4096\n203.212.80.0 4096\n203.215.232.0 2048\n203.217.164.0 1024\n203.223.16.0 2048\n204.52.191.0 256\n210.2.0.0 4096\n210.2.16.0 4096\n210.5.0.0 8192\n210.5.56.0 2048\n210.5.128.0 4096\n210.5.144.0 4096\n210.7.56.0 1024\n210.7.60.0 1024\n210.12.0.0 16384\n210.12.64.0 16384\n210.12.128.0 16384\n210.12.192.0 16384\n210.13.0.0 16384\n210.13.64.0 16384\n210.13.128.0 32768\n210.14.64.0 8192\n210.14.112.0 4096\n210.14.128.0 8192\n210.14.160.0 8192\n210.14.192.0 8192\n210.14.224.0 8192\n210.15.0.0 8192\n210.15.32.0 8192\n210.15.64.0 8192\n210.15.96.0 8192\n210.15.128.0 16384\n210.16.104.0 1024\n210.16.128.0 16384\n210.21.0.0 32768\n210.21.128.0 32768\n210.22.0.0 65536\n210.23.32.0 8192\n210.25.0.0 65536\n210.26.0.0 131072\n210.28.0.0 262144\n210.32.0.0 262144\n210.36.0.0 262144\n210.40.0.0 524288\n210.51.0.0 65536\n210.52.0.0 16384\n210.52.64.0 16384\n210.52.128.0 32768\n210.53.0.0 32768\n210.53.128.0 32768\n210.56.192.0 8192\n210.72.0.0 32768\n210.72.128.0 8192\n210.72.160.0 8192\n210.72.192.0 16384\n210.73.0.0 8192\n210.73.32.0 8192\n210.73.64.0 16384\n210.73.128.0 32768\n210.74.0.0 8192\n210.74.32.0 8192\n210.74.64.0 8192\n210.74.96.0 8192\n210.74.128.0 8192\n210.74.160.0 8192\n210.74.192.0 16384\n210.75.0.0 32768\n210.75.128.0 8192\n210.75.160.0 8192\n210.75.192.0 8192\n210.75.224.0 8192\n210.76.0.0 8192\n210.76.32.0 8192\n210.76.64.0 16384\n210.76.128.0 16384\n210.76.192.0 8192\n210.76.224.0 8192\n210.77.0.0 8192\n210.77.32.0 8192\n210.77.64.0 8192\n210.77.96.0 8192\n210.77.128.0 32768\n210.78.0.0 8192\n210.78.32.0 8192\n210.78.64.0 16384\n210.78.128.0 8192\n210.78.160.0 8192\n210.78.192.0 16384\n210.79.64.0 16384\n210.79.224.0 8192\n210.82.0.0 131072\n210.87.72.0 512\n210.87.114.0 512\n210.87.128.0 4096\n210.87.144.0 4096\n210.87.160.0 8192\n210.185.192.0 16384\n210.192.96.0 8192\n211.64.0.0 262144\n211.68.0.0 131072\n211.70.0.0 131072\n211.80.0.0 65536\n211.81.0.0 65536\n211.82.0.0 65536\n211.83.0.0 65536\n211.84.0.0 131072\n211.86.0.0 131072\n211.88.0.0 65536\n211.89.0.0 65536\n211.90.0.0 131072\n211.92.0.0 131072\n211.94.0.0 131072\n211.96.0.0 131072\n211.98.0.0 65536\n211.99.0.0 16384\n211.99.64.0 8192\n211.99.96.0 8192\n211.99.128.0 32768\n211.100.0.0 65536\n211.101.0.0 16384\n211.101.64.0 16384\n211.101.128.0 32768\n211.102.0.0 65536\n211.103.0.0 32768\n211.103.128.0 32768\n211.136.0.0 262144\n211.140.0.0 131072\n211.142.0.0 32768\n211.142.128.0 32768\n211.143.0.0 65536\n211.144.0.0 131072\n211.146.0.0 65536\n211.147.0.0 32768\n211.147.128.0 16384\n211.147.192.0 4096\n211.147.208.0 4096\n211.147.224.0 8192\n211.148.0.0 262144\n211.152.0.0 131072\n211.154.0.0 65536\n211.155.0.0 16384\n211.155.64.0 8192\n211.155.96.0 8192\n211.155.128.0 32768\n211.156.0.0 16384\n211.156.64.0 4096\n211.156.80.0 4096\n211.156.96.0 8192\n211.156.128.0 8192\n211.156.160.0 4096\n211.156.176.0 4096\n211.156.192.0 16384\n211.157.0.0 65536\n211.158.0.0 131072\n211.160.0.0 262144\n211.164.0.0 131072\n211.166.0.0 65536\n211.167.0.0 32768\n211.167.128.0 8192\n211.167.160.0 4096\n211.167.176.0 4096\n211.167.192.0 16384\n212.64.0.0 32768\n212.129.128.0 32768\n218.0.0.0 65536\n218.1.0.0 65536\n218.2.0.0 131072\n218.4.0.0 131072\n218.6.0.0 65536\n218.7.0.0 65536\n218.8.0.0 131072\n218.10.0.0 65536\n218.11.0.0 65536\n218.12.0.0 65536\n218.13.0.0 65536\n218.14.0.0 131072\n218.16.0.0 262144\n218.20.0.0 65536\n218.21.0.0 32768\n218.21.128.0 32768\n218.22.0.0 131072\n218.24.0.0 131072\n218.26.0.0 65536\n218.27.0.0 65536\n218.28.0.0 131072\n218.30.0.0 131072\n218.56.0.0 262144\n218.60.0.0 131072\n218.62.0.0 32768\n218.62.128.0 32768\n218.63.0.0 65536\n218.64.0.0 131072\n218.66.0.0 65536\n218.67.0.0 32768\n218.67.128.0 32768\n218.68.0.0 131072\n218.70.0.0 131072\n218.72.0.0 262144\n218.76.0.0 131072\n218.78.0.0 131072\n218.80.0.0 262144\n218.84.0.0 262144\n218.88.0.0 524288\n218.96.0.0 131072\n218.98.0.0 32768\n218.98.128.0 16384\n218.98.192.0 8192\n218.98.224.0 8192\n218.99.0.0 65536\n218.100.88.0 2048\n218.100.96.0 8192\n218.100.128.0 32768\n218.104.0.0 32768\n218.104.128.0 8192\n218.104.160.0 8192\n218.104.192.0 2048\n218.104.200.0 2048\n218.104.208.0 4096\n218.104.224.0 8192\n218.105.0.0 65536\n218.106.0.0 131072\n218.108.0.0 65536\n218.109.0.0 65536\n218.185.192.0 8192\n218.185.240.0 2048\n218.192.0.0 65536\n218.193.0.0 65536\n218.194.0.0 65536\n218.195.0.0 65536\n218.196.0.0 262144\n218.200.0.0 262144\n218.204.0.0 131072\n218.206.0.0 131072\n218.240.0.0 262144\n218.244.0.0 16384\n218.244.64.0 8192\n218.244.96.0 8192\n218.244.128.0 32768\n218.245.0.0 65536\n218.246.0.0 131072\n218.249.0.0 65536\n219.72.0.0 65536\n219.82.0.0 65536\n219.83.128.0 32768\n219.90.68.0 1024\n219.90.72.0 1024\n219.90.76.0 1024\n219.128.0.0 1048576\n219.144.0.0 262144\n219.148.0.0 65536\n219.149.0.0 32768\n219.149.128.0 16384\n219.149.192.0 16384\n219.150.0.0 8192\n219.150.32.0 8192\n219.150.64.0 8192\n219.150.96.0 4096\n219.150.112.0 4096\n219.150.128.0 32768\n219.151.0.0 8192\n219.151.32.0 8192\n219.151.64.0 16384\n219.151.128.0 32768\n219.152.0.0 131072\n219.154.0.0 131072\n219.156.0.0 131072\n219.158.0.0 32768\n219.158.128.0 32768\n219.159.0.0 16384\n219.159.64.0 16384\n219.159.128.0 32768\n219.216.0.0 131072\n219.218.0.0 131072\n219.220.0.0 65536\n219.221.0.0 65536\n219.222.0.0 131072\n219.224.0.0 131072\n219.226.0.0 65536\n219.227.0.0 65536\n219.228.0.0 131072\n219.230.0.0 131072\n219.232.0.0 262144\n219.236.0.0 131072\n219.238.0.0 131072\n219.242.0.0 131072\n219.244.0.0 262144\n220.101.192.0 16384\n220.112.0.0 262144\n220.152.128.0 32768\n220.154.0.0 131072\n220.158.240.0 1024\n220.160.0.0 2097152\n220.192.0.0 131072\n220.194.0.0 131072\n220.196.0.0 262144\n220.200.0.0 524288\n220.231.0.0 16384\n220.231.128.0 32768\n220.232.64.0 16384\n220.234.0.0 65536\n220.242.0.0 131072\n220.247.136.0 2048\n220.248.0.0 262144\n220.252.0.0 65536\n221.0.0.0 131072\n221.2.0.0 65536\n221.3.0.0 32768\n221.3.128.0 32768\n221.4.0.0 65536\n221.5.0.0 32768\n221.5.128.0 32768\n221.6.0.0 65536\n221.7.0.0 8192\n221.7.32.0 8192\n221.7.64.0 8192\n221.7.96.0 8192\n221.7.128.0 32768\n221.8.0.0 131072\n221.10.0.0 65536\n221.11.0.0 32768\n221.11.128.0 16384\n221.11.192.0 8192\n221.11.224.0 8192\n221.12.0.0 32768\n221.12.128.0 16384\n221.13.0.0 16384\n221.13.64.0 8192\n221.13.96.0 8192\n221.13.128.0 32768\n221.14.0.0 131072\n221.122.0.0 131072\n221.128.128.0 32768\n221.129.0.0 65536\n221.130.0.0 131072\n221.133.224.0 8192\n221.136.0.0 65536\n221.137.0.0 65536\n221.172.0.0 262144\n221.176.0.0 524288\n221.192.0.0 131072\n221.194.0.0 65536\n221.195.0.0 65536\n221.196.0.0 131072\n221.198.0.0 65536\n221.199.0.0 8192\n221.199.32.0 4096\n221.199.48.0 4096\n221.199.64.0 16384\n221.199.128.0 16384\n221.199.192.0 4096\n221.199.224.0 8192\n221.200.0.0 262144\n221.204.0.0 131072\n221.206.0.0 65536\n221.207.0.0 16384\n221.207.64.0 16384\n221.207.128.0 32768\n221.208.0.0 262144\n221.212.0.0 65536\n221.213.0.0 65536\n221.214.0.0 131072\n221.216.0.0 524288\n221.224.0.0 524288\n221.232.0.0 262144\n221.236.0.0 131072\n221.238.0.0 65536\n221.239.0.0 32768\n221.239.128.0 32768\n222.16.0.0 131072\n222.18.0.0 131072\n222.20.0.0 131072\n222.22.0.0 65536\n222.23.0.0 65536\n222.24.0.0 131072\n222.26.0.0 131072\n222.28.0.0 262144\n222.32.0.0 2097152\n222.64.0.0 524288\n222.72.0.0 131072\n222.74.0.0 65536\n222.75.0.0 65536\n222.76.0.0 262144\n222.80.0.0 131072\n222.82.0.0 65536\n222.83.0.0 32768\n222.83.128.0 32768\n222.84.0.0 65536\n222.85.0.0 32768\n222.85.128.0 32768\n222.86.0.0 131072\n222.88.0.0 131072\n222.90.0.0 131072\n222.92.0.0 262144\n222.125.0.0 65536\n222.126.128.0 32768\n222.128.0.0 262144\n222.132.0.0 262144\n222.136.0.0 524288\n222.160.0.0 131072\n222.162.0.0 65536\n222.163.0.0 8192\n222.163.32.0 8192\n222.163.64.0 16384\n222.163.128.0 32768\n222.168.0.0 131072\n222.170.0.0 131072\n222.172.0.0 32768\n222.172.128.0 32768\n222.173.0.0 65536\n222.174.0.0 131072\n222.176.0.0 524288\n222.184.0.0 524288\n222.192.0.0 262144\n222.196.0.0 131072\n222.198.0.0 65536\n222.199.0.0 65536\n222.200.0.0 262144\n222.204.0.0 131072\n222.206.0.0 131072\n222.208.0.0 524288\n222.216.0.0 131072\n222.218.0.0 65536\n222.219.0.0 65536\n222.220.0.0 131072\n222.222.0.0 131072\n222.240.0.0 524288\n222.248.0.0 65536\n222.249.0.0 32768\n222.249.128.0 8192\n222.249.160.0 4096\n222.249.176.0 4096\n222.249.192.0 16384\n223.0.0.0 131072\n223.2.0.0 131072\n223.4.0.0 262144\n223.8.0.0 524288\n223.20.0.0 131072\n223.27.184.0 1024\n223.29.208.0 1024\n223.29.252.0 1024\n223.64.0.0 2097152\n223.96.0.0 1048576\n223.112.0.0 262144\n223.116.0.0 131072\n223.120.128.0 32768\n223.121.128.0 32768\n223.123.128.0 32768\n223.124.0.0 262144\n223.128.0.0 131072\n223.144.0.0 1048576\n223.160.0.0 262144\n223.166.0.0 131072\n223.192.0.0 131072\n223.198.0.0 131072\n223.201.0.0 65536\n223.202.0.0 131072\n223.208.0.0 262144\n223.212.0.0 131072\n223.214.0.0 131072\n223.220.0.0 131072\n223.223.176.0 2048\n223.223.184.0 2048\n223.223.192.0 4096\n223.240.0.0 524288\n223.248.0.0 262144\n223.252.128.0 32768\n223.254.0.0 65536\n223.255.0.0 32768\n223.255.236.0 1024\n223.255.252.0 512\n"
  },
  {
    "path": "code/default/smart_router/local/connect_manager.py",
    "content": "import os\nimport sys\nimport socket\nimport operator\nimport time\nimport threading\nimport struct\n\nimport utils\n\nif __name__ == '__main__':\n    current_path = os.path.dirname(os.path.abspath(__file__))\n    root_path = os.path.abspath(os.path.join(current_path, os.pardir))\n    python_path = root_path\n    noarch_lib = os.path.join(python_path, 'lib', 'noarch')\n    sys.path.append(noarch_lib)\n\n\nfrom .socket_wrap import SocketWrap\nfrom queue import Queue\nimport socks\nfrom . import global_var as g\nfrom xlog import getLogger\nxlog = getLogger(\"smart_router\")\n\n\ndef load_proxy_config():\n    global default_socket\n    if g.config.PROXY_ENABLE:\n\n        if g.config.PROXY_TYPE == \"HTTP\":\n            proxy_type = socks.HTTP\n        elif g.config.PROXY_TYPE == \"SOCKS4\":\n            proxy_type = socks.SOCKS4\n        elif g.config.PROXY_TYPE == \"SOCKS5\":\n            proxy_type = socks.SOCKS5\n        else:\n            xlog.error(\"proxy type %s unknown, disable proxy\", g.config.PROXY_TYPE)\n            raise Exception()\n\n        socks.set_default_proxy(proxy_type, g.config.PROXY_HOST, g.config.PROXY_PORT,\n                                g.config.PROXY_USER, g.config.PROXY_PASSWD)\n\n\nclass ConnectManager(object):\n    def __init__(self, connection_timeout=15, connect_threads=3, connect_timeout=5):\n        self.lock = threading.Lock()\n        self.cache = {}\n        # host => [ { \"conn\":.., \"create_time\" }\n        #    ... ]\n        self.connection_timeout = connection_timeout\n        self.connect_timeout = connect_timeout\n        self.connect_threads = connect_threads\n\n        self.running = True\n        threading.Thread(target=self.connection_check_worker, name=\"smart_router_conn_checker\").start()\n\n    def stop(self):\n        self.running = False\n\n    def connection_check_worker(self):\n        while self.running:\n            time_now = time.time()\n            with self.lock:\n                for host_port in list(self.cache.keys()):\n                    try:\n                        cache = self.cache[host_port]\n                        for cc in list(cache):\n                            if time_now - cc[\"create_time\"] > self.connection_timeout:\n                                cache.remove(cc)\n                                cc[\"conn\"].close()\n                    except:\n                        pass\n\n            time.sleep(10)\n\n    def add_sock(self, host_port, sock):\n        with self.lock:\n            if host_port not in self.cache:\n                self.cache[host_port] = []\n            self.cache[host_port].append({\"create_time\": time.time(), \"conn\": sock})\n\n    def get_sock_from_cache(self, host_port):\n        time_now = time.time()\n        with self.lock:\n            if host_port in self.cache:\n                cache = self.cache[host_port]\n                while len(cache):\n                    try:\n                        cc = cache.pop(0)\n                        if time_now - cc[\"create_time\"] > self.connection_timeout:\n                            cc[\"conn\"].close()\n                            continue\n\n                        return cc[\"conn\"]\n                    except Exception as e:\n                        xlog.exception(\"get_conn:%r\", e)\n                        break\n\n    def create_connect(self, queue, host, ip, port, timeout=5):\n        ip = utils.to_bytes(ip)\n        if int(g.config.PROXY_ENABLE):\n            sock = socks.socksocket(socket.AF_INET if b':' not in ip else socket.AF_INET6)\n        else:\n            sock = socket.socket(socket.AF_INET if b':' not in ip else socket.AF_INET6)\n        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)\n        # set struct linger{l_onoff=1,l_linger=0} to avoid 10048 socket error\n        sock.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack('ii', 1, 0))\n        # resize socket recv buffer 8K->32K to improve browser releated application performance\n        sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 512 * 1024)\n        sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 512 * 1024)\n\n        sock.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, True)\n        sock.settimeout(timeout)\n\n        start_time = time.time()\n        try:\n            sock.connect((ip, port))\n            time_cost = (time.time() - start_time) * 1000\n            # xlog.debug(\"connect %s %s:%d time:%d\", host, ip, port, time_cost)\n            g.ip_cache.update_connect_time(ip, port, time_cost)\n            s = SocketWrap(sock, ip, port, host)\n            host_port = \"%s:%d\" % (host, port)\n            self.add_sock(host_port, s)\n            queue.put(True)\n        except Exception as e:\n            # xlog.debug(\"connect %s %s:%d fail:%r\", host, ip, port, e)\n            g.ip_cache.report_connect_fail(ip, port)\n            queue.put(False)\n\n    def get_conn(self, host, ips, port, timeout=5):\n        # xlog.debug(\"connect to %s:%d %r\", host, port, ips)\n        end_time = time.time() + timeout\n        host_port = \"%s:%d\" % (host, port)\n        sock = self.get_sock_from_cache(host_port)\n        if sock:\n            return sock\n\n        ip_rate = {}\n        for ip in ips:\n            connect_time = g.ip_cache.get_connect_time(ip, port)\n            if connect_time >= 8000:\n                continue\n\n            ip_rate[ip] = connect_time\n\n        if not ip_rate:\n            return None\n\n        ip_time = sorted(list(ip_rate.items()), key=operator.itemgetter(1))\n        ordered_ips = [ip for ip, rate in ip_time]\n\n        wait_queue = Queue()\n        wait_t = 0.2\n        for ip in ordered_ips:\n            threading.Thread(target=self.create_connect, args=(wait_queue, host, ip, port),\n                             name=\"smart_router_create_conn_%s\" % ip).start()\n            try:\n                status = wait_queue.get(timeout=wait_t)\n                sock = self.get_sock_from_cache(host_port)\n                if sock:\n                    return sock\n            except:\n                time.sleep(wait_t)\n                wait_t += 0.1\n\n        while True:\n            time_left = end_time - time.time()\n            if time_left <= 0:\n                return self.get_sock_from_cache(host_port)\n\n            try:\n                status = wait_queue.get(timeout=time_left)\n                sock = self.get_sock_from_cache(host_port)\n                if sock:\n                    return sock\n            except:\n                pass"
  },
  {
    "path": "code/default/smart_router/local/dns_query.py",
    "content": "#!/usr/bin/env python\n# coding:utf-8\n\n# public DNS servers https://en.wikipedia.org/wiki/Public_recursive_name_server\n\nimport json\nimport os\nimport sys\nimport threading\nimport socket\nimport time\nimport re\nimport ssl\nimport random\nimport struct\nimport subprocess\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nroot_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))\n\npython_path = root_path\nnoarch_lib = os.path.join(python_path, 'lib', 'noarch')\nsys.path.append(noarch_lib)\n\nimport env_info\ndata_path = os.path.join(env_info.data_path, 'smart_router')\n\nfrom queue import Queue\nimport lru_cache\nimport utils\nimport simple_http_client\nfrom dnslib import DNSRecord, DNSHeader, A, AAAA, RR, DNSQuestion, QTYPE\n\nfrom . import global_var as g\n\nfrom xlog import getLogger\nxlog = getLogger(\"smart_router\")\n\n\ndef get_local_ips():\n    def get_ip_address(NICname):\n        import fcntl\n        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)\n        return socket.inet_ntoa(fcntl.ioctl(\n            s.fileno(),\n            0x8915,  # SIOCGIFADDR\n            struct.pack('256s', NICname[:15].encode(\"UTF-8\"))\n        )[20:24])\n\n    if sys.platform.startswith(\"linux\"):\n\n        if os.path.isfile(\"/system/bin/dalvikvm\") or os.path.isfile(\"/system/bin/dalvikvm64\") or \\\n                \"android.googlesource.com\" in sys.version:\n            ips = [b'127.0.0.1']\n        else:\n            try:\n                proc = subprocess.Popen([\"ip addr show | egrep inet | awk '{{print $2}}' | awk -F'/' '{{print $1}}'\"],\n                                        stdout=subprocess.PIPE, shell=True)\n                x = proc.communicate()[0]\n                ips = x.strip().split(b\"\\n\")\n            except Exception as e:\n                xlog.warn(\"get ip address e:%r\", e)\n                ips = [b'127.0.0.1']\n    elif sys.platform == \"darwin\":\n        try:\n            proc = subprocess.Popen([\"ifconfig | egrep inet | awk '{{print $2}}' | awk -F'/' '{{print $1}}'\"],\n                                    stdout=subprocess.PIPE, shell=True)\n            x = proc.communicate()[0]\n            ips = x.strip().split(b\"\\n\")\n        except Exception as e:\n            xlog.warn(\"get ip address e:%r\", e)\n            ips = [b'127.0.0.1']\n    elif sys.platform == \"ios\":\n        ips = [b'127.0.0.1']\n    elif sys.platform == \"win32\":\n        try:\n            ips = [ip for ip in socket.gethostbyname_ex(socket.gethostname())[2]]\n            ips = utils.to_bytes(ips)\n            if b\"127.0.0.1\" not in ips:\n                ips.append(b\"127.0.0.1\")\n        except Exception as e:\n            xlog.warn(\"get local ip fail:%r\", e)\n            ips = [b\"127.0.0.1\"]\n    else:\n        ips = []\n        try:\n            for ix in socket.if_nameindex():\n                name = ix[1]\n                ip = get_ip_address(name)\n                ips.append(ip)\n        except Exception as e:\n            xlog.warn(\"get ip address e:%r\", e)\n            ips = [b'127.0.0.1']\n\n    xlog.debug(\"local ips: %s\", ips)\n    return ips\n\n\ndef query_dns_from_xxnet(domain, dns_type=None):\n    if not g.x_tunnel:\n        return []\n\n    t0 = time.time()\n    content, status, response = g.x_tunnel.front_dispatcher.request(\n        \"GET\", \"dns.xx-net.org\", path=\"/query?domain=%s\" % (utils.to_str(domain)), timeout=5)\n    t1 = time.time()\n\n    if status != 200:\n        xlog.warn(\"query_dns_from_xxnet fail status:%d, cost=%f\", status, t1 - t0)\n        return []\n\n    if isinstance(content, memoryview):\n        content = content.tobytes()\n\n    content = utils.to_str(content)\n\n    try:\n        rs = json.loads(content)\n        ips = rs[\"ip\"]\n        xlog.debug(\"query_dns_from_xxnet %s cost:%f return:%s\", domain, t1 - t0, ips)\n        #if dns_type == 1:\n        #    ips = [ip for ip in ips if \".\" in ip]\n        ips_out = []\n        for ip_cn in ips:\n            ip, cn = ip_cn.split(\"|\")\n            ips_out.append(ip)\n        return ips_out\n    except Exception as e:\n        xlog.warn(\"query_dns_from_xxnet %s json:%s parse fail:%s\", domain, content, e)\n        return []\n\n\nclass LocalDnsQuery():\n    def __init__(self, timeout=3):\n        self.timeout = timeout\n        self.waiters = lru_cache.LruCache(100)\n        self.dns_server = self.get_local_dns_server()\n\n        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)\n        self.sock6 = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)\n        self.sock.settimeout(1)\n        self.sock6.settimeout(1)\n\n        self.running = True\n        self.th = threading.Thread(target=self.dns_recv_worker, args=(self.sock,), name=\"dns_ipv4_receiver\")\n        self.th.start()\n\n        self.th6 = threading.Thread(target=self.dns_recv_worker, args=(self.sock6,), name=\"dns_ipv6_receiver\")\n        self.th6.start()\n\n    def get_local_dns_server(self):\n        iplist = []\n        if os.name == 'nt':\n            import ctypes, ctypes.wintypes, struct, socket\n            DNS_CONFIG_DNS_SERVER_LIST = 6\n            buf = ctypes.create_string_buffer(2048)\n            ctypes.windll.dnsapi.DnsQueryConfig(DNS_CONFIG_DNS_SERVER_LIST, 0, None, None, ctypes.byref(buf),\n                                                ctypes.byref(ctypes.wintypes.DWORD(len(buf))))\n            ipcount = struct.unpack('I', buf[0:4])[0]\n\n            iplist = []\n            for i in range(4, ipcount * 4 + 4, 4):\n                ip = socket.inet_ntoa(buf[i:i + 4])\n                iplist.append(ip)\n\n        elif os.path.isfile('/etc/resolv.conf'):\n            try:\n                with open('/etc/resolv.conf', 'rb') as fp:\n                    iplist = re.findall(br'(?m)^nameserver\\s+(\\S+)', fp.read())\n\n                xlog.debug(\"DNS resolve servers:%s\", iplist)\n\n                local_ips = g.local_ips\n                for ip in local_ips:\n                    if ip in iplist:\n                        xlog.warn(\"remove local DNS server %s from upstream\", ip)\n                        iplist.remove(ip)\n            except Exception as e:\n                xlog.warn(\"load /etc/resolv.conf fail:%r\", e)\n\n        if not iplist:\n            if g.config.country_code == \"CN\":\n                iplist = [\n                    b\"114.114.114.114\",\n                    b\"114.114.115.115\",\n                    b\"119.29.29.29\",\n                    b\"182.254.118.118\",\n                    b\"223.5.5.5\",\n                    b\"223.6.6.6\",\n                    b\"180.76.76.76\"\n                ]\n            else:\n                iplist = [\n                    b\"1.1.1.1\",\n                    b\"8.8.8.8\",\n                    b\"9.9.9.9\",\n                    b\"208.67.222.222\",\n                    b\"168.126.63.2\"\n                ]\n\n        out_list = []\n        for ip in iplist:\n            if ip == b\"127.0.0.1\":\n                continue\n            out_list.append(ip)\n            xlog.info(\"Local DNS server:%s\", ip)\n\n        return out_list\n\n    def stop(self):\n        self.running = False\n        self.sock.close()\n\n    def dns_recv_worker(self, sock):\n        while self.running:\n            try:\n                try:\n                    response, server = sock.recvfrom(8192)\n                    server, port = server\n                except Exception as e:\n                    # xlog.exception(\"sock.recvfrom except:%r\", e)\n                    continue\n\n                if not response:\n                    continue\n\n                try:\n                    p = DNSRecord.parse(response)\n                except Exception as e:\n                    xlog.exception(\"dns client parse response fail:%r\", e)\n                    continue\n\n                if len(p.questions) == 0:\n                    xlog.warn(\"received response without question\")\n                    continue\n\n                id = p.header.id\n\n                if id not in self.waiters:\n                    continue\n\n                que = self.waiters[id]\n                org_domain = que.domain\n                domain = str(p.questions[0].qname)\n                xlog.debug(\"DNS local query received %s from:%s domain:%s org:%s\", len(p.rr), server, domain, org_domain)\n                ips = []\n                for r in p.rr:\n                    ip = utils.to_bytes(str(r.rdata))\n                    ips.append(ip)\n\n                if ips:\n                    que.put(ips)\n            except Exception as e:\n                xlog.exception(\"dns recv_worker except:%r\", e)\n\n        xlog.info(\"DNS Client recv worker exit.\")\n        sock.close()\n\n    def send_request(self, id, server_ip, domain, dns_type):\n        try:\n            d = DNSRecord(DNSHeader(id))\n            d.add_question(DNSQuestion(domain, dns_type))\n            req4_pack = d.pack()\n\n            if utils.check_ip_valid4(server_ip):\n                self.sock.sendto(req4_pack, (server_ip, 53))\n            else:\n                self.sock6.sendto(req4_pack, (server_ip, 53))\n        except Exception as e:\n            xlog.warn(\"send_request except:%r\", e)\n\n    def query_by_system(self, domain, dns_type):\n        ips = []\n        try:\n            t0 = time.time()\n            ip = socket.gethostbyname(domain)\n            t1 = time.time()\n            ips.append(ip)\n\n            xlog.debug(\"query_by_system, %s %d cost:%f, return:%s\", domain, dns_type, t1 - t0, ips)\n        except Exception as e:\n            xlog.warn(\"query_by_system %s %d e:%r\", domain, dns_type, e)\n\n        return ips\n\n    def query(self, domain, dns_type=1, timeout=3):\n        if sys.platform == \"ios\":\n            return self.query_by_system(domain, dns_type)\n\n        t0 = time.time()\n        end_time = t0 + timeout\n        while True:\n            id = random.randint(0, 65535)\n            if id not in self.waiters:\n                break\n\n        que = Queue()\n        que.domain = domain\n\n        for server_ip in self.dns_server:\n            new_time = time.time()\n            if new_time > end_time:\n                break\n\n            self.waiters[id] = que\n            self.send_request(id, server_ip, domain, dns_type)\n\n        try:\n            ips = que.get(timeout=self.timeout)\n        except:\n            ips = []\n\n        if ips:\n            ips = list(set(ips))\n\n        if id in self.waiters:\n            del self.waiters[id]\n\n        t1 = time.time()\n        xlog.debug(\"query by udp, %s cost:%f, return:%s\", domain, t1-t0, ips)\n\n        return ips\n\n\nclass DnsOverTcpQuery():\n    def __init__(self, server_list=[b\"114.114.114.114\"], port=53):\n        self.protocol = \"Tcp\"\n        self.timeout = 3\n        self.connection_timeout = 60\n        self.public_list = server_list\n        self.port = port\n        self.connections = []\n\n    def get_server(self):\n        return random.choice(self.public_list)\n\n    def direct_connect(self, host, port):\n        connect_timeout = 30\n\n        if b':' in host:\n            info = [(socket.AF_INET6, socket.SOCK_STREAM, 0, \"\", (host, port, 0, 0))]\n        elif utils.check_ip_valid4(host):\n            info = [(socket.AF_INET, socket.SOCK_STREAM, 0, \"\", (host, port))]\n        else:\n            try:\n                info = socket.getaddrinfo(host, port, socket.AF_UNSPEC,\n                                          socket.SOCK_STREAM)\n            except socket.gaierror:\n                info = [(socket.AF_INET, socket.SOCK_STREAM, 0, \"\", (host, port))]\n\n        for res in info:\n            af, socktype, proto, canonname, sa = res\n            s = None\n            try:\n                s = socket.socket(af, socktype, proto)\n\n                s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)\n                s.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 32 * 1024)\n                s.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, True)\n                s.settimeout(connect_timeout)\n                s.connect((host, port))\n                return s\n            except socket.error:\n                if s:\n                    s.close()\n            except Exception as e:\n                xlog.warn(\"Connect to DNS server %s:%d fail:%r\", host, port)\n\n        return None\n\n    def connect(self, host, port):\n        if not g.config.PROXY_ENABLE:\n            sock = self.direct_connect(host, self.port)\n        else:\n            connect_timeout = 5\n\n            import socks\n\n            sock = socks.socksocket(socket.AF_INET)\n            sock.set_proxy(proxy_type=g.config.PROXY_TYPE,\n                           addr=g.config.PROXY_HOST,\n                           port=g.config.PROXY_PORT, rdns=True,\n                           username=g.config.PROXY_USER,\n                           password=g.config.PROXY_PASSWD)\n\n            sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)\n            sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 32*1024)\n            sock.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, True)\n            sock.settimeout(connect_timeout)\n\n            sock.connect((host, self.port))\n\n        return sock\n\n    def get_connection(self):\n        while len(self.connections):\n            try:\n                [sock, last_query_time] = self.connections.pop()\n                if time.time() - last_query_time < self.connection_timeout:\n                    return sock\n            except:\n                pass\n\n        server_ip = self.get_server()\n        if not server_ip:\n            return None\n\n        sock = self.connect(server_ip, self.port)\n        return sock\n\n    def query(self, domain, dns_type=1):\n        t0 = time.time()\n        try:\n            sock = self.get_connection()\n            if not sock:\n                xlog.warn(\"query_over_tcp %s type:%s connect fail.\", domain, dns_type)\n                return []\n\n            d = DNSRecord(DNSHeader())\n            d.add_question(DNSQuestion(domain, dns_type))\n\n            data = d.pack()\n            data = struct.pack(\"!H\", len(data)) + data\n            sock.sendall(data)\n\n            response = sock.recv(8192)\n            if not response:\n                return []\n\n            length = struct.unpack(\"!H\", bytes(response[:2]))[0]\n            while len(response) - 2 < length:\n                response += sock.recv(8192)\n\n            t2 = time.time()\n\n            p = DNSRecord.parse(response[2:])\n            if len(p.rr) == 0:\n                xlog.warn(\"query_over_tcp for %s type:%d return none, cost:%f\", domain, dns_type, t2-t0)\n\n            ips = []\n            for r in p.rr:\n                ip = utils.to_bytes(str(r.rdata))\n                if not utils.check_ip_valid(ip) and dns_type != 2:\n                    if ip == domain:\n                        continue\n\n                    ip_ips = self.query(ip, dns_type)\n                    ips += ip_ips\n                else:\n                    ips.append(ip)\n\n            xlog.debug(\"DNS %s %s return %s t:%f\", self.protocol, domain, ips, t2-t0)\n            self.connections.append([sock, time.time()])\n            return ips\n        except socket.timeout:\n            xlog.warn(\"query_over_tcp %s type:%s timeout\", domain, dns_type)\n            return []\n        except Exception as e:\n            xlog.exception(\"query_over_tcp %s type:%s except:%r\", domain, dns_type, e)\n            return []\n\n\nclass DnsOverTlsQuery(DnsOverTcpQuery):\n    def __init__(self, server_list=None):\n        if not server_list:\n            server_list = [\n                {\n                    \"domain\": \"one.one.one.one\",\n                    \"ipv4s\": [b\"1.1.1.1\", b\"1.0.0.1\"],\n                },\n                {\n                    \"domain\": \"dns.quad9.net\",\n                    \"ipv4s\": [b\"9.9.9.9\", b\"149.112.112.112\"],\n                }\n            ]\n\n        DnsOverTcpQuery.__init__(self, server_list=server_list, port=853)\n        self.protocol = \"DoT\"\n        self.ssl_context = ssl.create_default_context()\n        self.ssl_context.check_hostname = False\n        self.ssl_context.verify_mode = ssl.CERT_REQUIRED\n\n    def connect(self, host, port):\n        domain = host[\"domain\"]\n        ipv4 =  random.choice(host[\"ipv4s\"])\n        try:\n            s = super(DnsOverTlsQuery, self).connect(ipv4, port)\n            sock = self.ssl_context.wrap_socket(s, server_hostname=domain)\n            return sock\n        except Exception as e:\n            xlog.warn(\"DnsOverTlsQuery connect %s %s:%d fail:%r\", ipv4, domain, port, e)\n            return None\n\n\nclass DnsOverHttpsQuery(object):\n    def __init__(self, timeout=6):\n        self.protocol = \"DoH\"\n        self.timeout = timeout\n        self.cn_servers = [\"https://1.12.12.12/dns-query\", \"https://223.5.5.5/dns-query\"]\n        self.other_servers = [\n            \"https://1.1.1.1/dns-query\",\n            \"https://dns10.quad9.net/dns-query\",\n            \"https://dns.aa.net.uk/dns-query\",\n        ]\n        self.connection_timeout = 60\n        self.connections = []\n\n    def get_connection(self):\n        while len(self.connections):\n            try:\n                [client, last_query_time] = self.connections.pop()\n                if time.time() - last_query_time < self.connection_timeout:\n                    return client\n            except:\n                pass\n\n        if g.config.PROXY_ENABLE == 1:\n            return simple_http_client.Client(proxy={\n                \"type\": g.config.PROXY_TYPE,\n                \"host\": g.config.PROXY_HOST,\n                \"port\": g.config.PROXY_PORT,\n                \"user\": g.config.PROXY_USER,\n                \"pass\": g.config.PROXY_PASSWD,\n            }, timeout=self.timeout)\n        else:\n            return simple_http_client.Client(timeout=self.timeout)\n\n    @property\n    def server(self):\n        return random.choice(self.other_servers)\n\n    def query_json(self, domain, dns_type=1):\n        try:\n            t0 = time.time()\n            client = self.get_connection()\n\n            url = self.server + \"?name=\" + domain + \"&type=A\" # type need to map to Text.\n            r = client.request(\"GET\", url, headers={\"accept\": \"application/dns-json\"})\n            t2 = time.time()\n            ips = []\n            if not r:\n                xlog.warn(\"DNS server:%s domain:%s fail t:%f\", self.server, domain,  t2 - t0)\n                return ips\n\n            t = utils.to_str(r.text)\n\n            data = json.loads(t)\n            for answer in data[\"Answer\"]:\n                ips.append(answer[\"data\"])\n\n            self.connections.append([client, time.time()])\n\n            xlog.debug(\"DNS server:%s query:%s return %s t:%f\", self.server, domain, ips, t2 - t0)\n            return ips\n        except Exception as e:\n            xlog.warn(\"DNSOverHttpsQuery query fail:%r\", e)\n            return []\n\n    def query(self, domain, dns_type=1, url=None):\n        t0 = time.time()\n        try:\n            client = self.get_connection()\n\n            if not url:\n                url = self.server\n            # xlog.debug(\"DoH use %s\", url)\n\n            d = DNSRecord(DNSHeader())\n            d.add_question(DNSQuestion(domain, dns_type))\n            data = d.pack()\n\n            r = client.request(\"POST\", url, headers={\"accept\": \"application/dns-message\",\n                                                     \"content-type\": \"application/dns-message\"}, body=data)\n\n            t2 = time.time()\n            ips = []\n            if not r:\n                xlog.warn(\"DNS s:%s query:%s fail t:%f\", self.server, domain,  t2 - t0)\n                return ips\n\n            p = DNSRecord.parse(r.text)\n\n            self.connections.append([client, time.time()])\n\n            for r in p.rr:\n                ip = utils.to_bytes(str(r.rdata))\n                if not utils.check_ip_valid(ip):\n                    if ip == domain:\n                        continue\n\n                    ip_ips = self.query(ip, dns_type)\n                    ips += ip_ips\n                else:\n                    ips.append(ip)\n\n            xlog.debug(\"DNS %s %s return %s t:%f\", self.protocol, domain, ips, t2 - t0)\n            return ips\n        except Exception as e:\n            t1 = time.time()\n            t = t1 - t0\n            xlog.warn(\"DnsOverHttpsQuery query %s cost:%f fail:%r\", domain, t, e)\n            return []\n\n\nclass ParallelQuery():\n    def query_worker(self, task, function):\n        ips = function(task.domain, task.dns_type)\n        if len(ips):\n            g.domain_cache.set_ips(task.domain, ips, task.dns_type)\n            task.put(ips)\n\n    def query(self, domain, dns_type, funcs):\n        task = Queue()\n        task.domain = domain\n        task.dns_type = dns_type\n\n        for func in funcs:\n            threading.Thread(target=self.query_worker, args=(task, func), name=\"ParalleQuery_%s\" % domain).start()\n\n        try:\n            ips = task.get(timeout=5)\n        except:\n            ips = []\n\n        return ips\n\n\nclass CombineDnsQuery():\n    def __init__(self):\n        self.domain_allowed_pattern = re.compile(br\"(?!-)[A-Z\\d-]{1,63}(?<!-)$\")\n        self.local_dns_resolve = LocalDnsQuery()\n\n        self.tcp_query = DnsOverTcpQuery()\n        self.tls_query = DnsOverTlsQuery()\n        self.https_query = DnsOverHttpsQuery()\n\n        self.parallel_query = ParallelQuery()\n\n    def is_valid_hostname(self, hostname):\n        hostname = hostname.upper()\n        if len(hostname) > 255:\n            return False\n        if hostname.endswith(b\".\"):\n            hostname = hostname[:-1]\n\n        return all(self.domain_allowed_pattern.match(x) for x in hostname.split(b\".\"))\n\n    def query_blocked_domain(self, domain, dns_type):\n        return self.parallel_query.query(domain, dns_type, [\n            self.https_query.query,\n            self.tls_query.query,\n            query_dns_from_xxnet,\n        ])\n\n    def query_unknown_domain(self, domain, dns_type):\n        res = self.local_dns_resolve.query(domain, dns_type)\n        if res:\n            return res\n\n        return self.parallel_query.query(domain, dns_type, [\n            self.https_query.query,\n            self.tls_query.query,\n            self.tcp_query.query,\n            query_dns_from_xxnet\n        ])\n\n    def query(self, domain, dns_type=1, history=[]):\n        domain = utils.to_bytes(domain)\n        if utils.check_ip_valid(domain):\n            return [domain]\n\n        if not self.is_valid_hostname(domain):\n            xlog.warn(\"DNS query:%s not valid, type:%d\", domain, dns_type)\n            return []\n\n        ips = g.domain_cache.get_ips(domain, dns_type)\n        if ips:\n            return ips\n\n        rule = g.user_rules.check_host(domain, 0)\n        if rule == \"black\":\n            # user define black list like advertisement or malware server.\n            ips = [\"127.0.0.1\"]\n            xlog.debug(\"DNS query:%s in black\", domain)\n            return ips\n\n        elif b\".\" not in domain or g.gfwlist.in_white_list(domain) or rule in [\"direct\"] or g.config.pac_policy == \"all_Direct\":\n            ips = self.local_dns_resolve.query(domain, timeout=1)\n            g.domain_cache.set_ips(domain, ips, dns_type)\n            return ips\n\n        elif g.gfwlist.in_block_list(domain) or rule in [\"gae\", \"socks\"] or g.config.pac_policy == \"all_X-Tunnel\":\n            ips = self.query_blocked_domain(domain, dns_type)\n        elif g.gfwlist.in_white_list(domain):\n            ips = self.local_dns_resolve.query(domain, dns_type, timeout=1)\n        else:\n            ips = self.query_unknown_domain(domain, dns_type)\n\n        if not ips:\n            ips = self.local_dns_resolve.query(domain, timeout=1)\n\n        out_ips = []\n        for ip in ips:\n            if not utils.check_ip_valid(ip):\n                if ip == domain:\n                    continue\n\n                if ip in history:\n                    continue\n\n                history.append(ip)\n                ip_ips = self.query(ip, dns_type, history)\n                for ip in ip_ips:\n                    out_ips.append(ip)\n\n            elif ip not in out_ips:\n                out_ips.append(ip)\n\n        return out_ips\n\n    def query_recursively(self, domain, dns_type=None):\n        if not dns_type:\n            dns_types = [1, 28]\n        else:\n            dns_types = [dns_type]\n\n        ips_out = []\n        for dns_type in dns_types:\n            ips = self.query(domain, dns_type)\n            for ip in ips:\n                if dns_type == 2 or utils.check_ip_valid(ip):\n                    ips_out.append(ip)\n                else:\n                    ips_s = self.query_recursively(ip, dns_type)\n                    ips_out += ips_s\n\n        return ips_out\n\n    def stop(self):\n        self.local_dns_resolve.stop()"
  },
  {
    "path": "code/default/smart_router/local/dns_server.py",
    "content": "#!/usr/bin/env python\n# coding:utf-8\n\nimport os\nimport sys\nimport threading\nimport socket\nimport time\nimport select\nimport struct\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nroot_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))\ntop_path = os.path.abspath(os.path.join(root_path, os.pardir, os.pardir))\n\npython_path = root_path\nnoarch_lib = os.path.join(python_path, 'lib', 'noarch')\nsys.path.append(noarch_lib)\n\nimport env_info\ndata_path = os.path.join(env_info.data_path, 'smart_router')\n\nimport utils\nfrom dnslib import DNSRecord, DNSHeader, A, AAAA, RR, DNSQuestion, QTYPE, NS\n\nfrom . import global_var as g\nfrom xlog import getLogger\nxlog = getLogger(\"smart_router\")\n\n\nclass DnsServer(object):\n    def __init__(self, bind_ip=\"127.0.0.1\", port=53, backup_port=8053, ttl=24*3600):\n        self.sockets = []\n        self.udp_relay_sock = None\n        self.udp_relay_port = 0\n        self.listen_port = port\n        self.running = False\n        if isinstance(bind_ip, str):\n            self.bind_ip = [bind_ip]\n        else:\n            # server can listen multi-port\n            self.bind_ip = bind_ip\n        self.port = port\n        self.backup_port = backup_port\n        self.ttl = ttl\n        self.th = None\n\n    def init_socket(self):\n        ips = set(self.bind_ip)\n        listen_all_v4 = \"0.0.0.0\" in ips\n        listen_all_v6 = \"::\" in ips\n        for ip in ips:\n            if ip not in (\"0.0.0.0\", \"::\") and (\n                    listen_all_v4 and '.' in ip or\n                    listen_all_v6 and ':' in ip):\n                continue\n            self.bing_udp_relay(ip)\n            self.bing_listen(ip)\n\n    def bing_listen(self, bind_ip):\n        if \":\" in bind_ip:\n            sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)\n        else:\n            sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)\n\n        try:\n            sock.bind((bind_ip, self.port))\n            xlog.info(\"start DNS server at %s:%d\", bind_ip, self.port)\n            self.running = True\n            self.sockets.append(sock)\n            return\n        except:\n            xlog.warn(\"bind DNS %s:%d fail\", bind_ip, self.port)\n            pass\n\n        try:\n            sock.bind((bind_ip, self.backup_port))\n            xlog.info(\"start DNS server at %s:%d\", bind_ip, self.backup_port)\n            self.running = True\n            self.listen_port = self.backup_port\n            self.sockets.append(sock)\n            return\n        except Exception as e:\n            xlog.warn(\"bind DNS %s:%d fail\", bind_ip, self.backup_port)\n\n            if sys.platform.startswith(\"linux\"):\n                xlog.warn(\"You can try: install libcap2-bin\")\n                xlog.warn(\"Then: sudo setcap 'cap_net_bind_service=+ep' /usr/bin/python2.7\")\n                xlog.warn(\"Or run as root\")\n\n    def bing_udp_relay(self, bind_ip):\n        if \":\" in bind_ip:\n            sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)\n        else:\n            sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)\n\n        port = g.config.udp_relay_port\n        for port in range(port, port + 20):\n            try:\n                sock.bind((bind_ip, port))\n                xlog.info(\"start UDP relay server at %s:%d\", bind_ip, port)\n                self.sockets.append(sock)\n                self.udp_relay_sock = sock\n                self.udp_relay_port = port\n                return\n            except:\n                xlog.warn(\"bind UDP %s:%d fail\", bind_ip, self.port)\n\n    def dns_query(self, req_data, addr):\n        start_time = time.time()\n        try:\n            request = DNSRecord.parse(req_data)\n            if len(request.questions) != 1:\n                xlog.warn(\"query num:%d %s\", len(request.questions), request)\n                return\n\n            domain = utils.to_bytes(str(request.questions[0].qname))\n\n            if domain.endswith(b\".\"):\n                domain = domain[:-1]\n\n            dns_type = request.questions[0].qtype\n            xlog.debug(\"DNS query:%s type:%d from %s\", domain, dns_type, addr)\n\n            ips = g.dns_query.query(domain, dns_type)\n            if not ips:\n                xlog.debug(\"query:%s type:%d from:%s, get fail, cost:%d\", domain, dns_type, addr,\n                           (time.time() - start_time) * 1000)\n\n            reply = DNSRecord(DNSHeader(id=request.header.id, qr=1, aa=1, ra=1, auth=1), q=request.q)\n            ips = utils.to_bytes(ips)\n            for ip_cn in ips:\n                ipcn_p = ip_cn.split(b\"|\")\n                ip = ipcn_p[0]\n                if utils.check_ip_valid4(ip) and dns_type == 1:\n                    reply.add_answer(RR(domain, ttl=60, rdata=A(ip)))\n                elif utils.check_ip_valid6(ip) and dns_type == 28:\n                    reply.add_answer(RR(domain, rtype=dns_type, ttl=60, rdata=AAAA(ip)))\n                elif dns_type == 2:\n                    reply.add_answer(RR(domain, rtype=dns_type, ttl=60, rdata=NS(ip)))\n            res_data = reply.pack()\n\n            xlog.debug(\"query:%s type:%d from:%s, return ip num:%d cost:%d\", domain, dns_type, addr,\n                       len(reply.rr), (time.time()-start_time)*1000)\n            return res_data\n        except Exception as e:\n            xlog.exception(\"on_query except:%r\", e)\n\n    def on_udp_query(self, rsock, req_data, addr):\n        res_data = self.dns_query(req_data, addr)\n        rsock.sendto(res_data, addr)\n\n    def on_udp_relay(self, rsock, req_data, from_addr):\n        # We currently only support DNS query for UDP relay\n\n        # SOCKS5 UDP forward request\n        # reserved, frag, addr_type, domain_len, domain, port, data\n        try:\n            reserved = struct.unpack(\">H\", req_data[0:2])[0]\n            frag = ord(req_data[2:3])\n            if reserved != 0 or frag != 0:\n                xlog.warn(\"reserved:%d frag:%d\", reserved, frag)\n                return\n\n            addr_type = ord(req_data[3:4])\n            if addr_type == 1:  # IPv4\n                addr_pack = req_data[4:8]\n                addr = socket.inet_ntoa(addr_pack)\n                port = struct.unpack(\">H\", req_data[8:10])[0]\n                data = req_data[10:]\n            elif addr_type == 3:  # Domain name\n                domain_len_pack = req_data[4:5]\n                domain_len = ord(domain_len_pack)\n                domain = req_data[5:5 + domain_len]\n                addr = domain\n                port = struct.unpack(\">H\", req_data[5 + domain_len:5 + domain_len + 2])[0]\n                data = req_data[5 + domain_len + 2:]\n            elif addr_type == 4:  # IPv6\n                addr_pack = req_data[4:20]\n                addr = socket.inet_ntop(socket.AF_INET6, addr_pack)\n                port = struct.unpack(\">H\", req_data[20:22])[0]\n                data = req_data[22:]\n            else:\n                xlog.warn(\"request address type unknown:%d\", addr_type)\n                return\n\n            xlog.debug(\"UDP relay from %s size:%d to:%s:%d\", from_addr, len(data), addr, port)\n            if port != 53:\n                return\n\n            head_length = len(req_data) - len(data)\n            head = req_data[:head_length]\n            res_data = self.dns_query(data, from_addr)\n            if not res_data:\n                return\n\n            rsock.sendto(head + res_data, from_addr)\n            xlog.debug(\"UDP relay from %s size:%d to:%s:%d res len:%d\", from_addr, len(data), addr, port, len(res_data))\n        except Exception as e:\n            xlog.exception(\"on_udp_relay data:[%s] except:%r\", utils.str2hex(req_data), e)\n\n    def server_forever(self):\n        while self.running:\n            r, w, e = select.select(self.sockets, [], [], 1)\n            for rsock in r:\n                if not self.running:\n                    break\n\n                try:\n                    data, addr = rsock.recvfrom(1024)\n                except Exception as e:\n                    xlog.warn(\"recv except: %r\", e)\n                    break\n\n                if rsock == self.udp_relay_sock:\n                    threading.Thread(target=self.on_udp_relay, args=(rsock, data, addr), name=\"UDP_relay\").start()\n                else:\n                    threading.Thread(target=self.on_udp_query, args=(rsock, data, addr), name=\"DNSServer_udp_handler\").start()\n\n        self.th = None\n\n    def start(self):\n        self.init_socket()\n        self.th = threading.Thread(target=self.server_forever, name=\"DNSServer\")\n        self.th.start()\n\n    def stop(self):\n        self.running = False\n        while self.th:\n            time.sleep(1)\n        for sock in self.sockets:\n            sock.close()\n        self.sockets = []\n        xlog.info(\"dns_server stop\")\n\n\n"
  },
  {
    "path": "code/default/smart_router/local/gfw_black_list.txt",
    "content": "030buy.com\n0rz.tw\n1-apple.com.tw\n1000giri.net\n100ke.org\n10conditionsoflove.com\n10musume.com\n123rf.com\n12bet.com\n12vpn.com\n12vpn.net\n141hongkong.com\n141tube.com\n1688.com.au\n173ng.com\n177pic.info\n17t17p.com\n18board.com\n18board.info\n18onlygirls.com\n18p2p.com\n18virginsex.com\n1949er.org\n1984bbs.com\n1984bbs.org\n1989report.hkja.org.hk\n1991way.com\n1998cdp.org\n1bao.org\n1dumb.com\n1e100.net\n1eew.com\n1mobile.com\n1mobile.tw\n1pondo.tv\n2-hand.info\n2000fun.com\n2008xianzhang.info\n2017.hk\n21andy.com\n21pron.com\n21sextury.com\n228.net.tw\n233abc.com\n24hrs.ca\n24smile.org\n25u.com\n2dbook.com\n2lipstube.com\n2shared.com\n2waky.com\n3-a.net\n30boxes.com\n315lz.com\n32red.com\n36rain.com\n3a5a.com\n3arabtv.com\n3boys2girls.com\n3d-game.com\n3proxy.ru\n3ren.ca\n3tui.net\n466453.com\n4bluestones.biz\n4chan.com\n4dq.com\n4everproxy.com\n4irc.com\n4mydomain.com\n4pu.com\n4rbtv.com\n4shared.com\n4sqi.ne\n4tern.com\n51.ca\n51jav.org\n51luoben.com\n5278.cc\n56cun04.jigsy.com\n5aimiku.com\n5i01.com\n5isotoi5.org\n5maodang.com\n63i.com\n64memo.com\n64museum.org\n64tianwang.com\n64wiki.com\n66.ca\n666kb.com\n6park.com\n7capture.com\n7cow.com\n8-d.com\n85cc.net\n85cc.u\n85cc.us\n85st.com\n881903.com\n888.com\n888poker.com\n89-64.org\n8news.com.tw\n8z1.net\n9001700.com\n908taiwan.org\n91porn.com\n91vps.club\n92ccav.com\n991.com\n99btgc01.com\n99cn.info\n9bis.com\n9bis.net\na-normal-day.com\na.hao123.com\na248.e.akamai.net\na5.com.ru\naa-usa.org\naamacau.com\nabc.com\nabc.pp.ru\nabc.xyz\nabchinese.com\nabclite.ne\nabclite.net\nabitno.linpie.com\nablwang.com\naboluowang.com\naboutgfw.com\nabs.edu\nac.jiruan.net\naccim.org\naceros-de-hispania.com\nacevpn.com\nacg.in\nacg.li\nacg.me\nacg.red\nacg18.me\nacgkj.com\nackoverflow.com\nacmetoy.com\nacnw.com.au\nactfortibet.org\nactimes.com.au\nactivpn.com\naculo.us\naddictedtocoffee.de\nadelaidebbs.com\nadmob.com\nadorama.com\nadpl.org.hk\nads-twitter.com\nadsense.com\nadult-sex-games.com\nadult.friendfinder.com\nadultfriendfinder.com\nadultkeep.net\nadvanscene.com\nadvertfan.com\nae.hao123.com\nae.org\naenhancers.com\naf.mil\nafantibbs.com\nagnesb.fr\nagoogleaday.com\nagro.hk\nai-kan.net\nai-wen.net\nai.binwang.me\naintyculture.com\naiph.net\nairasia.com\nairconsole.com\nairvpn.org\naisex.com\naiss.anws.gov.tw\nait.org.tw\naiweiwei.com\naiweiweiblog.com\najsands.com\nakademiye.org\nakamaihd.ne\nakiba-online.com\nakiba-web.com\nal-islam.com\nal-qimmah.net\nalabout.com\nalanhou.com\nalarab.qa\nalasbarricadas.org\nalexlur.org\nalforattv.net\nalhayat.com\nalicejapan.co.jp\nalien-ufos.com\naliengu.com\nalkasir.com\nallconnected.co\nalldrawnsex.com\nallervpn.com\nallfinegirls.com\nallgirlmassage.com\nallgirlsallowed.org\nallgravure.com\nalliance.org.hk\nallinfa.com\nalljackpotscasino.com\nallmovie.com\nallowed.org\nalmasdarnews.com\nalmostmy.com\nalphaporno.com\nalternate-tools.com\nalternativeto.net\naltrec.com\nalvinalexander.com\nalwaysdata.com\nalwaysdata.net\nalwaysvpn.com\nam730.com.hk\namazon.com\nameblo.jp\namericangreencard.com\namericanunfinished.com\namericorps.gov\namiblockedornot.com\namigobbs.net\namitabhafoundation.u\namitabhafoundation.us\namnesty.org\namnesty.org.hk\namnesty.tw\namnestyusa.org\namnyemachen.org\namoiist.com\nampproject.org\namtb-taipei.org\nanchorfree.com\nancsconf.org\nandfaraway.net\nandroid-x86.org\nandroid.com\nandroidify.com\nandroidplus.co\nandygod.com\nangelfire.com\nangularjs.org\nanimecrazy.net\nanimeshippuuden.com\naniscartujo.com\nannatam.com\nanobii.com\nanontext.com\nanonymise.us\nanonymitynetwork.com\nanonymizer.com\nanpopo.com\nanswering-islam.org\nantd.org\nanthonycalzadilla.com\nanti1984.com\nantichristendom.com\nantiwave.ne\nantiwave.net\nanyporn.com\nanysex.com\naobo.com.au\naofriend.com\naofriend.com.au\naoism.ne\naojiao.org\naolchannels.aol.com\naolnews.com\naomiwang.com\napetube.com\napi-secure.recaptcha.net\napi-verify.recaptcha.net\napi.ai\napi.dropboxapi.com\napi.linksalpha.com\napi.proxlet.com\napi.recaptcha.net\napiary.io\napidocs.linksalpha.com\napigee.com\napk-dl.com\napkdler.com\napkmirror.com\napkmonk.com\napkplz.com\napkpure.com\naplusvpn.com\napp-measurement.com\napp.box.com\napp.heywire.com\napp.tutanota.com\nappdownloader.net\nappledaily.com\nappshopper.com\nappsocks.net\nappspot.com\nappsto.re\nar.hao123.com\narchive.fo\narchive.i\narchive.is\narchive.org\narchives.gov\narchives.gov.tw\narctosia.com\nareca-backup.org\narena.taipei\narethusa.su\narlingtoncemetery.mil\narmy.mil\narr.uspto.gov\narstechnica.com\nart4tibet1998.org\nartofpeacefoundation.org\nartsy.net\nartuplivingchina.com\narunyahya.com\nasacp.org\nasahichinese.com\nasdfg.jp\nasg.to\nasia-gaming.com\nasiaharvest.org\nasianews.it\nasiansexdiary.com\nasianspiss.com\nasianwomensfilm.de\nasiatgp.com\nasiatoday.us\naskstudent.com\naskynz.net\nassembla.com\nassimp.org\nastrill.com\natc.org.au\natchinese.com\natdmt.com\natgfw.org\nathenaeizou.com\natlanta168.com\natlaspost.com\natnext.com\nauthorizeddns.net\nauthorizeddns.org\nauthorizeddns.us\nautodraw.com\nav.nightlife141.com\navaaz.org\navbody.tv\navcity.tv\navcool.com\navdb.in\navdb.tv\navfantasy.com\navidemux.org\navmo.pw\navmoo.com\navmoo.ne\navmoo.net\navmoo.pw\navoision.com\navyahoo.com\naxureformac.com\nazerbaycan.tv\nazerimix.com\nazubu.tv\nazurewebsites.net\nb0ne.com\nbabynet.com.hk\nbackchina.com\nbackpackers.com.tw\nbacktotiananmen.com\nbadjojo.com\nbadoo.com\nbahamut.com.tw\nbaidu.jp\nbailandaily.com\nbaixing.me\nbakgeekhome.tk\nbanana-vpn.com\nbandwagonhost.com\nbangbrosnetwork.com\nbangchen.ne\nbangchen.net\nbangyoulater.com\nbannedbook.org\nbannednews.org\nbanorte.com\nbaramangaonline.com\nbarenakedislam.com\nbarnabu.co.uk\nbartvpn.com\nbash-hackers.org\nbastillepost.com\nbayvoice.net\nbb-chat.tv\nbb.ttv.com.tw\nbbc.co.uk\nbbc.com\nbbc.in\nbbcchinese.com\nbbchat.tv\nbbg.gov\nbbkz.com\nbbnradio.org\nbbs-tw.com\nbbs.brockbbs.com\nbbs.cantonese.asia\nbbs.ecstart.com\nbbs.hanminzu.org\nbbs.hasi.wang\nbbs.huasing.org\nbbs.junglobal.net\nbbs.kimy.com.tw\nbbs.morbell.com\nbbs.mychat.to\nbbs.netbig.com\nbbs.ozchinese.com\nbbs.qmzdd.com\nbbs.sina.com\nbbs.skykiwi.com\nbbs.sou-tong.org\nbbs.tuitui.info\nbbsdigest.com\nbbsfeed.com\nbbsland.com\nbbsmo.com\nbbsone.com\nbbtoystore.com\nbcast.co.nz\nbcc.com.tw\nbcchinese.net\nbcmorning.com\nbdsmvideos.net\nbeaconevents.com\nbebo.com\nbeeg.com\nbeevpn.com\nbehindkink.com\nbeijing1989.com\nbeijingspring.com\nbeijingzx.org\nbelamionline.com\nbell.wiki\nbemywife.cc\nberic.me\nberlintwitterwall.com\nberm.co.nz\nbestforchina.org\nbestgore.com\nbestpornstardb.com\nbestvpn.com\nbestvpnanalysis.com\nbestvpnserver.com\nbestvpnservice.com\nbestvpnusa.com\nbet365.com\nbeta.usejump.com\nbetfair.com\nbetternet.co\nbettervpn.com\nbettween.com\nbetvictor.com\nbewww.net\nbeyondfirewall.com\nbfnn.org\nbfsh.hk\nbgvpn.com\nbianlei.com\nbiantailajiao.com\nbiantailajiao.in\nbiblesforamerica.org\nbic2011.org\nbigfools.com\nbigjapanesesex.com\nbigmoney.biz\nbignews.org\nbigsound.org\nbiliworld.com\nbillypan.com\nbing.com\nbinux.me\nbipic.net\nbit.do\nbit.ly\nbitcointalk.org\nbitshare.com\nbitsnoop.com\nbitvise.com\nbizhat.com\nbjnewlife.org\nbjs.org\nbjzc.org\nbl-doujinsouko.com\nblacklogic.com\nblackvpn.com\nblewpass.com\nblinkx.com\nblinw.com\nblip.tv\nblockcn.com\nblockless.com\nblog.calibre-ebook.com\nblog.cnyes.com\nblog.daum.net\nblog.de\nblog.exblog.co.jp\nblog.excite.co.jp\nblog.expofutures.com\nblog.fizzik.com\nblog.foolsmountain.com\nblog.fuckgfw233.org\nblog.goo.ne.jp\nblog.google\nblog.inoreader.com\nblog.istef.info\nblog.jackjia.com\nblog.jp\nblog.kangye.org\nblog.lester850.info\nblog.martinoei.com\nblog.pathtosharepoint.com\nblog.pentalogic.net\nblog.qooza.hk\nblog.ranxiang.com\nblog.sina.com.tw\nblog.sogoo.org\nblog.soylent.com\nblog.syx86.cn\nblog.syx86.com\nblog.taragana.com\nblog.tiney.com\nblog.xuite.net\nblog.youthwant.com.tw\nblog.youxu.info\nblogblog.com\nblogcatalog.com\nblogcity.me\nblogdns.org\nblogger.com\nblogimg.jp\nbloglines.com\nbloglovin.com\nblogs.icerocket.com\nblogs.libraryinformationtechnology.com\nblogs.tampabay.com\nblogs.yahoo.co.jp\nblogspot.com\nblogspot.hk\nblogspot.jp\nblogtd.net\nblogtd.org\nbloodshed.net\nbloomberg.cn\nbloomberg.com\nbloomberg.de\nbloombergview.com\nbloomfortune.com\nblueangellive.com\nbme.me\nbmfinn.com\nbnews.co\nbnrmetal.com\nboardreader.com\nbod.asia\nbodog88.com\nbolehvpn.net\nbolin.netfirms.com\nbonbonme.com\nbonbonsex.com\nbonfoundation.org\nbongacams.com\nboobstagram.com\nbook.com.tw\nbook.zi5.me\nbookepub.com\nbooks.com.tw\nboomssr.com\nbot.nu\nbotanwang.com\nbowenpress.com\nboxpn.com\nboxun.com\nboxun.tv\nboxunblog.com\nboxunclub.com\nboyangu.com\nboyfriendtv.com\nboysfood.com\nboysmaster.com\nbr.hao123.com\nbr.st\nbrainyquote.com\nbrandonhutchinson.com\nbraumeister.org\nbravotube.net\nbrazzers.com\nbreak.com\nbreakgfw.com\nbreaking911.com\nbreakingtweets.com\nbreakwall.net\nbriefdream.com\nbriian.com\nbrizzly.com\nbrkmd.com\nbroadbook.com\nbroadpressinc.com\nbrucewang.net\nbrutaltgp.com\nbssqh.org\nbt2mag.com\nbt95.com\nbtaia.com\nbtbtav.com\nbtdigg.org\nbtku.me\nbtku.org\nbtspread.com\nbudaedu.org\nbuddhanet.com.tw\nbuddhistchannel.tv\nbuffered.com\nbullog.org\nbullogger.com\nbunbunhk.com\nbusayari.com\nbusinessinsider.com\nbusinessinsider.com.au\nbusinessweek.com\nbusu.org\nbusytrade.com\nbuugaa.com\nbuy.yahoo.com.tw\nbuzzhand.com\nbuzzhand.net\nbuzzorange.com\nbvpn.com\nbwsj.hk\nbx.tl\nbynet.co.il\nc-est-simple.com\nc-spanvideo.org\nc100tibet.org\nc1522.mooo.com\ncablegatesearch.net\ncachinese.com\ncacnw.com\ncactusvpn.com\ncafepress.com\ncahr.org.tw\ncalameo.com\ncalebelston.com\ncalgarychinese.ca\ncalgarychinese.com\ncalgarychinese.net\ncam4.com\ncam4.jp\ncam4.sg\ncamfrog.com\ncams.com\ncams.org.sg\ncanadameet.com\ncanalporno.com\ncanyu.org\ncao.im\ncaobian.info\ncaochangqing.com\ncap.org.hk\ncarabinasypistolas.com\ncardinalkungfoundation.org\ncarfax.com\ncari.com.my\ncaribbeancom.com\ncarmotorshow.com\ncartoonmovement.com\ncasadeltibetbcn.org\ncasatibet.org.mx\ncasino.williamhill.com\ncasinobellini.com\ncasinoking.com\ncasinoriva.com\ncatch22.net\ncatfightpayperview.xxx\ncatholic.org.hk\ncatholic.org.tw\ncathvoice.org.tw\ncattt.com\ncbc.ca\ncbs.ntu.edu.tw\ncbsnews.com\ncbtc.org.hk\ncccat.cc\ncccat.co\nccdtr.org\ncchere.com\nccim.org\ncclife.ca\ncclife.org\ncclifefl.org\nccthere.com\ncctongbao.com\nccue.ca\nccue.com\nccvoice.ca\nccw.org.tw\ncdbook.org\ncdcparty.com\ncdef.org\ncdig.info\ncdjp.org\ncdn-apple.com\ncdn-images.mailchimp.com\ncdn.assets.lfpcontent.com\ncdn.helixstudios.net\ncdn.printfriendly.com\ncdn.softlayer.net\ncdn1.lp.saboom.com\ncdnews.com.tw\ncdninstagram.com\ncdp1989.org\ncdp1998.org\ncdp2006.org\ncdpa.url.tw\ncdpeu.org\ncdpusa.org\ncdpweb.org\ncdpwu.org\ncdw.com\ncecc.gov\ncellulo.info\ncenews.eu\ncentauro.com.br\ncenterforhumanreprod.com\ncentralnation.com\ncenturys.ne\ncenturys.net\ncertificate-transparency.org\ncertificate.revocationcheck.com\ncfhks.org.hk\ncftfc.com\ncgdepot.org\ncgst.edu\nch.shvoong.com\nchallenges.cloudflare.com\nchange.org\nchangeip.name\nchangeip.net\nchangeip.org\nchangp.com\nchangsa.ne\nchangsa.net\nchannel8news.sg\nchapm25.com\nchatnook.com\nchaturbate.com\nchengmingmag.com\nchenguangcheng.com\nchenpokong.com\nchenpokong.ne\nchenpokong.net\nchenshan20042005.wordpress.com\ncherrysave.com\nchhongbi.org\nchicagoncmtv.com\nchina-mmm.jp.net\nchina-mmm.net\nchina-mmm.sa.com\nchina-review.com.ua\nchina-week.com\nchina.hket.com\nchina.ucanews.com\nchina101.com\nchina18.org\nchina21.com\nchina21.org\nchina5000.us\nchinaaffairs.org\nchinaaid.me\nchinaaid.net\nchinaaid.org\nchinaaid.us\nchinachange.org\nchinachannel.hk\nchinacitynews.be\nchinacomments.org\nchinadialogue.net\nchinadigitaltimes.net\nchinaelections.org\nchinaeweekly.com\nchinafreepress.org\nchinagate.com\nchinageeks.org\nchinagfw.org\nchinagonet.com\nchinagreenparty.org\nchinahorizon.org\nchinahush.com\nchinainperspective.com\nchinainterimgov.org\nchinalaborwatch.org\nchinalawandpolicy.com\nchinalawtranslate.com\nchinamule.com\nchinamz.org\nchinapost.com.tw\nchinapress.com.my\nchinarightsia.org\nchinasmile.net\nchinasocialdemocraticparty.com\nchinasoul.org\nchinasucks.net\nchinatimes.com\nchinatopsex.com\nchinatown.com.au\nchinatweeps.com\nchinaway.org\nchinaworker.info\nchinaxchina.com\nchinayouth.org.hk\nchinayuanmin.org\nchinese-hermit.net\nchinese-leaders.org\nchinese-memorial.org\nchinese.engadget.com\nchinese.irib.ir\nchinese.soifind.com\nchinesedaily.com\nchinesedailynews.com\nchinesedemocracy.com\nchinesegay.org\nchinesen.de\nchinesepen.org\nchinesetalks.net\nchingcheong.com\nchinman.ne\nchinman.net\nchithu.org\nchn.chosun.com\nchrdnet.com\nchristianfreedom.org\nchristianstudy.com\nchristiantimes.org.hk\nchristusrex.org\nchrlawyers.hk\nchrome.com\nchromecast.com\nchromeexperiments.com\nchromercise.com\nchromestatus.com\nchromium.org\nchuang-yen.org\nchubold.com\nchubun.com\nchuizi.net\nchurchinhongkong.org\nchushigangdrug.ch\ncienen.com\ncij.org\ncineastentreff.de\ncipfg.org\ncirclethebayfortibet.org\ncitizencn.com\ncitizenlab.org\ncitizenscommission.hk\ncitizensradio.org\ncity365.ca\ncity9x.com\ncitypopulation.de\ncitytalk.tw\ncivicparty.hk\ncivildisobediencemovement.org\ncivilhrfront.org\nciviliangunner.com\ncivilmedia.tw\nck101.com\ncl.d0z.net\nclarionproject.org\nclassicalguitarblog.net\nclb.org.hk\ncldr.unicode.org\ncleansite.biz\ncleansite.info\ncleansite.us\nclearharmony.net\nclearwisdom.net\nclementine-player.org\ncling.omy.sg\nclinica-tibet.ru\nclipfish.de\ncloakpoint.com\ncloud.mail.ru\nclub1069.com\ncmi.org.tw\ncmoinc.org\ncmp.hku.hk\ncms.gov\ncmule.com\ncmule.org\ncn-proxy.com\ncn.calameo.com\ncn.dayabook.com\ncn.fmnnow.com\ncn.freeones.com\ncn.giganews.com\ncn.ibtimes.com\ncn.nytstyle.com\ncn.sandscotaicentral.com\ncn.shafaqna.com\ncn.streetvoice.com\ncn.uncyclopedia.wikia.com\ncn.voa.mobi\ncn2.streetvoice.com\ncn6.eu\ncna.com.tw\ncnabc.com\ncnbbnews.wordpress.com\ncnd.org\ncnex.org.cn\ncnineu.com\ncnn.com\ncnnews.chosun.com\ncnpolitics.org\ncnproxy.com\nco.ng.mil\ncoat.co.jp\ncochina.co\ncochina.org\ncode1984.com\ncodeshare.io\ncodeskulptor.org\ncollateralmurder.com\ncollateralmurder.org\ncom.google\ncomefromchina.com\ncomic-mega.me\ncommandarms.com\ncommentshk.com\ncommunistcrimes.org\ncommunitychoicecu.com\ncompileheart.com\ncompress.to\nconnect.facebook.net\nconoha.jp\ncontactmagazine.net\ncontentabc.com\ncontests.twilio.com\nconvio.net\ncoobay.com\ncool18.com\ncoolaler.com\ncoolder.com\ncoolloud.org.tw\ncoolncute.com\ncorumcollege.com\ncos-moe.com\ncosmic.monar.c\ncosplayjav.pl\ncotweet.com\ncoursehero.com\ncpj.org\ncq99.u\ncq99.us\ncrackle.com\ncrazys.cc\ncrchina.org\ncrd-net.org\ncreaders.net\ncreadersnet.com\ncreativelab5.com\ncristyli.com\ncrocotube.com\ncrossfire.co.kr\ncrossthewall.net\ncrossvpn.net\ncrrev.com\ncrucial.com\ncsdparty.com\ncss.pixnet.in\ncsuchen.de\ncsw.org.uk\nct.org.tw\nctao.org\nctfriend.net\ncthlo.github.io\nctitv.com.tw\ncts.com.tw\ncuhkacs.org\ncuihua.org\ncuiweiping.net\nculture.tw\ncumlouder.com\ncurvefish.com\ncusu.hk\ncw.com.tw\ncyberghost.natado.com\ncyberghostvpn.com\ncynscribe.com\ncytode.us\nd-fukyu.com\nd100.net\nd1b183sg0nvnuh.cloudfront.ne\nd1b183sg0nvnuh.cloudfront.net\nd1c37gjwa26taa.cloudfront.ne\nd1c37gjwa26taa.cloudfront.net\nd2bay.com\nd2pass.com\nd3c33hcgiwev3.cloudfront.ne\nd3c33hcgiwev3.cloudfront.net\nd3rhr7kgmtrq1v.cloudfront.net\ndabr.co.uk\ndabr.eu\ndabr.me\ndabr.mobi\ndadazim.com\ndadi360.com\ndafagood.com\ndafahao.com\ndafoh.org\ndagelijksestandaard.nl\ndaidostup.ru\ndailidaili.com\ndailymotion.com\ndailynews.sina.com\ndaiphapinfo.net\ndajiyuan.com\ndajiyuan.de\ndajiyuan.eu\ndajusha.baywords.com\ndalailama-archives.org\ndalailama.com\ndalailama.mn\ndalailama.ru\ndalailama.usc.edu\ndalailama80.org\ndalailamacenter.org\ndalailamafellows.org\ndalailamafilm.com\ndalailamafoundation.org\ndalailamahindi.com\ndalailamainaustralia.org\ndalailamajapanese.com\ndalailamaprotesters.info\ndalailamaquotes.org\ndalailamatrust.org\ndalailamavisit.org.nz\ndalailamaworld.com\ndalianmeng.org\ndaliulian.org\ndanke4china.net\ndanwei.org\ndaodu14.jigsy.com\ndaolan.net\ndaozhongxing.org\ndarktech.org\ndarktoy.net\ndarpa.mil\ndastrassi.org\ndata-vocabulary.org\ndata.flurry.com\ndata.gov.tw\ndavid-kilgour.com\ndawangidc.com\ndaxa.cn\ndaylife.com\ndb.tt\ndbc.hk\ndcard.tw\ndcmilitary.com\nddc.com.tw\nddhw.info\nddns.info\nddns.me.uk\nddns.mobi\nddns.ms\nddns.name\nddns.net\nddns.us\nde-sci.org\ndeaftone.com\ndebug.com\ndeck.ly\ndecodet.co\ndeepmind.com\ndeezer.com\ndefinebabe.com\ndeja.com\ndelcamp.net\ndelicious.com\ndemo.opera-mini.net\ndemocrats.org\ndenis.stalker.upeer.me\nderekhsu.homeip.net\ndesc.se\ndesign.google\ndesipro.de\ndessci.com\ndestiny.xfiles.to\ndestroy-china.jp\ndeutsche-welle.de\ndevelopers.box.net\ndevio.us\ndevpn.com\ndfas.mil\ndfn.org\ndharamsalanet.com\ndharmakara.net\ndhcp.biz\ndiaoyuislands.org\ndigiland.tw\ndigisfera.com\ndigitalnomadsproject.org\ndiigo.com\ndilber.se\ndingchin.com.tw\ndipity.com\ndirectcreative.com\ndiscuss.com.hk\ndiscuss4u.com\ndish.com\ndisp.cc\ndisqus.com\ndit-inc.us\ndizhidizhi.com\ndizhuzhishang.com\ndjangosnippets.org\ndjorz.com\ndl-laby.jp\ndl.box.net\ndlsite.com\ndlyoutube.com\ndm530.net\ndmcdn.net\ndmm.co.jp\ndmm.com\ndns-dns.com\ndns-stuff.com\ndns04.com\ndns05.com\ndns1.us\ndns2.us\ndns2go.com\ndnscrypt.org\ndnset.com\ndnsrd.com\ndnssec.net\ndnvod.tv\ndoctorvoice.org\ndogfartnetwork.com\ndojin.com\ndok-forum.net\ndolc.de\ndolf.org.hk\ndollf.com\ndomain.club.tw\ndomainhelp.search.com\ndomains.google\ndomaintoday.com.au\ndongtaiwang.com\ndongtaiwang.net\ndongyangjing.com\ndontfilter.us\ndontmovetochina.com\ndorjeshugden.com\ndotplane.com\ndotsub.com\ndotvpn.com\ndoub.io\ndougscripts.com\ndouhokanko.net\ndoujincafe.com\ndowei.org\ndownload.aircrack-ng.org\ndownload.cnet.com\ndownload.ithome.com.tw\ndphk.org\ndpp.org.tw\ndpr.info\ndragonsprings.org\ndreamamateurs.com\ndrepung.org\ndrgan.net\ndrmingxia.org\ndropbooks.tv\ndropbox.com\ndropboxusercontent.com\ndrsunacademy.com\ndrtuber.com\ndscn.info\ndsmtp.com\ndstk.dk\ndtdns.net\ndtiblog.com\ndtic.mil\ndtwang.org\nduanzhihu.com\nduck.com\nduckdns.org\nduckduckgo-owned-server.yahoo.net\nduckduckgo.com\nduckload.com\nduckmylife.com\nduga.j\nduga.jp\nduihua.org\nduihuahrjournal.org\ndumb1.com\ndunyabulteni.net\nduoweitimes.com\nduping.net\nduplicati.com\ndupola.com\ndupola.net\ndushi.ca\ndutchtracking.com\ndvorak.org\ndw-world.com\ndw-world.de\ndw.com\ndw.de\ndwheeler.com\ndwnews.com\ndwnews.net\ndynamic-dns.net\ndynamicdns.biz\ndynamicdns.co.uk\ndynamicdns.me.uk\ndynamicdns.org.uk\ndynawebinc.com\ndyndns-ip.com\ndyndns-pics.com\ndyndns.org\ndyndns.pro\ndynssl.com\ndynu.com\ndynu.net\ndynupdate.no-ip.com\ndzog.com\ndzze.com\ne-classical.com.tw\ne-gold.com\ne-hentaidb.com\ne-info.org.tw\ne-traderland.net\ne-zone.com.hk\ne123.hk\nearch.disconnect.me\nearlher.org\nearlytibet.com\nearthcam.com\nearthvpn.com\neastern-ark.com\neasternlightning.org\neastturkestan.com\neastturkistan-gov.org\neastturkistan.ne\neastturkistancc.org\neastturkistangovernmentinexile.us\neasyca.ca\neasypic.com\nebony-beauty.com\nebook.hyread.com.tw\nebookbrowse.com\nebookee.com\nec.su\necfa.org.tw\nech2.in.com\nechofon.com\necimg.tw\necministry.net\neconomist.com\necsm.vs.com\necure.hustler.com\nedalailamamovie.com\nedgecastcdn.net\nedicypages.com\nedmontonchina.cn\nedmontonservice.com\nedns.biz\nedoors.com\nedubridge.com\nedupro.org\neeas.europa.eu\neesti.ee\neevpn.com\nefcc.org.hk\neffers.com\nefksoft.com\nefukt.com\negioitinhoc.vn\negre-art.com\neic-av.com\neireinikotaerukai.com\neisbb.com\neksisozluk.com\nelectionsmeter.com\nelgoog.im\nelpais.com\neltondisney.com\nemaga.com\nemanna.com\nembr.in\nemilylau.org.hk\nempfil.com\nemule-ed2k.com\nemulefans.com\nemulihan.or.id\nemuparadise.me\nen.favotter.net\nen.hao123.com\nenanyang.my\nenewstree.com\nenfal.de\nengagedaily.org\nenglishforeveryone.org\nenglishfromengland.co.uk\nenglishpen.org\nenlighten.org.tw\nentermap.com\nentnt.com\nenvironment.google\nepa.gov.tw\nepac.to\nepiscopalchurch.org\nepochhk.com\nepochtimes-bg.com\nepochtimes-romania.com\nepochtimes.co.il\nepochtimes.co.kr\nepochtimes.com\nepochtimes.cz\nepochtimes.de\nepochtimes.fr\nepochtimes.ie\nepochtimes.it\nepochtimes.jp\nepochtimes.ru\nepochtimes.se\nepochtimestr.com\nepochweek.com\nepochweekly.com\neporner.com\nequinenow.com\nerabaru.net\neracom.com.tw\neraysoft.com.tr\nerepublik.com\nerights.net\neriversoft.com\nerktv.com\nernestmandel.org\nerodaizensyu.com\nerodoujinlog.com\nerodoujinworld.com\neromanga-kingdom.com\neromangadouzin.com\neromon.ne\neromon.net\neroprofile.com\neroticsaloon.net\neslite.com\nesmtp.biz\netaa.org.au\netadult.com\netaiwannews.com\netizer.org\netokki.com\netools.ncol.com\netowns.net\netowns.org\nettoday.net\netvonline.hk\neu.org\neucasino.com\neulam.com\neurekavpt.com\nevchk.wikia.com\nevschool.ne\nevschool.net\nexblog.jp\nexchristian.hk\nexmormon.org\nexpatshield.com\nexpecthim.com\nexpekt.com\nexperts-univers.com\nexploader.net\nexpressvpn.com\nextmatrix.com\nextremetube.com\neyevio.jp\neyny.com\nezpc.tk\nezpeer.com\nezua.com\nfa.gov.tw\nfacebook.br\nfacebook.com\nfacebook.design\nfacebook.hu\nfacebook.in\nfacebook.nl\nfacebook.se\nfacebookquotes4u.com\nfaceless.me\nfacesofnyfw.com\nfacesoftibetanselfimmolators.info\nfail.hk\nfaith100.org\nfaithfuleye.com\nfaiththedog.info\nfakku.net\nfalsefire.com\nfalun-co.org\nfalun-ny.net\nfalun.caltech.edu\nfalunart.org\nfalunasia.info\nfalunau.org\nfalunaz.net\nfalundafa-dc.org\nfalundafa-florida.org\nfalundafa-nc.org\nfalundafa-pa.net\nfalundafa-sacramento.org\nfalundafa.org\nfalundafaindia.org\nfalundafamuseum.org\nfalungong.club\nfalungong.de\nfalungong.org.uk\nfalunhr.org\nfaluninfo.de\nfaluninfo.net\nfalunpilipinas.net\nfalunworld.net\nfamilyfed.org\nfamunion.com\nfan-qiang.com\nfangbinxing.com\nfangeming.com\nfanglizhi.info\nfangmincn.org\nfangong.forums-free.com\nfangong.org\nfangongheike.com\nfanhaodang.com\nfanqiang.tk\nfanqianghou.com\nfanqiangyakexi.net\nfanqiangzhe.com\nfanswong.com\nfanyue.info\nfapdu.com\nfaproxy.com\nfaqserv.com\nfartit.com\nfarwestchina.com\nfast.wistia.com\nfastpic.ru\nfastssh.com\nfaststone.org\nfavstar.fm\nfawanghuihui.org\nfaydao.com\nfb.com\nfb.me\nfbcdn.net\nfbsbx.com\nfc2.com\nfc2blog.net\nfc2china.com\nfc2cn.com\nfda.gov.tw\nfdc64.de\nfdc64.org\nfdc89.jp\nfeedburner.com\nfeeds.fileforum.com\nfeelssh.com\nfeer.com\nfeifeiss.com\nfeitian-california.org\nfeitianacademy.org\nfeministteacher.com\nfengzhenghu.com\nfengzhenghu.net\nfevernet.com\nff.im\nfffff.at\nfflick.com\nffvpn.com\nfgmtv.net\nfgmtv.org\nfhreports.ne\nfhreports.net\nfigprayer.com\nfileflyer.com\nfiles2me.com\nfileserve.com\nfilesor.com\nfillthesquare.org\nfilmingfortibet.org\nfilmy.olabloga.pl\nfilthdump.com\nfinancetwitter.com\nfinchvpn.com\nfindmespot.com\nfindyoutube.com\nfingerdaily.com\nfinler.net\nfirearmsworld.ne\nfirearmsworld.net\nfirebaseio.com\nfireofliberty.org\nfiretweet.io\nfirstfivefollowers.com\nflagsonline.it\nflecheinthepeche.fr\nfleshbot.com\nfleursdeslettres.com\nflgg.us\nflgjustice.org\nflickr.com\nflickrhivemind.net\nflickriver.com\nfling.com\nflipboard.com\nflipkart.com\nflitto.com\nflnet.org\nflog.tw\nfochk.org\nfocustaiwan.tw\nfocusvpn.com\nfofg-europe.net\nfofg.org\nfofldfradio.org\nfooooo.com\nfootwiball.com\nforum.baby-kingdom.com\nforum.cyberctm.com\nforum.idsam.com\nforum.my903.com\nforum.mymaji.com\nforum.omy.sg\nforum.palmislife.com\nforum.setty.com.tw\nforum.sina.com.hk\nforum.slime.com.tw\nforum.tvb.com\nforum.xinbao.de\nforum4hk.com\nfotile.me\nfourface.nodesnoop.com\nfourthinternational.org\nfoxdie.us\nfoxgay.com\nfoxsub.com\nfoxtang.com\nfpmt-osel.org\nfpmt.org\nfpmt.tw\nfpmtmexico.org\nfq.wikia.com\nfqok.org\nfqrouter.com\nfranklc.com\nfreakshare.com\nfree-gate.org\nfree-hada-now.org\nfree-proxy.cz\nfree-ssh.com\nfree.fr\nfree4u.com.ar\nfreealim.com\nfreebrowser.org\nfreechal.com\nfreechina.net\nfreeddns.com\nfreeddns.org\nfreedomchina.info\nfreedomcollection.org\nfreedomhouse.org\nfreedominfonetweb.wordpress.com\nfreedomsherald.org\nfreeforums.org\nfreefq.com\nfreefuckvids.com\nfreegao.com\nfreeilhamtohti.org\nfreekwonpyong.org\nfreelotto.com\nfreeman2.com\nfreemoren.com\nfreemorenews.com\nfreemuse.org\nfreenet-china.org\nfreenetproject.org\nfreenewscn.com\nfreeopenvpn.com\nfreeoz.org\nfreessh.us\nfreetcp.com\nfreetibet.net\nfreetibet.org\nfreetibetanheroes.org\nfreeviewmovies.com\nfreevpn.me\nfreevpn.nl\nfreewallpaper4.me\nfreewebs.com\nfreewechat.com\nfreeweibo.com\nfreewww.biz\nfreewww.info\nfreexinwen.com\nfreeyellow.com\nfreeyoutubeproxy.net\nfriendfeed-media.com\nfriendfeed.com\nfriends-of-tibet.org\nfriendsoftibet.org\nfring.com\nfringenetwork.com\nfrom-pr.com\nfrom-sd.com\nfromchinatousa.net\nfrommel.net\nfrontlinedefenders.org\nfrootvpn.com\nfscked.org\nfsurf.com\nftchinese.com\nftp1.biz\nftpserver.biz\nftv.com.tw\nfucd.com\nfuckcnnic.net\nfuckgfw.org\nfullerconsideration.com\nfulue.com\nfunf.tw\nfunkyimg.com\nfunp.com\nfuq.com\nfurbo.org\nfurhhdl.org\nfurinkan.com\nfurl.net\nfuturechinaforum.org\nfuturemessage.org\nfux.com\nfuyin.net\nfuyindiantai.org\nfuyu.org.tw\nfw.cm\nfxcm-chinese.com\nfxnetworks.com\nfzh999.com\nfzh999.net\nfzlm.com\ng-area.org\ng-queen.com\ng.co\ng.e-hentai.org\ng6hentai.com\ngabocorp.com\ngaeproxy.com\ngaforum.org\ngalaxymacau.com\ngalenwu.com\ngalstars.net\ngame735.com\ngamebase.com.tw\ngamejolt.com\ngamer.com.tw\ngamez.com.tw\ngamousa.com\nganges.com\ngaoming.net\ngaopi.ne\ngaopi.net\ngaozhisheng.net\ngaozhisheng.org\ngardennetworks.com\ngardennetworks.org\ngartlive.com\ngate-project.com\ngather.com\ngatherproxy.com\ngati.org.tw\ngaybubble.com\ngaycn.net\ngayhub.com\ngaymap.cc\ngaytube.com\ngaywatch.com\ngazotube.com\ngcc.org.hk\ngclooney.com\ngcpnews.com\ngcr.io\ngdbt.net\ngdzf.org\ngeek-art.net\ngeekerhome.com\ngeekheart.info\ngekikame.com\ngelbooru.com\ngeocities.co.jp\ngeocities.com\ngeocities.jp\ngerefoundation.org\nget.how\ngetastrill.com\ngetchu.com\ngetcloak.com\ngetfoxyproxy.org\ngetfreedur.com\ngetgom.com\ngeti2p.net\ngetiton.com\ngetjetso.com\ngetlantern.org\ngetmdl.io\ngetsocialscope.com\ngetsync.com\ngettrials.com\ngettyimages.com\ngetuploader.com\ngfbv.de\ngfgold.com.hk\ngfsale.com\ngfw.org.ua\ngfw.press\nggpht.com\nggssl.com\nghost.org\nghostpath.com\nghut.org\ngiantessnight.com\ngifree.com\ngiga-web.jp\ngigporno.ru\ngirlbanker.com\ngist.github.com\ngit.io\ngithub.com\ngithub.io\ngithubusercontent.com\ngithubassets.com\ngithubapp.com\ngithub.community\nghcr.io\ngizlen.net\ngjczz.com\nglass8.eu\nglobal.bing.com\nglobal.co\nglobaljihad.net\nglobalmediaoutreach.com\nglobalmuseumoncommunism.org\nglobalrescue.net\nglobaltm.org\nglobalvoicesonline.org\nglobalvpn.net\nglock.com\ngloryhole.com\nglorystar.me\ngluckman.com\nglype.com\ngmail.com\ngmbd.cn\ngmhz.org\ngmiddle.com\ngmiddle.ne\ngmll.org\ngmodules.com\ngmozomg.izihost.org\ngnci.org.hk\ngo-pki.com\ngo.nesnode.com\ngo141.com\ngoagent.biz\ngoagent.codeplex.com\ngoagentplus.com\ngobet.cc\ngodfootsteps.org\ngodns.work\ngodoc.org\ngodsdirectcontact.co.uk\ngodsdirectcontact.org\ngodsdirectcontact.org.tw\ngodsimmediatecontact.com\ngogotunnel.com\ngohappy.com.tw\ngojet.krtco.com.tw\ngokbayrak.com\ngolang.org\ngoldbet.com\ngoldbetsports.com\ngoldeneyevault.com\ngoldenfrog.com\ngoldjizz.com\ngoldstep.net\ngoldwave.com\ngongm.in\ngongmeng.info\ngongminliliang.com\ngongwt.com\ngoo.gl\ngooday.xyz\ngooddns.info\ngoodreaders.com\ngoodreads.com\ngoodtv.com.tw\ngoodtv.tv\ngoofind.com\ngoogle.ae\ngoogle.am\ngoogle.as\ngoogle.at\ngoogle.az\ngoogle.ba\ngoogle.be\ngoogle.bg\ngoogle.ca\ngoogle.calstate.edu\ngoogle.cd\ngoogle.ci\ngoogle.cn\ngoogle.co.id\ngoogle.co.jp\ngoogle.co.kr\ngoogle.co.ma\ngoogle.co.uk\ngoogle.com\ngoogle.com.hk\ngoogle.de\ngoogle.dj\ngoogle.dk\ngoogle.es\ngoogle.fi\ngoogle.fm\ngoogle.fr\ngoogle.gg\ngoogle.gl\ngoogle.gr\ngoogle.ie\ngoogle.is\ngoogle.it\ngoogle.jo\ngoogle.kz\ngoogle.lv\ngoogle.mn\ngoogle.ms\ngoogle.nl\ngoogle.no\ngoogle.nu\ngoogle.ro\ngoogle.ru\ngoogle.rw\ngoogle.sc\ngoogle.sh\ngoogle.sk\ngoogle.sm\ngoogle.sn\ngoogle.tk\ngoogle.tm\ngoogle.to\ngoogle.tt\ngoogle.vu\ngoogle.ws\ngoogleads.g.doubleclick.net\ngoogleapis.cn\ngoogleapis.com\ngoogleapps.com\ngooglearth.com\ngoogleartproject.com\ngoogleblog.com\ngooglebot.com\ngooglechinawebmaster.com\ngooglecode.com\ngooglecommerce.com\ngoogledomains.com\ngoogledrive.com\ngoogleearth.com\ngooglegroups.com\ngooglehosted.com\ngoogleideas.com\ngoogleinsidesearch.com\ngooglelabs.com\ngooglemail.com\ngooglemashups.com\ngooglepagecreator.com\ngoogleplay.com\ngoogleplus.com\ngooglescholar.com\ngooglesile.com\ngooglesource.com\ngooglesyndication.com\ngoogletagservices.com\ngoogleusercontent.com\ngooglevideo.com\ngoogleweblight.com\ngooglezip.net\ngopetition.com\ngoproxing.net\ngospelherald.com\ngot-game.org\ngotdns.ch\ngotgeeks.com\ngotrusted.com\ngotw.ca\ngov.taipei\ngov.tw\ngr8domain.biz\ngr8name.biz\ngrammaly.com\ngrandtrial.org\ngrangorz.org\ngraphis.ne.jp\ngraphql.org\ngreasespot.net\ngreat-firewall.com\ngreat-roc.org\ngreatfire.org\ngreatfire.us7.list-manage.com\ngreatfirewall.biz\ngreatfirewallofchina.net\ngreatfirewallofchina.org\ngreatroc.org\ngreatroc.tw\ngreatzhonghua.org\ngreenfieldbookstore.com.hk\ngreenparty.org.tw\ngreenpeace.com.tw\ngreenpeace.org\ngreenreadings.com\ngreenvpn.net\ngreenvpn.org\ngroups.google.cn\ngs-discuss.com\ngstatic.com\ngtricks.com\ngts-vpn.com\ngu-chu-sum.org\nguaguass.com\nguaguass.org\nguancha.org\nguangming.com.my\nguardster.com\nguishan.org\ngumroad.com\ngun-world.net\ngunsamerica.com\ngunsandammo.com\nguruonline.hk\ngutteruncensored.com\ngvlib.com\ngvm.com.tw\ngvt0.com\ngvt1.com\ngvt3.com\ngwtproject.org\ngyalwarinpoche.com\ngyatsostudio.com\ngzm.tv\ngzone-anime.info\nh-china.org\nh-moe.com\nh1n1china.org\nh528.com\nh5dm.com\nh5galgame.me\nhacg.club\nhacg.in\nhacg.li\nhacg.me\nhacg.red\nhacken.cc\nhacker.org\nhackthatphone.net\nhahlo.com\nhakkatv.org.tw\nhandcraftedsoftware.org\nhanunyi.com\nhao.news\nhao123.com\nhaoel.github.io\nhappy-vpn.com\nhaproxy.org\nhardsextube.com\nharunyahya.com\nhautelook.com\nhautelookcdn.com\nhave8.com\nhclips.com\nhd.stheadline.com\nhdlt.me\nhdtvb.net\nhdzog.com\nheartyit.com\nhec.su\nhecaitou.net\nhechaji.com\nheeact.edu.tw\nhegre-art.com\nheix.pp.ru\nhelloandroid.com\nhelloqueer.com\nhelloss.pw\nhellotxt.com\nhellouk.org\nhelp.linksalpha.com\nhelpeachpeople.com\nhelplinfen.com\nhelpster.de\nhelpzhuling.org\nhentai.to\nhentaitube.tv\nhentaivideoworld.com\nheqinglian.net\nheungkongdiscuss.com\nhexieshe.com\nhexxeh.net\nheyzo.com\nhgseav.com\nhhdcb3office.org\nhhthesakyatrizin.org\nhi-on.org.tw\nhidden-advent.org\nhide.me\nhidecloud.com\nhidein.net\nhideipvpn.com\nhideman.net\nhideme.nl\nhidemy.name\nhidemyass.com\nhidemycomp.com\nhigfw.com\nhighpeakspureearth.com\nhighrockmedia.com\nhihiforum.com\nhihistory.net\nhiitch.com\nhikinggfw.org\nhilive.tv\nhimalayan-foundation.org\nhimalayanglacier.com\nhimemix.com\nhimemix.net\nhitomi.la\nhiwifi.com\nhizb-ut-tahrir.info\nhizb-ut-tahrir.org\nhizbuttahrir.org\nhjclub.info\nhk-pub.com\nhk.frienddy.com\nhk.geocities.com\nhk.jiepang.com\nhk.knowledge.yahoo.com\nhk.myblog.yahoo.com\nhk.news.yahoo.com\nhk.rd.yahoo.com\nhk.search.yahoo.com\nhk.video.news.yahoo.com\nhk.yahoo.com\nhk01.com\nhk32168.com\nhka8964.wordpress.com\nhkacg.com\nhkacg.net\nhkanews.wordpress.com\nhkatvnews.com\nhkbc.net\nhkbf.org\nhkbookcity.com\nhkchurch.org\nhkci.org.hk\nhkcmi.edu\nhkcnews.com\nhkcoc.com\nhkdailynews.com.hk\nhkday.net\nhkdf.org\nhkej.com\nhkepc.com\nhkfaa.com\nhkfreezone.com\nhkfront.org\nhkgolden.com\nhkgreenradio.org\nhkheadline.com\nhkhkhk.com\nhkhrc.org.hk\nhkhrm.org.hk\nhkip.org.uk\nhkjc.com\nhkjp.org\nhklft.com\nhklts.org.hk\nhkptu.org\nhkreporter.com\nhkreporter.loved.hk\nhkupop.hku.hk\nhkusu.net\nhkvwet.com\nhkwcc.org.hk\nhkzone.org\nhmonghot.com\nhmvdigital.ca\nhmvdigital.com\nhnjhj.com\nhnntube.com\nhola.com\nhola.org\nholymountaincn.com\nholyspiritspeaks.org\nhome.sina.com\nhome.so-net.net.tw\nhomedepot.com\nhomeperversion.com\nhongkongfp.com\nhongmeimei.com\nhongzhi.li\nhootsuite.com\nhoovers.com\nhopedialogue.org\nhopto.org\nhornygamer.com\nhornytrip.com\nhotav.tv\nhotels.cn\nhotfrog.com.tw\nhotgoo.com\nhotpornshow.com\nhotpot.hk\nhotshame.com\nhotspotshield.com\nhotvpn.com\nhougaige.com\nhowtoforge.com\nhpa.gov.tw\nhqcdp.org\nhqjapanesesex.com\nhqmovies.com\nhqsbonline.wordpress.com\nhrcchina.org\nhrcir.com\nhrea.org\nhrichina.org\nhrw.org\nhrweb.org\nhsjp.net\nhsselite.com\nhstern.net\nhstt.net\nhtkou.net\nhtml5rocks.com\nhtmldog.com\nhttps443.net\nhttps443.org\nhua-yue.net\nhuaglad.com\nhuanghuagang.org\nhuangyiyu.com\nhuaren.us\nhuashangnews.com\nhuaxia-news.com\nhuaxiabao.org\nhuaxin.ph\nhuayuworld.org\nhudatoriq.web.id\nhuffingtonpost.com\nhugoroy.eu\nhuhaitai.com\nhuhamhire.com\nhuiyi.in\nhulkshare.com\nhulu.com\nhuluim.com\nhumanrightsbriefing.org\nhung-ya.com\nhungerstrikeforaids.org\nhuping.net\nhurgokbayrak.com\nhurriyet.com.tr\nhustlercash.com\nhut2.ru\nhutianyi.net\nhutong9.net\nhuyandex.com\nhwadzan.tw\nhwayue.org.tw\nhwinfo.com\nhxwk.org\nhxwq.org\nhybrid-analysis.com\nhyperrate.com\ni-cable.com\ni-part.com.tw\ni-scmp.com\ni.lithium.com\ni1.hk\ni2p2.de\ni2runner.com\ni818hk.com\niam.soy\niamtopone.com\niask.bz\niask.ca\niav19.com\nibet.a.se\nibet3rdpole.org\nibetanbuddhistinstitute.org\nibetancommunityuk.ne\nibetansports.org\nibetanwomen.org\nibetexpress.ne\nibetmuseum.org\nibetoffice.c\nibetoffice.com.au\nibetoralhistory.org\nibetsupportgroup.org\nibiblio.org\niblist.com\niblogserv-f.net\nibros.org\nibvpn.com\nicams.com\nice.audionow.com\nicij.org\nicl-fi.org\nicoco.com\niconpaper.org\nictures.playboy.com\nicu-project.org\nid.hao123.com\nid.heroku.com\niddddg.com\nidemocracy.asia\nidenti.ca\nidiomconnection.com\nidlcoyote.com\nidouga.com\nidreamx.com\nidv.tw\nieasy5.com\nied2k.net\nienergy1.com\nifan.cz.cc\nifanqiang.com\nifcss.org\nifjc.org\nifreewares.com\nift.tt\nigcd.net\nigfw.net\nigfw.tech\nigmg.de\nignitedetroit.net\nigoogle.com\nigotmail.com.tw\nigvita.com\nihakka.net\nihao.org\niicns.com\nikstar.com\nikwb.com\nillusionfactory.com\nilove80.be\nilovelongtoes.com\nim.tv\nim88.tw\nimageab.com\nimagefap.com\nimageflea.com\nimages-gaytube.com\nimages.comico.tw\nimageshack.us\nimagevenue.com\nimagezilla.net\nimb.org\nimdb.com\nimdir.com\nime.com\nimg.dlsite.j\nimg.ly\nimgchili.ne\nimgchili.net\nimgmega.com\nimgur.com\nimkev.com\nimlive.com\nimmigration.gov.tw\nimmoral.jp\nimpact.org.au\nimpp.mn\nin-disguise.com\nin99.org\nincapdns.net\nincloak.com\nincredibox.fr\nindiandefensenews.in\nindiemerch.com\ninfo-graf.fr\ninitiativesforchina.org\ninkui.com\ninmediahk.net\ninnermongolia.org\ninote.tw\ninsecam.org\ninsidevoa.com\ninstagram.com\ninstanthq.com\ninstitut-tibetain.org\ninternet.org\ninternetdefenseleague.org\ninternetfreedom.org\ninternetpopculture.com\ninvestigating.wordpress.com\ninxian.com\niny.cc\niownyour.biz\niownyour.org\nipalter.com\nipfire.org\niphone4hongkong.com\niphonehacks.com\niphonetaiwan.org\niphonix.fr\nipicture.ru\nipjetable.net\nipml5.org\nipobar.com\nipoock.com\niportal.me\nippotv.com\nipredator.se\niptv.com.tw\niptvbin.com\nipvanish.com\niredmail.org\nironbigfools.compython.net\nironpython.net\nironsocket.com\nis-a-hunter.com\nis.gd\nisaacmao.com\nisasecret.com\nisav.com\nisgreat.org\nislahhaber.net\nislam.org.hk\nislamawareness.net\nislamhouse.com\nislamicity.com\nislamicpluralism.org\nislamtoday.net\nismaelan.com\nismalltits.com\nismprofessional.net\nisohunt.com\nisrabox.com\nissuu.com\nistars.co.nz\nistiqlalhewer.com\nistockphoto.com\nisunaffairs.com\nisuntv.com\nitaboo.info\nitaiwan.gov.tw\nitaliatibet.org\nitasoftware.com\nitemdb.com\nithelp.ithome.com.tw\nitomi.la\nits.caltech.edu\nitsaol.com\nitshidden.com\nitsky.it\nitweet.ne\nitweet.net\niu45.com\niuhrdf.org\niuksky.com\nivacy.com\niverycd.com\nivpn.net\nixquick.com\nixxx.com\niyouport.com\nizaobao.us\nizles.net\nizlesem.org\nj.mp\njamaat.org\njamyangnorbu.com\njandyx.com\njanwongphoto.com\njapan-whores.com\njapanfirst.asianfreeforum.com\njav101.com\njav2be.com\njav68.tv\njavakiba.org\njavbus.com\njavfor.me\njavhd.com\njavhip.com\njavhub.net\njavhuge.com\njavlibrary.com\njavmobile.ne\njavmobile.net\njavmoo.com\njavmoo.xyz\njavseen.com\njavtag.com\njavzoo.com\njbtalks.cc\njbtalks.com\njbtalks.my\njcpenney.com\njdwsy.com\njeanyim.com\njetos.com\njfqu36.club\njfqu37.xyz\njgoodies.com\njiangweiping.com\njiaoyou8.com\njiehua.cz\njieshibaobao.com\njigglegifs.com\njigong1024.com\njihadintel.meforum.org\njihadology.ne\njihadology.net\njiji.com\njims.net\njinbushe.org\njingpin.org\njingsim.org\njinpianwang.com\njinroukong.com\njitouch.com\njizzthis.com\njjgirls.com\njkb.cc\njkforum.net\njkub.com\njma.go.jp\njmscult.com\njoachims.org\njobnewera.wordpress.com\njobso.tv\njournalchretien.net\njournalofdemocracy.org\njoymiihub.com\njoyourself.com\njp.hao123.com\njpl.nasa.gov\njpopforum.net\njrt.org\njubushoushen.com\njuhuaren.com\njukujo-club.com\njuliepost.com\njuliereyc.com\njunauza.com\njune4commemoration.org\njunefourth-20.net\njungleheart.com\njuoaa.com\njustdied.com\njustfreevpn.com\njusticefortenzin.org\njustpaste.it\njusttristan.com\njuyuange.org\njuziyue.com\njwmusic.org\njyxf.net\nk-doujin.net\nk-pub.com\nk.gradconnection.com\nk.hao123img.com\nka-wai.com\nkagyu.org\nkagyu.org.za\nkagyumonlam.org\nkagyunews.com.hk\nkagyuoffice.org\nkagyuoffice.org.tw\nkaiyuan.de\nkakao.com\nkalachakralugano.org\nkankan.today\nkannewyork.com\nkanshifang.com\nkantie.org\nkanzhongguo.com\nkanzhongguo.eu\nkaotic.com\nkarayou.com\nkarkhung.com\nkarmapa-teachings.org\nkarmapa.org\nkawaiikawaii.jp\nkb.monitorware.com\nkba-tx.org\nkcoc.weather.com.hk\nkcoolonline.com\nkebrum.com\nkechara.com\nkeepandshare.com\nkeezmovies.com\nkendatire.com\nkendincos.net\nkenengba.com\nkeontech.net\nkepard.com\nkeycdn.com\nkhabdha.org\nkhatrimaza.org\nkhmusic.com.tw\nkichiku-doujinko.com\nkik.com\nkillwall.com\nkindleren.com\nkineox.free.fr\nkingdomsalvation.org\nkinghost.com\nkingstone.com.tw\nkink.com\nkinmen.org.tw\nkinmen.travel\nkir.jp\nkissbbao.cn\nkiwi.kz\nkk-whys.co.jp\nkkbox.com\nkknews.cc\nklip.me\nkmuh.org.tw\nknowledgerush.com\nkobo.com\nkobobooks.com\nkodingen.com\nkompozer.net\nkonachan.com\nkone.com\nkoolsolutions.com\nkoornk.com\nkoranmandarin.com\nkorenan2.com\nksdl.org\nksnews.com.tw\nktzhk.com\nkui.name\nkun.im\nkupop.hku.hk\nkurashsultan.com\nkurtmunger.com\nkusocity.com\nkwcg.ca\nkwongwah.com.my\nkxsw.life\nkyofun.com\nkyohk.net\nkyoyue.com\nkyzyhello.com\nkzeng.info\nl.gd\nl.li\nla-forum.org\nlabiennale.org\nladbrokes.com\nlagranepoca.com\nlalulalu.com\nlama.com.tw\nlamayeshe.com\nlamenhu.com\nlamnia.co.uk\nlamrim.com\nlanterncn.cn\nlantosfoundation.org\nlaod.cn\nlaogai.org\nlaomiu.com\nlaoyang.info\nlaptoplockdown.com\nlaqingdan.net\nlarsgeorge.com\nlastcombat.com\nlastfm.es\nlatelinenews.com\nlatibet.org\nld.hao123img.com\nle-vpn.com\nleafyvpn.net\nlecloud.net\nleeao.com.cn\nlefora.com\nleft21.hk\nlegalporno.com\nlegaltech.law.com\nlegsjapan.com\nleirentv.ca\nleisurecafe.ca\nleisurepro.com\nlematin.ch\nlemonde.fr\nlenwhite.com\nlerosua.org\nlers.google\nlesoir.be\nletou.com\nletscorp.net\nlflink.com\nlflinkup.com\nlflinkup.net\nlflinkup.org\nlhakar.org\nlhasocialwork.org\nliangyou.net\nlianyue.net\nliaowangxizang.net\nlib.virginia.edu\nliberal.org.hk\nlibertytimes.com.tw\nlibrary.usc.cuhk.edu.hk\nlidecheng.com\nlifemiles.com\nlighten.org.tw\nlightnovel.cn\nlike.com\nlimiao.net\nline-apps.com\nline-scdn.net\nline.me\nline.naver.jp\nlinglingfa.com\nlingvodics.com\nlink-o-rama.com\nlinkideo.com\nlinksalpha.com\nlinkuswell.com\nlinux.org.hk\nlinuxtoy.org\nlionsroar.com\nlipuman.com\nliquidvpn.com\nlistentoyoutube.com\nlistorious.com\nlists.w3.org\nliudejun.com\nliuhanyu.com\nliujianshu.com\nliuxiaobo.ne\nliuxiaobo.net\nliuxiaotong.com\nlivedoor.jp\nliveleak.com\nlivestation.com\nlivestream.com\nlivevideo.com\nlivingonline.us\nlivingstream.com\nliwangyang.com\nlizhizhuangbi.com\nlkcn.net\nllss.me\nload.to\nlobsangwangyal.com\nlocaldomain.ws\nlocalpresshk.com\nlockestek.com\nlofi.e-hentai.org\nlogbot.net\nlogiqx.com\nlondonchinese.ca\nlonghair.hk\nlongmusic.com\nlongtermly.net\nlongtoes.com\nlookpic.com\nlooktoronto.com\nlotsawahouse.org\nlotuslight.org.hk\nlotuslight.org.tw\nlovetvshow.com\nlpsg.com\nlrfz.com\nlrip.org\nlsd.org.hk\nlsforum.net\nlsm.org\nlsmchinese.org\nlsmkorean.org\nlsmradio.com\nlsmwebcast.com\nlsxszzg.com\nltn.com.tw\nluke54.com\nluke54.org\nlupm.org\nlushstories.com\nluxebc.com\nlvhai.org\nlvv2.com\nlyfhk.net\nlzmtnews.org\nm-sport.co.uk\nm-team.cc\nm.hkgalden.com\nm.me\nm.plixi.com\nm.slandr.net\nma.hao123.com\nmacgamestore.com\nmacrovpn.com\nmacts.com.tw\nmad-ar.ch\nmadewithcode.com\nmadonna-av.com\nmadthumbs.com\nmagazines.sina.com.tw\nmagic-net.info\nmahabodhi.org\nmaiio.net\nmail-archive.com\nmaildns.xyz\nmaiplus.com\nmaizhong.org\nmakemymood.com\nmakkahnewspaper.com\nmakzhou.warehouse333.com\nmalaysiakini.com\nmamingzhe.com\nmangafox.com\nmangafox.me\nmaniash.com\nmanicur4ik.ru\nmansion.com\nmansionpoker.com\nmanta.com\nmaplew.com\nmarc.info\nmarguerite.su\nmartau.com\nmartincartoons.com\nmartsangkagyuofficial.org\nmaruta.be\nmarxist.com\nmarxist.net\nmarxists.org\nmash.to\nmaskedip.com\nmatainja.com\nmatehunter.com\nmaterial.io\nmathable.io\nmathiew-badimon.com\nmatome-plus.com\nmatome-plus.net\nmatsushimakaede.com\nmattwilcox.net\nmaturejp.com\nmaxing.jp\nmayimayi.com\nmcadforums.com\nmcaf.ee\nmcfog.com\nmcreasite.com\nmd-t.org\nme.youthwant.com.tw\nmeansys.com\nmedia.nu.nl\nmedia.org.hk\nmediachinese.com\nmediafire.com\nmediafreakcity.com\nmedium.com\nmeetav.com\nmeetup.com\nmefeedia.com\nmefound.com\nmega.nz\nmegaproxy.com\nmegarotic.com\nmegavideo.com\nmegurineluka.com\nmeirixiaochao.com\nmelon-peach.com\nmeltoday.com\nmeme.yahoo.com\nmemehk.com\nmemorybbs.com\nmemri.org\nmemrijttm.org\nmercyprophet.org\nmeridian-trust.org\nmeripet.biz\nmeripet.com\nmerit-times.com.tw\nmeshrep.com\nmesotw.com\nmessenger.com\nmetacafe.com\nmetarthunter.com\nmeteorshowersonline.com\nmetro.taipei\nmetrohk.com.hk\nmetrolife.ca\nmetroradio.com.hk\nmeyou.jp\nmeyul.com\nmfxmedia.com\nmgoon.com\nmgstage.com\nmh4u.org\nmhradio.org\nmi.me\nmichaelanti.com\nmichaelmarketl.com\nmicrovpn.com\nmiddle-way.net\nmihk.hk\nmihr.com\nmihua.org\nmike.cz.cc\nmikesoltys.com\nmilph.ne\nmilph.net\nmilsurps.com\nmimiai.net\nmimivip.com\nmimivv.com\nmindrolling.org\nminghui-a.org\nminghui-b.org\nminghui-school.org\nminghui.or.kr\nminghui.org\nmingjinglishi.com\nmingjingnews.com\nmingjingtimes.com\nmingpao.com\nmingpaocanada.com\nmingpaomonthly.com\nmingpaonews.com\nmingpaony.com\nmingpaosf.com\nmingpaotor.com\nmingpaovan.com\nmingshengbao.com\nminhhue.net\nminiforum.org\nministrybooks.org\nminzhuhua.net\nminzhuzhanxian.com\nminzhuzhongguo.org\nmiroguide.com\nmirrorbooks.com\nmist.vip\nmitao.com.tw\nmitbbs.com\nmixero.com\nmixpod.com\nmixx.com\nmizzmona.com\nmjib.gov.tw\nmjlsh.usc.cuhk.edu.hk\nmk5000.com\nmlcool.com\nmmaaxx.com\nmmmca.com\nmnewstv.com\nmo.nightlife141.com\nmobatek.net\nmobile01.com\nmobileways.de\nmoby.to\nmobypicture.com\nmoeaic.gov.tw\nmoeerolibrary.com\nmofaxiehui.com\nmofos.com\nmog.com\nmol.gov.tw\nmolihua.org\nmondex.org\nmoney-link.com.tw\nmoneyhome.biz\nmonghot.com\nmonitorchina.org\nmonlamit.org\nmonster.com\nmoodyz.com\nmoonbbs.com\nmorningsun.org\nmoroneta.com\nmos.ru\nmotherless.com\nmotor4ik.ru\nmousebreaker.com\nmovements.org\nmoviefap.com\nmoztw.org\nmp3buscador.com\nmp3ye.eu\nmpettis.com\nmpfinance.com\nmpinews.com\nmponline.hk\nmpp.org\nmqxd.org\nmrbasic.com\nmrbonus.com\nmrface.com\nmrslove.com\nmrtweet.com\nmsguancha.com\nmsha.gov\nmswe1.org\nmthruf.com\nmtw.tl\nmuchosucko.com\nmullvad.net\nmultiply.com\nmultiproxy.org\nmultiupload.com\nmummysgold.com\nmurmur.tw\nmusicade.net\nmuslimvideo.com\nmuzi.com\nmuzi.net\nmuzu.tv\nmvdis.gov.tw\nmvg.jp\nmx.hao123.com\nmx981.com\nmy-formosa.com\nmy-private-network.co.uk\nmy-proxy.com\nmy.mail.ru\nmy.opera.com\nmy03.com\nmyactimes.com\nmyanniu.com\nmyaudiocast.com\nmyav.com.tw\nmybbs.us\nmybet.com\nmyca168.com\nmycanadanow.com\nmychinamyhome.com\nmychinanet.com\nmychinanews.com\nmychinese.news\nmycnnews.com\nmycould.com\nmydad.info\nmyddns.com\nmyeasytv.com\nmyeclipseide.com\nmyforum.com.hk\nmyforum.com.uk\nmyfreecams.com\nmyfreepaysite.com\nmyfreshnet.com\nmyftp.info\nmyftp.name\nmyiphide.com\nmykomica.org\nmylftv.com\nmymediarom.com\nmymoe.moe\nmymom.info\nmymusic.net.tw\nmynetav.net\nmynetav.org\nmynumber.org\nmyparagliding.com\nmypicture.info\nmypop3.net\nmypop3.org\nmypopescu.com\nmyradio.hk\nmysecondarydns.com\nmyshare.url.com.tw\nmysinablog.com\nmysite.verizon.net\nmyspace.com\nmyspacecdn.com\nmytalkbox.com\nmytizi.com\nmywww.biz\nmyz.info\nnaacoalition.org\nnaitik.net\nnakido.com\nnakuz.com\nnalandabodhi.org\nnalandawest.org\nnamgyal.org\nnamgyalmonastery.org\nnamsisi.com\nnanyang.com\nnanyangpost.com\nnanzao.com\nnaol.ca\nnaol.cc\nnat.gov.tw\nnat.moe\nnational-lottery.co.uk\nnationsonline.org\nnationwide.com\nnaughtyamerica.com\nnavyfamily.navy.mil\nnavyreserve.navy.mil\nnaweeklytimes.com\nnbc.com\nnbtvpn.com\nnccwatch.org.tw\nnch.com.tw\nncn.org\nnde.de\nndr.de\nned.org\nnekoslovakia.net\nnemesis2.qx.net\nneo-miracle.com\nnepusoku.com\nnet-fits.pro\nnet.tw\nnetbirds.com\nnetcolony.com\nnetflix.com\nnetme.cc\nnetsneak.com\nnetwork54.com\nnetworkedblogs.com\nnetworktunnel.net\nneverforget8964.org\nnew-3lunch.net\nnew-akiba.com\nnew96.ca\nnewcenturymc.com\nnewcenturynews.com\nnewchen.com\nnewgrounds.com\nnewipnow.com\nnewlandmagazine.com.au\nnewnews.ca\nnews.bbc.co.uk\nnews.cnyes.com\nnews.hk.msn.com\nnews.hkpeanut.com\nnews.msn.com.tw\nnews.nationalgeographic.com\nnews.now.com\nnews.omy.sg\nnews.seehua.com\nnews.sina.com.hk\nnews.sina.com.tw\nnews.sinchew.com.my\nnews.singtao.ca\nnews.tvb.com\nnews.tvbs.com.tw\nnews.yahoo.com\nnews100.com.tw\nnewsancai.com\nnewschinacomment.org\nnewscn.org\nnewsdetox.ca\nnewsdh.com\nnewsforums.bbc.co.uk\nnewspeak.cc\nnewstamago.com\nnewstapa.org\nnewstarnet.com\nnewtaiwan.com.tw\nnewtalk.tw\nnewyorktimes.com\nnexon.com\nnext11.co.jp\nnextmag.com.tw\nnextmedia.com\nnexton-net.jp\nnexttv.com.tw\nnf.id.au\nnfjtyd.com\nnflxext.com\nnflximg.com\nnflximg.net\nnflxso.net\nnflxvideo.net\nnga.mil\nngensis.com\nnhentai.ne\nnhentai.net\nnhi.gov.tw\nnhk-ondemand.jp\nnic.cz.cc\nnic.google\nnic.gov\nnicovideo.jp\nnighost.org\nnikkei.com\nninecommentaries.com\nninjacloak.com\nninjaproxy.ninja\nnintendium.com\nninth.biz\nniusnews.com\nnjactb.org\nnjuice.com\nnko.navy.mil\nnlfreevpn.com\nno-ip.org\nnobel.se\nnobelprize.org\nnobodycanstop.us\nnokogiri.org\nnokola.com\nnoodlevpn.com\nnorbulingka.org\nnordstrom.com\nnordstromimage.com\nnordstromrack.com\nnordvpn.com\nnottinghampost.com\nnovelasia.com\nnow.im\nnownews.com\nnowtorrents.com\nnoypf.com\nnp.org\nnpa.go.jp\nnpa.gov.tw\nnpnt.me\nnps.gov\nnr-data.net\nnradio.me\nnrk.no\nns01.biz\nns01.info\nns01.us\nns02.biz\nns02.info\nns02.us\nns1.name\nns2.name\nns3.name\nnsc.gov.tw\nntbk.gov.tw\nntbna.gov.tw\nntbt.gov.tw\nntd.tv\nntdtv.ca\nntdtv.co.kr\nntdtv.com\nntdtv.cz\nntdtv.org\nntdtv.ru\nntdtvla.com\nntrfun.com\nntsna.gov.tw\nnubiles.net\nnuexpo.com\nnukistream.com\nnurgo-software.com\nnusatrip.com\nnutaku.net\nnuuvem.com\nnuvid.com\nnuzcom.com\nnvdst.com\nnvquan.org\nnvtongzhisheng.org\nnwtca.org\nny.stgloballink.com\nny.visiontimes.com\nnyaa.eu\nnyaa.si\nnydus.ca\nnylon-angel.com\nnylonstockingsonline.com\nnyt.com\nnytchina.com\nnytcn.me\nnytco.com\nnyti.m\nnytimes.com\nnytimes.map.fastly.net\nnytimg.com\nnytstyle.com\nnzchinese.com\nnzchinese.net.nz\nobservechina.net\nobutu.com\nocaspro.com\noccupytiananmen.com\noclp.hk\nocreampies.com\nocrec.org\nocry.com\noctober-review.org\noculus.com\noculuscdn.com\noffbeatchina.com\nofficeoftibet.com\nofile.org\noftwaredownload.gitbooks.io\nogaoga.org\nogate.org\noikos.com.tw\noiktv.com\noizoblog.com\nok.ru\nokayfreedom.com\nokk.tw\nold-cat.net\nold.honeynet.org\nold.nabble.com\nolumpo.com\nolymerhk.com\nolympicwatch.org\nomeservershow.com\nomgili.com\nomni7.jp\nomnitalk.com\nomnitalk.org\non.cc\non2.com\nonapp.com\nonedrive.live.com\nonedumb.com\nonion.city\nonline.recoveryversion.org\nonlinecha.com\nonlineyoutube.com\nonmoon.com\nonmoon.net\nonmypc.biz\nonmypc.info\nonmypc.net\nonmypc.org\nonmypc.us\nonthehunt.com\nontrac.com\noopsforum.com\nopedialogue.org\nopen.com.hk\nopen.demonii.si\nopenallweb.com\nopenai.com\nopendemocracy.net\nopendn.xyz\nopenervpn.in\nopenid.net\nopenleaks.org\nopentracker.xyz\nopenvpn.net\nopenwebster.com\nopenwrt.org.cn\nopml.radiotime.com\noppornsites.com\nor.cn.uptodown.com\norchidbbs.com\norgancare.org.tw\norganharvestinvestigation.net\norganiccrap.com\norgasm.com\norgfree.com\norient-doll.com\norientaldaily.com.my\norn.jp\nornhubdeutsch.ne\nornsharing.com\nornytrip.com\norrentproject.se\norzistic.org\nosfoora.com\nosh.comedycentral.com\notnd.org\notto.de\notzo.com\noubory.com\nourceforge.net\nourdearamy.com\nourhobby.com\noursogo.com\noursteps.com.au\noursweb.net\nourtv.hk\noverplay.net\noversea.istarshine.com\now.ly\nowind.com\nowl.li\noxid.i\noyax.com\noyghan.com\nozchinese.com\nozvoice.org\nozxw.com\nozyoyo.com\npachosting.com\npacificpoker.com\npackages.debian.org\npacketix.net\npacopacomama.com\npadmanet.com\npage.bid.yahoo.com\npage2rss.com\npagodabox.com\npalacemoon.com\npaldengyal.com\npaljorpublications.com\npaltalk.com\npanacom.co.jp\npanamapapers.sueddeutsche.de\npandapow.co\npandapow.net\npandavpn-jp.com\npandora.com\npandora.tv\npangci.net\npanluan.net\npanoramio.com\npao-pao.net\npaper.li\npaperb.us\nparadisehill.cc\nparadisepoker.com\nparkansky.com\npartycasino.com\npartypoker.com\npassion.com\npassiontimes.hk\npastebin.com\npastie.org\npbs.org\npbwiki.com\npbworks.com\npbxes.com\npbxes.org\npcanywhere.net\npcc.gov.tw\npcdvd.com.tw\npchome.com.tw\npcstore.com.tw\npct.org.tw\npdetails.com\npdproxy.com\npds.nasa.gov\npeace.ca\npeacefire.org\npeacehall.com\npeeasian.com\npekingduck.org\npemulihan.or.id\npen.io\npenchinese.com\npenchinese.net\npengyulong.com\npenisbot.com\npenthouse.com\npentoy.hk\npeoplebookcafe.com\npeoplenews.tw\npeopo.org\npercy.in\nperfectgirls.net\nperfectvpn.net\nperiscope.tv\npersecutionblog.com\npersiankitty.com\npfd.org.hk\nphapluan.org\nphayul.com\nphilborges.com\nphilly.com\nphmsociety.org\nphncdn.com\nphobos.apple.com\nphosphation13.rssing.com\nphotodharma.net\nphotofocus.com\nphuquocservices.com\npicasaweb.com\npicidae.net\npicturedip.com\npicturesocial.com\npimg.tw\npin-cong.com\npin6.com\nping.fm\npinimg.com\npinkrod.com\npinoy-n.com\npinterest.at\npinterest.co.kr\npinterest.co.uk\npinterest.com\npinterest.de\npinterest.dk\npinterest.fr\npinterest.jp\npinterest.nl\npinterest.se\npioneer-worker.forums-free.com\npipii.tv\npiposay.com\npiraattilahti.org\npiring.com\npixelqi.com\npixiv.net\npixiv.org\npixnet.net\npk.com\nplacemix.com\nplayboy.com\nplayboyplus.com\nplayer.fm\nplayno1.com\nplaypcesor.com\nplays.com.tw\nplm.org.hk\nplunder.com\nplus28.com\nplusbb.com\npmatehunter.com\npmates.com\npo2b.com\npobieramy.top\npodictionary.com\npokerstars.net\npoliticalchina.org\npoliticalconsultation.org\npoloniex.com\npolymer-project.org\npolymerhk.com\npopo.tw\npopvote.hk\npopyard.com\npopyard.org\nporn.com\nporn2.com\nporn5.com\npornbase.org\npornerbros.com\npornhd.com\npornhost.com\npornhub.com\npornhubdeutsch.net\npornmm.net\npornoxo.com\npornrapidshare.com\npornsharing.com\npornsocket.com\npornstarclub.com\nporntube.com\nporntubenews.com\nporntvblog.com\npornvisit.com\nport25.biz\nportablevpn.nl\nposkotanews.com\npost01.com\npost76.com\npost852.com\npostadult.com\npostimg.org\npotvpn.com\npower.com\npowerapple.com\npowercx.com\npowerphoto.org\npowerpointninja.com\nprayforchina.net\npremeforwindows7.com\npresentationzen.com\npresidentlee.tw\nprestige-av.com\nprisoneralert.com\npritunl.com\nprivacybox.de\nprivate.com\nprivateinternetaccess.com\nprivatepaste.com\nprivatetunnel.com\nprivatevpn.com\nprocopytips.com\nprosiben.de\nprovideocoalition.com\nprovpnaccounts.com\nproxfree.com\nproxifier.com\nproxomitron.info\nproxpn.com\nproxyanonimo.es\nproxydns.com\nproxylist.org.uk\nproxynetwork.org.uk\nproxypy.net\nproxyroad.com\nproxytunnel.net\nproyectoclubes.com\nprozz.net\npsblog.name\npscp.tv\npsiphon.ca\npsiphon.civisec.org\npsiphon3.com\npsiphontoday.com\npts.org.tw\nptt.cc\npttvan.org\npubu.com.tw\npuffinbrowser.com\npuffstore.com\npullfolio.com\npulse.yahoo.com\npunyu.com\npure18.com\npureconcepts.net\npureinsight.org\npurepdf.com\npurevpn.com\npurplelotus.org\npursuestar.com\npussyspace.com\nputihome.org\nputlocker.com\nputty.org\npuuko.com\npwned.com\npximg.net\npython.com\npython.com.tw\npythonhackers.com\nqanote.com\nqgirl.com.tw\nqhigh.com\nqi-gong.me\nqiandao.today\nqidian.ca\nqienkuen.org\nqiwen.lu\nqixianglu.cn\nqkshare.com\nqoos.com\nqpoe.com\nqq.co.za\nqstatus.com\nqtrac.eu\nqtweeter.com\nquannengshen.org\nquantumbooter.net\nquestvisual.com\nquitccp.net\nquitccp.org\nquora.com\nquran.com\nquranexplorer.com\nqusi8.net\nqvodzy.org\nqxbbs.org\nr18.com\nra.gg\nradicalparty.org\nradiko.j\nradioaustralia.net.au\nradiohilight.net\nradiovaticana.org\nradiovncr.com\nrael.org\nraggedbanner.com\nraidcall.com.tw\nraidtalk.com.tw\nrainbowplan.org\nraizoji.or.j\nraizoji.or.jp\nramcity.com.au\nrangwang.biz\nrangzen.com\nrangzen.net\nrangzen.org\nrans.wenweipo.com\nranyunfei.com\nrapbull.net\nrapidgator.ne\nrapidmoviez.com\nrapidvpn.com\nraremovie.cc\nraremovie.ne\nraremovie.net\nraw.githubusercontent.com\nrawgit.com\nrawgithub.com\nrazyboard.com\nrcinet.ca\nrconversation.blogs.com\nrd.com\nrdio.com\nre-tracker.uz\nread01.com\nread100.com\nreadingtimes.com.tw\nreadmoo.com\nreadydown.com\nrealcourage.org\nrealforum.zkiz.com\nrealitykings.com\nrealraptalk.com\nrealsexpass.com\nrebatesrule.net\nrecordhistory.org\nrecovery.org.tw\nrecoveryversion.com.tw\nred-lang.org\nredchinacn.ne\nredchinacn.net\nredchinacn.org\nredhotlabs.com\nredtube.com\nreferer.us\nreflectivecode.com\nregistry.google\nrelaxbbs.com\nrelay.com.tw\nreleaseinternational.org\nreligioustolerance.org\nrenminbao.com\nrenyurenquan.org\nresearch.jmsc.hku.hk\nresilio.com\nretweeteffect.com\nretweetist.com\nretweetrank.com\nreuters.com\nreutersmedia.net\nrevleft.com\nrevver.com\nrfa.org\nrfachina.com\nrfamobile.org\nrfaweb.org\nrferl.org\nrfi.fr\nrfi.my\nrigpa.org\nriku.me\nrileyguide.com\nring4u.info\nriseup.ne\nritouki.jp\nrlwlw.com\nrmjdw.com\nrmjdw132.info\nro.ml\nroadshow.hk\nroboforex.com\nrobustnessiskey.com\nroc-taiwan.org\nrocket-inc.net\nrocksdb.org\nrojo.com\nrolia.net\nronjoneswriter.com\nroodo.com\nrosechina.net\nrotten.com\nrouw.nl\nrsf-chinese.org\nrsf.org\nrsgamen.org\nrssmeme.com\nrtalabel.org\nrthk.hk\nrthk.org.hk\nrti.org.tw\nrtycminnesota.org\nruanyifeng.com\nruebuddha-md.org\nrukor.org\nrushbee.com\nruten.com.tw\nruth101.co.tv\nruthontour.org\nrutube.ru\nruyiseek.com\nrxhj.ne\nrxhj.net\ns-cute.com\ns-dragon.org\ns1.nudezz.com\ns1heng.com\ns1s1s1.com\ns3-ap-northeast-1.amazonaws.com\ns3-ap-southeast-2.amazonaws.com\ns3.amazonaws.com\ns4miniarchive.com\ns8forum.com\nsacks.com\nsacom.hk\nsadistic-v.com\nsadpanda.us\nsafervpn.com\nsaintyculture.com\nsaiq.me\nsakuralive.com\nsakya.org\nsalvation.org.hk\nsamair.ru\nsambhota.org\nsanmin.com.tw\nsapikachu.net\nsaveliuxiaobo.com\nsavemedia.com\nsavethedate.foo\nsavetibet.de\nsavetibet.fr\nsavetibet.nl\nsavetibet.org\nsavetibet.ru\nsavetibetstore.org\nsavevid.com\nsay2.info\nsbme.me\nsbs.com.au\nscasino.com\nschema.org\nsciencemag.org\nsciencenets.com\nscieron.com\nscmp.com\nscmpchinese.com\nscramble.io\nscribd.com\nscriptspot.com\nseapuff.com\nsearch.aol.com\nsearch.xxx\nsearch.yahoo.co.jp\nsearchtruth.com\nsecretchina.com\nsecretgarden.no\nsecretsline.biz\nsecure.logmein.com\nsecure.raxcdn.com\nsecuretunnel.com\nsecuritykiss.com\nseed4.me\nseesmic.com\nseevpn.com\nseezone.net\nsejie.com\nsellclassics.com\nsendsmtp.com\nsendspace.com\nservehttp.com\nserveuser.com\nserveusers.com\nsesawe.net\nsesawe.org\nsethwklein.net\nsetn.com\nsettv.com.tw\nsevenload.com\nsex-11.com\nsex.com\nsex3.com\nsex8.cc\nsexandsubmission.com\nsexbot.com\nsexhu.com\nsexhuang.com\nsexidude.com\nsexinsex.net\nsextvx.com\nsexxxy.biz\nsf.ne\nsfileydy.com\nsfshibao.com\nsftindia.org\nsftuk.org\nshadeyouvpn.com\nshadow.ma\nshadowsky.xyz\nshadowsocks-r.com\nshadowsocks.asia\nshadowsocks.com\nshadowsocks.com.hk\nshadowsocks.org\nshambalapost.com\nshambhalasun.com\nshangfang.org\nshapeservices.com\nshare.dmhy.org\nshare.ovi.com\nshare.youthwant.com.tw\nsharebee.com\nsharecool.org\nsharpdaily.com.hk\nsharpdaily.hk\nsharpdaily.tw\nshat-tibet.com\nshattered.io\nsheikyermami.com\nshellfire.de\nshenshou.org\nshenyun.com\nshenyunperformingarts.org\nshenzhoufilm.com\nsherabgyaltsen.com\nshiatv.net\nshicheng.org\nshinychan.com\nshipcamouflage.com\nshireyishunjian.com\nshitaotv.org\nshixiao.org\nshizhao.org\nshkspr.mobi\nshodanhq.com\nshooshtime.com\nshop2000.com.tw\nshopping.com\nshowbiz.omy.sg\nshowhaotu.com\nshowtime.jp\nshutterstock.com\nshwchurch.org\nshwchurch3.com\nsiddharthasintent.org\nsidelinesnews.com\nsidelinessportseatery.com\nsierrafriendsoftibet.org\nsijihuisuo.club\nsijihuisuo.com\nsilkbook.com\nsimbolostwitter.com\nsimplecd.org\nsimpleproductivityblog.com\nsinchew.com.my\nsingaporepools.com.sg\nsingfortibet.com\nsingpao.com.hk\nsingtao.com\nsingtaousa.com\nsino-monthly.com\nsinoants.com\nsinocast.com\nsinocism.com\nsinomontreal.ca\nsinonet.ca\nsinopitt.info\nsinoquebec.com\nsis.xxx\nsis001.com\nsis001.us\nsite90.net\nsitebro.tw\nsitekreator.com\nsiteks.uk.to\nsitemaps.org\nsixth.biz\nsjrt.org\nsjum.cn\nskeettools.com\nsketchappsources.com\nskimtube.com\nskybet.com\nskyking.com.tw\nskype.com\nskyvegas.com\nskyxvpn.com\nslacker.com\nslaytizle.com\nsleazydream.com\nslheng.com\nslickvpn.com\nslideshare.net\nslinkset.com\nslutload.com\nslutmoonbeam.com\nslyip.com\nslyip.net\nsm-miracle.com\nsmartdnsproxy.com\nsmarthide.com\nsmchbooks.com\nsmh.com.au\nsmhric.org\nsmith.edu\nsmyxy.org\nsnapchat.com\nsnaptu.com\nsndcdn.com\nsneakme.net\nsnowlionpub.com\nsobees.com\nsoc.mil\nsocialwhale.com\nsockscap64.com\nsockslist.net\nsocrec.org\nsod.co.jp\nsodatea.github.io\nsoftether-download.com\nsoftether.co.jp\nsoftether.org\nsoftwarebychuck.com\nsogclub.com\nsogrady.me\nsoh.tw\nsohcradio.com\nsohfrance.org\nsokamonline.com\nsokmil.com\nsolarsystem.nasa.gov\nsolidaritetibet.org\nsolidfiles.com\nsomee.com\nsongjianjun.com\nsonicbbs.cc\nsonidodelaesperanza.org\nsopcast.com\nsopcast.org\nsorazone.net\nsorting-algorithms.com\nsos.org\nsostibet.org\nsoubory.com\nsoul-plus.net\nsoulcaliburhentai.net\nsoumo.info\nsoundcloud.com\nsoundofhope.kr\nsoundofhope.org\nsoup.io\nsoupofmedia.com\nsourcewadio.com\nsouthnews.com.tw\nsowers.org.hk\nspankbang.com\nspankingtube.com\nspankwire.com\nspb.com\nspeakerdeck.com\nspecxinzl.jigsy.com\nspeedify.com\nspem.at\nspencertipping.com\nspicevpn.com\nspideroak.com\nspike.com\nsports.williamhill.com\nspotflux.com\nspotify.com\nspreadshirt.es\nspring4u.info\nspringboardplatform.com\nsprite.org\nsproutcore.com\nsproxy.info\nsquirly.info\nsrcf.ucam.org\nsrocket.us\nss-link.com\nss.carryzhou.com\nss.levyhsu.com\nssglobal.co\nssglobal.me\nssh91.com\nssl.webpack.de\nssl443.org\nsspro.ml\nsss.camp\nsstmlt.moe\nsstmlt.net\nstage64.hk\nstandupfortibet.org\nstanford.edu\nstarfishfx.com\nstarp2p.com\nstartpage.com\nstartuplivingchina.com\nstat.gov.tw\nstatic-economist.com\nstatic.comico.tw\nstatic01.nyt.com\nstaticflickr.com\nstatueofdemocracy.org\nstc.com.sa\nsteamcommunity.com\nsteel-storm.com\nsteganos.com\nsteganos.net\nstepchina.com\nstephaniered.com\nsthoo.com\nstickam.com\nstickeraction.com\nstileproject.com\nsto.cc\nstoneip.info\nstoptibetcrisis.net\nstoragenewsletter.com\nstories.google\nstorify.com\nstorm.mg\nstormmediagroup.com\nstoweboyd.com\nstranabg.com\nstraplessdildo.com\nstreamingthe.net\nstreema.com\nstrikingly.com\nstrongvpn.com\nstrongwindpress.com\nstudent.tw\nstudentsforafreetibet.org\nstumbleupon.com\nstupidvideos.com\nsubacme.rerouted.org\nsuccessfn.com\nsugarsync.com\nsugobbs.com\nsugumiru18.com\nsuissl.com\nsujiatun.wordpress.com\nsulian.me\nsummify.com\nsumrando.com\nsun1911.com\nsunmedia.ca\nsunporno.com\nsunskyforum.com\nsunta.com.tw\nsunvpn.net\nsuoluo.org\nsuperfreevpn.com\nsuperokayama.com\nsuperpages.com\nsupervpn.net\nsuppig.net\nsuprememastertv.com\nsurfeasy.com\nsurfeasy.com.au\nsuroot.com\nsurrenderat20.net\nsuyangg.com\nsvsfx.com\nswagbucks.com\nswift-tools.net\nswissvpn.net\nswitch1.jp\nswitchvpn.net\nsydneytoday.com\nsylfoundation.org\nsyncback.com\nsynergyse.com\nsysresccd.org\nsytes.net\nszbbs.net\nszetowah.org.hk\nt-g.com\nt.co\nt.me\nt.orzdream.com\nt35.com\nt66y.com\ntaa-usa.org\ntaaze.tw\ntablesgenerator.com\ntabtter.jp\ntacc.cwb.gov.tw\ntacem.org\ntaconet.com.tw\ntaedp.org.tw\ntafm.org\ntagwa.org.au\ntagwalk.com\ntahr.org.tw\ntaipei.gov.tw\ntaipeisociety.org\ntaiwan-sex.com\ntaiwanbible.com\ntaiwancon.com\ntaiwandaily.net\ntaiwandc.org\ntaiwanembassy.org\ntaiwanjobs.gov.tw\ntaiwanjustice.com\ntaiwankiss.com\ntaiwannation.50webs.com\ntaiwannation.com\ntaiwannation.com.tw\ntaiwanncf.org.tw\ntaiwannews.com.tw\ntaiwanonline.cc\ntaiwantoday.tw\ntaiwantp.net\ntaiwantt.org.tw\ntaiwanus.net\ntaiwanyes.com\ntaiwanyes.ning.com\ntalk853.com\ntalkboxapp.com\ntalkonly.net\ntamiaode.tk\ntanc.org\ntangben.com\ntangren.us\ntaoism.net\ntaolun.info\ntapanwap.com\ntapatalk.com\ntascn.com.au\ntaup.net\ntaup.org.tw\ntaweet.com\ntbcollege.org\ntbi.org.hk\ntbicn.org\ntbjyt.org\ntbpic.info\ntbrc.org\ntbs-rainbow.org\ntbsec.org\ntbskkinabalu.page.tl\ntbsmalaysia.org\ntbsn.org\ntbsseattle.org\ntbssqh.org\ntbswd.org\ntbtemple.org.uk\ntbthouston.org\ntccwonline.org\ntcewf.org\ntchrd.org\ntcnynj.org\ntcpspeed.co\ntcpspeed.com\ntcsofbc.org\ntcsovi.org\nteachparentstech.org\nteamamericany.com\nteck.in\nteeniefuck.net\nteensinasia.com\ntelecomspace.com\ntelegram.dog\ntelegram.me\ntelegram.org\ntelegramdownload.com\ntelegraph.co.uk\ntellme.pw\ntenacy.com\ntensorflow.org\ntenzinpalmo.com\ntew.org\nthaicn.com\nthb.gov.tw\ntheatrum-belli.com\nthebcomplex.com\ntheblemish.com\nthebobs.com\nthebodyshop-usa.com\nthecenter.mit.edu\nthechinabeat.org\nthechinastory.org\nthedalailamamovie.com\nthedw.us\nthefacebook.com\nthefrontier.hk\nthegly.com\nthehots.info\nthehousenews.com\nthehun.net\ntheinitium.com\nthenewslens.com\nthepiratebay.org\ntheportalwiki.com\nthereallove.kr\ntherock.net.nz\nthespeeder.com\nthestandnews.com\nthetibetcenter.org\nthetibetconnection.org\nthetibetmuseum.org\nthetibetpost.com\nthetrotskymovie.com\nthevivekspot.com\nthewgo.org\nthinkingtaiwan.com\nthinkwithgoogle.com\nthisav.com\nthlib.org\nthomasbernhard.org\nthongdreams.com\nthreatchaos.com\nthroughnightsfire.com\nthumbzilla.com\nthywords.com\nthywords.com.tw\ntiananmenduizhi.com\ntiananmenmother.org\ntiananmenuniv.com\ntiananmenuniv.net\ntiandixing.org\ntianhuayuan.com\ntianlawoffice.com\ntianti.io\ntiantibooks.org\ntianyantong.org.cn\ntianzhu.org\ntibet-envoy.eu\ntibet-foundation.org\ntibet-house-trust.co.uk\ntibet-info.net\ntibet-initiative.de\ntibet-munich.de\ntibet.a.se\ntibet.at\ntibet.ca\ntibet.com\ntibet.fr\ntibet.net\ntibet.nu\ntibet.org\ntibet.org.tw\ntibet.sk\ntibet.to\ntibet3rdpole.org\ntibetaction.net\ntibetaid.org\ntibetalk.com\ntibetan-alliance.org\ntibetan.fr\ntibetanaidproject.org\ntibetanarts.org\ntibetanbuddhistinstitute.org\ntibetancommunity.org\ntibetancommunityuk.net\ntibetanculture.org\ntibetanfeministcollective.org\ntibetanjournal.com\ntibetanlanguage.org\ntibetanliberation.org\ntibetanpaintings.com\ntibetanphotoproject.com\ntibetanpoliticalreview.org\ntibetanreview.net\ntibetanwomen.org\ntibetanyouth.org\ntibetanyouthcongress.org\ntibetcharity.dk\ntibetcharity.in\ntibetchild.org\ntibetcity.com\ntibetcollection.com\ntibetcorps.org\ntibetexpress.net\ntibetfocus.com\ntibetfund.org\ntibetgermany.com\ntibetgermany.de\ntibethaus.com\ntibetheritagefund.org\ntibethouse.jp\ntibethouse.org\ntibethouse.us\ntibetinfonet.net\ntibetjustice.org\ntibetkomite.dk\ntibetlibre.free.fr\ntibetnetwork.org\ntibetoffice.ch\ntibetoffice.com.au\ntibetoffice.eu\ntibetoffice.org\ntibetonline.com\ntibetonline.tv\ntibetoralhistory.org\ntibetpolicy.eu\ntibetrelieffund.co.uk\ntibetsites.com\ntibetsociety.com\ntibetsun.com\ntibetsupportgroup.org\ntibetswiss.ch\ntibettelegraph.com\ntibettimes.net\ntibetwrites.org\nticket.com.tw\ntigervpn.com\ntiltbrush.com\ntimdir.com\ntime.com\ntimes.hinet.net\ntimesofindia.indiatimes.com\ntimsah.com\ntintuc101.com\ntiny.cc\ntinychat.com\ntinypaste.com\ntipo.gov.tw\ntistory.com\ntkcs-collins.com\ntma.co.jp\ntmagazine.com\ntmdfish.com\ntmpp.org\ntnaflix.com\ntngrnow.com\ntngrnow.net\ntnp.org\nto-porno.com\ntogetter.com\ntoh.info\ntokyo-247.com\ntokyo-hot.com\ntokyo-porn-tube.com\ntokyocn.com\ntongil.or.kr\ntono-oka.jp\ntonyyan.net\ntoodoc.com\ntoonel.net\ntop.tv\ntop81.ws\ntopic.youthwant.com.tw\ntopnews.in\ntoppornsites.com\ntopshareware.com\ntopsy.com\ntoptip.ca\ntor.blingblingsquad.net\ntor.updatestar.com\ntora.to\ntorcn.com\ntorguard.net\ntorproject.org\ntorrentcrazy.com\ntorrentprivacy.com\ntorrenty.org\ntorrentz.eu\ntorvpn.com\ntotalvpn.com\ntoutiaoabc.com\ntowngain.com\ntoypark.in\ntoythieves.com\ntoytractorshow.com\ntparents.org\ntpi.org.tw\ntracfone.com\ntraffichaus.com\ntrafficjunky.net\ntransparency.org\ntreemall.com.tw\ntrendsmap.com\ntrialofccp.org\ntrickip.net\ntrickip.org\ntrimondi.de\ntrouw.nl\ntrt.net.tr\ntrtc.com.tw\ntruebuddha-md.org\ntrulyergonomic.com\ntruth101.co.tv\ntruthontour.org\ntruveo.com\ntryheart.jp\ntsctv.net\ntsdr.uspto.gov\ntsemtulku.com\ntsquare.tv\ntsu.org.tw\ntsunagarumon.com\ntt-rss.org\ntt1069.com\ntttan.com\ntu8964.com\ntubaholic.com\ntube.com\ntube8.com\ntube911.com\ntubecup.com\ntubegals.com\ntubeislam.com\ntubestack.com\ntubewolf.com\ntui.orzdream.com\ntuidang.net\ntuidang.org\ntuidang.se\ntuitwit.com\ntumblr.com\ntumutanzi.com\ntumview.com\ntunein.com\ntunnelbear.com\ntunnelr.com\ntuo8.blue\ntuo8.cc\ntuo8.club\ntuo8.fit\ntuo8.hk\ntuo8.in\ntuo8.ninja\ntuo8.org\ntuo8.pw\ntuo8.red\ntuo8.space\nturansam.org\nturbobit.net\nturbohide.com\nturbotwitter.com\nturntable.fm\ntushycash.com\ntuvpn.com\ntuzaijidi.com\ntv.com\ntvants.com\ntvboxnow.com\ntvider.com\ntvmost.com.hk\ntvplayvideos.com\ntvunetworks.com\ntw-blog.com\ntw-npo.org\ntw.answers.yahoo.com\ntw.bid.yahoo.com\ntw.gigacircle.com\ntw.jiepang.com\ntw.knowledge.yahoo.com\ntw.mall.yahoo.com\ntw.mobi.yahoo.com\ntw.myblog.yahoo.com\ntw.news.yahoo.com\ntw.streetvoice.com\ntw.tomonews.net\ntw.voa.mobi\ntw.yahoo.com\ntw01.org\ntwaitter.com\ntwapperkeeper.com\ntwaud.io\ntwavi.com\ntwbbs.net.tw\ntwbbs.org\ntwbbs.tw\ntwblogger.com\ntweepguide.com\ntweeplike.me\ntweepmag.com\ntweepml.org\ntweetbackup.com\ntweetboard.com\ntweetboner.biz\ntweetcs.com\ntweetdeck.com\ntweetedtimes.com\ntweetmylast.fm\ntweetphoto.com\ntweetrans.com\ntweetree.com\ntweettunnel.com\ntweetwally.com\ntweetymail.com\ntweez.net\ntwelve.today\ntwerkingbutt.com\ntwftp.org\ntwgreatdaily.com\ntwibase.com\ntwibble.de\ntwibbon.com\ntwibs.com\ntwicsy.com\ntwiends.com\ntwifan.com\ntwiffo.com\ntwiggit.org\ntwilightsex.com\ntwilog.org\ntwimbow.com\ntwimg.com\ntwindexx.com\ntwip.me\ntwipple.jp\ntwishort.com\ntwistar.cc\ntwister.net.co\ntwisterio.com\ntwisternow.com\ntwistory.net\ntwit2d.com\ntwitbrowser.net\ntwitcause.com\ntwitgether.com\ntwitgoo.com\ntwitiq.com\ntwitlonger.com\ntwitmania.com\ntwitoaster.com\ntwitonmsn.com\ntwitpic.com\ntwitstat.com\ntwittbot.net\ntwitter.com\ntwitter.jp\ntwitter4j.org\ntwittercounter.com\ntwitterfeed.com\ntwittergadget.com\ntwitterkr.com\ntwittermail.com\ntwitterrific.com\ntwittertim.es\ntwitthat.com\ntwitturk.com\ntwitturly.com\ntwitvid.com\ntwitzap.com\ntwiyia.com\ntwnorth.org.tw\ntwskype.com\ntwstar.net\ntwtkr.com\ntwtr2src.ogaoga.org\ntwtrland.com\ntwttr.com\ntwurl.nl\ntwyac.org\ntxxx.com\ntycool.com\ntypepad.com\ntzangms.com\nu9un.com\nuashangnews.com\nub0.cc\nubddns.org\nubeislam.com\nuberproxy.net\nuc-japan.org\nucdc1998.org\nuchicago.edu\nuderzo.it\nudn.com\nudn.com.tw\nudnbkk.com\nuforadio.com.tw\nufreevpn.com\nugo.com\nuhdwallpapers.org\nuhrp.org\nuighur.narod.ru\nuighur.nl\nuighurbiz.net\nukcdp.co.uk\nukliferadio.co.uk\nulike.net\nulop.net\nultrasurf.us\nultravpn.fr\nultraxs.com\numich.edu\numutanzi.com\nunblock-us.com\nunblock.cn.com\nunblockdmm.com\nunblocker.yt\nunblocksit.es\nuncyclomedia.org\nuncyclopedia.hk\nuncyclopedia.tw\nunderwoodammo.com\nunein.com\nunholyknight.com\nuni.cc\nunification.net\nunification.org.tw\nunitedsocialpress.com\nunix100.com\nunknownspace.org\nunodedos.com\nunpo.org\nuntraceable.u\nuntraceable.us\nuo8.pw\nuocn.org\nupcoming.yahoo.com\nupdates.tdesktop.com\nupholdjustice.org\nupload4u.info\nuploaded.net\nuploaded.to\nuploadstation.com\nupmedia.mg\nupornia.com\nuprememastertv.com\nuproxy.org\nupwill.org\nur7s.com\nurbansurvival.com\nurbobit.ne\nurchin.com\nurfeasy.com.au\nurlborg.com\nurlparser.com\nus.to\nusacn.com\nusaip.eu\nuserapi.nytlog.com\nusers.skynet.be\nusfk.mil\nushuarencity.echainhost.com\nushycash.com\nusinfo.state.gov\nusma.edu\nusmc.mil\nusmgtcg.ning.com\nusno.navy.mil\nusocctn.com\nustlercash.com\nustream.tv\nusunitednews.com\nusus.cc\nutopianpal.com\nuu-gg.com\nuvwxyz.xyz\nuwants.com\nuwants.net\nuyangg.com\nuyghur-j.org\nuyghur.co.uk\nuyghuramerican.org\nuyghurcanadiansociety.org\nuyghurcongress.org\nuyghurensemble.co.uk\nuyghurpen.org\nuyghurpress.com\nuyghurstudies.org\nuygur.fc2web.com\nuygur.org\nuymaarip.com\nuzaijidi.com\nv.com\nv2ex.com\nv2ray.com\nvan001.com\nvan698.com\nvanemu.cn\nvanilla-jp.com\nvanpeople.com\nvansky.com\nvatn.org\nvboxnow.com\nvcf-online.org\nvcfbuilder.org\nvds.rightster.com\nvegas.williamhill.com\nvegasred.com\nvelkaepocha.sk\nvenbbs.com\nvenchina.com\nvenetianmacao.com\nventureswell.com\nveoh.com\nvermonttibet.org\nversavpn.com\nverybs.com\nvevo.com\nvft.com.tw\nviber.com\nvica.info\nvictimsofcommunism.org\nvid.me\nvidble.com\nvideo.aol.ca\nvideo.aol.co.uk\nvideo.aol.com\nvideo.ap.org\nvideo.fdbox.com\nvideo.foxbusiness.com\nvideo.pbs.org\nvideo.yahoo.com\nvideobam.com\nvideodetective.com\nvideomega.tv\nvideomo.com\nvideopediaworld.com\nvideopress.com\nvidinfo.org\nvietdaikynguyen.com\nviidii.info\nvijayatemple.org\nvimeo.com\nvimperator.org\nvincnd.com\nvine.co\nvinniev.com\nvip-enterprise.com\nvisibletweets.com\nvital247.org\nviu.com\nviu.tv\nvivahentai4u.net\nvivatube.com\nvivthomas.com\nvizvaz.com\nvjmedia.com.hk\nvllcs.org\nvlog.xuite.net\nvmixcore.com\nvn.hao123.com\nvnet.link\nvoa-11.akacast.akamaistream.net\nvoacantonese.com\nvoachinese.com\nvoachineseblog.com\nvoagd.com\nvoanews.com\nvoatibetan.com\nvoatibetanenglish.com\nvocativ.com\nvocn.tv\nvod.wwe.com\nvot.org\nvovo2000.com\nvoxer.com\nvoy.com\nvpn.ac\nvpn.cjb.net\nvpn.cmu.edu\nvpn.sv.cmu.edu\nvpn4all.com\nvpnaccount.org\nvpnaccounts.com\nvpnbook.com\nvpncomparison.org\nvpncoupons.com\nvpncup.com\nvpndada.com\nvpnfan.com\nvpnfire.com\nvpnforgame.net\nvpngate.jp\nvpngate.net\nvpngratis.net\nvpnhq.com\nvpninja.net\nvpnintouch.com\nvpnintouch.net\nvpnjack.com\nvpnmaster.com\nvpnmentor.com\nvpnpick.com\nvpnpop.com\nvpnpronet.com\nvpnreactor.com\nvpnreviewz.com\nvpnsecure.me\nvpnshazam.com\nvpnshieldapp.com\nvpnsp.com\nvpntraffic.com\nvpntunnel.com\nvpnuk.info\nvpnunlimitedapp.com\nvpnvip.com\nvpnworldwide.com\nvporn.com\nvpser.net\nvraiesagesse.net\nvrmtr.com\nvtunnel.com\nvuku.cc\nw-blog.com\nw.answers.yahoo.com\nw.bid.yahoo.com\nw.hao123.com\nw.idaiwan.com\nw01.org\nw3schools.com\nwaffle1999.com\nwahas.com\nwaigaobu.com\nwaikeung.org\nwailaike.net\nwaiwaier.com\nwallmama.com\nwallornot.org\nwallpapercasa.com\nwallproxy.com\nwaltermartin.com\nwaltermartin.org\nwan-press.org\nwanderinghorse.net\nwangafu.net\nwangjinbo.org\nwanglixiong.com\nwango.org\nwangruoshui.net\nwangruowang.org\nwant-daily.com\nwanz-factory.com\nwapedia.mobi\nwarbler.iconfactory.net\nwaselpro.com\nwasheng.net\nwatch8x.com\nwatchinese.com\nwatchmygf.net\nwattpad.com\nwav.tv\nwaveprotocol.org\nwaymo.com\nwchurch3.com\nwda.gov.tw\nwdf5.com\nwearehairy.com\nwearn.com\nweb2project.net\nwebbang.net\nwebevader.org\nwebfreer.com\nwebjb.org\nweblagu.com\nwebmproject.org\nwebrtc.org\nwebrush.net\nwebs-tv.net\nwebsite.informer.com\nwebsitepulse.com\nwebsnapr.com\nwebwarper.ne\nwebwarper.net\nwebworkerdaily.com\nweekmag.info\nweetcs.com\nweets.seraph.me\nweez.ne\nwefightcensorship.org\nwefong.com\nweiboleak.com\nweiboscope.jmsc.hku.hk\nweihuo.org\nweijingsheng.org\nweiming.info\nweiquanwang.org\nweisuo.w\nwelovecock.com\nwemigrate.org\nwengewang.com\nwengewang.org\nwenhui.ch\nwenxuecity.com\nwenyunchao.com\nwestca.com\nwesternshugdensociety.org\nwesternwolves.com\nwestkit.net\nwestpoint.edu\nwetplace.com\nwetpussygames.com\nwexiaobo.org\nwezhiyong.org\nwezone.net\nwforum.com\nwha.la\nwhatblocked.com\nwhatbrowser.org\nwhatsapp.net\nwheatseeds.org\nwheelockslatin.com\nwhereiswerner.com\nwheretowatch.com\nwhippedass.com\nwhitebear.freebearblog.org\nwhodns.xyz\nwhoer.net\nwhotalking.com\nwhylover.com\nwhyx.org\nwi.to\nwidevine.com\nwiends.com\nwifan.com\nwikaba.com\nwiki.cnitter.com\nwiki.esu.im\nwiki.gamerp.j\nwiki.jqueryui.com\nwiki.keso.cn\nwiki.moegirl.org\nwiki.oauth.net\nwiki.phonegap.com\nwikileaks-forum.com\nwikileaks.ch\nwikileaks.com\nwikileaks.de\nwikileaks.eu\nwikileaks.lu\nwikileaks.org\nwikileaks.pl\nwikilivres.info\nwikimapia.org\nwikiwiki.jp\nwildammo.com\nwillw.net\nwindowsphoneme.com\nwindscribe.com\nwingamestore.com\nwingy.site\nwinning11.com\nwinwhispers.info\nwiredbytes.com\nwiredpen.com\nwireshark.org\nwisdompubs.org\nwisevid.com\nwithgoogle.com\nwitnessleeteaching.com\nwitopia.net\nwizcrafts.net\nwjbk.org\nwlcnew.jigsy.com\nwlx.sowiki.net\nwn.com\nwnacg.com\nwnacg.org\nwo.tc\nwo3ttt.wordpress.com\nwoeser.com\nwoesermiddle-way.ne\nwokar.org\nwolfax.com\nwoolyss.com\nwoopie.jp\nwoopie.tv\nwordpress.com\nworkatruna.com\nworkerdemo.org.hk\nworkersthebig.net\nworldcat.org\nworldjournal.com\nworldvpn.net\nwow-life.net\nwow.com\nwowgirls.com\nwowlegacy.ml\nwowporn.com\nwowrk.com\nwoxinghuiguo.com\nwoyaolian.org\nwozy.in\nwp.com\nwpoforum.com\nwqyd.org\nwrchina.org\nwretch.cc\nwriter.zoho.com\nwsgzao.github.io\nwsj.com\nwsj.net\nwsjhk.com\nwt.tl\nwtbn.org\nwtfpeople.com\nwtkr.com\nwuerkaixi.com\nwufafangwen.com\nwufi.org.tw\nwuguoguang.com\nwujie.net\nwujieliulan.com\nwukangrui.net\nwuu.wikipedia.org\nwuw.red\nwwitv.com\nwww1.american.edu\nwww1.biz\nwww2.ohchr.org\nwww2.rocketbbs.com\nwwwhost.biz\nwzyboy.im\nx-art.com\nx-berry.com\nx-wall.org\nx1949x.com\nx24hr.com\nx365x.com\nxa.yimg.com\nxanga.com\nxbabe.com\nxbookcn.com\nxcafe.in\nxcity.jp\nxcritic.com\nxda-developers.com\nxerotica.com\nxfinity.com\nxfm.pp.ru\nxgmyd.com\nxhamster.com\nxianchawang.net\nxianjian.tw\nxianqiao.net\nxiaobaiwu.com\nxiaochuncnjp.com\nxiaod.in\nxiaohexie.com\nxiaolan.me\nxiaoma.org\nxiezhua.com\nxihua.es\nxing.com\nxinhuanet.org\nxinmiao.com.hk\nxinqimeng.over-blog.com\nxinsheng.net\nxinshijue.com\nxinyubbs.ne\nxiongpian.com\nxiuren.org\nxizang-zhiye.org\nxjp.cc\nxjtravelguide.com\nxkiwi.tk\nxlfmtalk.com\nxlfmwz.info\nxm.com\nxml-training-guide.com\nxmovies.com\nxn--4gq171p.com\nxn--czq75pvv1aj5c.org\nxn--i2ru8q2qg.com\nxn--ngstr-lra8j.com\nxn--p8j9a0d9c9a.xn--q9jyb4c\nxnxx.com\nxpdo.net\nxpud.org\nxrentdvd.com\nxskywalker.com\nxskywalker.net\nxtube.com\nxuchao.net\nxuchao.org\nxuzhiyong.net\nxvideo.cc\nxvideos.com\nxvideos.es\nxxbbx.com\nxxlmovies.com\nxxuz.com\nxxx.com\nxxx.xxx\nxxxfuckmom.com\nxxxx.com.au\nxxxy.biz\nxxxy.info\nxxxymovies.com\nxys.dxiong.com\nxys.org\nxysblogs.org\nxyy69.com\nxyy69.info\nyahoo.com.hk\nyakbutterblues.com\nyam.com\nyam.org.tw\nyanghengjun.com\nyangjianli.com\nyasni.co.uk\nyayabay.com\nydy.com\nyeahteentube.com\nyecl.net\nyeelou.com\nyeeyi.com\nyegle.net\nyes-news.com\nyes.xxx\nyes123.com.tw\nyesasia.com\nyesasia.com.hk\nyespornplease.com\nyeyeclub.com\nygto.com\nyhcw.net\nyibada.com\nyibaochina.com\nyidio.com\nyilubbs.com\nyingsuoss.com\nyinlei.org\nyipub.com\nyizhihongxing.com\nyobt.com\nyobt.tv\nyogichen.org\nyong.hu\nyorkbbs.ca\nyoudontcare.com\nyoujizz.com\nyoumaker.com\nyoungpornvideos.com\nyoungspiration.hk\nyoupai.org\nyouporn.com\nyouporngay.com\nyour-freedom.net\nyourepeat.com\nyourlisten.com\nyourlust.com\nyourprivatevpn.com\nyourtrap.com\nyousendit.com\nyoushun12.com\nyouthnetradio.org\nyoutu.be\nyoutube-nocookie.com\nyoutube.com\nyoutubecn.com\nyoutubeeducation.com\nyoutubegaming.com\nyouversion.com\nyouxu.info\nyt.be\nython.com.tw\nytht.net\nytimg.com\nytn.co.kr\nyuanming.net\nyuanzhengtang.org\nyulghun.com\nyunchao.net\nyuntipub.com\nyuvutu.com\nyvesgeleyn.com\nywpw.com\nyx51.net\nyyii.org\nyzzk.com\nzacebook.com\nzalmos.com\nzannel.com\nzaobao.com.sg\nzaozon.com\nzapto.org\nzattoo.com\nzdnet.com.tw\nzello.com\nzengjinyan.org\nzenmate.com\nzenmate.com.ru\nzensur.freerk.com\nzeronet.io\nzeutch.com\nzfreet.com\nzgsddh.com\nzgzcjj.net\nzh-yue.wikipedia.org\nzh.ecdm.wikia.com\nzh.m.wikipedia.org\nzh.pokerstrategy.com\nzh.uncyclopedia.wikia.com\nzh.wikinews.org\nzh.wikipedia.org\nzh.wikisource.org\nzhanbin.net\nzhangboli.net\nzhangtianliang.com\nzhanlve.org\nzhao.1984.city\nzhao.jinhai.de\nzhenghui.org\nzhengjian.org\nzhengwunet.org\nzhenlibu.info\nzhenlibu1984.com\nzhenxiang.biz\nzhinengluyou.com\nzhongguo.ca\nzhongguorenquan.org\nzhongguotese.net\nzhongmeng.org\nzhreader.com\nzhuangbi.me\nzhuanxing.cn\nzhuatieba.com\nzhuichaguoji.org\nziddu.com\nzillionk.com\nzim.vn\nzinio.com\nziporn.com\nzkaip.com\nzmw.cn\nzodgame.us\nzomobo.net\nzonaeuropa.com\nzonghexinwen.com\nzonghexinwen.net\nzoogvpn.com\nzootool.com\nzoozle.net\nzozotown.com\nzpn.im\nzshare.net\nzsrhao.com\nzuo.la\nzuobiao.me\nzuola.com\nzvereff.com\nzynaima.com\nzynamics.com\nzyns.com\nzyzc9.com\nzzcartoon.com\nzzux.com"
  },
  {
    "path": "code/default/smart_router/local/gfw_white_list.txt",
    "content": "126.net\n127.net\n163.com\n163yun.com\n17173cdn.com\n178.com\n2345.com\n360safe.com\n51.la\n56.com\n5eplay.com\n5ewin.com\n71.am\n71edge.com\n78dm.net\n88cdn.com\n93x.net\naboutcg.org\nacfunchina.com\naixifan.com\najmide.com\nali213.net\naliapp.org\nalibabadns.com\nalicdn.com\nalipay.com\nalipayobjects.com\nalivecdn.com\naliyuncs.com\naliyunddos1030.com\nallrace.com\namap.com\namemv.com\napcdns.net\napple.com\nautonavi.com\nbaidu.com\nbaidupcs.com\nbaidustatic.com\nbaike.com\nbcebos.com\nbcevod.com\nbdimg.com\nbdstatic.com\nbdurl.net\nbibi-baidu.com\nbiliapi.net\nbilibili.com\nbiligame.com\nbiligame.net\nbilivideo.com\nbing.com\nbingapis.com\nbokecs.net\nbootcss.com\nbtigroup.io\nbytedance.com\nbytedns1.com\nbytefcdn.com\nbyteimg.com\nbytegecko.co\ncccpan.com\ncdncl.net\nchiphell.com\ncibntv.net\ncloudcdn.net\ncmcmcdn.com\ncn\ncnblogs.com\ncnhsjz.com\ncnwest.com\ncsdn.net\nctobsnssdk.com\ndbankcdn.com\ndftoutiao.com\ndianshihome.com\ndiyidan.net\ndlfyb.com\ndmzj.com\ndo1byvision.com\ndouyin.com\ndouyincdn.com\ndouyinliving.com\ndouyinpic.com\ndouyinstatic.com.w.cdngslb.com\ndouyinstatic.com.queniuuf.com\ndouyinvod.com\ndouyu.com\nduoduocdn.com\nduokanbox.com\nduolebo.com\nduomi.com\nduowan.com\nfjhbwc.com\nfunshion.com\ngame100.wiki\ngamekee.com\ngitv.tv\ngmugmu.com\ngtimg.com\ngxw9s.com\nh2os.com\nhaima.me\nhalihali.tv\nhdslb.com\nhicloud.com\nhinet.net\nhitv.com\nhuijistatic.com\nhunantv.com\nhuoshanlive.com\nhupucdn.com\nhuya.com\nicloud.com\niask.com\nid6.me\nimkan.tv\nimooc.com\nip138.com\niqiyi.com\niqiyipic.com\nishuhui.com\nixigua.com\njfcdns.com\njiaoyimao.com\njomodns.com\njquery.com\njxcctjg.com\nkandian.com\nkankan.com\nkantv6.com\nkmf.com\nksyungslb.com\nkugou.com\nkuiniuca.com\nkunluncan.com\nle.com\nlecloud.com\nleisu.com\nlenovomm.com\nletv.com\nlinstitute.net\nlive.com\nljcdn.com\nmankosupply.com\nmax-c.com\nmgtv.com\nmi.com\nmi-img.com\nmiaopai.com\nmicrosoft.com\nmiguvideo.com\nmissevan.com\nmiui.com\nmjshcn.com\nmomocdn.com\nmsn.com\nmyalicdn.com\nmyqcloud.com\nmzstatic.com\nnetease.com\nnexusmods.com\nnio.com\noffice.com\noffice365.com\nonlinedown.net\noschina.com\nourdvsss.com\npangolin-sdk-toutiao.com\npps.tv\nppstream.com\npptv.com\npstatp.com\npublic-api.com\nqfxmj.com\nqianqian.com\nqianxin.com\nqie.tv\nqiecdn.com\nqiqiuyun.net\nqiyi.com\nqq-zuidazy.com\nqq.com\nqqmail.com\nqtlglb.com\nqueniusy.com\nremuxhdr.com\nruioushang.com\nsandai.net\nsdo.com\nsjmhw.com\nskyollie.com\nsmtcdns.com\nsnssdk.com\nsogoucdn.com\nsogou.com\nsohu.com\nsoku.com\nsqgkw.com\nssports.com\nsuning.com\nswh.app\ntancdn.com\ntaobao.com\ntapimg.com\ntaptapdada.com\ntbcache.com\ntencent.com\ntencent-cloud.net\ntjxnwt.com\ntoutiaoimg.com\nttpod.com\ntuchong.net\ntudou.com\ntutlook.com\nubuntu.com\nuniqueway.com\numeng.com\nvideocc.net\nvolcfcdndvs.com\nvzan.cc\nvzuu.com\nwangyuan.com\nweibo.com\nweibocdn.com\nweilekangnet.com\nweixinbridge.com\nweiyun.com\nwekan.tv\nwindows.com\nwindowsupdate.com\nwscdns.com\nxdcdn.net\nxhscdn.com\nxiami.com\nxiami.net\nxiaomi.net\nxiaodutv.com\nxiaohongshu.com\nxiaoka.tv\nxiaomingming.org\nximalaya.com\nxitu.io\nxmcdn.com\nxssdcdn.com\nxuetangx.com\nxunlei.com\nxycdn.com\nxygjx.com\nyfcache.com\nyiihuu.com\nyinxiang.com\nyinyuetai.com\nyixinwulian.com\nyongjiu6.com\nyoudao.com\nyouku.com\nysten.com\nyuboyun.com\nyximgs.com\nyy.com\nyzmfy.com\nzhan.com\nzhangyu.tv\nzhibo.tv\nzhihu.com\nzhimg.com\nzhuafan.live\nzijieapi.com\nzookingsoft.com\nzuidadianying.com\nzypbo.com"
  },
  {
    "path": "code/default/smart_router/local/gfwlist.py",
    "content": "#!/usr/bin/env python\n# coding:utf-8\n\n\nimport os\nimport sys\nimport base64\nimport re\nimport socket\nimport struct\ntry:\n    from urllib.request import urlopen\nexcept ImportError:\n    from urllib2 import urlopen\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nroot_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))\n\nif __name__ == '__main__':\n    python_path = root_path\n    noarch_lib = os.path.abspath(os.path.join(python_path, 'lib', 'noarch'))\n    sys.path.append(noarch_lib)\n\n\nimport env_info\nimport utils\nfrom xlog import getLogger\nxlog = getLogger(\"smart_router\")\n\ndata_path = os.path.join(env_info.data_path, \"smart_router\")\n\n\nclass IpMask(object):\n    def __init__(self, ip_masks):\n        self.masks = self.generate_masks(ip_masks)\n\n    def makeMask(self, n):\n        # return a mask of n bits as a long integer\n        return (2 << int(n) - 1) - 1\n\n    def dottedQuadToNum(self, ip):\n        # convert decimal dotted quad string to long integer\n        try:\n            i = socket.inet_aton(ip)\n        except Exception as e:\n            xlog.exception(\"inet_aton e:%r\", e)\n\n        return struct.unpack('I', i)[0]\n\n    def networkMask(self, ip, bits):\n        # Convert a network address to a long integer\n        return self.dottedQuadToNum(ip) & self.makeMask(bits)\n\n    def generate_masks(self, ip_masks):\n        masks = []\n        for ip_mask in ip_masks:\n            ip, m = ip_mask.split(\"/\")\n            mask = self.networkMask(ip, m)\n            masks.append(mask)\n\n        return tuple(masks)\n\n    def check_ip(self, ip):\n        address = self.dottedQuadToNum(ip)\n        for mask in self.masks:\n            if address & mask == mask:\n                return True\n\n        return False\n\n\nclass GfwList(object):\n    def __init__(self):\n        # self.gfw_black_list = utils.to_bytes(self.load(\"gfw_black_list.txt\"))\n        # https://johnshall.github.io/Shadowrocket-ADBlock-Rules-Forever/sr_top500_banlist.conf\n        self.gfw_black_list, ip_masks, keywords = self.load_banlist(\"sr_top500_banlist.conf\")\n        self.keyword_re = re.compile(\"|\".join(keywords))\n        self.black_subnets = IpMask(ip_masks)\n        self.gfw_white_list = utils.to_bytes(self.load(\"gfw_white_list.txt\"))\n        self.speedtest_whitelist = utils.to_bytes(self.load(\"speedtest_whitelist.txt\"))\n        self.advertisement_list = utils.to_bytes(self.load(\"advertisement_list.txt\"))\n        # xlog.debug(\"white_list size:%d mem:%d\", len(self.gfw_white_list), sys.getsizeof(self.gfw_white_list))\n        # xlog.debug(\"black_list size:%d mem:%d\", len(self.gfw_black_list), sys.getsizeof(self.gfw_black_list))\n\n    @staticmethod\n    def load(name):\n        user_file = os.path.join(data_path, name)\n        if os.path.isfile(user_file):\n            list_file = user_file\n        else:\n            list_file = os.path.join(current_path, name)\n\n        xlog.info(\"Load file:%s\", list_file)\n\n        with open(list_file, \"r\") as fd:\n            gfwdict = {}\n            for line in fd.readlines():\n                line = line.strip()\n                if not line:\n                    continue\n\n                gfwdict[\".\" + line] = 1\n\n        gfwlist = [h for h in gfwdict]\n        return tuple(gfwlist)\n\n    def load_banlist(self, fn):\n        gfwdict = {}\n        ip_masks = []\n        keywords = []\n        list_file = os.path.join(current_path, fn)\n        with open(list_file, \"rb\") as fd:\n            for line in fd.readlines():\n                line = utils.to_str(line.strip())\n                if not line or line.startswith(\"#\") or line.startswith(\"[\"):\n                    continue\n\n                if line.startswith(\"DOMAIN-SUFFIX,\"):\n                    suffix = line.split(\",\")[1]\n                    gfwdict[\".\" + suffix] = 1\n\n                if line.startswith(\"IP-CIDR,\"):\n                    ip_mask = line.split(\",\")[1]\n                    if \":\" not in ip_mask:\n                        ip_masks.append(ip_mask)\n\n                if line.startswith(\"DOMAIN-KEYWORD,\"):\n                    keyword = line.split(\",\")[1]\n                    keywords.append(keyword)\n\n        gfwlist = [h for h in gfwdict]\n        return tuple(utils.to_bytes(gfwlist)), ip_masks, keywords\n\n    def ip_in_black_list(self, ip):\n        return self.black_subnets.check_ip(ip)\n\n    def in_block_list(self, host):\n        dot_host = b\".\" + utils.to_bytes(host)\n        if dot_host.endswith(self.gfw_black_list):\n            return True\n        elif self.keyword_re.search(utils.to_str(host)):\n            return True\n        else:\n            return False\n\n    def in_white_list(self, host):\n        dot_host = b\".\" + host\n        if dot_host.endswith(self.gfw_white_list):\n            return True\n        else:\n            return False\n\n    def in_speedtest_whitelist(self, host):\n        dot_host = b\".\" + host\n        if dot_host.endswith(self.speedtest_whitelist):\n            return True\n        else:\n            return False\n\n    def is_advertisement(self, host):\n        dot_host = b\".\" + host\n        if dot_host.endswith(self.advertisement_list):\n            return True\n        else:\n            return False\n\n\nclass UpdateGFWList(object):\n    white_list_fn = os.path.join(current_path, \"gfw_white_list.txt\")\n    black_list_fn = os.path.join(current_path, \"gfw_black_list.txt\")\n\n    def __init__(self):\n        self.white_list = self.load_white_list()\n\n    def load_white_list(self):\n        white_list = []\n        with open(self.white_list_fn, \"r\") as fd:\n            for line in fd.readlines():\n                domain = line.strip()\n                if domain not in white_list:\n                    white_list.append(domain)\n\n        return white_list\n\n    def download_update_white_list(self):\n        import subprocess\n        url = 'https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/accelerated-domains.china.conf'\n        try:\n            data = subprocess.check_output(['wget', url, '-O-'])\n        except (OSError, AttributeError):\n            xlog.info(\"Fetching data from apnic.net, it might take a few minutes, please wait...\")\n            data = urlopen(url).read()\n\n        for line in data.split(b\"\\n\"):\n            line = line.strip()\n            line = utils.to_str(line)\n            pl = line.split(\"/\")\n            if len(pl) != 3:\n                xlog.warn(\"line:%s\", line)\n                continue\n            domain = pl[1]\n            if domain in self.white_list:\n                continue\n\n            self.white_list.append(domain)\n            xlog.debug(\"white list add:%s\", domain)\n\n    def download_update_gfwlist(self):\n        import subprocess\n        url = 'https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt'\n        try:\n            data = subprocess.check_output(['wget', url, '-O-'])\n        except (OSError, AttributeError):\n            xlog.info(\"Fetching data from apnic.net, it might take a few minutes, please wait...\")\n            data = urlopen(url).read()\n\n        data = base64.b64decode(data)\n\n        with open(\"gfwlist.txt\", \"w\") as fd:\n            for line in data.split(b\"\\n\"):\n                line = line.strip()\n                line = utils.to_str(line)\n                if line.startswith(\"!\"):\n                    continue\n\n                xlog.debug(\"%s\", line)\n                fd.write(\"%s\\n\" % line)\n\n                if not line.startswith(\"@@\"):\n                    continue\n\n                domain = line[2:]\n                if domain.startswith(\"http://\"):\n                    domain = domain[7:]\n                elif domain.startswith(\"https://\"):\n                    domain = domain[8:]\n\n                if domain in self.white_list:\n                    continue\n\n                self.white_list.append(domain)\n                xlog.debug(\"white list add:%s\", domain)\n\n    def save_white_list(self):\n        self.white_list.sort()\n\n        with open(self.white_list_fn, \"w\") as fd:\n            for domain in self.white_list:\n                fd.write(\"%s\\n\" % domain)\n\n        xlog.info(\"white list updated to %s\", self.white_list_fn)\n\n\nif __name__ == \"__main__\":\n    updater = UpdateGFWList()\n    updater.download_update_white_list()\n    updater.save_white_list()\n"
  },
  {
    "path": "code/default/smart_router/local/global_var.py",
    "content": "\nrunning = True\n\ngae_proxy = None\nx_tunnel = None\n\nconfig = None\nip_region = None\ngfwlist = None\ndomain_cache = None\nip_cache = None\nuser_rules = None\n\nconnect_manager = None\npipe_socks = None\ndns_client = None\n\nproxy_server = None\ndns_srv = None\ndns_query = None\n\ngae_proxy_listen_port = None\nx_tunnel_socks_port = None\nlocal_ips = []"
  },
  {
    "path": "code/default/smart_router/local/host_records.py",
    "content": "import os\nimport threading\nimport time\nimport collections\n\nfrom . import global_var as g\n\nimport utils\nfrom xlog import getLogger\nxlog = getLogger(\"smart_router\")\n\n\ndef is_network_ok(ip):\n    if not g.gae_proxy:\n        return False\n\n    return g.gae_proxy.check_local_network.is_ok(ip)\n\n\nclass DomainRecords(object):\n    # File Format:\n    # ===============\n    # host $rule gae_acceptable [ip|CN,ip|CN ip_update_time]\n    # rule: direct, gae, socks, black, other\n    # gae_acceptable: 0 or 1, default 1\n    # CN: country name\n\n    # Cache struct\n    # ==============\n    # \"r\": rule\n    # \"g\": gae_acceptable\n    # \"dns\": { dns_type: [ip], ..}\n    # \"update\": $ip_update_time\n\n    def __init__(self, file_path, capacity=1000, ttl=3600):\n        self.file_path = file_path\n        self.capacity = capacity\n        self.ttl = ttl\n        self.cache = collections.OrderedDict()\n        self.last_save_time = time.time()\n        self.lock = threading.RLock()\n        self.last_update_time = 0\n        self.need_save = False\n        self.load()\n\n        self.running = True\n\n    def _get(self, domain):\n        with self.lock:\n            try:\n                record = self.cache[domain]\n\n                time_now = time.time()\n                if time_now - record[\"update\"] > self.ttl:\n                   record = None\n            except KeyError:\n                record = None\n\n            if not record:\n                record = {\"r\": \"unknown\", \"dns\": {}, \"g\": 1, \"query_count\": 0}\n            #self.cache[domain] = record\n            return record\n\n    def _set(self, domain, record):\n        with self.lock:\n            try:\n                self.cache.pop(domain)\n            except KeyError:\n                if len(self.cache) >= self.capacity:\n                    self.cache.popitem(last=False)\n\n            record[\"update\"] = time.time()\n            self.cache[domain] = record\n            self.need_save = True\n            self.last_update_time = time.time()\n\n    def clean(self):\n        with self.lock:\n            self.cache = collections.OrderedDict()\n        self.save(True)\n\n    def get_content(self):\n        socks_lines = []\n        gae_lines = []\n        direct_lines = []\n        with open(self.file_path, \"r\") as fd:\n            for line in fd.readlines():\n                if not line:\n                    continue\n                try:\n                    lp = line.split()\n                    if len(lp) < 2:\n                        continue\n\n                    rule = lp[1]\n                    if rule == \"socks\":\n                        socks_lines.append(line)\n                    elif rule == \"gae\":\n                        gae_lines.append(line)\n                    else:\n                        direct_lines.append(line)\n                except Exception as e:\n                    xlog.warn(\"rule line:%s fail:%r\", line, e)\n                    continue\n        return \"\".join(socks_lines + gae_lines + direct_lines)\n\n    def load(self):\n        if not os.path.isfile(self.file_path):\n            return\n\n        with self.lock:\n            with open(self.file_path, \"r\") as fd:\n                for line in fd.readlines():\n                    if not line:\n                        continue\n\n                    try:\n                        lp = line.split()\n                        if len(lp) == 3:\n                            domain = lp[0]\n                            rule = lp[1]\n                            gae_acceptable = int(lp[2])\n                            record = {\"r\": rule, \"ip\": {}, \"g\":gae_acceptable}\n                        elif len(lp) == 5:\n                            domain = lp[0]\n                            rule = lp[1]\n                            gae_acceptable = int(lp[2])\n\n                            record = {\"r\": rule, \"ip\":{}, \"g\":gae_acceptable}\n                        else:\n                            xlog.warn(\"rule line:%s fail\", line)\n                            continue\n                    except Exception as e:\n                        xlog.warn(\"rule line:%s fail:%r\", line, e)\n                        continue\n\n                    self.cache[domain] = record\n\n    def save(self, force=False):\n        time_now = time.time()\n        if not force:\n            if not self.need_save:\n                return\n\n            if time_now - self.last_save_time < 10:\n                return\n\n        with self.lock:\n            with open(self.file_path, \"w\") as fd:\n                for host, record in self.cache.items():\n                    line = utils.to_str(host) + \" \" + record[\"r\"] + \" \" + str(record[\"g\"]) + \" \"\n\n                    fd.write(line + \"\\n\")\n\n        self.last_save_time = time.time()\n        self.need_save = False\n\n    def set_ips(self, domain, ips, dns_type):\n        if not ips:\n            return ips\n\n        with self.lock:\n            record = self._get(domain)\n\n            if dns_type not in record[\"dns\"]:\n                record[\"dns\"][dns_type] = set(ips)\n            else:\n                for ip in ips:\n                    if ip in record[\"dns\"][dns_type]:\n                        continue\n                    record[\"dns\"][dns_type].add(ip)\n\n            self._set(domain, record)\n\n    def get_ips(self, domain, dns_type=None):\n        if domain not in self.cache:\n            return []\n\n        record = self._get(domain)\n        if not dns_type:\n            dns_types = [1, 28]\n        else:\n            dns_types = [dns_type]\n\n        ips = []\n        for dns_type in dns_types:\n            if dns_type not in record[\"dns\"]:\n                continue\n            ips += record[\"dns\"][dns_type]\n\n        return ips\n\n    def update_rule(self, domain, rule):\n        record = self._get(domain)\n        record[\"r\"] = rule\n        return self._set(domain, record)\n\n    def get_rule(self, domain):\n        record = self._get(domain)\n        return record[\"r\"]\n\n    def report_gae_deny(self, domain, port=None):\n        record = self._get(domain)\n        record[\"g\"] = 0\n        return self._set(domain, record)\n\n    def accept_gae(self, domain, port=None):\n        record = self._get(domain)\n        return record[\"g\"]\n\n    def get_query_count(self, domain):\n        record = self._get(domain)\n        return record[\"query_count\"]\n\n    def add_query_count(self, domain):\n        record = self._get(domain)\n        record[\"query_count\"] += 1\n        self._set(domain, record)\n\n\nclass IpRecord(object):\n    # File Format:\n    # =============\n    # ip $rule $connect_time $update_time\n    # rule: direct, gae, socks, black, other\n    # connect_time: -1(fail times), n>=0 connect time cost in ms.\n    # default: IPv4 6000, IPv6 4000\n    # fail: 7000 + (fail time * 1000)\n\n    # IPv6 will try first if IPv6 exist.\n\n    # Cache struct\n    # ==============\n    # \"r\": rule\n    # \"c\": $connect_time\n    # \"update\": $update_time\n\n    def __init__(self, file_path, capacity=1000, ttl=3600):\n        self.file_path = file_path\n        self.capacity = capacity\n        self.ttl = ttl\n        self.cache = collections.OrderedDict()\n        self.last_save_time = time.time()\n        self.lock = threading.Lock()\n        self.last_update_time = 0\n        self.need_save = False\n        self.load()\n\n        self.running = True\n\n    def get(self, ip):\n        ip = utils.to_str(ip)\n        with self.lock:\n            record = None\n            try:\n                record = self.cache.pop(ip)\n                self.cache[ip] = record\n            except KeyError:\n                pass\n            return record\n\n    def set(self, ip, record):\n        ip = utils.to_str(ip)\n        with self.lock:\n            try:\n                self.cache.pop(ip)\n            except KeyError:\n                if len(self.cache) >= self.capacity:\n                    self.cache.popitem(last=False)\n\n            self.cache[ip] = record\n            self.need_save = True\n            self.last_update_time = time.time()\n\n    def clean(self):\n        with self.lock:\n            self.cache = collections.OrderedDict()\n        self.save(True)\n\n    def get_content(self):\n        with open(self.file_path, \"r\") as fd:\n            content = fd.read()\n            return content\n\n    def load(self):\n        if not os.path.isfile(self.file_path):\n            return\n\n        with self.lock:\n            with open(self.file_path, \"r\") as fd:\n                for line in fd.readlines():\n                    if not line:\n                        continue\n\n                    lp = line.split()\n                    if len(lp) != 4:\n                        xlog.warn(\"rule line:%s fail\", line)\n                        continue\n\n                    ip = lp[0]\n                    if ip.startswith(\"b'\"):\n                        ip = ip[2:-1]\n                    rule = lp[1]\n                    connect_time = int(lp[2])\n                    update_time = int(lp[3])\n                    self.cache[ip] = {\"r\": rule, \"c\": connect_time, \"update\": update_time}\n\n    def save(self, force=False):\n        if not force:\n            if not self.need_save:\n                return\n\n            if time.time() - self.last_save_time < 10:\n                return\n\n        with self.lock:\n            with open(self.file_path, \"w\") as fd:\n                for ip in self.cache:\n                    record = self.cache[ip]\n                    rule = record[\"r\"]\n                    connect_time = record[\"c\"]\n                    update_time = record[\"update\"]\n\n                    fd.write(\"%s %s %d %d\\n\" % (ip, rule, connect_time, update_time))\n\n        self.last_save_time = time.time()\n        self.need_save = False\n\n    def get_connect_time(self, ip, port=None):\n        ip = utils.to_str(ip)\n        record = self.get(ip)\n        if not record or time.time() - record[\"update\"] > self.ttl:\n            if utils.check_ip_valid4(ip):\n                return 6000\n            else:\n                return 4000\n        else:\n            return record[\"c\"]\n\n    def update_rule(self, ip, port, rule):\n        ip = utils.to_str(ip)\n        record = self.get(ip)\n        if b\".\" in ip:\n            connect_time = 6000\n        else:\n            connect_time = 4000\n\n        if not record:\n            record = {\"r\": rule, \"c\": connect_time}\n        else:\n            record[\"r\"] = rule\n\n        record[\"update\"] = time.time()\n        return self.set(ip, record)\n\n    def update_connect_time(self, ip, port, connect_time):\n        ip = utils.to_str(ip)\n        record = self.get(ip)\n        if not record:\n            record = {\"r\": \"direct\", \"c\": connect_time}\n        else:\n            record[\"c\"] = connect_time\n        record[\"update\"] = time.time()\n        return self.set(ip, record)\n\n    def report_connect_fail(self, ip, port):\n        ip = utils.to_str(ip)\n        if not is_network_ok(ip):\n            return\n\n        record = self.get(ip)\n        if not record:\n            record = {\"r\": \"direct\", \"c\": 7000}\n        else:\n            if record[\"c\"] <= 7000:\n                record[\"c\"] = 7000\n            else:\n                record[\"c\"] += 1000\n        record[\"update\"] = time.time()\n        return self.set(ip, record)"
  },
  {
    "path": "code/default/smart_router/local/ip_region.py",
    "content": "#!/usr/bin/env python\n# coding: utf-8\n\nimport os\nimport struct\nimport sys\nimport socket\ntry:\n    from urllib.request import urlopen\nexcept ImportError:\n    from urllib2 import urlopen\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nlauncher_path = os.path.abspath( os.path.join(current_path, os.pardir, os.pardir, \"launcher\"))\n\nroot_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))\ntop_path = os.path.abspath(os.path.join(root_path, os.pardir, os.pardir))\n\nif __name__ == '__main__':\n    python_path = root_path\n    noarch_lib = os.path.abspath(os.path.join(python_path, 'lib', 'noarch'))\n    sys.path.append(noarch_lib)\n\n\nimport env_info\nimport utils\nfrom xlog import getLogger\nxlog = getLogger(\"smart_router\")\n\ndata_path = os.path.join(env_info.data_path, \"smart_router\")\n\n\nclass IpRegion(object):\n    cn_ipv4_range = os.path.join(current_path, \"cn_ipv4_range.txt\")\n    cn_ipdb = os.path.join(data_path, \"cn_ipdb.dat\")\n\n    def __init__(self):\n        self.cn = b\"CN\"\n        self.ipdb = self.load_db()\n\n    def load_db(self):\n        if not os.path.isfile(self.cn_ipdb):\n            self.generate_db()\n\n        with open(self.cn_ipdb, 'rb') as f:\n            # 读取 IP 范围数据长度 BE Ulong -> int\n            data_len, = struct.unpack('>L', f.read(4))\n            # 读取索引数据\n            index = f.read(224 * 4)\n            # 读取 IP 范围数据\n            data = f.read(data_len)\n            # 简单验证结束\n            if f.read(3) != b'end':\n                raise ValueError('%s file format error' % self.cn_ipdb)\n            # 读取更新信息\n            self.update = f.read().decode('ascii')\n        # 格式化并缓存索引数据\n        # 使用 struct.unpack 一次性分割数据效率更高\n        # 每 4 字节为一个索引范围 fip：BE short -> int，对应 IP 范围序数\n        self.index = struct.unpack('>' + 'h' * (224 * 2), index)\n        # 每 8 字节对应一段直连 IP 范围和一段非直连 IP 范围\n        self.raw_data = data\n\n    def check_ip(self, ip):\n        ip = utils.to_str(ip)\n        if \":\" in ip:\n            return False\n\n        #转换 IP 为 BE Uint32，实际类型 bytes\n        nip = socket.inet_aton(ip)\n        #确定索引范围\n        index = self.index\n        fip = ord(nip[0:1])\n        #从 224 开始都属于保留地址\n        if fip >= 224:\n            return True\n        fip *= 2\n        lo = index[fip]\n        if lo < 0:\n            return False\n        hi = index[fip + 1]\n        #与 IP 范围比较确定 IP 位置\n        while lo < hi:\n            mid = (lo + hi) // 2\n            mid_dat_raw = self.raw_data[mid * 4: mid*4 + 4]\n            mid_dat = struct.unpack('4s', mid_dat_raw)[0]\n            if mid_dat > nip:\n                hi = mid\n            else:\n                lo = mid + 1\n        #根据位置序数奇偶确定是否属于直连 IP\n        return lo & 1\n\n    def check_ips(self, ips):\n        # return True if any ip in China\n        ips = utils.to_str(ips)\n        for ip in ips:\n            try:\n                if self.check_ip(ip):\n                    return True\n            except Exception as e:\n                xlog.exception(\"check ip %s fail:%r\", ip, e)\n\n        return False\n\n    def generate_db(self):\n        keeprange = (\n                     '0.0.0.0/8',  # 本地网络\n                     '10.0.0.0/8',  # 私有网络\n                     '100.64.0.0/10',  # 地址共享（运营商 NAT）\n                     '127.0.0.0/8',  # 环回地址\n                     '169.254.0.0/16',  # 链路本地\n                     '172.16.0.0/12',  # 私有网络\n                     '192.0.0.0/24',  # 保留地址（IANA）\n                     '192.0.2.0/24',  # TEST-NET-1\n                     '192.88.99.0/24',  # 6to4 中继\n                     '192.168.0.0/16',  # 私有网络\n                     '198.18.0.0/15',  # 网络基准测试\n                     '198.51.100.0/24',  # TEST-NET-2\n                     '203.0.113.0/24',  # TEST-NET-3\n                     # 连续地址直到 IP 结束，特殊处理\n                     '224.0.0.0/4',  #组播地址（D类）\n                     # '240.0.0.0/4',  #保留地址（E类）\n                     )\n        keeplist = []\n        for iprange in keeprange:\n            ip, mask = iprange.split('/')\n            keeplist.append((utils.ip_string_to_num(ip), 32 - int(mask)))\n\n        mask_dict = dict((str(2 ** i), i) for i in range(8, 25))\n\n        def int2bytes2(n, pack=struct.pack):\n            '''将整数转换为大端序字节'''\n            return pack('>H', n)\n            # return bytes(map(lambda b: (-1 >> b & 255), (8, 0)))\n\n        def int2bytes4(n, pack=struct.pack):\n            '''将整数转换为大端序字节'''\n            return pack('>I', n)\n            # return bytes(map(lambda b: (n >> b & 255), (24, 16, 8, 0)))\n\n        def bytes2int(s):\n\n            nchars = len(s)\n            # string to int or long. Type depends on nchars\n            x = sum(ord(s[byte]) << 8 * (nchars - byte - 1) for byte in range(nchars))\n            return x\n\n\n        #    +---------+\n        #    | 4 bytes |                     <- data length\n        #    +---------------+\n        #    | 224 * 4 bytes |               <- first ip number index\n        #    +---------------+\n        #    |  2n * 4 bytes |               <- cn ip ranges data\n        #    +------------------------+\n        #    | b'end' and update info |      <- end verify\n        #    +------------------------+\n        lastip_s = 0\n        lastip_e = 0\n        index = {}\n        index_n = 0\n        index_fip = -1\n        offset = 0\n\n        padding = b'\\xff\\xff'\n        update = \"\"\n\n        iplist = []\n        fdi = open(self.cn_ipv4_range,\"r\")\n        for line in fdi.readlines():\n            line = line.strip()\n            if not line or line.startswith(\"#\"):\n                continue\n\n            if \"/\" in line:\n                lp = line.split(\"/\")\n                iplist.append((utils.ip_string_to_num(lp[0]), int(lp[1])))\n            else:\n                lp = line.split()\n                iplist.append((utils.ip_string_to_num(lp[0]), mask_dict[lp[1]]))\n\n        iplist.extend(keeplist)\n        # 排序，不然无法处理\n        iplist.sort(key=lambda x: x[0])\n        # 随便算一下\n        buffering = len(iplist) * 8 + 224 * 4 + 64 + 4\n        buffer = bytearray(buffering)\n        for ip, mask in iplist:\n            ip_s = ip >> mask << mask\n            ip_e = (ip >> mask) + 1 << mask\n            # 判断连续\n            if ip_s <= lastip_e:\n                # 判断覆盖\n                if ip_e > lastip_e:\n                    lastip_e = ip_e\n                continue\n            # 排除初始值\n            if lastip_e:\n                # 一段范围分为包含和排除\n                buffer[offset:] = lastip_s = int2bytes4(lastip_s)\n                buffer[offset + 4:] = int2bytes4(lastip_e)\n                # 一个索引分为开始和结束\n                fip = ord(lastip_s[0:1]) * 2\n                if fip != index_fip:\n                    # 前一个索引结束，序数多 1\n                    # 避免无法搜索从当前索引结尾地址到下个索引开始地址\n                    index[index_fip + 1] = index_b = int2bytes2(index_n)\n                    # 当前索引开始\n                    index[fip] = index_b\n                    index_fip = fip\n                index_n += 2\n                offset += 8\n            lastip_s = ip_s\n            lastip_e = ip_e\n        # 添加最后一段范围\n        buffer[offset:] = lastip_s = int2bytes4(lastip_s)\n        buffer[offset + 4:] = int2bytes4(lastip_e)\n        fip = ord(lastip_s[0:1]) * 2\n        if fip != index_fip:\n            index[index_fip + 1] = index_b = int2bytes2(index_n)\n            index[fip] = index_b\n        index_n += 2\n        offset += 8\n        # 添加最后一个结束索引\n        index[fip + 1] = int2bytes2(index_n)\n        # 写入文件\n        fd = open(self.cn_ipdb, 'wb', buffering)\n        fd.write(int2bytes4(offset))\n        for i in range(224 * 2):\n            fd.write(index.get(i, padding))\n        fd.write(buffer[:offset])\n        fd.write(b'endCN IP from ')\n        fd.write(update.encode('ascii'))\n\n        count = int(index_n // 2)\n        fd.write(b', range count: %d' % count)\n        fd.close()\n\n        xlog.debug('include IP range number: %s' % count)\n        xlog.debug('save to file:%s' % self.cn_ipdb)\n\n\nclass UpdateIpRange(object):\n    cn_ipv4_range = os.path.join(current_path, \"cn_ipv4_range.txt\")\n\n    def __init__(self):\n        fn = os.path.join(data_path, \"apnic.txt\")\n\n        self.download_apnic(fn)\n        self.save_apnic_cniplist(fn)\n\n    def download_apnic(self, fn):\n        import subprocess\n        url = 'https://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest'\n        try:\n            data = subprocess.check_output(['wget', url, '-O-'])\n        except (OSError, AttributeError):\n            xlog.info(\"Fetching data from apnic.net, it might take a few minutes, please wait...\")\n            data = urlopen(url).read()\n\n        with open(fn, \"bw\") as f:\n            f.write(data)\n        return data\n\n    def save_apnic_cniplist(self, fn):\n        try:\n            fd = open(fn, \"br\")\n            fw = open(self.cn_ipv4_range, \"bw\")\n            for line in fd.readlines():\n                if line.startswith(b'apnic|CN|ipv4'):\n                    ip = line.split(b'|')\n                    if len(ip) > 5:\n                        fw.write(b\"%s %s\\n\" % (ip[3], ip[4]))\n\n        except Exception as e:\n            xlog.exception(\"parse_apnic_cniplist %s e:%r\", fn, e)\n\n\nif __name__ == '__main__':\n    up = UpdateIpRange()\n    ipr = IpRegion()\n    xlog.info(\"8.8.8.8: %s\", ipr.check_ip(\"8.8.8.8\"))\n    xlog.info(\"114.114.114.114: %s\", ipr.check_ip(\"114.111.114.114\"))\n"
  },
  {
    "path": "code/default/smart_router/local/pac_server.py",
    "content": "#!/usr/bin/env python\n# coding:utf-8\n\nimport os\n\ntry:\n    from urllib.parse import urlparse\nexcept ImportError:\n    from urlparse import urlparse\n\nimport simple_http_server\nimport env_info\nfrom . import global_var as g\nfrom xlog import getLogger\nxlog = getLogger(\"smart_router\")\nimport utils\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\n\nroot_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))\ntop_path = os.path.abspath(os.path.join(root_path, os.pardir, os.pardir))\ndata_path = os.path.join(env_info.data_path, \"smart_router\")\n\ndefault_pacfile = os.path.join(current_path, \"proxy.pac\")\nuser_pacfile = os.path.join(data_path, \"proxy.pac\")\n\ngae_ca_file = os.path.join(env_info.data_path, \"gae_proxy\", \"CA.crt\")\n\n\nallow_policy = [\"black_GAE\", \"black_X-Tunnel\", \"smart-router\", \"all_X-Tunnel\", \"all_Direct\"]\n\n\ndef get_serving_pacfile():\n    if not os.path.isfile(user_pacfile):\n        serving_pacfile = default_pacfile\n    else:\n        serving_pacfile = user_pacfile\n\n    with open(serving_pacfile, 'r') as fp:\n        content = fp.read()\n\n    return content\n\n\nclass PacHandler(simple_http_server.HttpServerHandler):\n    PROXY_LISTEN = \"PROXY_LISTEN\"\n\n    def policy_all_to_proxy(self, host, port):\n        content = \"\"\"function FindProxyForURL(url, host) { return 'PROXY PROXY_LISTEN';}\"\"\"\n\n        proxy = host + \":\" + str(port)\n        content = content.replace(self.PROXY_LISTEN, proxy)\n        return content\n\n    def policy_all_to_direct(self):\n        content = \"\"\"function FindProxyForURL(url, host) { return 'DIRECT';}\"\"\"\n        return content\n\n    def policy_blacklist_to_proxy(self, host, port):\n        content = get_serving_pacfile()\n\n        proxy = host + \":\" + str(port)\n        content = content.replace(self.PROXY_LISTEN, proxy)\n\n        black_list = tuple([domain[1:] for domain in g.gfwlist.gfw_black_list])\n        white_list = tuple([domain[1:] for domain in g.gfwlist.gfw_white_list])\n\n        black = b'\",\\n\"'.join(black_list\n                             + g.user_rules.rule_lists[\"gae\"]\n                             + g.user_rules.rule_lists[\"socks\"]\n                             )\n        white = b'\",\\n\"'.join(white_list + g.user_rules.rule_lists[\"direct\"])\n\n        content = content.replace(\"BLACK_LIST\", utils.to_str(black)).replace(\"WHITE_LIST\", utils.to_str(white))\n        return content\n\n    def do_GET(self):\n        path = urlparse(self.path).path # '/proxy.pac'\n        path = utils.to_str(path)\n        self.headers = utils.to_str(self.headers)\n\n        filename = os.path.normpath('./' + path)\n        if filename != 'proxy.pac':\n            xlog.warn(\"pac_server GET %s fail\", self.path)\n            return self.send_not_found()\n\n        host = self.headers.get('Host')\n        host, _, port = host.rpartition(\":\")\n\n        if g.config.pac_policy == \"black_GAE\":\n            content = self.policy_blacklist_to_proxy(host, \"%s\" % g.gae_proxy_listen_port)\n        elif g.config.pac_policy == \"black_X-Tunnel\":\n            content = self.policy_blacklist_to_proxy(host, \"%s\" % g.x_tunnel_socks_port)\n        elif g.config.pac_policy == \"all_X-Tunnel\":\n            content = self.policy_all_to_proxy(host, \"%s\" % g.x_tunnel_socks_port)\n        elif g.config.pac_policy == \"all_Direct\":\n            content = self.policy_all_to_direct()\n        else:\n            content = self.policy_all_to_proxy(host, g.config.proxy_port)\n\n        self.send_response('application/x-ns-proxy-autoconfig', content)\n"
  },
  {
    "path": "code/default/smart_router/local/pipe_socks.py",
    "content": "import threading\nimport time\nimport sys\nimport socket\nimport errno\n\nfrom xx_six import BlockingIOError\nimport utils\nimport selectors2 as selectors\n\nfrom . import global_var as g\nfrom xlog import getLogger\nxlog = getLogger(\"smart_router\")\n\n\nclass PipeSocks(object):\n    def __init__(self, buf_size=16*1024):\n        self.buf_size = buf_size\n\n        self.select2 = selectors.DefaultSelector()\n        self.read_set = set([])\n        self.write_set = set([])\n\n        self.running = True\n        self.sock_lock = threading.Lock()\n        self.sock_notify = threading.Condition(self.sock_lock)\n\n    def __str__(self):\n        outs = [\"Pipe Sockets:\"]\n        outs.append(\"buf_size=%d\" % self.buf_size)\n        outs.append(\"running=%d\" % self.running)\n        outs.append(\"\")\n\n        outs.append(\"read dict:\")\n        for s in self.read_set:\n            outs.append(\" %s\" % s)\n\n        outs.append(\"write dict:\")\n        for s in self.write_set:\n            outs.append(\" %s\" % s)\n\n        return \"\\n\".join(outs)\n\n    def run(self):\n        self.down_th = threading.Thread(target=self.pipe, name=\"pipe\")\n        self.down_th.start()\n\n    def stop(self):\n        self.running = False\n        with self.sock_notify:\n            for s in list(self.read_set) + list(self.write_set):\n                self.close(s, \"stop\")\n\n            self.sock_notify.notify()\n\n    def add_socks(self, s1, s2):\n        for s in [s1, s2]:\n            if hasattr(s._sock, \"socket_closed\") and s._sock.socket_closed:\n                xlog.error(\"try to add_socks closed socket:%s %s\", s1, s2)\n                s1.close()\n                s2.close()\n                return\n\n        s1.setblocking(0)\n        s2.setblocking(0)\n\n        with self.sock_notify:\n            s1.pair_sock = s2\n            s2.pair_sock = s1\n            # self.select2.register(s1, selectors.EVENT_READ)\n            # self.select2.register(s2, selectors.EVENT_READ)\n            # self.read_set.add(s1)\n            # self.read_set.add(s2)\n            self.try_add(\"READ\", s1)\n            self.try_add(\"READ\", s2)\n\n            self.sock_notify.notify()\n\n    def try_add(self, l, s):\n        try:\n            if l == \"READ\":\n                if s in self.read_set:\n                    # xlog.warn(\"%s already in read set\", s)\n                    pass\n                else:\n                    if s in self.write_set:\n                        self.select2.modify(s, selectors.EVENT_WRITE | selectors.EVENT_READ)\n                        # xlog.debug(\"change %s to read|write\", s)\n                    else:\n                        self.select2.register(s, selectors.EVENT_READ)\n                        # xlog.debug(\"change %s to read\", s)\n                    self.read_set.add(s)\n            elif l == \"WRITE\":\n                if s in self.write_set:\n                    # xlog.warn(\"%s already in write set\", s)\n                    pass\n                else:\n                    if s in self.read_set:\n                        self.select2.modify(s, selectors.EVENT_WRITE | selectors.EVENT_READ)\n                        # xlog.debug(\"change %s to read|write\", s)\n                    else:\n                        self.select2.register(s, selectors.EVENT_WRITE)\n                        # xlog.debug(\"change %s to write\", s)\n                    self.write_set.add(s)\n            else:\n                xlog.error(\"unknown list %s\", l)\n        except Exception as e:\n            xlog.exception(\"try_add e:%r\", e)\n\n    def try_remove(self, l, s):\n        try:\n            if l == \"READ\":\n                if s in self.read_set:\n                    if s in self.write_set:\n                        self.select2.modify(s, selectors.EVENT_WRITE)\n                        # xlog.debug(\"modify to write %s\", s)\n                    else:\n                        self.select2.unregister(s)\n                        # xlog.debug(\"unregister %s\", s)\n                    self.read_set.remove(s)\n            elif l == \"WRITE\":\n                if s in self.write_set:\n                    if s in self.read_set:\n                        self.select2.modify(s, selectors.EVENT_READ)\n                        # xlog.debug(\"modify to read %s\", s)\n                    else:\n                        self.select2.unregister(s)\n                        # xlog.debug(\"unregister %s\", s)\n                    self.write_set.remove(s)\n            else:\n                xlog.error(\"unknown list %s\", l)\n        except Exception as e:\n            xlog.exception(\"try_remove e:%r\", e)\n\n    def close(self, s1, e):\n        xlog.debug(\"%s close\", s1)\n\n        s2 = s1.pair_sock\n\n        if utils.is_private_ip(s1.ip):\n            local_sock = s1\n            remote_sock = s2\n        else:\n            local_sock = s2\n            remote_sock = s1\n\n        create_time = time.time() - remote_sock.create_time\n        xlog.debug(\"pipe close %s->%s run_time:%.2f upload:%d(%d)->%d(%d) download:%d(%d)->%d(%d), by remote:%d, server left:%d client left:%d e:%r\",\n                   local_sock, remote_sock, create_time,\n                   local_sock.recved_data, local_sock.recved_times, remote_sock.sent_data, remote_sock.sent_times,\n                   remote_sock.recved_data, remote_sock.recved_times, local_sock.sent_data, local_sock.sent_times,\n                   s1==remote_sock, remote_sock.buf_size, local_sock.buf_size, e)\n\n        if local_sock.recved_data > 0 and local_sock.recved_times == 1 and remote_sock.port == 443 and \\\n                ((s1 == local_sock and create_time > 30) or (s1 == remote_sock)):\n            host = remote_sock.host\n            xlog.debug(\"SNI:%s fail.\", host)\n            #g.domain_cache.update_rule(host, 443, \"gae\")\n\n        self.try_remove(\"READ\", s1)\n        self.try_remove(\"WRITE\", s1)\n        s1.close()\n\n        if s2.buf_size:\n            xlog.debug(\"pipe close %s e:%s, but s2:%s have data(%d) to send\", s1, e, s2, s2.buf_size)\n            s2.add_dat(\"\")  # add empty block to close socket.\n            return\n\n        if not s2.is_closed():\n            self.try_remove(\"READ\", s2)\n            self.try_remove(\"WRITE\", s2)\n            s2.close()\n\n    def pipe(self):\n        def flush_send_s(s2, d1):\n            # xlog.debug(\"pipe flush_send_s %s %d\", s2, len(d1))\n            s2.setblocking(1)\n            s2.settimeout(1)\n            s2.sendall(d1)\n            s2.setblocking(0)\n\n        while self.running:\n            if not self.read_set and not self.write_set:\n                with self.sock_notify:\n                    self.sock_notify.wait()\n                continue\n\n            try:\n                # r, w, error_set = select.select(self.read_set, self.write_set, self.error_set, 0.1)\n                events = self.select2.select(timeout=5)\n            except ValueError as e:\n                xlog.exception(\"pipe select except:%r\", e)\n                return\n\n            read_list = []\n            write_list = []\n            error_list = []\n            for key, event in events:\n                s1 = key.fileobj\n                if event & selectors.EVENT_READ:\n                    s1.can_read = True\n                    read_list.append(s1)\n                    # xlog.debug(\"get read on %s\", s1)\n                elif event & selectors.EVENT_WRITE:\n                    s1.can_write = True\n                    write_list.append(s1)\n                    # xlog.debug(\"get write on %s\", s1)\n                else:\n                    error_list.append(s1)\n                    xlog.error(\"get error on %s\", s1)\n\n            try:\n                for s1 in read_list:\n                    if s1.is_closed():\n                        continue\n\n                    try:\n                        d = s1.recv(65535)\n                    except BlockingIOError as e:\n                        xlog.debug(\"%s recv BlockingIOError:%r\", s1, e)\n                        continue\n                    except Exception as e:\n                        xlog.debug(\"%s recv e:%r\", s1, e)\n                        self.close(s1, \"r\")\n                        continue\n\n                    if not d:\n                        # socket closed by peer.\n                        xlog.debug(\"%s recv empty, close\", s1)\n                        self.close(s1, \"r\")\n                        continue\n\n                    # xlog.debug(\"direct received %d bytes from:%s\", len(d), s1)\n                    s1.recved_data += len(d)\n                    s1.recved_times += 1\n\n                    s2 = s1.pair_sock\n                    if s2.is_closed():\n                        # xlog.debug(\"s2:%s is closed\", s2)\n                        continue\n\n                    if g.config.direct_split_SNI and\\\n                                    s1.recved_times == 1 and \\\n                                    s2.port == 443 and \\\n                                    d[0] == '\\x16' and \\\n                            g.gfwlist.in_block_list(s2.host):\n                        p1 = d.find(s2.host)\n                        if p1 > 1:\n                            if b\"google\" in s2.host:\n                                p2 = d.find(b\"google\") + 3\n                            else:\n                                p2 = p1 + len(s2.host) - 6\n\n                            d1 = d[:p2]\n                            d2 = d[p2:]\n\n                            try:\n                                flush_send_s(s2, d1)\n                                s2.sent_data += len(d1)\n                                s2.sent_times += 1\n                            except BlockingIOError as e:\n                                xlog.warn(\"Except %s flush_send_s BlockingIOError %r\", s2, e)\n                                self.close(s2, \"w\")\n                                continue\n                            except Exception as e:\n                                xlog.warn(\"send split SNI:%s fail:%r\", s2.host, e)\n                                self.close(s2, \"w\")\n                                continue\n\n                            s2.add_dat(d2)\n                            d = b\"\"\n                            xlog.debug(\"pipe send split SNI:%s\", s2.host)\n\n                    if s2.buf_size == 0:\n                        try:\n                            sent = s2.send(d)\n                            s2.sent_data += sent\n                            s2.sent_times += 1\n                            # xlog.debug(\"direct send %d to %s from:%s total:%d\", sent, s2, s1, len(d))\n                        except BlockingIOError as e:\n                            xlog.warn(\"Except %s send BlockingIOError %r\", s2, e)\n                            sent = 0\n                        except socket.error as e:\n                            if e.errno == errno.EAGAIN:\n                                # if str(e) == \"[Errno 35] Resource temporarily unavailable\":\n                                xlog.warn(\"%s send errno.EAGAIN %r\", s2, e)\n                                time.sleep(0.1)\n                                sent = 0\n                            else:\n                                self.close(s2, \"w\")\n                                continue\n                        except Exception as e:\n                            # xlog.debug(\"%s send e:%r\", s2, e)\n                            if sys.version_info[0] == 3 and isinstance(e, BlockingIOError):\n                                # This error happened on upload large file or speed test\n                                # Just ignore this error and will be fine\n                                xlog.warn(\"%s send BlockingIOError %r\", s2, e)\n                                sent = 0\n                            else:\n                                # xlog.warn(\"%s send except:%r\", s2, e)\n                                self.close(s2, \"w\")\n                                continue\n\n                        if sent == len(d):\n                            # xlog.debug(\"direct send all from %s to %s\", s1, s2)\n                            continue\n                        else:\n                            # xlog.debug(\"direct send from %s to %s, total:%d left:%d\", s1, s2, len(d), len(d)-sent)\n                            d_view = memoryview(d)\n                            d = d_view[sent:]\n\n                    if d:\n                        if not isinstance(d, memoryview):\n                            d = memoryview(d)\n                        s2.add_dat(d)\n\n                    self.try_add(\"WRITE\", s2)\n\n                    if s2.buf_size > self.buf_size:\n                        self.try_remove(\"READ\", s1)\n\n                for s1 in write_list:\n                    if s1 not in self.write_set:\n                        xlog.error(\"%s not in write list\", s1)\n                        continue\n\n                    if s1.buf_num == 0:\n                        xlog.error(\"%s write event but no buf\", s1)\n                        self.try_remove(\"WRITE\", s1)\n                        continue\n\n                    while s1.buf_num:\n                        dat = s1.get_dat()\n                        if not dat:\n                            xlog.error(\"%s get data fail\", s1)\n                            self.close(s1, \"n\")\n                            break\n\n                        try:\n                            sent = s1.send(dat)\n                            s1.sent_data += sent\n                            s1.sent_times += 1\n                            # xlog.debug(\"send buffered %d bytes to %s\", sent, s1)\n                        except BlockingIOError as e:\n                            xlog.warn(\"Except %s send BlockingIOError %r\", s1, e)\n                            sent = 0\n                        except socket.error as e:\n                            if e.errno == errno.EAGAIN:\n                                # if str(e) == \"[Errno 35] Resource temporarily unavailable\":\n                                xlog.warn(\"%s send errno.EAGAIN %r\", s1, e)\n                                time.sleep(0.1)\n                                sent = 0\n                            else:\n                                self.close(s1, \"w\")\n                                continue\n                        except Exception as e:\n                            if sys.version_info[0] == 3 and isinstance(e, BlockingIOError):\n                                # This error happened on upload large file or speed test\n                                # Just ignore this error and will be fine\n                                xlog.debug(\"%s sent BlockingIOError %r\", s1, e)\n                                sent = 0\n                            else:\n                                # xlog.debug(\"%s sent e:%r\", s1, e)\n                                self.close(s1, \"w\")\n                                break\n\n                        if len(dat) - sent > 0:\n                            s1.restore_dat(dat[sent:])\n                            break\n\n                    if s1.buf_size < self.buf_size:\n                        if not s1.buf_size:\n                            self.try_remove(\"WRITE\", s1)\n\n                        if s1.is_closed():\n                            # xlog.debug(\"%s can send but removed\", s1)\n                            continue\n\n                        s2 = s1.pair_sock\n                        if s2.is_closed():\n                            if s1.buf_size == 0:\n                                self.close(s1, \"n\")\n                            continue\n\n                        self.try_add(\"READ\", s2)\n\n                for s1 in error_list:\n                    xlog.error(\"close pipe %s in error list\", s1)\n                    self.close(s1, \"e\")\n            except Exception as e:\n                xlog.exception(\"pipe except:%r\", e)\n\n        with self.sock_notify:\n            for s in list(self.read_set) + list(self.write_set):\n                self.close(s, \"stop\")\n\n        xlog.info(\"pipe stopped.\")"
  },
  {
    "path": "code/default/smart_router/local/proxy.pac",
    "content": "/**\r\n * fork from genpac 2.0.1 https://github.com/JinnLynn/genpac\r\n * GFWList From: online[https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt]\r\n */\r\n\r\nvar black_list = [\r\n    \"BLACK_LIST\"\r\n];\r\n\r\nvar white_list = [\r\n    \"WHITE_LIST\"\r\n];\r\n\r\nvar proxy = 'PROXY PROXY_LISTEN';\r\nfunction FindProxyForURL(url, host) {\r\n\r\n    for (var i = 0; i < white_list.length; i++) {\r\n        var host_end = white_list[i];\r\n        if (host == host_end || host.endsWith('.' + host_end)) {\r\n            return 'DIRECT';\r\n        }\r\n    }\r\n\r\n    for (var i = 0; i < black_list.length; i++) {\r\n        var host_end = black_list[i];\r\n        if (host == host_end || host.endsWith('.' + host_end)) {\r\n            return proxy;\r\n        }\r\n    }\r\n    return 'DIRECT';\r\n}\r\n\r\n\r\n// REF: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith\r\nif (!String.prototype.endsWith) {\r\n    String.prototype.endsWith = function(searchString, position) {\r\n        var subjectString = this.toString();\r\n        if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) {\r\n            position = subjectString.length;\r\n        }\r\n        position -= searchString.length;\r\n        var lastIndex = subjectString.indexOf(searchString, position);\r\n        return lastIndex !== -1 && lastIndex === position;\r\n    };\r\n}\r\n"
  },
  {
    "path": "code/default/smart_router/local/proxy_handler.py",
    "content": "import time\nimport socket\nimport struct\nimport json\n\ntry:\n    from urllib.parse import urlparse\n    from urllib.parse import parse_qs\nexcept ImportError:\n    from urlparse import urlparse\n\nfrom . import pac_server\nfrom . import global_var as g\nfrom .socket_wrap import SocketWrap\nimport utils\nfrom .smart_route import handle_ip_proxy, handle_domain_proxy, netloc_to_host_port\nfrom xlog import getLogger\nxlog = getLogger(\"smart_router\")\n\nSO_ORIGINAL_DST = 80\n\n\nclass ProxyServer():\n    handle_num = 0\n\n    def __init__(self, sock, client, args):\n        self.conn = sock\n        self.rfile = self.conn.makefile(\"rb\", 0)\n        self.wfile = self.conn.makefile(\"wb\", 0)\n        self.client_address = client\n\n        self.read_buffer = b\"\"\n        self.buffer_start = 0\n        self.support_redirect = True\n\n    def try_redirect(self):\n        if not self.support_redirect:\n            return False\n\n        try:\n            dst = self.conn.getsockopt(socket.SOL_IP, SO_ORIGINAL_DST, 16)\n        except:\n            self.support_redirect = False\n            return False\n\n        try:\n            dst_port, srv_ip = struct.unpack(\"!2xH4s8x\", dst)\n            ip_str = socket.inet_ntoa(srv_ip)\n\n            if dst_port == g.config.proxy_port and utils.to_bytes(ip_str) in g.local_ips:\n                return False\n\n            xlog.debug(\"Redirect to:%s:%d from:%s\", ip_str, dst_port, self.client_address)\n            handle_ip_proxy(self.conn, ip_str, dst_port, self.client_address)\n        except Exception as e:\n            xlog.exception(\"redirect except:%r\", e)\n\n        return True\n\n    def handle(self):\n        self.__class__.handle_num += 1\n\n        if not self.try_redirect():\n            self.handle_request()\n\n    def handle_request(self):\n        try:\n            socks_version = self.conn.recv(1, socket.MSG_PEEK)\n            if not socks_version:\n                return\n\n            if socks_version == b\"\\x04\":\n                self.socks4_handler()\n            elif socks_version == b\"\\x05\":\n                self.socks5_handler()\n            elif socks_version == b\"C\":\n                self.https_handler()\n            elif socks_version in [b\"G\", b\"P\", b\"D\", b\"O\", b\"H\", b\"T\"]:\n                self.http_handler()\n            else:\n                xlog.warn(\"socks version:%s[%s] not supported\", socks_version, utils.str2hex(socks_version))\n                return\n\n        except socket.error as e:\n            xlog.warn('socks handler read error:%r', e)\n            self.conn.close()\n        except Exception as e:\n            xlog.exception(\"any err:%r\", e)\n            self.conn.close()\n\n    def read_null_end_line(self):\n        sock = self.conn\n        sock.setblocking(0)\n        try:\n            while True:\n                n1 = self.read_buffer.find(b\"\\x00\", self.buffer_start)\n                if n1 > -1:\n                    line = self.read_buffer[self.buffer_start:n1]\n                    self.buffer_start = n1 + 1\n                    return line\n\n                try:\n                    data = sock.recv(8192)\n                except socket.error as e:\n                    # logging.exception(\"e:%r\", e)\n                    if e.errno in [2, 11, 10035]:\n                        time.sleep(0.01)\n                        continue\n                    else:\n                        raise e\n\n                self.read_buffer += data\n        finally:\n            sock.setblocking(1)\n\n    def read_crlf_line(self):\n        sock = self.conn\n        sock.setblocking(0)\n        try:\n            while True:\n                n1 = self.read_buffer.find(b\"\\r\\n\", self.buffer_start)\n                if n1 > -1:\n                    line = self.read_buffer[self.buffer_start:n1]\n                    self.buffer_start = n1 + 2\n                    return line\n\n                try:\n                    data = sock.recv(8192)\n                except socket.error as e:\n                    # logging.exception(\"e:%r\", e)\n                    if e.errno in [2, 11, 10035]:\n                        time.sleep(0.01)\n                        continue\n                    else:\n                        raise e\n\n                self.read_buffer += data\n        finally:\n            sock.setblocking(1)\n\n    def read_headers(self):\n        sock = self.conn\n        sock.setblocking(0)\n        try:\n            while True:\n                if self.read_buffer[self.buffer_start:] == b\"\\r\\n\":\n                    self.buffer_start += 2\n                    return \"\"\n\n                n1 = self.read_buffer.find(b\"\\r\\n\\r\\n\", self.buffer_start)\n                if n1 > -1:\n                    block = self.read_buffer[self.buffer_start:n1]\n                    self.buffer_start = n1 + 4\n                    return block\n\n                try:\n                    data = sock.recv(8192)\n                except socket.error as e:\n                    # logging.exception(\"e:%r\", e)\n                    if e.errno in [2, 11, 10035]:\n                        time.sleep(0.01)\n                        continue\n                    else:\n                        raise e\n\n                self.read_buffer += data\n        finally:\n            sock.setblocking(1)\n\n    def read_bytes(self, size):\n        sock = self.conn\n        sock.setblocking(1)\n        try:\n            while True:\n                left = len(self.read_buffer) - self.buffer_start\n                if left >= size:\n                    break\n\n                need = size - left\n\n                try:\n                    data = sock.recv(need)\n                except socket.error as e:\n                    # logging.exception(\"e:%r\", e)\n                    if e.errno in [2, 11, 10035]:\n                        time.sleep(0.01)\n                        continue\n                    else:\n                        raise e\n\n                if len(data):\n                    self.read_buffer += data\n                else:\n                    raise socket.error(\"recv fail\")\n        finally:\n            sock.setblocking(1)\n\n        data = self.read_buffer[self.buffer_start:self.buffer_start + size]\n        self.buffer_start += size\n        return data\n\n    def socks4_handler(self):\n        # Socks4 or Socks4a\n        sock = self.conn\n        socks_version = ord(self.read_bytes(1))\n        cmd = ord(self.read_bytes(1))\n        if cmd != 1:\n            xlog.warn(\"Socks4 cmd:%d not supported\", cmd)\n            return\n\n        data = self.read_bytes(6)\n        port = struct.unpack(\">H\", data[0:2])[0]\n        addr_pack = data[2:6]\n        if addr_pack[0:3] == b'\\x00\\x00\\x00' and addr_pack[3:4] != b'\\x00':\n            domain_mode = True\n        else:\n            ip = socket.inet_ntoa(addr_pack)\n            domain_mode = False\n\n        user_id = self.read_null_end_line()\n        if len(user_id):\n            xlog.debug(\"Socks4 user_id:%s\", user_id)\n\n        if domain_mode:\n            addr = self.read_null_end_line()\n        else:\n            addr = ip\n\n        reply = b\"\\x00\\x5a\" + addr_pack + struct.pack(\">H\", port)\n        sock.send(reply)\n\n        # xlog.debug(\"Socks4:%r to %s:%d\", self.client_address, addr, port)\n        if domain_mode:\n            handle_domain_proxy(sock, addr, port, self.client_address)\n        else:\n            handle_ip_proxy(sock, addr, port, self.client_address)\n\n    def handle_udp_associate(self, sock, addr, port, addrtype_pack, addr_pack):\n        udp_relay_port = g.dns_srv.udp_relay_port\n        xlog.debug(\"socks5 from:%r udp associate to %s:%d use udp_relay_port:%d\", self.client_address, addr, port, udp_relay_port)\n        reply = b\"\\x05\\x00\\x00\" + addrtype_pack + addr_pack + struct.pack(\">H\", udp_relay_port)\n        sock.send(reply)\n\n        self.rfile.read(1)\n        xlog.debug(\"socks5 from:%r udp associate to %s:%d closed\", self.client_address, addr, port)\n\n    def socks5_handler(self):\n        sock = self.conn\n        socks_version = ord(self.read_bytes(1))\n        auth_mode_num = ord(self.read_bytes(1))\n        data = self.read_bytes(auth_mode_num)\n\n        sock.send(b\"\\x05\\x00\")  # socks version 5, no auth needed.\n        try:\n            data = self.read_bytes(4)\n        except Exception as e:\n            xlog.debug(\"socks5 auth num:%d, list:%s\", auth_mode_num, utils.str2hex(data))\n            xlog.warn(\"socks5 protocol error:%r\", e)\n            return\n\n        socks_version = ord(data[0:1])\n        if socks_version != 5:\n            xlog.warn(\"request version:%d error\", socks_version)\n            return\n\n        command = ord(data[1:2])\n        addrtype_pack = data[3:4]\n        addrtype = ord(addrtype_pack)\n        if addrtype == 1:  # IPv4\n            addr_pack = self.read_bytes(4)\n            addr = socket.inet_ntoa(addr_pack)\n        elif addrtype == 3:  # Domain name\n            domain_len_pack = self.read_bytes(1)[0:1]\n            domain_len = ord(domain_len_pack)\n            domain = self.read_bytes(domain_len)\n            addr_pack = domain_len_pack + domain\n            addr = domain\n        elif addrtype == 4:  # IPv6\n            addr_pack = self.read_bytes(16)\n            addr = socket.inet_ntop(socket.AF_INET6, addr_pack)\n        else:\n            xlog.warn(\"request address type unknown:%d\", addrtype)\n            sock.send(b\"\\x05\\x07\\x00\\x01\")  # Command not supported\n            return\n        port = struct.unpack('>H', self.rfile.read(2))[0]\n\n        if command == 3:  # 3. UDP associate\n            return self.handle_udp_associate(sock, addr, port, addrtype_pack, addr_pack)\n\n        if command != 1:  # 1. Tcp connect\n            xlog.warn(\"request not supported command mode:%d\", command)\n            sock.send(b\"\\x05\\x07\\x00\\x01\")  # Command not supported\n            return\n\n        # xlog.debug(\"socks5 %r connect to %s:%d\", self.client_address, addr, port)\n        reply = b\"\\x05\\x00\\x00\" + addrtype_pack + addr_pack + struct.pack(\">H\", port)\n        sock.send(reply)\n\n        if addrtype in [1, 4]:\n            handle_ip_proxy(sock, addr, port, self.client_address)\n        else:\n            handle_domain_proxy(sock, addr, port, self.client_address)\n\n    def https_handler(self):\n        line = self.read_crlf_line()\n        line = line\n        words = line.split()\n        if len(words) == 3:\n            command, path, version = words\n        elif len(words) == 2:\n            command, path = words\n            version = b\"HTTP/1.1\"\n        else:\n            xlog.warn(\"https req line fail:%s\", line)\n            return\n\n        if command != b\"CONNECT\":\n            xlog.warn(\"https req line fail:%s\", line)\n            return\n\n        host, _, port = path.rpartition(b':')\n        port = int(port)\n\n        header_block = self.read_headers()\n        sock = self.conn\n\n        # xlog.debug(\"https %r connect to %s:%d\", self.client_address, host, port)\n        sock.send(b'HTTP/1.1 200 OK\\r\\n\\r\\n')\n\n        handle_domain_proxy(sock, host, port, self.client_address)\n\n    def http_handler(self):\n        req_data = self.conn.recv(65537, socket.MSG_PEEK)\n        rp = req_data.split(b\"\\r\\n\")\n        req_line = rp[0]\n\n        words = req_line.split()\n        if len(words) == 3:\n            method, url, http_version = words\n        elif len(words) == 2:\n            method, url = words\n            http_version = b\"HTTP/1.1\"\n        else:\n            xlog.warn(\"http req line fail:%s\", req_line)\n            return\n\n        if url.lower().startswith(b\"http://\"):\n            o = urlparse(url)\n            host, port = netloc_to_host_port(o.netloc)\n\n            url_prex_len = url[7:].find(b\"/\")\n            if url_prex_len >= 0:\n                url_prex_len += 7\n                path = url[url_prex_len:]\n            else:\n                url_prex_len = len(url)\n                path = b\"/\"\n        else:\n            # not proxy request\n            parsed_url = urlparse(utils.to_str(url))\n            kv = parse_qs(parsed_url.query)\n            if parsed_url.path == \"/dns-query\":\n                return self.DoH_handler(kv)\n            else:\n                xlog.debug(\"PAC %s %s from:%s\", method, url, self.client_address)\n                handler = pac_server.PacHandler(self.conn, self.client_address, None, xlog)\n                return handler.handle()\n\n        sock = SocketWrap(self.conn, self.client_address[0], self.client_address[1])\n        sock.replace_pattern = [url[:url_prex_len], b\"\"]\n\n        xlog.debug(\"http %r connect to %s:%d %s %s\", self.client_address, host, port, method, path)\n        handle_domain_proxy(sock, host, port, self.client_address)\n\n    def DoH_handler(self, kv):\n        handler = pac_server.PacHandler(self.conn, self.client_address, None, xlog)\n        name = kv.get(\"name\", [None])[0]\n        if not name:\n            xlog.warn(\"DoH request no name\")\n            return handler.send_response(content=b'{\"error\":\"no name\"}', status=400)\n\n        dns_type = kv.get(\"type\", [\"1\"])[0]\n        if dns_type.isnumeric():\n            dns_type = int(dns_type)\n\n        ips = utils.to_str(g.dns_query.query(name, dns_type))\n        info = {\n            \"Status\": 0,\n            \"Answer\": [\n            ]\n        }\n        for ip in ips:\n            if dns_type == 1 and not utils.check_ip_valid4(ip):\n                continue\n            if dns_type == 16 and not utils.check_ip_valid6(ip):\n                continue\n\n            info[\"Answer\"].append({\n                \"name\": name,\n                \"type\": dns_type,\n                \"data\": ip\n            })\n        res = json.dumps(info)\n        headers = {\n            \"Content-Type\": \"application/dns-json\",\n            \"Access-Control-Allow-Origin\": \"*\"\n        }\n        return handler.send_response(content=res, headers=headers, status=200)\n"
  },
  {
    "path": "code/default/smart_router/local/smart_route.py",
    "content": "import time\nimport socket\nimport struct\nimport io\nimport ssl\n\ntry:\n    from urllib.parse import urlparse\nexcept ImportError:\n    from urlparse import urlparse\n\nimport utils\nimport simple_http_server\nfrom .socket_wrap import SocketWrap\nfrom . import global_var as g\nimport socks\n\nfrom xlog import getLogger\nxlog = getLogger(\"smart_router\")\n\n\nSO_ORIGINAL_DST = 80\n\n\nfake_host = \"\"\n\nssl_context = ssl.create_default_context()\nssl_context.check_hostname = False\nssl_context.verify_mode = ssl.CERT_REQUIRED\n\n\nclass DontFakeCA(Exception):\n    pass\n\n\nclass ConnectFail(Exception):\n    pass\n\n\nclass RedirectHttpsFail(Exception):\n    pass\n\n\nclass SniNotExist(Exception):\n    pass\n\n\nclass NotSupported(Exception):\n    def __init__(self, req, sock):\n        self.req = req\n        self.sock = sock\n\n\nclass SslWrapFail(Exception):\n    pass\n\n\nclass XTunnelNotRunning(Exception):\n    pass\n\n\ndef is_gae_workable():\n    if not g.gae_proxy:\n        return False\n\n    return g.gae_proxy.apis.is_workable()\n\n\ndef is_ipv6_ok():\n    if not g.gae_proxy:\n        return False\n\n    return g.gae_proxy.check_local_network.IPv6.is_ok()\n\n\ndef is_x_tunnel_workable():\n    if not g.x_tunnel:\n        return False\n\n    return g.x_tunnel.apis.is_workable()\n\n\ndef is_clienthello(data):\n    if len(data) < 20:\n        return False\n    if data.startswith(b'\\x16\\x03'):\n        # TLSv12/TLSv11/TLSv1/SSLv3\n        length, = struct.unpack('>h', data[3:5])\n        return len(data) == 5 + length\n    elif data[0] == '\\x80' and data[2:4] == '\\x01\\x03':\n        # SSLv23\n        return len(data) == 2 + ord(data[1])\n    else:\n        return False\n\n\ndef have_ipv6(ips):\n    for ip in ips:\n        if \":\" in ip:\n            return True\n\n    return False\n\n\ndef extract_sni_name(packet):\n    if not packet.startswith(b'\\x16\\x03'):\n        return\n\n    stream = io.BytesIO(packet)\n    stream.read(0x2b)\n    session_id_length = ord(stream.read(1))\n    stream.read(session_id_length)\n    cipher_suites_length, = struct.unpack('>h', stream.read(2))\n    stream.read(cipher_suites_length+2)\n    extensions_length, = struct.unpack('>h', stream.read(2))\n    # extensions = {}\n    while True:\n        data = stream.read(2)\n        if not data:\n            break\n        etype, = struct.unpack('>h', data)\n        elen, = struct.unpack('>h', stream.read(2))\n        edata = stream.read(elen)\n        if etype == 0:\n            server_name = edata[5:]\n            return server_name\n\n\ndef netloc_to_host_port(netloc, default_port=80):\n    if b\":\" in netloc:\n        host, _, port = netloc.rpartition(b':')\n        port = int(port)\n    else:\n        host = netloc\n        port = default_port\n    return host, port\n\n\ndef get_sni(sock, left_buf=b\"\"):\n    if left_buf:\n        leadbyte = left_buf[0]\n    else:\n        leadbyte = sock.recv(1, socket.MSG_PEEK)\n\n    if leadbyte in (b'\\x80', b'\\x16'):\n        if leadbyte == b'\\x16':\n            for _ in range(2):\n                leaddata = left_buf + sock.recv(4096, socket.MSG_PEEK)\n                if is_clienthello(leaddata):\n                    try:\n                        server_name = extract_sni_name(leaddata)\n                        return server_name\n                    except:\n                        break\n\n        raise SniNotExist\n\n    elif leadbyte not in [b\"G\", b\"P\", b\"D\", b\"O\", b\"H\", b\"T\"]:\n        raise SniNotExist\n\n    leaddata = b\"\"\n    for _ in range(20):\n        leaddata = left_buf + sock.recv(65535, socket.MSG_PEEK)\n        if leaddata:\n            break\n        else:\n            time.sleep(0.01)\n            continue\n    if not leaddata:\n        raise SniNotExist\n\n    n1 = leaddata.find(b\"\\r\\n\")\n    if n1 <= -1:\n        raise SniNotExist\n\n    req_line = leaddata[:n1]\n    words = req_line.split()\n    if len(words) == 3:\n        method, url, http_version = words\n    elif len(words) == 2:\n        method, url = words\n        http_version = b\"HTTP/1.1\"\n    else:\n        raise SniNotExist\n\n    support_methods = tuple([b\"GET\", b\"POST\", b\"HEAD\", b\"PUT\", b\"DELETE\", b\"PATCH\"])\n    if method not in support_methods:\n        raise SniNotExist\n\n    n2 = leaddata.find(b\"\\r\\n\\r\\n\", n1)\n    if n2 <= -1:\n        raise SniNotExist\n    header_block = leaddata[n1+2:n2]\n\n    lines = header_block.split(b\"\\r\\n\")\n    # path = url\n    host = None\n    for line in lines:\n        key, _, value = line.rpartition(b\":\")\n        value = value.strip()\n        if key.lower() == b\"host\":\n            host, port = netloc_to_host_port(value)\n            break\n    if host is None or host == b\"\":\n        raise SniNotExist\n\n    return host\n\n\ndef do_direct(sock, host, ips, port, client_address, left_buf=b\"\"):\n    xlog.debug(\"host:%s:%d try direct connect from %s\", host, port, client_address)\n    remote_sock = g.connect_manager.get_conn(host, ips, port)\n    if not remote_sock:\n        raise ConnectFail()\n\n    xlog.debug(\"host:%s:%d direct connect %s success\", host, port, remote_sock.ip)\n    if left_buf:\n        remote_sock.send(left_buf)\n    g.pipe_socks.add_socks(sock, remote_sock)\n\n\ndef do_redirect_https(sock, host, ips, port, client_address, left_buf=b\"\"):\n    remote_sock = g.connect_manager.get_conn(host, ips, 443)\n    if not remote_sock:\n        raise RedirectHttpsFail()\n\n    try:\n        ssl_sock = ssl_context.wrap_socket(remote_sock._sock, server_hostname=host)\n    except Exception as e:\n        raise RedirectHttpsFail()\n\n    xlog.debug(\"host:%s:%d redirect_https connect %s success\", host, port, remote_sock.ip)\n\n    if left_buf:\n        ssl_sock.send(left_buf)\n    sw = SocketWrap(ssl_sock, remote_sock.ip, port, host)\n    sock.recved_times = 3\n    g.pipe_socks.add_socks(sock, sw)\n\n\ndef do_socks(sock, host, port, client_address, left_buf=b\"\"):\n    if not g.x_tunnel:\n        raise XTunnelNotRunning()\n\n    try:\n        conn_id = g.x_tunnel.proxy_session.create_conn(sock, host, port, True)\n    except Exception as e:\n        xlog.warn(\"do_sock to %s:%d, x_tunnel fail:%r\", host, port, e)\n        raise XTunnelNotRunning()\n\n    if not conn_id:\n        xlog.warn(\"x_tunnel create conn fail\")\n        raise XTunnelNotRunning()\n\n    # xlog.debug(\"do_socks %r connect to %s:%d conn_id:%d\", client_address, host, port, conn_id)\n    if left_buf:\n        g.x_tunnel.global_var.session.conn_list[conn_id].transfer_received_data(left_buf)\n    g.x_tunnel.global_var.session.conn_list[conn_id].start(block=True)\n\n\ndef do_unwrap_socks(sock, host, port, client_address, req, left_buf=b\"\"):\n    if not g.x_tunnel:\n        return\n\n    try:\n        remote_sock = socks.create_connection(\n            (host, port),\n            proxy_type=\"socks5h\", proxy_addr=\"127.0.0.1\", proxy_port=g.x_tunnel_socks_port, timeout=15\n        )\n    except Exception as e:\n        xlog.warn(\"do_unwrap_socks connect to x-tunnel for %s:%d proxy fail.\", host, port)\n        return\n\n    if isinstance(req.connection, ssl.SSLSocket):\n        try:\n            remote_ssl_sock = ssl_context.wrap_socket(remote_sock, server_hostname=host)\n        except:\n            xlog.warn(\"do_unwrap_socks ssl_wrap for %s:%d proxy fail.\", host, port)\n            return\n    else:\n        remote_ssl_sock = remote_sock\n\n    # avoid close by req.__del__\n    req.rfile._close = False\n    req.wfile._close = False\n    req.connection = None\n\n    if not isinstance(sock, SocketWrap):\n        sock = SocketWrap(sock, client_address[0], client_address[1])\n\n    xlog.info(\"host:%s:%d do_unwrap_socks\", host, port)\n\n    remote_ssl_sock.send(left_buf)\n    sw = SocketWrap(remote_ssl_sock, \"x-tunnel\", port, host)\n    sock.recved_times = 3\n    g.pipe_socks.add_socks(sock, sw)\n\n\ndef do_gae(sock, host, port, client_address, left_buf=\"\"):\n    if not g.gae_proxy:\n        raise DontFakeCA()\n\n    sock.setblocking(1)\n    if left_buf:\n        schema = b\"http\"\n    else:\n        leadbyte = sock.recv(1, socket.MSG_PEEK)\n        if leadbyte in (b'\\x80', b'\\x16'):\n            if host != fake_host and not g.config.enable_fake_ca:\n                raise DontFakeCA()\n\n            try:\n                sock._sock = g.gae_proxy.proxy_handler.wrap_ssl(sock._sock, host, port, client_address)\n            except Exception as e:\n                raise SslWrapFail()\n\n            schema = b\"https\"\n        else:\n            schema = b\"http\"\n\n    sock.setblocking(1)\n    xlog.debug(\"host:%s:%d do gae\", host, port)\n    req = g.gae_proxy.proxy_handler.GAEProxyHandler(sock._sock, client_address, None, xlog)\n    req.parse_request()\n\n    if req.path[0] == b'/':\n        url = b'%s://%s%s' % (schema, req.headers[b'Host'], req.path)\n    else:\n        url = req.path\n\n    if url in [b\"http://www.twitter.com/xxnet\",\n                    b\"https://www.twitter.com/xxnet\",\n                    b\"http://www.deja.com/xxnet\",\n                    b\"https://www.deja.com/xxnet\"\n                    ]:\n        # for web_ui status page\n        # auto detect browser proxy setting is work\n        xlog.debug(\"CONNECT %s %s\", req.command, req.path)\n        req.wfile.write(req.self_check_response_data)\n        return\n\n    if req.upgrade == b\"websocket\":\n        xlog.debug(\"gae %s not support WebSocket\", req.path)\n        raise NotSupported(req, sock)\n\n    if len(req.path) >= 2048:\n        xlog.debug(\"gae %s path len exceed 1024 limit\", req.path)\n        raise NotSupported(req, sock)\n\n    if req.command not in req.gae_support_methods:\n        xlog.debug(\"gae %s %s, method not supported\", req.command, req.path)\n        raise NotSupported(req, sock)\n\n    req.parsed_url = urlparse(req.path)\n    req.do_METHOD()\n\n\ndef try_loop(scense, rule_list, sock, host, port, client_address, left_buf=\"\"):\n    xlog.debug(\"try_loop %s %s to %s:%d\", scense, rule_list, host, port)\n\n    start_time = time.time()\n\n    for rule in rule_list:\n        try:\n            if rule == \"redirect_https\":\n                continue\n\n                # if port != 80:\n                #     continue\n                #\n                # if is_ipv6_ok():\n                #     query_type = None\n                # else:\n                #     query_type = 1\n                # ips = g.dns_query.query(host, query_type)\n                #\n                # do_redirect_https(sock, host, ips, port, client_address, left_buf)\n                # xlog.info(\"%s %s:%d redirect_https\", scense, host, port)\n                # return\n\n            elif rule == \"direct\":\n                if is_ipv6_ok():\n                    query_type = 6\n                else:\n                    query_type = 1\n                ips = g.dns_query.query(host, query_type)\n                if not ips:\n                    continue\n\n                try:\n                    do_direct(sock, host, ips, port, client_address, left_buf)\n                except ConnectFail:\n                    continue\n\n                xlog.info(\"%s %s:%d forward to direct\", scense, host, port)\n                return\n\n            elif rule == \"direct6\":\n                if not is_ipv6_ok():\n                    continue\n\n                ips = g.dns_query.query(host, 28)\n                if not ips:\n                    continue\n                    \n                do_direct(sock, host, ips, port, client_address, left_buf)\n                xlog.info(\"%s %s:%d forward to direct6\", scense, host, port)\n                return\n\n            elif rule == \"gae\":\n                if not is_gae_workable() and host != fake_host:\n                    # xlog.debug(\"%s gae host:%s:%d, but gae not work\", scense, host, port)\n                    continue\n\n                if not g.domain_cache.accept_gae(host):\n                    continue\n\n                try:\n                    # sni_host = get_sni(sock, left_buf)\n                    # xlog.info(\"%s %s:%d try gae\", scense, host, port)\n                    do_gae(sock, host, port, client_address, left_buf)\n                    return\n                except DontFakeCA:\n                    continue\n                except NotSupported as e:\n                    req = e.req\n                    left_bufs = [req.raw_requestline]\n                    for k in req.headers:\n                        v = req.headers[k]\n                        left_bufs.append(b\"%s: %s\\r\\n\" % (k, v))\n                    left_bufs.append(b\"\\r\\n\")\n                    left_buf = b\"\".join(left_bufs)\n\n                    return do_unwrap_socks(e.sock, host, port, client_address, req, left_buf=left_buf)\n                except SniNotExist:\n                    xlog.debug(\"%s domain:%s get sni fail\", scense, host)\n                    continue\n                except (SslWrapFail, simple_http_server.ParseReqFail) as e:\n                    xlog.warn(\"%s domain:%s fail:%r\", scense, host, e)\n                    g.domain_cache.report_gae_deny(host, port)\n                    sock.close()\n                    return\n                except simple_http_server.GetReqTimeout:\n                    # Happen sometimes, don't known why.\n                    xlog.debug(\"%s host:%s:%d try gae, GetReqTimeout:%d\", scense, host, port,\n                             (time.time() - start_time) * 1000)\n                    sock.close()\n                    return\n                except Exception as e:\n                    xlog.exception(\"%s host:%s:%d rule:%s except:%r\", scense, host, port, rule, e)\n                    g.domain_cache.report_gae_deny(host, port)\n                    sock.close()\n                    return\n\n            elif rule == \"socks\":\n                if not g.x_tunnel or not g.x_tunnel.proxy_session.login_process():\n                    continue\n\n                xlog.info(\"%s %s:%d forward to socks\", scense, host, port)\n                if isinstance(sock, SocketWrap):\n                    _sock = sock._sock\n                else:\n                    _sock = sock\n                do_socks(_sock, host, port, client_address, left_buf)\n                return\n            elif rule == \"black\":\n                xlog.info(\"%s to:%s:%d black\", scense, host, port)\n                sock.close()\n                return\n            else:\n                xlog.error(\"%s %s:%d rule:%s unknown\", scense, host, port, host, rule)\n                sock.close()\n                return\n        except Exception as e:\n            xlog.exception(\"%s %s to %s:%d except:%r\", scense, rule, host, port, e)\n\n    xlog.warn(\"%s %s to %s:%d try_loop fail\", scense, rule_list, host, port)\n    sock.close()\n    return\n\n\ndef handle_ip_proxy(sock, ip, port, client_address):\n    xlog.debug(\"handle_ip_proxy to %s:%d from:%s:%d\", ip, port, client_address[0], client_address[1])\n\n    if not isinstance(sock, SocketWrap):\n        sock = SocketWrap(sock, client_address[0], client_address[1])\n\n    if port == 443:\n        try:\n            host = get_sni(sock)\n            if host and not utils.check_ip_valid(host):\n                xlog.debug(\"ip connect to %s:%d translate to %s\", ip, port, host)\n                return handle_domain_proxy(sock, host, port, client_address)\n        except SniNotExist as e:\n            xlog.debug(\"ip:%s:%d get sni fail\", ip, port)\n\n    rule = g.user_rules.check_host(ip, port)\n    if not rule:\n        if utils.is_private_ip(ip):\n            rule = \"direct\"\n        elif g.config.pac_policy == \"all_X-Tunnel\":\n            rule = \"socks\"\n        elif g.config.pac_policy == \"all_Direct\":\n            rule = \"direct\"\n\n    if rule:\n        return try_loop(\"ip user\", [rule], sock, ip, port, client_address)\n\n    record = g.ip_cache.get(ip)\n    if record and record[\"r\"] != \"unknown\":\n        rule = record[\"r\"]\n        if rule == \"gae\":\n            rule_list = [\"gae\", \"socks\", \"direct\"]\n        elif rule == \"socks\":\n            rule_list = [\"socks\", \"gae\", \"direct\"]\n        else:\n            rule_list = [\"direct\", \"gae\", \"socks\"]\n    elif g.ip_region.check_ip(ip):\n        # China IP\n        rule_list = [\"direct\", \"socks\"]\n    elif g.gfwlist.in_block_list(ip):\n        rule_list = [\"gae\", \"socks\"]\n    else:\n        rule_list = [\"direct\", \"gae\", \"socks\", ]\n\n    if not g.config.auto_direct:\n        for rule in [\"direct\", \"redirect_https\"]:\n            try:\n                rule_list.remove(rule)\n            except:\n                pass\n    elif g.config.auto_direct6 and \"direct\" in rule_list:\n        rule_list.insert(rule_list.index(\"direct\"), \"direct6\")\n\n    if not g.config.enable_fake_ca and port == 443 or not g.config.auto_gae:\n        try:\n            rule_list.remove(\"gae\")\n        except:\n            pass\n\n    if g.config.pac_policy == \"all_X-Tunnel\":\n        rule_list = [\"socks\", ]\n\n    try_loop(\"ip\", rule_list, sock, ip, port, client_address)\n\n\ndef handle_domain_proxy(sock, host, port, client_address, left_buf=\"\"):\n    global fake_host\n\n    if not fake_host and g.gae_proxy:\n        fake_host = g.gae_proxy.web_control.get_fake_host()\n\n    if not isinstance(sock, SocketWrap):\n        sock = SocketWrap(sock, client_address[0], client_address[1])\n\n    # Check user rules\n    sock.target = \"%s:%d\" % (host, port)\n    rule = g.user_rules.check_host(host, port)\n    if not rule:\n        if host == fake_host:\n            rule = \"gae\"\n        elif utils.check_ip_valid(host) and utils.is_private_ip(host):\n            rule = \"direct\"\n        elif g.config.pac_policy == \"all_Direct\":\n            rule = \"direct\"\n\n    if not rule and (g.config.bypass_speedtest and g.gfwlist.in_speedtest_whitelist(host)):\n        xlog.debug(\"speedtest %s\", host)\n        rule = \"direct\"\n\n    if rule:\n        return try_loop(\"domain user\", [rule], sock, host, port, client_address, left_buf)\n\n    if g.config.block_advertisement and g.gfwlist.is_advertisement(host):\n        xlog.info(\"block advertisement %s:%d\", host, port)\n        sock.close()\n        return\n\n    #ips = g.dns_query.query(host)\n    #if check_local_network.IPv6.is_ok() and have_ipv6(ips) and port == 443:\n    #    rule_list = [\"direct\", \"gae\", \"socks\", \"redirect_https\"]\n    # gae is fast then direct.\n\n    rule = g.domain_cache.get_rule(host)\n    if rule != \"unknown\":\n        if rule == \"gae\":\n            rule_list = [\"gae\", \"socks\", \"redirect_https\", \"direct\"]\n        elif rule == \"socks\":\n            rule_list = [\"socks\", \"gae\", \"redirect_https\", \"direct\"]\n        else:\n            rule_list = [\"direct\", \"gae\", \"socks\", \"redirect_https\"]\n\n        if not g.domain_cache.accept_gae(host):\n            rule_list.remove(\"gae\")\n    elif g.config.country_code == \"CN\":\n        if g.gfwlist.in_block_list(host):\n            if g.config.pac_policy == \"black_X-Tunnel\":\n                rule_list = [\"socks\", \"redirect_https\", \"direct\", \"gae\"]\n            else:\n                rule_list = [\"gae\", \"socks\", \"redirect_https\", \"direct\"]\n        elif g.gfwlist.in_white_list(host):\n            rule_list = [\"direct\", \"gae\", \"socks\", \"redirect_https\"]\n        else:\n            ips = g.dns_query.query_recursively(host, 1)\n            if g.ip_region.check_ips(ips):\n                rule_list = [\"direct\", \"redirect_https\", \"socks\", \"gae\"]\n            else:\n                rule_list = [\"gae\", \"socks\", \"direct\", \"redirect_https\"]\n    else:\n        rule_list = [\"direct\", \"socks\", \"gae\", \"redirect_https\"]\n\n    # check config.\n    if not g.config.auto_direct:\n        for rule in [\"direct\", \"redirect_https\"]:\n            try:\n                rule_list.remove(rule)\n            except:\n                pass\n    elif g.config.auto_direct6 and \"direct\" in rule_list:\n        rule_list.insert(rule_list.index(\"direct\"), \"direct6\")\n\n    if not g.config.enable_fake_ca and port == 443 or not g.config.auto_gae:\n        try:\n            rule_list.remove(\"gae\")\n        except:\n            pass\n\n    if g.config.pac_policy == \"all_X-Tunnel\":\n        rule_list = [\"socks\", ]\n\n    xlog.debug(\"handle_domain_proxy to %s:%d from:%s:%d, rule:%s\", host, port, client_address[0], client_address[1],\n               utils.to_str(rule_list))\n    try_loop(\"domain\", rule_list, sock, host, port, client_address, left_buf)\n"
  },
  {
    "path": "code/default/smart_router/local/socket_wrap.py",
    "content": "import time\n\nfrom xlog import getLogger\nxlog = getLogger(\"smart_router\")\n\n\nclass SocketWrap(object):\n\n    def __init__(self, sock, ip=None, port=None, host=\"\", target=\"\"):\n        self._sock = sock\n        self.ip = ip\n        self.port = port\n        self.host = host\n        self.target = target\n        self.recved_data = 0\n        self.recved_times = 0\n        self.sent_data = 0\n        self.sent_times = 0\n        self.create_time = time.time()\n        self.closed = False\n        self.replace_pattern = None\n\n        self.buf = []\n        self.buf_size = 0\n        self.buf_num = 0\n\n        self.can_read = False\n        self.can_write = False\n        self.pair_sock = None\n\n    def __getattr__(self, attr):\n        return getattr(self._sock, attr)\n\n    def close(self):\n        # xlog.debug(\"%s close\", self)\n        try:\n            self._sock.close()\n        except Exception as e:\n            xlog.error(\"close _sock:%s e:%r\", self._sock, e)\n        self.closed = True\n\n    def is_closed(self):\n        return self.closed\n\n    def __str__(self):\n        return \"%s[%s]:%d\" % (self.host, self.ip, self.port)\n\n    def recv(self, bufsiz, flags=0):\n        d = self._sock.recv(bufsiz, flags)\n        if self.replace_pattern and b\" HTTP/1.1\\r\\n\" in d:\n            line_end = d.find(b\"\\r\\n\")\n            req_line = d[:line_end]\n\n            words = req_line.split()\n            if len(words) == 3:\n                method, url, http_version = words\n                url = url.replace(self.replace_pattern[0], self.replace_pattern[1])\n\n                d = b\"%s %s %s\" % (method, url, http_version) + d[line_end:]\n\n        # xlog.debug(\"%s recv %d\", self, len(d))\n        return d\n\n    def add_dat(self, data):\n        # xlog.debug(\"%s add data %d\", self, len(data))\n        self.buf.append(data)\n        self.buf_size += len(data)\n        self.buf_num += 1\n\n    def get_dat(self):\n        if not self.buf:\n            return b\"\"\n        dat = self.buf.pop(0)\n        self.buf_size -= len(dat)\n        self.buf_num -= 1\n        return dat\n\n    def restore_dat(self, dat):\n        # xlog.debug(\"%s restore_dat %d\", self, len(dat))\n        self.buf.insert(0, dat)\n        self.buf_size += len(dat)\n        self.buf_num += 1\n"
  },
  {
    "path": "code/default/smart_router/local/speedtest_whitelist.txt",
    "content": "cdnst.net\ncellmaps.com\nekahau.cloud\nekahau.com\nookla.com\nooklaserver.net\npingtest.net\nspeedtest.co\nspeedtest.net\nspeedtestcustom.com\nwebtest.net\nmeasurement-lab.org\nmeasurementlab.net"
  },
  {
    "path": "code/default/smart_router/local/sr_top500_banlist.conf",
    "content": "# Best Shadowrocket Rules (https://github.com/Johnshall/Shadowrocket-ADBlock-Rules-Forever)\n# by Moshel and Johnshall\n# build time: UTC 2024-02-10 23:02:05\n\n[General]\n# 默认关闭 ipv6 支持，如果需要请手动开启\nipv6 = false\nbypass-system = true\nskip-proxy = 192.168.0.0/16, 10.0.0.0/8, 172.16.0.0/12, localhost, *.local, e.crashlytics.com, captive.apple.com, sequoia.apple.com, seed-sequoia.siri.apple.com\nbypass-tun = 10.0.0.0/8,100.64.0.0/10,127.0.0.0/8,169.254.0.0/16,172.16.0.0/12,192.0.0.0/24,192.0.2.0/24,192.88.99.0/24,192.168.0.0/16,198.18.0.0/15,198.51.100.0/24,203.0.113.0/24,224.0.0.0/4,255.255.255.255/32\ndns-server = https://1.12.12.12/dns-query, https://223.5.5.5/dns-query\n[Rule]\n#\n# 黑名单中包含了 GFWList 中定义的无法访问的网站，剩下的网站直连。\n# 未包含广告过滤\n#\n\n\n# 手工定义的 Proxy 列表\n#TED\nDOMAIN-SUFFIX,tedcdn.com,Proxy\n#Telegram\nDOMAIN-SUFFIX,t.me,Proxy\nDOMAIN-SUFFIX,tdesktop.com,Proxy\nDOMAIN-SUFFIX,telegra.ph,Proxy\nDOMAIN-SUFFIX,telegram.me,Proxy\nDOMAIN-SUFFIX,telegram.org,Proxy\nDOMAIN-SUFFIX,telesco.pe,Proxy\nIP-CIDR,91.108.56.0/22,Proxy\nIP-CIDR,91.108.4.0/22,Proxy\nIP-CIDR,91.108.8.0/22,Proxy\nIP-CIDR,91.108.16.0/22,Proxy\nIP-CIDR,91.108.12.0/22,Proxy\nIP-CIDR,149.154.160.0/20,Proxy\nIP-CIDR,91.105.192.0/23,Proxy\nIP-CIDR,91.108.20.0/22,Proxy\nIP-CIDR,185.76.151.0/24,Proxy\nIP-CIDR,2001:b28:f23d::/48,Proxy\nIP-CIDR,2001:b28:f23f::/48,Proxy\nIP-CIDR,2001:67c:4e8::/48,Proxy\nIP-CIDR,2001:b28:f23c::/48,Proxy\nIP-CIDR,2a0a:f280::/32,Proxy\n#disqus\nDOMAIN-SUFFIX,disquscdn.com,Proxy\n#50 whatsapp\nIP-CIDR,18.194.0.0/15,Proxy\nIP-CIDR,34.224.0.0/12,Proxy\n#54 台湾香港澳门 常用网站\nDOMAIN-SUFFIX,appledaily.tw,Proxy\n#72 #112 Google Voice\nIP-CIDR,74.125.0.0/16,Proxy\n#85（可能冗余）\nDOMAIN-SUFFIX,www-google-analytics.l.google.com,Proxy\nDOMAIN-SUFFIX,ssl-google-analytics.l.google.com,Proxy\nDOMAIN-SUFFIX,partnerad.l.google.com,Proxy\nDOMAIN-SUFFIX,pagead.l.google.com,Proxy\nDOMAIN-SUFFIX,pagead.google.com,Proxy\nDOMAIN-SUFFIX,pagead-tpc.l.google.com,Proxy\nDOMAIN-SUFFIX,mobileads.google.com,Proxy\nDOMAIN-SUFFIX,ads.google.com,Proxy\nDOMAIN-SUFFIX,afd.l.google.com,Proxy\n#175 华尔街邮报\nDOMAIN-SUFFIX,dowjones.com,Proxy\n#180 OneDrive（可能冗余）\nDOMAIN-SUFFIX,bcbits.com,Proxy\nDOMAIN-SUFFIX,ogma.iad.appboy.com,Proxy\nDOMAIN-SUFFIX,odc.officeapps.live.com,Proxy\nDOMAIN-SUFFIX,skyapi.live.net,Proxy\nDOMAIN-SUFFIX,centralus1.mediap.svc.ms,Proxy\nDOMAIN-SUFFIX,dm.files.1drv.com,Proxy\nDOMAIN-SUFFIX,mobile.pipe.aria.microsoft.com,Proxy\nDOMAIN-SUFFIX,gate.hockeyapp.net,Proxy\nDOMAIN-SUFFIX,api.onedrive.com,Proxy\nDOMAIN-SUFFIX,vortex.data.microsoft.com,Proxy\n#183\nDOMAIN-SUFFIX,mendeley.com,Proxy\n#205 APPLE NEWS\nDOMAIN-SUFFIX,news-events.apple.com,Proxy\nDOMAIN-SUFFIX,news-edge.apple.com,Proxy\nDOMAIN-SUFFIX,apple.comscoreresearch.com,Proxy\nDOMAIN-SUFFIX,play.itunes.apple.com,Proxy\nDOMAIN-SUFFIX,play-cdn.itunes-apple.com.akadns.net,Proxy\nDOMAIN-SUFFIX,ls.apple.com,Proxy\nDOMAIN-SUFFIX,cvws.apple-dns.net,Proxy\nDOMAIN-SUFFIX,news.apple-dns.net,Proxy\nDOMAIN-SUFFIX,gateway.fe.apple-dns.net,Proxy\nDOMAIN-SUFFIX,akamaiedge.net,Proxy\nDOMAIN-SUFFIX,gs-loc.apple.com,Proxy\nDOMAIN-SUFFIX,bag.itunes.apple.com,Proxy\nDOMAIN-SUFFIX,apple.news,Proxy\nDOMAIN-SUFFIX,news.iadsdk.apple.com,Proxy\n#github\nDOMAIN-SUFFIX,raw.githubusercontent.com,Proxy\n# news\nDOMAIN-SUFFIX,vox.com,Proxy\n#苹果域名及其CDN 代理\nDOMAIN-SUFFIX,adcdownload.apple.com.akadns.net,Proxy\nDOMAIN-SUFFIX,appldnld.g.aaplimg.com,Proxy\nDOMAIN-SUFFIX,cds-cdn.v.aaplimg.com,Proxy\nDOMAIN-SUFFIX,cds.apple.com.akadns.net,Proxy\nDOMAIN-SUFFIX,cl1-cdn.origin-apple.com.akadns.net,Proxy\nDOMAIN-SUFFIX,cl3-cdn.origin-apple.com.akadns.net,Proxy\nDOMAIN-SUFFIX,cl4-cdn.origin-apple.com.akadns.net,Proxy\nDOMAIN-SUFFIX,cl5-cdn.origin-apple.com.akadns.net,Proxy\nDOMAIN-SUFFIX,clientflow.apple.com.akadns.net,Proxy\nDOMAIN-SUFFIX,configuration.apple.com.akadns.net,Proxy\nDOMAIN-SUFFIX,dd-cdn.origin-apple.com.akadns.net,Proxy\nDOMAIN-SUFFIX,cdn.apple-mapkit.com,Proxy\nDOMAIN-SUFFIX,gspe19-cn.ls-apple.com.akadns.net,Proxy\nDOMAIN-SUFFIX,gs-loc-cn.apple.com,Proxy\nDOMAIN-SUFFIX,gsp10-ssl-cn.ls.apple.com,Proxy\nDOMAIN-SUFFIX,icloud-cdn.icloud.com.akadns.net,Proxy\nDOMAIN-SUFFIX,init-p01md-lb.push-apple.com.akadns.net,Proxy\nDOMAIN-SUFFIX,init-p01st-lb.push-apple.com.akadns.net,Proxy\nDOMAIN-SUFFIX,init-s01st-lb.push-apple.com.akadns.net,Proxy\nDOMAIN-SUFFIX,gsp85-cn-ssl.ls.apple.com,Proxy\nDOMAIN-SUFFIX,itunes-apple.com.akadns.net,Proxy\nDOMAIN-SUFFIX,gspe21.ls.apple.com,Proxy\nDOMAIN-SUFFIX,mesu-china.apple.com.akadns.net,Proxy\nDOMAIN-SUFFIX,mesu-cdn.apple.com.akadns.net,Proxy\nDOMAIN-SUFFIX,ocsp-lb.apple.com.akadns.net,Proxy\nDOMAIN-SUFFIX,oscdn.origin-apple.com.akadns.net,Proxy\nDOMAIN-SUFFIX,pancake.cdn-apple.com.akadns.net,Proxy\nDOMAIN-SUFFIX,prod-support.apple-support.akadns.net,Proxy\nDOMAIN-SUFFIX,stocks-sparkline-lb.apple.com.akadns.net,Proxy\nDOMAIN-SUFFIX,store.storeimages.apple.com.akadns.net,Proxy\nDOMAIN-SUFFIX,support-china.apple-support.akadns.net,Proxy\nDOMAIN-SUFFIX,swcatalog-cdn.apple.com.akadns.net,Proxy\nDOMAIN-SUFFIX,swdist.apple.com.akadns.net,Proxy\nDOMAIN-SUFFIX,swscan-cdn.apple.com.akadns.net,Proxy\nDOMAIN-SUFFIX,valid.origin-apple.com.akadns.net,Proxy\nDOMAIN-SUFFIX,phobos.apple.com,Proxy\n# DisneyPlus\nDOMAIN-SUFFIX,disney.asia,Proxy\nDOMAIN-SUFFIX,disney.be,Proxy\nDOMAIN-SUFFIX,disney.bg,Proxy\nDOMAIN-SUFFIX,disney.ca,Proxy\nDOMAIN-SUFFIX,disney.ch,Proxy\nDOMAIN-SUFFIX,disney.co.il,Proxy\nDOMAIN-SUFFIX,disney.co.jp,Proxy\nDOMAIN-SUFFIX,disney.co.kr,Proxy\nDOMAIN-SUFFIX,disney.co.th,Proxy\nDOMAIN-SUFFIX,disney.co.uk,Proxy\nDOMAIN-SUFFIX,disney.co.za,Proxy\nDOMAIN-SUFFIX,disney.com,Proxy\nDOMAIN-SUFFIX,disney.com.au,Proxy\nDOMAIN-SUFFIX,disney.com.br,Proxy\nDOMAIN-SUFFIX,disney.com.hk,Proxy\nDOMAIN-SUFFIX,disney.com.tw,Proxy\nDOMAIN-SUFFIX,disney.cz,Proxy\nDOMAIN-SUFFIX,disney.de,Proxy\nDOMAIN-SUFFIX,disney.dk,Proxy\nDOMAIN-SUFFIX,disney.es,Proxy\nDOMAIN-SUFFIX,disney.fi,Proxy\nDOMAIN-SUFFIX,disney.fr,Proxy\nDOMAIN-SUFFIX,disney.gr,Proxy\nDOMAIN-SUFFIX,disney.hu,Proxy\nDOMAIN-SUFFIX,disney.id,Proxy\nDOMAIN-SUFFIX,disney.in,Proxy\nDOMAIN-SUFFIX,disney.io,Proxy\nDOMAIN-SUFFIX,disney.it,Proxy\nDOMAIN-SUFFIX,disney.my,Proxy\nDOMAIN-SUFFIX,disney.nl,Proxy\nDOMAIN-SUFFIX,disney.no,Proxy\nDOMAIN-SUFFIX,disney.ph,Proxy\nDOMAIN-SUFFIX,disney.pl,Proxy\nDOMAIN-SUFFIX,disney.pt,Proxy\nDOMAIN-SUFFIX,disney.ro,Proxy\nDOMAIN-SUFFIX,disney.ru,Proxy\nDOMAIN-SUFFIX,disney.se,Proxy\nDOMAIN-SUFFIX,disney.sg,Proxy\nDOMAIN-SUFFIX,20thcenturystudios.com.au,Proxy\nDOMAIN-SUFFIX,20thcenturystudios.com.br,Proxy\nDOMAIN-SUFFIX,20thcenturystudios.jp,Proxy\nDOMAIN-SUFFIX,adventuresbydisney.com,Proxy\nDOMAIN-SUFFIX,babble.com,Proxy\nDOMAIN-SUFFIX,babyzone.com,Proxy\nDOMAIN-SUFFIX,bamgrid.com,Proxy\nDOMAIN-SUFFIX,beautyandthebeastmusical.co.uk,Proxy\nDOMAIN-SUFFIX,dilcdn.com,Proxy\nDOMAIN-SUFFIX,disney-asia.com,Proxy\nDOMAIN-SUFFIX,disney-discount.com,Proxy\nDOMAIN-SUFFIX,disney-plus.net,Proxy\nDOMAIN-SUFFIX,disney-portal.my.onetrust.com,Proxy\nDOMAIN-SUFFIX,disney-studio.com,Proxy\nDOMAIN-SUFFIX,disney-studio.net,Proxy\nDOMAIN-SUFFIX,disney.my.sentry.io,Proxy\nDOMAIN-SUFFIX,disneyadsales.com,Proxy\nDOMAIN-SUFFIX,disneyarena.com,Proxy\nDOMAIN-SUFFIX,disneyaulani.com,Proxy\nDOMAIN-SUFFIX,disneybaby.com,Proxy\nDOMAIN-SUFFIX,disneycareers.com,Proxy\nDOMAIN-SUFFIX,disneychannelonstage.com,Proxy\nDOMAIN-SUFFIX,disneychannelroadtrip.com,Proxy\nDOMAIN-SUFFIX,disneycruisebrasil.com,Proxy\nDOMAIN-SUFFIX,disneyenconcert.com,Proxy\nDOMAIN-SUFFIX,disneyiejobs.com,Proxy\nDOMAIN-SUFFIX,disneyinflight.com,Proxy\nDOMAIN-SUFFIX,disneyinternational.com,Proxy\nDOMAIN-SUFFIX,disneyinternationalhd.com,Proxy\nDOMAIN-SUFFIX,disneyjunior.com,Proxy\nDOMAIN-SUFFIX,disneyjuniortreataday.com,Proxy\nDOMAIN-SUFFIX,disneylatino.com,Proxy\nDOMAIN-SUFFIX,disneymagicmoments.co.il,Proxy\nDOMAIN-SUFFIX,disneymagicmoments.co.uk,Proxy\nDOMAIN-SUFFIX,disneymagicmoments.co.za,Proxy\nDOMAIN-SUFFIX,disneymagicmoments.de,Proxy\nDOMAIN-SUFFIX,disneymagicmoments.es,Proxy\nDOMAIN-SUFFIX,disneymagicmoments.fr,Proxy\nDOMAIN-SUFFIX,disneymagicmoments.gen.tr,Proxy\nDOMAIN-SUFFIX,disneymagicmoments.gr,Proxy\nDOMAIN-SUFFIX,disneymagicmoments.it,Proxy\nDOMAIN-SUFFIX,disneymagicmoments.pl,Proxy\nDOMAIN-SUFFIX,disneymagicmomentsme.com,Proxy\nDOMAIN-SUFFIX,disneyme.com,Proxy\nDOMAIN-SUFFIX,disneymeetingsandevents.com,Proxy\nDOMAIN-SUFFIX,disneymovieinsiders.com,Proxy\nDOMAIN-SUFFIX,disneymusicpromotion.com,Proxy\nDOMAIN-SUFFIX,disneynewseries.com,Proxy\nDOMAIN-SUFFIX,disneynow.com,Proxy\nDOMAIN-SUFFIX,disneypeoplesurveys.com,Proxy\nDOMAIN-SUFFIX,disneyplus.bn5x.net,Proxy\nDOMAIN-SUFFIX,disneyplus.com,Proxy\nDOMAIN-SUFFIX,disneyplus.com.ssl.sc.omtrdc.net,Proxy\nDOMAIN-SUFFIX,disneyredirects.com,Proxy\nDOMAIN-SUFFIX,disneysrivieraresort.com,Proxy\nDOMAIN-SUFFIX,disneystore.com,Proxy\nDOMAIN-SUFFIX,disneystreaming.com,Proxy\nDOMAIN-SUFFIX,disneysubscription.com,Proxy\nDOMAIN-SUFFIX,disneytickets.co.uk,Proxy\nDOMAIN-SUFFIX,disneyturkiye.com.tr,Proxy\nDOMAIN-SUFFIX,disneytvajobs.com,Proxy\nDOMAIN-SUFFIX,disneyworld-go.com,Proxy\nDOMAIN-SUFFIX,dssott.com,Proxy\nDOMAIN-SUFFIX,go-disneyworldgo.com,Proxy\nDOMAIN-SUFFIX,go.com,Proxy\nDOMAIN-SUFFIX,mickey.tv,Proxy\nDOMAIN-SUFFIX,moviesanywhere.com,Proxy\nDOMAIN-SUFFIX,nomadlandmovie.ch,Proxy\nDOMAIN-SUFFIX,playmation.com,Proxy\nDOMAIN-SUFFIX,shopdisney.com,Proxy\nDOMAIN-SUFFIX,shops-disney.com,Proxy\nDOMAIN-SUFFIX,sorcerersarena.com,Proxy\nDOMAIN-SUFFIX,spaindisney.com,Proxy\nDOMAIN-SUFFIX,star-brasil.com,Proxy\nDOMAIN-SUFFIX,star-latam.com,Proxy\nDOMAIN-SUFFIX,starwars.com,Proxy\nDOMAIN-SUFFIX,starwarsgalacticstarcruiser.com,Proxy\nDOMAIN-SUFFIX,starwarskids.com,Proxy\nDOMAIN-SUFFIX,streamingdisney.net,Proxy\nDOMAIN-SUFFIX,thestationbymaker.com,Proxy\nDOMAIN-SUFFIX,thisispolaris.com,Proxy\nDOMAIN-SUFFIX,watchdisneyfe.com,Proxy\n# Amazon\nDOMAIN-SUFFIX,a2z.com,Proxy\nDOMAIN-SUFFIX,aboutamazon.co.uk,Proxy\nDOMAIN-SUFFIX,aboutamazon.com,Proxy\nDOMAIN-SUFFIX,aboutamazon.com.au,Proxy\nDOMAIN-SUFFIX,aboutamazon.de,Proxy\nDOMAIN-SUFFIX,aboutamazon.es,Proxy\nDOMAIN-SUFFIX,aboutamazon.eu,Proxy\nDOMAIN-SUFFIX,aboutamazon.fr,Proxy\nDOMAIN-SUFFIX,aboutamazon.in,Proxy\nDOMAIN-SUFFIX,aboutamazon.it,Proxy\nDOMAIN-SUFFIX,aboutamazon.jp,Proxy\nDOMAIN-SUFFIX,aboutamazon.pl,Proxy\nDOMAIN-SUFFIX,acmvalidations.com,Proxy\nDOMAIN-SUFFIX,acmvalidationsaws.com,Proxy\nDOMAIN-SUFFIX,aesworkshops.com,Proxy\nDOMAIN-SUFFIX,aiv-cdn.net,Proxy\nDOMAIN-SUFFIX,aiv-delivery.net,Proxy\nDOMAIN-SUFFIX,alexa.com,Proxy\nDOMAIN-SUFFIX,amaaozn.com,Proxy\nDOMAIN-KEYWORD,amazon,Proxy\nDOMAIN-SUFFIX,amazon-adsystem.com,Proxy\nDOMAIN-SUFFIX,amazon-fashions.com,Proxy\nDOMAIN-SUFFIX,amazon-jp-recruiting.com,Proxy\nDOMAIN-SUFFIX,amazon-lantern.com,Proxy\nDOMAIN-SUFFIX,amazon-launchpad.com,Proxy\nDOMAIN-SUFFIX,amazon.ae,Proxy\nDOMAIN-SUFFIX,amazon.ca,Proxy\nDOMAIN-SUFFIX,amazon.co.jp,Proxy\nDOMAIN-SUFFIX,amazon.co.uk,Proxy\nDOMAIN-SUFFIX,amazon.com,Proxy\nDOMAIN-SUFFIX,amazon.com.au,Proxy\nDOMAIN-SUFFIX,amazon.com.br,Proxy\nDOMAIN-SUFFIX,amazon.com.mx,Proxy\nDOMAIN-SUFFIX,amazon.com.tr,Proxy\nDOMAIN-SUFFIX,amazon.de,Proxy\nDOMAIN-SUFFIX,amazon.es,Proxy\nDOMAIN-SUFFIX,amazon.fr,Proxy\nDOMAIN-SUFFIX,amazon.in,Proxy\nDOMAIN-SUFFIX,amazon.it,Proxy\nDOMAIN-SUFFIX,amazon.jobs,Proxy\nDOMAIN-SUFFIX,amazon.jp,Proxy\nDOMAIN-SUFFIX,amazon.nl,Proxy\nDOMAIN-SUFFIX,amazon.red,Proxy\nDOMAIN-SUFFIX,amazon.sg,Proxy\nDOMAIN-SUFFIX,amazonalexavoxcon.com,Proxy\nDOMAIN-SUFFIX,amazonauthorinsights.com,Proxy\nDOMAIN-SUFFIX,amazonaws-china.com,Proxy\nDOMAIN-SUFFIX,amazonaws.co.uk,Proxy\nDOMAIN-SUFFIX,amazonaws.com,Proxy\nDOMAIN-SUFFIX,amazonaws.tv,Proxy\nDOMAIN-SUFFIX,amazonbusiness.org,Proxy\nDOMAIN-SUFFIX,amazonbusinessblog.com,Proxy\nDOMAIN-SUFFIX,amazondevicesupport.com,Proxy\nDOMAIN-SUFFIX,amazonfctours.com,Proxy\nDOMAIN-SUFFIX,amazonianblog.com,Proxy\nDOMAIN-SUFFIX,amazonimages.com,Proxy\nDOMAIN-SUFFIX,amazonlaunchpad.com,Proxy\nDOMAIN-SUFFIX,amazonliterarypartnership.com,Proxy\nDOMAIN-SUFFIX,amazonlumberyard.wang,Proxy\nDOMAIN-SUFFIX,amazonpay.com,Proxy\nDOMAIN-SUFFIX,amazonpay.in,Proxy\nDOMAIN-SUFFIX,amazonprimevideos.com,Proxy\nDOMAIN-SUFFIX,amazonsdi.com,Proxy\nDOMAIN-SUFFIX,amazonstudiosguilds.com,Proxy\nDOMAIN-SUFFIX,amazontrust.com,Proxy\nDOMAIN-SUFFIX,amazonuniversity.jobs,Proxy\nDOMAIN-SUFFIX,amazonvideo.cc,Proxy\nDOMAIN-SUFFIX,amazonvideo.com,Proxy\nDOMAIN-SUFFIX,amazonvideodirect.com,Proxy\nDOMAIN-SUFFIX,amazonworkdocs.com,Proxy\nDOMAIN-SUFFIX,amplifyapp.com,Proxy\nDOMAIN-SUFFIX,amplifyframework.com,Proxy\nDOMAIN-SUFFIX,amzn.asia,Proxy\nDOMAIN-SUFFIX,amzn.com,Proxy\nDOMAIN-SUFFIX,amzn.to,Proxy\nDOMAIN-SUFFIX,amznl.com,Proxy\nDOMAIN-SUFFIX,associates-amazon.com,Proxy\nDOMAIN-SUFFIX,audible.com,Proxy\nDOMAIN-SUFFIX,avodmp4s3ww-a.akamaihd.net,Proxy\nDOMAIN-KEYWORD,aws,Proxy\nDOMAIN-SUFFIX,aws-iot-hackathon.com,Proxy\nDOMAIN-SUFFIX,awsautopilot.com,Proxy\nDOMAIN-SUFFIX,awsautoscaling.com,Proxy\nDOMAIN-SUFFIX,awsbraket.com,Proxy\nDOMAIN-SUFFIX,awscloud.com,Proxy\nDOMAIN-SUFFIX,awscommandlineinterface.com,Proxy\nDOMAIN-SUFFIX,awsedstart.com,Proxy\nDOMAIN-SUFFIX,awseducate.com,Proxy\nDOMAIN-SUFFIX,awseducate.net,Proxy\nDOMAIN-SUFFIX,awseducate.org,Proxy\nDOMAIN-SUFFIX,awsloft-johannesburg.com,Proxy\nDOMAIN-SUFFIX,awsloft-stockholm.com,Proxy\nDOMAIN-SUFFIX,awssecworkshops.com,Proxy\nDOMAIN-SUFFIX,awsstatic.com,Proxy\nDOMAIN-SUFFIX,awsthinkbox.com,Proxy\nDOMAIN-SUFFIX,awstrack.me,Proxy\nDOMAIN-SUFFIX,awstrust.com,Proxy\nDOMAIN-SUFFIX,boxofficemojo.com,Proxy\nDOMAIN-SUFFIX,cdkworkshop.com,Proxy\nDOMAIN-SUFFIX,cloudfront.net,Proxy\nDOMAIN-SUFFIX,containersonaws.com,Proxy\nDOMAIN-SUFFIX,createspace.com,Proxy\nDOMAIN-SUFFIX,elasticbeanstalk.com,Proxy\nDOMAIN-SUFFIX,gameon-masters.com,Proxy\nDOMAIN-SUFFIX,gdansk-amazon.com,Proxy\nDOMAIN-SUFFIX,images-amazon.com,Proxy\nDOMAIN-SUFFIX,imdb.com,Proxy\nDOMAIN-SUFFIX,imdb.to,Proxy\nDOMAIN-SUFFIX,kindle.co.jp,Proxy\nDOMAIN-SUFFIX,kindle.co.uk,Proxy\nDOMAIN-SUFFIX,kindle.com,Proxy\nDOMAIN-SUFFIX,kindle.de,Proxy\nDOMAIN-SUFFIX,kindle.es,Proxy\nDOMAIN-SUFFIX,kindle.fr,Proxy\nDOMAIN-SUFFIX,kindle.in,Proxy\nDOMAIN-SUFFIX,kindle.it,Proxy\nDOMAIN-SUFFIX,kindle.jp,Proxy\nDOMAIN-SUFFIX,kindleoasis.com,Proxy\nDOMAIN-SUFFIX,kindleoasis.info,Proxy\nDOMAIN-SUFFIX,kindleoasis.jp,Proxy\nDOMAIN-SUFFIX,kindleoasis.org,Proxy\nDOMAIN-SUFFIX,kindleoasis.us,Proxy\nDOMAIN-SUFFIX,kindleoasisnews.com,Proxy\nDOMAIN-SUFFIX,kindleproject.com,Proxy\nDOMAIN-SUFFIX,llnwd.net,Proxy\nDOMAIN-SUFFIX,media-amazon.com,Proxy\nDOMAIN-SUFFIX,media-imdb.com,Proxy\nDOMAIN-SUFFIX,prime-video.com,Proxy\nDOMAIN-SUFFIX,primeday.info,Proxy\nDOMAIN-SUFFIX,primevideo.cc,Proxy\nDOMAIN-SUFFIX,primevideo.com,Proxy\nDOMAIN-SUFFIX,primevideo.info,Proxy\nDOMAIN-SUFFIX,primevideo.org,Proxy\nDOMAIN-SUFFIX,primevideo.tv,Proxy\nDOMAIN-SUFFIX,pv-cdn.net,Proxy\nDOMAIN-SUFFIX,siege-amazon.com,Proxy\nDOMAIN-SUFFIX,ssl-images-amazon.com,Proxy\nDOMAIN-SUFFIX,thinkboxsoftware.com,Proxy\nDOMAIN-SUFFIX,ueberamazon.de,Proxy\nDOMAIN-SUFFIX,wfm.com,Proxy\nDOMAIN-SUFFIX,wholecitiesfoundation.org,Proxy\nDOMAIN-SUFFIX,wholefoods.com,Proxy\nDOMAIN-SUFFIX,wholefoodsmarket.co.uk,Proxy\nDOMAIN-SUFFIX,wholefoodsmarket.com,Proxy\nDOMAIN-SUFFIX,wholekidsfoundation.org,Proxy\nDOMAIN-SUFFIX,wholeplanetfoundation.org,Proxy\nDOMAIN-SUFFIX,yamaxun.com,Proxy\n# Paramount\nDOMAIN-SUFFIX,paramountplus.com,Proxy\n# New Bing\nDOMAIN-SUFFIX,bing.com,Proxy\n# DNS Leak\nDOMAIN-SUFFIX,dnsleaktest.com,Proxy\nDOMAIN-SUFFIX,ipleak.net,Proxy\nDOMAIN-SUFFIX,browserleaks.com,Proxy\nDOMAIN-SUFFIX,browserleaks.org,Proxy\nDOMAIN-SUFFIX,vpnunlimited.com,Proxy\nDOMAIN-SUFFIX,whrq.net,Proxy\n# Forefront\nDOMAIN-SUFFIX,forefront.ai,Proxy\n# Mozilla\nDOMAIN-SUFFIX,mozilla.org,Proxy\n# Txt.fyi\nDOMAIN-SUFFIX,txt.fyi,Proxy\n# Adobe\nDOMAIN-SUFFIX,adobe.com,Proxy\n# AOL\nDOMAIN-SUFFIX,aol.com,Proxy\n# Yahoo\nDOMAIN-SUFFIX,yahoo.com,Proxy\n# Linkedin\nDOMAIN-SUFFIX,linkedin.cn,Proxy\n# Copilot\nDOMAIN-SUFFIX,copilot.microsoft.com,Proxy\n# hoyolab\nDOMAIN-SUFFIX,hoyolab.com,Proxy\n# 防止 bing 地区检测\nDOMAIN-SUFFIX,location.microsoft.com,Proxy\n# devv\nDOMAIN-SUFFIX,devv.ai,Proxy\n\nDOMAIN-SUFFIX,wjbk.org,Proxy\nDOMAIN-SUFFIX,torss.cf,Proxy\nDOMAIN-SUFFIX,promotion.gbe168.com,Proxy\nDOMAIN-SUFFIX,cute82.com,Proxy\nDOMAIN-SUFFIX,swc5555.com,Proxy\nDOMAIN-SUFFIX,css22.ga,Proxy\nDOMAIN-SUFFIX,lpxtv.com,Proxy\nDOMAIN-SUFFIX,gadu-gadu.pl,Proxy\nDOMAIN-SUFFIX,karlosb.com,Proxy\nDOMAIN-SUFFIX,www.ofmchina.com,Proxy\nDOMAIN-SUFFIX,beijing1989.com,Proxy\nDOMAIN-SUFFIX,feet9.com,Proxy\nDOMAIN-SUFFIX,www.vpncloud.co,Proxy\nDOMAIN-SUFFIX,twitese.spaces.live.com,Proxy\nDOMAIN-SUFFIX,uyghurbiz.org,Proxy\nDOMAIN-SUFFIX,myheritage.com,Proxy\nDOMAIN-SUFFIX,wiki.oauth.net,Proxy\nDOMAIN-SUFFIX,666365.tv,Proxy\nDOMAIN-SUFFIX,tor-exit-45.for-privacy.net,Proxy\nDOMAIN-SUFFIX,xmbus1.xyz,Proxy\nDOMAIN-SUFFIX,bisicdn.cc,Proxy\nDOMAIN-SUFFIX,bb-in.net,Proxy\nDOMAIN-SUFFIX,www.ibizababes.com,Proxy\nDOMAIN-SUFFIX,dns.adguard.com,Proxy\nDOMAIN-SUFFIX,victimsofcommunism.org,Proxy\nDOMAIN-SUFFIX,www.cifglobalmarkets.com,Proxy\nDOMAIN-SUFFIX,goldseek.com,Proxy\nDOMAIN-SUFFIX,www.casinolasvegas.com,Proxy\nDOMAIN-SUFFIX,d1993.com,Proxy\nDOMAIN-SUFFIX,www.llsif.moe,Proxy\nDOMAIN-SUFFIX,d2pxvvqoon1wcs.cloudfront.net,Proxy\nDOMAIN-SUFFIX,pox.cleansite.us,Proxy\nDOMAIN-SUFFIX,www.fun8807.com,Proxy\nDOMAIN-SUFFIX,www.zinio.com.tw,Proxy\nDOMAIN-SUFFIX,apk.asso.st,Proxy\nDOMAIN-SUFFIX,google.de,Proxy\nDOMAIN-SUFFIX,remax.com,Proxy\nDOMAIN-SUFFIX,twaud.io,Proxy\nDOMAIN-SUFFIX,freedns.org,Proxy\nDOMAIN-SUFFIX,savetibet.nl,Proxy\nDOMAIN-SUFFIX,fun129.com,Proxy\nDOMAIN-SUFFIX,90011.com,Proxy\nDOMAIN-SUFFIX,heute.de,Proxy\nDOMAIN-SUFFIX,schmorp.de,Proxy\nDOMAIN-SUFFIX,richardweb.net,Proxy\nDOMAIN-SUFFIX,tc168.cf,Proxy\nDOMAIN-SUFFIX,vascar.ro,Proxy\nDOMAIN-SUFFIX,www.dajinyule.vip,Proxy\nDOMAIN-SUFFIX,zhongguo.ca,Proxy\nDOMAIN-SUFFIX,bt49.com,Proxy\nDOMAIN-SUFFIX,interpark.com,Proxy\nDOMAIN-SUFFIX,doctorofcredit.wpengine.com,Proxy\nDOMAIN-SUFFIX,yespornplease.to,Proxy\nDOMAIN-SUFFIX,cloud.com,Proxy\nDOMAIN-SUFFIX,canonrumors.com,Proxy\nDOMAIN-SUFFIX,835ooo.net,Proxy\nDOMAIN-SUFFIX,www.itb9999.com,Proxy\nDOMAIN-SUFFIX,www.themarket.ch,Proxy\nDOMAIN-SUFFIX,youcoby.com,Proxy\nDOMAIN-SUFFIX,pe.com,Proxy\nDOMAIN-SUFFIX,bldaily.com,Proxy\nDOMAIN-SUFFIX,www.protocol.com,Proxy\nDOMAIN-SUFFIX,www.simonandschuster.com,Proxy\nDOMAIN-SUFFIX,zpn.im,Proxy\nDOMAIN-SUFFIX,transparency.org,Proxy\nDOMAIN-SUFFIX,www.cncurrent.com,Proxy\nDOMAIN-SUFFIX,larsgeorge.com,Proxy\nDOMAIN-SUFFIX,falundafanevada.org,Proxy\nDOMAIN-SUFFIX,gtv.org,Proxy\nDOMAIN-SUFFIX,forum.tvb.com,Proxy\nDOMAIN-SUFFIX,avatars2.githubusercontent.com,Proxy\nDOMAIN-SUFFIX,ssrapid.com,Proxy\nDOMAIN-SUFFIX,amateurgalls.com,Proxy\nDOMAIN-SUFFIX,t513.site,Proxy\nDOMAIN-SUFFIX,chubun.com,Proxy\nDOMAIN-SUFFIX,iamnick.ddns.net,Proxy\nDOMAIN-SUFFIX,nitter.soopy.moe,Proxy\nDOMAIN-SUFFIX,edubridge.com,Proxy\nDOMAIN-SUFFIX,khurul.ru,Proxy\nDOMAIN-SUFFIX,v2raytech.com,Proxy\nDOMAIN-SUFFIX,glasker.com,Proxy\nDOMAIN-SUFFIX,jz706.com,Proxy\nDOMAIN-SUFFIX,d2kve7asq7urrz.cloudfront.net,Proxy\nDOMAIN-SUFFIX,coursebase.co,Proxy\nDOMAIN-SUFFIX,zyd.jygweb.org,Proxy\nDOMAIN-SUFFIX,pornscum.com,Proxy\nDOMAIN-SUFFIX,skybl.life,Proxy\nDOMAIN-SUFFIX,www.bennythink.com,Proxy\nDOMAIN-SUFFIX,viewer3.com,Proxy\nDOMAIN-SUFFIX,karodalnet.blogspot.hk,Proxy\nDOMAIN-SUFFIX,adidas.me,Proxy\nDOMAIN-SUFFIX,www.tibetcorps.org,Proxy\nDOMAIN-SUFFIX,shop.netgate.com,Proxy\nDOMAIN-SUFFIX,avidemux.org,Proxy\nDOMAIN-SUFFIX,guardster.com,Proxy\nDOMAIN-SUFFIX,ixquick-proxy.com,Proxy\nDOMAIN-SUFFIX,apiary.io,Proxy\nDOMAIN-SUFFIX,qingyangmovie.be,Proxy\nDOMAIN-SUFFIX,vns2006.com,Proxy\nDOMAIN-SUFFIX,www.ybbbet.com,Proxy\nDOMAIN-SUFFIX,wenhui.ch,Proxy\nDOMAIN-SUFFIX,eventtest.e21magicmedia.com.tw,Proxy\nDOMAIN-SUFFIX,mtw.tl,Proxy\nDOMAIN-SUFFIX,www.atomcentral.com,Proxy\nDOMAIN-SUFFIX,7966.com,Proxy\nDOMAIN-SUFFIX,betway388.com,Proxy\nDOMAIN-SUFFIX,bisi888.cc,Proxy\nDOMAIN-SUFFIX,yotube.com,Proxy\nDOMAIN-SUFFIX,jpname.blogspot.jp,Proxy\nDOMAIN-SUFFIX,raym.ca,Proxy\nDOMAIN-SUFFIX,cgdepot.org,Proxy\nDOMAIN-SUFFIX,apk.tw,Proxy\nDOMAIN-SUFFIX,hk522.ga,Proxy\nDOMAIN-SUFFIX,m.t2201.com,Proxy\nDOMAIN-SUFFIX,tibet-envoy.eu,Proxy\nDOMAIN-SUFFIX,epochweek.com,Proxy\nDOMAIN-SUFFIX,hkbookcity.com,Proxy\nDOMAIN-SUFFIX,www.wahahaha.idv.tw,Proxy\nDOMAIN-SUFFIX,hungry.tw,Proxy\nDOMAIN-SUFFIX,vpnaccounts.com,Proxy\nDOMAIN-SUFFIX,corpus.quran.com,Proxy\nDOMAIN-SUFFIX,wsdc1122.com,Proxy\nDOMAIN-SUFFIX,www.yzc288.com,Proxy\nDOMAIN-SUFFIX,www.institutvajrayogini.fr,Proxy\nDOMAIN-SUFFIX,koryogroup.com,Proxy\nDOMAIN-SUFFIX,test.cloudfunctions.net,Proxy\nDOMAIN-SUFFIX,www.buddhistelibrary.org,Proxy\nDOMAIN-SUFFIX,stemi.tv,Proxy\nDOMAIN-SUFFIX,9605796487-plus.sa168.ws,Proxy\nDOMAIN-SUFFIX,oricon.co.jp,Proxy\nDOMAIN-SUFFIX,blog.revillweb.com,Proxy\nDOMAIN-SUFFIX,democrats.org.au,Proxy\nDOMAIN-SUFFIX,tnr.com,Proxy\nDOMAIN-SUFFIX,hanmibank.com,Proxy\nDOMAIN-SUFFIX,m.yyzb.tv,Proxy\nDOMAIN-SUFFIX,blogs.yahoo.com,Proxy\nDOMAIN-SUFFIX,tibetanliberation.org,Proxy\nDOMAIN-SUFFIX,mrbasic.com,Proxy\nDOMAIN-SUFFIX,milliyet.com.tr,Proxy\nDOMAIN-SUFFIX,shopnbc.com,Proxy\nDOMAIN-SUFFIX,fuckgfw.ggss.cf,Proxy\nDOMAIN-SUFFIX,moduslink.com,Proxy\nDOMAIN-SUFFIX,blogtd.org,Proxy\nDOMAIN-SUFFIX,zenpeacemakers.org,Proxy\nDOMAIN-SUFFIX,whitebear.freebearblog.org,Proxy\nDOMAIN-SUFFIX,code-hub.com,Proxy\nDOMAIN-SUFFIX,tor-exit.eecs.umich.edu,Proxy\nDOMAIN-SUFFIX,speakingclubonline.com,Proxy\nDOMAIN-SUFFIX,20188w.com,Proxy\nDOMAIN-SUFFIX,dolf.org.hk,Proxy\nDOMAIN-SUFFIX,blogs.myspace.com,Proxy\nDOMAIN-SUFFIX,catandbird.net,Proxy\nDOMAIN-SUFFIX,www.vw.idv.tw,Proxy\nDOMAIN-SUFFIX,serveminecraft.net,Proxy\nDOMAIN-SUFFIX,slfwrdbaqv.com,Proxy\nDOMAIN-SUFFIX,wfrick.net,Proxy\nDOMAIN-SUFFIX,www.bellaliant.net,Proxy\nDOMAIN-SUFFIX,571.ddnsking.com,Proxy\nDOMAIN-SUFFIX,online.alexanderforbes.co.za,Proxy\nDOMAIN-SUFFIX,impact.org.au,Proxy\nDOMAIN-SUFFIX,www.gteman.com,Proxy\nDOMAIN-SUFFIX,mjsnails.com.au,Proxy\nDOMAIN-SUFFIX,cloudflare.cdn.openbsd.org,Proxy\nDOMAIN-SUFFIX,unblocked.in,Proxy\nDOMAIN-SUFFIX,seevpn.com,Proxy\nDOMAIN-SUFFIX,searx.tiekoetter.com,Proxy\nDOMAIN-SUFFIX,isc.sans.edu,Proxy\nDOMAIN-SUFFIX,sevenload.com,Proxy\nDOMAIN-SUFFIX,ok.xxx,Proxy\nDOMAIN-SUFFIX,freelan.org,Proxy\nDOMAIN-SUFFIX,www.sau60.org,Proxy\nDOMAIN-SUFFIX,myparagliding.com,Proxy\nDOMAIN-SUFFIX,xianqiao.net,Proxy\nDOMAIN-SUFFIX,hopetv.cz,Proxy\nDOMAIN-SUFFIX,11199662.com,Proxy\nDOMAIN-SUFFIX,333com1.app,Proxy\nDOMAIN-SUFFIX,mooo.com,Proxy\nDOMAIN-SUFFIX,www.wsj-asia.com,Proxy\nDOMAIN-SUFFIX,it4all.ch,Proxy\nDOMAIN-SUFFIX,www.asteimmobili.it,Proxy\nDOMAIN-SUFFIX,bestvpnserver.com,Proxy\nDOMAIN-SUFFIX,wtf.hiigara.net,Proxy\nDOMAIN-SUFFIX,ocxpressit.com,Proxy\nDOMAIN-SUFFIX,seba.cl,Proxy\nDOMAIN-SUFFIX,tiltbrush.com,Proxy\nDOMAIN-SUFFIX,nitter.varishangout.net,Proxy\nDOMAIN-SUFFIX,pttweb.tw,Proxy\nDOMAIN-SUFFIX,sheshaft.com,Proxy\nDOMAIN-SUFFIX,niuyouge.com,Proxy\nDOMAIN-SUFFIX,www.hjdc93.com,Proxy\nDOMAIN-SUFFIX,zaif.jp,Proxy\nDOMAIN-SUFFIX,www.schaumburger-zeitung.de,Proxy\nDOMAIN-SUFFIX,stuarttown.com.au,Proxy\nDOMAIN-SUFFIX,porn87.com,Proxy\nDOMAIN-SUFFIX,ddg.gg,Proxy\nDOMAIN-SUFFIX,sss988.com,Proxy\nDOMAIN-SUFFIX,np.updog.co,Proxy\nDOMAIN-SUFFIX,www.garethmusic.com,Proxy\nDOMAIN-SUFFIX,www.zambianwatchdog.com,Proxy\nDOMAIN-SUFFIX,cmx.im,Proxy\nDOMAIN-SUFFIX,channel24.co.za,Proxy\nDOMAIN-SUFFIX,persecutionblog.com,Proxy\nDOMAIN-SUFFIX,ca7055.com,Proxy\nDOMAIN-SUFFIX,www.hotseeshow.com,Proxy\nDOMAIN-SUFFIX,justicewillprevail.com,Proxy\nDOMAIN-SUFFIX,imb.org,Proxy\nDOMAIN-SUFFIX,strongwindpress.com,Proxy\nDOMAIN-SUFFIX,applemusic-spotlight.myunidays.com,Proxy\nDOMAIN-SUFFIX,www.ggncr.com,Proxy\nDOMAIN-SUFFIX,js44444.com,Proxy\nDOMAIN-SUFFIX,trendsmap.com,Proxy\nDOMAIN-SUFFIX,yo88.com,Proxy\nDOMAIN-SUFFIX,www.hkci.org.hk,Proxy\nDOMAIN-SUFFIX,doujinantena.com,Proxy\nDOMAIN-SUFFIX,4fun.tw,Proxy\nDOMAIN-SUFFIX,btmye.xyz,Proxy\nDOMAIN-SUFFIX,d1gvju21bnqlk7.cloudfront.net,Proxy\nDOMAIN-SUFFIX,izaobao.us,Proxy\nDOMAIN-SUFFIX,668z668.com,Proxy\nDOMAIN-SUFFIX,telega.one,Proxy\nDOMAIN-SUFFIX,d2s7jtuv2mt6lv.cloudfront.net,Proxy\nDOMAIN-SUFFIX,developer.apple.com,Proxy\nDOMAIN-SUFFIX,nlfreevpn.com,Proxy\nDOMAIN-SUFFIX,www.yuebet.com,Proxy\nDOMAIN-SUFFIX,1680103kai.co,Proxy\nDOMAIN-SUFFIX,taiwannation.com,Proxy\nDOMAIN-SUFFIX,apk-dl.com,Proxy\nDOMAIN-SUFFIX,www.shangproperties.com,Proxy\nDOMAIN-SUFFIX,b.mome.pro,Proxy\nDOMAIN-SUFFIX,www.e8926.com,Proxy\nDOMAIN-SUFFIX,mod.cht.com.tw,Proxy\nDOMAIN-SUFFIX,thegrocerygame.com,Proxy\nDOMAIN-SUFFIX,openprompt.co,Proxy\nDOMAIN-SUFFIX,www.vhx.tv,Proxy\nDOMAIN-SUFFIX,ty535.com,Proxy\nDOMAIN-SUFFIX,pscp.tv,Proxy\nDOMAIN-SUFFIX,privatevoyeur.com,Proxy\nDOMAIN-SUFFIX,www.amtb-dba.org,Proxy\nDOMAIN-SUFFIX,gmodules.com,Proxy\nDOMAIN-SUFFIX,stlyrics.com,Proxy\nDOMAIN-SUFFIX,calgarychinese.com,Proxy\nDOMAIN-SUFFIX,tw.nextapple.com,Proxy\nDOMAIN-SUFFIX,www.bithumb.com,Proxy\nDOMAIN-SUFFIX,wodemo.com,Proxy\nDOMAIN-SUFFIX,collateralmurder.com,Proxy\nDOMAIN-SUFFIX,mobile.cgpay.io,Proxy\nDOMAIN-SUFFIX,8587i.cc,Proxy\nDOMAIN-SUFFIX,yourprivatevpn.com,Proxy\nDOMAIN-SUFFIX,trovi.com,Proxy\nDOMAIN-SUFFIX,newswhip.com,Proxy\nDOMAIN-SUFFIX,ddj118.com,Proxy\nDOMAIN-SUFFIX,mysitecost.com,Proxy\nDOMAIN-SUFFIX,a.baos.us,Proxy\nDOMAIN-SUFFIX,dd5.dtdns.net,Proxy\nDOMAIN-SUFFIX,cdn.zgjznkyy.com,Proxy\nDOMAIN-SUFFIX,www.xh8703.com,Proxy\nDOMAIN-SUFFIX,soundcloud.org,Proxy\nDOMAIN-SUFFIX,breakwall.net,Proxy\nDOMAIN-SUFFIX,www.kproxy.org,Proxy\nDOMAIN-SUFFIX,www.wildbild.com,Proxy\nDOMAIN-SUFFIX,eevpn.com,Proxy\nDOMAIN-SUFFIX,shmooze.com,Proxy\nDOMAIN-SUFFIX,largeporntube.com,Proxy\nDOMAIN-SUFFIX,291.microcycas.com,Proxy\nDOMAIN-SUFFIX,xiezhua.com,Proxy\nDOMAIN-SUFFIX,520ccc.cc,Proxy\nDOMAIN-SUFFIX,100mermaids.kir.jp,Proxy\nDOMAIN-SUFFIX,zzux.com,Proxy\nDOMAIN-SUFFIX,abadcaseofthedates.com,Proxy\nDOMAIN-SUFFIX,orthodome.com,Proxy\nDOMAIN-SUFFIX,ozvoice.org,Proxy\nDOMAIN-SUFFIX,foojar.com,Proxy\nDOMAIN-SUFFIX,thetaskforce.org,Proxy\nDOMAIN-SUFFIX,corpuslibros.com.ar,Proxy\nDOMAIN-SUFFIX,zh.nyahentai.com,Proxy\nDOMAIN-SUFFIX,ozdav.com,Proxy\nDOMAIN-SUFFIX,d2usayt5upxf6i.cloudfront.net,Proxy\nDOMAIN-SUFFIX,homezz.com,Proxy\nDOMAIN-SUFFIX,johnham.net,Proxy\nDOMAIN-SUFFIX,economistasia.com,Proxy\nDOMAIN-SUFFIX,b.hoob.us,Proxy\nDOMAIN-SUFFIX,ddns.me.uk,Proxy\nDOMAIN-SUFFIX,dmbjjp7n9kgns.cloudfront.net,Proxy\nDOMAIN-SUFFIX,fengzhenghu.net,Proxy\nDOMAIN-SUFFIX,270700.cc,Proxy\nDOMAIN-SUFFIX,d42i.r5.cr.rs,Proxy\nDOMAIN-SUFFIX,hrgj42.com,Proxy\nDOMAIN-SUFFIX,api.api.ai,Proxy\nDOMAIN-SUFFIX,1616.com,Proxy\nDOMAIN-SUFFIX,bigtits.com,Proxy\nDOMAIN-SUFFIX,www.m88sb.com,Proxy\nDOMAIN-SUFFIX,j088088.com,Proxy\nDOMAIN-SUFFIX,zh.ecdm.wikia.com,Proxy\nDOMAIN-SUFFIX,c23.privatedns.org,Proxy\nDOMAIN-SUFFIX,twapperkeeper.com,Proxy\nDOMAIN-SUFFIX,www.tb518.com,Proxy\nDOMAIN-SUFFIX,netaffiliation.com,Proxy\nDOMAIN-SUFFIX,8.jygnet.org,Proxy\nDOMAIN-SUFFIX,br.linkedin.com,Proxy\nDOMAIN-SUFFIX,kinokuniya.com,Proxy\nDOMAIN-SUFFIX,hwayue.org.tw,Proxy\nDOMAIN-SUFFIX,rzo.cc,Proxy\nDOMAIN-SUFFIX,www.paofucloud.com,Proxy\nDOMAIN-SUFFIX,www.infranken.de,Proxy\nDOMAIN-SUFFIX,go.icann.org,Proxy\nDOMAIN-SUFFIX,nas.hcy.idv.tw,Proxy\nDOMAIN-SUFFIX,d2.sku117.club,Proxy\nDOMAIN-SUFFIX,iqq.biz,Proxy\nDOMAIN-SUFFIX,krinreed.ml,Proxy\nDOMAIN-SUFFIX,pixolium.com,Proxy\nDOMAIN-SUFFIX,yifanhunaa.com,Proxy\nDOMAIN-SUFFIX,dlxthj4dgku6j.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.austria.org,Proxy\nDOMAIN-SUFFIX,www.neilyoung.com,Proxy\nDOMAIN-SUFFIX,static.comico.tw,Proxy\nDOMAIN-SUFFIX,chihuahuas.com.ar,Proxy\nDOMAIN-SUFFIX,marcenes.com.br,Proxy\nDOMAIN-SUFFIX,arrowcat.co.uk,Proxy\nDOMAIN-SUFFIX,www.liwangyang.com,Proxy\nDOMAIN-SUFFIX,yyjlymb.xyz,Proxy\nDOMAIN-SUFFIX,pascual.co.nz,Proxy\nDOMAIN-SUFFIX,paopao6.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,linkedin.com,Proxy\nDOMAIN-SUFFIX,blockless.com,Proxy\nDOMAIN-SUFFIX,com.google,Proxy\nDOMAIN-SUFFIX,tibetanaidproject.org,Proxy\nDOMAIN-SUFFIX,oclearningteam.co.uk,Proxy\nDOMAIN-SUFFIX,m.dj0020.com,Proxy\nDOMAIN-SUFFIX,safetunnel.tk,Proxy\nDOMAIN-SUFFIX,www.readingthechinadream.com,Proxy\nDOMAIN-SUFFIX,comic-mega.me,Proxy\nDOMAIN-SUFFIX,cyberghost.com,Proxy\nDOMAIN-SUFFIX,www.mystrongvpn.com,Proxy\nDOMAIN-SUFFIX,digitalcourage.de,Proxy\nDOMAIN-SUFFIX,sis.powayusd.com,Proxy\nDOMAIN-SUFFIX,60designwebpick.com,Proxy\nDOMAIN-SUFFIX,www.falconstudios.com,Proxy\nDOMAIN-SUFFIX,fr1lib.org,Proxy\nDOMAIN-SUFFIX,apic.pinnacle.com,Proxy\nDOMAIN-SUFFIX,31666333.com,Proxy\nDOMAIN-SUFFIX,forum.mymaji.com,Proxy\nDOMAIN-SUFFIX,violet.la,Proxy\nDOMAIN-SUFFIX,www.tblop.com,Proxy\nDOMAIN-SUFFIX,puredrifter.com,Proxy\nDOMAIN-SUFFIX,ai-kan.net,Proxy\nDOMAIN-SUFFIX,clipdrop.co,Proxy\nDOMAIN-SUFFIX,avg.com,Proxy\nDOMAIN-SUFFIX,www.globaltm.org,Proxy\nDOMAIN-SUFFIX,nofile.io,Proxy\nDOMAIN-SUFFIX,www.pttbrain.com,Proxy\nDOMAIN-SUFFIX,www.on3.cn,Proxy\nDOMAIN-SUFFIX,civicparty.hk,Proxy\nDOMAIN-SUFFIX,officialcharts.com,Proxy\nDOMAIN-SUFFIX,edu.blisswisdom.org,Proxy\nDOMAIN-SUFFIX,taylor-swift-club.sclub.tw,Proxy\nDOMAIN-SUFFIX,915813.com,Proxy\nDOMAIN-SUFFIX,lyricsmasti.com,Proxy\nDOMAIN-SUFFIX,chubold.com,Proxy\nDOMAIN-SUFFIX,xj8865.com,Proxy\nDOMAIN-SUFFIX,nord4china.com,Proxy\nDOMAIN-SUFFIX,6684.strikingly.com,Proxy\nDOMAIN-SUFFIX,van001.com,Proxy\nDOMAIN-SUFFIX,82ccbb.com,Proxy\nDOMAIN-SUFFIX,vpnintouch.net,Proxy\nDOMAIN-SUFFIX,static.criteo.net,Proxy\nDOMAIN-SUFFIX,d4b2zqvgah5lo.cloudfront.net,Proxy\nDOMAIN-SUFFIX,devio.us,Proxy\nDOMAIN-SUFFIX,barnabu.co.uk,Proxy\nDOMAIN-SUFFIX,myeasytv.com,Proxy\nDOMAIN-SUFFIX,m.yzc369.com,Proxy\nDOMAIN-SUFFIX,ro.lt,Proxy\nDOMAIN-SUFFIX,cincodias.com,Proxy\nDOMAIN-SUFFIX,cchere.com,Proxy\nDOMAIN-SUFFIX,millalen.cl,Proxy\nDOMAIN-SUFFIX,googlelabs.com,Proxy\nDOMAIN-SUFFIX,meibath.com,Proxy\nDOMAIN-SUFFIX,www.lovekimo.com,Proxy\nDOMAIN-SUFFIX,xh.freepac.pw,Proxy\nDOMAIN-SUFFIX,d11qmx1pyond8k.cloudfront.net,Proxy\nDOMAIN-SUFFIX,imlive.com,Proxy\nDOMAIN-SUFFIX,ca151.com,Proxy\nDOMAIN-SUFFIX,vns1020.com,Proxy\nDOMAIN-SUFFIX,xiuxiqu.life,Proxy\nDOMAIN-SUFFIX,workflows.co.uk,Proxy\nDOMAIN-SUFFIX,qizhenyu.com,Proxy\nDOMAIN-SUFFIX,mcaf.ee,Proxy\nDOMAIN-SUFFIX,oreilco.com,Proxy\nDOMAIN-SUFFIX,b464.com,Proxy\nDOMAIN-SUFFIX,google.co.tz,Proxy\nDOMAIN-SUFFIX,battle1.gtasia777.com,Proxy\nDOMAIN-SUFFIX,btaia.com,Proxy\nDOMAIN-SUFFIX,shile.xyz,Proxy\nDOMAIN-SUFFIX,www.econjobrumors.com,Proxy\nDOMAIN-SUFFIX,video.genyt.net,Proxy\nDOMAIN-SUFFIX,ekh3.way-to-win.com,Proxy\nDOMAIN-SUFFIX,tibetnetwork.com,Proxy\nDOMAIN-SUFFIX,www.nicolasmoro.net,Proxy\nDOMAIN-SUFFIX,povcum.com,Proxy\nDOMAIN-SUFFIX,pornburst.xxx,Proxy\nDOMAIN-SUFFIX,usacn.com,Proxy\nDOMAIN-SUFFIX,security.googleblog.com,Proxy\nDOMAIN-SUFFIX,americankabuki.blogspot.hk,Proxy\nDOMAIN-SUFFIX,cl.flag.fi,Proxy\nDOMAIN-SUFFIX,d28g4cvl4xumtr.cloudfront.net,Proxy\nDOMAIN-SUFFIX,iisacc.net,Proxy\nDOMAIN-SUFFIX,pr0xy.com,Proxy\nDOMAIN-SUFFIX,boxunclub.com,Proxy\nDOMAIN-SUFFIX,heqinglian.net,Proxy\nDOMAIN-SUFFIX,rixcloud.com,Proxy\nDOMAIN-SUFFIX,rangzen.net,Proxy\nDOMAIN-SUFFIX,lianyue.net,Proxy\nDOMAIN-SUFFIX,ca891.com,Proxy\nDOMAIN-SUFFIX,www.20thingsilearned.com,Proxy\nDOMAIN-SUFFIX,tanglaoshu.com,Proxy\nDOMAIN-SUFFIX,www.409z.com,Proxy\nDOMAIN-SUFFIX,centauro.com.br,Proxy\nDOMAIN-SUFFIX,hackpad.com,Proxy\nDOMAIN-SUFFIX,www.lenoircityschools.net,Proxy\nDOMAIN-SUFFIX,www.bj6666.com,Proxy\nDOMAIN-SUFFIX,d33rhn1om6dyij.cloudfront.net,Proxy\nDOMAIN-SUFFIX,search.xxx,Proxy\nDOMAIN-SUFFIX,www.top10vpn.com,Proxy\nDOMAIN-SUFFIX,maverlinn.com,Proxy\nDOMAIN-SUFFIX,d1.zgdhhjha.com,Proxy\nDOMAIN-SUFFIX,montajrigips.ro,Proxy\nDOMAIN-SUFFIX,fayknowles.com,Proxy\nDOMAIN-SUFFIX,zverovich.net,Proxy\nDOMAIN-SUFFIX,dudcpok.animefreak.tv,Proxy\nDOMAIN-SUFFIX,unblocksocial.net,Proxy\nDOMAIN-SUFFIX,24hrs.ca,Proxy\nDOMAIN-SUFFIX,www.looktoronto.com,Proxy\nDOMAIN-SUFFIX,portavitae.cl,Proxy\nDOMAIN-SUFFIX,www.akhersaa-dz.com,Proxy\nDOMAIN-SUFFIX,anvpn.com,Proxy\nDOMAIN-SUFFIX,www.sakuravpn.com,Proxy\nDOMAIN-SUFFIX,0888.azureedge.net,Proxy\nDOMAIN-SUFFIX,onmypc.info,Proxy\nDOMAIN-SUFFIX,338763.com,Proxy\nDOMAIN-SUFFIX,candor-ags.com,Proxy\nDOMAIN-SUFFIX,www.dailydalailama.com,Proxy\nDOMAIN-SUFFIX,azubu.com,Proxy\nDOMAIN-SUFFIX,nakedtube.com,Proxy\nDOMAIN-SUFFIX,www.janusnig.gnbo.com.ng,Proxy\nDOMAIN-SUFFIX,kh.tcp4.me,Proxy\nDOMAIN-SUFFIX,pinterest.nl,Proxy\nDOMAIN-SUFFIX,limousinethailand.com,Proxy\nDOMAIN-SUFFIX,inmediahk.net,Proxy\nDOMAIN-SUFFIX,195554.com,Proxy\nDOMAIN-SUFFIX,stuarttown.org.au,Proxy\nDOMAIN-SUFFIX,1dumb.com,Proxy\nDOMAIN-SUFFIX,2049bbs.github.io,Proxy\nDOMAIN-SUFFIX,lantern1.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,naol.cc,Proxy\nDOMAIN-SUFFIX,huffingtonpost.ca,Proxy\nDOMAIN-SUFFIX,beemp3s.net,Proxy\nDOMAIN-SUFFIX,www.laserfiche.com,Proxy\nDOMAIN-SUFFIX,faproxy.com,Proxy\nDOMAIN-SUFFIX,www.cnfree.com,Proxy\nDOMAIN-SUFFIX,prendiporno.tv,Proxy\nDOMAIN-SUFFIX,xinhuanet.org,Proxy\nDOMAIN-SUFFIX,dailyniner.com,Proxy\nDOMAIN-SUFFIX,himalaya2020.com,Proxy\nDOMAIN-SUFFIX,deledible.com.au,Proxy\nDOMAIN-SUFFIX,luxebc.com,Proxy\nDOMAIN-SUFFIX,panel.starp.work,Proxy\nDOMAIN-SUFFIX,www.versal.com,Proxy\nDOMAIN-SUFFIX,www.techfun.us,Proxy\nDOMAIN-SUFFIX,dlugosza25a.pl,Proxy\nDOMAIN-SUFFIX,tibet.to,Proxy\nDOMAIN-SUFFIX,newstag.com,Proxy\nDOMAIN-SUFFIX,mobile.teenslovehugecocks.com,Proxy\nDOMAIN-SUFFIX,www.aboutus.com,Proxy\nDOMAIN-SUFFIX,jasaresmi.com,Proxy\nDOMAIN-SUFFIX,www.playwoods.com,Proxy\nDOMAIN-SUFFIX,build-laccd.org,Proxy\nDOMAIN-SUFFIX,newsdh.com,Proxy\nDOMAIN-SUFFIX,bit.orgs.hk,Proxy\nDOMAIN-SUFFIX,joys999.com,Proxy\nDOMAIN-SUFFIX,mydogear.com,Proxy\nDOMAIN-SUFFIX,fuligirls.me,Proxy\nDOMAIN-SUFFIX,www.99cscs.com,Proxy\nDOMAIN-SUFFIX,www.bbgdirect.com,Proxy\nDOMAIN-SUFFIX,jgjsvip2.com,Proxy\nDOMAIN-SUFFIX,igrejauniversal.org.br,Proxy\nDOMAIN-SUFFIX,81666.com,Proxy\nDOMAIN-SUFFIX,www.hw11.cc,Proxy\nDOMAIN-SUFFIX,www.lobstertube.com,Proxy\nDOMAIN-SUFFIX,tracking.rb88.com,Proxy\nDOMAIN-SUFFIX,wb.graylady.us,Proxy\nDOMAIN-SUFFIX,xh4777.com,Proxy\nDOMAIN-SUFFIX,galaxybuy.net,Proxy\nDOMAIN-SUFFIX,djpt988.com,Proxy\nDOMAIN-SUFFIX,peggo.co,Proxy\nDOMAIN-SUFFIX,gets-it.net,Proxy\nDOMAIN-SUFFIX,veixin.icccq.com,Proxy\nDOMAIN-SUFFIX,lantern.com,Proxy\nDOMAIN-SUFFIX,ley.flnet.org,Proxy\nDOMAIN-SUFFIX,wng.org,Proxy\nDOMAIN-SUFFIX,leasequery.com,Proxy\nDOMAIN-SUFFIX,vpncompare.co.uk,Proxy\nDOMAIN-SUFFIX,freeviewmovies.com,Proxy\nDOMAIN-SUFFIX,www.innohat.com,Proxy\nDOMAIN-SUFFIX,googledomains.com,Proxy\nDOMAIN-SUFFIX,privadovpn.com,Proxy\nDOMAIN-SUFFIX,aculo.us,Proxy\nDOMAIN-SUFFIX,jaycybird.com,Proxy\nDOMAIN-SUFFIX,ssnode.com,Proxy\nDOMAIN-SUFFIX,lezcuties.com,Proxy\nDOMAIN-SUFFIX,gbf.co.in,Proxy\nDOMAIN-SUFFIX,desinfecteya.com.ar,Proxy\nDOMAIN-SUFFIX,csis.org,Proxy\nDOMAIN-SUFFIX,dalailam.com,Proxy\nDOMAIN-SUFFIX,eprice.com.hk,Proxy\nDOMAIN-SUFFIX,vpnunlimitedapp.com,Proxy\nDOMAIN-SUFFIX,hellohost.net,Proxy\nDOMAIN-SUFFIX,velkaepocha.sk,Proxy\nDOMAIN-SUFFIX,ch23.ga,Proxy\nDOMAIN-SUFFIX,29.flnet.org,Proxy\nDOMAIN-SUFFIX,hentaidude.com,Proxy\nDOMAIN-SUFFIX,05350988.com,Proxy\nDOMAIN-SUFFIX,moe2.ga,Proxy\nDOMAIN-SUFFIX,insecam.org,Proxy\nDOMAIN-SUFFIX,no.flnet.org,Proxy\nDOMAIN-SUFFIX,jeziorski.me,Proxy\nDOMAIN-SUFFIX,www.2adultflashgames.com,Proxy\nDOMAIN-SUFFIX,amjs669.com,Proxy\nDOMAIN-SUFFIX,falundafa-pa.net,Proxy\nDOMAIN-SUFFIX,www.twgbr.org.tw,Proxy\nDOMAIN-SUFFIX,ssl443.org,Proxy\nDOMAIN-SUFFIX,fuyin.net,Proxy\nDOMAIN-SUFFIX,dongtalwang.com,Proxy\nDOMAIN-SUFFIX,actuweb.net,Proxy\nDOMAIN-SUFFIX,www.myubet.com,Proxy\nDOMAIN-SUFFIX,test.freepac.pw,Proxy\nDOMAIN-SUFFIX,1818.net,Proxy\nDOMAIN-SUFFIX,www.mihk.tv,Proxy\nDOMAIN-SUFFIX,thinkstockphotos.com,Proxy\nDOMAIN-SUFFIX,www.huisun.tw,Proxy\nDOMAIN-SUFFIX,kakao.com,Proxy\nDOMAIN-SUFFIX,simonsharp.ch,Proxy\nDOMAIN-SUFFIX,cyber-insider.com,Proxy\nDOMAIN-SUFFIX,gpt.mygpt.bid,Proxy\nDOMAIN-SUFFIX,mail.xin-hua-net.com,Proxy\nDOMAIN-SUFFIX,beijingzx.org,Proxy\nDOMAIN-SUFFIX,flurry.com,Proxy\nDOMAIN-SUFFIX,h5.ld7777.tv,Proxy\nDOMAIN-SUFFIX,www.mhakel.com,Proxy\nDOMAIN-SUFFIX,www.tinhte.vn,Proxy\nDOMAIN-SUFFIX,www.91ipip.com,Proxy\nDOMAIN-SUFFIX,www.cat-sky.idv.tw,Proxy\nDOMAIN-SUFFIX,ihned.cz,Proxy\nDOMAIN-SUFFIX,www.1883030.com,Proxy\nDOMAIN-SUFFIX,91av.us,Proxy\nDOMAIN-SUFFIX,tsu.org.tw,Proxy\nDOMAIN-SUFFIX,yilubbs.com,Proxy\nDOMAIN-SUFFIX,cx.v2ray.cx,Proxy\nDOMAIN-SUFFIX,mail.hsbpartners.com,Proxy\nDOMAIN-SUFFIX,pixpol.com,Proxy\nDOMAIN-SUFFIX,d3i52hv1lob0i9.cloudfront.net,Proxy\nDOMAIN-SUFFIX,wikileaks.lu,Proxy\nDOMAIN-SUFFIX,ahri8.top,Proxy\nDOMAIN-SUFFIX,www.cht.com.tw,Proxy\nDOMAIN-SUFFIX,hellotxt.com,Proxy\nDOMAIN-SUFFIX,kurtmunger.com,Proxy\nDOMAIN-SUFFIX,rthklive1-lh.akamaihd.net,Proxy\nDOMAIN-SUFFIX,zzs.dnstogo.xyz,Proxy\nDOMAIN-SUFFIX,q2678.com,Proxy\nDOMAIN-SUFFIX,greenreadings.com,Proxy\nDOMAIN-SUFFIX,www.interiorsandsources.com,Proxy\nDOMAIN-SUFFIX,hexwell.net,Proxy\nDOMAIN-SUFFIX,54.from-nh.com,Proxy\nDOMAIN-SUFFIX,233.ddns.net,Proxy\nDOMAIN-SUFFIX,tegenlicht.vpro.nl,Proxy\nDOMAIN-SUFFIX,passeporttibetain.org,Proxy\nDOMAIN-SUFFIX,youtubekids.com,Proxy\nDOMAIN-SUFFIX,www.fastwave.tw,Proxy\nDOMAIN-SUFFIX,mlcool.com,Proxy\nDOMAIN-SUFFIX,sinopsis.cz,Proxy\nDOMAIN-SUFFIX,ifsmarkets.com,Proxy\nDOMAIN-SUFFIX,mathmidterm.com,Proxy\nDOMAIN-SUFFIX,fuckteamfive.com,Proxy\nDOMAIN-SUFFIX,www.oxid.it,Proxy\nDOMAIN-SUFFIX,doh.la.ahadns.net,Proxy\nDOMAIN-SUFFIX,jp.tiar.app,Proxy\nDOMAIN-SUFFIX,copymanga.com,Proxy\nDOMAIN-SUFFIX,healthorg.xyz,Proxy\nDOMAIN-SUFFIX,gfrevenge.com,Proxy\nDOMAIN-SUFFIX,15vfw8.com,Proxy\nDOMAIN-SUFFIX,gongchao.org,Proxy\nDOMAIN-SUFFIX,bcast.co.nz,Proxy\nDOMAIN-SUFFIX,wtbnnews.org,Proxy\nDOMAIN-SUFFIX,www.avmask.com,Proxy\nDOMAIN-SUFFIX,www.themonthly.com.au,Proxy\nDOMAIN-SUFFIX,projectredcap.org,Proxy\nDOMAIN-SUFFIX,headlinestoday.intoday.in,Proxy\nDOMAIN-SUFFIX,apk.tv333.us,Proxy\nDOMAIN-SUFFIX,zh.erocool.me,Proxy\nDOMAIN-SUFFIX,zh999.kickme.to,Proxy\nDOMAIN-SUFFIX,castawaysinn.com,Proxy\nDOMAIN-SUFFIX,quaktre.blogspot.com.tr,Proxy\nDOMAIN-SUFFIX,cweb-pix.com,Proxy\nDOMAIN-SUFFIX,fastdog.uk,Proxy\nDOMAIN-SUFFIX,ssl.webpack.de,Proxy\nDOMAIN-SUFFIX,www.moscowicc.org,Proxy\nDOMAIN-SUFFIX,399xpj.com,Proxy\nDOMAIN-SUFFIX,www.tonalsoft.com,Proxy\nDOMAIN-SUFFIX,fyt82.com,Proxy\nDOMAIN-SUFFIX,counter.social,Proxy\nDOMAIN-SUFFIX,finler.net,Proxy\nDOMAIN-SUFFIX,fdc89.org,Proxy\nDOMAIN-SUFFIX,dynit.it,Proxy\nDOMAIN-SUFFIX,610811.com,Proxy\nDOMAIN-SUFFIX,d2jxuacjsb1afr.cloudfront.net,Proxy\nDOMAIN-SUFFIX,shadowsocks.be,Proxy\nDOMAIN-SUFFIX,www.thebigconversationspace.org,Proxy\nDOMAIN-SUFFIX,vw.com.tr,Proxy\nDOMAIN-SUFFIX,iloveinterracial.com,Proxy\nDOMAIN-SUFFIX,us12.campaign-archive.com,Proxy\nDOMAIN-SUFFIX,brightcr.com,Proxy\nDOMAIN-SUFFIX,ied2k.net,Proxy\nDOMAIN-SUFFIX,hkchurch.org,Proxy\nDOMAIN-SUFFIX,y1708.com,Proxy\nDOMAIN-SUFFIX,sod.co.jp,Proxy\nDOMAIN-SUFFIX,reyval.mx,Proxy\nDOMAIN-SUFFIX,88cnpanda.com,Proxy\nDOMAIN-SUFFIX,en.chine.eu,Proxy\nDOMAIN-SUFFIX,imgmega.com,Proxy\nDOMAIN-SUFFIX,status.twhirl.org,Proxy\nDOMAIN-SUFFIX,h88h88.com,Proxy\nDOMAIN-SUFFIX,windscribe.net,Proxy\nDOMAIN-SUFFIX,er-webs.com,Proxy\nDOMAIN-SUFFIX,notevenwrong.net,Proxy\nDOMAIN-SUFFIX,evilangelvideo.com,Proxy\nDOMAIN-SUFFIX,ggso.me,Proxy\nDOMAIN-SUFFIX,sq.itimemachine.net,Proxy\nDOMAIN-SUFFIX,centerforhumanreprod.com,Proxy\nDOMAIN-SUFFIX,dsn1171a.com,Proxy\nDOMAIN-SUFFIX,netsohes.com.br,Proxy\nDOMAIN-SUFFIX,byt101.com,Proxy\nDOMAIN-SUFFIX,pornlulu.com,Proxy\nDOMAIN-SUFFIX,slyip.net,Proxy\nDOMAIN-SUFFIX,5626k.com,Proxy\nDOMAIN-SUFFIX,www.3proxy.com,Proxy\nDOMAIN-SUFFIX,ie.h2.dhcp.biz,Proxy\nDOMAIN-SUFFIX,wiki.beparanoid.de,Proxy\nDOMAIN-SUFFIX,tgvpn.com,Proxy\nDOMAIN-SUFFIX,duckdns.org,Proxy\nDOMAIN-SUFFIX,allasianpornstars.com,Proxy\nDOMAIN-SUFFIX,smartsimcha.com,Proxy\nDOMAIN-SUFFIX,www.xiaxiaoqiang.net,Proxy\nDOMAIN-SUFFIX,manwa.me,Proxy\nDOMAIN-SUFFIX,sxqp1.vip,Proxy\nDOMAIN-SUFFIX,dalailamafilm.com,Proxy\nDOMAIN-SUFFIX,leolux.com,Proxy\nDOMAIN-SUFFIX,c0770.com,Proxy\nDOMAIN-SUFFIX,www.kwarizm.com,Proxy\nDOMAIN-SUFFIX,pp25server.com,Proxy\nDOMAIN-SUFFIX,blazinghosted.com,Proxy\nDOMAIN-SUFFIX,www.runoz.us,Proxy\nDOMAIN-SUFFIX,www.taichung-plaza.com,Proxy\nDOMAIN-SUFFIX,coinsbank.com,Proxy\nDOMAIN-SUFFIX,yourdailypornstars.com,Proxy\nDOMAIN-SUFFIX,518.com.tw,Proxy\nDOMAIN-SUFFIX,certificate.revocationcheck.com,Proxy\nDOMAIN-SUFFIX,hkreadingcity.net,Proxy\nDOMAIN-SUFFIX,bbbccj.com,Proxy\nDOMAIN-SUFFIX,bangyoulater.com,Proxy\nDOMAIN-SUFFIX,www.dyvip676.com,Proxy\nDOMAIN-SUFFIX,1155buyu.com,Proxy\nDOMAIN-SUFFIX,comcast.net,Proxy\nDOMAIN-SUFFIX,infiniteguest.com,Proxy\nDOMAIN-SUFFIX,on.cc,Proxy\nDOMAIN-SUFFIX,ru1lib.org,Proxy\nDOMAIN-SUFFIX,iqq3.xyz,Proxy\nDOMAIN-SUFFIX,wheatseeds.org,Proxy\nDOMAIN-SUFFIX,shemalestube.com,Proxy\nDOMAIN-SUFFIX,s2.scieron.com,Proxy\nDOMAIN-SUFFIX,chhy01.com,Proxy\nDOMAIN-SUFFIX,www.1kan.org,Proxy\nDOMAIN-SUFFIX,hizbuttahrir.org,Proxy\nDOMAIN-SUFFIX,ladina.com.au,Proxy\nDOMAIN-SUFFIX,andinista.cl,Proxy\nDOMAIN-SUFFIX,softether-download.com,Proxy\nDOMAIN-SUFFIX,www.sisd.net,Proxy\nDOMAIN-SUFFIX,paramitadirect.com,Proxy\nDOMAIN-SUFFIX,dragon-fly.club,Proxy\nDOMAIN-SUFFIX,cko8.com,Proxy\nDOMAIN-SUFFIX,freetibetanheroes.org,Proxy\nDOMAIN-SUFFIX,www.hotmovies.com,Proxy\nDOMAIN-SUFFIX,pymc.cl,Proxy\nDOMAIN-SUFFIX,www.plexvip.com,Proxy\nDOMAIN-SUFFIX,qqgroup.insight-labs.org,Proxy\nDOMAIN-SUFFIX,image01.fenhao24.com,Proxy\nDOMAIN-SUFFIX,www.humanite.fr,Proxy\nDOMAIN-SUFFIX,qiangyou.org,Proxy\nDOMAIN-SUFFIX,thespeeder.com,Proxy\nDOMAIN-SUFFIX,542.quantumidiot.com,Proxy\nDOMAIN-SUFFIX,xinbi228.com,Proxy\nDOMAIN-SUFFIX,img.buzzfeed.com,Proxy\nDOMAIN-SUFFIX,69story.com,Proxy\nDOMAIN-SUFFIX,ss-free.net,Proxy\nDOMAIN-SUFFIX,watvintro.org,Proxy\nDOMAIN-SUFFIX,purplelotus.org,Proxy\nDOMAIN-SUFFIX,sougouwiki.com,Proxy\nDOMAIN-SUFFIX,cannotfind.me,Proxy\nDOMAIN-SUFFIX,retweetist.com,Proxy\nDOMAIN-SUFFIX,sometconstruct.ro,Proxy\nDOMAIN-SUFFIX,bjh3.com,Proxy\nDOMAIN-SUFFIX,nitter.mint.lgbt,Proxy\nDOMAIN-SUFFIX,lantern6.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,yyvpn.com,Proxy\nDOMAIN-SUFFIX,katyisd.instructure.com,Proxy\nDOMAIN-SUFFIX,www.gulige.com,Proxy\nDOMAIN-SUFFIX,ozchinese.com,Proxy\nDOMAIN-SUFFIX,inkstonenews.com,Proxy\nDOMAIN-SUFFIX,s.tinyrealm.com,Proxy\nDOMAIN-SUFFIX,darrensibley.co.uk,Proxy\nDOMAIN-SUFFIX,data.leafwind.tw,Proxy\nDOMAIN-SUFFIX,www.nouvelobs.com,Proxy\nDOMAIN-SUFFIX,www.gettyimages.it,Proxy\nDOMAIN-SUFFIX,789046.cc,Proxy\nDOMAIN-SUFFIX,amuldairy.com,Proxy\nDOMAIN-SUFFIX,guardcalls.demojoomla.com,Proxy\nDOMAIN-SUFFIX,superman2012.hostzi.com,Proxy\nDOMAIN-SUFFIX,wt586.com,Proxy\nDOMAIN-SUFFIX,rightsin.com,Proxy\nDOMAIN-SUFFIX,nytcnapp.blob.core.windows.net,Proxy\nDOMAIN-SUFFIX,gspshipyard.ro,Proxy\nDOMAIN-SUFFIX,www.archiviolastampa.it,Proxy\nDOMAIN-SUFFIX,etowns.net,Proxy\nDOMAIN-SUFFIX,pornbb.org,Proxy\nDOMAIN-SUFFIX,www.surplusglobal.cn,Proxy\nDOMAIN-SUFFIX,tsc5332.com,Proxy\nDOMAIN-SUFFIX,7ibt.com,Proxy\nDOMAIN-SUFFIX,www.porno.com.ar,Proxy\nDOMAIN-SUFFIX,gpservices.co.za,Proxy\nDOMAIN-SUFFIX,fulidao168.com,Proxy\nDOMAIN-SUFFIX,aax.com,Proxy\nDOMAIN-SUFFIX,avday.tv,Proxy\nDOMAIN-SUFFIX,www.ibbusinessandmanagement.com,Proxy\nDOMAIN-SUFFIX,play.54647gameshop.com,Proxy\nDOMAIN-SUFFIX,soc.mil,Proxy\nDOMAIN-SUFFIX,zozotown.com,Proxy\nDOMAIN-SUFFIX,blog.vipin.us,Proxy\nDOMAIN-SUFFIX,www.alqp160.com,Proxy\nDOMAIN-SUFFIX,duotai.org,Proxy\nDOMAIN-SUFFIX,rti.tw,Proxy\nDOMAIN-SUFFIX,hideip.co,Proxy\nDOMAIN-SUFFIX,portal.cheng.pet,Proxy\nDOMAIN-SUFFIX,blog.turntable.fm,Proxy\nDOMAIN-SUFFIX,faluninfo.ru,Proxy\nDOMAIN-SUFFIX,ai.goeast.io,Proxy\nDOMAIN-SUFFIX,69vj.com,Proxy\nDOMAIN-SUFFIX,jm-comic.xyz,Proxy\nDOMAIN-SUFFIX,www.guge138.com,Proxy\nDOMAIN-SUFFIX,golden-ages.org,Proxy\nDOMAIN-SUFFIX,suroot.com,Proxy\nDOMAIN-SUFFIX,www.xinbi007.com,Proxy\nDOMAIN-SUFFIX,cs455.com,Proxy\nDOMAIN-SUFFIX,dc772.com,Proxy\nDOMAIN-SUFFIX,www.ytios.com,Proxy\nDOMAIN-SUFFIX,b52222.com,Proxy\nDOMAIN-SUFFIX,riche99.com,Proxy\nDOMAIN-SUFFIX,presscite.com,Proxy\nDOMAIN-SUFFIX,yt.dorper.me,Proxy\nDOMAIN-SUFFIX,taiwandaily.net,Proxy\nDOMAIN-SUFFIX,we-see.xyz,Proxy\nDOMAIN-SUFFIX,63qq.net,Proxy\nDOMAIN-SUFFIX,xh4999.com,Proxy\nDOMAIN-SUFFIX,pastebay.com,Proxy\nDOMAIN-SUFFIX,bisi666.xyz,Proxy\nDOMAIN-SUFFIX,cryptogems.org,Proxy\nDOMAIN-SUFFIX,pinterest.vn,Proxy\nDOMAIN-SUFFIX,bbs.ecstart.com,Proxy\nDOMAIN-SUFFIX,www.mitgaisim.idf.il,Proxy\nDOMAIN-SUFFIX,hkfreezone.com,Proxy\nDOMAIN-SUFFIX,raremovie.net,Proxy\nDOMAIN-SUFFIX,magnetix.co.il,Proxy\nDOMAIN-SUFFIX,www.yzc999.com,Proxy\nDOMAIN-SUFFIX,www.nunuyy1.top,Proxy\nDOMAIN-SUFFIX,just-album.blogspot.hk,Proxy\nDOMAIN-SUFFIX,ultravpn.com,Proxy\nDOMAIN-SUFFIX,marcianoag.es,Proxy\nDOMAIN-SUFFIX,toy-navi.blog.jp,Proxy\nDOMAIN-SUFFIX,usenet4all.com,Proxy\nDOMAIN-SUFFIX,www.riograndegames.com,Proxy\nDOMAIN-SUFFIX,qqq578.com,Proxy\nDOMAIN-SUFFIX,www.bookmarkinghost.com,Proxy\nDOMAIN-SUFFIX,www.fanqiang-cn.com,Proxy\nDOMAIN-SUFFIX,g4w.me,Proxy\nDOMAIN-SUFFIX,from-co.net,Proxy\nDOMAIN-SUFFIX,zh.b-ok.lat,Proxy\nDOMAIN-SUFFIX,d2hmder3sb33g4.cloudfront.net,Proxy\nDOMAIN-SUFFIX,dawanews.com,Proxy\nDOMAIN-SUFFIX,www.bw3785.com,Proxy\nDOMAIN-SUFFIX,haoli777.net,Proxy\nDOMAIN-SUFFIX,www.pcp.pt,Proxy\nDOMAIN-SUFFIX,av-movie.xyz,Proxy\nDOMAIN-SUFFIX,www.yhdmp.cc,Proxy\nDOMAIN-SUFFIX,byj13.com,Proxy\nDOMAIN-SUFFIX,googleblog.blogspot.jp,Proxy\nDOMAIN-SUFFIX,d368ozj6xi7rhe.cloudfront.net,Proxy\nDOMAIN-SUFFIX,google.ge,Proxy\nDOMAIN-SUFFIX,ttb.org,Proxy\nDOMAIN-SUFFIX,dreammask.net,Proxy\nDOMAIN-SUFFIX,imgbb.com,Proxy\nDOMAIN-SUFFIX,ahri-plus.com,Proxy\nDOMAIN-SUFFIX,kepard.com,Proxy\nDOMAIN-SUFFIX,toytractorshow.com,Proxy\nDOMAIN-SUFFIX,hj046.com,Proxy\nDOMAIN-SUFFIX,538877.com,Proxy\nDOMAIN-SUFFIX,www.starbo999.com,Proxy\nDOMAIN-SUFFIX,coolloud.org.tw,Proxy\nDOMAIN-SUFFIX,borderlands-books.com,Proxy\nDOMAIN-SUFFIX,kenyons.org,Proxy\nDOMAIN-SUFFIX,www.greenway.ie,Proxy\nDOMAIN-SUFFIX,www.hentairon.net,Proxy\nDOMAIN-SUFFIX,www.avgthreatlabs.com,Proxy\nDOMAIN-SUFFIX,bufalopedia.ch,Proxy\nDOMAIN-SUFFIX,al-islam.com,Proxy\nDOMAIN-SUFFIX,peoplesproxy.com,Proxy\nDOMAIN-SUFFIX,xtube.com,Proxy\nDOMAIN-SUFFIX,dakaba.pw,Proxy\nDOMAIN-SUFFIX,b.cr.rs,Proxy\nDOMAIN-SUFFIX,itsaol.com,Proxy\nDOMAIN-SUFFIX,mm.net.my,Proxy\nDOMAIN-SUFFIX,drtuber.com,Proxy\nDOMAIN-SUFFIX,hdbits.org,Proxy\nDOMAIN-SUFFIX,get-tune.net,Proxy\nDOMAIN-SUFFIX,updates-http.cdn-apple.com,Proxy\nDOMAIN-SUFFIX,www.ustv.com.tw,Proxy\nDOMAIN-SUFFIX,etaireia.gr,Proxy\nDOMAIN-SUFFIX,www.sto2.cc,Proxy\nDOMAIN-SUFFIX,www.x1949x.in,Proxy\nDOMAIN-SUFFIX,myporn.club,Proxy\nDOMAIN-SUFFIX,33a.strikingly.com,Proxy\nDOMAIN-SUFFIX,iredmail.org,Proxy\nDOMAIN-SUFFIX,avsforum.com,Proxy\nDOMAIN-SUFFIX,www.ca821.com,Proxy\nDOMAIN-SUFFIX,civiliangunner.com,Proxy\nDOMAIN-SUFFIX,www.klartale.no,Proxy\nDOMAIN-SUFFIX,343dy.net,Proxy\nDOMAIN-SUFFIX,theproxyfree.com,Proxy\nDOMAIN-SUFFIX,mywot.com,Proxy\nDOMAIN-SUFFIX,beijingbiden.com,Proxy\nDOMAIN-SUFFIX,dylanpedavoli.com,Proxy\nDOMAIN-SUFFIX,www.associationmediaandpublishing.org,Proxy\nDOMAIN-SUFFIX,6do.news,Proxy\nDOMAIN-SUFFIX,gogle.com.hk,Proxy\nDOMAIN-SUFFIX,scms.spu.ac.th,Proxy\nDOMAIN-SUFFIX,padmarigdzinling.org,Proxy\nDOMAIN-SUFFIX,150kai.com,Proxy\nDOMAIN-SUFFIX,m.33380.cc,Proxy\nDOMAIN-SUFFIX,creditcardforum.com,Proxy\nDOMAIN-SUFFIX,pfdc89.com,Proxy\nDOMAIN-SUFFIX,redflava.com,Proxy\nDOMAIN-SUFFIX,sakura.sakuravpn.wang,Proxy\nDOMAIN-SUFFIX,portal.shadowsocks.ch,Proxy\nDOMAIN-SUFFIX,nubilefilms.com,Proxy\nDOMAIN-SUFFIX,skypost.ulifestyle.com.hk,Proxy\nDOMAIN-SUFFIX,upjav.org,Proxy\nDOMAIN-SUFFIX,hkatvnews.com,Proxy\nDOMAIN-SUFFIX,weinidaohang.com,Proxy\nDOMAIN-SUFFIX,www.eveil-delaconscience.com,Proxy\nDOMAIN-SUFFIX,www.openarena.ws,Proxy\nDOMAIN-SUFFIX,vpnys.com,Proxy\nDOMAIN-SUFFIX,ait.org.tw,Proxy\nDOMAIN-SUFFIX,a248.e.akamai.net,Proxy\nDOMAIN-SUFFIX,atob.ws,Proxy\nDOMAIN-SUFFIX,penchinese.org,Proxy\nDOMAIN-SUFFIX,www.4gtv.tv,Proxy\nDOMAIN-SUFFIX,555022.com,Proxy\nDOMAIN-SUFFIX,www.cdw.ca,Proxy\nDOMAIN-SUFFIX,www.globalchina.com,Proxy\nDOMAIN-SUFFIX,zongse888.com,Proxy\nDOMAIN-SUFFIX,www.csmonitor.com,Proxy\nDOMAIN-SUFFIX,msgforex.com,Proxy\nDOMAIN-SUFFIX,forums.thesims.com,Proxy\nDOMAIN-SUFFIX,tt.bd.to,Proxy\nDOMAIN-SUFFIX,freeones.nl,Proxy\nDOMAIN-SUFFIX,www.plexvpn.pro,Proxy\nDOMAIN-SUFFIX,ixquick.com,Proxy\nDOMAIN-SUFFIX,casanctuary.org,Proxy\nDOMAIN-SUFFIX,bonertube.com,Proxy\nDOMAIN-SUFFIX,virtuallythere.com,Proxy\nDOMAIN-SUFFIX,fwvpn.com,Proxy\nDOMAIN-SUFFIX,tuvpn.com,Proxy\nDOMAIN-SUFFIX,www.giga-web.jp,Proxy\nDOMAIN-SUFFIX,rtycminnesota.org,Proxy\nDOMAIN-SUFFIX,editionsmahayana.fr,Proxy\nDOMAIN-SUFFIX,askynz.net,Proxy\nDOMAIN-SUFFIX,insidefacebook.com,Proxy\nDOMAIN-SUFFIX,3dss.hitrustpay.com.tw,Proxy\nDOMAIN-SUFFIX,aq.c5cbca7s.pw,Proxy\nDOMAIN-SUFFIX,gtadmin.ddnsking.com,Proxy\nDOMAIN-SUFFIX,whispersystems.org,Proxy\nDOMAIN-SUFFIX,hdsky.me,Proxy\nDOMAIN-SUFFIX,duv8dpvm6a4ae.cloudfront.net,Proxy\nDOMAIN-SUFFIX,sebe.fairuse.org,Proxy\nDOMAIN-SUFFIX,jex.com,Proxy\nDOMAIN-SUFFIX,google.mx,Proxy\nDOMAIN-SUFFIX,299.isasecret.com,Proxy\nDOMAIN-SUFFIX,bw3355.com,Proxy\nDOMAIN-SUFFIX,www.hkaim.org.hk,Proxy\nDOMAIN-SUFFIX,game.sina.com.hk,Proxy\nDOMAIN-SUFFIX,guge.io,Proxy\nDOMAIN-SUFFIX,www.1xiaoshivpn.com,Proxy\nDOMAIN-SUFFIX,va.vizvaz.com,Proxy\nDOMAIN-SUFFIX,tumview.com,Proxy\nDOMAIN-SUFFIX,likeyoutube.com,Proxy\nDOMAIN-SUFFIX,tunnello.com,Proxy\nDOMAIN-SUFFIX,paste.ee,Proxy\nDOMAIN-SUFFIX,pinterest.in,Proxy\nDOMAIN-SUFFIX,comunitatibetana.org,Proxy\nDOMAIN-SUFFIX,kik.com,Proxy\nDOMAIN-SUFFIX,www.sonnar.net,Proxy\nDOMAIN-SUFFIX,securevsaas.secureinc.co.jp,Proxy\nDOMAIN-SUFFIX,mkto-sj020171.com,Proxy\nDOMAIN-SUFFIX,tuyetnguyen927.wixsite.com,Proxy\nDOMAIN-SUFFIX,mi9.com,Proxy\nDOMAIN-SUFFIX,girlfriendvideos.com,Proxy\nDOMAIN-SUFFIX,bandwagonhost.com,Proxy\nDOMAIN-SUFFIX,chinesetalks.net,Proxy\nDOMAIN-SUFFIX,chocalanwines.com,Proxy\nDOMAIN-SUFFIX,thedailyshow.com,Proxy\nDOMAIN-SUFFIX,www.pinterest.com.au,Proxy\nDOMAIN-SUFFIX,deadline.com,Proxy\nDOMAIN-SUFFIX,codernism.com,Proxy\nDOMAIN-SUFFIX,www.jiji.com,Proxy\nDOMAIN-SUFFIX,226.qc.to,Proxy\nDOMAIN-SUFFIX,www.mobintouch.com,Proxy\nDOMAIN-SUFFIX,d35w2oo5rcyg8v.cloudfront.net,Proxy\nDOMAIN-SUFFIX,77.syntereo.com,Proxy\nDOMAIN-SUFFIX,to.onmypc.net,Proxy\nDOMAIN-SUFFIX,d2xsio5v4myrvc.cloudfront.net,Proxy\nDOMAIN-SUFFIX,de.hideproxy.me,Proxy\nDOMAIN-SUFFIX,ld286.com,Proxy\nDOMAIN-SUFFIX,freeopenproxy.com,Proxy\nDOMAIN-SUFFIX,x535346.com,Proxy\nDOMAIN-SUFFIX,www.babepedia.com,Proxy\nDOMAIN-SUFFIX,freespeechdebate.com,Proxy\nDOMAIN-SUFFIX,www.422208.net,Proxy\nDOMAIN-SUFFIX,www.chibanippo.co.jp,Proxy\nDOMAIN-SUFFIX,vpnxr.com,Proxy\nDOMAIN-SUFFIX,anxpro.com,Proxy\nDOMAIN-SUFFIX,www.chinadmd.com,Proxy\nDOMAIN-SUFFIX,11773885.com,Proxy\nDOMAIN-SUFFIX,sodichan.com,Proxy\nDOMAIN-SUFFIX,www.ho5ho.com,Proxy\nDOMAIN-SUFFIX,www.hongkongvpn.net,Proxy\nDOMAIN-SUFFIX,animeultima.tv,Proxy\nDOMAIN-SUFFIX,gerefoundation.org,Proxy\nDOMAIN-SUFFIX,javhd.com,Proxy\nDOMAIN-SUFFIX,gmll.org,Proxy\nDOMAIN-SUFFIX,us03-28.ssv4.net,Proxy\nDOMAIN-SUFFIX,kiwifarms.st,Proxy\nDOMAIN-SUFFIX,ourxv.com,Proxy\nDOMAIN-SUFFIX,www.spa.gov.sa,Proxy\nDOMAIN-SUFFIX,jerkmate.com,Proxy\nDOMAIN-SUFFIX,riben888.com,Proxy\nDOMAIN-SUFFIX,books.xxgirls.pro,Proxy\nDOMAIN-SUFFIX,academicjournals.org,Proxy\nDOMAIN-SUFFIX,mediafreakcity.com,Proxy\nDOMAIN-SUFFIX,zbo.com,Proxy\nDOMAIN-SUFFIX,e6sb.gl.grr.io,Proxy\nDOMAIN-SUFFIX,revver.com,Proxy\nDOMAIN-SUFFIX,avcity.tv,Proxy\nDOMAIN-SUFFIX,doh.acg49nine.eu.org,Proxy\nDOMAIN-SUFFIX,m.fun551.com,Proxy\nDOMAIN-SUFFIX,www.rechina.org,Proxy\nDOMAIN-SUFFIX,www.sex-11.com,Proxy\nDOMAIN-SUFFIX,chinadigitaltimes.net,Proxy\nDOMAIN-SUFFIX,chobit.cc,Proxy\nDOMAIN-SUFFIX,s2.reutersmedia.net,Proxy\nDOMAIN-SUFFIX,2008xianzhang.info,Proxy\nDOMAIN-SUFFIX,footytube.com,Proxy\nDOMAIN-SUFFIX,love100girl.com,Proxy\nDOMAIN-SUFFIX,www.undergrad.hk,Proxy\nDOMAIN-SUFFIX,www.wegewerk.com,Proxy\nDOMAIN-SUFFIX,botanwang.com,Proxy\nDOMAIN-SUFFIX,fetishshrine.com,Proxy\nDOMAIN-SUFFIX,www.cmcmarkets.com,Proxy\nDOMAIN-SUFFIX,disk.yandex.com,Proxy\nDOMAIN-SUFFIX,blog.jackjia.com,Proxy\nDOMAIN-SUFFIX,eliademy.com,Proxy\nDOMAIN-SUFFIX,paysimple.com,Proxy\nDOMAIN-SUFFIX,www.huobi.me,Proxy\nDOMAIN-SUFFIX,dingmtv.site,Proxy\nDOMAIN-SUFFIX,libertyshield.com,Proxy\nDOMAIN-SUFFIX,goldeneyevault.com,Proxy\nDOMAIN-SUFFIX,avgle.com,Proxy\nDOMAIN-SUFFIX,project162977.tilda.ws,Proxy\nDOMAIN-SUFFIX,link-o-rama.com,Proxy\nDOMAIN-SUFFIX,html5rocks.com,Proxy\nDOMAIN-SUFFIX,wikissl.com,Proxy\nDOMAIN-SUFFIX,askit.kone.com,Proxy\nDOMAIN-SUFFIX,goodtv.tv,Proxy\nDOMAIN-SUFFIX,g.page,Proxy\nDOMAIN-SUFFIX,foxgay.com,Proxy\nDOMAIN-SUFFIX,form.jotform.com,Proxy\nDOMAIN-SUFFIX,dailyview.tw,Proxy\nDOMAIN-SUFFIX,nflximg.com,Proxy\nDOMAIN-SUFFIX,hraff.org.au,Proxy\nDOMAIN-SUFFIX,javdove6.site,Proxy\nDOMAIN-SUFFIX,fireworks.eklablog.com,Proxy\nDOMAIN-SUFFIX,www.taiwanclayart.org.tw,Proxy\nDOMAIN-SUFFIX,jakubchmura.pl,Proxy\nDOMAIN-SUFFIX,internetdefenseleague.org,Proxy\nDOMAIN-SUFFIX,facade.gr,Proxy\nDOMAIN-SUFFIX,ylg30.com,Proxy\nDOMAIN-SUFFIX,www.zodgame.us,Proxy\nDOMAIN-SUFFIX,vod-abematv.akamaized.net,Proxy\nDOMAIN-SUFFIX,free-ssh.com,Proxy\nDOMAIN-SUFFIX,twnorth.org.tw,Proxy\nDOMAIN-SUFFIX,miaopaidao.firebaseio.com,Proxy\nDOMAIN-SUFFIX,www.btcherry.net,Proxy\nDOMAIN-SUFFIX,www.buzzle.com,Proxy\nDOMAIN-SUFFIX,6227755.com,Proxy\nDOMAIN-SUFFIX,asas-team.strikingly.com,Proxy\nDOMAIN-SUFFIX,cinemablend.com,Proxy\nDOMAIN-SUFFIX,bitc.bme.emory.edu,Proxy\nDOMAIN-SUFFIX,www.acgn.ren,Proxy\nDOMAIN-SUFFIX,www.bladevpn.com,Proxy\nDOMAIN-SUFFIX,yangjianli.com,Proxy\nDOMAIN-SUFFIX,talk.maemo.org,Proxy\nDOMAIN-SUFFIX,x.xxgirls2.com,Proxy\nDOMAIN-SUFFIX,1qqtv.cc,Proxy\nDOMAIN-SUFFIX,www.icctw.com,Proxy\nDOMAIN-SUFFIX,satangcorp.com,Proxy\nDOMAIN-SUFFIX,hkg12s09-in-f4.1e100.net,Proxy\nDOMAIN-SUFFIX,blm644.com,Proxy\nDOMAIN-SUFFIX,www.nexon.com,Proxy\nDOMAIN-SUFFIX,miniprox.org,Proxy\nDOMAIN-SUFFIX,www.say-huahuo.com,Proxy\nDOMAIN-SUFFIX,35.flnet.org,Proxy\nDOMAIN-SUFFIX,hkdtmb.com,Proxy\nDOMAIN-SUFFIX,www.indianexpress.com,Proxy\nDOMAIN-SUFFIX,asredas.com,Proxy\nDOMAIN-SUFFIX,www.cavip111.com,Proxy\nDOMAIN-SUFFIX,stream.live.vc.bbcmedia.co.uk,Proxy\nDOMAIN-SUFFIX,www.momentsapp.com,Proxy\nDOMAIN-SUFFIX,kzaobao.com,Proxy\nDOMAIN-SUFFIX,googledrive.com,Proxy\nDOMAIN-SUFFIX,www.hj906.com,Proxy\nDOMAIN-SUFFIX,prdelb.mezenger.net,Proxy\nDOMAIN-SUFFIX,winwintours.wixsite.com,Proxy\nDOMAIN-SUFFIX,nitter.fdn.fr,Proxy\nDOMAIN-SUFFIX,leaks-xlcloud.rhcloud.com,Proxy\nDOMAIN-SUFFIX,www.nkpicture.com,Proxy\nDOMAIN-SUFFIX,yu33.net,Proxy\nDOMAIN-SUFFIX,vpn4all.zendesk.com,Proxy\nDOMAIN-SUFFIX,599499.com,Proxy\nDOMAIN-SUFFIX,d1uvehqt9n5kbe.cloudfront.net,Proxy\nDOMAIN-SUFFIX,brainyquote.com,Proxy\nDOMAIN-SUFFIX,xsden.info,Proxy\nDOMAIN-SUFFIX,softwarebychuck.com,Proxy\nDOMAIN-SUFFIX,www.neutrinosatemyhomework.com,Proxy\nDOMAIN-SUFFIX,weiweishe.github.io,Proxy\nDOMAIN-SUFFIX,www.easytogrowbulbs.com,Proxy\nDOMAIN-SUFFIX,arabs-youtube.com,Proxy\nDOMAIN-SUFFIX,techxpert.org,Proxy\nDOMAIN-SUFFIX,d.htcc.us,Proxy\nDOMAIN-SUFFIX,jp.ivankyo.com,Proxy\nDOMAIN-SUFFIX,idaili.club,Proxy\nDOMAIN-SUFFIX,www.paofuyun.vip,Proxy\nDOMAIN-SUFFIX,www.82299.com,Proxy\nDOMAIN-SUFFIX,vpnuu.com,Proxy\nDOMAIN-SUFFIX,www.beginnersmindzencenter.org,Proxy\nDOMAIN-SUFFIX,candia.co.za,Proxy\nDOMAIN-SUFFIX,www.nuk.edu.tw,Proxy\nDOMAIN-SUFFIX,flexpool.io,Proxy\nDOMAIN-SUFFIX,tor-exit-34.for-privacy.net,Proxy\nDOMAIN-SUFFIX,bnbzaubernuss.ch,Proxy\nDOMAIN-SUFFIX,d1wcyl67re4p3e.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.jdb1688.net,Proxy\nDOMAIN-SUFFIX,soubory.com,Proxy\nDOMAIN-SUFFIX,www.sakura.zone,Proxy\nDOMAIN-SUFFIX,www.chinesepen.org,Proxy\nDOMAIN-SUFFIX,c1008.com,Proxy\nDOMAIN-SUFFIX,downparadise.ws,Proxy\nDOMAIN-SUFFIX,bbon.net,Proxy\nDOMAIN-SUFFIX,m.tengbo9885.com,Proxy\nDOMAIN-SUFFIX,oanda.com,Proxy\nDOMAIN-SUFFIX,hostloc.com,Proxy\nDOMAIN-SUFFIX,putiban.blogspot.jp,Proxy\nDOMAIN-SUFFIX,bondageblog.com,Proxy\nDOMAIN-SUFFIX,technews.tw,Proxy\nDOMAIN-SUFFIX,bbcukchina.com,Proxy\nDOMAIN-SUFFIX,expressvpn.asia,Proxy\nDOMAIN-SUFFIX,21cambodia.com,Proxy\nDOMAIN-SUFFIX,www.bet18xl.org,Proxy\nDOMAIN-SUFFIX,elladies.com,Proxy\nDOMAIN-SUFFIX,tigravista.com,Proxy\nDOMAIN-SUFFIX,getuploader.com,Proxy\nDOMAIN-SUFFIX,esball.com,Proxy\nDOMAIN-SUFFIX,mixmin.net,Proxy\nDOMAIN-SUFFIX,cdn2.i-scmp.com,Proxy\nDOMAIN-SUFFIX,yzc888.com,Proxy\nDOMAIN-SUFFIX,frootvpn.com,Proxy\nDOMAIN-SUFFIX,www.vps000.com,Proxy\nDOMAIN-SUFFIX,www.keyloom.com,Proxy\nDOMAIN-SUFFIX,nobitex.ir,Proxy\nDOMAIN-SUFFIX,voanews.eu,Proxy\nDOMAIN-SUFFIX,blog.youthwant.com.tw,Proxy\nDOMAIN-SUFFIX,9646378.com,Proxy\nDOMAIN-SUFFIX,sun350.com,Proxy\nDOMAIN-SUFFIX,prochoice.org,Proxy\nDOMAIN-SUFFIX,dwpty1o5z9lax.cloudfront.net,Proxy\nDOMAIN-SUFFIX,cafe.naver.com,Proxy\nDOMAIN-SUFFIX,3166604.com,Proxy\nDOMAIN-SUFFIX,nitter.grimneko.de,Proxy\nDOMAIN-SUFFIX,kodirectory.com,Proxy\nDOMAIN-SUFFIX,webdisk.andong.org.tw,Proxy\nDOMAIN-SUFFIX,unblockmyweb.com,Proxy\nDOMAIN-SUFFIX,881903.com,Proxy\nDOMAIN-SUFFIX,www.easternlightning.org,Proxy\nDOMAIN-SUFFIX,laspalmas.dskbudismo.org,Proxy\nDOMAIN-SUFFIX,real-instand-copy.pages.dev,Proxy\nDOMAIN-SUFFIX,vansky.com,Proxy\nDOMAIN-SUFFIX,sftindia.org,Proxy\nDOMAIN-SUFFIX,vpnry.com,Proxy\nDOMAIN-SUFFIX,scientology.it,Proxy\nDOMAIN-SUFFIX,lifebuzz.com,Proxy\nDOMAIN-SUFFIX,pf3262.tudouser.com,Proxy\nDOMAIN-SUFFIX,22gg940.com,Proxy\nDOMAIN-SUFFIX,notyoutube.com,Proxy\nDOMAIN-SUFFIX,www.tubebdsm.com,Proxy\nDOMAIN-SUFFIX,player.fm,Proxy\nDOMAIN-SUFFIX,tibethouse.org,Proxy\nDOMAIN-SUFFIX,hket.com,Proxy\nDOMAIN-SUFFIX,cointiger.com,Proxy\nDOMAIN-SUFFIX,dl-laby.jp,Proxy\nDOMAIN-SUFFIX,crrev.com,Proxy\nDOMAIN-SUFFIX,fangongheike.com,Proxy\nDOMAIN-SUFFIX,geppeivpn.asia,Proxy\nDOMAIN-SUFFIX,www.tiaotiaowen.com,Proxy\nDOMAIN-SUFFIX,ustv123.com,Proxy\nDOMAIN-SUFFIX,xcity.jp,Proxy\nDOMAIN-SUFFIX,tw.myblog.yahoo.com,Proxy\nDOMAIN-SUFFIX,xj37777.com,Proxy\nDOMAIN-SUFFIX,www.e8678.com,Proxy\nDOMAIN-SUFFIX,sex3.com,Proxy\nDOMAIN-SUFFIX,feitianacademy.org,Proxy\nDOMAIN-SUFFIX,bjtm.com,Proxy\nDOMAIN-SUFFIX,red-lang.org,Proxy\nDOMAIN-SUFFIX,www.btc.com,Proxy\nDOMAIN-SUFFIX,www.wanyi777.com,Proxy\nDOMAIN-SUFFIX,www.twfc.org.tw,Proxy\nDOMAIN-SUFFIX,amysecure.com,Proxy\nDOMAIN-SUFFIX,fuq.com,Proxy\nDOMAIN-SUFFIX,hx2.tv,Proxy\nDOMAIN-SUFFIX,avaaz.com,Proxy\nDOMAIN-SUFFIX,jgg18.xyz,Proxy\nDOMAIN-SUFFIX,fides.org,Proxy\nDOMAIN-SUFFIX,syji5.xyz,Proxy\nDOMAIN-SUFFIX,www.51jiasu.com,Proxy\nDOMAIN-SUFFIX,checkyoutube.com,Proxy\nDOMAIN-SUFFIX,ns2.name,Proxy\nDOMAIN-SUFFIX,blog.excite.co.jp,Proxy\nDOMAIN-SUFFIX,falunart.org,Proxy\nDOMAIN-SUFFIX,inclk.com,Proxy\nDOMAIN-SUFFIX,inamov.net,Proxy\nDOMAIN-SUFFIX,www.ucsc.edu,Proxy\nDOMAIN-SUFFIX,kurier.at,Proxy\nDOMAIN-SUFFIX,baryes.com,Proxy\nDOMAIN-SUFFIX,fppchile.org,Proxy\nDOMAIN-SUFFIX,www.lambsteps.com,Proxy\nDOMAIN-SUFFIX,phpbido.com,Proxy\nDOMAIN-SUFFIX,foliart.org,Proxy\nDOMAIN-SUFFIX,nebula.zyxel.com,Proxy\nDOMAIN-SUFFIX,www.dinotube.com,Proxy\nDOMAIN-SUFFIX,nude-art-erotic.com,Proxy\nDOMAIN-SUFFIX,ilhamtohtiinstitute.org,Proxy\nDOMAIN-SUFFIX,hilive.tv,Proxy\nDOMAIN-SUFFIX,xianba.net,Proxy\nDOMAIN-SUFFIX,triiix.io,Proxy\nDOMAIN-SUFFIX,share.acgnx.se,Proxy\nDOMAIN-SUFFIX,www.democraticchina.net,Proxy\nDOMAIN-SUFFIX,www.anonine.se,Proxy\nDOMAIN-SUFFIX,s20.tiktokcdn.com,Proxy\nDOMAIN-SUFFIX,dns.silen.org,Proxy\nDOMAIN-SUFFIX,bullogger.com,Proxy\nDOMAIN-SUFFIX,dns.wang.art,Proxy\nDOMAIN-SUFFIX,266248.com,Proxy\nDOMAIN-SUFFIX,www.korea.com,Proxy\nDOMAIN-SUFFIX,podzone.net,Proxy\nDOMAIN-SUFFIX,xbsj6789.site,Proxy\nDOMAIN-SUFFIX,taiwanplus.com,Proxy\nDOMAIN-SUFFIX,viemo.com,Proxy\nDOMAIN-SUFFIX,pokerstars.net,Proxy\nDOMAIN-SUFFIX,freechinaweibo.com,Proxy\nDOMAIN-SUFFIX,ruten.com.tw,Proxy\nDOMAIN-SUFFIX,plexvpn.pro,Proxy\nDOMAIN-SUFFIX,tor.blingblingsquad.net,Proxy\nDOMAIN-SUFFIX,nitter.kylrth.com,Proxy\nDOMAIN-SUFFIX,www.stormmediagroup.com,Proxy\nDOMAIN-SUFFIX,invidious.privacydev.net,Proxy\nDOMAIN-SUFFIX,pm.me,Proxy\nDOMAIN-SUFFIX,www.scpr.org,Proxy\nDOMAIN-SUFFIX,thelifeyoucansave.com,Proxy\nDOMAIN-SUFFIX,instragram.com,Proxy\nDOMAIN-SUFFIX,64museum.blogspot.hk,Proxy\nDOMAIN-SUFFIX,iscm.zyxel.com,Proxy\nDOMAIN-SUFFIX,z789.com,Proxy\nDOMAIN-SUFFIX,xp1024.com,Proxy\nDOMAIN-SUFFIX,nvpn.net,Proxy\nDOMAIN-SUFFIX,tibetcorps.org,Proxy\nDOMAIN-SUFFIX,shoppingpos.com,Proxy\nDOMAIN-SUFFIX,apk4fun.com,Proxy\nDOMAIN-SUFFIX,google.ie,Proxy\nDOMAIN-SUFFIX,dragonsprings.org,Proxy\nDOMAIN-SUFFIX,medilab.us,Proxy\nDOMAIN-SUFFIX,le989.com,Proxy\nDOMAIN-SUFFIX,ci.nii.ac.jp,Proxy\nDOMAIN-SUFFIX,guancha.org,Proxy\nDOMAIN-SUFFIX,tuibeitu.net,Proxy\nDOMAIN-SUFFIX,nsarchive.gwu.edu,Proxy\nDOMAIN-SUFFIX,www.powerphoto.org,Proxy\nDOMAIN-SUFFIX,expressvpn.io,Proxy\nDOMAIN-SUFFIX,ziyouliulan.net,Proxy\nDOMAIN-SUFFIX,www.discovernauru.com,Proxy\nDOMAIN-SUFFIX,aboutgfw.com,Proxy\nDOMAIN-SUFFIX,www.deepl.com,Proxy\nDOMAIN-SUFFIX,tengbo18.com,Proxy\nDOMAIN-SUFFIX,7cow.com,Proxy\nDOMAIN-SUFFIX,84493366.com,Proxy\nDOMAIN-SUFFIX,ahri8.com,Proxy\nDOMAIN-SUFFIX,acgnx.se,Proxy\nDOMAIN-SUFFIX,wiki.esu.im,Proxy\nDOMAIN-SUFFIX,www.svd.se,Proxy\nDOMAIN-SUFFIX,www.dalailamaworld.com,Proxy\nDOMAIN-SUFFIX,g5.slyip.com,Proxy\nDOMAIN-SUFFIX,axios.com,Proxy\nDOMAIN-SUFFIX,torlock.com,Proxy\nDOMAIN-SUFFIX,w6532.com,Proxy\nDOMAIN-SUFFIX,twelverocks.com,Proxy\nDOMAIN-SUFFIX,sm5278.com,Proxy\nDOMAIN-SUFFIX,www.asapm.org,Proxy\nDOMAIN-SUFFIX,data-vocabulary.org,Proxy\nDOMAIN-SUFFIX,newipnow.com,Proxy\nDOMAIN-SUFFIX,h-china.org,Proxy\nDOMAIN-SUFFIX,hentaiworld.tv,Proxy\nDOMAIN-SUFFIX,www.3165365.com,Proxy\nDOMAIN-SUFFIX,shadow.ma,Proxy\nDOMAIN-SUFFIX,pmatehunter.com,Proxy\nDOMAIN-SUFFIX,pu0023.com,Proxy\nDOMAIN-SUFFIX,tor-exit-46.for-privacy.net,Proxy\nDOMAIN-SUFFIX,lsmradio.com,Proxy\nDOMAIN-SUFFIX,mrlbookkeeping.com,Proxy\nDOMAIN-SUFFIX,observechina.net,Proxy\nDOMAIN-SUFFIX,w3.now-ip.net,Proxy\nDOMAIN-SUFFIX,meta.com,Proxy\nDOMAIN-SUFFIX,nobel.se,Proxy\nDOMAIN-SUFFIX,cms.09230927.webnode.tw,Proxy\nDOMAIN-SUFFIX,kocovi.cz,Proxy\nDOMAIN-SUFFIX,www.visiontimesjp.com,Proxy\nDOMAIN-SUFFIX,agentwho.net,Proxy\nDOMAIN-SUFFIX,adidas.co.ma,Proxy\nDOMAIN-SUFFIX,koyuman.com,Proxy\nDOMAIN-SUFFIX,96tang.xyz,Proxy\nDOMAIN-SUFFIX,logbot.net,Proxy\nDOMAIN-SUFFIX,d1pj9ca5pce20m.cloudfront.net,Proxy\nDOMAIN-SUFFIX,amuniverse.6te.net,Proxy\nDOMAIN-SUFFIX,5332t.com,Proxy\nDOMAIN-SUFFIX,williammallory.com,Proxy\nDOMAIN-SUFFIX,apuestasdemurcia.es,Proxy\nDOMAIN-SUFFIX,dnsfre.xyz,Proxy\nDOMAIN-SUFFIX,atlasvpn.com,Proxy\nDOMAIN-SUFFIX,mail.bu2021.xyz,Proxy\nDOMAIN-SUFFIX,saber.love,Proxy\nDOMAIN-SUFFIX,vip-enterprise.com,Proxy\nDOMAIN-SUFFIX,www.77-bet.com,Proxy\nDOMAIN-SUFFIX,wenyunchao.spaces.live.com,Proxy\nDOMAIN-SUFFIX,bw45.bgx.ro,Proxy\nDOMAIN-SUFFIX,iverycd.com,Proxy\nDOMAIN-SUFFIX,lc.com,Proxy\nDOMAIN-SUFFIX,www.tarainstitute.org.au,Proxy\nDOMAIN-SUFFIX,leckinger.com,Proxy\nDOMAIN-SUFFIX,www.dybee.co,Proxy\nDOMAIN-SUFFIX,jsdaodu16.jigsy.com,Proxy\nDOMAIN-SUFFIX,mymusic.net.tw,Proxy\nDOMAIN-SUFFIX,www.galvestonzen.org,Proxy\nDOMAIN-SUFFIX,sambhota.org,Proxy\nDOMAIN-SUFFIX,getcloudapp.com,Proxy\nDOMAIN-SUFFIX,qoo-app.com,Proxy\nDOMAIN-SUFFIX,www.mlzs.work,Proxy\nDOMAIN-SUFFIX,theworkpc.com,Proxy\nDOMAIN-SUFFIX,ca1077.com,Proxy\nDOMAIN-SUFFIX,tclwinu.sp5178.com,Proxy\nDOMAIN-SUFFIX,doujincafe.com,Proxy\nDOMAIN-SUFFIX,dns.decloudus.com,Proxy\nDOMAIN-SUFFIX,freetcp.com,Proxy\nDOMAIN-SUFFIX,ctnonprofitalliance.org,Proxy\nDOMAIN-SUFFIX,google.ps,Proxy\nDOMAIN-SUFFIX,b2.flnet.org,Proxy\nDOMAIN-SUFFIX,www.h365.asia,Proxy\nDOMAIN-SUFFIX,amis-tibet.lu,Proxy\nDOMAIN-SUFFIX,forgot.her.name,Proxy\nDOMAIN-SUFFIX,spotmeup.com,Proxy\nDOMAIN-SUFFIX,09292.com,Proxy\nDOMAIN-SUFFIX,daringfireball.net,Proxy\nDOMAIN-SUFFIX,www.qimila.net,Proxy\nDOMAIN-SUFFIX,www.3467zf.com,Proxy\nDOMAIN-SUFFIX,www.hetunzhibo.com,Proxy\nDOMAIN-SUFFIX,lulubar.net,Proxy\nDOMAIN-SUFFIX,d3dj5kib20koez.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.crhk.com.hk,Proxy\nDOMAIN-SUFFIX,mixiu001.top,Proxy\nDOMAIN-SUFFIX,www.economictimes.com,Proxy\nDOMAIN-SUFFIX,www.poofreesky.gq,Proxy\nDOMAIN-SUFFIX,usgfx.com,Proxy\nDOMAIN-SUFFIX,www.creativecommons.com,Proxy\nDOMAIN-SUFFIX,domai.com,Proxy\nDOMAIN-SUFFIX,www.sifangtv.club,Proxy\nDOMAIN-SUFFIX,asu.su,Proxy\nDOMAIN-SUFFIX,www.v772.net,Proxy\nDOMAIN-SUFFIX,gzomh.site,Proxy\nDOMAIN-SUFFIX,cmct.cc,Proxy\nDOMAIN-SUFFIX,www.rootinstitute.com,Proxy\nDOMAIN-SUFFIX,googleplay.com,Proxy\nDOMAIN-SUFFIX,www.yaoihavenreborn.com,Proxy\nDOMAIN-SUFFIX,videoixir.net,Proxy\nDOMAIN-SUFFIX,jmcomic9.cc,Proxy\nDOMAIN-SUFFIX,edr6u.xyz,Proxy\nDOMAIN-SUFFIX,bi.bd.to,Proxy\nDOMAIN-SUFFIX,idrive.com,Proxy\nDOMAIN-SUFFIX,www.pearlabyss.net,Proxy\nDOMAIN-SUFFIX,app.asso.st,Proxy\nDOMAIN-SUFFIX,bestforchina.org,Proxy\nDOMAIN-SUFFIX,cn.streetvoice.com,Proxy\nDOMAIN-SUFFIX,cusu.hk,Proxy\nDOMAIN-SUFFIX,www.icej.org.tw,Proxy\nDOMAIN-SUFFIX,macmate.me,Proxy\nDOMAIN-SUFFIX,alljackpotscasino.com,Proxy\nDOMAIN-SUFFIX,www.01001.com,Proxy\nDOMAIN-SUFFIX,www.institut-tibetain.org,Proxy\nDOMAIN-SUFFIX,seancody.com,Proxy\nDOMAIN-SUFFIX,v2-13.ssrsub.xyz,Proxy\nDOMAIN-SUFFIX,free-vpn.ru,Proxy\nDOMAIN-SUFFIX,bloomberg.net,Proxy\nDOMAIN-SUFFIX,nudgeworry.com,Proxy\nDOMAIN-SUFFIX,8dy.me,Proxy\nDOMAIN-SUFFIX,8327804.com,Proxy\nDOMAIN-SUFFIX,d14qd3he45186l.cloudfront.net,Proxy\nDOMAIN-SUFFIX,furutoppen.com,Proxy\nDOMAIN-SUFFIX,t25b.com,Proxy\nDOMAIN-SUFFIX,ytbcp4.com,Proxy\nDOMAIN-SUFFIX,blog.de,Proxy\nDOMAIN-SUFFIX,e6396.com,Proxy\nDOMAIN-SUFFIX,fatwa-online.com,Proxy\nDOMAIN-SUFFIX,myhero.com,Proxy\nDOMAIN-SUFFIX,c88588.com,Proxy\nDOMAIN-SUFFIX,www.cordcloud.me,Proxy\nDOMAIN-SUFFIX,www.google.com.cu,Proxy\nDOMAIN-SUFFIX,wozy.in,Proxy\nDOMAIN-SUFFIX,els.net.br,Proxy\nDOMAIN-SUFFIX,pervers.ch,Proxy\nDOMAIN-SUFFIX,www.freevpnsoftware.net,Proxy\nDOMAIN-SUFFIX,blog.bitsrc.io,Proxy\nDOMAIN-SUFFIX,zsvip999.com,Proxy\nDOMAIN-SUFFIX,pbs-ec.twimg.com,Proxy\nDOMAIN-SUFFIX,www.phantom2.com,Proxy\nDOMAIN-SUFFIX,crowdworks.jp,Proxy\nDOMAIN-SUFFIX,scoalagepiu.ro,Proxy\nDOMAIN-SUFFIX,zebpay.com,Proxy\nDOMAIN-SUFFIX,blogspot.hr,Proxy\nDOMAIN-SUFFIX,www.week.com,Proxy\nDOMAIN-SUFFIX,jiuweike.com,Proxy\nDOMAIN-SUFFIX,avsox.host,Proxy\nDOMAIN-SUFFIX,memopal.com,Proxy\nDOMAIN-SUFFIX,www.x78cc.com,Proxy\nDOMAIN-SUFFIX,wowrk.com,Proxy\nDOMAIN-SUFFIX,movements.org,Proxy\nDOMAIN-SUFFIX,freedom.tm,Proxy\nDOMAIN-SUFFIX,www.hycm.com,Proxy\nDOMAIN-SUFFIX,bt-king.xyz,Proxy\nDOMAIN-SUFFIX,kater.me,Proxy\nDOMAIN-SUFFIX,smutgusher.com,Proxy\nDOMAIN-SUFFIX,www.chaca.org.tw,Proxy\nDOMAIN-SUFFIX,freedome-jp-gw.fd.f-secure.com,Proxy\nDOMAIN-SUFFIX,linepost.hk,Proxy\nDOMAIN-SUFFIX,falunfofa.org,Proxy\nDOMAIN-SUFFIX,night19.icu,Proxy\nDOMAIN-SUFFIX,pariz-co.ir,Proxy\nDOMAIN-SUFFIX,www.fashssh.com,Proxy\nDOMAIN-SUFFIX,pbl.nl,Proxy\nDOMAIN-SUFFIX,roigtaxi.com,Proxy\nDOMAIN-SUFFIX,bione.cc,Proxy\nDOMAIN-SUFFIX,searx.prvcy.eu,Proxy\nDOMAIN-SUFFIX,www.jimmyliikala.se,Proxy\nDOMAIN-SUFFIX,yobt.com,Proxy\nDOMAIN-SUFFIX,223qq.net,Proxy\nDOMAIN-SUFFIX,yb.domain888.pw,Proxy\nDOMAIN-SUFFIX,gemini.com,Proxy\nDOMAIN-SUFFIX,menonedge.com,Proxy\nDOMAIN-SUFFIX,www.ids.ac.uk,Proxy\nDOMAIN-SUFFIX,heraldmonthly.ca,Proxy\nDOMAIN-SUFFIX,www.lifaner.com,Proxy\nDOMAIN-SUFFIX,www.harvestedalive.com,Proxy\nDOMAIN-SUFFIX,baidu-18.cc,Proxy\nDOMAIN-SUFFIX,networldsolutions.org,Proxy\nDOMAIN-SUFFIX,nivn.com,Proxy\nDOMAIN-SUFFIX,patria.org.ve,Proxy\nDOMAIN-SUFFIX,www.openervpn.com,Proxy\nDOMAIN-SUFFIX,sc.mp,Proxy\nDOMAIN-SUFFIX,cnavideo.cna.com.tw,Proxy\nDOMAIN-SUFFIX,www.yzc988.com,Proxy\nDOMAIN-SUFFIX,night20.icu,Proxy\nDOMAIN-SUFFIX,jav-free.org,Proxy\nDOMAIN-SUFFIX,slinkset.com,Proxy\nDOMAIN-SUFFIX,www.ibtimes.sg,Proxy\nDOMAIN-SUFFIX,old.honeynet.org,Proxy\nDOMAIN-SUFFIX,en.immi.is,Proxy\nDOMAIN-SUFFIX,www.sunisec.com,Proxy\nDOMAIN-SUFFIX,helpuyghursnow.org,Proxy\nDOMAIN-SUFFIX,www.043225.com,Proxy\nDOMAIN-SUFFIX,www.ziporn.com,Proxy\nDOMAIN-SUFFIX,ninecommentaries.com,Proxy\nDOMAIN-SUFFIX,jsproxy.tk,Proxy\nDOMAIN-SUFFIX,gudanglagu.com,Proxy\nDOMAIN-SUFFIX,huomie.com,Proxy\nDOMAIN-SUFFIX,n4i2.es,Proxy\nDOMAIN-SUFFIX,134723.cc,Proxy\nDOMAIN-SUFFIX,citizencn.com,Proxy\nDOMAIN-SUFFIX,ishr.ch,Proxy\nDOMAIN-SUFFIX,mjlsh.usc.cuhk.edu.hk,Proxy\nDOMAIN-SUFFIX,upgrade-chat.nyc3.cdn.digitaloceanspaces.com,Proxy\nDOMAIN-SUFFIX,crason.com,Proxy\nDOMAIN-SUFFIX,mclouis.com,Proxy\nDOMAIN-SUFFIX,www.prcleader.org,Proxy\nDOMAIN-SUFFIX,tor-exit-49.for-privacy.net,Proxy\nDOMAIN-SUFFIX,d2f1egay8yehza.cloudfront.net,Proxy\nDOMAIN-SUFFIX,creampietubeporn.com,Proxy\nDOMAIN-SUFFIX,tcnr2016.netne.net,Proxy\nDOMAIN-SUFFIX,dunyabulteni.net,Proxy\nDOMAIN-SUFFIX,bbs.omnitalk.org,Proxy\nDOMAIN-SUFFIX,pawfoundation.org,Proxy\nDOMAIN-SUFFIX,www.vrporzo.com,Proxy\nDOMAIN-SUFFIX,justwp.org,Proxy\nDOMAIN-SUFFIX,www.1kho.com,Proxy\nDOMAIN-SUFFIX,thevineyardchurch.com,Proxy\nDOMAIN-SUFFIX,m.businesstoday.in,Proxy\nDOMAIN-SUFFIX,k.ns02.top,Proxy\nDOMAIN-SUFFIX,israbox.com,Proxy\nDOMAIN-SUFFIX,av2be.com,Proxy\nDOMAIN-SUFFIX,0rz.tw,Proxy\nDOMAIN-SUFFIX,www.dwheeler.com,Proxy\nDOMAIN-SUFFIX,getukvpn.com,Proxy\nDOMAIN-SUFFIX,www.lotoo.com.tw,Proxy\nDOMAIN-SUFFIX,newsbreak.com,Proxy\nDOMAIN-SUFFIX,www.xh3666.com,Proxy\nDOMAIN-SUFFIX,half-shot.uk,Proxy\nDOMAIN-SUFFIX,tv2.tv322.yustu.net,Proxy\nDOMAIN-SUFFIX,egafd.com,Proxy\nDOMAIN-SUFFIX,google.co.in,Proxy\nDOMAIN-SUFFIX,ocsolutions.servehttp.com,Proxy\nDOMAIN-SUFFIX,colbertnation.com,Proxy\nDOMAIN-SUFFIX,china-underground.com,Proxy\nDOMAIN-SUFFIX,betway289.com,Proxy\nDOMAIN-SUFFIX,acg.rip,Proxy\nDOMAIN-SUFFIX,videocyborg.com,Proxy\nDOMAIN-SUFFIX,sell.ssvps.site,Proxy\nDOMAIN-SUFFIX,yahoo.tw,Proxy\nDOMAIN-SUFFIX,www.translatetheweb.com,Proxy\nDOMAIN-SUFFIX,matters.news,Proxy\nDOMAIN-SUFFIX,pigav.com,Proxy\nDOMAIN-SUFFIX,www.barbixas.com,Proxy\nDOMAIN-SUFFIX,wen.lu,Proxy\nDOMAIN-SUFFIX,forum.iset.com.tw,Proxy\nDOMAIN-SUFFIX,www.daliulian.com,Proxy\nDOMAIN-SUFFIX,stories.google,Proxy\nDOMAIN-SUFFIX,516nn.net,Proxy\nDOMAIN-SUFFIX,ps.pass.fm,Proxy\nDOMAIN-SUFFIX,search.aol.com,Proxy\nDOMAIN-SUFFIX,helanonline.cn,Proxy\nDOMAIN-SUFFIX,ttvnw.net,Proxy\nDOMAIN-SUFFIX,twindexx.com,Proxy\nDOMAIN-SUFFIX,vpnworldwide.com,Proxy\nDOMAIN-SUFFIX,223pp.net,Proxy\nDOMAIN-SUFFIX,meripet.biz,Proxy\nDOMAIN-SUFFIX,facebook.nl,Proxy\nDOMAIN-SUFFIX,ns1.name,Proxy\nDOMAIN-SUFFIX,thisismoney.co.uk,Proxy\nDOMAIN-SUFFIX,2nine.net,Proxy\nDOMAIN-SUFFIX,blogspot.co.id,Proxy\nDOMAIN-SUFFIX,riolearn.org,Proxy\nDOMAIN-SUFFIX,www.volksblatt.li,Proxy\nDOMAIN-SUFFIX,japonx.net,Proxy\nDOMAIN-SUFFIX,mingpaocanada.com,Proxy\nDOMAIN-SUFFIX,www.wojsq.com,Proxy\nDOMAIN-SUFFIX,lizakii.000webhostapp.com,Proxy\nDOMAIN-SUFFIX,rael.gq,Proxy\nDOMAIN-SUFFIX,mcreasite.com,Proxy\nDOMAIN-SUFFIX,qjxu.r5.cr.rs,Proxy\nDOMAIN-SUFFIX,7chan.org,Proxy\nDOMAIN-SUFFIX,china-mmm.jp.net,Proxy\nDOMAIN-SUFFIX,blogspot.cl,Proxy\nDOMAIN-SUFFIX,dreyers.com,Proxy\nDOMAIN-SUFFIX,bnr.bg,Proxy\nDOMAIN-SUFFIX,ww-cc1.xyz,Proxy\nDOMAIN-SUFFIX,app3.ga,Proxy\nDOMAIN-SUFFIX,ak.com,Proxy\nDOMAIN-SUFFIX,dalailamainaustralia.org,Proxy\nDOMAIN-SUFFIX,mobilka.net,Proxy\nDOMAIN-SUFFIX,clubveronicaavluv.com,Proxy\nDOMAIN-SUFFIX,fcmtv.site,Proxy\nDOMAIN-SUFFIX,www.zfbd108.com,Proxy\nDOMAIN-SUFFIX,parikaruna.org.au,Proxy\nDOMAIN-SUFFIX,googlefiber.net,Proxy\nDOMAIN-SUFFIX,postlm.com,Proxy\nDOMAIN-SUFFIX,galstars.net,Proxy\nDOMAIN-SUFFIX,wikimirror.org,Proxy\nDOMAIN-SUFFIX,zg99.1apps.com,Proxy\nDOMAIN-SUFFIX,imgasd.com,Proxy\nDOMAIN-SUFFIX,fringenetwork.com,Proxy\nDOMAIN-SUFFIX,storagenewsletter.com,Proxy\nDOMAIN-SUFFIX,wowhead.com,Proxy\nDOMAIN-SUFFIX,proksiak.pl,Proxy\nDOMAIN-SUFFIX,www.islamicpluralism.org,Proxy\nDOMAIN-SUFFIX,6tyxfks2.top,Proxy\nDOMAIN-SUFFIX,qiandao.today,Proxy\nDOMAIN-SUFFIX,4706.cabet125.com,Proxy\nDOMAIN-SUFFIX,edomtech.com,Proxy\nDOMAIN-SUFFIX,list.juwai.com,Proxy\nDOMAIN-SUFFIX,900678.com,Proxy\nDOMAIN-SUFFIX,www.mingpaotor.com,Proxy\nDOMAIN-SUFFIX,news.yahoo.com,Proxy\nDOMAIN-SUFFIX,psiphon.onl,Proxy\nDOMAIN-SUFFIX,www.pornative.com,Proxy\nDOMAIN-SUFFIX,zamzata.com,Proxy\nDOMAIN-SUFFIX,firebaseapp.com,Proxy\nDOMAIN-SUFFIX,topic.youthwant.com.tw,Proxy\nDOMAIN-SUFFIX,zzs.healthgov.xyz,Proxy\nDOMAIN-SUFFIX,bitlynx.com,Proxy\nDOMAIN-SUFFIX,jmcomic.cc,Proxy\nDOMAIN-SUFFIX,avjavjav.com,Proxy\nDOMAIN-SUFFIX,idemocracy.asia,Proxy\nDOMAIN-SUFFIX,www.freedomonthenet.org,Proxy\nDOMAIN-SUFFIX,www.meansys.com,Proxy\nDOMAIN-SUFFIX,vs856.com,Proxy\nDOMAIN-SUFFIX,google.eu,Proxy\nDOMAIN-SUFFIX,syunkanclub.strikingly.com,Proxy\nDOMAIN-SUFFIX,d3or87wg8f69ex.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.ctitv.com.tw,Proxy\nDOMAIN-SUFFIX,r1.cr.rs,Proxy\nDOMAIN-SUFFIX,www.egyptindependent.com,Proxy\nDOMAIN-SUFFIX,apk.webgis.ro,Proxy\nDOMAIN-SUFFIX,emersonbrookforest.org,Proxy\nDOMAIN-SUFFIX,abstracta.cl,Proxy\nDOMAIN-SUFFIX,google.co.uz,Proxy\nDOMAIN-SUFFIX,m.fjbet.com,Proxy\nDOMAIN-SUFFIX,nord-cn.net,Proxy\nDOMAIN-SUFFIX,www.yptea.com.tw,Proxy\nDOMAIN-SUFFIX,www.devina.es,Proxy\nDOMAIN-SUFFIX,www.grandis.nu,Proxy\nDOMAIN-SUFFIX,www.wsj.de,Proxy\nDOMAIN-SUFFIX,islamtoday.net,Proxy\nDOMAIN-SUFFIX,cn.venetianmacau.com,Proxy\nDOMAIN-SUFFIX,lux.dhcp.biz,Proxy\nDOMAIN-SUFFIX,inote.tw,Proxy\nDOMAIN-SUFFIX,woopie.jp,Proxy\nDOMAIN-SUFFIX,52.onmypc.net,Proxy\nDOMAIN-SUFFIX,gfwbrowser.com,Proxy\nDOMAIN-SUFFIX,opendn.xyz,Proxy\nDOMAIN-SUFFIX,fancy7.com,Proxy\nDOMAIN-SUFFIX,thehousenews.com,Proxy\nDOMAIN-SUFFIX,fora.pl,Proxy\nDOMAIN-SUFFIX,bivpn.com,Proxy\nDOMAIN-SUFFIX,lookins.me,Proxy\nDOMAIN-SUFFIX,allisons.org,Proxy\nDOMAIN-SUFFIX,99scouts.ca,Proxy\nDOMAIN-SUFFIX,doughcalc.com,Proxy\nDOMAIN-SUFFIX,breakingtweets.com,Proxy\nDOMAIN-SUFFIX,www.tucao.lol,Proxy\nDOMAIN-SUFFIX,danke4china.net,Proxy\nDOMAIN-SUFFIX,images.plurk.com,Proxy\nDOMAIN-SUFFIX,h5.ldsvip74.cc,Proxy\nDOMAIN-SUFFIX,cn.souka.xyz,Proxy\nDOMAIN-SUFFIX,sftuk.org,Proxy\nDOMAIN-SUFFIX,comprotusjuguetes.com,Proxy\nDOMAIN-SUFFIX,twishort.com,Proxy\nDOMAIN-SUFFIX,www.linkev.com,Proxy\nDOMAIN-SUFFIX,val.id.lv,Proxy\nDOMAIN-SUFFIX,10beasts.net,Proxy\nDOMAIN-SUFFIX,www.betvictor51.com,Proxy\nDOMAIN-SUFFIX,twavi.com,Proxy\nDOMAIN-SUFFIX,dziama.ca,Proxy\nDOMAIN-SUFFIX,wol.jw.org,Proxy\nDOMAIN-SUFFIX,m.39879.com,Proxy\nDOMAIN-SUFFIX,zh.mexgroup.com,Proxy\nDOMAIN-SUFFIX,btku.me,Proxy\nDOMAIN-SUFFIX,airvpn.org,Proxy\nDOMAIN-SUFFIX,www.f6cu.com,Proxy\nDOMAIN-SUFFIX,itweet.net,Proxy\nDOMAIN-SUFFIX,unknownspace.org,Proxy\nDOMAIN-SUFFIX,ghostvpn.com,Proxy\nDOMAIN-SUFFIX,sc.sh22.us,Proxy\nDOMAIN-SUFFIX,11xh888.com,Proxy\nDOMAIN-SUFFIX,lutaigao.snfda.com,Proxy\nDOMAIN-SUFFIX,www.spectator.co.uk,Proxy\nDOMAIN-SUFFIX,tweetboard.com,Proxy\nDOMAIN-SUFFIX,chinasoul.org,Proxy\nDOMAIN-SUFFIX,www.pichunter.com,Proxy\nDOMAIN-SUFFIX,epochtimes.ie,Proxy\nDOMAIN-SUFFIX,cdn.worldmate.com,Proxy\nDOMAIN-SUFFIX,googlecode.com,Proxy\nDOMAIN-SUFFIX,hashbase.io,Proxy\nDOMAIN-SUFFIX,healthgovt.xyz,Proxy\nDOMAIN-SUFFIX,smart.com.ph,Proxy\nDOMAIN-SUFFIX,seen.pk,Proxy\nDOMAIN-SUFFIX,china.resellerclub.com,Proxy\nDOMAIN-SUFFIX,mtp9.xyz,Proxy\nDOMAIN-SUFFIX,www.sscshishi.com,Proxy\nDOMAIN-SUFFIX,www.labour.gov.hk,Proxy\nDOMAIN-SUFFIX,tryjumps.org,Proxy\nDOMAIN-SUFFIX,wikiless.esmailelbob.xyz,Proxy\nDOMAIN-SUFFIX,obyte.org,Proxy\nDOMAIN-SUFFIX,fulibl.club,Proxy\nDOMAIN-SUFFIX,www.fy88.com,Proxy\nDOMAIN-SUFFIX,zim.vn,Proxy\nDOMAIN-SUFFIX,xtvx.5lxtv.com,Proxy\nDOMAIN-SUFFIX,dousyoko.net,Proxy\nDOMAIN-SUFFIX,25u.com,Proxy\nDOMAIN-SUFFIX,ctwant.com,Proxy\nDOMAIN-SUFFIX,notaricluj.ro,Proxy\nDOMAIN-SUFFIX,manybooks.net,Proxy\nDOMAIN-SUFFIX,naples-seo.com,Proxy\nDOMAIN-SUFFIX,aomiwang.com,Proxy\nDOMAIN-SUFFIX,www.w889889.net,Proxy\nDOMAIN-SUFFIX,anysex.com,Proxy\nDOMAIN-SUFFIX,www.571678.com,Proxy\nDOMAIN-SUFFIX,athoughtfulfaith.org,Proxy\nDOMAIN-SUFFIX,bbcnews.com,Proxy\nDOMAIN-SUFFIX,singtaousa.com,Proxy\nDOMAIN-SUFFIX,allowed.org,Proxy\nDOMAIN-SUFFIX,www.champion.gg,Proxy\nDOMAIN-SUFFIX,www.googlemaps.com,Proxy\nDOMAIN-SUFFIX,ccbill.com,Proxy\nDOMAIN-SUFFIX,tv.photo-frame.com,Proxy\nDOMAIN-SUFFIX,tgs.tca.org.tw,Proxy\nDOMAIN-SUFFIX,www.nokiacn.net,Proxy\nDOMAIN-SUFFIX,nl.hideproxy.me,Proxy\nDOMAIN-SUFFIX,pstatic.net,Proxy\nDOMAIN-SUFFIX,3cnet.tw,Proxy\nDOMAIN-SUFFIX,www.anime.cn,Proxy\nDOMAIN-SUFFIX,www.8356156.com,Proxy\nDOMAIN-SUFFIX,www.zuzazu.com,Proxy\nDOMAIN-SUFFIX,homeftp.net,Proxy\nDOMAIN-SUFFIX,le-vpn.com,Proxy\nDOMAIN-SUFFIX,reminderfox.org,Proxy\nDOMAIN-SUFFIX,nuzcom.com,Proxy\nDOMAIN-SUFFIX,backroomfacials.com,Proxy\nDOMAIN-SUFFIX,d7mglq142hzrl.cloudfront.net,Proxy\nDOMAIN-SUFFIX,keia.org,Proxy\nDOMAIN-SUFFIX,tor-exit-38.for-privacy.net,Proxy\nDOMAIN-SUFFIX,mbaprepschool.cn,Proxy\nDOMAIN-SUFFIX,rainbowplan.org,Proxy\nDOMAIN-SUFFIX,redtube.com,Proxy\nDOMAIN-SUFFIX,virtualtarget.com.br,Proxy\nDOMAIN-SUFFIX,delaynomo.re,Proxy\nDOMAIN-SUFFIX,fxopenasia.com,Proxy\nDOMAIN-SUFFIX,xslist.org,Proxy\nDOMAIN-SUFFIX,bodog127.com,Proxy\nDOMAIN-SUFFIX,community.worldebooklibrary.org,Proxy\nDOMAIN-SUFFIX,jigsawthirsty.com,Proxy\nDOMAIN-SUFFIX,xbet1996.com,Proxy\nDOMAIN-SUFFIX,cc9514.com,Proxy\nDOMAIN-SUFFIX,wikilivres.info,Proxy\nDOMAIN-SUFFIX,www.spreaker.com,Proxy\nDOMAIN-SUFFIX,mercatox.com,Proxy\nDOMAIN-SUFFIX,on-smarter-address-book.android.informer.com,Proxy\nDOMAIN-SUFFIX,iptv.com.tw,Proxy\nDOMAIN-SUFFIX,maicloud.me,Proxy\nDOMAIN-SUFFIX,gfw.wtf,Proxy\nDOMAIN-SUFFIX,iqq3.club,Proxy\nDOMAIN-SUFFIX,d1q88zzddlkcnv.cloudfront.net,Proxy\nDOMAIN-SUFFIX,yb188.emc388.com,Proxy\nDOMAIN-SUFFIX,mypop3.net,Proxy\nDOMAIN-SUFFIX,tibetanpoliticalreview.org,Proxy\nDOMAIN-SUFFIX,1024.05et.club,Proxy\nDOMAIN-SUFFIX,991.com,Proxy\nDOMAIN-SUFFIX,daum.net,Proxy\nDOMAIN-SUFFIX,www.hdzone.org,Proxy\nDOMAIN-SUFFIX,heartyit.com,Proxy\nDOMAIN-SUFFIX,ltn.com.tw,Proxy\nDOMAIN-SUFFIX,www.freevpnss.org,Proxy\nDOMAIN-SUFFIX,www.aspi.org.au,Proxy\nDOMAIN-SUFFIX,www.globeandmail.ca,Proxy\nDOMAIN-SUFFIX,www.dogma.co.jp,Proxy\nDOMAIN-SUFFIX,fatbtc.com,Proxy\nDOMAIN-SUFFIX,jims.net,Proxy\nDOMAIN-SUFFIX,jhatkaa.org,Proxy\nDOMAIN-SUFFIX,www.xb606.net,Proxy\nDOMAIN-SUFFIX,submit.jotformpro.com,Proxy\nDOMAIN-SUFFIX,emvpn.com,Proxy\nDOMAIN-SUFFIX,flyzy2005.com,Proxy\nDOMAIN-SUFFIX,www.jtw007.com,Proxy\nDOMAIN-SUFFIX,sellusedlaptopz.com,Proxy\nDOMAIN-SUFFIX,wiki.ncad.fr,Proxy\nDOMAIN-SUFFIX,www.avyahoo.com,Proxy\nDOMAIN-SUFFIX,d2lo5qw37fgyx7.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.fun277.com,Proxy\nDOMAIN-SUFFIX,federalres.com,Proxy\nDOMAIN-SUFFIX,d2981wk3xzypor.cloudfront.net,Proxy\nDOMAIN-SUFFIX,tobet.io,Proxy\nDOMAIN-SUFFIX,www.avirtualfriend.ch,Proxy\nDOMAIN-SUFFIX,aqqgroup.insight-labs.org,Proxy\nDOMAIN-SUFFIX,cn.shopbxb.com,Proxy\nDOMAIN-SUFFIX,k5ww.com,Proxy\nDOMAIN-SUFFIX,zzb.bz,Proxy\nDOMAIN-SUFFIX,1024.ddos3344.com,Proxy\nDOMAIN-SUFFIX,15.is-by.us,Proxy\nDOMAIN-SUFFIX,35955i.com,Proxy\nDOMAIN-SUFFIX,mv.3d-game.com,Proxy\nDOMAIN-SUFFIX,d3rkfw22xppori.cloudfront.net,Proxy\nDOMAIN-SUFFIX,mad-ar.ch,Proxy\nDOMAIN-SUFFIX,p88803.com,Proxy\nDOMAIN-SUFFIX,since1989.org,Proxy\nDOMAIN-SUFFIX,www.ilustradordigital.es,Proxy\nDOMAIN-SUFFIX,i.init.shop,Proxy\nDOMAIN-SUFFIX,tibetalk.com,Proxy\nDOMAIN-SUFFIX,kbs.com,Proxy\nDOMAIN-SUFFIX,www.starwarsminute.com,Proxy\nDOMAIN-SUFFIX,aluminium-stewardship.org,Proxy\nDOMAIN-SUFFIX,www.bluestacks.com,Proxy\nDOMAIN-SUFFIX,qhigh.com,Proxy\nDOMAIN-SUFFIX,vp.com,Proxy\nDOMAIN-SUFFIX,jmcomic.one,Proxy\nDOMAIN-SUFFIX,chaos-system.de,Proxy\nDOMAIN-SUFFIX,mingpaotor.com,Proxy\nDOMAIN-SUFFIX,www.rb88137.com,Proxy\nDOMAIN-SUFFIX,www.nbhao.net,Proxy\nDOMAIN-SUFFIX,www.thinkstockphotos.ae,Proxy\nDOMAIN-SUFFIX,www.yourpornbus.com,Proxy\nDOMAIN-SUFFIX,www.vkontakte.com,Proxy\nDOMAIN-SUFFIX,chinalawblog.com,Proxy\nDOMAIN-SUFFIX,hkgpao.com,Proxy\nDOMAIN-SUFFIX,peertube.co.uk,Proxy\nDOMAIN-SUFFIX,singularitys.spaces.live.com,Proxy\nDOMAIN-SUFFIX,proxfree.com,Proxy\nDOMAIN-SUFFIX,sg8899.com,Proxy\nDOMAIN-SUFFIX,www.tsdm.love,Proxy\nDOMAIN-SUFFIX,vpnik.com,Proxy\nDOMAIN-SUFFIX,hua-yue.net,Proxy\nDOMAIN-SUFFIX,teeniefuck.net,Proxy\nDOMAIN-SUFFIX,stormmediagroup.com,Proxy\nDOMAIN-SUFFIX,app.zerion.io,Proxy\nDOMAIN-SUFFIX,www.mycanadanow.com,Proxy\nDOMAIN-SUFFIX,destruct.co,Proxy\nDOMAIN-SUFFIX,dogvpn.com,Proxy\nDOMAIN-SUFFIX,igcd.net,Proxy\nDOMAIN-SUFFIX,808181.com,Proxy\nDOMAIN-SUFFIX,barrymatv.com,Proxy\nDOMAIN-SUFFIX,d34igfgmww1rs6.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.dh6666.com,Proxy\nDOMAIN-SUFFIX,d2po1w1hux4wug.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.nnn.co.jp,Proxy\nDOMAIN-SUFFIX,63gg.net,Proxy\nDOMAIN-SUFFIX,dollf.com,Proxy\nDOMAIN-SUFFIX,rthkaudio4-lh.akamaihd.net,Proxy\nDOMAIN-SUFFIX,www.tbet88.com,Proxy\nDOMAIN-SUFFIX,zhengjian.or.kr,Proxy\nDOMAIN-SUFFIX,battle.net,Proxy\nDOMAIN-SUFFIX,www.bellingencourier.com.au,Proxy\nDOMAIN-SUFFIX,theowendavis.com,Proxy\nDOMAIN-SUFFIX,www.uholiday.com.tw,Proxy\nDOMAIN-SUFFIX,deepai.org,Proxy\nDOMAIN-SUFFIX,gopetition.com,Proxy\nDOMAIN-SUFFIX,zap2it.com,Proxy\nDOMAIN-SUFFIX,from-sd.com,Proxy\nDOMAIN-SUFFIX,moheet.com,Proxy\nDOMAIN-SUFFIX,tb9991.com,Proxy\nDOMAIN-SUFFIX,nvtongzhisheng.org,Proxy\nDOMAIN-SUFFIX,aavideo.live,Proxy\nDOMAIN-SUFFIX,www.ashbournecollege.co.uk,Proxy\nDOMAIN-SUFFIX,dcj0f5wks23rq.cloudfront.net,Proxy\nDOMAIN-SUFFIX,tiny18.net,Proxy\nDOMAIN-SUFFIX,vpnxxw.com,Proxy\nDOMAIN-SUFFIX,mlh.tv,Proxy\nDOMAIN-SUFFIX,kool.nyc,Proxy\nDOMAIN-SUFFIX,ipo-90.maaii.com,Proxy\nDOMAIN-SUFFIX,hkdailynews.com.hk,Proxy\nDOMAIN-SUFFIX,www.taup.org.tw,Proxy\nDOMAIN-SUFFIX,max.rethinkdns.com,Proxy\nDOMAIN-SUFFIX,v2ph.com,Proxy\nDOMAIN-SUFFIX,chinaaid.us,Proxy\nDOMAIN-SUFFIX,c4ads.org,Proxy\nDOMAIN-SUFFIX,d34w42arfi4222.cloudfront.net,Proxy\nDOMAIN-SUFFIX,nytcn.me,Proxy\nDOMAIN-SUFFIX,hdzog.com,Proxy\nDOMAIN-SUFFIX,nztd.vip,Proxy\nDOMAIN-SUFFIX,t3.slyip.net,Proxy\nDOMAIN-SUFFIX,pornfromczech.com,Proxy\nDOMAIN-SUFFIX,www.cehs.net,Proxy\nDOMAIN-SUFFIX,dzogchengonpa.org,Proxy\nDOMAIN-SUFFIX,www.dailyvpn.io,Proxy\nDOMAIN-SUFFIX,tilde.zone,Proxy\nDOMAIN-SUFFIX,www.liuzheyuan.com,Proxy\nDOMAIN-SUFFIX,shuipaizi.blogspot.hk,Proxy\nDOMAIN-SUFFIX,www.jainchetan.com,Proxy\nDOMAIN-SUFFIX,syntheticjournal.com,Proxy\nDOMAIN-SUFFIX,cs696.com,Proxy\nDOMAIN-SUFFIX,bine.me,Proxy\nDOMAIN-SUFFIX,library.pressdisplay.com,Proxy\nDOMAIN-SUFFIX,cryptocert.org,Proxy\nDOMAIN-SUFFIX,mem3.cleansite.us,Proxy\nDOMAIN-SUFFIX,zh.wikipedia.hfut.cf,Proxy\nDOMAIN-SUFFIX,fyptt.to,Proxy\nDOMAIN-SUFFIX,hp.cool,Proxy\nDOMAIN-SUFFIX,reloadtech.com,Proxy\nDOMAIN-SUFFIX,www.acgxmh.com,Proxy\nDOMAIN-SUFFIX,www.dalailamavillage.it,Proxy\nDOMAIN-SUFFIX,www.facebook.com.au,Proxy\nDOMAIN-SUFFIX,youversion.com,Proxy\nDOMAIN-SUFFIX,www.genevasummit.org,Proxy\nDOMAIN-SUFFIX,m.cc161.com,Proxy\nDOMAIN-SUFFIX,penisbot.com,Proxy\nDOMAIN-SUFFIX,ylg20.com,Proxy\nDOMAIN-SUFFIX,fflick.com,Proxy\nDOMAIN-SUFFIX,vpn-ninja.net,Proxy\nDOMAIN-SUFFIX,785.microcycas.com,Proxy\nDOMAIN-SUFFIX,www.colombogazette.com,Proxy\nDOMAIN-SUFFIX,spotflux.com,Proxy\nDOMAIN-SUFFIX,409.microcycas.com,Proxy\nDOMAIN-SUFFIX,is-very-sweet.org,Proxy\nDOMAIN-SUFFIX,huajiadi.spaces.live.com,Proxy\nDOMAIN-SUFFIX,oskay.web.tr,Proxy\nDOMAIN-SUFFIX,zfxasia.com,Proxy\nDOMAIN-SUFFIX,e4a62.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,fidh.org,Proxy\nDOMAIN-SUFFIX,isa-geek.com,Proxy\nDOMAIN-SUFFIX,www.brawandpurvis.com,Proxy\nDOMAIN-SUFFIX,taedp.org.tw,Proxy\nDOMAIN-SUFFIX,pkw-aufladen.de,Proxy\nDOMAIN-SUFFIX,www.proxfree.com,Proxy\nDOMAIN-SUFFIX,google.cc,Proxy\nDOMAIN-SUFFIX,carsandmiles.com,Proxy\nDOMAIN-SUFFIX,mycrazyvids.com,Proxy\nDOMAIN-SUFFIX,mapp-web.r88app04.com,Proxy\nDOMAIN-SUFFIX,cc.hacked.jp,Proxy\nDOMAIN-SUFFIX,tv5.spacetechnology.net,Proxy\nDOMAIN-SUFFIX,vpnhm.com,Proxy\nDOMAIN-SUFFIX,www.oacac.com,Proxy\nDOMAIN-SUFFIX,worldyoutube.com,Proxy\nDOMAIN-SUFFIX,colombiavpn.com,Proxy\nDOMAIN-SUFFIX,graphis.ne.jp,Proxy\nDOMAIN-SUFFIX,woeser.com,Proxy\nDOMAIN-SUFFIX,www.biance.com,Proxy\nDOMAIN-SUFFIX,cnpolitics.org,Proxy\nDOMAIN-SUFFIX,www.zrii.com,Proxy\nDOMAIN-SUFFIX,www.jetanimes.com,Proxy\nDOMAIN-SUFFIX,communitychoicecu.com,Proxy\nDOMAIN-SUFFIX,mp3buscador.com,Proxy\nDOMAIN-SUFFIX,doh.applied-privacy.net,Proxy\nDOMAIN-SUFFIX,www.tweentribune.com,Proxy\nDOMAIN-SUFFIX,www.liveany.com,Proxy\nDOMAIN-SUFFIX,www.suncity.com,Proxy\nDOMAIN-SUFFIX,18comic3.biz,Proxy\nDOMAIN-SUFFIX,trimleng.cn,Proxy\nDOMAIN-SUFFIX,specxinzl.jigsy.com,Proxy\nDOMAIN-SUFFIX,www2.ohchr.org,Proxy\nDOMAIN-SUFFIX,python.com,Proxy\nDOMAIN-SUFFIX,shadowsocks.blogspot.ca,Proxy\nDOMAIN-SUFFIX,dns.jstockley.com,Proxy\nDOMAIN-SUFFIX,thunder.free-signal.com,Proxy\nDOMAIN-SUFFIX,kingofvpn.com,Proxy\nDOMAIN-SUFFIX,chromestatus.com,Proxy\nDOMAIN-SUFFIX,cloudflare-dns.com,Proxy\nDOMAIN-SUFFIX,lhasocialwork.org,Proxy\nDOMAIN-SUFFIX,celebrityandcommunityamebo.blogspot.hk,Proxy\nDOMAIN-SUFFIX,attachment.fbsbx.com,Proxy\nDOMAIN-SUFFIX,chinavpn.xyz,Proxy\nDOMAIN-SUFFIX,soundofhope.kr,Proxy\nDOMAIN-SUFFIX,dbc.hk,Proxy\nDOMAIN-SUFFIX,valeursactuelles.com,Proxy\nDOMAIN-SUFFIX,www.lockergnome.com,Proxy\nDOMAIN-SUFFIX,dlsite.com,Proxy\nDOMAIN-SUFFIX,www.merchantmethod.com,Proxy\nDOMAIN-SUFFIX,www.google.com.im,Proxy\nDOMAIN-SUFFIX,www.mensheer.cc,Proxy\nDOMAIN-SUFFIX,uncyclomedia.org,Proxy\nDOMAIN-SUFFIX,www.yizhihongxing.com,Proxy\nDOMAIN-SUFFIX,www.methodist.org.tw,Proxy\nDOMAIN-SUFFIX,medium.com,Proxy\nDOMAIN-SUFFIX,mammothtube.com,Proxy\nDOMAIN-SUFFIX,www.nudelive.com,Proxy\nDOMAIN-SUFFIX,google.ba,Proxy\nDOMAIN-SUFFIX,maneskin.it,Proxy\nDOMAIN-SUFFIX,gamingsoft.com,Proxy\nDOMAIN-SUFFIX,www.sydneytoday.com,Proxy\nDOMAIN-SUFFIX,page2rss.com,Proxy\nDOMAIN-SUFFIX,vt.com,Proxy\nDOMAIN-SUFFIX,hkpics.net,Proxy\nDOMAIN-SUFFIX,milsurps.com,Proxy\nDOMAIN-SUFFIX,www.wral.com,Proxy\nDOMAIN-SUFFIX,talk853.com,Proxy\nDOMAIN-SUFFIX,www.kir.jp,Proxy\nDOMAIN-SUFFIX,www.coolncute.com,Proxy\nDOMAIN-SUFFIX,redhat.com,Proxy\nDOMAIN-SUFFIX,www.6699.com.tw,Proxy\nDOMAIN-SUFFIX,www.bangbus.com,Proxy\nDOMAIN-SUFFIX,www.channelnewsasia.com.sg,Proxy\nDOMAIN-SUFFIX,www.cathvoice.org.tw,Proxy\nDOMAIN-SUFFIX,www.firebaseio.com,Proxy\nDOMAIN-SUFFIX,flitto.com,Proxy\nDOMAIN-SUFFIX,advspmatch.blogspot.com.tr,Proxy\nDOMAIN-SUFFIX,protonmail.ch,Proxy\nDOMAIN-SUFFIX,miaona.xyz,Proxy\nDOMAIN-SUFFIX,miaosss.top,Proxy\nDOMAIN-SUFFIX,frenchtorrentdb.com,Proxy\nDOMAIN-SUFFIX,248bc.com,Proxy\nDOMAIN-SUFFIX,acnw.com.au,Proxy\nDOMAIN-SUFFIX,tb0090.com,Proxy\nDOMAIN-SUFFIX,patw.idv.tw,Proxy\nDOMAIN-SUFFIX,worlds-diver-9515e.firebaseio.com,Proxy\nDOMAIN-SUFFIX,www.govbooks.com.tw,Proxy\nDOMAIN-SUFFIX,00899b.com,Proxy\nDOMAIN-SUFFIX,blue-sea.idv.tw,Proxy\nDOMAIN-SUFFIX,az276019.vo.msecnd.net,Proxy\nDOMAIN-SUFFIX,proxy.yt,Proxy\nDOMAIN-SUFFIX,pushchinawall.com,Proxy\nDOMAIN-SUFFIX,us-central1-ripple-3dc2d.cloudfunctions.net,Proxy\nDOMAIN-SUFFIX,zsrhao.com,Proxy\nDOMAIN-SUFFIX,www.wallmama.com,Proxy\nDOMAIN-SUFFIX,3849.cc,Proxy\nDOMAIN-SUFFIX,google.com.ec,Proxy\nDOMAIN-SUFFIX,ggpht.com,Proxy\nDOMAIN-SUFFIX,ys0.ballbet4.com,Proxy\nDOMAIN-SUFFIX,stockportnsg.co.uk,Proxy\nDOMAIN-SUFFIX,tenacy.com,Proxy\nDOMAIN-SUFFIX,yam.org.tw,Proxy\nDOMAIN-SUFFIX,www.cgbc.org,Proxy\nDOMAIN-SUFFIX,ca975.com,Proxy\nDOMAIN-SUFFIX,softonic.com,Proxy\nDOMAIN-SUFFIX,kfc8001.com,Proxy\nDOMAIN-SUFFIX,wanbet.com,Proxy\nDOMAIN-SUFFIX,pieayu.com,Proxy\nDOMAIN-SUFFIX,www.wikipedia.ahut.cf,Proxy\nDOMAIN-SUFFIX,yuekma.github.io,Proxy\nDOMAIN-SUFFIX,www.google.sk,Proxy\nDOMAIN-SUFFIX,17.live,Proxy\nDOMAIN-SUFFIX,expresscargo.cl,Proxy\nDOMAIN-SUFFIX,www.flowvpn.com,Proxy\nDOMAIN-SUFFIX,www.sg215.xyz,Proxy\nDOMAIN-SUFFIX,useraudio.net,Proxy\nDOMAIN-SUFFIX,www.theadvocate.com.au,Proxy\nDOMAIN-SUFFIX,haoli747.com,Proxy\nDOMAIN-SUFFIX,d6565.com,Proxy\nDOMAIN-SUFFIX,fc2china.com,Proxy\nDOMAIN-SUFFIX,stickeraction.com,Proxy\nDOMAIN-SUFFIX,www.tsescorts.com,Proxy\nDOMAIN-SUFFIX,xam66666.com,Proxy\nDOMAIN-SUFFIX,kissbbao.cn,Proxy\nDOMAIN-SUFFIX,kugo.cc,Proxy\nDOMAIN-SUFFIX,sfxslibrary.club,Proxy\nDOMAIN-SUFFIX,shabi.com,Proxy\nDOMAIN-SUFFIX,nozomi.la,Proxy\nDOMAIN-SUFFIX,cybertv.tv,Proxy\nDOMAIN-SUFFIX,fsurf.com,Proxy\nDOMAIN-SUFFIX,zfx.com,Proxy\nDOMAIN-SUFFIX,www.fyzhuji.com,Proxy\nDOMAIN-SUFFIX,classroom.teachwithkoala.com,Proxy\nDOMAIN-SUFFIX,penthousehdtv.com,Proxy\nDOMAIN-SUFFIX,369.ddnsking.com,Proxy\nDOMAIN-SUFFIX,yaganexpress.cl,Proxy\nDOMAIN-SUFFIX,www.sgchinese.com,Proxy\nDOMAIN-SUFFIX,mrc58.com,Proxy\nDOMAIN-SUFFIX,www.tokyo-np.co.jp,Proxy\nDOMAIN-SUFFIX,bridgefy.me,Proxy\nDOMAIN-SUFFIX,chung-yang.com,Proxy\nDOMAIN-SUFFIX,shishissc.com,Proxy\nDOMAIN-SUFFIX,pf.anonplus.org,Proxy\nDOMAIN-SUFFIX,224dh.com,Proxy\nDOMAIN-SUFFIX,dot.sb,Proxy\nDOMAIN-SUFFIX,ai.53xtv.com,Proxy\nDOMAIN-SUFFIX,hyphen.cl,Proxy\nDOMAIN-SUFFIX,editor.p5js.org,Proxy\nDOMAIN-SUFFIX,webbooksnow.org,Proxy\nDOMAIN-SUFFIX,www.hotfunhouse.com,Proxy\nDOMAIN-SUFFIX,www.twsextop.com,Proxy\nDOMAIN-SUFFIX,petel.us,Proxy\nDOMAIN-SUFFIX,adepoju.org,Proxy\nDOMAIN-SUFFIX,jkorlow.com,Proxy\nDOMAIN-SUFFIX,liuli.se,Proxy\nDOMAIN-SUFFIX,hkgalden.org,Proxy\nDOMAIN-SUFFIX,chineseupress.com,Proxy\nDOMAIN-SUFFIX,www.biwei6699.com,Proxy\nDOMAIN-SUFFIX,freegateget.googlepages.com,Proxy\nDOMAIN-SUFFIX,cyit.xyz,Proxy\nDOMAIN-SUFFIX,bootstrapcdn.com,Proxy\nDOMAIN-SUFFIX,fuhuiglobal.com,Proxy\nDOMAIN-SUFFIX,cs0099.com,Proxy\nDOMAIN-SUFFIX,chitter.xyz,Proxy\nDOMAIN-SUFFIX,iepl.us,Proxy\nDOMAIN-SUFFIX,nztd.fun,Proxy\nDOMAIN-SUFFIX,shadowsocks9.com,Proxy\nDOMAIN-SUFFIX,www.diedart5.com,Proxy\nDOMAIN-SUFFIX,bbb.com,Proxy\nDOMAIN-SUFFIX,tw.linkedin.com,Proxy\nDOMAIN-SUFFIX,qanote.com,Proxy\nDOMAIN-SUFFIX,www.55115.com,Proxy\nDOMAIN-SUFFIX,akriluss.cl,Proxy\nDOMAIN-SUFFIX,09305.com,Proxy\nDOMAIN-SUFFIX,blakeliuhk.blogspot.hk,Proxy\nDOMAIN-SUFFIX,defilter.us,Proxy\nDOMAIN-SUFFIX,rukor.org,Proxy\nDOMAIN-SUFFIX,www.jwsprings.com,Proxy\nDOMAIN-SUFFIX,dougscripts.com,Proxy\nDOMAIN-SUFFIX,in-disguise.com,Proxy\nDOMAIN-SUFFIX,okvpn.cn,Proxy\nDOMAIN-SUFFIX,fanqiangcn.net,Proxy\nDOMAIN-SUFFIX,dm530.net,Proxy\nDOMAIN-SUFFIX,blogspot.cz,Proxy\nDOMAIN-SUFFIX,iqq1.net,Proxy\nDOMAIN-SUFFIX,www.ikangke.com,Proxy\nDOMAIN-SUFFIX,hot1024.win,Proxy\nDOMAIN-SUFFIX,www.ruizhongguo.com,Proxy\nDOMAIN-SUFFIX,boye.xyz,Proxy\nDOMAIN-SUFFIX,onnogo.site,Proxy\nDOMAIN-SUFFIX,uncyclopedia.miraheze.org,Proxy\nDOMAIN-SUFFIX,onepieceofbleach.com,Proxy\nDOMAIN-SUFFIX,livestrip.com,Proxy\nDOMAIN-SUFFIX,artemisweb.jp,Proxy\nDOMAIN-SUFFIX,cccat.cc,Proxy\nDOMAIN-SUFFIX,xmbs2.xyz,Proxy\nDOMAIN-SUFFIX,warroom.org,Proxy\nDOMAIN-SUFFIX,walkology.com,Proxy\nDOMAIN-SUFFIX,mcpedl.com,Proxy\nDOMAIN-SUFFIX,bitpay.com,Proxy\nDOMAIN-SUFFIX,comedycentral.com,Proxy\nDOMAIN-SUFFIX,36.effers.com,Proxy\nIP-CIDR,67.220.91.23/32,Proxy\nDOMAIN-SUFFIX,dns11.quad9.net,Proxy\nDOMAIN-SUFFIX,gg.eeload.com,Proxy\nDOMAIN-SUFFIX,d3mxmaz2dl5jbh.cloudfront.net,Proxy\nDOMAIN-SUFFIX,1050668.com,Proxy\nDOMAIN-SUFFIX,memritv.org,Proxy\nDOMAIN-SUFFIX,resistchina.org,Proxy\nDOMAIN-SUFFIX,slate.fr,Proxy\nDOMAIN-SUFFIX,jm-comic1.cc,Proxy\nDOMAIN-SUFFIX,4488buyu.com,Proxy\nDOMAIN-SUFFIX,cf79.cc,Proxy\nDOMAIN-SUFFIX,in04.icu,Proxy\nDOMAIN-SUFFIX,facebook.at,Proxy\nDOMAIN-SUFFIX,restofworld.org,Proxy\nDOMAIN-SUFFIX,www.audi.de,Proxy\nDOMAIN-SUFFIX,nl-pptp.unovpn.com,Proxy\nDOMAIN-SUFFIX,www.188166.com,Proxy\nDOMAIN-SUFFIX,istartsurf.com,Proxy\nDOMAIN-SUFFIX,glad-pro.com,Proxy\nDOMAIN-SUFFIX,kwok7.com,Proxy\nDOMAIN-SUFFIX,v1.68668.com,Proxy\nDOMAIN-SUFFIX,getinto.strikingly.com,Proxy\nDOMAIN-SUFFIX,www.iavbobo.com,Proxy\nDOMAIN-SUFFIX,imap.vivaldi.net,Proxy\nDOMAIN-SUFFIX,rapidproxy.org,Proxy\nDOMAIN-SUFFIX,ssrfree.tk,Proxy\nDOMAIN-SUFFIX,mstdn.io,Proxy\nDOMAIN-SUFFIX,www.youx.xxx,Proxy\nDOMAIN-SUFFIX,javbus2.pw,Proxy\nDOMAIN-SUFFIX,ahentai.top,Proxy\nDOMAIN-SUFFIX,tsquare.tv,Proxy\nDOMAIN-SUFFIX,easternlightning.org,Proxy\nDOMAIN-SUFFIX,socialiststudies.ca,Proxy\nDOMAIN-SUFFIX,epicbrowser.com,Proxy\nDOMAIN-SUFFIX,qltxshop.com,Proxy\nDOMAIN-SUFFIX,chin-chi.ch,Proxy\nDOMAIN-SUFFIX,wezone.net,Proxy\nDOMAIN-SUFFIX,24.slyip.net,Proxy\nDOMAIN-SUFFIX,unwatch.org,Proxy\nDOMAIN-SUFFIX,www.vimeopro.com,Proxy\nDOMAIN-SUFFIX,bat.me,Proxy\nDOMAIN-SUFFIX,d10ea7zpqv7soq.cloudfront.net,Proxy\nDOMAIN-SUFFIX,aspi.org.au,Proxy\nDOMAIN-SUFFIX,enteons.com.com,Proxy\nDOMAIN-SUFFIX,xu.domain888.pw,Proxy\nDOMAIN-SUFFIX,yzc518.com,Proxy\nDOMAIN-SUFFIX,ouyi.run,Proxy\nDOMAIN-SUFFIX,jria.jpn.com,Proxy\nDOMAIN-SUFFIX,mewe.com,Proxy\nDOMAIN-SUFFIX,itsallgay.eu,Proxy\nDOMAIN-SUFFIX,lab.skk.moe,Proxy\nDOMAIN-SUFFIX,wikipedia.de,Proxy\nDOMAIN-SUFFIX,binged.it,Proxy\nDOMAIN-SUFFIX,homura.net,Proxy\nDOMAIN-SUFFIX,cn.akinator.com,Proxy\nDOMAIN-SUFFIX,www.jewelheart.nl,Proxy\nDOMAIN-SUFFIX,www.877369.com,Proxy\nDOMAIN-SUFFIX,cn.uncyclopedia.wikia.com,Proxy\nDOMAIN-SUFFIX,vt19i.com,Proxy\nDOMAIN-SUFFIX,www.monolithic3d.com,Proxy\nDOMAIN-SUFFIX,expressvpn.net,Proxy\nDOMAIN-SUFFIX,www.jungl.me,Proxy\nDOMAIN-SUFFIX,kakao.co.kr,Proxy\nDOMAIN-SUFFIX,byt070.com,Proxy\nDOMAIN-SUFFIX,www.fh303.com,Proxy\nDOMAIN-SUFFIX,nitter.net,Proxy\nDOMAIN-SUFFIX,nordvpn.net,Proxy\nDOMAIN-SUFFIX,escortforumit.xxx,Proxy\nDOMAIN-SUFFIX,web.dev,Proxy\nDOMAIN-SUFFIX,bjchuhai.com,Proxy\nDOMAIN-SUFFIX,discord.gg,Proxy\nDOMAIN-SUFFIX,o3o.ca,Proxy\nDOMAIN-SUFFIX,bulldogfrances.com.ar,Proxy\nDOMAIN-SUFFIX,d1plizitxo67xx.cloudfront.net,Proxy\nDOMAIN-SUFFIX,ugo.com,Proxy\nDOMAIN-SUFFIX,fun881211.com,Proxy\nDOMAIN-SUFFIX,www.vungle.com,Proxy\nDOMAIN-SUFFIX,tt033.com,Proxy\nDOMAIN-SUFFIX,m.fun336.com,Proxy\nDOMAIN-SUFFIX,www.mailonline.co.uk,Proxy\nDOMAIN-SUFFIX,drenthecollege.nl,Proxy\nDOMAIN-SUFFIX,magenta.tk.global.prod.fastly.net,Proxy\nDOMAIN-SUFFIX,ns1.wp.com,Proxy\nDOMAIN-SUFFIX,www.rocket.com,Proxy\nDOMAIN-SUFFIX,ken.flnet.org,Proxy\nDOMAIN-SUFFIX,s.pixfs.net,Proxy\nDOMAIN-SUFFIX,cityofdreamsmacau.com,Proxy\nDOMAIN-SUFFIX,qui.suis.je,Proxy\nDOMAIN-SUFFIX,rtbot.net,Proxy\nDOMAIN-SUFFIX,jk-sexvideos.com,Proxy\nDOMAIN-SUFFIX,gmail.fr,Proxy\nDOMAIN-SUFFIX,softnology.biz,Proxy\nDOMAIN-SUFFIX,pc.tv333.us,Proxy\nDOMAIN-SUFFIX,sanyofoods.us,Proxy\nDOMAIN-SUFFIX,afcp09.com,Proxy\nDOMAIN-SUFFIX,holeyfuck.com,Proxy\nDOMAIN-SUFFIX,boxcn.net,Proxy\nDOMAIN-SUFFIX,www.ahlsj.xyz,Proxy\nDOMAIN-SUFFIX,lat.dhcp.biz,Proxy\nDOMAIN-SUFFIX,d1d8olcghscezm.cloudfront.net,Proxy\nDOMAIN-SUFFIX,198299.com,Proxy\nDOMAIN-SUFFIX,taiwaninsight.org,Proxy\nDOMAIN-SUFFIX,www.yasukuni.or.jp,Proxy\nDOMAIN-SUFFIX,abc.com.py,Proxy\nDOMAIN-SUFFIX,sha679.com,Proxy\nDOMAIN-SUFFIX,www.eyes-e-tools.net,Proxy\nDOMAIN-SUFFIX,image.playno1.com,Proxy\nDOMAIN-SUFFIX,surfert.nl,Proxy\nDOMAIN-SUFFIX,twitgoo.com,Proxy\nDOMAIN-SUFFIX,pixelqi.com,Proxy\nDOMAIN-SUFFIX,mohu.club,Proxy\nDOMAIN-SUFFIX,moneytips.hk,Proxy\nDOMAIN-SUFFIX,sunnysidepac.ca,Proxy\nDOMAIN-SUFFIX,podictionary.com,Proxy\nDOMAIN-SUFFIX,ae3803.com,Proxy\nDOMAIN-SUFFIX,streamer1.rfaweb.org,Proxy\nDOMAIN-SUFFIX,mindflash.com,Proxy\nDOMAIN-SUFFIX,poyopara.com,Proxy\nDOMAIN-SUFFIX,malaysiakini.com,Proxy\nDOMAIN-SUFFIX,shophq.com,Proxy\nDOMAIN-SUFFIX,ftp1.biz,Proxy\nDOMAIN-SUFFIX,potalapost.com,Proxy\nDOMAIN-SUFFIX,manwa.one,Proxy\nDOMAIN-SUFFIX,taco-land.net,Proxy\nDOMAIN-SUFFIX,tubepornclassic.com,Proxy\nDOMAIN-SUFFIX,cams.com,Proxy\nDOMAIN-SUFFIX,tian.yam.com,Proxy\nDOMAIN-SUFFIX,arriortua.es,Proxy\nDOMAIN-SUFFIX,cahr.org.tw,Proxy\nDOMAIN-SUFFIX,moat.torproject.org.global.prod.fastly.net,Proxy\nDOMAIN-SUFFIX,ewakaa.com,Proxy\nDOMAIN-SUFFIX,overdaily.org,Proxy\nDOMAIN-SUFFIX,xinjiang.sppga.ubc.ca,Proxy\nDOMAIN-SUFFIX,93bifa.com,Proxy\nDOMAIN-SUFFIX,9999cn.org,Proxy\nDOMAIN-SUFFIX,evchk.wikia.org,Proxy\nDOMAIN-SUFFIX,d1trltv50ka2uf.cloudfront.net,Proxy\nDOMAIN-SUFFIX,astraprod.ro,Proxy\nDOMAIN-SUFFIX,suny.ch,Proxy\nDOMAIN-SUFFIX,archlinuxstudio.github.io,Proxy\nDOMAIN-SUFFIX,keenmonkey.com,Proxy\nDOMAIN-SUFFIX,e4p7c9i3.stackpathcdn.com,Proxy\nDOMAIN-SUFFIX,submit.jotformz.com,Proxy\nDOMAIN-SUFFIX,m-78.jp,Proxy\nDOMAIN-SUFFIX,www.qingse.one,Proxy\nDOMAIN-SUFFIX,s1347.photobucket.com,Proxy\nDOMAIN-SUFFIX,sexfind.com,Proxy\nDOMAIN-SUFFIX,experts-univers.com,Proxy\nDOMAIN-SUFFIX,www.surfly.com,Proxy\nDOMAIN-SUFFIX,javakiba.org,Proxy\nDOMAIN-SUFFIX,static.pubu.tw,Proxy\nDOMAIN-SUFFIX,www.runox.biz,Proxy\nDOMAIN-SUFFIX,www.xw283.com,Proxy\nDOMAIN-SUFFIX,y6880.com,Proxy\nDOMAIN-SUFFIX,pjbar2.xyz,Proxy\nDOMAIN-SUFFIX,awrkapp.asia,Proxy\nDOMAIN-SUFFIX,checkfront.com,Proxy\nDOMAIN-SUFFIX,3youtube.com,Proxy\nDOMAIN-SUFFIX,2.llsif.moe,Proxy\nDOMAIN-SUFFIX,aliveproxy.com,Proxy\nDOMAIN-SUFFIX,jitsuroku.kir.jp,Proxy\nDOMAIN-SUFFIX,www.e8wx.com,Proxy\nDOMAIN-SUFFIX,localdomain.ws,Proxy\nDOMAIN-SUFFIX,vbzmh.site,Proxy\nDOMAIN-SUFFIX,huaile.me,Proxy\nDOMAIN-SUFFIX,w2.h2.dhcp.biz,Proxy\nDOMAIN-SUFFIX,urban-rivals.com,Proxy\nDOMAIN-SUFFIX,bet365.es,Proxy\nDOMAIN-SUFFIX,pimpandhost.com,Proxy\nDOMAIN-SUFFIX,www.mymusic.net.tw,Proxy\nDOMAIN-SUFFIX,www.vips6666.com,Proxy\nDOMAIN-SUFFIX,icl-fi.org,Proxy\nDOMAIN-SUFFIX,kzeng.info,Proxy\nDOMAIN-SUFFIX,www.9news.com.au,Proxy\nDOMAIN-SUFFIX,4206232.com,Proxy\nDOMAIN-SUFFIX,excore.biz,Proxy\nDOMAIN-SUFFIX,www.fandhstudios.com,Proxy\nDOMAIN-SUFFIX,isohunt.com,Proxy\nDOMAIN-SUFFIX,zootool.com,Proxy\nDOMAIN-SUFFIX,okk.tw,Proxy\nDOMAIN-SUFFIX,william0204.blogspot.hk,Proxy\nDOMAIN-SUFFIX,crazyshit.com,Proxy\nDOMAIN-SUFFIX,vlasnn.com,Proxy\nDOMAIN-SUFFIX,99btgc01.com,Proxy\nDOMAIN-SUFFIX,www.xiaoluyiqing.com,Proxy\nDOMAIN-SUFFIX,ca971.com,Proxy\nDOMAIN-SUFFIX,www.mis.mpg.de,Proxy\nDOMAIN-SUFFIX,55.cr.rs,Proxy\nDOMAIN-SUFFIX,weekmag.info,Proxy\nDOMAIN-SUFFIX,zhao.jinhai.de,Proxy\nDOMAIN-SUFFIX,freezing.tv,Proxy\nDOMAIN-SUFFIX,www.utjd.org,Proxy\nDOMAIN-SUFFIX,similarsitesearch.com,Proxy\nDOMAIN-SUFFIX,p6858.com,Proxy\nDOMAIN-SUFFIX,premium-beauty.com,Proxy\nDOMAIN-SUFFIX,www.happytugs.com,Proxy\nDOMAIN-SUFFIX,anyalandman.com,Proxy\nDOMAIN-SUFFIX,sub.kamigami.org,Proxy\nDOMAIN-SUFFIX,www.pornplays.com,Proxy\nDOMAIN-SUFFIX,gnowbe-app-2.firebaseio.com,Proxy\nDOMAIN-SUFFIX,smart.businessweekly.com.tw,Proxy\nDOMAIN-SUFFIX,www.aex.com,Proxy\nDOMAIN-SUFFIX,blog.foolsmountain.com,Proxy\nDOMAIN-SUFFIX,kvbr.com,Proxy\nDOMAIN-SUFFIX,totaladblock.com,Proxy\nDOMAIN-SUFFIX,www.javbaike.com,Proxy\nDOMAIN-SUFFIX,www.landbank.com.tw,Proxy\nDOMAIN-SUFFIX,google.ci,Proxy\nDOMAIN-SUFFIX,4irc.com,Proxy\nDOMAIN-SUFFIX,avaya.nqu.edu.tw,Proxy\nDOMAIN-SUFFIX,bookwalker.jp,Proxy\nDOMAIN-SUFFIX,j86o8.com,Proxy\nDOMAIN-SUFFIX,hkci.org.hk,Proxy\nDOMAIN-SUFFIX,www.fukuishimbun.co.jp,Proxy\nDOMAIN-SUFFIX,95662222r.com,Proxy\nDOMAIN-SUFFIX,www.doctwo.com,Proxy\nDOMAIN-SUFFIX,areca-backup.org,Proxy\nDOMAIN-SUFFIX,politi.co,Proxy\nDOMAIN-SUFFIX,www.cam4.com,Proxy\nDOMAIN-SUFFIX,blog.yeslx.com,Proxy\nDOMAIN-SUFFIX,www.twranking.com,Proxy\nDOMAIN-SUFFIX,www.xzcblog.com,Proxy\nDOMAIN-SUFFIX,artworld.tw,Proxy\nDOMAIN-SUFFIX,ooni.org,Proxy\nDOMAIN-SUFFIX,98123w.com,Proxy\nDOMAIN-SUFFIX,acidcow.com,Proxy\nDOMAIN-SUFFIX,edenfantasys.com,Proxy\nDOMAIN-SUFFIX,my.jumpthewall.net,Proxy\nDOMAIN-SUFFIX,newbigtube.com,Proxy\nDOMAIN-SUFFIX,vidademerda.com.br,Proxy\nDOMAIN-SUFFIX,k36.the-kaisers.net,Proxy\nDOMAIN-SUFFIX,qjvpn.com.cn,Proxy\nDOMAIN-SUFFIX,2460257.com,Proxy\nDOMAIN-SUFFIX,access.f3b.work,Proxy\nDOMAIN-SUFFIX,18comic.cc,Proxy\nDOMAIN-SUFFIX,www.andrewerickson.com,Proxy\nDOMAIN-SUFFIX,bbc.com,Proxy\nDOMAIN-SUFFIX,tibetwrites.org,Proxy\nDOMAIN-SUFFIX,www.taiwanlottery.com.tw,Proxy\nDOMAIN-SUFFIX,51smt2.xyz,Proxy\nDOMAIN-SUFFIX,www.rhumdefrance.com,Proxy\nDOMAIN-SUFFIX,does-it.net,Proxy\nDOMAIN-SUFFIX,www.bway889052.com,Proxy\nDOMAIN-SUFFIX,protoshost.com,Proxy\nDOMAIN-SUFFIX,m859.com,Proxy\nDOMAIN-SUFFIX,bn65.com,Proxy\nDOMAIN-SUFFIX,d2fj39scx1bkj7.cloudfront.net,Proxy\nDOMAIN-SUFFIX,ukusvpn.com,Proxy\nDOMAIN-SUFFIX,travian.de,Proxy\nDOMAIN-SUFFIX,wordpress.com,Proxy\nDOMAIN-SUFFIX,hxwk.org,Proxy\nDOMAIN-SUFFIX,2092866.com,Proxy\nDOMAIN-SUFFIX,mmmoffice.com,Proxy\nDOMAIN-SUFFIX,avjoy.me,Proxy\nDOMAIN-SUFFIX,thevivekspot.com,Proxy\nDOMAIN-SUFFIX,koolsolutions.com,Proxy\nDOMAIN-SUFFIX,sa.hao123.com,Proxy\nDOMAIN-SUFFIX,jav.guru,Proxy\nDOMAIN-SUFFIX,pavesdeluxe.com,Proxy\nDOMAIN-SUFFIX,imagepower.com,Proxy\nDOMAIN-SUFFIX,wiki.komica.org,Proxy\nDOMAIN-SUFFIX,truthortrust.com,Proxy\nDOMAIN-SUFFIX,skybet.com,Proxy\nDOMAIN-SUFFIX,echofon.com,Proxy\nDOMAIN-SUFFIX,viv.id.lv,Proxy\nDOMAIN-SUFFIX,www.pure18.com,Proxy\nDOMAIN-SUFFIX,www.printfriendly.com,Proxy\nDOMAIN-SUFFIX,www.fengherili.cc,Proxy\nDOMAIN-SUFFIX,9898777.com,Proxy\nDOMAIN-SUFFIX,www.huangyiyu.com,Proxy\nDOMAIN-SUFFIX,a-normal-day.com,Proxy\nDOMAIN-SUFFIX,aranym.net,Proxy\nDOMAIN-SUFFIX,www.988bt.com,Proxy\nDOMAIN-SUFFIX,www.antiwall.com,Proxy\nDOMAIN-SUFFIX,ocry.com,Proxy\nDOMAIN-SUFFIX,sigen.pro,Proxy\nDOMAIN-SUFFIX,grahamdutton.com,Proxy\nDOMAIN-SUFFIX,chinaaid.org,Proxy\nDOMAIN-SUFFIX,1188650.com,Proxy\nDOMAIN-SUFFIX,app.thebeacon.gg,Proxy\nDOMAIN-SUFFIX,pinterest.dk,Proxy\nDOMAIN-SUFFIX,dhtbhsgrz11qt.cloudfront.net,Proxy\nDOMAIN-SUFFIX,chinaway.org,Proxy\nDOMAIN-SUFFIX,citadel.prophpbb.com,Proxy\nDOMAIN-SUFFIX,www.larganmed.com.tw,Proxy\nDOMAIN-SUFFIX,882110022.com,Proxy\nDOMAIN-SUFFIX,hjc205.com,Proxy\nDOMAIN-SUFFIX,20.120v.ac,Proxy\nDOMAIN-SUFFIX,www.frenchcreek.ca,Proxy\nDOMAIN-SUFFIX,suika-vpn.com,Proxy\nDOMAIN-SUFFIX,4u.vnsce.com,Proxy\nDOMAIN-SUFFIX,www.katestube.com,Proxy\nDOMAIN-SUFFIX,sellclassics.com,Proxy\nDOMAIN-SUFFIX,controld.com,Proxy\nDOMAIN-SUFFIX,porntubenews.com,Proxy\nDOMAIN-SUFFIX,aka-fs721.bsoversea.com,Proxy\nDOMAIN-SUFFIX,www.propertynl.com,Proxy\nDOMAIN-SUFFIX,sandpointehoa.com,Proxy\nDOMAIN-SUFFIX,www.2859x.com,Proxy\nDOMAIN-SUFFIX,sokamonline.com,Proxy\nDOMAIN-SUFFIX,vuze.com,Proxy\nDOMAIN-SUFFIX,www.milepoint.com,Proxy\nDOMAIN-SUFFIX,chuang-yen.org,Proxy\nDOMAIN-SUFFIX,istella.it,Proxy\nDOMAIN-SUFFIX,d2jq89e8bit3j3.cloudfront.net,Proxy\nDOMAIN-SUFFIX,wynn009.com,Proxy\nDOMAIN-SUFFIX,piposay.com,Proxy\nDOMAIN-SUFFIX,twitterkr.com,Proxy\nDOMAIN-SUFFIX,gtflixtv.com,Proxy\nDOMAIN-SUFFIX,kajsacases.com,Proxy\nDOMAIN-SUFFIX,twelvehere.com,Proxy\nDOMAIN-SUFFIX,mycnnews.com,Proxy\nDOMAIN-SUFFIX,www.hustvpn.com,Proxy\nDOMAIN-SUFFIX,www.ustream.tv,Proxy\nDOMAIN-SUFFIX,design.jobbole.com,Proxy\nDOMAIN-SUFFIX,tsai1993.github.io,Proxy\nDOMAIN-SUFFIX,sip.mx,Proxy\nDOMAIN-SUFFIX,kk.bd.to,Proxy\nDOMAIN-SUFFIX,18h.animezilla.com,Proxy\nDOMAIN-SUFFIX,fun127.com,Proxy\nDOMAIN-SUFFIX,gigporno.ru,Proxy\nDOMAIN-SUFFIX,j-cast.com,Proxy\nDOMAIN-SUFFIX,www.theuselessweb.com,Proxy\nDOMAIN-SUFFIX,7822y.com,Proxy\nDOMAIN-SUFFIX,arkadiem.co.uk,Proxy\nDOMAIN-SUFFIX,faluninfo.at,Proxy\nDOMAIN-SUFFIX,submityourflicks.com,Proxy\nDOMAIN-SUFFIX,userproxy.com,Proxy\nDOMAIN-SUFFIX,www.isnao.com,Proxy\nDOMAIN-SUFFIX,voazimbabwe.com,Proxy\nDOMAIN-SUFFIX,dy9991.com,Proxy\nDOMAIN-SUFFIX,china-digital-times.github.io,Proxy\nDOMAIN-SUFFIX,netsjoes.com.br,Proxy\nDOMAIN-SUFFIX,spinejs.com,Proxy\nDOMAIN-SUFFIX,news.sky.com,Proxy\nDOMAIN-SUFFIX,094233.com,Proxy\nDOMAIN-SUFFIX,global.udn.com,Proxy\nDOMAIN-SUFFIX,hic.3d-game.com,Proxy\nDOMAIN-SUFFIX,openallweb.com,Proxy\nDOMAIN-SUFFIX,www.cahr.org.tw,Proxy\nDOMAIN-SUFFIX,ftvin.com,Proxy\nDOMAIN-SUFFIX,oyghan.com,Proxy\nDOMAIN-SUFFIX,jojos.tw,Proxy\nDOMAIN-SUFFIX,yslang.com,Proxy\nDOMAIN-SUFFIX,horlicks.co.uk,Proxy\nDOMAIN-SUFFIX,attorz.com,Proxy\nDOMAIN-SUFFIX,www.thinkstockphotos.co.uk,Proxy\nDOMAIN-SUFFIX,milph.net,Proxy\nDOMAIN-SUFFIX,mimivip.com,Proxy\nDOMAIN-SUFFIX,yogichen.org,Proxy\nDOMAIN-SUFFIX,paldengyal.com,Proxy\nDOMAIN-SUFFIX,scoken.com,Proxy\nDOMAIN-SUFFIX,www.panoramio.com,Proxy\nDOMAIN-SUFFIX,iblist.com,Proxy\nDOMAIN-SUFFIX,watchersweb.com,Proxy\nDOMAIN-SUFFIX,freedomsherald.org,Proxy\nDOMAIN-SUFFIX,www.optimalmrm.com,Proxy\nDOMAIN-SUFFIX,thebestvpn.com,Proxy\nDOMAIN-SUFFIX,freedomhouse.org,Proxy\nDOMAIN-SUFFIX,gayfuckporn.com,Proxy\nDOMAIN-SUFFIX,mm-cg.com,Proxy\nDOMAIN-SUFFIX,chinapost.com.tw,Proxy\nDOMAIN-SUFFIX,oneworldgaming.com,Proxy\nDOMAIN-SUFFIX,www.idepa.com,Proxy\nDOMAIN-SUFFIX,www.howbbs.com,Proxy\nDOMAIN-SUFFIX,www.tpuser.idv.tw,Proxy\nDOMAIN-SUFFIX,astrill.com,Proxy\nDOMAIN-SUFFIX,zengjinyan.org,Proxy\nDOMAIN-SUFFIX,vip.zz903.com,Proxy\nDOMAIN-SUFFIX,china-files.com,Proxy\nDOMAIN-SUFFIX,comparison.com.au,Proxy\nDOMAIN-SUFFIX,surfeasy.com.au,Proxy\nDOMAIN-SUFFIX,casino.com,Proxy\nDOMAIN-SUFFIX,bbc6.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,filmyoutube.com,Proxy\nDOMAIN-SUFFIX,s.wxga.us,Proxy\nDOMAIN-SUFFIX,voxer.com,Proxy\nDOMAIN-SUFFIX,dm3a8dsjmaqu2.cloudfront.net,Proxy\nDOMAIN-SUFFIX,tibet-drustvo.si,Proxy\nDOMAIN-SUFFIX,www.broadbean.com,Proxy\nDOMAIN-SUFFIX,gendergear.ca,Proxy\nDOMAIN-SUFFIX,endccp.com,Proxy\nDOMAIN-SUFFIX,ggjav.com,Proxy\nDOMAIN-SUFFIX,bianlei.com,Proxy\nDOMAIN-SUFFIX,tvmost.com.hk,Proxy\nDOMAIN-SUFFIX,techinternets.com,Proxy\nDOMAIN-SUFFIX,www.0528899.com,Proxy\nDOMAIN-SUFFIX,chinese-leaders.org,Proxy\nDOMAIN-SUFFIX,censorship.com,Proxy\nDOMAIN-SUFFIX,unstable.icu,Proxy\nDOMAIN-SUFFIX,apat1989.org,Proxy\nDOMAIN-SUFFIX,libgen.rs,Proxy\nDOMAIN-SUFFIX,btku.org,Proxy\nDOMAIN-SUFFIX,leisurecafe.ca,Proxy\nDOMAIN-SUFFIX,chinamediaproject.org,Proxy\nDOMAIN-SUFFIX,chenghuavideo.asia,Proxy\nDOMAIN-SUFFIX,www.zhaoav8.co,Proxy\nDOMAIN-SUFFIX,xskywalker.net,Proxy\nDOMAIN-SUFFIX,aisexbbs.com,Proxy\nDOMAIN-SUFFIX,airbrake.io,Proxy\nDOMAIN-SUFFIX,meyou.jp,Proxy\nDOMAIN-SUFFIX,democraticsocialism.noblogs.org,Proxy\nDOMAIN-SUFFIX,freetribe.me,Proxy\nDOMAIN-SUFFIX,wiki22.tk,Proxy\nDOMAIN-SUFFIX,ahoeab.org,Proxy\nDOMAIN-SUFFIX,deutschetibethilfe.de,Proxy\nDOMAIN-SUFFIX,truveo.com,Proxy\nDOMAIN-SUFFIX,adnmb2.com,Proxy\nDOMAIN-SUFFIX,www.chinataiwan.org,Proxy\nDOMAIN-SUFFIX,facebook.de,Proxy\nDOMAIN-SUFFIX,www.quanser.com,Proxy\nDOMAIN-SUFFIX,kinnman.000webhostapp.com,Proxy\nDOMAIN-SUFFIX,keet.p2pdown.net,Proxy\nDOMAIN-SUFFIX,mypornstation.com,Proxy\nDOMAIN-SUFFIX,ip.travisborovatz.com,Proxy\nDOMAIN-SUFFIX,bannedthought.net,Proxy\nDOMAIN-SUFFIX,www.sir.com.tw,Proxy\nDOMAIN-SUFFIX,rc.vc,Proxy\nDOMAIN-SUFFIX,wango.org,Proxy\nDOMAIN-SUFFIX,stonehold.se,Proxy\nDOMAIN-SUFFIX,discord.app,Proxy\nDOMAIN-SUFFIX,poow.ga,Proxy\nDOMAIN-SUFFIX,whoresinpublic.com,Proxy\nDOMAIN-SUFFIX,jb5678.com,Proxy\nDOMAIN-SUFFIX,google.in,Proxy\nDOMAIN-SUFFIX,google.ws,Proxy\nDOMAIN-SUFFIX,amrc.org.hk,Proxy\nDOMAIN-SUFFIX,sharpdaily.hk,Proxy\nDOMAIN-SUFFIX,tps.bus.flnet.org,Proxy\nDOMAIN-SUFFIX,fangong.org,Proxy\nDOMAIN-SUFFIX,k3.cao669k.com,Proxy\nDOMAIN-SUFFIX,kirin-lin.idv.tw,Proxy\nDOMAIN-SUFFIX,heartfirst.com,Proxy\nDOMAIN-SUFFIX,gfw.press,Proxy\nDOMAIN-SUFFIX,a9w.dyndns.work,Proxy\nDOMAIN-SUFFIX,democracy.com,Proxy\nDOMAIN-SUFFIX,app.tutanota.com,Proxy\nDOMAIN-SUFFIX,abs.edu,Proxy\nDOMAIN-SUFFIX,torrentav.net,Proxy\nDOMAIN-SUFFIX,www.aswetalk.net,Proxy\nDOMAIN-SUFFIX,gt-tidning.se,Proxy\nDOMAIN-SUFFIX,wmcloud.org,Proxy\nDOMAIN-SUFFIX,51cg1.com,Proxy\nDOMAIN-SUFFIX,kanliao.one,Proxy\nDOMAIN-SUFFIX,www.lasprovincias.es,Proxy\nDOMAIN-SUFFIX,recoveryversion.com.tw,Proxy\nDOMAIN-SUFFIX,craiyon.com,Proxy\nDOMAIN-SUFFIX,followme.com,Proxy\nDOMAIN-SUFFIX,www.9997.com,Proxy\nDOMAIN-SUFFIX,76.effers.com,Proxy\nDOMAIN-SUFFIX,pianopiano.pt,Proxy\nDOMAIN-SUFFIX,podcast.ru,Proxy\nDOMAIN-SUFFIX,fyt225.com,Proxy\nDOMAIN-SUFFIX,xfs8.cc,Proxy\nDOMAIN-SUFFIX,d1fctm4x4lk1e2.cloudfront.net,Proxy\nDOMAIN-SUFFIX,laborinfocn3.com,Proxy\nDOMAIN-SUFFIX,d9677.com,Proxy\nDOMAIN-SUFFIX,google.mn,Proxy\nDOMAIN-SUFFIX,is-a-candidate.org,Proxy\nDOMAIN-SUFFIX,www.wardchurch.com,Proxy\nDOMAIN-SUFFIX,www.hwadzan.tw,Proxy\nDOMAIN-SUFFIX,c5.etowns.net,Proxy\nDOMAIN-SUFFIX,gay1069.cf,Proxy\nDOMAIN-SUFFIX,bk.tw.lvfukeji.com,Proxy\nDOMAIN-SUFFIX,thisorthatedition.com,Proxy\nDOMAIN-SUFFIX,60702.com,Proxy\nDOMAIN-SUFFIX,idaydre.am,Proxy\nDOMAIN-SUFFIX,244kk.com,Proxy\nDOMAIN-SUFFIX,900byb.com,Proxy\nDOMAIN-SUFFIX,bennyp.net,Proxy\nDOMAIN-SUFFIX,etokki.com,Proxy\nDOMAIN-SUFFIX,youjizzlive.com,Proxy\nDOMAIN-SUFFIX,bangxporn.com,Proxy\nDOMAIN-SUFFIX,blogspot.fr,Proxy\nDOMAIN-SUFFIX,okfun.org,Proxy\nDOMAIN-SUFFIX,loginyoutube.com,Proxy\nDOMAIN-SUFFIX,exodus.com,Proxy\nDOMAIN-SUFFIX,bw.com,Proxy\nDOMAIN-SUFFIX,inspecturgadget.net,Proxy\nDOMAIN-SUFFIX,parkerwise.com,Proxy\nDOMAIN-SUFFIX,plastichk.blogspot.hk,Proxy\nDOMAIN-SUFFIX,putalocura.com,Proxy\nDOMAIN-SUFFIX,padmanet.com,Proxy\nDOMAIN-SUFFIX,ingtv.xyz,Proxy\nDOMAIN-SUFFIX,lt122.com,Proxy\nDOMAIN-SUFFIX,gwtproject.org,Proxy\nDOMAIN-SUFFIX,www.a4v5.com,Proxy\nDOMAIN-SUFFIX,cna.com.tw,Proxy\nDOMAIN-SUFFIX,www.6396g.com,Proxy\nDOMAIN-SUFFIX,m.670038.com,Proxy\nDOMAIN-SUFFIX,truth101.co.tv,Proxy\nDOMAIN-SUFFIX,newsancai.com,Proxy\nDOMAIN-SUFFIX,www.qianxiuge.com,Proxy\nDOMAIN-SUFFIX,d.u6p.co,Proxy\nDOMAIN-SUFFIX,www.healthymultiplicity.com,Proxy\nDOMAIN-SUFFIX,1188651.com,Proxy\nDOMAIN-SUFFIX,bbs.9shenmi.com,Proxy\nDOMAIN-SUFFIX,yesmryang.net,Proxy\nDOMAIN-SUFFIX,ra5312.com,Proxy\nDOMAIN-SUFFIX,file.talktoday.net,Proxy\nDOMAIN-SUFFIX,rif1.lflink.com,Proxy\nDOMAIN-SUFFIX,clickjogos.uol.com.br,Proxy\nDOMAIN-SUFFIX,reimu.net,Proxy\nDOMAIN-SUFFIX,freejav.org,Proxy\nDOMAIN-SUFFIX,epa.gov.tw,Proxy\nDOMAIN-SUFFIX,songjianjun.com,Proxy\nDOMAIN-SUFFIX,tour.evanotty.com,Proxy\nDOMAIN-SUFFIX,cyberchango.tk,Proxy\nDOMAIN-SUFFIX,kozmoz.box.com,Proxy\nDOMAIN-SUFFIX,xh0018.com,Proxy\nDOMAIN-SUFFIX,emotionjam.com,Proxy\nDOMAIN-SUFFIX,nationalinterest.org,Proxy\nDOMAIN-SUFFIX,pp.greensolutions.ro,Proxy\nDOMAIN-SUFFIX,www.moneydj.com,Proxy\nDOMAIN-SUFFIX,secrets7days.com,Proxy\nDOMAIN-SUFFIX,upwill.org,Proxy\nDOMAIN-SUFFIX,kouji6309.idv.tw,Proxy\nDOMAIN-SUFFIX,jm-comic3.org,Proxy\nDOMAIN-SUFFIX,112233.ch,Proxy\nDOMAIN-SUFFIX,eldastyle.it,Proxy\nDOMAIN-SUFFIX,zzx.healthcom.xyz,Proxy\nDOMAIN-SUFFIX,www.onepointcommerce.com,Proxy\nDOMAIN-SUFFIX,vpninja.net,Proxy\nDOMAIN-SUFFIX,nhentai.xxx,Proxy\nDOMAIN-SUFFIX,officialkarmenkarma.com,Proxy\nDOMAIN-SUFFIX,hentai-porn.net,Proxy\nDOMAIN-SUFFIX,chen-lin.idv.tw,Proxy\nDOMAIN-SUFFIX,domainzomg.com,Proxy\nDOMAIN-SUFFIX,benguldan.net,Proxy\nDOMAIN-SUFFIX,buyu358.com,Proxy\nDOMAIN-SUFFIX,www.1000hands.idv.tw,Proxy\nDOMAIN-SUFFIX,unapec.instructure.com,Proxy\nDOMAIN-SUFFIX,www.ishadowsocks.org,Proxy\nDOMAIN-SUFFIX,52huxian.com,Proxy\nDOMAIN-SUFFIX,newadvent.org,Proxy\nDOMAIN-SUFFIX,bakerpr.com.au,Proxy\nDOMAIN-SUFFIX,www.kobe-np.co.jp,Proxy\nDOMAIN-SUFFIX,ca983.com,Proxy\nDOMAIN-SUFFIX,www.jbo98.com,Proxy\nDOMAIN-SUFFIX,gdzf.org,Proxy\nDOMAIN-SUFFIX,www.focus.de,Proxy\nDOMAIN-SUFFIX,www.327hk.com,Proxy\nDOMAIN-SUFFIX,worldview.stratfor.com,Proxy\nDOMAIN-SUFFIX,jbizz.biz,Proxy\nDOMAIN-SUFFIX,av2books.com,Proxy\nDOMAIN-SUFFIX,blog.iset.com.tw,Proxy\nDOMAIN-SUFFIX,bestmalevideos.com,Proxy\nDOMAIN-SUFFIX,hypothes.is,Proxy\nDOMAIN-SUFFIX,www.bb-in.cc,Proxy\nDOMAIN-SUFFIX,www.red-dragonrising.com,Proxy\nDOMAIN-SUFFIX,cdn4.i-scmp.com,Proxy\nDOMAIN-SUFFIX,b99655.com,Proxy\nDOMAIN-SUFFIX,livecoin.net,Proxy\nDOMAIN-SUFFIX,xxxfk.com,Proxy\nDOMAIN-SUFFIX,kum.com,Proxy\nDOMAIN-SUFFIX,www.000aa.com,Proxy\nDOMAIN-SUFFIX,90011.vip,Proxy\nDOMAIN-SUFFIX,jamestown.org,Proxy\nDOMAIN-SUFFIX,www.pkuhollow.com,Proxy\nDOMAIN-SUFFIX,www.orgs.one,Proxy\nDOMAIN-SUFFIX,njactb.org,Proxy\nDOMAIN-SUFFIX,65.my03.com,Proxy\nDOMAIN-SUFFIX,www.slot.it,Proxy\nDOMAIN-SUFFIX,boycc.top,Proxy\nDOMAIN-SUFFIX,www.ewant.org,Proxy\nDOMAIN-SUFFIX,steamgames.com,Proxy\nDOMAIN-SUFFIX,7874vip.com,Proxy\nDOMAIN-SUFFIX,watchjavonline.com,Proxy\nDOMAIN-SUFFIX,www.storetorrent.org,Proxy\nDOMAIN-SUFFIX,tanc.org,Proxy\nDOMAIN-SUFFIX,ladiprevet.com.ar,Proxy\nDOMAIN-SUFFIX,doh-fi.blahdns.com,Proxy\nDOMAIN-SUFFIX,www.ain-es.org,Proxy\nDOMAIN-SUFFIX,mvlike.tv,Proxy\nDOMAIN-SUFFIX,spotify.com,Proxy\nDOMAIN-SUFFIX,d.hdd2.host,Proxy\nDOMAIN-SUFFIX,camfrog.com,Proxy\nDOMAIN-SUFFIX,d2jrsb65jaeeog.cloudfront.net,Proxy\nDOMAIN-SUFFIX,sch-design.com.ar,Proxy\nDOMAIN-SUFFIX,www.realclearprivacy.biz,Proxy\nDOMAIN-SUFFIX,sfu.ca,Proxy\nDOMAIN-SUFFIX,sohobroadway.org,Proxy\nDOMAIN-SUFFIX,www.bittorrent.com,Proxy\nDOMAIN-SUFFIX,188service.com,Proxy\nDOMAIN-SUFFIX,uyghurensemble.co.uk,Proxy\nDOMAIN-SUFFIX,plus28.com,Proxy\nDOMAIN-SUFFIX,sonidodelaesperanza.org,Proxy\nDOMAIN-SUFFIX,cambiumnetworks.com,Proxy\nDOMAIN-SUFFIX,889ut.com,Proxy\nDOMAIN-SUFFIX,gbtv.com,Proxy\nDOMAIN-SUFFIX,ppyq1.com,Proxy\nDOMAIN-SUFFIX,d1m0a5s9pgearu.cloudfront.net,Proxy\nDOMAIN-SUFFIX,ecoinbroker.com,Proxy\nDOMAIN-SUFFIX,www.voakorea.com,Proxy\nDOMAIN-SUFFIX,maruta.be,Proxy\nDOMAIN-SUFFIX,duckduckgo.org,Proxy\nDOMAIN-SUFFIX,www.adl.org,Proxy\nDOMAIN-SUFFIX,av789gg.com,Proxy\nDOMAIN-SUFFIX,fuli.us,Proxy\nDOMAIN-SUFFIX,sitetag.us,Proxy\nDOMAIN-SUFFIX,www.tubefairs.com,Proxy\nDOMAIN-SUFFIX,www.7x24hrs.com,Proxy\nDOMAIN-SUFFIX,spark.adobe.com,Proxy\nDOMAIN-SUFFIX,ku17.net,Proxy\nDOMAIN-SUFFIX,www.bcw7777.com,Proxy\nDOMAIN-SUFFIX,www.deluxe-tech.com,Proxy\nDOMAIN-SUFFIX,canalisystem.biz,Proxy\nDOMAIN-SUFFIX,globus.de,Proxy\nDOMAIN-SUFFIX,gstf.org,Proxy\nDOMAIN-SUFFIX,api.trajectore.com,Proxy\nDOMAIN-SUFFIX,www.sidraelgaitero.com,Proxy\nDOMAIN-SUFFIX,eurone.ws,Proxy\nDOMAIN-SUFFIX,senfun.net,Proxy\nDOMAIN-SUFFIX,wl19www502.webland.ch,Proxy\nDOMAIN-SUFFIX,www.shopbentley.com,Proxy\nDOMAIN-SUFFIX,sin.cl,Proxy\nDOMAIN-SUFFIX,alanhou.com,Proxy\nDOMAIN-SUFFIX,dailey1.net,Proxy\nDOMAIN-SUFFIX,danbooru.donmai.us,Proxy\nDOMAIN-SUFFIX,www.wsdc332.com,Proxy\nDOMAIN-SUFFIX,falundafa.fr,Proxy\nDOMAIN-SUFFIX,00899j.com,Proxy\nDOMAIN-SUFFIX,bravotube.net,Proxy\nDOMAIN-SUFFIX,connect.3ds.com,Proxy\nDOMAIN-SUFFIX,qantas.com.au,Proxy\nDOMAIN-SUFFIX,stealthy.co,Proxy\nDOMAIN-SUFFIX,www.5604t.com,Proxy\nDOMAIN-SUFFIX,770b3.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,readmyblog.org,Proxy\nDOMAIN-SUFFIX,mindandlife.org,Proxy\nDOMAIN-SUFFIX,hellolynn.hpd.io,Proxy\nDOMAIN-SUFFIX,www.ehime-np.co.jp,Proxy\nDOMAIN-SUFFIX,aj.com,Proxy\nDOMAIN-SUFFIX,www.jgg18.me,Proxy\nDOMAIN-SUFFIX,ibook.idv.tw,Proxy\nDOMAIN-SUFFIX,css.now-ip.net,Proxy\nDOMAIN-SUFFIX,destroy-china.jp,Proxy\nDOMAIN-SUFFIX,protonmail.com,Proxy\nDOMAIN-SUFFIX,b13ky.vip,Proxy\nDOMAIN-SUFFIX,www.talkaboutxinjiang.com,Proxy\nDOMAIN-SUFFIX,ambasadat.net,Proxy\nDOMAIN-SUFFIX,skcp2.com,Proxy\nDOMAIN-SUFFIX,stage64.hk,Proxy\nDOMAIN-SUFFIX,m.lifanacg.com,Proxy\nDOMAIN-SUFFIX,sun4400.com,Proxy\nDOMAIN-SUFFIX,jinpianwang.com,Proxy\nDOMAIN-SUFFIX,pervclips.com,Proxy\nDOMAIN-SUFFIX,www.youlucky.biz,Proxy\nDOMAIN-SUFFIX,wy.domain888.pw,Proxy\nDOMAIN-SUFFIX,315lz.com,Proxy\nDOMAIN-SUFFIX,www.singup.org,Proxy\nDOMAIN-SUFFIX,to-porno.com,Proxy\nDOMAIN-SUFFIX,aspistrategist.org.au,Proxy\nDOMAIN-SUFFIX,google.com.ai,Proxy\nDOMAIN-SUFFIX,www.w88asia.com,Proxy\nDOMAIN-SUFFIX,d-fukyu.com,Proxy\nDOMAIN-SUFFIX,8587k.cc,Proxy\nDOMAIN-SUFFIX,www.hao666777.com,Proxy\nDOMAIN-SUFFIX,tvnet.lv,Proxy\nDOMAIN-SUFFIX,workspace.loyola.edu,Proxy\nDOMAIN-SUFFIX,www.hwadzan.com,Proxy\nDOMAIN-SUFFIX,huinyc.com,Proxy\nDOMAIN-SUFFIX,b93333.com,Proxy\nDOMAIN-SUFFIX,hamas92.blogspot.hk,Proxy\nDOMAIN-SUFFIX,tumblr.com,Proxy\nDOMAIN-SUFFIX,shuipaizi.blogspot.jp,Proxy\nDOMAIN-SUFFIX,jjj626.net,Proxy\nDOMAIN-SUFFIX,btsynckeys.com,Proxy\nDOMAIN-SUFFIX,www.xuehua.us,Proxy\nDOMAIN-SUFFIX,thefreelibrary.com,Proxy\nDOMAIN-SUFFIX,salangane-books.com,Proxy\nDOMAIN-SUFFIX,speakerdeck.com,Proxy\nDOMAIN-SUFFIX,sobees.com,Proxy\nDOMAIN-SUFFIX,www.ct24.cz,Proxy\nDOMAIN-SUFFIX,stboy.net,Proxy\nDOMAIN-SUFFIX,avmoo.net,Proxy\nDOMAIN-SUFFIX,bit.ly,Proxy\nDOMAIN-SUFFIX,bringingtibethome.com,Proxy\nDOMAIN-SUFFIX,api.phantom.avira-vpn.com,Proxy\nDOMAIN-SUFFIX,schedule.ceno.life,Proxy\nDOMAIN-SUFFIX,d3tk7p3j2qouin.cloudfront.net,Proxy\nDOMAIN-SUFFIX,specreport01.jigsy.com,Proxy\nDOMAIN-SUFFIX,a6tk39.com,Proxy\nDOMAIN-SUFFIX,qg222.com,Proxy\nDOMAIN-SUFFIX,w188bet.com,Proxy\nDOMAIN-SUFFIX,softwaredownload.gitbooks.io,Proxy\nDOMAIN-SUFFIX,chinaaction.org,Proxy\nDOMAIN-SUFFIX,zzy.healthsection.xyz,Proxy\nDOMAIN-SUFFIX,apimages.com,Proxy\nDOMAIN-SUFFIX,tiktokv.com,Proxy\nDOMAIN-SUFFIX,tibetanarts.org,Proxy\nDOMAIN-SUFFIX,dw-world.com,Proxy\nDOMAIN-SUFFIX,bbs.jygnet.org,Proxy\nDOMAIN-SUFFIX,www.lighthz.com,Proxy\nDOMAIN-SUFFIX,omgili.com,Proxy\nDOMAIN-SUFFIX,www.ccworld.us,Proxy\nDOMAIN-SUFFIX,islam.about.com,Proxy\nDOMAIN-SUFFIX,linglingfa.com,Proxy\nDOMAIN-SUFFIX,electric.bg,Proxy\nDOMAIN-SUFFIX,jmcomic.city,Proxy\nDOMAIN-SUFFIX,www.sussex.ac.uk,Proxy\nDOMAIN-SUFFIX,duck.co,Proxy\nDOMAIN-SUFFIX,remnote.com,Proxy\nDOMAIN-SUFFIX,2-hand.info,Proxy\nDOMAIN-SUFFIX,numbr.com,Proxy\nDOMAIN-SUFFIX,www.nytchina.com,Proxy\nDOMAIN-SUFFIX,schelley.co,Proxy\nDOMAIN-SUFFIX,www.2dfan.com,Proxy\nDOMAIN-SUFFIX,dadazim.com,Proxy\nDOMAIN-SUFFIX,thaimazda2.com,Proxy\nDOMAIN-SUFFIX,unblockyoutube.com,Proxy\nDOMAIN-SUFFIX,www.3285b.net,Proxy\nDOMAIN-SUFFIX,1.c7799.ws,Proxy\nDOMAIN-SUFFIX,www.appbrain.com,Proxy\nDOMAIN-SUFFIX,kt.we-see2.xyz,Proxy\nDOMAIN-SUFFIX,omny.fm,Proxy\nDOMAIN-SUFFIX,asiareps.cl,Proxy\nDOMAIN-SUFFIX,mingpaonews.com,Proxy\nDOMAIN-SUFFIX,zh.prolewiki.org,Proxy\nDOMAIN-SUFFIX,vip7909.com,Proxy\nDOMAIN-SUFFIX,www.chenrezig.com.au,Proxy\nDOMAIN-SUFFIX,sexbot.com,Proxy\nDOMAIN-SUFFIX,esu.dog,Proxy\nDOMAIN-SUFFIX,www.binance.us,Proxy\nDOMAIN-SUFFIX,18-comic.cc,Proxy\nDOMAIN-SUFFIX,88edn.com,Proxy\nDOMAIN-SUFFIX,xh8701.com,Proxy\nDOMAIN-SUFFIX,7345345.com,Proxy\nDOMAIN-SUFFIX,metropole.nantes.fr,Proxy\nDOMAIN-SUFFIX,sun303.com,Proxy\nDOMAIN-SUFFIX,www.itunes.com,Proxy\nDOMAIN-SUFFIX,c-est-simple.com,Proxy\nDOMAIN-SUFFIX,www.akazienzendo.de,Proxy\nDOMAIN-SUFFIX,sistemamlc.com.ar,Proxy\nDOMAIN-SUFFIX,www.watson.ch,Proxy\nDOMAIN-SUFFIX,hulezone.ir,Proxy\nDOMAIN-SUFFIX,310a.com,Proxy\nDOMAIN-SUFFIX,8278z.com,Proxy\nDOMAIN-SUFFIX,theconservativetreehouse.com,Proxy\nDOMAIN-SUFFIX,bgme.me,Proxy\nDOMAIN-SUFFIX,google.ca,Proxy\nDOMAIN-SUFFIX,ultravpn.fr,Proxy\nDOMAIN-SUFFIX,www.jav468.com,Proxy\nDOMAIN-SUFFIX,serproeventos.cl,Proxy\nDOMAIN-SUFFIX,epig.idv.tw,Proxy\nDOMAIN-SUFFIX,xiaoma.org,Proxy\nDOMAIN-SUFFIX,xiph.org,Proxy\nDOMAIN-SUFFIX,www.aerosoloem.com.tw,Proxy\nDOMAIN-SUFFIX,www.surveyusa.com,Proxy\nDOMAIN-SUFFIX,upload4u.info,Proxy\nDOMAIN-SUFFIX,bjh10.com,Proxy\nDOMAIN-SUFFIX,app.flowkey.com,Proxy\nDOMAIN-SUFFIX,31.podzone.org,Proxy\nDOMAIN-SUFFIX,hotpornshow.com,Proxy\nDOMAIN-SUFFIX,animeflavor.com,Proxy\nDOMAIN-SUFFIX,newsletter.com,Proxy\nDOMAIN-SUFFIX,www.lloydsbank.com,Proxy\nDOMAIN-SUFFIX,2646.com,Proxy\nDOMAIN-SUFFIX,www.623307.com,Proxy\nDOMAIN-SUFFIX,google-analytics.com,Proxy\nDOMAIN-SUFFIX,maa1801.com,Proxy\nDOMAIN-SUFFIX,wnacg.org,Proxy\nDOMAIN-SUFFIX,h.bebc.us,Proxy\nDOMAIN-SUFFIX,aa888.com,Proxy\nDOMAIN-SUFFIX,gumroad.com,Proxy\nDOMAIN-SUFFIX,ytht.net,Proxy\nDOMAIN-SUFFIX,projecth.us,Proxy\nDOMAIN-SUFFIX,myssrhub.com,Proxy\nDOMAIN-SUFFIX,my-formosa.com,Proxy\nDOMAIN-SUFFIX,avatrade.com.tw,Proxy\nDOMAIN-SUFFIX,pu889.com,Proxy\nDOMAIN-SUFFIX,inovtrad.com,Proxy\nDOMAIN-SUFFIX,books.com.tw,Proxy\nDOMAIN-SUFFIX,chancenter.org,Proxy\nDOMAIN-SUFFIX,busymouse.de,Proxy\nDOMAIN-SUFFIX,lansis.com.ar,Proxy\nDOMAIN-SUFFIX,www.bomao.com,Proxy\nDOMAIN-SUFFIX,www.kingbally.com,Proxy\nDOMAIN-SUFFIX,www.videosdemadurasx.com,Proxy\nDOMAIN-SUFFIX,17t17p.com,Proxy\nDOMAIN-SUFFIX,www.radiosunna.com,Proxy\nDOMAIN-SUFFIX,voat.co,Proxy\nDOMAIN-SUFFIX,www.topics.or.jp,Proxy\nDOMAIN-SUFFIX,138111.co,Proxy\nDOMAIN-SUFFIX,anonymous.si,Proxy\nDOMAIN-SUFFIX,tb5959.com,Proxy\nDOMAIN-SUFFIX,xijinping.pusytroller.cf,Proxy\nDOMAIN-SUFFIX,cm04.coaching-baum.de,Proxy\nDOMAIN-SUFFIX,kindgirls.com,Proxy\nDOMAIN-SUFFIX,www.p2585.com,Proxy\nDOMAIN-SUFFIX,incapdns.net,Proxy\nDOMAIN-SUFFIX,jm-comic.art,Proxy\nDOMAIN-SUFFIX,rapidmoviez.com,Proxy\nDOMAIN-SUFFIX,www.pc500.cc,Proxy\nDOMAIN-SUFFIX,yesasia.com.hk,Proxy\nDOMAIN-SUFFIX,ea.twimg.com,Proxy\nDOMAIN-SUFFIX,11711.qgirlmm.com,Proxy\nDOMAIN-SUFFIX,the1room.com,Proxy\nDOMAIN-SUFFIX,webproxy.com.de,Proxy\nDOMAIN-SUFFIX,jeaga.com,Proxy\nDOMAIN-SUFFIX,lightnovel.cn,Proxy\nDOMAIN-SUFFIX,thegay.porn,Proxy\nDOMAIN-SUFFIX,d1i6trxfzvmxc9.cloudfront.net,Proxy\nIP-CIDR,85.17.73.31/32,Proxy\nDOMAIN-SUFFIX,intelligencesquaredus.org,Proxy\nDOMAIN-SUFFIX,synhak.org,Proxy\nDOMAIN-SUFFIX,cup.ddns.us,Proxy\nDOMAIN-SUFFIX,zhikanlouzhu.com,Proxy\nDOMAIN-SUFFIX,dinersclubnorthamerica.com,Proxy\nDOMAIN-SUFFIX,sadistic-v.com,Proxy\nDOMAIN-SUFFIX,creeklandmiddle.org,Proxy\nDOMAIN-SUFFIX,jbex.com,Proxy\nDOMAIN-SUFFIX,tbsseattle.org,Proxy\nDOMAIN-SUFFIX,portalinc.org,Proxy\nDOMAIN-SUFFIX,pigcha.com,Proxy\nDOMAIN-SUFFIX,fc.maa1828.com,Proxy\nDOMAIN-SUFFIX,google.az,Proxy\nDOMAIN-SUFFIX,io.airforce1.cyou,Proxy\nDOMAIN-SUFFIX,alasbarricadas.org,Proxy\nDOMAIN-SUFFIX,dfp6ofk9ssz35.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.ebookservice.tw,Proxy\nDOMAIN-SUFFIX,talkcc.com,Proxy\nDOMAIN-SUFFIX,jgoodies.com,Proxy\nDOMAIN-SUFFIX,www.gay.com,Proxy\nDOMAIN-SUFFIX,download.windowsupdate.nsatc.net,Proxy\nDOMAIN-SUFFIX,php5.ml,Proxy\nDOMAIN-SUFFIX,www.bgeneral.com,Proxy\nDOMAIN-SUFFIX,book4you.org,Proxy\nDOMAIN-SUFFIX,emu486.net,Proxy\nDOMAIN-SUFFIX,d1ul2gmffx4xs7.cloudfront.net,Proxy\nDOMAIN-SUFFIX,prosiben.de,Proxy\nDOMAIN-SUFFIX,wartowall.openwebster.com,Proxy\nDOMAIN-SUFFIX,intel.com,Proxy\nDOMAIN-SUFFIX,bigbreastarchive.com,Proxy\nDOMAIN-SUFFIX,ksdl.org,Proxy\nDOMAIN-SUFFIX,tibethaus.com,Proxy\nDOMAIN-SUFFIX,webhop.biz,Proxy\nDOMAIN-SUFFIX,myreadingmanga.info,Proxy\nDOMAIN-SUFFIX,www.libertyvpn.net,Proxy\nDOMAIN-SUFFIX,joachims.org,Proxy\nDOMAIN-SUFFIX,workerempowerment.org,Proxy\nDOMAIN-SUFFIX,www.chesterstandard.co.uk,Proxy\nDOMAIN-SUFFIX,www.gowanbo.cc,Proxy\nDOMAIN-SUFFIX,rnzi.com,Proxy\nDOMAIN-SUFFIX,whichmba.com,Proxy\nDOMAIN-SUFFIX,yin017.com,Proxy\nDOMAIN-SUFFIX,wenxuecity.com,Proxy\nDOMAIN-SUFFIX,bcw888.net,Proxy\nDOMAIN-SUFFIX,nikkei.com,Proxy\nDOMAIN-SUFFIX,netcolony.com,Proxy\nDOMAIN-SUFFIX,tonyskansascity.com,Proxy\nDOMAIN-SUFFIX,24.now-ip.net,Proxy\nDOMAIN-SUFFIX,handcraftedsoftware.org,Proxy\nDOMAIN-SUFFIX,network-consulting.ro,Proxy\nDOMAIN-SUFFIX,www.freeinchina.org,Proxy\nDOMAIN-SUFFIX,www.26yd.net,Proxy\nDOMAIN-SUFFIX,fu2.club,Proxy\nDOMAIN-SUFFIX,jizzthis.com,Proxy\nDOMAIN-SUFFIX,www.afrsmartinvestor.com.au,Proxy\nDOMAIN-SUFFIX,www.hx-ss.cc,Proxy\nDOMAIN-SUFFIX,bluemonkeyfish.com,Proxy\nDOMAIN-SUFFIX,brill.com,Proxy\nDOMAIN-SUFFIX,freetibet.net,Proxy\nDOMAIN-SUFFIX,thechinacollection.org,Proxy\nDOMAIN-SUFFIX,www.r18.com,Proxy\nDOMAIN-SUFFIX,nitter.pussthecat.org,Proxy\nDOMAIN-SUFFIX,www.fxcm.co.uk,Proxy\nDOMAIN-SUFFIX,porn-wanted.com,Proxy\nDOMAIN-SUFFIX,www.grid.news,Proxy\nDOMAIN-SUFFIX,justpilih.com,Proxy\nDOMAIN-SUFFIX,015001.com,Proxy\nDOMAIN-SUFFIX,protocol.ai,Proxy\nDOMAIN-SUFFIX,www.ohmyrss.com,Proxy\nDOMAIN-SUFFIX,helloavgirls.com,Proxy\nDOMAIN-SUFFIX,oblongseller.com,Proxy\nDOMAIN-SUFFIX,english.aljazeera.net,Proxy\nDOMAIN-SUFFIX,www.fhglobalcn.com,Proxy\nDOMAIN-SUFFIX,dnsrd.com,Proxy\nDOMAIN-SUFFIX,nuuvem.com,Proxy\nDOMAIN-SUFFIX,whyyoutube.com,Proxy\nDOMAIN-SUFFIX,www.blogo.it,Proxy\nDOMAIN-SUFFIX,a3285.com,Proxy\nDOMAIN-SUFFIX,gratismusica.org,Proxy\nDOMAIN-SUFFIX,www.szzd.org,Proxy\nDOMAIN-SUFFIX,akb38.com,Proxy\nDOMAIN-SUFFIX,www.kv.com.ua,Proxy\nDOMAIN-SUFFIX,taiwanyes.com,Proxy\nDOMAIN-SUFFIX,www.rfa.com,Proxy\nDOMAIN-SUFFIX,wikipdia.org,Proxy\nDOMAIN-SUFFIX,91sp.v3p.co,Proxy\nDOMAIN-SUFFIX,faz.de,Proxy\nDOMAIN-SUFFIX,hocphapluancong.com,Proxy\nDOMAIN-SUFFIX,www.hhcomic.com,Proxy\nDOMAIN-SUFFIX,d5539.com,Proxy\nDOMAIN-SUFFIX,hallandsposten.se,Proxy\nDOMAIN-SUFFIX,www.mimissr.net,Proxy\nDOMAIN-SUFFIX,vikiporn.com,Proxy\nDOMAIN-SUFFIX,bognmb.com,Proxy\nDOMAIN-SUFFIX,honeonet.spaces.live.com,Proxy\nDOMAIN-SUFFIX,speedmm.com,Proxy\nDOMAIN-SUFFIX,material-theme-builder.glitch.me,Proxy\nDOMAIN-SUFFIX,sax2.lflink.com,Proxy\nDOMAIN-SUFFIX,www.asian-food.com.tw,Proxy\nDOMAIN-SUFFIX,www.dele88.com,Proxy\nDOMAIN-SUFFIX,www.heavy-r.com,Proxy\nDOMAIN-SUFFIX,hkgolden.com,Proxy\nDOMAIN-SUFFIX,antpool.com,Proxy\nDOMAIN-SUFFIX,letelegramme.com,Proxy\nDOMAIN-SUFFIX,h.42tv.pw,Proxy\nDOMAIN-SUFFIX,n3sr.gl.grr.io,Proxy\nDOMAIN-SUFFIX,jumbo-window.com,Proxy\nDOMAIN-SUFFIX,www.designwant.com,Proxy\nDOMAIN-SUFFIX,51cg.fun,Proxy\nDOMAIN-SUFFIX,herokuapp.com,Proxy\nDOMAIN-SUFFIX,www.anpopo.com,Proxy\nDOMAIN-SUFFIX,www.kylegomes.com,Proxy\nDOMAIN-SUFFIX,www.huobi.br.com,Proxy\nDOMAIN-SUFFIX,esbline.site,Proxy\nDOMAIN-SUFFIX,youtube.ru,Proxy\nDOMAIN-SUFFIX,www.collingibson.com,Proxy\nDOMAIN-SUFFIX,www.bestgift.tv,Proxy\nDOMAIN-SUFFIX,coolery.com,Proxy\nDOMAIN-SUFFIX,icaqd.com,Proxy\nDOMAIN-SUFFIX,erma.zyxel.com,Proxy\nDOMAIN-SUFFIX,xcritic.com,Proxy\nDOMAIN-SUFFIX,dippindots.com.au,Proxy\nDOMAIN-SUFFIX,css.pixnet.in,Proxy\nDOMAIN-SUFFIX,linco.cl,Proxy\nDOMAIN-SUFFIX,clapaftis.com,Proxy\nDOMAIN-SUFFIX,dp02chdsg9x39.cloudfront.net,Proxy\nDOMAIN-SUFFIX,gs326.com,Proxy\nDOMAIN-SUFFIX,voy.com,Proxy\nDOMAIN-SUFFIX,cua.edu,Proxy\nDOMAIN-SUFFIX,d2yqt7czk9pifv.cloudfront.net,Proxy\nDOMAIN-SUFFIX,adad09.com,Proxy\nDOMAIN-SUFFIX,www.theglobeandmail.com,Proxy\nDOMAIN-SUFFIX,hmv.co.jp,Proxy\nDOMAIN-SUFFIX,cm365.club,Proxy\nDOMAIN-SUFFIX,dns.rotunneling.net,Proxy\nDOMAIN-SUFFIX,mrcat88.com,Proxy\nDOMAIN-SUFFIX,wsdc220.com,Proxy\nDOMAIN-SUFFIX,www.iwank.tv,Proxy\nDOMAIN-SUFFIX,www.totemarketing.com,Proxy\nDOMAIN-SUFFIX,www.xiankaba.club,Proxy\nDOMAIN-SUFFIX,chinacivilrights.org,Proxy\nDOMAIN-SUFFIX,d34u7pm9nz1rel.cloudfront.net,Proxy\nDOMAIN-SUFFIX,roigpremium.com,Proxy\nDOMAIN-SUFFIX,rapidgator.net,Proxy\nDOMAIN-SUFFIX,xvideos.com.es,Proxy\nDOMAIN-SUFFIX,www.wikipedia.co.uk,Proxy\nDOMAIN-SUFFIX,www.aip.idv.tw,Proxy\nDOMAIN-SUFFIX,perderpeso.pt,Proxy\nDOMAIN-SUFFIX,twatc.net,Proxy\nDOMAIN-SUFFIX,janoffs.com,Proxy\nDOMAIN-SUFFIX,dl-mail.ymail.com,Proxy\nDOMAIN-SUFFIX,rdrtech.com,Proxy\nDOMAIN-SUFFIX,weather.com.cn,Proxy\nDOMAIN-SUFFIX,yanghengjun.com,Proxy\nDOMAIN-SUFFIX,pinterest.ru,Proxy\nDOMAIN-SUFFIX,enzkin.org,Proxy\nDOMAIN-SUFFIX,mangareader.com,Proxy\nDOMAIN-SUFFIX,ham.mylab.idv.tw,Proxy\nDOMAIN-SUFFIX,www.pct.org.tw,Proxy\nDOMAIN-SUFFIX,d1hdqacsv5ykad.cloudfront.net,Proxy\nDOMAIN-SUFFIX,ns01.gq,Proxy\nDOMAIN-SUFFIX,www.liberation.com,Proxy\nDOMAIN-SUFFIX,738.authorizeddns.org,Proxy\nDOMAIN-SUFFIX,zbo1.app,Proxy\nDOMAIN-SUFFIX,1501999.com,Proxy\nDOMAIN-SUFFIX,milfhunter.com,Proxy\nDOMAIN-SUFFIX,your-freedom.net,Proxy\nDOMAIN-SUFFIX,bookpop.com,Proxy\nDOMAIN-SUFFIX,hunmagyar.org,Proxy\nDOMAIN-SUFFIX,reuters.de,Proxy\nDOMAIN-SUFFIX,meilizhongguo.biz,Proxy\nDOMAIN-SUFFIX,av.movie,Proxy\nDOMAIN-SUFFIX,chavesasoc.com.ar,Proxy\nDOMAIN-SUFFIX,pttgopolitics.com,Proxy\nDOMAIN-SUFFIX,dkmkksg4qabm2.cloudfront.net,Proxy\nDOMAIN-SUFFIX,nas.kimlulz.dev,Proxy\nDOMAIN-SUFFIX,h5.ld717.cc,Proxy\nDOMAIN-SUFFIX,yam.com,Proxy\nDOMAIN-SUFFIX,google.cm,Proxy\nDOMAIN-SUFFIX,j3.ovpn.im,Proxy\nDOMAIN-SUFFIX,www.torrentkitty.net,Proxy\nDOMAIN-SUFFIX,feichangdao.com,Proxy\nDOMAIN-SUFFIX,hypergames.net,Proxy\nDOMAIN-SUFFIX,barenakedislam.com,Proxy\nDOMAIN-SUFFIX,meridian.sparkes.zone,Proxy\nDOMAIN-SUFFIX,272a.net,Proxy\nDOMAIN-SUFFIX,hookipa.net,Proxy\nDOMAIN-SUFFIX,lfpress.com,Proxy\nDOMAIN-SUFFIX,main.v2ray.cx,Proxy\nDOMAIN-SUFFIX,kqes.net,Proxy\nDOMAIN-SUFFIX,www.seed-city.com,Proxy\nDOMAIN-SUFFIX,018389.com,Proxy\nDOMAIN-SUFFIX,tibetanphotoproject.com,Proxy\nDOMAIN-SUFFIX,18av.cc,Proxy\nDOMAIN-SUFFIX,engineering.carsguide.com.au,Proxy\nDOMAIN-SUFFIX,www.templepourlapaix.org,Proxy\nDOMAIN-SUFFIX,eegay.com,Proxy\nDOMAIN-SUFFIX,is-a-musician.com,Proxy\nDOMAIN-SUFFIX,xxxjapanporn24.com,Proxy\nDOMAIN-SUFFIX,agent-plotio.com,Proxy\nDOMAIN-SUFFIX,www.smartcardmacao.com,Proxy\nDOMAIN-SUFFIX,qubxv.com,Proxy\nDOMAIN-SUFFIX,www.themovs.com,Proxy\nDOMAIN-SUFFIX,afterdark.tw,Proxy\nDOMAIN-SUFFIX,mist.so,Proxy\nDOMAIN-SUFFIX,bccp.com,Proxy\nDOMAIN-SUFFIX,www.chinainstitute.org,Proxy\nDOMAIN-SUFFIX,scicomm.xyz,Proxy\nDOMAIN-SUFFIX,wwwfacebook.com,Proxy\nDOMAIN-SUFFIX,heels2wheels.tv,Proxy\nDOMAIN-SUFFIX,dns.circl.lu,Proxy\nDOMAIN-SUFFIX,www.x8m8tech.net,Proxy\nDOMAIN-SUFFIX,cecc.gov,Proxy\nDOMAIN-SUFFIX,www.weser-kurier.de,Proxy\nDOMAIN-SUFFIX,91cqmm.com,Proxy\nDOMAIN-SUFFIX,japan.cna.com.tw,Proxy\nDOMAIN-SUFFIX,www.hostloc.net,Proxy\nDOMAIN-SUFFIX,www.buddhistdoor.com,Proxy\nDOMAIN-SUFFIX,18comic.vip,Proxy\nDOMAIN-SUFFIX,bucee.net,Proxy\nDOMAIN-SUFFIX,harunyahya.com,Proxy\nDOMAIN-SUFFIX,www.singee.me,Proxy\nDOMAIN-SUFFIX,d2gxp14gfgh0mu.cloudfront.net,Proxy\nDOMAIN-SUFFIX,lupm.org,Proxy\nDOMAIN-SUFFIX,vegaschinaren.com,Proxy\nDOMAIN-SUFFIX,bugcrowd.com,Proxy\nDOMAIN-SUFFIX,szbbs.net,Proxy\nDOMAIN-SUFFIX,dupola.com,Proxy\nDOMAIN-SUFFIX,24zbw.com,Proxy\nDOMAIN-SUFFIX,wnacg.wtf,Proxy\nDOMAIN-SUFFIX,booklive.jp,Proxy\nDOMAIN-SUFFIX,blockedonweibo.com,Proxy\nDOMAIN-SUFFIX,www.blakebush.com,Proxy\nDOMAIN-SUFFIX,id.001www.com,Proxy\nDOMAIN-SUFFIX,www.hispanidad.com,Proxy\nDOMAIN-SUFFIX,voachineseblog.com,Proxy\nDOMAIN-SUFFIX,indsr.org.tw,Proxy\nDOMAIN-SUFFIX,thubtenchodron.org,Proxy\nDOMAIN-SUFFIX,tx9996.com,Proxy\nDOMAIN-SUFFIX,www.niniyeh.com.com,Proxy\nDOMAIN-SUFFIX,joyourself.com,Proxy\nDOMAIN-SUFFIX,reallyboringman.blogspot.jp,Proxy\nDOMAIN-SUFFIX,tensorflow.org,Proxy\nDOMAIN-SUFFIX,library.medaille.edu,Proxy\nDOMAIN-SUFFIX,javdb.com,Proxy\nDOMAIN-SUFFIX,jin321.com,Proxy\nDOMAIN-SUFFIX,www.teamviewer.us,Proxy\nDOMAIN-SUFFIX,mail.vivaldi.net,Proxy\nDOMAIN-SUFFIX,999.860dd.com,Proxy\nDOMAIN-SUFFIX,laintranet.es,Proxy\nDOMAIN-SUFFIX,www.myorz.com,Proxy\nDOMAIN-SUFFIX,ok.ru,Proxy\nDOMAIN-SUFFIX,syncback.com,Proxy\nDOMAIN-SUFFIX,rb887.com,Proxy\nDOMAIN-SUFFIX,www.fun8893.com,Proxy\nDOMAIN-SUFFIX,1949er.org,Proxy\nDOMAIN-SUFFIX,panikal.com,Proxy\nDOMAIN-SUFFIX,enia.net,Proxy\nDOMAIN-SUFFIX,freebrowser.softonic.cn,Proxy\nDOMAIN-SUFFIX,d3paoszdcej0fm.cloudfront.net,Proxy\nDOMAIN-SUFFIX,popularpages.net,Proxy\nDOMAIN-SUFFIX,www.coltstudiogroup.com,Proxy\nDOMAIN-SUFFIX,nos.nl,Proxy\nDOMAIN-SUFFIX,xh72222.com,Proxy\nDOMAIN-SUFFIX,invidious.nerdvpn.de,Proxy\nDOMAIN-SUFFIX,8587m.cc,Proxy\nDOMAIN-SUFFIX,www.qqjlb.com,Proxy\nDOMAIN-SUFFIX,tsio-hai.strikingly.com,Proxy\nDOMAIN-SUFFIX,1125533.net,Proxy\nDOMAIN-SUFFIX,www.xf122.com,Proxy\nDOMAIN-SUFFIX,sub.ssrsub.com,Proxy\nDOMAIN-SUFFIX,ic.etowns.net,Proxy\nDOMAIN-SUFFIX,www.zte.com.cn,Proxy\nDOMAIN-SUFFIX,akune.com.br,Proxy\nDOMAIN-SUFFIX,everycircuit.com,Proxy\nDOMAIN-SUFFIX,www.centralwesterndaily.com.au,Proxy\nDOMAIN-SUFFIX,wh.slyip.net,Proxy\nDOMAIN-SUFFIX,tweetedtimes.com,Proxy\nDOMAIN-SUFFIX,galaxion.net,Proxy\nDOMAIN-SUFFIX,mods.io,Proxy\nDOMAIN-SUFFIX,www.kde.org,Proxy\nDOMAIN-SUFFIX,cdn-images.mailchimp.com,Proxy\nDOMAIN-SUFFIX,web4proxy.com,Proxy\nDOMAIN-SUFFIX,www.xbosoft.com,Proxy\nDOMAIN-SUFFIX,hhthesakyatrizin.org,Proxy\nDOMAIN-SUFFIX,radioaustralia.net.au,Proxy\nDOMAIN-SUFFIX,ch.videosection.com,Proxy\nDOMAIN-SUFFIX,api.tiktokproxy.com,Proxy\nDOMAIN-SUFFIX,lufthansa.de,Proxy\nDOMAIN-SUFFIX,standard-molecules.webnode.tw,Proxy\nDOMAIN-SUFFIX,m.ca951.com,Proxy\nDOMAIN-SUFFIX,ca837.com,Proxy\nDOMAIN-SUFFIX,biubiu999.net,Proxy\nDOMAIN-SUFFIX,falundafa.org.ar,Proxy\nDOMAIN-SUFFIX,blogspot.hk,Proxy\nDOMAIN-SUFFIX,uncontrolledsurfer.com,Proxy\nDOMAIN-SUFFIX,dayaarmongol.ning.com,Proxy\nDOMAIN-SUFFIX,www.kaixin.icu,Proxy\nDOMAIN-SUFFIX,forum.sina.com.hk,Proxy\nDOMAIN-SUFFIX,04647.net,Proxy\nDOMAIN-SUFFIX,tb0500.com,Proxy\nDOMAIN-SUFFIX,ovpn.se,Proxy\nDOMAIN-SUFFIX,009466.com,Proxy\nDOMAIN-SUFFIX,tunnelr.com,Proxy\nDOMAIN-SUFFIX,18comic.site,Proxy\nDOMAIN-SUFFIX,uc-japan.org,Proxy\nDOMAIN-SUFFIX,h2.elf168.net,Proxy\nDOMAIN-SUFFIX,thegioitinhoc.vn,Proxy\nDOMAIN-SUFFIX,d1dov4j460320u.cloudfront.net,Proxy\nDOMAIN-SUFFIX,54647.xyz,Proxy\nDOMAIN-SUFFIX,gooday.xyz,Proxy\nDOMAIN-SUFFIX,www.7171hu.com,Proxy\nDOMAIN-SUFFIX,tyc3334.com,Proxy\nDOMAIN-SUFFIX,ivpn.net,Proxy\nDOMAIN-SUFFIX,72660.com,Proxy\nDOMAIN-SUFFIX,64tianwang.com,Proxy\nDOMAIN-SUFFIX,danu.ro,Proxy\nDOMAIN-SUFFIX,buyu206.com,Proxy\nDOMAIN-SUFFIX,huaren4us.com,Proxy\nDOMAIN-SUFFIX,nfjtyd.com,Proxy\nDOMAIN-SUFFIX,stacloud.seagull.no,Proxy\nDOMAIN-SUFFIX,www.1soccer.com,Proxy\nDOMAIN-SUFFIX,lgmnow.com,Proxy\nDOMAIN-SUFFIX,bbnradio.org,Proxy\nDOMAIN-SUFFIX,rfachina.com,Proxy\nDOMAIN-SUFFIX,www.calu.edu,Proxy\nDOMAIN-SUFFIX,cmule.org,Proxy\nDOMAIN-SUFFIX,lotto.arclink.com.tw,Proxy\nDOMAIN-SUFFIX,gavbus3.com,Proxy\nDOMAIN-SUFFIX,kawase.com,Proxy\nDOMAIN-SUFFIX,lasvegaschinesedailynews.com,Proxy\nDOMAIN-SUFFIX,honx.in,Proxy\nDOMAIN-SUFFIX,ffh.de,Proxy\nDOMAIN-SUFFIX,hc.com,Proxy\nDOMAIN-SUFFIX,www.twwiki.com,Proxy\nDOMAIN-SUFFIX,moo.im,Proxy\nDOMAIN-SUFFIX,ms52.ga,Proxy\nDOMAIN-SUFFIX,smt.live,Proxy\nDOMAIN-SUFFIX,www.gurtong.net,Proxy\nDOMAIN-SUFFIX,mikandi.com,Proxy\nDOMAIN-SUFFIX,dnsget.xyz,Proxy\nDOMAIN-SUFFIX,web.tginfo.me,Proxy\nDOMAIN-SUFFIX,www.cyc.org.tw,Proxy\nDOMAIN-SUFFIX,www.zyzg.us,Proxy\nDOMAIN-SUFFIX,a311452.com,Proxy\nDOMAIN-SUFFIX,lifemiles.com,Proxy\nDOMAIN-SUFFIX,google.co,Proxy\nDOMAIN-SUFFIX,smnz.de,Proxy\nDOMAIN-SUFFIX,bloomberg.de,Proxy\nDOMAIN-SUFFIX,camdough.com,Proxy\nDOMAIN-SUFFIX,ushuarencity.echainhost.com,Proxy\nDOMAIN-SUFFIX,telegraph.co.uk,Proxy\nDOMAIN-SUFFIX,xxxporno.win,Proxy\nDOMAIN-SUFFIX,wf.flnet.org,Proxy\nDOMAIN-SUFFIX,vpnfx.com,Proxy\nDOMAIN-SUFFIX,hakkatv.org.tw,Proxy\nDOMAIN-SUFFIX,www.yc6429.com,Proxy\nDOMAIN-SUFFIX,19260817.ml,Proxy\nDOMAIN-SUFFIX,ag.js77777.com,Proxy\nDOMAIN-SUFFIX,bingfeng.tw,Proxy\nDOMAIN-SUFFIX,gcgc.cc,Proxy\nDOMAIN-SUFFIX,german-webproxy.de,Proxy\nDOMAIN-SUFFIX,alfabank.ru,Proxy\nDOMAIN-SUFFIX,tubepornstars.com,Proxy\nDOMAIN-SUFFIX,vpn.prod.arcticwolf.net,Proxy\nDOMAIN-SUFFIX,setravieso.com,Proxy\nDOMAIN-SUFFIX,taiwan.wtf,Proxy\nDOMAIN-SUFFIX,www.reutersagency.com,Proxy\nDOMAIN-SUFFIX,www.ti9mfk.com,Proxy\nDOMAIN-SUFFIX,wa.dnsmail.xyz,Proxy\nDOMAIN-SUFFIX,n.opnxng.com,Proxy\nDOMAIN-SUFFIX,mangakakalot.com,Proxy\nDOMAIN-SUFFIX,www.acheckglobal.com,Proxy\nDOMAIN-SUFFIX,unblockdmm.com,Proxy\nDOMAIN-SUFFIX,www.18123xz.com,Proxy\nDOMAIN-SUFFIX,mikesoltys.com,Proxy\nDOMAIN-SUFFIX,k4gsl.org,Proxy\nDOMAIN-SUFFIX,thoof.com,Proxy\nDOMAIN-SUFFIX,youtube2mp3.net,Proxy\nDOMAIN-SUFFIX,cn.picacomiccn.com,Proxy\nDOMAIN-SUFFIX,xinshijue.com,Proxy\nDOMAIN-SUFFIX,y-china.org,Proxy\nDOMAIN-SUFFIX,yj.healthonsite.xyz,Proxy\nDOMAIN-SUFFIX,dl.box.net,Proxy\nDOMAIN-SUFFIX,w.yi.wccnw.top,Proxy\nDOMAIN-SUFFIX,healthysites.xyz,Proxy\nDOMAIN-SUFFIX,pezblanco.cl,Proxy\nDOMAIN-SUFFIX,www.queanbeyanage.com.au,Proxy\nDOMAIN-SUFFIX,www.elconfidencial.com,Proxy\nDOMAIN-SUFFIX,www.igmetall.de,Proxy\nDOMAIN-SUFFIX,bunnycdn.com,Proxy\nDOMAIN-SUFFIX,u2bp.com,Proxy\nDOMAIN-SUFFIX,mail.atlanticcouncil.org,Proxy\nDOMAIN-SUFFIX,www.peoplebookcafe.com,Proxy\nDOMAIN-SUFFIX,av6699.com,Proxy\nDOMAIN-SUFFIX,www.m-sport.co.uk,Proxy\nDOMAIN-SUFFIX,www.jaiku.com,Proxy\nDOMAIN-SUFFIX,yjdm.io,Proxy\nDOMAIN-SUFFIX,idouga.com,Proxy\nDOMAIN-SUFFIX,www.essential6.co.uk,Proxy\nDOMAIN-SUFFIX,laqingdan1984.com,Proxy\nDOMAIN-SUFFIX,www.chinesewinnipeg.com,Proxy\nDOMAIN-SUFFIX,www.excelhelp.idv.tw,Proxy\nDOMAIN-SUFFIX,www.9ehao.com,Proxy\nDOMAIN-SUFFIX,d2fstso2jh4dhr.cloudfront.net,Proxy\nDOMAIN-SUFFIX,israaid.co.il,Proxy\nDOMAIN-SUFFIX,onlyblowjob.com,Proxy\nDOMAIN-SUFFIX,hnjhj.com,Proxy\nDOMAIN-SUFFIX,javmobile.net,Proxy\nDOMAIN-SUFFIX,www.befuck.com,Proxy\nDOMAIN-SUFFIX,metronews.ca,Proxy\nDOMAIN-SUFFIX,vlog.xuite.net,Proxy\nDOMAIN-SUFFIX,kobobooks.com,Proxy\nDOMAIN-SUFFIX,www.777pornotube.com,Proxy\nDOMAIN-SUFFIX,circodaparro.be,Proxy\nDOMAIN-SUFFIX,www.providencehk.com,Proxy\nDOMAIN-SUFFIX,zb99666.com,Proxy\nDOMAIN-SUFFIX,sdhts.com,Proxy\nDOMAIN-SUFFIX,moreniche.com,Proxy\nDOMAIN-SUFFIX,attikastudio.com,Proxy\nDOMAIN-SUFFIX,www.ily18.com,Proxy\nDOMAIN-SUFFIX,wallhaven.cc,Proxy\nDOMAIN-SUFFIX,360zbz.com,Proxy\nDOMAIN-SUFFIX,thaicn.com,Proxy\nDOMAIN-SUFFIX,www.internationalpreschoolcurriculum.com,Proxy\nDOMAIN-SUFFIX,ukcdp.co.uk,Proxy\nDOMAIN-SUFFIX,freelancer.com,Proxy\nDOMAIN-SUFFIX,36666022.com,Proxy\nDOMAIN-SUFFIX,myhd1080.com,Proxy\nDOMAIN-SUFFIX,tlamovies.com,Proxy\nDOMAIN-SUFFIX,bezaat.com,Proxy\nDOMAIN-SUFFIX,securitysite.tech,Proxy\nDOMAIN-SUFFIX,proxy.net.in,Proxy\nDOMAIN-SUFFIX,www.55113885.com,Proxy\nDOMAIN-SUFFIX,www.ramakrishnansr.com,Proxy\nDOMAIN-SUFFIX,ecusa.anglican.org,Proxy\nDOMAIN-SUFFIX,toward.fi,Proxy\nDOMAIN-SUFFIX,www.babeasiantube.com,Proxy\nDOMAIN-SUFFIX,1056480.com,Proxy\nDOMAIN-SUFFIX,ydo1.pat.flnet.org,Proxy\nDOMAIN-SUFFIX,g00gle.pw,Proxy\nDOMAIN-SUFFIX,zonaeuropa.com,Proxy\nDOMAIN-SUFFIX,www.qobuz.com,Proxy\nDOMAIN-SUFFIX,broadbook.com,Proxy\nDOMAIN-SUFFIX,www.1cat.xyz,Proxy\nDOMAIN-SUFFIX,www.f88vip115.com,Proxy\nDOMAIN-SUFFIX,43.podzone.org,Proxy\nDOMAIN-SUFFIX,rfienglish.com,Proxy\nDOMAIN-SUFFIX,coronadoplaceandtowers.com,Proxy\nDOMAIN-SUFFIX,weiquanwang.org,Proxy\nDOMAIN-SUFFIX,tdesktop.com,Proxy\nDOMAIN-SUFFIX,nn633.com,Proxy\nDOMAIN-SUFFIX,xcams4u.com,Proxy\nDOMAIN-SUFFIX,us.44.14.iamallama.com,Proxy\nDOMAIN-SUFFIX,cs225.com,Proxy\nDOMAIN-SUFFIX,nexton-net.jp,Proxy\nDOMAIN-SUFFIX,gametrailer.com,Proxy\nDOMAIN-SUFFIX,twyac.org,Proxy\nDOMAIN-SUFFIX,s3.hicloud.net.tw,Proxy\nDOMAIN-SUFFIX,abacusnews.com,Proxy\nDOMAIN-SUFFIX,clubhouse.pubnubapi.com,Proxy\nDOMAIN-SUFFIX,zengjinyan.spaces.live.com,Proxy\nDOMAIN-SUFFIX,thechasernews.co.uk,Proxy\nDOMAIN-SUFFIX,private.com,Proxy\nDOMAIN-SUFFIX,religioustolerance.org,Proxy\nDOMAIN-SUFFIX,casatibet.org.mx,Proxy\nDOMAIN-SUFFIX,www.gay104.com,Proxy\nDOMAIN-SUFFIX,safechat.com,Proxy\nDOMAIN-SUFFIX,www.orwell.live,Proxy\nDOMAIN-SUFFIX,www.thinkingtaiwan.com,Proxy\nDOMAIN-SUFFIX,panoramio.com,Proxy\nDOMAIN-SUFFIX,coinegg.com,Proxy\nDOMAIN-SUFFIX,www.g.cn,Proxy\nDOMAIN-SUFFIX,www.ksnews.com.tw,Proxy\nDOMAIN-SUFFIX,redso.com.hk,Proxy\nDOMAIN-SUFFIX,chuangcn.org,Proxy\nDOMAIN-SUFFIX,cdt.firstory.io,Proxy\nDOMAIN-SUFFIX,google.si,Proxy\nDOMAIN-SUFFIX,app.snapchat.com,Proxy\nDOMAIN-SUFFIX,rsdlmonitor.com,Proxy\nDOMAIN-SUFFIX,chinesedailynews.com,Proxy\nDOMAIN-SUFFIX,www.jbo8822.com,Proxy\nDOMAIN-SUFFIX,777.asiabet11.com,Proxy\nDOMAIN-SUFFIX,tsunagarumon.com,Proxy\nDOMAIN-SUFFIX,www.whitewolf.co.za,Proxy\nDOMAIN-SUFFIX,622564.cc,Proxy\nDOMAIN-SUFFIX,cienen.com,Proxy\nDOMAIN-SUFFIX,t77.usoba.com,Proxy\nDOMAIN-SUFFIX,d2pgxwl4gvz6jg.cloudfront.net,Proxy\nDOMAIN-SUFFIX,officialwindowsmagazine.com,Proxy\nDOMAIN-SUFFIX,webptt.com,Proxy\nDOMAIN-SUFFIX,www.cumshot.com,Proxy\nDOMAIN-SUFFIX,www.centralazsupply.com,Proxy\nDOMAIN-SUFFIX,www.544952.com,Proxy\nDOMAIN-SUFFIX,ccrt.cc,Proxy\nDOMAIN-SUFFIX,zoogvpn.com,Proxy\nDOMAIN-SUFFIX,r18.clickme.net,Proxy\nDOMAIN-SUFFIX,test.domain888.pw,Proxy\nDOMAIN-SUFFIX,galacg.me,Proxy\nDOMAIN-SUFFIX,fanqiangdang.com,Proxy\nDOMAIN-SUFFIX,anonymize.net,Proxy\nDOMAIN-SUFFIX,p0636.com,Proxy\nDOMAIN-SUFFIX,theqingyun.me,Proxy\nDOMAIN-SUFFIX,1ws.pj12.tk,Proxy\nDOMAIN-SUFFIX,tgpcanada.org,Proxy\nDOMAIN-SUFFIX,www.abs.edu.kw,Proxy\nDOMAIN-SUFFIX,88348.net,Proxy\nDOMAIN-SUFFIX,ifjc.org,Proxy\nDOMAIN-SUFFIX,w3.assembly.go.kr,Proxy\nDOMAIN-SUFFIX,cl.eye.rs,Proxy\nDOMAIN-SUFFIX,avcool.com,Proxy\nDOMAIN-SUFFIX,savethesounds.info,Proxy\nDOMAIN-SUFFIX,elnagh.com,Proxy\nDOMAIN-SUFFIX,www.moxa.com,Proxy\nDOMAIN-SUFFIX,www.timeshighereducation.com,Proxy\nDOMAIN-SUFFIX,rod9.cleansite.us,Proxy\nDOMAIN-SUFFIX,hirane.cl,Proxy\nDOMAIN-SUFFIX,narutopixxx.com,Proxy\nDOMAIN-SUFFIX,www.kanglesoft.com,Proxy\nDOMAIN-SUFFIX,jkb.cc,Proxy\nDOMAIN-SUFFIX,16c.com,Proxy\nDOMAIN-SUFFIX,jizzall.com,Proxy\nDOMAIN-SUFFIX,olumpo.com,Proxy\nDOMAIN-SUFFIX,www.google.ma,Proxy\nDOMAIN-SUFFIX,hootsuite.com,Proxy\nDOMAIN-SUFFIX,picacgp.com,Proxy\nDOMAIN-SUFFIX,ch3.uk.to,Proxy\nDOMAIN-SUFFIX,www.forhertube.com,Proxy\nDOMAIN-SUFFIX,www.shaw.ca,Proxy\nDOMAIN-SUFFIX,18comic.art,Proxy\nDOMAIN-SUFFIX,google.co.uk,Proxy\nDOMAIN-SUFFIX,ocreampies.com,Proxy\nDOMAIN-SUFFIX,mywebproxy.net,Proxy\nDOMAIN-SUFFIX,webdao.github.io,Proxy\nDOMAIN-SUFFIX,wqsl.c9rta.com,Proxy\nDOMAIN-SUFFIX,nordjyske.dk,Proxy\nDOMAIN-SUFFIX,englishforeveryone.org,Proxy\nDOMAIN-SUFFIX,nic.gov,Proxy\nDOMAIN-SUFFIX,continuingcounterreformation.blogspot.ca,Proxy\nDOMAIN-SUFFIX,motherboard.vice.com,Proxy\nDOMAIN-SUFFIX,ssatpracticetest.com,Proxy\nDOMAIN-SUFFIX,ca973.com,Proxy\nDOMAIN-SUFFIX,www.ok246.com,Proxy\nDOMAIN-SUFFIX,showhaotu.com,Proxy\nDOMAIN-SUFFIX,www.mt.de,Proxy\nDOMAIN-SUFFIX,9lblhk.jzcmysxx.com,Proxy\nDOMAIN-SUFFIX,megastudy.com,Proxy\nDOMAIN-SUFFIX,www.evangelion.hk,Proxy\nDOMAIN-SUFFIX,drive.netflix.com,Proxy\nDOMAIN-SUFFIX,fl-170-185-1.fri-gate.biz,Proxy\nDOMAIN-SUFFIX,cn.timesofisrael.com,Proxy\nDOMAIN-SUFFIX,tv2.byinter.net,Proxy\nDOMAIN-SUFFIX,nps.gov,Proxy\nDOMAIN-SUFFIX,altvpn.com,Proxy\nDOMAIN-SUFFIX,spn999.com,Proxy\nDOMAIN-SUFFIX,www.volunteertibet.org.in,Proxy\nDOMAIN-SUFFIX,xixicui.icu,Proxy\nDOMAIN-SUFFIX,meinpaket.de,Proxy\nDOMAIN-SUFFIX,vidble.com,Proxy\nDOMAIN-SUFFIX,jhk.one,Proxy\nDOMAIN-SUFFIX,www.rferl.com,Proxy\nDOMAIN-SUFFIX,livingstream.com,Proxy\nDOMAIN-SUFFIX,tumutanzi.com,Proxy\nDOMAIN-SUFFIX,ai.mygpt.bid,Proxy\nDOMAIN-SUFFIX,myfreshnet.com,Proxy\nDOMAIN-SUFFIX,proxyunblocker.org,Proxy\nDOMAIN-SUFFIX,95992222x.com,Proxy\nDOMAIN-SUFFIX,me.ns.ci,Proxy\nDOMAIN-SUFFIX,teensnow.com,Proxy\nDOMAIN-SUFFIX,www.futuhk.com,Proxy\nDOMAIN-SUFFIX,trouw.nl,Proxy\nDOMAIN-SUFFIX,av-5278.com,Proxy\nDOMAIN-SUFFIX,d2l5fbjg2vvdi.cloudfront.net,Proxy\nDOMAIN-SUFFIX,saveyoutube.com,Proxy\nDOMAIN-SUFFIX,1414639.com,Proxy\nDOMAIN-SUFFIX,pixnet.net,Proxy\nDOMAIN-SUFFIX,dafoh.org,Proxy\nDOMAIN-SUFFIX,www.gowfb.ca,Proxy\nDOMAIN-SUFFIX,actionsportsready.absorbtraining.com,Proxy\nDOMAIN-SUFFIX,329.my03.com,Proxy\nDOMAIN-SUFFIX,viu.tv,Proxy\nDOMAIN-SUFFIX,88pt6.com,Proxy\nDOMAIN-SUFFIX,redir.fd.f-secure.com,Proxy\nDOMAIN-SUFFIX,www.ukproxyserver.co.uk,Proxy\nDOMAIN-SUFFIX,www.mgvip35.com,Proxy\nDOMAIN-SUFFIX,eyevio.jp,Proxy\nDOMAIN-SUFFIX,www.fccchina.org,Proxy\nDOMAIN-SUFFIX,app6.cf,Proxy\nDOMAIN-SUFFIX,ntdtv.ca,Proxy\nDOMAIN-SUFFIX,www.gfsswy.com,Proxy\nDOMAIN-SUFFIX,nitter.lunar.icu,Proxy\nDOMAIN-SUFFIX,77.effers.com,Proxy\nDOMAIN-SUFFIX,www.buddhism.hk,Proxy\nDOMAIN-SUFFIX,googleapps.com,Proxy\nDOMAIN-SUFFIX,www.tsdm.me,Proxy\nDOMAIN-SUFFIX,www.nyam1380.com,Proxy\nDOMAIN-SUFFIX,orn.jp,Proxy\nDOMAIN-SUFFIX,d190vlqkktza4c.cloudfront.net,Proxy\nDOMAIN-SUFFIX,hxoxo.com,Proxy\nDOMAIN-SUFFIX,668779.xyz,Proxy\nDOMAIN-SUFFIX,b5.fe100.net,Proxy\nDOMAIN-SUFFIX,www.shireyishunjian.vip,Proxy\nDOMAIN-SUFFIX,www.e8luck.cc,Proxy\nDOMAIN-SUFFIX,www.bb-ingames.com,Proxy\nDOMAIN-SUFFIX,yomiuri.co.jp,Proxy\nDOMAIN-SUFFIX,p1686.com,Proxy\nDOMAIN-SUFFIX,www.glenelg.org,Proxy\nDOMAIN-SUFFIX,ooo-sex.com,Proxy\nDOMAIN-SUFFIX,rcam.target.com,Proxy\nDOMAIN-SUFFIX,droidsecurity.com,Proxy\nDOMAIN-SUFFIX,learnreligions.com,Proxy\nDOMAIN-SUFFIX,www.nakedyoungtube.com,Proxy\nDOMAIN-SUFFIX,xv9.cc,Proxy\nDOMAIN-SUFFIX,j3569.com,Proxy\nDOMAIN-SUFFIX,weijingsheng.org,Proxy\nDOMAIN-SUFFIX,andrewmccoy.org,Proxy\nDOMAIN-SUFFIX,timetohide.me,Proxy\nDOMAIN-SUFFIX,uk.yahoo.com,Proxy\nDOMAIN-SUFFIX,wam-nyt.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,kawaiikawaii.jp,Proxy\nDOMAIN-SUFFIX,alexpescaru.ro,Proxy\nDOMAIN-SUFFIX,ii63.net,Proxy\nDOMAIN-SUFFIX,88vid.com,Proxy\nDOMAIN-SUFFIX,jailbreaked.net,Proxy\nDOMAIN-SUFFIX,www.yinmo.xyz,Proxy\nDOMAIN-SUFFIX,d18s29gmamtamp.cloudfront.net,Proxy\nDOMAIN-SUFFIX,access.azuritegate.com,Proxy\nDOMAIN-SUFFIX,ao3.ink,Proxy\nDOMAIN-SUFFIX,fuyindiantai.org,Proxy\nDOMAIN-SUFFIX,getlantern.github.io,Proxy\nDOMAIN-SUFFIX,big126.com,Proxy\nDOMAIN-SUFFIX,coingi.com,Proxy\nDOMAIN-SUFFIX,dashboard.securingdemocracy.org,Proxy\nDOMAIN-SUFFIX,simplexsolutionsinc.com,Proxy\nDOMAIN-SUFFIX,neo.keanu.im,Proxy\nDOMAIN-SUFFIX,proxy-zone.net,Proxy\nDOMAIN-SUFFIX,ei.etowns.net,Proxy\nDOMAIN-SUFFIX,shiwuyuetian.xyz,Proxy\nDOMAIN-SUFFIX,120830.xyz,Proxy\nDOMAIN-SUFFIX,uyghur-j.org,Proxy\nDOMAIN-SUFFIX,ag.39173366.com,Proxy\nDOMAIN-SUFFIX,fnac.com.br,Proxy\nDOMAIN-SUFFIX,lncn.org,Proxy\nDOMAIN-SUFFIX,www.theislanderonline.com.au,Proxy\nDOMAIN-SUFFIX,zbty999.com,Proxy\nDOMAIN-SUFFIX,pandora.com,Proxy\nDOMAIN-SUFFIX,cabet228.com,Proxy\nDOMAIN-SUFFIX,xinbi700.com,Proxy\nDOMAIN-SUFFIX,www.htl-steyr.ac.at,Proxy\nDOMAIN-SUFFIX,i2runner.com,Proxy\nDOMAIN-SUFFIX,www.fatbtc.com,Proxy\nDOMAIN-SUFFIX,blm86.com,Proxy\nDOMAIN-SUFFIX,derschreibendecowboy.de,Proxy\nDOMAIN-SUFFIX,fdc89.jp,Proxy\nDOMAIN-SUFFIX,tl.gd,Proxy\nDOMAIN-SUFFIX,www.anix.moe,Proxy\nDOMAIN-SUFFIX,oke8.ddns.us,Proxy\nDOMAIN-SUFFIX,huaren.us,Proxy\nDOMAIN-SUFFIX,jeremy.visser.name,Proxy\nDOMAIN-SUFFIX,www.tpcdct.org,Proxy\nDOMAIN-SUFFIX,zh.wikipedia.shisu.cf,Proxy\nDOMAIN-SUFFIX,nttxstore.jp,Proxy\nDOMAIN-SUFFIX,nowlink.app,Proxy\nDOMAIN-SUFFIX,pic.pimg.tw,Proxy\nDOMAIN-SUFFIX,pioneer-worker.forums-free.com,Proxy\nDOMAIN-SUFFIX,bysol.org,Proxy\nDOMAIN-SUFFIX,vwin055.com,Proxy\nDOMAIN-SUFFIX,gatherproxy.com,Proxy\nDOMAIN-SUFFIX,forum.palmislife.com,Proxy\nDOMAIN-SUFFIX,homo.xxx,Proxy\nDOMAIN-SUFFIX,p6686.com,Proxy\nDOMAIN-SUFFIX,www.shs.edu.tw,Proxy\nDOMAIN-SUFFIX,onapple.jp,Proxy\nDOMAIN-SUFFIX,www.amnesty.ch,Proxy\nDOMAIN-SUFFIX,blm866.com,Proxy\nDOMAIN-SUFFIX,u3c3.org,Proxy\nDOMAIN-SUFFIX,www.bmd5.com,Proxy\nDOMAIN-SUFFIX,6345345.com,Proxy\nDOMAIN-SUFFIX,eap.einaudi.cornell.edu,Proxy\nDOMAIN-SUFFIX,blog.youxu.info,Proxy\nDOMAIN-SUFFIX,armscontrolcenter.org,Proxy\nDOMAIN-SUFFIX,www.dataplugs.com,Proxy\nDOMAIN-SUFFIX,w.poss.pw,Proxy\nDOMAIN-SUFFIX,theclassicporn.com,Proxy\nDOMAIN-SUFFIX,dc0075.com,Proxy\nDOMAIN-SUFFIX,winning11.com,Proxy\nDOMAIN-SUFFIX,3kirikou.org,Proxy\nDOMAIN-SUFFIX,www.businessweekly.com.tw,Proxy\nDOMAIN-SUFFIX,whotalking.com,Proxy\nDOMAIN-SUFFIX,32.css5.bid,Proxy\nDOMAIN-SUFFIX,www.dilidili.name,Proxy\nDOMAIN-SUFFIX,www.airitilibrary.com,Proxy\nDOMAIN-SUFFIX,www.jiasheng-global.com,Proxy\nDOMAIN-SUFFIX,mofos.com,Proxy\nDOMAIN-SUFFIX,naughtymag.com,Proxy\nDOMAIN-SUFFIX,authorizeddns.net,Proxy\nDOMAIN-SUFFIX,www.hurriyetdailynews.com,Proxy\nDOMAIN-SUFFIX,nwtca.org,Proxy\nDOMAIN-SUFFIX,subscribetomyadventure.firebaseio.com,Proxy\nDOMAIN-SUFFIX,vpnguard.net,Proxy\nDOMAIN-SUFFIX,demosafi.lifi.plus,Proxy\nDOMAIN-SUFFIX,chinatweeps.com,Proxy\nDOMAIN-SUFFIX,v2fly.org,Proxy\nDOMAIN-SUFFIX,dipndip.com,Proxy\nDOMAIN-SUFFIX,hk.search.yahoo.com,Proxy\nDOMAIN-SUFFIX,voa-islam.com,Proxy\nDOMAIN-SUFFIX,www.wfaa.de,Proxy\nDOMAIN-SUFFIX,ysb88.com,Proxy\nDOMAIN-SUFFIX,www.zakzak.co.jp,Proxy\nDOMAIN-SUFFIX,binance.com,Proxy\nDOMAIN-SUFFIX,tbpic.info,Proxy\nDOMAIN-SUFFIX,006005.cc,Proxy\nDOMAIN-SUFFIX,russian.learnfalungong.com,Proxy\nDOMAIN-SUFFIX,catros.com,Proxy\nDOMAIN-SUFFIX,www.pussy.org,Proxy\nDOMAIN-SUFFIX,cusp.hk,Proxy\nDOMAIN-SUFFIX,bratgpt.com,Proxy\nDOMAIN-SUFFIX,vpnonline.org,Proxy\nDOMAIN-SUFFIX,free.moliwebss.com,Proxy\nDOMAIN-SUFFIX,fda.gov.tw,Proxy\nDOMAIN-SUFFIX,66go.vip,Proxy\nDOMAIN-SUFFIX,celticnorse.com,Proxy\nDOMAIN-SUFFIX,baidu.ehrenreich.ca,Proxy\nDOMAIN-SUFFIX,webmail.xiangshanforum.org,Proxy\nDOMAIN-SUFFIX,php5.ga,Proxy\nDOMAIN-SUFFIX,upcoming.yahoo.com,Proxy\nDOMAIN-SUFFIX,gand-khujli.com,Proxy\nDOMAIN-SUFFIX,cn1lib.org,Proxy\nDOMAIN-SUFFIX,blog9go.com,Proxy\nDOMAIN-SUFFIX,afreecatv.com,Proxy\nDOMAIN-SUFFIX,etaa.org.au,Proxy\nDOMAIN-SUFFIX,sexoquente.tv,Proxy\nDOMAIN-SUFFIX,free-proxysite.com,Proxy\nDOMAIN-SUFFIX,freemorenews.com,Proxy\nDOMAIN-SUFFIX,immifit.ca,Proxy\nDOMAIN-SUFFIX,www.politicalcartoons.com,Proxy\nDOMAIN-SUFFIX,nitter.it,Proxy\nDOMAIN-SUFFIX,h5.140ld.cc,Proxy\nDOMAIN-SUFFIX,www.kuai500.com,Proxy\nDOMAIN-SUFFIX,emailbox-qq.com,Proxy\nDOMAIN-SUFFIX,hqpornlinks.com,Proxy\nDOMAIN-SUFFIX,ipjlvpn.com,Proxy\nDOMAIN-SUFFIX,mitramandalajaya.id,Proxy\nDOMAIN-SUFFIX,durex.com,Proxy\nDOMAIN-SUFFIX,supervigor.com,Proxy\nDOMAIN-SUFFIX,www.bitcointalk.org,Proxy\nDOMAIN-SUFFIX,csuchen.de,Proxy\nDOMAIN-SUFFIX,zh.wikipedia.shutcm.cf,Proxy\nDOMAIN-SUFFIX,gosuslugi.ru,Proxy\nDOMAIN-SUFFIX,en.alalam.ir,Proxy\nDOMAIN-SUFFIX,22.ly.rs,Proxy\nDOMAIN-SUFFIX,2886.net,Proxy\nDOMAIN-SUFFIX,betway599.com,Proxy\nDOMAIN-SUFFIX,bunshun.jp,Proxy\nDOMAIN-SUFFIX,wdly005.com,Proxy\nDOMAIN-SUFFIX,chinese.donga.com,Proxy\nDOMAIN-SUFFIX,www.itb92.com,Proxy\nDOMAIN-SUFFIX,travian.com.tr,Proxy\nDOMAIN-SUFFIX,proxymice.com,Proxy\nDOMAIN-SUFFIX,karuna.org.au,Proxy\nDOMAIN-SUFFIX,qsbook.com,Proxy\nDOMAIN-SUFFIX,ipfs.infura.io,Proxy\nDOMAIN-SUFFIX,mzc23.com,Proxy\nDOMAIN-SUFFIX,fastssh.com,Proxy\nDOMAIN-SUFFIX,artsy.net,Proxy\nDOMAIN-SUFFIX,www.techni-modul-engineering.eu,Proxy\nDOMAIN-SUFFIX,zg88.1apps.com,Proxy\nDOMAIN-SUFFIX,ljwpte.site,Proxy\nDOMAIN-SUFFIX,25.slyip.net,Proxy\nDOMAIN-SUFFIX,www.game.com.cn,Proxy\nDOMAIN-SUFFIX,lk.com,Proxy\nDOMAIN-SUFFIX,chromeexperiments.com,Proxy\nDOMAIN-SUFFIX,747833.com,Proxy\nDOMAIN-SUFFIX,megarotic.com,Proxy\nDOMAIN-SUFFIX,www.andaluciaenruta.com,Proxy\nDOMAIN-SUFFIX,257.now-ip.net,Proxy\nDOMAIN-SUFFIX,pornhome.com,Proxy\nDOMAIN-SUFFIX,96xae.com,Proxy\nDOMAIN-SUFFIX,letou666.com,Proxy\nDOMAIN-SUFFIX,www.fibreone.co.uk,Proxy\nDOMAIN-SUFFIX,cdp2006.org,Proxy\nDOMAIN-SUFFIX,tokyo-hot.com,Proxy\nDOMAIN-SUFFIX,stat.gov.tw,Proxy\nDOMAIN-SUFFIX,wallesspku.com,Proxy\nDOMAIN-SUFFIX,yzc178.com,Proxy\nDOMAIN-SUFFIX,helios.plan9-dns.com,Proxy\nDOMAIN-SUFFIX,fortus.com.tr,Proxy\nDOMAIN-SUFFIX,www.ligui.com,Proxy\nDOMAIN-SUFFIX,ufreevpn.com,Proxy\nDOMAIN-SUFFIX,www.xcyy.cn.to,Proxy\nDOMAIN-SUFFIX,avq.avbuy.com.tw,Proxy\nDOMAIN-SUFFIX,playpcesor.com,Proxy\nDOMAIN-SUFFIX,abc.xwzb.net,Proxy\nDOMAIN-SUFFIX,vpnxd.com,Proxy\nDOMAIN-SUFFIX,dafahao.com,Proxy\nDOMAIN-SUFFIX,gratisjuegos.org,Proxy\nDOMAIN-SUFFIX,ru-video.com,Proxy\nDOMAIN-SUFFIX,www.jbo87.com,Proxy\nDOMAIN-SUFFIX,chinaxchina.com,Proxy\nDOMAIN-SUFFIX,wovpn.com,Proxy\nDOMAIN-SUFFIX,tbs-rainbow.org,Proxy\nDOMAIN-SUFFIX,greatfire.org,Proxy\nDOMAIN-SUFFIX,ptbtm.com,Proxy\nDOMAIN-SUFFIX,j88889.com,Proxy\nDOMAIN-SUFFIX,chatbot.theb.ai,Proxy\nDOMAIN-SUFFIX,dwnews.net,Proxy\nDOMAIN-SUFFIX,steamcomnunity.com,Proxy\nDOMAIN-SUFFIX,shxp.top,Proxy\nDOMAIN-SUFFIX,initiativesforchina.org,Proxy\nDOMAIN-SUFFIX,knowyourmeme.com,Proxy\nDOMAIN-SUFFIX,nan.so,Proxy\nDOMAIN-SUFFIX,tokyo-247.com,Proxy\nDOMAIN-SUFFIX,cafemaker.wakingsands.com,Proxy\nDOMAIN-SUFFIX,compuinter.com,Proxy\nDOMAIN-SUFFIX,www.fengherili.xyz,Proxy\nDOMAIN-SUFFIX,theqingyun.co,Proxy\nDOMAIN-SUFFIX,s6.slyip.net,Proxy\nDOMAIN-SUFFIX,cordcloud.co,Proxy\nDOMAIN-SUFFIX,php3.gq,Proxy\nDOMAIN-SUFFIX,www.xf802.com,Proxy\nDOMAIN-SUFFIX,is-into-anime.com,Proxy\nDOMAIN-SUFFIX,www.avatamsaka.ca,Proxy\nDOMAIN-SUFFIX,60cp01.com,Proxy\nDOMAIN-SUFFIX,povpn.com,Proxy\nDOMAIN-SUFFIX,www.binancezh.com,Proxy\nDOMAIN-SUFFIX,576.slyip.net,Proxy\nDOMAIN-SUFFIX,qsvpn.com,Proxy\nDOMAIN-SUFFIX,www.aiwin988.com,Proxy\nDOMAIN-SUFFIX,go2av.com,Proxy\nDOMAIN-SUFFIX,www.hkbdsmc.com,Proxy\nDOMAIN-SUFFIX,alabout.com,Proxy\nDOMAIN-SUFFIX,18youtube.com,Proxy\nDOMAIN-SUFFIX,www.sxswtorrent.org,Proxy\nDOMAIN-SUFFIX,0.1kku.xyz,Proxy\nDOMAIN-SUFFIX,www.fun585.com,Proxy\nDOMAIN-SUFFIX,www.06966e.com,Proxy\nDOMAIN-SUFFIX,91vjj.com,Proxy\nDOMAIN-SUFFIX,eamonnbrennan.com,Proxy\nDOMAIN-SUFFIX,32thing.com,Proxy\nDOMAIN-SUFFIX,supervpn.net,Proxy\nDOMAIN-SUFFIX,mirror.genesisadaptive.com,Proxy\nDOMAIN-SUFFIX,www.22world.us,Proxy\nDOMAIN-SUFFIX,karkhung.com,Proxy\nDOMAIN-SUFFIX,1588766.com,Proxy\nDOMAIN-SUFFIX,heryan.web.id,Proxy\nDOMAIN-SUFFIX,eu78.com,Proxy\nDOMAIN-SUFFIX,www.portpirierecorder.com.au,Proxy\nDOMAIN-SUFFIX,www.joangus.idv.tw,Proxy\nDOMAIN-SUFFIX,www.outlawstar.net,Proxy\nDOMAIN-SUFFIX,941-hd.com,Proxy\nDOMAIN-SUFFIX,azproxies.com,Proxy\nDOMAIN-SUFFIX,walletconnect.com,Proxy\nDOMAIN-SUFFIX,www.dailytime.gq,Proxy\nDOMAIN-SUFFIX,martincartoons.com,Proxy\nDOMAIN-SUFFIX,advocatesforyouth.org,Proxy\nDOMAIN-SUFFIX,minnano-av.com,Proxy\nDOMAIN-SUFFIX,www.saga-s.co.jp,Proxy\nDOMAIN-SUFFIX,edvim.ro,Proxy\nDOMAIN-SUFFIX,pornpussy.com,Proxy\nDOMAIN-SUFFIX,copart.com,Proxy\nDOMAIN-SUFFIX,ncn.org,Proxy\nDOMAIN-SUFFIX,google.ad,Proxy\nDOMAIN-SUFFIX,selfip.net,Proxy\nDOMAIN-SUFFIX,xxuz.com,Proxy\nDOMAIN-SUFFIX,sondaggibidimedia.it,Proxy\nDOMAIN-SUFFIX,juliepost.com,Proxy\nDOMAIN-SUFFIX,leafyvpn.net,Proxy\nDOMAIN-SUFFIX,77.now-ip.net,Proxy\nDOMAIN-SUFFIX,hkbbcc.xyz,Proxy\nDOMAIN-SUFFIX,fring.com,Proxy\nDOMAIN-SUFFIX,cgi.f1.com.tw,Proxy\nDOMAIN-SUFFIX,hotels.cn,Proxy\nDOMAIN-SUFFIX,wanmm.com,Proxy\nDOMAIN-SUFFIX,magri.ca,Proxy\nDOMAIN-SUFFIX,035009.com,Proxy\nDOMAIN-SUFFIX,gettrials.com,Proxy\nDOMAIN-SUFFIX,xhamster.one,Proxy\nDOMAIN-SUFFIX,doctorhart.com,Proxy\nDOMAIN-SUFFIX,google.com.ph,Proxy\nDOMAIN-SUFFIX,mirrorfiction.com,Proxy\nDOMAIN-SUFFIX,ismalltits.com,Proxy\nDOMAIN-SUFFIX,ntdtv.ru,Proxy\nDOMAIN-SUFFIX,coyoter.com,Proxy\nDOMAIN-SUFFIX,goldjizz.com,Proxy\nDOMAIN-SUFFIX,reuters.com.cn,Proxy\nDOMAIN-SUFFIX,www.78in.net,Proxy\nDOMAIN-SUFFIX,ucdc1998.org,Proxy\nDOMAIN-SUFFIX,63rr.net,Proxy\nDOMAIN-SUFFIX,i.smte.ch,Proxy\nDOMAIN-SUFFIX,uhb168.com,Proxy\nDOMAIN-SUFFIX,german-proxy.de,Proxy\nDOMAIN-SUFFIX,cafegoodnews.com,Proxy\nDOMAIN-SUFFIX,3366buyu.com,Proxy\nDOMAIN-SUFFIX,pj3635.com,Proxy\nDOMAIN-SUFFIX,portablevpn.nl,Proxy\nDOMAIN-SUFFIX,www.zavodjenje.com,Proxy\nDOMAIN-SUFFIX,roobaroo.org,Proxy\nDOMAIN-SUFFIX,dalailama.mn,Proxy\nDOMAIN-SUFFIX,poker.net.br,Proxy\nDOMAIN-SUFFIX,www.povpn3.com,Proxy\nDOMAIN-SUFFIX,novelasia.com,Proxy\nDOMAIN-SUFFIX,h.gooto.win,Proxy\nDOMAIN-SUFFIX,dw-world.de,Proxy\nDOMAIN-SUFFIX,worldtribune.com,Proxy\nDOMAIN-SUFFIX,dou.lesile.net,Proxy\nDOMAIN-SUFFIX,friendsofchina.org,Proxy\nDOMAIN-SUFFIX,amitabhafoundation.us,Proxy\nDOMAIN-SUFFIX,saturdaynightlatinas.com,Proxy\nDOMAIN-SUFFIX,www.duoguge.net,Proxy\nDOMAIN-SUFFIX,www.illawarramercury.com.au,Proxy\nDOMAIN-SUFFIX,www.mobilevirtual.com.br,Proxy\nDOMAIN-SUFFIX,bywsvz.site,Proxy\nDOMAIN-SUFFIX,m.rse43.com,Proxy\nDOMAIN-SUFFIX,jm-comic2.art,Proxy\nDOMAIN-SUFFIX,93xaa.com,Proxy\nDOMAIN-SUFFIX,uyghurpen.org,Proxy\nDOMAIN-SUFFIX,utvpn.com,Proxy\nDOMAIN-SUFFIX,www.uncut.co.uk,Proxy\nDOMAIN-SUFFIX,en.wanweibaike.com,Proxy\nDOMAIN-SUFFIX,2waky.com,Proxy\nDOMAIN-SUFFIX,guardiangroupnw.com,Proxy\nDOMAIN-SUFFIX,www.naluone.net,Proxy\nDOMAIN-SUFFIX,pec24.com,Proxy\nDOMAIN-SUFFIX,www.ag9.us,Proxy\nDOMAIN-SUFFIX,gfx.com.ar,Proxy\nDOMAIN-SUFFIX,bizzapp.com,Proxy\nDOMAIN-SUFFIX,bemywife.cc,Proxy\nDOMAIN-SUFFIX,00338449.com,Proxy\nDOMAIN-SUFFIX,bigbir.com,Proxy\nDOMAIN-SUFFIX,nordstromrack.com,Proxy\nDOMAIN-SUFFIX,croatiavpn.com,Proxy\nDOMAIN-SUFFIX,google.es,Proxy\nDOMAIN-SUFFIX,student.tw,Proxy\nDOMAIN-SUFFIX,fattylewis.com,Proxy\nDOMAIN-SUFFIX,m88.com,Proxy\nDOMAIN-SUFFIX,sitegetter.net,Proxy\nDOMAIN-SUFFIX,nhactruoc75.com,Proxy\nDOMAIN-SUFFIX,www.inverelltimes.com.au,Proxy\nDOMAIN-SUFFIX,www.putty.org,Proxy\nDOMAIN-SUFFIX,google.co.zm,Proxy\nDOMAIN-SUFFIX,falunau.org,Proxy\nDOMAIN-SUFFIX,wandu.pw,Proxy\nDOMAIN-SUFFIX,wukangrui.net,Proxy\nDOMAIN-SUFFIX,u8.flnet.org,Proxy\nDOMAIN-SUFFIX,yuntipub.com,Proxy\nDOMAIN-SUFFIX,www.5888casino.com,Proxy\nDOMAIN-SUFFIX,freevpnss.com,Proxy\nDOMAIN-SUFFIX,ixxxxporn.com,Proxy\nIP-CIDR,69.65.19.160/32,Proxy\nDOMAIN-SUFFIX,test01.paopaocloud.cyou,Proxy\nDOMAIN-SUFFIX,subacme.rerouted.org,Proxy\nDOMAIN-SUFFIX,tibetcharity.in,Proxy\nDOMAIN-SUFFIX,www.freedomcollection.org,Proxy\nDOMAIN-SUFFIX,yunfan.pw,Proxy\nDOMAIN-SUFFIX,tibet.org,Proxy\nDOMAIN-SUFFIX,nuvid.com,Proxy\nDOMAIN-SUFFIX,xsela.com,Proxy\nDOMAIN-SUFFIX,skyscrapercity.com,Proxy\nDOMAIN-SUFFIX,d1b183sg0nvnuh.cloudfront.net,Proxy\nDOMAIN-SUFFIX,compuspire.it,Proxy\nDOMAIN-SUFFIX,kisspanzio.ro,Proxy\nDOMAIN-SUFFIX,www.thinkstockphotos.fr,Proxy\nDOMAIN-SUFFIX,stc.com.sa,Proxy\nDOMAIN-SUFFIX,fireson.cc,Proxy\nDOMAIN-SUFFIX,www.lapeople.com,Proxy\nDOMAIN-SUFFIX,davpn.com,Proxy\nDOMAIN-SUFFIX,c7511.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,7022555.com,Proxy\nDOMAIN-SUFFIX,us-189-255-4.fri-gate.biz,Proxy\nDOMAIN-SUFFIX,vwin152.com,Proxy\nDOMAIN-SUFFIX,answersingenesis.org,Proxy\nDOMAIN-SUFFIX,buzzorange.com,Proxy\nDOMAIN-SUFFIX,my.faster.pw,Proxy\nDOMAIN-SUFFIX,windscribe.com,Proxy\nDOMAIN-SUFFIX,dengeki.com,Proxy\nDOMAIN-SUFFIX,safevpn.net,Proxy\nDOMAIN-SUFFIX,belamionline.com,Proxy\nDOMAIN-SUFFIX,hqg888.com,Proxy\nDOMAIN-SUFFIX,newxys8.com,Proxy\nDOMAIN-SUFFIX,www.tusi8.com,Proxy\nDOMAIN-SUFFIX,digisfera.com,Proxy\nDOMAIN-SUFFIX,eecs.berkeley.edu,Proxy\nDOMAIN-SUFFIX,spicevpn.com,Proxy\nDOMAIN-SUFFIX,www.b1473.com,Proxy\nDOMAIN-SUFFIX,126.flnet.org,Proxy\nDOMAIN-SUFFIX,artstation.com,Proxy\nDOMAIN-SUFFIX,djgaq19cn1f4u.cloudfront.net,Proxy\nDOMAIN-SUFFIX,liuli.in,Proxy\nDOMAIN-SUFFIX,na.ddns.name,Proxy\nDOMAIN-SUFFIX,everia.club,Proxy\nDOMAIN-SUFFIX,tibetuprising.org,Proxy\nDOMAIN-SUFFIX,yuanotes.com,Proxy\nDOMAIN-SUFFIX,www.sshs.cc,Proxy\nDOMAIN-SUFFIX,sjhs.pw,Proxy\nDOMAIN-SUFFIX,am399.com,Proxy\nDOMAIN-SUFFIX,bdsmvideos.net,Proxy\nDOMAIN-SUFFIX,abufariz.com,Proxy\nDOMAIN-SUFFIX,trickip.net,Proxy\nDOMAIN-SUFFIX,pagodabox.com,Proxy\nDOMAIN-SUFFIX,www.trips-edu.nl,Proxy\nDOMAIN-SUFFIX,thb.wh8pro.cc,Proxy\nDOMAIN-SUFFIX,bbs.astro.nyc,Proxy\nDOMAIN-SUFFIX,tfino.com,Proxy\nDOMAIN-SUFFIX,csx.com,Proxy\nDOMAIN-SUFFIX,ss.levyhsu.com,Proxy\nDOMAIN-SUFFIX,pinterest.com.mx,Proxy\nDOMAIN-SUFFIX,gaforum.org,Proxy\nDOMAIN-SUFFIX,falunpilipinas.net,Proxy\nDOMAIN-SUFFIX,mypicture.info,Proxy\nDOMAIN-SUFFIX,paopao11.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,homoeopathy.com,Proxy\nDOMAIN-SUFFIX,doh.futa.gg,Proxy\nDOMAIN-SUFFIX,faluninfo.or.kr,Proxy\nDOMAIN-SUFFIX,www.lll836.net,Proxy\nDOMAIN-SUFFIX,sydneytoday.com,Proxy\nDOMAIN-SUFFIX,rferl.mobi,Proxy\nDOMAIN-SUFFIX,sf.net,Proxy\nDOMAIN-SUFFIX,taiwantp.net,Proxy\nDOMAIN-SUFFIX,3494781.com,Proxy\nDOMAIN-SUFFIX,monster.com,Proxy\nDOMAIN-SUFFIX,ss9874.com,Proxy\nDOMAIN-SUFFIX,th.bway899.com,Proxy\nDOMAIN-SUFFIX,yahoo.com.cn,Proxy\nDOMAIN-SUFFIX,www.mobygames.com,Proxy\nDOMAIN-SUFFIX,zy.etowns.net,Proxy\nDOMAIN-SUFFIX,kanzhongguo.com.au,Proxy\nDOMAIN-SUFFIX,blenderartists.com,Proxy\nDOMAIN-SUFFIX,workermediaweb.hostingerapp.com,Proxy\nDOMAIN-SUFFIX,www.hkbu.edu.hk,Proxy\nDOMAIN-SUFFIX,xys.dxiong.com,Proxy\nDOMAIN-SUFFIX,lund.se,Proxy\nDOMAIN-SUFFIX,shenshou.org,Proxy\nDOMAIN-SUFFIX,www.google.com.kw,Proxy\nDOMAIN-SUFFIX,ddc.com.tw,Proxy\nDOMAIN-SUFFIX,ccw.org.tw,Proxy\nDOMAIN-SUFFIX,still-damp-hill.bsc.quiknode.pro,Proxy\nDOMAIN-SUFFIX,classicscore.hut2.ru,Proxy\nDOMAIN-SUFFIX,nflxso.net,Proxy\nDOMAIN-SUFFIX,leiting001.com,Proxy\nDOMAIN-SUFFIX,www.adpl.org.hk,Proxy\nDOMAIN-SUFFIX,hj0018.com,Proxy\nDOMAIN-SUFFIX,md.voanpd.com,Proxy\nDOMAIN-SUFFIX,www.securitycoverage.com,Proxy\nDOMAIN-SUFFIX,hkhl.hk,Proxy\nDOMAIN-SUFFIX,theksj.com,Proxy\nDOMAIN-SUFFIX,388766.com,Proxy\nDOMAIN-SUFFIX,justhost.ru,Proxy\nDOMAIN-SUFFIX,eastturkestan.com,Proxy\nDOMAIN-SUFFIX,www.hurriyet.com,Proxy\nDOMAIN-SUFFIX,t1.c.zxdl.pw,Proxy\nDOMAIN-SUFFIX,motrildigital.net,Proxy\nDOMAIN-SUFFIX,p2.mypi.co,Proxy\nDOMAIN-SUFFIX,www.ibtimes.co.in,Proxy\nDOMAIN-SUFFIX,pbworks.com,Proxy\nDOMAIN-SUFFIX,movie-rush.com,Proxy\nDOMAIN-SUFFIX,909cpa8.com,Proxy\nDOMAIN-SUFFIX,jtzgcd.neocities.org,Proxy\nDOMAIN-SUFFIX,dom.dl.wu.akadns.net,Proxy\nDOMAIN-SUFFIX,tew.org,Proxy\nDOMAIN-SUFFIX,www.insecam.org,Proxy\nDOMAIN-SUFFIX,www.mrt188.com,Proxy\nDOMAIN-SUFFIX,cn.colleges.chat,Proxy\nDOMAIN-SUFFIX,8qr3.authorizeddns.us,Proxy\nDOMAIN-SUFFIX,iqq8.club,Proxy\nDOMAIN-SUFFIX,objects.dreamhost.com,Proxy\nDOMAIN-SUFFIX,is-a-hard-worker.com,Proxy\nDOMAIN-SUFFIX,covidcon.org,Proxy\nDOMAIN-SUFFIX,paradisepoker.com,Proxy\nDOMAIN-SUFFIX,friendfeed-media.com,Proxy\nDOMAIN-SUFFIX,7867310.com,Proxy\nDOMAIN-SUFFIX,talesofwisdom.com,Proxy\nDOMAIN-SUFFIX,vxia.4.688.org,Proxy\nDOMAIN-SUFFIX,27.flnet.org,Proxy\nDOMAIN-SUFFIX,beetalkmobile.com,Proxy\nDOMAIN-SUFFIX,googlee.com,Proxy\nDOMAIN-SUFFIX,rthklive2-lh.akamaihd.net,Proxy\nDOMAIN-SUFFIX,classicalguitarblog.net,Proxy\nDOMAIN-SUFFIX,d2iak8jpf2cptl.cloudfront.net,Proxy\nDOMAIN-SUFFIX,tokyocn.com,Proxy\nDOMAIN-SUFFIX,porn2012.com,Proxy\nDOMAIN-SUFFIX,www.bcw00.net,Proxy\nDOMAIN-SUFFIX,bitn.com,Proxy\nDOMAIN-SUFFIX,dit-inc.us,Proxy\nDOMAIN-SUFFIX,xoxo.zone,Proxy\nDOMAIN-SUFFIX,vpnhi.com,Proxy\nDOMAIN-SUFFIX,futuremessage.org,Proxy\nDOMAIN-SUFFIX,bolin.netfirms.com,Proxy\nDOMAIN-SUFFIX,ifmc.co,Proxy\nDOMAIN-SUFFIX,www.meltingsource.com,Proxy\nDOMAIN-SUFFIX,my.mail.ru,Proxy\nDOMAIN-SUFFIX,www.1961115.app,Proxy\nDOMAIN-SUFFIX,www.pncle8.com,Proxy\nDOMAIN-SUFFIX,www.ifpe.tw,Proxy\nDOMAIN-SUFFIX,dancemeets.com,Proxy\nDOMAIN-SUFFIX,privatix.com,Proxy\nDOMAIN-SUFFIX,belarus.com,Proxy\nDOMAIN-SUFFIX,www.betfair.com,Proxy\nDOMAIN-SUFFIX,freebox.dk,Proxy\nDOMAIN-SUFFIX,92.3d-game.com,Proxy\nDOMAIN-SUFFIX,zzy.healthonsite.xyz,Proxy\nDOMAIN-SUFFIX,yahoo.dk,Proxy\nDOMAIN-SUFFIX,anchorfree.com,Proxy\nDOMAIN-SUFFIX,hacg.li,Proxy\nDOMAIN-SUFFIX,driftt.com,Proxy\nDOMAIN-SUFFIX,api.xc17868.com,Proxy\nDOMAIN-SUFFIX,rocketmail.com,Proxy\nDOMAIN-SUFFIX,69.dnsalias.org,Proxy\nDOMAIN-SUFFIX,vpncn.net,Proxy\nDOMAIN-SUFFIX,uscnpm.org,Proxy\nDOMAIN-SUFFIX,vpndp.com,Proxy\nDOMAIN-SUFFIX,www.socketpro.help,Proxy\nDOMAIN-SUFFIX,freel2tpvpn.com,Proxy\nDOMAIN-SUFFIX,tycool.com,Proxy\nDOMAIN-SUFFIX,digital.avbuy.com.tw,Proxy\nDOMAIN-SUFFIX,rawgit.com,Proxy\nDOMAIN-SUFFIX,gldnrtvr.com,Proxy\nDOMAIN-SUFFIX,888.suroot.com,Proxy\nDOMAIN-SUFFIX,eggc111.com,Proxy\nDOMAIN-SUFFIX,bitchute.com,Proxy\nDOMAIN-SUFFIX,kyzyhello.com,Proxy\nDOMAIN-SUFFIX,gmail.gunnery.org,Proxy\nDOMAIN-SUFFIX,rx8800.com,Proxy\nDOMAIN-SUFFIX,tor-exit-53.for-privacy.net,Proxy\nDOMAIN-SUFFIX,cacnw.com,Proxy\nDOMAIN-SUFFIX,android-x86.org,Proxy\nDOMAIN-SUFFIX,www.ecfa.org.tw,Proxy\nDOMAIN-SUFFIX,www.bumeizhiye.com,Proxy\nDOMAIN-SUFFIX,iqq18.fun,Proxy\nDOMAIN-SUFFIX,cguidemacau.com,Proxy\nDOMAIN-SUFFIX,www.173128.com,Proxy\nDOMAIN-SUFFIX,mercari.com,Proxy\nDOMAIN-SUFFIX,www.nnyy6.top,Proxy\nDOMAIN-SUFFIX,cd.chrismac.org,Proxy\nDOMAIN-SUFFIX,pao-pao.net,Proxy\nDOMAIN-SUFFIX,laurelvictoriagray.com,Proxy\nDOMAIN-SUFFIX,dnv9o962ksri1.cloudfront.net,Proxy\nDOMAIN-SUFFIX,howfu.me,Proxy\nDOMAIN-SUFFIX,texashistoric.com,Proxy\nDOMAIN-SUFFIX,lionsdesneigesmontblanc.over-blog.com,Proxy\nDOMAIN-SUFFIX,ytub.com,Proxy\nDOMAIN-SUFFIX,qw.com,Proxy\nDOMAIN-SUFFIX,passion-hd.com,Proxy\nDOMAIN-SUFFIX,www.learnosity.com,Proxy\nDOMAIN-SUFFIX,gamefaqs.gamespot.com,Proxy\nDOMAIN-SUFFIX,zhuangbi.me,Proxy\nDOMAIN-SUFFIX,vaticannews.va,Proxy\nDOMAIN-SUFFIX,nsd.asia,Proxy\nDOMAIN-SUFFIX,www.888funcity.com,Proxy\nDOMAIN-SUFFIX,tweetadder.com,Proxy\nDOMAIN-SUFFIX,hk.aboluowang.com,Proxy\nDOMAIN-SUFFIX,3utilities.com,Proxy\nDOMAIN-SUFFIX,courrierinternational.com,Proxy\nDOMAIN-SUFFIX,webshare.io,Proxy\nDOMAIN-SUFFIX,is-an-accountant.com,Proxy\nDOMAIN-SUFFIX,masterlu.fzgyh.com,Proxy\nDOMAIN-SUFFIX,www.96vpn.com,Proxy\nDOMAIN-SUFFIX,crucial.com,Proxy\nDOMAIN-SUFFIX,auctions.yahoo.co.jp,Proxy\nDOMAIN-SUFFIX,lingvodics.com,Proxy\nDOMAIN-SUFFIX,svmblocker.com,Proxy\nDOMAIN-SUFFIX,macts.com.tw,Proxy\nDOMAIN-SUFFIX,freewww.biz,Proxy\nDOMAIN-SUFFIX,turansam.org,Proxy\nDOMAIN-SUFFIX,stupidbeauty.com,Proxy\nDOMAIN-SUFFIX,roupascaipiras.com,Proxy\nDOMAIN-SUFFIX,silkbook.com,Proxy\nDOMAIN-SUFFIX,www.223oo.net,Proxy\nDOMAIN-SUFFIX,www.one88bet.com,Proxy\nDOMAIN-SUFFIX,wen-jos.idv.tw,Proxy\nDOMAIN-SUFFIX,piraattipuolue.fi,Proxy\nDOMAIN-SUFFIX,www.integral-calculator.com,Proxy\nDOMAIN-SUFFIX,axsetubal.pt,Proxy\nDOMAIN-SUFFIX,prvpn.com,Proxy\nDOMAIN-SUFFIX,oll.libertyfund.org,Proxy\nDOMAIN-SUFFIX,cod-88.com,Proxy\nDOMAIN-SUFFIX,ww5800.com,Proxy\nDOMAIN-SUFFIX,wiki.keso.cn,Proxy\nDOMAIN-SUFFIX,www.freenewscn.com,Proxy\nDOMAIN-SUFFIX,yuhanxuan.com,Proxy\nDOMAIN-SUFFIX,zzz.healthsection.xyz,Proxy\nDOMAIN-SUFFIX,www.proxyie.com,Proxy\nDOMAIN-SUFFIX,ptt.com,Proxy\nDOMAIN-SUFFIX,www.freeproxysite.com,Proxy\nDOMAIN-SUFFIX,torguard-cn.com,Proxy\nDOMAIN-SUFFIX,www.twatter.com,Proxy\nDOMAIN-SUFFIX,p2885.com,Proxy\nDOMAIN-SUFFIX,alexandnova.com,Proxy\nDOMAIN-SUFFIX,fgmtv.net,Proxy\nDOMAIN-SUFFIX,goproctoru.com,Proxy\nDOMAIN-SUFFIX,atfx.com,Proxy\nDOMAIN-SUFFIX,libgen.fun,Proxy\nDOMAIN-SUFFIX,sovpn.com,Proxy\nDOMAIN-SUFFIX,www.dtnext.in,Proxy\nDOMAIN-SUFFIX,mangabuddy.com,Proxy\nDOMAIN-SUFFIX,usaeducationgateway.com,Proxy\nDOMAIN-SUFFIX,dm233.cc,Proxy\nDOMAIN-SUFFIX,breachforums.is-1,Proxy\nDOMAIN-SUFFIX,aa935.net,Proxy\nDOMAIN-SUFFIX,b1966.com,Proxy\nDOMAIN-SUFFIX,ipfs.smartsignature.io,Proxy\nDOMAIN-SUFFIX,otcbtc.com,Proxy\nDOMAIN-SUFFIX,pherrie.dj,Proxy\nDOMAIN-SUFFIX,feisu261.xyz,Proxy\nDOMAIN-SUFFIX,paowang.net,Proxy\nDOMAIN-SUFFIX,d3jxgdhw7wksio.cloudfront.net,Proxy\nDOMAIN-SUFFIX,herrneckara.bhitest.com,Proxy\nDOMAIN-SUFFIX,xxmap.co,Proxy\nDOMAIN-SUFFIX,277.gotgeeks.com,Proxy\nDOMAIN-SUFFIX,006787.com,Proxy\nDOMAIN-SUFFIX,www.79.net,Proxy\nDOMAIN-SUFFIX,www.hd-inc.com,Proxy\nDOMAIN-SUFFIX,www.cellsystech.cn,Proxy\nDOMAIN-SUFFIX,socialblade.com,Proxy\nDOMAIN-SUFFIX,22youtube.com,Proxy\nDOMAIN-SUFFIX,dstk.dk,Proxy\nDOMAIN-SUFFIX,disconnect.me,Proxy\nDOMAIN-SUFFIX,internetofjunk.com,Proxy\nDOMAIN-SUFFIX,chingcheong.com,Proxy\nDOMAIN-SUFFIX,hovpn.com,Proxy\nDOMAIN-SUFFIX,mv.ip.onmypc.net,Proxy\nDOMAIN-SUFFIX,pemulihan.or.id,Proxy\nDOMAIN-SUFFIX,tube8.fr,Proxy\nDOMAIN-SUFFIX,bbchat.tv,Proxy\nDOMAIN-SUFFIX,www.hkcmi.edu,Proxy\nDOMAIN-SUFFIX,dns10.quad9.net,Proxy\nDOMAIN-SUFFIX,rubias19.com,Proxy\nDOMAIN-SUFFIX,nexitcore.com,Proxy\nDOMAIN-SUFFIX,forum.aperx.org,Proxy\nDOMAIN-SUFFIX,58559.com,Proxy\nDOMAIN-SUFFIX,article19.org,Proxy\nDOMAIN-SUFFIX,www.iyejie.com,Proxy\nDOMAIN-SUFFIX,hxtg.14.iamallama.com,Proxy\nDOMAIN-SUFFIX,cs.colorado.edu,Proxy\nDOMAIN-SUFFIX,www.bizppurio.com,Proxy\nDOMAIN-SUFFIX,nyt2.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,nastyvideotube.com,Proxy\nDOMAIN-SUFFIX,h5.ld70.tv,Proxy\nDOMAIN-SUFFIX,tekniktv.com,Proxy\nDOMAIN-SUFFIX,tb555.com,Proxy\nDOMAIN-SUFFIX,sadpanda.us,Proxy\nDOMAIN-SUFFIX,www.bestfreevpn.com,Proxy\nDOMAIN-SUFFIX,kaishao.idv.tw,Proxy\nDOMAIN-SUFFIX,fscked.org,Proxy\nDOMAIN-SUFFIX,blog.mozilla.com,Proxy\nDOMAIN-SUFFIX,bcapps.cat,Proxy\nDOMAIN-SUFFIX,h5.ldmedia32.com,Proxy\nDOMAIN-SUFFIX,wickedpictures.com,Proxy\nDOMAIN-SUFFIX,cart.chickenkiller.com,Proxy\nDOMAIN-SUFFIX,penpaperpixel.org,Proxy\nDOMAIN-SUFFIX,ecosys.gr,Proxy\nDOMAIN-SUFFIX,youdontcare.com,Proxy\nDOMAIN-SUFFIX,twitbridge.com,Proxy\nDOMAIN-SUFFIX,library.proletarian.me,Proxy\nDOMAIN-SUFFIX,www.361caipiao.com,Proxy\nDOMAIN-SUFFIX,humanesociety.org,Proxy\nDOMAIN-SUFFIX,www.qqc.co,Proxy\nDOMAIN-SUFFIX,paopao17.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,ojeremy.com,Proxy\nDOMAIN-SUFFIX,www.thinkstockphotos.co.kr,Proxy\nDOMAIN-SUFFIX,lfporn.com,Proxy\nDOMAIN-SUFFIX,vpnnet.net,Proxy\nDOMAIN-SUFFIX,chineseonboard.com,Proxy\nDOMAIN-SUFFIX,potatso.com,Proxy\nDOMAIN-SUFFIX,www.tensojapan.com,Proxy\nDOMAIN-SUFFIX,www.youramateurporn.com,Proxy\nDOMAIN-SUFFIX,xphimheo.com,Proxy\nDOMAIN-SUFFIX,webmail.aces.su.se,Proxy\nDOMAIN-SUFFIX,pornototale.com,Proxy\nDOMAIN-SUFFIX,xx3641.com,Proxy\nDOMAIN-SUFFIX,apply.jhu.edu,Proxy\nDOMAIN-SUFFIX,www.forbesadvocate.com.au,Proxy\nDOMAIN-SUFFIX,cem4.pat.flnet.org,Proxy\nDOMAIN-SUFFIX,sasze.ro,Proxy\nDOMAIN-SUFFIX,hentaihaven.xxx,Proxy\nDOMAIN-SUFFIX,secretproxy.org,Proxy\nDOMAIN-SUFFIX,paopao4.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,pinkclips.mobi,Proxy\nDOMAIN-SUFFIX,exmo.com,Proxy\nDOMAIN-SUFFIX,www.aggressivebabes.com,Proxy\nDOMAIN-SUFFIX,pursuestar.com,Proxy\nDOMAIN-SUFFIX,www.96777.cc,Proxy\nDOMAIN-SUFFIX,justproxy.co.uk,Proxy\nDOMAIN-SUFFIX,www.rsk.co.uk,Proxy\nDOMAIN-SUFFIX,idreamx.com,Proxy\nDOMAIN-SUFFIX,letou99.net,Proxy\nDOMAIN-SUFFIX,bbb678.com,Proxy\nDOMAIN-SUFFIX,mudfish.net,Proxy\nDOMAIN-SUFFIX,www.itb8888.com,Proxy\nDOMAIN-SUFFIX,bolehvpn.net,Proxy\nDOMAIN-SUFFIX,www.dancor.sumy.ua,Proxy\nDOMAIN-SUFFIX,cc.com,Proxy\nDOMAIN-SUFFIX,dou000.top,Proxy\nDOMAIN-SUFFIX,1bao.org,Proxy\nDOMAIN-SUFFIX,sanqianying.jigsy.com,Proxy\nDOMAIN-SUFFIX,mcatlove.com,Proxy\nDOMAIN-SUFFIX,gsvpn.com,Proxy\nDOMAIN-SUFFIX,porn5f.live,Proxy\nDOMAIN-SUFFIX,20497173p.rfihub.com,Proxy\nDOMAIN-SUFFIX,www.hacg.lol,Proxy\nDOMAIN-SUFFIX,feixiaohao.com,Proxy\nDOMAIN-SUFFIX,c3344.com,Proxy\nDOMAIN-SUFFIX,mims.com,Proxy\nDOMAIN-SUFFIX,coolmagnets.co.il,Proxy\nDOMAIN-SUFFIX,vip.hkwesi.xyz,Proxy\nDOMAIN-SUFFIX,wikisource.org,Proxy\nDOMAIN-SUFFIX,www.udnnews.com,Proxy\nDOMAIN-SUFFIX,nas.jochen-hoenicke.de,Proxy\nDOMAIN-SUFFIX,tor-exit-41.for-privacy.net,Proxy\nDOMAIN-SUFFIX,foobar.withgoogle.com,Proxy\nDOMAIN-SUFFIX,frommyascloset.com,Proxy\nDOMAIN-SUFFIX,meteorshowersonline.com,Proxy\nDOMAIN-SUFFIX,costco.com,Proxy\nDOMAIN-SUFFIX,www.pyrmonter-nachrichten.de,Proxy\nDOMAIN-SUFFIX,pmates.com,Proxy\nDOMAIN-SUFFIX,977ai.com,Proxy\nDOMAIN-SUFFIX,cdn.jsdelivr.net,Proxy\nDOMAIN-SUFFIX,habbix.fr,Proxy\nDOMAIN-SUFFIX,bernoldi.com.ar,Proxy\nDOMAIN-SUFFIX,plvpn.com,Proxy\nDOMAIN-SUFFIX,xijie.wordpress.com,Proxy\nDOMAIN-SUFFIX,app.smartmailcloud.com,Proxy\nDOMAIN-SUFFIX,www.uscardforum.com,Proxy\nDOMAIN-SUFFIX,ww1.acgnz.cc,Proxy\nDOMAIN-SUFFIX,11sebb.com,Proxy\nDOMAIN-SUFFIX,3344.flnet.org,Proxy\nDOMAIN-SUFFIX,85st.com,Proxy\nDOMAIN-SUFFIX,androidify.com,Proxy\nDOMAIN-SUFFIX,www.longlivehhdl.ning.com,Proxy\nDOMAIN-SUFFIX,h5.012ld.com,Proxy\nDOMAIN-SUFFIX,youtube.co.jp,Proxy\nDOMAIN-SUFFIX,nasa.gov,Proxy\nDOMAIN-SUFFIX,destiny.xfiles.to,Proxy\nDOMAIN-SUFFIX,skyav.me,Proxy\nDOMAIN-SUFFIX,ettoday.net,Proxy\nDOMAIN-SUFFIX,costumesupercenter.com,Proxy\nDOMAIN-SUFFIX,id.rlcdn.com,Proxy\nDOMAIN-SUFFIX,d3w2o0gs4j96ib.cloudfront.net,Proxy\nDOMAIN-SUFFIX,hbo.com,Proxy\nDOMAIN-SUFFIX,zh.anarchistlibraries.net,Proxy\nDOMAIN-SUFFIX,223.ax.lt,Proxy\nDOMAIN-SUFFIX,kielconsulting.org,Proxy\nDOMAIN-SUFFIX,pu3366.com,Proxy\nDOMAIN-SUFFIX,streameuwe1su021.azureedge.net,Proxy\nDOMAIN-SUFFIX,smathis.com,Proxy\nDOMAIN-SUFFIX,t.17uu.tw,Proxy\nDOMAIN-SUFFIX,theweek.com,Proxy\nDOMAIN-SUFFIX,bdy365.com,Proxy\nDOMAIN-SUFFIX,betkk52.com,Proxy\nDOMAIN-SUFFIX,www.appappapps.com,Proxy\nDOMAIN-SUFFIX,playtube.pk,Proxy\nDOMAIN-SUFFIX,douxeyewear.com,Proxy\nDOMAIN-SUFFIX,borneobulletin.com.bn,Proxy\nDOMAIN-SUFFIX,www.youtubu.com,Proxy\nDOMAIN-SUFFIX,wz9745.com,Proxy\nDOMAIN-SUFFIX,bituzi.com,Proxy\nDOMAIN-SUFFIX,jbl12345.com,Proxy\nDOMAIN-SUFFIX,sugarsync.com,Proxy\nDOMAIN-SUFFIX,www.infraworld.eu,Proxy\nDOMAIN-SUFFIX,mitbbsau.com,Proxy\nDOMAIN-SUFFIX,yl2299.org,Proxy\nDOMAIN-SUFFIX,bidsquare.com,Proxy\nDOMAIN-SUFFIX,times.hinet.net,Proxy\nDOMAIN-SUFFIX,firebase.com,Proxy\nDOMAIN-SUFFIX,lionsroardharmacenter.org,Proxy\nDOMAIN-SUFFIX,www.kporno.com,Proxy\nDOMAIN-SUFFIX,cn-proxy.com,Proxy\nDOMAIN-SUFFIX,dc7789.com,Proxy\nDOMAIN-SUFFIX,dsn04.co,Proxy\nDOMAIN-SUFFIX,195aaa195.com,Proxy\nDOMAIN-SUFFIX,clsp.fun,Proxy\nDOMAIN-SUFFIX,legendowl.com,Proxy\nDOMAIN-SUFFIX,do25.gq,Proxy\nDOMAIN-SUFFIX,grammaly.com,Proxy\nDOMAIN-SUFFIX,mikanani.me,Proxy\nDOMAIN-SUFFIX,1680218.com,Proxy\nDOMAIN-SUFFIX,www.365-aa.xyz,Proxy\nDOMAIN-SUFFIX,www.epsilonsystems.com,Proxy\nDOMAIN-SUFFIX,reassess.com.br,Proxy\nDOMAIN-SUFFIX,www.airtel.com,Proxy\nDOMAIN-SUFFIX,porzo.com,Proxy\nDOMAIN-SUFFIX,bonbonme.com,Proxy\nDOMAIN-SUFFIX,www.betterworldbooks.com,Proxy\nDOMAIN-SUFFIX,canada.com,Proxy\nDOMAIN-SUFFIX,ipfs.anonymize.com,Proxy\nDOMAIN-SUFFIX,webmail.telus.net,Proxy\nDOMAIN-SUFFIX,www.ienergy1.com,Proxy\nDOMAIN-SUFFIX,0youtube.com,Proxy\nDOMAIN-SUFFIX,gofundme.com,Proxy\nDOMAIN-SUFFIX,hhh-av.com,Proxy\nDOMAIN-SUFFIX,exonet.net,Proxy\nDOMAIN-SUFFIX,owzg.gl.grr.io,Proxy\nDOMAIN-SUFFIX,registry.yarnpkg.com,Proxy\nDOMAIN-SUFFIX,cloudfunctions.net,Proxy\nDOMAIN-SUFFIX,oac.cdlib.org,Proxy\nDOMAIN-SUFFIX,www.churchmilitant.com,Proxy\nDOMAIN-SUFFIX,lvmpd.com,Proxy\nDOMAIN-SUFFIX,www.fuyin.tv,Proxy\nDOMAIN-SUFFIX,www.resistchina.org,Proxy\nDOMAIN-SUFFIX,jlc01.com,Proxy\nDOMAIN-SUFFIX,asian18tube.com,Proxy\nDOMAIN-SUFFIX,load.to,Proxy\nDOMAIN-SUFFIX,www.vpnour.com,Proxy\nDOMAIN-SUFFIX,vpncap.com,Proxy\nDOMAIN-SUFFIX,www.themalaymailonline.com,Proxy\nDOMAIN-SUFFIX,is-a-furry.org,Proxy\nDOMAIN-SUFFIX,w3511.com,Proxy\nDOMAIN-SUFFIX,www.hg888.com,Proxy\nDOMAIN-SUFFIX,webanonymizer.org,Proxy\nDOMAIN-SUFFIX,vft.com.tw,Proxy\nDOMAIN-SUFFIX,gloria.tv,Proxy\nDOMAIN-SUFFIX,www.gohappy.com.tw,Proxy\nDOMAIN-SUFFIX,www.kuckucktv.de,Proxy\nDOMAIN-SUFFIX,fanqiang.org,Proxy\nDOMAIN-SUFFIX,www.zhaochenmo.com,Proxy\nDOMAIN-SUFFIX,www.cultdeadcow.com,Proxy\nDOMAIN-SUFFIX,www.groove.co,Proxy\nDOMAIN-SUFFIX,insideoutchina.blogspot.hk,Proxy\nDOMAIN-SUFFIX,www.astroawani.com,Proxy\nDOMAIN-SUFFIX,www.vpngate.com,Proxy\nDOMAIN-SUFFIX,jollytime.com,Proxy\nDOMAIN-SUFFIX,arteviva.ch,Proxy\nDOMAIN-SUFFIX,earth2.io,Proxy\nDOMAIN-SUFFIX,today33.flnet.org,Proxy\nDOMAIN-SUFFIX,goody25.com,Proxy\nDOMAIN-SUFFIX,placemix.com,Proxy\nDOMAIN-SUFFIX,633ttt.com,Proxy\nDOMAIN-SUFFIX,lutube.cc,Proxy\nDOMAIN-SUFFIX,pinterest.co.kr,Proxy\nDOMAIN-SUFFIX,notproductive.com,Proxy\nDOMAIN-SUFFIX,magento.com,Proxy\nDOMAIN-SUFFIX,www.pinterest.es,Proxy\nDOMAIN-SUFFIX,google.com.pa,Proxy\nDOMAIN-SUFFIX,nu-skin-shop.firebaseio.com,Proxy\nDOMAIN-SUFFIX,www.w88jin.com,Proxy\nDOMAIN-SUFFIX,16560077.com,Proxy\nDOMAIN-SUFFIX,cyberghost.natado.com,Proxy\nDOMAIN-SUFFIX,1by-day.com,Proxy\nDOMAIN-SUFFIX,www.sqlspace.com,Proxy\nDOMAIN-SUFFIX,www.ptw8.com,Proxy\nDOMAIN-SUFFIX,vipyues.com,Proxy\nDOMAIN-SUFFIX,2newcenturynet.blogspot.ae,Proxy\nDOMAIN-SUFFIX,www.lightnovel.cn,Proxy\nDOMAIN-SUFFIX,solv.finance,Proxy\nDOMAIN-SUFFIX,caaviar.appengine.valeo.com,Proxy\nDOMAIN-SUFFIX,32.etowns.net,Proxy\nDOMAIN-SUFFIX,mmmca.com,Proxy\nDOMAIN-SUFFIX,c.box3.bid,Proxy\nDOMAIN-SUFFIX,onion.xor.sc,Proxy\nDOMAIN-SUFFIX,www.sipartnersglobal.com,Proxy\nDOMAIN-SUFFIX,invidious.silur.me,Proxy\nDOMAIN-SUFFIX,nflxvideo.net,Proxy\nDOMAIN-SUFFIX,www.orgyenkhamdroling.ca,Proxy\nDOMAIN-SUFFIX,bbs4.2djgame.net,Proxy\nDOMAIN-SUFFIX,share.youthwant.com.tw,Proxy\nDOMAIN-SUFFIX,sex18.xyz,Proxy\nDOMAIN-SUFFIX,www.seattlechinesepost.com,Proxy\nDOMAIN-SUFFIX,www.vpncup.biz,Proxy\nDOMAIN-SUFFIX,faluninfo.nl,Proxy\nDOMAIN-SUFFIX,koumori51.html.xdomain.jp,Proxy\nDOMAIN-SUFFIX,bx.in.th,Proxy\nDOMAIN-SUFFIX,research.gavekal.com,Proxy\nDOMAIN-SUFFIX,979568.com,Proxy\nDOMAIN-SUFFIX,savevid.com,Proxy\nDOMAIN-SUFFIX,www.indiatoday.in,Proxy\nDOMAIN-SUFFIX,www.yahoo.co.id,Proxy\nDOMAIN-SUFFIX,sdk.fra-01.braze.eu,Proxy\nDOMAIN-SUFFIX,macauley.us,Proxy\nDOMAIN-SUFFIX,ssl-proxy.my-addr.org,Proxy\nDOMAIN-SUFFIX,gloriaadams.ml,Proxy\nDOMAIN-SUFFIX,ccthere.com,Proxy\nDOMAIN-SUFFIX,tc88.com,Proxy\nDOMAIN-SUFFIX,www.ccccn.org,Proxy\nDOMAIN-SUFFIX,d21c6awi91d66g.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.topvpnreviews.com,Proxy\nDOMAIN-SUFFIX,fulibl.org,Proxy\nDOMAIN-SUFFIX,t1ent.co.kr,Proxy\nDOMAIN-SUFFIX,www.dcfe.com,Proxy\nDOMAIN-SUFFIX,jm-comic3.art,Proxy\nDOMAIN-SUFFIX,www.solomontimes.com,Proxy\nDOMAIN-SUFFIX,a771.dscq.akamai.net,Proxy\nDOMAIN-SUFFIX,am808.com,Proxy\nDOMAIN-SUFFIX,www.adsmt4.com,Proxy\nDOMAIN-SUFFIX,listed.to,Proxy\nDOMAIN-SUFFIX,mywww.biz,Proxy\nDOMAIN-SUFFIX,volatile.bz,Proxy\nDOMAIN-SUFFIX,vwin365.com,Proxy\nDOMAIN-SUFFIX,1024.917rbb.pw,Proxy\nDOMAIN-SUFFIX,jcomic.xyz,Proxy\nDOMAIN-SUFFIX,d161muecmaw7zv.cloudfront.net,Proxy\nDOMAIN-SUFFIX,fulione.com,Proxy\nDOMAIN-SUFFIX,vegasred.com,Proxy\nDOMAIN-SUFFIX,eidenvall.se,Proxy\nDOMAIN-SUFFIX,www.xingdaili.com,Proxy\nDOMAIN-SUFFIX,teachablemachine.withgoogle.com,Proxy\nDOMAIN-SUFFIX,amh1111.com,Proxy\nDOMAIN-SUFFIX,www.cowraguardian.com.au,Proxy\nDOMAIN-SUFFIX,qloudie.com,Proxy\nDOMAIN-SUFFIX,webinars-api.cyberlink.com,Proxy\nDOMAIN-SUFFIX,ss.ishadowx.com,Proxy\nDOMAIN-SUFFIX,chatroom.sk9901.com,Proxy\nDOMAIN-SUFFIX,smutty.com,Proxy\nDOMAIN-SUFFIX,xpresit.net,Proxy\nDOMAIN-SUFFIX,vns001.cc,Proxy\nDOMAIN-SUFFIX,upsc.co.uk,Proxy\nDOMAIN-SUFFIX,w88club.com,Proxy\nDOMAIN-SUFFIX,www.earlmiller.com,Proxy\nDOMAIN-SUFFIX,tw.aboluowang.com,Proxy\nDOMAIN-SUFFIX,ganjing.com,Proxy\nDOMAIN-SUFFIX,nitter.freedit.eu,Proxy\nDOMAIN-SUFFIX,d3cfzu4vlvtoqp.cloudfront.net,Proxy\nDOMAIN-SUFFIX,pauldawson.us,Proxy\nDOMAIN-SUFFIX,ns02.info,Proxy\nDOMAIN-SUFFIX,blog.isakira.com,Proxy\nDOMAIN-SUFFIX,advanscene.com,Proxy\nDOMAIN-SUFFIX,smdingenieria.cl,Proxy\nDOMAIN-SUFFIX,www.cincainews.com,Proxy\nDOMAIN-SUFFIX,gist.githubusercontent.com,Proxy\nDOMAIN-SUFFIX,cutscenes.net,Proxy\nDOMAIN-SUFFIX,nerdculture.de,Proxy\nDOMAIN-SUFFIX,www.yobet.com,Proxy\nDOMAIN-SUFFIX,meow.idv.tw,Proxy\nDOMAIN-SUFFIX,freefq.com,Proxy\nDOMAIN-SUFFIX,reyval.com.mx,Proxy\nDOMAIN-SUFFIX,solidaritywithtibet.org,Proxy\nDOMAIN-SUFFIX,d.tube,Proxy\nDOMAIN-SUFFIX,convio.net,Proxy\nDOMAIN-SUFFIX,www.proxylord.com,Proxy\nDOMAIN-SUFFIX,shoppix.es,Proxy\nDOMAIN-SUFFIX,am1470.com,Proxy\nDOMAIN-SUFFIX,net-fits.pro,Proxy\nDOMAIN-SUFFIX,www.cmd368.com,Proxy\nDOMAIN-SUFFIX,www.eselami.com,Proxy\nDOMAIN-SUFFIX,newsletter.laborinfocn.com,Proxy\nDOMAIN-SUFFIX,matthiasdohm.de,Proxy\nDOMAIN-SUFFIX,eightcap-ch.com,Proxy\nDOMAIN-SUFFIX,kone.com,Proxy\nDOMAIN-SUFFIX,www.icde.org,Proxy\nDOMAIN-SUFFIX,myav.com.tw,Proxy\nDOMAIN-SUFFIX,www.kimo.com.tw,Proxy\nDOMAIN-SUFFIX,funf.tw,Proxy\nDOMAIN-SUFFIX,tempsreel.nouvelobs.com,Proxy\nDOMAIN-SUFFIX,fd2z.cn,Proxy\nDOMAIN-SUFFIX,xxxlog.co,Proxy\nDOMAIN-SUFFIX,rts.ch,Proxy\nDOMAIN-SUFFIX,filecoin.io,Proxy\nDOMAIN-SUFFIX,traffichaus.com,Proxy\nDOMAIN-SUFFIX,reeve.xyz,Proxy\nDOMAIN-SUFFIX,instaforex.org,Proxy\nDOMAIN-SUFFIX,telecom-cafe.com,Proxy\nDOMAIN-SUFFIX,www.farmaid.org,Proxy\nDOMAIN-SUFFIX,privatoria.net,Proxy\nDOMAIN-SUFFIX,www.mvitraining.com,Proxy\nDOMAIN-SUFFIX,www.anonymousvpn.org,Proxy\nDOMAIN-SUFFIX,zd.net,Proxy\nDOMAIN-SUFFIX,hn-ru.com,Proxy\nDOMAIN-SUFFIX,pen-international.org,Proxy\nDOMAIN-SUFFIX,iask.ca,Proxy\nDOMAIN-SUFFIX,prolink.pl,Proxy\nDOMAIN-SUFFIX,64memo.com,Proxy\nDOMAIN-SUFFIX,www.whatscap.com,Proxy\nDOMAIN-SUFFIX,conoha.jp,Proxy\nDOMAIN-SUFFIX,www.pttweb.cc,Proxy\nDOMAIN-SUFFIX,www.fubooks.com,Proxy\nDOMAIN-SUFFIX,www10.eyny.com,Proxy\nDOMAIN-SUFFIX,b0ne.com,Proxy\nDOMAIN-SUFFIX,blog.naver.com,Proxy\nDOMAIN-SUFFIX,alphaporno.com,Proxy\nDOMAIN-SUFFIX,237.com,Proxy\nDOMAIN-SUFFIX,www.yujiangshan.com,Proxy\nDOMAIN-SUFFIX,b5535.com,Proxy\nDOMAIN-SUFFIX,islahhaber.net,Proxy\nDOMAIN-SUFFIX,ntd.com,Proxy\nDOMAIN-SUFFIX,en.wikipedia-on-ipfs.org,Proxy\nDOMAIN-SUFFIX,dns.sb,Proxy\nDOMAIN-SUFFIX,read9891.github.io,Proxy\nDOMAIN-SUFFIX,mod.red,Proxy\nDOMAIN-SUFFIX,bjl2033.com,Proxy\nDOMAIN-SUFFIX,kingkong.com.tw,Proxy\nDOMAIN-SUFFIX,www.dxlive.com,Proxy\nDOMAIN-SUFFIX,flikr.com,Proxy\nDOMAIN-SUFFIX,freeyoutubeproxy.net,Proxy\nDOMAIN-SUFFIX,peltsi.fi,Proxy\nDOMAIN-SUFFIX,sextube-6.com,Proxy\nDOMAIN-SUFFIX,x78aa.com,Proxy\nDOMAIN-SUFFIX,www.quilt.idv.tw,Proxy\nDOMAIN-SUFFIX,pornyeah.com,Proxy\nDOMAIN-SUFFIX,popvote.hk,Proxy\nDOMAIN-SUFFIX,0007777.com,Proxy\nDOMAIN-SUFFIX,potato.im,Proxy\nDOMAIN-SUFFIX,chinesesoup.com,Proxy\nDOMAIN-SUFFIX,weebly.com,Proxy\nDOMAIN-SUFFIX,tlc122.com,Proxy\nDOMAIN-SUFFIX,chat.yike-cited.com,Proxy\nDOMAIN-SUFFIX,www.hjhs222.com,Proxy\nDOMAIN-SUFFIX,www.wan111.com,Proxy\nDOMAIN-SUFFIX,md-cc.org,Proxy\nDOMAIN-SUFFIX,timeslive.co.za,Proxy\nDOMAIN-SUFFIX,www.141tube.com,Proxy\nDOMAIN-SUFFIX,www.copymanga.site,Proxy\nDOMAIN-SUFFIX,eo.demerzel.org,Proxy\nDOMAIN-SUFFIX,proxied.org,Proxy\nDOMAIN-SUFFIX,centerforsecuritypolicy.org,Proxy\nDOMAIN-SUFFIX,yzc91.com,Proxy\nDOMAIN-SUFFIX,mis1.zhis.cc,Proxy\nDOMAIN-SUFFIX,nakedsecurity.sophos.com,Proxy\nDOMAIN-SUFFIX,sokmil.com,Proxy\nDOMAIN-SUFFIX,trojan-tutor.github.io,Proxy\nDOMAIN-SUFFIX,www.thehentaiworld.com,Proxy\nDOMAIN-SUFFIX,www.grjsq.biz,Proxy\nDOMAIN-SUFFIX,busroig.com,Proxy\nDOMAIN-SUFFIX,51153322.com,Proxy\nDOMAIN-SUFFIX,lust18.cc,Proxy\nDOMAIN-SUFFIX,huobi.me,Proxy\nDOMAIN-SUFFIX,video.aol.co.uk,Proxy\nDOMAIN-SUFFIX,arunachalpradesh.gov.in,Proxy\nDOMAIN-SUFFIX,d14ufge6rsnlpy.cloudfront.net,Proxy\nDOMAIN-SUFFIX,adsense.google.cn,Proxy\nDOMAIN-SUFFIX,discuss.com.hk,Proxy\nDOMAIN-SUFFIX,video-api.yql.yahoo.com,Proxy\nDOMAIN-SUFFIX,mtgirl.pw,Proxy\nDOMAIN-SUFFIX,www.eat-travel.com.tw,Proxy\nDOMAIN-SUFFIX,46.ddnsking.com,Proxy\nDOMAIN-SUFFIX,www.cesnur.org,Proxy\nDOMAIN-SUFFIX,21ffd1.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,religioustolerance.com,Proxy\nDOMAIN-SUFFIX,18comic1.one,Proxy\nDOMAIN-SUFFIX,www.bt737.com,Proxy\nDOMAIN-SUFFIX,mm-11.com,Proxy\nDOMAIN-SUFFIX,sangunia.webuda.com,Proxy\nDOMAIN-SUFFIX,dalailamajapanese.com,Proxy\nDOMAIN-SUFFIX,d187uwkna1fqb9.cloudfront.net,Proxy\nDOMAIN-SUFFIX,bf8666.com,Proxy\nDOMAIN-SUFFIX,is-a-therapist.com,Proxy\nDOMAIN-SUFFIX,carrefourtw.inone.useinsider.com,Proxy\nDOMAIN-SUFFIX,oxfordscholarship.com,Proxy\nDOMAIN-SUFFIX,falundafa.gr,Proxy\nDOMAIN-SUFFIX,www.hddolby.com,Proxy\nDOMAIN-SUFFIX,onevps.com,Proxy\nDOMAIN-SUFFIX,www.echo-online.de,Proxy\nDOMAIN-SUFFIX,metavideos.com,Proxy\nDOMAIN-SUFFIX,www.twitcasting.tv,Proxy\nDOMAIN-SUFFIX,pincongbackup.github.io,Proxy\nDOMAIN-SUFFIX,lea.flnet.org,Proxy\nDOMAIN-SUFFIX,www.twitlonger.com,Proxy\nDOMAIN-SUFFIX,beaconjuice.com,Proxy\nDOMAIN-SUFFIX,news.tvb.com,Proxy\nDOMAIN-SUFFIX,jp01-28.ssv4.net,Proxy\nDOMAIN-SUFFIX,www.leancloud.cn,Proxy\nDOMAIN-SUFFIX,merit-times.com,Proxy\nDOMAIN-SUFFIX,joinbbs.net,Proxy\nDOMAIN-SUFFIX,curlie.org,Proxy\nDOMAIN-SUFFIX,www.xf833.com,Proxy\nDOMAIN-SUFFIX,www.tangeng.com.tw,Proxy\nDOMAIN-SUFFIX,tube.cadence.moe,Proxy\nDOMAIN-SUFFIX,freeoda.com,Proxy\nDOMAIN-SUFFIX,fuchsia.dev,Proxy\nDOMAIN-SUFFIX,www.ntz.de,Proxy\nDOMAIN-SUFFIX,d.sh22.us,Proxy\nDOMAIN-SUFFIX,8824440.com,Proxy\nDOMAIN-SUFFIX,www.secretosx.com,Proxy\nDOMAIN-SUFFIX,thelius.org,Proxy\nDOMAIN-SUFFIX,cs.syhwyh.com,Proxy\nDOMAIN-SUFFIX,twitch.tv,Proxy\nDOMAIN-SUFFIX,us01-7.ssv4.net,Proxy\nDOMAIN-SUFFIX,myavsuper.com,Proxy\nDOMAIN-SUFFIX,jv12s1190.tudouser.com,Proxy\nDOMAIN-SUFFIX,www.pornoshock.org,Proxy\nDOMAIN-SUFFIX,pp990.com,Proxy\nDOMAIN-SUFFIX,w9i8x3d5.stackpathcdn.com,Proxy\nDOMAIN-SUFFIX,zzw.dyndns.work,Proxy\nDOMAIN-SUFFIX,3ren.ca,Proxy\nDOMAIN-SUFFIX,spanking.wiki,Proxy\nDOMAIN-SUFFIX,www.materialplus.io,Proxy\nDOMAIN-SUFFIX,asianwomensfilm.de,Proxy\nDOMAIN-SUFFIX,dogfart.com,Proxy\nDOMAIN-SUFFIX,battle.gtasia777.com,Proxy\nDOMAIN-SUFFIX,cyberghost-vpn.updatestar.com,Proxy\nDOMAIN-SUFFIX,humanrights.org,Proxy\nDOMAIN-SUFFIX,546007.com,Proxy\nDOMAIN-SUFFIX,hihiforum.com,Proxy\nDOMAIN-SUFFIX,917.microcycas.com,Proxy\nDOMAIN-SUFFIX,animalzooporn.me,Proxy\nDOMAIN-SUFFIX,us.h2.dhcp.biz,Proxy\nDOMAIN-SUFFIX,10959.com,Proxy\nDOMAIN-SUFFIX,www.02902.com,Proxy\nDOMAIN-SUFFIX,chaterbate.com,Proxy\nDOMAIN-SUFFIX,theyoutube.com,Proxy\nDOMAIN-SUFFIX,is-an-engineer.com,Proxy\nDOMAIN-SUFFIX,ingeasy.cl,Proxy\nDOMAIN-SUFFIX,s.scss.pw,Proxy\nDOMAIN-SUFFIX,intporn.com,Proxy\nDOMAIN-SUFFIX,tibet.at,Proxy\nDOMAIN-SUFFIX,fuadfauzi.web.id,Proxy\nDOMAIN-SUFFIX,www.n56b.com,Proxy\nDOMAIN-SUFFIX,img.dlsite.jp,Proxy\nDOMAIN-SUFFIX,libertics.com.ar,Proxy\nDOMAIN-SUFFIX,club69.cc,Proxy\nDOMAIN-SUFFIX,www.assteenmouth.com,Proxy\nDOMAIN-SUFFIX,www.btkitty.net,Proxy\nDOMAIN-SUFFIX,blurb.com,Proxy\nDOMAIN-SUFFIX,myboooks.googlepages.com,Proxy\nDOMAIN-SUFFIX,xj6663.com,Proxy\nDOMAIN-SUFFIX,www.indexxx.com,Proxy\nDOMAIN-SUFFIX,caoporn.com,Proxy\nDOMAIN-SUFFIX,yingsuoss.com,Proxy\nDOMAIN-SUFFIX,hideme.ru,Proxy\nDOMAIN-SUFFIX,www.apug.org,Proxy\nDOMAIN-SUFFIX,fun88.com,Proxy\nDOMAIN-SUFFIX,www.365smfx.com,Proxy\nDOMAIN-SUFFIX,clementine-player.org,Proxy\nDOMAIN-SUFFIX,ck.css5.bid,Proxy\nDOMAIN-SUFFIX,qq.co.za,Proxy\nDOMAIN-SUFFIX,9428.com,Proxy\nDOMAIN-SUFFIX,www.coinx.ph,Proxy\nDOMAIN-SUFFIX,cheaperapp.work,Proxy\nDOMAIN-SUFFIX,www.the24.co.uk,Proxy\nDOMAIN-SUFFIX,www.codastory.com,Proxy\nDOMAIN-SUFFIX,andrewshomelabs.com,Proxy\nDOMAIN-SUFFIX,www.888.so,Proxy\nDOMAIN-SUFFIX,vpnninja.com,Proxy\nDOMAIN-SUFFIX,dyslexiala.com,Proxy\nDOMAIN-SUFFIX,d2ykmpy1pzss7q.cloudfront.net,Proxy\nDOMAIN-SUFFIX,chinaworker.info,Proxy\nDOMAIN-SUFFIX,www.dailyliberal.com.au,Proxy\nDOMAIN-SUFFIX,h5.017ld.com,Proxy\nDOMAIN-SUFFIX,h5.ldvip19.com,Proxy\nDOMAIN-SUFFIX,gourabpaul.com,Proxy\nDOMAIN-SUFFIX,mapxtv.site,Proxy\nDOMAIN-SUFFIX,crunchyroll.com,Proxy\nDOMAIN-SUFFIX,flyvpn.com,Proxy\nDOMAIN-SUFFIX,www.bendigoadvertiser.com.au,Proxy\nDOMAIN-SUFFIX,eco-visio.net,Proxy\nDOMAIN-SUFFIX,www.met-art.com,Proxy\nDOMAIN-SUFFIX,to.hacked.jp,Proxy\nDOMAIN-SUFFIX,www.78800a.com,Proxy\nDOMAIN-SUFFIX,vs8855.com,Proxy\nDOMAIN-SUFFIX,engavac.com,Proxy\nDOMAIN-SUFFIX,www.tablesgenerator.com,Proxy\nDOMAIN-SUFFIX,b49t.com,Proxy\nDOMAIN-SUFFIX,ffdy.cc,Proxy\nDOMAIN-SUFFIX,blog.klip.me,Proxy\nDOMAIN-SUFFIX,63kk.net,Proxy\nDOMAIN-SUFFIX,kenhk.org,Proxy\nDOMAIN-SUFFIX,www.picuki.com,Proxy\nDOMAIN-SUFFIX,pornhd.com,Proxy\nDOMAIN-SUFFIX,pornhubcasino.com,Proxy\nDOMAIN-SUFFIX,www.f88vip34.com,Proxy\nDOMAIN-SUFFIX,beauty.is,Proxy\nDOMAIN-SUFFIX,575bet.com,Proxy\nDOMAIN-SUFFIX,i818hk.com,Proxy\nDOMAIN-SUFFIX,nunaartaiwan.nl,Proxy\nDOMAIN-SUFFIX,bisipic.xyz,Proxy\nDOMAIN-SUFFIX,futurechinaforum.org,Proxy\nDOMAIN-SUFFIX,de-sci.org,Proxy\nDOMAIN-SUFFIX,doh.ibr.cs.tu-bs.de,Proxy\nDOMAIN-SUFFIX,7mvq.82.flnet.org,Proxy\nDOMAIN-SUFFIX,usa.edu.kg,Proxy\nDOMAIN-SUFFIX,deribit.com,Proxy\nDOMAIN-SUFFIX,hong.com,Proxy\nDOMAIN-SUFFIX,gzzt.org,Proxy\nDOMAIN-SUFFIX,youtube.it,Proxy\nDOMAIN-SUFFIX,www.gtja.com.hk,Proxy\nDOMAIN-SUFFIX,bm10000.com,Proxy\nDOMAIN-SUFFIX,sgswsetwetwtwt.ml,Proxy\nDOMAIN-SUFFIX,forum.raidcall.com.tw,Proxy\nDOMAIN-SUFFIX,selfie.id.au,Proxy\nDOMAIN-SUFFIX,thestar.com,Proxy\nDOMAIN-SUFFIX,runhomefast.com,Proxy\nDOMAIN-SUFFIX,www.p8862.com,Proxy\nDOMAIN-SUFFIX,f1.com,Proxy\nDOMAIN-SUFFIX,tibetexpress.net,Proxy\nDOMAIN-SUFFIX,www.juliuscentrum.nl,Proxy\nDOMAIN-SUFFIX,kingss.win,Proxy\nDOMAIN-SUFFIX,www.ek21.com,Proxy\nDOMAIN-SUFFIX,meizhong.report,Proxy\nDOMAIN-SUFFIX,www.emule-ed2k.com,Proxy\nDOMAIN-SUFFIX,comersalv.com.br,Proxy\nDOMAIN-SUFFIX,d1z871soab7j1m.cloudfront.net,Proxy\nDOMAIN-SUFFIX,fyt222.com,Proxy\nDOMAIN-SUFFIX,is-a-patsfan.org,Proxy\nDOMAIN-SUFFIX,www.edpuzzle.com,Proxy\nDOMAIN-SUFFIX,palacemoon.com,Proxy\nDOMAIN-SUFFIX,across-gfw.com,Proxy\nDOMAIN-SUFFIX,882110055.com,Proxy\nDOMAIN-SUFFIX,lemonde.fr,Proxy\nDOMAIN-SUFFIX,www.filecrop.com,Proxy\nDOMAIN-SUFFIX,huo360.com,Proxy\nDOMAIN-SUFFIX,bdsmforall.com,Proxy\nDOMAIN-SUFFIX,in01.icu,Proxy\nDOMAIN-SUFFIX,mynet.com,Proxy\nDOMAIN-SUFFIX,t.umblr.com,Proxy\nDOMAIN-SUFFIX,www.doctorofcredit.com,Proxy\nDOMAIN-SUFFIX,sejie.com,Proxy\nDOMAIN-SUFFIX,us.twitcasting.tv,Proxy\nDOMAIN-SUFFIX,labour.org.hk,Proxy\nDOMAIN-SUFFIX,xianzhe001.com,Proxy\nDOMAIN-SUFFIX,paper.li,Proxy\nDOMAIN-SUFFIX,quick.likeso.ml,Proxy\nDOMAIN-SUFFIX,reuters.es,Proxy\nDOMAIN-SUFFIX,download.iranville.com,Proxy\nDOMAIN-SUFFIX,www.ompartners.com,Proxy\nDOMAIN-SUFFIX,animalporn.tv,Proxy\nDOMAIN-SUFFIX,pgi.com,Proxy\nDOMAIN-SUFFIX,program-think.blogspot.ca,Proxy\nDOMAIN-SUFFIX,forum.omy.sg,Proxy\nDOMAIN-SUFFIX,bway889.com,Proxy\nDOMAIN-SUFFIX,www.aacrix.com,Proxy\nDOMAIN-SUFFIX,xinbi568.com,Proxy\nDOMAIN-SUFFIX,www.javlibrary.com,Proxy\nDOMAIN-SUFFIX,gscssr.net,Proxy\nDOMAIN-SUFFIX,eracom.com.tw,Proxy\nDOMAIN-SUFFIX,dynamodb.ap-northeast-1.amazonaws.com,Proxy\nDOMAIN-SUFFIX,bw68vip.com,Proxy\nDOMAIN-SUFFIX,hinet.net,Proxy\nDOMAIN-SUFFIX,lobsangwangyal.com,Proxy\nDOMAIN-SUFFIX,www.w8b96.com,Proxy\nDOMAIN-SUFFIX,usmc.mil,Proxy\nDOMAIN-SUFFIX,www.popkontv.com,Proxy\nDOMAIN-SUFFIX,www.google.gl,Proxy\nDOMAIN-SUFFIX,quetzalcoatl-relays.org,Proxy\nDOMAIN-SUFFIX,res.web.id,Proxy\nDOMAIN-SUFFIX,www.nvtongzhisheng.org,Proxy\nDOMAIN-SUFFIX,cstudiohd.com,Proxy\nDOMAIN-SUFFIX,proxyweb.com.es,Proxy\nDOMAIN-SUFFIX,forum.omegarealm.com,Proxy\nDOMAIN-SUFFIX,www.hawkesburygazette.com.au,Proxy\nDOMAIN-SUFFIX,exness.com,Proxy\nDOMAIN-SUFFIX,cs368.com,Proxy\nDOMAIN-SUFFIX,tyvpn.com,Proxy\nDOMAIN-SUFFIX,rodzinnawiez.pl,Proxy\nDOMAIN-SUFFIX,sherpasgroup.cl,Proxy\nDOMAIN-SUFFIX,adaptiveco.com,Proxy\nDOMAIN-SUFFIX,kontiki.com,Proxy\nDOMAIN-SUFFIX,www.dropitto.me,Proxy\nDOMAIN-SUFFIX,thongdreams.com,Proxy\nDOMAIN-SUFFIX,amxj5588.com,Proxy\nDOMAIN-SUFFIX,chrdnet.com,Proxy\nDOMAIN-SUFFIX,www.swr.de,Proxy\nDOMAIN-SUFFIX,xn--rs8h.tk,Proxy\nDOMAIN-SUFFIX,listorious.com,Proxy\nDOMAIN-SUFFIX,www.digifinex.com,Proxy\nDOMAIN-SUFFIX,www.yundong.idv.tw,Proxy\nDOMAIN-SUFFIX,porn5.com,Proxy\nDOMAIN-SUFFIX,sdyun.cc,Proxy\nDOMAIN-SUFFIX,rbetway88.agent1818.com,Proxy\nDOMAIN-SUFFIX,www.inmondadori.it,Proxy\nDOMAIN-SUFFIX,027.dhcp.biz,Proxy\nDOMAIN-SUFFIX,www.shihguang.org.tw,Proxy\nDOMAIN-SUFFIX,sylvainlavoie.ca,Proxy\nDOMAIN-SUFFIX,giftube.com,Proxy\nDOMAIN-SUFFIX,www.mgscl123.com,Proxy\nDOMAIN-SUFFIX,endlessmatches.com,Proxy\nDOMAIN-SUFFIX,www.boards.ie,Proxy\nDOMAIN-SUFFIX,enigma.im,Proxy\nDOMAIN-SUFFIX,marxist.tw,Proxy\nDOMAIN-SUFFIX,chatbuzzer.com,Proxy\nDOMAIN-SUFFIX,www.fatlai.com,Proxy\nDOMAIN-SUFFIX,www.asasmr.com,Proxy\nDOMAIN-SUFFIX,zh.coursera.org,Proxy\nDOMAIN-SUFFIX,twitmania.com,Proxy\nDOMAIN-SUFFIX,api.arcadia.pncle8.com,Proxy\nDOMAIN-SUFFIX,globalmuseumoncommunism.org,Proxy\nDOMAIN-SUFFIX,www.bbcitv.site,Proxy\nDOMAIN-SUFFIX,leizhiyuan.github.io,Proxy\nDOMAIN-SUFFIX,tryclimb.net,Proxy\nDOMAIN-SUFFIX,9877y.com,Proxy\nDOMAIN-SUFFIX,daveproxy.co.uk,Proxy\nDOMAIN-SUFFIX,yahoo.com.hk,Proxy\nDOMAIN-SUFFIX,sumrando.com,Proxy\nDOMAIN-SUFFIX,sanalpazar.com,Proxy\nDOMAIN-SUFFIX,av777.tv,Proxy\nDOMAIN-SUFFIX,haoel.github.io,Proxy\nDOMAIN-SUFFIX,widget.adplan7.com,Proxy\nDOMAIN-SUFFIX,www.avoidr.com,Proxy\nDOMAIN-SUFFIX,website.informer.com,Proxy\nDOMAIN-SUFFIX,816.microcycas.com,Proxy\nDOMAIN-SUFFIX,unblock-us.com,Proxy\nDOMAIN-SUFFIX,245.slyip.net,Proxy\nDOMAIN-SUFFIX,bdx.chatapp.win,Proxy\nDOMAIN-SUFFIX,cordcloud.cc,Proxy\nDOMAIN-SUFFIX,2805s.com,Proxy\nDOMAIN-SUFFIX,www.ultrabestproxy.com,Proxy\nDOMAIN-SUFFIX,catch22.net,Proxy\nDOMAIN-SUFFIX,ida.org,Proxy\nDOMAIN-SUFFIX,m.yyzb.live,Proxy\nDOMAIN-SUFFIX,pentoy.hk,Proxy\nDOMAIN-SUFFIX,uncyclopedia.tw,Proxy\nDOMAIN-SUFFIX,00899d.com,Proxy\nDOMAIN-SUFFIX,www.fwsgps.edu.hk,Proxy\nDOMAIN-SUFFIX,glo.li,Proxy\nDOMAIN-SUFFIX,nyt5.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,tubenza.com,Proxy\nDOMAIN-SUFFIX,shopbetreiber-blog.de,Proxy\nDOMAIN-SUFFIX,userapi.nytlog.com,Proxy\nDOMAIN-SUFFIX,attackmen.com,Proxy\nDOMAIN-SUFFIX,lee.flnet.org,Proxy\nDOMAIN-SUFFIX,dna2t2kyn7c1r.cloudfront.net,Proxy\nDOMAIN-SUFFIX,okex.com,Proxy\nDOMAIN-SUFFIX,763.microcycas.com,Proxy\nDOMAIN-SUFFIX,hg2200.com,Proxy\nDOMAIN-SUFFIX,laowaixiaohan.bloguje.cz,Proxy\nDOMAIN-SUFFIX,www.everforo.com,Proxy\nDOMAIN-SUFFIX,eta.3d-game.com,Proxy\nDOMAIN-SUFFIX,cs037.com,Proxy\nDOMAIN-SUFFIX,i-cable.com,Proxy\nDOMAIN-SUFFIX,mk16.de,Proxy\nDOMAIN-SUFFIX,xmvpn.com,Proxy\nDOMAIN-SUFFIX,blog.iruo.cc,Proxy\nDOMAIN-SUFFIX,caribbeancom.com,Proxy\nDOMAIN-SUFFIX,voamusicmix.net,Proxy\nDOMAIN-SUFFIX,www.bajie123.com,Proxy\nDOMAIN-SUFFIX,scientology.de,Proxy\nDOMAIN-SUFFIX,fosunhani.com,Proxy\nDOMAIN-SUFFIX,www.707xh.com,Proxy\nDOMAIN-SUFFIX,makerdao.com,Proxy\nDOMAIN-SUFFIX,24x7servicecenter.com,Proxy\nDOMAIN-SUFFIX,finnciti.com,Proxy\nDOMAIN-SUFFIX,ma-bimbo.com,Proxy\nDOMAIN-SUFFIX,kuniao.com,Proxy\nDOMAIN-SUFFIX,stonesriver.org,Proxy\nDOMAIN-SUFFIX,money.udn.com,Proxy\nDOMAIN-SUFFIX,yesasia.com,Proxy\nDOMAIN-SUFFIX,coolporn7.com,Proxy\nDOMAIN-SUFFIX,bloglovin.com,Proxy\nDOMAIN-SUFFIX,d25sjojy31mnh6.cloudfront.net,Proxy\nDOMAIN-SUFFIX,okexcn.com,Proxy\nDOMAIN-SUFFIX,phreedom.club,Proxy\nDOMAIN-SUFFIX,exhentai.org,Proxy\nDOMAIN-SUFFIX,pornflip.com,Proxy\nDOMAIN-SUFFIX,torrentz2.is,Proxy\nDOMAIN-SUFFIX,amoiist.com,Proxy\nDOMAIN-SUFFIX,gtdb.to,Proxy\nDOMAIN-SUFFIX,www.234k7.com,Proxy\nDOMAIN-SUFFIX,al-qimmah.net,Proxy\nDOMAIN-SUFFIX,hxwq.org,Proxy\nDOMAIN-SUFFIX,d2hx45h2v0extv.cloudfront.net,Proxy\nDOMAIN-SUFFIX,peopo.org,Proxy\nDOMAIN-SUFFIX,searx.fmac.xyz,Proxy\nDOMAIN-SUFFIX,c2.flnet.org,Proxy\nDOMAIN-SUFFIX,psrcorp.net,Proxy\nDOMAIN-SUFFIX,b82.tv,Proxy\nDOMAIN-SUFFIX,d2cku5cz0anyt3.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.fuhuimkt.com,Proxy\nDOMAIN-SUFFIX,bbs.sex169.xyz,Proxy\nDOMAIN-SUFFIX,gob.spacetechnology.net,Proxy\nDOMAIN-SUFFIX,hentai.tv,Proxy\nDOMAIN-SUFFIX,lsmwebcast.com,Proxy\nDOMAIN-SUFFIX,nsfwyoutube.com,Proxy\nDOMAIN-SUFFIX,www.theme.xyz,Proxy\nDOMAIN-SUFFIX,mefound.com,Proxy\nDOMAIN-SUFFIX,b-ok.com,Proxy\nDOMAIN-SUFFIX,pub.dartlang.org,Proxy\nDOMAIN-SUFFIX,google.com.hk,Proxy\nDOMAIN-SUFFIX,cvhs.csd509j.net,Proxy\nDOMAIN-SUFFIX,tsna.com.tw,Proxy\nDOMAIN-SUFFIX,5222575.com,Proxy\nDOMAIN-SUFFIX,usinfo.state.gov,Proxy\nDOMAIN-SUFFIX,lmb.betway118.com,Proxy\nDOMAIN-SUFFIX,wanderinghorse.net,Proxy\nDOMAIN-SUFFIX,coder.si,Proxy\nDOMAIN-SUFFIX,ivacykodi.com,Proxy\nDOMAIN-SUFFIX,libreddit.nl,Proxy\nDOMAIN-SUFFIX,www.techradar.com,Proxy\nDOMAIN-SUFFIX,www.hurriyet.com.tr,Proxy\nDOMAIN-SUFFIX,www.tibetrightscollective.in,Proxy\nDOMAIN-SUFFIX,cybersecurity.masto.host,Proxy\nDOMAIN-SUFFIX,www.aquaproxy.net,Proxy\nDOMAIN-SUFFIX,static01.nyt.com,Proxy\nDOMAIN-SUFFIX,aojiao.org,Proxy\nDOMAIN-SUFFIX,javgiga.com,Proxy\nDOMAIN-SUFFIX,ustream.tv,Proxy\nDOMAIN-SUFFIX,e.gov.kw,Proxy\nDOMAIN-SUFFIX,mdqd02.com,Proxy\nDOMAIN-SUFFIX,psmag.com,Proxy\nDOMAIN-SUFFIX,1396b.com,Proxy\nDOMAIN-SUFFIX,2.hdd2.host,Proxy\nDOMAIN-SUFFIX,doomdns.com,Proxy\nDOMAIN-SUFFIX,www.buda.idv.tw,Proxy\nDOMAIN-SUFFIX,3583k.com,Proxy\nDOMAIN-SUFFIX,www.idowa.de,Proxy\nDOMAIN-SUFFIX,voacambodia.com,Proxy\nDOMAIN-SUFFIX,qgirl.com.tw,Proxy\nDOMAIN-SUFFIX,behance.net,Proxy\nDOMAIN-SUFFIX,a365.vip,Proxy\nDOMAIN-SUFFIX,rferl.org,Proxy\nDOMAIN-SUFFIX,twiter.com,Proxy\nDOMAIN-SUFFIX,www.miccc.com.tw,Proxy\nDOMAIN-SUFFIX,lindenboom.be,Proxy\nDOMAIN-SUFFIX,agencias.renfe.com,Proxy\nDOMAIN-SUFFIX,oc.com.ar,Proxy\nDOMAIN-SUFFIX,beta.usejump.com,Proxy\nDOMAIN-SUFFIX,2047.name,Proxy\nDOMAIN-SUFFIX,www.0setang.top,Proxy\nDOMAIN-SUFFIX,www.taiwan-pharma.org.tw,Proxy\nDOMAIN-SUFFIX,limbopro.xyz,Proxy\nDOMAIN-SUFFIX,c3lingxiu.org,Proxy\nDOMAIN-SUFFIX,www.jbo311.com,Proxy\nDOMAIN-SUFFIX,seeres.com,Proxy\nDOMAIN-SUFFIX,www.alwaysdata.com,Proxy\nDOMAIN-SUFFIX,egu72.xyz,Proxy\nDOMAIN-SUFFIX,www.vid2c.com,Proxy\nDOMAIN-SUFFIX,g2.cctvgeo.akadns.net,Proxy\nDOMAIN-SUFFIX,chinaweb.bsgroup.com.hk,Proxy\nDOMAIN-SUFFIX,www.f88vip25.com,Proxy\nDOMAIN-SUFFIX,lookpic.com,Proxy\nDOMAIN-SUFFIX,www.bibox.com,Proxy\nDOMAIN-SUFFIX,lslk.org,Proxy\nDOMAIN-SUFFIX,iqq2.me,Proxy\nDOMAIN-SUFFIX,pandapow.co,Proxy\nDOMAIN-SUFFIX,xvpn.io,Proxy\nDOMAIN-SUFFIX,nae.3d-game.com,Proxy\nDOMAIN-SUFFIX,mrbonus.com,Proxy\nDOMAIN-SUFFIX,tracfone.com,Proxy\nDOMAIN-SUFFIX,pu0038.com,Proxy\nDOMAIN-SUFFIX,bway882338.com,Proxy\nDOMAIN-SUFFIX,www.fdd.org,Proxy\nDOMAIN-SUFFIX,glory-amphibian-43c.notion.site,Proxy\nDOMAIN-SUFFIX,scholarships.com,Proxy\nDOMAIN-SUFFIX,chito.com.mx,Proxy\nDOMAIN-SUFFIX,www.overdaily.org,Proxy\nDOMAIN-SUFFIX,cdn.goldpay.com,Proxy\nDOMAIN-SUFFIX,cash.tbet88.com,Proxy\nDOMAIN-SUFFIX,avmoo.cyou,Proxy\nDOMAIN-SUFFIX,xn--p8j9a0d9c9a.xn--q9jyb4c,Proxy\nDOMAIN-SUFFIX,destiny.pro,Proxy\nDOMAIN-SUFFIX,38850000.com,Proxy\nDOMAIN-SUFFIX,namkha.org,Proxy\nDOMAIN-SUFFIX,apk.support,Proxy\nDOMAIN-SUFFIX,cotizalia.com,Proxy\nDOMAIN-SUFFIX,inien.com,Proxy\nDOMAIN-SUFFIX,www.powx-russia.com,Proxy\nDOMAIN-SUFFIX,nav.dj0020.com,Proxy\nDOMAIN-SUFFIX,reachadvisory.cl,Proxy\nDOMAIN-SUFFIX,oglobo.com.br,Proxy\nDOMAIN-SUFFIX,is-a-hunter.com,Proxy\nDOMAIN-SUFFIX,telegra.ph,Proxy\nDOMAIN-SUFFIX,asiafriendfinder.com,Proxy\nDOMAIN-SUFFIX,www.lesechos.fr,Proxy\nDOMAIN-SUFFIX,www.maplin.com,Proxy\nDOMAIN-SUFFIX,sd.domain888.pw,Proxy\nDOMAIN-SUFFIX,southeastasianfood.about.com,Proxy\nDOMAIN-SUFFIX,cabet266.com,Proxy\nDOMAIN-SUFFIX,proxify.com,Proxy\nDOMAIN-SUFFIX,deep-throat.tv,Proxy\nDOMAIN-SUFFIX,cloudtv.bz,Proxy\nDOMAIN-SUFFIX,www.diedart2.com,Proxy\nDOMAIN-SUFFIX,yunex.io,Proxy\nDOMAIN-SUFFIX,sz.de,Proxy\nDOMAIN-SUFFIX,315333.com,Proxy\nDOMAIN-SUFFIX,nonet.ddnsking.com,Proxy\nDOMAIN-SUFFIX,institut-tibetain.org,Proxy\nDOMAIN-SUFFIX,hongkong.fandom.com,Proxy\nDOMAIN-SUFFIX,fb.4irc.com,Proxy\nDOMAIN-SUFFIX,logiqx.com,Proxy\nDOMAIN-SUFFIX,onlinevideoconverter.com,Proxy\nDOMAIN-SUFFIX,www.worldofmods.com,Proxy\nDOMAIN-SUFFIX,s1.djyimg.com,Proxy\nDOMAIN-SUFFIX,d28ftqgm7njw2a.cloudfront.net,Proxy\nDOMAIN-SUFFIX,tibetlibre.org,Proxy\nDOMAIN-SUFFIX,xam01.com,Proxy\nDOMAIN-SUFFIX,www.facebook.in,Proxy\nDOMAIN-SUFFIX,sav88.com,Proxy\nDOMAIN-SUFFIX,dyndns-pics.com,Proxy\nDOMAIN-SUFFIX,nexo.io,Proxy\nDOMAIN-SUFFIX,biennaledemocrazia.it,Proxy\nDOMAIN-SUFFIX,1000rub.com,Proxy\nDOMAIN-SUFFIX,baike.tw.lvfukeji.com,Proxy\nDOMAIN-SUFFIX,mxvpn.com,Proxy\nDOMAIN-SUFFIX,maniash.com,Proxy\nDOMAIN-SUFFIX,starchu.com,Proxy\nDOMAIN-SUFFIX,india.fm,Proxy\nDOMAIN-SUFFIX,thisav.com,Proxy\nDOMAIN-SUFFIX,tibetpolicy.eu,Proxy\nDOMAIN-SUFFIX,699.gotgeeks.com,Proxy\nDOMAIN-SUFFIX,9699888.com,Proxy\nDOMAIN-SUFFIX,www.everrich.com,Proxy\nDOMAIN-SUFFIX,radiko.jp,Proxy\nDOMAIN-SUFFIX,moroneta.com,Proxy\nDOMAIN-SUFFIX,refind.com,Proxy\nDOMAIN-SUFFIX,hk-wesi3.xyz,Proxy\nDOMAIN-SUFFIX,pandafan.me,Proxy\nDOMAIN-SUFFIX,instaglam.com,Proxy\nDOMAIN-SUFFIX,sublexical.spaces.live.com,Proxy\nDOMAIN-SUFFIX,iqq1.fun,Proxy\nDOMAIN-SUFFIX,faiththedog.info,Proxy\nDOMAIN-SUFFIX,101.cc.st,Proxy\nDOMAIN-SUFFIX,www.taiwanfellowship.org,Proxy\nDOMAIN-SUFFIX,jbo9.com,Proxy\nDOMAIN-SUFFIX,1xl6.gl.grr.io,Proxy\nDOMAIN-SUFFIX,www.qafone.net,Proxy\nDOMAIN-SUFFIX,7mmtv.cc,Proxy\nDOMAIN-SUFFIX,www.code42.com,Proxy\nDOMAIN-SUFFIX,dwebcamp.org,Proxy\nDOMAIN-SUFFIX,pin6.com,Proxy\nDOMAIN-SUFFIX,opengw.net,Proxy\nDOMAIN-SUFFIX,d1nfzinqpp07se.cloudfront.net,Proxy\nDOMAIN-SUFFIX,kaotic.com,Proxy\nDOMAIN-SUFFIX,www.hjdc878.com,Proxy\nDOMAIN-SUFFIX,falundafa.de,Proxy\nDOMAIN-SUFFIX,killerjo.net,Proxy\nDOMAIN-SUFFIX,openweathermap.org,Proxy\nDOMAIN-SUFFIX,alday.de,Proxy\nDOMAIN-SUFFIX,getoutline.org,Proxy\nDOMAIN-SUFFIX,surf-chinaz.com,Proxy\nDOMAIN-SUFFIX,changken.idv.tw,Proxy\nDOMAIN-SUFFIX,www.x1m1global.tech,Proxy\nDOMAIN-SUFFIX,jichi.ca,Proxy\nDOMAIN-SUFFIX,sun1911.com,Proxy\nDOMAIN-SUFFIX,www.digisocial.com,Proxy\nDOMAIN-SUFFIX,ahri-hentai.com,Proxy\nDOMAIN-SUFFIX,falundafa.org.my,Proxy\nDOMAIN-SUFFIX,tb9908.com,Proxy\nDOMAIN-SUFFIX,go2099.com,Proxy\nDOMAIN-SUFFIX,tankman.programthink.com,Proxy\nDOMAIN-SUFFIX,thenanfang.com,Proxy\nDOMAIN-SUFFIX,pchome.net,Proxy\nDOMAIN-SUFFIX,gooddns.info,Proxy\nDOMAIN-SUFFIX,unseen.is,Proxy\nDOMAIN-SUFFIX,www.hkce.com,Proxy\nDOMAIN-SUFFIX,tw.knowledge.yahoo.com,Proxy\nDOMAIN-SUFFIX,32.slyip.net,Proxy\nDOMAIN-SUFFIX,pan.doyo.icu,Proxy\nDOMAIN-SUFFIX,72724243473.de,Proxy\nDOMAIN-SUFFIX,sfstandard.com,Proxy\nDOMAIN-SUFFIX,fallenark.com,Proxy\nDOMAIN-SUFFIX,menu-live.firebaseio.com,Proxy\nDOMAIN-SUFFIX,om.flnet.org,Proxy\nDOMAIN-SUFFIX,webjb.org,Proxy\nDOMAIN-SUFFIX,home.nanhuatemple.org,Proxy\nDOMAIN-SUFFIX,www.ericjoung.idv.tw,Proxy\nDOMAIN-SUFFIX,hbg.com,Proxy\nDOMAIN-SUFFIX,punyu.com,Proxy\nDOMAIN-SUFFIX,www.zb.cn,Proxy\nDOMAIN-SUFFIX,www.rickh.cf,Proxy\nDOMAIN-SUFFIX,reader.roodo.com,Proxy\nDOMAIN-SUFFIX,nailedhard.com,Proxy\nDOMAIN-SUFFIX,www.dalailama.it,Proxy\nDOMAIN-SUFFIX,willowcreek.org,Proxy\nDOMAIN-SUFFIX,woodmancastingx.com,Proxy\nDOMAIN-SUFFIX,rty.deaftone.com,Proxy\nDOMAIN-SUFFIX,doubibackup.com,Proxy\nDOMAIN-SUFFIX,zh88.jumpingcrab.com,Proxy\nDOMAIN-SUFFIX,nitter.bgme.bid,Proxy\nDOMAIN-SUFFIX,rcnradio.com,Proxy\nDOMAIN-SUFFIX,bunbunhk.com,Proxy\nDOMAIN-SUFFIX,iqq2.net,Proxy\nDOMAIN-SUFFIX,www.javtube.com,Proxy\nDOMAIN-SUFFIX,98xaf.com,Proxy\nDOMAIN-SUFFIX,mail.prentvorur.is,Proxy\nDOMAIN-SUFFIX,mail.yahoo.com,Proxy\nDOMAIN-SUFFIX,72pro.xyz,Proxy\nDOMAIN-SUFFIX,javmoo.xyz,Proxy\nDOMAIN-SUFFIX,abclite.net,Proxy\nDOMAIN-SUFFIX,festivalsandshows.com,Proxy\nDOMAIN-SUFFIX,www.fanwall.org,Proxy\nDOMAIN-SUFFIX,d2apx3fwniaev7.cloudfront.net,Proxy\nDOMAIN-SUFFIX,shadows.pw,Proxy\nDOMAIN-SUFFIX,www.fcbarcelona.com,Proxy\nDOMAIN-SUFFIX,8587b.cc,Proxy\nDOMAIN-SUFFIX,xpud.org,Proxy\nDOMAIN-SUFFIX,wi.slyip.net,Proxy\nDOMAIN-SUFFIX,www.pornsos.com,Proxy\nDOMAIN-SUFFIX,xys3.dxiong.com,Proxy\nDOMAIN-SUFFIX,www.exovoid.ch,Proxy\nDOMAIN-SUFFIX,9bap1.com,Proxy\nDOMAIN-SUFFIX,prestige-av.com,Proxy\nDOMAIN-SUFFIX,d.pc22.pw,Proxy\nDOMAIN-SUFFIX,weddingsmap.com,Proxy\nDOMAIN-SUFFIX,www.pf.org.tw,Proxy\nDOMAIN-SUFFIX,chonglangtv.pythonanywhere.com,Proxy\nDOMAIN-SUFFIX,adminforge.de,Proxy\nDOMAIN-SUFFIX,18comic3.art,Proxy\nDOMAIN-SUFFIX,www.uscycs.org,Proxy\nDOMAIN-SUFFIX,d.vhdd.us,Proxy\nDOMAIN-SUFFIX,betlego888.com,Proxy\nDOMAIN-SUFFIX,easyspace.us,Proxy\nDOMAIN-SUFFIX,faqserv.com,Proxy\nDOMAIN-SUFFIX,f.cr.rs,Proxy\nDOMAIN-SUFFIX,on2.com,Proxy\nDOMAIN-SUFFIX,asiapr.id,Proxy\nDOMAIN-SUFFIX,covaxon.my.salesforce.com,Proxy\nDOMAIN-SUFFIX,ecomapas.cl,Proxy\nDOMAIN-SUFFIX,google.lt,Proxy\nDOMAIN-SUFFIX,jpnn.com,Proxy\nDOMAIN-SUFFIX,xh.domain888.pw,Proxy\nDOMAIN-SUFFIX,trojan-gfw.github.io,Proxy\nDOMAIN-SUFFIX,zt.com,Proxy\nDOMAIN-SUFFIX,zjeban.si,Proxy\nDOMAIN-SUFFIX,metropop.com.hk,Proxy\nDOMAIN-SUFFIX,hln.be,Proxy\nDOMAIN-SUFFIX,news.sina.com.tw,Proxy\nDOMAIN-SUFFIX,ntd.tv,Proxy\nDOMAIN-SUFFIX,sbf822.com,Proxy\nDOMAIN-SUFFIX,google.pt,Proxy\nDOMAIN-SUFFIX,today.com,Proxy\nDOMAIN-SUFFIX,buyu357.com,Proxy\nDOMAIN-SUFFIX,usbloadergx.koureio.net,Proxy\nDOMAIN-SUFFIX,aidecn.cn,Proxy\nDOMAIN-SUFFIX,cepa.ecms.pl,Proxy\nDOMAIN-SUFFIX,videosexarchive.com,Proxy\nDOMAIN-SUFFIX,www.119sihu.com,Proxy\nDOMAIN-SUFFIX,ns01.biz,Proxy\nDOMAIN-SUFFIX,proxies.by,Proxy\nDOMAIN-SUFFIX,blog.tiney.com,Proxy\nDOMAIN-SUFFIX,dbo15s62lcu1q.cloudfront.net,Proxy\nDOMAIN-SUFFIX,milkav.com,Proxy\nDOMAIN-SUFFIX,parnassusbooks.net,Proxy\nDOMAIN-SUFFIX,www.buckeyeinstitute.org,Proxy\nDOMAIN-SUFFIX,www1.cbn.com,Proxy\nDOMAIN-SUFFIX,fr.yahoo.com,Proxy\nDOMAIN-SUFFIX,www.theflindersnews.com.au,Proxy\nDOMAIN-SUFFIX,www.tibet.ee,Proxy\nDOMAIN-SUFFIX,spankwire.com,Proxy\nDOMAIN-SUFFIX,secure.free-signal.com,Proxy\nDOMAIN-SUFFIX,yl8.com,Proxy\nDOMAIN-SUFFIX,mormonmatters.org,Proxy\nDOMAIN-SUFFIX,enlighten.org.tw,Proxy\nDOMAIN-SUFFIX,yes-news.com,Proxy\nDOMAIN-SUFFIX,wsdc000.com,Proxy\nDOMAIN-SUFFIX,twitturk.com,Proxy\nDOMAIN-SUFFIX,www.realestate.com.kh,Proxy\nDOMAIN-SUFFIX,cellsystech.com,Proxy\nDOMAIN-SUFFIX,fromyoutube.com,Proxy\nDOMAIN-SUFFIX,www.polarstar.cc,Proxy\nDOMAIN-SUFFIX,postini.com,Proxy\nDOMAIN-SUFFIX,cari.com.my,Proxy\nDOMAIN-SUFFIX,tt3855.com,Proxy\nDOMAIN-SUFFIX,vpnfq.in,Proxy\nDOMAIN-SUFFIX,www.fast-ssr.org,Proxy\nDOMAIN-SUFFIX,drive.com,Proxy\nDOMAIN-SUFFIX,ht.ly,Proxy\nDOMAIN-SUFFIX,d5585.com,Proxy\nDOMAIN-SUFFIX,tw.jzbet666.net,Proxy\nDOMAIN-SUFFIX,sjy003.jigsy.com,Proxy\nDOMAIN-SUFFIX,telefonica.com,Proxy\nDOMAIN-SUFFIX,scieron.com,Proxy\nDOMAIN-SUFFIX,dc8816.com,Proxy\nDOMAIN-SUFFIX,culcairnbakery.com.au,Proxy\nDOMAIN-SUFFIX,allanmay.com,Proxy\nDOMAIN-SUFFIX,astrill4u.com,Proxy\nDOMAIN-SUFFIX,www.openervpn.us,Proxy\nDOMAIN-SUFFIX,geoip.over9000.wtf,Proxy\nDOMAIN-SUFFIX,www.uan.edu.mx,Proxy\nDOMAIN-SUFFIX,hkip.org.uk,Proxy\nDOMAIN-SUFFIX,barbarasbookstore.com,Proxy\nDOMAIN-SUFFIX,ipadporn.com,Proxy\nDOMAIN-SUFFIX,id.hao123.com,Proxy\nDOMAIN-SUFFIX,www.lcg.com,Proxy\nDOMAIN-SUFFIX,blogdeizquierda.com,Proxy\nDOMAIN-SUFFIX,265vip.com,Proxy\nDOMAIN-SUFFIX,onlinecha.com,Proxy\nDOMAIN-SUFFIX,helloprojectclothes.blogspot.jp,Proxy\nDOMAIN-SUFFIX,www.ftvnews.com.tw,Proxy\nDOMAIN-SUFFIX,samuhik.com,Proxy\nDOMAIN-SUFFIX,voiceofserbia.org,Proxy\nDOMAIN-SUFFIX,www.tlcc.com.tw,Proxy\nDOMAIN-SUFFIX,www.gloucesteradvocate.com.au,Proxy\nDOMAIN-SUFFIX,iam.soy,Proxy\nDOMAIN-SUFFIX,santa-mars.blogspot.hk,Proxy\nDOMAIN-SUFFIX,theproject333.com,Proxy\nDOMAIN-SUFFIX,erocool.net,Proxy\nDOMAIN-SUFFIX,parun.com.ar,Proxy\nDOMAIN-SUFFIX,tcfexpress.com,Proxy\nDOMAIN-SUFFIX,stormfront.org,Proxy\nDOMAIN-SUFFIX,www.askasu.idv.tw,Proxy\nDOMAIN-SUFFIX,animephile.com,Proxy\nDOMAIN-SUFFIX,twip.me,Proxy\nDOMAIN-SUFFIX,iporntv.net,Proxy\nDOMAIN-SUFFIX,zjcqoo.github.io,Proxy\nDOMAIN-SUFFIX,epicfail.com,Proxy\nDOMAIN-SUFFIX,le2018.com,Proxy\nDOMAIN-SUFFIX,gongwt.com,Proxy\nDOMAIN-SUFFIX,wujie.net,Proxy\nDOMAIN-SUFFIX,pussyspace.com,Proxy\nDOMAIN-SUFFIX,85porn.com,Proxy\nDOMAIN-SUFFIX,www.bobobra.com,Proxy\nDOMAIN-SUFFIX,moefuns.fun,Proxy\nDOMAIN-SUFFIX,xvideos.com,Proxy\nDOMAIN-SUFFIX,hapi.ettoday.net,Proxy\nDOMAIN-SUFFIX,fofg-europe.net,Proxy\nDOMAIN-SUFFIX,nico.one,Proxy\nDOMAIN-SUFFIX,www.274044.com,Proxy\nDOMAIN-SUFFIX,d1v2ylre1hanhh.cloudfront.net,Proxy\nDOMAIN-SUFFIX,887814.com,Proxy\nDOMAIN-SUFFIX,dns1.us,Proxy\nDOMAIN-SUFFIX,www.freelancer.cn,Proxy\nDOMAIN-SUFFIX,inews.mingpao.com,Proxy\nDOMAIN-SUFFIX,mobile.356884.com,Proxy\nDOMAIN-SUFFIX,xmissy.nl,Proxy\nDOMAIN-SUFFIX,www.5157002.com,Proxy\nDOMAIN-SUFFIX,mahabodhi.org,Proxy\nDOMAIN-SUFFIX,tnp.org,Proxy\nDOMAIN-SUFFIX,porn5f.com,Proxy\nDOMAIN-SUFFIX,luedeke-bremen.eu,Proxy\nDOMAIN-SUFFIX,hanime.tv,Proxy\nDOMAIN-SUFFIX,www.bannedbook.net,Proxy\nDOMAIN-SUFFIX,incredibleindia.org,Proxy\nDOMAIN-SUFFIX,pj9685.com,Proxy\nDOMAIN-SUFFIX,xeper.org,Proxy\nDOMAIN-SUFFIX,ps.pics.mu,Proxy\nDOMAIN-SUFFIX,pjba1.club,Proxy\nDOMAIN-SUFFIX,images-ext-2.discordapp.net,Proxy\nDOMAIN-SUFFIX,www.pinnacle888.com,Proxy\nDOMAIN-SUFFIX,nembutalhub.com,Proxy\nDOMAIN-SUFFIX,zdbwoet.com,Proxy\nDOMAIN-SUFFIX,edn.udn.com,Proxy\nDOMAIN-SUFFIX,twiyia.com,Proxy\nDOMAIN-SUFFIX,valdostano.com,Proxy\nDOMAIN-SUFFIX,manyhats.pao-pao.org,Proxy\nDOMAIN-SUFFIX,alkamil.co.nz,Proxy\nDOMAIN-SUFFIX,www.caseyneistat.com,Proxy\nDOMAIN-SUFFIX,jayde.xyz,Proxy\nDOMAIN-SUFFIX,yahoo.hk,Proxy\nDOMAIN-SUFFIX,st4rz.blogspot.hk,Proxy\nDOMAIN-SUFFIX,e89898.com,Proxy\nDOMAIN-SUFFIX,377955.com,Proxy\nDOMAIN-SUFFIX,www.fitnessdigital.com.tw,Proxy\nDOMAIN-SUFFIX,trialofccp.org,Proxy\nDOMAIN-SUFFIX,login.target.com,Proxy\nDOMAIN-SUFFIX,www.babefox.com,Proxy\nDOMAIN-SUFFIX,ratemysketa.com,Proxy\nDOMAIN-SUFFIX,thomasandsarah.net,Proxy\nDOMAIN-SUFFIX,lustypuppy.com,Proxy\nDOMAIN-SUFFIX,456787a.com,Proxy\nDOMAIN-SUFFIX,akali.club,Proxy\nDOMAIN-SUFFIX,www.8car.com.tw,Proxy\nDOMAIN-SUFFIX,minghui-school.org,Proxy\nDOMAIN-SUFFIX,woobox.com,Proxy\nDOMAIN-SUFFIX,chromegae.com,Proxy\nDOMAIN-SUFFIX,p888588.com,Proxy\nDOMAIN-SUFFIX,www.hollyrandall.com,Proxy\nDOMAIN-SUFFIX,islam101.net,Proxy\nDOMAIN-SUFFIX,avmoo.com,Proxy\nDOMAIN-SUFFIX,boxuanfilm.blogspot.ca,Proxy\nDOMAIN-SUFFIX,hanime1.me,Proxy\nDOMAIN-SUFFIX,www.hkmap.live,Proxy\nDOMAIN-SUFFIX,d1yzmsm07h8ddx.cloudfront.net,Proxy\nDOMAIN-SUFFIX,pcdvd.com.tw,Proxy\nDOMAIN-SUFFIX,89-64.org,Proxy\nDOMAIN-SUFFIX,secure.famemaine.com,Proxy\nDOMAIN-SUFFIX,9288js.com,Proxy\nDOMAIN-SUFFIX,biliworld.com,Proxy\nDOMAIN-SUFFIX,hautelook.com,Proxy\nDOMAIN-SUFFIX,bbs.cn1069.net,Proxy\nDOMAIN-SUFFIX,www.retweetrank.com,Proxy\nDOMAIN-SUFFIX,xmbs.live,Proxy\nDOMAIN-SUFFIX,3xplanet.net,Proxy\nDOMAIN-SUFFIX,wmscog.cc,Proxy\nDOMAIN-SUFFIX,homeperversion.com,Proxy\nDOMAIN-SUFFIX,chat3.geekr.dev,Proxy\nDOMAIN-SUFFIX,8757.org,Proxy\nDOMAIN-SUFFIX,www.abigcompany.com,Proxy\nDOMAIN-SUFFIX,www.intronis.com,Proxy\nDOMAIN-SUFFIX,youbiyao.net,Proxy\nDOMAIN-SUFFIX,hegre-art.com,Proxy\nDOMAIN-SUFFIX,ap3.esunsec.com.tw,Proxy\nDOMAIN-SUFFIX,statul-paralel.ro,Proxy\nDOMAIN-SUFFIX,nflximg.net,Proxy\nDOMAIN-SUFFIX,www.moztw.org,Proxy\nDOMAIN-SUFFIX,www.hottg.com,Proxy\nDOMAIN-SUFFIX,www.boyi188.com,Proxy\nDOMAIN-SUFFIX,now.im,Proxy\nDOMAIN-SUFFIX,world.kbs.co.kr,Proxy\nDOMAIN-SUFFIX,hulu.com,Proxy\nDOMAIN-SUFFIX,muchtv.eracom.com.tw,Proxy\nDOMAIN-SUFFIX,cacss.me,Proxy\nDOMAIN-SUFFIX,cbn.org,Proxy\nDOMAIN-SUFFIX,2345vpn.com,Proxy\nDOMAIN-SUFFIX,kukuku.cc,Proxy\nDOMAIN-SUFFIX,health2.icu,Proxy\nDOMAIN-SUFFIX,www.porn5.com,Proxy\nDOMAIN-SUFFIX,olevod.com,Proxy\nDOMAIN-SUFFIX,f.wheredreams.com,Proxy\nDOMAIN-SUFFIX,xfm.pp.ru,Proxy\nDOMAIN-SUFFIX,briian.com,Proxy\nDOMAIN-SUFFIX,boyfriendtv.com,Proxy\nDOMAIN-SUFFIX,gu-chu-sum.org,Proxy\nDOMAIN-SUFFIX,500px.com,Proxy\nDOMAIN-SUFFIX,browse007.com,Proxy\nDOMAIN-SUFFIX,25570000.com,Proxy\nDOMAIN-SUFFIX,ms52.ml,Proxy\nDOMAIN-SUFFIX,hidester.com,Proxy\nDOMAIN-SUFFIX,safervpn.com,Proxy\nDOMAIN-SUFFIX,ssbdh.icu,Proxy\nDOMAIN-SUFFIX,aarberg-bierwanderung.ch,Proxy\nDOMAIN-SUFFIX,organiccrap.com,Proxy\nDOMAIN-SUFFIX,fireflychinese.com,Proxy\nDOMAIN-SUFFIX,google.al,Proxy\nDOMAIN-SUFFIX,topmtv.site,Proxy\nDOMAIN-SUFFIX,tibet-initiative.de,Proxy\nDOMAIN-SUFFIX,www.pxaa.com,Proxy\nDOMAIN-SUFFIX,sieduacdamic.cfd,Proxy\nDOMAIN-SUFFIX,www.opendoorvpn.com,Proxy\nDOMAIN-SUFFIX,ziporn.com,Proxy\nDOMAIN-SUFFIX,surfshark.com,Proxy\nDOMAIN-SUFFIX,www.nodecache.com,Proxy\nDOMAIN-SUFFIX,e8777.co,Proxy\nDOMAIN-SUFFIX,hellovpn.app,Proxy\nDOMAIN-SUFFIX,38kq.com,Proxy\nDOMAIN-SUFFIX,my.jw.org,Proxy\nDOMAIN-SUFFIX,76652200.com,Proxy\nDOMAIN-SUFFIX,tspdh2.xyz,Proxy\nDOMAIN-SUFFIX,higu.tv,Proxy\nDOMAIN-SUFFIX,bravoteens.com,Proxy\nDOMAIN-SUFFIX,coursmos.com,Proxy\nDOMAIN-SUFFIX,van698.com,Proxy\nDOMAIN-SUFFIX,cams.org.sg,Proxy\nDOMAIN-SUFFIX,jizzmontoo.com,Proxy\nDOMAIN-SUFFIX,trimurti.us,Proxy\nDOMAIN-SUFFIX,beeitv.site,Proxy\nDOMAIN-SUFFIX,fun568.com,Proxy\nDOMAIN-SUFFIX,www.goulburnpost.com.au,Proxy\nDOMAIN-SUFFIX,vermonttibet.org,Proxy\nDOMAIN-SUFFIX,einfachporno.com,Proxy\nDOMAIN-SUFFIX,99557148.com,Proxy\nDOMAIN-SUFFIX,36.podzone.org,Proxy\nDOMAIN-SUFFIX,www.ae003.com,Proxy\nDOMAIN-SUFFIX,vpnbook.com,Proxy\nDOMAIN-SUFFIX,aliengu.com,Proxy\nDOMAIN-SUFFIX,globalnewstv.com.tw,Proxy\nDOMAIN-SUFFIX,cmp.hku.hk,Proxy\nDOMAIN-SUFFIX,tngrnow.com,Proxy\nDOMAIN-SUFFIX,teco-hk.org,Proxy\nDOMAIN-SUFFIX,rat.b0ne.com,Proxy\nDOMAIN-SUFFIX,digbysblog.blogspot.hk,Proxy\nDOMAIN-SUFFIX,www.penarthtimes.co.uk,Proxy\nDOMAIN-SUFFIX,myads.longluntan.com,Proxy\nDOMAIN-SUFFIX,mlmmlm-icu.github.io,Proxy\nDOMAIN-SUFFIX,xartfan.com,Proxy\nDOMAIN-SUFFIX,easyceipt.com,Proxy\nDOMAIN-SUFFIX,ip5008.com,Proxy\nDOMAIN-SUFFIX,www.ajsands.com,Proxy\nDOMAIN-SUFFIX,10bo1000.com,Proxy\nDOMAIN-SUFFIX,www.ngemu.com,Proxy\nDOMAIN-SUFFIX,songkimo.okk.tw,Proxy\nDOMAIN-SUFFIX,tb9992.com,Proxy\nDOMAIN-SUFFIX,www.alizila.com.global.prod.fastly.net,Proxy\nDOMAIN-SUFFIX,mysoundpod.com,Proxy\nDOMAIN-SUFFIX,wetplace.com,Proxy\nDOMAIN-SUFFIX,lighten.org.tw,Proxy\nDOMAIN-SUFFIX,vpnjp.com,Proxy\nDOMAIN-SUFFIX,tuxing.live,Proxy\nDOMAIN-SUFFIX,y1875.com,Proxy\nDOMAIN-SUFFIX,dirpy.com,Proxy\nDOMAIN-SUFFIX,equestriadaily.com,Proxy\nDOMAIN-SUFFIX,tn1.shemalez.com,Proxy\nDOMAIN-SUFFIX,nchc.dl.sourceforge.net,Proxy\nDOMAIN-SUFFIX,candied-early-point.glitch.me,Proxy\nDOMAIN-SUFFIX,pgsqldeepdive.blogspot.jp,Proxy\nDOMAIN-SUFFIX,losduartes.com.br,Proxy\nDOMAIN-SUFFIX,www.ymca.org.tw,Proxy\nDOMAIN-SUFFIX,thefreevpn.com,Proxy\nDOMAIN-SUFFIX,www.59lfw.com,Proxy\nDOMAIN-SUFFIX,bynet.co.il,Proxy\nDOMAIN-SUFFIX,us.serveuser.com,Proxy\nDOMAIN-SUFFIX,zh9.lima-city.de,Proxy\nDOMAIN-SUFFIX,isunaffairs.com,Proxy\nDOMAIN-SUFFIX,mmyyds.net,Proxy\nDOMAIN-SUFFIX,baidu36.oikodomo.gr,Proxy\nDOMAIN-SUFFIX,iwwhm.r5.cr.rs,Proxy\nDOMAIN-SUFFIX,levanovich.com.ar,Proxy\nDOMAIN-SUFFIX,www.lovesb.com,Proxy\nDOMAIN-SUFFIX,vip77765.com,Proxy\nDOMAIN-SUFFIX,forum.setty.com.tw,Proxy\nDOMAIN-SUFFIX,www.thinkhk.com,Proxy\nDOMAIN-SUFFIX,mastodon.top,Proxy\nDOMAIN-SUFFIX,72.effers.com,Proxy\nDOMAIN-SUFFIX,www.zhanliejian.com,Proxy\nDOMAIN-SUFFIX,bbs.yibook.org,Proxy\nDOMAIN-SUFFIX,davidlee.ddns.net,Proxy\nDOMAIN-SUFFIX,funav.tv,Proxy\nDOMAIN-SUFFIX,linkbucks.com,Proxy\nDOMAIN-SUFFIX,workersthebig.net,Proxy\nDOMAIN-SUFFIX,www.alqp37.com,Proxy\nDOMAIN-SUFFIX,pp699.net,Proxy\nDOMAIN-SUFFIX,zoobestialitymovies.com,Proxy\nDOMAIN-SUFFIX,food.taiwannumber1.com,Proxy\nDOMAIN-SUFFIX,www.zhaiclub.com,Proxy\nDOMAIN-SUFFIX,humanharvestmovie.com,Proxy\nDOMAIN-SUFFIX,www.s-und-n.de,Proxy\nDOMAIN-SUFFIX,dns.twnic.tw,Proxy\nDOMAIN-SUFFIX,vapors.eu,Proxy\nDOMAIN-SUFFIX,taiwannation.com.tw,Proxy\nDOMAIN-SUFFIX,quality-electronics.com,Proxy\nDOMAIN-SUFFIX,vpninja.com,Proxy\nDOMAIN-SUFFIX,isak.ws,Proxy\nDOMAIN-SUFFIX,db48ymmipqi6b.cloudfront.net,Proxy\nDOMAIN-SUFFIX,hibiscus.com,Proxy\nDOMAIN-SUFFIX,www.impeachbiden.com,Proxy\nDOMAIN-SUFFIX,vanderfoguel.com.ar,Proxy\nDOMAIN-SUFFIX,washeng.net,Proxy\nDOMAIN-SUFFIX,antrodia-legend.strikingly.com,Proxy\nDOMAIN-SUFFIX,mail.yahoo.co.id,Proxy\nDOMAIN-SUFFIX,all-quran.com,Proxy\nDOMAIN-SUFFIX,joymiihub.com,Proxy\nDOMAIN-SUFFIX,www.djjsq.cn,Proxy\nDOMAIN-SUFFIX,phiphicake.blogspot.hk,Proxy\nDOMAIN-SUFFIX,laserproxy.com,Proxy\nDOMAIN-SUFFIX,dscn.info,Proxy\nDOMAIN-SUFFIX,polymer-project.org,Proxy\nDOMAIN-SUFFIX,allthingsd.com,Proxy\nDOMAIN-SUFFIX,goldmail.etsu.edu,Proxy\nDOMAIN-SUFFIX,668000111.com,Proxy\nDOMAIN-SUFFIX,www.207678.com,Proxy\nDOMAIN-SUFFIX,dizimag4.co,Proxy\nDOMAIN-SUFFIX,vpnda.com,Proxy\nDOMAIN-SUFFIX,954.dhcp.biz,Proxy\nDOMAIN-SUFFIX,u14333.com,Proxy\nDOMAIN-SUFFIX,nukistream.com,Proxy\nDOMAIN-SUFFIX,tropicaisland.com,Proxy\nDOMAIN-SUFFIX,3arabtv.com,Proxy\nDOMAIN-SUFFIX,samuelkong.com,Proxy\nDOMAIN-SUFFIX,yifantea8866.mybbs.us,Proxy\nDOMAIN-SUFFIX,dorjeshugden.com,Proxy\nDOMAIN-SUFFIX,stealthvisitor.com,Proxy\nDOMAIN-SUFFIX,www.kuihua888.com,Proxy\nDOMAIN-SUFFIX,mobile.36500365.com,Proxy\nDOMAIN-SUFFIX,www.kisscos.net,Proxy\nDOMAIN-SUFFIX,casamea.org,Proxy\nDOMAIN-SUFFIX,minghui.ca,Proxy\nDOMAIN-SUFFIX,ello.co,Proxy\nDOMAIN-SUFFIX,666kb.com,Proxy\nDOMAIN-SUFFIX,cc9007.spaces.live.com,Proxy\nDOMAIN-SUFFIX,nm.x8e9ft7k.net,Proxy\nDOMAIN-SUFFIX,www.drivewealth.com,Proxy\nDOMAIN-SUFFIX,trialmu.com,Proxy\nDOMAIN-SUFFIX,dailymail.com,Proxy\nDOMAIN-SUFFIX,aei.org,Proxy\nDOMAIN-SUFFIX,www.uwc-maastricht.com,Proxy\nDOMAIN-SUFFIX,www.15651100.com,Proxy\nDOMAIN-SUFFIX,eiga.com,Proxy\nDOMAIN-SUFFIX,covid19classaction.it,Proxy\nDOMAIN-SUFFIX,www.fun8801.com,Proxy\nDOMAIN-SUFFIX,google.nu,Proxy\nDOMAIN-SUFFIX,youfck.com,Proxy\nDOMAIN-SUFFIX,wiki3.cf,Proxy\nDOMAIN-SUFFIX,bbs.cantonese.asia,Proxy\nDOMAIN-SUFFIX,www.tibetanlife.com,Proxy\nDOMAIN-SUFFIX,omct.org,Proxy\nDOMAIN-SUFFIX,neattogo.com,Proxy\nDOMAIN-SUFFIX,chicagoreader.com,Proxy\nDOMAIN-SUFFIX,p2558.com,Proxy\nDOMAIN-SUFFIX,w88w989.com,Proxy\nDOMAIN-SUFFIX,288x.com,Proxy\nDOMAIN-SUFFIX,im-alan.idv.tw,Proxy\nDOMAIN-SUFFIX,www.tilastopaja.org,Proxy\nDOMAIN-SUFFIX,d310ewn6a6lefs.cloudfront.net,Proxy\nDOMAIN-SUFFIX,kompozer.net,Proxy\nDOMAIN-SUFFIX,www.kcai336.com,Proxy\nDOMAIN-SUFFIX,ss.pythonic.life,Proxy\nDOMAIN-SUFFIX,talkyshow.com,Proxy\nDOMAIN-SUFFIX,news.gallup.com,Proxy\nDOMAIN-SUFFIX,monova.org,Proxy\nDOMAIN-SUFFIX,gg4u.in,Proxy\nDOMAIN-SUFFIX,textnow.me,Proxy\nDOMAIN-SUFFIX,dish.com,Proxy\nDOMAIN-SUFFIX,cs017.com,Proxy\nDOMAIN-SUFFIX,www.babydiscuss.com,Proxy\nDOMAIN-SUFFIX,d3obcr2u6lxl5q.cloudfront.net,Proxy\nDOMAIN-SUFFIX,mynetwork.de,Proxy\nDOMAIN-SUFFIX,18comic.cool,Proxy\nDOMAIN-SUFFIX,63jj.net,Proxy\nDOMAIN-SUFFIX,google.sh,Proxy\nDOMAIN-SUFFIX,hdmbox.com,Proxy\nDOMAIN-SUFFIX,www.biblepoint.net,Proxy\nDOMAIN-SUFFIX,kadimatransport.co.za,Proxy\nDOMAIN-SUFFIX,3proxy.ru,Proxy\nDOMAIN-SUFFIX,acg12.com,Proxy\nDOMAIN-SUFFIX,promar.xyz,Proxy\nDOMAIN-SUFFIX,18-comic1.cc,Proxy\nDOMAIN-SUFFIX,d100.net,Proxy\nDOMAIN-SUFFIX,tweakwarevpn.net,Proxy\nDOMAIN-SUFFIX,homesteadsurvival.blogspot.hk,Proxy\nDOMAIN-SUFFIX,scripts.sil.org,Proxy\nDOMAIN-SUFFIX,www.fktv99.com,Proxy\nDOMAIN-SUFFIX,discordapp.com,Proxy\nDOMAIN-SUFFIX,infiltrate.ca,Proxy\nDOMAIN-SUFFIX,m8.my03.com,Proxy\nDOMAIN-SUFFIX,www.moynegazette.com.au,Proxy\nDOMAIN-SUFFIX,haproxy.org,Proxy\nDOMAIN-SUFFIX,theexgirlfriends.com,Proxy\nDOMAIN-SUFFIX,100mountain.com,Proxy\nDOMAIN-SUFFIX,ce4arab.com,Proxy\nDOMAIN-SUFFIX,encyclopedia.com,Proxy\nDOMAIN-SUFFIX,www.hkex.com.hk,Proxy\nDOMAIN-SUFFIX,eeeeeesile.com,Proxy\nDOMAIN-SUFFIX,www.z-unity.com.tw,Proxy\nDOMAIN-SUFFIX,nctimes.com,Proxy\nDOMAIN-SUFFIX,ktunnel.com,Proxy\nDOMAIN-SUFFIX,www.ca88.cc,Proxy\nDOMAIN-SUFFIX,1saleaday.com,Proxy\nDOMAIN-SUFFIX,www.guardiannews.com,Proxy\nDOMAIN-SUFFIX,ab8kai.com,Proxy\nDOMAIN-SUFFIX,sulian.me,Proxy\nDOMAIN-SUFFIX,modx.com,Proxy\nDOMAIN-SUFFIX,www.natmo.com,Proxy\nDOMAIN-SUFFIX,www.tb65s.com,Proxy\nDOMAIN-SUFFIX,2ljz.14.iamallama.com,Proxy\nDOMAIN-SUFFIX,aptoide.com,Proxy\nDOMAIN-SUFFIX,www.cnfree.org,Proxy\nDOMAIN-SUFFIX,865ba.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,media.aalah.me,Proxy\nDOMAIN-SUFFIX,kui.name,Proxy\nDOMAIN-SUFFIX,www.ukpunting.com,Proxy\nDOMAIN-SUFFIX,tw6668.com,Proxy\nDOMAIN-SUFFIX,equusdesigns.net,Proxy\nDOMAIN-SUFFIX,www.itb13.com,Proxy\nDOMAIN-SUFFIX,sh.effers.com,Proxy\nDOMAIN-SUFFIX,www.xinbi222.com,Proxy\nDOMAIN-SUFFIX,fw6.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,ll699.net,Proxy\nDOMAIN-SUFFIX,osilo.net,Proxy\nDOMAIN-SUFFIX,cs170.com,Proxy\nDOMAIN-SUFFIX,theartofthevisit.com,Proxy\nDOMAIN-SUFFIX,1984bbs.com,Proxy\nDOMAIN-SUFFIX,wallhub.org,Proxy\nDOMAIN-SUFFIX,luminoslabs.com,Proxy\nDOMAIN-SUFFIX,888t.com,Proxy\nDOMAIN-SUFFIX,guochan2048.com,Proxy\nDOMAIN-SUFFIX,www.bewalnews.com,Proxy\nDOMAIN-SUFFIX,34567hb.com,Proxy\nDOMAIN-SUFFIX,blm801.com,Proxy\nDOMAIN-SUFFIX,organharvestinvestigation.net,Proxy\nDOMAIN-SUFFIX,meetup.com,Proxy\nDOMAIN-SUFFIX,banzai.co,Proxy\nDOMAIN-SUFFIX,il.ax,Proxy\nDOMAIN-SUFFIX,titanic-magazin.de,Proxy\nDOMAIN-SUFFIX,www.vpncup.com,Proxy\nDOMAIN-SUFFIX,visualphotography.com,Proxy\nDOMAIN-SUFFIX,jeefeng.com,Proxy\nDOMAIN-SUFFIX,parler.com,Proxy\nDOMAIN-SUFFIX,abc.com.au,Proxy\nDOMAIN-SUFFIX,youiv.tv,Proxy\nDOMAIN-SUFFIX,igossip.com,Proxy\nDOMAIN-SUFFIX,fhc111.com,Proxy\nDOMAIN-SUFFIX,tibetrelieffund.co.uk,Proxy\nDOMAIN-SUFFIX,aa835.net,Proxy\nDOMAIN-SUFFIX,whylover.com,Proxy\nDOMAIN-SUFFIX,projectshield.withgoogle.com,Proxy\nDOMAIN-SUFFIX,ku555.net,Proxy\nDOMAIN-SUFFIX,www.rolfoundation.org,Proxy\nDOMAIN-SUFFIX,www.singaporestar.com,Proxy\nDOMAIN-SUFFIX,jungmc.org,Proxy\nDOMAIN-SUFFIX,white-plus.net,Proxy\nDOMAIN-SUFFIX,proxybuster.org,Proxy\nDOMAIN-SUFFIX,dnsgood.xyz,Proxy\nDOMAIN-SUFFIX,www.stovax.com,Proxy\nDOMAIN-SUFFIX,www.theacru.org,Proxy\nDOMAIN-SUFFIX,anntw.com,Proxy\nDOMAIN-SUFFIX,mrface.com,Proxy\nDOMAIN-SUFFIX,blog.binux.me,Proxy\nDOMAIN-SUFFIX,theworld.org,Proxy\nDOMAIN-SUFFIX,4freeproxy.com,Proxy\nDOMAIN-SUFFIX,proxy-service.com.de,Proxy\nDOMAIN-SUFFIX,eleven-games.net,Proxy\nDOMAIN-SUFFIX,hycgame9.xyz,Proxy\nDOMAIN-SUFFIX,www.xvideo.org,Proxy\nDOMAIN-SUFFIX,guttle.com,Proxy\nDOMAIN-SUFFIX,opentechfund.org,Proxy\nDOMAIN-SUFFIX,ssr.acgfor.com,Proxy\nDOMAIN-SUFFIX,lejdd.fr,Proxy\nDOMAIN-SUFFIX,laesquina.com,Proxy\nDOMAIN-SUFFIX,www.ziyuanhai.com,Proxy\nDOMAIN-SUFFIX,www.cclifefl.org,Proxy\nDOMAIN-SUFFIX,fqrouter.com,Proxy\nDOMAIN-SUFFIX,jyzj.waqn.com,Proxy\nDOMAIN-SUFFIX,tagesschau.de,Proxy\nDOMAIN-SUFFIX,www.ontology.co,Proxy\nDOMAIN-SUFFIX,blogspot.de,Proxy\nDOMAIN-SUFFIX,www.cnn.com,Proxy\nDOMAIN-SUFFIX,nut.cc,Proxy\nDOMAIN-SUFFIX,ep56.dk,Proxy\nDOMAIN-SUFFIX,is-a-landscaper.com,Proxy\nDOMAIN-SUFFIX,kosmo.com.my,Proxy\nDOMAIN-SUFFIX,fun8878.com,Proxy\nDOMAIN-SUFFIX,www.binance.top,Proxy\nDOMAIN-SUFFIX,lzjscript.com,Proxy\nDOMAIN-SUFFIX,sugumiru18.com,Proxy\nDOMAIN-SUFFIX,api.earthcam.net,Proxy\nDOMAIN-SUFFIX,lbry.tv,Proxy\nDOMAIN-SUFFIX,www.sportslottery.com.tw,Proxy\nDOMAIN-SUFFIX,xinbi666.com,Proxy\nDOMAIN-SUFFIX,www.aznude.com,Proxy\nDOMAIN-SUFFIX,vnil.de,Proxy\nDOMAIN-SUFFIX,ms014.com,Proxy\nDOMAIN-SUFFIX,1300kai.com,Proxy\nDOMAIN-SUFFIX,skykiwi.com,Proxy\nDOMAIN-SUFFIX,bbsland.com,Proxy\nDOMAIN-SUFFIX,xlfmtalk.com,Proxy\nDOMAIN-SUFFIX,d2iugpu0nyf2uw.cloudfront.net,Proxy\nDOMAIN-SUFFIX,hamrodolakha.com,Proxy\nDOMAIN-SUFFIX,uno.keithlu.com,Proxy\nDOMAIN-SUFFIX,gqes.co.za,Proxy\nDOMAIN-SUFFIX,n.yam.com,Proxy\nDOMAIN-SUFFIX,bayria.com,Proxy\nDOMAIN-SUFFIX,zh.wikipedia.ahau.cf,Proxy\nDOMAIN-SUFFIX,hornygamer.com,Proxy\nDOMAIN-SUFFIX,79796h.com,Proxy\nDOMAIN-SUFFIX,wx99.com,Proxy\nDOMAIN-SUFFIX,www.11ja.com,Proxy\nDOMAIN-SUFFIX,8tube.com,Proxy\nDOMAIN-SUFFIX,taraholidayxxx.com,Proxy\nDOMAIN-SUFFIX,adsense.com,Proxy\nDOMAIN-SUFFIX,www.jump2see.net,Proxy\nDOMAIN-SUFFIX,videodetective.com,Proxy\nDOMAIN-SUFFIX,www.9mynews.com,Proxy\nDOMAIN-SUFFIX,onejav.com,Proxy\nDOMAIN-SUFFIX,ssltunnel.net,Proxy\nDOMAIN-SUFFIX,yacy.net,Proxy\nDOMAIN-SUFFIX,www.xxbao.com,Proxy\nDOMAIN-SUFFIX,vx.freepac.pw,Proxy\nDOMAIN-SUFFIX,xiaochuncnjp.com,Proxy\nDOMAIN-SUFFIX,horizonteglobal.com.br,Proxy\nDOMAIN-SUFFIX,dns2.us,Proxy\nDOMAIN-SUFFIX,6575888.com,Proxy\nDOMAIN-SUFFIX,thecenter.mit.edu,Proxy\nDOMAIN-SUFFIX,wapo.com,Proxy\nDOMAIN-SUFFIX,zahnarzt-oberwil.ch,Proxy\nDOMAIN-SUFFIX,homenet.org,Proxy\nDOMAIN-SUFFIX,www.vgobet.com,Proxy\nDOMAIN-SUFFIX,dzbapp.com,Proxy\nDOMAIN-SUFFIX,pizap.com,Proxy\nDOMAIN-SUFFIX,s-cute.com,Proxy\nDOMAIN-SUFFIX,hotmovs.com,Proxy\nDOMAIN-SUFFIX,hk32168.com,Proxy\nDOMAIN-SUFFIX,alittlemarket.com,Proxy\nDOMAIN-SUFFIX,d3320oxsssjvdn.cloudfront.net,Proxy\nDOMAIN-SUFFIX,cdnews.com.tw,Proxy\nDOMAIN-SUFFIX,bbq.chat,Proxy\nDOMAIN-SUFFIX,www.libraryofmoria.com,Proxy\nDOMAIN-SUFFIX,www.acgnx.se,Proxy\nDOMAIN-SUFFIX,no-ip.org,Proxy\nDOMAIN-SUFFIX,epochtimes.cz,Proxy\nDOMAIN-SUFFIX,3d-game.com,Proxy\nDOMAIN-SUFFIX,candyhug.com,Proxy\nDOMAIN-SUFFIX,goldbetsports.com,Proxy\nDOMAIN-SUFFIX,amiblockedornot.com,Proxy\nDOMAIN-SUFFIX,h5.480ld.com,Proxy\nDOMAIN-SUFFIX,xxx.xxx,Proxy\nDOMAIN-SUFFIX,www.drumnbass.net,Proxy\nDOMAIN-SUFFIX,skvpn.com,Proxy\nDOMAIN-SUFFIX,b2202.com,Proxy\nDOMAIN-SUFFIX,anime-sharing.com,Proxy\nDOMAIN-SUFFIX,asia-gaming.com,Proxy\nDOMAIN-SUFFIX,pulse.yahoo.com,Proxy\nDOMAIN-SUFFIX,www.malaysiachinainsight.com,Proxy\nDOMAIN-SUFFIX,mobile01.com,Proxy\nDOMAIN-SUFFIX,www.twliuchang.com,Proxy\nDOMAIN-SUFFIX,nyahentai.github.io,Proxy\nDOMAIN-SUFFIX,cooljsq.com,Proxy\nDOMAIN-SUFFIX,ecat-47d68.firebaseio.com,Proxy\nDOMAIN-SUFFIX,blog.cnyes.com,Proxy\nDOMAIN-SUFFIX,technorati.com,Proxy\nDOMAIN-SUFFIX,tubethumbs.com,Proxy\nDOMAIN-SUFFIX,gamez.com.tw,Proxy\nDOMAIN-SUFFIX,vpnuk.info,Proxy\nDOMAIN-SUFFIX,yumegumi.net,Proxy\nDOMAIN-SUFFIX,jmcomic1.cc,Proxy\nDOMAIN-SUFFIX,mict-international.org,Proxy\nDOMAIN-SUFFIX,www.dashlane.com,Proxy\nDOMAIN-SUFFIX,hga030.com,Proxy\nDOMAIN-SUFFIX,nitter.ca,Proxy\nDOMAIN-SUFFIX,www.midphoto.com,Proxy\nDOMAIN-SUFFIX,hkopentv.com,Proxy\nDOMAIN-SUFFIX,moonbingo.com,Proxy\nDOMAIN-SUFFIX,www.fun105.com,Proxy\nDOMAIN-SUFFIX,uw23.ddnsking.com,Proxy\nDOMAIN-SUFFIX,google.ae,Proxy\nDOMAIN-SUFFIX,vpnac.com,Proxy\nDOMAIN-SUFFIX,reflectivecode.com,Proxy\nDOMAIN-SUFFIX,firststrike.mobi,Proxy\nDOMAIN-SUFFIX,xx.domain888.pw,Proxy\nDOMAIN-SUFFIX,medibang.com,Proxy\nDOMAIN-SUFFIX,wb.tc,Proxy\nDOMAIN-SUFFIX,www.taiwanenews.com,Proxy\nDOMAIN-SUFFIX,vpnask.com,Proxy\nDOMAIN-SUFFIX,annies.com,Proxy\nDOMAIN-SUFFIX,ianhenderson.org,Proxy\nDOMAIN-SUFFIX,w209.com,Proxy\nDOMAIN-SUFFIX,maa1815.com,Proxy\nDOMAIN-SUFFIX,maxjav.com,Proxy\nDOMAIN-SUFFIX,toolbox.snopyta.org,Proxy\nDOMAIN-SUFFIX,www.yungton.org,Proxy\nDOMAIN-SUFFIX,mihk.hk,Proxy\nDOMAIN-SUFFIX,d.070790.com,Proxy\nDOMAIN-SUFFIX,dns01.flm9.net,Proxy\nDOMAIN-SUFFIX,wallproxy.com,Proxy\nDOMAIN-SUFFIX,abadecla.lv,Proxy\nDOMAIN-SUFFIX,cequens.xyz,Proxy\nDOMAIN-SUFFIX,soccer-live.pl,Proxy\nDOMAIN-SUFFIX,wedding-in-lanzhou.strikingly.com,Proxy\nDOMAIN-SUFFIX,premier.org.uk,Proxy\nDOMAIN-SUFFIX,www.lehaofa.com,Proxy\nDOMAIN-SUFFIX,consent.google.cn,Proxy\nDOMAIN-SUFFIX,ii69.net,Proxy\nDOMAIN-SUFFIX,gpt.tool00.com,Proxy\nDOMAIN-SUFFIX,uscirf.gov,Proxy\nDOMAIN-SUFFIX,telegram.org,Proxy\nDOMAIN-SUFFIX,appledaily.com.tw,Proxy\nDOMAIN-SUFFIX,s1122.com,Proxy\nDOMAIN-SUFFIX,ninisite.com,Proxy\nDOMAIN-SUFFIX,freewechat.com,Proxy\nDOMAIN-SUFFIX,dsn01.com,Proxy\nDOMAIN-SUFFIX,shopee.tw,Proxy\nDOMAIN-SUFFIX,twibbon.com,Proxy\nDOMAIN-SUFFIX,masiukiewicz.pl,Proxy\nDOMAIN-SUFFIX,51fanqiang.net,Proxy\nDOMAIN-SUFFIX,f73.net,Proxy\nDOMAIN-SUFFIX,kirtan.pro,Proxy\nDOMAIN-SUFFIX,babycatchina.com,Proxy\nDOMAIN-SUFFIX,robsmyth.com,Proxy\nDOMAIN-SUFFIX,projectsegfau.lt,Proxy\nDOMAIN-SUFFIX,southmongolia.org,Proxy\nDOMAIN-SUFFIX,xswqert56jki.point2this.com,Proxy\nDOMAIN-SUFFIX,fairy.id,Proxy\nDOMAIN-SUFFIX,www.uzaobao.com,Proxy\nDOMAIN-SUFFIX,askstudent.com,Proxy\nDOMAIN-SUFFIX,asciimw.jp,Proxy\nDOMAIN-SUFFIX,dyndns-work.com,Proxy\nDOMAIN-SUFFIX,msa-it.org,Proxy\nDOMAIN-SUFFIX,www.carousell.com.hk,Proxy\nDOMAIN-SUFFIX,skype.daesung.com,Proxy\nDOMAIN-SUFFIX,gotw.ca,Proxy\nDOMAIN-SUFFIX,rhinofabstudio.com,Proxy\nDOMAIN-SUFFIX,tibet-house-trust.co.uk,Proxy\nDOMAIN-SUFFIX,chromecast.com,Proxy\nDOMAIN-SUFFIX,alertmedia.com,Proxy\nDOMAIN-SUFFIX,ezbox.idv.tw,Proxy\nDOMAIN-SUFFIX,bmofa.org.au,Proxy\nDOMAIN-SUFFIX,www.zg999999.com,Proxy\nDOMAIN-SUFFIX,id.heroku.com,Proxy\nDOMAIN-SUFFIX,xwall.io,Proxy\nDOMAIN-SUFFIX,tonyrivera.ml,Proxy\nDOMAIN-SUFFIX,magiccloak.net,Proxy\nDOMAIN-SUFFIX,s3.radio.co,Proxy\nDOMAIN-SUFFIX,sparkpolicy.com,Proxy\nDOMAIN-SUFFIX,download.camfrogcdn.com,Proxy\nDOMAIN-SUFFIX,findyoutube.com,Proxy\nDOMAIN-SUFFIX,dynathome.net,Proxy\nDOMAIN-SUFFIX,ezjoy.com.my,Proxy\nDOMAIN-SUFFIX,joshrichardson.net,Proxy\nDOMAIN-SUFFIX,interurban-ore.000webhostapp.com,Proxy\nDOMAIN-SUFFIX,jtvnw.net,Proxy\nDOMAIN-SUFFIX,for-j.com,Proxy\nDOMAIN-SUFFIX,orangemail.okstate.edu,Proxy\nDOMAIN-SUFFIX,hj1755.com,Proxy\nDOMAIN-SUFFIX,hellouk.org,Proxy\nDOMAIN-SUFFIX,www.gmail.com.hk,Proxy\nDOMAIN-SUFFIX,v2.f1tz.eu.org,Proxy\nDOMAIN-SUFFIX,web-help-service.net,Proxy\nDOMAIN-SUFFIX,www.winept.com,Proxy\nDOMAIN-SUFFIX,www.nogomi.ru,Proxy\nDOMAIN-SUFFIX,threads.net,Proxy\nDOMAIN-SUFFIX,www.govecn.org,Proxy\nDOMAIN-SUFFIX,vpncomparison.org,Proxy\nDOMAIN-SUFFIX,xx-net.com,Proxy\nDOMAIN-SUFFIX,faydao.com,Proxy\nDOMAIN-SUFFIX,www.esslinger-zeitung.de,Proxy\nDOMAIN-SUFFIX,668ww668.com,Proxy\nDOMAIN-SUFFIX,qdl.omg.com.tw,Proxy\nDOMAIN-SUFFIX,taxisroig.es,Proxy\nDOMAIN-SUFFIX,socks-proxy.net,Proxy\nDOMAIN-SUFFIX,www.myunidays.com,Proxy\nDOMAIN-SUFFIX,airav.me,Proxy\nDOMAIN-SUFFIX,www.iweide88.com,Proxy\nDOMAIN-SUFFIX,informe.com,Proxy\nDOMAIN-SUFFIX,www.gfsoso.com,Proxy\nDOMAIN-SUFFIX,12yaki.siteonlinetest.com,Proxy\nDOMAIN-SUFFIX,ismprofessional.net,Proxy\nDOMAIN-SUFFIX,javmix.tv,Proxy\nDOMAIN-SUFFIX,www.grandlisboa.com,Proxy\nDOMAIN-SUFFIX,www.qootoon.net,Proxy\nDOMAIN-SUFFIX,fun122.com,Proxy\nDOMAIN-SUFFIX,banned-historical-archives.github.io,Proxy\nDOMAIN-SUFFIX,finstagram.com,Proxy\nDOMAIN-SUFFIX,www.skiescomic.com,Proxy\nDOMAIN-SUFFIX,public-media-cdn.blackedraw.com,Proxy\nDOMAIN-SUFFIX,myradio.hk,Proxy\nDOMAIN-SUFFIX,sharkchina.org,Proxy\nDOMAIN-SUFFIX,www.islamreligion.com,Proxy\nDOMAIN-SUFFIX,www.mp3buscador.com,Proxy\nDOMAIN-SUFFIX,www.sipgate.de,Proxy\nDOMAIN-SUFFIX,www.topchinesevpn.com,Proxy\nDOMAIN-SUFFIX,www.mgvpn1.com,Proxy\nDOMAIN-SUFFIX,wildammo.com,Proxy\nDOMAIN-SUFFIX,telegramcn.org,Proxy\nDOMAIN-SUFFIX,zyns.com,Proxy\nDOMAIN-SUFFIX,onapp.com,Proxy\nDOMAIN-SUFFIX,guge.pro,Proxy\nDOMAIN-SUFFIX,grotty-monday.com,Proxy\nDOMAIN-SUFFIX,blog.ranxiang.com,Proxy\nDOMAIN-SUFFIX,www.bluefirepoker.com,Proxy\nDOMAIN-SUFFIX,www.instaforex.eu,Proxy\nDOMAIN-SUFFIX,taiwantimes.com.tw,Proxy\nDOMAIN-SUFFIX,www.blogspot.ca,Proxy\nDOMAIN-SUFFIX,hotfucktube.com,Proxy\nDOMAIN-SUFFIX,gamejolt.com,Proxy\nDOMAIN-SUFFIX,idn.com.tw,Proxy\nDOMAIN-SUFFIX,www.eraysecure.com.tw,Proxy\nDOMAIN-SUFFIX,karthikjain.in,Proxy\nDOMAIN-SUFFIX,www-7377.com,Proxy\nDOMAIN-SUFFIX,b6617.com,Proxy\nDOMAIN-SUFFIX,worldtrade.546413.xyz,Proxy\nDOMAIN-SUFFIX,www.y-cymro.com,Proxy\nDOMAIN-SUFFIX,sankei.com,Proxy\nDOMAIN-SUFFIX,rumble.com,Proxy\nDOMAIN-SUFFIX,niceporn.tv,Proxy\nDOMAIN-SUFFIX,www.poeppelmann.com,Proxy\nDOMAIN-SUFFIX,omegle.com,Proxy\nDOMAIN-SUFFIX,wda.gov.tw,Proxy\nDOMAIN-SUFFIX,tuidang1.mh4u.org,Proxy\nDOMAIN-SUFFIX,pornsocket.com,Proxy\nDOMAIN-SUFFIX,nzmao.co.nz,Proxy\nDOMAIN-SUFFIX,blogcatalog.com,Proxy\nDOMAIN-SUFFIX,ethermine.org,Proxy\nDOMAIN-SUFFIX,www.chandrakirti.co.nz,Proxy\nDOMAIN-SUFFIX,theqoo.net,Proxy\nDOMAIN-SUFFIX,king269.com,Proxy\nDOMAIN-SUFFIX,cafedots.com,Proxy\nDOMAIN-SUFFIX,bway885.com,Proxy\nDOMAIN-SUFFIX,federalpay.org,Proxy\nDOMAIN-SUFFIX,yt.be,Proxy\nDOMAIN-SUFFIX,darktech.org,Proxy\nDOMAIN-SUFFIX,diwh6rhklifti.cloudfront.net,Proxy\nDOMAIN-SUFFIX,wireguard.com,Proxy\nDOMAIN-SUFFIX,33m33.cc,Proxy\nDOMAIN-SUFFIX,superchina.xyz,Proxy\nDOMAIN-SUFFIX,centresuite.com,Proxy\nDOMAIN-SUFFIX,partycasino.com,Proxy\nDOMAIN-SUFFIX,video.yahoo.com,Proxy\nDOMAIN-SUFFIX,www.3cblog.idv.tw,Proxy\nDOMAIN-SUFFIX,tor-exit-61.for-privacy.net,Proxy\nDOMAIN-SUFFIX,pydabogados.com.ar,Proxy\nDOMAIN-SUFFIX,pewhispanic.org,Proxy\nDOMAIN-SUFFIX,www.tibetpolicy.net,Proxy\nDOMAIN-SUFFIX,www.vivid.com,Proxy\nDOMAIN-SUFFIX,fileservice.meetcafe.net,Proxy\nDOMAIN-SUFFIX,seaofog.com,Proxy\nDOMAIN-SUFFIX,medbill.com.au,Proxy\nDOMAIN-SUFFIX,gamefaqs.com,Proxy\nDOMAIN-SUFFIX,freepornofreeporn.com,Proxy\nDOMAIN-SUFFIX,shaaid.com,Proxy\nDOMAIN-SUFFIX,zzv.dnstool.xyz,Proxy\nDOMAIN-SUFFIX,www.middleeasteye.net,Proxy\nDOMAIN-SUFFIX,244.dhcp.biz,Proxy\nDOMAIN-SUFFIX,faithfuleye.com,Proxy\nDOMAIN-SUFFIX,netflix.net,Proxy\nDOMAIN-SUFFIX,www.asianresearch.org,Proxy\nDOMAIN-SUFFIX,orz.pp.ru,Proxy\nDOMAIN-SUFFIX,sportscar365.com,Proxy\nDOMAIN-SUFFIX,watchinese.com,Proxy\nDOMAIN-SUFFIX,www.haldanes.com,Proxy\nDOMAIN-SUFFIX,sidelinessportseatery.com,Proxy\nDOMAIN-SUFFIX,google.tm,Proxy\nDOMAIN-SUFFIX,radiohilight.net,Proxy\nDOMAIN-SUFFIX,flyercenter.com,Proxy\nDOMAIN-SUFFIX,leeleelin.blogspot.jp,Proxy\nDOMAIN-SUFFIX,trimondi.de,Proxy\nDOMAIN-SUFFIX,usefulhand.com,Proxy\nDOMAIN-SUFFIX,vpnjantit.com,Proxy\nDOMAIN-SUFFIX,fc2livecn.com,Proxy\nDOMAIN-SUFFIX,sankakucomplex.com,Proxy\nDOMAIN-SUFFIX,uploadfiles.io,Proxy\nDOMAIN-SUFFIX,www.onecentralmall.com.mo,Proxy\nDOMAIN-SUFFIX,paopao14.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,e123.hk,Proxy\nDOMAIN-SUFFIX,www.4hu.com,Proxy\nDOMAIN-SUFFIX,gmfus.org,Proxy\nDOMAIN-SUFFIX,zh.vn1lib.org,Proxy\nDOMAIN-SUFFIX,dawanda.com,Proxy\nDOMAIN-SUFFIX,90022.com,Proxy\nDOMAIN-SUFFIX,cameleo.ru,Proxy\nDOMAIN-SUFFIX,f.sh22.us,Proxy\nDOMAIN-SUFFIX,xxxx.com.au,Proxy\nDOMAIN-SUFFIX,hulichicken.com,Proxy\nDOMAIN-SUFFIX,lighti.me,Proxy\nDOMAIN-SUFFIX,alliance.org.hk,Proxy\nDOMAIN-SUFFIX,pcdasm.flnet.org,Proxy\nDOMAIN-SUFFIX,www.ideaheart.net,Proxy\nDOMAIN-SUFFIX,www.mexico.com,Proxy\nDOMAIN-SUFFIX,bicycle-store-123.business.site,Proxy\nDOMAIN-SUFFIX,marxist.com,Proxy\nDOMAIN-SUFFIX,www.freerussiasex.com,Proxy\nDOMAIN-SUFFIX,yes.6te.net,Proxy\nDOMAIN-SUFFIX,www.capital.com.tw,Proxy\nDOMAIN-SUFFIX,www.vpnauthority.com,Proxy\nDOMAIN-SUFFIX,www.barebackpayperview.com,Proxy\nDOMAIN-SUFFIX,galleries.pimproll.com,Proxy\nDOMAIN-SUFFIX,hetzner.us,Proxy\nDOMAIN-SUFFIX,lujunhong2or.com,Proxy\nDOMAIN-SUFFIX,yngling.com,Proxy\nDOMAIN-SUFFIX,youtufab.cc,Proxy\nDOMAIN-SUFFIX,www.gigoptix.com,Proxy\nDOMAIN-SUFFIX,post.news,Proxy\nDOMAIN-SUFFIX,www.elegantangel.com,Proxy\nDOMAIN-SUFFIX,singyoutube.com,Proxy\nDOMAIN-SUFFIX,bgsystem.1680210.com,Proxy\nDOMAIN-SUFFIX,www.crackawines.com.au,Proxy\nDOMAIN-SUFFIX,d1jrgar08cs9fx.cloudfront.net,Proxy\nDOMAIN-SUFFIX,b766.com,Proxy\nDOMAIN-SUFFIX,seehua.com,Proxy\nDOMAIN-SUFFIX,grapecartoons.com,Proxy\nDOMAIN-SUFFIX,878m.cc,Proxy\nDOMAIN-SUFFIX,from-de.com,Proxy\nDOMAIN-SUFFIX,www.bobo25.com,Proxy\nDOMAIN-SUFFIX,vpnintouch.biz,Proxy\nDOMAIN-SUFFIX,cyclingfunmontreal.blogspot.ca,Proxy\nDOMAIN-SUFFIX,www.w88108.com,Proxy\nDOMAIN-SUFFIX,1x.com,Proxy\nDOMAIN-SUFFIX,story.udn.com,Proxy\nDOMAIN-SUFFIX,merryclinic.com,Proxy\nDOMAIN-SUFFIX,ppcafe.net,Proxy\nDOMAIN-SUFFIX,whatsapp.net,Proxy\nDOMAIN-SUFFIX,grangorz.org,Proxy\nDOMAIN-SUFFIX,www.youngthroats.com,Proxy\nDOMAIN-SUFFIX,www.hostinguk.net,Proxy\nDOMAIN-SUFFIX,549.freegamepc.org,Proxy\nDOMAIN-SUFFIX,hottg.com,Proxy\nDOMAIN-SUFFIX,dpp.org.tw,Proxy\nDOMAIN-SUFFIX,kylestech.com,Proxy\nDOMAIN-SUFFIX,18soo.com,Proxy\nDOMAIN-SUFFIX,yakbutterblues.com,Proxy\nDOMAIN-SUFFIX,cantonese.learnfalungong.com,Proxy\nDOMAIN-SUFFIX,streema.com,Proxy\nDOMAIN-SUFFIX,static.shemalez.com,Proxy\nDOMAIN-SUFFIX,thepiratebay.com,Proxy\nDOMAIN-SUFFIX,fw9.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,creedscorner.com,Proxy\nDOMAIN-SUFFIX,sukebei.pantsu.cat,Proxy\nDOMAIN-SUFFIX,www.taiwanembassy.org,Proxy\nDOMAIN-SUFFIX,bluekoff.net,Proxy\nDOMAIN-SUFFIX,108.hbmygj.cn,Proxy\nDOMAIN-SUFFIX,winbet8.com,Proxy\nDOMAIN-SUFFIX,www.tlcp8.com,Proxy\nDOMAIN-SUFFIX,worldsex.com,Proxy\nDOMAIN-SUFFIX,south-plus.org,Proxy\nDOMAIN-SUFFIX,nutaku.net,Proxy\nDOMAIN-SUFFIX,yzc333.com,Proxy\nDOMAIN-SUFFIX,cdn.helixstudios.net,Proxy\nDOMAIN-SUFFIX,ottakars.co.uk,Proxy\nDOMAIN-SUFFIX,www.songtsenhouse.ch,Proxy\nDOMAIN-SUFFIX,englandproxy.co.uk,Proxy\nDOMAIN-SUFFIX,liudejun.com,Proxy\nDOMAIN-SUFFIX,jkforum.net,Proxy\nDOMAIN-SUFFIX,fsld.fed.3d-game.com,Proxy\nDOMAIN-SUFFIX,www.288ysb.com,Proxy\nDOMAIN-SUFFIX,www.innovision.com.tw,Proxy\nDOMAIN-SUFFIX,delicious.com,Proxy\nDOMAIN-SUFFIX,wannaflix.com,Proxy\nDOMAIN-SUFFIX,edicypages.com,Proxy\nDOMAIN-SUFFIX,iownyour.biz,Proxy\nDOMAIN-SUFFIX,apsense.com,Proxy\nDOMAIN-SUFFIX,krisarruda.com.br,Proxy\nDOMAIN-SUFFIX,airconsole.com,Proxy\nDOMAIN-SUFFIX,zh.stuzenter.com,Proxy\nDOMAIN-SUFFIX,bwin01.com,Proxy\nDOMAIN-SUFFIX,www.golf.be,Proxy\nDOMAIN-SUFFIX,i.kamigami.org,Proxy\nDOMAIN-SUFFIX,bbs.gudicn.com,Proxy\nDOMAIN-SUFFIX,wiredpen.com,Proxy\nDOMAIN-SUFFIX,mallorcaluxurycars.com,Proxy\nDOMAIN-SUFFIX,cdpa.url.tw,Proxy\nDOMAIN-SUFFIX,taiwanheart.ning.com,Proxy\nDOMAIN-SUFFIX,timeweb.ru,Proxy\nDOMAIN-SUFFIX,www.diguo911.com,Proxy\nDOMAIN-SUFFIX,yizhihongxingss.com,Proxy\nDOMAIN-SUFFIX,ahri.work,Proxy\nDOMAIN-SUFFIX,navyfamily.navy.mil,Proxy\nDOMAIN-SUFFIX,atomicwallet.io,Proxy\nDOMAIN-SUFFIX,nat.gov.tw,Proxy\nDOMAIN-SUFFIX,www.e8693.com,Proxy\nDOMAIN-SUFFIX,m.2990ii2990.com,Proxy\nDOMAIN-SUFFIX,cachinese.com,Proxy\nDOMAIN-SUFFIX,prchistory.org,Proxy\nDOMAIN-SUFFIX,theepochtimes.com,Proxy\nDOMAIN-SUFFIX,cdpusa.org,Proxy\nDOMAIN-SUFFIX,www.awarenessplace.com,Proxy\nDOMAIN-SUFFIX,ai.3il33n.com,Proxy\nDOMAIN-SUFFIX,iqq.bike,Proxy\nDOMAIN-SUFFIX,ca152.com,Proxy\nDOMAIN-SUFFIX,yourlustmovies.com,Proxy\nDOMAIN-SUFFIX,1683900.com,Proxy\nDOMAIN-SUFFIX,www.penguin.com.au,Proxy\nDOMAIN-SUFFIX,492.ddnsking.com,Proxy\nDOMAIN-SUFFIX,caobian.info,Proxy\nDOMAIN-SUFFIX,www.fuckingmachines.com,Proxy\nDOMAIN-SUFFIX,d2bvykbh16nwxe.cloudfront.net,Proxy\nDOMAIN-SUFFIX,javdove2.club,Proxy\nDOMAIN-SUFFIX,allasianreviews.com,Proxy\nDOMAIN-SUFFIX,www.lifetvcn.com,Proxy\nDOMAIN-SUFFIX,usocctn.com,Proxy\nDOMAIN-SUFFIX,zaloapp.com,Proxy\nDOMAIN-SUFFIX,jamyangnorbu.com,Proxy\nDOMAIN-SUFFIX,chinarumor.com,Proxy\nDOMAIN-SUFFIX,socialeel.com,Proxy\nDOMAIN-SUFFIX,www.reachtel.com.au,Proxy\nDOMAIN-SUFFIX,hongkongdoll.tv,Proxy\nDOMAIN-SUFFIX,damplips.com,Proxy\nDOMAIN-SUFFIX,g.starmoe.xyz,Proxy\nDOMAIN-SUFFIX,animesling.com,Proxy\nDOMAIN-SUFFIX,6093.com,Proxy\nDOMAIN-SUFFIX,www.chinanewsx.com,Proxy\nDOMAIN-SUFFIX,www.northweststar.com.au,Proxy\nDOMAIN-SUFFIX,nobeijing2022.org,Proxy\nDOMAIN-SUFFIX,nexitallysafe.com,Proxy\nDOMAIN-SUFFIX,migna.ir,Proxy\nDOMAIN-SUFFIX,vpnav.com,Proxy\nDOMAIN-SUFFIX,72pro1.xyz,Proxy\nDOMAIN-SUFFIX,www.agefans.cc,Proxy\nDOMAIN-SUFFIX,guo.media,Proxy\nDOMAIN-SUFFIX,hopto.org,Proxy\nDOMAIN-SUFFIX,www.qubicaamf.com,Proxy\nDOMAIN-SUFFIX,www.bonfoundation.org,Proxy\nDOMAIN-SUFFIX,galnetwork.hr,Proxy\nDOMAIN-SUFFIX,tw.pikolive.com,Proxy\nDOMAIN-SUFFIX,earthcam.com,Proxy\nDOMAIN-SUFFIX,ns02.us,Proxy\nDOMAIN-SUFFIX,www.chip.co.id,Proxy\nDOMAIN-SUFFIX,manwa.life,Proxy\nDOMAIN-SUFFIX,army.mil,Proxy\nDOMAIN-SUFFIX,ecrparty.eu,Proxy\nDOMAIN-SUFFIX,bwin9099.com,Proxy\nDOMAIN-SUFFIX,d3372z5ghuqrcg.cloudfront.net,Proxy\nDOMAIN-SUFFIX,tibetpost.com,Proxy\nDOMAIN-SUFFIX,www.artsticket.com.tw,Proxy\nDOMAIN-SUFFIX,canadavpn.com,Proxy\nDOMAIN-SUFFIX,s1.8qi8.com,Proxy\nDOMAIN-SUFFIX,array.ws,Proxy\nDOMAIN-SUFFIX,chiloenet.cl,Proxy\nDOMAIN-SUFFIX,pelicanpointhoa.com,Proxy\nDOMAIN-SUFFIX,jav18.cc,Proxy\nDOMAIN-SUFFIX,ccpapk.com,Proxy\nDOMAIN-SUFFIX,www.bitasiaex.com,Proxy\nDOMAIN-SUFFIX,youtube.com.br,Proxy\nDOMAIN-SUFFIX,playaproperty.com,Proxy\nDOMAIN-SUFFIX,gettr.com,Proxy\nDOMAIN-SUFFIX,fun379.com,Proxy\nDOMAIN-SUFFIX,xvideos51.com,Proxy\nDOMAIN-SUFFIX,dzze.com,Proxy\nDOMAIN-SUFFIX,eksisozluk.com,Proxy\nDOMAIN-SUFFIX,xh5999.com,Proxy\nDOMAIN-SUFFIX,avi78.com,Proxy\nDOMAIN-SUFFIX,osm.org,Proxy\nDOMAIN-SUFFIX,tt1069.com,Proxy\nDOMAIN-SUFFIX,sickipedia.org,Proxy\nDOMAIN-SUFFIX,93.cao1024lui99.club,Proxy\nDOMAIN-SUFFIX,jianminchina.com,Proxy\nDOMAIN-SUFFIX,sanmin.com.tw,Proxy\nDOMAIN-SUFFIX,2267k.com,Proxy\nDOMAIN-SUFFIX,logme.in,Proxy\nDOMAIN-SUFFIX,themoviedb.org,Proxy\nDOMAIN-SUFFIX,bitsnoop.com,Proxy\nDOMAIN-SUFFIX,www.arnablog.com,Proxy\nDOMAIN-SUFFIX,pornplanner.com,Proxy\nDOMAIN-SUFFIX,mkt.w123123.com,Proxy\nDOMAIN-SUFFIX,www.zorya.dp.ua,Proxy\nDOMAIN-SUFFIX,raggedbanner.com,Proxy\nDOMAIN-SUFFIX,sex169.org,Proxy\nDOMAIN-SUFFIX,highpeakspureearth.com,Proxy\nDOMAIN-SUFFIX,www.winter-company.com,Proxy\nDOMAIN-SUFFIX,www.glorymark.com.tw,Proxy\nDOMAIN-SUFFIX,guanyincitta.com.my,Proxy\nDOMAIN-SUFFIX,www.nzmao.com,Proxy\nDOMAIN-SUFFIX,am661.com,Proxy\nDOMAIN-SUFFIX,zhinengluyou.com,Proxy\nDOMAIN-SUFFIX,gs-discuss.com,Proxy\nDOMAIN-SUFFIX,vip.meomiao.xyz,Proxy\nDOMAIN-SUFFIX,facebook.com.ar,Proxy\nDOMAIN-SUFFIX,www.vpnme.me,Proxy\nDOMAIN-SUFFIX,avq.52avq.cc,Proxy\nDOMAIN-SUFFIX,jigong1024.com,Proxy\nDOMAIN-SUFFIX,zenvpn.net,Proxy\nDOMAIN-SUFFIX,bestmodels.com,Proxy\nDOMAIN-SUFFIX,www.welovemassmeditation.com,Proxy\nDOMAIN-SUFFIX,redgti.com.ar,Proxy\nDOMAIN-SUFFIX,byt0022.com,Proxy\nDOMAIN-SUFFIX,www.lin08.com,Proxy\nDOMAIN-SUFFIX,www.fxcmmarkets.com,Proxy\nDOMAIN-SUFFIX,www.sciencenews.org,Proxy\nDOMAIN-SUFFIX,www.cunhua.mba,Proxy\nDOMAIN-SUFFIX,pacforum.org,Proxy\nDOMAIN-SUFFIX,211365.com,Proxy\nDOMAIN-SUFFIX,www.uscnpm.org,Proxy\nDOMAIN-SUFFIX,www.tomorrowland.com,Proxy\nDOMAIN-SUFFIX,tieba.comlu.com,Proxy\nDOMAIN-SUFFIX,dmoj.tk,Proxy\nDOMAIN-SUFFIX,celavi.ch,Proxy\nDOMAIN-SUFFIX,ziuata.ro,Proxy\nDOMAIN-SUFFIX,site-928529-7636-3242.strikingly.com,Proxy\nDOMAIN-SUFFIX,dmmbus.com,Proxy\nDOMAIN-SUFFIX,chat.thinkbetter.cc,Proxy\nDOMAIN-SUFFIX,sexix.net,Proxy\nDOMAIN-SUFFIX,webapplications.us,Proxy\nDOMAIN-SUFFIX,www.oxfam.org.au,Proxy\nDOMAIN-SUFFIX,carolynshymns.com,Proxy\nDOMAIN-SUFFIX,hopedialogue.org,Proxy\nDOMAIN-SUFFIX,zz9515.pw,Proxy\nDOMAIN-SUFFIX,www.rawvoice.com,Proxy\nDOMAIN-SUFFIX,aquexu.github.io,Proxy\nDOMAIN-SUFFIX,ktzhk.com,Proxy\nDOMAIN-SUFFIX,youbo365.com,Proxy\nDOMAIN-SUFFIX,bkm15.com,Proxy\nDOMAIN-SUFFIX,bbs.kimy.com.tw,Proxy\nDOMAIN-SUFFIX,jav-onlines.com,Proxy\nDOMAIN-SUFFIX,www.netaya.com,Proxy\nDOMAIN-SUFFIX,pron.tv,Proxy\nDOMAIN-SUFFIX,tingtalk.me,Proxy\nDOMAIN-SUFFIX,rb82.com,Proxy\nDOMAIN-SUFFIX,566js.com,Proxy\nDOMAIN-SUFFIX,renminbao.com,Proxy\nDOMAIN-SUFFIX,huddle.net,Proxy\nDOMAIN-SUFFIX,zzg.healthsites.xyz,Proxy\nDOMAIN-SUFFIX,snowflake-broker.torproject.net.global.prod.fastly.net,Proxy\nDOMAIN-SUFFIX,penthousemagazine.com,Proxy\nDOMAIN-SUFFIX,cnex.org.cn,Proxy\nDOMAIN-SUFFIX,tor-exit-48.for-privacy.net,Proxy\nDOMAIN-SUFFIX,s67.snode.xyz,Proxy\nDOMAIN-SUFFIX,dyndns-free.com,Proxy\nDOMAIN-SUFFIX,www.z100.com,Proxy\nDOMAIN-SUFFIX,ctfriend.net,Proxy\nDOMAIN-SUFFIX,islamicity.com,Proxy\nDOMAIN-SUFFIX,ns01.info,Proxy\nDOMAIN-SUFFIX,yull.co.uk,Proxy\nDOMAIN-SUFFIX,www.green-living.com.tw,Proxy\nDOMAIN-SUFFIX,m.leduo222.com,Proxy\nDOMAIN-SUFFIX,calgarychinese.ca,Proxy\nDOMAIN-SUFFIX,tn3.shemalez.com,Proxy\nDOMAIN-SUFFIX,tutanota.com,Proxy\nDOMAIN-SUFFIX,tw.mall.yahoo.com,Proxy\nDOMAIN-SUFFIX,djk7uv3rkkqs8.cloudfront.net,Proxy\nDOMAIN-SUFFIX,guaguass.org,Proxy\nDOMAIN-SUFFIX,boulevard-sa.com.ar,Proxy\nDOMAIN-SUFFIX,va.v.liveperson.net,Proxy\nDOMAIN-SUFFIX,1000.tv,Proxy\nDOMAIN-SUFFIX,blog.davidziegler.net,Proxy\nDOMAIN-SUFFIX,www.cmharmony.net,Proxy\nDOMAIN-SUFFIX,sockslist.net,Proxy\nDOMAIN-SUFFIX,blogs.tampabay.com,Proxy\nDOMAIN-SUFFIX,shopping.com,Proxy\nDOMAIN-SUFFIX,c02444.com,Proxy\nDOMAIN-SUFFIX,tibetan.fr,Proxy\nDOMAIN-SUFFIX,c.chei.us,Proxy\nDOMAIN-SUFFIX,stoptibetcrisis.net,Proxy\nDOMAIN-SUFFIX,avpapa.co,Proxy\nDOMAIN-SUFFIX,almostmy.com,Proxy\nDOMAIN-SUFFIX,bartender.dowjones.com,Proxy\nDOMAIN-SUFFIX,www.inoxpa.com,Proxy\nDOMAIN-SUFFIX,www.boundgods.com,Proxy\nDOMAIN-SUFFIX,ebookee.com,Proxy\nDOMAIN-SUFFIX,lqqtv.me,Proxy\nDOMAIN-SUFFIX,jbslot.com,Proxy\nDOMAIN-SUFFIX,lkcn.net,Proxy\nDOMAIN-SUFFIX,www.alchemer.com,Proxy\nDOMAIN-SUFFIX,empflix.com,Proxy\nDOMAIN-SUFFIX,568.net,Proxy\nDOMAIN-SUFFIX,domaintest.soy,Proxy\nDOMAIN-SUFFIX,www.xijinping.one,Proxy\nDOMAIN-SUFFIX,porn99.net,Proxy\nDOMAIN-SUFFIX,lb039.com,Proxy\nDOMAIN-SUFFIX,k8222.com,Proxy\nDOMAIN-SUFFIX,falundafaindia.org,Proxy\nDOMAIN-SUFFIX,reddogs.ro,Proxy\nDOMAIN-SUFFIX,blogspot.co.at,Proxy\nDOMAIN-SUFFIX,h5.469ld.com,Proxy\nDOMAIN-SUFFIX,www.indianporngirls.com,Proxy\nDOMAIN-SUFFIX,553300.com,Proxy\nDOMAIN-SUFFIX,xxxtik.com,Proxy\nDOMAIN-SUFFIX,wineit-25142.firebaseio.com,Proxy\nDOMAIN-SUFFIX,beric.me,Proxy\nDOMAIN-SUFFIX,stoweboyd.com,Proxy\nDOMAIN-SUFFIX,redtube.cc,Proxy\nDOMAIN-SUFFIX,www.magispartners.com,Proxy\nDOMAIN-SUFFIX,www.adssasia.com,Proxy\nDOMAIN-SUFFIX,b2h3x3f6.stackpathcdn.com,Proxy\nDOMAIN-SUFFIX,singtao.tv,Proxy\nDOMAIN-SUFFIX,imgur.io,Proxy\nDOMAIN-SUFFIX,onedrive.live.com,Proxy\nDOMAIN-SUFFIX,eiresol.com,Proxy\nDOMAIN-SUFFIX,stream4free.live,Proxy\nDOMAIN-SUFFIX,podsync.net,Proxy\nDOMAIN-SUFFIX,newsdetox.ca,Proxy\nDOMAIN-SUFFIX,cd88.ga,Proxy\nDOMAIN-SUFFIX,fxcm.co,Proxy\nDOMAIN-SUFFIX,xh02222.com,Proxy\nDOMAIN-SUFFIX,thecrosbygroup.com,Proxy\nDOMAIN-SUFFIX,www.netbirds.com,Proxy\nDOMAIN-SUFFIX,boards.4channel.org,Proxy\nDOMAIN-SUFFIX,mkt.bogou188.com,Proxy\nDOMAIN-SUFFIX,camscreative.com,Proxy\nDOMAIN-SUFFIX,secure.footprint.net,Proxy\nDOMAIN-SUFFIX,www.javbus.work,Proxy\nDOMAIN-SUFFIX,83231.com,Proxy\nDOMAIN-SUFFIX,www.gunworld.com.au,Proxy\nDOMAIN-SUFFIX,kowalskypage.com,Proxy\nDOMAIN-SUFFIX,chkci.org.hk,Proxy\nDOMAIN-SUFFIX,mardware.com,Proxy\nDOMAIN-SUFFIX,paipaitxt.com,Proxy\nDOMAIN-SUFFIX,t3.com,Proxy\nDOMAIN-SUFFIX,224000111.com,Proxy\nDOMAIN-SUFFIX,brat.gq,Proxy\nDOMAIN-SUFFIX,nlvpn.com,Proxy\nDOMAIN-SUFFIX,ned.org,Proxy\nDOMAIN-SUFFIX,himemix.net,Proxy\nDOMAIN-SUFFIX,cscp894.com,Proxy\nDOMAIN-SUFFIX,kagyumonlam.org,Proxy\nDOMAIN-SUFFIX,rushlimbaugh.com,Proxy\nDOMAIN-SUFFIX,www.happypositivesuccessful.com,Proxy\nDOMAIN-SUFFIX,tinypaste.com,Proxy\nDOMAIN-SUFFIX,mastodon.host,Proxy\nDOMAIN-SUFFIX,schema.org,Proxy\nDOMAIN-SUFFIX,yb188.emc77.com,Proxy\nDOMAIN-SUFFIX,wiki.llsif.moe,Proxy\nDOMAIN-SUFFIX,kelinsky.com,Proxy\nDOMAIN-SUFFIX,six-degrees.io,Proxy\nDOMAIN-SUFFIX,u2990.com,Proxy\nDOMAIN-SUFFIX,mastodon.sergal.org,Proxy\nDOMAIN-SUFFIX,qingshe888.com,Proxy\nDOMAIN-SUFFIX,youtube.hk,Proxy\nDOMAIN-SUFFIX,dj2111.com,Proxy\nDOMAIN-SUFFIX,eyoutube.com,Proxy\nDOMAIN-SUFFIX,nm.nmcsym.org,Proxy\nDOMAIN-SUFFIX,rss.app,Proxy\nDOMAIN-SUFFIX,kraftbrands.com,Proxy\nDOMAIN-SUFFIX,www.blmkt.com,Proxy\nDOMAIN-SUFFIX,freexcafe.com,Proxy\nDOMAIN-SUFFIX,japan-whores.com,Proxy\nDOMAIN-SUFFIX,google.com.ni,Proxy\nDOMAIN-SUFFIX,bbc.in,Proxy\nDOMAIN-SUFFIX,adss.asia,Proxy\nDOMAIN-SUFFIX,feedx.pw,Proxy\nDOMAIN-SUFFIX,ablwang.com,Proxy\nDOMAIN-SUFFIX,hidemytraxproxy.ca,Proxy\nDOMAIN-SUFFIX,www.manybo.com,Proxy\nDOMAIN-SUFFIX,nnbctn.site,Proxy\nDOMAIN-SUFFIX,f95zone.com,Proxy\nDOMAIN-SUFFIX,lemongame.tw,Proxy\nDOMAIN-SUFFIX,388285.com,Proxy\nDOMAIN-SUFFIX,local.com,Proxy\nDOMAIN-SUFFIX,police.gov.sg,Proxy\nDOMAIN-SUFFIX,bonfoundation.org,Proxy\nDOMAIN-SUFFIX,zh.wikipedia.njau.cf,Proxy\nDOMAIN-SUFFIX,www.maresrealty.es,Proxy\nDOMAIN-SUFFIX,9709632.com,Proxy\nDOMAIN-SUFFIX,britishproxy.uk,Proxy\nDOMAIN-SUFFIX,2lipstube.com,Proxy\nDOMAIN-SUFFIX,63i.com,Proxy\nDOMAIN-SUFFIX,www.studyinaust.com.tw,Proxy\nDOMAIN-SUFFIX,d2ehbxnrtj7x3l.cloudfront.net,Proxy\nDOMAIN-SUFFIX,usejump.net,Proxy\nDOMAIN-SUFFIX,imageshack.us,Proxy\nDOMAIN-SUFFIX,jm-comic2.xyz,Proxy\nDOMAIN-SUFFIX,ninetail.tk,Proxy\nDOMAIN-SUFFIX,mdtmotors.ro,Proxy\nDOMAIN-SUFFIX,yourtango.com,Proxy\nDOMAIN-SUFFIX,gs108.com,Proxy\nDOMAIN-SUFFIX,www.bunburymail.com.au,Proxy\nDOMAIN-SUFFIX,newopen.org,Proxy\nDOMAIN-SUFFIX,opindia.com,Proxy\nDOMAIN-SUFFIX,usahealth.xyz,Proxy\nDOMAIN-SUFFIX,airav.co,Proxy\nDOMAIN-SUFFIX,hidemyna.me,Proxy\nDOMAIN-SUFFIX,redbuzzl2.airasia.com,Proxy\nDOMAIN-SUFFIX,outfw.net,Proxy\nDOMAIN-SUFFIX,thenationalpulse.com,Proxy\nDOMAIN-SUFFIX,is.bahadr.xyz,Proxy\nDOMAIN-SUFFIX,sexhuang.com,Proxy\nDOMAIN-SUFFIX,mofidonline.com,Proxy\nDOMAIN-SUFFIX,www.678amblr.com,Proxy\nDOMAIN-SUFFIX,dee1.dhcp.biz,Proxy\nDOMAIN-SUFFIX,wufafangwen.com,Proxy\nDOMAIN-SUFFIX,www.xinshengming.com,Proxy\nDOMAIN-SUFFIX,www.evergreenbuddhist.com,Proxy\nDOMAIN-SUFFIX,hoy.tv,Proxy\nDOMAIN-SUFFIX,sysdsolutions.com,Proxy\nDOMAIN-SUFFIX,1680100.com,Proxy\nDOMAIN-SUFFIX,postcardandtag.com,Proxy\nDOMAIN-SUFFIX,greyhurst.ca,Proxy\nDOMAIN-SUFFIX,tidex.com,Proxy\nDOMAIN-SUFFIX,bjl2077.com,Proxy\nDOMAIN-SUFFIX,joinhomebase.com,Proxy\nDOMAIN-SUFFIX,www.amssa.org,Proxy\nDOMAIN-SUFFIX,www.bunny.net,Proxy\nDOMAIN-SUFFIX,le881.com,Proxy\nDOMAIN-SUFFIX,operavpn.com,Proxy\nDOMAIN-SUFFIX,chinainperspective.org,Proxy\nDOMAIN-SUFFIX,nitter.d420.de,Proxy\nDOMAIN-SUFFIX,prezi.org,Proxy\nDOMAIN-SUFFIX,bitfinex.com,Proxy\nDOMAIN-SUFFIX,bcw115.com,Proxy\nDOMAIN-SUFFIX,signatureweds.com,Proxy\nDOMAIN-SUFFIX,juyuange.org,Proxy\nDOMAIN-SUFFIX,52jav.com,Proxy\nDOMAIN-SUFFIX,supertweet.net,Proxy\nDOMAIN-SUFFIX,www.vividads.com.au,Proxy\nDOMAIN-SUFFIX,www.camillethomas.com,Proxy\nDOMAIN-SUFFIX,casinobellini.com,Proxy\nDOMAIN-SUFFIX,www.qzg33.com,Proxy\nDOMAIN-SUFFIX,proxies4u.com,Proxy\nDOMAIN-SUFFIX,btos.pw,Proxy\nDOMAIN-SUFFIX,500px.org,Proxy\nDOMAIN-SUFFIX,github.io,Proxy\nDOMAIN-SUFFIX,biblesforamerica.org,Proxy\nDOMAIN-SUFFIX,tpsl-india.in,Proxy\nDOMAIN-SUFFIX,greenvpn.biz,Proxy\nDOMAIN-SUFFIX,singtao.com,Proxy\nDOMAIN-SUFFIX,aabc.ml,Proxy\nDOMAIN-SUFFIX,itsky.it,Proxy\nDOMAIN-SUFFIX,mediamatters.org,Proxy\nDOMAIN-SUFFIX,ok.writers.idv.tw,Proxy\nDOMAIN-SUFFIX,blowjob.com,Proxy\nDOMAIN-SUFFIX,erik-ellis.com,Proxy\nDOMAIN-SUFFIX,www.jhgroupcpa.com,Proxy\nDOMAIN-SUFFIX,prdelb.talkk.net,Proxy\nDOMAIN-SUFFIX,cdbook.org,Proxy\nDOMAIN-SUFFIX,zenguard.org,Proxy\nDOMAIN-SUFFIX,avos.pw,Proxy\nDOMAIN-SUFFIX,networktunnel.net,Proxy\nDOMAIN-SUFFIX,focustaiwan.tw,Proxy\nDOMAIN-SUFFIX,xvinlink.com,Proxy\nDOMAIN-SUFFIX,rightcam.com,Proxy\nDOMAIN-SUFFIX,ff1483.pw,Proxy\nDOMAIN-SUFFIX,podcastaddict.com,Proxy\nDOMAIN-SUFFIX,www.expressintnet.com,Proxy\nDOMAIN-SUFFIX,widevine.com,Proxy\nDOMAIN-SUFFIX,www.tok.life,Proxy\nDOMAIN-SUFFIX,www.wangruowang.org,Proxy\nDOMAIN-SUFFIX,www.1000giri.net,Proxy\nDOMAIN-SUFFIX,hd.cssyz.xyz,Proxy\nDOMAIN-SUFFIX,solhimal.org,Proxy\nDOMAIN-SUFFIX,meditateinseattle.org,Proxy\nDOMAIN-SUFFIX,www.mitao520.com,Proxy\nDOMAIN-SUFFIX,bit.now-ip.net,Proxy\nDOMAIN-SUFFIX,christianteens.about.com,Proxy\nDOMAIN-SUFFIX,20188v.com,Proxy\nDOMAIN-SUFFIX,rolosworld.com,Proxy\nDOMAIN-SUFFIX,y48bc.com,Proxy\nDOMAIN-SUFFIX,www.rwsentosa.com,Proxy\nDOMAIN-SUFFIX,daili.zquanzi.com,Proxy\nDOMAIN-SUFFIX,mrskin.com,Proxy\nDOMAIN-SUFFIX,vanessasoares.com,Proxy\nDOMAIN-SUFFIX,51150011.com,Proxy\nDOMAIN-SUFFIX,cnnphilippines.com,Proxy\nDOMAIN-SUFFIX,14barapp.site,Proxy\nDOMAIN-SUFFIX,xun600.com,Proxy\nDOMAIN-SUFFIX,wikimedia.org,Proxy\nDOMAIN-SUFFIX,bloombergbusiness.com,Proxy\nDOMAIN-SUFFIX,www.88yule5.com,Proxy\nDOMAIN-SUFFIX,mlnd.ir,Proxy\nDOMAIN-SUFFIX,ftvgirls.com,Proxy\nDOMAIN-SUFFIX,inthenameofconfuciusmovie.com,Proxy\nDOMAIN-SUFFIX,www.cvpncup.com,Proxy\nDOMAIN-SUFFIX,www.lastss.com,Proxy\nDOMAIN-SUFFIX,www.takinoracing.com,Proxy\nDOMAIN-SUFFIX,www.chancentre.org,Proxy\nDOMAIN-SUFFIX,yvesgeleyn.com,Proxy\nDOMAIN-SUFFIX,bild.de,Proxy\nDOMAIN-SUFFIX,tapestry.tapad.com,Proxy\nDOMAIN-SUFFIX,agomtv.site,Proxy\nDOMAIN-SUFFIX,adanwebnet.site44.com,Proxy\nDOMAIN-SUFFIX,faceporn.no,Proxy\nDOMAIN-SUFFIX,mix.com,Proxy\nDOMAIN-SUFFIX,www.horizonweekly.ca,Proxy\nDOMAIN-SUFFIX,cbtc.org.hk,Proxy\nDOMAIN-SUFFIX,chinaknowledge.de,Proxy\nDOMAIN-SUFFIX,sostibet.com,Proxy\nDOMAIN-SUFFIX,marceloroyo.com.ar,Proxy\nDOMAIN-SUFFIX,dns.nextdns.io,Proxy\nDOMAIN-SUFFIX,www.fulidao2.com,Proxy\nDOMAIN-SUFFIX,fxvpn.com,Proxy\nDOMAIN-SUFFIX,www.5ye8.com,Proxy\nDOMAIN-SUFFIX,16563300.com,Proxy\nDOMAIN-SUFFIX,fileserve.com,Proxy\nDOMAIN-SUFFIX,cc18sm.tv,Proxy\nDOMAIN-SUFFIX,zynaima.com,Proxy\nDOMAIN-SUFFIX,barnel.net,Proxy\nDOMAIN-SUFFIX,7771.yzc615.com,Proxy\nDOMAIN-SUFFIX,www.diigo.com,Proxy\nDOMAIN-SUFFIX,expedia.co.jp,Proxy\nDOMAIN-SUFFIX,vica.info,Proxy\nDOMAIN-SUFFIX,zippyshare.com,Proxy\nDOMAIN-SUFFIX,smartschool.be,Proxy\nDOMAIN-SUFFIX,www.berliner-zeitung.de,Proxy\nDOMAIN-SUFFIX,ezpc.tk,Proxy\nDOMAIN-SUFFIX,lt619.com,Proxy\nDOMAIN-SUFFIX,pixel.wp.com,Proxy\nDOMAIN-SUFFIX,beatsondemand.ch,Proxy\nDOMAIN-SUFFIX,boxun8.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,download.speedcat.cc,Proxy\nDOMAIN-SUFFIX,www.safervpn.net,Proxy\nDOMAIN-SUFFIX,blog.istef.info,Proxy\nDOMAIN-SUFFIX,www.microsoftstore.com,Proxy\nDOMAIN-SUFFIX,google2.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,www.vantagefx.com,Proxy\nDOMAIN-SUFFIX,734bm.com,Proxy\nDOMAIN-SUFFIX,www.breakingnews.com,Proxy\nDOMAIN-SUFFIX,cart.mn,Proxy\nDOMAIN-SUFFIX,835kkk.net,Proxy\nDOMAIN-SUFFIX,rpever1.ccub168.com,Proxy\nDOMAIN-SUFFIX,www.redditstatic.com,Proxy\nDOMAIN-SUFFIX,ddys2.me,Proxy\nDOMAIN-SUFFIX,xm.co.uk,Proxy\nDOMAIN-SUFFIX,swi16.com,Proxy\nDOMAIN-SUFFIX,nytcnapps.oss-cn-hongkong.aliyuncs.com,Proxy\nDOMAIN-SUFFIX,ae.com,Proxy\nDOMAIN-SUFFIX,d250oh0inbp07d.cloudfront.net,Proxy\nDOMAIN-SUFFIX,helloandroid.com,Proxy\nDOMAIN-SUFFIX,iyouport.org,Proxy\nDOMAIN-SUFFIX,unblock-proxy.com.de,Proxy\nDOMAIN-SUFFIX,4everproxy.com,Proxy\nDOMAIN-SUFFIX,turbotwitter.com,Proxy\nDOMAIN-SUFFIX,kulichan.com,Proxy\nDOMAIN-SUFFIX,mvvpn.com,Proxy\nDOMAIN-SUFFIX,greenproxy.net,Proxy\nDOMAIN-SUFFIX,huesoi.es,Proxy\nDOMAIN-SUFFIX,www.pinkun.com,Proxy\nDOMAIN-SUFFIX,cogc.box.com,Proxy\nDOMAIN-SUFFIX,d38lsot0ifah2n.cloudfront.net,Proxy\nDOMAIN-SUFFIX,reut.rs,Proxy\nDOMAIN-SUFFIX,www.ganttproject.biz,Proxy\nDOMAIN-SUFFIX,www.xf103.com,Proxy\nDOMAIN-SUFFIX,www.sparklabs.com,Proxy\nDOMAIN-SUFFIX,n9887.com,Proxy\nDOMAIN-SUFFIX,maskvpn.com,Proxy\nDOMAIN-SUFFIX,xh00017.com,Proxy\nDOMAIN-SUFFIX,besibetonbaja.com,Proxy\nDOMAIN-SUFFIX,cdnjs.com,Proxy\nDOMAIN-SUFFIX,younganaltryouts.com,Proxy\nDOMAIN-SUFFIX,mingjingnews.com,Proxy\nDOMAIN-SUFFIX,infotmj.com,Proxy\nDOMAIN-SUFFIX,blogspot.se,Proxy\nDOMAIN-SUFFIX,nekoslovakia.net,Proxy\nDOMAIN-SUFFIX,belarusvpn.com,Proxy\nDOMAIN-SUFFIX,bebe.com,Proxy\nDOMAIN-SUFFIX,hideipusa.com,Proxy\nDOMAIN-SUFFIX,googleapis.cn,Proxy\nDOMAIN-SUFFIX,mh23.tk,Proxy\nDOMAIN-SUFFIX,vcup.in,Proxy\nDOMAIN-SUFFIX,imesport.jbo03.com,Proxy\nDOMAIN-SUFFIX,bw8668.com,Proxy\nDOMAIN-SUFFIX,twbbs.net.tw,Proxy\nDOMAIN-SUFFIX,vine.co,Proxy\nDOMAIN-SUFFIX,gall.dcinside.com,Proxy\nDOMAIN-SUFFIX,safasti.com,Proxy\nDOMAIN-SUFFIX,0car0.com,Proxy\nDOMAIN-SUFFIX,booloo.com,Proxy\nDOMAIN-SUFFIX,design-solutions.com,Proxy\nDOMAIN-SUFFIX,freeweibo.me,Proxy\nDOMAIN-SUFFIX,682135.com,Proxy\nDOMAIN-SUFFIX,onavo.com,Proxy\nDOMAIN-SUFFIX,m.1eighty8.com,Proxy\nDOMAIN-SUFFIX,royalcams.com,Proxy\nDOMAIN-SUFFIX,jysoftetc.com,Proxy\nDOMAIN-SUFFIX,seahorsenet.com,Proxy\nDOMAIN-SUFFIX,info140419.over-blog.com,Proxy\nDOMAIN-SUFFIX,8news.com.tw,Proxy\nDOMAIN-SUFFIX,9k1024.cc,Proxy\nDOMAIN-SUFFIX,error.pncle8.com,Proxy\nDOMAIN-SUFFIX,anovademocracia.com.br,Proxy\nDOMAIN-SUFFIX,free-ss.ooo,Proxy\nDOMAIN-SUFFIX,free-proxy.cz,Proxy\nDOMAIN-SUFFIX,web.nycu.edu.tw,Proxy\nDOMAIN-SUFFIX,www.pospaper.com,Proxy\nDOMAIN-SUFFIX,spiegel.tv,Proxy\nDOMAIN-SUFFIX,grjsq.me,Proxy\nDOMAIN-SUFFIX,m.jgg18.io,Proxy\nDOMAIN-SUFFIX,www.refdag.nl,Proxy\nDOMAIN-SUFFIX,www.gnc.com,Proxy\nDOMAIN-SUFFIX,www.hengssc88.com,Proxy\nDOMAIN-SUFFIX,image8.fmgstatic.com,Proxy\nDOMAIN-SUFFIX,videos.com,Proxy\nDOMAIN-SUFFIX,jmcomic7.cc,Proxy\nDOMAIN-SUFFIX,fryx.ca,Proxy\nDOMAIN-SUFFIX,y68vv.com,Proxy\nDOMAIN-SUFFIX,xxsy.vip,Proxy\nDOMAIN-SUFFIX,designsprintkit.withgoogle.com,Proxy\nDOMAIN-SUFFIX,acmedia365.com,Proxy\nDOMAIN-SUFFIX,www.skynewsinternational.com,Proxy\nDOMAIN-SUFFIX,masnafood.com,Proxy\nDOMAIN-SUFFIX,bb248.com,Proxy\nDOMAIN-SUFFIX,is-a-photographer.com,Proxy\nDOMAIN-SUFFIX,www.wikizero.com,Proxy\nDOMAIN-SUFFIX,2shared.com,Proxy\nDOMAIN-SUFFIX,geek-art.net,Proxy\nDOMAIN-SUFFIX,1lib.at,Proxy\nDOMAIN-SUFFIX,eroerogames.com,Proxy\nDOMAIN-SUFFIX,friendfinder.com,Proxy\nDOMAIN-SUFFIX,pickup.ucccc.org,Proxy\nDOMAIN-SUFFIX,hello.blogspot.hk,Proxy\nDOMAIN-SUFFIX,sabsecurities.co.uk,Proxy\nDOMAIN-SUFFIX,www.amateurallure.com,Proxy\nDOMAIN-SUFFIX,zwaar.net,Proxy\nDOMAIN-SUFFIX,powerriddle.com,Proxy\nDOMAIN-SUFFIX,amazon.com,Proxy\nDOMAIN-SUFFIX,blogspot.com.es,Proxy\nDOMAIN-SUFFIX,mapsofindia.com,Proxy\nDOMAIN-SUFFIX,60005sc.com,Proxy\nDOMAIN-SUFFIX,prokulturgut.net,Proxy\nDOMAIN-SUFFIX,www.098.com,Proxy\nDOMAIN-SUFFIX,www.bw88188.com,Proxy\nDOMAIN-SUFFIX,saturnvpn.com,Proxy\nDOMAIN-SUFFIX,project-maelstrom.bittorrent.com,Proxy\nDOMAIN-SUFFIX,cspan.org,Proxy\nDOMAIN-SUFFIX,aminoapps.com,Proxy\nDOMAIN-SUFFIX,messenger.com,Proxy\nDOMAIN-SUFFIX,2.bahamut.com.tw,Proxy\nDOMAIN-SUFFIX,www.calciumale.com,Proxy\nDOMAIN-SUFFIX,lsemtv.site,Proxy\nDOMAIN-SUFFIX,findyoutube.net,Proxy\nDOMAIN-SUFFIX,get.goreact.com,Proxy\nDOMAIN-SUFFIX,manavenue.com,Proxy\nDOMAIN-SUFFIX,unblockweb.co,Proxy\nDOMAIN-SUFFIX,roboforex-cn.com,Proxy\nDOMAIN-SUFFIX,mediafiretrend.com,Proxy\nDOMAIN-SUFFIX,invidious.weblibre.org,Proxy\nDOMAIN-SUFFIX,r13.com,Proxy\nDOMAIN-SUFFIX,immigration.gov.tw,Proxy\nDOMAIN-SUFFIX,j2.jygnet.org,Proxy\nDOMAIN-SUFFIX,aydinergil.com,Proxy\nDOMAIN-SUFFIX,hkjc.com,Proxy\nDOMAIN-SUFFIX,zg.com,Proxy\nDOMAIN-SUFFIX,snowpear.com,Proxy\nDOMAIN-SUFFIX,wowgirls.com,Proxy\nDOMAIN-SUFFIX,www.biggy.ws,Proxy\nDOMAIN-SUFFIX,zh.wikiquote.org,Proxy\nDOMAIN-SUFFIX,hung-ya.com,Proxy\nDOMAIN-SUFFIX,www.luxehomes.com.hk,Proxy\nDOMAIN-SUFFIX,search-mp3.com,Proxy\nDOMAIN-SUFFIX,m.niu88ty.com,Proxy\nDOMAIN-SUFFIX,developers.box.net,Proxy\nDOMAIN-SUFFIX,linkuswell.com,Proxy\nDOMAIN-SUFFIX,awn1.icu,Proxy\nDOMAIN-SUFFIX,pornzog.com,Proxy\nDOMAIN-SUFFIX,xn--mesr8b36xr0o.com,Proxy\nDOMAIN-SUFFIX,www.srilankantours.org,Proxy\nDOMAIN-SUFFIX,qqwljs.cc,Proxy\nDOMAIN-SUFFIX,www.gclubs.com,Proxy\nDOMAIN-SUFFIX,cn.flnet.org,Proxy\nDOMAIN-SUFFIX,kuanyu.host56.com,Proxy\nDOMAIN-SUFFIX,15.redirectme.net,Proxy\nDOMAIN-SUFFIX,www.fisk.edu,Proxy\nDOMAIN-SUFFIX,readingtimes.com.tw,Proxy\nDOMAIN-SUFFIX,syinji4.xyz,Proxy\nDOMAIN-SUFFIX,prestigeused.co.za,Proxy\nDOMAIN-SUFFIX,www.nuoyavpn.com,Proxy\nDOMAIN-SUFFIX,academy.hslda.org,Proxy\nDOMAIN-SUFFIX,dynvpn.com,Proxy\nDOMAIN-SUFFIX,newrelic.com,Proxy\nDOMAIN-SUFFIX,care2.com,Proxy\nDOMAIN-SUFFIX,impp.mn,Proxy\nDOMAIN-SUFFIX,mail.baroque-global.com,Proxy\nDOMAIN-SUFFIX,angelfire.com,Proxy\nDOMAIN-SUFFIX,australiaplus.cn,Proxy\nDOMAIN-SUFFIX,k883.com,Proxy\nDOMAIN-SUFFIX,raw.githack.com,Proxy\nDOMAIN-SUFFIX,www.theberylinstitute.org,Proxy\nDOMAIN-SUFFIX,agrtech.com.au,Proxy\nDOMAIN-SUFFIX,keezmovies.com,Proxy\nDOMAIN-SUFFIX,www.theblackalley.com,Proxy\nDOMAIN-SUFFIX,tw.voicetube.com,Proxy\nDOMAIN-SUFFIX,www.webproxy.at,Proxy\nDOMAIN-SUFFIX,gum8.instanthq.com,Proxy\nDOMAIN-SUFFIX,www.voiceplaces.com,Proxy\nDOMAIN-SUFFIX,advertising.bbcworldwide.com,Proxy\nDOMAIN-SUFFIX,order.shadowsocks.se,Proxy\nDOMAIN-SUFFIX,sohosuite.ro,Proxy\nDOMAIN-SUFFIX,hexxeh.net,Proxy\nDOMAIN-SUFFIX,brilliantcode.com,Proxy\nDOMAIN-SUFFIX,facilelogin.com,Proxy\nDOMAIN-SUFFIX,www.tufts.edu,Proxy\nDOMAIN-SUFFIX,www.fun6868.com,Proxy\nDOMAIN-SUFFIX,cdef.org,Proxy\nDOMAIN-SUFFIX,chineseaci.com,Proxy\nDOMAIN-SUFFIX,alwaysdata.com,Proxy\nDOMAIN-SUFFIX,vpnra.com,Proxy\nDOMAIN-SUFFIX,18-comic2.cc,Proxy\nDOMAIN-SUFFIX,easyvpn.zone,Proxy\nDOMAIN-SUFFIX,free-ss.site,Proxy\nDOMAIN-SUFFIX,www.norabarcelona.com,Proxy\nDOMAIN-SUFFIX,equalitylabs.org,Proxy\nDOMAIN-SUFFIX,github.com,Proxy\nDOMAIN-SUFFIX,www.winnipegfreepress.com,Proxy\nDOMAIN-SUFFIX,xvideos.tv,Proxy\nDOMAIN-SUFFIX,ms.kity.pw,Proxy\nDOMAIN-SUFFIX,www.ocreampies.com,Proxy\nDOMAIN-SUFFIX,yeyemo.us,Proxy\nDOMAIN-SUFFIX,dnset.com,Proxy\nDOMAIN-SUFFIX,fourth.com,Proxy\nDOMAIN-SUFFIX,zhaojiaren.club,Proxy\nDOMAIN-SUFFIX,7778954.com,Proxy\nDOMAIN-SUFFIX,vw699.com,Proxy\nDOMAIN-SUFFIX,pluggd.in,Proxy\nDOMAIN-SUFFIX,avoision.com,Proxy\nDOMAIN-SUFFIX,ss1.gate-project.com,Proxy\nDOMAIN-SUFFIX,ftchinese.com,Proxy\nDOMAIN-SUFFIX,www.xiangbao888.com,Proxy\nDOMAIN-SUFFIX,ssp.linz.host,Proxy\nDOMAIN-SUFFIX,sbox.ws,Proxy\nDOMAIN-SUFFIX,pwnz.org,Proxy\nDOMAIN-SUFFIX,wa.freepac.pw,Proxy\nDOMAIN-SUFFIX,www.gettyimages.ca,Proxy\nDOMAIN-SUFFIX,wizcrafts.net,Proxy\nDOMAIN-SUFFIX,independent.ie,Proxy\nDOMAIN-SUFFIX,program-think.blogspot.jp,Proxy\nDOMAIN-SUFFIX,vpns.com,Proxy\nDOMAIN-SUFFIX,1337.cx,Proxy\nDOMAIN-SUFFIX,usb3.gq,Proxy\nDOMAIN-SUFFIX,tv3.tv322.yustu.net,Proxy\nDOMAIN-SUFFIX,rojadirecta.me,Proxy\nDOMAIN-SUFFIX,apkgk.com,Proxy\nDOMAIN-SUFFIX,hulkshare.com,Proxy\nDOMAIN-SUFFIX,megurineluka.com,Proxy\nDOMAIN-SUFFIX,d1ae6hadrbjhyp.cloudfront.net,Proxy\nDOMAIN-SUFFIX,rental-mobil.com,Proxy\nDOMAIN-SUFFIX,slheng.com,Proxy\nDOMAIN-SUFFIX,1138x.com,Proxy\nDOMAIN-SUFFIX,www.wikipedia.ch,Proxy\nDOMAIN-SUFFIX,dmkp4o0o0bc6a.cloudfront.net,Proxy\nDOMAIN-SUFFIX,xmanhua.com,Proxy\nDOMAIN-SUFFIX,yvwin.com,Proxy\nDOMAIN-SUFFIX,nordstrom.com,Proxy\nDOMAIN-SUFFIX,sstm.moe,Proxy\nDOMAIN-SUFFIX,rebatesrule.net,Proxy\nDOMAIN-SUFFIX,vpnranks.com,Proxy\nDOMAIN-SUFFIX,tv555.ml,Proxy\nDOMAIN-SUFFIX,mosucloud.one,Proxy\nDOMAIN-SUFFIX,92.effers.com,Proxy\nDOMAIN-SUFFIX,pbxes.org,Proxy\nDOMAIN-SUFFIX,s54s.com,Proxy\nDOMAIN-SUFFIX,gay-torrents.net,Proxy\nDOMAIN-SUFFIX,content.wuala.com,Proxy\nDOMAIN-SUFFIX,d1noxvjsj183v.cloudfront.net,Proxy\nDOMAIN-SUFFIX,d2pwipkj00sm9z.cloudfront.net,Proxy\nDOMAIN-SUFFIX,x-berry.com,Proxy\nDOMAIN-SUFFIX,www.ois.idv.tw,Proxy\nDOMAIN-SUFFIX,bdsmstreak.com,Proxy\nDOMAIN-SUFFIX,honey.my,Proxy\nDOMAIN-SUFFIX,50134.53xtv.com,Proxy\nDOMAIN-SUFFIX,allforkids.co.uk,Proxy\nDOMAIN-SUFFIX,apjforex.com,Proxy\nDOMAIN-SUFFIX,news.modia.com.hk,Proxy\nDOMAIN-SUFFIX,gametop.com,Proxy\nDOMAIN-SUFFIX,95jyb05.com,Proxy\nDOMAIN-SUFFIX,n.stood.pw,Proxy\nDOMAIN-SUFFIX,epochtimes.com.au,Proxy\nDOMAIN-SUFFIX,fzh999.net,Proxy\nDOMAIN-SUFFIX,workatruna.com,Proxy\nDOMAIN-SUFFIX,uxdesign.cc,Proxy\nDOMAIN-SUFFIX,lattecloud.net,Proxy\nDOMAIN-SUFFIX,cdig.info,Proxy\nDOMAIN-SUFFIX,deno.dev,Proxy\nDOMAIN-SUFFIX,fourthinternational.org,Proxy\nDOMAIN-SUFFIX,uvwxyz.xyz,Proxy\nDOMAIN-SUFFIX,www.gmail.co,Proxy\nDOMAIN-SUFFIX,youporn.com,Proxy\nDOMAIN-SUFFIX,startss.net,Proxy\nDOMAIN-SUFFIX,vpnmakers.com,Proxy\nDOMAIN-SUFFIX,www.jbo53.com,Proxy\nDOMAIN-SUFFIX,po.st,Proxy\nDOMAIN-SUFFIX,qienkuen.org,Proxy\nDOMAIN-SUFFIX,openstreetmap.com,Proxy\nDOMAIN-SUFFIX,gaycenter.org,Proxy\nDOMAIN-SUFFIX,softsmirror.cf,Proxy\nDOMAIN-SUFFIX,ytpub.com,Proxy\nDOMAIN-SUFFIX,gagaoolala.com,Proxy\nDOMAIN-SUFFIX,lakeballs.fi,Proxy\nDOMAIN-SUFFIX,empfil.com,Proxy\nDOMAIN-SUFFIX,trickip.org,Proxy\nDOMAIN-SUFFIX,www.chinagaze.com,Proxy\nDOMAIN-SUFFIX,fowlergo.org,Proxy\nDOMAIN-SUFFIX,bestvpn.com,Proxy\nDOMAIN-SUFFIX,jilw.xyz,Proxy\nDOMAIN-SUFFIX,88wins.com,Proxy\nDOMAIN-SUFFIX,obywatel.gov.pl,Proxy\nDOMAIN-SUFFIX,thefrontier.hk,Proxy\nDOMAIN-SUFFIX,www.dffgames.com,Proxy\nDOMAIN-SUFFIX,www.roadshow.hk,Proxy\nDOMAIN-SUFFIX,hywt.000webhostapp.com,Proxy\nDOMAIN-SUFFIX,jiaoyou8.com,Proxy\nDOMAIN-SUFFIX,d.ns22.ru,Proxy\nDOMAIN-SUFFIX,cdn2.1024gc.net,Proxy\nDOMAIN-SUFFIX,michaelanti.com,Proxy\nDOMAIN-SUFFIX,kagyuoffice.org,Proxy\nDOMAIN-SUFFIX,nestlabs.box.com,Proxy\nDOMAIN-SUFFIX,pegasone.com,Proxy\nDOMAIN-SUFFIX,gif.deaftone.com,Proxy\nDOMAIN-SUFFIX,google.pl,Proxy\nDOMAIN-SUFFIX,s2.slyip.com,Proxy\nDOMAIN-SUFFIX,www.yooread.com,Proxy\nDOMAIN-SUFFIX,musicyoutube.com,Proxy\nDOMAIN-SUFFIX,watv.org,Proxy\nDOMAIN-SUFFIX,rategf.com,Proxy\nDOMAIN-SUFFIX,tweetbackup.com,Proxy\nDOMAIN-SUFFIX,realitylust.com,Proxy\nDOMAIN-SUFFIX,w3.68668.com,Proxy\nDOMAIN-SUFFIX,wmw.tr.vu,Proxy\nDOMAIN-SUFFIX,d1rgxtcej8p3lg.cloudfront.net,Proxy\nDOMAIN-SUFFIX,putihome.org,Proxy\nDOMAIN-SUFFIX,www.breezometer.com,Proxy\nDOMAIN-SUFFIX,fh21.com.cn,Proxy\nDOMAIN-SUFFIX,n24.de,Proxy\nDOMAIN-SUFFIX,lerner.co.il,Proxy\nDOMAIN-SUFFIX,filmon.com,Proxy\nDOMAIN-SUFFIX,www.18mcy.co,Proxy\nDOMAIN-SUFFIX,xuchao.net,Proxy\nDOMAIN-SUFFIX,bad-dragon.com,Proxy\nDOMAIN-SUFFIX,efksoft.com,Proxy\nDOMAIN-SUFFIX,germany-webproxy.de,Proxy\nDOMAIN-SUFFIX,www.xasiat.com,Proxy\nDOMAIN-SUFFIX,7765jj.com,Proxy\nDOMAIN-SUFFIX,www.mabarrat.org.lb,Proxy\nDOMAIN-SUFFIX,xx.com,Proxy\nDOMAIN-SUFFIX,blogspot.co.ke,Proxy\nDOMAIN-SUFFIX,dsnfree.xyz,Proxy\nDOMAIN-SUFFIX,efratasol.com,Proxy\nDOMAIN-SUFFIX,www.almokhtsar.com,Proxy\nDOMAIN-SUFFIX,ai.jitsu.top,Proxy\nDOMAIN-SUFFIX,www.thedodo.com,Proxy\nDOMAIN-SUFFIX,iyouport.wixsite.com,Proxy\nDOMAIN-SUFFIX,xam73.com,Proxy\nDOMAIN-SUFFIX,www.elmercurio.com,Proxy\nDOMAIN-SUFFIX,tanamonastery.org,Proxy\nDOMAIN-SUFFIX,platform.openai.com,Proxy\nDOMAIN-SUFFIX,www.allsync.com,Proxy\nDOMAIN-SUFFIX,digitalcollections.hoover.org,Proxy\nDOMAIN-SUFFIX,tt2311.com,Proxy\nDOMAIN-SUFFIX,chainreactioncycles.com,Proxy\nDOMAIN-SUFFIX,chineseporn.org,Proxy\nDOMAIN-SUFFIX,job8.com.tw,Proxy\nDOMAIN-SUFFIX,www.01-torte.com,Proxy\nDOMAIN-SUFFIX,ozsese.com,Proxy\nDOMAIN-SUFFIX,tmagazine.com,Proxy\nDOMAIN-SUFFIX,amzs.me,Proxy\nDOMAIN-SUFFIX,x8live.com,Proxy\nDOMAIN-SUFFIX,plainlaw.me,Proxy\nDOMAIN-SUFFIX,rosinstrument.com,Proxy\nDOMAIN-SUFFIX,www.w88live.com,Proxy\nDOMAIN-SUFFIX,grnet.gr,Proxy\nDOMAIN-SUFFIX,news.gamme.com.tw,Proxy\nDOMAIN-SUFFIX,pri.org,Proxy\nDOMAIN-SUFFIX,www.fucd.com,Proxy\nDOMAIN-SUFFIX,ipicture.ru,Proxy\nDOMAIN-SUFFIX,www.tkc.im,Proxy\nDOMAIN-SUFFIX,webmail.lonestar.edu,Proxy\nDOMAIN-SUFFIX,spokesman.com,Proxy\nDOMAIN-SUFFIX,www.ts5688.com,Proxy\nDOMAIN-SUFFIX,99289.com,Proxy\nDOMAIN-SUFFIX,priyankadelhiescort.in,Proxy\nDOMAIN-SUFFIX,alldigital.com.br,Proxy\nDOMAIN-SUFFIX,central64.com,Proxy\nDOMAIN-SUFFIX,youporngay.com,Proxy\nDOMAIN-SUFFIX,magmafilm.com,Proxy\nDOMAIN-SUFFIX,pen.flnet.org,Proxy\nDOMAIN-SUFFIX,sunshine-pv.com,Proxy\nDOMAIN-SUFFIX,disc.cc,Proxy\nDOMAIN-SUFFIX,ookangzheng.com,Proxy\nDOMAIN-SUFFIX,www.glamour.com,Proxy\nDOMAIN-SUFFIX,c88788.com,Proxy\nDOMAIN-SUFFIX,retroshare.ch,Proxy\nDOMAIN-SUFFIX,ipfs.cf-ipfs.com,Proxy\nDOMAIN-SUFFIX,devicebondage.com,Proxy\nDOMAIN-SUFFIX,andrescaldironi.com.ar,Proxy\nDOMAIN-SUFFIX,www.2012ab.com,Proxy\nDOMAIN-SUFFIX,www.portlincolntimes.com.au,Proxy\nDOMAIN-SUFFIX,www.pornosvane.com,Proxy\nDOMAIN-SUFFIX,www.google.no,Proxy\nDOMAIN-SUFFIX,lenwhite.com,Proxy\nDOMAIN-SUFFIX,10b1010.com,Proxy\nDOMAIN-SUFFIX,p5bpbw.com,Proxy\nDOMAIN-SUFFIX,www.relink.us,Proxy\nDOMAIN-SUFFIX,www.cnas.org,Proxy\nDOMAIN-SUFFIX,dessci.com,Proxy\nDOMAIN-SUFFIX,zhshi.top,Proxy\nDOMAIN-SUFFIX,whispertalks.com,Proxy\nDOMAIN-SUFFIX,helpster.de,Proxy\nDOMAIN-SUFFIX,nutsvpn.work,Proxy\nDOMAIN-SUFFIX,warbler.iconfactory.net,Proxy\nDOMAIN-SUFFIX,luozang.chickenkiller.com,Proxy\nDOMAIN-SUFFIX,business-humanrights.org,Proxy\nDOMAIN-SUFFIX,fictionfanatic.ca,Proxy\nDOMAIN-SUFFIX,extabit.com,Proxy\nDOMAIN-SUFFIX,freetongdiy.blogspot.hk,Proxy\nDOMAIN-SUFFIX,va.gov,Proxy\nDOMAIN-SUFFIX,www.yjymm.com,Proxy\nDOMAIN-SUFFIX,share.playbabies.net,Proxy\nDOMAIN-SUFFIX,my66777.com,Proxy\nDOMAIN-SUFFIX,xijinpingdejiankangma.github.io,Proxy\nDOMAIN-SUFFIX,www.sytes.net,Proxy\nDOMAIN-SUFFIX,investigating.wordpress.com,Proxy\nDOMAIN-SUFFIX,www.ascendex.com,Proxy\nDOMAIN-SUFFIX,cabet706.com,Proxy\nDOMAIN-SUFFIX,www.elegant.be,Proxy\nDOMAIN-SUFFIX,freecause.com,Proxy\nDOMAIN-SUFFIX,religionnews.com,Proxy\nDOMAIN-SUFFIX,www.blogger.idv.tw,Proxy\nDOMAIN-SUFFIX,ikidol.com,Proxy\nDOMAIN-SUFFIX,www.hopthewall.com,Proxy\nDOMAIN-SUFFIX,www.uushare.com,Proxy\nDOMAIN-SUFFIX,gmail.ucar.edu,Proxy\nDOMAIN-SUFFIX,nhi.gov.tw,Proxy\nDOMAIN-SUFFIX,www.tahsintour.com.tw,Proxy\nDOMAIN-SUFFIX,initiummall.com,Proxy\nDOMAIN-SUFFIX,tsctv.net,Proxy\nDOMAIN-SUFFIX,tokyotech.box.com,Proxy\nDOMAIN-SUFFIX,bitinka.com.ar,Proxy\nDOMAIN-SUFFIX,www.skincareorganics.co.uk,Proxy\nDOMAIN-SUFFIX,www.wonder-wall.com,Proxy\nDOMAIN-SUFFIX,789666365.com,Proxy\nDOMAIN-SUFFIX,zeetv.com,Proxy\nDOMAIN-SUFFIX,cdn.sanity.io,Proxy\nDOMAIN-SUFFIX,unblock.pl,Proxy\nDOMAIN-SUFFIX,sanbu.org,Proxy\nDOMAIN-SUFFIX,blueriderart.com,Proxy\nDOMAIN-SUFFIX,newmitbbs.com,Proxy\nDOMAIN-SUFFIX,youthforfreechina.org,Proxy\nDOMAIN-SUFFIX,www.shelfari.com,Proxy\nDOMAIN-SUFFIX,gr8name.biz,Proxy\nDOMAIN-SUFFIX,coolder.com,Proxy\nDOMAIN-SUFFIX,homeproxy.net,Proxy\nDOMAIN-SUFFIX,wdly096.com,Proxy\nDOMAIN-SUFFIX,dancingbear.com,Proxy\nDOMAIN-SUFFIX,www.obcc.idv.tw,Proxy\nDOMAIN-SUFFIX,quitccp.net,Proxy\nDOMAIN-SUFFIX,www.koopjeskrant.be,Proxy\nDOMAIN-SUFFIX,ceedendai.com,Proxy\nDOMAIN-SUFFIX,dariknews.bg,Proxy\nDOMAIN-SUFFIX,shenyun.org,Proxy\nDOMAIN-SUFFIX,www.608c.com,Proxy\nDOMAIN-SUFFIX,d32cwrrdtwwwz8.cloudfront.net,Proxy\nDOMAIN-SUFFIX,n.populas.no,Proxy\nDOMAIN-SUFFIX,www.piaproxy.net,Proxy\nDOMAIN-SUFFIX,xmbs5.xyz,Proxy\nDOMAIN-SUFFIX,magcasting.co,Proxy\nDOMAIN-SUFFIX,www.kaguragames.com,Proxy\nDOMAIN-SUFFIX,drliui.com,Proxy\nDOMAIN-SUFFIX,eranews.eracom.com.tw,Proxy\nDOMAIN-SUFFIX,abitno.linpie.com,Proxy\nDOMAIN-SUFFIX,onlytweets.com,Proxy\nDOMAIN-SUFFIX,www.bimiacg.one,Proxy\nDOMAIN-SUFFIX,dawhois.com,Proxy\nDOMAIN-SUFFIX,thus.org,Proxy\nDOMAIN-SUFFIX,www.bloomberg.com.br,Proxy\nDOMAIN-SUFFIX,docs.zoho.com,Proxy\nDOMAIN-SUFFIX,pinterest.tw,Proxy\nDOMAIN-SUFFIX,xiao-sheng.ml,Proxy\nDOMAIN-SUFFIX,iknowthatgirl.com,Proxy\nDOMAIN-SUFFIX,daniela-counselling.com,Proxy\nDOMAIN-SUFFIX,ny.stgloballink.com,Proxy\nDOMAIN-SUFFIX,wsjradio.com,Proxy\nDOMAIN-SUFFIX,www.lingxiu98.com,Proxy\nDOMAIN-SUFFIX,zzw.healthsection.xyz,Proxy\nDOMAIN-SUFFIX,users.skynet.be,Proxy\nDOMAIN-SUFFIX,google.sm,Proxy\nDOMAIN-SUFFIX,fansly.com,Proxy\nDOMAIN-SUFFIX,candywarehouse.com,Proxy\nDOMAIN-SUFFIX,leeao.com.cn,Proxy\nDOMAIN-SUFFIX,www.picaacg.com,Proxy\nDOMAIN-SUFFIX,vps.bi-si1.xyz,Proxy\nDOMAIN-SUFFIX,greenfilm.tw,Proxy\nDOMAIN-SUFFIX,coindesk.com,Proxy\nDOMAIN-SUFFIX,www.mercadobitcoin.com.br,Proxy\nDOMAIN-SUFFIX,d3jyt20v04wtfn.cloudfront.net,Proxy\nDOMAIN-SUFFIX,91exl.com,Proxy\nDOMAIN-SUFFIX,hsex.men,Proxy\nDOMAIN-SUFFIX,paypal-australia.com.au,Proxy\nDOMAIN-SUFFIX,www.taipeidaniel.idv.tw,Proxy\nDOMAIN-SUFFIX,kapeika.id.lv,Proxy\nDOMAIN-SUFFIX,lethean.io,Proxy\nDOMAIN-SUFFIX,www.puuko.com,Proxy\nDOMAIN-SUFFIX,sexgames.cc,Proxy\nDOMAIN-SUFFIX,lp-03.chat.online.citi.com,Proxy\nDOMAIN-SUFFIX,tavistockandportman.nhs.uk,Proxy\nDOMAIN-SUFFIX,boxun.com,Proxy\nDOMAIN-SUFFIX,d3evyuyj06cyvx.cloudfront.net,Proxy\nDOMAIN-SUFFIX,rliya.com,Proxy\nDOMAIN-SUFFIX,sicomoros.cl,Proxy\nDOMAIN-SUFFIX,fuhui-zh.com,Proxy\nDOMAIN-SUFFIX,biantailajiao.com,Proxy\nDOMAIN-SUFFIX,515.dynamicdns.biz,Proxy\nDOMAIN-SUFFIX,hst.net.tw,Proxy\nDOMAIN-SUFFIX,www.herfirstanalsex.ws,Proxy\nDOMAIN-SUFFIX,dns-stuff.com,Proxy\nDOMAIN-SUFFIX,www.wikiredia.com,Proxy\nDOMAIN-SUFFIX,jf8833.com,Proxy\nDOMAIN-SUFFIX,opendemocracy.net,Proxy\nDOMAIN-SUFFIX,50294.u2xtv.com,Proxy\nDOMAIN-SUFFIX,fbcdn.com,Proxy\nDOMAIN-SUFFIX,hkjp.org,Proxy\nDOMAIN-SUFFIX,www.suppig.net,Proxy\nDOMAIN-SUFFIX,sakai.club,Proxy\nDOMAIN-SUFFIX,18-comic2.work,Proxy\nDOMAIN-SUFFIX,2ortv.com,Proxy\nDOMAIN-SUFFIX,anppy.com,Proxy\nDOMAIN-SUFFIX,myconnect.powayusd.com,Proxy\nDOMAIN-SUFFIX,www.krtc.com.tw,Proxy\nDOMAIN-SUFFIX,angshare.blogspot.hk,Proxy\nDOMAIN-SUFFIX,masto.pt,Proxy\nDOMAIN-SUFFIX,fb.com,Proxy\nDOMAIN-SUFFIX,superokayama.com,Proxy\nDOMAIN-SUFFIX,chineseradiousa.org,Proxy\nDOMAIN-SUFFIX,quoracdn.net,Proxy\nDOMAIN-SUFFIX,nibblehole.com,Proxy\nDOMAIN-SUFFIX,exploader.net,Proxy\nDOMAIN-SUFFIX,eatingwell.com,Proxy\nDOMAIN-SUFFIX,shkspr.mobi,Proxy\nDOMAIN-SUFFIX,wallzhihu.com,Proxy\nDOMAIN-SUFFIX,www.leonoticias.com,Proxy\nDOMAIN-SUFFIX,d36cz9buwru1tt.cloudfront.net,Proxy\nDOMAIN-SUFFIX,gogole.com,Proxy\nDOMAIN-SUFFIX,y666.com,Proxy\nDOMAIN-SUFFIX,www.xf197.com,Proxy\nDOMAIN-SUFFIX,www.camdencourier.com.au,Proxy\nDOMAIN-SUFFIX,www.modernchinastudies.org,Proxy\nDOMAIN-SUFFIX,www.socrec.org,Proxy\nDOMAIN-SUFFIX,m.4irc.com,Proxy\nDOMAIN-SUFFIX,www.2ilt.com,Proxy\nDOMAIN-SUFFIX,bifa6677.com,Proxy\nDOMAIN-SUFFIX,ifex.org,Proxy\nDOMAIN-SUFFIX,clubazb.com,Proxy\nDOMAIN-SUFFIX,mbtrx.com,Proxy\nDOMAIN-SUFFIX,d2sqppr60gazez.cloudfront.net,Proxy\nDOMAIN-SUFFIX,1380tt.com,Proxy\nDOMAIN-SUFFIX,fartit.com,Proxy\nDOMAIN-SUFFIX,xxxkinky.com,Proxy\nDOMAIN-SUFFIX,detnews.com,Proxy\nDOMAIN-SUFFIX,genexisinc.com,Proxy\nDOMAIN-SUFFIX,i999.fun,Proxy\nDOMAIN-SUFFIX,hcomic.net,Proxy\nDOMAIN-SUFFIX,scirp.org,Proxy\nDOMAIN-SUFFIX,telecomitalia.it,Proxy\nDOMAIN-SUFFIX,www.raybet.com,Proxy\nDOMAIN-SUFFIX,v2rayse.com,Proxy\nDOMAIN-SUFFIX,lyricstranslate.com,Proxy\nDOMAIN-SUFFIX,images-gaytube.com,Proxy\nDOMAIN-SUFFIX,223mm.net,Proxy\nDOMAIN-SUFFIX,uyghuraustralia.proboards.com,Proxy\nDOMAIN-SUFFIX,greenfieldbookstore.com.hk,Proxy\nDOMAIN-SUFFIX,d21infu4q1sdvm.cloudfront.net,Proxy\nDOMAIN-SUFFIX,d3c33hcgiwev3.cloudfront.net,Proxy\nDOMAIN-SUFFIX,nalandabodhi.org,Proxy\nDOMAIN-SUFFIX,vip.az,Proxy\nDOMAIN-SUFFIX,www.bwbw86.com,Proxy\nDOMAIN-SUFFIX,alkasir.com,Proxy\nDOMAIN-SUFFIX,www.6969.com,Proxy\nDOMAIN-SUFFIX,iphone7.com,Proxy\nDOMAIN-SUFFIX,syriatimes.sy,Proxy\nDOMAIN-SUFFIX,americorps.gov,Proxy\nDOMAIN-SUFFIX,sex-kontakte.at,Proxy\nDOMAIN-SUFFIX,shiksha.com,Proxy\nDOMAIN-SUFFIX,8888boma365.com,Proxy\nDOMAIN-SUFFIX,s-dm.com,Proxy\nDOMAIN-SUFFIX,gci.agtbkbet.com,Proxy\nDOMAIN-SUFFIX,firebaseio.com,Proxy\nDOMAIN-SUFFIX,www.oryon.net,Proxy\nDOMAIN-SUFFIX,archive.org,Proxy\nDOMAIN-SUFFIX,shoujichahao.com,Proxy\nDOMAIN-SUFFIX,14bar.site,Proxy\nDOMAIN-SUFFIX,dalailamafoundation.org,Proxy\nDOMAIN-SUFFIX,yuyantiyu.live,Proxy\nDOMAIN-SUFFIX,crossorigin.me,Proxy\nDOMAIN-SUFFIX,www.60hjdc.com,Proxy\nDOMAIN-SUFFIX,won.pe,Proxy\nDOMAIN-SUFFIX,www.darknight.blog,Proxy\nDOMAIN-SUFFIX,suissl.com,Proxy\nDOMAIN-SUFFIX,njuice.com,Proxy\nDOMAIN-SUFFIX,h.2047.name,Proxy\nDOMAIN-SUFFIX,hc.dhcp.biz,Proxy\nDOMAIN-SUFFIX,riviere.com.ar,Proxy\nDOMAIN-SUFFIX,d111u3mxrnneix.cloudfront.net,Proxy\nDOMAIN-SUFFIX,missrissa.net,Proxy\nDOMAIN-SUFFIX,babesho.ws,Proxy\nDOMAIN-SUFFIX,ninth.biz,Proxy\nDOMAIN-SUFFIX,ogplus.oriental-game.com,Proxy\nDOMAIN-SUFFIX,vidds.net,Proxy\nDOMAIN-SUFFIX,youiv.net,Proxy\nDOMAIN-SUFFIX,tmemail.media.org.hk,Proxy\nDOMAIN-SUFFIX,netbirds.com,Proxy\nDOMAIN-SUFFIX,is-uberleet.com,Proxy\nDOMAIN-SUFFIX,bookslive.co.za,Proxy\nDOMAIN-SUFFIX,10tracks.ru,Proxy\nDOMAIN-SUFFIX,radardedescontos.com.br,Proxy\nDOMAIN-SUFFIX,is-a-celticsfan.org,Proxy\nDOMAIN-SUFFIX,libgen.gs,Proxy\nDOMAIN-SUFFIX,stilbon.ntuu.cf,Proxy\nDOMAIN-SUFFIX,tw-npo.org,Proxy\nDOMAIN-SUFFIX,dawateislami.net,Proxy\nDOMAIN-SUFFIX,google.dz,Proxy\nDOMAIN-SUFFIX,sousebar2.xyz,Proxy\nDOMAIN-SUFFIX,www.668cp99.com,Proxy\nDOMAIN-SUFFIX,wweb.goheitv.site,Proxy\nDOMAIN-SUFFIX,www.southwalesargus.co.uk,Proxy\nDOMAIN-SUFFIX,www.turismoensevilla.com,Proxy\nDOMAIN-SUFFIX,registry.npmjs.org,Proxy\nDOMAIN-SUFFIX,blazinglink.com,Proxy\nDOMAIN-SUFFIX,bjl5.com,Proxy\nDOMAIN-SUFFIX,blog.google,Proxy\nDOMAIN-SUFFIX,therealpornwikileaks.com,Proxy\nDOMAIN-SUFFIX,is-an-actress.com,Proxy\nDOMAIN-SUFFIX,ebookbrowse.com,Proxy\nDOMAIN-SUFFIX,me.me,Proxy\nDOMAIN-SUFFIX,hen9.fat.flnet.org,Proxy\nDOMAIN-SUFFIX,www.eatapple.net,Proxy\nDOMAIN-SUFFIX,invidious.lunar.icu,Proxy\nDOMAIN-SUFFIX,anonypost.com,Proxy\nDOMAIN-SUFFIX,www.litebit.eu,Proxy\nDOMAIN-SUFFIX,krypto.link,Proxy\nDOMAIN-SUFFIX,aise.me,Proxy\nDOMAIN-SUFFIX,www.18avday.com,Proxy\nDOMAIN-SUFFIX,hjc.org,Proxy\nDOMAIN-SUFFIX,zoemama.com,Proxy\nDOMAIN-SUFFIX,pornpic4u.com,Proxy\nDOMAIN-SUFFIX,hhmanhua.com,Proxy\nDOMAIN-SUFFIX,hkupop.hku.hk,Proxy\nDOMAIN-SUFFIX,quitccp.org,Proxy\nDOMAIN-SUFFIX,www.zgzy037.gq,Proxy\nDOMAIN-SUFFIX,www.sinotv.us,Proxy\nDOMAIN-SUFFIX,www.distribution.dhxmedia.com,Proxy\nDOMAIN-SUFFIX,hiccears.com,Proxy\nDOMAIN-SUFFIX,videovor.com,Proxy\nDOMAIN-SUFFIX,ubergate.com,Proxy\nDOMAIN-SUFFIX,twitzap.com,Proxy\nDOMAIN-SUFFIX,www.eyny.com,Proxy\nDOMAIN-SUFFIX,eastmarketing.ro,Proxy\nDOMAIN-SUFFIX,tma.co.jp,Proxy\nDOMAIN-SUFFIX,e127f.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,www.qmllt.com,Proxy\nDOMAIN-SUFFIX,sunsmoke.net,Proxy\nDOMAIN-SUFFIX,www.fxcm.eu,Proxy\nDOMAIN-SUFFIX,ag.n888ss.com,Proxy\nDOMAIN-SUFFIX,thememriblog.org,Proxy\nDOMAIN-SUFFIX,www.minpo.jp,Proxy\nDOMAIN-SUFFIX,k.mmhz.us,Proxy\nDOMAIN-SUFFIX,google.com.ar,Proxy\nDOMAIN-SUFFIX,d1niq08vfntl7v.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.cumlouder.com,Proxy\nDOMAIN-SUFFIX,wethinker.com,Proxy\nDOMAIN-SUFFIX,lp888.tv,Proxy\nDOMAIN-SUFFIX,google.ru,Proxy\nDOMAIN-SUFFIX,zenways.org,Proxy\nDOMAIN-SUFFIX,cloudcomputer.ddns.net,Proxy\nDOMAIN-SUFFIX,kisstv.cc,Proxy\nDOMAIN-SUFFIX,pj2019.com,Proxy\nDOMAIN-SUFFIX,papi.com,Proxy\nDOMAIN-SUFFIX,walmart.com.br,Proxy\nDOMAIN-SUFFIX,lethalhardcore.com,Proxy\nDOMAIN-SUFFIX,registry.npm.taobao.org,Proxy\nDOMAIN-SUFFIX,zhaoyang.byethost7.com,Proxy\nDOMAIN-SUFFIX,bdj55.com,Proxy\nDOMAIN-SUFFIX,palpung.org.uk,Proxy\nDOMAIN-SUFFIX,sul.bus.flnet.org,Proxy\nDOMAIN-SUFFIX,gopanda-b26fa.firebaseio.com,Proxy\nDOMAIN-SUFFIX,bloomberg.it,Proxy\nDOMAIN-SUFFIX,asian-boy-models.com,Proxy\nDOMAIN-SUFFIX,dq35vkjfos06.cloudfront.net,Proxy\nDOMAIN-SUFFIX,dicionar.io,Proxy\nDOMAIN-SUFFIX,suadientudienlanh.com,Proxy\nDOMAIN-SUFFIX,bo7.net,Proxy\nDOMAIN-SUFFIX,cmule.com,Proxy\nDOMAIN-SUFFIX,shooshtime.com,Proxy\nDOMAIN-SUFFIX,anstor.com,Proxy\nDOMAIN-SUFFIX,opposk.ga,Proxy\nDOMAIN-SUFFIX,ca963.com,Proxy\nDOMAIN-SUFFIX,gaymap.cc,Proxy\nDOMAIN-SUFFIX,archive-it.org,Proxy\nDOMAIN-SUFFIX,onedumb.com,Proxy\nDOMAIN-SUFFIX,fromchinatousa.net,Proxy\nDOMAIN-SUFFIX,atchinese.com,Proxy\nDOMAIN-SUFFIX,www.39vpn.com,Proxy\nDOMAIN-SUFFIX,saoliao.net,Proxy\nDOMAIN-SUFFIX,dynamicdns.org.uk,Proxy\nDOMAIN-SUFFIX,walmart.ca,Proxy\nDOMAIN-SUFFIX,discuss4u.com,Proxy\nDOMAIN-SUFFIX,www.murrayvalleystandard.com.au,Proxy\nDOMAIN-SUFFIX,lindasbrushstrokes.com,Proxy\nDOMAIN-SUFFIX,hkbf.org,Proxy\nDOMAIN-SUFFIX,ideas.com,Proxy\nDOMAIN-SUFFIX,freeyoutube.net,Proxy\nDOMAIN-SUFFIX,38856677.com,Proxy\nDOMAIN-SUFFIX,www.958b.com,Proxy\nDOMAIN-SUFFIX,hitremixes.com,Proxy\nDOMAIN-SUFFIX,d1dqx91p2uadmw.cloudfront.net,Proxy\nDOMAIN-SUFFIX,d1bdz086ztl2x6.cloudfront.net,Proxy\nDOMAIN-SUFFIX,noxinfluencer.com,Proxy\nDOMAIN-SUFFIX,domain.com.au,Proxy\nDOMAIN-SUFFIX,stop-block.com,Proxy\nDOMAIN-SUFFIX,xh66.org,Proxy\nDOMAIN-SUFFIX,krytykapolityczna.pl,Proxy\nDOMAIN-SUFFIX,moefuns.asia,Proxy\nDOMAIN-SUFFIX,server2.techfun.us,Proxy\nDOMAIN-SUFFIX,yout.com,Proxy\nDOMAIN-SUFFIX,leftvalues.github.io,Proxy\nDOMAIN-SUFFIX,veja.ro,Proxy\nDOMAIN-SUFFIX,businessinsider.com,Proxy\nDOMAIN-SUFFIX,javhuge.com,Proxy\nDOMAIN-SUFFIX,watchporninpublic.com,Proxy\nDOMAIN-SUFFIX,yobt.tv,Proxy\nDOMAIN-SUFFIX,d454.net,Proxy\nDOMAIN-SUFFIX,3lib.net,Proxy\nDOMAIN-SUFFIX,av666.tv,Proxy\nDOMAIN-SUFFIX,b7311.com,Proxy\nDOMAIN-SUFFIX,00899c.com,Proxy\nDOMAIN-SUFFIX,dukou.org,Proxy\nDOMAIN-SUFFIX,rbvpn.com,Proxy\nDOMAIN-SUFFIX,zzt.familyhealth.xyz,Proxy\nDOMAIN-SUFFIX,google.bg,Proxy\nDOMAIN-SUFFIX,tlc307.com,Proxy\nDOMAIN-SUFFIX,92.lui66sy.club,Proxy\nDOMAIN-SUFFIX,klnwcity.org,Proxy\nDOMAIN-SUFFIX,bbs.fuliba.net,Proxy\nDOMAIN-SUFFIX,falunchicago.org,Proxy\nDOMAIN-SUFFIX,h5.ldmedia68.tv,Proxy\nDOMAIN-SUFFIX,www.igag.ml,Proxy\nDOMAIN-SUFFIX,vivaldi.com,Proxy\nDOMAIN-SUFFIX,m.myvideo.net.tw,Proxy\nDOMAIN-SUFFIX,social.technet.microsoft.com,Proxy\nDOMAIN-SUFFIX,tweettunnel.com,Proxy\nDOMAIN-SUFFIX,bbsmo.com,Proxy\nDOMAIN-SUFFIX,blog.elhacker.net,Proxy\nDOMAIN-SUFFIX,tintuc101.com,Proxy\nDOMAIN-SUFFIX,tweepml.org,Proxy\nDOMAIN-SUFFIX,yogipops.com,Proxy\nDOMAIN-SUFFIX,telegram.me,Proxy\nDOMAIN-SUFFIX,proxomitron.info,Proxy\nDOMAIN-SUFFIX,dailymaverick.co.za,Proxy\nDOMAIN-SUFFIX,showyourdick.org,Proxy\nDOMAIN-SUFFIX,www.mikuclub.xyz,Proxy\nDOMAIN-SUFFIX,omlet.gg,Proxy\nDOMAIN-SUFFIX,www.tianxingvpnss.com,Proxy\nDOMAIN-SUFFIX,www.alpinehearingprotection.com,Proxy\nDOMAIN-SUFFIX,226vitech.com,Proxy\nDOMAIN-SUFFIX,tiny-url.cc,Proxy\nDOMAIN-SUFFIX,page.link,Proxy\nDOMAIN-SUFFIX,deviantclip.com,Proxy\nDOMAIN-SUFFIX,hgob.org,Proxy\nDOMAIN-SUFFIX,32852222.com,Proxy\nDOMAIN-SUFFIX,ro89.com,Proxy\nDOMAIN-SUFFIX,gay-needed.com,Proxy\nDOMAIN-SUFFIX,hideman.net,Proxy\nDOMAIN-SUFFIX,coolrom.com,Proxy\nDOMAIN-SUFFIX,ingarden.pt,Proxy\nDOMAIN-SUFFIX,fh128.com,Proxy\nDOMAIN-SUFFIX,silkroaddance.com,Proxy\nDOMAIN-SUFFIX,www.dc666999.com,Proxy\nDOMAIN-SUFFIX,www.dyvip1.com,Proxy\nDOMAIN-SUFFIX,www.xxshe.com,Proxy\nDOMAIN-SUFFIX,cchr.org,Proxy\nDOMAIN-SUFFIX,diaoyuislands.org,Proxy\nDOMAIN-SUFFIX,www.perverzija.com,Proxy\nDOMAIN-SUFFIX,www.letstalkapp.net,Proxy\nDOMAIN-SUFFIX,compileheart.com,Proxy\nDOMAIN-SUFFIX,fqzhan.com,Proxy\nDOMAIN-SUFFIX,www.thesundaily.my,Proxy\nDOMAIN-SUFFIX,www.jex.com,Proxy\nDOMAIN-SUFFIX,ohara.cl,Proxy\nDOMAIN-SUFFIX,tbthouston.org,Proxy\nDOMAIN-SUFFIX,fortuneinsight.com,Proxy\nDOMAIN-SUFFIX,d3n5ctwpka3afz.cloudfront.net,Proxy\nDOMAIN-SUFFIX,djangosnippets.org,Proxy\nDOMAIN-SUFFIX,mygaysites.com,Proxy\nDOMAIN-SUFFIX,www.anastasialin.com,Proxy\nDOMAIN-SUFFIX,kingstone.com.tw,Proxy\nDOMAIN-SUFFIX,emule-ed2k.com,Proxy\nDOMAIN-SUFFIX,dynlrgfzo6vb5.cloudfront.net,Proxy\nDOMAIN-SUFFIX,i-sev.com,Proxy\nDOMAIN-SUFFIX,www.getoutfox.com,Proxy\nDOMAIN-SUFFIX,riddikx.de,Proxy\nDOMAIN-SUFFIX,unblock-proxy.com,Proxy\nDOMAIN-SUFFIX,b-ok.org,Proxy\nDOMAIN-SUFFIX,pj111177.com,Proxy\nDOMAIN-SUFFIX,www.drba.org,Proxy\nDOMAIN-SUFFIX,qq404.gq,Proxy\nDOMAIN-SUFFIX,tweeplike.me,Proxy\nDOMAIN-SUFFIX,www.websnapr.com,Proxy\nDOMAIN-SUFFIX,terracrudus.blogspot.hk,Proxy\nDOMAIN-SUFFIX,austinjadams.com,Proxy\nDOMAIN-SUFFIX,bongacams.com,Proxy\nDOMAIN-SUFFIX,shahamat-english.com,Proxy\nDOMAIN-SUFFIX,ss7.vzw.com,Proxy\nDOMAIN-SUFFIX,www.123ssh.net,Proxy\nDOMAIN-SUFFIX,taweet.com,Proxy\nDOMAIN-SUFFIX,geekerhome.com,Proxy\nDOMAIN-SUFFIX,davila.com.ve,Proxy\nDOMAIN-SUFFIX,twipple.jp,Proxy\nDOMAIN-SUFFIX,www.islamtoleran.com,Proxy\nDOMAIN-SUFFIX,www.foxnews.com,Proxy\nDOMAIN-SUFFIX,tbsmalaysia.org,Proxy\nDOMAIN-SUFFIX,post01.com,Proxy\nDOMAIN-SUFFIX,chay.cl,Proxy\nDOMAIN-SUFFIX,chn.chosun.com,Proxy\nDOMAIN-SUFFIX,8000.com,Proxy\nDOMAIN-SUFFIX,freevpnhosting.com,Proxy\nDOMAIN-SUFFIX,osisaksen.com,Proxy\nDOMAIN-SUFFIX,nuskin.com,Proxy\nDOMAIN-SUFFIX,ugetube.com,Proxy\nDOMAIN-SUFFIX,xmlpad.com,Proxy\nDOMAIN-SUFFIX,taladriz.cl,Proxy\nDOMAIN-SUFFIX,www.urlgot.com,Proxy\nDOMAIN-SUFFIX,uproxy.org,Proxy\nDOMAIN-SUFFIX,dyndns.pro,Proxy\nDOMAIN-SUFFIX,breakgfw.com,Proxy\nDOMAIN-SUFFIX,tutturu.tv,Proxy\nDOMAIN-SUFFIX,idol-blog.com,Proxy\nDOMAIN-SUFFIX,nz1c2evxs0.enghu.shop,Proxy\nDOMAIN-SUFFIX,www.postimees.ee,Proxy\nDOMAIN-SUFFIX,etizer.org,Proxy\nDOMAIN-SUFFIX,gleeze.com,Proxy\nDOMAIN-SUFFIX,www.moyuvpn.net,Proxy\nDOMAIN-SUFFIX,ocaspro.com,Proxy\nDOMAIN-SUFFIX,twgngc.cnns.tw,Proxy\nDOMAIN-SUFFIX,fabric.io,Proxy\nDOMAIN-SUFFIX,dc7ia.eu,Proxy\nDOMAIN-SUFFIX,9691vip.com,Proxy\nDOMAIN-SUFFIX,onestore.co.kr,Proxy\nDOMAIN-SUFFIX,www.pagesix.com,Proxy\nDOMAIN-SUFFIX,www.fitch-av.com,Proxy\nDOMAIN-SUFFIX,kvbprime.asia,Proxy\nDOMAIN-SUFFIX,apk.fr.cr,Proxy\nDOMAIN-SUFFIX,bwin00087.com,Proxy\nDOMAIN-SUFFIX,elpais.com.co,Proxy\nDOMAIN-SUFFIX,nyshalong.com,Proxy\nDOMAIN-SUFFIX,m.search.aol.com,Proxy\nDOMAIN-SUFFIX,toptoon.net,Proxy\nDOMAIN-SUFFIX,bodog189.com,Proxy\nDOMAIN-SUFFIX,uproxysite.cloudfunctions.net,Proxy\nDOMAIN-SUFFIX,www.xxnxx.com,Proxy\nDOMAIN-SUFFIX,cn.gmimarkets.com,Proxy\nDOMAIN-SUFFIX,223zz.net,Proxy\nDOMAIN-SUFFIX,www.manchukuo.net,Proxy\nDOMAIN-SUFFIX,xxx-porn-hub.com,Proxy\nDOMAIN-SUFFIX,fulladultclips.com,Proxy\nDOMAIN-SUFFIX,cuies.com,Proxy\nDOMAIN-SUFFIX,withkoji.com,Proxy\nDOMAIN-SUFFIX,abc.xyz,Proxy\nDOMAIN-SUFFIX,nitter.woodland.cafe,Proxy\nDOMAIN-SUFFIX,www.ibackup.com,Proxy\nDOMAIN-SUFFIX,publicpickups.com,Proxy\nDOMAIN-SUFFIX,pornoxo.com,Proxy\nDOMAIN-SUFFIX,ghproxy.com,Proxy\nDOMAIN-SUFFIX,9hentai.com,Proxy\nDOMAIN-SUFFIX,proxyanonimo.es,Proxy\nDOMAIN-SUFFIX,icis.ws,Proxy\nDOMAIN-SUFFIX,www.sijihuisuo.club,Proxy\nDOMAIN-SUFFIX,getfoxyproxy.org,Proxy\nDOMAIN-SUFFIX,alljapanesepass.com,Proxy\nDOMAIN-SUFFIX,think.withgoogle.com,Proxy\nDOMAIN-SUFFIX,www.agefans.tv,Proxy\nDOMAIN-SUFFIX,sc.chihching.org,Proxy\nDOMAIN-SUFFIX,torvpn.com,Proxy\nDOMAIN-SUFFIX,d2t99ovihtf3ur.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.usassh.net,Proxy\nDOMAIN-SUFFIX,xn--omlea-e9b.ro,Proxy\nDOMAIN-SUFFIX,webproxy.to,Proxy\nDOMAIN-SUFFIX,hj1838.com,Proxy\nDOMAIN-SUFFIX,muchosucko.com,Proxy\nDOMAIN-SUFFIX,www.biwei6688.com,Proxy\nDOMAIN-SUFFIX,lexas.com.ar,Proxy\nDOMAIN-SUFFIX,www.alantong.com,Proxy\nDOMAIN-SUFFIX,56cun04.jigsy.com,Proxy\nDOMAIN-SUFFIX,www.ibtimes.com,Proxy\nDOMAIN-SUFFIX,9aem1.com,Proxy\nDOMAIN-SUFFIX,omnitalk.com,Proxy\nDOMAIN-SUFFIX,webpkgcache.com,Proxy\nDOMAIN-SUFFIX,9ppe.com,Proxy\nDOMAIN-SUFFIX,bd295.com,Proxy\nDOMAIN-SUFFIX,relevantradio.com,Proxy\nDOMAIN-SUFFIX,spiritunus.com,Proxy\nDOMAIN-SUFFIX,toutiaoqushi.com,Proxy\nDOMAIN-SUFFIX,fw4.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,apc.io,Proxy\nDOMAIN-SUFFIX,mail.usf.edu,Proxy\nDOMAIN-SUFFIX,cloud.tauflight.com,Proxy\nDOMAIN-SUFFIX,2157.sbfa99.com,Proxy\nDOMAIN-SUFFIX,mcat06.com,Proxy\nDOMAIN-SUFFIX,www.tribalnationsmaps.com,Proxy\nDOMAIN-SUFFIX,uloz.to,Proxy\nDOMAIN-SUFFIX,www.hopesky.net,Proxy\nDOMAIN-SUFFIX,www.internet2-0.com,Proxy\nDOMAIN-SUFFIX,chineseculture.about.com,Proxy\nDOMAIN-SUFFIX,yeahteentube.com,Proxy\nDOMAIN-SUFFIX,bygcloud.com,Proxy\nDOMAIN-SUFFIX,kinisis.ro,Proxy\nDOMAIN-SUFFIX,www.clips4sale.com,Proxy\nDOMAIN-SUFFIX,xj8866.com,Proxy\nDOMAIN-SUFFIX,www.rigzod.org,Proxy\nDOMAIN-SUFFIX,surfeasy.com,Proxy\nDOMAIN-SUFFIX,www.sundayroad.net,Proxy\nDOMAIN-SUFFIX,iavnight.com,Proxy\nDOMAIN-SUFFIX,presapescurt.ro,Proxy\nDOMAIN-SUFFIX,timdir.com,Proxy\nDOMAIN-SUFFIX,frontlinedefenders.org,Proxy\nDOMAIN-SUFFIX,baifayule.com,Proxy\nDOMAIN-SUFFIX,ysvpn.com,Proxy\nDOMAIN-SUFFIX,helloqueer.com,Proxy\nDOMAIN-SUFFIX,opensports.ca,Proxy\nDOMAIN-SUFFIX,www.pornwatchers.com,Proxy\nDOMAIN-SUFFIX,madeinchinajournal.com,Proxy\nDOMAIN-SUFFIX,ag.hg0088.com,Proxy\nDOMAIN-SUFFIX,2022vpn.net,Proxy\nDOMAIN-SUFFIX,buyu3388.com,Proxy\nDOMAIN-SUFFIX,dailymotion.fr,Proxy\nDOMAIN-SUFFIX,funk.co.za,Proxy\nDOMAIN-SUFFIX,bastillepost.com,Proxy\nDOMAIN-SUFFIX,falundafa.se,Proxy\nDOMAIN-SUFFIX,eternicode.org,Proxy\nDOMAIN-SUFFIX,www.rasid.com,Proxy\nDOMAIN-SUFFIX,www.americorps.gov,Proxy\nDOMAIN-SUFFIX,paradisehill.cc,Proxy\nDOMAIN-SUFFIX,downloadapkfree.com,Proxy\nDOMAIN-SUFFIX,m.tuancai.net,Proxy\nDOMAIN-SUFFIX,book.kanunu.org,Proxy\nDOMAIN-SUFFIX,ag.hga035.com,Proxy\nDOMAIN-SUFFIX,ca9055.com,Proxy\nDOMAIN-SUFFIX,affiliate.w88win.com,Proxy\nDOMAIN-SUFFIX,camdvr.org,Proxy\nDOMAIN-SUFFIX,ucvtelevision.cl,Proxy\nDOMAIN-SUFFIX,guishan.org,Proxy\nDOMAIN-SUFFIX,shadowsocks-r.com,Proxy\nDOMAIN-SUFFIX,chinachange.org,Proxy\nDOMAIN-SUFFIX,nccwatch.org.tw,Proxy\nDOMAIN-SUFFIX,google.hk,Proxy\nDOMAIN-SUFFIX,blog.jxu.me,Proxy\nDOMAIN-SUFFIX,axejjyy.cn,Proxy\nDOMAIN-SUFFIX,pornhodl.com,Proxy\nDOMAIN-SUFFIX,richporntube.com,Proxy\nDOMAIN-SUFFIX,www.smzb255.com,Proxy\nDOMAIN-SUFFIX,boardreader.com,Proxy\nDOMAIN-SUFFIX,freenuts.com,Proxy\nDOMAIN-SUFFIX,fux.com,Proxy\nDOMAIN-SUFFIX,links.org.au,Proxy\nDOMAIN-SUFFIX,150666.com,Proxy\nDOMAIN-SUFFIX,m.188asia.com,Proxy\nDOMAIN-SUFFIX,yunchao.net,Proxy\nDOMAIN-SUFFIX,zzv.familyhealth.xyz,Proxy\nDOMAIN-SUFFIX,lungta.cz,Proxy\nDOMAIN-SUFFIX,opensource.google,Proxy\nDOMAIN-SUFFIX,www.afr.com,Proxy\nDOMAIN-SUFFIX,18937.uobf005.authorizeddns.net,Proxy\nDOMAIN-SUFFIX,x.co,Proxy\nDOMAIN-SUFFIX,bway995.com,Proxy\nDOMAIN-SUFFIX,skn.noip.me,Proxy\nDOMAIN-SUFFIX,icomsex.com,Proxy\nDOMAIN-SUFFIX,invest-system-blog.blogspot.hk,Proxy\nDOMAIN-SUFFIX,www.6366888555.com,Proxy\nDOMAIN-SUFFIX,search.yahoo.co.jp,Proxy\nDOMAIN-SUFFIX,www.forextime.com.cn,Proxy\nDOMAIN-SUFFIX,welking-garment.com,Proxy\nDOMAIN-SUFFIX,www.myday.cn,Proxy\nDOMAIN-SUFFIX,disqus.com,Proxy\nDOMAIN-SUFFIX,avwong.com,Proxy\nDOMAIN-SUFFIX,proyectoclubes.com,Proxy\nDOMAIN-SUFFIX,www.tybio.com.tw,Proxy\nDOMAIN-SUFFIX,www.luno.com,Proxy\nDOMAIN-SUFFIX,fangong.forums-free.com,Proxy\nDOMAIN-SUFFIX,civilhrfront.org,Proxy\nDOMAIN-SUFFIX,fileflyer.com,Proxy\nDOMAIN-SUFFIX,linuxtoy.org,Proxy\nDOMAIN-SUFFIX,dilidili.wang,Proxy\nDOMAIN-SUFFIX,dsdv001.com,Proxy\nDOMAIN-SUFFIX,h5.435ld.com,Proxy\nDOMAIN-SUFFIX,www.likeqiang.org,Proxy\nDOMAIN-SUFFIX,www.fzkx.net,Proxy\nDOMAIN-SUFFIX,loopring.io,Proxy\nDOMAIN-SUFFIX,xnxx.com,Proxy\nDOMAIN-SUFFIX,abcschool.info,Proxy\nDOMAIN-SUFFIX,daburinternational.com,Proxy\nDOMAIN-SUFFIX,getdns.xyz,Proxy\nDOMAIN-SUFFIX,githubusercontent.com,Proxy\nDOMAIN-SUFFIX,bankmobilevibe.com,Proxy\nDOMAIN-SUFFIX,softether.co.jp,Proxy\nDOMAIN-SUFFIX,sslpro.eu,Proxy\nDOMAIN-SUFFIX,get.app,Proxy\nDOMAIN-SUFFIX,go2free.xyz,Proxy\nDOMAIN-SUFFIX,puffstore.com,Proxy\nDOMAIN-SUFFIX,vworldc.com,Proxy\nDOMAIN-SUFFIX,aofriend.com,Proxy\nDOMAIN-SUFFIX,bd739.com,Proxy\nDOMAIN-SUFFIX,blogspot.gr,Proxy\nDOMAIN-SUFFIX,mbusa.com,Proxy\nDOMAIN-SUFFIX,minzhuhua.net,Proxy\nDOMAIN-SUFFIX,622.dtdns.net,Proxy\nDOMAIN-SUFFIX,www.revleft.com,Proxy\nDOMAIN-SUFFIX,www.vipcubancigars.hk,Proxy\nDOMAIN-SUFFIX,d.ebeta.cloud.zyxel.com,Proxy\nDOMAIN-SUFFIX,www.xuehua.tw,Proxy\nDOMAIN-SUFFIX,betacloud2.longgood.com.tw,Proxy\nDOMAIN-SUFFIX,ghut.org,Proxy\nDOMAIN-SUFFIX,bbs.sou-tong.org,Proxy\nDOMAIN-SUFFIX,pptp-hk-2.expressnetwork.net,Proxy\nDOMAIN-SUFFIX,allfreeapk.com,Proxy\nDOMAIN-SUFFIX,hd25.tk,Proxy\nDOMAIN-SUFFIX,df9fdmen4z70s.cloudfront.net,Proxy\nDOMAIN-SUFFIX,hkdf.org,Proxy\nDOMAIN-SUFFIX,www.188betkr.com,Proxy\nDOMAIN-SUFFIX,d9mkt1vyl2mop.cloudfront.net,Proxy\nDOMAIN-SUFFIX,jcpenney.com,Proxy\nDOMAIN-SUFFIX,vpnshazam.com,Proxy\nDOMAIN-SUFFIX,australiainstitute.org.au,Proxy\nDOMAIN-SUFFIX,webbang.net,Proxy\nDOMAIN-SUFFIX,f-url.com,Proxy\nDOMAIN-SUFFIX,minecraftr.us,Proxy\nDOMAIN-SUFFIX,geekroom.tibetangeeks.com,Proxy\nDOMAIN-SUFFIX,yabo.com,Proxy\nDOMAIN-SUFFIX,b5572.com,Proxy\nDOMAIN-SUFFIX,zspeeder.me,Proxy\nDOMAIN-SUFFIX,plurielles.fr,Proxy\nDOMAIN-SUFFIX,phuquocservices.com,Proxy\nDOMAIN-SUFFIX,tlanyan.me,Proxy\nDOMAIN-SUFFIX,www.puff-store.com,Proxy\nDOMAIN-SUFFIX,themecraft.net,Proxy\nDOMAIN-SUFFIX,1666tdfamily.000webhostapp.com,Proxy\nDOMAIN-SUFFIX,1681380.com,Proxy\nDOMAIN-SUFFIX,cloud.bjcluestarvpn.tk,Proxy\nDOMAIN-SUFFIX,harshfam.org,Proxy\nDOMAIN-SUFFIX,tapatalk.com,Proxy\nDOMAIN-SUFFIX,torrenty.org,Proxy\nDOMAIN-SUFFIX,www.nydus-vpn.com,Proxy\nDOMAIN-SUFFIX,www.bbb558.com,Proxy\nDOMAIN-SUFFIX,69.mu,Proxy\nDOMAIN-SUFFIX,pinterest.at,Proxy\nDOMAIN-SUFFIX,vpncn.github.io,Proxy\nDOMAIN-SUFFIX,teachparentstech.org,Proxy\nDOMAIN-SUFFIX,officialyoutube.com,Proxy\nDOMAIN-SUFFIX,secure.ncsoft.com,Proxy\nDOMAIN-SUFFIX,ummah.com,Proxy\nDOMAIN-SUFFIX,jiji.com,Proxy\nDOMAIN-SUFFIX,www.cp3511.com,Proxy\nDOMAIN-SUFFIX,xs.freepac.pw,Proxy\nDOMAIN-SUFFIX,wikiwiki.jp,Proxy\nDOMAIN-SUFFIX,www.soaps.com,Proxy\nDOMAIN-SUFFIX,www.girlfriendsfilms.com,Proxy\nDOMAIN-SUFFIX,024.namoworld.co,Proxy\nDOMAIN-SUFFIX,www.rhoson.com,Proxy\nDOMAIN-SUFFIX,ntvmsnbc.com,Proxy\nDOMAIN-SUFFIX,zr999.com,Proxy\nDOMAIN-SUFFIX,bitbucket.io,Proxy\nDOMAIN-SUFFIX,11013.ero02mh.site,Proxy\nDOMAIN-SUFFIX,www.designandpeople.org,Proxy\nDOMAIN-SUFFIX,chinesedaily.com,Proxy\nDOMAIN-SUFFIX,www.eastturkistan.ca,Proxy\nDOMAIN-SUFFIX,yoyovpn.com,Proxy\nDOMAIN-SUFFIX,kvbprime.com,Proxy\nDOMAIN-SUFFIX,strengthlevel.com,Proxy\nDOMAIN-SUFFIX,ca157.com,Proxy\nDOMAIN-SUFFIX,jimdofree.com,Proxy\nDOMAIN-SUFFIX,namethatpornstar.com,Proxy\nDOMAIN-SUFFIX,ilbe.com,Proxy\nDOMAIN-SUFFIX,yc6395.com,Proxy\nDOMAIN-SUFFIX,card.llsif.moe,Proxy\nDOMAIN-SUFFIX,madthumbs.com,Proxy\nDOMAIN-SUFFIX,www.dharmazen.com,Proxy\nDOMAIN-SUFFIX,12031v.com,Proxy\nDOMAIN-SUFFIX,myca168.com,Proxy\nDOMAIN-SUFFIX,www.334418.net,Proxy\nDOMAIN-SUFFIX,pc4328.com,Proxy\nDOMAIN-SUFFIX,av978.cc,Proxy\nDOMAIN-SUFFIX,www.globalpost.com,Proxy\nDOMAIN-SUFFIX,kullorki.it.cx,Proxy\nDOMAIN-SUFFIX,blm2222.com,Proxy\nDOMAIN-SUFFIX,www.uswebproxy.com,Proxy\nDOMAIN-SUFFIX,chile4rent.cl,Proxy\nDOMAIN-SUFFIX,biz.ppurio.com,Proxy\nDOMAIN-SUFFIX,admiralmarkets.sc,Proxy\nDOMAIN-SUFFIX,free.fr,Proxy\nDOMAIN-SUFFIX,indiawest.com,Proxy\nDOMAIN-SUFFIX,safeforwork.net,Proxy\nDOMAIN-SUFFIX,yzc261.com,Proxy\nDOMAIN-SUFFIX,www.zodgame.org,Proxy\nDOMAIN-SUFFIX,d3vv89cvqbrqlq.cloudfront.net,Proxy\nDOMAIN-SUFFIX,paradoxwikis.com,Proxy\nDOMAIN-SUFFIX,www.archsocks.com,Proxy\nDOMAIN-SUFFIX,www.parramattasun.com.au,Proxy\nDOMAIN-SUFFIX,d1xzlgv0kaseav.cloudfront.net,Proxy\nDOMAIN-SUFFIX,aff.ezeebet.com,Proxy\nDOMAIN-SUFFIX,emu8086.com,Proxy\nDOMAIN-SUFFIX,www.tubegalore.com,Proxy\nDOMAIN-SUFFIX,d8vp5mbry9zys.cloudfront.net,Proxy\nDOMAIN-SUFFIX,meze.gen.tr,Proxy\nDOMAIN-SUFFIX,bd373.com,Proxy\nDOMAIN-SUFFIX,privoxy.org,Proxy\nDOMAIN-SUFFIX,drmingxia.org,Proxy\nDOMAIN-SUFFIX,arzon.com,Proxy\nDOMAIN-SUFFIX,infer.cl,Proxy\nDOMAIN-SUFFIX,www.laborrights.org,Proxy\nDOMAIN-SUFFIX,family.adguard-dns.com,Proxy\nDOMAIN-SUFFIX,iht.com,Proxy\nDOMAIN-SUFFIX,www.amnesty.nl,Proxy\nDOMAIN-SUFFIX,www.wlz-online.de,Proxy\nDOMAIN-SUFFIX,ku101.com,Proxy\nDOMAIN-SUFFIX,vd05s8261.tudouser.com,Proxy\nDOMAIN-SUFFIX,wi55.cf,Proxy\nDOMAIN-SUFFIX,alw.authorizeddns.org,Proxy\nDOMAIN-SUFFIX,www.facebook.hu,Proxy\nDOMAIN-SUFFIX,searx.tuxcloud.net,Proxy\nDOMAIN-SUFFIX,www.my-formosa.com,Proxy\nDOMAIN-SUFFIX,prtimes.jp,Proxy\nDOMAIN-SUFFIX,broadpressinc.com,Proxy\nDOMAIN-SUFFIX,points-media.com,Proxy\nDOMAIN-SUFFIX,tubestack.com,Proxy\nDOMAIN-SUFFIX,wingame168.com,Proxy\nDOMAIN-SUFFIX,24video.xxx,Proxy\nDOMAIN-SUFFIX,www.xnylfcp.com,Proxy\nDOMAIN-SUFFIX,hkday.net,Proxy\nDOMAIN-SUFFIX,vim.ddns.us,Proxy\nDOMAIN-SUFFIX,bifa8866.com,Proxy\nDOMAIN-SUFFIX,www.km-produce.com,Proxy\nDOMAIN-SUFFIX,nitter.x86-64-unknown-linux-gnu.zip,Proxy\nDOMAIN-SUFFIX,www.solinger-tageblatt.de,Proxy\nDOMAIN-SUFFIX,seattlepi.com,Proxy\nDOMAIN-SUFFIX,rss.cnn.com,Proxy\nDOMAIN-SUFFIX,tangben.com,Proxy\nDOMAIN-SUFFIX,iportal.me,Proxy\nDOMAIN-SUFFIX,adguard-vpn.com,Proxy\nDOMAIN-SUFFIX,fh68.com,Proxy\nDOMAIN-SUFFIX,izotope.com,Proxy\nDOMAIN-SUFFIX,liaowangxizang.net,Proxy\nDOMAIN-SUFFIX,6.tt,Proxy\nDOMAIN-SUFFIX,ssglobal.co,Proxy\nDOMAIN-SUFFIX,www.itslive.com,Proxy\nDOMAIN-SUFFIX,1lib.uk,Proxy\nDOMAIN-SUFFIX,qvodzy.org,Proxy\nDOMAIN-SUFFIX,2lib.org,Proxy\nDOMAIN-SUFFIX,politicalislam.com,Proxy\nDOMAIN-SUFFIX,windstream.net,Proxy\nDOMAIN-SUFFIX,cdn.gitpod.io,Proxy\nDOMAIN-SUFFIX,hayagriva.org.au,Proxy\nDOMAIN-SUFFIX,novosti.dn.ua,Proxy\nDOMAIN-SUFFIX,oldertube.com,Proxy\nDOMAIN-SUFFIX,cytode.us,Proxy\nDOMAIN-SUFFIX,superssr.cf,Proxy\nDOMAIN-SUFFIX,dot.tiar.app,Proxy\nDOMAIN-SUFFIX,ca77.com,Proxy\nDOMAIN-SUFFIX,viewonbuddhism.org,Proxy\nDOMAIN-SUFFIX,pornvideos.com,Proxy\nDOMAIN-SUFFIX,chat.hezijin.net,Proxy\nDOMAIN-SUFFIX,ku178.net,Proxy\nDOMAIN-SUFFIX,cctvleak.net,Proxy\nDOMAIN-SUFFIX,mabutou.com,Proxy\nDOMAIN-SUFFIX,pornpros.com,Proxy\nDOMAIN-SUFFIX,sugobbs.com,Proxy\nDOMAIN-SUFFIX,www.joeware.net,Proxy\nDOMAIN-SUFFIX,nhentai.to,Proxy\nDOMAIN-SUFFIX,www.884aa.com,Proxy\nDOMAIN-SUFFIX,freexinwen.com,Proxy\nDOMAIN-SUFFIX,lottomatica.it,Proxy\nDOMAIN-SUFFIX,ccdtr.org,Proxy\nDOMAIN-SUFFIX,thlib.org,Proxy\nDOMAIN-SUFFIX,world.einnews.com,Proxy\nDOMAIN-SUFFIX,www.wd2go.com,Proxy\nDOMAIN-SUFFIX,hiddencuriosities.com,Proxy\nDOMAIN-SUFFIX,ccbs.ntu.edu.tw,Proxy\nDOMAIN-SUFFIX,changp.com,Proxy\nDOMAIN-SUFFIX,winweb.byethost7.com,Proxy\nDOMAIN-SUFFIX,tooot.im,Proxy\nDOMAIN-SUFFIX,www.religion.dk,Proxy\nDOMAIN-SUFFIX,7889cc.com,Proxy\nDOMAIN-SUFFIX,fluimec.com.br,Proxy\nDOMAIN-SUFFIX,thevpn.guru,Proxy\nDOMAIN-SUFFIX,nxgx.com,Proxy\nDOMAIN-SUFFIX,climatedatalibrary.cl,Proxy\nDOMAIN-SUFFIX,meitaav.com,Proxy\nDOMAIN-SUFFIX,it-neuhauser.de,Proxy\nDOMAIN-SUFFIX,dqmobile6.po888.net,Proxy\nDOMAIN-SUFFIX,70911h.com,Proxy\nDOMAIN-SUFFIX,ylvpn.com,Proxy\nDOMAIN-SUFFIX,xmbus5.xyz,Proxy\nDOMAIN-SUFFIX,huc755.com,Proxy\nDOMAIN-SUFFIX,webmail.vivaldi.net,Proxy\nDOMAIN-SUFFIX,yuanming.net,Proxy\nDOMAIN-SUFFIX,www.mimiok.com,Proxy\nDOMAIN-SUFFIX,montreuxhoa.com,Proxy\nDOMAIN-SUFFIX,louana.com,Proxy\nDOMAIN-SUFFIX,828.ddnsking.com,Proxy\nDOMAIN-SUFFIX,wego.here.com,Proxy\nDOMAIN-SUFFIX,www.luogu.org,Proxy\nDOMAIN-SUFFIX,zzu.healthgov.xyz,Proxy\nDOMAIN-SUFFIX,meinpcservice.at,Proxy\nDOMAIN-SUFFIX,www.slsbearings.com.sg,Proxy\nDOMAIN-SUFFIX,feiyudianying.com,Proxy\nDOMAIN-SUFFIX,getcloak.com,Proxy\nDOMAIN-SUFFIX,teenmegaworld.net,Proxy\nDOMAIN-SUFFIX,www.stratfor.com,Proxy\nDOMAIN-SUFFIX,dakashangche.com,Proxy\nDOMAIN-SUFFIX,kaidesa.com,Proxy\nDOMAIN-SUFFIX,ganjingworld.tv,Proxy\nDOMAIN-SUFFIX,123rf.com,Proxy\nDOMAIN-SUFFIX,fw.cm,Proxy\nDOMAIN-SUFFIX,scratch.org,Proxy\nDOMAIN-SUFFIX,www.btso.pw,Proxy\nDOMAIN-SUFFIX,blm69.com,Proxy\nDOMAIN-SUFFIX,doh.xfinity.com,Proxy\nDOMAIN-SUFFIX,topstory.io,Proxy\nDOMAIN-SUFFIX,jbo27.com,Proxy\nDOMAIN-SUFFIX,clubaustinkincaid.com,Proxy\nDOMAIN-SUFFIX,www.driade.com,Proxy\nDOMAIN-SUFFIX,sha2075.com,Proxy\nDOMAIN-SUFFIX,www.lawlove.org,Proxy\nDOMAIN-SUFFIX,www.proxyriver.com,Proxy\nDOMAIN-SUFFIX,namewee4896.com,Proxy\nDOMAIN-SUFFIX,preming.si,Proxy\nDOMAIN-SUFFIX,kex.com,Proxy\nDOMAIN-SUFFIX,www.91100sc.com,Proxy\nDOMAIN-SUFFIX,t.co,Proxy\nDOMAIN-SUFFIX,fxcm.com,Proxy\nDOMAIN-SUFFIX,c4story.com,Proxy\nDOMAIN-SUFFIX,ntr.odyssey346.dev,Proxy\nDOMAIN-SUFFIX,www.sportauto.cn,Proxy\nDOMAIN-SUFFIX,smileawei.com,Proxy\nDOMAIN-SUFFIX,www.shenyuncreations.com,Proxy\nDOMAIN-SUFFIX,www.inews-arabia.com,Proxy\nDOMAIN-SUFFIX,www.aiuu2.com,Proxy\nDOMAIN-SUFFIX,feathersite.com,Proxy\nDOMAIN-SUFFIX,www.shadowsocks.com,Proxy\nDOMAIN-SUFFIX,coinf.com.mx,Proxy\nDOMAIN-SUFFIX,dynssl.com,Proxy\nDOMAIN-SUFFIX,yande.re,Proxy\nDOMAIN-SUFFIX,likextv.com,Proxy\nDOMAIN-SUFFIX,dnyuz.com,Proxy\nDOMAIN-SUFFIX,www.reddit.cn,Proxy\nDOMAIN-SUFFIX,www.fsb.ru,Proxy\nDOMAIN-SUFFIX,www.salafy.net,Proxy\nDOMAIN-SUFFIX,www.nicotv.me,Proxy\nDOMAIN-SUFFIX,chinaheritage.net,Proxy\nDOMAIN-SUFFIX,tw.answers.yahoo.com,Proxy\nDOMAIN-SUFFIX,hentaiera.com,Proxy\nDOMAIN-SUFFIX,radiopublic.com,Proxy\nDOMAIN-SUFFIX,www.xh8718.com,Proxy\nDOMAIN-SUFFIX,unblockit.cc,Proxy\nDOMAIN-SUFFIX,cdn5.telesco.pe,Proxy\nDOMAIN-SUFFIX,www.fh.game,Proxy\nDOMAIN-SUFFIX,www.20498g.com,Proxy\nDOMAIN-SUFFIX,pa3hcm.nl,Proxy\nDOMAIN-SUFFIX,professionalclick.com,Proxy\nDOMAIN-SUFFIX,canagot.fi,Proxy\nDOMAIN-SUFFIX,1lib.ml,Proxy\nDOMAIN-SUFFIX,icbc.com,Proxy\nDOMAIN-SUFFIX,cirubla.github.io,Proxy\nDOMAIN-SUFFIX,www.post852.com,Proxy\nDOMAIN-SUFFIX,bbs.hanminzu.org,Proxy\nDOMAIN-SUFFIX,no.dj0020.com,Proxy\nDOMAIN-SUFFIX,gb.macaotourism.gov.mo,Proxy\nDOMAIN-SUFFIX,www.lonlife.cn,Proxy\nDOMAIN-SUFFIX,www.xw312.com,Proxy\nDOMAIN-SUFFIX,06966c.com,Proxy\nDOMAIN-SUFFIX,zhangtianliang.com,Proxy\nDOMAIN-SUFFIX,lavioleta.cl,Proxy\nDOMAIN-SUFFIX,cdn.line-apps.com,Proxy\nDOMAIN-SUFFIX,miss148.com,Proxy\nDOMAIN-SUFFIX,wikiquote.org,Proxy\nDOMAIN-SUFFIX,kenengba.com,Proxy\nDOMAIN-SUFFIX,www.bible-history.com,Proxy\nDOMAIN-SUFFIX,statebuilding.tw,Proxy\nDOMAIN-SUFFIX,422555.com,Proxy\nDOMAIN-SUFFIX,aneuron.com,Proxy\nDOMAIN-SUFFIX,b8812.com,Proxy\nDOMAIN-SUFFIX,kefi.me,Proxy\nDOMAIN-SUFFIX,www.journal.com.ph,Proxy\nDOMAIN-SUFFIX,www.kyofun.com,Proxy\nDOMAIN-SUFFIX,htl.li,Proxy\nDOMAIN-SUFFIX,id.oup.com,Proxy\nDOMAIN-KEYWORD,freenet,Proxy\nDOMAIN-SUFFIX,freenewscn.com,Proxy\nDOMAIN-SUFFIX,aishatv.tk,Proxy\nDOMAIN-SUFFIX,d2ntqoy263cfg5.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.x78.com,Proxy\nDOMAIN-SUFFIX,babel.ua,Proxy\nDOMAIN-SUFFIX,enewstree.com,Proxy\nDOMAIN-SUFFIX,b6618.com,Proxy\nDOMAIN-SUFFIX,dzcp9666.com,Proxy\nDOMAIN-SUFFIX,d1ywq0sy6ac055.cloudfront.net,Proxy\nDOMAIN-SUFFIX,mastodon.art,Proxy\nDOMAIN-SUFFIX,relay.com.tw,Proxy\nDOMAIN-SUFFIX,d158fyo7wcllqp.cloudfront.net,Proxy\nDOMAIN-SUFFIX,healthusa.xyz,Proxy\nDOMAIN-SUFFIX,3011aa3011.com,Proxy\nDOMAIN-SUFFIX,www.topshelfpussy.com,Proxy\nDOMAIN-SUFFIX,sslsecureproxy.com,Proxy\nDOMAIN-SUFFIX,wotlife.net,Proxy\nDOMAIN-SUFFIX,fxcmapac.com,Proxy\nDOMAIN-SUFFIX,yong.hu,Proxy\nDOMAIN-SUFFIX,tor-exit-52.for-privacy.net,Proxy\nDOMAIN-SUFFIX,www.unblockthat.com,Proxy\nDOMAIN-SUFFIX,info-buddhism.com,Proxy\nDOMAIN-SUFFIX,fw5.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,awk.so,Proxy\nDOMAIN-SUFFIX,tributetoliberty.ca,Proxy\nDOMAIN-SUFFIX,etherscan.com,Proxy\nDOMAIN-SUFFIX,www.rxhj.net,Proxy\nDOMAIN-SUFFIX,d1x0p3lmdequ0z.cloudfront.net,Proxy\nDOMAIN-SUFFIX,zeenews.india.com,Proxy\nDOMAIN-SUFFIX,summerofcode.withgoogle.com,Proxy\nDOMAIN-SUFFIX,videopress.com,Proxy\nDOMAIN-SUFFIX,vm.reuters.tv,Proxy\nDOMAIN-SUFFIX,autocity.us,Proxy\nDOMAIN-SUFFIX,33007.com,Proxy\nDOMAIN-SUFFIX,www.bitcoin86.com,Proxy\nDOMAIN-SUFFIX,registrar.mcmaster.ca,Proxy\nDOMAIN-SUFFIX,g3285.app,Proxy\nDOMAIN-SUFFIX,twylah.com,Proxy\nDOMAIN-SUFFIX,firstbusinessnews.com,Proxy\nDOMAIN-SUFFIX,vanilla-jp.com,Proxy\nDOMAIN-SUFFIX,picacomic.com,Proxy\nDOMAIN-SUFFIX,zenguard.zendesk.com,Proxy\nDOMAIN-SUFFIX,uclaut.net,Proxy\nDOMAIN-SUFFIX,www.s6tu.com,Proxy\nDOMAIN-SUFFIX,555798.com,Proxy\nDOMAIN-SUFFIX,nationwide.com,Proxy\nDOMAIN-SUFFIX,aivpn.com,Proxy\nDOMAIN-SUFFIX,amnesty.fr,Proxy\nDOMAIN-SUFFIX,moess.cc,Proxy\nDOMAIN-SUFFIX,8z3g.06.homeip.net,Proxy\nDOMAIN-SUFFIX,renyurenquan.org,Proxy\nDOMAIN-SUFFIX,followcn.com,Proxy\nDOMAIN-SUFFIX,coswas.org,Proxy\nDOMAIN-SUFFIX,es.cumlouder.com,Proxy\nDOMAIN-SUFFIX,g0v.tw,Proxy\nDOMAIN-SUFFIX,sixth.biz,Proxy\nDOMAIN-SUFFIX,juoaa.com,Proxy\nDOMAIN-SUFFIX,www.civicus.org,Proxy\nDOMAIN-SUFFIX,airav.asia,Proxy\nDOMAIN-SUFFIX,www.lecho.be,Proxy\nDOMAIN-SUFFIX,www.netevader.com,Proxy\nDOMAIN-SUFFIX,blog.kangye.org,Proxy\nDOMAIN-SUFFIX,proxypa.com,Proxy\nDOMAIN-SUFFIX,outlooktibet.com,Proxy\nDOMAIN-SUFFIX,www.businessinsider.com.au,Proxy\nDOMAIN-SUFFIX,82.effers.com,Proxy\nDOMAIN-SUFFIX,krita-artists.org,Proxy\nDOMAIN-SUFFIX,www.twnextdigital.com,Proxy\nDOMAIN-SUFFIX,lili100.com,Proxy\nDOMAIN-SUFFIX,fillthesquare.org,Proxy\nDOMAIN-SUFFIX,xh82222.com,Proxy\nDOMAIN-SUFFIX,gofile.io,Proxy\nDOMAIN-SUFFIX,www.gruenbeck.de,Proxy\nDOMAIN-SUFFIX,allconnected.co,Proxy\nDOMAIN-SUFFIX,www.mulanci.org,Proxy\nDOMAIN-SUFFIX,bb-in.com,Proxy\nDOMAIN-SUFFIX,bbs.qoos.com,Proxy\nDOMAIN-SUFFIX,dyu130k051ujc.cloudfront.net,Proxy\nDOMAIN-SUFFIX,checkmm.com,Proxy\nDOMAIN-SUFFIX,megavideo.com,Proxy\nDOMAIN-SUFFIX,cloudfront.glb.cellopoint.com,Proxy\nDOMAIN-SUFFIX,doublethinklab.org,Proxy\nDOMAIN-SUFFIX,www.512xiaojin.com,Proxy\nDOMAIN-SUFFIX,www.jbo255.com,Proxy\nDOMAIN-SUFFIX,myezlife.com,Proxy\nDOMAIN-SUFFIX,skilljar.com,Proxy\nDOMAIN-SUFFIX,bing.ro,Proxy\nDOMAIN-SUFFIX,www.ftimg.net,Proxy\nDOMAIN-SUFFIX,www.breakingtweets.com,Proxy\nDOMAIN-SUFFIX,cloud.ccu.edu.tw,Proxy\nDOMAIN-SUFFIX,www.liquidvpn.com,Proxy\nDOMAIN-SUFFIX,manyouyinli.blogspot.ca,Proxy\nDOMAIN-SUFFIX,www.tercera.cl,Proxy\nDOMAIN-SUFFIX,skilling.com,Proxy\nDOMAIN-SUFFIX,mail.gosen.jp,Proxy\nDOMAIN-SUFFIX,hongkong.geoexpat.com,Proxy\nDOMAIN-SUFFIX,torrentproject.se,Proxy\nDOMAIN-SUFFIX,f37555.com,Proxy\nDOMAIN-SUFFIX,www.twz.com,Proxy\nDOMAIN-SUFFIX,66.ca,Proxy\nDOMAIN-SUFFIX,cn.sandscotaicentral.com,Proxy\nDOMAIN-SUFFIX,alpharesources.org,Proxy\nDOMAIN-SUFFIX,gb.com,Proxy\nDOMAIN-SUFFIX,www.advisory.com,Proxy\nDOMAIN-SUFFIX,d1mjc71lmzgj1n.cloudfront.net,Proxy\nDOMAIN-SUFFIX,tryheart.jp,Proxy\nDOMAIN-SUFFIX,fun1100.com,Proxy\nDOMAIN-SUFFIX,horecacloud.com,Proxy\nDOMAIN-SUFFIX,ereb.us,Proxy\nDOMAIN-SUFFIX,www.ujizzcn.com,Proxy\nDOMAIN-SUFFIX,co.spacetechnology.net,Proxy\nDOMAIN-SUFFIX,myftp.org,Proxy\nDOMAIN-SUFFIX,citizentruth.org,Proxy\nDOMAIN-SUFFIX,www.xin-hua-net.com,Proxy\nDOMAIN-SUFFIX,www.bw558558.com,Proxy\nDOMAIN-SUFFIX,www.openedition.org,Proxy\nDOMAIN-SUFFIX,6263a.cc,Proxy\nDOMAIN-SUFFIX,theguardian.com,Proxy\nDOMAIN-SUFFIX,thehiddenbay.com,Proxy\nDOMAIN-SUFFIX,gavpn.com,Proxy\nDOMAIN-SUFFIX,bookshome.org,Proxy\nDOMAIN-SUFFIX,en.mwikipedia.org,Proxy\nDOMAIN-SUFFIX,etools.ncol.com,Proxy\nDOMAIN-SUFFIX,repos.accorhotels.com,Proxy\nDOMAIN-SUFFIX,witopia.com,Proxy\nDOMAIN-SUFFIX,designagehk.org,Proxy\nDOMAIN-SUFFIX,dabr.eu,Proxy\nDOMAIN-SUFFIX,ssnode.me,Proxy\nDOMAIN-SUFFIX,test.nadeo.com,Proxy\nDOMAIN-SUFFIX,www.k88133.com,Proxy\nDOMAIN-SUFFIX,iqqav.org,Proxy\nDOMAIN-SUFFIX,lsd.org.hk,Proxy\nDOMAIN-SUFFIX,imquyi.com,Proxy\nDOMAIN-SUFFIX,www.freelxb.com,Proxy\nDOMAIN-SUFFIX,lolisz.com,Proxy\nDOMAIN-SUFFIX,dev-creations.de,Proxy\nDOMAIN-SUFFIX,wiby.me,Proxy\nDOMAIN-SUFFIX,besssoftware.net,Proxy\nDOMAIN-SUFFIX,jizzhut.com,Proxy\nDOMAIN-SUFFIX,daodu14.jigsy.com,Proxy\nDOMAIN-SUFFIX,www.fiuxy.net,Proxy\nDOMAIN-SUFFIX,bigone.com,Proxy\nDOMAIN-SUFFIX,jackav.tv,Proxy\nDOMAIN-SUFFIX,sv5111.idv.tw,Proxy\nDOMAIN-SUFFIX,cleansite.us,Proxy\nDOMAIN-SUFFIX,www.rai-playroom.net,Proxy\nDOMAIN-SUFFIX,seenis.com,Proxy\nDOMAIN-SUFFIX,tsunamivpn.com,Proxy\nDOMAIN-SUFFIX,738682.com,Proxy\nDOMAIN-SUFFIX,www.isdp.eu,Proxy\nDOMAIN-SUFFIX,ssd5.cf,Proxy\nDOMAIN-SUFFIX,doridro.com,Proxy\nDOMAIN-SUFFIX,happy-science.jp,Proxy\nDOMAIN-SUFFIX,hongkong.coconuts.co,Proxy\nDOMAIN-SUFFIX,wav.tv,Proxy\nDOMAIN-SUFFIX,dmhy.org,Proxy\nDOMAIN-SUFFIX,hkstockinvestment.blogspot.hk,Proxy\nDOMAIN-SUFFIX,www.fanqiangzhe.com,Proxy\nDOMAIN-SUFFIX,nyp.st,Proxy\nDOMAIN-SUFFIX,ezcoinpro.com,Proxy\nDOMAIN-SUFFIX,82.solfa.org,Proxy\nDOMAIN-SUFFIX,www.t3641.com,Proxy\nDOMAIN-SUFFIX,capitalfm.co.ke,Proxy\nDOMAIN-SUFFIX,tutifruta.pt,Proxy\nDOMAIN-SUFFIX,gmera.howbbs.com,Proxy\nDOMAIN-SUFFIX,www.f88vip1.com,Proxy\nDOMAIN-SUFFIX,ddhw.com,Proxy\nDOMAIN-SUFFIX,financetwitter.com,Proxy\nDOMAIN-SUFFIX,www.teco-hk.org,Proxy\nDOMAIN-SUFFIX,9527.one,Proxy\nDOMAIN-SUFFIX,www.freemansec.com,Proxy\nDOMAIN-SUFFIX,www.ccofah.org,Proxy\nDOMAIN-SUFFIX,google.tse.moe,Proxy\nDOMAIN-SUFFIX,assets2.xboxlive.com,Proxy\nDOMAIN-SUFFIX,cevpn.com,Proxy\nDOMAIN-SUFFIX,veepn.com,Proxy\nDOMAIN-SUFFIX,18av.tv,Proxy\nDOMAIN-SUFFIX,unblocker.me,Proxy\nDOMAIN-SUFFIX,www.fdroid.org,Proxy\nDOMAIN-SUFFIX,video-edge-23d398.pdx01.abs.hls.ttvnw.net,Proxy\nDOMAIN-SUFFIX,sineed.com,Proxy\nDOMAIN-SUFFIX,tubeplus.me,Proxy\nDOMAIN-SUFFIX,nationalbazaar.com,Proxy\nDOMAIN-SUFFIX,globe-ao-glb-lb-edgecast-v3.ksrd.xyz,Proxy\nDOMAIN-SUFFIX,1056559.com,Proxy\nDOMAIN-SUFFIX,www.chinasfailedtibetpolicies.org,Proxy\nDOMAIN-SUFFIX,nimb.ws,Proxy\nDOMAIN-SUFFIX,cochina.org,Proxy\nDOMAIN-SUFFIX,weiweicam.com,Proxy\nDOMAIN-SUFFIX,www.xiongmao3.com,Proxy\nDOMAIN-SUFFIX,health2.fun,Proxy\nDOMAIN-SUFFIX,dojin.com,Proxy\nDOMAIN-SUFFIX,sikaozhe1997.github.io,Proxy\nDOMAIN-SUFFIX,558.slyip.net,Proxy\nDOMAIN-SUFFIX,wdf5.com,Proxy\nDOMAIN-SUFFIX,ijays.com,Proxy\nDOMAIN-SUFFIX,www.uu-gg.com,Proxy\nDOMAIN-SUFFIX,rlwlw.com,Proxy\nDOMAIN-SUFFIX,beyders.com,Proxy\nDOMAIN-SUFFIX,404.mn,Proxy\nDOMAIN-SUFFIX,ontrac.com,Proxy\nDOMAIN-SUFFIX,22.tobuy.us,Proxy\nDOMAIN-SUFFIX,ghosthauntings.org,Proxy\nDOMAIN-SUFFIX,jp1lib.org,Proxy\nDOMAIN-SUFFIX,www.subpig.net,Proxy\nDOMAIN-SUFFIX,pam6.lflink.com,Proxy\nDOMAIN-SUFFIX,deepsukebe.io,Proxy\nDOMAIN-SUFFIX,www.fun66996.com,Proxy\nDOMAIN-SUFFIX,c1365.com,Proxy\nDOMAIN-SUFFIX,ea-cp.eu,Proxy\nDOMAIN-SUFFIX,zboisw.site,Proxy\nDOMAIN-SUFFIX,app.e8777.com,Proxy\nDOMAIN-SUFFIX,sermitsiaq.ag,Proxy\nDOMAIN-SUFFIX,gay.xxx,Proxy\nDOMAIN-SUFFIX,d2fhyjmqg8thfc.cloudfront.net,Proxy\nDOMAIN-SUFFIX,pro.eimi.vip,Proxy\nDOMAIN-SUFFIX,gvt0.com,Proxy\nDOMAIN-SUFFIX,lexpress.fr,Proxy\nDOMAIN-SUFFIX,hopkins-consulting.com,Proxy\nDOMAIN-SUFFIX,aobo.com.au,Proxy\nDOMAIN-SUFFIX,acetop.com,Proxy\nDOMAIN-SUFFIX,ddkbbsr.gov.in,Proxy\nDOMAIN-SUFFIX,socialmediaweek.org,Proxy\nDOMAIN-SUFFIX,cloaker.us,Proxy\nDOMAIN-SUFFIX,topsailinc.com,Proxy\nDOMAIN-SUFFIX,www.tapiooca.com,Proxy\nDOMAIN-SUFFIX,waselpro.com,Proxy\nDOMAIN-SUFFIX,775476.com,Proxy\nDOMAIN-SUFFIX,dnssec.net,Proxy\nDOMAIN-SUFFIX,blogarama.com,Proxy\nDOMAIN-SUFFIX,www.dcb77.com,Proxy\nDOMAIN-SUFFIX,gordonchang.com,Proxy\nDOMAIN-SUFFIX,ty51888.com,Proxy\nDOMAIN-SUFFIX,yewtu.be,Proxy\nDOMAIN-SUFFIX,acproxy.com,Proxy\nDOMAIN-SUFFIX,ground.news,Proxy\nDOMAIN-SUFFIX,tor-exit-42.for-privacy.net,Proxy\nDOMAIN-SUFFIX,fanwall.sheng.guru,Proxy\nDOMAIN-SUFFIX,ggtt8865.xyz,Proxy\nDOMAIN-SUFFIX,citystudent.ca,Proxy\nDOMAIN-SUFFIX,goagentplus.com,Proxy\nDOMAIN-SUFFIX,www.f88-line.com,Proxy\nDOMAIN-SUFFIX,denaturized-sunligh.000webhostapp.com,Proxy\nDOMAIN-SUFFIX,api-verify.recaptcha.net,Proxy\nDOMAIN-SUFFIX,uku.im,Proxy\nDOMAIN-SUFFIX,lalulalu.com,Proxy\nDOMAIN-SUFFIX,unblocksite.net,Proxy\nDOMAIN-SUFFIX,server8.kproxy.com,Proxy\nDOMAIN-SUFFIX,nvyoub.xyz,Proxy\nDOMAIN-SUFFIX,ctxt.io,Proxy\nDOMAIN-SUFFIX,twicsy.com,Proxy\nDOMAIN-SUFFIX,www.262xx.com,Proxy\nDOMAIN-SUFFIX,www.dandefoe.com,Proxy\nDOMAIN-SUFFIX,syinji1.xyz,Proxy\nDOMAIN-SUFFIX,static.fxcm.co.uk,Proxy\nDOMAIN-SUFFIX,lernsax.de,Proxy\nDOMAIN-SUFFIX,m6vip2.com,Proxy\nDOMAIN-SUFFIX,www.cyworld.com,Proxy\nDOMAIN-SUFFIX,www.e8351.com,Proxy\nDOMAIN-SUFFIX,lj.com,Proxy\nDOMAIN-SUFFIX,ndtv.com,Proxy\nDOMAIN-SUFFIX,islamhk.com,Proxy\nDOMAIN-SUFFIX,buyu864.com,Proxy\nDOMAIN-SUFFIX,www.348080.idv.tw,Proxy\nDOMAIN-SUFFIX,cn.cari.com.my,Proxy\nDOMAIN-SUFFIX,www.swapvpn.com,Proxy\nDOMAIN-SUFFIX,crossfire.co.kr,Proxy\nDOMAIN-SUFFIX,swarajyamag.com,Proxy\nDOMAIN-SUFFIX,jjgirls.com,Proxy\nDOMAIN-SUFFIX,www.encyclopedia.com,Proxy\nDOMAIN-SUFFIX,wionews.org,Proxy\nDOMAIN-SUFFIX,dnscrypt.org,Proxy\nDOMAIN-SUFFIX,ellawine.org,Proxy\nDOMAIN-SUFFIX,nwanime.tv,Proxy\nDOMAIN-SUFFIX,www.safervpn.com,Proxy\nDOMAIN-SUFFIX,ivonblog.com,Proxy\nDOMAIN-SUFFIX,falsefire.com,Proxy\nDOMAIN-SUFFIX,moralesbrothers.com,Proxy\nDOMAIN-SUFFIX,www.365-588.com,Proxy\nDOMAIN-SUFFIX,www.longhuibei.com,Proxy\nDOMAIN-SUFFIX,cutedeadguys.net,Proxy\nDOMAIN-SUFFIX,yurafuca.com,Proxy\nDOMAIN-SUFFIX,www.ztlt.org,Proxy\nDOMAIN-SUFFIX,jmcomic5.cc,Proxy\nDOMAIN-SUFFIX,sto.cc,Proxy\nDOMAIN-SUFFIX,www.finansakrobat.com,Proxy\nDOMAIN-SUFFIX,www.txsvpn.org,Proxy\nDOMAIN-SUFFIX,233yes.com,Proxy\nDOMAIN-SUFFIX,xinli.mx,Proxy\nDOMAIN-SUFFIX,killstar.com,Proxy\nDOMAIN-SUFFIX,union1.aubdas.com,Proxy\nDOMAIN-SUFFIX,epotala.com,Proxy\nDOMAIN-SUFFIX,ym29.com,Proxy\nDOMAIN-SUFFIX,veoh.com,Proxy\nDOMAIN-SUFFIX,exx.com,Proxy\nDOMAIN-SUFFIX,668770000.com,Proxy\nDOMAIN-SUFFIX,www.debatepolitics.com,Proxy\nDOMAIN-SUFFIX,am6599.com,Proxy\nDOMAIN-SUFFIX,broker.to,Proxy\nDOMAIN-SUFFIX,ulusalkanal.com.tr,Proxy\nDOMAIN-SUFFIX,dnsdojo.com,Proxy\nDOMAIN-SUFFIX,twitter.co.uk,Proxy\nDOMAIN-SUFFIX,www.allaboutmicrosoft.com,Proxy\nDOMAIN-SUFFIX,let601.com,Proxy\nDOMAIN-SUFFIX,en.paradisehill.cc,Proxy\nDOMAIN-SUFFIX,parkfamily.ca,Proxy\nDOMAIN-SUFFIX,556js.com,Proxy\nDOMAIN-SUFFIX,ienergy1.com,Proxy\nDOMAIN-SUFFIX,go.milliways.fr,Proxy\nDOMAIN-SUFFIX,api.wit.ai,Proxy\nDOMAIN-SUFFIX,39170088.com,Proxy\nDOMAIN-SUFFIX,ns01.us,Proxy\nDOMAIN-SUFFIX,am822.com,Proxy\nDOMAIN-SUFFIX,hsez.rip,Proxy\nDOMAIN-SUFFIX,xyvpn.com,Proxy\nDOMAIN-SUFFIX,provideocoalition.com,Proxy\nDOMAIN-SUFFIX,www.dandanzan.cc,Proxy\nDOMAIN-SUFFIX,tqvpn.com,Proxy\nDOMAIN-SUFFIX,btdig.com,Proxy\nDOMAIN-SUFFIX,humansofnewyork.com,Proxy\nDOMAIN-SUFFIX,new6.yggonline.com,Proxy\nDOMAIN-SUFFIX,brutaltgp.com,Proxy\nDOMAIN-SUFFIX,xxxxx520.com,Proxy\nDOMAIN-SUFFIX,anghami.com,Proxy\nDOMAIN-SUFFIX,www.jinsha574.com,Proxy\nDOMAIN-SUFFIX,helplinfen.com,Proxy\nDOMAIN-SUFFIX,jonathancervantes.me,Proxy\nDOMAIN-SUFFIX,makemymood.com,Proxy\nDOMAIN-SUFFIX,nyt.com,Proxy\nDOMAIN-SUFFIX,nyti.ms,Proxy\nDOMAIN-SUFFIX,defillama.com,Proxy\nDOMAIN-SUFFIX,javdove8.xyz,Proxy\nDOMAIN-SUFFIX,norestnetwork.com,Proxy\nDOMAIN-SUFFIX,apina.biz,Proxy\nDOMAIN-SUFFIX,cabet372.com,Proxy\nDOMAIN-SUFFIX,zypartner.zyxel.com,Proxy\nDOMAIN-SUFFIX,www.b7751.com,Proxy\nDOMAIN-SUFFIX,dtiblog.com,Proxy\nDOMAIN-SUFFIX,07cps.com,Proxy\nDOMAIN-SUFFIX,clyp.it,Proxy\nDOMAIN-SUFFIX,fpn.firefox.com,Proxy\nDOMAIN-SUFFIX,touchvpn.com,Proxy\nDOMAIN-SUFFIX,t.8964.in,Proxy\nDOMAIN-SUFFIX,www.alqp41.com,Proxy\nDOMAIN-SUFFIX,epodunk.com,Proxy\nDOMAIN-SUFFIX,uscellular.com,Proxy\nDOMAIN-SUFFIX,www.arte.fr,Proxy\nDOMAIN-SUFFIX,saves-the-whales.com,Proxy\nDOMAIN-SUFFIX,www.gv520.com,Proxy\nDOMAIN-SUFFIX,www.wineinstitute.org,Proxy\nDOMAIN-SUFFIX,www.youtube.co.kr,Proxy\nDOMAIN-SUFFIX,www.zerkalo.az,Proxy\nDOMAIN-SUFFIX,a2infotech.com,Proxy\nDOMAIN-SUFFIX,rapbull.net,Proxy\nDOMAIN-SUFFIX,744.flnet.org,Proxy\nDOMAIN-SUFFIX,pornprosnetwork.com,Proxy\nDOMAIN-SUFFIX,theatresh.org,Proxy\nDOMAIN-SUFFIX,888poker.com,Proxy\nDOMAIN-SUFFIX,n2k2.ch,Proxy\nDOMAIN-SUFFIX,thenews.cc,Proxy\nDOMAIN-SUFFIX,francesoir.fr,Proxy\nDOMAIN-SUFFIX,229103.com,Proxy\nDOMAIN-SUFFIX,ebaumsworld.com,Proxy\nDOMAIN-SUFFIX,amateursexy.net,Proxy\nDOMAIN-SUFFIX,glamourwebcams.com,Proxy\nDOMAIN-SUFFIX,drgan.net,Proxy\nDOMAIN-SUFFIX,kantie.org,Proxy\nDOMAIN-SUFFIX,allgravure.com,Proxy\nDOMAIN-SUFFIX,ulike.net,Proxy\nDOMAIN-SUFFIX,alqp86.com,Proxy\nDOMAIN-SUFFIX,saintyculture.com,Proxy\nDOMAIN-SUFFIX,www.monicastube.com,Proxy\nDOMAIN-SUFFIX,blog.workflow.is,Proxy\nDOMAIN-SUFFIX,mega.co.nz,Proxy\nDOMAIN-SUFFIX,2048.malash.net,Proxy\nDOMAIN-SUFFIX,vinca.me,Proxy\nDOMAIN-SUFFIX,freehost.cc,Proxy\nDOMAIN-SUFFIX,social-blog.wix.com,Proxy\nDOMAIN-SUFFIX,thenorthface.com,Proxy\nDOMAIN-SUFFIX,xh066.com,Proxy\nDOMAIN-SUFFIX,ulster.ac.uk,Proxy\nDOMAIN-SUFFIX,38889.com,Proxy\nDOMAIN-SUFFIX,hinet.com,Proxy\nDOMAIN-SUFFIX,mature.nl,Proxy\nDOMAIN-SUFFIX,682148.com,Proxy\nDOMAIN-SUFFIX,www.zflmingli.org,Proxy\nDOMAIN-SUFFIX,wauwfactory.nl,Proxy\nDOMAIN-SUFFIX,d3rt8kdbxi1g81.cloudfront.net,Proxy\nDOMAIN-SUFFIX,wxxinews.org,Proxy\nDOMAIN-SUFFIX,www-cpk06.com,Proxy\nDOMAIN-SUFFIX,thula.co.uk,Proxy\nDOMAIN-SUFFIX,visionsrv.club,Proxy\nDOMAIN-SUFFIX,addtoany.com,Proxy\nDOMAIN-SUFFIX,wu.domain888.pw,Proxy\nDOMAIN-SUFFIX,ca763.com,Proxy\nDOMAIN-SUFFIX,vpnyu.com,Proxy\nDOMAIN-SUFFIX,dy91fq.com,Proxy\nDOMAIN-SUFFIX,zenmate.com.ru,Proxy\nDOMAIN-SUFFIX,scache1.vzw.com,Proxy\nDOMAIN-SUFFIX,stensul.com,Proxy\nDOMAIN-SUFFIX,zypcoatings.com,Proxy\nDOMAIN-SUFFIX,murtadho.com.br,Proxy\nDOMAIN-SUFFIX,central64.net,Proxy\nDOMAIN-SUFFIX,archiveofourown.com,Proxy\nDOMAIN-SUFFIX,saigaocy.com,Proxy\nDOMAIN-SUFFIX,www.chatpdf.com,Proxy\nDOMAIN-SUFFIX,cdn-lg.line-apps.com,Proxy\nDOMAIN-SUFFIX,bd935.com,Proxy\nDOMAIN-SUFFIX,long3158.com,Proxy\nDOMAIN-SUFFIX,www.e8706.com,Proxy\nDOMAIN-SUFFIX,allinfa.com,Proxy\nDOMAIN-SUFFIX,cm.uk.to,Proxy\nDOMAIN-SUFFIX,xmsina.com,Proxy\nDOMAIN-SUFFIX,www.unblockvideos.com,Proxy\nDOMAIN-SUFFIX,ubnon.com,Proxy\nDOMAIN-SUFFIX,knuddels.de,Proxy\nDOMAIN-SUFFIX,www.letong128.com,Proxy\nDOMAIN-SUFFIX,image.duanzh.com,Proxy\nDOMAIN-SUFFIX,www.etmall.com.tw,Proxy\nDOMAIN-SUFFIX,wiki.zhtube.com,Proxy\nDOMAIN-SUFFIX,vpnninja.net,Proxy\nDOMAIN-SUFFIX,chinese.learnfalungong.com,Proxy\nDOMAIN-SUFFIX,fun78.com,Proxy\nDOMAIN-SUFFIX,t9bet.com,Proxy\nDOMAIN-SUFFIX,www.manycai.com,Proxy\nDOMAIN-SUFFIX,chinacitynews.be,Proxy\nDOMAIN-SUFFIX,www.chaomedia.net,Proxy\nDOMAIN-SUFFIX,kinghost.com,Proxy\nDOMAIN-SUFFIX,onthisday.com,Proxy\nDOMAIN-SUFFIX,d1so5st96np159.cloudfront.net,Proxy\nDOMAIN-SUFFIX,sk99.com,Proxy\nDOMAIN-SUFFIX,sciowl.org,Proxy\nDOMAIN-SUFFIX,archive.st,Proxy\nDOMAIN-SUFFIX,viettan.org,Proxy\nDOMAIN-SUFFIX,librex.beparanoid.de,Proxy\nDOMAIN-SUFFIX,www.lib.virginia.edu,Proxy\nDOMAIN-SUFFIX,456777.com,Proxy\nDOMAIN-SUFFIX,falun-ne.org,Proxy\nDOMAIN-SUFFIX,1388110.com,Proxy\nDOMAIN-SUFFIX,www.hotgamesforgirls.com,Proxy\nDOMAIN-SUFFIX,pewreligion.org,Proxy\nDOMAIN-SUFFIX,www.f9010.com,Proxy\nDOMAIN-SUFFIX,www.vpnanalysis.com,Proxy\nDOMAIN-SUFFIX,www.1266xx.com,Proxy\nDOMAIN-SUFFIX,tibet.com,Proxy\nDOMAIN-SUFFIX,www.xunleiso.com,Proxy\nDOMAIN-SUFFIX,metro.taipei,Proxy\nDOMAIN-SUFFIX,gy978.xyz,Proxy\nDOMAIN-SUFFIX,badjojo.com,Proxy\nDOMAIN-SUFFIX,blog.calibre-ebook.com,Proxy\nDOMAIN-SUFFIX,hahlo.com,Proxy\nDOMAIN-SUFFIX,www.huanzhongnet.com,Proxy\nDOMAIN-SUFFIX,www.fxcm.de,Proxy\nDOMAIN-SUFFIX,www.myetherwallet.com,Proxy\nDOMAIN-SUFFIX,missav888.com,Proxy\nDOMAIN-SUFFIX,imagegals.com,Proxy\nDOMAIN-SUFFIX,sa.jwportal.org,Proxy\nDOMAIN-SUFFIX,obs.line-apps.com,Proxy\nDOMAIN-SUFFIX,d14qqseh1jha6e.cloudfront.net,Proxy\nDOMAIN-SUFFIX,washingtonexaminer.com,Proxy\nDOMAIN-SUFFIX,freshxxxtube.com,Proxy\nDOMAIN-SUFFIX,hk.frienddy.com,Proxy\nDOMAIN-SUFFIX,sumally.com,Proxy\nDOMAIN-SUFFIX,www.hkrdb.net,Proxy\nDOMAIN-SUFFIX,xpeeps.com,Proxy\nDOMAIN-SUFFIX,healthaegis.com,Proxy\nDOMAIN-SUFFIX,web5.cf,Proxy\nDOMAIN-SUFFIX,tucao.me,Proxy\nDOMAIN-SUFFIX,radiant-torch-3037.firebaseio.com,Proxy\nDOMAIN-SUFFIX,db.tt,Proxy\nDOMAIN-SUFFIX,www.cmcn.org,Proxy\nDOMAIN-SUFFIX,wwwdns.work,Proxy\nDOMAIN-SUFFIX,giancarlo.spadini.it,Proxy\nDOMAIN-SUFFIX,jojoex.com,Proxy\nDOMAIN-SUFFIX,80letou.com,Proxy\nDOMAIN-SUFFIX,ag8.com,Proxy\nDOMAIN-SUFFIX,freechinaradio.com,Proxy\nDOMAIN-SUFFIX,www.wkek.net,Proxy\nDOMAIN-SUFFIX,us-pptp.unovpn.com,Proxy\nDOMAIN-SUFFIX,gfwbrowse.com,Proxy\nDOMAIN-SUFFIX,videomo.com,Proxy\nDOMAIN-SUFFIX,www.ellisonballet.com,Proxy\nDOMAIN-SUFFIX,www.cathayglory.org,Proxy\nDOMAIN-SUFFIX,oktw.6te.net,Proxy\nDOMAIN-SUFFIX,book.bfnn.org,Proxy\nDOMAIN-SUFFIX,orgfree.com,Proxy\nDOMAIN-SUFFIX,www.everysoft.com,Proxy\nDOMAIN-SUFFIX,gongfa.com,Proxy\nDOMAIN-SUFFIX,sharks-lagoon.fr,Proxy\nDOMAIN-SUFFIX,www.weheartit.com,Proxy\nDOMAIN-SUFFIX,i4a.shop,Proxy\nDOMAIN-SUFFIX,soul-plus.net,Proxy\nDOMAIN-SUFFIX,crocoporn.com,Proxy\nDOMAIN-SUFFIX,www.kan84.net,Proxy\nDOMAIN-SUFFIX,marguerite.su,Proxy\nDOMAIN-SUFFIX,www.nova.bg,Proxy\nDOMAIN-SUFFIX,cd.olife.org,Proxy\nDOMAIN-SUFFIX,srvpn.com,Proxy\nDOMAIN-SUFFIX,jingpin.org,Proxy\nDOMAIN-SUFFIX,d7fjv2bxgldcl.cloudfront.net,Proxy\nDOMAIN-SUFFIX,6park.com,Proxy\nDOMAIN-SUFFIX,www.eclipsewebmedia.com,Proxy\nDOMAIN-SUFFIX,swag.live,Proxy\nDOMAIN-SUFFIX,call.to,Proxy\nDOMAIN-SUFFIX,fanqiangzhe.com,Proxy\nDOMAIN-SUFFIX,member.uswap.tube,Proxy\nDOMAIN-SUFFIX,stripes.com,Proxy\nDOMAIN-SUFFIX,eslite.com,Proxy\nDOMAIN-SUFFIX,ca288.com,Proxy\nDOMAIN-SUFFIX,falundafa.ca,Proxy\nDOMAIN-SUFFIX,beastiality.tv,Proxy\nDOMAIN-SUFFIX,epochtimes.eu,Proxy\nDOMAIN-SUFFIX,getjetso.com,Proxy\nDOMAIN-SUFFIX,ordns.he.net,Proxy\nDOMAIN-SUFFIX,loli.com.co,Proxy\nDOMAIN-SUFFIX,17kav.net,Proxy\nDOMAIN-SUFFIX,japane.se,Proxy\nDOMAIN-SUFFIX,oyunlari.net,Proxy\nDOMAIN-SUFFIX,dcdbjkjn.fzgyh.com,Proxy\nDOMAIN-SUFFIX,travel.rakuten.co.jp,Proxy\nDOMAIN-SUFFIX,xila88.com,Proxy\nDOMAIN-SUFFIX,www.sgreenvpn.com,Proxy\nDOMAIN-SUFFIX,qqjlb2.com,Proxy\nDOMAIN-SUFFIX,yaguar.com.ar,Proxy\nDOMAIN-SUFFIX,www.tibetwatch.org,Proxy\nDOMAIN-SUFFIX,allegro.pl,Proxy\nDOMAIN-SUFFIX,inlajav.com,Proxy\nDOMAIN-SUFFIX,broadcast.me,Proxy\nDOMAIN-SUFFIX,feastforthepen.com,Proxy\nDOMAIN-SUFFIX,www.saaaaaaaan.com,Proxy\nDOMAIN-SUFFIX,hongkongwatch.org,Proxy\nDOMAIN-SUFFIX,i2.am,Proxy\nDOMAIN-SUFFIX,www.tuo8.red,Proxy\nDOMAIN-SUFFIX,096.ca,Proxy\nDOMAIN-SUFFIX,churchinplano.org,Proxy\nDOMAIN-SUFFIX,unblock.im,Proxy\nDOMAIN-SUFFIX,dnsbl.sorbs.net,Proxy\nDOMAIN-SUFFIX,lt113.com,Proxy\nDOMAIN-SUFFIX,rolfoundation.org,Proxy\nDOMAIN-SUFFIX,www.tsechenling.org,Proxy\nDOMAIN-SUFFIX,h5.ld2090.com,Proxy\nDOMAIN-SUFFIX,profession.hu,Proxy\nDOMAIN-SUFFIX,terapatrick.com,Proxy\nDOMAIN-SUFFIX,24.co.za,Proxy\nDOMAIN-SUFFIX,bb-cc.xyz,Proxy\nDOMAIN-SUFFIX,goreforum.com,Proxy\nDOMAIN-SUFFIX,www.dspguide.com,Proxy\nDOMAIN-SUFFIX,www.pandafe.com,Proxy\nDOMAIN-SUFFIX,envpn.com,Proxy\nDOMAIN-SUFFIX,www.hifuli.com,Proxy\nDOMAIN-SUFFIX,bamboointhewind.org,Proxy\nDOMAIN-SUFFIX,yinheviphy.com,Proxy\nDOMAIN-SUFFIX,pagesinxt.com,Proxy\nDOMAIN-SUFFIX,startuplivingchina.com,Proxy\nDOMAIN-SUFFIX,maps.google.ch,Proxy\nDOMAIN-SUFFIX,m.gb508.com,Proxy\nDOMAIN-SUFFIX,aevpn.com,Proxy\nDOMAIN-SUFFIX,myeclipseide.com,Proxy\nDOMAIN-SUFFIX,ggdada.com,Proxy\nDOMAIN-SUFFIX,tahr.org.tw,Proxy\nDOMAIN-SUFFIX,www.oassf.com,Proxy\nDOMAIN-SUFFIX,crashlytics.com,Proxy\nDOMAIN-SUFFIX,gg773.net,Proxy\nDOMAIN-SUFFIX,wengewang.com,Proxy\nDOMAIN-SUFFIX,inredware.com.ar,Proxy\nDOMAIN-SUFFIX,www.777021.com,Proxy\nDOMAIN-SUFFIX,goa.spacetechnology.net,Proxy\nDOMAIN-SUFFIX,getsocialscope.com,Proxy\nDOMAIN-SUFFIX,timbuk2.com,Proxy\nDOMAIN-SUFFIX,www.bbcrussian.com,Proxy\nDOMAIN-SUFFIX,cc.srsr.ml,Proxy\nDOMAIN-SUFFIX,dooprime.net,Proxy\nDOMAIN-SUFFIX,legalporno.com,Proxy\nDOMAIN-SUFFIX,d2wzzf3ucmnxes.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.unicorntw.com,Proxy\nDOMAIN-SUFFIX,www.portnews.com.au,Proxy\nDOMAIN-SUFFIX,myenrich.com,Proxy\nDOMAIN-SUFFIX,static.plurk.com,Proxy\nDOMAIN-SUFFIX,d3s6xpomh6soe4.cloudfront.net,Proxy\nDOMAIN-SUFFIX,exozwiki.com,Proxy\nDOMAIN-SUFFIX,i.filmot.org,Proxy\nDOMAIN-SUFFIX,701136.com,Proxy\nDOMAIN-SUFFIX,www.thesparklabs.com,Proxy\nDOMAIN-SUFFIX,ibb.gov,Proxy\nDOMAIN-SUFFIX,smcyinternationalfamily.org,Proxy\nDOMAIN-SUFFIX,yc2365.com,Proxy\nDOMAIN-SUFFIX,notepad-plus-plus.org,Proxy\nDOMAIN-SUFFIX,publicknowledge.org,Proxy\nDOMAIN-SUFFIX,dwql015inscdy.cloudfront.net,Proxy\nDOMAIN-SUFFIX,ny.visiontimes.com,Proxy\nDOMAIN-SUFFIX,zlib.cydiar.com,Proxy\nDOMAIN-SUFFIX,hizb-ut-tahrir.info,Proxy\nDOMAIN-SUFFIX,api-ds.kkbox.com.tw,Proxy\nDOMAIN-SUFFIX,twilog.org,Proxy\nDOMAIN-SUFFIX,m.boxenterprise.net,Proxy\nDOMAIN-SUFFIX,www.studyabroadfoundation.org,Proxy\nDOMAIN-SUFFIX,linusmediagroup.com,Proxy\nDOMAIN-SUFFIX,www.7hills.org,Proxy\nDOMAIN-SUFFIX,facebool.com,Proxy\nDOMAIN-SUFFIX,waybig.com,Proxy\nDOMAIN-SUFFIX,www.nzbgrabit.nl,Proxy\nDOMAIN-SUFFIX,www.joseph-studio.com,Proxy\nDOMAIN-SUFFIX,www.365winner.biz,Proxy\nDOMAIN-SUFFIX,www.vanadv.com,Proxy\nDOMAIN-SUFFIX,wefong.com,Proxy\nDOMAIN-SUFFIX,51442.gtoxtv.com,Proxy\nDOMAIN-SUFFIX,tlcprod.app.link,Proxy\nDOMAIN-SUFFIX,africaddy.com,Proxy\nDOMAIN-SUFFIX,gamcore.com,Proxy\nDOMAIN-SUFFIX,3boys2girls.com,Proxy\nDOMAIN-SUFFIX,tuberl.com,Proxy\nDOMAIN-SUFFIX,stuff-4-sale.us,Proxy\nDOMAIN-SUFFIX,www.aeco.tw,Proxy\nDOMAIN-SUFFIX,romirain.com,Proxy\nDOMAIN-SUFFIX,dharmakara.net,Proxy\nDOMAIN-SUFFIX,piaohua.com,Proxy\nDOMAIN-SUFFIX,psiphontoday.com,Proxy\nDOMAIN-SUFFIX,savetibet.de,Proxy\nDOMAIN-SUFFIX,sytes.net,Proxy\nDOMAIN-SUFFIX,xcg123.com,Proxy\nDOMAIN-SUFFIX,ooguy.com,Proxy\nDOMAIN-SUFFIX,jmcomic2.me,Proxy\nDOMAIN-SUFFIX,www.ca551.com,Proxy\nDOMAIN-SUFFIX,freemuse.org,Proxy\nDOMAIN-SUFFIX,weidb.com,Proxy\nDOMAIN-SUFFIX,cannedcodes.com,Proxy\nDOMAIN-SUFFIX,www.oscclub.com,Proxy\nDOMAIN-SUFFIX,y.tv100.us,Proxy\nDOMAIN-SUFFIX,nate.com,Proxy\nDOMAIN-SUFFIX,4221.f88yule1.com,Proxy\nDOMAIN-SUFFIX,x-art.com,Proxy\nDOMAIN-SUFFIX,frprn.com,Proxy\nDOMAIN-SUFFIX,www.o2tv.cz,Proxy\nDOMAIN-SUFFIX,kuma-academy.org,Proxy\nDOMAIN-SUFFIX,falundafa.or.id,Proxy\nDOMAIN-SUFFIX,dmd85.com,Proxy\nDOMAIN-SUFFIX,www.sun988.com,Proxy\nDOMAIN-SUFFIX,nginx.com,Proxy\nDOMAIN-SUFFIX,citizensradio.org,Proxy\nDOMAIN-SUFFIX,bccard.xyz,Proxy\nDOMAIN-SUFFIX,lastfm.es,Proxy\nDOMAIN-SUFFIX,www.lestapackaging.co.uk,Proxy\nDOMAIN-SUFFIX,mingshengbao.com,Proxy\nDOMAIN-SUFFIX,www.metso.com,Proxy\nDOMAIN-SUFFIX,podbean.com,Proxy\nDOMAIN-SUFFIX,standupfortibet.org,Proxy\nDOMAIN-SUFFIX,11youtube.com,Proxy\nDOMAIN-SUFFIX,porn.sexy,Proxy\nDOMAIN-SUFFIX,api.amplitude.com,Proxy\nDOMAIN-SUFFIX,www.gazco.com,Proxy\nDOMAIN-SUFFIX,bbs.outian.idv.tw,Proxy\nDOMAIN-SUFFIX,buddhism.kiev.ua,Proxy\nDOMAIN-SUFFIX,pu0025.com,Proxy\nDOMAIN-SUFFIX,wiki.jqueryui.com,Proxy\nDOMAIN-SUFFIX,esteticaduende.cat,Proxy\nDOMAIN-SUFFIX,blog.tsunanet.net,Proxy\nDOMAIN-SUFFIX,og.yzdgzw.com,Proxy\nDOMAIN-SUFFIX,bobiporn.com,Proxy\nDOMAIN-SUFFIX,buyu350.com,Proxy\nDOMAIN-SUFFIX,levo.com,Proxy\nDOMAIN-SUFFIX,wangyi64.spaces.live.com,Proxy\nDOMAIN-SUFFIX,torrenticity.com,Proxy\nDOMAIN-SUFFIX,325.deaftone.com,Proxy\nDOMAIN-SUFFIX,acglover.me,Proxy\nDOMAIN-SUFFIX,www.coinall.com,Proxy\nDOMAIN-SUFFIX,guanliyuan.org,Proxy\nDOMAIN-SUFFIX,tubepornfilm.com,Proxy\nDOMAIN-SUFFIX,myasiantv.com,Proxy\nDOMAIN-SUFFIX,001717.com,Proxy\nDOMAIN-SUFFIX,zippyproxy.com,Proxy\nDOMAIN-SUFFIX,giveawaylist.com,Proxy\nDOMAIN-SUFFIX,b5513.com,Proxy\nDOMAIN-SUFFIX,twitcause.com,Proxy\nDOMAIN-SUFFIX,relay.firefox.com,Proxy\nDOMAIN-SUFFIX,api.robotbv.com,Proxy\nDOMAIN-SUFFIX,f8.com,Proxy\nDOMAIN-SUFFIX,general-porn.com,Proxy\nDOMAIN-SUFFIX,zhanzongg.yupage.com,Proxy\nDOMAIN-SUFFIX,mongoliavpn.com,Proxy\nDOMAIN-SUFFIX,witopia.net,Proxy\nDOMAIN-SUFFIX,ohayoutube.com,Proxy\nDOMAIN-SUFFIX,fibarra.cl,Proxy\nDOMAIN-SUFFIX,pd5109.ts666.net,Proxy\nDOMAIN-SUFFIX,nytimes.org,Proxy\nDOMAIN-SUFFIX,aizhi.co,Proxy\nDOMAIN-SUFFIX,dqmobile3.po888.net,Proxy\nDOMAIN-SUFFIX,fc.iwant-in.net,Proxy\nDOMAIN-SUFFIX,storify.com,Proxy\nDOMAIN-SUFFIX,1056477.com,Proxy\nDOMAIN-SUFFIX,listennotes.com,Proxy\nDOMAIN-SUFFIX,xhamster.pornred.net,Proxy\nDOMAIN-SUFFIX,www.videodetective.com,Proxy\nDOMAIN-SUFFIX,kuaishangche.buzz,Proxy\nDOMAIN-SUFFIX,edmontonchina.com,Proxy\nDOMAIN-SUFFIX,fridaysforfuture.org,Proxy\nDOMAIN-SUFFIX,pttvan.org,Proxy\nDOMAIN-SUFFIX,supportukraine.us,Proxy\nDOMAIN-SUFFIX,www.thsrc.com.tw,Proxy\nDOMAIN-SUFFIX,eatnews.net,Proxy\nDOMAIN-SUFFIX,pipii.tv,Proxy\nDOMAIN-SUFFIX,89.64.charter.constitutionalism.solutions,Proxy\nDOMAIN-SUFFIX,slutmoonbeam.com,Proxy\nDOMAIN-SUFFIX,virginia.gov,Proxy\nDOMAIN-SUFFIX,bc5188.com,Proxy\nDOMAIN-SUFFIX,riseup.net,Proxy\nDOMAIN-SUFFIX,nickipedia.us,Proxy\nDOMAIN-SUFFIX,followgram.me,Proxy\nDOMAIN-SUFFIX,wam-fw.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,daloushan.com,Proxy\nDOMAIN-SUFFIX,news.mb.com.ph,Proxy\nDOMAIN-SUFFIX,www.eroxia.com,Proxy\nDOMAIN-SUFFIX,iron874111.emc77.com,Proxy\nDOMAIN-SUFFIX,aoxvpn.cc,Proxy\nDOMAIN-SUFFIX,ftpaccess.cc,Proxy\nDOMAIN-SUFFIX,www.sonny.idv.tw,Proxy\nDOMAIN-SUFFIX,blmdc66.com,Proxy\nDOMAIN-SUFFIX,twingyeo.kr,Proxy\nDOMAIN-SUFFIX,goolge.com,Proxy\nDOMAIN-SUFFIX,www.p12p.com,Proxy\nDOMAIN-SUFFIX,bowenpress.com,Proxy\nDOMAIN-SUFFIX,corp-umbrella.com,Proxy\nDOMAIN-SUFFIX,www.inxtv.site,Proxy\nDOMAIN-SUFFIX,gree.ddns.name,Proxy\nDOMAIN-SUFFIX,h5.ledong2023.com,Proxy\nDOMAIN-SUFFIX,www.petaasia.cn,Proxy\nDOMAIN-SUFFIX,engagedaily.org,Proxy\nDOMAIN-SUFFIX,bopsecrets.org,Proxy\nDOMAIN-SUFFIX,xvxv9.com,Proxy\nDOMAIN-SUFFIX,myownconference.com,Proxy\nDOMAIN-SUFFIX,swinginvent.com.au,Proxy\nDOMAIN-SUFFIX,hidemyass.com,Proxy\nDOMAIN-SUFFIX,linksysinfo.org,Proxy\nDOMAIN-SUFFIX,workerdemo.org.hk,Proxy\nDOMAIN-SUFFIX,blogs.icerocket.com,Proxy\nDOMAIN-SUFFIX,www.convert.com,Proxy\nDOMAIN-SUFFIX,googlearth.com,Proxy\nDOMAIN-SUFFIX,oursweb.net,Proxy\nDOMAIN-SUFFIX,facebook.com.br,Proxy\nDOMAIN-SUFFIX,tobing.web.id,Proxy\nDOMAIN-SUFFIX,www.twistys.com,Proxy\nDOMAIN-SUFFIX,starcelebs.com,Proxy\nDOMAIN-SUFFIX,iipdigital.usembassy.gov,Proxy\nDOMAIN-SUFFIX,proxylist.org.uk,Proxy\nDOMAIN-SUFFIX,russiavsukraine.com,Proxy\nDOMAIN-SUFFIX,cam4.jp,Proxy\nDOMAIN-SUFFIX,26.etowns.net,Proxy\nDOMAIN-SUFFIX,lso.saponeworld.com,Proxy\nDOMAIN-SUFFIX,flyflv.com,Proxy\nDOMAIN-SUFFIX,www.tennyy.com,Proxy\nDOMAIN-SUFFIX,rconversation.blogs.com,Proxy\nDOMAIN-SUFFIX,blog.j172.tw,Proxy\nDOMAIN-SUFFIX,officemax.com,Proxy\nDOMAIN-SUFFIX,fuckbook.com,Proxy\nDOMAIN-SUFFIX,ca953.com,Proxy\nDOMAIN-SUFFIX,hk-wesi2.xyz,Proxy\nDOMAIN-SUFFIX,v2.52rosi.com,Proxy\nDOMAIN-SUFFIX,hoststool.net,Proxy\nDOMAIN-SUFFIX,www.settv.com.tw,Proxy\nDOMAIN-SUFFIX,webupd8.org,Proxy\nDOMAIN-SUFFIX,xxmap2.vip,Proxy\nIP-CIDR,14.102.250.19/32,Proxy\nDOMAIN-SUFFIX,singaporeair.com,Proxy\nDOMAIN-SUFFIX,rss.superssr.me,Proxy\nDOMAIN-SUFFIX,googlesource.com,Proxy\nDOMAIN-SUFFIX,228.net.tw,Proxy\nDOMAIN-SUFFIX,panluan.net,Proxy\nDOMAIN-SUFFIX,www.gjsq.biz,Proxy\nDOMAIN-SUFFIX,xh88.org,Proxy\nDOMAIN-SUFFIX,obmem.com,Proxy\nDOMAIN-SUFFIX,jobs.canexchange.org,Proxy\nDOMAIN-SUFFIX,kokoro.heartbeat.red,Proxy\nDOMAIN-SUFFIX,vwin.com,Proxy\nIP-CIDR,14.102.250.18/32,Proxy\nDOMAIN-SUFFIX,www.aiosearch.com,Proxy\nDOMAIN-SUFFIX,d35q7oiklifjy3.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.iblf.org,Proxy\nDOMAIN-SUFFIX,www.yzc212.com,Proxy\nDOMAIN-SUFFIX,swissvpn.net,Proxy\nDOMAIN-SUFFIX,ent.fanpiece.com,Proxy\nDOMAIN-SUFFIX,dvdpac.com,Proxy\nDOMAIN-SUFFIX,akuma.moe,Proxy\nDOMAIN-SUFFIX,pu0037.com,Proxy\nDOMAIN-SUFFIX,boobstagram.com,Proxy\nDOMAIN-SUFFIX,cn.ec21.com,Proxy\nDOMAIN-SUFFIX,camtools.cam.ac.uk,Proxy\nDOMAIN-SUFFIX,xiaochengriji.com,Proxy\nDOMAIN-SUFFIX,blog.vic.mh4u.org,Proxy\nDOMAIN-SUFFIX,ss.zhen-chen.xyz,Proxy\nDOMAIN-SUFFIX,qpby0066.com,Proxy\nDOMAIN-SUFFIX,j.mr,Proxy\nDOMAIN-SUFFIX,redd.it,Proxy\nDOMAIN-SUFFIX,www.jahproxy.com,Proxy\nDOMAIN-SUFFIX,qxcp88888.com,Proxy\nDOMAIN-SUFFIX,hz8801.com,Proxy\nDOMAIN-SUFFIX,www.shinmai.co.jp,Proxy\nDOMAIN-SUFFIX,777777.com,Proxy\nDOMAIN-SUFFIX,bbs.skykiwi.com,Proxy\nDOMAIN-SUFFIX,www.heji233.com,Proxy\nDOMAIN-SUFFIX,google.com.eg,Proxy\nDOMAIN-SUFFIX,blm4455.com,Proxy\nDOMAIN-SUFFIX,hihbt.com,Proxy\nDOMAIN-SUFFIX,search.mywebsearch.com,Proxy\nDOMAIN-SUFFIX,www.153z.com,Proxy\nDOMAIN-SUFFIX,rimagine.com,Proxy\nDOMAIN-SUFFIX,eastern-ark.com,Proxy\nDOMAIN-SUFFIX,submit.jotform.co,Proxy\nDOMAIN-SUFFIX,dytt.net,Proxy\nDOMAIN-SUFFIX,npm.nextep-app.com,Proxy\nDOMAIN-SUFFIX,www.davidrevoy.com,Proxy\nDOMAIN-SUFFIX,prprcloud.com,Proxy\nDOMAIN-SUFFIX,letou2024.com,Proxy\nDOMAIN-SUFFIX,www122.eyny.com,Proxy\nDOMAIN-SUFFIX,gmgard.us,Proxy\nDOMAIN-SUFFIX,d1pvxajn4vc7ng.cloudfront.net,Proxy\nDOMAIN-SUFFIX,zzt.whodns.xyz,Proxy\nDOMAIN-SUFFIX,wavearttrend.com,Proxy\nDOMAIN-SUFFIX,thumbzila.com,Proxy\nDOMAIN-SUFFIX,536216.com,Proxy\nDOMAIN-SUFFIX,internet.org,Proxy\nDOMAIN-SUFFIX,301.com,Proxy\nDOMAIN-SUFFIX,paperspace.com,Proxy\nDOMAIN-SUFFIX,philly.com,Proxy\nDOMAIN-SUFFIX,stirni.li,Proxy\nDOMAIN-SUFFIX,ai.googleblog.com,Proxy\nDOMAIN-SUFFIX,clicksia.com,Proxy\nDOMAIN-SUFFIX,fbaddins.com,Proxy\nDOMAIN-SUFFIX,lausan.hk,Proxy\nDOMAIN-SUFFIX,i59v.r5.cr.rs,Proxy\nDOMAIN-SUFFIX,2000fun.com,Proxy\nDOMAIN-SUFFIX,ghh666.com,Proxy\nDOMAIN-SUFFIX,tibetoffice.ch,Proxy\nDOMAIN-SUFFIX,www.lavaone.com,Proxy\nDOMAIN-SUFFIX,www.facebook-studio.com,Proxy\nDOMAIN-SUFFIX,environment.google,Proxy\nDOMAIN-SUFFIX,21andy.com,Proxy\nDOMAIN-SUFFIX,tibet-kailash-haus.de,Proxy\nDOMAIN-SUFFIX,www.times.com,Proxy\nDOMAIN-SUFFIX,ovpn.com,Proxy\nDOMAIN-SUFFIX,dongtaiwang.net,Proxy\nDOMAIN-SUFFIX,www.enimerosi.com,Proxy\nDOMAIN-SUFFIX,9ff450a4-6dc6-4b0c-9e7a-87c74a5b5e70.realclearprivacy.biz,Proxy\nDOMAIN-SUFFIX,hjedd.com,Proxy\nDOMAIN-SUFFIX,facefucking.com,Proxy\nDOMAIN-SUFFIX,www.transcontinental.com.au,Proxy\nDOMAIN-SUFFIX,www.yesjav.com,Proxy\nDOMAIN-SUFFIX,www.boobpedia.com,Proxy\nDOMAIN-SUFFIX,beevpn.com,Proxy\nDOMAIN-SUFFIX,baidyanath.net.in,Proxy\nDOMAIN-SUFFIX,train.web.id,Proxy\nDOMAIN-SUFFIX,footensalle.be,Proxy\nDOMAIN-SUFFIX,program-think.blogspot.ro,Proxy\nDOMAIN-SUFFIX,trinitidinamik.com,Proxy\nDOMAIN-SUFFIX,girlsgotcream.com,Proxy\nDOMAIN-SUFFIX,www.missdeer.com,Proxy\nDOMAIN-SUFFIX,www.businessinsider.nl,Proxy\nDOMAIN-SUFFIX,btse.com,Proxy\nDOMAIN-SUFFIX,twisterio.com,Proxy\nDOMAIN-SUFFIX,99cn.info,Proxy\nDOMAIN-SUFFIX,e-hentai.org,Proxy\nDOMAIN-SUFFIX,wgc2017.cnns.tw,Proxy\nDOMAIN-SUFFIX,spiegel.de,Proxy\nDOMAIN-SUFFIX,xn--i2ru8q2qg.com,Proxy\nDOMAIN-SUFFIX,pythonhackers.com,Proxy\nDOMAIN-SUFFIX,av567.net,Proxy\nDOMAIN-SUFFIX,rationalwiki.org,Proxy\nDOMAIN-SUFFIX,porn-porn-porn.com,Proxy\nDOMAIN-SUFFIX,gbga.gi,Proxy\nDOMAIN-SUFFIX,connectssr.com,Proxy\nDOMAIN-SUFFIX,newgame.ag888.com,Proxy\nDOMAIN-SUFFIX,tushiou.blogspot.jp,Proxy\nDOMAIN-SUFFIX,513613.xyz,Proxy\nDOMAIN-SUFFIX,zaozon.com,Proxy\nDOMAIN-SUFFIX,goo.ne.jp,Proxy\nDOMAIN-SUFFIX,app.evozi.com,Proxy\nDOMAIN-SUFFIX,blockedsiteaccess.com,Proxy\nDOMAIN-SUFFIX,browser.sentry-cdn.com,Proxy\nDOMAIN-SUFFIX,letsconvene.im,Proxy\nDOMAIN-SUFFIX,www.bestfreevpn.net,Proxy\nDOMAIN-SUFFIX,nigger.mov,Proxy\nDOMAIN-SUFFIX,543215.com,Proxy\nDOMAIN-SUFFIX,helpeachpeople.com,Proxy\nDOMAIN-SUFFIX,falundafabooks.com,Proxy\nDOMAIN-SUFFIX,pincong.rocks,Proxy\nDOMAIN-SUFFIX,www.luckcases.net,Proxy\nDOMAIN-SUFFIX,www.lotte.co.jp,Proxy\nDOMAIN-SUFFIX,newsroom.co.nz,Proxy\nDOMAIN-SUFFIX,tb9996.com,Proxy\nDOMAIN-SUFFIX,www.nc.hcc.edu.tw,Proxy\nDOMAIN-SUFFIX,www.madata.gr,Proxy\nDOMAIN-SUFFIX,lsmchinese.org,Proxy\nDOMAIN-SUFFIX,dwj10.com,Proxy\nDOMAIN-SUFFIX,u.georgianlimerick.com,Proxy\nDOMAIN-SUFFIX,lihkg.com,Proxy\nDOMAIN-SUFFIX,kh1.spacetechnology.net,Proxy\nDOMAIN-SUFFIX,bookgb.bfnn2.org,Proxy\nDOMAIN-SUFFIX,www.rocmgov.org,Proxy\nDOMAIN-SUFFIX,www.heraeus.com,Proxy\nDOMAIN-SUFFIX,www.av191.com,Proxy\nDOMAIN-SUFFIX,www.cyborgreality.com,Proxy\nDOMAIN-SUFFIX,fun88asia.agent1818.com,Proxy\nDOMAIN-SUFFIX,biqiku.com,Proxy\nDOMAIN-SUFFIX,www.wiesbadener-kurier.de,Proxy\nDOMAIN-SUFFIX,xypc28.com,Proxy\nDOMAIN-SUFFIX,d2wlijk77wx86m.cloudfront.net,Proxy\nDOMAIN-SUFFIX,epac.to,Proxy\nDOMAIN-SUFFIX,433409.com,Proxy\nDOMAIN-SUFFIX,bifa998.com,Proxy\nDOMAIN-SUFFIX,rop.org.au,Proxy\nDOMAIN-SUFFIX,cchcu.strikingly.com,Proxy\nDOMAIN-SUFFIX,7765bb.com,Proxy\nDOMAIN-SUFFIX,31599.com,Proxy\nDOMAIN-SUFFIX,ddd304w8960jc.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.myxmagnet.com,Proxy\nDOMAIN-SUFFIX,2ninesm.net,Proxy\nDOMAIN-SUFFIX,www.xbookcn.net,Proxy\nDOMAIN-SUFFIX,eireinikotaerukai.com,Proxy\nDOMAIN-SUFFIX,iuksky.com,Proxy\nDOMAIN-SUFFIX,nqma.net,Proxy\nDOMAIN-SUFFIX,www.torrentsland.com,Proxy\nDOMAIN-SUFFIX,www.learnerlane.com,Proxy\nDOMAIN-SUFFIX,flower.is,Proxy\nDOMAIN-SUFFIX,limelight.moe,Proxy\nDOMAIN-SUFFIX,qpby2255.com,Proxy\nDOMAIN-SUFFIX,www.cams.org.sg,Proxy\nDOMAIN-SUFFIX,pewinternet.org,Proxy\nDOMAIN-SUFFIX,yahoo.cn,Proxy\nDOMAIN-SUFFIX,wrp.org.uk,Proxy\nDOMAIN-SUFFIX,www.oneindia.com,Proxy\nDOMAIN-SUFFIX,blogspot.sk,Proxy\nDOMAIN-SUFFIX,hikinggfw.org,Proxy\nDOMAIN-SUFFIX,voa-11.akacast.akamaistream.net,Proxy\nDOMAIN-SUFFIX,nightscloak.com,Proxy\nDOMAIN-SUFFIX,ndvv.ru,Proxy\nDOMAIN-SUFFIX,www.newcastlestar.com.au,Proxy\nDOMAIN-SUFFIX,vpnu.com,Proxy\nDOMAIN-SUFFIX,ironpython.net,Proxy\nDOMAIN-SUFFIX,l3m-data-collator.firebaseio.com,Proxy\nDOMAIN-SUFFIX,clarionproject.org,Proxy\nDOMAIN-SUFFIX,iuhrdf.org,Proxy\nDOMAIN-SUFFIX,www.innadimood.com,Proxy\nDOMAIN-SUFFIX,webhost4life.com,Proxy\nDOMAIN-SUFFIX,m.cp999ff.com,Proxy\nDOMAIN-SUFFIX,www.steampowered.com,Proxy\nDOMAIN-SUFFIX,nhentai.io,Proxy\nDOMAIN-SUFFIX,s.frlt.one,Proxy\nDOMAIN-SUFFIX,h5.ledong2027.com,Proxy\nDOMAIN-SUFFIX,www.catholicleague.org,Proxy\nDOMAIN-SUFFIX,freevpn001.simplesite.com,Proxy\nDOMAIN-SUFFIX,www.decanter.com,Proxy\nDOMAIN-SUFFIX,gate.huang.cool,Proxy\nDOMAIN-SUFFIX,www.pfcchina.org,Proxy\nDOMAIN-SUFFIX,jpiq.com,Proxy\nDOMAIN-SUFFIX,safeguarddefenders.com,Proxy\nDOMAIN-SUFFIX,shenpoker.com,Proxy\nDOMAIN-SUFFIX,www.g9997.com,Proxy\nDOMAIN-SUFFIX,d3svuyn6awh7rq.cloudfront.net,Proxy\nDOMAIN-SUFFIX,jet.com,Proxy\nDOMAIN-SUFFIX,mdj02.com,Proxy\nDOMAIN-SUFFIX,tor.xmission.com,Proxy\nDOMAIN-SUFFIX,mbaprepschool.com,Proxy\nDOMAIN-SUFFIX,istrash.com,Proxy\nDOMAIN-SUFFIX,porndoepremium.com,Proxy\nDOMAIN-SUFFIX,www.safervpn.cc,Proxy\nDOMAIN-SUFFIX,www.schwaebische.de,Proxy\nDOMAIN-SUFFIX,www.yc6346.com,Proxy\nDOMAIN-SUFFIX,ktrmr.com,Proxy\nDOMAIN-SUFFIX,kqvpn.com,Proxy\nDOMAIN-SUFFIX,www.toypark.in,Proxy\nDOMAIN-SUFFIX,firetell.net,Proxy\nDOMAIN-SUFFIX,tlc181.com,Proxy\nDOMAIN-SUFFIX,avaxhome.cc,Proxy\nDOMAIN-SUFFIX,drinkuproot.com,Proxy\nDOMAIN-SUFFIX,www.823252.xyz,Proxy\nDOMAIN-SUFFIX,dustri.org,Proxy\nDOMAIN-SUFFIX,www.sandu7.com,Proxy\nDOMAIN-SUFFIX,bartender.mobile.dowjones.io,Proxy\nDOMAIN-SUFFIX,y7340.com,Proxy\nDOMAIN-SUFFIX,dawakarpo.com,Proxy\nDOMAIN-SUFFIX,chicagoncmtv.com,Proxy\nDOMAIN-SUFFIX,the-japan-news.com,Proxy\nDOMAIN-SUFFIX,d9691.com,Proxy\nDOMAIN-SUFFIX,rael.cf,Proxy\nDOMAIN-SUFFIX,sharebee.com,Proxy\nDOMAIN-SUFFIX,jfqu37.xyz,Proxy\nDOMAIN-SUFFIX,str.sg,Proxy\nDOMAIN-SUFFIX,www.welt.de,Proxy\nDOMAIN-SUFFIX,guangming.com.my,Proxy\nDOMAIN-SUFFIX,unblockyoutube.us,Proxy\nDOMAIN-SUFFIX,www.alotporn.com,Proxy\nDOMAIN-SUFFIX,primadoll.jp,Proxy\nDOMAIN-SUFFIX,www.bj2222.com,Proxy\nDOMAIN-SUFFIX,goodreaders.com,Proxy\nDOMAIN-SUFFIX,ipoock.com,Proxy\nDOMAIN-SUFFIX,030buy.com,Proxy\nDOMAIN-SUFFIX,boxun10.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,dnsinfo.xyz,Proxy\nDOMAIN-SUFFIX,tw.user.bid.yahoo.com,Proxy\nDOMAIN-SUFFIX,fap-nation.com,Proxy\nDOMAIN-SUFFIX,save516.icu,Proxy\nDOMAIN-SUFFIX,btdigg.org,Proxy\nDOMAIN-SUFFIX,porntube.com,Proxy\nDOMAIN-SUFFIX,dns.moonssif.com,Proxy\nDOMAIN-SUFFIX,orgasm.com,Proxy\nDOMAIN-SUFFIX,www.site44.com,Proxy\nDOMAIN-SUFFIX,matsu.idv.tw,Proxy\nDOMAIN-SUFFIX,siyi123123123.spaces.live.com,Proxy\nDOMAIN-SUFFIX,hqmovies.com,Proxy\nDOMAIN-SUFFIX,69192.com,Proxy\nDOMAIN-SUFFIX,apps.ps8318.com,Proxy\nDOMAIN-SUFFIX,ems03.your-freedom.de,Proxy\nDOMAIN-SUFFIX,ag.hg1088.com,Proxy\nDOMAIN-SUFFIX,bitbay.net,Proxy\nDOMAIN-SUFFIX,fhyuan.net,Proxy\nDOMAIN-SUFFIX,api.rlcdn.com,Proxy\nDOMAIN-SUFFIX,hyuuga.booklikes.com,Proxy\nDOMAIN-SUFFIX,www.lesoleil.com,Proxy\nDOMAIN-SUFFIX,www.lrt.lt,Proxy\nDOMAIN-SUFFIX,rf199.com,Proxy\nDOMAIN-SUFFIX,hotvpn.com,Proxy\nDOMAIN-SUFFIX,web.tresorit.com,Proxy\nDOMAIN-SUFFIX,dxknrbi6q6qmb.cloudfront.net,Proxy\nDOMAIN-SUFFIX,666.com,Proxy\nDOMAIN-SUFFIX,hiawatha.org,Proxy\nDOMAIN-SUFFIX,chinafreepress.org,Proxy\nDOMAIN-SUFFIX,ukproxyserver.com,Proxy\nDOMAIN-SUFFIX,campuschristianfellowship.com,Proxy\nDOMAIN-SUFFIX,zhongjiwenti.000webhostapp.com,Proxy\nDOMAIN-SUFFIX,wymy.serveusers.com,Proxy\nDOMAIN-SUFFIX,realraptalk.com,Proxy\nDOMAIN-SUFFIX,scorser.com,Proxy\nDOMAIN-SUFFIX,www.cmoney.tw,Proxy\nDOMAIN-SUFFIX,enfal.de,Proxy\nDOMAIN-SUFFIX,huffingtonpost.co.uk,Proxy\nDOMAIN-SUFFIX,behance.org,Proxy\nDOMAIN-SUFFIX,url365.club,Proxy\nDOMAIN-SUFFIX,middle-way.net,Proxy\nDOMAIN-SUFFIX,www.h365.site,Proxy\nDOMAIN-SUFFIX,www.bworldonline.com,Proxy\nDOMAIN-SUFFIX,amws5544.com,Proxy\nDOMAIN-SUFFIX,biantailajiao.in,Proxy\nDOMAIN-SUFFIX,x7373455.com,Proxy\nDOMAIN-SUFFIX,tw.iqiyi.com,Proxy\nDOMAIN-SUFFIX,beyondfirewall.com,Proxy\nDOMAIN-SUFFIX,dsn559.com,Proxy\nDOMAIN-SUFFIX,www.fsbbs.net,Proxy\nDOMAIN-SUFFIX,adswu.com,Proxy\nDOMAIN-SUFFIX,liwenlianghero.github.io,Proxy\nDOMAIN-SUFFIX,axureformac.com,Proxy\nDOMAIN-SUFFIX,simbafood.com,Proxy\nDOMAIN-SUFFIX,dynalias.net,Proxy\nDOMAIN-SUFFIX,masters-of-cloud.de,Proxy\nDOMAIN-SUFFIX,chinaaffairs.org,Proxy\nDOMAIN-SUFFIX,freewebproxy.us,Proxy\nDOMAIN-SUFFIX,17pps.com,Proxy\nDOMAIN-SUFFIX,www.chineseupress.com,Proxy\nDOMAIN-SUFFIX,ssr.mx,Proxy\nDOMAIN-SUFFIX,19youtube.com,Proxy\nDOMAIN-SUFFIX,tlc818.com,Proxy\nDOMAIN-SUFFIX,bc525.com,Proxy\nDOMAIN-SUFFIX,nytimes.com,Proxy\nDOMAIN-SUFFIX,threadreaderapp.com,Proxy\nDOMAIN-SUFFIX,skyperfectv.co.jp,Proxy\nDOMAIN-SUFFIX,taiwan-fugue.blogspot.ca,Proxy\nDOMAIN-SUFFIX,fpmt.org.uk,Proxy\nDOMAIN-SUFFIX,www.unblocker.yt,Proxy\nDOMAIN-SUFFIX,pptv.com,Proxy\nDOMAIN-SUFFIX,www.shafou.com,Proxy\nDOMAIN-SUFFIX,tibet.org.tw,Proxy\nDOMAIN-SUFFIX,mining.transparency.org.au,Proxy\nDOMAIN-SUFFIX,iudnmi.site,Proxy\nDOMAIN-SUFFIX,d5350.com,Proxy\nDOMAIN-SUFFIX,vcupmars.com,Proxy\nDOMAIN-SUFFIX,eggc.com,Proxy\nDOMAIN-SUFFIX,urbandictionary.com,Proxy\nDOMAIN-SUFFIX,sarahpac.com,Proxy\nDOMAIN-SUFFIX,www.endless-ss.com,Proxy\nDOMAIN-SUFFIX,cnd.org,Proxy\nDOMAIN-SUFFIX,www.javbus3.com,Proxy\nDOMAIN-SUFFIX,mypikpak.com,Proxy\nDOMAIN-SUFFIX,olehdtv.com,Proxy\nDOMAIN-SUFFIX,aabb1802.com,Proxy\nDOMAIN-SUFFIX,proxite.in,Proxy\nDOMAIN-SUFFIX,www.himalaya.com,Proxy\nDOMAIN-SUFFIX,www.peoplesforum.com,Proxy\nDOMAIN-SUFFIX,compuspire.co.uk,Proxy\nDOMAIN-SUFFIX,themoshpit.us,Proxy\nDOMAIN-SUFFIX,nicotv.cc,Proxy\nDOMAIN-SUFFIX,rolia.com,Proxy\nDOMAIN-SUFFIX,voatibetanenglish.com,Proxy\nDOMAIN-SUFFIX,www.hishadowsocks.com,Proxy\nDOMAIN-SUFFIX,www.lb185.com,Proxy\nDOMAIN-SUFFIX,otto.de,Proxy\nDOMAIN-SUFFIX,temporal-held-crocodile.glitch.me,Proxy\nDOMAIN-SUFFIX,benihunik.com,Proxy\nDOMAIN-SUFFIX,cn.swj.com,Proxy\nDOMAIN-SUFFIX,instagantt.com,Proxy\nDOMAIN-SUFFIX,imgam.top,Proxy\nDOMAIN-SUFFIX,freetls.fastly.net,Proxy\nDOMAIN-SUFFIX,198tlc.com,Proxy\nDOMAIN-SUFFIX,casadeltibetbcn.org,Proxy\nDOMAIN-SUFFIX,xam00.com,Proxy\nDOMAIN-SUFFIX,www.19463331.com,Proxy\nDOMAIN-SUFFIX,todayapp.cc,Proxy\nDOMAIN-SUFFIX,6366888111.com,Proxy\nDOMAIN-SUFFIX,sh26.pat.flnet.org,Proxy\nDOMAIN-SUFFIX,dns-doh-no-safe-search.dnsforfamily.com,Proxy\nDOMAIN-SUFFIX,www.mvclub.net,Proxy\nDOMAIN-SUFFIX,freebieit.com,Proxy\nDOMAIN-SUFFIX,bg567.com,Proxy\nDOMAIN-SUFFIX,t8j.jystoruz.com,Proxy\nDOMAIN-SUFFIX,debate.org,Proxy\nDOMAIN-SUFFIX,torrentkittycn.com,Proxy\nDOMAIN-SUFFIX,liberationprisonproject.org,Proxy\nDOMAIN-SUFFIX,marvel.app.com,Proxy\nDOMAIN-SUFFIX,www.5278.mobi,Proxy\nDOMAIN-SUFFIX,w.w3.ns3.name,Proxy\nDOMAIN-SUFFIX,lovetvshow.com,Proxy\nDOMAIN-SUFFIX,blubrry.com,Proxy\nDOMAIN-SUFFIX,doesntexist.com,Proxy\nDOMAIN-SUFFIX,g.linkscholar.org,Proxy\nDOMAIN-SUFFIX,www.263xx.com,Proxy\nDOMAIN-SUFFIX,est-a-la-masion.com,Proxy\nDOMAIN-SUFFIX,stoporganharvesting.org,Proxy\nDOMAIN-SUFFIX,paopao15.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,btunnel.com,Proxy\nDOMAIN-SUFFIX,5s.slyip.net,Proxy\nDOMAIN-SUFFIX,arcobaleno.xyz,Proxy\nDOMAIN-SUFFIX,www.fuli35.lv,Proxy\nDOMAIN-SUFFIX,dogbus.org,Proxy\nDOMAIN-SUFFIX,www.morbitzer.de,Proxy\nDOMAIN-SUFFIX,gesundteam.se,Proxy\nDOMAIN-SUFFIX,vajranorth.org,Proxy\nDOMAIN-SUFFIX,gratisprogramas.org,Proxy\nDOMAIN-SUFFIX,redtabfoundation.org,Proxy\nDOMAIN-SUFFIX,s.team,Proxy\nDOMAIN-SUFFIX,www.srkoo.com,Proxy\nDOMAIN-SUFFIX,peachyforum.com,Proxy\nDOMAIN-SUFFIX,google.co.th,Proxy\nDOMAIN-SUFFIX,tw01.org,Proxy\nDOMAIN-SUFFIX,edtechteacher.org,Proxy\nDOMAIN-SUFFIX,quranexplorer.com,Proxy\nDOMAIN-SUFFIX,cyfrowypolsat.pl,Proxy\nDOMAIN-SUFFIX,db2ywah86wj5b.cloudfront.net,Proxy\nDOMAIN-SUFFIX,theblackship.com,Proxy\nDOMAIN-SUFFIX,facebook.in,Proxy\nDOMAIN-SUFFIX,laowanghas786.vip,Proxy\nDOMAIN-SUFFIX,wikileaks.org,Proxy\nDOMAIN-SUFFIX,motherjones.com,Proxy\nDOMAIN-SUFFIX,www.your-freedom.de,Proxy\nDOMAIN-SUFFIX,www.vpndirect.com,Proxy\nDOMAIN-SUFFIX,mos.ru,Proxy\nDOMAIN-SUFFIX,top.fadama.com,Proxy\nDOMAIN-SUFFIX,www.asia1.com,Proxy\nDOMAIN-SUFFIX,athenaeizou.com,Proxy\nDOMAIN-SUFFIX,mail-archive.com,Proxy\nDOMAIN-SUFFIX,www.h-moe.com,Proxy\nDOMAIN-SUFFIX,freerepublic.com,Proxy\nDOMAIN-SUFFIX,youtube.ie,Proxy\nDOMAIN-SUFFIX,mhub.dafapoker.com,Proxy\nDOMAIN-SUFFIX,ultraxs.com,Proxy\nDOMAIN-SUFFIX,bmh001.com,Proxy\nDOMAIN-SUFFIX,blogblog.com,Proxy\nDOMAIN-SUFFIX,www.milsurps.com,Proxy\nDOMAIN-SUFFIX,www.zlvc.net,Proxy\nDOMAIN-SUFFIX,babynet.com.hk,Proxy\nDOMAIN-SUFFIX,fqvpn.net,Proxy\nDOMAIN-SUFFIX,www.ltm.com.tw,Proxy\nDOMAIN-SUFFIX,uml.navitas.com,Proxy\nDOMAIN-SUFFIX,www.blocktempo.com,Proxy\nDOMAIN-SUFFIX,dc9922.com,Proxy\nDOMAIN-SUFFIX,dnl-09.geo.kaspersky.com,Proxy\nDOMAIN-SUFFIX,www.188188188188b.com,Proxy\nDOMAIN-SUFFIX,www.accorhotels.com,Proxy\nDOMAIN-SUFFIX,sinoinsider.com,Proxy\nDOMAIN-SUFFIX,bfbet.com,Proxy\nDOMAIN-SUFFIX,metart.com,Proxy\nDOMAIN-SUFFIX,d2u17gw7yvvb2k.cloudfront.net,Proxy\nDOMAIN-SUFFIX,94xac.com,Proxy\nDOMAIN-SUFFIX,fsimnet.com,Proxy\nDOMAIN-SUFFIX,followthegls.com,Proxy\nDOMAIN-SUFFIX,www.quran-radio.com,Proxy\nDOMAIN-SUFFIX,tora.to,Proxy\nDOMAIN-SUFFIX,comdns.xyz,Proxy\nDOMAIN-SUFFIX,pornhubapparel.com,Proxy\nDOMAIN-SUFFIX,video.aol.com,Proxy\nDOMAIN-SUFFIX,trubadis.com,Proxy\nDOMAIN-SUFFIX,apps.dtic.mil,Proxy\nDOMAIN-SUFFIX,imomoe.net,Proxy\nDOMAIN-SUFFIX,www.taiwan.net.tw,Proxy\nDOMAIN-SUFFIX,xinbi088.com,Proxy\nDOMAIN-SUFFIX,flowertucci.com,Proxy\nDOMAIN-SUFFIX,www.indiatoday.com,Proxy\nDOMAIN-SUFFIX,xinbi606.com,Proxy\nDOMAIN-SUFFIX,lematin.ch,Proxy\nDOMAIN-SUFFIX,merics.org,Proxy\nDOMAIN-SUFFIX,extreme-fetish.org,Proxy\nDOMAIN-SUFFIX,instaspot.net,Proxy\nDOMAIN-SUFFIX,hrea.org,Proxy\nDOMAIN-SUFFIX,northboot.xyz,Proxy\nDOMAIN-SUFFIX,makemoneythai.com,Proxy\nDOMAIN-SUFFIX,trtc.com.tw,Proxy\nDOMAIN-SUFFIX,freshlive.tv,Proxy\nDOMAIN-SUFFIX,thegly.com,Proxy\nDOMAIN-SUFFIX,btsow.one,Proxy\nDOMAIN-SUFFIX,www.4001.xyz,Proxy\nDOMAIN-SUFFIX,rhgroup.net,Proxy\nDOMAIN-SUFFIX,bravotube.com,Proxy\nDOMAIN-SUFFIX,jtfx.mobi,Proxy\nDOMAIN-SUFFIX,www.xi666.com,Proxy\nDOMAIN-SUFFIX,qiqi.com,Proxy\nDOMAIN-SUFFIX,www.pinterest.cl,Proxy\nDOMAIN-SUFFIX,nyaa.si,Proxy\nDOMAIN-SUFFIX,wxw.cat,Proxy\nDOMAIN-SUFFIX,sports.williamhill.com,Proxy\nDOMAIN-SUFFIX,www.greatcellenergy.com,Proxy\nDOMAIN-SUFFIX,d7hpybo0qewfl.cloudfront.net,Proxy\nDOMAIN-SUFFIX,ivyseeds.com,Proxy\nDOMAIN-SUFFIX,trabajo.gob.ar,Proxy\nDOMAIN-SUFFIX,promter-management.onelink.me,Proxy\nDOMAIN-SUFFIX,s1s1s1.com,Proxy\nDOMAIN-SUFFIX,yao.cl,Proxy\nDOMAIN-SUFFIX,www.moe-acg.cc,Proxy\nDOMAIN-SUFFIX,nationalawakening.org,Proxy\nDOMAIN-SUFFIX,spyno1.webnode.tw,Proxy\nDOMAIN-SUFFIX,h.139.re,Proxy\nDOMAIN-SUFFIX,www.71938811.com,Proxy\nDOMAIN-SUFFIX,entermap.com,Proxy\nDOMAIN-SUFFIX,jike0001.net,Proxy\nDOMAIN-SUFFIX,cuiweiping.net,Proxy\nDOMAIN-SUFFIX,www.shadowsocks.biz,Proxy\nDOMAIN-SUFFIX,bed.b0ne.com,Proxy\nDOMAIN-SUFFIX,dtnews.github.io,Proxy\nDOMAIN-SUFFIX,vo.domain888.pw,Proxy\nDOMAIN-SUFFIX,am8299.com,Proxy\nDOMAIN-SUFFIX,lanterncn.cn,Proxy\nDOMAIN-SUFFIX,xxxdessert.com,Proxy\nDOMAIN-SUFFIX,www.cchr.org.tw,Proxy\nDOMAIN-SUFFIX,ambjl20.com,Proxy\nDOMAIN-SUFFIX,byrut.org,Proxy\nDOMAIN-SUFFIX,idiomconnection.com,Proxy\nDOMAIN-SUFFIX,freegroup.droppages.com,Proxy\nDOMAIN-SUFFIX,www.peoplesworld.org,Proxy\nDOMAIN-SUFFIX,play.hbogo.com,Proxy\nDOMAIN-SUFFIX,cdn.kone.com,Proxy\nDOMAIN-SUFFIX,bridgefund.org,Proxy\nDOMAIN-SUFFIX,www.22hjdc.com,Proxy\nDOMAIN-SUFFIX,www.nytims.com,Proxy\nDOMAIN-SUFFIX,digi-gra.net,Proxy\nDOMAIN-SUFFIX,www.xf811.com,Proxy\nDOMAIN-SUFFIX,www.firmex.com,Proxy\nDOMAIN-SUFFIX,fuckgfw.org,Proxy\nDOMAIN-SUFFIX,pornrapidshare.com,Proxy\nDOMAIN-SUFFIX,mastadon.sdf.org,Proxy\nDOMAIN-SUFFIX,tokyo-porn-tube.com,Proxy\nDOMAIN-SUFFIX,mingpaosf.com,Proxy\nDOMAIN-SUFFIX,hmvdigital.com,Proxy\nDOMAIN-SUFFIX,zannel.com,Proxy\nDOMAIN-SUFFIX,blog.martinoei.com,Proxy\nDOMAIN-SUFFIX,roulette.xijinping.one,Proxy\nDOMAIN-SUFFIX,84493333.com,Proxy\nDOMAIN-SUFFIX,velaciela.ms,Proxy\nDOMAIN-SUFFIX,yesav.net,Proxy\nDOMAIN-SUFFIX,easylist.to,Proxy\nDOMAIN-SUFFIX,poe.com,Proxy\nDOMAIN-SUFFIX,feedly.com,Proxy\nDOMAIN-SUFFIX,www.asiasentinel.com,Proxy\nDOMAIN-SUFFIX,www.dynamicsignal.com,Proxy\nDOMAIN-SUFFIX,dj.gamecyber.net,Proxy\nDOMAIN-SUFFIX,ry88.com,Proxy\nDOMAIN-SUFFIX,strongvpn.cc,Proxy\nDOMAIN-SUFFIX,4tubemate.com,Proxy\nDOMAIN-SUFFIX,javocado.com,Proxy\nDOMAIN-SUFFIX,m.taiwan.net.tw,Proxy\nDOMAIN-SUFFIX,blah.me,Proxy\nDOMAIN-SUFFIX,hacken.cc,Proxy\nDOMAIN-SUFFIX,proxy2974.my-addr.org,Proxy\nDOMAIN-SUFFIX,www.zgzy039.eu.org,Proxy\nDOMAIN-SUFFIX,nord-mirror-site.net,Proxy\nDOMAIN-SUFFIX,resistenciacamponesa.com,Proxy\nDOMAIN-SUFFIX,edmontonchina.cn,Proxy\nDOMAIN-SUFFIX,www.geti2p.com,Proxy\nDOMAIN-SUFFIX,huffingtonpost.com,Proxy\nDOMAIN-SUFFIX,newsdigest.jp,Proxy\nDOMAIN-SUFFIX,soh.tw,Proxy\nDOMAIN-SUFFIX,retrodprk.com,Proxy\nDOMAIN-SUFFIX,dpsekuio8buzd.cloudfront.net,Proxy\nDOMAIN-SUFFIX,appshopper.com,Proxy\nDOMAIN-SUFFIX,hugoroy.eu,Proxy\nDOMAIN-SUFFIX,gmbd.cn,Proxy\nDOMAIN-SUFFIX,oxlife.co,Proxy\nDOMAIN-SUFFIX,www.otatop.app,Proxy\nDOMAIN-SUFFIX,4rbtv.com,Proxy\nDOMAIN-SUFFIX,www01.eyny.com,Proxy\nDOMAIN-SUFFIX,facebook.co.jp,Proxy\nDOMAIN-SUFFIX,www.j9038.com,Proxy\nDOMAIN-SUFFIX,xh47777.com,Proxy\nDOMAIN-SUFFIX,www.e8792.com,Proxy\nDOMAIN-SUFFIX,google.co.ls,Proxy\nDOMAIN-SUFFIX,aporlebeke.us,Proxy\nDOMAIN-SUFFIX,bavpn.com,Proxy\nDOMAIN-SUFFIX,defy-studios.com,Proxy\nDOMAIN-SUFFIX,mike.cz.cc,Proxy\nDOMAIN-SUFFIX,smutcam.com,Proxy\nDOMAIN-SUFFIX,uniregistry.com,Proxy\nDOMAIN-SUFFIX,funkyimg.com,Proxy\nDOMAIN-SUFFIX,635-788.com,Proxy\nDOMAIN-SUFFIX,casadeltibet.it,Proxy\nDOMAIN-SUFFIX,ky4408.com,Proxy\nDOMAIN-SUFFIX,1lib.eu,Proxy\nDOMAIN-SUFFIX,wqa.org,Proxy\nDOMAIN-SUFFIX,www.yzc666.com,Proxy\nDOMAIN-SUFFIX,www.bendigoweekly.com,Proxy\nDOMAIN-SUFFIX,fotiaoqiang.club,Proxy\nDOMAIN-SUFFIX,pornav.co,Proxy\nDOMAIN-SUFFIX,www.realcleardefense.com,Proxy\nDOMAIN-SUFFIX,westelm.com,Proxy\nDOMAIN-SUFFIX,www.upstate.edu,Proxy\nDOMAIN-SUFFIX,twifan.com,Proxy\nDOMAIN-SUFFIX,pinip.net,Proxy\nDOMAIN-SUFFIX,www.kanunu8.com,Proxy\nDOMAIN-SUFFIX,dongyangjing.com,Proxy\nDOMAIN-SUFFIX,dvs.com.my,Proxy\nDOMAIN-SUFFIX,wainao.me,Proxy\nDOMAIN-SUFFIX,kagmoe.strikingly.com,Proxy\nDOMAIN-SUFFIX,puffinbrowser.com,Proxy\nDOMAIN-SUFFIX,archive.li,Proxy\nDOMAIN-SUFFIX,ogli.org,Proxy\nDOMAIN-SUFFIX,jav101.com,Proxy\nDOMAIN-SUFFIX,meltoday.com,Proxy\nDOMAIN-SUFFIX,hkmap.live,Proxy\nDOMAIN-SUFFIX,www.babypips.com,Proxy\nDOMAIN-SUFFIX,usa1lib.org,Proxy\nDOMAIN-SUFFIX,www.irrigator.com.au,Proxy\nDOMAIN-SUFFIX,kkbox.com,Proxy\nDOMAIN-SUFFIX,www.bloomberg.co.kr,Proxy\nDOMAIN-SUFFIX,hot2.gq,Proxy\nDOMAIN-SUFFIX,google.jo,Proxy\nDOMAIN-SUFFIX,allsaintsclinton.org,Proxy\nDOMAIN-SUFFIX,me.688.org,Proxy\nDOMAIN-SUFFIX,melodicamen.com,Proxy\nDOMAIN-SUFFIX,epochstories.com,Proxy\nDOMAIN-SUFFIX,bbs.by1024.com,Proxy\nDOMAIN-SUFFIX,moptcmoney.webnode.tw,Proxy\nDOMAIN-SUFFIX,vpnjs.com,Proxy\nDOMAIN-SUFFIX,tv.com,Proxy\nDOMAIN-SUFFIX,zh.wikipeida.org,Proxy\nDOMAIN-SUFFIX,cherrysave.com,Proxy\nDOMAIN-SUFFIX,www.bida-tech.com,Proxy\nDOMAIN-SUFFIX,live-cdn.xzxwhcb.com,Proxy\nDOMAIN-SUFFIX,weirdhentai.com,Proxy\nDOMAIN-SUFFIX,www.cilifeng.me,Proxy\nDOMAIN-SUFFIX,cnyes.com,Proxy\nDOMAIN-SUFFIX,nitter.esmailelbob.xyz,Proxy\nDOMAIN-SUFFIX,www.dynasys.org,Proxy\nDOMAIN-SUFFIX,utzsnacks.com,Proxy\nDOMAIN-SUFFIX,dyro.net,Proxy\nDOMAIN-SUFFIX,268.tobuy.us,Proxy\nDOMAIN-SUFFIX,ytimg.com,Proxy\nDOMAIN-SUFFIX,cp999.com,Proxy\nDOMAIN-SUFFIX,www.imxprs.com,Proxy\nDOMAIN-SUFFIX,trueporn.com,Proxy\nDOMAIN-SUFFIX,singlelogin.org,Proxy\nDOMAIN-SUFFIX,it-native.de,Proxy\nDOMAIN-SUFFIX,vpnreviewer.com,Proxy\nDOMAIN-SUFFIX,www.lz.de,Proxy\nDOMAIN-SUFFIX,bestvpnchina.com,Proxy\nDOMAIN-SUFFIX,codeger.com,Proxy\nDOMAIN-SUFFIX,keepanonymous.com,Proxy\nDOMAIN-SUFFIX,tibetoffice.eu,Proxy\nDOMAIN-SUFFIX,www.tianhuaculture.net,Proxy\nDOMAIN-SUFFIX,strikingly.com,Proxy\nDOMAIN-SUFFIX,www.tubekittysex.com,Proxy\nDOMAIN-SUFFIX,itemfix.com,Proxy\nDOMAIN-SUFFIX,sindclub.com,Proxy\nDOMAIN-SUFFIX,www.fanqiang.net,Proxy\nDOMAIN-SUFFIX,hispachan.org,Proxy\nDOMAIN-SUFFIX,tinyhomes.co,Proxy\nDOMAIN-SUFFIX,xxltv.fr,Proxy\nDOMAIN-SUFFIX,coinbene.com,Proxy\nDOMAIN-SUFFIX,i2phides.me,Proxy\nDOMAIN-SUFFIX,geek2live.org,Proxy\nDOMAIN-SUFFIX,www.lhassa.org,Proxy\nDOMAIN-SUFFIX,greatroc.org,Proxy\nDOMAIN-SUFFIX,booksamillioninc.com,Proxy\nDOMAIN-SUFFIX,quiz.directory,Proxy\nDOMAIN-SUFFIX,harrowdrive.com,Proxy\nDOMAIN-SUFFIX,www.486646.com,Proxy\nDOMAIN-SUFFIX,4409698.com,Proxy\nDOMAIN-SUFFIX,doh.appliedprivacy.net,Proxy\nDOMAIN-SUFFIX,qycz.org,Proxy\nDOMAIN-SUFFIX,billypan.com,Proxy\nDOMAIN-SUFFIX,roboforex.com,Proxy\nDOMAIN-SUFFIX,italk5.com,Proxy\nDOMAIN-SUFFIX,shadowsocks.org,Proxy\nDOMAIN-SUFFIX,www.mhchina.net,Proxy\nDOMAIN-SUFFIX,ddfprod.com,Proxy\nDOMAIN-SUFFIX,www.hidemenow.net,Proxy\nDOMAIN-SUFFIX,saycheese.hk,Proxy\nDOMAIN-SUFFIX,www.mangaz.com,Proxy\nDOMAIN-SUFFIX,22.eye.rs,Proxy\nDOMAIN-SUFFIX,pets.udn.com,Proxy\nDOMAIN-SUFFIX,cl.1024cl.org,Proxy\nDOMAIN-SUFFIX,gitlab.io,Proxy\nDOMAIN-SUFFIX,apkmodmirror.com,Proxy\nDOMAIN-SUFFIX,c888.net,Proxy\nDOMAIN-SUFFIX,chinafile.com,Proxy\nDOMAIN-SUFFIX,bnrmetal.com,Proxy\nDOMAIN-SUFFIX,www.javseeds.com,Proxy\nDOMAIN-SUFFIX,sbofa123.com,Proxy\nDOMAIN-SUFFIX,torrentprivacy.com,Proxy\nDOMAIN-SUFFIX,jlvpn.com,Proxy\nDOMAIN-SUFFIX,www.accp.com,Proxy\nDOMAIN-SUFFIX,www.icq.com,Proxy\nDOMAIN-SUFFIX,grjsq.tv,Proxy\nDOMAIN-SUFFIX,www.sa36.net,Proxy\nDOMAIN-SUFFIX,w1.adca2cf2fdb.xyz,Proxy\nDOMAIN-SUFFIX,konachan.com,Proxy\nDOMAIN-SUFFIX,gyp.gsrc.io,Proxy\nDOMAIN-SUFFIX,tbswd.org,Proxy\nDOMAIN-SUFFIX,playno1.com,Proxy\nDOMAIN-SUFFIX,atlanta168.com,Proxy\nDOMAIN-SUFFIX,playboy.com,Proxy\nDOMAIN-SUFFIX,www.fh-asia.com,Proxy\nDOMAIN-SUFFIX,xnxx.blog.br,Proxy\nDOMAIN-SUFFIX,kirtu.com,Proxy\nDOMAIN-SUFFIX,www.redditinc.com,Proxy\nDOMAIN-SUFFIX,ivee.us,Proxy\nDOMAIN-SUFFIX,www.rubyfortune.com,Proxy\nDOMAIN-SUFFIX,yuri.ws,Proxy\nDOMAIN-SUFFIX,feifeiss.com,Proxy\nDOMAIN-SUFFIX,www.beduu.com,Proxy\nDOMAIN-SUFFIX,www.pin8899.com,Proxy\nDOMAIN-SUFFIX,troniac.com,Proxy\nDOMAIN-SUFFIX,mbetwayintw.agent1818.com,Proxy\nDOMAIN-SUFFIX,beimeilife.com,Proxy\nDOMAIN-SUFFIX,bifa2007.com,Proxy\nDOMAIN-SUFFIX,effectivecpmgate.com,Proxy\nDOMAIN-SUFFIX,www.meiji-dondon.com,Proxy\nDOMAIN-SUFFIX,newrealmstudios.ca,Proxy\nDOMAIN-SUFFIX,v1.truth.gq,Proxy\nDOMAIN-SUFFIX,yadi.sk,Proxy\nDOMAIN-SUFFIX,boylove.cc,Proxy\nDOMAIN-SUFFIX,h5.ld2089.cc,Proxy\nDOMAIN-SUFFIX,karupsha.com,Proxy\nDOMAIN-SUFFIX,pornhb.com,Proxy\nDOMAIN-SUFFIX,2daylink.com,Proxy\nDOMAIN-SUFFIX,zello.com,Proxy\nDOMAIN-SUFFIX,theync.com,Proxy\nDOMAIN-SUFFIX,www.ydn.com.tw,Proxy\nDOMAIN-SUFFIX,proxynetwork.org.uk,Proxy\nDOMAIN-SUFFIX,w1.vz05.club,Proxy\nDOMAIN-SUFFIX,dlercloud.com,Proxy\nDOMAIN-SUFFIX,874.freegamepc.org,Proxy\nDOMAIN-SUFFIX,www.aucklandzen.org.nz,Proxy\nDOMAIN-SUFFIX,ddnews.gov.in,Proxy\nDOMAIN-SUFFIX,npa.go.jp,Proxy\nDOMAIN-SUFFIX,pandora.tv,Proxy\nDOMAIN-SUFFIX,bbc1.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,hg0882.com,Proxy\nDOMAIN-SUFFIX,allervpn.com,Proxy\nDOMAIN-SUFFIX,suncity818.com,Proxy\nDOMAIN-SUFFIX,www.afanga.com,Proxy\nDOMAIN-SUFFIX,abcvpn.com,Proxy\nDOMAIN-SUFFIX,icefoc.org,Proxy\nDOMAIN-SUFFIX,loufisher.org,Proxy\nDOMAIN-SUFFIX,xmbs3.xyz,Proxy\nDOMAIN-SUFFIX,dz.adj.idv.tw,Proxy\nDOMAIN-SUFFIX,re.etowns.net,Proxy\nDOMAIN-SUFFIX,liangspace.droppages.com,Proxy\nDOMAIN-SUFFIX,www.makeupcartel.com.au,Proxy\nDOMAIN-SUFFIX,hkctu.org.hk,Proxy\nDOMAIN-SUFFIX,tradingview.com,Proxy\nDOMAIN-SUFFIX,evhead.com,Proxy\nDOMAIN-SUFFIX,kikadraws.hr,Proxy\nDOMAIN-SUFFIX,tx2600.net,Proxy\nDOMAIN-SUFFIX,12bet.com,Proxy\nDOMAIN-SUFFIX,xjtravelguide.com,Proxy\nDOMAIN-SUFFIX,proximize.me,Proxy\nDOMAIN-SUFFIX,shuihu.ca,Proxy\nDOMAIN-SUFFIX,ieasytimes.jigsy.com,Proxy\nDOMAIN-SUFFIX,www.88lo.com,Proxy\nDOMAIN-SUFFIX,www.qkforman.com,Proxy\nDOMAIN-SUFFIX,www.yzlhb686.com,Proxy\nDOMAIN-SUFFIX,hec.su,Proxy\nDOMAIN-SUFFIX,iqq3.cc,Proxy\nDOMAIN-SUFFIX,tizi.nu,Proxy\nDOMAIN-SUFFIX,mingpaony.com,Proxy\nDOMAIN-SUFFIX,www.pinterest.fr,Proxy\nDOMAIN-SUFFIX,eightcap-8.com,Proxy\nDOMAIN-SUFFIX,li.taipei,Proxy\nDOMAIN-SUFFIX,chinademocrats.org,Proxy\nDOMAIN-SUFFIX,cph.org,Proxy\nDOMAIN-SUFFIX,china18.org,Proxy\nDOMAIN-SUFFIX,www.bombalatimes.com.au,Proxy\nDOMAIN-SUFFIX,www.take2hosting.com,Proxy\nDOMAIN-SUFFIX,1000novel.com,Proxy\nDOMAIN-SUFFIX,54647.io,Proxy\nDOMAIN-SUFFIX,mail.mediamonks.com,Proxy\nDOMAIN-SUFFIX,www.douyin.com,Proxy\nDOMAIN-SUFFIX,nytfilmclub.com,Proxy\nDOMAIN-SUFFIX,pianku.me,Proxy\nDOMAIN-SUFFIX,yy635.com,Proxy\nDOMAIN-SUFFIX,rhythmusic.net,Proxy\nDOMAIN-SUFFIX,superpages.com,Proxy\nDOMAIN-SUFFIX,18gal.xyz,Proxy\nDOMAIN-SUFFIX,www.mgty.com,Proxy\nDOMAIN-SUFFIX,pcc.gov.tw,Proxy\nDOMAIN-SUFFIX,mykomica.org,Proxy\nDOMAIN-SUFFIX,d1syk2f6goqzr.cloudfront.net,Proxy\nDOMAIN-SUFFIX,ddnsfree.com,Proxy\nDOMAIN-SUFFIX,www.40sihu.com,Proxy\nDOMAIN-SUFFIX,localyoutube.com,Proxy\nDOMAIN-SUFFIX,popularcommunitybank.com,Proxy\nDOMAIN-SUFFIX,www.881903.com,Proxy\nDOMAIN-SUFFIX,point2hk.com,Proxy\nDOMAIN-SUFFIX,dns.52306.org,Proxy\nDOMAIN-SUFFIX,dynhost.ws,Proxy\nDOMAIN-SUFFIX,www.antvpn.com,Proxy\nDOMAIN-SUFFIX,javjunkies.com,Proxy\nDOMAIN-SUFFIX,yopmail.com,Proxy\nDOMAIN-SUFFIX,www.zensur.freerk.com,Proxy\nDOMAIN-SUFFIX,www.91vpnn.com,Proxy\nDOMAIN-SUFFIX,duga.jp,Proxy\nDOMAIN-SUFFIX,knowledgerush.com,Proxy\nDOMAIN-SUFFIX,linkin.com,Proxy\nDOMAIN-SUFFIX,boeddhistischdagblad.nl,Proxy\nDOMAIN-SUFFIX,acg18.life,Proxy\nDOMAIN-SUFFIX,catfightpayperview.xxx,Proxy\nDOMAIN-SUFFIX,www.chinatown.com.au,Proxy\nDOMAIN-SUFFIX,facebookmail.com,Proxy\nDOMAIN-SUFFIX,39.my03.com,Proxy\nDOMAIN-SUFFIX,90kxw.com,Proxy\nDOMAIN-SUFFIX,dutch7.com,Proxy\nDOMAIN-SUFFIX,zdx.in,Proxy\nDOMAIN-SUFFIX,5555cs.com,Proxy\nDOMAIN-SUFFIX,m.moegirl.org,Proxy\nDOMAIN-SUFFIX,g1.nytimg.com,Proxy\nDOMAIN-SUFFIX,ibcp07.com,Proxy\nDOMAIN-SUFFIX,indonesiavpn.com,Proxy\nDOMAIN-SUFFIX,ddnsgeek.com,Proxy\nDOMAIN-SUFFIX,memeyou.net,Proxy\nDOMAIN-SUFFIX,www.erosexotica.com,Proxy\nDOMAIN-SUFFIX,kokuyo-furniture.com,Proxy\nDOMAIN-SUFFIX,youdian.in,Proxy\nDOMAIN-SUFFIX,dawangidc.com,Proxy\nDOMAIN-SUFFIX,peoplenews.tw,Proxy\nDOMAIN-SUFFIX,dsn5050.com,Proxy\nDOMAIN-SUFFIX,d35ln70levegcl.cloudfront.net,Proxy\nDOMAIN-SUFFIX,twdown.com,Proxy\nDOMAIN-SUFFIX,d37dptkgws0x4v.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.tianjing.org,Proxy\nDOMAIN-SUFFIX,www.etop.idv.tw,Proxy\nDOMAIN-SUFFIX,baipiaoyun.xyz,Proxy\nDOMAIN-SUFFIX,vpncoupons.com,Proxy\nDOMAIN-SUFFIX,cftfc.com,Proxy\nDOMAIN-SUFFIX,happy-porn.com,Proxy\nDOMAIN-SUFFIX,www.ts2.se,Proxy\nDOMAIN-SUFFIX,sg.finance.yahoo.com,Proxy\nDOMAIN-SUFFIX,leorockwell.com,Proxy\nDOMAIN-SUFFIX,free-proxy.com.de,Proxy\nDOMAIN-SUFFIX,sex888.cc,Proxy\nDOMAIN-SUFFIX,rutube.ru,Proxy\nDOMAIN-SUFFIX,vns2003.com,Proxy\nDOMAIN-SUFFIX,3d.ddos.im,Proxy\nDOMAIN-SUFFIX,222666.com,Proxy\nDOMAIN-SUFFIX,ipjetable.net,Proxy\nDOMAIN-SUFFIX,identi.ca,Proxy\nDOMAIN-SUFFIX,www.ca88.com,Proxy\nDOMAIN-SUFFIX,www.ddns.net,Proxy\nDOMAIN-SUFFIX,scriptvealpatronage.com,Proxy\nDOMAIN-SUFFIX,it.bnaz.org,Proxy\nDOMAIN-SUFFIX,zeronet.io,Proxy\nDOMAIN-SUFFIX,t.livekn.com,Proxy\nDOMAIN-SUFFIX,turbovpn.com,Proxy\nDOMAIN-SUFFIX,cityoftemecula.org,Proxy\nDOMAIN-SUFFIX,www.cosmid.net,Proxy\nDOMAIN-SUFFIX,wormholevpn.net,Proxy\nDOMAIN-SUFFIX,tfiflve.com,Proxy\nDOMAIN-SUFFIX,nikeinvest.ro,Proxy\nDOMAIN-SUFFIX,d3f53u330ucwkp.cloudfront.net,Proxy\nDOMAIN-SUFFIX,ecimg.tw,Proxy\nDOMAIN-SUFFIX,nxpay.com,Proxy\nDOMAIN-SUFFIX,www.mudgeeguardian.com.au,Proxy\nDOMAIN-SUFFIX,files2me.com,Proxy\nDOMAIN-SUFFIX,wionews.com,Proxy\nDOMAIN-SUFFIX,www.sexypattycake.com,Proxy\nDOMAIN-SUFFIX,171gifs.com,Proxy\nDOMAIN-SUFFIX,ipburger.com,Proxy\nDOMAIN-SUFFIX,668fff668.com,Proxy\nDOMAIN-SUFFIX,maatools.com,Proxy\nDOMAIN-SUFFIX,www.91szy.com,Proxy\nDOMAIN-SUFFIX,bignews.org,Proxy\nDOMAIN-SUFFIX,eurogirlsongirls.com,Proxy\nDOMAIN-SUFFIX,www.paofucloud.vip,Proxy\nDOMAIN-SUFFIX,easyeaves.com.au,Proxy\nDOMAIN-SUFFIX,d18idkgh47r8la.cloudfront.net,Proxy\nDOMAIN-SUFFIX,byj01.com,Proxy\nDOMAIN-SUFFIX,www.acast.com,Proxy\nDOMAIN-SUFFIX,barodanzltd.co.nz,Proxy\nDOMAIN-SUFFIX,acgheaven.org,Proxy\nDOMAIN-SUFFIX,hsselite.com,Proxy\nDOMAIN-SUFFIX,273529.top,Proxy\nDOMAIN-SUFFIX,thenewyorker.com,Proxy\nDOMAIN-SUFFIX,player.haoli787.com,Proxy\nDOMAIN-SUFFIX,karmapa.org,Proxy\nDOMAIN-SUFFIX,rickhuang.asuscomm.com,Proxy\nDOMAIN-SUFFIX,tor-exit-56.for-privacy.net,Proxy\nDOMAIN-SUFFIX,www.avdvd.tv,Proxy\nDOMAIN-SUFFIX,72pro.cc,Proxy\nDOMAIN-SUFFIX,tcpspeed.com,Proxy\nDOMAIN-SUFFIX,sockscap64.com,Proxy\nDOMAIN-SUFFIX,huoqiang.club,Proxy\nDOMAIN-SUFFIX,cn.goophone.hk,Proxy\nDOMAIN-SUFFIX,anthonycalzadilla.com,Proxy\nDOMAIN-SUFFIX,igg.biz,Proxy\nDOMAIN-SUFFIX,www.bhutannewsonline.com,Proxy\nDOMAIN-SUFFIX,avatrade.com,Proxy\nDOMAIN-SUFFIX,dogshotel.tw,Proxy\nDOMAIN-SUFFIX,en.jinzhao.wiki,Proxy\nDOMAIN-SUFFIX,ritter.vg,Proxy\nDOMAIN-SUFFIX,www.fxprocn.cn,Proxy\nDOMAIN-SUFFIX,google.com.br,Proxy\nDOMAIN-SUFFIX,great2choice.com,Proxy\nDOMAIN-SUFFIX,fantasyworld.idv.tw,Proxy\nDOMAIN-SUFFIX,goodtimesgaming.com,Proxy\nDOMAIN-SUFFIX,4612.yzc596.com,Proxy\nDOMAIN-SUFFIX,www.vriendenvantibet.be,Proxy\nDOMAIN-SUFFIX,drone-hacks.com,Proxy\nDOMAIN-SUFFIX,systrarna.com,Proxy\nDOMAIN-SUFFIX,lang.idv.tw,Proxy\nDOMAIN-SUFFIX,bulink.xyz,Proxy\nDOMAIN-SUFFIX,hkam2011.blogspot.hk,Proxy\nDOMAIN-SUFFIX,ee2694.com,Proxy\nDOMAIN-SUFFIX,apk.tv,Proxy\nDOMAIN-SUFFIX,efmoe.club,Proxy\nDOMAIN-SUFFIX,tvspielfilm.de,Proxy\nDOMAIN-SUFFIX,etherdream.github.io,Proxy\nDOMAIN-SUFFIX,iqlinkus.net,Proxy\nDOMAIN-SUFFIX,bamatheatre.com,Proxy\nDOMAIN-SUFFIX,blogspot.in,Proxy\nDOMAIN-SUFFIX,covid19.forget.eu.org,Proxy\nDOMAIN-SUFFIX,libgen.is,Proxy\nDOMAIN-SUFFIX,a69779.com,Proxy\nDOMAIN-SUFFIX,souseba2.icu,Proxy\nDOMAIN-SUFFIX,blogspot.pt,Proxy\nDOMAIN-SUFFIX,jigei.github.io,Proxy\nDOMAIN-SUFFIX,podcast.co,Proxy\nDOMAIN-SUFFIX,papers.ssrn.com,Proxy\nDOMAIN-SUFFIX,fpmta.org.au,Proxy\nDOMAIN-SUFFIX,cdn.cloud.zyxel.com,Proxy\nDOMAIN-SUFFIX,comments.app,Proxy\nDOMAIN-SUFFIX,kyacg.top,Proxy\nDOMAIN-SUFFIX,huijiadelu.com,Proxy\nDOMAIN-SUFFIX,d33uxjz28fpmpx.cloudfront.net,Proxy\nDOMAIN-SUFFIX,offmp3.com,Proxy\nDOMAIN-SUFFIX,images-ext-1.discordapp.net,Proxy\nDOMAIN-SUFFIX,bite.lt,Proxy\nDOMAIN-SUFFIX,91cname.com,Proxy\nDOMAIN-SUFFIX,service.kvbgc.com,Proxy\nDOMAIN-SUFFIX,rsz6ms.lotcai.com,Proxy\nDOMAIN-SUFFIX,www.kcai969.com,Proxy\nDOMAIN-SUFFIX,mapp-web.r88app05.com,Proxy\nDOMAIN-SUFFIX,www.agoradrugs.com,Proxy\nDOMAIN-SUFFIX,www.chinese-atfx.com,Proxy\nDOMAIN-SUFFIX,www.ming99.com,Proxy\nDOMAIN-SUFFIX,cyberctm.com,Proxy\nDOMAIN-SUFFIX,javmoo.com,Proxy\nDOMAIN-SUFFIX,nilgiris.nic.in,Proxy\nDOMAIN-SUFFIX,questvisual.com,Proxy\nDOMAIN-SUFFIX,weiboscope.jmsc.hku.hk,Proxy\nDOMAIN-SUFFIX,falundafa.ru,Proxy\nDOMAIN-SUFFIX,loft.omni7.jp,Proxy\nDOMAIN-SUFFIX,singaporepools.com.sg,Proxy\nDOMAIN-SUFFIX,cryptostorm.is,Proxy\nDOMAIN-SUFFIX,pornzone.net,Proxy\nDOMAIN-SUFFIX,falungong.se,Proxy\nDOMAIN-SUFFIX,kchr.org,Proxy\nDOMAIN-SUFFIX,livpn.com,Proxy\nDOMAIN-SUFFIX,www.pornhd.com,Proxy\nDOMAIN-SUFFIX,bell.ca,Proxy\nDOMAIN-SUFFIX,share.wordshare.in,Proxy\nDOMAIN-SUFFIX,9130.com,Proxy\nDOMAIN-SUFFIX,blog.yahoo.com,Proxy\nDOMAIN-SUFFIX,blogspot.com.ar,Proxy\nDOMAIN-SUFFIX,eventsair.com,Proxy\nDOMAIN-SUFFIX,avbebe.com,Proxy\nDOMAIN-SUFFIX,www.xxxymovies.com,Proxy\nDOMAIN-SUFFIX,xh75555.com,Proxy\nDOMAIN-SUFFIX,8969.org,Proxy\nDOMAIN-SUFFIX,direct.lc.chat,Proxy\nDOMAIN-SUFFIX,cdn.softlayer.net,Proxy\nDOMAIN-SUFFIX,20230817.v4speed.cc,Proxy\nDOMAIN-SUFFIX,sopcast.com,Proxy\nDOMAIN-SUFFIX,jb658.com,Proxy\nDOMAIN-SUFFIX,lovemov.cc,Proxy\nDOMAIN-SUFFIX,successfulpatience.com,Proxy\nDOMAIN-SUFFIX,troet.cafe,Proxy\nDOMAIN-SUFFIX,secretchina.com,Proxy\nDOMAIN-SUFFIX,thecoolquest.com,Proxy\nDOMAIN-SUFFIX,hkdvb.com,Proxy\nDOMAIN-SUFFIX,vpnfire.com,Proxy\nDOMAIN-SUFFIX,2.ns32.us,Proxy\nDOMAIN-SUFFIX,ftqss.com,Proxy\nDOMAIN-SUFFIX,voacantonese.com,Proxy\nDOMAIN-SUFFIX,g0v.social,Proxy\nDOMAIN-SUFFIX,goojara.ch,Proxy\nDOMAIN-SUFFIX,co.ng.mil,Proxy\nDOMAIN-SUFFIX,www.blogspot.ch,Proxy\nDOMAIN-SUFFIX,w3.now-ip.org,Proxy\nDOMAIN-SUFFIX,cleansolutions.mx,Proxy\nDOMAIN-SUFFIX,www.sunriver.com.tw,Proxy\nDOMAIN-SUFFIX,www.upnext.eu,Proxy\nDOMAIN-SUFFIX,www.bellesa.co,Proxy\nDOMAIN-SUFFIX,bbs.cdbook.org,Proxy\nDOMAIN-SUFFIX,pratikpatel.in,Proxy\nDOMAIN-SUFFIX,theprint.in,Proxy\nDOMAIN-SUFFIX,www.speeder.cf,Proxy\nDOMAIN-SUFFIX,www.newschinacomment.org,Proxy\nDOMAIN-SUFFIX,wolfgang.site40.net,Proxy\nDOMAIN-SUFFIX,blogspot.com,Proxy\nDOMAIN-SUFFIX,china.swissquote.com,Proxy\nDOMAIN-SUFFIX,pinkape.net,Proxy\nDOMAIN-SUFFIX,gf1238.com,Proxy\nDOMAIN-SUFFIX,chinese.chosun.com,Proxy\nDOMAIN-SUFFIX,watter.cc,Proxy\nDOMAIN-SUFFIX,dalailama.com,Proxy\nDOMAIN-SUFFIX,falix.de,Proxy\nDOMAIN-SUFFIX,portal.shadowsocks.nu,Proxy\nDOMAIN-SUFFIX,fareasternpotato.blogspot.ca,Proxy\nDOMAIN-SUFFIX,www.fun702.com,Proxy\nDOMAIN-SUFFIX,andrej.podzimek.org,Proxy\nDOMAIN-SUFFIX,av-opera.jp,Proxy\nDOMAIN-SUFFIX,www.taiwanlii.ccu.edu.tw,Proxy\nDOMAIN-SUFFIX,vpnsh.com,Proxy\nDOMAIN-SUFFIX,is.gd,Proxy\nDOMAIN-SUFFIX,manwa.biz,Proxy\nDOMAIN-SUFFIX,hhg.dubya.us,Proxy\nDOMAIN-SUFFIX,mohu.tw,Proxy\nDOMAIN-SUFFIX,www.memorydealers.com,Proxy\nDOMAIN-SUFFIX,layer7tech.com,Proxy\nDOMAIN-SUFFIX,hive.io,Proxy\nDOMAIN-SUFFIX,snappea.com,Proxy\nDOMAIN-SUFFIX,stat100.ameba.jp,Proxy\nDOMAIN-SUFFIX,teleplus.in,Proxy\nDOMAIN-SUFFIX,www.usresi.com,Proxy\nDOMAIN-SUFFIX,yh478.com,Proxy\nDOMAIN-SUFFIX,treasuresource.com,Proxy\nDOMAIN-SUFFIX,www.ggc-project.de,Proxy\nDOMAIN-SUFFIX,checkgfw.com,Proxy\nDOMAIN-SUFFIX,wl19www59.webland.ch,Proxy\nDOMAIN-SUFFIX,www.hide-my-ip.net,Proxy\nDOMAIN-SUFFIX,facebook.cn,Proxy\nDOMAIN-SUFFIX,google.fi,Proxy\nDOMAIN-SUFFIX,hao8tv.com,Proxy\nDOMAIN-SUFFIX,icad.ae.org,Proxy\nDOMAIN-SUFFIX,www.18onlygirls.com,Proxy\nDOMAIN-SUFFIX,www.ysgj.com.hk,Proxy\nDOMAIN-SUFFIX,sponsus.org,Proxy\nDOMAIN-SUFFIX,vpnai.com,Proxy\nDOMAIN-SUFFIX,350988q.net,Proxy\nDOMAIN-SUFFIX,www.vermont.org,Proxy\nDOMAIN-SUFFIX,evchk.wikia.com,Proxy\nDOMAIN-SUFFIX,ssr.shouyeren.net,Proxy\nDOMAIN-SUFFIX,fq-vpn.com,Proxy\nDOMAIN-SUFFIX,djnuntaoradea.ro,Proxy\nDOMAIN-SUFFIX,www.tibet.dk,Proxy\nDOMAIN-SUFFIX,xh9777.com,Proxy\nDOMAIN-SUFFIX,h2.slyip.net,Proxy\nDOMAIN-SUFFIX,gh.effers.com,Proxy\nDOMAIN-SUFFIX,jerryxiao.cc,Proxy\nDOMAIN-SUFFIX,www.chihchih.net,Proxy\nDOMAIN-SUFFIX,css22.gq,Proxy\nDOMAIN-SUFFIX,nicesextube.com,Proxy\nDOMAIN-SUFFIX,www.wilsoncenter.org,Proxy\nDOMAIN-SUFFIX,dziama.com,Proxy\nDOMAIN-SUFFIX,wionnews.com,Proxy\nDOMAIN-SUFFIX,7874c.com,Proxy\nDOMAIN-SUFFIX,tibetanwomen.org,Proxy\nDOMAIN-SUFFIX,virtual-browser.com,Proxy\nDOMAIN-SUFFIX,freeproxy.ca,Proxy\nDOMAIN-SUFFIX,david-kilgour.com,Proxy\nDOMAIN-SUFFIX,nu.com,Proxy\nDOMAIN-SUFFIX,nvdst.com,Proxy\nDOMAIN-SUFFIX,standwithhk.org,Proxy\nDOMAIN-SUFFIX,bangumi.tv,Proxy\nDOMAIN-SUFFIX,ag.6061.vip,Proxy\nDOMAIN-SUFFIX,w2.68668.com,Proxy\nDOMAIN-SUFFIX,etherdelta.com,Proxy\nDOMAIN-SUFFIX,upornia.com,Proxy\nDOMAIN-SUFFIX,eurytus.feralhosting.com,Proxy\nDOMAIN-SUFFIX,powerfulinfographic.com,Proxy\nDOMAIN-SUFFIX,findl.com,Proxy\nDOMAIN-SUFFIX,panampost.com,Proxy\nDOMAIN-SUFFIX,shattered.io,Proxy\nDOMAIN-SUFFIX,falun.nl,Proxy\nDOMAIN-SUFFIX,www.usasialaw.org,Proxy\nDOMAIN-SUFFIX,dangerousdongs.com,Proxy\nDOMAIN-SUFFIX,waveprotocol.org,Proxy\nDOMAIN-SUFFIX,www.fx77.com,Proxy\nDOMAIN-SUFFIX,ddns.net,Proxy\nDOMAIN-SUFFIX,bbs.brockbbs.com,Proxy\nDOMAIN-SUFFIX,royal865.com,Proxy\nDOMAIN-SUFFIX,avmo.pw,Proxy\nDOMAIN-SUFFIX,h5.ldsports20.bet,Proxy\nDOMAIN-SUFFIX,www.langest.org,Proxy\nDOMAIN-SUFFIX,ritouki.jp,Proxy\nDOMAIN-SUFFIX,zshyjr.com,Proxy\nDOMAIN-SUFFIX,www.badiucao.com,Proxy\nDOMAIN-SUFFIX,www.softonic.cn,Proxy\nDOMAIN-SUFFIX,www.wesley.wa.edu.au,Proxy\nDOMAIN-SUFFIX,d5ux7398801j0.cloudfront.net,Proxy\nDOMAIN-SUFFIX,tv101.tk,Proxy\nDOMAIN-SUFFIX,nqvpn.com,Proxy\nDOMAIN-SUFFIX,mediageniuses.com,Proxy\nDOMAIN-SUFFIX,cam4.com,Proxy\nDOMAIN-SUFFIX,thetibetconnection.org,Proxy\nDOMAIN-SUFFIX,990808.com,Proxy\nDOMAIN-SUFFIX,www.hrblock.com,Proxy\nDOMAIN-SUFFIX,opml.radiotime.com,Proxy\nDOMAIN-SUFFIX,jelita-reload.com,Proxy\nDOMAIN-SUFFIX,manhuagui.com,Proxy\nDOMAIN-SUFFIX,pierot.pl,Proxy\nDOMAIN-SUFFIX,www.dmmbus.cam,Proxy\nDOMAIN-SUFFIX,megaproxy.com,Proxy\nDOMAIN-SUFFIX,mediapermata.com.bn,Proxy\nDOMAIN-SUFFIX,actualitte.com,Proxy\nDOMAIN-SUFFIX,www.obrismorgan.com,Proxy\nDOMAIN-SUFFIX,byb90.app,Proxy\nDOMAIN-SUFFIX,www.betvictor98.com,Proxy\nDOMAIN-SUFFIX,nownews.com,Proxy\nDOMAIN-SUFFIX,reddawn.co.nz,Proxy\nDOMAIN-SUFFIX,ratspots.com,Proxy\nDOMAIN-SUFFIX,hg7078.com,Proxy\nDOMAIN-SUFFIX,ua1lib.org,Proxy\nDOMAIN-SUFFIX,qbvip7.com,Proxy\nDOMAIN-SUFFIX,yzc262.com,Proxy\nDOMAIN-SUFFIX,ahri.xyz,Proxy\nDOMAIN-SUFFIX,ampj60.com,Proxy\nDOMAIN-SUFFIX,baiyun.net,Proxy\nDOMAIN-SUFFIX,8sjp03.link,Proxy\nDOMAIN-SUFFIX,pmatteoricci.it,Proxy\nDOMAIN-SUFFIX,istiqlalhewer.com,Proxy\nDOMAIN-SUFFIX,xlfmguanyin.com,Proxy\nDOMAIN-SUFFIX,aboluowang.com,Proxy\nDOMAIN-SUFFIX,www.cafepress.com,Proxy\nDOMAIN-SUFFIX,noblecasino.com,Proxy\nDOMAIN-SUFFIX,22411119.com,Proxy\nDOMAIN-SUFFIX,www.xvconsult.com,Proxy\nDOMAIN-SUFFIX,35jiasu.xyz,Proxy\nDOMAIN-SUFFIX,manhuabika.com,Proxy\nDOMAIN-SUFFIX,www.shyhjg.com,Proxy\nDOMAIN-SUFFIX,chatrubate.com,Proxy\nDOMAIN-SUFFIX,deeper.com,Proxy\nDOMAIN-SUFFIX,www2.bestjavporn.com,Proxy\nDOMAIN-SUFFIX,dynamic-dns.net,Proxy\nDOMAIN-SUFFIX,www.limetorrents.cc,Proxy\nDOMAIN-SUFFIX,apartmentratings.com,Proxy\nDOMAIN-SUFFIX,fullerconsideration.com,Proxy\nDOMAIN-SUFFIX,cn.goeuro.com,Proxy\nDOMAIN-SUFFIX,www.88866.cc,Proxy\nDOMAIN-SUFFIX,www.google.com.qa,Proxy\nDOMAIN-SUFFIX,youtube.pl,Proxy\nDOMAIN-SUFFIX,trtworld.com,Proxy\nDOMAIN-SUFFIX,konnectuci.wixsite.com,Proxy\nDOMAIN-SUFFIX,www.metrodate.com,Proxy\nDOMAIN-SUFFIX,fujikong.com,Proxy\nDOMAIN-SUFFIX,www.mpfive.com,Proxy\nDOMAIN-SUFFIX,hqjapanesesex.com,Proxy\nDOMAIN-SUFFIX,www.bongolearn.com,Proxy\nDOMAIN-SUFFIX,tronscan.org,Proxy\nDOMAIN-SUFFIX,skyzip.de,Proxy\nDOMAIN-SUFFIX,wiredbytes.com,Proxy\nDOMAIN-SUFFIX,www.turboimagehost.com,Proxy\nDOMAIN-SUFFIX,www.solidfiles.com,Proxy\nDOMAIN-SUFFIX,mandev.rfaweb.org,Proxy\nDOMAIN-SUFFIX,priv08.com,Proxy\nDOMAIN-SUFFIX,tenzinpalmo.com,Proxy\nDOMAIN-SUFFIX,xvideo.com,Proxy\nDOMAIN-SUFFIX,raw.githubusercontent.com,Proxy\nDOMAIN-SUFFIX,www.navarra.es,Proxy\nDOMAIN-SUFFIX,axashop.ro,Proxy\nDOMAIN-SUFFIX,d3r45cet3usdyi.cloudfront.net,Proxy\nDOMAIN-SUFFIX,houxu.app,Proxy\nDOMAIN-SUFFIX,www.520nh.net,Proxy\nDOMAIN-SUFFIX,qltx.live,Proxy\nDOMAIN-SUFFIX,www.swaneye.com,Proxy\nDOMAIN-SUFFIX,drand.love,Proxy\nDOMAIN-SUFFIX,ok1188.net,Proxy\nDOMAIN-SUFFIX,mediafactory.jp,Proxy\nDOMAIN-SUFFIX,pwned.com,Proxy\nDOMAIN-SUFFIX,www.netflav.com,Proxy\nDOMAIN-SUFFIX,zdf.de,Proxy\nDOMAIN-SUFFIX,www.ironfx.cn,Proxy\nDOMAIN-SUFFIX,prozz.net,Proxy\nDOMAIN-SUFFIX,ipfs.tech,Proxy\nDOMAIN-SUFFIX,wbur.com,Proxy\nDOMAIN-SUFFIX,www.newhana.com,Proxy\nDOMAIN-SUFFIX,youtube-to-mp3.org,Proxy\nDOMAIN-SUFFIX,vpnmaster.com,Proxy\nDOMAIN-SUFFIX,vw.mangaz.com,Proxy\nDOMAIN-SUFFIX,10010388.com,Proxy\nDOMAIN-SUFFIX,www.btsmth.com,Proxy\nDOMAIN-SUFFIX,2023cp4.com,Proxy\nDOMAIN-SUFFIX,hutong9.net,Proxy\nDOMAIN-SUFFIX,familyfed.org,Proxy\nDOMAIN-SUFFIX,schalk.com.br,Proxy\nDOMAIN-SUFFIX,www.vpngratis.net,Proxy\nDOMAIN-SUFFIX,bi-si8.xyz,Proxy\nDOMAIN-SUFFIX,qbittorrent.org,Proxy\nDOMAIN-SUFFIX,kuaishangche.link,Proxy\nDOMAIN-SUFFIX,studybuddhism.com,Proxy\nDOMAIN-SUFFIX,vpnprivacy.com,Proxy\nDOMAIN-SUFFIX,c24.privatedns.org,Proxy\nDOMAIN-SUFFIX,mobileaction.co,Proxy\nDOMAIN-SUFFIX,google.dj,Proxy\nDOMAIN-SUFFIX,www.agriculture.com,Proxy\nDOMAIN-SUFFIX,malaysia.yahoo.com,Proxy\nDOMAIN-SUFFIX,www.rubixfx.com,Proxy\nDOMAIN-SUFFIX,twitonmsn.com,Proxy\nDOMAIN-SUFFIX,www.888cff.com,Proxy\nDOMAIN-SUFFIX,coobay.com,Proxy\nDOMAIN-SUFFIX,domftrcwqk9w3.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.proxeasy.com,Proxy\nDOMAIN-SUFFIX,bookzz.ren,Proxy\nDOMAIN-SUFFIX,jm-comic.club,Proxy\nDOMAIN-SUFFIX,vinacf.com,Proxy\nDOMAIN-SUFFIX,www.ry1002.com,Proxy\nDOMAIN-SUFFIX,www.fhjtzh.com,Proxy\nDOMAIN-SUFFIX,icpc-chinesepen.org,Proxy\nDOMAIN-SUFFIX,lobo826.homeip.net,Proxy\nDOMAIN-SUFFIX,cdbaby.com,Proxy\nDOMAIN-SUFFIX,javdb007.com,Proxy\nDOMAIN-SUFFIX,tibet.a.se,Proxy\nDOMAIN-SUFFIX,bet365.com.pe,Proxy\nDOMAIN-SUFFIX,bloombergtradebook.com,Proxy\nDOMAIN-SUFFIX,a679.com,Proxy\nDOMAIN-SUFFIX,www.qafone.co,Proxy\nDOMAIN-SUFFIX,insightly.com,Proxy\nDOMAIN-SUFFIX,matrixteens.com,Proxy\nDOMAIN-SUFFIX,dd57625.9cash.net,Proxy\nDOMAIN-SUFFIX,www.bjdl6988.com,Proxy\nDOMAIN-SUFFIX,iconpaper.org,Proxy\nDOMAIN-SUFFIX,www.mxvpn.cc,Proxy\nDOMAIN-SUFFIX,inxian.com,Proxy\nDOMAIN-SUFFIX,w1713.com,Proxy\nDOMAIN-SUFFIX,asherknibbe.com,Proxy\nDOMAIN-SUFFIX,streamate.com,Proxy\nDOMAIN-SUFFIX,www.yes.xxx,Proxy\nDOMAIN-SUFFIX,bittorrent.org,Proxy\nDOMAIN-SUFFIX,miroguide.com,Proxy\nDOMAIN-SUFFIX,gvlib.com,Proxy\nDOMAIN-SUFFIX,www.youporn.bz,Proxy\nDOMAIN-SUFFIX,effies.com,Proxy\nDOMAIN-SUFFIX,google1.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,huiyi.in,Proxy\nDOMAIN-SUFFIX,image1.fmgstatic.com,Proxy\nDOMAIN-SUFFIX,51xtv.net,Proxy\nDOMAIN-SUFFIX,mail.vcu.edu,Proxy\nDOMAIN-SUFFIX,ioxoxi.club,Proxy\nDOMAIN-SUFFIX,21sextury.com,Proxy\nDOMAIN-SUFFIX,888rch.co,Proxy\nDOMAIN-SUFFIX,www.triquanta.nl,Proxy\nDOMAIN-SUFFIX,falundafanorge.com,Proxy\nDOMAIN-SUFFIX,meltdownintibet.com,Proxy\nDOMAIN-SUFFIX,freebrowser.app,Proxy\nDOMAIN-SUFFIX,www.19fortyfive.com,Proxy\nDOMAIN-SUFFIX,starfishfx.com,Proxy\nDOMAIN-SUFFIX,homemoviestube.com,Proxy\nDOMAIN-SUFFIX,www.vg008.com,Proxy\nDOMAIN-SUFFIX,www.google.bi,Proxy\nDOMAIN-SUFFIX,www.lanyustar.idv.tw,Proxy\nDOMAIN-SUFFIX,www.turnitinuk.com,Proxy\nDOMAIN-SUFFIX,www.daigoji.or.jp,Proxy\nDOMAIN-SUFFIX,8587n.cc,Proxy\nDOMAIN-SUFFIX,www.fakku.net,Proxy\nDOMAIN-SUFFIX,huayuworld.org,Proxy\nDOMAIN-SUFFIX,bsdrp.net,Proxy\nDOMAIN-SUFFIX,www.ilovegrow.com,Proxy\nDOMAIN-SUFFIX,www.injil.net,Proxy\nDOMAIN-SUFFIX,grahamreaper.com,Proxy\nDOMAIN-SUFFIX,google.at,Proxy\nDOMAIN-SUFFIX,d-copy.blogspot.hk,Proxy\nDOMAIN-SUFFIX,d2uzsrnmmf6tds.cloudfront.net,Proxy\nDOMAIN-SUFFIX,a6ksr8.syhwyh.com,Proxy\nDOMAIN-SUFFIX,www.foilchat.com,Proxy\nDOMAIN-SUFFIX,shodanhq.com,Proxy\nDOMAIN-SUFFIX,www.chinesespanking.com,Proxy\nDOMAIN-SUFFIX,circleofmoms.com,Proxy\nDOMAIN-SUFFIX,coinone.co.kr,Proxy\nDOMAIN-SUFFIX,site-836743-9773-4081.strikingly.com,Proxy\nDOMAIN-SUFFIX,acebook.com,Proxy\nDOMAIN-SUFFIX,glassass.com,Proxy\nDOMAIN-SUFFIX,blogger.com,Proxy\nDOMAIN-SUFFIX,securitales.com,Proxy\nDOMAIN-SUFFIX,truth-out.org,Proxy\nDOMAIN-SUFFIX,patriciaivanconnections.blogspot.ca,Proxy\nDOMAIN-SUFFIX,www.haitbook.com,Proxy\nDOMAIN-SUFFIX,switchvpn.net,Proxy\nDOMAIN-SUFFIX,twit2d.com,Proxy\nDOMAIN-SUFFIX,www.idealis.nl,Proxy\nDOMAIN-SUFFIX,media.org.hk,Proxy\nDOMAIN-SUFFIX,backtotiananmen.com,Proxy\nDOMAIN-SUFFIX,nyaa.eu,Proxy\nDOMAIN-SUFFIX,mywall.us,Proxy\nDOMAIN-SUFFIX,project-gutenberg.github.io,Proxy\nDOMAIN-SUFFIX,hudson.org,Proxy\nDOMAIN-SUFFIX,show-live.tw,Proxy\nDOMAIN-SUFFIX,svsfx.com,Proxy\nDOMAIN-SUFFIX,hh.hjort.nu,Proxy\nDOMAIN-SUFFIX,nuan9.dynssl.com,Proxy\nDOMAIN-SUFFIX,75811.com,Proxy\nDOMAIN-SUFFIX,google.to,Proxy\nDOMAIN-SUFFIX,kkp.org.hk,Proxy\nDOMAIN-SUFFIX,3ssee.com,Proxy\nDOMAIN-SUFFIX,wqw2010.blogspot.hk,Proxy\nDOMAIN-SUFFIX,kvbprime.me,Proxy\nDOMAIN-SUFFIX,bitflyer.com,Proxy\nDOMAIN-SUFFIX,bl3p.eu,Proxy\nDOMAIN-SUFFIX,metamask.io,Proxy\nDOMAIN-SUFFIX,mt0.google.cn,Proxy\nDOMAIN-SUFFIX,walls.io,Proxy\nDOMAIN-SUFFIX,barbie.com,Proxy\nDOMAIN-SUFFIX,hd.stheadline.com,Proxy\nDOMAIN-SUFFIX,www.3011a3011.com,Proxy\nDOMAIN-SUFFIX,umcconnections.org,Proxy\nDOMAIN-SUFFIX,96t888.com,Proxy\nDOMAIN-SUFFIX,iguge.club,Proxy\nDOMAIN-SUFFIX,d2ujbgixmqypkk.cloudfront.net,Proxy\nDOMAIN-SUFFIX,tibethouse.us,Proxy\nDOMAIN-SUFFIX,efukt.com,Proxy\nDOMAIN-SUFFIX,tv222.tk,Proxy\nDOMAIN-SUFFIX,mauricioestrella.com,Proxy\nDOMAIN-SUFFIX,kxsw.life,Proxy\nDOMAIN-SUFFIX,wjy002.jigsy.com,Proxy\nDOMAIN-SUFFIX,igeekai.com,Proxy\nDOMAIN-SUFFIX,en.hao123.com,Proxy\nDOMAIN-SUFFIX,woop.io,Proxy\nDOMAIN-SUFFIX,blog.kengao.tw,Proxy\nDOMAIN-SUFFIX,beaumontmusic.com,Proxy\nDOMAIN-SUFFIX,wacca.yuangezhizao.cn,Proxy\nDOMAIN-SUFFIX,life.tw,Proxy\nDOMAIN-SUFFIX,www.4hu60.com,Proxy\nDOMAIN-SUFFIX,ye168-www.c0505.com,Proxy\nDOMAIN-SUFFIX,d3g5xn5mtes6dj.cloudfront.net,Proxy\nDOMAIN-SUFFIX,erodoujinlog.com,Proxy\nDOMAIN-SUFFIX,digi.net,Proxy\nDOMAIN-SUFFIX,julienpineault.blogspot.ca,Proxy\nDOMAIN-SUFFIX,mpinews.com,Proxy\nDOMAIN-SUFFIX,gm9999.cc,Proxy\nDOMAIN-SUFFIX,atgfw.org,Proxy\nDOMAIN-SUFFIX,lcx.cc,Proxy\nDOMAIN-SUFFIX,findjiayi.jigsy.com,Proxy\nDOMAIN-SUFFIX,assente.vega9.com,Proxy\nDOMAIN-SUFFIX,vpn-pay.itshidden.com,Proxy\nDOMAIN-SUFFIX,pornhub.org,Proxy\nDOMAIN-SUFFIX,www.miel-soft.com,Proxy\nDOMAIN-SUFFIX,taiwan-sex.com,Proxy\nDOMAIN-SUFFIX,almasdarnews.com,Proxy\nDOMAIN-SUFFIX,chat-ai.logcg.com,Proxy\nDOMAIN-SUFFIX,d3h17ayt96lii4.cloudfront.net,Proxy\nDOMAIN-SUFFIX,my.tranzact.com,Proxy\nDOMAIN-SUFFIX,dj5758.com,Proxy\nDOMAIN-SUFFIX,javcn.net,Proxy\nDOMAIN-SUFFIX,blog.x188.cn,Proxy\nDOMAIN-SUFFIX,www.toho-shoten.co.jp,Proxy\nDOMAIN-SUFFIX,webevader.com,Proxy\nDOMAIN-SUFFIX,zhangboli.net,Proxy\nDOMAIN-SUFFIX,utopianpal.com,Proxy\nDOMAIN-SUFFIX,bp8nyohd6k.com,Proxy\nDOMAIN-SUFFIX,www.asianlawcaucus.org,Proxy\nDOMAIN-SUFFIX,from.io,Proxy\nDOMAIN-SUFFIX,mrcat123.com,Proxy\nDOMAIN-SUFFIX,www.9458win.com,Proxy\nDOMAIN-SUFFIX,www.jav008.com,Proxy\nDOMAIN-SUFFIX,wingy.site,Proxy\nDOMAIN-SUFFIX,hitomi.la,Proxy\nDOMAIN-SUFFIX,hacg.red,Proxy\nDOMAIN-SUFFIX,fantasycraft.com,Proxy\nDOMAIN-SUFFIX,dfn.de,Proxy\nDOMAIN-SUFFIX,gaymenring.com,Proxy\nDOMAIN-SUFFIX,dontbubble.us,Proxy\nDOMAIN-SUFFIX,impulsoti.com,Proxy\nDOMAIN-SUFFIX,rhathd.club,Proxy\nDOMAIN-SUFFIX,www.thehindu.com,Proxy\nDOMAIN-SUFFIX,superfastdatanet.com,Proxy\nDOMAIN-SUFFIX,youngfatties.com,Proxy\nDOMAIN-SUFFIX,naiyouu.com,Proxy\nDOMAIN-SUFFIX,lhakardiaries.com,Proxy\nDOMAIN-SUFFIX,free-hada-now.org,Proxy\nDOMAIN-SUFFIX,is-a-cpa.com,Proxy\nDOMAIN-SUFFIX,hacg.wiki,Proxy\nDOMAIN-SUFFIX,ggssl.com,Proxy\nDOMAIN-SUFFIX,10musume.com,Proxy\nDOMAIN-SUFFIX,ca6033.com,Proxy\nDOMAIN-SUFFIX,its.caltech.edu,Proxy\nDOMAIN-SUFFIX,e8803.com,Proxy\nDOMAIN-SUFFIX,school.studioweb.com,Proxy\nDOMAIN-SUFFIX,www.zuihulu.net,Proxy\nDOMAIN-SUFFIX,www.kwokwahtyre.com,Proxy\nDOMAIN-SUFFIX,s3.eu-central-1.amazonaws.com,Proxy\nDOMAIN-SUFFIX,cosmic.monar.ch,Proxy\nDOMAIN-SUFFIX,www.tubeprox.com,Proxy\nDOMAIN-SUFFIX,w3schools.com,Proxy\nDOMAIN-SUFFIX,cgn-sa.cl,Proxy\nDOMAIN-SUFFIX,www.anonyproz.com,Proxy\nDOMAIN-SUFFIX,www.sakingdom.com,Proxy\nDOMAIN-SUFFIX,maketecheasier.com,Proxy\nDOMAIN-SUFFIX,boettiger.cl,Proxy\nDOMAIN-SUFFIX,gmail.babson.edu,Proxy\nDOMAIN-SUFFIX,hidefporn.ws,Proxy\nDOMAIN-SUFFIX,adultfriendfinder.com,Proxy\nDOMAIN-SUFFIX,spideroak.com,Proxy\nDOMAIN-SUFFIX,piratestreaming.net,Proxy\nDOMAIN-SUFFIX,www.newszealand.blogspot.hk,Proxy\nDOMAIN-SUFFIX,freexhamster.com,Proxy\nDOMAIN-SUFFIX,betboy.cc,Proxy\nDOMAIN-SUFFIX,kurinjikathambam.com,Proxy\nDOMAIN-SUFFIX,myftp.info,Proxy\nDOMAIN-SUFFIX,hk01.com,Proxy\nDOMAIN-SUFFIX,politicalcompass.org,Proxy\nDOMAIN-SUFFIX,fdlsies.gotgeeks.com,Proxy\nDOMAIN-SUFFIX,friendfeed.com,Proxy\nDOMAIN-SUFFIX,www.dhakatribune.com,Proxy\nDOMAIN-SUFFIX,gzone-anime.info,Proxy\nDOMAIN-SUFFIX,citrahalal.co.id,Proxy\nDOMAIN-SUFFIX,uk.serveuser.com,Proxy\nDOMAIN-SUFFIX,xsz-av.com,Proxy\nDOMAIN-SUFFIX,shadowsocks.com.au,Proxy\nDOMAIN-SUFFIX,www.opengg.cn,Proxy\nDOMAIN-SUFFIX,altrec.com,Proxy\nDOMAIN-SUFFIX,lifesitenews.com,Proxy\nDOMAIN-SUFFIX,funp.com,Proxy\nDOMAIN-SUFFIX,www.vpning.com,Proxy\nDOMAIN-SUFFIX,ultrasurf.us,Proxy\nDOMAIN-SUFFIX,chinacath.org,Proxy\nDOMAIN-SUFFIX,dcva.dovercorp.com,Proxy\nDOMAIN-SUFFIX,moefuns.com,Proxy\nDOMAIN-SUFFIX,healthitnews.xyz,Proxy\nDOMAIN-SUFFIX,uhrp.org,Proxy\nDOMAIN-SUFFIX,2017.hk,Proxy\nDOMAIN-SUFFIX,sowers.org.hk,Proxy\nDOMAIN-SUFFIX,globalvoices.org,Proxy\nDOMAIN-SUFFIX,fw.288ysb.com,Proxy\nDOMAIN-SUFFIX,ibra.uk,Proxy\nDOMAIN-SUFFIX,www.pixnet.jp,Proxy\nDOMAIN-SUFFIX,vpnsp.com,Proxy\nDOMAIN-SUFFIX,pxvpn.com,Proxy\nDOMAIN-SUFFIX,www.inspiredminds.de,Proxy\nDOMAIN-SUFFIX,b586.com,Proxy\nDOMAIN-SUFFIX,www.handelsblatt.de,Proxy\nDOMAIN-SUFFIX,jb.wojb.org,Proxy\nDOMAIN-SUFFIX,im.tv,Proxy\nDOMAIN-SUFFIX,www.nettv.live,Proxy\nDOMAIN-SUFFIX,www.benzishe.net,Proxy\nDOMAIN-SUFFIX,gj6699.com,Proxy\nDOMAIN-SUFFIX,invidious.tube,Proxy\nDOMAIN-SUFFIX,vidaprimaria.cl,Proxy\nDOMAIN-SUFFIX,nzlife.nz,Proxy\nDOMAIN-SUFFIX,3094124.com,Proxy\nDOMAIN-SUFFIX,sd.freepac.pw,Proxy\nDOMAIN-SUFFIX,www.zgzy037.eu.org,Proxy\nDOMAIN-SUFFIX,nytimes-se.com,Proxy\nDOMAIN-SUFFIX,hdd.biz.st,Proxy\nDOMAIN-SUFFIX,bookinh.com.br,Proxy\nDOMAIN-SUFFIX,gude.co,Proxy\nDOMAIN-SUFFIX,doh-ch.blahdns.com,Proxy\nDOMAIN-SUFFIX,my.pcloud.com,Proxy\nDOMAIN-SUFFIX,rsf.org,Proxy\nDOMAIN-SUFFIX,www.crn.ngo,Proxy\nDOMAIN-SUFFIX,frdelaw.com,Proxy\nDOMAIN-SUFFIX,www.zdfsport.de,Proxy\nDOMAIN-SUFFIX,nurgo-software.com,Proxy\nDOMAIN-SUFFIX,yuesao369.com,Proxy\nDOMAIN-SUFFIX,search.sethforprivacy.com,Proxy\nDOMAIN-SUFFIX,umich.edu,Proxy\nDOMAIN-SUFFIX,nusatrip.com,Proxy\nDOMAIN-SUFFIX,share666.com,Proxy\nDOMAIN-SUFFIX,jsdaodu.over-blog.com,Proxy\nDOMAIN-SUFFIX,hebdo.ch,Proxy\nDOMAIN-SUFFIX,abcdka.com,Proxy\nDOMAIN-SUFFIX,incibe.es,Proxy\nDOMAIN-SUFFIX,ycon-api.line-apps.com,Proxy\nDOMAIN-SUFFIX,wikivoyage.com,Proxy\nDOMAIN-SUFFIX,whh.suroot.com,Proxy\nDOMAIN-SUFFIX,goedit.boxun.com,Proxy\nDOMAIN-SUFFIX,missfuli.com,Proxy\nDOMAIN-SUFFIX,ntq.comlu.com,Proxy\nDOMAIN-SUFFIX,e-hental.org,Proxy\nDOMAIN-SUFFIX,sosom.mynetav.org,Proxy\nDOMAIN-SUFFIX,guanyincitta.com,Proxy\nDOMAIN-SUFFIX,federacionpah.cl,Proxy\nDOMAIN-SUFFIX,gizlen.net,Proxy\nDOMAIN-SUFFIX,mehide.org,Proxy\nDOMAIN-SUFFIX,ebook.hyread.com.tw,Proxy\nDOMAIN-SUFFIX,nvquan.org,Proxy\nDOMAIN-SUFFIX,hjd2048.com,Proxy\nDOMAIN-SUFFIX,thepolicy.us,Proxy\nDOMAIN-SUFFIX,gifree.com,Proxy\nDOMAIN-SUFFIX,casey.nyc,Proxy\nDOMAIN-SUFFIX,prettyvirgin.com,Proxy\nDOMAIN-SUFFIX,h5.ld2069.cc,Proxy\nDOMAIN-SUFFIX,teamskeet.com,Proxy\nDOMAIN-SUFFIX,c100tibet.org,Proxy\nDOMAIN-SUFFIX,ocics.tw,Proxy\nDOMAIN-SUFFIX,www.rights-practice.org,Proxy\nDOMAIN-SUFFIX,d3dsacqprgcsqh.cloudfront.net,Proxy\nDOMAIN-SUFFIX,vs8989.com,Proxy\nDOMAIN-SUFFIX,dasheguoji.org,Proxy\nDOMAIN-SUFFIX,cynscribe.com,Proxy\nDOMAIN-SUFFIX,www.simma.nu,Proxy\nDOMAIN-SUFFIX,www.hoplite.cn,Proxy\nDOMAIN-SUFFIX,le2222.com,Proxy\nDOMAIN-SUFFIX,mvpn.pro,Proxy\nDOMAIN-SUFFIX,hj0056.com,Proxy\nDOMAIN-SUFFIX,souseba3.icu,Proxy\nDOMAIN-SUFFIX,fr2135.com,Proxy\nDOMAIN-SUFFIX,gootman.ca,Proxy\nDOMAIN-SUFFIX,bansheerocks.com,Proxy\nDOMAIN-SUFFIX,www.tthdd.com,Proxy\nDOMAIN-SUFFIX,maa1810.com,Proxy\nDOMAIN-SUFFIX,2049bbs.xyz,Proxy\nDOMAIN-SUFFIX,silverbay.ca,Proxy\nDOMAIN-SUFFIX,bd790.com,Proxy\nDOMAIN-SUFFIX,mail.kohako.com,Proxy\nDOMAIN-SUFFIX,kkutu.co.kr,Proxy\nDOMAIN-SUFFIX,freessr.ml,Proxy\nDOMAIN-SUFFIX,service-dispatcher.cloud.zyxel.com,Proxy\nDOMAIN-SUFFIX,tw.gigacircle.com,Proxy\nDOMAIN-SUFFIX,baileypaving.com,Proxy\nDOMAIN-SUFFIX,sextvx.com,Proxy\nDOMAIN-SUFFIX,jbex.cc,Proxy\nDOMAIN-SUFFIX,sg.privateinternetaccess.net,Proxy\nDOMAIN-SUFFIX,www.vpn100.xyz,Proxy\nDOMAIN-SUFFIX,xo77.com,Proxy\nDOMAIN-SUFFIX,admin.recaptcha.net,Proxy\nDOMAIN-SUFFIX,auth0.openai.com,Proxy\nDOMAIN-SUFFIX,tbjyt.org,Proxy\nDOMAIN-SUFFIX,orzistic.org,Proxy\nDOMAIN-SUFFIX,www.townandcountrymagazine.com.au,Proxy\nDOMAIN-SUFFIX,vpncup.com,Proxy\nDOMAIN-SUFFIX,gokbayrak.com,Proxy\nDOMAIN-SUFFIX,eisbb.com,Proxy\nDOMAIN-SUFFIX,g.co,Proxy\nDOMAIN-KEYWORD,prisoner-state-secret-journal-premier,Proxy\nDOMAIN-SUFFIX,onyoutube.com,Proxy\nDOMAIN-SUFFIX,bigpictures.ch,Proxy\nDOMAIN-SUFFIX,porn-db.com,Proxy\nDOMAIN-SUFFIX,yule.hk,Proxy\nDOMAIN-SUFFIX,play.pl,Proxy\nDOMAIN-SUFFIX,aeistar.com,Proxy\nDOMAIN-SUFFIX,chat.geekr.dev,Proxy\nDOMAIN-SUFFIX,islamawareness.net,Proxy\nDOMAIN-SUFFIX,wiki2.org,Proxy\nDOMAIN-SUFFIX,623.gotgeeks.com,Proxy\nDOMAIN-SUFFIX,69hbook.com,Proxy\nDOMAIN-SUFFIX,chinalawandpolicy.com,Proxy\nDOMAIN-SUFFIX,www.highspeedvpn.com,Proxy\nDOMAIN-SUFFIX,www.vxrl.org,Proxy\nDOMAIN-SUFFIX,hottystop.com,Proxy\nDOMAIN-SUFFIX,proxysite.com,Proxy\nDOMAIN-SUFFIX,www.my285.com,Proxy\nDOMAIN-SUFFIX,tucao.tv,Proxy\nDOMAIN-SUFFIX,64000sc.com,Proxy\nDOMAIN-SUFFIX,mmm-office.com,Proxy\nDOMAIN-SUFFIX,proxy.zalmos.com,Proxy\nDOMAIN-SUFFIX,xiaomi.eu,Proxy\nDOMAIN-SUFFIX,obe.rs,Proxy\nDOMAIN-SUFFIX,www.epochtimes.cn,Proxy\nDOMAIN-SUFFIX,zerohedge.com,Proxy\nDOMAIN-SUFFIX,video.ap.org,Proxy\nDOMAIN-SUFFIX,ruby.com,Proxy\nDOMAIN-SUFFIX,zedporn.com,Proxy\nDOMAIN-SUFFIX,solidaritetibet.org,Proxy\nDOMAIN-SUFFIX,a3678.com,Proxy\nDOMAIN-SUFFIX,udn.com,Proxy\nDOMAIN-SUFFIX,888.xcw00.com,Proxy\nDOMAIN-SUFFIX,www.mystrongvpn.org,Proxy\nDOMAIN-SUFFIX,scontent.cdninstagram.com,Proxy\nDOMAIN-SUFFIX,odysee.com,Proxy\nDOMAIN-SUFFIX,trainenquiry.com,Proxy\nDOMAIN-SUFFIX,hg141.com,Proxy\nDOMAIN-SUFFIX,www.sipiapa.org,Proxy\nDOMAIN-SUFFIX,invidious.sethforprivacy.com,Proxy\nDOMAIN-SUFFIX,www.imonss.com,Proxy\nDOMAIN-SUFFIX,s3-eu-central-1.amazonaws.com,Proxy\nDOMAIN-SUFFIX,www.intelligenceonline.com,Proxy\nDOMAIN-SUFFIX,linkmetube.com,Proxy\nDOMAIN-SUFFIX,www.mikuclub.org,Proxy\nDOMAIN-SUFFIX,www.eaintl.com,Proxy\nDOMAIN-SUFFIX,gonzoxxxmovies.com,Proxy\nDOMAIN-SUFFIX,leddit.xyz,Proxy\nDOMAIN-SUFFIX,stpaulsholyoke.org,Proxy\nDOMAIN-SUFFIX,ssr.tips,Proxy\nDOMAIN-SUFFIX,onmypc.org,Proxy\nDOMAIN-SUFFIX,www.hooball.com,Proxy\nDOMAIN-SUFFIX,yiamuc.com,Proxy\nDOMAIN-SUFFIX,1563666.com,Proxy\nDOMAIN-SUFFIX,www.freedur.com,Proxy\nDOMAIN-SUFFIX,www.64memo.org,Proxy\nDOMAIN-SUFFIX,lifechanyuan.org,Proxy\nDOMAIN-SUFFIX,8587t.cc,Proxy\nDOMAIN-SUFFIX,us-central1-show-user-extension-ebs.cloudfunctions.net,Proxy\nDOMAIN-SUFFIX,sexidude.com,Proxy\nDOMAIN-SUFFIX,55hg.com.com,Proxy\nDOMAIN-SUFFIX,goldpearl.firmex.com,Proxy\nDOMAIN-SUFFIX,artzi.org,Proxy\nDOMAIN-SUFFIX,1688938.com,Proxy\nDOMAIN-SUFFIX,g.me,Proxy\nDOMAIN-SUFFIX,hr8763.com,Proxy\nDOMAIN-SUFFIX,socraticforum.org,Proxy\nDOMAIN-SUFFIX,tvants.com,Proxy\nDOMAIN-SUFFIX,dynamicdns.co.uk,Proxy\nDOMAIN-SUFFIX,diif.co.uk,Proxy\nDOMAIN-SUFFIX,www.ivoox.com,Proxy\nDOMAIN-SUFFIX,trump.icu,Proxy\nDOMAIN-SUFFIX,abe.com,Proxy\nDOMAIN-SUFFIX,c2cx.com,Proxy\nDOMAIN-SUFFIX,tacem.org,Proxy\nDOMAIN-SUFFIX,sexandsubmission.com,Proxy\nDOMAIN-SUFFIX,d1eo0ryngmtyn5.cloudfront.net,Proxy\nDOMAIN-SUFFIX,reportingproject.net,Proxy\nDOMAIN-SUFFIX,www.ntdtv.kr,Proxy\nDOMAIN-SUFFIX,steganos.net,Proxy\nDOMAIN-SUFFIX,eltelu.blogspot.hk,Proxy\nDOMAIN-SUFFIX,mtvav.com,Proxy\nDOMAIN-SUFFIX,iraqinews.com,Proxy\nDOMAIN-SUFFIX,duc-tran.com,Proxy\nDOMAIN-SUFFIX,edwardhibbert.com,Proxy\nDOMAIN-SUFFIX,ianeo.de,Proxy\nDOMAIN-SUFFIX,jetos.com,Proxy\nDOMAIN-SUFFIX,blogdns.org,Proxy\nDOMAIN-SUFFIX,w5278.com,Proxy\nDOMAIN-SUFFIX,www.bestialitytaboo.tv,Proxy\nDOMAIN-SUFFIX,goldenkamui.eastasia.cloudapp.azure.com,Proxy\nDOMAIN-SUFFIX,dupola.net,Proxy\nDOMAIN-SUFFIX,chinahorizon.org,Proxy\nDOMAIN-SUFFIX,mister-wong.de,Proxy\nDOMAIN-SUFFIX,freehaven.net,Proxy\nDOMAIN-SUFFIX,www.googlechinawebmaster.com,Proxy\nDOMAIN-SUFFIX,www.policija.si,Proxy\nDOMAIN-SUFFIX,www.nishinippon.co.jp,Proxy\nDOMAIN-SUFFIX,hklft.com,Proxy\nDOMAIN-SUFFIX,www.chaum.net,Proxy\nDOMAIN-SUFFIX,v2s1.333789.xyz,Proxy\nDOMAIN-SUFFIX,nyvpn.com,Proxy\nDOMAIN-SUFFIX,838888.net,Proxy\nDOMAIN-SUFFIX,www.uproxy.co.uk,Proxy\nDOMAIN-SUFFIX,acast.com,Proxy\nDOMAIN-SUFFIX,freeddns.org,Proxy\nDOMAIN-SUFFIX,maiio.net,Proxy\nDOMAIN-SUFFIX,tfhub.dev,Proxy\nDOMAIN-SUFFIX,www.vzw.com,Proxy\nDOMAIN-SUFFIX,qk3p.com,Proxy\nDOMAIN-SUFFIX,web.telegrammy.ml,Proxy\nDOMAIN-SUFFIX,zh.wikiredia.com,Proxy\nDOMAIN-SUFFIX,667.microcycas.com,Proxy\nDOMAIN-SUFFIX,www.sankei.co.jp,Proxy\nDOMAIN-SUFFIX,erepublik.com,Proxy\nDOMAIN-SUFFIX,jubushoushen.com,Proxy\nDOMAIN-SUFFIX,hyperbeam.com,Proxy\nDOMAIN-SUFFIX,genexcomics.com,Proxy\nDOMAIN-SUFFIX,m.816cp5.com,Proxy\nDOMAIN-SUFFIX,d2ey43lez2ddmm.cloudfront.net,Proxy\nDOMAIN-SUFFIX,pole-emploi.fr,Proxy\nDOMAIN-SUFFIX,uguu.se,Proxy\nDOMAIN-SUFFIX,tool.ssrshare.xyz,Proxy\nDOMAIN-SUFFIX,canadabaidu.com,Proxy\nDOMAIN-SUFFIX,pj7997.com,Proxy\nDOMAIN-SUFFIX,national-lottery.co.uk,Proxy\nDOMAIN-SUFFIX,669d.app,Proxy\nDOMAIN-SUFFIX,news.housefun.com.tw,Proxy\nDOMAIN-SUFFIX,38850001.com,Proxy\nDOMAIN-SUFFIX,cnproxy.com,Proxy\nDOMAIN-SUFFIX,enoughschool.com,Proxy\nDOMAIN-SUFFIX,liberal.org.hk,Proxy\nDOMAIN-SUFFIX,eu49.com,Proxy\nDOMAIN-SUFFIX,58avgo.com,Proxy\nDOMAIN-SUFFIX,have8.tv,Proxy\nDOMAIN-SUFFIX,javdove2.live,Proxy\nDOMAIN-SUFFIX,www.cna.asia,Proxy\nDOMAIN-SUFFIX,jm-comic2.club,Proxy\nDOMAIN-SUFFIX,stimme-de.de,Proxy\nDOMAIN-SUFFIX,streameuno1su021.azureedge.net,Proxy\nDOMAIN-SUFFIX,www.freeandopenweb.com,Proxy\nDOMAIN-SUFFIX,insidekdrama.com,Proxy\nDOMAIN-SUFFIX,www.triumph.com,Proxy\nDOMAIN-SUFFIX,chrlawyers.hk,Proxy\nDOMAIN-SUFFIX,bigshorts.tv,Proxy\nDOMAIN-SUFFIX,aofriend.com.au,Proxy\nDOMAIN-SUFFIX,glvpn.com,Proxy\nDOMAIN-SUFFIX,japaninporn.com,Proxy\nDOMAIN-SUFFIX,capital.com,Proxy\nDOMAIN-SUFFIX,vrporn.com,Proxy\nDOMAIN-SUFFIX,sercomcloud.ap01.aws.af.cm,Proxy\nDOMAIN-SUFFIX,ktv58.net,Proxy\nDOMAIN-SUFFIX,www.fairfaxmedia.com.au,Proxy\nDOMAIN-SUFFIX,xiaobingss.com,Proxy\nDOMAIN-SUFFIX,www.caravan.kz,Proxy\nDOMAIN-SUFFIX,zpwa1.dcvw3.331368.com,Proxy\nDOMAIN-SUFFIX,fun7803.com,Proxy\nDOMAIN-SUFFIX,islam.org.hk,Proxy\nDOMAIN-SUFFIX,vpnjack.com,Proxy\nDOMAIN-SUFFIX,authorizeddns.org,Proxy\nDOMAIN-SUFFIX,apps.disney.com,Proxy\nDOMAIN-SUFFIX,project2049.net,Proxy\nDOMAIN-SUFFIX,mousouzoku-av.com,Proxy\nDOMAIN-SUFFIX,t.me,Proxy\nDOMAIN-SUFFIX,agoogleaday.com,Proxy\nDOMAIN-SUFFIX,517m5.com,Proxy\nDOMAIN-SUFFIX,5libo.com,Proxy\nDOMAIN-SUFFIX,mubi.com,Proxy\nDOMAIN-SUFFIX,daili9.663k.eu.org,Proxy\nDOMAIN-SUFFIX,14barcps.com,Proxy\nDOMAIN-SUFFIX,pedimedic.ro,Proxy\nDOMAIN-SUFFIX,webapp.bfnw-ds.com,Proxy\nDOMAIN-SUFFIX,mykynetec.com,Proxy\nDOMAIN-SUFFIX,cartoonsqueen.com,Proxy\nDOMAIN-SUFFIX,falungong.sk,Proxy\nDOMAIN-SUFFIX,6667766.com,Proxy\nDOMAIN-SUFFIX,game.udn.com,Proxy\nDOMAIN-SUFFIX,turnguard.com,Proxy\nDOMAIN-SUFFIX,xrentdvd.com,Proxy\nDOMAIN-SUFFIX,gherase.ro,Proxy\nDOMAIN-SUFFIX,wtfpass.com,Proxy\nDOMAIN-SUFFIX,hole-thu.github.io,Proxy\nDOMAIN-SUFFIX,zuixindizhi.org,Proxy\nDOMAIN-SUFFIX,baihua.org,Proxy\nDOMAIN-SUFFIX,www.bway997.com,Proxy\nDOMAIN-SUFFIX,antislavery.org,Proxy\nDOMAIN-SUFFIX,teamamericany.com,Proxy\nDOMAIN-SUFFIX,solana.com,Proxy\nDOMAIN-SUFFIX,ca7705.com,Proxy\nDOMAIN-SUFFIX,news.singtao.ca,Proxy\nDOMAIN-SUFFIX,80250333.com,Proxy\nDOMAIN-SUFFIX,myav123.com,Proxy\nDOMAIN-SUFFIX,hardtobelievemovie.com,Proxy\nDOMAIN-SUFFIX,rigpa.org.au,Proxy\nDOMAIN-SUFFIX,www.avseesee.com,Proxy\nDOMAIN-SUFFIX,xn--4gq171p.com,Proxy\nDOMAIN-SUFFIX,youtube.fr,Proxy\nDOMAIN-SUFFIX,www.redporn.com,Proxy\nDOMAIN-SUFFIX,25565.com,Proxy\nDOMAIN-SUFFIX,www38.eyny.com,Proxy\nDOMAIN-SUFFIX,www.zodgame.com,Proxy\nDOMAIN-SUFFIX,moefuns.vip,Proxy\nDOMAIN-SUFFIX,www.vpn520.com,Proxy\nDOMAIN-SUFFIX,dalailama-archives.org,Proxy\nDOMAIN-SUFFIX,miniforum.org,Proxy\nDOMAIN-SUFFIX,www.topcolighting.com,Proxy\nDOMAIN-SUFFIX,wb.com,Proxy\nDOMAIN-SUFFIX,pinapk.xyz,Proxy\nDOMAIN-SUFFIX,boomss.cc,Proxy\nDOMAIN-SUFFIX,doh.tiar.app,Proxy\nDOMAIN-SUFFIX,larakaras.com,Proxy\nDOMAIN-SUFFIX,287.slyip.net,Proxy\nDOMAIN-SUFFIX,www.shuku.net,Proxy\nDOMAIN-SUFFIX,2408.bfa678.com,Proxy\nDOMAIN-SUFFIX,bj1111.com,Proxy\nDOMAIN-SUFFIX,anonymise.us,Proxy\nDOMAIN-SUFFIX,d2l1odspphj7ns.cloudfront.net,Proxy\nDOMAIN-SUFFIX,susjed.com,Proxy\nDOMAIN-SUFFIX,donotban.com,Proxy\nDOMAIN-SUFFIX,just-cool.net,Proxy\nDOMAIN-SUFFIX,lookmv.cc,Proxy\nDOMAIN-SUFFIX,hclips.com,Proxy\nDOMAIN-SUFFIX,35.podzone.org,Proxy\nDOMAIN-SUFFIX,monlamdic.com,Proxy\nDOMAIN-SUFFIX,togethertube.com,Proxy\nDOMAIN-SUFFIX,92ccav.com,Proxy\nDOMAIN-SUFFIX,www.riverinaleader.com.au,Proxy\nDOMAIN-SUFFIX,www.milivpn.net,Proxy\nDOMAIN-SUFFIX,www.travelpayouts.com,Proxy\nDOMAIN-SUFFIX,2.pfsense.pool.ntp.org,Proxy\nDOMAIN-SUFFIX,app63.cf,Proxy\nDOMAIN-SUFFIX,funny-games.biz,Proxy\nDOMAIN-SUFFIX,tw.shop.com,Proxy\nDOMAIN-SUFFIX,plusbb.com,Proxy\nDOMAIN-SUFFIX,encyclopedia.tw,Proxy\nDOMAIN-SUFFIX,search.com,Proxy\nDOMAIN-SUFFIX,www.imdb.com,Proxy\nDOMAIN-SUFFIX,kichiku-doujinko.com,Proxy\nDOMAIN-SUFFIX,vpnb.com,Proxy\nDOMAIN-SUFFIX,muzi.com,Proxy\nDOMAIN-SUFFIX,akiyama.ca,Proxy\nDOMAIN-SUFFIX,safe-inet.com,Proxy\nDOMAIN-SUFFIX,www.hh999.xyz,Proxy\nDOMAIN-SUFFIX,www.share-tube.eu,Proxy\nDOMAIN-SUFFIX,hlw799.com,Proxy\nDOMAIN-SUFFIX,zff.co,Proxy\nDOMAIN-SUFFIX,mtmkbf.xyz,Proxy\nDOMAIN-SUFFIX,freeproxy.it,Proxy\nDOMAIN-SUFFIX,www.wankzvr.com,Proxy\nDOMAIN-SUFFIX,williamhill.es,Proxy\nDOMAIN-SUFFIX,www.ppcpa.com.tw,Proxy\nDOMAIN-SUFFIX,king.kinapharma.com,Proxy\nDOMAIN-SUFFIX,www-google-com.firelayers.net,Proxy\nDOMAIN-SUFFIX,app3.tk,Proxy\nDOMAIN-SUFFIX,googlr.com,Proxy\nDOMAIN-SUFFIX,read01.com,Proxy\nDOMAIN-SUFFIX,www.kards.com,Proxy\nDOMAIN-SUFFIX,agro.hk,Proxy\nDOMAIN-SUFFIX,yuyanzhibo.cc,Proxy\nDOMAIN-SUFFIX,gfw.org.ua,Proxy\nDOMAIN-SUFFIX,www.gleninnesexaminer.com.au,Proxy\nDOMAIN-SUFFIX,open.lifechurch.tv,Proxy\nDOMAIN-SUFFIX,mail.yahoo.ca,Proxy\nDOMAIN-SUFFIX,proxywebsite.co.uk,Proxy\nDOMAIN-SUFFIX,bhkta.org,Proxy\nDOMAIN-SUFFIX,share.dmhy.org,Proxy\nDOMAIN-SUFFIX,ventureswell.com,Proxy\nDOMAIN-SUFFIX,www.banana-vpn.com,Proxy\nDOMAIN-SUFFIX,ie1810.com,Proxy\nDOMAIN-SUFFIX,youchat.4irc.com,Proxy\nDOMAIN-SUFFIX,b-ok.as,Proxy\nDOMAIN-SUFFIX,dnsdns.xyz,Proxy\nDOMAIN-SUFFIX,www.googke.me,Proxy\nDOMAIN-SUFFIX,u.f-q.me,Proxy\nDOMAIN-SUFFIX,libsolutions.net,Proxy\nDOMAIN-SUFFIX,www.upress.co.il,Proxy\nDOMAIN-SUFFIX,lfexacg.com,Proxy\nDOMAIN-SUFFIX,lopgold.com,Proxy\nDOMAIN-SUFFIX,sheikyermami.com,Proxy\nDOMAIN-SUFFIX,www.caranddriver.com,Proxy\nDOMAIN-SUFFIX,www.pocucn.com,Proxy\nDOMAIN-SUFFIX,www.guge163.com,Proxy\nDOMAIN-SUFFIX,dalailamaworld.com,Proxy\nDOMAIN-SUFFIX,thedns.work,Proxy\nDOMAIN-SUFFIX,lnbphoto.net,Proxy\nDOMAIN-SUFFIX,blog.syx86.com,Proxy\nDOMAIN-SUFFIX,zhazhijiav.com,Proxy\nDOMAIN-SUFFIX,catswall.net,Proxy\nDOMAIN-SUFFIX,myhotsite.net,Proxy\nDOMAIN-SUFFIX,pornstarclub.com,Proxy\nDOMAIN-SUFFIX,www.middleeastmonitor.com,Proxy\nDOMAIN-SUFFIX,kfc2008.com,Proxy\nDOMAIN-SUFFIX,celo.net,Proxy\nDOMAIN-SUFFIX,xinbi999.com,Proxy\nDOMAIN-SUFFIX,ipfire.org,Proxy\nDOMAIN-SUFFIX,www.itechzero.com,Proxy\nDOMAIN-SUFFIX,javhdporn.net,Proxy\nDOMAIN-SUFFIX,newtaiwan.com.tw,Proxy\nDOMAIN-SUFFIX,www.rti.tw,Proxy\nDOMAIN-SUFFIX,javbus.com,Proxy\nDOMAIN-SUFFIX,nordvpn.de,Proxy\nDOMAIN-SUFFIX,xsoh.casa,Proxy\nDOMAIN-SUFFIX,maxteq.com,Proxy\nDOMAIN-SUFFIX,freeproxies.org,Proxy\nDOMAIN-SUFFIX,spin88.com,Proxy\nDOMAIN-SUFFIX,vs6868.com,Proxy\nDOMAIN-SUFFIX,www.wikitionary.org,Proxy\nDOMAIN-SUFFIX,arrowsoftruth.org,Proxy\nDOMAIN-SUFFIX,overlordmedia.com,Proxy\nDOMAIN-SUFFIX,aztecleisure.biz,Proxy\nDOMAIN-SUFFIX,fuccunt.com,Proxy\nDOMAIN-SUFFIX,vwin115.com,Proxy\nDOMAIN-SUFFIX,kingeshop.com,Proxy\nDOMAIN-SUFFIX,li-hongzhi-master.org,Proxy\nDOMAIN-SUFFIX,www.serajey.org,Proxy\nDOMAIN-SUFFIX,aipower.io,Proxy\nDOMAIN-SUFFIX,banhaw.com,Proxy\nDOMAIN-SUFFIX,www.skoda.de,Proxy\nDOMAIN-SUFFIX,sproutcore.com,Proxy\nDOMAIN-SUFFIX,upghsbc.com,Proxy\nDOMAIN-SUFFIX,arena.taipei,Proxy\nDOMAIN-SUFFIX,vpngate2.jp,Proxy\nDOMAIN-SUFFIX,forum4hk.com,Proxy\nDOMAIN-SUFFIX,food.com,Proxy\nDOMAIN-SUFFIX,jz3366.com,Proxy\nDOMAIN-SUFFIX,googlepagecreator.com,Proxy\nDOMAIN-SUFFIX,wubangtu.com,Proxy\nDOMAIN-SUFFIX,rti.org,Proxy\nDOMAIN-SUFFIX,wm.com,Proxy\nDOMAIN-SUFFIX,conceptm.eu,Proxy\nDOMAIN-SUFFIX,sq.com,Proxy\nDOMAIN-SUFFIX,abc.jzyy.net,Proxy\nDOMAIN-SUFFIX,boylove.live,Proxy\nDOMAIN-SUFFIX,catvpn.com,Proxy\nDOMAIN-SUFFIX,a3366.com,Proxy\nDOMAIN-SUFFIX,ar.hao123.com,Proxy\nDOMAIN-SUFFIX,suppig.net,Proxy\nDOMAIN-SUFFIX,2881.ca231.com,Proxy\nDOMAIN-SUFFIX,ggg626.net,Proxy\nDOMAIN-SUFFIX,imageproxy.pimg.tw,Proxy\nDOMAIN-SUFFIX,www.dytt8.com,Proxy\nDOMAIN-SUFFIX,westernsem.instructure.com,Proxy\nDOMAIN-SUFFIX,samplesolutions.com,Proxy\nDOMAIN-SUFFIX,www.leyicai888.com,Proxy\nDOMAIN-SUFFIX,geekz0ne.fr,Proxy\nDOMAIN-SUFFIX,martix.org,Proxy\nDOMAIN-SUFFIX,onmypc.net,Proxy\nDOMAIN-SUFFIX,zulily.com,Proxy\nDOMAIN-SUFFIX,www.spyoff.com,Proxy\nDOMAIN-SUFFIX,www.tibethaus.com,Proxy\nDOMAIN-SUFFIX,peing.net,Proxy\nDOMAIN-SUFFIX,yy0110.com,Proxy\nDOMAIN-SUFFIX,ctee.com.tw,Proxy\nDOMAIN-SUFFIX,webevader.org,Proxy\nDOMAIN-SUFFIX,jav4.me,Proxy\nDOMAIN-SUFFIX,www.boeckler.de,Proxy\nDOMAIN-SUFFIX,www.ourppc.com,Proxy\nDOMAIN-SUFFIX,fbvpn.com,Proxy\nDOMAIN-SUFFIX,www.rfachinese.com,Proxy\nDOMAIN-SUFFIX,nobita1069.blogspot.hk,Proxy\nDOMAIN-SUFFIX,dailytodo.org,Proxy\nDOMAIN-SUFFIX,223gg.net,Proxy\nDOMAIN-SUFFIX,ilovexjp.github.io,Proxy\nDOMAIN-SUFFIX,wsgzao.github.io,Proxy\nDOMAIN-SUFFIX,ftvcash.com,Proxy\nDOMAIN-SUFFIX,ting6600.com,Proxy\nDOMAIN-SUFFIX,cdn.aznude.com,Proxy\nDOMAIN-SUFFIX,analvids.com,Proxy\nDOMAIN-SUFFIX,ifj.org,Proxy\nDOMAIN-SUFFIX,videoyoutube.com,Proxy\nDOMAIN-SUFFIX,cineastentreff.de,Proxy\nDOMAIN-SUFFIX,www.gkfx.co.uk,Proxy\nDOMAIN-SUFFIX,bbs.soul-plus.org,Proxy\nDOMAIN-SUFFIX,shopatron.com,Proxy\nDOMAIN-SUFFIX,nya.one,Proxy\nDOMAIN-SUFFIX,btt904.com,Proxy\nDOMAIN-SUFFIX,game735.com,Proxy\nDOMAIN-SUFFIX,ofile.org,Proxy\nDOMAIN-SUFFIX,atty.co.uk,Proxy\nDOMAIN-SUFFIX,justproxy.de,Proxy\nDOMAIN-SUFFIX,google.com.fj,Proxy\nDOMAIN-SUFFIX,mod.run,Proxy\nDOMAIN-SUFFIX,binance-cn.com,Proxy\nDOMAIN-SUFFIX,browser.comodo.com,Proxy\nDOMAIN-SUFFIX,m.huancai66.com,Proxy\nDOMAIN-SUFFIX,27.etowns.net,Proxy\nDOMAIN-SUFFIX,norbulingka.org,Proxy\nDOMAIN-SUFFIX,s12223.com,Proxy\nDOMAIN-SUFFIX,inkui.com,Proxy\nDOMAIN-SUFFIX,thefederalist.com,Proxy\nDOMAIN-SUFFIX,999105.com,Proxy\nDOMAIN-SUFFIX,hknet.org.nz,Proxy\nDOMAIN-SUFFIX,avatarify.ai,Proxy\nDOMAIN-SUFFIX,secure.sourcemap.com,Proxy\nDOMAIN-SUFFIX,wikipedia.moesalih.com,Proxy\nDOMAIN-SUFFIX,from-hi.com,Proxy\nDOMAIN-SUFFIX,pacopacomama.com,Proxy\nDOMAIN-SUFFIX,earthview.withgoogle.com,Proxy\nDOMAIN-SUFFIX,ts33.net,Proxy\nDOMAIN-SUFFIX,www.new-av.com,Proxy\nDOMAIN-SUFFIX,vpnxt.com,Proxy\nDOMAIN-SUFFIX,jm-comic2.org,Proxy\nDOMAIN-SUFFIX,pureconcepts.net,Proxy\nDOMAIN-SUFFIX,elgoog.im,Proxy\nDOMAIN-SUFFIX,www.xskywalker.net,Proxy\nDOMAIN-SUFFIX,sproxy.net,Proxy\nDOMAIN-SUFFIX,r0.ru,Proxy\nDOMAIN-SUFFIX,www.emol.com,Proxy\nDOMAIN-SUFFIX,im88.tw,Proxy\nDOMAIN-SUFFIX,csh.ro,Proxy\nDOMAIN-SUFFIX,shake-zone.blogspot.ro,Proxy\nDOMAIN-SUFFIX,6220077.com,Proxy\nDOMAIN-SUFFIX,hga038.com,Proxy\nDOMAIN-SUFFIX,fyt80.com,Proxy\nDOMAIN-SUFFIX,www.krypt.com,Proxy\nDOMAIN-SUFFIX,sexyfuckgames.com,Proxy\nDOMAIN-SUFFIX,xcream.net,Proxy\nDOMAIN-SUFFIX,psiphon.me,Proxy\nDOMAIN-SUFFIX,zneth.com,Proxy\nDOMAIN-SUFFIX,mp3juices.cc,Proxy\nDOMAIN-SUFFIX,nuo.me,Proxy\nDOMAIN-SUFFIX,radicalwings.tw,Proxy\nDOMAIN-SUFFIX,yt.d0.cx,Proxy\nDOMAIN-SUFFIX,covis.ch,Proxy\nDOMAIN-SUFFIX,www.loverslab.com,Proxy\nDOMAIN-SUFFIX,google.lv,Proxy\nDOMAIN-SUFFIX,holymountaincn.com,Proxy\nDOMAIN-SUFFIX,jihadwatch.org,Proxy\nDOMAIN-SUFFIX,images.qdmzy.cn,Proxy\nDOMAIN-SUFFIX,crisisresponse.google,Proxy\nDOMAIN-SUFFIX,www.gateway.com,Proxy\nDOMAIN-SUFFIX,buzzav.com,Proxy\nDOMAIN-SUFFIX,ce.qc.to,Proxy\nDOMAIN-SUFFIX,www.acgft.com,Proxy\nDOMAIN-SUFFIX,yts.am,Proxy\nDOMAIN-SUFFIX,wire.com,Proxy\nDOMAIN-SUFFIX,vsv66.com,Proxy\nDOMAIN-SUFFIX,acgpy.com,Proxy\nDOMAIN-SUFFIX,vpnsecure.me,Proxy\nDOMAIN-SUFFIX,vip3.988cp13.cc,Proxy\nDOMAIN-SUFFIX,www.figprayer.com,Proxy\nDOMAIN-SUFFIX,bbs.lxty8.com,Proxy\nDOMAIN-SUFFIX,solemnvine.com,Proxy\nDOMAIN-SUFFIX,taiwannation.50webs.com,Proxy\nDOMAIN-SUFFIX,ygg.mkg20001.io,Proxy\nDOMAIN-SUFFIX,gegeshe2014.com,Proxy\nDOMAIN-SUFFIX,tbcollege.org,Proxy\nDOMAIN-SUFFIX,www.77pan.cc,Proxy\nDOMAIN-SUFFIX,polarzone.se,Proxy\nDOMAIN-SUFFIX,x531057.com,Proxy\nDOMAIN-SUFFIX,ablebrain.us,Proxy\nDOMAIN-SUFFIX,nc.bd.to,Proxy\nDOMAIN-SUFFIX,hacker.org,Proxy\nDOMAIN-SUFFIX,nob7.dhcp.biz,Proxy\nDOMAIN-SUFFIX,scientology.org.mx,Proxy\nDOMAIN-SUFFIX,b3533.com,Proxy\nDOMAIN-SUFFIX,www.thinkstockphotos.ca,Proxy\nDOMAIN-SUFFIX,huashangnews.com,Proxy\nDOMAIN-SUFFIX,www.kimomm.com,Proxy\nDOMAIN-SUFFIX,chicoscam.com,Proxy\nDOMAIN-SUFFIX,monitor.civicus.org,Proxy\nDOMAIN-SUFFIX,www.vpncloud.biz,Proxy\nDOMAIN-SUFFIX,63ii.net,Proxy\nDOMAIN-SUFFIX,idrlabs.com,Proxy\nDOMAIN-SUFFIX,www.xlgirls.com,Proxy\nDOMAIN-SUFFIX,www.timebridge.com,Proxy\nDOMAIN-SUFFIX,www.wowvpn.net,Proxy\nDOMAIN-SUFFIX,ipalter.com,Proxy\nDOMAIN-SUFFIX,toonel.net,Proxy\nDOMAIN-SUFFIX,xxmap2.xyz,Proxy\nDOMAIN-SUFFIX,form.aone-edu.com,Proxy\nDOMAIN-SUFFIX,wikiwand.com,Proxy\nDOMAIN-SUFFIX,upholdjustice.org,Proxy\nDOMAIN-SUFFIX,m9909.com,Proxy\nDOMAIN-SUFFIX,www.bituan.io,Proxy\nDOMAIN-SUFFIX,custommonkey.org,Proxy\nDOMAIN-SUFFIX,dailidaili.com,Proxy\nDOMAIN-SUFFIX,cnn.it,Proxy\nDOMAIN-SUFFIX,app.hicam.net,Proxy\nDOMAIN-SUFFIX,tibetcollection.com,Proxy\nDOMAIN-SUFFIX,bss.pppsong.com,Proxy\nDOMAIN-SUFFIX,www.y688300.com,Proxy\nDOMAIN-SUFFIX,internetproxies.net,Proxy\nDOMAIN-SUFFIX,www.vesselfinder.com,Proxy\nDOMAIN-SUFFIX,archiveofourown.net,Proxy\nDOMAIN-SUFFIX,xml-training-guide.com,Proxy\nDOMAIN-SUFFIX,dphk.org,Proxy\nDOMAIN-SUFFIX,otnd.org,Proxy\nDOMAIN-SUFFIX,parsely.com,Proxy\nDOMAIN-SUFFIX,raw-hunters.net,Proxy\nDOMAIN-SUFFIX,secure.shadowsocks.nu,Proxy\nDOMAIN-SUFFIX,sismonda.com.ar,Proxy\nDOMAIN-SUFFIX,behindkink.com,Proxy\nDOMAIN-SUFFIX,www.cmoinc.org,Proxy\nDOMAIN-SUFFIX,social.datalabour.com,Proxy\nDOMAIN-SUFFIX,thisrecording.com,Proxy\nDOMAIN-SUFFIX,033004.com,Proxy\nDOMAIN-SUFFIX,22.fx.rs,Proxy\nDOMAIN-SUFFIX,dmhy.best,Proxy\nDOMAIN-SUFFIX,www.krtco.com.tw,Proxy\nDOMAIN-SUFFIX,vimperator.org,Proxy\nDOMAIN-SUFFIX,gocomics.com,Proxy\nDOMAIN-SUFFIX,chinadigitaltimes.org,Proxy\nDOMAIN-SUFFIX,www.p3081.com,Proxy\nDOMAIN-SUFFIX,avparty.org,Proxy\nDOMAIN-SUFFIX,freeones.com,Proxy\nDOMAIN-SUFFIX,curioustore.com,Proxy\nDOMAIN-SUFFIX,duckmovies.net,Proxy\nDOMAIN-SUFFIX,msnapk.com,Proxy\nDOMAIN-SUFFIX,duckgo.com,Proxy\nDOMAIN-SUFFIX,cosplayjav.pl,Proxy\nDOMAIN-SUFFIX,krd.sputniknews.com,Proxy\nDOMAIN-SUFFIX,z-lib.io,Proxy\nDOMAIN-SUFFIX,ulianex.com,Proxy\nDOMAIN-SUFFIX,justmysocks1.net,Proxy\nDOMAIN-SUFFIX,contest.jinfengming.com,Proxy\nDOMAIN-SUFFIX,politicalconsultation.org,Proxy\nDOMAIN-SUFFIX,thefrisky.com,Proxy\nDOMAIN-SUFFIX,www.canalporno.com,Proxy\nDOMAIN-SUFFIX,www.mty.org.cn,Proxy\nDOMAIN-SUFFIX,d1zf37pb2kxnxf.cloudfront.net,Proxy\nDOMAIN-SUFFIX,tv.domain888.pw,Proxy\nDOMAIN-SUFFIX,sigupdates.marshal.com,Proxy\nDOMAIN-SUFFIX,b16001.com,Proxy\nDOMAIN-SUFFIX,pornfind.org,Proxy\nDOMAIN-SUFFIX,www.roccat.de,Proxy\nDOMAIN-SUFFIX,ushahidi.com,Proxy\nDOMAIN-SUFFIX,www.truthrevolt.org,Proxy\nDOMAIN-SUFFIX,ezto.in,Proxy\nDOMAIN-SUFFIX,blog.dun.im,Proxy\nDOMAIN-SUFFIX,wezhiyong.org,Proxy\nDOMAIN-SUFFIX,mail.tiscali.it,Proxy\nDOMAIN-SUFFIX,www.9apps.com,Proxy\nDOMAIN-SUFFIX,pori.hk,Proxy\nDOMAIN-SUFFIX,welcome2neverland.com,Proxy\nDOMAIN-SUFFIX,thewire.in,Proxy\nDOMAIN-SUFFIX,nitter.privacy.com.de,Proxy\nDOMAIN-SUFFIX,greatfirewall.biz,Proxy\nDOMAIN-SUFFIX,websearch.rakuten.co.jp,Proxy\nDOMAIN-SUFFIX,www.muhsinlar.com,Proxy\nDOMAIN-SUFFIX,jinkela.pw,Proxy\nDOMAIN-SUFFIX,www.fantasyfactory.xyz,Proxy\nDOMAIN-SUFFIX,protonvpn.com,Proxy\nDOMAIN-SUFFIX,ds2v8dhpuxcwv.cloudfront.net,Proxy\nDOMAIN-SUFFIX,abc.net.au,Proxy\nDOMAIN-SUFFIX,apple.co,Proxy\nDOMAIN-SUFFIX,hideme.be,Proxy\nDOMAIN-SUFFIX,hkdoujin.com,Proxy\nDOMAIN-SUFFIX,www.news1.kr,Proxy\nDOMAIN-SUFFIX,kofcmonroe.org,Proxy\nDOMAIN-SUFFIX,dongti.cc,Proxy\nDOMAIN-SUFFIX,474233.com,Proxy\nDOMAIN-SUFFIX,tubeum.com,Proxy\nDOMAIN-SUFFIX,www.bytick.com,Proxy\nDOMAIN-SUFFIX,php.now-ip.net,Proxy\nDOMAIN-SUFFIX,hustlercash.com,Proxy\nDOMAIN-SUFFIX,static-res-jtw.xxqzzx.cn,Proxy\nDOMAIN-SUFFIX,yt3.ggpht.com,Proxy\nDOMAIN-SUFFIX,bloglines.com,Proxy\nDOMAIN-SUFFIX,www.palden-dharma-tare.de,Proxy\nDOMAIN-SUFFIX,youtube.com.tw,Proxy\nDOMAIN-SUFFIX,twhawk.tw,Proxy\nDOMAIN-SUFFIX,vpn.blackvpn.ee,Proxy\nDOMAIN-SUFFIX,d3588w5hqzcepn.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.proxyanonymizer.net,Proxy\nDOMAIN-SUFFIX,1787411.com,Proxy\nDOMAIN-SUFFIX,engengraving.ca,Proxy\nDOMAIN-SUFFIX,www.tonyperkins.com,Proxy\nDOMAIN-SUFFIX,ccp-porn.8964.xyz,Proxy\nDOMAIN-SUFFIX,354.com,Proxy\nDOMAIN-SUFFIX,www.djangoproject.com,Proxy\nDOMAIN-SUFFIX,www.eucasino.com,Proxy\nDOMAIN-SUFFIX,lg513.com,Proxy\nDOMAIN-SUFFIX,dalailamacenter.org,Proxy\nDOMAIN-SUFFIX,my.freev2ray.org,Proxy\nDOMAIN-SUFFIX,roadshow.hk,Proxy\nDOMAIN-SUFFIX,bttt8.com,Proxy\nDOMAIN-SUFFIX,cproxyer.com,Proxy\nDOMAIN-SUFFIX,dobryvpn.pl,Proxy\nDOMAIN-SUFFIX,laptoplockdown.com,Proxy\nDOMAIN-SUFFIX,angularjs.org,Proxy\nDOMAIN-SUFFIX,eesile.org,Proxy\nDOMAIN-SUFFIX,falunnews.org.il,Proxy\nDOMAIN-SUFFIX,www.kimchiadventures.com,Proxy\nDOMAIN-SUFFIX,www.daloopa.com,Proxy\nDOMAIN-SUFFIX,ic.slyip.net,Proxy\nDOMAIN-SUFFIX,vivigirl7.xyz,Proxy\nDOMAIN-SUFFIX,zg111.1apps.com,Proxy\nDOMAIN-SUFFIX,nd1551.xyz,Proxy\nDOMAIN-SUFFIX,tuite.im,Proxy\nDOMAIN-SUFFIX,www.avia.org,Proxy\nDOMAIN-SUFFIX,gramho.com,Proxy\nDOMAIN-SUFFIX,www.bb3.com,Proxy\nDOMAIN-SUFFIX,funav.me,Proxy\nDOMAIN-SUFFIX,tor-exit-51.for-privacy.net,Proxy\nDOMAIN-SUFFIX,turnnewsapp.com,Proxy\nDOMAIN-SUFFIX,imageab.com,Proxy\nDOMAIN-SUFFIX,google.kg,Proxy\nDOMAIN-SUFFIX,bbwei818.com,Proxy\nDOMAIN-SUFFIX,chinese.soifind.com,Proxy\nDOMAIN-SUFFIX,www.esit.com,Proxy\nDOMAIN-SUFFIX,141hongkong.com,Proxy\nDOMAIN-SUFFIX,wakanim.tv,Proxy\nDOMAIN-SUFFIX,chinablog.xyz,Proxy\nDOMAIN-SUFFIX,rob3.ddns.us,Proxy\nDOMAIN-SUFFIX,www.azattyq.mobi,Proxy\nDOMAIN-SUFFIX,pewforum.org,Proxy\nDOMAIN-SUFFIX,zodgame.us,Proxy\nDOMAIN-SUFFIX,020gay.com,Proxy\nDOMAIN-SUFFIX,www.profinda.com,Proxy\nDOMAIN-SUFFIX,www.dashaqi.ga,Proxy\nDOMAIN-SUFFIX,gnunet.org,Proxy\nDOMAIN-SUFFIX,th.betwaythai8.com,Proxy\nDOMAIN-SUFFIX,naweeklytimes.com,Proxy\nDOMAIN-SUFFIX,kobo.com,Proxy\nDOMAIN-SUFFIX,newwinner.com.hk,Proxy\nDOMAIN-SUFFIX,www.emome.net,Proxy\nDOMAIN-SUFFIX,hardx.com,Proxy\nDOMAIN-SUFFIX,www.colafile.com,Proxy\nDOMAIN-SUFFIX,health2.live,Proxy\nDOMAIN-SUFFIX,thenude.eu,Proxy\nDOMAIN-SUFFIX,gaynewsnetwork.com.au,Proxy\nDOMAIN-SUFFIX,mirrormedia.mg,Proxy\nDOMAIN-SUFFIX,net.now-ip.net,Proxy\nDOMAIN-SUFFIX,chenshan20042005.wordpress.com,Proxy\nDOMAIN-SUFFIX,www.668200600.com,Proxy\nDOMAIN-SUFFIX,redlen.co.za,Proxy\nDOMAIN-SUFFIX,blmxl.com,Proxy\nDOMAIN-SUFFIX,hub.docker.com,Proxy\nDOMAIN-SUFFIX,www.blacktechpipeline.com,Proxy\nDOMAIN-SUFFIX,p2pvpn.org,Proxy\nDOMAIN-SUFFIX,www.808pb.com,Proxy\nDOMAIN-SUFFIX,www.story.alshames.com,Proxy\nDOMAIN-SUFFIX,baiduyun.me,Proxy\nDOMAIN-SUFFIX,wildstar-online.com,Proxy\nDOMAIN-SUFFIX,google.sc,Proxy\nDOMAIN-SUFFIX,www.idealmilf.com,Proxy\nDOMAIN-SUFFIX,webproxy.ca,Proxy\nDOMAIN-SUFFIX,www.indiatvnews.com,Proxy\nDOMAIN-SUFFIX,663.bot.nu,Proxy\nDOMAIN-SUFFIX,www.sdjzy.com,Proxy\nDOMAIN-SUFFIX,bodogasia.com,Proxy\nDOMAIN-SUFFIX,www.gravuregirlz.com,Proxy\nDOMAIN-SUFFIX,w2.flnet.org,Proxy\nDOMAIN-SUFFIX,m21.my03.com,Proxy\nDOMAIN-SUFFIX,cfr.org,Proxy\nDOMAIN-SUFFIX,cnabc.com,Proxy\nDOMAIN-SUFFIX,goagent.codeplex.com,Proxy\nDOMAIN-SUFFIX,youtuble.com,Proxy\nDOMAIN-SUFFIX,fc2blog.us,Proxy\nDOMAIN-SUFFIX,tor-exit-32.for-privacy.net,Proxy\nDOMAIN-SUFFIX,xh7333.com,Proxy\nDOMAIN-SUFFIX,jx2833.com,Proxy\nDOMAIN-SUFFIX,ieobserve.com,Proxy\nDOMAIN-SUFFIX,www.porntubenews.com,Proxy\nDOMAIN-SUFFIX,book.zi5.me,Proxy\nDOMAIN-SUFFIX,r2.dev,Proxy\nDOMAIN-SUFFIX,connect.facebook.net,Proxy\nDOMAIN-SUFFIX,av234567.com,Proxy\nDOMAIN-SUFFIX,yespornplease.cc,Proxy\nDOMAIN-SUFFIX,www.geekonsite.ca,Proxy\nDOMAIN-SUFFIX,merkur-online.de,Proxy\nDOMAIN-SUFFIX,myav.life,Proxy\nDOMAIN-SUFFIX,gayxmens.com,Proxy\nDOMAIN-SUFFIX,h.32top.xyz,Proxy\nDOMAIN-SUFFIX,cclifefl.org,Proxy\nDOMAIN-SUFFIX,vpn.minecloud.in,Proxy\nDOMAIN-SUFFIX,tor-exit-35.for-privacy.net,Proxy\nDOMAIN-SUFFIX,kaiyun.com,Proxy\nDOMAIN-SUFFIX,www.39173366.com,Proxy\nDOMAIN-SUFFIX,114ss.tk,Proxy\nDOMAIN-SUFFIX,scramble.io,Proxy\nDOMAIN-SUFFIX,www.svpn.tech,Proxy\nDOMAIN-SUFFIX,www.movieffm.net,Proxy\nDOMAIN-SUFFIX,gearvpn.com,Proxy\nDOMAIN-SUFFIX,22.suroot.com,Proxy\nDOMAIN-SUFFIX,www.rfiplaneteradio.org,Proxy\nDOMAIN-SUFFIX,fhreports.net,Proxy\nDOMAIN-SUFFIX,nnn3285.com,Proxy\nDOMAIN-SUFFIX,quantfury.com,Proxy\nDOMAIN-SUFFIX,www.sgwritings.com,Proxy\nDOMAIN-SUFFIX,verticalresponse.com,Proxy\nDOMAIN-SUFFIX,dnsorg.xyz,Proxy\nDOMAIN-SUFFIX,bunkerbustervpn.com,Proxy\nDOMAIN-SUFFIX,www.shype.com,Proxy\nDOMAIN-SUFFIX,go.informatica.com,Proxy\nDOMAIN-SUFFIX,bondagetube.tv,Proxy\nDOMAIN-SUFFIX,dysfz.cc,Proxy\nDOMAIN-SUFFIX,gatewayfun88.gamealiyun.com,Proxy\nDOMAIN-SUFFIX,marc.info,Proxy\nDOMAIN-SUFFIX,www.dyvip282.com,Proxy\nDOMAIN-SUFFIX,fbrowser.org,Proxy\nDOMAIN-SUFFIX,50034.xromtv.site,Proxy\nDOMAIN-SUFFIX,hotavxxx.com,Proxy\nDOMAIN-SUFFIX,asdfg.jp,Proxy\nDOMAIN-SUFFIX,usaip.eu,Proxy\nDOMAIN-SUFFIX,tianzhu.org,Proxy\nDOMAIN-SUFFIX,www.eebb168.com,Proxy\nDOMAIN-SUFFIX,tibetanparliament.org,Proxy\nDOMAIN-SUFFIX,rrsav.cc,Proxy\nDOMAIN-SUFFIX,www.xxxpornx.com,Proxy\nDOMAIN-SUFFIX,www.kkkapk.com,Proxy\nDOMAIN-SUFFIX,huyandex.com,Proxy\nDOMAIN-SUFFIX,www.openfilm.com,Proxy\nDOMAIN-SUFFIX,gov.taipei,Proxy\nDOMAIN-SUFFIX,contactmagazine.net,Proxy\nDOMAIN-SUFFIX,www.myactimes.com.au,Proxy\nDOMAIN-SUFFIX,oculus.com,Proxy\nDOMAIN-SUFFIX,www.deutschland.de,Proxy\nDOMAIN-SUFFIX,alxu.ca,Proxy\nDOMAIN-SUFFIX,firemp3.ru,Proxy\nDOMAIN-SUFFIX,now.ameba.jp,Proxy\nDOMAIN-SUFFIX,jonnidarkkoxxx.com,Proxy\nDOMAIN-SUFFIX,jostens.com,Proxy\nDOMAIN-SUFFIX,big5sex.com,Proxy\nDOMAIN-SUFFIX,ikforums.com,Proxy\nDOMAIN-SUFFIX,www.scasino.com,Proxy\nDOMAIN-SUFFIX,autosmallorca.es,Proxy\nDOMAIN-SUFFIX,maa1814.com,Proxy\nDOMAIN-SUFFIX,ice.audionow.com,Proxy\nDOMAIN-SUFFIX,githubassets.com,Proxy\nDOMAIN-SUFFIX,mlb.mlb.com,Proxy\nDOMAIN-KEYWORD,remembering_tiananmen_20_years,Proxy\nDOMAIN-SUFFIX,dotcom-monitor.com,Proxy\nDOMAIN-SUFFIX,rdio.com,Proxy\nDOMAIN-SUFFIX,cn.uptodown.com,Proxy\nDOMAIN-SUFFIX,terminus2049.xyz,Proxy\nDOMAIN-SUFFIX,mhub.dafa888.com,Proxy\nDOMAIN-SUFFIX,www.jiedaibao10g.com,Proxy\nDOMAIN-SUFFIX,www.mahabodhi.org,Proxy\nDOMAIN-SUFFIX,creek22.idv.tw,Proxy\nDOMAIN-SUFFIX,ww.orange01.org,Proxy\nDOMAIN-SUFFIX,api-login.kkbox.com.tw,Proxy\nDOMAIN-SUFFIX,fatanduseless.com,Proxy\nDOMAIN-SUFFIX,mygirlfriendsbustyfriend.com,Proxy\nDOMAIN-SUFFIX,is-a-linux-user.org,Proxy\nDOMAIN-SUFFIX,sfbbq.com,Proxy\nDOMAIN-SUFFIX,thepetitionsite.com,Proxy\nDOMAIN-SUFFIX,twitvid.com,Proxy\nDOMAIN-SUFFIX,taipeitimes.com,Proxy\nDOMAIN-SUFFIX,byt020.com,Proxy\nDOMAIN-SUFFIX,sur.ly,Proxy\nDOMAIN-SUFFIX,k6.c7b44558.org,Proxy\nDOMAIN-SUFFIX,www.animefreak.tv,Proxy\nDOMAIN-SUFFIX,rnew.org,Proxy\nDOMAIN-SUFFIX,576092.com,Proxy\nDOMAIN-SUFFIX,crds.co,Proxy\nDOMAIN-SUFFIX,rentry.co,Proxy\nDOMAIN-SUFFIX,www.9901235.com,Proxy\nDOMAIN-SUFFIX,xvideos9.com,Proxy\nDOMAIN-SUFFIX,www.silkbook.com,Proxy\nDOMAIN-SUFFIX,news.now.com,Proxy\nDOMAIN-SUFFIX,www.857zb.tv,Proxy\nDOMAIN-SUFFIX,jasenkorjaaja.fi,Proxy\nDOMAIN-SUFFIX,ntbt.gov.tw,Proxy\nDOMAIN-SUFFIX,obenabe.ch,Proxy\nDOMAIN-SUFFIX,libgen.st,Proxy\nDOMAIN-SUFFIX,d2kw3gauypnc3f.cloudfront.net,Proxy\nDOMAIN-SUFFIX,topescortbabes.com,Proxy\nDOMAIN-SUFFIX,arctosia.com,Proxy\nDOMAIN-SUFFIX,www.nomalys.com,Proxy\nDOMAIN-SUFFIX,kebrum.com,Proxy\nDOMAIN-SUFFIX,lyoutube.com,Proxy\nDOMAIN-SUFFIX,carbonated-cut-sousaphone.glitch.me,Proxy\nDOMAIN-SUFFIX,www.chinabyte.com,Proxy\nDOMAIN-SUFFIX,sciencenets.com,Proxy\nDOMAIN-SUFFIX,a.gufen.ga,Proxy\nDOMAIN-SUFFIX,dnxepj861ggav.cloudfront.net,Proxy\nDOMAIN-SUFFIX,yifa933.com,Proxy\nDOMAIN-SUFFIX,vb065051.tudouser.com,Proxy\nDOMAIN-SUFFIX,m20022.com,Proxy\nDOMAIN-SUFFIX,www.jin178.com,Proxy\nDOMAIN-SUFFIX,www.gal123.com,Proxy\nDOMAIN-SUFFIX,bettervpn.com,Proxy\nDOMAIN-SUFFIX,roigrentacar.es,Proxy\nDOMAIN-SUFFIX,pandapow.net,Proxy\nDOMAIN-SUFFIX,mol2.dhcp.biz,Proxy\nDOMAIN-SUFFIX,google.com.et,Proxy\nDOMAIN-SUFFIX,sorazone.net,Proxy\nDOMAIN-SUFFIX,www.myeasytv.com,Proxy\nDOMAIN-SUFFIX,kukov.com,Proxy\nDOMAIN-SUFFIX,d1ani98g6ik72n.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.ccfellow.org,Proxy\nDOMAIN-SUFFIX,glastream.ca,Proxy\nDOMAIN-SUFFIX,www.americamovil.com,Proxy\nDOMAIN-SUFFIX,www.acgzone.org,Proxy\nDOMAIN-SUFFIX,www.xingsu.me,Proxy\nDOMAIN-SUFFIX,ca892.com,Proxy\nDOMAIN-SUFFIX,wuw.red,Proxy\nDOMAIN-SUFFIX,4chan.org,Proxy\nDOMAIN-SUFFIX,dvdtrailertube.com,Proxy\nDOMAIN-SUFFIX,321.slyip.com,Proxy\nDOMAIN-SUFFIX,serveuser.com,Proxy\nDOMAIN-SUFFIX,neyshoes.com.br,Proxy\nDOMAIN-SUFFIX,paopao2.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,www.privatvpn.se,Proxy\nDOMAIN-SUFFIX,ashleyhinson.com,Proxy\nDOMAIN-SUFFIX,instaforex.com,Proxy\nDOMAIN-SUFFIX,hinduism.about.com,Proxy\nDOMAIN-SUFFIX,tvboxnow.com,Proxy\nDOMAIN-SUFFIX,nauu66.com,Proxy\nDOMAIN-SUFFIX,www.coasttocoastam.com,Proxy\nDOMAIN-SUFFIX,insidevoa.com,Proxy\nDOMAIN-SUFFIX,schoolisgood.com,Proxy\nDOMAIN-SUFFIX,t.airasia.com,Proxy\nDOMAIN-SUFFIX,www.amnesty.or.jp,Proxy\nDOMAIN-SUFFIX,websitebabble.com,Proxy\nDOMAIN-SUFFIX,www.taiwannation.org.tw,Proxy\nDOMAIN-SUFFIX,findex.cn,Proxy\nDOMAIN-SUFFIX,www.china2all.com,Proxy\nDOMAIN-SUFFIX,www.xuanleba2014.com,Proxy\nDOMAIN-SUFFIX,cnews.cna.com.tw,Proxy\nDOMAIN-SUFFIX,megumin.moe,Proxy\nDOMAIN-SUFFIX,www.hkbdsm.com,Proxy\nDOMAIN-SUFFIX,globaltracktrace.ptc.post,Proxy\nDOMAIN-SUFFIX,www.tempi.it,Proxy\nDOMAIN-SUFFIX,bizzabo.com,Proxy\nDOMAIN-SUFFIX,avatars1.githubusercontent.com,Proxy\nDOMAIN-SUFFIX,gg.bet,Proxy\nDOMAIN-SUFFIX,www.electronicbeats.net,Proxy\nDOMAIN-SUFFIX,taiwans.tw,Proxy\nDOMAIN-SUFFIX,www.f88vip9.com,Proxy\nDOMAIN-SUFFIX,download-youtube.com,Proxy\nDOMAIN-SUFFIX,fuckccp.xyz,Proxy\nDOMAIN-SUFFIX,www.hwazan.org,Proxy\nDOMAIN-SUFFIX,iconn.xyz,Proxy\nDOMAIN-SUFFIX,echo360.com,Proxy\nDOMAIN-SUFFIX,bakaproxy.moe,Proxy\nDOMAIN-SUFFIX,mobypicture.com,Proxy\nDOMAIN-SUFFIX,www.hjdc18.com,Proxy\nDOMAIN-SUFFIX,cs8881.com,Proxy\nDOMAIN-SUFFIX,findbook.tw,Proxy\nDOMAIN-SUFFIX,coolkidz.xyz,Proxy\nDOMAIN-SUFFIX,bizpowa.com,Proxy\nDOMAIN-SUFFIX,tvunetworks.com,Proxy\nDOMAIN-SUFFIX,kr71.4.688.org,Proxy\nDOMAIN-SUFFIX,meme.yahoo.com,Proxy\nDOMAIN-SUFFIX,h5dm.com,Proxy\nDOMAIN-SUFFIX,buevich.com,Proxy\nDOMAIN-SUFFIX,m2.my03.com,Proxy\nDOMAIN-SUFFIX,www.8host.com,Proxy\nDOMAIN-SUFFIX,www.studyportals.com,Proxy\nDOMAIN-SUFFIX,nutsvpn.site,Proxy\nDOMAIN-SUFFIX,www.caribbeancom.com,Proxy\nDOMAIN-SUFFIX,www.kenandrobintalkaboutstuff.com,Proxy\nDOMAIN-SUFFIX,badiucao.com,Proxy\nDOMAIN-SUFFIX,nde.de,Proxy\nDOMAIN-SUFFIX,21mm.5525.eu.org,Proxy\nDOMAIN-SUFFIX,supchina.com,Proxy\nDOMAIN-SUFFIX,sehuatang.org,Proxy\nDOMAIN-SUFFIX,woyaolian.org,Proxy\nDOMAIN-SUFFIX,www.rebelmouse.com,Proxy\nDOMAIN-SUFFIX,hqsbnet.wordpress.com,Proxy\nDOMAIN-SUFFIX,videobam.com,Proxy\nDOMAIN-SUFFIX,yopol.com,Proxy\nDOMAIN-SUFFIX,cortexstl.com,Proxy\nDOMAIN-SUFFIX,psiphon3.com,Proxy\nDOMAIN-SUFFIX,biz.oricon.co.jp,Proxy\nDOMAIN-SUFFIX,vpndeluxe.com,Proxy\nDOMAIN-SUFFIX,japanhdv.com,Proxy\nDOMAIN-SUFFIX,zhanlve.org,Proxy\nDOMAIN-SUFFIX,shenyunshop.com,Proxy\nDOMAIN-SUFFIX,www.nunuyy5.org,Proxy\nDOMAIN-SUFFIX,webtunnel.org,Proxy\nDOMAIN-SUFFIX,tu8964.com,Proxy\nDOMAIN-SUFFIX,polysolve.com,Proxy\nDOMAIN-SUFFIX,pttweb.com,Proxy\nDOMAIN-SUFFIX,meripet.com,Proxy\nDOMAIN-SUFFIX,redballoonsolidarity.org,Proxy\nDOMAIN-SUFFIX,minghuiyw.wordpress.com,Proxy\nDOMAIN-SUFFIX,strelchenok.com,Proxy\nDOMAIN-SUFFIX,www.keithmoyer.com,Proxy\nDOMAIN-SUFFIX,www.thefootballsack.com,Proxy\nDOMAIN-SUFFIX,kanporno.com,Proxy\nDOMAIN-SUFFIX,bit.biz.st,Proxy\nDOMAIN-SUFFIX,tggt.net,Proxy\nDOMAIN-SUFFIX,www.libe.com,Proxy\nDOMAIN-SUFFIX,ck101.com,Proxy\nDOMAIN-SUFFIX,grindr.com,Proxy\nDOMAIN-SUFFIX,www.bcc.com.tw,Proxy\nDOMAIN-SUFFIX,jmcomic.xyz,Proxy\nDOMAIN-SUFFIX,pu0021.com,Proxy\nDOMAIN-SUFFIX,soulforce.org,Proxy\nDOMAIN-SUFFIX,loseyourip.com,Proxy\nDOMAIN-SUFFIX,cyberbase.agglo-pau.fr,Proxy\nDOMAIN-SUFFIX,youtubelike.com,Proxy\nDOMAIN-SUFFIX,shadowsocks.cn,Proxy\nDOMAIN-SUFFIX,is-a-techie.com,Proxy\nDOMAIN-SUFFIX,ra.gg,Proxy\nDOMAIN-SUFFIX,videosz.com,Proxy\nDOMAIN-SUFFIX,app2.hkatv.com,Proxy\nDOMAIN-SUFFIX,g-queen.com,Proxy\nDOMAIN-SUFFIX,members.puuko.com,Proxy\nDOMAIN-SUFFIX,cosersuki.net,Proxy\nDOMAIN-SUFFIX,phmsociety.org,Proxy\nDOMAIN-SUFFIX,todayapp.tv,Proxy\nDOMAIN-SUFFIX,kima88.com,Proxy\nDOMAIN-SUFFIX,soft.idv.tw,Proxy\nDOMAIN-SUFFIX,www.jdyvpn.com.cn,Proxy\nDOMAIN-SUFFIX,blitzmetrics.com,Proxy\nDOMAIN-SUFFIX,vpnd.com,Proxy\nDOMAIN-SUFFIX,dd516.net,Proxy\nDOMAIN-SUFFIX,cc.ee.ntu.edu.tw,Proxy\nDOMAIN-SUFFIX,gospelforasia-books.org,Proxy\nDOMAIN-SUFFIX,www.macrovpn.com,Proxy\nDOMAIN-SUFFIX,maillater.com,Proxy\nDOMAIN-SUFFIX,sikhism.about.com,Proxy\nDOMAIN-SUFFIX,quora.com,Proxy\nDOMAIN-SUFFIX,www.avanguard.com.tw,Proxy\nDOMAIN-SUFFIX,ibit.am,Proxy\nDOMAIN-SUFFIX,i-cf.pximg.net,Proxy\nDOMAIN-SUFFIX,mmaaxx.com,Proxy\nDOMAIN-SUFFIX,se.bv39.club,Proxy\nDOMAIN-SUFFIX,cfdtrading.com,Proxy\nDOMAIN-SUFFIX,huaxin.ph,Proxy\nDOMAIN-SUFFIX,forum.baby-kingdom.com,Proxy\nDOMAIN-SUFFIX,po2b.com,Proxy\nDOMAIN-SUFFIX,betertech.com.ar,Proxy\nDOMAIN-SUFFIX,www.099529.com,Proxy\nDOMAIN-SUFFIX,dvorak.org,Proxy\nDOMAIN-SUFFIX,dcmilitary.com,Proxy\nDOMAIN-SUFFIX,hosted.met-art.com,Proxy\nDOMAIN-SUFFIX,sunrocks.com.ar,Proxy\nDOMAIN-SUFFIX,wikileaks-forum.com,Proxy\nDOMAIN-SUFFIX,www.nonproliferation.eu,Proxy\nDOMAIN-SUFFIX,www.europeaninnovators.eu,Proxy\nDOMAIN-SUFFIX,maaxv.com,Proxy\nDOMAIN-SUFFIX,imagezilla.net,Proxy\nDOMAIN-SUFFIX,liuxiaobo.net,Proxy\nDOMAIN-SUFFIX,8dice168.com,Proxy\nDOMAIN-SUFFIX,australia.kinokuniya.com,Proxy\nDOMAIN-SUFFIX,gmgard.com,Proxy\nDOMAIN-SUFFIX,vpnhub.com,Proxy\nDOMAIN-SUFFIX,www.bwei8668.com,Proxy\nDOMAIN-SUFFIX,www.toastynews.com,Proxy\nDOMAIN-SUFFIX,site-1864713-2044-5258.strikingly.com,Proxy\nDOMAIN-SUFFIX,www.hills.qld.edu.au,Proxy\nDOMAIN-SUFFIX,wanz-factory.com,Proxy\nDOMAIN-SUFFIX,d1s5ussrz0ovn0.cloudfront.net,Proxy\nDOMAIN-SUFFIX,6701.com,Proxy\nDOMAIN-SUFFIX,www.sex8.com,Proxy\nDOMAIN-SUFFIX,travelwithoutquit.com,Proxy\nDOMAIN-SUFFIX,33327.com,Proxy\nDOMAIN-SUFFIX,www.fomsin.com,Proxy\nDOMAIN-SUFFIX,endorganpillaging.org,Proxy\nDOMAIN-SUFFIX,aiss.anws.gov.tw,Proxy\nDOMAIN-SUFFIX,higfw.com,Proxy\nDOMAIN-SUFFIX,your-world-at-penn.workplace.com,Proxy\nDOMAIN-SUFFIX,apkdownloadforwindows.com,Proxy\nDOMAIN-SUFFIX,vpntunnel.com,Proxy\nDOMAIN-SUFFIX,porn-video-tube.com,Proxy\nDOMAIN-SUFFIX,www.wochenblatt.es,Proxy\nDOMAIN-SUFFIX,jp.hao123.com,Proxy\nDOMAIN-SUFFIX,bzm456.me,Proxy\nDOMAIN-SUFFIX,google.ua,Proxy\nDOMAIN-SUFFIX,kindleren.com,Proxy\nDOMAIN-SUFFIX,m.ca551.com,Proxy\nDOMAIN-SUFFIX,lantern7.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,usus.cc,Proxy\nDOMAIN-SUFFIX,legra.ph,Proxy\nDOMAIN-SUFFIX,www.pacificresearch.org,Proxy\nDOMAIN-SUFFIX,xiongpian.com,Proxy\nDOMAIN-SUFFIX,kckc.onedumb.com,Proxy\nDOMAIN-SUFFIX,godsimmediatecontact.com,Proxy\nDOMAIN-SUFFIX,dnainfo.com,Proxy\nDOMAIN-SUFFIX,tn2.shemalez.com,Proxy\nDOMAIN-SUFFIX,boxun7.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,hy88998.com,Proxy\nDOMAIN-SUFFIX,omofun.tv,Proxy\nDOMAIN-SUFFIX,yipub.com,Proxy\nDOMAIN-SUFFIX,www.bio-pigeondna.com,Proxy\nDOMAIN-SUFFIX,07cp1.com,Proxy\nDOMAIN-SUFFIX,hdlt.me,Proxy\nDOMAIN-SUFFIX,mergersandinquisitions.org,Proxy\nDOMAIN-SUFFIX,molihua.org,Proxy\nDOMAIN-SUFFIX,hpjav.tv,Proxy\nDOMAIN-SUFFIX,spicybigbutt.com,Proxy\nDOMAIN-SUFFIX,www.mmkao.net,Proxy\nDOMAIN-SUFFIX,x513.fun,Proxy\nDOMAIN-SUFFIX,452.dhcp.biz,Proxy\nDOMAIN-SUFFIX,37.wha.la,Proxy\nDOMAIN-SUFFIX,18comic.biz,Proxy\nDOMAIN-SUFFIX,betway556.com,Proxy\nDOMAIN-SUFFIX,cc1505.com,Proxy\nDOMAIN-SUFFIX,www.gameschool.idv.tw,Proxy\nDOMAIN-SUFFIX,jmscult.com,Proxy\nDOMAIN-SUFFIX,btguard.com,Proxy\nDOMAIN-SUFFIX,gamefront.com,Proxy\nDOMAIN-SUFFIX,filmschoolrejects.com,Proxy\nDOMAIN-SUFFIX,www.00bbcc.com,Proxy\nDOMAIN-SUFFIX,gu.twimg.com,Proxy\nDOMAIN-SUFFIX,iptvbin.com,Proxy\nDOMAIN-SUFFIX,n.l5.ca,Proxy\nDOMAIN-SUFFIX,177702222.com,Proxy\nDOMAIN-SUFFIX,europe-west1-ottplay.cloudfunctions.net,Proxy\nDOMAIN-SUFFIX,fuskator.com,Proxy\nDOMAIN-SUFFIX,www.tuwang.org,Proxy\nDOMAIN-SUFFIX,alhayat.com,Proxy\nDOMAIN-SUFFIX,laval.cl,Proxy\nDOMAIN-SUFFIX,tw.mobi.yahoo.com,Proxy\nDOMAIN-SUFFIX,www.alicejapan.co.jp,Proxy\nDOMAIN-SUFFIX,yanghengjun.spaces.live.com,Proxy\nDOMAIN-SUFFIX,www.baihe.com,Proxy\nDOMAIN-SUFFIX,cdn1.lp.saboom.com,Proxy\nDOMAIN-SUFFIX,tmksoft.net,Proxy\nDOMAIN-SUFFIX,www.bemindfulfortcollins.org,Proxy\nDOMAIN-SUFFIX,ppyq9.com,Proxy\nDOMAIN-SUFFIX,willie.idv.tw,Proxy\nDOMAIN-SUFFIX,177703333.com,Proxy\nDOMAIN-SUFFIX,coinn.me,Proxy\nDOMAIN-SUFFIX,rfanews.org,Proxy\nDOMAIN-SUFFIX,sbobet.com,Proxy\nDOMAIN-SUFFIX,2365000333.com,Proxy\nDOMAIN-SUFFIX,ponselhp.blogspot.hk,Proxy\nDOMAIN-SUFFIX,show.aikantube.com,Proxy\nDOMAIN-SUFFIX,tre.9bah1.com,Proxy\nDOMAIN-SUFFIX,javdoe.to,Proxy\nDOMAIN-SUFFIX,www.julis.de,Proxy\nDOMAIN-SUFFIX,googleweblight.com,Proxy\nDOMAIN-SUFFIX,b68.xyz,Proxy\nDOMAIN-SUFFIX,dsndsn00.com,Proxy\nDOMAIN-SUFFIX,martinez-perez.es,Proxy\nDOMAIN-SUFFIX,www.youfap.me,Proxy\nDOMAIN-SUFFIX,mikeinbrazil.com,Proxy\nDOMAIN-SUFFIX,www.crookwellgazette.com.au,Proxy\nDOMAIN-SUFFIX,c.cari.com.my,Proxy\nDOMAIN-SUFFIX,mastodon.social,Proxy\nDOMAIN-SUFFIX,br.hao123.com,Proxy\nDOMAIN-SUFFIX,digitizer.us,Proxy\nDOMAIN-SUFFIX,www.game456.net,Proxy\nDOMAIN-SUFFIX,gettyimages.com,Proxy\nDOMAIN-SUFFIX,www.theredmondcloud.com,Proxy\nDOMAIN-SUFFIX,thediplomat.com,Proxy\nDOMAIN-SUFFIX,trace.org,Proxy\nDOMAIN-SUFFIX,nationbuilder.com,Proxy\nDOMAIN-SUFFIX,oslofreedomforum.com,Proxy\nDOMAIN-SUFFIX,www.fun88-i78.com,Proxy\nDOMAIN-SUFFIX,jm365.xyz,Proxy\nDOMAIN-SUFFIX,feel031344.wixsite.com,Proxy\nDOMAIN-SUFFIX,www.counterpunch.org,Proxy\nDOMAIN-SUFFIX,madewithcode.com,Proxy\nDOMAIN-SUFFIX,o265433.ingest.sentry.io,Proxy\nDOMAIN-SUFFIX,brave.com,Proxy\nDOMAIN-SUFFIX,99jre.com.stat001.com,Proxy\nDOMAIN-SUFFIX,dafabet.com,Proxy\nDOMAIN-SUFFIX,iccbrasil.com.br,Proxy\nDOMAIN-SUFFIX,motowind.net,Proxy\nDOMAIN-SUFFIX,quranicaudio.com,Proxy\nDOMAIN-SUFFIX,twttr.com,Proxy\nDOMAIN-SUFFIX,www.tb68s.com,Proxy\nDOMAIN-SUFFIX,www.gatewaybuickgmc.com,Proxy\nDOMAIN-SUFFIX,girlwithcurves.com,Proxy\nDOMAIN-SUFFIX,e-activist.com,Proxy\nDOMAIN-SUFFIX,portal-istiqlal.net,Proxy\nDOMAIN-SUFFIX,vimeo.com,Proxy\nDOMAIN-SUFFIX,jdjcc.org,Proxy\nDOMAIN-SUFFIX,ao3.site,Proxy\nDOMAIN-SUFFIX,www.106666.com,Proxy\nDOMAIN-SUFFIX,shoebridge.me.uk,Proxy\nDOMAIN-SUFFIX,ifcayouth.org,Proxy\nDOMAIN-SUFFIX,c.3mon.xyz,Proxy\nDOMAIN-SUFFIX,6annonce.com,Proxy\nDOMAIN-SUFFIX,band.com,Proxy\nDOMAIN-SUFFIX,vpnshieldapp.com,Proxy\nDOMAIN-SUFFIX,www.jlist.com,Proxy\nDOMAIN-SUFFIX,h5.065ld.com,Proxy\nDOMAIN-SUFFIX,hs.vc,Proxy\nDOMAIN-SUFFIX,novini247.com,Proxy\nDOMAIN-SUFFIX,nighost.org,Proxy\nDOMAIN-SUFFIX,research.googleblog.com,Proxy\nDOMAIN-SUFFIX,jinsha7555.com,Proxy\nDOMAIN-SUFFIX,3029828.com,Proxy\nDOMAIN-SUFFIX,assets.totallyacdn.com,Proxy\nDOMAIN-SUFFIX,nyoutube.com,Proxy\nDOMAIN-SUFFIX,lovemyanime.com,Proxy\nDOMAIN-SUFFIX,doh-jp.blahdns.com,Proxy\nDOMAIN-SUFFIX,filelist.ro,Proxy\nDOMAIN-SUFFIX,dnsforge.de,Proxy\nDOMAIN-SUFFIX,axvpn.com,Proxy\nDOMAIN-SUFFIX,rutracker.net,Proxy\nDOMAIN-SUFFIX,hospisoft.net,Proxy\nDOMAIN-SUFFIX,unblock.cn.com,Proxy\nDOMAIN-SUFFIX,epochtimes.com,Proxy\nDOMAIN-SUFFIX,feba.org.uk,Proxy\nDOMAIN-SUFFIX,pu2299.com,Proxy\nDOMAIN-SUFFIX,www.ruixy.cc,Proxy\nDOMAIN-SUFFIX,kadokawa.co.jp,Proxy\nDOMAIN-SUFFIX,jdwsy.com,Proxy\nDOMAIN-SUFFIX,suvpn.com,Proxy\nDOMAIN-SUFFIX,tube911.com,Proxy\nDOMAIN-SUFFIX,faststore.org,Proxy\nDOMAIN-SUFFIX,b.we55.us,Proxy\nDOMAIN-SUFFIX,deezer.com,Proxy\nDOMAIN-SUFFIX,cs067.com,Proxy\nDOMAIN-SUFFIX,jamyang.co.uk,Proxy\nDOMAIN-SUFFIX,ew.sab.flnet.org,Proxy\nDOMAIN-SUFFIX,www.vpndefender.com,Proxy\nDOMAIN-SUFFIX,vxea.fed.3d-game.com,Proxy\nDOMAIN-SUFFIX,18comic-god.biz,Proxy\nDOMAIN-SUFFIX,img.favsite.jp,Proxy\nDOMAIN-SUFFIX,tengbiao.org,Proxy\nDOMAIN-SUFFIX,sunsmoke.com,Proxy\nDOMAIN-SUFFIX,www.data18.com,Proxy\nDOMAIN-SUFFIX,yl3322.org,Proxy\nDOMAIN-SUFFIX,s1.pimg.tw,Proxy\nDOMAIN-SUFFIX,xiuxiuda233.000webhostapp.com,Proxy\nDOMAIN-SUFFIX,nord-cn-site.org,Proxy\nDOMAIN-SUFFIX,westernwolves.com,Proxy\nDOMAIN-SUFFIX,www.tianmei.la,Proxy\nDOMAIN-SUFFIX,tokyomotion.net,Proxy\nDOMAIN-SUFFIX,ss-link.com,Proxy\nDOMAIN-SUFFIX,comefromchina.com,Proxy\nDOMAIN-SUFFIX,en.wikipedia.shutcm.cf,Proxy\nDOMAIN-SUFFIX,signal.org,Proxy\nDOMAIN-SUFFIX,blog.sogoo.org,Proxy\nDOMAIN-SUFFIX,islamhouse.com,Proxy\nDOMAIN-SUFFIX,immensegames.com,Proxy\nDOMAIN-SUFFIX,neat-url.com,Proxy\nDOMAIN-SUFFIX,meneame.net,Proxy\nDOMAIN-SUFFIX,godaddy.gay,Proxy\nDOMAIN-SUFFIX,quietmindsangha.org,Proxy\nDOMAIN-SUFFIX,www.letelegramme.fr,Proxy\nDOMAIN-SUFFIX,pornstarsporno.com,Proxy\nDOMAIN-SUFFIX,s1.ss2wall.tk,Proxy\nDOMAIN-SUFFIX,ashemaletube.com,Proxy\nDOMAIN-SUFFIX,soas.ac.uk,Proxy\nDOMAIN-SUFFIX,xinlingfamen.net,Proxy\nDOMAIN-SUFFIX,www.grneggs.com,Proxy\nDOMAIN-SUFFIX,heloisenadeau.com,Proxy\nDOMAIN-SUFFIX,proxy4free.com,Proxy\nDOMAIN-SUFFIX,ecaipe.com.ar,Proxy\nDOMAIN-SUFFIX,inanews.tw,Proxy\nDOMAIN-SUFFIX,www.newproxylist.net,Proxy\nDOMAIN-SUFFIX,wingamestore.com,Proxy\nDOMAIN-SUFFIX,gamona.de,Proxy\nDOMAIN-SUFFIX,theatoms.com,Proxy\nDOMAIN-SUFFIX,lovesexbody.com,Proxy\nDOMAIN-SUFFIX,livemint.com,Proxy\nDOMAIN-SUFFIX,amoweb.fr,Proxy\nDOMAIN-SUFFIX,www.hj935.com,Proxy\nDOMAIN-SUFFIX,liveleak.com,Proxy\nDOMAIN-SUFFIX,cjb.net,Proxy\nDOMAIN-SUFFIX,download-a.akamaihd.net,Proxy\nDOMAIN-SUFFIX,wh.wha.la,Proxy\nDOMAIN-SUFFIX,live.streamingfast.net,Proxy\nDOMAIN-SUFFIX,7686g.com,Proxy\nDOMAIN-SUFFIX,chinesen.de,Proxy\nDOMAIN-SUFFIX,newlinesinstitute.org,Proxy\nDOMAIN-SUFFIX,dcm3cu7yundx2.cloudfront.net,Proxy\nDOMAIN-SUFFIX,popxi.click,Proxy\nDOMAIN-SUFFIX,ting0123.com,Proxy\nDOMAIN-SUFFIX,3653651.com,Proxy\nDOMAIN-SUFFIX,www.imianmian.com,Proxy\nDOMAIN-SUFFIX,rivier.com.ar,Proxy\nDOMAIN-SUFFIX,rame.net,Proxy\nDOMAIN-SUFFIX,taiwandc.org,Proxy\nDOMAIN-SUFFIX,tdworks.com,Proxy\nDOMAIN-SUFFIX,e-zone.com.hk,Proxy\nDOMAIN-SUFFIX,www7775678.com,Proxy\nDOMAIN-SUFFIX,fcchk.org,Proxy\nDOMAIN-SUFFIX,webfreer.com,Proxy\nDOMAIN-SUFFIX,www.faceboook.com,Proxy\nDOMAIN-SUFFIX,go365.ml,Proxy\nDOMAIN-SUFFIX,juddstevens.ml,Proxy\nDOMAIN-SUFFIX,kq.im-ec.com.ar,Proxy\nDOMAIN-SUFFIX,d2518dpi0ehrmy.cloudfront.net,Proxy\nDOMAIN-SUFFIX,5idd.us,Proxy\nDOMAIN-SUFFIX,wuerkaixi.com,Proxy\nDOMAIN-SUFFIX,www.vvw18.com,Proxy\nDOMAIN-SUFFIX,www.grannar.no,Proxy\nDOMAIN-SUFFIX,pekinger-fruehling.univie.ac.at,Proxy\nDOMAIN-SUFFIX,martau.com,Proxy\nDOMAIN-SUFFIX,www.betvictor96.com,Proxy\nDOMAIN-SUFFIX,mingjingtimes.com,Proxy\nDOMAIN-SUFFIX,d1fvf4htqulvuq.cloudfront.net,Proxy\nDOMAIN-SUFFIX,nitter.nl,Proxy\nDOMAIN-SUFFIX,18comic2.biz,Proxy\nDOMAIN-SUFFIX,tor-exit-39.for-privacy.net,Proxy\nDOMAIN-SUFFIX,tv2.max.st,Proxy\nDOMAIN-SUFFIX,huffpost.com,Proxy\nDOMAIN-SUFFIX,health.businessweekly.com.tw,Proxy\nDOMAIN-SUFFIX,mansion.com,Proxy\nDOMAIN-SUFFIX,pixlr.com,Proxy\nDOMAIN-SUFFIX,blog.cloudboost.io,Proxy\nDOMAIN-SUFFIX,eurosexparties.com,Proxy\nDOMAIN-SUFFIX,m.1680101kai.co,Proxy\nDOMAIN-SUFFIX,nonproliferation.org,Proxy\nDOMAIN-SUFFIX,155899.com,Proxy\nDOMAIN-SUFFIX,pu0029.com,Proxy\nDOMAIN-SUFFIX,expressvpn.co,Proxy\nDOMAIN-SUFFIX,688.flnet.org,Proxy\nDOMAIN-SUFFIX,forum.8cyber.net,Proxy\nDOMAIN-SUFFIX,www.forum4hk.com,Proxy\nDOMAIN-SUFFIX,freevpn.wwdhz.com,Proxy\nDOMAIN-SUFFIX,zzc.healthins.xyz,Proxy\nDOMAIN-SUFFIX,recode.net,Proxy\nDOMAIN-SUFFIX,www.gaymaletube.com,Proxy\nDOMAIN-SUFFIX,brownpapertickets.com,Proxy\nDOMAIN-SUFFIX,api01.meomiao.me,Proxy\nDOMAIN-SUFFIX,hk.rd.yahoo.com,Proxy\nDOMAIN-SUFFIX,310app1.com,Proxy\nDOMAIN-SUFFIX,cs585.com,Proxy\nDOMAIN-SUFFIX,ii9911.com,Proxy\nDOMAIN-SUFFIX,img-9gag-fun.9cache.com,Proxy\nDOMAIN-SUFFIX,topconservativenews.com,Proxy\nDOMAIN-SUFFIX,mailbox.org,Proxy\nDOMAIN-SUFFIX,wikimapia.org,Proxy\nDOMAIN-SUFFIX,www.hkfeature.com,Proxy\nDOMAIN-SUFFIX,ekiry.com,Proxy\nDOMAIN-SUFFIX,hce.itechzero.com,Proxy\nDOMAIN-SUFFIX,cldr.unicode.org,Proxy\nDOMAIN-SUFFIX,valibarbulescu.ro,Proxy\nDOMAIN-SUFFIX,yibaochina.com,Proxy\nDOMAIN-SUFFIX,www.australia-proxy.com,Proxy\nDOMAIN-SUFFIX,thehun.net,Proxy\nDOMAIN-SUFFIX,olafbreuning.com,Proxy\nDOMAIN-SUFFIX,www.dolphinfitness.co.uk,Proxy\nDOMAIN-SUFFIX,brizzly.com,Proxy\nDOMAIN-SUFFIX,gamelink.com,Proxy\nDOMAIN-SUFFIX,d3rnjxpkwf3le1.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.bclc.com,Proxy\nDOMAIN-SUFFIX,mindrolling.org,Proxy\nDOMAIN-SUFFIX,www.guotaigold.com,Proxy\nDOMAIN-SUFFIX,news-af.feednews.com,Proxy\nDOMAIN-SUFFIX,playcool.co,Proxy\nDOMAIN-SUFFIX,tvvtvv.com,Proxy\nDOMAIN-SUFFIX,skimtube.com,Proxy\nDOMAIN-SUFFIX,shadowsocks.asia,Proxy\nDOMAIN-SUFFIX,xiaojiadianmovie.asia,Proxy\nDOMAIN-SUFFIX,888.com,Proxy\nDOMAIN-SUFFIX,oizoblog.com,Proxy\nDOMAIN-SUFFIX,goo.gle,Proxy\nDOMAIN-SUFFIX,www.mahamudra.org.nz,Proxy\nDOMAIN-SUFFIX,www2.yasegg.com,Proxy\nDOMAIN-SUFFIX,campaignforuyghurs.org,Proxy\nDOMAIN-SUFFIX,vpn.com,Proxy\nDOMAIN-SUFFIX,www.383645.com,Proxy\nDOMAIN-SUFFIX,twilightsex.com,Proxy\nDOMAIN-SUFFIX,www.sensivini.com,Proxy\nDOMAIN-SUFFIX,insomnia247.nl,Proxy\nDOMAIN-SUFFIX,www.flower-agri.com,Proxy\nDOMAIN-SUFFIX,www.lionsroar.com,Proxy\nDOMAIN-SUFFIX,ieemdai.spaces.live.com,Proxy\nDOMAIN-SUFFIX,page.bid.yahoo.com,Proxy\nDOMAIN-SUFFIX,shvpn.com,Proxy\nDOMAIN-SUFFIX,www.socialism.hk,Proxy\nDOMAIN-SUFFIX,h1388.com,Proxy\nDOMAIN-SUFFIX,nitter.winscloud.net,Proxy\nDOMAIN-SUFFIX,xunzhaoshiliantongzhi.github.io,Proxy\nDOMAIN-SUFFIX,discuss.python.org,Proxy\nDOMAIN-SUFFIX,www.7117dd.com,Proxy\nDOMAIN-SUFFIX,as0011.com,Proxy\nDOMAIN-SUFFIX,fastestvpn.com,Proxy\nDOMAIN-SUFFIX,mdr18.com,Proxy\nDOMAIN-SUFFIX,www.ry99.com,Proxy\nDOMAIN-SUFFIX,d1pe5bii6cq59.cloudfront.net,Proxy\nDOMAIN-SUFFIX,pauldelongcpa.com,Proxy\nDOMAIN-SUFFIX,mst.ai,Proxy\nDOMAIN-SUFFIX,wikiversity.org,Proxy\nDOMAIN-SUFFIX,bellabox.com.au,Proxy\nDOMAIN-SUFFIX,www.busjav.cc,Proxy\nDOMAIN-SUFFIX,portugal4u.pt,Proxy\nDOMAIN-SUFFIX,amcas.org,Proxy\nDOMAIN-SUFFIX,www.nyfalls.com,Proxy\nDOMAIN-SUFFIX,foxtang.com,Proxy\nDOMAIN-SUFFIX,www.dynup.net,Proxy\nDOMAIN-SUFFIX,mariecallenders.com,Proxy\nDOMAIN-SUFFIX,studentsexparties.com,Proxy\nDOMAIN-SUFFIX,cdn.anycast.eu.org,Proxy\nDOMAIN-SUFFIX,redtube.com.br,Proxy\nDOMAIN-SUFFIX,pixiv.cat,Proxy\nDOMAIN-SUFFIX,6cqgd.com,Proxy\nDOMAIN-SUFFIX,cattide.com,Proxy\nDOMAIN-SUFFIX,j32aa.com,Proxy\nDOMAIN-SUFFIX,www.parkeschampionpost.com.au,Proxy\nDOMAIN-SUFFIX,www.5d7y.net,Proxy\nDOMAIN-SUFFIX,www.state.nm.us,Proxy\nDOMAIN-SUFFIX,lex.idv.tw,Proxy\nDOMAIN-SUFFIX,nylonstockingsonline.com,Proxy\nDOMAIN-SUFFIX,vtunnel.com,Proxy\nDOMAIN-SUFFIX,mimiai.net,Proxy\nDOMAIN-SUFFIX,www.weixianghost.com,Proxy\nDOMAIN-SUFFIX,daili39.com,Proxy\nDOMAIN-SUFFIX,whsmith.co.uk,Proxy\nDOMAIN-SUFFIX,d2wcnv22o4lmnt.cloudfront.net,Proxy\nDOMAIN-SUFFIX,askjeeves.com,Proxy\nDOMAIN-SUFFIX,jinbo989898.com,Proxy\nDOMAIN-SUFFIX,geocities.co.jp,Proxy\nDOMAIN-SUFFIX,socrec.org,Proxy\nDOMAIN-SUFFIX,tankionline.com,Proxy\nDOMAIN-SUFFIX,waiguoaccelerator.org,Proxy\nDOMAIN-SUFFIX,bi-si999.xyz,Proxy\nDOMAIN-SUFFIX,ld77.tv,Proxy\nDOMAIN-SUFFIX,mingbairen.com.au,Proxy\nDOMAIN-SUFFIX,henet.icu,Proxy\nDOMAIN-SUFFIX,brannans.org,Proxy\nDOMAIN-SUFFIX,000webhost.com,Proxy\nDOMAIN-SUFFIX,misskey.io,Proxy\nDOMAIN-SUFFIX,www.nubiles.net,Proxy\nDOMAIN-SUFFIX,hga025.com,Proxy\nDOMAIN-SUFFIX,bestproxylist.com,Proxy\nDOMAIN-SUFFIX,twreporter.org,Proxy\nDOMAIN-SUFFIX,ihopkc.org,Proxy\nDOMAIN-SUFFIX,www.my188.com,Proxy\nDOMAIN-SUFFIX,freetibet.com,Proxy\nDOMAIN-SUFFIX,usmagazine.com,Proxy\nDOMAIN-SUFFIX,b20104.com,Proxy\nDOMAIN-SUFFIX,emaga.com,Proxy\nDOMAIN-SUFFIX,www.456787c.com,Proxy\nDOMAIN-SUFFIX,madresestresadas.com,Proxy\nDOMAIN-SUFFIX,www.tnhsub.com,Proxy\nDOMAIN-SUFFIX,tibetanjournal.com,Proxy\nDOMAIN-SUFFIX,nd.joyphoto.ro,Proxy\nDOMAIN-SUFFIX,www.wardchurch.org,Proxy\nDOMAIN-SUFFIX,pepeempanadas.be,Proxy\nDOMAIN-SUFFIX,www.mail.aol.com,Proxy\nDOMAIN-SUFFIX,cereim.com,Proxy\nDOMAIN-SUFFIX,soonnight.com,Proxy\nDOMAIN-SUFFIX,app.airdata.com,Proxy\nDOMAIN-SUFFIX,google.cl,Proxy\nDOMAIN-SUFFIX,hechaji.com,Proxy\nDOMAIN-SUFFIX,wiki.chinapedia.org,Proxy\nDOMAIN-SUFFIX,www.lweb14.twmail.cc,Proxy\nDOMAIN-SUFFIX,zhongguotese.net,Proxy\nDOMAIN-SUFFIX,huanghuagang.org,Proxy\nDOMAIN-SUFFIX,pobieramy.top,Proxy\nDOMAIN-SUFFIX,www.dalailamasandiego.org,Proxy\nDOMAIN-SUFFIX,fastdog.cc,Proxy\nDOMAIN-SUFFIX,mdsqd02.com,Proxy\nDOMAIN-SUFFIX,tweetphoto.com,Proxy\nDOMAIN-SUFFIX,ferreroperotti.com.ar,Proxy\nDOMAIN-SUFFIX,diggingtunnels.com,Proxy\nDOMAIN-SUFFIX,358nn.com,Proxy\nDOMAIN-SUFFIX,shat-tibet.com,Proxy\nDOMAIN-SUFFIX,china5000.us,Proxy\nDOMAIN-SUFFIX,junau.com,Proxy\nDOMAIN-SUFFIX,www.leyicai666.com,Proxy\nDOMAIN-SUFFIX,sunporno.com,Proxy\nDOMAIN-SUFFIX,hkjam.com,Proxy\nDOMAIN-SUFFIX,68799.net,Proxy\nDOMAIN-SUFFIX,www.19371949.net,Proxy\nDOMAIN-SUFFIX,www.jamiesonvitamins.com,Proxy\nDOMAIN-SUFFIX,virtuozzo.com,Proxy\nDOMAIN-SUFFIX,abc.sytq.net,Proxy\nDOMAIN-SUFFIX,miaopu.tk,Proxy\nDOMAIN-SUFFIX,ysl888.cd77.net,Proxy\nDOMAIN-SUFFIX,www.nude-gals.com,Proxy\nDOMAIN-SUFFIX,www.mgm132.net,Proxy\nDOMAIN-SUFFIX,liquiditytp.com,Proxy\nDOMAIN-SUFFIX,tlinks.run,Proxy\nDOMAIN-SUFFIX,d3d2609eouseq3.cloudfront.net,Proxy\nDOMAIN-SUFFIX,612fund.hk,Proxy\nDOMAIN-SUFFIX,riseup.com,Proxy\nDOMAIN-SUFFIX,guardiandirect.com,Proxy\nDOMAIN-SUFFIX,www.baike14.com,Proxy\nDOMAIN-SUFFIX,angli.com.au,Proxy\nDOMAIN-SUFFIX,dlsh.66.flnet.org,Proxy\nDOMAIN-SUFFIX,www.maannews.net,Proxy\nDOMAIN-SUFFIX,china3m.jpn.com,Proxy\nDOMAIN-SUFFIX,vpnhx.com,Proxy\nDOMAIN-SUFFIX,playbeasts.com,Proxy\nDOMAIN-SUFFIX,www.google.iq,Proxy\nDOMAIN-SUFFIX,82.cr.rs,Proxy\nDOMAIN-SUFFIX,www.22msc.com,Proxy\nDOMAIN-SUFFIX,signalhfx.ca,Proxy\nDOMAIN-SUFFIX,machotube.tv,Proxy\nDOMAIN-SUFFIX,7377.com,Proxy\nDOMAIN-SUFFIX,smigit.com,Proxy\nDOMAIN-SUFFIX,myiphide.com,Proxy\nDOMAIN-SUFFIX,dev.viewtube.io,Proxy\nDOMAIN-SUFFIX,davapc1.bioch.dundee.ac.uk,Proxy\nDOMAIN-SUFFIX,voa.com,Proxy\nDOMAIN-SUFFIX,crossthewall.net,Proxy\nDOMAIN-SUFFIX,ortus.rtu.lv,Proxy\nDOMAIN-SUFFIX,ntdtv.com.tw,Proxy\nDOMAIN-SUFFIX,bloomberg.com,Proxy\nDOMAIN-SUFFIX,www.188letou.com,Proxy\nDOMAIN-SUFFIX,dev-gameservice-v2.firebaseio.com,Proxy\nDOMAIN-SUFFIX,xh7yy.com,Proxy\nDOMAIN-SUFFIX,videosurf.com,Proxy\nDOMAIN-SUFFIX,jointcrypto.com,Proxy\nDOMAIN-SUFFIX,wk.etowns.net,Proxy\nDOMAIN-SUFFIX,robustnessiskey.com,Proxy\nDOMAIN-SUFFIX,archiveofourown.xyz,Proxy\nDOMAIN-SUFFIX,vpnpick.com,Proxy\nDOMAIN-SUFFIX,www.linkyoutube.com,Proxy\nDOMAIN-SUFFIX,www.iwin856.com,Proxy\nDOMAIN-SUFFIX,808879.cc,Proxy\nDOMAIN-SUFFIX,horizon-entertainment.com,Proxy\nDOMAIN-SUFFIX,pbassociates.biz,Proxy\nDOMAIN-SUFFIX,telegre.at,Proxy\nDOMAIN-SUFFIX,bb-chat.tv,Proxy\nDOMAIN-SUFFIX,khilok.ru,Proxy\nDOMAIN-SUFFIX,top5.ga,Proxy\nDOMAIN-SUFFIX,tube.com,Proxy\nDOMAIN-SUFFIX,resilio.com,Proxy\nDOMAIN-SUFFIX,linshiyouxiang.net,Proxy\nDOMAIN-SUFFIX,iloveallaah.com,Proxy\nDOMAIN-SUFFIX,fastdog.app,Proxy\nDOMAIN-SUFFIX,www.299hk.com,Proxy\nDOMAIN-SUFFIX,www.flutrackers.com,Proxy\nDOMAIN-SUFFIX,borgenmagazine.com,Proxy\nDOMAIN-SUFFIX,nyesek.com,Proxy\nDOMAIN-SUFFIX,koreafish.co.kr,Proxy\nDOMAIN-SUFFIX,cougarsexclub.com,Proxy\nDOMAIN-SUFFIX,btio.pw,Proxy\nDOMAIN-SUFFIX,orkut.com,Proxy\nDOMAIN-SUFFIX,www.szgay.net,Proxy\nDOMAIN-SUFFIX,freealim.com,Proxy\nDOMAIN-SUFFIX,trust.zone,Proxy\nDOMAIN-SUFFIX,tue.nl,Proxy\nDOMAIN-SUFFIX,www.8muses.com,Proxy\nDOMAIN-SUFFIX,gb.net,Proxy\nDOMAIN-SUFFIX,sports.188asia.com,Proxy\nDOMAIN-SUFFIX,www.sinostand.com,Proxy\nDOMAIN-SUFFIX,getnaijajob.blogspot.hk,Proxy\nDOMAIN-SUFFIX,polymerhk.com,Proxy\nDOMAIN-SUFFIX,send.firefox.com,Proxy\nDOMAIN-SUFFIX,mygod.tk,Proxy\nDOMAIN-SUFFIX,10qiu.com,Proxy\nDOMAIN-SUFFIX,www.cool18.com,Proxy\nDOMAIN-SUFFIX,blogspot.jp,Proxy\nDOMAIN-SUFFIX,www.xunread.com,Proxy\nDOMAIN-SUFFIX,businesstoday.com.tw,Proxy\nDOMAIN-SUFFIX,www.xw266.com,Proxy\nDOMAIN-SUFFIX,equinenow.com,Proxy\nDOMAIN-SUFFIX,www.zimuzu.com,Proxy\nDOMAIN-SUFFIX,www.yourdicklooksgreatinthoseheels.com,Proxy\nDOMAIN-SUFFIX,btcbank.bank,Proxy\nDOMAIN-SUFFIX,d2cvld8j44ztkj.cloudfront.net,Proxy\nDOMAIN-SUFFIX,neraex.pro,Proxy\nDOMAIN-SUFFIX,nfap.com,Proxy\nDOMAIN-SUFFIX,www.sanmin.com.tw,Proxy\nDOMAIN-SUFFIX,www.youtube.cl,Proxy\nDOMAIN-SUFFIX,liveclass.fr,Proxy\nDOMAIN-SUFFIX,10conditionsoflove.com,Proxy\nDOMAIN-SUFFIX,hctax.net,Proxy\nDOMAIN-SUFFIX,tibetdata.github.io,Proxy\nDOMAIN-SUFFIX,hyp.deaftone.com,Proxy\nDOMAIN-SUFFIX,www.kingcanholdings.com,Proxy\nDOMAIN-SUFFIX,eraysoft.com.tr,Proxy\nDOMAIN-SUFFIX,www.xh8715.com,Proxy\nDOMAIN-SUFFIX,yuanpingan.com,Proxy\nDOMAIN-SUFFIX,www.9x9.tw,Proxy\nDOMAIN-SUFFIX,vpn.cmu.edu,Proxy\nDOMAIN-SUFFIX,popcornsupply.com,Proxy\nDOMAIN-SUFFIX,bbsxv.xyz,Proxy\nDOMAIN-SUFFIX,b6363.com,Proxy\nDOMAIN-SUFFIX,dropcam.com,Proxy\nDOMAIN-SUFFIX,www.kvmdtv.com,Proxy\nDOMAIN-SUFFIX,portal.juliuscentrum.nl,Proxy\nDOMAIN-SUFFIX,cubelish.com.tw,Proxy\nDOMAIN-SUFFIX,econ.st,Proxy\nDOMAIN-SUFFIX,okayfreedom.com,Proxy\nDOMAIN-SUFFIX,c4v6d7v3.stackpathcdn.com,Proxy\nDOMAIN-SUFFIX,unification.org,Proxy\nDOMAIN-SUFFIX,missliberty.com,Proxy\nDOMAIN-SUFFIX,www.learnfalungong.com,Proxy\nDOMAIN-SUFFIX,dabr.me,Proxy\nDOMAIN-SUFFIX,driannini.com.br,Proxy\nDOMAIN-SUFFIX,tibetanyouthcongress.org,Proxy\nDOMAIN-SUFFIX,ficer.com.ar,Proxy\nDOMAIN-SUFFIX,gamousa.com,Proxy\nDOMAIN-SUFFIX,lantern2.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,oann.com,Proxy\nDOMAIN-SUFFIX,privatetunnel.com,Proxy\nDOMAIN-SUFFIX,91vyy.com,Proxy\nDOMAIN-SUFFIX,llss.bz,Proxy\nDOMAIN-SUFFIX,www.fastmail.com,Proxy\nDOMAIN-SUFFIX,faluninfo.pl,Proxy\nDOMAIN-SUFFIX,erabaru.net,Proxy\nDOMAIN-SUFFIX,purpose.nike.com,Proxy\nDOMAIN-SUFFIX,suprememastertv.com,Proxy\nDOMAIN-SUFFIX,188jinbi.com,Proxy\nDOMAIN-SUFFIX,jb98955.com,Proxy\nDOMAIN-SUFFIX,tportal.hr,Proxy\nDOMAIN-SUFFIX,socks-mall.com,Proxy\nDOMAIN-SUFFIX,www.unodedos.com,Proxy\nDOMAIN-SUFFIX,dns.quad9.net,Proxy\nDOMAIN-SUFFIX,www.490tv.com,Proxy\nDOMAIN-SUFFIX,wyv68.xyz,Proxy\nDOMAIN-SUFFIX,mitao.com.tw,Proxy\nDOMAIN-SUFFIX,www.letstalk.net,Proxy\nDOMAIN-SUFFIX,www2.onleihe.de,Proxy\nDOMAIN-SUFFIX,gmi-gaming.com,Proxy\nDOMAIN-SUFFIX,www.digitalfreedomfund.org,Proxy\nDOMAIN-SUFFIX,www.fileshare.ro,Proxy\nDOMAIN-SUFFIX,stargate.one,Proxy\nDOMAIN-SUFFIX,www.kapwing.com,Proxy\nDOMAIN-SUFFIX,todon.nl,Proxy\nDOMAIN-SUFFIX,www.yamagata-np.jp,Proxy\nDOMAIN-SUFFIX,elecmas.cl,Proxy\nDOMAIN-SUFFIX,public.dns.iij.jp,Proxy\nDOMAIN-SUFFIX,singfortibet.com,Proxy\nDOMAIN-SUFFIX,forum.xinbao.de,Proxy\nDOMAIN-SUFFIX,cupfox.app,Proxy\nDOMAIN-SUFFIX,hrwf.eu,Proxy\nDOMAIN-SUFFIX,www.terrorism-info.org.il,Proxy\nDOMAIN-SUFFIX,oclp.hk,Proxy\nDOMAIN-SUFFIX,849cp6.top,Proxy\nDOMAIN-SUFFIX,aa6789.com,Proxy\nDOMAIN-SUFFIX,ghmz.org,Proxy\nDOMAIN-SUFFIX,unfetteredmind.org,Proxy\nDOMAIN-SUFFIX,sport24.co.za,Proxy\nDOMAIN-SUFFIX,phx.e-carms.ca,Proxy\nDOMAIN-SUFFIX,gfw.report,Proxy\nDOMAIN-SUFFIX,xh13333.com,Proxy\nIP-CIDR,174.142.105.153/32,Proxy\nDOMAIN-SUFFIX,becktothegarden.com,Proxy\nDOMAIN-SUFFIX,m.huaren4us.com,Proxy\nDOMAIN-SUFFIX,98198v.com,Proxy\nDOMAIN-SUFFIX,twitturly.com,Proxy\nDOMAIN-SUFFIX,vital247.org,Proxy\nDOMAIN-SUFFIX,huc44.com,Proxy\nDOMAIN-SUFFIX,10c.pat.flnet.org,Proxy\nDOMAIN-SUFFIX,www.digiket.com,Proxy\nDOMAIN-SUFFIX,lds52mm.com,Proxy\nDOMAIN-SUFFIX,erktv.com,Proxy\nDOMAIN-SUFFIX,biz.crast.net,Proxy\nDOMAIN-SUFFIX,www.tribune.net.ph,Proxy\nDOMAIN-SUFFIX,v6565.com,Proxy\nDOMAIN-SUFFIX,i.forbesimg.com,Proxy\nDOMAIN-SUFFIX,www56.eyny.com,Proxy\nDOMAIN-SUFFIX,antyweb.pl,Proxy\nDOMAIN-SUFFIX,from-nc.com,Proxy\nDOMAIN-SUFFIX,sjhs02.com,Proxy\nDOMAIN-SUFFIX,tv22.infos.st,Proxy\nDOMAIN-SUFFIX,darisungaiderhaka.blogspot.hk,Proxy\nDOMAIN-SUFFIX,nalandawest.org,Proxy\nDOMAIN-SUFFIX,gowalla.com,Proxy\nDOMAIN-SUFFIX,blogspot.co.nz,Proxy\nDOMAIN-SUFFIX,bypassthe.net,Proxy\nDOMAIN-SUFFIX,hcc.flnet.org,Proxy\nDOMAIN-SUFFIX,8601234.com,Proxy\nDOMAIN-SUFFIX,globaleast.org,Proxy\nDOMAIN-SUFFIX,port25.biz,Proxy\nDOMAIN-SUFFIX,www.c2552.com,Proxy\nDOMAIN-SUFFIX,sinomontreal.ca,Proxy\nDOMAIN-SUFFIX,uyghurpress.com,Proxy\nDOMAIN-SUFFIX,entrecopas.com.ar,Proxy\nDOMAIN-SUFFIX,www.ntdvn.com,Proxy\nDOMAIN-SUFFIX,3048094784.com,Proxy\nDOMAIN-SUFFIX,pornfromcz.com,Proxy\nDOMAIN-SUFFIX,shaoshuren.org,Proxy\nDOMAIN-SUFFIX,56xtv.com,Proxy\nDOMAIN-SUFFIX,www.deutschegrammophon.com,Proxy\nDOMAIN-SUFFIX,bronzwellington.org.nz,Proxy\nDOMAIN-SUFFIX,matome-plus.net,Proxy\nDOMAIN-SUFFIX,waiwaier.com,Proxy\nDOMAIN-SUFFIX,www.getvy.net,Proxy\nDOMAIN-SUFFIX,drciocan.ro,Proxy\nDOMAIN-SUFFIX,pawoo.net,Proxy\nDOMAIN-SUFFIX,yhcw.net,Proxy\nDOMAIN-SUFFIX,rue89.nouvelobs.com,Proxy\nDOMAIN-SUFFIX,modpingouin.free.fr,Proxy\nDOMAIN-SUFFIX,linkinglizard.com,Proxy\nDOMAIN-SUFFIX,ehc.ac,Proxy\nDOMAIN-SUFFIX,www.epochweek.com,Proxy\nDOMAIN-SUFFIX,www.javdog.com,Proxy\nDOMAIN-SUFFIX,clinica-tibet.ru,Proxy\nDOMAIN-SUFFIX,lovematterschina.com,Proxy\nDOMAIN-SUFFIX,feeder.com,Proxy\nDOMAIN-SUFFIX,cloud111.top,Proxy\nDOMAIN-SUFFIX,scoan.org,Proxy\nDOMAIN-SUFFIX,socialprogress.org,Proxy\nDOMAIN-SUFFIX,www.ckcoinpro.cn,Proxy\nDOMAIN-SUFFIX,a.pemsrv.com,Proxy\nDOMAIN-SUFFIX,51luoben.com,Proxy\nDOMAIN-SUFFIX,bex.cl,Proxy\nDOMAIN-SUFFIX,mpfinance.com,Proxy\nDOMAIN-SUFFIX,kingclub.com.tw,Proxy\nDOMAIN-SUFFIX,teapartycommunity.com,Proxy\nDOMAIN-SUFFIX,dsn501.com,Proxy\nDOMAIN-SUFFIX,proxyserver.asia,Proxy\nDOMAIN-SUFFIX,citiesskylines2.com,Proxy\nDOMAIN-SUFFIX,startup-ecosystem.compass.co,Proxy\nDOMAIN-SUFFIX,kosdaqca.or.kr,Proxy\nDOMAIN-SUFFIX,mullvad.net,Proxy\nDOMAIN-SUFFIX,stheadline.com,Proxy\nDOMAIN-SUFFIX,www.daigobang.com,Proxy\nDOMAIN-SUFFIX,276ww.com,Proxy\nDOMAIN-SUFFIX,fuq.ink,Proxy\nDOMAIN-SUFFIX,xs.domain888.pw,Proxy\nDOMAIN-SUFFIX,adcex.com,Proxy\nDOMAIN-SUFFIX,globalmediaoutreach.com,Proxy\nDOMAIN-SUFFIX,wowfans.digwow.com,Proxy\nDOMAIN-SUFFIX,uyghurstudies.org,Proxy\nDOMAIN-SUFFIX,openstreetmap.org,Proxy\nDOMAIN-SUFFIX,www.younewporn.com,Proxy\nDOMAIN-SUFFIX,www1.downsx.com,Proxy\nDOMAIN-SUFFIX,onlybl.xyz,Proxy\nDOMAIN-SUFFIX,www.hindupost.in,Proxy\nDOMAIN-SUFFIX,h5.ld073.com,Proxy\nDOMAIN-SUFFIX,gajahmadafm.co.id,Proxy\nDOMAIN-SUFFIX,shambhalasun.com,Proxy\nDOMAIN-SUFFIX,zzy.namedns.xyz,Proxy\nDOMAIN-SUFFIX,dhnq96zntgnq1.cloudfront.net,Proxy\nDOMAIN-SUFFIX,maskedip.com,Proxy\nDOMAIN-SUFFIX,whodns.xyz,Proxy\nDOMAIN-SUFFIX,jingyindao.com,Proxy\nDOMAIN-SUFFIX,minetcraft.chickenkiller.com,Proxy\nDOMAIN-SUFFIX,www.departuresvpn.tk,Proxy\nDOMAIN-SUFFIX,www.timewarner.com,Proxy\nDOMAIN-SUFFIX,myfreepaysite.com,Proxy\nDOMAIN-SUFFIX,chinese.javmodel.com,Proxy\nDOMAIN-SUFFIX,999102.com,Proxy\nDOMAIN-SUFFIX,baiduyun.wiki,Proxy\nDOMAIN-SUFFIX,evschool.net,Proxy\nDOMAIN-SUFFIX,hongkongfp.com,Proxy\nDOMAIN-SUFFIX,rfahls-i.akamaihd.net,Proxy\nDOMAIN-SUFFIX,dailydripper.com,Proxy\nDOMAIN-SUFFIX,www.tsgh.ndmctsgh.edu.tw,Proxy\nDOMAIN-SUFFIX,www1.cgmh.org.tw,Proxy\nDOMAIN-SUFFIX,www.bizuyghur.net,Proxy\nDOMAIN-SUFFIX,ap.gg626.com,Proxy\nDOMAIN-SUFFIX,redvos.com,Proxy\nDOMAIN-SUFFIX,www.theweek.co.uk,Proxy\nDOMAIN-SUFFIX,www.v968.net,Proxy\nDOMAIN-SUFFIX,www.tien-i.com,Proxy\nDOMAIN-SUFFIX,www.bfsforex.com,Proxy\nDOMAIN-SUFFIX,www.hokkaido-np.co.jp,Proxy\nDOMAIN-SUFFIX,lagranepoca.com,Proxy\nDOMAIN-SUFFIX,rieasagiri2008.kir.jp,Proxy\nDOMAIN-SUFFIX,ntdtv.org,Proxy\nDOMAIN-SUFFIX,011f011.com,Proxy\nDOMAIN-SUFFIX,0mag.net,Proxy\nDOMAIN-SUFFIX,www.03038.com,Proxy\nDOMAIN-SUFFIX,ja.wikipedia.org,Proxy\nDOMAIN-SUFFIX,nrtshoes.com.br,Proxy\nDOMAIN-SUFFIX,www.ssfpp.tw,Proxy\nDOMAIN-SUFFIX,www.xxshe.xyz,Proxy\nDOMAIN-SUFFIX,2dway.com,Proxy\nDOMAIN-SUFFIX,www.enanyang.my,Proxy\nDOMAIN-SUFFIX,dw.com,Proxy\nDOMAIN-SUFFIX,gequ888.com,Proxy\nDOMAIN-SUFFIX,login.jw.org,Proxy\nDOMAIN-SUFFIX,wow-life.net,Proxy\nDOMAIN-SUFFIX,youtour.withgoogle.com,Proxy\nDOMAIN-SUFFIX,yiqiedoushiganggangkaishi.org,Proxy\nDOMAIN-SUFFIX,falundafa.org,Proxy\nDOMAIN-SUFFIX,mega.io,Proxy\nDOMAIN-SUFFIX,www.x1m1global.net,Proxy\nDOMAIN-SUFFIX,www.ivpncup.me,Proxy\nDOMAIN-SUFFIX,www.bet36530000.com,Proxy\nDOMAIN-SUFFIX,freevideo.cz,Proxy\nDOMAIN-SUFFIX,rdwwm.site,Proxy\nDOMAIN-SUFFIX,twblogger.com,Proxy\nDOMAIN-SUFFIX,66go.net,Proxy\nDOMAIN-SUFFIX,acg-moe.com,Proxy\nDOMAIN-SUFFIX,cristyli.com,Proxy\nDOMAIN-SUFFIX,www.xumin.cc,Proxy\nDOMAIN-SUFFIX,blockedbyhk.com,Proxy\nDOMAIN-SUFFIX,gaynetwork.co.uk,Proxy\nDOMAIN-SUFFIX,www.rb8807.com,Proxy\nDOMAIN-SUFFIX,teleconomiser.com,Proxy\nDOMAIN-SUFFIX,blogbeast.com,Proxy\nDOMAIN-SUFFIX,dailymotion.com,Proxy\nDOMAIN-SUFFIX,dgxmusic.com,Proxy\nDOMAIN-SUFFIX,arethusa.su,Proxy\nDOMAIN-SUFFIX,mtslash.me,Proxy\nDOMAIN-SUFFIX,kyodo-d.jp,Proxy\nDOMAIN-SUFFIX,imagic.ntue.edu.tw,Proxy\nDOMAIN-SUFFIX,aa228.net,Proxy\nDOMAIN-SUFFIX,www.teamrock.com,Proxy\nDOMAIN-SUFFIX,jameshenson.net,Proxy\nDOMAIN-SUFFIX,css5.tk,Proxy\nDOMAIN-SUFFIX,fitnessmania.gr,Proxy\nDOMAIN-SUFFIX,doh.mmmalia.com,Proxy\nDOMAIN-SUFFIX,restaurantgraf.ro,Proxy\nDOMAIN-SUFFIX,croxyproxy.com,Proxy\nDOMAIN-SUFFIX,www.blisswisdom.org,Proxy\nDOMAIN-SUFFIX,reddit.app.link,Proxy\nDOMAIN-SUFFIX,etherality.com,Proxy\nDOMAIN-SUFFIX,n0.eac9f1fc.net,Proxy\nDOMAIN-SUFFIX,www.nolord.com,Proxy\nDOMAIN-SUFFIX,m5.com,Proxy\nDOMAIN-SUFFIX,woodhome.us,Proxy\nDOMAIN-SUFFIX,www.gliocchidellaguerra.it,Proxy\nDOMAIN-SUFFIX,hkchronicles.com,Proxy\nDOMAIN-SUFFIX,qkan8.com,Proxy\nDOMAIN-SUFFIX,f35.flnet.org,Proxy\nDOMAIN-SUFFIX,26.suroot.com,Proxy\nDOMAIN-SUFFIX,spem.at,Proxy\nDOMAIN-SUFFIX,www.hs8881.com,Proxy\nDOMAIN-SUFFIX,easyca.ca,Proxy\nDOMAIN-SUFFIX,landing.hentaiheroes.com,Proxy\nDOMAIN-SUFFIX,mail.lumimodule.com,Proxy\nDOMAIN-SUFFIX,xxbook.cc,Proxy\nDOMAIN-SUFFIX,infogalactic.com,Proxy\nDOMAIN-SUFFIX,xh0016.com,Proxy\nDOMAIN-SUFFIX,iwantavnow.com,Proxy\nDOMAIN-SUFFIX,www.epost.de,Proxy\nDOMAIN-SUFFIX,lttstore.com,Proxy\nDOMAIN-SUFFIX,omni7.jp,Proxy\nDOMAIN-SUFFIX,flipbizz-prod.firebaseio.com,Proxy\nDOMAIN-SUFFIX,zzf.healthins.xyz,Proxy\nDOMAIN-SUFFIX,www.radmin-vpn.com,Proxy\nDOMAIN-SUFFIX,91vps.club,Proxy\nDOMAIN-SUFFIX,tamretail.com,Proxy\nDOMAIN-SUFFIX,warning.news,Proxy\nDOMAIN-SUFFIX,hk.gradconnection.com,Proxy\nDOMAIN-SUFFIX,dotsub.com,Proxy\nDOMAIN-SUFFIX,febcchinese.com,Proxy\nDOMAIN-SUFFIX,news.zerkalo.io,Proxy\nDOMAIN-SUFFIX,e-classical.com.tw,Proxy\nDOMAIN-SUFFIX,adam.mx,Proxy\nDOMAIN-SUFFIX,zith.us,Proxy\nDOMAIN-SUFFIX,teco-mo.org,Proxy\nDOMAIN-SUFFIX,a66aa.com,Proxy\nDOMAIN-SUFFIX,andfaraway.net,Proxy\nDOMAIN-SUFFIX,624663.com,Proxy\nDOMAIN-SUFFIX,vl.woozy.dev,Proxy\nDOMAIN-SUFFIX,allfacebook.de,Proxy\nDOMAIN-SUFFIX,google.jp,Proxy\nDOMAIN-SUFFIX,www.tbsseattle.org,Proxy\nDOMAIN-SUFFIX,tccwonline.org,Proxy\nDOMAIN-SUFFIX,loepfe.org,Proxy\nDOMAIN-SUFFIX,cs2.24241872.site,Proxy\nDOMAIN-SUFFIX,dvu3e8bos1auj.cloudfront.net,Proxy\nDOMAIN-SUFFIX,walderviolin.com,Proxy\nDOMAIN-SUFFIX,thepiratebay.einnews.com,Proxy\nDOMAIN-SUFFIX,hyc1324.xyz,Proxy\nDOMAIN-SUFFIX,sciowl.club,Proxy\nDOMAIN-SUFFIX,avlang.com,Proxy\nDOMAIN-SUFFIX,travian.it,Proxy\nDOMAIN-SUFFIX,99006a.com,Proxy\nDOMAIN-SUFFIX,uwants.com.hk,Proxy\nDOMAIN-SUFFIX,www.cipe.org,Proxy\nDOMAIN-SUFFIX,universaluclick.com,Proxy\nDOMAIN-SUFFIX,nylon-angel.com,Proxy\nDOMAIN-SUFFIX,hjf0d.com,Proxy\nDOMAIN-SUFFIX,uda-web-app-service-ptjda2qd6q-uc.a.run.app,Proxy\nDOMAIN-SUFFIX,atlaspost.com,Proxy\nDOMAIN-SUFFIX,wavpn.com,Proxy\nDOMAIN-SUFFIX,taiwannews.com.tw,Proxy\nDOMAIN-SUFFIX,www.bikiniriot.com,Proxy\nDOMAIN-SUFFIX,globalfirepower.com,Proxy\nDOMAIN-SUFFIX,cogniti.xyz,Proxy\nDOMAIN-SUFFIX,coinex.com,Proxy\nDOMAIN-SUFFIX,qiangui678.com,Proxy\nDOMAIN-SUFFIX,tweetmylast.fm,Proxy\nDOMAIN-SUFFIX,blog.exblog.co.jp,Proxy\nDOMAIN-SUFFIX,dio168.net,Proxy\nDOMAIN-SUFFIX,www.crossvpn.org,Proxy\nDOMAIN-SUFFIX,rb88help.com,Proxy\nDOMAIN-SUFFIX,m.crackle.com,Proxy\nDOMAIN-SUFFIX,fanqianghou.com,Proxy\nDOMAIN-SUFFIX,iteke.ml,Proxy\nDOMAIN-SUFFIX,dustdrops.blogspot.hk,Proxy\nDOMAIN-SUFFIX,319o.4.688.org,Proxy\nDOMAIN-SUFFIX,google.co.nz,Proxy\nDOMAIN-SUFFIX,www.yc6336.com,Proxy\nDOMAIN-SUFFIX,www.tube4u.com,Proxy\nDOMAIN-SUFFIX,www.vgp.de,Proxy\nDOMAIN-SUFFIX,laogaimuseum.org,Proxy\nDOMAIN-SUFFIX,splashnews.com,Proxy\nDOMAIN-SUFFIX,ln.sync.com,Proxy\nDOMAIN-SUFFIX,ccthere.net,Proxy\nDOMAIN-SUFFIX,www.paofuyun.me,Proxy\nDOMAIN-SUFFIX,www.69shu.com,Proxy\nDOMAIN-SUFFIX,peersfer.com,Proxy\nDOMAIN-SUFFIX,au.pool.ntp.org,Proxy\nDOMAIN-SUFFIX,southpark.cc.com,Proxy\nDOMAIN-SUFFIX,195770.com,Proxy\nDOMAIN-SUFFIX,67.ddnsking.com,Proxy\nDOMAIN-SUFFIX,csdc111.com,Proxy\nDOMAIN-SUFFIX,newgrounds.com,Proxy\nDOMAIN-SUFFIX,bwh1.net,Proxy\nDOMAIN-SUFFIX,frommel.net,Proxy\nDOMAIN-SUFFIX,3636.me,Proxy\nDOMAIN-SUFFIX,cngkfxprime.com,Proxy\nDOMAIN-SUFFIX,marxists.org,Proxy\nDOMAIN-SUFFIX,anyporn.com,Proxy\nDOMAIN-SUFFIX,talk910.com,Proxy\nDOMAIN-SUFFIX,dubox.com,Proxy\nDOMAIN-SUFFIX,csmonitor.com,Proxy\nDOMAIN-SUFFIX,gfsale.com,Proxy\nDOMAIN-SUFFIX,www.hymnal.net,Proxy\nDOMAIN-SUFFIX,www.siruba.com,Proxy\nDOMAIN-SUFFIX,beliefnet.com,Proxy\nDOMAIN-SUFFIX,handong888.com,Proxy\nDOMAIN-SUFFIX,dizhuzhishang.com,Proxy\nDOMAIN-SUFFIX,gap2.cleansite.us,Proxy\nDOMAIN-SUFFIX,cdn.metartnetwork.com,Proxy\nDOMAIN-SUFFIX,www.vulnwatch.org,Proxy\nDOMAIN-SUFFIX,78945633.com,Proxy\nDOMAIN-SUFFIX,hobby-site.com,Proxy\nDOMAIN-SUFFIX,tyyl77.com,Proxy\nDOMAIN-SUFFIX,nitter.unixfox.eu,Proxy\nDOMAIN-SUFFIX,dns.1565.com,Proxy\nDOMAIN-SUFFIX,tubegals.com,Proxy\nDOMAIN-SUFFIX,kadampa-center.org,Proxy\nDOMAIN-SUFFIX,myfreecams.com,Proxy\nDOMAIN-SUFFIX,vertix.cl,Proxy\nDOMAIN-SUFFIX,kycloud.co,Proxy\nDOMAIN-SUFFIX,ssvpn.me,Proxy\nDOMAIN-SUFFIX,www.ft.com,Proxy\nDOMAIN-SUFFIX,3885.com,Proxy\nDOMAIN-SUFFIX,bdg859.com,Proxy\nDOMAIN-SUFFIX,www.journalism.org,Proxy\nDOMAIN-SUFFIX,www.accausa.org,Proxy\nDOMAIN-SUFFIX,rcvpn.com,Proxy\nDOMAIN-SUFFIX,air.lemonawa.xyz,Proxy\nDOMAIN-SUFFIX,c.zr55.us,Proxy\nDOMAIN-SUFFIX,d28q8bz7q2kx4q.cloudfront.net,Proxy\nDOMAIN-SUFFIX,gun.3d-game.com,Proxy\nDOMAIN-SUFFIX,c.ns02.top,Proxy\nDOMAIN-SUFFIX,starvpnapp.com,Proxy\nDOMAIN-SUFFIX,dssd.us,Proxy\nDOMAIN-SUFFIX,iqq.asia,Proxy\nDOMAIN-SUFFIX,mediapart.fr,Proxy\nDOMAIN-SUFFIX,www.2459yhhd.com,Proxy\nDOMAIN-SUFFIX,www.fun909.com,Proxy\nDOMAIN-SUFFIX,niagaracc.suny.edu,Proxy\nDOMAIN-SUFFIX,jmcomic.mobi,Proxy\nDOMAIN-SUFFIX,pk1200.com,Proxy\nDOMAIN-SUFFIX,26268.com,Proxy\nDOMAIN-SUFFIX,slixa.com,Proxy\nDOMAIN-SUFFIX,aavpn.com,Proxy\nDOMAIN-SUFFIX,go.nesnode.com,Proxy\nDOMAIN-SUFFIX,www.4xspeed.net,Proxy\nDOMAIN-SUFFIX,comparis.ch,Proxy\nDOMAIN-SUFFIX,freechina.tech.blog,Proxy\nDOMAIN-SUFFIX,squirrelvpn.com,Proxy\nDOMAIN-SUFFIX,zinio.com,Proxy\nDOMAIN-SUFFIX,blog.jp,Proxy\nDOMAIN-SUFFIX,chatgpt.tool00.com,Proxy\nDOMAIN-SUFFIX,www.appeas.org,Proxy\nDOMAIN-SUFFIX,webcast.gov.in,Proxy\nDOMAIN-SUFFIX,elefante.org,Proxy\nDOMAIN-SUFFIX,www.alqp177.com,Proxy\nDOMAIN-SUFFIX,www.3917800.com,Proxy\nDOMAIN-SUFFIX,mandest.com,Proxy\nDOMAIN-SUFFIX,f95zone.to,Proxy\nDOMAIN-SUFFIX,678168.app,Proxy\nDOMAIN-SUFFIX,tushycash.com,Proxy\nDOMAIN-SUFFIX,cheaper.work,Proxy\nDOMAIN-SUFFIX,shenyunperformingarts.org,Proxy\nDOMAIN-SUFFIX,15x15.cc,Proxy\nDOMAIN-SUFFIX,d2lsncgts5yrhd.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.avhaha.com,Proxy\nDOMAIN-SUFFIX,www.freevpnservers.com,Proxy\nDOMAIN-SUFFIX,wombo.art,Proxy\nDOMAIN-SUFFIX,tor.eff.org,Proxy\nDOMAIN-SUFFIX,oslo.town,Proxy\nDOMAIN-SUFFIX,ganjing.io,Proxy\nDOMAIN-SUFFIX,www.yihenji.com,Proxy\nDOMAIN-SUFFIX,hgseav.com,Proxy\nDOMAIN-SUFFIX,woolyss.com,Proxy\nDOMAIN-SUFFIX,gfbrowse.com,Proxy\nDOMAIN-SUFFIX,is-a-player.com,Proxy\nDOMAIN-SUFFIX,fyt365.com,Proxy\nDOMAIN-SUFFIX,cod8888.com,Proxy\nDOMAIN-SUFFIX,cs.cncn.eu.org,Proxy\nDOMAIN-SUFFIX,www.any0109.com,Proxy\nDOMAIN-SUFFIX,dnx.sg.ekapool.com,Proxy\nDOMAIN-SUFFIX,cw.com.tw,Proxy\nDOMAIN-SUFFIX,p888zz.com,Proxy\nDOMAIN-SUFFIX,www.dongyuxin.com,Proxy\nDOMAIN-SUFFIX,divgearcmrfs2.cloudfront.net,Proxy\nDOMAIN-SUFFIX,beeg.porn,Proxy\nDOMAIN-SUFFIX,pornoid.com,Proxy\nDOMAIN-SUFFIX,velkaepocha.cz,Proxy\nDOMAIN-SUFFIX,10minutemail.net,Proxy\nDOMAIN-SUFFIX,fuckcnnic.net,Proxy\nDOMAIN-SUFFIX,boringart.lt,Proxy\nDOMAIN-SUFFIX,tibet.no,Proxy\nDOMAIN-SUFFIX,surf-chiny.com,Proxy\nDOMAIN-SUFFIX,busbeurs.nl,Proxy\nDOMAIN-SUFFIX,c6633.com,Proxy\nDOMAIN-SUFFIX,www.ponhub.com,Proxy\nDOMAIN-SUFFIX,hd.tv100.us,Proxy\nDOMAIN-SUFFIX,b311457.com,Proxy\nDOMAIN-SUFFIX,d14mrn6lcec9zq.cloudfront.net,Proxy\nDOMAIN-SUFFIX,mastodon.sdf.org,Proxy\nDOMAIN-SUFFIX,www.cppr.in,Proxy\nDOMAIN-SUFFIX,lemmy.ml,Proxy\nDOMAIN-SUFFIX,hwtang.com,Proxy\nDOMAIN-SUFFIX,hca.twimg.com,Proxy\nDOMAIN-SUFFIX,97555vip.com,Proxy\nDOMAIN-SUFFIX,18dj18.com,Proxy\nDOMAIN-SUFFIX,89901.com,Proxy\nDOMAIN-SUFFIX,utahtibetanassociation.org,Proxy\nDOMAIN-SUFFIX,dd57625.btt9.net,Proxy\nDOMAIN-SUFFIX,franche.ca,Proxy\nDOMAIN-SUFFIX,www.tsemrinpoche.com,Proxy\nDOMAIN-SUFFIX,www2.rocketbbs.com,Proxy\nDOMAIN-SUFFIX,gnet-research.org,Proxy\nDOMAIN-SUFFIX,hitv.amtb.tw,Proxy\nDOMAIN-SUFFIX,zonghexinwen.com,Proxy\nDOMAIN-SUFFIX,ca758.com,Proxy\nDOMAIN-SUFFIX,xifailstibet.org,Proxy\nDOMAIN-SUFFIX,tibetpost.net,Proxy\nDOMAIN-SUFFIX,18979.net,Proxy\nDOMAIN-SUFFIX,www.dharmaocean.org,Proxy\nDOMAIN-SUFFIX,www.threes-clever.com.tw,Proxy\nDOMAIN-SUFFIX,mobatek.net,Proxy\nDOMAIN-SUFFIX,www.fox13memphis.com,Proxy\nDOMAIN-SUFFIX,v.surboard.net,Proxy\nDOMAIN-SUFFIX,multiupload.com,Proxy\nDOMAIN-SUFFIX,taiwanncf.org.tw,Proxy\nDOMAIN-SUFFIX,ddrk.me,Proxy\nDOMAIN-SUFFIX,d2bay.com,Proxy\nDOMAIN-SUFFIX,itaeromanga.com,Proxy\nDOMAIN-SUFFIX,www.jybdsm.com,Proxy\nDOMAIN-SUFFIX,everyonedraw.com,Proxy\nDOMAIN-SUFFIX,sopcast.org,Proxy\nDOMAIN-SUFFIX,coin2co.in,Proxy\nDOMAIN-SUFFIX,www.e991.com,Proxy\nDOMAIN-SUFFIX,wikileaks.com,Proxy\nDOMAIN-SUFFIX,milarepacenter.org,Proxy\nDOMAIN-SUFFIX,gifsauce.com,Proxy\nDOMAIN-SUFFIX,jundy.org,Proxy\nDOMAIN-SUFFIX,drepung.org,Proxy\nDOMAIN-SUFFIX,pu6622.com,Proxy\nDOMAIN-SUFFIX,www.csgolounge.com,Proxy\nDOMAIN-SUFFIX,www.zerocensorship.com,Proxy\nDOMAIN-SUFFIX,huhangfei.com,Proxy\nDOMAIN-SUFFIX,www.skipton.co.uk,Proxy\nDOMAIN-SUFFIX,www.ub8one.com,Proxy\nDOMAIN-SUFFIX,homaei.ir,Proxy\nDOMAIN-SUFFIX,youxnxxtube.com,Proxy\nDOMAIN-SUFFIX,whitneyquesenbery.com,Proxy\nDOMAIN-SUFFIX,fastest-proxy.com.de,Proxy\nDOMAIN-SUFFIX,mytinari.etowns.net,Proxy\nDOMAIN-SUFFIX,atrapalo.com,Proxy\nDOMAIN-SUFFIX,unblocksocial.net.3s3s.org,Proxy\nDOMAIN-SUFFIX,jintian.net,Proxy\nDOMAIN-SUFFIX,www.haijiao.com,Proxy\nDOMAIN-SUFFIX,fapdu.com,Proxy\nDOMAIN-SUFFIX,dsn2272.com,Proxy\nDOMAIN-SUFFIX,www.dolopo.net,Proxy\nDOMAIN-SUFFIX,tibet.fr,Proxy\nDOMAIN-SUFFIX,sharecool.org,Proxy\nDOMAIN-SUFFIX,767pp.com,Proxy\nDOMAIN-SUFFIX,beetlebung.com,Proxy\nDOMAIN-SUFFIX,p333gg.com,Proxy\nDOMAIN-SUFFIX,cn.shafaqna.com,Proxy\nDOMAIN-SUFFIX,jamo.tv,Proxy\nDOMAIN-SUFFIX,kozow.com,Proxy\nDOMAIN-SUFFIX,rahsmann.de,Proxy\nDOMAIN-SUFFIX,ficuschillan.cl,Proxy\nDOMAIN-SUFFIX,softs.fun,Proxy\nDOMAIN-SUFFIX,azerbaycan.tv,Proxy\nDOMAIN-SUFFIX,parkansky.com,Proxy\nDOMAIN-SUFFIX,us-central-1.cloudfunctions.net,Proxy\nDOMAIN-SUFFIX,www.okb.com,Proxy\nDOMAIN-SUFFIX,news.livedoor.com,Proxy\nDOMAIN-SUFFIX,q2.bet.flnet.org,Proxy\nDOMAIN-SUFFIX,html.sxx.com,Proxy\nDOMAIN-SUFFIX,golinkcn.com,Proxy\nDOMAIN-SUFFIX,veritaspress.com,Proxy\nDOMAIN-SUFFIX,www.mcat.188.app,Proxy\nDOMAIN-SUFFIX,www.btcmarkets.net,Proxy\nDOMAIN-SUFFIX,737bm.com,Proxy\nDOMAIN-SUFFIX,berlinerbericht.de,Proxy\nDOMAIN-SUFFIX,www.835889.com,Proxy\nDOMAIN-SUFFIX,ygdy8.com,Proxy\nDOMAIN-SUFFIX,www.cilicili.me,Proxy\nDOMAIN-SUFFIX,gotovim-doma.ru,Proxy\nDOMAIN-SUFFIX,i.v2ex.co,Proxy\nDOMAIN-SUFFIX,vijayatemple.org,Proxy\nDOMAIN-SUFFIX,www.3001003.com,Proxy\nDOMAIN-SUFFIX,8cyber.com,Proxy\nDOMAIN-SUFFIX,m.kankanwu.com,Proxy\nDOMAIN-SUFFIX,moha.club,Proxy\nDOMAIN-SUFFIX,wnsnb.club,Proxy\nDOMAIN-SUFFIX,iu45.com,Proxy\nDOMAIN-SUFFIX,www.porno.com,Proxy\nDOMAIN-SUFFIX,ppalma.cl,Proxy\nDOMAIN-SUFFIX,hongzhi.li,Proxy\nDOMAIN-SUFFIX,todon.eu,Proxy\nDOMAIN-SUFFIX,xv1.cc,Proxy\nDOMAIN-SUFFIX,bbcmundo.com,Proxy\nDOMAIN-SUFFIX,50030.com,Proxy\nDOMAIN-SUFFIX,epochtime.com,Proxy\nDOMAIN-SUFFIX,nationalbooks.com,Proxy\nDOMAIN-SUFFIX,ssr.hissr.club,Proxy\nDOMAIN-SUFFIX,sostibet.org,Proxy\nDOMAIN-SUFFIX,taiwanjustice.net,Proxy\nDOMAIN-SUFFIX,hefeishi.xyz,Proxy\nDOMAIN-SUFFIX,sule08.com,Proxy\nDOMAIN-SUFFIX,br.st,Proxy\nDOMAIN-SUFFIX,hk-pic4.xyz,Proxy\nDOMAIN-SUFFIX,wiki.viva-la-vita.org,Proxy\nDOMAIN-SUFFIX,redditmedia.com,Proxy\nDOMAIN-SUFFIX,iyouport.com,Proxy\nDOMAIN-SUFFIX,www.debtwire.com,Proxy\nDOMAIN-SUFFIX,leexinyi.com,Proxy\nDOMAIN-SUFFIX,domaindecyrpiton.mysecondarydns.com,Proxy\nDOMAIN-SUFFIX,hkcoc.weather.com.hk,Proxy\nDOMAIN-SUFFIX,titancasino.com,Proxy\nDOMAIN-SUFFIX,cpls.xyz,Proxy\nDOMAIN-SUFFIX,jsdd17.jigsy.com,Proxy\nDOMAIN-SUFFIX,woeser.middle-way.net,Proxy\nDOMAIN-SUFFIX,shenlan.gq,Proxy\nDOMAIN-SUFFIX,yourlisten.com,Proxy\nDOMAIN-SUFFIX,makana.co.za,Proxy\nDOMAIN-SUFFIX,www.prvt.com,Proxy\nDOMAIN-SUFFIX,nuvpn.com,Proxy\nDOMAIN-SUFFIX,guti.cl,Proxy\nDOMAIN-SUFFIX,libe.fr,Proxy\nDOMAIN-SUFFIX,toutyrater.github.io,Proxy\nDOMAIN-SUFFIX,am730.com.hk,Proxy\nDOMAIN-SUFFIX,6parkbbs.com,Proxy\nDOMAIN-SUFFIX,indowebster.com,Proxy\nDOMAIN-SUFFIX,www.vanhi.com,Proxy\nDOMAIN-SUFFIX,news.omy.sg,Proxy\nDOMAIN-SUFFIX,www.ashnetworks.com,Proxy\nDOMAIN-SUFFIX,greenislandsangha.blogspot.com-1,Proxy\nDOMAIN-SUFFIX,98198i.com,Proxy\nDOMAIN-SUFFIX,sp1.comefreeloaders.com,Proxy\nDOMAIN-SUFFIX,phishingquiz.withgoogle.com,Proxy\nDOMAIN-SUFFIX,183882.com,Proxy\nDOMAIN-SUFFIX,mediawiki.org,Proxy\nDOMAIN-SUFFIX,www.bfa777.com,Proxy\nDOMAIN-SUFFIX,scontent-iad3-1.cdninstagram.com,Proxy\nDOMAIN-SUFFIX,ywca.org,Proxy\nDOMAIN-SUFFIX,vysupport.com,Proxy\nDOMAIN-SUFFIX,xvideos.es,Proxy\nDOMAIN-SUFFIX,www.authorstream.com,Proxy\nDOMAIN-SUFFIX,www.333tv.com,Proxy\nDOMAIN-SUFFIX,m.slandr.net,Proxy\nDOMAIN-SUFFIX,izlesem.org,Proxy\nDOMAIN-SUFFIX,liftoff.io,Proxy\nDOMAIN-SUFFIX,sadyoutube.com,Proxy\nDOMAIN-SUFFIX,rixcloud.us,Proxy\nDOMAIN-SUFFIX,duckduckgo.com,Proxy\nDOMAIN-SUFFIX,www.ntl.edu.tw,Proxy\nDOMAIN-SUFFIX,tibcert.org,Proxy\nDOMAIN-SUFFIX,angleproject.org,Proxy\nDOMAIN-SUFFIX,taoism.net,Proxy\nDOMAIN-SUFFIX,vivatrader.com,Proxy\nDOMAIN-SUFFIX,wende.tk,Proxy\nDOMAIN-SUFFIX,www.81fw.com,Proxy\nDOMAIN-SUFFIX,invidious.ggc-project.de,Proxy\nDOMAIN-SUFFIX,gal.voiux.com,Proxy\nDOMAIN-SUFFIX,usma.edu,Proxy\nDOMAIN-SUFFIX,dtt.dtdns.net,Proxy\nDOMAIN-SUFFIX,ntdtvla.com,Proxy\nDOMAIN-SUFFIX,proxynova.com,Proxy\nDOMAIN-SUFFIX,18comic.fun,Proxy\nDOMAIN-SUFFIX,dd57625.dnf88.net,Proxy\nDOMAIN-SUFFIX,c3j.fun,Proxy\nDOMAIN-SUFFIX,contem.bz,Proxy\nDOMAIN-SUFFIX,6ax.gxsdlm.com,Proxy\nDOMAIN-SUFFIX,erotelki.org,Proxy\nDOMAIN-SUFFIX,theweathernetwork.ca,Proxy\nDOMAIN-SUFFIX,fastdog.in,Proxy\nDOMAIN-SUFFIX,www.kinggiants.com,Proxy\nDOMAIN-SUFFIX,email.m-a-r-c-h-e-n.com,Proxy\nDOMAIN-SUFFIX,www.l3t.com,Proxy\nDOMAIN-SUFFIX,mybet.com,Proxy\nDOMAIN-SUFFIX,burchillnet.com,Proxy\nDOMAIN-SUFFIX,18comic.me,Proxy\nDOMAIN-SUFFIX,cleantechnica.com,Proxy\nDOMAIN-SUFFIX,d178ypdxd4lz8p.cloudfront.net,Proxy\nDOMAIN-SUFFIX,mt2.google.cn,Proxy\nDOMAIN-SUFFIX,www.google.com.bz,Proxy\nDOMAIN-SUFFIX,webproxy.ru,Proxy\nDOMAIN-SUFFIX,d1b3gtspywx8mw.cloudfront.net,Proxy\nDOMAIN-SUFFIX,rakulive.com,Proxy\nDOMAIN-SUFFIX,hz8808.com,Proxy\nDOMAIN-SUFFIX,xbiz.com,Proxy\nDOMAIN-SUFFIX,caliquid.kirchhoff-group.com,Proxy\nDOMAIN-SUFFIX,ww2464.com,Proxy\nDOMAIN-SUFFIX,fradkin.com.ar,Proxy\nDOMAIN-SUFFIX,insideinternetsecurity.com,Proxy\nDOMAIN-SUFFIX,www.dolorescatherino.com,Proxy\nDOMAIN-SUFFIX,www.musically.com,Proxy\nDOMAIN-SUFFIX,v2raya.org,Proxy\nDOMAIN-SUFFIX,blog.roodo.com,Proxy\nDOMAIN-SUFFIX,lifestyle-syreetasik.blogspot.hk,Proxy\nDOMAIN-SUFFIX,proxy.com,Proxy\nDOMAIN-SUFFIX,www.kurukulla.org,Proxy\nDOMAIN-SUFFIX,coedcherry.com,Proxy\nDOMAIN-SUFFIX,derpicdn.net,Proxy\nDOMAIN-SUFFIX,recaptcha.com,Proxy\nDOMAIN-SUFFIX,16151155.com,Proxy\nDOMAIN-SUFFIX,google.is,Proxy\nDOMAIN-SUFFIX,vikacg.com,Proxy\nDOMAIN-SUFFIX,www.dbw9999.com,Proxy\nDOMAIN-SUFFIX,freeproxy.cz,Proxy\nDOMAIN-SUFFIX,1024xp.com,Proxy\nDOMAIN-SUFFIX,goodav17.com,Proxy\nDOMAIN-SUFFIX,socialequality.com,Proxy\nDOMAIN-SUFFIX,serverunblock.com,Proxy\nDOMAIN-SUFFIX,webdns.work,Proxy\nDOMAIN-SUFFIX,passbird.com,Proxy\nDOMAIN-SUFFIX,darrenj.ca,Proxy\nDOMAIN-SUFFIX,dcdj.net,Proxy\nDOMAIN-SUFFIX,kralin.su,Proxy\nDOMAIN-SUFFIX,lereveartisanal.strikingly.com,Proxy\nDOMAIN-SUFFIX,qtweeter.com,Proxy\nDOMAIN-SUFFIX,www.hd21.com,Proxy\nDOMAIN-SUFFIX,suche.gmx.net,Proxy\nDOMAIN-SUFFIX,dappered.com,Proxy\nDOMAIN-SUFFIX,smartbusiness.us,Proxy\nDOMAIN-SUFFIX,extra.voyantic.com,Proxy\nDOMAIN-SUFFIX,www.91video.com,Proxy\nDOMAIN-SUFFIX,tweetcs.com,Proxy\nDOMAIN-SUFFIX,p2253.com,Proxy\nDOMAIN-SUFFIX,fayerwayer.com,Proxy\nDOMAIN-SUFFIX,bfsh.hk,Proxy\nDOMAIN-SUFFIX,f22.flnet.org,Proxy\nDOMAIN-SUFFIX,lh66a.com,Proxy\nDOMAIN-SUFFIX,patreon.com,Proxy\nDOMAIN-SUFFIX,www.lbh-group.com,Proxy\nDOMAIN-SUFFIX,thenewamerican.com,Proxy\nDOMAIN-SUFFIX,www.awebproxy.com,Proxy\nDOMAIN-SUFFIX,greatzhonghua.org,Proxy\nDOMAIN-SUFFIX,epinions.com,Proxy\nDOMAIN-SUFFIX,2365000000.com,Proxy\nDOMAIN-SUFFIX,www.idelreal.org,Proxy\nDOMAIN-SUFFIX,www.hk1282sec.com,Proxy\nDOMAIN-SUFFIX,102.ddnsking.com,Proxy\nDOMAIN-SUFFIX,caonima.net,Proxy\nDOMAIN-SUFFIX,maasentertainment.com,Proxy\nDOMAIN-SUFFIX,www.hej88.com,Proxy\nDOMAIN-SUFFIX,sacom.hk,Proxy\nDOMAIN-SUFFIX,cn.biwei666.com,Proxy\nDOMAIN-SUFFIX,www.h528.com,Proxy\nDOMAIN-SUFFIX,www.barus.cc,Proxy\nDOMAIN-SUFFIX,itm-tracker.witron.de,Proxy\nDOMAIN-SUFFIX,www.socialistdemocracy.org,Proxy\nDOMAIN-SUFFIX,iwannawatch.net,Proxy\nDOMAIN-SUFFIX,isupportuyghurs.org,Proxy\nDOMAIN-SUFFIX,tagwalk.com,Proxy\nDOMAIN-SUFFIX,uryoutube.com,Proxy\nDOMAIN-SUFFIX,firstpost.com,Proxy\nDOMAIN-SUFFIX,indexoncensorship.org,Proxy\nDOMAIN-SUFFIX,protv.ro,Proxy\nDOMAIN-SUFFIX,paltalk.com,Proxy\nDOMAIN-SUFFIX,1mobile.tw,Proxy\nDOMAIN-SUFFIX,lapka.us,Proxy\nDOMAIN-SUFFIX,pinse.pw,Proxy\nDOMAIN-SUFFIX,hk.yahoo.com,Proxy\nDOMAIN-SUFFIX,www.glock.com,Proxy\nDOMAIN-SUFFIX,finalteens.com,Proxy\nDOMAIN-SUFFIX,www.foodpolitics.com,Proxy\nDOMAIN-SUFFIX,www.neigbuy.com,Proxy\nDOMAIN-SUFFIX,blog.zhgchg.li,Proxy\nDOMAIN-SUFFIX,j3.5525.eu.org,Proxy\nDOMAIN-SUFFIX,52.cr.rs,Proxy\nDOMAIN-SUFFIX,notheroes.com,Proxy\nDOMAIN-SUFFIX,hrichina.org,Proxy\nDOMAIN-SUFFIX,dayu.ca,Proxy\nDOMAIN-SUFFIX,bwsj.hk,Proxy\nDOMAIN-SUFFIX,letou998.com,Proxy\nDOMAIN-SUFFIX,tb9993.com,Proxy\nDOMAIN-SUFFIX,funav.cc,Proxy\nDOMAIN-SUFFIX,kraken.com,Proxy\nDOMAIN-SUFFIX,blog.fdcn.org,Proxy\nDOMAIN-SUFFIX,blog.imprezagt1031.idv.tw,Proxy\nDOMAIN-SUFFIX,qq260.com,Proxy\nDOMAIN-SUFFIX,tw116.com,Proxy\nDOMAIN-SUFFIX,1proxy.de,Proxy\nDOMAIN-SUFFIX,www.tmdhack.org,Proxy\nDOMAIN-SUFFIX,zhengwunet.org,Proxy\nDOMAIN-SUFFIX,tenacy.home.kg,Proxy\nDOMAIN-SUFFIX,twt.tl,Proxy\nDOMAIN-SUFFIX,vex.flnet.org,Proxy\nDOMAIN-SUFFIX,3804411.com,Proxy\nDOMAIN-SUFFIX,jdw6.com,Proxy\nDOMAIN-SUFFIX,rxproxy.com,Proxy\nDOMAIN-SUFFIX,gg.qc.to,Proxy\nDOMAIN-SUFFIX,oldwillow.co.za,Proxy\nDOMAIN-SUFFIX,rawstory.com,Proxy\nDOMAIN-SUFFIX,18comic4.biz,Proxy\nDOMAIN-SUFFIX,fulibl.xyz,Proxy\nDOMAIN-SUFFIX,nyt4.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,d18aivqqvb7zv1.cloudfront.net,Proxy\nDOMAIN-SUFFIX,messenger.providesupport.net,Proxy\nDOMAIN-SUFFIX,stadia.com,Proxy\nDOMAIN-SUFFIX,www.boobinspector.com,Proxy\nDOMAIN-SUFFIX,cr.com,Proxy\nDOMAIN-SUFFIX,blog.52it.top,Proxy\nDOMAIN-SUFFIX,laowaiblog.com,Proxy\nDOMAIN-SUFFIX,fikrifaizah.org,Proxy\nDOMAIN-SUFFIX,dns-doh.dnsforfamily.com,Proxy\nDOMAIN-SUFFIX,yh88309.com,Proxy\nDOMAIN-SUFFIX,tibetanentrepreneurs.org,Proxy\nDOMAIN-SUFFIX,tonyyan.net,Proxy\nDOMAIN-SUFFIX,3000byb.com,Proxy\nDOMAIN-SUFFIX,mahjongsoul.com,Proxy\nDOMAIN-SUFFIX,www.islamchannel.tv,Proxy\nDOMAIN-SUFFIX,amnesty.org,Proxy\nDOMAIN-SUFFIX,ca.newfreevpn.com,Proxy\nDOMAIN-SUFFIX,hungerstrikeforaids.org,Proxy\nDOMAIN-SUFFIX,redchinacn.org,Proxy\nDOMAIN-SUFFIX,x.998fun.com,Proxy\nDOMAIN-SUFFIX,www.blinkx.com,Proxy\nDOMAIN-SUFFIX,morty.ononoki.org,Proxy\nDOMAIN-SUFFIX,www.adstream.com,Proxy\nDOMAIN-SUFFIX,elitter.net,Proxy\nDOMAIN-SUFFIX,www.colorificioveneziano.com,Proxy\nDOMAIN-SUFFIX,apkfab.com,Proxy\nDOMAIN-SUFFIX,m.3100tk.com,Proxy\nDOMAIN-SUFFIX,www.brighteon.com,Proxy\nDOMAIN-SUFFIX,dissidentvoice.org,Proxy\nDOMAIN-SUFFIX,axtuki216.wp.xdomain.jp,Proxy\nDOMAIN-SUFFIX,dl.dropboxusercontent.com,Proxy\nDOMAIN-SUFFIX,www.goldbet.com,Proxy\nDOMAIN-SUFFIX,www.redants.sg,Proxy\nDOMAIN-SUFFIX,helloss.pw,Proxy\nDOMAIN-SUFFIX,www.gee-kingdom.com,Proxy\nDOMAIN-SUFFIX,heise.de,Proxy\nDOMAIN-SUFFIX,rilhas.com,Proxy\nDOMAIN-SUFFIX,nodobjetos.com,Proxy\nDOMAIN-SUFFIX,yibada.com,Proxy\nDOMAIN-SUFFIX,www.ctcwri.idv.tw,Proxy\nDOMAIN-SUFFIX,ub66.net,Proxy\nDOMAIN-SUFFIX,cdt1.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,thebodyshop-usa.com,Proxy\nDOMAIN-SUFFIX,aing01.com,Proxy\nDOMAIN-SUFFIX,www.yes365.cc,Proxy\nDOMAIN-SUFFIX,www.ddtomm.com,Proxy\nDOMAIN-SUFFIX,tigervpn.com,Proxy\nDOMAIN-SUFFIX,vx.domain888.pw,Proxy\nDOMAIN-SUFFIX,cc.365cent.com,Proxy\nDOMAIN-SUFFIX,chatroom.dsn05.co,Proxy\nDOMAIN-SUFFIX,avalanche208.com,Proxy\nDOMAIN-SUFFIX,vpnxx.net,Proxy\nDOMAIN-SUFFIX,szetowah.org.hk,Proxy\nDOMAIN-SUFFIX,annieandmike.us,Proxy\nDOMAIN-SUFFIX,t7z.uc66.eu.org,Proxy\nDOMAIN-SUFFIX,lizafarrell.com,Proxy\nDOMAIN-SUFFIX,ddnete.com,Proxy\nDOMAIN-SUFFIX,www.cna.com,Proxy\nDOMAIN-SUFFIX,www.simfileshare.com,Proxy\nDOMAIN-SUFFIX,computers000.blogspot.hk,Proxy\nDOMAIN-SUFFIX,googlesyndication.com,Proxy\nDOMAIN-SUFFIX,taaze.tw,Proxy\nDOMAIN-SUFFIX,dyndns.org,Proxy\nDOMAIN-SUFFIX,sbrand988.com,Proxy\nDOMAIN-SUFFIX,cartoonmovement.com,Proxy\nDOMAIN-SUFFIX,www.ytdr.org,Proxy\nDOMAIN-SUFFIX,soundisallaround.com,Proxy\nDOMAIN-SUFFIX,keelyalgarlanguages.com,Proxy\nDOMAIN-SUFFIX,quranurdu.com,Proxy\nDOMAIN-SUFFIX,51.ca,Proxy\nDOMAIN-SUFFIX,www.floridablue.com,Proxy\nDOMAIN-SUFFIX,info.gf,Proxy\nDOMAIN-SUFFIX,pin-cong.com,Proxy\nDOMAIN-SUFFIX,headwater.ca,Proxy\nDOMAIN-SUFFIX,xinhuamall.com.pk,Proxy\nDOMAIN-SUFFIX,d775ya4i13qnx.cloudfront.net,Proxy\nDOMAIN-SUFFIX,993.ink,Proxy\nDOMAIN-SUFFIX,zoo.flnet.org,Proxy\nDOMAIN-SUFFIX,npf.org.tw,Proxy\nDOMAIN-SUFFIX,luuklamberts.com,Proxy\nDOMAIN-SUFFIX,mate.com,Proxy\nDOMAIN-SUFFIX,mediapermatangpauh.blogspot.hk,Proxy\nDOMAIN-SUFFIX,wofa.us,Proxy\nDOMAIN-SUFFIX,kwongwah.com.my,Proxy\nDOMAIN-SUFFIX,omega.yikyakapi.net,Proxy\nDOMAIN-SUFFIX,motor-talk.de,Proxy\nDOMAIN-SUFFIX,lesbiangirlongirl.com,Proxy\nDOMAIN-SUFFIX,b8899.com,Proxy\nDOMAIN-SUFFIX,pornmaki.com,Proxy\nDOMAIN-SUFFIX,matsushimakaede.com,Proxy\nDOMAIN-SUFFIX,vpnff.com,Proxy\nDOMAIN-SUFFIX,auntology.fandom.com,Proxy\nDOMAIN-SUFFIX,www.mylamson.com,Proxy\nDOMAIN-SUFFIX,xxxchinaporn.com,Proxy\nDOMAIN-SUFFIX,hyperboleandahalf.blogspot.hk,Proxy\nDOMAIN-SUFFIX,tibetlibre.free.fr,Proxy\nDOMAIN-SUFFIX,www.5858582.com,Proxy\nDOMAIN-SUFFIX,s77772.com,Proxy\nDOMAIN-SUFFIX,firstrade.com,Proxy\nDOMAIN-SUFFIX,vip6.88xbgg.com,Proxy\nDOMAIN-SUFFIX,ber01s08-in-f27.1e100.net,Proxy\nDOMAIN-SUFFIX,castbox.fm,Proxy\nDOMAIN-SUFFIX,arizona.box.com,Proxy\nDOMAIN-SUFFIX,ampproject.org,Proxy\nDOMAIN-SUFFIX,p4fb.com,Proxy\nDOMAIN-SUFFIX,slugterra.com,Proxy\nDOMAIN-SUFFIX,krhentai.com,Proxy\nDOMAIN-SUFFIX,liberia.com,Proxy\nDOMAIN-SUFFIX,xn--fiq681d48s.org,Proxy\nDOMAIN-SUFFIX,pastorfide.com,Proxy\nDOMAIN-SUFFIX,chinese-hermit.net,Proxy\nDOMAIN-SUFFIX,www.personalvpn.com,Proxy\nDOMAIN-SUFFIX,boxun.tv,Proxy\nDOMAIN-SUFFIX,657405.com,Proxy\nDOMAIN-SUFFIX,tk888.net,Proxy\nDOMAIN-SUFFIX,ccvoice.ca,Proxy\nDOMAIN-SUFFIX,93.serveirc.com,Proxy\nDOMAIN-SUFFIX,h1n1china.org,Proxy\nDOMAIN-SUFFIX,codeburst.io,Proxy\nDOMAIN-SUFFIX,franciswalker.ml,Proxy\nDOMAIN-SUFFIX,speedtest.googlefiber.net,Proxy\nDOMAIN-SUFFIX,webworkerdaily.com,Proxy\nDOMAIN-SUFFIX,wwwl.box.com,Proxy\nDOMAIN-SUFFIX,www.cp1897.com.hk,Proxy\nDOMAIN-SUFFIX,jiafen.strikingly.com,Proxy\nDOMAIN-SUFFIX,acg18.me,Proxy\nDOMAIN-SUFFIX,727.slyip.net,Proxy\nDOMAIN-SUFFIX,12v.si,Proxy\nDOMAIN-SUFFIX,3coms.gotgeeks.com,Proxy\nDOMAIN-SUFFIX,www.wonder-product.com,Proxy\nDOMAIN-SUFFIX,www.straight.com,Proxy\nDOMAIN-SUFFIX,facmata.net,Proxy\nDOMAIN-SUFFIX,jote.lile.cl,Proxy\nDOMAIN-SUFFIX,www.astost.com,Proxy\nDOMAIN-SUFFIX,allproxysites.com,Proxy\nDOMAIN-SUFFIX,www.bway88663.com,Proxy\nDOMAIN-SUFFIX,falundafaromania.net,Proxy\nDOMAIN-SUFFIX,yodyiam.com,Proxy\nDOMAIN-SUFFIX,www.ucbug.cc,Proxy\nDOMAIN-SUFFIX,alohabrowser.com,Proxy\nDOMAIN-SUFFIX,instafx.cn,Proxy\nDOMAIN-SUFFIX,34768.com,Proxy\nDOMAIN-SUFFIX,php.de,Proxy\nDOMAIN-SUFFIX,metroradio.com.hk,Proxy\nDOMAIN-SUFFIX,iask.bz,Proxy\nDOMAIN-SUFFIX,www.solopeliculasgratis.com,Proxy\nDOMAIN-SUFFIX,yh60089.com,Proxy\nDOMAIN-SUFFIX,ads.yahoo.com,Proxy\nDOMAIN-SUFFIX,www.ikea.nl,Proxy\nDOMAIN-SUFFIX,mangolanguages.com,Proxy\nDOMAIN-SUFFIX,www.lightsandco.com,Proxy\nDOMAIN-SUFFIX,smithcomputing.net,Proxy\nDOMAIN-SUFFIX,lizhizhuangbi.com,Proxy\nDOMAIN-SUFFIX,t20xez.com,Proxy\nDOMAIN-SUFFIX,farm.tanosecure.com.tw,Proxy\nDOMAIN-SUFFIX,www.fun223.com,Proxy\nDOMAIN-SUFFIX,www.gofundme.com,Proxy\nDOMAIN-SUFFIX,cat.casa,Proxy\nDOMAIN-SUFFIX,seesmic.com,Proxy\nDOMAIN-SUFFIX,vrsmash.com,Proxy\nDOMAIN-SUFFIX,www40.eyny.com,Proxy\nDOMAIN-SUFFIX,freedomchina.info,Proxy\nDOMAIN-SUFFIX,torguard.com,Proxy\nDOMAIN-SUFFIX,28810863.com,Proxy\nDOMAIN-SUFFIX,infinityfree.net,Proxy\nDOMAIN-SUFFIX,theway.org,Proxy\nDOMAIN-SUFFIX,www.moreechampion.com.au,Proxy\nDOMAIN-SUFFIX,vnet.link,Proxy\nDOMAIN-SUFFIX,skyxvpn.com,Proxy\nDOMAIN-SUFFIX,rollerteam.it,Proxy\nDOMAIN-SUFFIX,naixishaobing.com,Proxy\nDOMAIN-SUFFIX,twinflower.cc,Proxy\nDOMAIN-SUFFIX,lesbea.com,Proxy\nDOMAIN-SUFFIX,xinbi033.com,Proxy\nDOMAIN-SUFFIX,www.kaze-travel.co.jp,Proxy\nDOMAIN-SUFFIX,829882.com,Proxy\nDOMAIN-SUFFIX,esl1on1.com,Proxy\nDOMAIN-SUFFIX,apkplz.net,Proxy\nDOMAIN-SUFFIX,bangbrosnetwork.com,Proxy\nDOMAIN-SUFFIX,digforfire.org,Proxy\nDOMAIN-SUFFIX,98198.com,Proxy\nDOMAIN-SUFFIX,boysmaster.com,Proxy\nDOMAIN-SUFFIX,christianity.about.com,Proxy\nDOMAIN-SUFFIX,fnac.be,Proxy\nDOMAIN-SUFFIX,www.080909.com,Proxy\nDOMAIN-SUFFIX,cdp1998.org,Proxy\nDOMAIN-SUFFIX,www.luciditv.app,Proxy\nDOMAIN-SUFFIX,bit.do,Proxy\nDOMAIN-SUFFIX,bluffavenue.com,Proxy\nDOMAIN-SUFFIX,fighttube.pl,Proxy\nDOMAIN-SUFFIX,www.mashpedia.com,Proxy\nDOMAIN-SUFFIX,www.tpimage.com,Proxy\nDOMAIN-SUFFIX,tb9994.com,Proxy\nDOMAIN-SUFFIX,stranabg.com,Proxy\nDOMAIN-SUFFIX,marine.rutgers.edu,Proxy\nDOMAIN-SUFFIX,programthinkmirror.com,Proxy\nDOMAIN-SUFFIX,hmonghot.com,Proxy\nDOMAIN-SUFFIX,ziggo.ws,Proxy\nDOMAIN-SUFFIX,rscihoops.com,Proxy\nDOMAIN-SUFFIX,crchina.org,Proxy\nDOMAIN-SUFFIX,alifta.com,Proxy\nDOMAIN-SUFFIX,www.jcu.cz,Proxy\nDOMAIN-SUFFIX,yveschanyou.com,Proxy\nDOMAIN-SUFFIX,codeskulptor.org,Proxy\nDOMAIN-SUFFIX,www.teenslovehugecocks.com,Proxy\nDOMAIN-SUFFIX,hkcoc.com,Proxy\nDOMAIN-SUFFIX,vialka.com,Proxy\nDOMAIN-SUFFIX,22.now-ip.net,Proxy\nDOMAIN-SUFFIX,8595.cc,Proxy\nDOMAIN-SUFFIX,detongling.org,Proxy\nDOMAIN-SUFFIX,g-truc.net,Proxy\nDOMAIN-SUFFIX,373699.com,Proxy\nDOMAIN-SUFFIX,hanime1.com,Proxy\nDOMAIN-SUFFIX,aex.com,Proxy\nDOMAIN-SUFFIX,smartappsapk.com,Proxy\nDOMAIN-SUFFIX,videogameheat.com,Proxy\nDOMAIN-SUFFIX,cn.resellerclub.com,Proxy\nDOMAIN-SUFFIX,mirror.xyz,Proxy\nDOMAIN-SUFFIX,www.buddhist.idv.tw,Proxy\nDOMAIN-SUFFIX,pj807.com,Proxy\nDOMAIN-SUFFIX,yogiproducts.com,Proxy\nDOMAIN-SUFFIX,d27.dhcp.biz,Proxy\nDOMAIN-SUFFIX,zh.sa1lib.org,Proxy\nDOMAIN-SUFFIX,lvv2.com,Proxy\nDOMAIN-SUFFIX,zh.wikipedia.aust.cf,Proxy\nDOMAIN-SUFFIX,sharkchinaz.com,Proxy\nDOMAIN-SUFFIX,voyeur-house.tv,Proxy\nDOMAIN-SUFFIX,1qqtv.net,Proxy\nDOMAIN-SUFFIX,download.cnet.com,Proxy\nDOMAIN-SUFFIX,d3sw8he2kp6367.cloudfront.net,Proxy\nDOMAIN-SUFFIX,fxnetworks.com,Proxy\nDOMAIN-SUFFIX,ippotv.com,Proxy\nDOMAIN-SUFFIX,pornaccess.com,Proxy\nDOMAIN-SUFFIX,email.re.fastdog.org,Proxy\nDOMAIN-SUFFIX,june6.dubya.net,Proxy\nDOMAIN-SUFFIX,5.inc.gs,Proxy\nDOMAIN-SUFFIX,joinbl.xyz,Proxy\nDOMAIN-SUFFIX,justfreevpn.com,Proxy\nDOMAIN-SUFFIX,d24f0fbbs0l72b.cloudfront.net,Proxy\nDOMAIN-SUFFIX,elenasandu.com,Proxy\nDOMAIN-SUFFIX,mist.vip,Proxy\nDOMAIN-SUFFIX,24k88.com,Proxy\nDOMAIN-SUFFIX,vpnreactor.com,Proxy\nDOMAIN-SUFFIX,newtalk.tw,Proxy\nDOMAIN-SUFFIX,ultimatesurrender.com,Proxy\nDOMAIN-SUFFIX,pipelinemag.com,Proxy\nDOMAIN-SUFFIX,hometeenmovs.com,Proxy\nDOMAIN-SUFFIX,www.12858.cc,Proxy\nDOMAIN-SUFFIX,www.chugoku-np.co.jp,Proxy\nDOMAIN-SUFFIX,223nn.net,Proxy\nDOMAIN-SUFFIX,auluckylottery.com,Proxy\nDOMAIN-SUFFIX,digitalnomadsproject.org,Proxy\nDOMAIN-SUFFIX,www.670038.com,Proxy\nDOMAIN-SUFFIX,proxmecallmenames.com,Proxy\nDOMAIN-SUFFIX,groups.google.cn,Proxy\nDOMAIN-SUFFIX,pekingduck.org,Proxy\nDOMAIN-SUFFIX,www.rexxx.com,Proxy\nDOMAIN-SUFFIX,centreforfeministforeignpolicy.org,Proxy\nDOMAIN-SUFFIX,eurashe.be,Proxy\nDOMAIN-SUFFIX,niconode.xyz,Proxy\nDOMAIN-SUFFIX,vpnca.com,Proxy\nDOMAIN-SUFFIX,drivelab.net,Proxy\nDOMAIN-SUFFIX,3583n.com,Proxy\nDOMAIN-SUFFIX,roboforex-cn.org,Proxy\nDOMAIN-SUFFIX,www.mingpao.com,Proxy\nDOMAIN-SUFFIX,irna.ir,Proxy\nDOMAIN-SUFFIX,alphacigar.com,Proxy\nDOMAIN-SUFFIX,mvyd.ws,Proxy\nDOMAIN-SUFFIX,d2g9sdr0k888cv.cloudfront.net,Proxy\nDOMAIN-SUFFIX,ivfminiua.com,Proxy\nDOMAIN-SUFFIX,abs.twimg.com,Proxy\nDOMAIN-SUFFIX,www.ukrainianjournal.com,Proxy\nDOMAIN-SUFFIX,macomi.nl,Proxy\nDOMAIN-SUFFIX,8899bn.com,Proxy\nDOMAIN-SUFFIX,www.bestukvpn.com,Proxy\nDOMAIN-SUFFIX,tmc6425.blogspot.hk,Proxy\nDOMAIN-SUFFIX,d3nw6kcmyopsns.cloudfront.net,Proxy\nDOMAIN-SUFFIX,thetibetpost.com,Proxy\nDOMAIN-SUFFIX,crowncloud.net,Proxy\nDOMAIN-SUFFIX,ting6622.com,Proxy\nDOMAIN-SUFFIX,www.frcc.us,Proxy\nDOMAIN-SUFFIX,www.tryvy.net,Proxy\nDOMAIN-SUFFIX,myshare.url.com.tw,Proxy\nDOMAIN-SUFFIX,zhllg.spaces.live.com,Proxy\nDOMAIN-SUFFIX,www.striking.ly,Proxy\nDOMAIN-SUFFIX,d0ae73.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,newspeak.cc,Proxy\nDOMAIN-SUFFIX,archive.today,Proxy\nDOMAIN-SUFFIX,nihaocloud.com,Proxy\nDOMAIN-SUFFIX,1eight8.com,Proxy\nDOMAIN-SUFFIX,www.socialmediawall.me,Proxy\nDOMAIN-SUFFIX,looktoronto.com,Proxy\nDOMAIN-SUFFIX,weave.wearvr.com,Proxy\nDOMAIN-SUFFIX,scache2.vzw.com,Proxy\nDOMAIN-SUFFIX,playboyplus.com,Proxy\nDOMAIN-SUFFIX,tendaiuk.com,Proxy\nDOMAIN-SUFFIX,www.elkosmos.gr,Proxy\nDOMAIN-SUFFIX,doh.nic.lv,Proxy\nDOMAIN-SUFFIX,kirakira-av.com,Proxy\nDOMAIN-SUFFIX,snipurl.com,Proxy\nDOMAIN-SUFFIX,tripadvisor.de,Proxy\nDOMAIN-SUFFIX,chatgpt-global.com,Proxy\nDOMAIN-SUFFIX,www.voafanti.com,Proxy\nDOMAIN-SUFFIX,www.tvi24.iol.pt,Proxy\nDOMAIN-SUFFIX,d2r33j4rn8i3g5.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.beautyleg.com,Proxy\nDOMAIN-SUFFIX,yvesli.com,Proxy\nDOMAIN-SUFFIX,dlyoutube.com,Proxy\nDOMAIN-SUFFIX,mybluemix.net,Proxy\nDOMAIN-SUFFIX,rssmeme.com,Proxy\nDOMAIN-SUFFIX,4151.yzc596.com,Proxy\nDOMAIN-SUFFIX,123fala.com,Proxy\nDOMAIN-SUFFIX,law-hongkong.com,Proxy\nDOMAIN-SUFFIX,sineplex.net,Proxy\nDOMAIN-SUFFIX,wk18.app,Proxy\nDOMAIN-SUFFIX,fileupload.ggc-project.de,Proxy\nDOMAIN-SUFFIX,www.morgenweb.de,Proxy\nDOMAIN-SUFFIX,sport24.com,Proxy\nDOMAIN-SUFFIX,00220022.net,Proxy\nDOMAIN-SUFFIX,www.tnmb.org,Proxy\nDOMAIN-SUFFIX,chat.kamiya.dev,Proxy\nDOMAIN-SUFFIX,express-vpn-links.com,Proxy\nDOMAIN-SUFFIX,freekazakhs.org,Proxy\nDOMAIN-SUFFIX,ssglobal.me,Proxy\nDOMAIN-SUFFIX,zynamics.com,Proxy\nDOMAIN-SUFFIX,dehainaut.org,Proxy\nDOMAIN-SUFFIX,83.b0ne.com,Proxy\nDOMAIN-SUFFIX,nhentai.org,Proxy\nDOMAIN-SUFFIX,thedigitalbits.com,Proxy\nDOMAIN-SUFFIX,presentationzen.com,Proxy\nDOMAIN-SUFFIX,ca-desktop-premium.zenmateuser.com,Proxy\nDOMAIN-SUFFIX,www.klxsw.com,Proxy\nDOMAIN-SUFFIX,app.arukas.io,Proxy\nDOMAIN-SUFFIX,na.kalone.net,Proxy\nDOMAIN-SUFFIX,i.ytimg.com,Proxy\nDOMAIN-SUFFIX,www.igmarkets.fr,Proxy\nDOMAIN-SUFFIX,spccaa-bc.org,Proxy\nDOMAIN-SUFFIX,og.gs,Proxy\nDOMAIN-SUFFIX,porndav.com,Proxy\nDOMAIN-SUFFIX,kiwi.kz,Proxy\nDOMAIN-SUFFIX,ngprobike.com,Proxy\nDOMAIN-SUFFIX,8587p.cc,Proxy\nDOMAIN-SUFFIX,www.twcd.com.tw,Proxy\nDOMAIN-SUFFIX,rfimusique.com,Proxy\nDOMAIN-SUFFIX,sat9.dhcp.biz,Proxy\nDOMAIN-SUFFIX,acgbuster.moe,Proxy\nDOMAIN-SUFFIX,google.cz,Proxy\nDOMAIN-SUFFIX,0328y.com,Proxy\nDOMAIN-SUFFIX,lb666.com,Proxy\nDOMAIN-SUFFIX,home.nzcity.co.nz,Proxy\nDOMAIN-SUFFIX,it.biguz.net,Proxy\nDOMAIN-SUFFIX,tigerbalm.com,Proxy\nDOMAIN-SUFFIX,www.zhongzidi.com,Proxy\nDOMAIN-SUFFIX,888star.com,Proxy\nDOMAIN-SUFFIX,download.aircrack-ng.org,Proxy\nDOMAIN-SUFFIX,avlulu.com,Proxy\nDOMAIN-SUFFIX,grow.google,Proxy\nDOMAIN-SUFFIX,d2gpylgs0l8fi4.cloudfront.net,Proxy\nDOMAIN-SUFFIX,pcgamer.com,Proxy\nDOMAIN-SUFFIX,iranzehn.com,Proxy\nDOMAIN-SUFFIX,static.ustream.tv,Proxy\nDOMAIN-SUFFIX,vidoevo.com,Proxy\nDOMAIN-SUFFIX,sextubepromo.com,Proxy\nDOMAIN-SUFFIX,www.harting.de,Proxy\nDOMAIN-SUFFIX,xmbs4.xyz,Proxy\nDOMAIN-SUFFIX,cuantico.com.ar,Proxy\nDOMAIN-SUFFIX,pgafan.net,Proxy\nDOMAIN-SUFFIX,focusvpn.com,Proxy\nDOMAIN-SUFFIX,fc2.com,Proxy\nDOMAIN-SUFFIX,sohcradio.com,Proxy\nDOMAIN-SUFFIX,wnacg.com,Proxy\nDOMAIN-SUFFIX,kc.id.lv,Proxy\nDOMAIN-SUFFIX,letou321.com,Proxy\nDOMAIN-SUFFIX,rejectccp.org,Proxy\nDOMAIN-SUFFIX,ntdtv.com,Proxy\nDOMAIN-SUFFIX,zh.beta.qualityready.de,Proxy\nDOMAIN-SUFFIX,outline.com,Proxy\nDOMAIN-SUFFIX,kcoolonline.com,Proxy\nDOMAIN-SUFFIX,ting9922.com,Proxy\nDOMAIN-SUFFIX,www.qm900.com,Proxy\nDOMAIN-SUFFIX,faccebook.com,Proxy\nDOMAIN-SUFFIX,ws.domain888.pw,Proxy\nDOMAIN-SUFFIX,30565vip.com,Proxy\nDOMAIN-SUFFIX,chineseperformingarts.net,Proxy\nDOMAIN-SUFFIX,tw.seemh.com,Proxy\nDOMAIN-SUFFIX,kangongyu.com,Proxy\nDOMAIN-SUFFIX,ksvpn.com,Proxy\nDOMAIN-SUFFIX,h55.slyip.com,Proxy\nDOMAIN-SUFFIX,cloud.mail.ru,Proxy\nDOMAIN-SUFFIX,fuckbookofsex.mobi,Proxy\nDOMAIN-SUFFIX,lcavallaro.com,Proxy\nDOMAIN-SUFFIX,glow.nz,Proxy\nDOMAIN-SUFFIX,dl-canary.discordapp.net,Proxy\nDOMAIN-SUFFIX,littlebabybum.com,Proxy\nDOMAIN-SUFFIX,sg01.gogovpn.org,Proxy\nDOMAIN-SUFFIX,zzcloud.me,Proxy\nDOMAIN-SUFFIX,fishproxy.com,Proxy\nDOMAIN-SUFFIX,tp.8pen.xyz,Proxy\nDOMAIN-SUFFIX,slides.com,Proxy\nDOMAIN-SUFFIX,blogspot.sg,Proxy\nDOMAIN-SUFFIX,ebookjapan.yahoo.co.jp,Proxy\nDOMAIN-SUFFIX,w.hdd2.host,Proxy\nDOMAIN-SUFFIX,73999g.com,Proxy\nDOMAIN-SUFFIX,tchrd.org,Proxy\nDOMAIN-SUFFIX,preview.editmysite.com,Proxy\nDOMAIN-SUFFIX,zapkolik.com,Proxy\nDOMAIN-SUFFIX,4690.com,Proxy\nDOMAIN-SUFFIX,www.cootamundraherald.com.au,Proxy\nDOMAIN-SUFFIX,vanitatis.com,Proxy\nDOMAIN-SUFFIX,w3.css5.pw,Proxy\nDOMAIN-SUFFIX,penchinese.com,Proxy\nDOMAIN-SUFFIX,fiveimmortals.com,Proxy\nDOMAIN-SUFFIX,mt1.google.cn,Proxy\nDOMAIN-SUFFIX,ocw.mit.edu,Proxy\nDOMAIN-SUFFIX,freefuckvidz.com,Proxy\nDOMAIN-SUFFIX,www.youtube.co.in,Proxy\nDOMAIN-SUFFIX,bbc2.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,btkitty.org,Proxy\nDOMAIN-SUFFIX,brooklyncreativestudio.com,Proxy\nDOMAIN-SUFFIX,ers6.dhcp.biz,Proxy\nDOMAIN-SUFFIX,hentai.xxx,Proxy\nDOMAIN-SUFFIX,ashford.com,Proxy\nDOMAIN-SUFFIX,uinvest.com.ua,Proxy\nDOMAIN-SUFFIX,bbs.mikocon.com,Proxy\nDOMAIN-SUFFIX,seip.strikingly.com,Proxy\nDOMAIN-SUFFIX,mixpod.com,Proxy\nDOMAIN-SUFFIX,playvpn.com,Proxy\nDOMAIN-SUFFIX,d3hbu04z1aigt7.cloudfront.net,Proxy\nDOMAIN-SUFFIX,xabbs.com,Proxy\nDOMAIN-SUFFIX,discordapp.net,Proxy\nDOMAIN-SUFFIX,www.squirrelvpn.com,Proxy\nDOMAIN-SUFFIX,huhamhire.com,Proxy\nDOMAIN-SUFFIX,emulefans.com,Proxy\nDOMAIN-SUFFIX,fremont.cname.xyz,Proxy\nDOMAIN-SUFFIX,dnsser.xyz,Proxy\nDOMAIN-SUFFIX,impressionmonster.com,Proxy\nDOMAIN-SUFFIX,dharmawheel.net,Proxy\nDOMAIN-SUFFIX,business.page,Proxy\nDOMAIN-SUFFIX,690088.com,Proxy\nDOMAIN-SUFFIX,ddl70q3k97azf.cloudfront.net,Proxy\nDOMAIN-SUFFIX,xn--noss43i.com,Proxy\nDOMAIN-SUFFIX,www.madewithcode.com,Proxy\nDOMAIN-SUFFIX,hkreporter.com,Proxy\nDOMAIN-SUFFIX,fw7.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,tuite.in,Proxy\nDOMAIN-SUFFIX,macaubusiness.com,Proxy\nDOMAIN-SUFFIX,www.bignaturals.com,Proxy\nDOMAIN-SUFFIX,vision42.net,Proxy\nDOMAIN-SUFFIX,forumosa.com,Proxy\nDOMAIN-SUFFIX,chinese-fxcm.com,Proxy\nDOMAIN-SUFFIX,ccue.com,Proxy\nDOMAIN-SUFFIX,mfxmedia.com,Proxy\nDOMAIN-SUFFIX,www.ahs.nccu.edu.tw,Proxy\nDOMAIN-SUFFIX,greatfire.us7.list-manage.com,Proxy\nDOMAIN-SUFFIX,ai-wen.net,Proxy\nDOMAIN-SUFFIX,oex.com,Proxy\nDOMAIN-SUFFIX,www.4hus60.com,Proxy\nDOMAIN-SUFFIX,www.nestor.minsk.by,Proxy\nDOMAIN-SUFFIX,duanzhihu.com,Proxy\nDOMAIN-SUFFIX,d1iu4getqkgua5.cloudfront.net,Proxy\nDOMAIN-SUFFIX,abc.com,Proxy\nDOMAIN-SUFFIX,www.citycenter.fi,Proxy\nDOMAIN-SUFFIX,454479.cc,Proxy\nDOMAIN-SUFFIX,www.fuyindiantai.org,Proxy\nDOMAIN-SUFFIX,xp.domain888.pw,Proxy\nDOMAIN-SUFFIX,gfashion.com,Proxy\nDOMAIN-SUFFIX,lau.sp5178.com,Proxy\nDOMAIN-SUFFIX,www.atangboss.com,Proxy\nDOMAIN-SUFFIX,www.fineboy.co,Proxy\nDOMAIN-SUFFIX,m.kuihua888.com,Proxy\nDOMAIN-SUFFIX,seven.wf,Proxy\nDOMAIN-SUFFIX,zamourispices.com,Proxy\nDOMAIN-SUFFIX,deuslife.com,Proxy\nDOMAIN-SUFFIX,rstt-lan.ch,Proxy\nDOMAIN-SUFFIX,www.greatzhonghua.org,Proxy\nDOMAIN-SUFFIX,h7.flnet.org,Proxy\nDOMAIN-SUFFIX,beijing2022.art,Proxy\nDOMAIN-SUFFIX,zbporn.com,Proxy\nDOMAIN-SUFFIX,paincompanion.com,Proxy\nDOMAIN-SUFFIX,puntosys.com,Proxy\nDOMAIN-SUFFIX,www.eroticbeauty.com,Proxy\nDOMAIN-SUFFIX,green960.com,Proxy\nDOMAIN-SUFFIX,www.harmonylove.com,Proxy\nDOMAIN-SUFFIX,xuchao.org,Proxy\nDOMAIN-SUFFIX,968558.com,Proxy\nDOMAIN-SUFFIX,godusevpn.org,Proxy\nDOMAIN-SUFFIX,jasmine-action.blogspot.jp,Proxy\nDOMAIN-SUFFIX,0099msc.com,Proxy\nDOMAIN-SUFFIX,statics.plurk.com,Proxy\nDOMAIN-SUFFIX,boa.dhcp.biz,Proxy\nDOMAIN-SUFFIX,ja.twitcasting.tv,Proxy\nDOMAIN-SUFFIX,rediff.com,Proxy\nDOMAIN-SUFFIX,cdt2.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,portal.shadowsocks.to,Proxy\nDOMAIN-SUFFIX,www.creditoycaucion.com,Proxy\nDOMAIN-SUFFIX,vpnp.com,Proxy\nDOMAIN-SUFFIX,36mmm.net,Proxy\nDOMAIN-SUFFIX,madrau.com,Proxy\nDOMAIN-SUFFIX,rogzpetinsurance.co.za,Proxy\nDOMAIN-SUFFIX,vpnsg.net,Proxy\nDOMAIN-SUFFIX,newspicks.com,Proxy\nDOMAIN-SUFFIX,now-here.com,Proxy\nDOMAIN-SUFFIX,zalmos.com,Proxy\nDOMAIN-SUFFIX,agkmg.com,Proxy\nDOMAIN-SUFFIX,agnesb.fr,Proxy\nDOMAIN-SUFFIX,wowfandom.com,Proxy\nDOMAIN-SUFFIX,www.yourprivatevpn.com,Proxy\nDOMAIN-SUFFIX,niwn.com,Proxy\nDOMAIN-SUFFIX,08.podzone.org,Proxy\nDOMAIN-SUFFIX,moonangel.com,Proxy\nDOMAIN-SUFFIX,blushmossy.com,Proxy\nDOMAIN-SUFFIX,www.collegedudes.com,Proxy\nDOMAIN-SUFFIX,mapp-web.r88app06.com,Proxy\nDOMAIN-SUFFIX,191927.com,Proxy\nDOMAIN-SUFFIX,demosisto.hk,Proxy\nDOMAIN-SUFFIX,tapi.pureapk.com,Proxy\nDOMAIN-SUFFIX,buddhanet.idv.tw,Proxy\nDOMAIN-SUFFIX,i999.work,Proxy\nDOMAIN-SUFFIX,boyangu.com,Proxy\nDOMAIN-SUFFIX,interactivebrokers.com,Proxy\nDOMAIN-SUFFIX,dynu.net,Proxy\nDOMAIN-SUFFIX,goldenseeds.si,Proxy\nDOMAIN-SUFFIX,www.gkfxprime.com.cn,Proxy\nDOMAIN-SUFFIX,www.xh036.com,Proxy\nDOMAIN-SUFFIX,kj.99kk.eu.org,Proxy\nDOMAIN-SUFFIX,image.itmedia.co.jp,Proxy\nDOMAIN-SUFFIX,pcchong.com,Proxy\nDOMAIN-SUFFIX,jappydolls.net,Proxy\nDOMAIN-SUFFIX,www.sumisora.org,Proxy\nDOMAIN-SUFFIX,www.4bc.cc,Proxy\nDOMAIN-SUFFIX,powerapple.com,Proxy\nDOMAIN-SUFFIX,m.yzc212.com,Proxy\nDOMAIN-SUFFIX,tibetoralhistory.org,Proxy\nDOMAIN-SUFFIX,news.google.com.are.uab.cat,Proxy\nDOMAIN-SUFFIX,doh.totoro.pub,Proxy\nDOMAIN-SUFFIX,gtricks.com,Proxy\nDOMAIN-SUFFIX,www.bettycrocker.com,Proxy\nDOMAIN-SUFFIX,eteenporn.com,Proxy\nDOMAIN-SUFFIX,boxun6.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,nedrink.org,Proxy\nDOMAIN-SUFFIX,www.bxjin.com,Proxy\nDOMAIN-SUFFIX,goyoutube.com,Proxy\nDOMAIN-SUFFIX,www.av01.tv,Proxy\nDOMAIN-SUFFIX,pinterest.se,Proxy\nDOMAIN-SUFFIX,301works.org,Proxy\nDOMAIN-SUFFIX,www.playsight.com,Proxy\nDOMAIN-SUFFIX,doh.li,Proxy\nDOMAIN-SUFFIX,artofpeacefoundation.org,Proxy\nDOMAIN-SUFFIX,byb80.app,Proxy\nDOMAIN-SUFFIX,news.abs-cbn.com,Proxy\nDOMAIN-SUFFIX,sethwklein.net,Proxy\nDOMAIN-SUFFIX,google.tg,Proxy\nDOMAIN-SUFFIX,www.hustlercash.com,Proxy\nDOMAIN-SUFFIX,adlestari.com,Proxy\nDOMAIN-SUFFIX,jumpnetwork.org,Proxy\nDOMAIN-SUFFIX,boxun1.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,debug.com,Proxy\nDOMAIN-SUFFIX,energitweb.com.ar,Proxy\nDOMAIN-SUFFIX,duyaoss.com,Proxy\nDOMAIN-SUFFIX,www.larazon.es,Proxy\nDOMAIN-SUFFIX,65uk7.com,Proxy\nDOMAIN-SUFFIX,laweekly.com,Proxy\nDOMAIN-SUFFIX,macmillan.com,Proxy\nDOMAIN-SUFFIX,fakku.net,Proxy\nDOMAIN-SUFFIX,fonts.proxy.ustclug.org,Proxy\nDOMAIN-SUFFIX,longlivemarxleninmaoism2022.ml,Proxy\nDOMAIN-SUFFIX,cdn.seatguru.com,Proxy\nDOMAIN-SUFFIX,night.sclub.tw,Proxy\nDOMAIN-SUFFIX,lala.im,Proxy\nDOMAIN-SUFFIX,it-como-hobby.com,Proxy\nDOMAIN-SUFFIX,www.qile789.com,Proxy\nDOMAIN-SUFFIX,1-apple.com.tw,Proxy\nDOMAIN-SUFFIX,39898.com,Proxy\nDOMAIN-SUFFIX,4safe.ubddns.org,Proxy\nDOMAIN-SUFFIX,blog.yitianshijie.net,Proxy\nDOMAIN-SUFFIX,gongm.in,Proxy\nDOMAIN-SUFFIX,d1jun1tcgd0bek.cloudfront.net,Proxy\nDOMAIN-SUFFIX,mixturecloud.com,Proxy\nDOMAIN-SUFFIX,www.uselessjunk.com,Proxy\nDOMAIN-SUFFIX,vpnac.net,Proxy\nDOMAIN-SUFFIX,smashingapps.com,Proxy\nDOMAIN-SUFFIX,avhome.tv,Proxy\nDOMAIN-SUFFIX,tibetanpaintings.com,Proxy\nDOMAIN-SUFFIX,22.te.rs,Proxy\nDOMAIN-SUFFIX,forum.cyberctm.com,Proxy\nDOMAIN-SUFFIX,sylfoundation.org,Proxy\nDOMAIN-SUFFIX,www.cfun88.com,Proxy\nDOMAIN-SUFFIX,www.qwqshow.com,Proxy\nDOMAIN-SUFFIX,systemventas.com,Proxy\nDOMAIN-SUFFIX,antidote.im,Proxy\nDOMAIN-SUFFIX,australiachinarelations.org,Proxy\nDOMAIN-SUFFIX,nsfwx.pics,Proxy\nDOMAIN-SUFFIX,w3.h2.dhcp.biz,Proxy\nDOMAIN-SUFFIX,cms.korea.net,Proxy\nDOMAIN-SUFFIX,www.nnconnect.com,Proxy\nDOMAIN-SUFFIX,peteryounghk.com,Proxy\nDOMAIN-SUFFIX,mynumber.org,Proxy\nDOMAIN-SUFFIX,www.ultrareach.net,Proxy\nDOMAIN-SUFFIX,ku116.net,Proxy\nDOMAIN-SUFFIX,web.pkuhollow.com,Proxy\nDOMAIN-SUFFIX,www.the-diplomat.com,Proxy\nDOMAIN-SUFFIX,scientology.cc,Proxy\nDOMAIN-SUFFIX,beecore.com.tw,Proxy\nDOMAIN-SUFFIX,www.channel8news.sg,Proxy\nDOMAIN-SUFFIX,1805.cc,Proxy\nDOMAIN-SUFFIX,getmdl.io,Proxy\nDOMAIN-SUFFIX,nrk.no,Proxy\nDOMAIN-SUFFIX,c10.patreonusercontent.com,Proxy\nDOMAIN-SUFFIX,chat.forefront.ai,Proxy\nDOMAIN-SUFFIX,canalisystem.fr,Proxy\nDOMAIN-SUFFIX,www.fun027.com,Proxy\nDOMAIN-SUFFIX,e.tv100.us,Proxy\nDOMAIN-SUFFIX,massjsq.com,Proxy\nDOMAIN-SUFFIX,naughtyblog.org,Proxy\nDOMAIN-SUFFIX,www.huffpo.com,Proxy\nDOMAIN-SUFFIX,www.millionhu.com,Proxy\nDOMAIN-SUFFIX,cduniverse.com,Proxy\nDOMAIN-SUFFIX,dz2kkf55yiy7s.cloudfront.net,Proxy\nDOMAIN-SUFFIX,vocn.tv,Proxy\nDOMAIN-SUFFIX,forum.my903.com,Proxy\nDOMAIN-SUFFIX,www.animetake.com,Proxy\nDOMAIN-SUFFIX,d24epasocofl3v.cloudfront.net,Proxy\nDOMAIN-SUFFIX,xxlmovies.com,Proxy\nDOMAIN-SUFFIX,meizhong.blog,Proxy\nDOMAIN-SUFFIX,www.vnsr9488.com,Proxy\nDOMAIN-SUFFIX,www.jihadology.net,Proxy\nDOMAIN-SUFFIX,98098f.com,Proxy\nDOMAIN-SUFFIX,freeweibo.com,Proxy\nDOMAIN-SUFFIX,www.ebeb55.com,Proxy\nDOMAIN-SUFFIX,www.rosi68.com,Proxy\nDOMAIN-SUFFIX,okcoin.com,Proxy\nDOMAIN-SUFFIX,shadowsocks.com.hk,Proxy\nDOMAIN-SUFFIX,apk2.ml,Proxy\nDOMAIN-SUFFIX,myxxxtoon.com,Proxy\nDOMAIN-SUFFIX,asianspiss.com,Proxy\nDOMAIN-SUFFIX,www.muscatdaily.com,Proxy\nDOMAIN-SUFFIX,www.stmarysstar.com.au,Proxy\nDOMAIN-SUFFIX,a.we55.us,Proxy\nDOMAIN-SUFFIX,osasiadispatch.yuanshen.com,Proxy\nDOMAIN-SUFFIX,www.mingtiandi.com,Proxy\nDOMAIN-SUFFIX,easypic.com,Proxy\nDOMAIN-SUFFIX,saishuu-hentai.net,Proxy\nDOMAIN-SUFFIX,www.barryanddistrictnews.co.uk,Proxy\nDOMAIN-SUFFIX,www.hjdc90.com,Proxy\nDOMAIN-SUFFIX,qiuworld.com,Proxy\nDOMAIN-SUFFIX,cmule.net,Proxy\nDOMAIN-SUFFIX,privacyprotector.eu,Proxy\nDOMAIN-SUFFIX,s75.xyz,Proxy\nDOMAIN-SUFFIX,watchmygf.com,Proxy\nDOMAIN-SUFFIX,vmwareitacademy.org,Proxy\nDOMAIN-SUFFIX,poontown.net,Proxy\nDOMAIN-SUFFIX,www.dyvip868.com,Proxy\nDOMAIN-SUFFIX,22.hobby-site.org,Proxy\nDOMAIN-SUFFIX,wwsj9688.xyz,Proxy\nDOMAIN-SUFFIX,www.ckrl.qc.ca,Proxy\nDOMAIN-SUFFIX,tipas.net,Proxy\nDOMAIN-SUFFIX,compuserve.com,Proxy\nDOMAIN-SUFFIX,adserverplus.com,Proxy\nDOMAIN-SUFFIX,i24news.tv,Proxy\nDOMAIN-SUFFIX,uyghurcongress.org,Proxy\nDOMAIN-SUFFIX,download.netsarang.com,Proxy\nDOMAIN-SUFFIX,blueangellive.com,Proxy\nDOMAIN-SUFFIX,rwsentosa.com.cn,Proxy\nDOMAIN-SUFFIX,cuhkacs.org,Proxy\nDOMAIN-SUFFIX,www.agpromotion.com,Proxy\nDOMAIN-SUFFIX,tousei-syasei-katagi.blog.jp,Proxy\nDOMAIN-SUFFIX,www.akiba-web.com,Proxy\nDOMAIN-SUFFIX,beclass.com,Proxy\nDOMAIN-SUFFIX,flink.cl,Proxy\nDOMAIN-SUFFIX,megaproxy.pw,Proxy\nDOMAIN-SUFFIX,gushi.tw,Proxy\nDOMAIN-SUFFIX,imkev.com,Proxy\nDOMAIN-SUFFIX,torrentdownloads.net,Proxy\nDOMAIN-SUFFIX,www.appledaily.com.tw,Proxy\nDOMAIN-SUFFIX,5best1s.com,Proxy\nDOMAIN-SUFFIX,seo.id.lv,Proxy\nDOMAIN-SUFFIX,oyax.com,Proxy\nDOMAIN-SUFFIX,www.vpn38.net,Proxy\nDOMAIN-SUFFIX,www.tushy.com,Proxy\nDOMAIN-SUFFIX,bestvpnz.com,Proxy\nDOMAIN-SUFFIX,playvids.com,Proxy\nDOMAIN-SUFFIX,bloombergview.com,Proxy\nDOMAIN-SUFFIX,androidapksfree.com,Proxy\nDOMAIN-SUFFIX,mi.577gc.net,Proxy\nDOMAIN-SUFFIX,tubepleasure.com,Proxy\nDOMAIN-SUFFIX,www.hcy.idv.tw,Proxy\nDOMAIN-SUFFIX,11222.com,Proxy\nDOMAIN-SUFFIX,airav.work,Proxy\nDOMAIN-SUFFIX,y1879.com,Proxy\nDOMAIN-SUFFIX,tuboshu.in,Proxy\nDOMAIN-SUFFIX,bodyfluids-jav.com,Proxy\nDOMAIN-SUFFIX,tt222.net,Proxy\nDOMAIN-SUFFIX,international.findmespot.com,Proxy\nDOMAIN-SUFFIX,gpt4.xunika.uk,Proxy\nDOMAIN-SUFFIX,www.ccc29.com,Proxy\nDOMAIN-SUFFIX,bobx.com,Proxy\nDOMAIN-SUFFIX,ppac.in,Proxy\nDOMAIN-SUFFIX,8522270.com,Proxy\nDOMAIN-SUFFIX,support.pubu.tw,Proxy\nDOMAIN-SUFFIX,realforum.zkiz.com,Proxy\nDOMAIN-SUFFIX,www.betway118.com,Proxy\nDOMAIN-SUFFIX,inc004.tudouser.com,Proxy\nDOMAIN-SUFFIX,www.youlucky.com,Proxy\nDOMAIN-SUFFIX,www.udnbkk.com,Proxy\nDOMAIN-SUFFIX,gartlive.com,Proxy\nDOMAIN-SUFFIX,sunskyforum.com,Proxy\nDOMAIN-SUFFIX,cliftonharper.ga,Proxy\nDOMAIN-SUFFIX,shanghai.ist,Proxy\nDOMAIN-SUFFIX,scribe.rip,Proxy\nDOMAIN-SUFFIX,www.bluesky.idv.tw,Proxy\nDOMAIN-SUFFIX,www.yankong.org,Proxy\nDOMAIN-SUFFIX,62.slyip.net,Proxy\nDOMAIN-SUFFIX,d2olp5khgu59g3.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.bodog.com,Proxy\nDOMAIN-SUFFIX,jbl228.com,Proxy\nDOMAIN-SUFFIX,5365.com,Proxy\nDOMAIN-SUFFIX,www.milivpn.com,Proxy\nDOMAIN-SUFFIX,fun88asia1.com,Proxy\nDOMAIN-SUFFIX,canchinese.com,Proxy\nDOMAIN-SUFFIX,falun-inlandnw.org,Proxy\nDOMAIN-SUFFIX,aamdotcom-us-central-staging.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,tcsovi.org,Proxy\nDOMAIN-SUFFIX,52.my.to,Proxy\nDOMAIN-SUFFIX,fstoppers.com,Proxy\nDOMAIN-SUFFIX,ladyboygloryhole.com,Proxy\nDOMAIN-SUFFIX,magazines.sina.com.tw,Proxy\nDOMAIN-SUFFIX,b612-api.line-apps.com,Proxy\nDOMAIN-SUFFIX,legrandcontinent.eu,Proxy\nDOMAIN-SUFFIX,www.pornpin.com,Proxy\nDOMAIN-SUFFIX,cloudso.org,Proxy\nDOMAIN-SUFFIX,www.betvictor38.com,Proxy\nDOMAIN-SUFFIX,ads-twitter.com,Proxy\nDOMAIN-SUFFIX,okay.com.tr,Proxy\nDOMAIN-SUFFIX,asvpn.com,Proxy\nDOMAIN-SUFFIX,forum.iask.fr,Proxy\nDOMAIN-SUFFIX,d1stdkq55ggsv7.cloudfront.net,Proxy\nDOMAIN-SUFFIX,timestalks.com,Proxy\nDOMAIN-SUFFIX,parcelsapp.com,Proxy\nDOMAIN-SUFFIX,rtsinfo.ch,Proxy\nDOMAIN-SUFFIX,www.tiltbrush.com,Proxy\nDOMAIN-SUFFIX,5aimiku.com,Proxy\nDOMAIN-SUFFIX,shoppinginde.blogspot.jp,Proxy\nDOMAIN-SUFFIX,crd-net.org,Proxy\nDOMAIN-SUFFIX,www.zhongfengmetal.com,Proxy\nDOMAIN-SUFFIX,freeman2.com,Proxy\nDOMAIN-SUFFIX,d2jrqt6j5wmepe.cloudfront.net,Proxy\nDOMAIN-SUFFIX,myftp.name,Proxy\nDOMAIN-SUFFIX,tibetoffice.org,Proxy\nDOMAIN-SUFFIX,www.nnby.org,Proxy\nDOMAIN-SUFFIX,ai.okmiku.com,Proxy\nDOMAIN-SUFFIX,www.sangong-recht.de,Proxy\nDOMAIN-SUFFIX,serviporno.com,Proxy\nDOMAIN-SUFFIX,securecdn.oculus.com,Proxy\nDOMAIN-SUFFIX,732bm.com,Proxy\nDOMAIN-SUFFIX,d2gdtgbwh92fx7.cloudfront.net,Proxy\nDOMAIN-SUFFIX,osfoora.com,Proxy\nDOMAIN-SUFFIX,www.xun6.net,Proxy\nDOMAIN-SUFFIX,facebook.co,Proxy\nDOMAIN-SUFFIX,teddit.privacytools.io,Proxy\nDOMAIN-SUFFIX,www.amxs333.com,Proxy\nDOMAIN-SUFFIX,getconfide.com,Proxy\nDOMAIN-SUFFIX,ccc.milkcoffee.uk,Proxy\nDOMAIN-SUFFIX,digitaldesire.com,Proxy\nDOMAIN-SUFFIX,x1949x.com,Proxy\nDOMAIN-SUFFIX,uu777.net,Proxy\nDOMAIN-SUFFIX,core3.proxyswitcher.com,Proxy\nDOMAIN-SUFFIX,feedx.net,Proxy\nDOMAIN-SUFFIX,miman.jp,Proxy\nDOMAIN-SUFFIX,comp.ouhk.edu.hk,Proxy\nDOMAIN-SUFFIX,7sea.ch,Proxy\nDOMAIN-SUFFIX,www.yoo1.com,Proxy\nDOMAIN-SUFFIX,sinoca.com,Proxy\nDOMAIN-SUFFIX,noypf.com,Proxy\nDOMAIN-SUFFIX,beritaharian.sg,Proxy\nDOMAIN-SUFFIX,234.slyip.net,Proxy\nDOMAIN-SUFFIX,x1080x.com,Proxy\nDOMAIN-SUFFIX,www.hxcsxs.live,Proxy\nDOMAIN-SUFFIX,shoebridge.org.uk,Proxy\nDOMAIN-SUFFIX,xmbus.xyz,Proxy\nDOMAIN-SUFFIX,nitter.lacontrevoie.fr,Proxy\nDOMAIN-SUFFIX,friendorfollow.com,Proxy\nDOMAIN-SUFFIX,545050.com,Proxy\nDOMAIN-SUFFIX,rojiuramod.php.xdomain.jp,Proxy\nDOMAIN-SUFFIX,ml4786.com,Proxy\nDOMAIN-SUFFIX,cp52-4.trixbox.com,Proxy\nDOMAIN-SUFFIX,tst.org.tw,Proxy\nDOMAIN-SUFFIX,www.qvodzy.com,Proxy\nDOMAIN-SUFFIX,www.tibet-institut.ch,Proxy\nDOMAIN-SUFFIX,nitter.drivet.xyz,Proxy\nDOMAIN-SUFFIX,7mm.tv,Proxy\nDOMAIN-SUFFIX,www.23312.com,Proxy\nDOMAIN-SUFFIX,www.vyrso.com,Proxy\nDOMAIN-SUFFIX,vpntube.com,Proxy\nDOMAIN-SUFFIX,www.moyu4.com,Proxy\nDOMAIN-SUFFIX,lotsawahouse.org,Proxy\nDOMAIN-SUFFIX,www.coinexchange.io,Proxy\nDOMAIN-SUFFIX,ddfnetwork.com,Proxy\nDOMAIN-SUFFIX,aceros-de-hispania.com,Proxy\nDOMAIN-SUFFIX,gpuhash.com,Proxy\nDOMAIN-SUFFIX,www.dyvip36.com,Proxy\nDOMAIN-SUFFIX,1991way.com,Proxy\nDOMAIN-SUFFIX,kiwispiritdistillery.co.nz,Proxy\nDOMAIN-SUFFIX,www.youtubee.com,Proxy\nDOMAIN-SUFFIX,curve.fi,Proxy\nDOMAIN-SUFFIX,freedomhacker.net,Proxy\nDOMAIN-SUFFIX,hautelookcdn.com,Proxy\nDOMAIN-SUFFIX,www.nunuyy10.top,Proxy\nDOMAIN-SUFFIX,jamaica-gleaner.com,Proxy\nDOMAIN-SUFFIX,www.eton.club,Proxy\nDOMAIN-SUFFIX,nyt3.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,www.watchproxy.com,Proxy\nDOMAIN-SUFFIX,www.usaupload.net,Proxy\nDOMAIN-SUFFIX,us.hk303.c8763.com,Proxy\nDOMAIN-SUFFIX,cnnews.chosun.com,Proxy\nDOMAIN-SUFFIX,flagsonline.it,Proxy\nDOMAIN-SUFFIX,d2b1gl7puillot.cloudfront.net,Proxy\nDOMAIN-SUFFIX,youwould.com.au,Proxy\nDOMAIN-SUFFIX,the-luxury-collection.marriott.com,Proxy\nDOMAIN-SUFFIX,good.news,Proxy\nDOMAIN-SUFFIX,iccpx.org,Proxy\nDOMAIN-SUFFIX,cathvoice.org.tw,Proxy\nDOMAIN-SUFFIX,saarp.org,Proxy\nDOMAIN-SUFFIX,dalailama.org.br,Proxy\nDOMAIN-SUFFIX,homemademoviez.com,Proxy\nDOMAIN-SUFFIX,app.box.com,Proxy\nDOMAIN-SUFFIX,nextmag.com.tw,Proxy\nDOMAIN-SUFFIX,jyapp2.com,Proxy\nDOMAIN-SUFFIX,www.qgirl.com.tw,Proxy\nDOMAIN-SUFFIX,gunguide.org,Proxy\nDOMAIN-SUFFIX,studiovk.com,Proxy\nDOMAIN-SUFFIX,bichosout.cl,Proxy\nDOMAIN-SUFFIX,www-origin.discoverhongkong.com,Proxy\nDOMAIN-SUFFIX,www.hyyo.net,Proxy\nDOMAIN-SUFFIX,rawdirect.com,Proxy\nDOMAIN-SUFFIX,lsm.org,Proxy\nDOMAIN-SUFFIX,912.fullcoveronline.com,Proxy\nDOMAIN-SUFFIX,www.ogleearth.com,Proxy\nDOMAIN-SUFFIX,minecraftwiki.net,Proxy\nDOMAIN-SUFFIX,zonasaridas.com.ar,Proxy\nDOMAIN-SUFFIX,kamakurasango.blogspot.jp,Proxy\nDOMAIN-SUFFIX,klodia.ru,Proxy\nDOMAIN-SUFFIX,vpn.asia,Proxy\nDOMAIN-SUFFIX,4136.com,Proxy\nDOMAIN-SUFFIX,hkzone.org,Proxy\nDOMAIN-SUFFIX,support.niceincontact.com,Proxy\nDOMAIN-SUFFIX,prideradio.iheart.com,Proxy\nDOMAIN-SUFFIX,india.gov.in,Proxy\nDOMAIN-SUFFIX,stumbleupon.com,Proxy\nDOMAIN-SUFFIX,www.sauditimes.com,Proxy\nDOMAIN-SUFFIX,savetibet.ru,Proxy\nDOMAIN-SUFFIX,gandkhujli.com,Proxy\nDOMAIN-SUFFIX,podpora-tibetu.org,Proxy\nDOMAIN-SUFFIX,home.so-net.net.tw,Proxy\nDOMAIN-SUFFIX,yuvpn.com,Proxy\nDOMAIN-SUFFIX,zambranolimitada.cl,Proxy\nDOMAIN-SUFFIX,yazhouse8.com,Proxy\nDOMAIN-SUFFIX,4565566.com,Proxy\nDOMAIN-SUFFIX,axelzone.ro,Proxy\nDOMAIN-SUFFIX,gr.com,Proxy\nDOMAIN-SUFFIX,d2f2nhyfqv5pkz.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.cfnmsecret.com,Proxy\nDOMAIN-SUFFIX,macaudailytimes.com.mo,Proxy\nDOMAIN-SUFFIX,fuckme.ga,Proxy\nDOMAIN-SUFFIX,raduvaduva.ro,Proxy\nDOMAIN-SUFFIX,chenfu.strikingly.com,Proxy\nDOMAIN-SUFFIX,tibetaction.net,Proxy\nDOMAIN-SUFFIX,cox.net,Proxy\nDOMAIN-SUFFIX,dyndns-ip.com,Proxy\nDOMAIN-SUFFIX,hk.mssi.pw,Proxy\nDOMAIN-SUFFIX,xingong.com.tw,Proxy\nDOMAIN-SUFFIX,18comic-now.org,Proxy\nDOMAIN-SUFFIX,ericjgagnon.com,Proxy\nDOMAIN-SUFFIX,ww2.money-link.com.tw,Proxy\nDOMAIN-SUFFIX,d2u1rdge9awnd8.cloudfront.net,Proxy\nDOMAIN-SUFFIX,t-mirror.github.io,Proxy\nDOMAIN-SUFFIX,mohu.rocks,Proxy\nDOMAIN-SUFFIX,savetibetstore.org,Proxy\nDOMAIN-SUFFIX,slixa.ch,Proxy\nDOMAIN-SUFFIX,888casino.com,Proxy\nDOMAIN-SUFFIX,dwnews.com,Proxy\nDOMAIN-SUFFIX,crownka.com,Proxy\nDOMAIN-SUFFIX,jobso.tv,Proxy\nDOMAIN-SUFFIX,linear-abematv.akamaized.net,Proxy\nDOMAIN-SUFFIX,felvidek.ma,Proxy\nDOMAIN-SUFFIX,gdanstum.net,Proxy\nDOMAIN-SUFFIX,jmcomic4.me,Proxy\nDOMAIN-SUFFIX,cn.fmnnow.com,Proxy\nDOMAIN-SUFFIX,tw.artemislena.eu,Proxy\nDOMAIN-SUFFIX,www.esukhia.org,Proxy\nDOMAIN-SUFFIX,vajrayana.com.au,Proxy\nDOMAIN-SUFFIX,curanderahealing.com,Proxy\nDOMAIN-SUFFIX,668200000.com,Proxy\nDOMAIN-SUFFIX,a394cbd382.xyz.global.prod.fastly.net,Proxy\nDOMAIN-SUFFIX,www.deerparkcenter.org,Proxy\nDOMAIN-SUFFIX,chinamule.com,Proxy\nDOMAIN-SUFFIX,fnc.ebc.net.tw,Proxy\nDOMAIN-SUFFIX,magnet.ml,Proxy\nDOMAIN-SUFFIX,www.hj2699.com,Proxy\nDOMAIN-SUFFIX,www.speedpan.com,Proxy\nDOMAIN-SUFFIX,apkplz.com,Proxy\nDOMAIN-SUFFIX,aetoscg.com,Proxy\nDOMAIN-SUFFIX,tech.lgbt,Proxy\nDOMAIN-SUFFIX,docbox.fricke-g.de,Proxy\nDOMAIN-SUFFIX,www.fulidao4.com,Proxy\nDOMAIN-SUFFIX,abbykitty.com,Proxy\nDOMAIN-SUFFIX,vcpd.com,Proxy\nDOMAIN-SUFFIX,jmcomic3.cc,Proxy\nDOMAIN-SUFFIX,abbykitty.000webhostapp.com,Proxy\nDOMAIN-SUFFIX,kusocity.com,Proxy\nDOMAIN-SUFFIX,proxy-youtube.net,Proxy\nDOMAIN-SUFFIX,megamor.com.br,Proxy\nDOMAIN-SUFFIX,nordstromimage.com,Proxy\nDOMAIN-SUFFIX,news1130.com,Proxy\nDOMAIN-SUFFIX,rkelly.com,Proxy\nDOMAIN-SUFFIX,www.frontpagemag.com,Proxy\nDOMAIN-SUFFIX,chromium.org,Proxy\nDOMAIN-SUFFIX,unrestrict.com,Proxy\nDOMAIN-SUFFIX,zh.asoiaf.wikia.com,Proxy\nDOMAIN-SUFFIX,www.exacteditions.com,Proxy\nDOMAIN-SUFFIX,www.blackoutforhumanrights.com,Proxy\nDOMAIN-SUFFIX,tibetnetwork.org,Proxy\nDOMAIN-SUFFIX,forums.lastbullet.net,Proxy\nDOMAIN-SUFFIX,feedzshare.com,Proxy\nDOMAIN-SUFFIX,www.quantarts.com,Proxy\nDOMAIN-SUFFIX,braindisconnect.com,Proxy\nDOMAIN-SUFFIX,app.gd.ddns.name,Proxy\nDOMAIN-SUFFIX,www.xun77.com,Proxy\nDOMAIN-SUFFIX,livejasmin.com,Proxy\nDOMAIN-SUFFIX,china-mmm.net,Proxy\nDOMAIN-SUFFIX,elprincipe.com,Proxy\nDOMAIN-SUFFIX,www.betway888.com,Proxy\nDOMAIN-SUFFIX,www.top10bestvpn.com,Proxy\nDOMAIN-SUFFIX,suomikoulu.de,Proxy\nDOMAIN-SUFFIX,www.esunsec.com.tw,Proxy\nDOMAIN-SUFFIX,www.xx1943.com,Proxy\nDOMAIN-SUFFIX,sites.iscvt.org,Proxy\nDOMAIN-SUFFIX,bravoerotica.com,Proxy\nDOMAIN-SUFFIX,www.tb883.com,Proxy\nDOMAIN-SUFFIX,goodssh.com,Proxy\nDOMAIN-SUFFIX,138.com,Proxy\nDOMAIN-SUFFIX,brightcove01.brightcove.com,Proxy\nDOMAIN-SUFFIX,www.tiananmenduizhi.com,Proxy\nDOMAIN-SUFFIX,google.pk,Proxy\nDOMAIN-SUFFIX,myrics.com,Proxy\nDOMAIN-SUFFIX,id.now-ip.net,Proxy\nDOMAIN-SUFFIX,www.ca181.com,Proxy\nDOMAIN-SUFFIX,googleforchina.com,Proxy\nDOMAIN-SUFFIX,nic.goog,Proxy\nDOMAIN-SUFFIX,landofhope.tv,Proxy\nDOMAIN-SUFFIX,www.aiuus.com,Proxy\nDOMAIN-SUFFIX,sh051996.tudouser.com,Proxy\nDOMAIN-SUFFIX,www.bilifuli.com,Proxy\nDOMAIN-SUFFIX,266.slyip.com,Proxy\nDOMAIN-SUFFIX,www.standard.net.au,Proxy\nDOMAIN-SUFFIX,boxpn.com,Proxy\nDOMAIN-SUFFIX,xrayjoe.com,Proxy\nDOMAIN-SUFFIX,lumaster.com,Proxy\nDOMAIN-SUFFIX,oliverjcole.co.uk,Proxy\nDOMAIN-SUFFIX,goalcounter.com,Proxy\nDOMAIN-SUFFIX,machix.com,Proxy\nDOMAIN-SUFFIX,thefacebook.com,Proxy\nDOMAIN-SUFFIX,newstarnet.com,Proxy\nDOMAIN-SUFFIX,www.netignition.com,Proxy\nDOMAIN-SUFFIX,wallmama.com,Proxy\nDOMAIN-SUFFIX,tesco.pl,Proxy\nDOMAIN-SUFFIX,mp.ejdj12.com,Proxy\nDOMAIN-SUFFIX,www.dd8tv.com,Proxy\nDOMAIN-SUFFIX,www.holyfamilykt.edu.hk,Proxy\nDOMAIN-SUFFIX,768.la,Proxy\nDOMAIN-SUFFIX,diygod.me,Proxy\nDOMAIN-SUFFIX,awabo.com,Proxy\nDOMAIN-SUFFIX,booms.cc,Proxy\nDOMAIN-SUFFIX,c1a.spacetechnology.net,Proxy\nDOMAIN-SUFFIX,asianews.it,Proxy\nDOMAIN-SUFFIX,lrfz.com,Proxy\nDOMAIN-SUFFIX,wit.im,Proxy\nDOMAIN-SUFFIX,terabox.com,Proxy\nDOMAIN-SUFFIX,rocksdb.org,Proxy\nDOMAIN-SUFFIX,tbskkinabalu.page.tl,Proxy\nDOMAIN-SUFFIX,twtkr.com,Proxy\nDOMAIN-SUFFIX,iam.ma,Proxy\nDOMAIN-SUFFIX,wheretowatch.com,Proxy\nDOMAIN-SUFFIX,biplus.date,Proxy\nDOMAIN-SUFFIX,sitemaps.org,Proxy\nDOMAIN-SUFFIX,busayari.com,Proxy\nDOMAIN-SUFFIX,getfreedur.com,Proxy\nDOMAIN-SUFFIX,www.siteonlinetest.com,Proxy\nDOMAIN-SUFFIX,bccnews.com.tw,Proxy\nDOMAIN-SUFFIX,search.avira.com,Proxy\nDOMAIN-SUFFIX,vpnfacile.net,Proxy\nDOMAIN-SUFFIX,epochtimes.fr,Proxy\nDOMAIN-SUFFIX,gateio.io,Proxy\nDOMAIN-SUFFIX,www.wavesandbox.com,Proxy\nDOMAIN-SUFFIX,ilove80.be,Proxy\nDOMAIN-SUFFIX,www.tvbts.com,Proxy\nDOMAIN-SUFFIX,ultrareach.com,Proxy\nDOMAIN-SUFFIX,www.lalgbtcenter.org,Proxy\nDOMAIN-SUFFIX,sunworld34.000webhostapp.com,Proxy\nDOMAIN-SUFFIX,d3aj00iefsmfgc.cloudfront.net,Proxy\nDOMAIN-SUFFIX,ham-radio-op.net,Proxy\nDOMAIN-SUFFIX,m.yuyanlive.tv,Proxy\nDOMAIN-SUFFIX,554js.com,Proxy\nDOMAIN-SUFFIX,devpn.com,Proxy\nDOMAIN-SUFFIX,www.peerio.com,Proxy\nDOMAIN-SUFFIX,bmw80000.com,Proxy\nDOMAIN-SUFFIX,avdish.com,Proxy\nDOMAIN-SUFFIX,smeeth.in,Proxy\nDOMAIN-SUFFIX,arte.tv,Proxy\nDOMAIN-SUFFIX,newpowerparty.tw,Proxy\nDOMAIN-SUFFIX,www.discovertaitung.com,Proxy\nDOMAIN-SUFFIX,hsj3.com,Proxy\nDOMAIN-SUFFIX,news.boxun.com,Proxy\nDOMAIN-SUFFIX,xh8716.com,Proxy\nDOMAIN-SUFFIX,doh.technochat.in,Proxy\nDOMAIN-SUFFIX,quicksprout.com,Proxy\nDOMAIN-SUFFIX,11cpk.com,Proxy\nDOMAIN-SUFFIX,dropboxstatic.com,Proxy\nDOMAIN-SUFFIX,366.wha.la,Proxy\nDOMAIN-SUFFIX,nostr.com,Proxy\nDOMAIN-SUFFIX,bailandaily.com,Proxy\nDOMAIN-SUFFIX,dabr.co.uk,Proxy\nDOMAIN-SUFFIX,d2u9f8yrwlx5va.cloudfront.net,Proxy\nDOMAIN-SUFFIX,xh8707.com,Proxy\nDOMAIN-SUFFIX,alvpn.com,Proxy\nDOMAIN-SUFFIX,2miners.com,Proxy\nDOMAIN-SUFFIX,a31.privatedns.org,Proxy\nDOMAIN-SUFFIX,www.extrabux.com,Proxy\nDOMAIN-SUFFIX,www.6396u.com,Proxy\nDOMAIN-SUFFIX,yanukovychleaks.org,Proxy\nDOMAIN-SUFFIX,www.a4v5.top,Proxy\nDOMAIN-SUFFIX,affyun.org,Proxy\nDOMAIN-SUFFIX,www.noyavpn.com,Proxy\nDOMAIN-SUFFIX,21947.net,Proxy\nDOMAIN-SUFFIX,kolody.net,Proxy\nDOMAIN-SUFFIX,w.htcc.us,Proxy\nDOMAIN-SUFFIX,mandelbaerli.com,Proxy\nDOMAIN-SUFFIX,difangwenge.org,Proxy\nDOMAIN-SUFFIX,www.bigboobsalert.com,Proxy\nDOMAIN-SUFFIX,shinnoca.byethost7.com,Proxy\nDOMAIN-SUFFIX,t35.com,Proxy\nDOMAIN-SUFFIX,n888yy.com,Proxy\nDOMAIN-SUFFIX,www.xxlottery.com,Proxy\nDOMAIN-SUFFIX,fqok.org,Proxy\nDOMAIN-SUFFIX,japantimes.co.jp,Proxy\nDOMAIN-SUFFIX,agnj3.fun805.com,Proxy\nDOMAIN-SUFFIX,18board.com,Proxy\nDOMAIN-SUFFIX,vpnwo.com,Proxy\nDOMAIN-SUFFIX,www.insect-mall.idv.tw,Proxy\nDOMAIN-SUFFIX,88.tv,Proxy\nDOMAIN-SUFFIX,www.purifymind.com,Proxy\nDOMAIN-SUFFIX,pcanet.org,Proxy\nDOMAIN-SUFFIX,nitter.cc,Proxy\nDOMAIN-SUFFIX,yuritelecom.com,Proxy\nDOMAIN-SUFFIX,google.fr,Proxy\nDOMAIN-SUFFIX,www.sss150.com,Proxy\nDOMAIN-SUFFIX,china.akamai.com.edgesuite.net,Proxy\nDOMAIN-SUFFIX,www.newsolids.com,Proxy\nDOMAIN-SUFFIX,www.pornorama.com,Proxy\nDOMAIN-SUFFIX,fitnessplanet.us,Proxy\nDOMAIN-SUFFIX,ca897.com,Proxy\nDOMAIN-SUFFIX,www.bb-in.tv,Proxy\nDOMAIN-SUFFIX,media.nu.nl,Proxy\nDOMAIN-SUFFIX,www.fraternali.com,Proxy\nDOMAIN-SUFFIX,xinbi288.com,Proxy\nDOMAIN-SUFFIX,pamelageller.com,Proxy\nDOMAIN-SUFFIX,orfonline.org,Proxy\nDOMAIN-SUFFIX,jinx.com,Proxy\nDOMAIN-SUFFIX,xwqp.club,Proxy\nDOMAIN-SUFFIX,www.lonlife.cc,Proxy\nDOMAIN-SUFFIX,verybs.com,Proxy\nDOMAIN-SUFFIX,nyandcompany.com,Proxy\nDOMAIN-SUFFIX,leirentv.ca,Proxy\nDOMAIN-SUFFIX,coolaler.com,Proxy\nDOMAIN-SUFFIX,sohfrance.org,Proxy\nDOMAIN-SUFFIX,www.lamenhu.com,Proxy\nDOMAIN-SUFFIX,rlzz8.fun,Proxy\nDOMAIN-SUFFIX,www.doritos.com.tw,Proxy\nDOMAIN-SUFFIX,www.antvpn.net,Proxy\nDOMAIN-SUFFIX,www.forum2000.cz,Proxy\nDOMAIN-SUFFIX,newyorktimes.com,Proxy\nDOMAIN-SUFFIX,govthealth.xyz,Proxy\nDOMAIN-SUFFIX,ca.wcar.us,Proxy\nDOMAIN-SUFFIX,privatevpn.com,Proxy\nDOMAIN-SUFFIX,kba-tx.org,Proxy\nDOMAIN-SUFFIX,nanrenfuli.com,Proxy\nDOMAIN-SUFFIX,www.ville-palaiseau.fr,Proxy\nDOMAIN-SUFFIX,k6s3v6r4.ssl.hwcdn.net,Proxy\nDOMAIN-SUFFIX,www.shikoku-np.co.jp,Proxy\nDOMAIN-SUFFIX,urvpn.com,Proxy\nDOMAIN-SUFFIX,www.themalaysianinsight.com,Proxy\nDOMAIN-SUFFIX,www.newzealandreview.com,Proxy\nDOMAIN-SUFFIX,en.beta.qualityready.de,Proxy\nDOMAIN-SUFFIX,javtag.com,Proxy\nDOMAIN-SUFFIX,factwire.org,Proxy\nDOMAIN-SUFFIX,www.affordablewebdesign.ca,Proxy\nDOMAIN-SUFFIX,1kan.com,Proxy\nDOMAIN-SUFFIX,www.challenger.it,Proxy\nDOMAIN-SUFFIX,wiki.com,Proxy\nDOMAIN-SUFFIX,www.999rich.com,Proxy\nDOMAIN-SUFFIX,aqd.net,Proxy\nDOMAIN-SUFFIX,www.resilientsystems.com,Proxy\nDOMAIN-SUFFIX,notabird.site,Proxy\nDOMAIN-SUFFIX,shapeshift.io,Proxy\nDOMAIN-SUFFIX,tibetgermany.de,Proxy\nDOMAIN-SUFFIX,www.alquds.edu,Proxy\nDOMAIN-SUFFIX,brkmd.com,Proxy\nDOMAIN-SUFFIX,2cytk.com,Proxy\nDOMAIN-SUFFIX,www.speedin.cc,Proxy\nDOMAIN-SUFFIX,vipcrew.com,Proxy\nDOMAIN-SUFFIX,rb233.com,Proxy\nDOMAIN-SUFFIX,blogspot.nl,Proxy\nDOMAIN-SUFFIX,imouto.me,Proxy\nDOMAIN-SUFFIX,xh077.com,Proxy\nDOMAIN-SUFFIX,www.fetc.net.tw,Proxy\nDOMAIN-SUFFIX,d3fwaul945bv9o.cloudfront.net,Proxy\nDOMAIN-SUFFIX,d3llow2umtkn18.cloudfront.net,Proxy\nDOMAIN-SUFFIX,gabocorp.com,Proxy\nDOMAIN-SUFFIX,www.voaindonesia.com,Proxy\nDOMAIN-SUFFIX,amp.twimg.com,Proxy\nDOMAIN-SUFFIX,adevar.net,Proxy\nDOMAIN-SUFFIX,www.dyvip567.com,Proxy\nDOMAIN-SUFFIX,64wiki.com,Proxy\nDOMAIN-SUFFIX,lushstories.com,Proxy\nDOMAIN-SUFFIX,d.css5.pw,Proxy\nDOMAIN-SUFFIX,javpub.me,Proxy\nDOMAIN-SUFFIX,s3-ap-northeast-1.toshiba-medical.biz,Proxy\nDOMAIN-SUFFIX,search.leptons.xyz,Proxy\nDOMAIN-SUFFIX,www.407678.com,Proxy\nDOMAIN-SUFFIX,serei.com.br,Proxy\nDOMAIN-SUFFIX,mangafox.com,Proxy\nDOMAIN-SUFFIX,expatshield.com,Proxy\nDOMAIN-SUFFIX,uni.cc,Proxy\nDOMAIN-SUFFIX,qkav9.cf,Proxy\nDOMAIN-SUFFIX,paymode.com,Proxy\nDOMAIN-SUFFIX,bbc3.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,busu.org,Proxy\nDOMAIN-SUFFIX,s1heng.com,Proxy\nDOMAIN-SUFFIX,ss.wuw.red,Proxy\nDOMAIN-SUFFIX,stoppornculture.org,Proxy\nDOMAIN-SUFFIX,bbs.k369.eu.org,Proxy\nDOMAIN-SUFFIX,21pron.com,Proxy\nDOMAIN-SUFFIX,hkzz8.com,Proxy\nDOMAIN-SUFFIX,tlc88.cc,Proxy\nDOMAIN-SUFFIX,officeoftibet.com,Proxy\nDOMAIN-SUFFIX,partypoker.com,Proxy\nDOMAIN-SUFFIX,www.superproxy.nl,Proxy\nDOMAIN-SUFFIX,www.twr360.org,Proxy\nDOMAIN-SUFFIX,d2mh2g99xg30dl.cloudfront.net,Proxy\nDOMAIN-SUFFIX,helpzhuling.org,Proxy\nDOMAIN-SUFFIX,www.genj.nl,Proxy\nDOMAIN-SUFFIX,libretooth.gr,Proxy\nDOMAIN-SUFFIX,rp8.github.io,Proxy\nDOMAIN-SUFFIX,www.52ico.com,Proxy\nDOMAIN-SUFFIX,www.ticket.com.tw,Proxy\nDOMAIN-SUFFIX,cvscs.org,Proxy\nDOMAIN-SUFFIX,61789c.com,Proxy\nDOMAIN-SUFFIX,airberlin.com,Proxy\nDOMAIN-SUFFIX,www.morningstar.co.uk,Proxy\nDOMAIN-SUFFIX,ippotsuko.com,Proxy\nDOMAIN-SUFFIX,www.duolingo.com,Proxy\nDOMAIN-SUFFIX,app.tuta.com,Proxy\nDOMAIN-SUFFIX,proxysites.com,Proxy\nDOMAIN-SUFFIX,hideme.nl,Proxy\nDOMAIN-SUFFIX,implicante.org,Proxy\nDOMAIN-SUFFIX,38850022.com,Proxy\nDOMAIN-SUFFIX,d2zw3ifm11rrr4.cloudfront.net,Proxy\nDOMAIN-SUFFIX,efatech.com,Proxy\nDOMAIN-SUFFIX,coolsex.biz,Proxy\nDOMAIN-SUFFIX,lb92.com,Proxy\nDOMAIN-SUFFIX,www.londonchinese.ca,Proxy\nDOMAIN-SUFFIX,xvideos.red,Proxy\nDOMAIN-SUFFIX,www.merimbulanewsweekly.com.au,Proxy\nDOMAIN-SUFFIX,andreotti.com.ar,Proxy\nDOMAIN-SUFFIX,mccormicklit.com,Proxy\nDOMAIN-SUFFIX,udn22.gq,Proxy\nDOMAIN-SUFFIX,www.conservapedia.com,Proxy\nDOMAIN-SUFFIX,cofoo.com,Proxy\nDOMAIN-SUFFIX,leglegs.com,Proxy\nDOMAIN-SUFFIX,softsense.ca,Proxy\nDOMAIN-SUFFIX,mangatraders.com,Proxy\nDOMAIN-SUFFIX,stileproject.com,Proxy\nDOMAIN-SUFFIX,teenmegaporn.com,Proxy\nDOMAIN-SUFFIX,hcaptcha.com,Proxy\nDOMAIN-SUFFIX,store.steampowered.com,Proxy\nDOMAIN-SUFFIX,tibetan-alliance.org,Proxy\nDOMAIN-SUFFIX,www.bodhi.tw,Proxy\nDOMAIN-SUFFIX,news.tvbs.com.tw,Proxy\nDOMAIN-SUFFIX,bioexpress.pt,Proxy\nDOMAIN-SUFFIX,pedapoint.fi,Proxy\nDOMAIN-SUFFIX,www.leche69.com,Proxy\nDOMAIN-SUFFIX,www.cambridgesatchel.com,Proxy\nDOMAIN-SUFFIX,md-t.org,Proxy\nDOMAIN-SUFFIX,google.tt,Proxy\nDOMAIN-SUFFIX,celerondude.com,Proxy\nDOMAIN-SUFFIX,beaconevents.com,Proxy\nDOMAIN-SUFFIX,dunktankbabes.com,Proxy\nDOMAIN-SUFFIX,lsmkorean.org,Proxy\nDOMAIN-SUFFIX,capitalmarket.us,Proxy\nDOMAIN-SUFFIX,grik.gr,Proxy\nDOMAIN-SUFFIX,maggi.co.uk,Proxy\nDOMAIN-SUFFIX,tubesafari.com,Proxy\nDOMAIN-SUFFIX,snl.no,Proxy\nDOMAIN-SUFFIX,www.nycu.edu.tw,Proxy\nDOMAIN-SUFFIX,gi.8888og.com,Proxy\nDOMAIN-SUFFIX,www.realteengirls.com,Proxy\nDOMAIN-SUFFIX,blog.seesaa.jp,Proxy\nDOMAIN-SUFFIX,dev.to,Proxy\nDOMAIN-SUFFIX,fpmtmexico.org,Proxy\nDOMAIN-SUFFIX,rebelpeppercartoons.com,Proxy\nDOMAIN-SUFFIX,flyssh.com,Proxy\nDOMAIN-SUFFIX,dy.ddns.name,Proxy\nDOMAIN-SUFFIX,www.diedart.com,Proxy\nDOMAIN-SUFFIX,hk.knowledge.yahoo.com,Proxy\nDOMAIN-SUFFIX,cpj.org,Proxy\nDOMAIN-SUFFIX,www.realclearworld.com,Proxy\nDOMAIN-SUFFIX,www.tcsb.com.tw,Proxy\nDOMAIN-SUFFIX,www.xw256.com,Proxy\nDOMAIN-SUFFIX,cn.chosun.com,Proxy\nDOMAIN-SUFFIX,www.befreebe.com,Proxy\nDOMAIN-SUFFIX,zhuanji.net,Proxy\nDOMAIN-SUFFIX,66.wha.la,Proxy\nDOMAIN-SUFFIX,venly.io,Proxy\nDOMAIN-SUFFIX,css.privatedns.org,Proxy\nDOMAIN-SUFFIX,westpoint.edu,Proxy\nDOMAIN-SUFFIX,theblondeabroad.com,Proxy\nDOMAIN-SUFFIX,zoosk.com,Proxy\nDOMAIN-SUFFIX,ssteam.me,Proxy\nDOMAIN-SUFFIX,opengoing.com,Proxy\nDOMAIN-SUFFIX,www.2859n.com,Proxy\nDOMAIN-SUFFIX,www.aviokarte.hr,Proxy\nDOMAIN-SUFFIX,doubi.neocities.org,Proxy\nDOMAIN-SUFFIX,ibo.com,Proxy\nDOMAIN-SUFFIX,www.ehamaide.com,Proxy\nDOMAIN-SUFFIX,ipsnews.net,Proxy\nDOMAIN-SUFFIX,thebl.com,Proxy\nDOMAIN-SUFFIX,abduzeedo.com,Proxy\nDOMAIN-SUFFIX,cctmweb.net,Proxy\nDOMAIN-SUFFIX,www.kkbox.com.tw,Proxy\nDOMAIN-SUFFIX,srcf.ucam.org,Proxy\nDOMAIN-SUFFIX,iqq.buzz,Proxy\nDOMAIN-SUFFIX,pixiviz.pwp.app,Proxy\nDOMAIN-SUFFIX,www.7kidsandus.com,Proxy\nDOMAIN-SUFFIX,daolan.net,Proxy\nDOMAIN-SUFFIX,188bet.com,Proxy\nDOMAIN-SUFFIX,anonym.im,Proxy\nDOMAIN-SUFFIX,breakblack.net,Proxy\nDOMAIN-SUFFIX,tusfiles.net,Proxy\nDOMAIN-SUFFIX,overclock.net,Proxy\nDOMAIN-SUFFIX,bifa.net,Proxy\nDOMAIN-SUFFIX,cp.walllink.cc,Proxy\nDOMAIN-SUFFIX,99958a.com,Proxy\nDOMAIN-SUFFIX,www.nikkei.co.jp,Proxy\nDOMAIN-SUFFIX,m.288ysb.com,Proxy\nDOMAIN-SUFFIX,pay.15311.com,Proxy\nDOMAIN-SUFFIX,meblobud.com,Proxy\nDOMAIN-SUFFIX,87.from-wy.com,Proxy\nDOMAIN-SUFFIX,nachovidal.com,Proxy\nDOMAIN-SUFFIX,soulchill.com,Proxy\nDOMAIN-SUFFIX,proxify.cc,Proxy\nDOMAIN-SUFFIX,biantube.com,Proxy\nDOMAIN-SUFFIX,haiwai.com,Proxy\nDOMAIN-SUFFIX,mp3searched.com,Proxy\nDOMAIN-SUFFIX,ifengus.com,Proxy\nDOMAIN-SUFFIX,staysafeonline.org,Proxy\nDOMAIN-SUFFIX,trader711.com,Proxy\nDOMAIN-SUFFIX,decolores.cl,Proxy\nDOMAIN-SUFFIX,www.saatchiart.com,Proxy\nDOMAIN-SUFFIX,ah-me.com,Proxy\nDOMAIN-SUFFIX,qqjj18.com,Proxy\nDOMAIN-SUFFIX,stufferdb.com,Proxy\nDOMAIN-SUFFIX,buyu255.com,Proxy\nDOMAIN-SUFFIX,nemesis.co.il,Proxy\nDOMAIN-SUFFIX,7j94.sec.b0ne.com,Proxy\nDOMAIN-SUFFIX,dds.crl.edu,Proxy\nDOMAIN-SUFFIX,www.90lhbd.com,Proxy\nDOMAIN-SUFFIX,cdn.donmai.us,Proxy\nDOMAIN-SUFFIX,gostats.cn,Proxy\nDOMAIN-SUFFIX,chatplus.pro,Proxy\nDOMAIN-SUFFIX,askmefast.com,Proxy\nDOMAIN-SUFFIX,www.118518.com,Proxy\nDOMAIN-SUFFIX,blog.cryptographyengineering.com,Proxy\nDOMAIN-SUFFIX,avno1.com,Proxy\nDOMAIN-SUFFIX,hentai.as,Proxy\nDOMAIN-SUFFIX,sugarcrm.com,Proxy\nDOMAIN-SUFFIX,theaterplasselb.ch,Proxy\nDOMAIN-SUFFIX,zlibrary.org,Proxy\nDOMAIN-SUFFIX,d1f56wscdlhp8n.cloudfront.net,Proxy\nDOMAIN-SUFFIX,tb0082.com,Proxy\nDOMAIN-SUFFIX,hongfire.com,Proxy\nDOMAIN-SUFFIX,www.cna.com.hk,Proxy\nDOMAIN-SUFFIX,www.helixstudios.net,Proxy\nDOMAIN-SUFFIX,globalsecurity.org,Proxy\nDOMAIN-SUFFIX,fail.hk,Proxy\nDOMAIN-SUFFIX,ie2205.com,Proxy\nDOMAIN-SUFFIX,tlc168.com,Proxy\nDOMAIN-SUFFIX,qiwen.lu,Proxy\nDOMAIN-SUFFIX,mega.nz,Proxy\nDOMAIN-SUFFIX,ohmyrss.com,Proxy\nDOMAIN-SUFFIX,918689.com,Proxy\nDOMAIN-SUFFIX,babylonbee.com,Proxy\nDOMAIN-SUFFIX,terence.tk,Proxy\nDOMAIN-SUFFIX,flowerofhappiness.spaces.live.com,Proxy\nDOMAIN-SUFFIX,fb.me,Proxy\nDOMAIN-SUFFIX,longbowgroup.com,Proxy\nDOMAIN-SUFFIX,www.cis.org.au,Proxy\nDOMAIN-SUFFIX,www.buddhisme.no,Proxy\nDOMAIN-SUFFIX,www.alqp190.com,Proxy\nDOMAIN-SUFFIX,pr.erdavet.ro,Proxy\nDOMAIN-SUFFIX,uhdwallpapers.org,Proxy\nDOMAIN-SUFFIX,hello.2heng.xin,Proxy\nDOMAIN-SUFFIX,moov.cc,Proxy\nDOMAIN-SUFFIX,pb1lib.org,Proxy\nDOMAIN-SUFFIX,d1c0f34jtncykr.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.atcc.org,Proxy\nDOMAIN-SUFFIX,senavn.com,Proxy\nDOMAIN-SUFFIX,vcf-online.org,Proxy\nDOMAIN-SUFFIX,rocketpride.com,Proxy\nDOMAIN-SUFFIX,www.shoryuken.com,Proxy\nDOMAIN-SUFFIX,www.halifax.co.uk,Proxy\nDOMAIN-SUFFIX,www.bubbaporn.com,Proxy\nDOMAIN-SUFFIX,twftp.org,Proxy\nDOMAIN-SUFFIX,nubiles.net,Proxy\nDOMAIN-SUFFIX,d2ch0rswg635zl.cloudfront.net,Proxy\nDOMAIN-SUFFIX,yuyou198.com,Proxy\nDOMAIN-SUFFIX,www.anew.live,Proxy\nDOMAIN-SUFFIX,www.google.co.il,Proxy\nDOMAIN-SUFFIX,scmpchinese.com,Proxy\nDOMAIN-SUFFIX,papakev.de,Proxy\nDOMAIN-SUFFIX,miniaturas.com.ar,Proxy\nDOMAIN-SUFFIX,stream.jw.org,Proxy\nDOMAIN-SUFFIX,piwik.pro,Proxy\nDOMAIN-SUFFIX,75866ss.com,Proxy\nDOMAIN-SUFFIX,www.breitbart.com,Proxy\nDOMAIN-SUFFIX,pornub.com,Proxy\nDOMAIN-SUFFIX,bevpn.com,Proxy\nDOMAIN-SUFFIX,fishandhappiness.blogspot.hk,Proxy\nDOMAIN-SUFFIX,mediaset.us,Proxy\nDOMAIN-SUFFIX,www.ceuandalucia.es,Proxy\nDOMAIN-SUFFIX,a.guge.ga,Proxy\nIP-CIDR,67.220.91.18/32,Proxy\nDOMAIN-SUFFIX,api.knightstory.io,Proxy\nDOMAIN-SUFFIX,bombbomb.com,Proxy\nDOMAIN-SUFFIX,wiki.esu.moe,Proxy\nDOMAIN-SUFFIX,xijinping.xyz,Proxy\nDOMAIN-SUFFIX,36.cr.rs,Proxy\nDOMAIN-SUFFIX,akhbor.com,Proxy\nDOMAIN-SUFFIX,news.tbs.co.jp,Proxy\nDOMAIN-SUFFIX,zzz.healthonsite.xyz,Proxy\nDOMAIN-SUFFIX,www.usessh001.com,Proxy\nDOMAIN-SUFFIX,heroli.com,Proxy\nDOMAIN-SUFFIX,www.global-math.com,Proxy\nDOMAIN-SUFFIX,flickr.com,Proxy\nDOMAIN-SUFFIX,www.twgreatdaily.com,Proxy\nDOMAIN-SUFFIX,www.freebookchina.com,Proxy\nDOMAIN-SUFFIX,www.visionchinatimes.com,Proxy\nDOMAIN-SUFFIX,xlfmwz.info,Proxy\nDOMAIN-SUFFIX,chiccharm.com.br,Proxy\nDOMAIN-SUFFIX,p90.zone,Proxy\nDOMAIN-SUFFIX,70966a.com,Proxy\nDOMAIN-SUFFIX,schoolcloud.net,Proxy\nDOMAIN-SUFFIX,www.creditoycaucion.es,Proxy\nDOMAIN-SUFFIX,blog.vsiu.ca,Proxy\nDOMAIN-SUFFIX,login.live.com,Proxy\nDOMAIN-SUFFIX,www.acss.red,Proxy\nDOMAIN-SUFFIX,5kli.r5.cr.rs,Proxy\nDOMAIN-SUFFIX,xpaja.net,Proxy\nDOMAIN-SUFFIX,cliti.com,Proxy\nDOMAIN-SUFFIX,manhub.com,Proxy\nDOMAIN-SUFFIX,omawww.sat.gob.mx,Proxy\nDOMAIN-SUFFIX,paganwiccan.about.com,Proxy\nDOMAIN-SUFFIX,www.lyzhendao.net,Proxy\nDOMAIN-SUFFIX,lyncone.lyncpay.com,Proxy\nDOMAIN-SUFFIX,www.avm.de,Proxy\nDOMAIN-SUFFIX,gaytag.net,Proxy\nDOMAIN-SUFFIX,bogusx.idv.tw,Proxy\nDOMAIN-SUFFIX,gayauthors.org,Proxy\nDOMAIN-SUFFIX,zalio.net,Proxy\nDOMAIN-SUFFIX,www.switchyomega.com,Proxy\nDOMAIN-SUFFIX,d331.uc66.eu.org,Proxy\nDOMAIN-SUFFIX,cclife.org,Proxy\nDOMAIN-SUFFIX,changeip.name,Proxy\nDOMAIN-SUFFIX,gun-world.net,Proxy\nDOMAIN-SUFFIX,openvpn.com,Proxy\nDOMAIN-SUFFIX,menotsu.blogspot.jp,Proxy\nDOMAIN-SUFFIX,cysll.com,Proxy\nDOMAIN-SUFFIX,europe-west1-mth-web.cloudfunctions.net,Proxy\nDOMAIN-SUFFIX,chinese.cgntv.net,Proxy\nDOMAIN-SUFFIX,turbohide.com,Proxy\nDOMAIN-SUFFIX,antenna.com.ua,Proxy\nDOMAIN-SUFFIX,alternativeto.net,Proxy\nDOMAIN-SUFFIX,chicagocitylimits.com,Proxy\nDOMAIN-SUFFIX,grmt.com,Proxy\nDOMAIN-SUFFIX,btkitty.com,Proxy\nDOMAIN-SUFFIX,www.lcu.edu.hk,Proxy\nDOMAIN-SUFFIX,t-hole.red,Proxy\nDOMAIN-SUFFIX,casonalampa.cl,Proxy\nDOMAIN-SUFFIX,sa.portal.jw.org,Proxy\nDOMAIN-SUFFIX,888.yycp.com,Proxy\nDOMAIN-SUFFIX,netahoes.com.br,Proxy\nDOMAIN-SUFFIX,99pk99.com,Proxy\nDOMAIN-SUFFIX,sentinel.co,Proxy\nDOMAIN-SUFFIX,www.fairfieldchampion.com.au,Proxy\nDOMAIN-SUFFIX,wgnradio.com,Proxy\nDOMAIN-SUFFIX,gamer2-cds.cdn.hinet.net,Proxy\nDOMAIN-SUFFIX,freearkham.cc,Proxy\nDOMAIN-SUFFIX,www.techinsider.io,Proxy\nDOMAIN-SUFFIX,app.sushi.com,Proxy\nDOMAIN-SUFFIX,e7067.com,Proxy\nDOMAIN-SUFFIX,www.inkrope.com,Proxy\nDOMAIN-SUFFIX,zh68.lima-city.de,Proxy\nDOMAIN-SUFFIX,facebook.br,Proxy\nDOMAIN-SUFFIX,blackwell.co.uk,Proxy\nDOMAIN-SUFFIX,vpn.agfirst.com,Proxy\nDOMAIN-SUFFIX,moptt.tw,Proxy\nDOMAIN-SUFFIX,www.google.mv,Proxy\nDOMAIN-SUFFIX,www.17avav.xyz,Proxy\nDOMAIN-SUFFIX,search.appledaily.com.tw,Proxy\nDOMAIN-SUFFIX,ufm1003.sg,Proxy\nDOMAIN-SUFFIX,badoo.co,Proxy\nDOMAIN-SUFFIX,savethedate.foo,Proxy\nDOMAIN-SUFFIX,www.28365365.com,Proxy\nDOMAIN-SUFFIX,www.news.mn,Proxy\nDOMAIN-SUFFIX,www.johdan.com,Proxy\nDOMAIN-SUFFIX,vpser.net,Proxy\nDOMAIN-SUFFIX,baby-kingdom.com,Proxy\nDOMAIN-SUFFIX,wutoupal.x10.mx,Proxy\nDOMAIN-SUFFIX,www.eaadvanced.com,Proxy\nDOMAIN-SUFFIX,biz.tm,Proxy\nDOMAIN-SUFFIX,54321365.com,Proxy\nDOMAIN-SUFFIX,fortescu.com,Proxy\nDOMAIN-SUFFIX,d2522tws4pjc2c.cloudfront.net,Proxy\nDOMAIN-SUFFIX,tlc881633.com,Proxy\nDOMAIN-SUFFIX,www.livanchuk.com,Proxy\nDOMAIN-SUFFIX,unitracker.aspi.org.au,Proxy\nDOMAIN-SUFFIX,www.828968.com,Proxy\nDOMAIN-SUFFIX,www.thedalailamamovie.com,Proxy\nDOMAIN-SUFFIX,rockwork.ch,Proxy\nDOMAIN-SUFFIX,www.palico.com,Proxy\nDOMAIN-SUFFIX,www.9900.la,Proxy\nDOMAIN-SUFFIX,www.sesenovel.com,Proxy\nDOMAIN-SUFFIX,upayhalf.com,Proxy\nDOMAIN-SUFFIX,mgstage.com,Proxy\nDOMAIN-SUFFIX,www.v-av.com,Proxy\nDOMAIN-SUFFIX,leangeder.eu,Proxy\nDOMAIN-SUFFIX,sendsmtp.com,Proxy\nDOMAIN-SUFFIX,welovecock.com,Proxy\nDOMAIN-SUFFIX,boyxv.com,Proxy\nDOMAIN-SUFFIX,mathable.io,Proxy\nDOMAIN-SUFFIX,bifa9999.com,Proxy\nDOMAIN-SUFFIX,tibetencostarica.com,Proxy\nDOMAIN-SUFFIX,www.facebook.co.za,Proxy\nDOMAIN-SUFFIX,www.everzon.com,Proxy\nDOMAIN-SUFFIX,www.xtb.com,Proxy\nDOMAIN-SUFFIX,tistory.com,Proxy\nDOMAIN-SUFFIX,webrtc.org,Proxy\nDOMAIN-SUFFIX,highjump.com,Proxy\nDOMAIN-SUFFIX,www.hdwin.idv.tw,Proxy\nDOMAIN-SUFFIX,www.tb0002.com,Proxy\nDOMAIN-SUFFIX,app.kxg.io,Proxy\nDOMAIN-SUFFIX,www.shimotsuke.co.jp,Proxy\nDOMAIN-SUFFIX,cforum.cari.com.my,Proxy\nDOMAIN-SUFFIX,www2.zyxel.com,Proxy\nDOMAIN-SUFFIX,www.52waha.com,Proxy\nDOMAIN-SUFFIX,mos66.com,Proxy\nDOMAIN-SUFFIX,www.speeder.ml,Proxy\nDOMAIN-SUFFIX,seebird.net,Proxy\nDOMAIN-SUFFIX,www.vpn4all.com,Proxy\nDOMAIN-SUFFIX,kagyuoffice.org.tw,Proxy\nDOMAIN-SUFFIX,orgasmatrix.com,Proxy\nDOMAIN-SUFFIX,proxy.piratenpartij.nl,Proxy\nDOMAIN-SUFFIX,ca167.com,Proxy\nDOMAIN-SUFFIX,urlgalleries.net,Proxy\nDOMAIN-SUFFIX,www.porncor.com,Proxy\nDOMAIN-SUFFIX,jokerlu.com,Proxy\nDOMAIN-SUFFIX,ghost-18763825.firebaseio.com,Proxy\nDOMAIN-SUFFIX,hh.wha.la,Proxy\nDOMAIN-SUFFIX,d2sji35pswhmgc.cloudfront.net,Proxy\nDOMAIN-SUFFIX,mysupervisor.org,Proxy\nDOMAIN-SUFFIX,www.xerotica.com,Proxy\nDOMAIN-SUFFIX,ddys.tv,Proxy\nDOMAIN-SUFFIX,globalcybersecurityforum.com,Proxy\nDOMAIN-SUFFIX,kazeo.com,Proxy\nDOMAIN-SUFFIX,unix.id.lv,Proxy\nDOMAIN-SUFFIX,www.entrepreneurshipaward.com,Proxy\nDOMAIN-SUFFIX,dwamdstream102.akamaized.net,Proxy\nDOMAIN-SUFFIX,www.cppa-dc.org,Proxy\nDOMAIN-SUFFIX,tibetanbuddhistinstitute.org,Proxy\nDOMAIN-SUFFIX,americanbible.org,Proxy\nDOMAIN-SUFFIX,siteci.de,Proxy\nDOMAIN-SUFFIX,pbwiki.com,Proxy\nDOMAIN-SUFFIX,www.whathifi.com,Proxy\nDOMAIN-SUFFIX,007500w.com,Proxy\nDOMAIN-SUFFIX,grvpn.com,Proxy\nDOMAIN-SUFFIX,fapdick.com,Proxy\nDOMAIN-SUFFIX,www.azattyq.org,Proxy\nDOMAIN-SUFFIX,wisevid.com,Proxy\nDOMAIN-SUFFIX,kanshifang.com,Proxy\nDOMAIN-SUFFIX,xn--9pr62r24a.com,Proxy\nDOMAIN-SUFFIX,pca-express.com,Proxy\nDOMAIN-SUFFIX,www.xhmaster.com,Proxy\nDOMAIN-SUFFIX,www.googlie.com,Proxy\nDOMAIN-SUFFIX,alexmurphy.net,Proxy\nDOMAIN-SUFFIX,yu.slyip.net,Proxy\nDOMAIN-SUFFIX,e-info.org.tw,Proxy\nDOMAIN-SUFFIX,drre79gku2ine.cloudfront.net,Proxy\nDOMAIN-SUFFIX,designwyo.com,Proxy\nDOMAIN-SUFFIX,chinadigitaltimes.com,Proxy\nDOMAIN-SUFFIX,www.rollerteam.com,Proxy\nDOMAIN-SUFFIX,13newsnow.com,Proxy\nDOMAIN-SUFFIX,hqbdsm.com,Proxy\nDOMAIN-SUFFIX,www.shenyunshop.com,Proxy\nDOMAIN-SUFFIX,nuvoices.com,Proxy\nDOMAIN-SUFFIX,syte4.com,Proxy\nDOMAIN-SUFFIX,sun503.com,Proxy\nDOMAIN-SUFFIX,boysfood.com,Proxy\nDOMAIN-SUFFIX,i999.tv,Proxy\nDOMAIN-SUFFIX,cybersyndrome.net,Proxy\nDOMAIN-SUFFIX,cn2.streetvoice.com,Proxy\nDOMAIN-SUFFIX,iyoutube.com,Proxy\nDOMAIN-SUFFIX,www.buddhistdoor.net,Proxy\nDOMAIN-SUFFIX,isaacmao.com,Proxy\nDOMAIN-SUFFIX,petterisaak.com,Proxy\nDOMAIN-SUFFIX,d12fm4vsc5tls2.cloudfront.net,Proxy\nDOMAIN-SUFFIX,ghostpath.com,Proxy\nDOMAIN-SUFFIX,www.lepoint.fr,Proxy\nDOMAIN-SUFFIX,sbme.me,Proxy\nDOMAIN-SUFFIX,hybrid-analysis.com,Proxy\nDOMAIN-SUFFIX,www.findyoutube.net,Proxy\nDOMAIN-SUFFIX,sports.my188.com,Proxy\nDOMAIN-SUFFIX,www.epochhk.com,Proxy\nDOMAIN-SUFFIX,vpnfires.biz,Proxy\nDOMAIN-SUFFIX,gamer.com.tw,Proxy\nDOMAIN-SUFFIX,nitter.spaceint.fr,Proxy\nDOMAIN-SUFFIX,worldcat.org,Proxy\nDOMAIN-SUFFIX,dajiyuan.eu,Proxy\nDOMAIN-SUFFIX,www.teleboerse.de,Proxy\nDOMAIN-SUFFIX,proxybytes.com,Proxy\nDOMAIN-SUFFIX,www.anonymitychecker.com,Proxy\nDOMAIN-SUFFIX,site2unblock.com,Proxy\nDOMAIN-SUFFIX,kupyansk.ru,Proxy\nDOMAIN-SUFFIX,1048.com,Proxy\nDOMAIN-SUFFIX,djhekgqf5l7bv.cloudfront.net,Proxy\nDOMAIN-SUFFIX,objmtv.site,Proxy\nDOMAIN-SUFFIX,minzhuzhanxian.com,Proxy\nDOMAIN-SUFFIX,xbo100.com,Proxy\nDOMAIN-SUFFIX,www.ctworld.org,Proxy\nDOMAIN-SUFFIX,iimovie.cc,Proxy\nDOMAIN-SUFFIX,mypornstarbook.net,Proxy\nDOMAIN-SUFFIX,lue4.ddns.name,Proxy\nDOMAIN-SUFFIX,www.torproject.net,Proxy\nDOMAIN-SUFFIX,rutracker.org,Proxy\nDOMAIN-SUFFIX,6parknews.com,Proxy\nDOMAIN-SUFFIX,ciyuan.cat,Proxy\nDOMAIN-SUFFIX,journalofdemocracy.org,Proxy\nDOMAIN-SUFFIX,www.wujieliulan.com,Proxy\nDOMAIN-SUFFIX,lotustv.cc,Proxy\nDOMAIN-SUFFIX,x18r.com,Proxy\nDOMAIN-SUFFIX,abc.pp.ru,Proxy\nDOMAIN-SUFFIX,inpatnet.org,Proxy\nDOMAIN-SUFFIX,google.com.pr,Proxy\nDOMAIN-SUFFIX,learn.lboro.ac.uk,Proxy\nDOMAIN-SUFFIX,gamebase.com.tw,Proxy\nDOMAIN-SUFFIX,jieshibaobao.com,Proxy\nDOMAIN-SUFFIX,www.kljhw.net,Proxy\nDOMAIN-SUFFIX,puredns.cn,Proxy\nDOMAIN-SUFFIX,hepc.net.au,Proxy\nDOMAIN-SUFFIX,roupajunina.com,Proxy\nDOMAIN-SUFFIX,user1.earthtor.com,Proxy\nDOMAIN-SUFFIX,www.yyys88.com,Proxy\nDOMAIN-SUFFIX,cn.shindanmaker.com,Proxy\nDOMAIN-SUFFIX,aff.bvaff.com,Proxy\nDOMAIN-SUFFIX,news.sina.com,Proxy\nDOMAIN-SUFFIX,corumcollege.com,Proxy\nDOMAIN-SUFFIX,d4508d6vomz2p.cloudfront.net,Proxy\nDOMAIN-SUFFIX,direction-x.com,Proxy\nDOMAIN-SUFFIX,www.beyerdynamic.com,Proxy\nDOMAIN-SUFFIX,www.tachles.ch,Proxy\nDOMAIN-SUFFIX,trading212.com,Proxy\nDOMAIN-SUFFIX,muvibee.net,Proxy\nDOMAIN-SUFFIX,dotunnel.com,Proxy\nDOMAIN-SUFFIX,delicious-fruit.com,Proxy\nDOMAIN-SUFFIX,freegroup.org,Proxy\nDOMAIN-SUFFIX,ps.pndsn.com,Proxy\nDOMAIN-SUFFIX,chinesegay.org,Proxy\nDOMAIN-SUFFIX,ministrybooks.org,Proxy\nDOMAIN-SUFFIX,androidappsapk.co,Proxy\nDOMAIN-SUFFIX,bk2888.com,Proxy\nDOMAIN-SUFFIX,social.caa-ins.org,Proxy\nDOMAIN-SUFFIX,plays.com.tw,Proxy\nDOMAIN-SUFFIX,r9s8.gr8name.biz,Proxy\nDOMAIN-SUFFIX,yecl.net,Proxy\nDOMAIN-SUFFIX,tibet-foundation.org,Proxy\nDOMAIN-SUFFIX,nitter.poast.org,Proxy\nDOMAIN-SUFFIX,betway801.com,Proxy\nDOMAIN-SUFFIX,yuvutu.com,Proxy\nDOMAIN-SUFFIX,thecollectivehk.com,Proxy\nDOMAIN-SUFFIX,southxchange.com,Proxy\nDOMAIN-SUFFIX,www.xf839.com,Proxy\nDOMAIN-SUFFIX,superzooi.com,Proxy\nDOMAIN-SUFFIX,cfhks.org.hk,Proxy\nDOMAIN-SUFFIX,6up.bet,Proxy\nDOMAIN-SUFFIX,ihakka.net,Proxy\nDOMAIN-SUFFIX,www.americanpublicmedia.org,Proxy\nDOMAIN-SUFFIX,doovi.com,Proxy\nDOMAIN-SUFFIX,www.alalam.ir,Proxy\nDOMAIN-SUFFIX,www.olevod.com,Proxy\nDOMAIN-SUFFIX,112.b0ne.com,Proxy\nDOMAIN-SUFFIX,opentech.fund,Proxy\nDOMAIN-SUFFIX,overdrive.com,Proxy\nDOMAIN-SUFFIX,mdk.flnet.org,Proxy\nDOMAIN-SUFFIX,www.yc6349.com,Proxy\nDOMAIN-SUFFIX,xo104.com,Proxy\nDOMAIN-SUFFIX,www.solomon.com.hk,Proxy\nDOMAIN-SUFFIX,rule34.xxx,Proxy\nDOMAIN-SUFFIX,www.art-japan.com,Proxy\nDOMAIN-SUFFIX,www.mengzhan12345.com,Proxy\nDOMAIN-SUFFIX,www.pornv.xxx,Proxy\nDOMAIN-SUFFIX,www.quran.com,Proxy\nDOMAIN-SUFFIX,dnt.twimg.com,Proxy\nDOMAIN-SUFFIX,god.tv,Proxy\nDOMAIN-SUFFIX,gekikame.com,Proxy\nDOMAIN-SUFFIX,bet.hkjc.com,Proxy\nDOMAIN-SUFFIX,www.fxtm.com,Proxy\nDOMAIN-SUFFIX,falungong.club,Proxy\nDOMAIN-SUFFIX,zhanbin.net,Proxy\nDOMAIN-SUFFIX,gdbt.net,Proxy\nDOMAIN-SUFFIX,mailp.in,Proxy\nDOMAIN-SUFFIX,xyzcomics.com,Proxy\nDOMAIN-SUFFIX,simustation.com,Proxy\nDOMAIN-SUFFIX,ismart.mrt188.com,Proxy\nDOMAIN-SUFFIX,sacks.com,Proxy\nDOMAIN-SUFFIX,youshun12.com,Proxy\nDOMAIN-SUFFIX,videoscavenger.com,Proxy\nDOMAIN-SUFFIX,c.boxc.pro,Proxy\nDOMAIN-SUFFIX,lyz.com,Proxy\nDOMAIN-SUFFIX,bod.asia,Proxy\nDOMAIN-SUFFIX,vpnts.com,Proxy\nDOMAIN-SUFFIX,getprivate.eu,Proxy\nDOMAIN-SUFFIX,auraria.org,Proxy\nDOMAIN-SUFFIX,javdove2.fun,Proxy\nDOMAIN-SUFFIX,onion.tube,Proxy\nDOMAIN-SUFFIX,thedw.us,Proxy\nDOMAIN-SUFFIX,infox.ru,Proxy\nDOMAIN-SUFFIX,tlc133.com,Proxy\nDOMAIN-SUFFIX,sharpdaily.tw,Proxy\nDOMAIN-SUFFIX,aa1142.com,Proxy\nDOMAIN-SUFFIX,dakaba.club,Proxy\nDOMAIN-SUFFIX,user.tf06.com,Proxy\nDOMAIN-SUFFIX,v18a.com,Proxy\nDOMAIN-SUFFIX,qm2017.github.io,Proxy\nDOMAIN-SUFFIX,vpnyy.com,Proxy\nDOMAIN-SUFFIX,xj87777.com,Proxy\nDOMAIN-SUFFIX,942porn.com,Proxy\nDOMAIN-SUFFIX,d362ghbo0d90w7.cloudfront.net,Proxy\nDOMAIN-SUFFIX,bvpn.com,Proxy\nDOMAIN-SUFFIX,pwc.to,Proxy\nDOMAIN-SUFFIX,m23.eu,Proxy\nDOMAIN-SUFFIX,imgflip.com,Proxy\nDOMAIN-SUFFIX,likes.com,Proxy\nDOMAIN-SUFFIX,ironfeather.com,Proxy\nDOMAIN-SUFFIX,404url.com,Proxy\nDOMAIN-SUFFIX,manaservi.com,Proxy\nDOMAIN-SUFFIX,citypress.co.za,Proxy\nDOMAIN-SUFFIX,luke173ministries.org,Proxy\nDOMAIN-SUFFIX,clicksvenue.com,Proxy\nDOMAIN-SUFFIX,btc98.com,Proxy\nDOMAIN-SUFFIX,vpnaccount.org,Proxy\nDOMAIN-SUFFIX,wombo.ai,Proxy\nDOMAIN-SUFFIX,sofu.me,Proxy\nDOMAIN-SUFFIX,sun3332.com,Proxy\nDOMAIN-SUFFIX,12223nn.com,Proxy\nDOMAIN-SUFFIX,govtrack.us,Proxy\nDOMAIN-SUFFIX,ali868.com,Proxy\nDOMAIN-SUFFIX,bifa1997.com,Proxy\nDOMAIN-SUFFIX,80700.com,Proxy\nDOMAIN-SUFFIX,kogan.com,Proxy\nDOMAIN-SUFFIX,eng.ghn.ge,Proxy\nDOMAIN-SUFFIX,www.wyzx.com,Proxy\nDOMAIN-SUFFIX,europeantour.com,Proxy\nDOMAIN-SUFFIX,webcitation.org,Proxy\nDOMAIN-SUFFIX,amazon.co.jp,Proxy\nDOMAIN-SUFFIX,www.bookrep.com.tw,Proxy\nDOMAIN-SUFFIX,www.alhawyah.com,Proxy\nDOMAIN-SUFFIX,unirule.cloud,Proxy\nDOMAIN-SUFFIX,theproductivityexperts.com,Proxy\nDOMAIN-SUFFIX,freemoren.com,Proxy\nDOMAIN-SUFFIX,een.dhcp.biz,Proxy\nDOMAIN-SUFFIX,yyy343.com,Proxy\nDOMAIN-SUFFIX,cibar.org,Proxy\nDOMAIN-SUFFIX,den.b0ne.com,Proxy\nDOMAIN-SUFFIX,wang9.authorizeddns.us,Proxy\nDOMAIN-SUFFIX,www.google.lu,Proxy\nDOMAIN-SUFFIX,www.fjbet.com,Proxy\nDOMAIN-SUFFIX,www.freevpnusa.com,Proxy\nDOMAIN-SUFFIX,assimp.org,Proxy\nDOMAIN-SUFFIX,ocean.edu,Proxy\nDOMAIN-SUFFIX,vpntraffic.com,Proxy\nDOMAIN-SUFFIX,picacomiccn.com,Proxy\nDOMAIN-SUFFIX,d1fkiayp9ijfhs.cloudfront.net,Proxy\nDOMAIN-SUFFIX,bybit.com,Proxy\nDOMAIN-SUFFIX,php3.ml,Proxy\nDOMAIN-SUFFIX,oogami.name,Proxy\nDOMAIN-SUFFIX,mrcat666.com,Proxy\nDOMAIN-SUFFIX,caritas.tk,Proxy\nDOMAIN-SUFFIX,www.luluck.com,Proxy\nDOMAIN-SUFFIX,i.ftimg.net,Proxy\nDOMAIN-SUFFIX,www.panorama.am,Proxy\nDOMAIN-SUFFIX,ww1.gcdz.pw,Proxy\nDOMAIN-SUFFIX,de4w2.99kk.eu.org,Proxy\nDOMAIN-SUFFIX,persecution.org,Proxy\nDOMAIN-SUFFIX,toc-online.ch,Proxy\nDOMAIN-SUFFIX,rec69.cc,Proxy\nDOMAIN-SUFFIX,mmm100.com,Proxy\nDOMAIN-SUFFIX,7249k.com,Proxy\nDOMAIN-SUFFIX,m.wujieliulan.com,Proxy\nDOMAIN-SUFFIX,webwash.net,Proxy\nDOMAIN-SUFFIX,195700.com,Proxy\nDOMAIN-SUFFIX,d1k6qx8578rprw.cloudfront.net,Proxy\nDOMAIN-SUFFIX,etched.page,Proxy\nDOMAIN-SUFFIX,www.y304.com,Proxy\nDOMAIN-SUFFIX,payserve.com,Proxy\nDOMAIN-SUFFIX,cponline.pw,Proxy\nDOMAIN-SUFFIX,raduborza.ro,Proxy\nDOMAIN-SUFFIX,xc222888.com,Proxy\nDOMAIN-SUFFIX,sogoo.org,Proxy\nDOMAIN-SUFFIX,awe.lflink.com,Proxy\nDOMAIN-SUFFIX,beijingcream.com,Proxy\nDOMAIN-SUFFIX,www.51argentina.com,Proxy\nDOMAIN-SUFFIX,vanpeople.com,Proxy\nDOMAIN-SUFFIX,www.yrcr4.com,Proxy\nDOMAIN-SUFFIX,caivirtual.policia.gov.co,Proxy\nDOMAIN-SUFFIX,polan888.com,Proxy\nDOMAIN-SUFFIX,bookza.org,Proxy\nDOMAIN-SUFFIX,3-a.net,Proxy\nDOMAIN-SUFFIX,merit-times.com.tw,Proxy\nDOMAIN-SUFFIX,www.thefacebook.com,Proxy\nDOMAIN-SUFFIX,learn-ap-southeast-2-prod-fleet01-xythos.s3.ap-southeast-2.amazonaws.com,Proxy\nDOMAIN-SUFFIX,doc.ivy2.nu,Proxy\nDOMAIN-SUFFIX,nowtorrents.com,Proxy\nDOMAIN-SUFFIX,s888.bet,Proxy\nDOMAIN-SUFFIX,www.wikidata.org,Proxy\nDOMAIN-SUFFIX,www.celebjihad.com,Proxy\nDOMAIN-SUFFIX,9p07.com,Proxy\nDOMAIN-SUFFIX,news.sinchew.com.my,Proxy\nDOMAIN-SUFFIX,taiwancanhelp.us,Proxy\nDOMAIN-SUFFIX,663047.com,Proxy\nDOMAIN-SUFFIX,www.zybooks.com,Proxy\nDOMAIN-SUFFIX,dd7448.com,Proxy\nDOMAIN-SUFFIX,mdacc.box.com,Proxy\nDOMAIN-SUFFIX,shangchingbest.000webhostapp.com,Proxy\nDOMAIN-SUFFIX,www.huancai66.com,Proxy\nDOMAIN-SUFFIX,jijiweb.jiji.com,Proxy\nDOMAIN-SUFFIX,d3977.com,Proxy\nDOMAIN-SUFFIX,cdpweb.org,Proxy\nDOMAIN-SUFFIX,ns02.biz,Proxy\nDOMAIN-SUFFIX,www.beeg.co,Proxy\nDOMAIN-SUFFIX,www.yizhihongxing.hk,Proxy\nDOMAIN-SUFFIX,dns.adguard-dns.com,Proxy\nDOMAIN-SUFFIX,amnesty.org.au,Proxy\nDOMAIN-SUFFIX,penthouse.com,Proxy\nDOMAIN-SUFFIX,status.im,Proxy\nDOMAIN-SUFFIX,crossmap.christianpost.com,Proxy\nDOMAIN-SUFFIX,fri-gate.org,Proxy\nDOMAIN-SUFFIX,suoluo.org,Proxy\nDOMAIN-SUFFIX,doh.safesurfer.io,Proxy\nDOMAIN-SUFFIX,newcenturynews.com,Proxy\nDOMAIN-SUFFIX,javdove.club,Proxy\nDOMAIN-SUFFIX,wsws.org,Proxy\nDOMAIN-SUFFIX,xx-book.com,Proxy\nDOMAIN-SUFFIX,paktamau.blogspot.hk,Proxy\nDOMAIN-SUFFIX,www.amazon.jp,Proxy\nDOMAIN-SUFFIX,txxx.com,Proxy\nDOMAIN-SUFFIX,nydus.biz,Proxy\nDOMAIN-SUFFIX,www.blockediniran.com,Proxy\nDOMAIN-SUFFIX,1eew.com,Proxy\nDOMAIN-SUFFIX,wang.biz,Proxy\nDOMAIN-SUFFIX,madebymaryblogg.blogg.se,Proxy\nDOMAIN-SUFFIX,gengshuang1.github.io,Proxy\nDOMAIN-SUFFIX,realorgasms.com,Proxy\nDOMAIN-SUFFIX,how.3d-game.com,Proxy\nDOMAIN-SUFFIX,dv8cnw6yu570m.cloudfront.net,Proxy\nDOMAIN-SUFFIX,happy-vpn.com,Proxy\nDOMAIN-SUFFIX,zapto.org,Proxy\nDOMAIN-SUFFIX,www.epohi.gr,Proxy\nDOMAIN-SUFFIX,www.rcinet.ca,Proxy\nDOMAIN-SUFFIX,google3.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,www.swissquote.com,Proxy\nDOMAIN-SUFFIX,hyvelab.us,Proxy\nDOMAIN-SUFFIX,alexandros-maleme.com,Proxy\nDOMAIN-SUFFIX,d2xgyu1v32z7j2.cloudfront.net,Proxy\nDOMAIN-SUFFIX,2femdom.com,Proxy\nDOMAIN-SUFFIX,s815.com,Proxy\nDOMAIN-SUFFIX,chat-test-app.firebaseio.com,Proxy\nDOMAIN-SUFFIX,zi.media,Proxy\nDOMAIN-SUFFIX,alicejapan.co.jp,Proxy\nDOMAIN-SUFFIX,94.viewdns.net,Proxy\nDOMAIN-SUFFIX,bithumb.com,Proxy\nDOMAIN-SUFFIX,bcfamily.com,Proxy\nDOMAIN-SUFFIX,tlc188.com,Proxy\nDOMAIN-SUFFIX,online-instagram.com,Proxy\nDOMAIN-SUFFIX,yd00s3052.tudouser.com,Proxy\nDOMAIN-SUFFIX,www.0391104.com,Proxy\nDOMAIN-SUFFIX,esu.red,Proxy\nDOMAIN-SUFFIX,www-26119.com,Proxy\nDOMAIN-SUFFIX,aclu.org,Proxy\nDOMAIN-SUFFIX,spys.one,Proxy\nDOMAIN-SUFFIX,www.rsgtrompmeesters.nl,Proxy\nDOMAIN-SUFFIX,fbs.com,Proxy\nDOMAIN-SUFFIX,www.sinotech.org.tw,Proxy\nDOMAIN-SUFFIX,hentaigo.com,Proxy\nDOMAIN-SUFFIX,zh.interush.net,Proxy\nDOMAIN-SUFFIX,fediscience.org,Proxy\nDOMAIN-SUFFIX,diedart.vip,Proxy\nDOMAIN-SUFFIX,www.xs9999.com,Proxy\nDOMAIN-SUFFIX,cocoa.zonble.net,Proxy\nDOMAIN-SUFFIX,ye168.789888.com,Proxy\nDOMAIN-SUFFIX,jav2be.com,Proxy\nDOMAIN-SUFFIX,sfshibao.com,Proxy\nDOMAIN-SUFFIX,www.ca883.com,Proxy\nDOMAIN-SUFFIX,www.valu-cn.com,Proxy\nDOMAIN-SUFFIX,byj02.com,Proxy\nDOMAIN-SUFFIX,justmysockscn.com,Proxy\nDOMAIN-SUFFIX,94xae.com,Proxy\nDOMAIN-SUFFIX,vpnforgame.net,Proxy\nDOMAIN-SUFFIX,kiss8.in,Proxy\nDOMAIN-SUFFIX,bloodshed.net,Proxy\nDOMAIN-SUFFIX,wi55.gq,Proxy\nDOMAIN-SUFFIX,squeez-soft.jp,Proxy\nDOMAIN-SUFFIX,www.qivanaproducts.com,Proxy\nDOMAIN-SUFFIX,1024.05ia.club,Proxy\nDOMAIN-SUFFIX,antvpn2015.com,Proxy\nDOMAIN-SUFFIX,old.nabble.com,Proxy\nDOMAIN-SUFFIX,matthewcingram.com,Proxy\nDOMAIN-SUFFIX,alldrawnsex.com,Proxy\nDOMAIN-SUFFIX,d8898.com,Proxy\nDOMAIN-SUFFIX,g6hentai.com,Proxy\nDOMAIN-SUFFIX,shenjiying005.jigsy.com,Proxy\nDOMAIN-SUFFIX,www.maisfutebol.iol.pt,Proxy\nDOMAIN-SUFFIX,www.nordsee-zeitung.de,Proxy\nDOMAIN-SUFFIX,mikly.org,Proxy\nDOMAIN-SUFFIX,2907766.com,Proxy\nDOMAIN-SUFFIX,fsvpn.com,Proxy\nDOMAIN-SUFFIX,urimbooks.com,Proxy\nDOMAIN-SUFFIX,borastapeter.se,Proxy\nDOMAIN-SUFFIX,referer.us,Proxy\nDOMAIN-SUFFIX,mail.nettoyeur.tk,Proxy\nDOMAIN-SUFFIX,www.bb-in.org,Proxy\nDOMAIN-SUFFIX,hdpornfull.com,Proxy\nDOMAIN-SUFFIX,tor-exit-50.for-privacy.net,Proxy\nDOMAIN-SUFFIX,www.cz100.net,Proxy\nDOMAIN-SUFFIX,k3a.privatedns.org,Proxy\nDOMAIN-SUFFIX,idemonch.cl,Proxy\nDOMAIN-SUFFIX,bethelweb.hk,Proxy\nDOMAIN-SUFFIX,bitforex.com,Proxy\nDOMAIN-SUFFIX,audio.voh.com.tw,Proxy\nDOMAIN-SUFFIX,sustainability.google,Proxy\nDOMAIN-SUFFIX,www.hj3299.com,Proxy\nDOMAIN-SUFFIX,kitting.ca,Proxy\nDOMAIN-SUFFIX,peterburk.free.fr,Proxy\nDOMAIN-SUFFIX,wretch.cc,Proxy\nDOMAIN-SUFFIX,suryavanshi.in,Proxy\nDOMAIN-SUFFIX,www.jamesyan.net,Proxy\nDOMAIN-SUFFIX,300tube.com,Proxy\nDOMAIN-SUFFIX,qstatus.com,Proxy\nDOMAIN-SUFFIX,kazakhstanvpn.com,Proxy\nDOMAIN-SUFFIX,www.workerempowerment.org,Proxy\nDOMAIN-SUFFIX,www.cruz.senate.gov,Proxy\nDOMAIN-SUFFIX,kanichi.jp,Proxy\nDOMAIN-SUFFIX,av-ok.com,Proxy\nDOMAIN-SUFFIX,myav.tv,Proxy\nDOMAIN-SUFFIX,stargazete.com,Proxy\nDOMAIN-SUFFIX,mengmao.org,Proxy\nDOMAIN-SUFFIX,xinbi777.com,Proxy\nDOMAIN-SUFFIX,calgarychinese.net,Proxy\nDOMAIN-SUFFIX,www.88kf.com,Proxy\nDOMAIN-SUFFIX,publ.co,Proxy\nDOMAIN-SUFFIX,tiptree.com,Proxy\nDOMAIN-SUFFIX,race2hugo.net,Proxy\nDOMAIN-SUFFIX,z2r7921695617528q7n48n6805r7594oqp11o0718.tf,Proxy\nDOMAIN-SUFFIX,44hjc.com,Proxy\nDOMAIN-SUFFIX,newyorkpost.com,Proxy\nDOMAIN-SUFFIX,w88124.com,Proxy\nDOMAIN-SUFFIX,vox.com,Proxy\nDOMAIN-SUFFIX,vvt.tw,Proxy\nDOMAIN-SUFFIX,freeddns.com,Proxy\nDOMAIN-SUFFIX,www.proxz.com,Proxy\nDOMAIN-SUFFIX,domainclub.us,Proxy\nDOMAIN-SUFFIX,www.biblerain.com,Proxy\nDOMAIN-SUFFIX,cctongbao.com,Proxy\nDOMAIN-SUFFIX,jwplayer.com,Proxy\nDOMAIN-SUFFIX,mail.sji.edu.sg,Proxy\nDOMAIN-SUFFIX,longtoes.com,Proxy\nDOMAIN-SUFFIX,freakshare.com,Proxy\nDOMAIN-SUFFIX,quickvpn.lipisoft.com,Proxy\nDOMAIN-SUFFIX,c2233.com,Proxy\nDOMAIN-SUFFIX,76ry.4.688.org,Proxy\nDOMAIN-SUFFIX,pornve.com,Proxy\nDOMAIN-SUFFIX,99thdistrictteaparty.blogspot.jp,Proxy\nDOMAIN-SUFFIX,www1.dotsvpn2.com,Proxy\nDOMAIN-SUFFIX,igfw.tech,Proxy\nDOMAIN-SUFFIX,www.adidas.kr,Proxy\nDOMAIN-SUFFIX,88sjz.com,Proxy\nDOMAIN-SUFFIX,continuingcounterreformation.blogspot.dk,Proxy\nDOMAIN-SUFFIX,psybnc.org,Proxy\nDOMAIN-SUFFIX,vyprvpn.com,Proxy\nDOMAIN-SUFFIX,prdelb.mezengerapp.net,Proxy\nDOMAIN-SUFFIX,tubitv.com,Proxy\nDOMAIN-SUFFIX,ss1115.com,Proxy\nDOMAIN-SUFFIX,stbl.me,Proxy\nDOMAIN-SUFFIX,privatemembers.com,Proxy\nDOMAIN-SUFFIX,spin808.com,Proxy\nDOMAIN-SUFFIX,vpnsolution.us,Proxy\nDOMAIN-SUFFIX,eroprofile.com,Proxy\nDOMAIN-SUFFIX,nnyy.best,Proxy\nDOMAIN-SUFFIX,www.wewin88.net,Proxy\nDOMAIN-SUFFIX,www.rocket-inc.net,Proxy\nDOMAIN-SUFFIX,www.setnews.net,Proxy\nDOMAIN-SUFFIX,amigobbs.net,Proxy\nDOMAIN-SUFFIX,advantagesales.biz,Proxy\nDOMAIN-SUFFIX,sexy-lingerie.ws,Proxy\nDOMAIN-SUFFIX,d8388.com,Proxy\nDOMAIN-SUFFIX,www.bcex.ca,Proxy\nDOMAIN-SUFFIX,vivahentai4u.net,Proxy\nDOMAIN-SUFFIX,vpngratis.net,Proxy\nDOMAIN-SUFFIX,truthsocial.com,Proxy\nDOMAIN-SUFFIX,buy.yahoo.com.tw,Proxy\nDOMAIN-SUFFIX,jmcomic3.mobi,Proxy\nDOMAIN-SUFFIX,post-gazette.com,Proxy\nDOMAIN-SUFFIX,australia.fm,Proxy\nDOMAIN-SUFFIX,spoilertv.com,Proxy\nDOMAIN-SUFFIX,www.sleazyneasy.com,Proxy\nDOMAIN-SUFFIX,c-span.org,Proxy\nDOMAIN-SUFFIX,www.xiaodanzhu.com,Proxy\nDOMAIN-SUFFIX,ci.etowns.net,Proxy\nDOMAIN-SUFFIX,tillberg.chickenkiller.com,Proxy\nDOMAIN-SUFFIX,doujin-moe.us,Proxy\nDOMAIN-SUFFIX,ca2055.com,Proxy\nDOMAIN-SUFFIX,hkbc.net,Proxy\nDOMAIN-SUFFIX,circusmimo.ch,Proxy\nDOMAIN-SUFFIX,ti.me,Proxy\nDOMAIN-SUFFIX,us-central1-metronaut-dev-fa32c.cloudfunctions.net,Proxy\nDOMAIN-SUFFIX,top81.ws,Proxy\nDOMAIN-SUFFIX,www.yahoomail.com,Proxy\nDOMAIN-SUFFIX,greatestfreeproxy.com,Proxy\nDOMAIN-SUFFIX,amosland.com,Proxy\nDOMAIN-SUFFIX,nt05s3093.juarvian.com,Proxy\nDOMAIN-SUFFIX,incredibox.fr,Proxy\nDOMAIN-SUFFIX,www.proxies.us,Proxy\nDOMAIN-SUFFIX,9133862.com,Proxy\nDOMAIN-SUFFIX,statueofdemocracy.org,Proxy\nDOMAIN-SUFFIX,www.cabet667.com,Proxy\nDOMAIN-SUFFIX,vpntaiwan.com,Proxy\nDOMAIN-SUFFIX,tubeislam.com,Proxy\nDOMAIN-SUFFIX,bbs.9baka.com,Proxy\nDOMAIN-SUFFIX,ca686.com,Proxy\nDOMAIN-SUFFIX,fawanghuihui.org,Proxy\nDOMAIN-SUFFIX,www.postfix.org,Proxy\nDOMAIN-SUFFIX,www.avtb01.com,Proxy\nDOMAIN-SUFFIX,zvereff.com,Proxy\nDOMAIN-SUFFIX,menatplay.com,Proxy\nDOMAIN-SUFFIX,hazlitt.net,Proxy\nDOMAIN-SUFFIX,xoomclips.com,Proxy\nDOMAIN-SUFFIX,www.vaticannews.va,Proxy\nDOMAIN-SUFFIX,www.f88yule1.com,Proxy\nDOMAIN-SUFFIX,forex.com,Proxy\nDOMAIN-SUFFIX,www.kusch.us,Proxy\nDOMAIN-SUFFIX,googlemashups.com,Proxy\nDOMAIN-SUFFIX,javgo.net,Proxy\nDOMAIN-SUFFIX,abchinese.com,Proxy\nDOMAIN-SUFFIX,johntool.com,Proxy\nDOMAIN-SUFFIX,www.o2switch.fr,Proxy\nDOMAIN-SUFFIX,84490077.com,Proxy\nDOMAIN-SUFFIX,vpnzx.com,Proxy\nDOMAIN-SUFFIX,www.coffee-maker-repair-tw.gq,Proxy\nDOMAIN-SUFFIX,appdownloader.net,Proxy\nDOMAIN-SUFFIX,tv55.ga,Proxy\nDOMAIN-SUFFIX,www.yzc795.com,Proxy\nDOMAIN-SUFFIX,www.spearswms.com,Proxy\nDOMAIN-SUFFIX,27.slyip.com,Proxy\nDOMAIN-SUFFIX,ssarea.com,Proxy\nDOMAIN-SUFFIX,betway88help.com,Proxy\nDOMAIN-SUFFIX,77.slyip.com,Proxy\nDOMAIN-SUFFIX,members.bib-arch.org,Proxy\nDOMAIN-SUFFIX,shop.tm,Proxy\nDOMAIN-SUFFIX,app6.ml,Proxy\nDOMAIN-SUFFIX,999.aoke33.com,Proxy\nDOMAIN-SUFFIX,muviza.net,Proxy\nDOMAIN-SUFFIX,98app5.com,Proxy\nDOMAIN-SUFFIX,ostara.co.nz,Proxy\nDOMAIN-SUFFIX,eng.collectivehealth.com,Proxy\nDOMAIN-SUFFIX,www.secureproxysite.com,Proxy\nDOMAIN-SUFFIX,dynawebinc.com,Proxy\nDOMAIN-SUFFIX,jio.com,Proxy\nDOMAIN-SUFFIX,marenas.cl,Proxy\nDOMAIN-SUFFIX,www.monlamit.org,Proxy\nDOMAIN-SUFFIX,bitshare.com,Proxy\nDOMAIN-SUFFIX,www.hernia.idv.tw,Proxy\nDOMAIN-SUFFIX,abs-cbnnews.com,Proxy\nDOMAIN-SUFFIX,www.zentrum-schwarzenberg.de,Proxy\nDOMAIN-SUFFIX,sixipoultry.com,Proxy\nDOMAIN-SUFFIX,zapiro.com,Proxy\nDOMAIN-SUFFIX,fandiingah.com,Proxy\nDOMAIN-SUFFIX,mlsexp.com,Proxy\nDOMAIN-SUFFIX,www.serajeymonastery.org,Proxy\nDOMAIN-SUFFIX,spoiledvirgins.com,Proxy\nDOMAIN-SUFFIX,youtube-nocookie.com,Proxy\nDOMAIN-SUFFIX,www.fxstatus-chinese.com,Proxy\nDOMAIN-SUFFIX,udoit.ciditools.com,Proxy\nDOMAIN-SUFFIX,bettween.com,Proxy\nDOMAIN-SUFFIX,johnytemplate.blogspot.hk,Proxy\nDOMAIN-SUFFIX,blog.mozilla.org,Proxy\nDOMAIN-SUFFIX,www.mirandegroup.com,Proxy\nDOMAIN-SUFFIX,google.com.ng,Proxy\nDOMAIN-SUFFIX,www.trigano-sea.com,Proxy\nDOMAIN-SUFFIX,ilovehk.hk,Proxy\nDOMAIN-SUFFIX,www.2018wang.net,Proxy\nDOMAIN-SUFFIX,btsow.bond,Proxy\nDOMAIN-SUFFIX,911tabs.com,Proxy\nDOMAIN-SUFFIX,rapgenius.com,Proxy\nDOMAIN-SUFFIX,b311452.com,Proxy\nDOMAIN-SUFFIX,download.free-hideip.com,Proxy\nDOMAIN-SUFFIX,www.meihuavpn.com,Proxy\nDOMAIN-SUFFIX,emmcsc.eklablog.com,Proxy\nDOMAIN-SUFFIX,rubao.link,Proxy\nDOMAIN-SUFFIX,mail.talentgroup.asia,Proxy\nDOMAIN-SUFFIX,falun.caltech.edu,Proxy\nDOMAIN-SUFFIX,sunnyleone.com,Proxy\nDOMAIN-SUFFIX,www.motherless.com,Proxy\nDOMAIN-SUFFIX,www.e8576.com,Proxy\nDOMAIN-SUFFIX,webspace.tiscali.it,Proxy\nDOMAIN-SUFFIX,fehrmann.net.br,Proxy\nDOMAIN-SUFFIX,inylx.com,Proxy\nDOMAIN-SUFFIX,www.cex.io,Proxy\nDOMAIN-SUFFIX,calebelston.com,Proxy\nDOMAIN-SUFFIX,vjmedia.com.hk,Proxy\nDOMAIN-SUFFIX,longseason.1200bps.xyz,Proxy\nDOMAIN-SUFFIX,h.v.gp,Proxy\nDOMAIN-SUFFIX,rediffmail.com,Proxy\nDOMAIN-SUFFIX,etowns.org,Proxy\nDOMAIN-SUFFIX,viralporn.com,Proxy\nDOMAIN-SUFFIX,doh.boje8.me,Proxy\nDOMAIN-SUFFIX,wokar.org,Proxy\nDOMAIN-SUFFIX,acy-zh.com,Proxy\nDOMAIN-SUFFIX,documentingreality.com,Proxy\nDOMAIN-SUFFIX,city.udn.com,Proxy\nDOMAIN-SUFFIX,justtristan.com,Proxy\nDOMAIN-SUFFIX,www.arsenal.com,Proxy\nDOMAIN-SUFFIX,d3q2rmcjrnnvi2.cloudfront.net,Proxy\nDOMAIN-SUFFIX,lux.uk7.org,Proxy\nDOMAIN-SUFFIX,btc-alpha.com,Proxy\nDOMAIN-SUFFIX,greatfire.uservoice.com,Proxy\nDOMAIN-SUFFIX,gcc.org.hk,Proxy\nDOMAIN-SUFFIX,www.velocity.net,Proxy\nDOMAIN-SUFFIX,extremetube.com,Proxy\nDOMAIN-SUFFIX,www.n888pp.com,Proxy\nDOMAIN-SUFFIX,baidu.swmbudokan.com,Proxy\nDOMAIN-SUFFIX,rjup.cn,Proxy\nDOMAIN-SUFFIX,dailytimes.com.pk,Proxy\nDOMAIN-SUFFIX,0328c.com,Proxy\nDOMAIN-SUFFIX,www.28tlc.com,Proxy\nDOMAIN-SUFFIX,en.favotter.net,Proxy\nDOMAIN-SUFFIX,global-proxy.com,Proxy\nDOMAIN-SUFFIX,apk2.ga,Proxy\nDOMAIN-SUFFIX,qtrac.eu,Proxy\nDOMAIN-SUFFIX,r.twimg.com,Proxy\nDOMAIN-SUFFIX,briarproject.org,Proxy\nDOMAIN-SUFFIX,www.singletonargus.com.au,Proxy\nDOMAIN-SUFFIX,effers.com,Proxy\nDOMAIN-SUFFIX,tibet3rdpole.org,Proxy\nDOMAIN-SUFFIX,vpn.blackvpn.sg,Proxy\nDOMAIN-SUFFIX,porndino.net,Proxy\nDOMAIN-SUFFIX,www.cutout.pro,Proxy\nDOMAIN-SUFFIX,ao3.club,Proxy\nDOMAIN-SUFFIX,pokemon.tf,Proxy\nDOMAIN-SUFFIX,irena.cn,Proxy\nDOMAIN-SUFFIX,fubl.xyz,Proxy\nDOMAIN-SUFFIX,rag8.dhcp.biz,Proxy\nDOMAIN-SUFFIX,nitter.tedomum.net,Proxy\nDOMAIN-SUFFIX,www.butterfly.idv.tw,Proxy\nDOMAIN-SUFFIX,mc-bbs.net,Proxy\nDOMAIN-SUFFIX,www.southwalesguardian.co.uk,Proxy\nDOMAIN-SUFFIX,chinageeks.org,Proxy\nDOMAIN-SUFFIX,www.jawapos.com,Proxy\nDOMAIN-SUFFIX,funique.com,Proxy\nDOMAIN-SUFFIX,prism-break.org,Proxy\nDOMAIN-SUFFIX,www.irishsun.com,Proxy\nDOMAIN-SUFFIX,centranic.co.uk,Proxy\nDOMAIN-SUFFIX,post.pinolino.de,Proxy\nDOMAIN-SUFFIX,i-meto.com,Proxy\nDOMAIN-SUFFIX,acd.com.au,Proxy\nDOMAIN-SUFFIX,magzter.com,Proxy\nDOMAIN-SUFFIX,mangacan.blogspot.hk,Proxy\nDOMAIN-SUFFIX,surfbouncer.com,Proxy\nDOMAIN-SUFFIX,www.waiyou8.wang,Proxy\nDOMAIN-SUFFIX,consulmexvan.com,Proxy\nDOMAIN-SUFFIX,kyohk.net,Proxy\nDOMAIN-SUFFIX,www.tlc8827.com,Proxy\nDOMAIN-SUFFIX,pinterest.fr,Proxy\nDOMAIN-SUFFIX,www.lgsinnovations.com,Proxy\nDOMAIN-SUFFIX,monsterproxy.co.uk,Proxy\nDOMAIN-SUFFIX,25.php5.bid,Proxy\nDOMAIN-SUFFIX,www.3dmgame.com,Proxy\nDOMAIN-SUFFIX,account.synology.com,Proxy\nDOMAIN-SUFFIX,www.archangelvideo.com,Proxy\nDOMAIN-SUFFIX,d3ax1ung5itt9v.cloudfront.net,Proxy\nDOMAIN-SUFFIX,xvideos4.com,Proxy\nDOMAIN-SUFFIX,www.94695.com,Proxy\nDOMAIN-SUFFIX,airfrance.com.hk,Proxy\nDOMAIN-SUFFIX,www.goldengirlstv.com,Proxy\nDOMAIN-SUFFIX,llbnchinese.tv,Proxy\nDOMAIN-SUFFIX,www.hrweb.org,Proxy\nDOMAIN-SUFFIX,jakubpejzl.me,Proxy\nDOMAIN-SUFFIX,totallynsfw.com,Proxy\nDOMAIN-SUFFIX,longjinglihua.com,Proxy\nDOMAIN-SUFFIX,d2v3zod1uvhp53.cloudfront.net,Proxy\nDOMAIN-SUFFIX,lenarcissique.com,Proxy\nDOMAIN-SUFFIX,h5.ldsvip86.cc,Proxy\nDOMAIN-SUFFIX,net2.cf,Proxy\nDOMAIN-SUFFIX,thepiratebay.ee,Proxy\nDOMAIN-SUFFIX,dalianmeng.org,Proxy\nDOMAIN-SUFFIX,kaskus.us,Proxy\nDOMAIN-SUFFIX,meansys.com,Proxy\nDOMAIN-SUFFIX,livestream.com,Proxy\nDOMAIN-SUFFIX,diario.elmercurio.cl,Proxy\nDOMAIN-SUFFIX,lj4r.4u.cr.rs,Proxy\nDOMAIN-SUFFIX,www.886vpn.com,Proxy\nDOMAIN-SUFFIX,play.54647.blog,Proxy\nDOMAIN-SUFFIX,mangago.me,Proxy\nDOMAIN-SUFFIX,now.com,Proxy\nDOMAIN-SUFFIX,v8293.com,Proxy\nDOMAIN-SUFFIX,www.thecrowd.net,Proxy\nDOMAIN-SUFFIX,avgo78.org,Proxy\nDOMAIN-SUFFIX,thb.gov.tw,Proxy\nDOMAIN-SUFFIX,cn4.rti.tw,Proxy\nDOMAIN-SUFFIX,shwchurch3.com,Proxy\nDOMAIN-SUFFIX,www.eurasie.net,Proxy\nDOMAIN-SUFFIX,www.3178d.com,Proxy\nDOMAIN-SUFFIX,www.utoronto.ca,Proxy\nDOMAIN-SUFFIX,www.hkddn.org,Proxy\nDOMAIN-SUFFIX,www.hornbunny.com,Proxy\nDOMAIN-SUFFIX,free-proxyserver.com,Proxy\nDOMAIN-SUFFIX,j.mp,Proxy\nDOMAIN-SUFFIX,r77000.cc,Proxy\nDOMAIN-SUFFIX,ipchanging.com,Proxy\nDOMAIN-SUFFIX,tineye.com,Proxy\nDOMAIN-SUFFIX,iranwire.com,Proxy\nDOMAIN-SUFFIX,crl.buypass.no,Proxy\nDOMAIN-SUFFIX,sstmlt.net,Proxy\nDOMAIN-SUFFIX,www.00006801.com,Proxy\nDOMAIN-SUFFIX,jbo030.com,Proxy\nDOMAIN-SUFFIX,www.xxlmovies.com,Proxy\nDOMAIN-SUFFIX,naluone-av.com,Proxy\nDOMAIN-SUFFIX,xiegongji.net,Proxy\nDOMAIN-SUFFIX,freespiritfilmfestival.com,Proxy\nDOMAIN-SUFFIX,www.fuhuistation.com,Proxy\nDOMAIN-SUFFIX,zendproxy.com,Proxy\nDOMAIN-SUFFIX,www.txtreport.com,Proxy\nDOMAIN-SUFFIX,www.rubio.senate.gov,Proxy\nDOMAIN-SUFFIX,www.ht.org.tw,Proxy\nDOMAIN-SUFFIX,digi-ateljee.be,Proxy\nDOMAIN-SUFFIX,www.apkmirror.com,Proxy\nDOMAIN-SUFFIX,30boxes.com,Proxy\nDOMAIN-SUFFIX,unblocker.yt,Proxy\nDOMAIN-SUFFIX,fihx.4.deaftone.com,Proxy\nDOMAIN-SUFFIX,radio.net,Proxy\nDOMAIN-SUFFIX,aa00600.com,Proxy\nDOMAIN-SUFFIX,www.jbo520.win,Proxy\nDOMAIN-SUFFIX,comic-nation.com,Proxy\nDOMAIN-SUFFIX,orangex.io,Proxy\nDOMAIN-SUFFIX,farpost.ru,Proxy\nDOMAIN-SUFFIX,rons-home.net,Proxy\nDOMAIN-SUFFIX,hrw.org,Proxy\nDOMAIN-SUFFIX,sneakme.net,Proxy\nDOMAIN-SUFFIX,www.835a835.net,Proxy\nDOMAIN-SUFFIX,tsantiri.gr,Proxy\nDOMAIN-SUFFIX,blogos.com,Proxy\nDOMAIN-SUFFIX,www.fxcm-chinese.com.cn,Proxy\nDOMAIN-SUFFIX,se.com,Proxy\nDOMAIN-SUFFIX,dyinggiraffe.com,Proxy\nDOMAIN-SUFFIX,answering-islam.org,Proxy\nDOMAIN-SUFFIX,xiuxiqu.wtf,Proxy\nDOMAIN-SUFFIX,budaedu.org,Proxy\nDOMAIN-SUFFIX,timesofindia.indiatimes.com,Proxy\nDOMAIN-SUFFIX,yex.ddns.us,Proxy\nDOMAIN-SUFFIX,www.blogspot.hk,Proxy\nDOMAIN-SUFFIX,clkuk.tradedoubler.com,Proxy\nDOMAIN-SUFFIX,bb678.com,Proxy\nDOMAIN-SUFFIX,ee.qc.to,Proxy\nDOMAIN-SUFFIX,proxy-service.de,Proxy\nDOMAIN-SUFFIX,chic.fat.flnet.org,Proxy\nDOMAIN-SUFFIX,affiliate.pncle8.com,Proxy\nDOMAIN-SUFFIX,www.facebook.nl,Proxy\nDOMAIN-SUFFIX,d3a.spacetechnology.net,Proxy\nDOMAIN-SUFFIX,merxury.com,Proxy\nDOMAIN-SUFFIX,rrrxv.com,Proxy\nDOMAIN-SUFFIX,mediabiasfactcheck.com,Proxy\nDOMAIN-SUFFIX,phapluan.org,Proxy\nDOMAIN-SUFFIX,1download.ru,Proxy\nDOMAIN-SUFFIX,wd.bible,Proxy\nDOMAIN-SUFFIX,stealthproxy.co.uk,Proxy\nDOMAIN-SUFFIX,sp.gan8.in,Proxy\nDOMAIN-SUFFIX,www.amd.com,Proxy\nDOMAIN-SUFFIX,www.linktree.com,Proxy\nDOMAIN-SUFFIX,inmwiki.com,Proxy\nDOMAIN-SUFFIX,x531051.com,Proxy\nDOMAIN-SUFFIX,dagospia.com,Proxy\nDOMAIN-SUFFIX,greenparty.org.tw,Proxy\nDOMAIN-SUFFIX,vpnzz.com,Proxy\nDOMAIN-SUFFIX,viu.com,Proxy\nDOMAIN-SUFFIX,businessinsider.in,Proxy\nDOMAIN-SUFFIX,waifulabs.com,Proxy\nDOMAIN-SUFFIX,fqvpn.com,Proxy\nDOMAIN-SUFFIX,www.a202.idv.tw,Proxy\nDOMAIN-SUFFIX,anonine.com,Proxy\nDOMAIN-SUFFIX,www.peaceportal.org,Proxy\nDOMAIN-SUFFIX,haberturk.com,Proxy\nDOMAIN-SUFFIX,jingpingmedia.com,Proxy\nDOMAIN-SUFFIX,betslip.hkjcfootball.com,Proxy\nDOMAIN-SUFFIX,livingotherwise.com,Proxy\nDOMAIN-SUFFIX,flecheinthepeche.fr,Proxy\nDOMAIN-SUFFIX,pornhubpremium.com,Proxy\nDOMAIN-SUFFIX,7mmtv.in,Proxy\nDOMAIN-SUFFIX,freemycloud.pw,Proxy\nDOMAIN-SUFFIX,www.itweet.net,Proxy\nDOMAIN-SUFFIX,acu.edu,Proxy\nDOMAIN-SUFFIX,marathonbet.com,Proxy\nDOMAIN-SUFFIX,searchquotes.com,Proxy\nDOMAIN-SUFFIX,bancochile.cl,Proxy\nDOMAIN-SUFFIX,ikstar.com,Proxy\nDOMAIN-SUFFIX,www.my-expat-network.com,Proxy\nDOMAIN-SUFFIX,d1v4gh14f21l8f.cloudfront.net,Proxy\nDOMAIN-SUFFIX,bcy01.com,Proxy\nDOMAIN-SUFFIX,fc336.com,Proxy\nDOMAIN-SUFFIX,him.slyip.net,Proxy\nDOMAIN-SUFFIX,www.1683550.com,Proxy\nDOMAIN-SUFFIX,liho.club,Proxy\nDOMAIN-SUFFIX,76.slyip.com,Proxy\nDOMAIN-SUFFIX,www.bottomlinestudios.net,Proxy\nDOMAIN-SUFFIX,couwe.com,Proxy\nDOMAIN-SUFFIX,google.comwikipedia.org,Proxy\nDOMAIN-SUFFIX,asach.org,Proxy\nDOMAIN-SUFFIX,06966.com,Proxy\nDOMAIN-SUFFIX,wgzl.vpokv.com,Proxy\nDOMAIN-SUFFIX,ss.wtf,Proxy\nDOMAIN-SUFFIX,www.5284064.com,Proxy\nDOMAIN-SUFFIX,www.amjs449.com,Proxy\nDOMAIN-SUFFIX,www.ganbey.com,Proxy\nDOMAIN-SUFFIX,seeshijie.com,Proxy\nDOMAIN-SUFFIX,www.naturalhigh.co.jp,Proxy\nDOMAIN-SUFFIX,tube8.com,Proxy\nDOMAIN-SUFFIX,meshrep.com,Proxy\nDOMAIN-SUFFIX,freedom.dun.im,Proxy\nDOMAIN-SUFFIX,proton.ch,Proxy\nDOMAIN-SUFFIX,yts.lt,Proxy\nDOMAIN-SUFFIX,falunworld.net,Proxy\nDOMAIN-SUFFIX,www.mogaforex.com,Proxy\nDOMAIN-SUFFIX,www.neskes.com,Proxy\nDOMAIN-SUFFIX,www.txingvpn.com,Proxy\nDOMAIN-SUFFIX,www.5high.net,Proxy\nDOMAIN-SUFFIX,twitlonger.com,Proxy\nDOMAIN-SUFFIX,egotastic.com,Proxy\nDOMAIN-SUFFIX,webmail.dataoncloud.com,Proxy\nDOMAIN-SUFFIX,omnitalk.org,Proxy\nDOMAIN-SUFFIX,ruhotgirls.com,Proxy\nDOMAIN-SUFFIX,www.xpj000888.com,Proxy\nDOMAIN-SUFFIX,bannedbook.org,Proxy\nDOMAIN-SUFFIX,www.baige-vpn.com,Proxy\nDOMAIN-SUFFIX,gifporntube.com,Proxy\nDOMAIN-SUFFIX,gnli.christianpost.com,Proxy\nDOMAIN-SUFFIX,pornhublive.com,Proxy\nDOMAIN-SUFFIX,infoonhealth.xyz,Proxy\nDOMAIN-SUFFIX,tinychat.com,Proxy\nDOMAIN-SUFFIX,xh93333.com,Proxy\nDOMAIN-SUFFIX,android.com,Proxy\nDOMAIN-SUFFIX,www.kwoktinlap.net,Proxy\nDOMAIN-SUFFIX,video.fdbox.com,Proxy\nDOMAIN-SUFFIX,vs221.com,Proxy\nDOMAIN-SUFFIX,ntdtv.co.kr,Proxy\nDOMAIN-SUFFIX,seventhousand.net,Proxy\nDOMAIN-SUFFIX,nipponhd.com,Proxy\nDOMAIN-SUFFIX,telegram.space,Proxy\nDOMAIN-SUFFIX,www.xuefeiw.com,Proxy\nDOMAIN-SUFFIX,735bm.com,Proxy\nDOMAIN-SUFFIX,changenow.io,Proxy\nDOMAIN-SUFFIX,lofe.morfans.cn,Proxy\nDOMAIN-SUFFIX,truth.atspace.eu,Proxy\nDOMAIN-SUFFIX,m.dzcp8999.com,Proxy\nDOMAIN-SUFFIX,coconutsecret.com,Proxy\nDOMAIN-SUFFIX,jichangtj.com,Proxy\nDOMAIN-SUFFIX,www.stonewall.org.uk,Proxy\nDOMAIN-SUFFIX,zoomtv.top,Proxy\nDOMAIN-SUFFIX,chinaso.com,Proxy\nDOMAIN-SUFFIX,h6.slyip.net,Proxy\nDOMAIN-SUFFIX,rsshub.app,Proxy\nDOMAIN-SUFFIX,bm50000.com,Proxy\nDOMAIN-SUFFIX,cydia.ifuckgfw.com,Proxy\nDOMAIN-SUFFIX,www.privoxy.org,Proxy\nDOMAIN-SUFFIX,springboardplatform.com,Proxy\nDOMAIN-SUFFIX,www.tibetfest.org,Proxy\nDOMAIN-SUFFIX,www.freetibet.lt,Proxy\nDOMAIN-SUFFIX,www.jht.idv.tw,Proxy\nDOMAIN-SUFFIX,www.kunsangyeshe.com.au,Proxy\nDOMAIN-SUFFIX,portis21.spaces.live.com,Proxy\nDOMAIN-SUFFIX,www.555fl.com,Proxy\nDOMAIN-SUFFIX,xiaoxintv.net,Proxy\nDOMAIN-SUFFIX,j6di6g3.x.incapdns.net,Proxy\nDOMAIN-SUFFIX,insideover.com,Proxy\nDOMAIN-SUFFIX,gracesiefer.com,Proxy\nDOMAIN-SUFFIX,www.veda.co.nz,Proxy\nDOMAIN-SUFFIX,thetibetcenter.org,Proxy\nDOMAIN-SUFFIX,www.easy4x.net,Proxy\nDOMAIN-SUFFIX,ndi.org,Proxy\nDOMAIN-SUFFIX,srft.nhs.uk,Proxy\nDOMAIN-SUFFIX,mayimayi.com,Proxy\nDOMAIN-SUFFIX,google.com.do,Proxy\nDOMAIN-SUFFIX,montrealgazette.com,Proxy\nDOMAIN-SUFFIX,new2.bg76.eu.org,Proxy\nDOMAIN-SUFFIX,tuidang.se,Proxy\nDOMAIN-SUFFIX,citypopulation.de,Proxy\nDOMAIN-SUFFIX,68399.com,Proxy\nDOMAIN-SUFFIX,www.baoyangchen.com,Proxy\nDOMAIN-SUFFIX,xxtv.5lxtv.com,Proxy\nDOMAIN-SUFFIX,google.com.py,Proxy\nDOMAIN-SUFFIX,3178a.com,Proxy\nDOMAIN-SUFFIX,katielopez.ml,Proxy\nDOMAIN-SUFFIX,jinshagt111.com,Proxy\nDOMAIN-SUFFIX,1ff2d.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,www.18porn.sex,Proxy\nDOMAIN-SUFFIX,schneiderhome.us,Proxy\nDOMAIN-SUFFIX,www.ipredator.com,Proxy\nDOMAIN-SUFFIX,doh.ffmuc.net,Proxy\nDOMAIN-SUFFIX,www.sanghalou.org,Proxy\nDOMAIN-SUFFIX,d1gx3j8kwj94us.cloudfront.net,Proxy\nDOMAIN-SUFFIX,crowdrise.com,Proxy\nDOMAIN-SUFFIX,farsipod101.com,Proxy\nDOMAIN-SUFFIX,ks288.com,Proxy\nDOMAIN-SUFFIX,ghandi.net,Proxy\nDOMAIN-SUFFIX,acgft.us,Proxy\nDOMAIN-SUFFIX,pornwild.com,Proxy\nDOMAIN-SUFFIX,network-tools.com,Proxy\nDOMAIN-SUFFIX,hkfront.org,Proxy\nDOMAIN-SUFFIX,www.bundestag.de,Proxy\nDOMAIN-SUFFIX,bbc-now.co.uk,Proxy\nDOMAIN-SUFFIX,google.com.sg,Proxy\nDOMAIN-SUFFIX,offbeatchina.com,Proxy\nDOMAIN-SUFFIX,netsee.co,Proxy\nDOMAIN-SUFFIX,theconversation.com,Proxy\nDOMAIN-SUFFIX,yourlust.com,Proxy\nDOMAIN-SUFFIX,www.remotevpn.net,Proxy\nDOMAIN-SUFFIX,google.tk,Proxy\nDOMAIN-SUFFIX,server.id.lv,Proxy\nDOMAIN-SUFFIX,f8899.com,Proxy\nDOMAIN-SUFFIX,clixstudios.com,Proxy\nDOMAIN-SUFFIX,css3.now-ip.net,Proxy\nDOMAIN-SUFFIX,www.uwants.com,Proxy\nDOMAIN-SUFFIX,mmandrade.com.br,Proxy\nDOMAIN-SUFFIX,99world.com,Proxy\nDOMAIN-SUFFIX,oroxy.com,Proxy\nDOMAIN-SUFFIX,www.omct.org,Proxy\nDOMAIN-SUFFIX,www.hoteldion.com.tw,Proxy\nDOMAIN-SUFFIX,b2b.gsk.com.tw,Proxy\nDOMAIN-SUFFIX,javbooks.com,Proxy\nDOMAIN-SUFFIX,xvip.site,Proxy\nDOMAIN-SUFFIX,fabsk.eu,Proxy\nDOMAIN-SUFFIX,www.free-strip-games.com,Proxy\nDOMAIN-SUFFIX,voaindonesia.com,Proxy\nDOMAIN-SUFFIX,bd835.com,Proxy\nDOMAIN-SUFFIX,bt2mag.com,Proxy\nDOMAIN-SUFFIX,38850099.com,Proxy\nDOMAIN-SUFFIX,www.hl168.com,Proxy\nDOMAIN-SUFFIX,wujieliulan.com,Proxy\nDOMAIN-SUFFIX,spoe.at,Proxy\nDOMAIN-SUFFIX,ipobar.com,Proxy\nDOMAIN-SUFFIX,desire2learn.com,Proxy\nDOMAIN-SUFFIX,www.eddid.com.hk,Proxy\nDOMAIN-SUFFIX,nbcnews.com,Proxy\nDOMAIN-SUFFIX,dissentmagazine.org,Proxy\nDOMAIN-SUFFIX,99c2.cc,Proxy\nDOMAIN-SUFFIX,ezcat.xyz,Proxy\nDOMAIN-SUFFIX,www.wnflb.com,Proxy\nDOMAIN-SUFFIX,epochtimes.se,Proxy\nDOMAIN-SUFFIX,nine07.icu,Proxy\nDOMAIN-SUFFIX,www.voipfone.co.uk,Proxy\nDOMAIN-SUFFIX,h00t.ca,Proxy\nDOMAIN-SUFFIX,poolin.com,Proxy\nDOMAIN-SUFFIX,lsak.eu,Proxy\nDOMAIN-SUFFIX,cloudy2.gq,Proxy\nDOMAIN-SUFFIX,0235ee.com,Proxy\nDOMAIN-SUFFIX,c82.compucase.com,Proxy\nDOMAIN-SUFFIX,radio-light.ro,Proxy\nDOMAIN-SUFFIX,www.liberty-ss.top,Proxy\nDOMAIN-SUFFIX,xvideos.com.br,Proxy\nDOMAIN-SUFFIX,yousendit.com,Proxy\nDOMAIN-SUFFIX,cloudflare-ipfs.com,Proxy\nDOMAIN-SUFFIX,beproxy.com,Proxy\nDOMAIN-SUFFIX,betboy.me,Proxy\nDOMAIN-SUFFIX,os.44.06.homeip.net,Proxy\nDOMAIN-SUFFIX,www.dvd-50.com,Proxy\nDOMAIN-SUFFIX,nine99.cc,Proxy\nDOMAIN-SUFFIX,www.cilifeng.club,Proxy\nDOMAIN-SUFFIX,rjlyapps3.com,Proxy\nDOMAIN-SUFFIX,knvpn.com,Proxy\nDOMAIN-SUFFIX,www.boboporn.com,Proxy\nDOMAIN-SUFFIX,ra4wvpn.com,Proxy\nDOMAIN-SUFFIX,humoron.com,Proxy\nDOMAIN-SUFFIX,tibet.nu,Proxy\nDOMAIN-SUFFIX,www.couponmeup.com,Proxy\nDOMAIN-SUFFIX,main.ga,Proxy\nDOMAIN-SUFFIX,nzchinese.net.nz,Proxy\nDOMAIN-SUFFIX,frontline.thehindu.com,Proxy\nDOMAIN-SUFFIX,brotesdelsur.cl,Proxy\nDOMAIN-SUFFIX,madouqu.com,Proxy\nDOMAIN-SUFFIX,ps5.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,h5.ldvip069.com,Proxy\nDOMAIN-SUFFIX,bbsone.com,Proxy\nDOMAIN-SUFFIX,tibetanyouth.org,Proxy\nDOMAIN-SUFFIX,dsn1500.com,Proxy\nDOMAIN-SUFFIX,tubekitty.com,Proxy\nDOMAIN-SUFFIX,google.it,Proxy\nDOMAIN-SUFFIX,cista-narava.net,Proxy\nDOMAIN-SUFFIX,nordvpnteams.com,Proxy\nDOMAIN-SUFFIX,stupidvideos.com,Proxy\nDOMAIN-SUFFIX,www.diffen.com,Proxy\nDOMAIN-SUFFIX,tryteens.com,Proxy\nDOMAIN-SUFFIX,www.tfvip88.com,Proxy\nDOMAIN-SUFFIX,commandarms.com,Proxy\nDOMAIN-SUFFIX,fun8802.com,Proxy\nDOMAIN-SUFFIX,tierrapura.org,Proxy\nDOMAIN-SUFFIX,plasa-umbrire.ro,Proxy\nDOMAIN-SUFFIX,www.june4commemoration.org,Proxy\nDOMAIN-SUFFIX,cgvpn.com,Proxy\nDOMAIN-SUFFIX,www.fotor.com,Proxy\nDOMAIN-SUFFIX,wi.wakingmoon.com,Proxy\nDOMAIN-SUFFIX,tecalliance.net,Proxy\nDOMAIN-SUFFIX,www.174sihu.com,Proxy\nDOMAIN-SUFFIX,mp3ye.eu,Proxy\nDOMAIN-SUFFIX,d18teiqcwhzbtm.cloudfront.net,Proxy\nDOMAIN-SUFFIX,world-rights.org,Proxy\nDOMAIN-SUFFIX,www.globalswitch.de,Proxy\nDOMAIN-SUFFIX,usp.ac.fj,Proxy\nDOMAIN-SUFFIX,cs0080.com,Proxy\nDOMAIN-SUFFIX,fireballrs.de,Proxy\nDOMAIN-SUFFIX,amc.com,Proxy\nDOMAIN-SUFFIX,cp929.com,Proxy\nDOMAIN-SUFFIX,radio.garden,Proxy\nDOMAIN-SUFFIX,heungkongdiscuss.com,Proxy\nDOMAIN-SUFFIX,www.dr-ming-xia.org,Proxy\nDOMAIN-SUFFIX,culturaletibetana.org,Proxy\nDOMAIN-SUFFIX,hp.hacked.jp,Proxy\nDOMAIN-SUFFIX,wwcr.com,Proxy\nDOMAIN-SUFFIX,hj5608.com,Proxy\nDOMAIN-SUFFIX,empfs.com,Proxy\nDOMAIN-SUFFIX,www.khg56.com,Proxy\nDOMAIN-SUFFIX,itaboo.info,Proxy\nDOMAIN-SUFFIX,straplessdildo.com,Proxy\nDOMAIN-SUFFIX,the-truths.com,Proxy\nDOMAIN-SUFFIX,instagram.com,Proxy\nDOMAIN-SUFFIX,whatisscientology.org,Proxy\nDOMAIN-SUFFIX,50045.gtoxtv.com,Proxy\nDOMAIN-SUFFIX,nradio.me,Proxy\nDOMAIN-SUFFIX,www.kosho.or.jp,Proxy\nDOMAIN-SUFFIX,dns-nyc.aaflalo.me,Proxy\nDOMAIN-SUFFIX,gateway.ravenland.org,Proxy\nDOMAIN-SUFFIX,www.ultrawebhosting.com,Proxy\nDOMAIN-SUFFIX,queerpixels.com,Proxy\nDOMAIN-SUFFIX,en.mercopress.com,Proxy\nDOMAIN-SUFFIX,mogi.ws,Proxy\nDOMAIN-SUFFIX,www.tendai.or.jp,Proxy\nDOMAIN-SUFFIX,iteke.tk,Proxy\nDOMAIN-SUFFIX,1984bbs.org,Proxy\nDOMAIN-SUFFIX,www.104fuck.com,Proxy\nDOMAIN-SUFFIX,desipro.de,Proxy\nDOMAIN-SUFFIX,www.icili.com,Proxy\nDOMAIN-SUFFIX,www.thinkstockphotos.in,Proxy\nDOMAIN-SUFFIX,learn.cpaaustralia.com.au,Proxy\nDOMAIN-SUFFIX,sora.komica.org,Proxy\nDOMAIN-SUFFIX,www.mgvip6.com,Proxy\nDOMAIN-SUFFIX,2.android.pool.ntp.org,Proxy\nDOMAIN-SUFFIX,theyogafarm.com,Proxy\nDOMAIN-SUFFIX,unlock-iceland.com,Proxy\nDOMAIN-SUFFIX,moeerolibrary.com,Proxy\nDOMAIN-SUFFIX,moran.ws,Proxy\nDOMAIN-SUFFIX,www.biwei198.com,Proxy\nDOMAIN-SUFFIX,mastodont.cat,Proxy\nDOMAIN-SUFFIX,www.raidcall.com.ru,Proxy\nDOMAIN-SUFFIX,www.sftpoland.org,Proxy\nDOMAIN-SUFFIX,www.asmr-100.com,Proxy\nDOMAIN-SUFFIX,dsn503.co,Proxy\nDOMAIN-SUFFIX,squirly.info,Proxy\nDOMAIN-SUFFIX,iqqtv.vip,Proxy\nDOMAIN-SUFFIX,www.radiofree.org,Proxy\nDOMAIN-SUFFIX,www.juicyads.com,Proxy\nDOMAIN-SUFFIX,www.yah.idv.tw,Proxy\nDOMAIN-SUFFIX,iglhrc.org,Proxy\nDOMAIN-SUFFIX,apkpure.com,Proxy\nDOMAIN-SUFFIX,vpngate.net,Proxy\nDOMAIN-SUFFIX,cn.nowness.com,Proxy\nDOMAIN-SUFFIX,gaydemon.com,Proxy\nDOMAIN-SUFFIX,479.com,Proxy\nDOMAIN-SUFFIX,youxu.info,Proxy\nDOMAIN-SUFFIX,www.islam.uz,Proxy\nDOMAIN-SUFFIX,46.flnet.org,Proxy\nDOMAIN-SUFFIX,huarian.com,Proxy\nDOMAIN-SUFFIX,blogspot.be,Proxy\nDOMAIN-SUFFIX,codingcompetitions.withgoogle.com,Proxy\nDOMAIN-SUFFIX,plasticnews.wf,Proxy\nDOMAIN-SUFFIX,lzmtnews.org,Proxy\nDOMAIN-SUFFIX,newbrazzers.com,Proxy\nDOMAIN-SUFFIX,webmail.intrepidcs.com,Proxy\nDOMAIN-SUFFIX,htmianfen.com,Proxy\nDOMAIN-SUFFIX,coreclan.net,Proxy\nDOMAIN-SUFFIX,letou.com,Proxy\nDOMAIN-SUFFIX,89951.com,Proxy\nDOMAIN-SUFFIX,wn9996.com,Proxy\nDOMAIN-SUFFIX,99.cr.rs,Proxy\nDOMAIN-SUFFIX,91stw.net,Proxy\nDOMAIN-SUFFIX,tirnanogpreschools.com,Proxy\nDOMAIN-SUFFIX,petitionsite.com,Proxy\nDOMAIN-SUFFIX,aniseedballs.co.uk,Proxy\nDOMAIN-SUFFIX,1qqtv.com,Proxy\nDOMAIN-SUFFIX,pjorn.com,Proxy\nDOMAIN-SUFFIX,forums.steampowered.com,Proxy\nDOMAIN-SUFFIX,facebook.se,Proxy\nDOMAIN-SUFFIX,vpnpop.com,Proxy\nDOMAIN-SUFFIX,bookdepository.com,Proxy\nDOMAIN-SUFFIX,minghui.org,Proxy\nDOMAIN-SUFFIX,mlzs.work,Proxy\nDOMAIN-SUFFIX,eth0.org.uk,Proxy\nDOMAIN-SUFFIX,cryptovion.com,Proxy\nDOMAIN-SUFFIX,is-leet.com,Proxy\nDOMAIN-SUFFIX,www.r-type.ca,Proxy\nDOMAIN-SUFFIX,heeact.edu.tw,Proxy\nDOMAIN-SUFFIX,hkhrm.org.hk,Proxy\nDOMAIN-SUFFIX,www.acgncyw.com,Proxy\nDOMAIN-SUFFIX,tibetanfeministcollective.org,Proxy\nDOMAIN-SUFFIX,www.saloncs.com.tw,Proxy\nDOMAIN-SUFFIX,onmypc.biz,Proxy\nDOMAIN-SUFFIX,ip5000.com,Proxy\nDOMAIN-SUFFIX,pizzarola.com,Proxy\nDOMAIN-SUFFIX,xcams.com,Proxy\nDOMAIN-SUFFIX,nerdkingdom.com,Proxy\nDOMAIN-SUFFIX,freevideoproxy.com,Proxy\nDOMAIN-SUFFIX,85po.com,Proxy\nDOMAIN-SUFFIX,bbs.islga.org,Proxy\nDOMAIN-SUFFIX,ipredator.se,Proxy\nDOMAIN-SUFFIX,pandavpn-jp.com,Proxy\nDOMAIN-SUFFIX,www.xnxx115.com,Proxy\nDOMAIN-SUFFIX,pornyoutube.com,Proxy\nDOMAIN-SUFFIX,wby118.com,Proxy\nDOMAIN-SUFFIX,www.taylorguitars.cn,Proxy\nDOMAIN-SUFFIX,spatio.li,Proxy\nDOMAIN-SUFFIX,12vpx.com,Proxy\nDOMAIN-SUFFIX,ntuaa-gp.org,Proxy\nDOMAIN-SUFFIX,sv.freepac.pw,Proxy\nDOMAIN-SUFFIX,martyhou.com,Proxy\nDOMAIN-SUFFIX,8587z.cc,Proxy\nDOMAIN-SUFFIX,e-hentaidb.com,Proxy\nDOMAIN-SUFFIX,threatchaos.com,Proxy\nDOMAIN-SUFFIX,www.tibet.org.il,Proxy\nDOMAIN-SUFFIX,zzm.dnspage.xyz,Proxy\nDOMAIN-SUFFIX,telesco.pe,Proxy\nDOMAIN-SUFFIX,799499.com,Proxy\nDOMAIN-SUFFIX,bbcc-consulting.com,Proxy\nDOMAIN-SUFFIX,boxun3.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,quickdraw.withgoogle.com,Proxy\nDOMAIN-SUFFIX,sanfen002.xyz,Proxy\nDOMAIN-SUFFIX,vpnqr.com,Proxy\nDOMAIN-SUFFIX,one.one.one.one,Proxy\nDOMAIN-SUFFIX,fun571.com,Proxy\nDOMAIN-SUFFIX,www.mangalashribhuti.org,Proxy\nDOMAIN-SUFFIX,pastie.org,Proxy\nDOMAIN-SUFFIX,www.forex4you.com,Proxy\nDOMAIN-SUFFIX,www.insight.ly,Proxy\nDOMAIN-SUFFIX,incezt.net,Proxy\nDOMAIN-SUFFIX,pornpranks.com,Proxy\nDOMAIN-SUFFIX,getgom.com,Proxy\nDOMAIN-SUFFIX,h5.ld2087.cc,Proxy\nDOMAIN-SUFFIX,h5.ld2040.cc,Proxy\nDOMAIN-SUFFIX,kir019464.kir.jp,Proxy\nDOMAIN-SUFFIX,ck.spacetechnology.net,Proxy\nDOMAIN-SUFFIX,dweb.link,Proxy\nDOMAIN-SUFFIX,cme.com,Proxy\nDOMAIN-SUFFIX,bcchinese.net,Proxy\nDOMAIN-SUFFIX,www.icenci.com,Proxy\nDOMAIN-SUFFIX,ftvnews.com.tw,Proxy\nDOMAIN-SUFFIX,www.hayatnuri.org,Proxy\nDOMAIN-SUFFIX,m.ptcff666.com,Proxy\nDOMAIN-SUFFIX,www.melonstube.com,Proxy\nDOMAIN-SUFFIX,tellefsen.org,Proxy\nDOMAIN-SUFFIX,bodog888.com,Proxy\nDOMAIN-SUFFIX,wn181.com,Proxy\nDOMAIN-SUFFIX,h782.com,Proxy\nDOMAIN-SUFFIX,dx7722.com,Proxy\nDOMAIN-SUFFIX,www.julesjordan.com,Proxy\nDOMAIN-SUFFIX,ssrtool.com,Proxy\nDOMAIN-SUFFIX,night13.live,Proxy\nDOMAIN-SUFFIX,64live.org,Proxy\nDOMAIN-SUFFIX,www.spectator.com.au,Proxy\nDOMAIN-SUFFIX,herrbischoff.com,Proxy\nDOMAIN-SUFFIX,april5action.blogspot.hk,Proxy\nDOMAIN-SUFFIX,mygalgame.com,Proxy\nDOMAIN-SUFFIX,www.top-able.com,Proxy\nDOMAIN-SUFFIX,00006809.com,Proxy\nDOMAIN-SUFFIX,tw.buy.yahoo.com,Proxy\nDOMAIN-SUFFIX,soupofmedia.com,Proxy\nDOMAIN-SUFFIX,radiovaticana.org,Proxy\nDOMAIN-SUFFIX,adultreviews.com,Proxy\nDOMAIN-SUFFIX,www.xw293.com,Proxy\nDOMAIN-SUFFIX,ygto.com,Proxy\nDOMAIN-SUFFIX,www.mmoncu.com,Proxy\nDOMAIN-SUFFIX,www.hsbc.ca,Proxy\nDOMAIN-SUFFIX,jbo02.com,Proxy\nDOMAIN-SUFFIX,baa3.ddns.us,Proxy\nDOMAIN-SUFFIX,secretsline.biz,Proxy\nDOMAIN-SUFFIX,tor01.com,Proxy\nDOMAIN-SUFFIX,welt.de,Proxy\nDOMAIN-SUFFIX,arabicbible.org,Proxy\nDOMAIN-SUFFIX,mefeedia.com,Proxy\nDOMAIN-SUFFIX,511.cc,Proxy\nDOMAIN-SUFFIX,tan.flnet.org,Proxy\nDOMAIN-SUFFIX,www.wuwweb.com,Proxy\nDOMAIN-SUFFIX,torquays.com,Proxy\nDOMAIN-SUFFIX,newsmax.com,Proxy\nDOMAIN-SUFFIX,from-ut.com,Proxy\nDOMAIN-SUFFIX,citrix-ca.cloudwerx.com,Proxy\nDOMAIN-SUFFIX,www.aex88.com,Proxy\nDOMAIN-SUFFIX,life.pigg.ameba.jp,Proxy\nDOMAIN-SUFFIX,uk.32bit.top,Proxy\nDOMAIN-SUFFIX,euronews.net,Proxy\nDOMAIN-SUFFIX,www.bigtitstokyo.com,Proxy\nDOMAIN-SUFFIX,computeconline.es,Proxy\nDOMAIN-SUFFIX,d15kylb2urt2n1.cloudfront.net,Proxy\nDOMAIN-SUFFIX,yes123.com.tw,Proxy\nDOMAIN-SUFFIX,mychiriqui.com,Proxy\nDOMAIN-SUFFIX,hkfaa.com,Proxy\nDOMAIN-SUFFIX,www.cloudwards.net,Proxy\nDOMAIN-SUFFIX,www.fanqianglu.com,Proxy\nDOMAIN-SUFFIX,adult-cartoon-sex.com,Proxy\nDOMAIN-SUFFIX,gcorelabs.com,Proxy\nDOMAIN-SUFFIX,theaggie.org,Proxy\nDOMAIN-SUFFIX,iz.com,Proxy\nDOMAIN-SUFFIX,www.wifemovies.net,Proxy\nDOMAIN-SUFFIX,magazine.godsdirectcontact.net,Proxy\nDOMAIN-SUFFIX,www.huffingtonpost.de,Proxy\nDOMAIN-SUFFIX,rfamobile.org,Proxy\nDOMAIN-SUFFIX,www.betvictor39.com,Proxy\nDOMAIN-SUFFIX,www.pocketmusic.it,Proxy\nDOMAIN-SUFFIX,www.seeshow.net,Proxy\nDOMAIN-SUFFIX,zhenlibu1984.com,Proxy\nDOMAIN-SUFFIX,bj.ssvps.site,Proxy\nDOMAIN-SUFFIX,8505046.com,Proxy\nDOMAIN-SUFFIX,assets.bomoda.com,Proxy\nDOMAIN-SUFFIX,www.tumgir.com,Proxy\nDOMAIN-SUFFIX,cnbbnews.wordpress.com,Proxy\nDOMAIN-SUFFIX,app.heywire.com,Proxy\nDOMAIN-SUFFIX,tuitwit.com,Proxy\nDOMAIN-SUFFIX,xbvpn.com,Proxy\nDOMAIN-SUFFIX,crabdance.com,Proxy\nDOMAIN-SUFFIX,uwants.com,Proxy\nDOMAIN-SUFFIX,av-e-body.com,Proxy\nDOMAIN-SUFFIX,gmilk.tv,Proxy\nDOMAIN-SUFFIX,www.tibetangeeks.com,Proxy\nDOMAIN-SUFFIX,www.keenow.com,Proxy\nDOMAIN-SUFFIX,web-merchant-trade.3366pay.com,Proxy\nDOMAIN-SUFFIX,www.ctbuddhamind.org,Proxy\nDOMAIN-SUFFIX,www.oreca-store.com,Proxy\nDOMAIN-SUFFIX,www.f88vip12.com,Proxy\nDOMAIN-SUFFIX,fupx.phi.b0ne.com,Proxy\nDOMAIN-SUFFIX,www.usogood.com,Proxy\nDOMAIN-SUFFIX,customs4u.com,Proxy\nDOMAIN-SUFFIX,ksnews.com.tw,Proxy\nDOMAIN-SUFFIX,tvplayvideos.com,Proxy\nDOMAIN-SUFFIX,vpn99.net,Proxy\nDOMAIN-SUFFIX,zhong788.com,Proxy\nDOMAIN-SUFFIX,www.008112.com,Proxy\nDOMAIN-SUFFIX,www.6396y.com,Proxy\nDOMAIN-SUFFIX,fg686.com,Proxy\nDOMAIN-SUFFIX,globalaffairs.org,Proxy\nDOMAIN-SUFFIX,planeseek.com,Proxy\nDOMAIN-SUFFIX,fpa.org,Proxy\nDOMAIN-SUFFIX,yuyan.live,Proxy\nDOMAIN-SUFFIX,globaltm.org,Proxy\nDOMAIN-SUFFIX,www.porndao.com,Proxy\nDOMAIN-SUFFIX,hk.ulifestyle.com.hk,Proxy\nDOMAIN-SUFFIX,www.9999cn.com,Proxy\nDOMAIN-SUFFIX,fantv.hk,Proxy\nDOMAIN-SUFFIX,www.xinbi555.com,Proxy\nDOMAIN-SUFFIX,de.roccat.com,Proxy\nDOMAIN-SUFFIX,k6.ac7074a8.com,Proxy\nDOMAIN-SUFFIX,www.will-japan.facebook.jp,Proxy\nDOMAIN-SUFFIX,gy18.xyz,Proxy\nDOMAIN-SUFFIX,www.javfee.com,Proxy\nDOMAIN-SUFFIX,10bet.com,Proxy\nDOMAIN-SUFFIX,m-team.cc,Proxy\nDOMAIN-SUFFIX,www.wikipedia.ahmu.cf,Proxy\nDOMAIN-SUFFIX,654309.xyz,Proxy\nDOMAIN-SUFFIX,soup.io,Proxy\nDOMAIN-SUFFIX,211.slyip.net,Proxy\nDOMAIN-SUFFIX,xxxvideosex.org,Proxy\nDOMAIN-SUFFIX,pinluoxiang.com,Proxy\nDOMAIN-SUFFIX,edc.dsv.com,Proxy\nDOMAIN-SUFFIX,wl.vern.cc,Proxy\nDOMAIN-SUFFIX,imagefap.com,Proxy\nDOMAIN-SUFFIX,www.100most.com.hk,Proxy\nDOMAIN-SUFFIX,glass8.eu,Proxy\nDOMAIN-SUFFIX,gamesoda.com,Proxy\nDOMAIN-SUFFIX,mingpao.com,Proxy\nDOMAIN-SUFFIX,kinmen.org.tw,Proxy\nDOMAIN-SUFFIX,my-proxy.com,Proxy\nDOMAIN-SUFFIX,hkdc.us,Proxy\nDOMAIN-SUFFIX,servebeer.com,Proxy\nDOMAIN-SUFFIX,www.nztd38.com,Proxy\nDOMAIN-SUFFIX,www.southernhighlandnews.com.au,Proxy\nDOMAIN-SUFFIX,gmail.de,Proxy\nDOMAIN-SUFFIX,free-gate.org,Proxy\nDOMAIN-SUFFIX,coinsquare.io,Proxy\nDOMAIN-SUFFIX,pornhub.net,Proxy\nDOMAIN-SUFFIX,ctowc.org,Proxy\nDOMAIN-SUFFIX,9youtube.com,Proxy\nDOMAIN-SUFFIX,885.my03.com,Proxy\nDOMAIN-SUFFIX,auto-aufladen.de,Proxy\nDOMAIN-SUFFIX,vultryhw.com,Proxy\nDOMAIN-SUFFIX,chihan.live,Proxy\nDOMAIN-SUFFIX,huobi.com,Proxy\nDOMAIN-SUFFIX,xjdp.aspi.org.au,Proxy\nDOMAIN-SUFFIX,mynewsolid.me,Proxy\nDOMAIN-SUFFIX,18xgroup.com,Proxy\nDOMAIN-SUFFIX,recolic.net,Proxy\nDOMAIN-SUFFIX,www.taiwandrone.org,Proxy\nDOMAIN-SUFFIX,chinesenews.net.au,Proxy\nDOMAIN-SUFFIX,forgiven-online.com,Proxy\nDOMAIN-SUFFIX,starlink.one,Proxy\nDOMAIN-SUFFIX,asia-api.yikyakapi.net,Proxy\nDOMAIN-SUFFIX,www.interfaithcincy.org,Proxy\nDOMAIN-SUFFIX,www.ouliannews.com,Proxy\nDOMAIN-SUFFIX,www.dewezet.de,Proxy\nDOMAIN-SUFFIX,a-pay.net,Proxy\nDOMAIN-SUFFIX,15659988.com,Proxy\nDOMAIN-SUFFIX,nokogiri.org,Proxy\nDOMAIN-SUFFIX,gretchenrubin.com,Proxy\nDOMAIN-SUFFIX,634949.com,Proxy\nDOMAIN-SUFFIX,thebarchive.com,Proxy\nDOMAIN-SUFFIX,437365.com,Proxy\nDOMAIN-SUFFIX,jp-sex.com,Proxy\nDOMAIN-SUFFIX,dalailama80.org,Proxy\nDOMAIN-SUFFIX,tv.freepac.pw,Proxy\nDOMAIN-SUFFIX,git.io,Proxy\nDOMAIN-SUFFIX,wildfireapp.com,Proxy\nDOMAIN-SUFFIX,schneider-electric.box.com,Proxy\nDOMAIN-SUFFIX,christianfreedom.org,Proxy\nDOMAIN-SUFFIX,vpnr.com,Proxy\nDOMAIN-SUFFIX,saoc.oar.3d-game.com,Proxy\nDOMAIN-SUFFIX,www.mbww.com,Proxy\nDOMAIN-SUFFIX,aenhancers.com,Proxy\nDOMAIN-SUFFIX,ww1.sldao.us,Proxy\nDOMAIN-SUFFIX,www.hidevpn.com,Proxy\nDOMAIN-SUFFIX,1665333888.com,Proxy\nDOMAIN-SUFFIX,braghini.com.ar,Proxy\nDOMAIN-SUFFIX,mail.osorhan.com,Proxy\nDOMAIN-SUFFIX,bfzbo.com,Proxy\nDOMAIN-SUFFIX,europalace.com,Proxy\nDOMAIN-SUFFIX,sun030.com,Proxy\nDOMAIN-SUFFIX,simonshen.blog,Proxy\nDOMAIN-SUFFIX,www.digitalvajra.com,Proxy\nDOMAIN-SUFFIX,tibet.sk,Proxy\nDOMAIN-SUFFIX,ca.hotfreevpn.com,Proxy\nDOMAIN-SUFFIX,64museum.org,Proxy\nDOMAIN-SUFFIX,chineseposters.net,Proxy\nDOMAIN-SUFFIX,baidu-18.com,Proxy\nDOMAIN-SUFFIX,www.eu2018.net,Proxy\nDOMAIN-SUFFIX,www.k51r.com,Proxy\nDOMAIN-SUFFIX,btctrade.im,Proxy\nDOMAIN-SUFFIX,instanthq.com,Proxy\nDOMAIN-SUFFIX,jadekwan.hk,Proxy\nDOMAIN-SUFFIX,asia-northeast1-saluton.cloudfunctions.net,Proxy\nDOMAIN-SUFFIX,toptip.ca,Proxy\nDOMAIN-SUFFIX,h.wha.la,Proxy\nDOMAIN-SUFFIX,www.5dm.app,Proxy\nDOMAIN-SUFFIX,digitalvspace.com,Proxy\nDOMAIN-SUFFIX,www.getrevue.co,Proxy\nDOMAIN-SUFFIX,chinatopsex.com,Proxy\nDOMAIN-SUFFIX,sbofa88.com,Proxy\nDOMAIN-SUFFIX,fw3.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,www.jav28.com,Proxy\nDOMAIN-SUFFIX,hotmai.us,Proxy\nDOMAIN-SUFFIX,washingtontimes.com,Proxy\nDOMAIN-SUFFIX,hiddendragon.site,Proxy\nDOMAIN-SUFFIX,www-bmc03.com,Proxy\nDOMAIN-SUFFIX,yuanzhengtang.org,Proxy\nDOMAIN-SUFFIX,sceadu.blog.shinobi.jp,Proxy\nDOMAIN-SUFFIX,playvid.com,Proxy\nDOMAIN-SUFFIX,picsart.com,Proxy\nDOMAIN-SUFFIX,web.pts.org.tw,Proxy\nDOMAIN-SUFFIX,cameratext.com,Proxy\nDOMAIN-SUFFIX,cissp.or.id,Proxy\nDOMAIN-SUFFIX,tor-exit-54.for-privacy.net,Proxy\nDOMAIN-SUFFIX,ping6.com,Proxy\nDOMAIN-SUFFIX,faith100.org,Proxy\nDOMAIN-SUFFIX,capezio.com,Proxy\nDOMAIN-SUFFIX,booksc.org,Proxy\nDOMAIN-SUFFIX,shadowsocksr.hk,Proxy\nDOMAIN-SUFFIX,www.bway881360.com,Proxy\nDOMAIN-SUFFIX,sujiatun.wordpress.com,Proxy\nDOMAIN-SUFFIX,18onlygirls.com,Proxy\nDOMAIN-SUFFIX,www.mondo64.com,Proxy\nDOMAIN-SUFFIX,quic.nginx.org,Proxy\nDOMAIN-SUFFIX,phayul.com,Proxy\nDOMAIN-SUFFIX,appbrain.com,Proxy\nDOMAIN-SUFFIX,ifunny.co,Proxy\nDOMAIN-SUFFIX,www.1pondo.tv,Proxy\nDOMAIN-SUFFIX,reuters.co.uk,Proxy\nDOMAIN-SUFFIX,hk.hacked.jp,Proxy\nDOMAIN-SUFFIX,chinaeforum.com,Proxy\nDOMAIN-SUFFIX,mingpaomonthly.com,Proxy\nDOMAIN-SUFFIX,www.navjot-singh.com,Proxy\nDOMAIN-SUFFIX,alexi.hu,Proxy\nDOMAIN-SUFFIX,pintrest.com,Proxy\nDOMAIN-SUFFIX,binancezh.io,Proxy\nDOMAIN-SUFFIX,www.gca-mining.com,Proxy\nDOMAIN-SUFFIX,w3z5q8a6.stackpathcdn.com,Proxy\nDOMAIN-SUFFIX,straitstimes.com,Proxy\nDOMAIN-SUFFIX,interharmony.com,Proxy\nDOMAIN-SUFFIX,177705555.com,Proxy\nDOMAIN-SUFFIX,facebook.com.tw,Proxy\nDOMAIN-SUFFIX,www.hj2966.com,Proxy\nDOMAIN-SUFFIX,www.truth-light.org.hk,Proxy\nDOMAIN-SUFFIX,d2b7lajjcl3dv8.cloudfront.net,Proxy\nDOMAIN-SUFFIX,sml.com,Proxy\nDOMAIN-SUFFIX,landofmedicinebuddha.org,Proxy\nDOMAIN-SUFFIX,www.studynb1.com,Proxy\nDOMAIN-SUFFIX,cloudmosa.com,Proxy\nDOMAIN-SUFFIX,d1.e86912e9.net,Proxy\nDOMAIN-SUFFIX,vatn.org,Proxy\nDOMAIN-SUFFIX,www.18qt.com,Proxy\nDOMAIN-SUFFIX,www.alconsrl.com,Proxy\nDOMAIN-SUFFIX,www.hostmonster.org,Proxy\nDOMAIN-SUFFIX,revolushii.ro,Proxy\nDOMAIN-SUFFIX,localytics.com,Proxy\nDOMAIN-SUFFIX,wn5988.com,Proxy\nDOMAIN-SUFFIX,257.ddnsking.com,Proxy\nDOMAIN-SUFFIX,proxy.org,Proxy\nDOMAIN-SUFFIX,www.merifet.net,Proxy\nDOMAIN-SUFFIX,indiandefensenews.in,Proxy\nDOMAIN-SUFFIX,chat.tool00.com,Proxy\nDOMAIN-SUFFIX,tecon.ro,Proxy\nDOMAIN-SUFFIX,jfqu36.club,Proxy\nDOMAIN-SUFFIX,worldsmileday.com,Proxy\nDOMAIN-SUFFIX,guild-site.com,Proxy\nDOMAIN-SUFFIX,livevideo.com,Proxy\nDOMAIN-SUFFIX,www.xpj123123.com,Proxy\nDOMAIN-SUFFIX,com.theeum.org,Proxy\nDOMAIN-SUFFIX,wdwoodworking.com,Proxy\nDOMAIN-SUFFIX,rfalive1.akacast.akamaistream.net,Proxy\nDOMAIN-SUFFIX,d29wm8dmhxnxqd.cloudfront.net,Proxy\nDOMAIN-SUFFIX,github.blog,Proxy\nDOMAIN-SUFFIX,www.newser.com,Proxy\nDOMAIN-SUFFIX,ca6699.com,Proxy\nDOMAIN-SUFFIX,www.proxicate.net,Proxy\nDOMAIN-SUFFIX,bigmoney.biz,Proxy\nDOMAIN-SUFFIX,www.al-islam.com,Proxy\nDOMAIN-SUFFIX,www.porniq.com,Proxy\nDOMAIN-SUFFIX,sanjeevkapoor.com,Proxy\nDOMAIN-SUFFIX,696988.xyz,Proxy\nDOMAIN-SUFFIX,deepmind.com,Proxy\nDOMAIN-SUFFIX,www.volksstimme.de,Proxy\nDOMAIN-SUFFIX,mamot.fr,Proxy\nDOMAIN-SUFFIX,hk1.pro.rixcloud.net,Proxy\nDOMAIN-SUFFIX,www.biza.com.tw,Proxy\nDOMAIN-SUFFIX,switch1.jp,Proxy\nDOMAIN-SUFFIX,dailyecho.co.uk,Proxy\nDOMAIN-SUFFIX,snapsave.io,Proxy\nDOMAIN-SUFFIX,d2s9m49id0uj1s.cloudfront.net,Proxy\nDOMAIN-SUFFIX,ys8805.com,Proxy\nDOMAIN-SUFFIX,server2.kproxy.com,Proxy\nDOMAIN-SUFFIX,rotten.com,Proxy\nDOMAIN-SUFFIX,voatibetan.org,Proxy\nDOMAIN-SUFFIX,06666b.com,Proxy\nDOMAIN-SUFFIX,www.mylife.hk,Proxy\nDOMAIN-SUFFIX,91thd.vip,Proxy\nDOMAIN-SUFFIX,8587u.cc,Proxy\nDOMAIN-SUFFIX,50352.5lxtv.com,Proxy\nDOMAIN-SUFFIX,btbtav.com,Proxy\nDOMAIN-SUFFIX,songyy123.com,Proxy\nDOMAIN-SUFFIX,medley.com,Proxy\nDOMAIN-SUFFIX,www.rheinpfalz.de,Proxy\nDOMAIN-SUFFIX,tjc.org,Proxy\nDOMAIN-SUFFIX,youthnetradio.org,Proxy\nDOMAIN-SUFFIX,38850088.com,Proxy\nDOMAIN-SUFFIX,86857.vip,Proxy\nDOMAIN-SUFFIX,novelai.net,Proxy\nDOMAIN-SUFFIX,graeleah.com,Proxy\nDOMAIN-SUFFIX,usfk.mil,Proxy\nDOMAIN-SUFFIX,d2kp122tm3b3cb.cloudfront.net,Proxy\nDOMAIN-SUFFIX,d2gi67xmfj8wai.cloudfront.net,Proxy\nDOMAIN-SUFFIX,bryce.ws,Proxy\nDOMAIN-SUFFIX,gigacircle.com,Proxy\nDOMAIN-SUFFIX,ai.binwang.me,Proxy\nDOMAIN-SUFFIX,sevpn.com,Proxy\nDOMAIN-SUFFIX,sjg007.com,Proxy\nDOMAIN-SUFFIX,www.christianpost.com,Proxy\nDOMAIN-SUFFIX,www.bminews.net,Proxy\nDOMAIN-SUFFIX,lgbtx.com,Proxy\nDOMAIN-SUFFIX,42842806.com,Proxy\nDOMAIN-SUFFIX,duckload.com,Proxy\nDOMAIN-SUFFIX,pexv.xyz,Proxy\nDOMAIN-SUFFIX,yulghun.com,Proxy\nDOMAIN-SUFFIX,theintercept.org,Proxy\nDOMAIN-SUFFIX,ipvanish.com,Proxy\nDOMAIN-SUFFIX,solografika.co.id,Proxy\nDOMAIN-SUFFIX,pkp.pl,Proxy\nDOMAIN-SUFFIX,www.ilove-blog-you.com,Proxy\nDOMAIN-SUFFIX,www.webproxyfree.net,Proxy\nDOMAIN-SUFFIX,w.boxc.pro,Proxy\nDOMAIN-SUFFIX,www.proxybutton.com,Proxy\nDOMAIN-SUFFIX,yeelou.com,Proxy\nDOMAIN-SUFFIX,iqq.life,Proxy\nDOMAIN-SUFFIX,fff36.net,Proxy\nDOMAIN-SUFFIX,wasted.id.lv,Proxy\nDOMAIN-SUFFIX,www.jd888.ws,Proxy\nDOMAIN-SUFFIX,get.page,Proxy\nDOMAIN-SUFFIX,tweetboner.biz,Proxy\nDOMAIN-SUFFIX,roboforexcn.org,Proxy\nDOMAIN-SUFFIX,www.tibetaans-instituut.org,Proxy\nDOMAIN-SUFFIX,www.sosick.org,Proxy\nDOMAIN-SUFFIX,open.spotifycdn.com,Proxy\nDOMAIN-SUFFIX,homecine.be,Proxy\nDOMAIN-SUFFIX,www.sijihuisuo.com,Proxy\nDOMAIN-SUFFIX,apk.ccgalaxylab.club,Proxy\nDOMAIN-SUFFIX,hb88vn.com,Proxy\nDOMAIN-SUFFIX,www.freedomnfly.net,Proxy\nDOMAIN-SUFFIX,postadult.com,Proxy\nDOMAIN-SUFFIX,mstdn.jp,Proxy\nDOMAIN-SUFFIX,101newsmedia.com,Proxy\nDOMAIN-SUFFIX,memri.org,Proxy\nDOMAIN-SUFFIX,adultkeep.net,Proxy\nDOMAIN-SUFFIX,kingss.top,Proxy\nDOMAIN-SUFFIX,p6629.com,Proxy\nDOMAIN-SUFFIX,9269av.co,Proxy\nDOMAIN-SUFFIX,d1hjdlu08v409i.cloudfront.net,Proxy\nDOMAIN-SUFFIX,sjy002.jigsy.com,Proxy\nDOMAIN-SUFFIX,tubeon.com,Proxy\nDOMAIN-SUFFIX,www.06966a.com,Proxy\nDOMAIN-SUFFIX,yh0108.com,Proxy\nDOMAIN-SUFFIX,gaialovescock.cammodels.com,Proxy\nDOMAIN-SUFFIX,duyaossr.com,Proxy\nDOMAIN-SUFFIX,whore.net,Proxy\nDOMAIN-SUFFIX,www.s36.com,Proxy\nDOMAIN-SUFFIX,f5577.com,Proxy\nDOMAIN-SUFFIX,health2.pro,Proxy\nDOMAIN-SUFFIX,d2chji0cyzopah.cloudfront.net,Proxy\nDOMAIN-SUFFIX,unblock123.com,Proxy\nDOMAIN-SUFFIX,pmpfilms.com,Proxy\nDOMAIN-SUFFIX,coinmarketcap.com,Proxy\nDOMAIN-SUFFIX,www.thestar.ca,Proxy\nDOMAIN-SUFFIX,tibettimes.com,Proxy\nDOMAIN-SUFFIX,foreignpolicy.com,Proxy\nDOMAIN-SUFFIX,4887.com,Proxy\nDOMAIN-SUFFIX,app.tv333.us,Proxy\nDOMAIN-SUFFIX,wearehairy.com,Proxy\nDOMAIN-SUFFIX,bookoffonline.co.jp,Proxy\nDOMAIN-SUFFIX,ranyunfei.com,Proxy\nDOMAIN-SUFFIX,blog.lishun.me,Proxy\nDOMAIN-SUFFIX,flnet.org,Proxy\nDOMAIN-SUFFIX,haileshe.club,Proxy\nDOMAIN-SUFFIX,arch.nqu.edu.tw,Proxy\nDOMAIN-SUFFIX,jmcomic2.love,Proxy\nDOMAIN-SUFFIX,marsbar.org.uk,Proxy\nDOMAIN-SUFFIX,bestvpnservice.com,Proxy\nDOMAIN-SUFFIX,atdmt.com,Proxy\nDOMAIN-SUFFIX,ac.bot.nu,Proxy\nDOMAIN-SUFFIX,askjelly.com,Proxy\nDOMAIN-SUFFIX,cubiccm.ddns.net,Proxy\nDOMAIN-SUFFIX,nord-for-apps.com,Proxy\nDOMAIN-SUFFIX,kshealthjobs.net,Proxy\nDOMAIN-SUFFIX,england.fm,Proxy\nDOMAIN-SUFFIX,www.apvc.com,Proxy\nDOMAIN-SUFFIX,changeip.net,Proxy\nDOMAIN-SUFFIX,jupiterns.org,Proxy\nDOMAIN-SUFFIX,www.8090789.com,Proxy\nDOMAIN-SUFFIX,tehrantimes.com,Proxy\nDOMAIN-SUFFIX,zh.1lib.tw,Proxy\nDOMAIN-SUFFIX,tehelka.com,Proxy\nDOMAIN-SUFFIX,hmoegirl.com,Proxy\nDOMAIN-SUFFIX,v2cross.com,Proxy\nDOMAIN-SUFFIX,zh.wikipedia.aufe.cf,Proxy\nDOMAIN-SUFFIX,xw88.pro,Proxy\nDOMAIN-SUFFIX,www.fq123.biz,Proxy\nDOMAIN-SUFFIX,ff97.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,www.cdns.com.tw,Proxy\nDOMAIN-SUFFIX,theportalwiki.com,Proxy\nDOMAIN-SUFFIX,excellencehealth.org,Proxy\nDOMAIN-SUFFIX,dns.switch.ch,Proxy\nDOMAIN-SUFFIX,embr.in,Proxy\nDOMAIN-SUFFIX,hj985.com,Proxy\nDOMAIN-SUFFIX,seattlefdc.com,Proxy\nDOMAIN-SUFFIX,www.ca772.com,Proxy\nDOMAIN-SUFFIX,www.vg76g.com,Proxy\nDOMAIN-SUFFIX,www.wyt002.xyz,Proxy\nDOMAIN-SUFFIX,blog.itgonglun.com,Proxy\nDOMAIN-SUFFIX,wanglixiong.com,Proxy\nDOMAIN-SUFFIX,www.e8388.com,Proxy\nDOMAIN-SUFFIX,sunwinism.joinbbs.net,Proxy\nDOMAIN-SUFFIX,retweeteffect.com,Proxy\nDOMAIN-SUFFIX,islamicpluralism.org,Proxy\nDOMAIN-SUFFIX,chinapress.com.my,Proxy\nDOMAIN-SUFFIX,www.hotav.tv,Proxy\nDOMAIN-SUFFIX,cnvalues.github.io,Proxy\nDOMAIN-SUFFIX,hardtied.com,Proxy\nDOMAIN-SUFFIX,redditblog.com,Proxy\nDOMAIN-SUFFIX,minzhuzhongguo.org,Proxy\nDOMAIN-SUFFIX,cdn.statically.io,Proxy\nDOMAIN-SUFFIX,www.redtube.org,Proxy\nDOMAIN-SUFFIX,www.yzc1188.com,Proxy\nDOMAIN-SUFFIX,woodrocket.com,Proxy\nDOMAIN-SUFFIX,www.ibcn.xyz,Proxy\nDOMAIN-SUFFIX,xj906.com,Proxy\nDOMAIN-SUFFIX,meetme.com,Proxy\nDOMAIN-SUFFIX,google.im,Proxy\nDOMAIN-SUFFIX,experiments.withgoogle.com,Proxy\nDOMAIN-SUFFIX,www.xinbi002.com,Proxy\nDOMAIN-SUFFIX,66993885.com,Proxy\nDOMAIN-SUFFIX,schoolasiagirls.net,Proxy\nDOMAIN-SUFFIX,lflinkup.net,Proxy\nDOMAIN-SUFFIX,baabao.com,Proxy\nDOMAIN-SUFFIX,afvpn.com,Proxy\nDOMAIN-SUFFIX,www.dyvip983.com,Proxy\nDOMAIN-SUFFIX,google.com.bo,Proxy\nDOMAIN-SUFFIX,eogli.org,Proxy\nDOMAIN-SUFFIX,pornolab.net,Proxy\nDOMAIN-SUFFIX,www.1616bbs.com,Proxy\nDOMAIN-SUFFIX,hotdh.xyz,Proxy\nDOMAIN-SUFFIX,www.jeffo.net,Proxy\nDOMAIN-SUFFIX,notube.lol,Proxy\nDOMAIN-SUFFIX,yourownvpn.com,Proxy\nDOMAIN-SUFFIX,www.lithgowmercury.com.au,Proxy\nDOMAIN-SUFFIX,www.luxresearchinc.com,Proxy\nDOMAIN-SUFFIX,www.googlesciencefair.com,Proxy\nDOMAIN-SUFFIX,bangbros.com,Proxy\nDOMAIN-SUFFIX,4000byb.com,Proxy\nDOMAIN-SUFFIX,vpn.net,Proxy\nDOMAIN-SUFFIX,kichiku.tv,Proxy\nDOMAIN-SUFFIX,www.sundayguardianlive.com,Proxy\nDOMAIN-SUFFIX,hide.io,Proxy\nDOMAIN-SUFFIX,ieasynews.com,Proxy\nDOMAIN-SUFFIX,ups.com,Proxy\nDOMAIN-SUFFIX,www.ca872.com,Proxy\nDOMAIN-SUFFIX,www.qiqidongman.com,Proxy\nDOMAIN-SUFFIX,chinmaya.com.au,Proxy\nDOMAIN-SUFFIX,99999.suroot.com,Proxy\nDOMAIN-SUFFIX,googleearth.com,Proxy\nDOMAIN-SUFFIX,htmlbook.ru,Proxy\nDOMAIN-SUFFIX,myoutube.com,Proxy\nDOMAIN-SUFFIX,deaobni15v34x.cloudfront.net,Proxy\nDOMAIN-SUFFIX,7765ee.com,Proxy\nDOMAIN-SUFFIX,favotter.net,Proxy\nDOMAIN-SUFFIX,tx.me,Proxy\nDOMAIN-SUFFIX,chinesenewyear.withgoogle.com,Proxy\nDOMAIN-SUFFIX,www.tibetnewsonline.com,Proxy\nDOMAIN-SUFFIX,michaelmarketl.com,Proxy\nDOMAIN-SUFFIX,improv4business.com,Proxy\nDOMAIN-SUFFIX,sign-in-o365.azureedge.net,Proxy\nDOMAIN-SUFFIX,www.jokerlu.asia,Proxy\nDOMAIN-SUFFIX,psblog.name,Proxy\nDOMAIN-SUFFIX,us-central1-nightcafe-creator.cloudfunctions.net,Proxy\nDOMAIN-SUFFIX,newspaperdirect.com,Proxy\nDOMAIN-SUFFIX,solidtorrents.to,Proxy\nDOMAIN-SUFFIX,vpnarea.com,Proxy\nDOMAIN-SUFFIX,altop.vn,Proxy\nDOMAIN-SUFFIX,badoo.com,Proxy\nDOMAIN-SUFFIX,mingming.com.au,Proxy\nDOMAIN-SUFFIX,parse.com,Proxy\nDOMAIN-SUFFIX,bbs.1tor.com,Proxy\nDOMAIN-SUFFIX,cs013.com,Proxy\nDOMAIN-SUFFIX,homeservershow.com,Proxy\nDOMAIN-SUFFIX,galaxyentertainment.com,Proxy\nDOMAIN-SUFFIX,homeunix.org,Proxy\nDOMAIN-SUFFIX,www.hbzyc0722.com,Proxy\nDOMAIN-SUFFIX,hentai.to,Proxy\nDOMAIN-SUFFIX,247.slyip.net,Proxy\nDOMAIN-SUFFIX,simplicus.se,Proxy\nDOMAIN-SUFFIX,etoro.com.cn,Proxy\nDOMAIN-SUFFIX,www.liisex.com,Proxy\nDOMAIN-SUFFIX,dontblockme.org,Proxy\nDOMAIN-SUFFIX,d7rme1d99gjjk.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.991c8.com,Proxy\nDOMAIN-SUFFIX,www.51fanqiang.com,Proxy\nDOMAIN-SUFFIX,fyoutube.com,Proxy\nDOMAIN-SUFFIX,rightbtc.com,Proxy\nDOMAIN-SUFFIX,zenra.net,Proxy\nDOMAIN-SUFFIX,proxylistpro.com,Proxy\nDOMAIN-SUFFIX,ilovexjp.netlify.app,Proxy\nDOMAIN-SUFFIX,jihadintel.meforum.org,Proxy\nDOMAIN-SUFFIX,www.hongkongherald.com,Proxy\nDOMAIN-SUFFIX,39.podzone.org,Proxy\nDOMAIN-SUFFIX,at.or.at,Proxy\nDOMAIN-SUFFIX,234222.cc,Proxy\nDOMAIN-SUFFIX,videoedit.cna.com.tw,Proxy\nDOMAIN-SUFFIX,lib-oym5w4uqqtemzvl6j5tmtzdk.resist.tel,Proxy\nDOMAIN-SUFFIX,hrntt.org,Proxy\nDOMAIN-SUFFIX,vuku.cc,Proxy\nDOMAIN-SUFFIX,ipcamouflage.com,Proxy\nDOMAIN-SUFFIX,www.thinkstockphotos.it,Proxy\nDOMAIN-SUFFIX,jm-comic1.xyz,Proxy\nDOMAIN-SUFFIX,keandra.com,Proxy\nDOMAIN-SUFFIX,bookzone.cwgv.com.tw,Proxy\nDOMAIN-SUFFIX,rideexpress.com,Proxy\nDOMAIN-SUFFIX,igogo.ca,Proxy\nDOMAIN-SUFFIX,jacklatiao.top,Proxy\nDOMAIN-SUFFIX,skillfeed.com,Proxy\nDOMAIN-SUFFIX,qyule.tv,Proxy\nDOMAIN-SUFFIX,javhip.com,Proxy\nDOMAIN-SUFFIX,nitter.bus-hit.me,Proxy\nDOMAIN-SUFFIX,blog.orph.eu,Proxy\nDOMAIN-SUFFIX,fengshui-magazine.com.hk,Proxy\nDOMAIN-SUFFIX,b.wxga.us,Proxy\nDOMAIN-SUFFIX,9p998.com,Proxy\nDOMAIN-SUFFIX,weisuo.ws,Proxy\nDOMAIN-SUFFIX,music.monstercat.com,Proxy\nDOMAIN-SUFFIX,vw112.com,Proxy\nDOMAIN-SUFFIX,twhentai.com,Proxy\nDOMAIN-SUFFIX,www.loccidentale.it,Proxy\nDOMAIN-SUFFIX,www.gonzalezdeotoya.com,Proxy\nDOMAIN-SUFFIX,www.africanews.com,Proxy\nDOMAIN-SUFFIX,poloniex.com,Proxy\nDOMAIN-SUFFIX,v2ray.com,Proxy\nDOMAIN-SUFFIX,hybssr.org,Proxy\nDOMAIN-SUFFIX,lens.hk,Proxy\nDOMAIN-SUFFIX,hmavpn.com,Proxy\nDOMAIN-SUFFIX,cmi.org.tw,Proxy\nDOMAIN-SUFFIX,finchvpn.com,Proxy\nDOMAIN-SUFFIX,mondediplo.com,Proxy\nDOMAIN-SUFFIX,googlezip.net,Proxy\nDOMAIN-SUFFIX,dio168.cd77.net,Proxy\nDOMAIN-SUFFIX,miamidade.gov,Proxy\nDOMAIN-SUFFIX,edupro.org,Proxy\nDOMAIN-SUFFIX,chouza.com.ar,Proxy\nDOMAIN-SUFFIX,souleader-tw.strikingly.com,Proxy\nDOMAIN-SUFFIX,hecaitou.net,Proxy\nDOMAIN-SUFFIX,api.threema.ch,Proxy\nDOMAIN-SUFFIX,sendspace.com,Proxy\nDOMAIN-SUFFIX,parsevideo.com,Proxy\nDOMAIN-SUFFIX,zmw.cn,Proxy\nDOMAIN-SUFFIX,www.narrominenewsonline.com.au,Proxy\nDOMAIN-SUFFIX,merlinblog.xyz,Proxy\nDOMAIN-SUFFIX,www.taiwanbible.com,Proxy\nDOMAIN-SUFFIX,utsandiego.com,Proxy\nDOMAIN-SUFFIX,rileyguide.com,Proxy\nDOMAIN-SUFFIX,www.inty3000.com,Proxy\nDOMAIN-SUFFIX,www.andrewchristian.com,Proxy\nDOMAIN-SUFFIX,mcs-va-useast2a.tiktokv.com-1,Proxy\nDOMAIN-SUFFIX,epochtimes.co.kr,Proxy\nDOMAIN-SUFFIX,simpleproductivityblog.com,Proxy\nDOMAIN-SUFFIX,www.chromes.cn,Proxy\nDOMAIN-SUFFIX,old-cat.net,Proxy\nDOMAIN-SUFFIX,hhhbook.com,Proxy\nDOMAIN-SUFFIX,fu8.me,Proxy\nDOMAIN-SUFFIX,subhd.com,Proxy\nDOMAIN-SUFFIX,leecheukyan.org,Proxy\nDOMAIN-SUFFIX,goldwave.com,Proxy\nDOMAIN-SUFFIX,tor-exit-47.for-privacy.net,Proxy\nDOMAIN-SUFFIX,videomega.tv,Proxy\nDOMAIN-SUFFIX,www.7777989.net,Proxy\nDOMAIN-SUFFIX,proxyness.com,Proxy\nDOMAIN-SUFFIX,www.494hu.com,Proxy\nDOMAIN-SUFFIX,paimon.moe,Proxy\nDOMAIN-SUFFIX,twelveweb.com,Proxy\nDOMAIN-SUFFIX,28.flnet.org,Proxy\nDOMAIN-SUFFIX,d2tdibg1u2lrg7.cloudfront.net,Proxy\nDOMAIN-SUFFIX,8040.com,Proxy\nDOMAIN-SUFFIX,nuezhilian.com,Proxy\nDOMAIN-SUFFIX,wwvpn.com,Proxy\nDOMAIN-SUFFIX,yts.mx,Proxy\nDOMAIN-SUFFIX,ctunnel.com,Proxy\nDOMAIN-SUFFIX,theladbible.com,Proxy\nDOMAIN-SUFFIX,hotav.tv,Proxy\nDOMAIN-SUFFIX,me.youthwant.com.tw,Proxy\nDOMAIN-SUFFIX,www.jathao.com,Proxy\nDOMAIN-SUFFIX,cn6.eu,Proxy\nDOMAIN-SUFFIX,libreddit.bus-hit.me,Proxy\nDOMAIN-SUFFIX,69avschool.com,Proxy\nDOMAIN-SUFFIX,8587h.cc,Proxy\nDOMAIN-SUFFIX,unblockyoutube.co,Proxy\nDOMAIN-SUFFIX,www.db458.com,Proxy\nDOMAIN-SUFFIX,hrf.org,Proxy\nDOMAIN-SUFFIX,javdove.com,Proxy\nDOMAIN-SUFFIX,wmkredit.ru,Proxy\nDOMAIN-SUFFIX,mediatemple.net,Proxy\nDOMAIN-SUFFIX,30520k.com,Proxy\nDOMAIN-SUFFIX,upiasia.com,Proxy\nDOMAIN-SUFFIX,www.gravure.com,Proxy\nDOMAIN-SUFFIX,us1.vpnme.me,Proxy\nDOMAIN-SUFFIX,ciprianman.net,Proxy\nDOMAIN-SUFFIX,se.bv39.pw,Proxy\nDOMAIN-SUFFIX,masto.ai,Proxy\nDOMAIN-SUFFIX,fhcrc.org,Proxy\nDOMAIN-SUFFIX,hkwesi111.xyz,Proxy\nDOMAIN-SUFFIX,kinmirai.dojin.com,Proxy\nDOMAIN-SUFFIX,imastodon.net,Proxy\nDOMAIN-SUFFIX,www.internationalschool.com,Proxy\nDOMAIN-SUFFIX,sagemath.org,Proxy\nDOMAIN-SUFFIX,oldip.asuscomm.com,Proxy\nDOMAIN-SUFFIX,facebook.pl,Proxy\nDOMAIN-SUFFIX,www.gb300.com,Proxy\nDOMAIN-SUFFIX,d377td6kcri7un.cloudfront.net,Proxy\nDOMAIN-SUFFIX,byt090.com,Proxy\nDOMAIN-SUFFIX,hggard.com,Proxy\nDOMAIN-SUFFIX,www.forextime.com,Proxy\nDOMAIN-SUFFIX,mmgal.com,Proxy\nDOMAIN-SUFFIX,www.ishadowsocks.biz,Proxy\nDOMAIN-SUFFIX,www.herald.ie,Proxy\nDOMAIN-SUFFIX,www.krisflyer.com,Proxy\nDOMAIN-SUFFIX,internetarchive.org,Proxy\nDOMAIN-SUFFIX,euk.slyip.net,Proxy\nDOMAIN-SUFFIX,ivacy.com,Proxy\nDOMAIN-SUFFIX,sjrt.org,Proxy\nDOMAIN-SUFFIX,yb.freepac.pw,Proxy\nDOMAIN-SUFFIX,mychinanet.com,Proxy\nDOMAIN-SUFFIX,www.gettyimages.de,Proxy\nDOMAIN-SUFFIX,www.taiwanhrj.org,Proxy\nDOMAIN-SUFFIX,www.zzwav.com,Proxy\nDOMAIN-SUFFIX,dmm.co.jp,Proxy\nDOMAIN-SUFFIX,astrology-zodiac-signs.com,Proxy\nDOMAIN-SUFFIX,www.bway981.com,Proxy\nDOMAIN-SUFFIX,bnf7.ras.flnet.org,Proxy\nDOMAIN-SUFFIX,uuc.slyip.com,Proxy\nDOMAIN-SUFFIX,www.h0930.com,Proxy\nDOMAIN-SUFFIX,oceanex.pro,Proxy\nDOMAIN-SUFFIX,bannedyoutube.com,Proxy\nDOMAIN-SUFFIX,www.latercera.com,Proxy\nDOMAIN-SUFFIX,xcdl6.com,Proxy\nDOMAIN-SUFFIX,pornfidelity.com,Proxy\nDOMAIN-SUFFIX,www.jbo090.com,Proxy\nDOMAIN-SUFFIX,artcomix.com,Proxy\nDOMAIN-SUFFIX,app.pingme.tel,Proxy\nDOMAIN-SUFFIX,ceec.cf,Proxy\nDOMAIN-SUFFIX,www.firstpost.com,Proxy\nDOMAIN-SUFFIX,72.bot.nu,Proxy\nDOMAIN-SUFFIX,cactusvpn.com,Proxy\nDOMAIN-SUFFIX,297.quantumidiot.com,Proxy\nDOMAIN-SUFFIX,63.slyip.net,Proxy\nDOMAIN-SUFFIX,dizhidizhi.com,Proxy\nDOMAIN-SUFFIX,63oo.net,Proxy\nDOMAIN-SUFFIX,www.skin79china.com,Proxy\nDOMAIN-SUFFIX,7377cc.com,Proxy\nDOMAIN-SUFFIX,thesafety.us,Proxy\nDOMAIN-SUFFIX,www.w88top.com,Proxy\nDOMAIN-SUFFIX,www.coinegg.com,Proxy\nDOMAIN-SUFFIX,hexieshe.com,Proxy\nDOMAIN-SUFFIX,mirai.ca,Proxy\nDOMAIN-SUFFIX,fakku.cc,Proxy\nDOMAIN-SUFFIX,fun8886.com,Proxy\nDOMAIN-SUFFIX,kannewyork.com,Proxy\nDOMAIN-SUFFIX,avemaria.cl,Proxy\nDOMAIN-SUFFIX,home.mihk.tv,Proxy\nDOMAIN-SUFFIX,www.lama.com.tw,Proxy\nDOMAIN-SUFFIX,proxifier.com,Proxy\nDOMAIN-SUFFIX,fofg.org,Proxy\nDOMAIN-SUFFIX,www.rmjdw.302.com,Proxy\nDOMAIN-SUFFIX,novavpn.com,Proxy\nDOMAIN-SUFFIX,asianclassics.org,Proxy\nDOMAIN-SUFFIX,baixaki.com.br,Proxy\nDOMAIN-SUFFIX,66.effers.com,Proxy\nDOMAIN-SUFFIX,relaxbbs.com,Proxy\nDOMAIN-SUFFIX,msha.gov,Proxy\nDOMAIN-SUFFIX,fuckccp.com,Proxy\nDOMAIN-SUFFIX,javdb009.com,Proxy\nDOMAIN-SUFFIX,www.alwaysvpn.com,Proxy\nDOMAIN-SUFFIX,zenyatrading.co.za,Proxy\nDOMAIN-SUFFIX,invidious.snopyta.org,Proxy\nDOMAIN-SUFFIX,us-central1-glaring-fire-4035.cloudfunctions.net,Proxy\nDOMAIN-SUFFIX,www.dorceltv.com,Proxy\nDOMAIN-SUFFIX,posts.careerengine.us,Proxy\nDOMAIN-SUFFIX,www.ottlite.com,Proxy\nDOMAIN-SUFFIX,www.oasisnetwork.org,Proxy\nDOMAIN-SUFFIX,social.kyaru.xyz,Proxy\nDOMAIN-SUFFIX,www.ericsson.com,Proxy\nDOMAIN-SUFFIX,owvpn.com,Proxy\nDOMAIN-SUFFIX,virtualrealporn.com,Proxy\nDOMAIN-SUFFIX,www.aiuu2.org,Proxy\nDOMAIN-SUFFIX,kuaishangche.club,Proxy\nDOMAIN-SUFFIX,dmc.nico,Proxy\nDOMAIN-SUFFIX,hrcir.com,Proxy\nDOMAIN-SUFFIX,bigtitsboss.com,Proxy\nDOMAIN-SUFFIX,anonymous-proxies.net,Proxy\nDOMAIN-SUFFIX,www.ssrcloud.com,Proxy\nDOMAIN-SUFFIX,www.vapingdirect.com,Proxy\nDOMAIN-SUFFIX,www.post.ly,Proxy\nDOMAIN-SUFFIX,servehttp.com,Proxy\nDOMAIN-SUFFIX,classmate.dcard.gift,Proxy\nDOMAIN-SUFFIX,smarter.co.jp,Proxy\nDOMAIN-SUFFIX,www.freelancer.ca,Proxy\nDOMAIN-SUFFIX,www.youtube.com.sg,Proxy\nDOMAIN-SUFFIX,www.cafun88.com,Proxy\nDOMAIN-SUFFIX,holyspiritspeaks.org,Proxy\nDOMAIN-SUFFIX,savvyfox.com,Proxy\nDOMAIN-SUFFIX,weblinkmedia.com,Proxy\nDOMAIN-SUFFIX,ok775.com,Proxy\nDOMAIN-SUFFIX,orchid.com,Proxy\nDOMAIN-SUFFIX,wanyepu.com,Proxy\nDOMAIN-SUFFIX,9news.com.au,Proxy\nDOMAIN-SUFFIX,worldpay.com,Proxy\nDOMAIN-SUFFIX,recordedfuture.com,Proxy\nDOMAIN-SUFFIX,putlocker.com,Proxy\nDOMAIN-SUFFIX,newsblog.chinatimes.com,Proxy\nDOMAIN-SUFFIX,www.avsex8.com,Proxy\nDOMAIN-SUFFIX,timesofoman.com,Proxy\nDOMAIN-SUFFIX,videobox.com,Proxy\nDOMAIN-SUFFIX,www.qingfengshenzhen.com,Proxy\nDOMAIN-SUFFIX,d34kq9ecg4rzxm.cloudfront.net,Proxy\nDOMAIN-SUFFIX,bullvpn.com,Proxy\nDOMAIN-SUFFIX,www.blintl.com,Proxy\nDOMAIN-SUFFIX,static-economist.com,Proxy\nDOMAIN-SUFFIX,cfaktor.com,Proxy\nDOMAIN-SUFFIX,gx.com,Proxy\nDOMAIN-SUFFIX,tushyraw.com,Proxy\nDOMAIN-SUFFIX,d2za9gczo4qgp5.cloudfront.net,Proxy\nDOMAIN-SUFFIX,kukuku.uk,Proxy\nDOMAIN-SUFFIX,wwx.idv.tw,Proxy\nDOMAIN-SUFFIX,tweetvalue.com,Proxy\nDOMAIN-SUFFIX,tosh.comedycentral.com,Proxy\nDOMAIN-SUFFIX,ph689.com,Proxy\nDOMAIN-SUFFIX,chatous.com,Proxy\nDOMAIN-SUFFIX,purolatinas.com,Proxy\nDOMAIN-SUFFIX,my.opera.com,Proxy\nDOMAIN-SUFFIX,bc2588.com,Proxy\nDOMAIN-SUFFIX,proxyzan.pw,Proxy\nDOMAIN-SUFFIX,tibetjustice.org,Proxy\nDOMAIN-SUFFIX,www.voaradiogram.net,Proxy\nDOMAIN-SUFFIX,faz.net,Proxy\nDOMAIN-SUFFIX,b3561.com,Proxy\nDOMAIN-SUFFIX,spring4u.info,Proxy\nDOMAIN-SUFFIX,firecams.com,Proxy\nDOMAIN-SUFFIX,gobet.cc,Proxy\nDOMAIN-SUFFIX,www.sng.idv.tw,Proxy\nDOMAIN-SUFFIX,steveeagle.com,Proxy\nDOMAIN-SUFFIX,53.gs,Proxy\nDOMAIN-SUFFIX,www.googletamanager.com,Proxy\nDOMAIN-SUFFIX,free.gfw.im,Proxy\nDOMAIN-SUFFIX,grigio.org,Proxy\nDOMAIN-SUFFIX,pda.giuffre.it,Proxy\nDOMAIN-SUFFIX,getlittlefox.com,Proxy\nDOMAIN-SUFFIX,www.youtube.com.au,Proxy\nDOMAIN-SUFFIX,7686592.com,Proxy\nDOMAIN-SUFFIX,rank.18-sex.us,Proxy\nDOMAIN-SUFFIX,edmimg.airasia.com,Proxy\nDOMAIN-SUFFIX,www.bloglovin.com,Proxy\nDOMAIN-SUFFIX,artchina.tw,Proxy\nDOMAIN-SUFFIX,fgmtv.org,Proxy\nDOMAIN-SUFFIX,yzc191.com,Proxy\nDOMAIN-SUFFIX,www.prhk.org,Proxy\nDOMAIN-SUFFIX,wbc.com,Proxy\nDOMAIN-SUFFIX,www.mathland.idv.tw,Proxy\nDOMAIN-SUFFIX,shersingh.com,Proxy\nDOMAIN-SUFFIX,www.goregrish.com,Proxy\nDOMAIN-SUFFIX,byb00.app,Proxy\nDOMAIN-SUFFIX,iclover.cf,Proxy\nDOMAIN-SUFFIX,facebookmarketingpartners.com,Proxy\nDOMAIN-SUFFIX,piko.live,Proxy\nDOMAIN-SUFFIX,bj-in-f90.1e100.net,Proxy\nDOMAIN-SUFFIX,amzn.to,Proxy\nDOMAIN-SUFFIX,www.tamus.edu,Proxy\nDOMAIN-SUFFIX,ganges.com,Proxy\nDOMAIN-SUFFIX,ddockslounge.com,Proxy\nDOMAIN-SUFFIX,usercenter.firemon.com,Proxy\nDOMAIN-SUFFIX,mastodon.ie,Proxy\nDOMAIN-SUFFIX,public.slidesharecdn.com,Proxy\nDOMAIN-SUFFIX,sexart.com,Proxy\nDOMAIN-SUFFIX,jbo8.com,Proxy\nDOMAIN-SUFFIX,boxun4.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,ka-wai.com,Proxy\nDOMAIN-SUFFIX,my.uwf.edu,Proxy\nDOMAIN-SUFFIX,www.lucrorfx.org,Proxy\nDOMAIN-SUFFIX,duuirrz9yev8b.cloudfront.net,Proxy\nDOMAIN-SUFFIX,lunaluna.org,Proxy\nDOMAIN-SUFFIX,reuters.com,Proxy\nDOMAIN-SUFFIX,www.lrytas.lt,Proxy\nDOMAIN-SUFFIX,onsiris.net,Proxy\nDOMAIN-SUFFIX,www.scmpchinese.com,Proxy\nDOMAIN-SUFFIX,www.meltoday.com,Proxy\nDOMAIN-SUFFIX,www.xfanz.com,Proxy\nDOMAIN-SUFFIX,roboforexcn.com,Proxy\nDOMAIN-SUFFIX,www.edu-infinity.org,Proxy\nDOMAIN-SUFFIX,23.slyip.net,Proxy\nDOMAIN-SUFFIX,anta888.com,Proxy\nDOMAIN-SUFFIX,www.simbolostwitter.com,Proxy\nDOMAIN-SUFFIX,himachal.nic.in,Proxy\nDOMAIN-SUFFIX,www.express.co.uk,Proxy\nDOMAIN-SUFFIX,qqi.com.tw,Proxy\nDOMAIN-SUFFIX,www.politico.eu,Proxy\nDOMAIN-SUFFIX,gustavoalvarez.com,Proxy\nDOMAIN-SUFFIX,womany.net,Proxy\nDOMAIN-SUFFIX,www.browsercam.com,Proxy\nDOMAIN-SUFFIX,www.carroll.k12.ia.us,Proxy\nDOMAIN-SUFFIX,yc6354.com,Proxy\nDOMAIN-SUFFIX,gunsandammo.com,Proxy\nDOMAIN-SUFFIX,cocm.org.uk,Proxy\nDOMAIN-SUFFIX,justmysocks.net,Proxy\nDOMAIN-SUFFIX,wc2a.yay.3d-game.com,Proxy\nDOMAIN-SUFFIX,muare.vn,Proxy\nDOMAIN-SUFFIX,rangzen.org,Proxy\nDOMAIN-SUFFIX,www.madou.la,Proxy\nDOMAIN-SUFFIX,7capture.com,Proxy\nDOMAIN-SUFFIX,www2.jiji.com,Proxy\nDOMAIN-SUFFIX,www.familyusercacdc61396.top,Proxy\nDOMAIN-SUFFIX,huobi.tf,Proxy\nDOMAIN-SUFFIX,zhao.1984.city,Proxy\nDOMAIN-SUFFIX,xskywalker.com,Proxy\nDOMAIN-SUFFIX,edwork.net,Proxy\nDOMAIN-SUFFIX,nord-in-cn.org,Proxy\nDOMAIN-SUFFIX,kanzhongguo.com,Proxy\nDOMAIN-SUFFIX,flickriver.com,Proxy\nDOMAIN-SUFFIX,www.imsystem.site,Proxy\nDOMAIN-SUFFIX,www.karmapa.org.nz,Proxy\nDOMAIN-SUFFIX,cdn.ub8.com,Proxy\nDOMAIN-SUFFIX,filesor.com,Proxy\nDOMAIN-SUFFIX,uygurlar.org,Proxy\nDOMAIN-SUFFIX,democrats.org,Proxy\nDOMAIN-SUFFIX,iingles.cl,Proxy\nDOMAIN-SUFFIX,kknews.cc,Proxy\nDOMAIN-SUFFIX,geektown.cn,Proxy\nDOMAIN-SUFFIX,982.flnet.org,Proxy\nDOMAIN-SUFFIX,710333.com,Proxy\nDOMAIN-SUFFIX,allbet3.com,Proxy\nDOMAIN-SUFFIX,85999g.vip,Proxy\nDOMAIN-SUFFIX,stackoverflow.com,Proxy\nDOMAIN-SUFFIX,megacorpwars.com,Proxy\nDOMAIN-SUFFIX,www.experian.fr,Proxy\nDOMAIN-SUFFIX,yl9936.com,Proxy\nDOMAIN-SUFFIX,huluim.com,Proxy\nDOMAIN-SUFFIX,reseed.memcpy.io,Proxy\nDOMAIN-SUFFIX,www.freecreators.com,Proxy\nDOMAIN-SUFFIX,fyt521.com,Proxy\nDOMAIN-SUFFIX,bityard.com,Proxy\nDOMAIN-SUFFIX,spankingtube.com,Proxy\nDOMAIN-SUFFIX,zh.pokerstrategy.com,Proxy\nDOMAIN-SUFFIX,game.samurai-games.net,Proxy\nDOMAIN-SUFFIX,publicagent.com,Proxy\nDOMAIN-SUFFIX,xinmiao.com.hk,Proxy\nDOMAIN-SUFFIX,buyu233.com,Proxy\nDOMAIN-SUFFIX,e5fit.com,Proxy\nDOMAIN-SUFFIX,www.muenchen.de,Proxy\nDOMAIN-SUFFIX,ronjoneswriter.com,Proxy\nDOMAIN-SUFFIX,ch.shvoong.com,Proxy\nDOMAIN-SUFFIX,48789x.com,Proxy\nDOMAIN-SUFFIX,freecloudvpn.com,Proxy\nDOMAIN-SUFFIX,www.lastweektonight.com,Proxy\nDOMAIN-SUFFIX,www.s52040.com,Proxy\nDOMAIN-SUFFIX,mysynology.net,Proxy\nDOMAIN-SUFFIX,gizmoxxx.com,Proxy\nDOMAIN-SUFFIX,www.musicdish.com,Proxy\nDOMAIN-SUFFIX,akiba-online.com,Proxy\nDOMAIN-SUFFIX,hacks.mozilla.org,Proxy\nDOMAIN-SUFFIX,luxurygirls.com,Proxy\nDOMAIN-SUFFIX,plmnt.im,Proxy\nDOMAIN-SUFFIX,talkboxapp.com,Proxy\nDOMAIN-SUFFIX,vpn.airwallex.com,Proxy\nDOMAIN-SUFFIX,legaltech.law.com,Proxy\nDOMAIN-SUFFIX,longtermly.net,Proxy\nDOMAIN-SUFFIX,www.mei-yao.com,Proxy\nDOMAIN-SUFFIX,onlygayvideo.com,Proxy\nDOMAIN-SUFFIX,bhpho.to,Proxy\nDOMAIN-SUFFIX,xxmap2.club,Proxy\nDOMAIN-SUFFIX,rtbf.be,Proxy\nDOMAIN-SUFFIX,ftp.iu45.net,Proxy\nDOMAIN-SUFFIX,rickful.com,Proxy\nDOMAIN-SUFFIX,www.eu7.com,Proxy\nDOMAIN-SUFFIX,www.dafa888.com,Proxy\nDOMAIN-SUFFIX,iboy1069.org,Proxy\nDOMAIN-SUFFIX,www.hohosex.com,Proxy\nDOMAIN-SUFFIX,www.pacific-times.com,Proxy\nDOMAIN-SUFFIX,m.poloniex.com,Proxy\nDOMAIN-SUFFIX,piped.mha.fi,Proxy\nDOMAIN-SUFFIX,8899683.com,Proxy\nDOMAIN-SUFFIX,vtm.be,Proxy\nDOMAIN-SUFFIX,hk.c.cloudss.pw,Proxy\nDOMAIN-SUFFIX,www.alqp76.com,Proxy\nDOMAIN-SUFFIX,t66y.com,Proxy\nDOMAIN-SUFFIX,vewas.net,Proxy\nDOMAIN-SUFFIX,dlxi9ddd6fxyg.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.rigpa.org,Proxy\nDOMAIN-SUFFIX,google.com.au,Proxy\nDOMAIN-SUFFIX,japan-forward.com,Proxy\nDOMAIN-SUFFIX,bbs.sopboy.com,Proxy\nDOMAIN-SUFFIX,www.shidaixianfeng.tk,Proxy\nDOMAIN-SUFFIX,rta.ae,Proxy\nDOMAIN-SUFFIX,sexhu.com,Proxy\nDOMAIN-SUFFIX,theblemish.com,Proxy\nDOMAIN-KEYWORD,ultrareach,Proxy\nDOMAIN-SUFFIX,falundafa.com,Proxy\nDOMAIN-SUFFIX,eporner.com,Proxy\nDOMAIN-SUFFIX,esbi8.com,Proxy\nDOMAIN-SUFFIX,www.vicentegandia.com,Proxy\nDOMAIN-SUFFIX,y5090.com,Proxy\nDOMAIN-SUFFIX,tbtemple.org.uk,Proxy\nDOMAIN-SUFFIX,bomb01.com,Proxy\nDOMAIN-SUFFIX,00899h.com,Proxy\nDOMAIN-SUFFIX,saveuighur.org,Proxy\nDOMAIN-SUFFIX,google.sg,Proxy\nDOMAIN-SUFFIX,www.oldmapsonline.org,Proxy\nDOMAIN-SUFFIX,dynupdate.no-ip.com,Proxy\nDOMAIN-SUFFIX,marvell.ent.box.com,Proxy\nDOMAIN-SUFFIX,app.ddns.net,Proxy\nDOMAIN-SUFFIX,nei.st,Proxy\nDOMAIN-SUFFIX,pingproxy.com,Proxy\nDOMAIN-SUFFIX,www.purespectrum.com,Proxy\nDOMAIN-SUFFIX,hktext.blogspot.hk,Proxy\nDOMAIN-SUFFIX,fetis.kir.jp,Proxy\nDOMAIN-SUFFIX,monocloud.com.au,Proxy\nDOMAIN-SUFFIX,pcanywhere.net,Proxy\nDOMAIN-SUFFIX,proxyserver.com,Proxy\nDOMAIN-SUFFIX,mbhs.mtbluersd.org,Proxy\nDOMAIN-SUFFIX,rb278.com,Proxy\nDOMAIN-SUFFIX,swagbucks.com,Proxy\nDOMAIN-SUFFIX,vid.me,Proxy\nDOMAIN-SUFFIX,www.hislands.org,Proxy\nDOMAIN-SUFFIX,tor-exit-55.for-privacy.net,Proxy\nDOMAIN-SUFFIX,www.63000sc.com,Proxy\nDOMAIN-SUFFIX,pinterest.co.uk,Proxy\nDOMAIN-SUFFIX,scholarlykitchen.sspnet.org,Proxy\nDOMAIN-SUFFIX,www.donnybrookmail.com.au,Proxy\nDOMAIN-SUFFIX,for-the.biz,Proxy\nDOMAIN-SUFFIX,telegramcn.net,Proxy\nDOMAIN-SUFFIX,pdetails.com,Proxy\nDOMAIN-SUFFIX,copywinner.org,Proxy\nDOMAIN-SUFFIX,mail.embraco.com,Proxy\nDOMAIN-SUFFIX,imgscloud.win,Proxy\nDOMAIN-SUFFIX,www.gga.asia,Proxy\nDOMAIN-SUFFIX,gg168.xyz,Proxy\nDOMAIN-SUFFIX,fulibl.cc,Proxy\nDOMAIN-SUFFIX,mangafox.me,Proxy\nDOMAIN-SUFFIX,www.88fanya.com,Proxy\nDOMAIN-SUFFIX,18av.andygod.com,Proxy\nDOMAIN-SUFFIX,www.w678678.com,Proxy\nDOMAIN-SUFFIX,thywords.com,Proxy\nDOMAIN-SUFFIX,harbourtimes.com,Proxy\nDOMAIN-SUFFIX,nudeflix.com,Proxy\nDOMAIN-SUFFIX,xc222999.com,Proxy\nDOMAIN-SUFFIX,google.com.bd,Proxy\nDOMAIN-SUFFIX,mirrorbooks.com,Proxy\nDOMAIN-SUFFIX,bbs.pcbeta.com,Proxy\nDOMAIN-SUFFIX,pormhub.com,Proxy\nDOMAIN-SUFFIX,dolc.de,Proxy\nDOMAIN-SUFFIX,wlcnew02.jigsy.com,Proxy\nDOMAIN-SUFFIX,qqav.tv,Proxy\nDOMAIN-SUFFIX,muviza.su,Proxy\nDOMAIN-SUFFIX,cdn.brand-display.com,Proxy\nDOMAIN-SUFFIX,d2v4451an2o2d1.cloudfront.net,Proxy\nDOMAIN-SUFFIX,pixiv.io,Proxy\nDOMAIN-SUFFIX,xizang-zhiye.org,Proxy\nDOMAIN-SUFFIX,www.ambjl00.com,Proxy\nDOMAIN-SUFFIX,betterandfaster.com,Proxy\nDOMAIN-SUFFIX,www.jin456.com,Proxy\nDOMAIN-SUFFIX,letou7.com,Proxy\nDOMAIN-SUFFIX,fun172.com,Proxy\nDOMAIN-SUFFIX,nest.com,Proxy\nDOMAIN-SUFFIX,cde.jp,Proxy\nDOMAIN-SUFFIX,hotgoo.com,Proxy\nDOMAIN-SUFFIX,booktopia.com.au,Proxy\nDOMAIN-SUFFIX,tor-exit-44.for-privacy.net,Proxy\nDOMAIN-SUFFIX,aje.io,Proxy\nDOMAIN-SUFFIX,oo699.net,Proxy\nDOMAIN-SUFFIX,video-edge-24826d.pdx01.abs.hls.ttvnw.net,Proxy\nDOMAIN-SUFFIX,www.sundaypost.com,Proxy\nDOMAIN-SUFFIX,boxopus.com,Proxy\nDOMAIN-SUFFIX,gt80.com,Proxy\nDOMAIN-SUFFIX,rosechina.net,Proxy\nDOMAIN-SUFFIX,scmp.tv,Proxy\nDOMAIN-SUFFIX,psiphondownload.com,Proxy\nDOMAIN-SUFFIX,freeopenvpn.org,Proxy\nDOMAIN-SUFFIX,xysblogs.org,Proxy\nDOMAIN-SUFFIX,casino.gpiops.com,Proxy\nDOMAIN-SUFFIX,www.gmiddle.com,Proxy\nDOMAIN-SUFFIX,game.fafafa3388.com,Proxy\nDOMAIN-SUFFIX,www.klcc.org,Proxy\nDOMAIN-SUFFIX,shuilu-2010.blogspot.hk,Proxy\nDOMAIN-SUFFIX,fanipa.com,Proxy\nDOMAIN-SUFFIX,63.flnet.org,Proxy\nDOMAIN-SUFFIX,210642.xyz,Proxy\nDOMAIN-SUFFIX,politiscales.net,Proxy\nDOMAIN-SUFFIX,www.viewfinder.com.tw,Proxy\nDOMAIN-SUFFIX,yuhaotech.blogspot.hk,Proxy\nDOMAIN-SUFFIX,biblia.com,Proxy\nDOMAIN-SUFFIX,fengzhenghu.com,Proxy\nDOMAIN-SUFFIX,himemix.com,Proxy\nDOMAIN-SUFFIX,stupa.org.au,Proxy\nDOMAIN-SUFFIX,alwaysdata.net,Proxy\nDOMAIN-SUFFIX,xb.dnsmail.xyz,Proxy\nDOMAIN-SUFFIX,blog.birdhouseapp.com,Proxy\nDOMAIN-SUFFIX,7tcg.com,Proxy\nDOMAIN-SUFFIX,upbit.com,Proxy\nDOMAIN-SUFFIX,www.hidemefast.net,Proxy\nDOMAIN-SUFFIX,duetdisplay.com,Proxy\nDOMAIN-SUFFIX,m88123.com,Proxy\nDOMAIN-SUFFIX,qjz.com.cn,Proxy\nDOMAIN-SUFFIX,bbs.9gal.com,Proxy\nDOMAIN-SUFFIX,decadencecomics.com,Proxy\nDOMAIN-SUFFIX,wawacity.ws,Proxy\nDOMAIN-SUFFIX,blog.xuite.net,Proxy\nDOMAIN-SUFFIX,www.vitas-official.com,Proxy\nDOMAIN-SUFFIX,www.v967.net,Proxy\nDOMAIN-SUFFIX,48.effers.com,Proxy\nDOMAIN-SUFFIX,fixit.com,Proxy\nDOMAIN-SUFFIX,ggso.co,Proxy\nDOMAIN-SUFFIX,8587q.cc,Proxy\nDOMAIN-SUFFIX,tzcafe.com,Proxy\nDOMAIN-SUFFIX,www.godfootsteps.org,Proxy\nDOMAIN-SUFFIX,4cdn.org,Proxy\nDOMAIN-SUFFIX,wechat.fingerdaily.com,Proxy\nDOMAIN-SUFFIX,h5.016ld.com,Proxy\nDOMAIN-SUFFIX,mastodon.cloud,Proxy\nDOMAIN-SUFFIX,everipedia.org,Proxy\nDOMAIN-SUFFIX,falundafa.org.sg,Proxy\nDOMAIN-SUFFIX,umbris.net,Proxy\nDOMAIN-SUFFIX,jgjsvip3.com,Proxy\nDOMAIN-SUFFIX,60caipiao.com,Proxy\nDOMAIN-SUFFIX,sinovision.net,Proxy\nDOMAIN-SUFFIX,free-china.tech.blog,Proxy\nDOMAIN-SUFFIX,www.rsf.com,Proxy\nDOMAIN-SUFFIX,www.laodongqushi.com,Proxy\nDOMAIN-SUFFIX,lknovel.lightnovel.cn,Proxy\nDOMAIN-SUFFIX,omofun.top,Proxy\nDOMAIN-SUFFIX,interc.pt,Proxy\nDOMAIN-SUFFIX,weirinhouse.com,Proxy\nDOMAIN-SUFFIX,us-central1-celebrity-voice.cloudfunctions.net,Proxy\nDOMAIN-SUFFIX,taiwanvpn.com,Proxy\nDOMAIN-SUFFIX,www.consultant5366.com,Proxy\nDOMAIN-SUFFIX,owa.baltimorecity.gov,Proxy\nDOMAIN-SUFFIX,89.flnet.org,Proxy\nDOMAIN-SUFFIX,demo2.sgwin123.com,Proxy\nDOMAIN-SUFFIX,jtl-software.de,Proxy\nDOMAIN-SUFFIX,watchout.tw,Proxy\nDOMAIN-SUFFIX,elitepvperstut.sweb.cz,Proxy\nDOMAIN-SUFFIX,pearlher.org,Proxy\nDOMAIN-SUFFIX,www.paektuculturalexchange.org,Proxy\nDOMAIN-SUFFIX,rssing.com,Proxy\nDOMAIN-SUFFIX,npnt.me,Proxy\nDOMAIN-SUFFIX,flipboard.com,Proxy\nDOMAIN-SUFFIX,thefacts.xyz,Proxy\nDOMAIN-SUFFIX,fb.gg,Proxy\nDOMAIN-SUFFIX,dnsdojo.net,Proxy\nDOMAIN-SUFFIX,china-mmm.sa.com,Proxy\nDOMAIN-SUFFIX,novelai.com,Proxy\nDOMAIN-SUFFIX,youneed.win,Proxy\nDOMAIN-SUFFIX,bluelivetv.net,Proxy\nDOMAIN-SUFFIX,d5.dtdns.net,Proxy\nDOMAIN-SUFFIX,pbs.twimg.com,Proxy\nDOMAIN-SUFFIX,xinbi616.com,Proxy\nDOMAIN-SUFFIX,usgfx.asia,Proxy\nDOMAIN-SUFFIX,m.byb70.com,Proxy\nDOMAIN-SUFFIX,bgproxy.org,Proxy\nDOMAIN-SUFFIX,d2cq20iolajbhj.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.ye321.com,Proxy\nDOMAIN-SUFFIX,wcili.com,Proxy\nDOMAIN-SUFFIX,hk.hao123img.com,Proxy\nDOMAIN-SUFFIX,www.bustybloom.com,Proxy\nDOMAIN-SUFFIX,cn42.gq,Proxy\nDOMAIN-SUFFIX,tibetanhealth.org,Proxy\nDOMAIN-SUFFIX,nitter.notraxx.ch,Proxy\nDOMAIN-SUFFIX,newshub.co.nz,Proxy\nDOMAIN-SUFFIX,woopie.tv,Proxy\nDOMAIN-SUFFIX,link.indiegogo.com,Proxy\nDOMAIN-SUFFIX,www.gayfuror.com,Proxy\nDOMAIN-SUFFIX,www.thecipherbrief.com,Proxy\nDOMAIN-SUFFIX,gtloli.com,Proxy\nDOMAIN-SUFFIX,ntsna.gov.tw,Proxy\nDOMAIN-SUFFIX,sr.domain888.pw,Proxy\nDOMAIN-SUFFIX,www.twhm.net,Proxy\nDOMAIN-SUFFIX,rawgithub.com,Proxy\nDOMAIN-SUFFIX,zzq.familyhealth.xyz,Proxy\nDOMAIN-SUFFIX,allgirlsallowed.org,Proxy\nDOMAIN-SUFFIX,1024yingyuan.com,Proxy\nDOMAIN-SUFFIX,www.hebo13.com,Proxy\nDOMAIN-SUFFIX,ggg112.net,Proxy\nDOMAIN-SUFFIX,www.tlc125.com,Proxy\nDOMAIN-SUFFIX,exchristian.hk,Proxy\nDOMAIN-SUFFIX,streamera.tv,Proxy\nDOMAIN-SUFFIX,sbf812.com,Proxy\nDOMAIN-SUFFIX,th.hao123.com,Proxy\nDOMAIN-SUFFIX,hl.mk,Proxy\nDOMAIN-SUFFIX,rocket-inc.net,Proxy\nDOMAIN-SUFFIX,wevpn.com,Proxy\nDOMAIN-SUFFIX,rthk.hk,Proxy\nDOMAIN-SUFFIX,edmontonservice.com,Proxy\nDOMAIN-SUFFIX,app.wvwuwvuwvw.com,Proxy\nDOMAIN-SUFFIX,shireyishunjian.com,Proxy\nDOMAIN-SUFFIX,ssrocket.com,Proxy\nDOMAIN-SUFFIX,aurateur.com,Proxy\nDOMAIN-SUFFIX,esjzone.cc,Proxy\nDOMAIN-SUFFIX,yyii.org,Proxy\nDOMAIN-SUFFIX,fandom.ink,Proxy\nDOMAIN-SUFFIX,m.mth02.com,Proxy\nDOMAIN-SUFFIX,tv.jtbc.joins.com,Proxy\nDOMAIN-SUFFIX,www.pionex.com,Proxy\nDOMAIN-SUFFIX,faluninfo.net,Proxy\nDOMAIN-SUFFIX,thegay.com,Proxy\nDOMAIN-SUFFIX,mevpn.com,Proxy\nDOMAIN-SUFFIX,maplew.com,Proxy\nDOMAIN-SUFFIX,roigpremium.es,Proxy\nDOMAIN-SUFFIX,www.gets.cn,Proxy\nDOMAIN-SUFFIX,20609.cc,Proxy\nDOMAIN-SUFFIX,gitcdn.link,Proxy\nDOMAIN-SUFFIX,grupompr.com,Proxy\nDOMAIN-SUFFIX,fluidbiz.us,Proxy\nDOMAIN-SUFFIX,xm.com,Proxy\nDOMAIN-SUFFIX,tibetinfonet.net,Proxy\nDOMAIN-SUFFIX,mdsv.tv,Proxy\nDOMAIN-SUFFIX,www.straitstimes.com,Proxy\nDOMAIN-SUFFIX,racefortibet.org,Proxy\nDOMAIN-SUFFIX,dukgo.com,Proxy\nDOMAIN-SUFFIX,www.playboytubes.com,Proxy\nDOMAIN-SUFFIX,alexrus.ro,Proxy\nDOMAIN-SUFFIX,b3939.com,Proxy\nDOMAIN-SUFFIX,ilhk.com,Proxy\nDOMAIN-SUFFIX,mingpaovan.com,Proxy\nDOMAIN-SUFFIX,6qing6.com,Proxy\nDOMAIN-SUFFIX,ukliferadio.co.uk,Proxy\nDOMAIN-SUFFIX,vpn.fantopia.club,Proxy\nDOMAIN-SUFFIX,twitstat.com,Proxy\nDOMAIN-SUFFIX,story.5article.com,Proxy\nDOMAIN-SUFFIX,picasaweb.com,Proxy\nDOMAIN-SUFFIX,h5.395ld.com,Proxy\nDOMAIN-SUFFIX,sixthtone.com,Proxy\nDOMAIN-SUFFIX,www.libertyfund.org,Proxy\nDOMAIN-SUFFIX,jinroukong.com,Proxy\nDOMAIN-SUFFIX,cs233.com,Proxy\nDOMAIN-SUFFIX,powells.com,Proxy\nDOMAIN-SUFFIX,xocat2.com,Proxy\nDOMAIN-SUFFIX,igmg.de,Proxy\nDOMAIN-SUFFIX,eastturkistan-gov.org,Proxy\nDOMAIN-SUFFIX,dim9.ddns.us,Proxy\nDOMAIN-SUFFIX,earthguardians.org,Proxy\nDOMAIN-SUFFIX,www.breath-takers.com,Proxy\nDOMAIN-SUFFIX,av777888.com,Proxy\nDOMAIN-SUFFIX,www.moi.gov.mm,Proxy\nDOMAIN-SUFFIX,bbci.co.uk,Proxy\nDOMAIN-SUFFIX,fullstack.cl,Proxy\nDOMAIN-SUFFIX,chenguangcheng.com,Proxy\nDOMAIN-SUFFIX,crutchfield.com,Proxy\nDOMAIN-SUFFIX,zzw.dnsmail.xyz,Proxy\nDOMAIN-SUFFIX,webmail.excelorthodontics.com,Proxy\nDOMAIN-SUFFIX,vns2005.com,Proxy\nDOMAIN-SUFFIX,south-plus.net,Proxy\nDOMAIN-SUFFIX,factpedia.org,Proxy\nDOMAIN-SUFFIX,avistaz.to,Proxy\nDOMAIN-SUFFIX,worldjournal.com,Proxy\nDOMAIN-SUFFIX,www.scientology.org.uk,Proxy\nDOMAIN-SUFFIX,f.2fine.de,Proxy\nDOMAIN-SUFFIX,www.cd4o.com,Proxy\nDOMAIN-SUFFIX,digiland.tw,Proxy\nDOMAIN-SUFFIX,contests.twilio.com,Proxy\nDOMAIN-SUFFIX,paopao5.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,3201320.com,Proxy\nDOMAIN-SUFFIX,ntvspor.net,Proxy\nDOMAIN-SUFFIX,ilvpn.com,Proxy\nDOMAIN-SUFFIX,laodi.cf,Proxy\nDOMAIN-SUFFIX,www.shishirere.com,Proxy\nDOMAIN-SUFFIX,www.pcnet.idv.tw,Proxy\nDOMAIN-SUFFIX,waynecn.com,Proxy\nDOMAIN-SUFFIX,bigporn.com,Proxy\nDOMAIN-SUFFIX,fpt.icu,Proxy\nDOMAIN-SUFFIX,myspace.com,Proxy\nDOMAIN-SUFFIX,visionchinatimes.org,Proxy\nDOMAIN-SUFFIX,www.w88981.com,Proxy\nDOMAIN-SUFFIX,pjbadh2.club,Proxy\nDOMAIN-SUFFIX,blogcity.me,Proxy\nDOMAIN-SUFFIX,explaineverything.com,Proxy\nDOMAIN-SUFFIX,googleartproject.com,Proxy\nDOMAIN-SUFFIX,tv72.gq,Proxy\nDOMAIN-SUFFIX,tc168.tk,Proxy\nDOMAIN-SUFFIX,wataru.moe,Proxy\nDOMAIN-SUFFIX,www.buzzhand.com,Proxy\nDOMAIN-SUFFIX,zaahir.com,Proxy\nDOMAIN-SUFFIX,www.anjiasu.com,Proxy\nDOMAIN-SUFFIX,hihistory.net,Proxy\nDOMAIN-SUFFIX,web.getmonero.org,Proxy\nDOMAIN-SUFFIX,wanderlustdrinks.com,Proxy\nDOMAIN-SUFFIX,se.5lxtv.com,Proxy\nDOMAIN-SUFFIX,eroticity.net,Proxy\nDOMAIN-SUFFIX,greatfirewallofchina.org,Proxy\nDOMAIN-SUFFIX,8njhaop.impervadns.net,Proxy\nDOMAIN-SUFFIX,vo.freepac.pw,Proxy\nDOMAIN-SUFFIX,ucanews.com,Proxy\nDOMAIN-SUFFIX,www.scoop.co.nz,Proxy\nDOMAIN-SUFFIX,navyreserve.navy.mil,Proxy\nDOMAIN-SUFFIX,download.mql5.com,Proxy\nDOMAIN-SUFFIX,matainja.com,Proxy\nDOMAIN-SUFFIX,www.wifebucket.com,Proxy\nDOMAIN-SUFFIX,www.mixcloud.com,Proxy\nDOMAIN-SUFFIX,801661.com,Proxy\nDOMAIN-SUFFIX,bm507.cc,Proxy\nDOMAIN-SUFFIX,www.orangehouse.idv.tw,Proxy\nDOMAIN-SUFFIX,20188u.com,Proxy\nDOMAIN-SUFFIX,deja.com,Proxy\nDOMAIN-SUFFIX,xbooru.com,Proxy\nDOMAIN-SUFFIX,cloud-jp.adminpub.com,Proxy\nDOMAIN-SUFFIX,alvinalexander.com,Proxy\nDOMAIN-SUFFIX,sammibaby.cc,Proxy\nDOMAIN-SUFFIX,tweez.net,Proxy\nDOMAIN-SUFFIX,pc.olife.org,Proxy\nDOMAIN-SUFFIX,www.hilive.tv,Proxy\nDOMAIN-SUFFIX,d2cu0gs939yg23.cloudfront.net,Proxy\nDOMAIN-SUFFIX,nitter.tinfoil-hat.net,Proxy\nDOMAIN-SUFFIX,pc.php5.us,Proxy\nDOMAIN-SUFFIX,shenyun.com,Proxy\nDOMAIN-SUFFIX,fileinfo.com,Proxy\nDOMAIN-SUFFIX,www.trycatchme.com,Proxy\nDOMAIN-SUFFIX,bodog39.com,Proxy\nDOMAIN-SUFFIX,vpscn.net,Proxy\nDOMAIN-SUFFIX,jmcomic6.cc,Proxy\nDOMAIN-SUFFIX,www.psa.org.au,Proxy\nDOMAIN-SUFFIX,is-a-geek.com,Proxy\nDOMAIN-SUFFIX,ieasy5.com,Proxy\nDOMAIN-SUFFIX,www.nanoplustech.com,Proxy\nDOMAIN-SUFFIX,misty-myth.com,Proxy\nDOMAIN-SUFFIX,steamcommunity.org,Proxy\nDOMAIN-SUFFIX,endirimler.az,Proxy\nDOMAIN-SUFFIX,blogtd.net,Proxy\nDOMAIN-SUFFIX,moefuns1.org,Proxy\nDOMAIN-SUFFIX,353.my03.com,Proxy\nDOMAIN-SUFFIX,twisternow.com,Proxy\nDOMAIN-SUFFIX,thinkingtaiwan.com,Proxy\nDOMAIN-SUFFIX,fcg101.com,Proxy\nDOMAIN-SUFFIX,xyy69.info,Proxy\nDOMAIN-SUFFIX,archiveofourown.org,Proxy\nDOMAIN-SUFFIX,www.glassdoor.com,Proxy\nDOMAIN-SUFFIX,tbi.org.hk,Proxy\nDOMAIN-SUFFIX,m.h9-h9.com,Proxy\nDOMAIN-SUFFIX,joinclubhouse.com,Proxy\nDOMAIN-SUFFIX,www.h11i.blogspot.hk,Proxy\nDOMAIN-SUFFIX,www.buddhistdoor.org,Proxy\nDOMAIN-SUFFIX,votesmart.org,Proxy\nDOMAIN-SUFFIX,aa2211.com,Proxy\nDOMAIN-SUFFIX,d3imx1e8hbmfql.cloudfront.net,Proxy\nDOMAIN-SUFFIX,savii.ro,Proxy\nDOMAIN-SUFFIX,www.mg787blm.com,Proxy\nDOMAIN-SUFFIX,www.e8198.com,Proxy\nDOMAIN-SUFFIX,565js.com,Proxy\nDOMAIN-SUFFIX,mx981.com,Proxy\nDOMAIN-SUFFIX,singpao.com.hk,Proxy\nDOMAIN-SUFFIX,news.com.au,Proxy\nDOMAIN-SUFFIX,www.babes.com,Proxy\nDOMAIN-SUFFIX,www.google.com.ag,Proxy\nDOMAIN-SUFFIX,alphagoteach.deepmind.com,Proxy\nDOMAIN-SUFFIX,popyard.com,Proxy\nDOMAIN-SUFFIX,33779sha.com,Proxy\nDOMAIN-SUFFIX,canvaslms.com,Proxy\nDOMAIN-SUFFIX,www.shadowfly.org,Proxy\nDOMAIN-SUFFIX,zh.joyhentai.fun,Proxy\nDOMAIN-SUFFIX,mstdn.ca,Proxy\nDOMAIN-SUFFIX,www.freiepresse.de,Proxy\nDOMAIN-SUFFIX,picturesocial.com,Proxy\nDOMAIN-SUFFIX,gd9vip.net,Proxy\nDOMAIN-SUFFIX,go.gringousa.com,Proxy\nDOMAIN-SUFFIX,7722xj.com,Proxy\nDOMAIN-SUFFIX,www.niteflirt.com,Proxy\nDOMAIN-SUFFIX,tlc288.com,Proxy\nDOMAIN-SUFFIX,www.johnl.org,Proxy\nDOMAIN-SUFFIX,h5.slpay-prod.com,Proxy\nDOMAIN-SUFFIX,nord-cn.org,Proxy\nDOMAIN-SUFFIX,airav1.fun,Proxy\nDOMAIN-SUFFIX,cn.duanzh.com,Proxy\nDOMAIN-SUFFIX,www.imcreator.com,Proxy\nDOMAIN-SUFFIX,casindonesia.com,Proxy\nDOMAIN-SUFFIX,pdproxy.com,Proxy\nDOMAIN-SUFFIX,static.namethatporn.com,Proxy\nDOMAIN-SUFFIX,dyndns-wiki.com,Proxy\nDOMAIN-SUFFIX,www.cabet081.com,Proxy\nDOMAIN-SUFFIX,paopao3.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,ur7s.com,Proxy\nDOMAIN-SUFFIX,panel.alink345.com,Proxy\nDOMAIN-SUFFIX,www.thekevinpoon.com,Proxy\nDOMAIN-SUFFIX,newstamago.com,Proxy\nDOMAIN-SUFFIX,nanoids.ws,Proxy\nDOMAIN-SUFFIX,www.cosmosbooks.com.hk,Proxy\nDOMAIN-SUFFIX,mytizi.com,Proxy\nDOMAIN-SUFFIX,westernshugdensociety.org,Proxy\nDOMAIN-SUFFIX,we.minecraftnoob.com,Proxy\nDOMAIN-SUFFIX,www.btku.org,Proxy\nDOMAIN-SUFFIX,apserver.net,Proxy\nDOMAIN-SUFFIX,dns.froth.zone,Proxy\nDOMAIN-SUFFIX,m.xf839.com,Proxy\nDOMAIN-SUFFIX,www.freemovies.tv,Proxy\nDOMAIN-SUFFIX,club.tgfcer.com,Proxy\nDOMAIN-SUFFIX,awr.org,Proxy\nDOMAIN-SUFFIX,58999.com.tw,Proxy\nDOMAIN-SUFFIX,tv2.spacetechnology.net,Proxy\nDOMAIN-SUFFIX,www.maitreya.nl,Proxy\nDOMAIN-SUFFIX,kspcoin.com,Proxy\nDOMAIN-SUFFIX,hjav.in,Proxy\nDOMAIN-SUFFIX,www.1952222.com,Proxy\nDOMAIN-SUFFIX,meyul.com,Proxy\nDOMAIN-SUFFIX,webmail.katamail.com,Proxy\nDOMAIN-SUFFIX,gmpg.org,Proxy\nDOMAIN-SUFFIX,pornzee.com,Proxy\nDOMAIN-SUFFIX,2209647.com,Proxy\nDOMAIN-SUFFIX,ctalicuza.ro,Proxy\nDOMAIN-SUFFIX,s4m.xyz,Proxy\nDOMAIN-SUFFIX,www.tubeislam.com,Proxy\nDOMAIN-SUFFIX,yb1111.com,Proxy\nDOMAIN-SUFFIX,www.u161.com,Proxy\nDOMAIN-SUFFIX,www.ebay.it,Proxy\nDOMAIN-SUFFIX,nangaspace.com,Proxy\nDOMAIN-SUFFIX,pornsharing.com,Proxy\nDOMAIN-SUFFIX,voanews.org,Proxy\nDOMAIN-SUFFIX,www.klip.me,Proxy\nDOMAIN-SUFFIX,centrump2p.com,Proxy\nDOMAIN-SUFFIX,secure.shadowsocks.ch,Proxy\nDOMAIN-SUFFIX,tweetymail.com,Proxy\nDOMAIN-SUFFIX,ys9023.com,Proxy\nDOMAIN-SUFFIX,mediafire.com,Proxy\nDOMAIN-SUFFIX,www.abc365.vip,Proxy\nDOMAIN-SUFFIX,vietdaikynguyen.com,Proxy\nDOMAIN-SUFFIX,fleshbot.com,Proxy\nDOMAIN-SUFFIX,idic.ro,Proxy\nDOMAIN-SUFFIX,gettyimages.hk,Proxy\nDOMAIN-SUFFIX,333.effers.com,Proxy\nDOMAIN-SUFFIX,www.silklabo.com,Proxy\nDOMAIN-SUFFIX,fw2.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,lsforum.net,Proxy\nDOMAIN-SUFFIX,freechinaforum.org,Proxy\nDOMAIN-SUFFIX,sr.com,Proxy\nDOMAIN-SUFFIX,mitbbs.com,Proxy\nDOMAIN-SUFFIX,dyndns-home.com,Proxy\nDOMAIN-SUFFIX,tibetsociety.com,Proxy\nDOMAIN-SUFFIX,00899e.com,Proxy\nDOMAIN-SUFFIX,www.makkahnewspaper.com,Proxy\nDOMAIN-SUFFIX,h-moe.com,Proxy\nDOMAIN-SUFFIX,google.org,Proxy\nDOMAIN-SUFFIX,scontent-b-ord.cdninstagram.com,Proxy\nDOMAIN-SUFFIX,fapa.org,Proxy\nDOMAIN-SUFFIX,appspot.com,Proxy\nDOMAIN-SUFFIX,muadness.com,Proxy\nDOMAIN-SUFFIX,chinauncensored.org,Proxy\nDOMAIN-SUFFIX,vichan.net,Proxy\nDOMAIN-SUFFIX,appledaily.com.hk,Proxy\nDOMAIN-SUFFIX,placehold.it,Proxy\nDOMAIN-SUFFIX,atlaslabs.org,Proxy\nDOMAIN-SUFFIX,pornworms.com,Proxy\nDOMAIN-SUFFIX,firstanalquest.com,Proxy\nDOMAIN-SUFFIX,gclubs.com,Proxy\nDOMAIN-SUFFIX,bliporn.com,Proxy\nDOMAIN-SUFFIX,moyuv5.com,Proxy\nDOMAIN-SUFFIX,untraceable.us,Proxy\nDOMAIN-SUFFIX,vpnbest5.com,Proxy\nDOMAIN-SUFFIX,fabercastell.com,Proxy\nDOMAIN-SUFFIX,1024.neocities.org,Proxy\nDOMAIN-SUFFIX,www.rchchope.edu.hk,Proxy\nDOMAIN-SUFFIX,cbs.ntu.edu.tw,Proxy\nDOMAIN-SUFFIX,swdevelop.de,Proxy\nDOMAIN-SUFFIX,js8699.com,Proxy\nDOMAIN-SUFFIX,qxbbs.org,Proxy\nDOMAIN-SUFFIX,mentadulce.cl,Proxy\nDOMAIN-SUFFIX,outlook.villanova.edu,Proxy\nDOMAIN-SUFFIX,pic5.pixclub.net,Proxy\nDOMAIN-SUFFIX,www.wnichangsha.com,Proxy\nDOMAIN-SUFFIX,xx.freepac.pw,Proxy\nDOMAIN-SUFFIX,automata.ms,Proxy\nDOMAIN-SUFFIX,blogdns.net,Proxy\nDOMAIN-SUFFIX,tibetgermany.com,Proxy\nDOMAIN-SUFFIX,h5.ld2082.cc,Proxy\nDOMAIN-SUFFIX,www.h4610.com,Proxy\nDOMAIN-SUFFIX,tw.forums.blizzard.com,Proxy\nDOMAIN-SUFFIX,www.zalmos.com,Proxy\nDOMAIN-SUFFIX,from-me.org,Proxy\nDOMAIN-SUFFIX,hkacg.com,Proxy\nDOMAIN-SUFFIX,sdxl.org,Proxy\nDOMAIN-SUFFIX,falundafa-se.nu,Proxy\nDOMAIN-SUFFIX,api.recaptcha.net,Proxy\nDOMAIN-SUFFIX,zuirt.com,Proxy\nDOMAIN-SUFFIX,www.yy06354.com,Proxy\nDOMAIN-SUFFIX,csstc.cssa.org.tw,Proxy\nDOMAIN-SUFFIX,cd.spacetechnology.net,Proxy\nDOMAIN-SUFFIX,banana-vpn.com,Proxy\nDOMAIN-SUFFIX,dalailamavisit.org.nz,Proxy\nDOMAIN-SUFFIX,tuidang.org,Proxy\nDOMAIN-SUFFIX,asiasociety.org,Proxy\nDOMAIN-SUFFIX,ggcarry.com,Proxy\nDOMAIN-SUFFIX,bj-jinchang.com,Proxy\nDOMAIN-SUFFIX,dnsdojo.org,Proxy\nDOMAIN-SUFFIX,gunge.com,Proxy\nDOMAIN-SUFFIX,tibet.net,Proxy\nDOMAIN-SUFFIX,freedsn.xyz,Proxy\nDOMAIN-SUFFIX,tampabay.com,Proxy\nDOMAIN-SUFFIX,leon.net,Proxy\nDOMAIN-SUFFIX,fvpn.com,Proxy\nDOMAIN-SUFFIX,shamaniclightwork.com,Proxy\nDOMAIN-SUFFIX,ertopen.com,Proxy\nDOMAIN-SUFFIX,www.abplive.com,Proxy\nDOMAIN-SUFFIX,freezhihu.org,Proxy\nDOMAIN-SUFFIX,shicheng.org,Proxy\nDOMAIN-SUFFIX,81rch.com,Proxy\nDOMAIN-SUFFIX,gaopi.net,Proxy\nDOMAIN-SUFFIX,www.havfruene.no,Proxy\nDOMAIN-SUFFIX,chinasucks.net,Proxy\nDOMAIN-SUFFIX,jmcomic.asia,Proxy\nDOMAIN-SUFFIX,www.susandaffron.com,Proxy\nDOMAIN-SUFFIX,tech2.in.com,Proxy\nDOMAIN-SUFFIX,roigbus.es,Proxy\nDOMAIN-SUFFIX,www.2015.xxx,Proxy\nDOMAIN-SUFFIX,faceofliberty.com,Proxy\nDOMAIN-SUFFIX,hornymatches.com,Proxy\nDOMAIN-SUFFIX,www.x78bb.com,Proxy\nDOMAIN-SUFFIX,www.cycfv.com.tw,Proxy\nDOMAIN-SUFFIX,www.coasiaholdings.com,Proxy\nDOMAIN-SUFFIX,ipkmedia.com,Proxy\nDOMAIN-SUFFIX,moeaic.gov.tw,Proxy\nDOMAIN-SUFFIX,s1.ccccc.in,Proxy\nDOMAIN-SUFFIX,hyoutube.com,Proxy\nDOMAIN-SUFFIX,33388.com,Proxy\nDOMAIN-SUFFIX,audioboom.com,Proxy\nDOMAIN-SUFFIX,www.riche88.com,Proxy\nDOMAIN-SUFFIX,www.quotev.com,Proxy\nDOMAIN-SUFFIX,www.padh.net,Proxy\nDOMAIN-SUFFIX,rusvpn.com,Proxy\nDOMAIN-SUFFIX,mykvbprime.asia,Proxy\nDOMAIN-SUFFIX,tragicbeyond.com,Proxy\nDOMAIN-SUFFIX,in.yahoo.com,Proxy\nDOMAIN-SUFFIX,bwgyhw.com,Proxy\nDOMAIN-SUFFIX,let911.com,Proxy\nDOMAIN-SUFFIX,rex9559.com,Proxy\nDOMAIN-SUFFIX,gachinco.com,Proxy\nDOMAIN-SUFFIX,63.effers.com,Proxy\nDOMAIN-SUFFIX,doh.lacontrevoie.fr,Proxy\nDOMAIN-SUFFIX,your-dns.run,Proxy\nDOMAIN-SUFFIX,cms.gov,Proxy\nDOMAIN-SUFFIX,ardmediathek.de,Proxy\nDOMAIN-SUFFIX,google.com,Proxy\nDOMAIN-SUFFIX,www.aptistock.com,Proxy\nDOMAIN-SUFFIX,zergnet.com,Proxy\nDOMAIN-SUFFIX,gaoloumi.cc,Proxy\nDOMAIN-SUFFIX,m.udn.com,Proxy\nDOMAIN-SUFFIX,www.claro.com.br,Proxy\nDOMAIN-SUFFIX,xvxx888.com,Proxy\nDOMAIN-SUFFIX,cs689.com,Proxy\nDOMAIN-SUFFIX,westca.com,Proxy\nDOMAIN-SUFFIX,youtube.es,Proxy\nDOMAIN-SUFFIX,boxun11.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,openvpn.net,Proxy\nDOMAIN-SUFFIX,wsj.com,Proxy\nDOMAIN-SUFFIX,d20cawbzduqk25.cloudfront.net,Proxy\nDOMAIN-SUFFIX,pewsocialtrends.org,Proxy\nDOMAIN-SUFFIX,h5.ld071.com,Proxy\nDOMAIN-SUFFIX,pierreobscure.eklablog.com,Proxy\nDOMAIN-SUFFIX,www.jazzradio.com,Proxy\nDOMAIN-SUFFIX,beauty.ulifestyle.com.hk,Proxy\nDOMAIN-SUFFIX,annas-archive.org,Proxy\nDOMAIN-SUFFIX,program-think.blogspot.hk,Proxy\nDOMAIN-SUFFIX,d24cpimf8b0gb8.cloudfront.net,Proxy\nDOMAIN-SUFFIX,uniteddaily.com.my,Proxy\nDOMAIN-SUFFIX,vincnd.com,Proxy\nDOMAIN-SUFFIX,www.euroleisure.net,Proxy\nDOMAIN-SUFFIX,cn.man993.com,Proxy\nDOMAIN-SUFFIX,yx1188.com,Proxy\nDOMAIN-SUFFIX,zomobo.net,Proxy\nDOMAIN-SUFFIX,mensrush.tv,Proxy\nDOMAIN-SUFFIX,bitcoin.com,Proxy\nDOMAIN-SUFFIX,3202.com,Proxy\nDOMAIN-SUFFIX,roccosiffredi.com,Proxy\nDOMAIN-SUFFIX,03641a.com,Proxy\nDOMAIN-SUFFIX,mozhua.net,Proxy\nDOMAIN-SUFFIX,tibet.de,Proxy\nDOMAIN-SUFFIX,www.pornblade.com,Proxy\nDOMAIN-SUFFIX,tvyoutube.com,Proxy\nDOMAIN-SUFFIX,blade-master-hk.blogspot.hk,Proxy\nDOMAIN-SUFFIX,charter08.com,Proxy\nDOMAIN-SUFFIX,www.audioverse.org,Proxy\nDOMAIN-SUFFIX,danwang.co,Proxy\nDOMAIN-SUFFIX,rivieri.com.ar,Proxy\nDOMAIN-SUFFIX,doctorvoice.org,Proxy\nDOMAIN-SUFFIX,www.g8mm.com,Proxy\nDOMAIN-SUFFIX,www.myyogaworks.com,Proxy\nDOMAIN-SUFFIX,1500kai.com,Proxy\nDOMAIN-SUFFIX,nitter.snopyta.org,Proxy\nDOMAIN-SUFFIX,18jack.com,Proxy\nDOMAIN-SUFFIX,directsupport.pt,Proxy\nDOMAIN-SUFFIX,csw.org.uk,Proxy\nDOMAIN-SUFFIX,lvdp.net,Proxy\nDOMAIN-SUFFIX,1049.com,Proxy\nDOMAIN-SUFFIX,la-conjugaison.fr,Proxy\nDOMAIN-SUFFIX,peacefire.org,Proxy\nDOMAIN-SUFFIX,thebcomplex.com,Proxy\nDOMAIN-SUFFIX,www.e8951.com,Proxy\nDOMAIN-SUFFIX,femaleagent.com,Proxy\nDOMAIN-SUFFIX,d2pass.com,Proxy\nDOMAIN-SUFFIX,zenhabits.net,Proxy\nDOMAIN-SUFFIX,fq.wikia.com,Proxy\nDOMAIN-SUFFIX,mixx.com,Proxy\nDOMAIN-SUFFIX,nicholaszuger.com,Proxy\nDOMAIN-SUFFIX,grandtrial.org,Proxy\nDOMAIN-SUFFIX,ampj10.com,Proxy\nDOMAIN-SUFFIX,freeproxy.net,Proxy\nDOMAIN-SUFFIX,puti.org,Proxy\nDOMAIN-SUFFIX,steffen-oliver.de,Proxy\nDOMAIN-SUFFIX,xiezi.us,Proxy\nDOMAIN-SUFFIX,oms6.dhcp.biz,Proxy\nDOMAIN-SUFFIX,1mobile.com,Proxy\nDOMAIN-SUFFIX,fairchildtv.com,Proxy\nDOMAIN-SUFFIX,mua6sf.net,Proxy\nDOMAIN-SUFFIX,gogotunnel.com,Proxy\nDOMAIN-SUFFIX,www.chitujsq.com,Proxy\nDOMAIN-SUFFIX,www.garudalinux.org,Proxy\nDOMAIN-SUFFIX,xh1789.com,Proxy\nDOMAIN-SUFFIX,www.yizhihongxing2017.com,Proxy\nDOMAIN-SUFFIX,tibetconnection.org,Proxy\nDOMAIN-SUFFIX,daikynguyen.com,Proxy\nDOMAIN-SUFFIX,odvr.nic.cz,Proxy\nDOMAIN-SUFFIX,www.oricon.co.jp,Proxy\nDOMAIN-SUFFIX,s22.slyip.net,Proxy\nDOMAIN-SUFFIX,facebook.com,Proxy\nDOMAIN-SUFFIX,popyard.org,Proxy\nDOMAIN-SUFFIX,hkhrc.org.hk,Proxy\nDOMAIN-SUFFIX,www.tour-ntpc.com,Proxy\nDOMAIN-SUFFIX,www.bcbay.com,Proxy\nDOMAIN-SUFFIX,admob.com,Proxy\nDOMAIN-SUFFIX,www.lumen.com,Proxy\nDOMAIN-SUFFIX,blog.fizzik.com,Proxy\nDOMAIN-SUFFIX,lingq.com,Proxy\nDOMAIN-SUFFIX,fun5520.com,Proxy\nDOMAIN-SUFFIX,justsexygallery.blogspot.hk,Proxy\nDOMAIN-SUFFIX,www.yxorproxy.com,Proxy\nDOMAIN-SUFFIX,www.shadowgov.tw,Proxy\nDOMAIN-SUFFIX,1951199.com,Proxy\nDOMAIN-SUFFIX,review33.com,Proxy\nDOMAIN-SUFFIX,wenyunchao.com,Proxy\nDOMAIN-SUFFIX,www.ganden.org,Proxy\nDOMAIN-SUFFIX,sosambiente.cl,Proxy\nDOMAIN-SUFFIX,www.18luckportal.biz,Proxy\nDOMAIN-SUFFIX,161sex.com,Proxy\nDOMAIN-SUFFIX,thechinaproject.com,Proxy\nDOMAIN-SUFFIX,5isotoi5.org,Proxy\nDOMAIN-SUFFIX,sr04.nflfan.org,Proxy\nDOMAIN-SUFFIX,brit.co,Proxy\nDOMAIN-SUFFIX,koaservice.nl,Proxy\nDOMAIN-SUFFIX,www.babysaying.net,Proxy\nDOMAIN-SUFFIX,21join.com,Proxy\nDOMAIN-SUFFIX,blog.fuckgfw233.org,Proxy\nDOMAIN-SUFFIX,sonicbbs.cc,Proxy\nDOMAIN-SUFFIX,martsangkagyuofficial.org,Proxy\nDOMAIN-SUFFIX,tv3.ignorelist.com,Proxy\nDOMAIN-SUFFIX,ws.dnsmail.xyz,Proxy\nDOMAIN-SUFFIX,www.livecoin.net,Proxy\nDOMAIN-SUFFIX,inkbunny.net,Proxy\nDOMAIN-SUFFIX,highrockmedia.com,Proxy\nDOMAIN-SUFFIX,85tube.com,Proxy\nDOMAIN-SUFFIX,gaozhisheng.org,Proxy\nDOMAIN-SUFFIX,www.bskk.com,Proxy\nDOMAIN-SUFFIX,www.jav007.com,Proxy\nDOMAIN-SUFFIX,www.yhusd.net,Proxy\nDOMAIN-SUFFIX,bi-si7.xyz,Proxy\nDOMAIN-SUFFIX,www.77msc.com,Proxy\nDOMAIN-SUFFIX,lovely.cl,Proxy\nDOMAIN-SUFFIX,ibasis.net,Proxy\nDOMAIN-SUFFIX,49.hobby-site.org,Proxy\nDOMAIN-SUFFIX,williamlong.jaiku.com,Proxy\nDOMAIN-SUFFIX,dvdba.cc,Proxy\nDOMAIN-SUFFIX,myforum.com.hk,Proxy\nDOMAIN-SUFFIX,mobile-4day.blogspot.ca,Proxy\nDOMAIN-SUFFIX,localpresshk.com,Proxy\nDOMAIN-SUFFIX,servebbs.com,Proxy\nDOMAIN-SUFFIX,bebo.com,Proxy\nDOMAIN-SUFFIX,d10t53jo20gzvv.cloudfront.net,Proxy\nDOMAIN-SUFFIX,tbrc.org,Proxy\nDOMAIN-SUFFIX,amnesty.org.hk,Proxy\nDOMAIN-SUFFIX,v2dn.com,Proxy\nDOMAIN-SUFFIX,picidae.net,Proxy\nDOMAIN-SUFFIX,www.tianshif.com,Proxy\nDOMAIN-SUFFIX,www.westernsafari.com.au,Proxy\nDOMAIN-SUFFIX,3774.com,Proxy\nDOMAIN-SUFFIX,rocksandco.com,Proxy\nDOMAIN-SUFFIX,ths.la,Proxy\nDOMAIN-SUFFIX,www.prutoncapital.com,Proxy\nDOMAIN-SUFFIX,www.16151100.com,Proxy\nDOMAIN-SUFFIX,www.gdaily.org,Proxy\nDOMAIN-SUFFIX,mp3hub.net,Proxy\nDOMAIN-SUFFIX,nakuz.com,Proxy\nDOMAIN-SUFFIX,9aaa5.com,Proxy\nDOMAIN-SUFFIX,carrd.co,Proxy\nDOMAIN-SUFFIX,littletikes.com,Proxy\nDOMAIN-SUFFIX,men-tsee-khang.org,Proxy\nDOMAIN-SUFFIX,dharamsalanet.com,Proxy\nDOMAIN-SUFFIX,www.ruleporn.com,Proxy\nDOMAIN-SUFFIX,program-think-mirror.github.io,Proxy\nDOMAIN-SUFFIX,www.future-interactive.net,Proxy\nDOMAIN-SUFFIX,by.bnaz.org,Proxy\nDOMAIN-SUFFIX,roscenzura.com,Proxy\nDOMAIN-SUFFIX,www.newsdetox.ca,Proxy\nDOMAIN-SUFFIX,dsn3373.com,Proxy\nDOMAIN-SUFFIX,www.on-online.de,Proxy\nDOMAIN-SUFFIX,www.heizhizhu.net,Proxy\nDOMAIN-SUFFIX,gw-pro-prod.wickr.com,Proxy\nDOMAIN-SUFFIX,flyingv.cc,Proxy\nDOMAIN-SUFFIX,www.waarbenjij.nl,Proxy\nDOMAIN-SUFFIX,www09.eyny.com,Proxy\nDOMAIN-SUFFIX,bkpi666.com,Proxy\nDOMAIN-SUFFIX,freebrowser.com,Proxy\nDOMAIN-SUFFIX,www.naifei.org,Proxy\nDOMAIN-SUFFIX,3393.ca182.com,Proxy\nDOMAIN-SUFFIX,www.adventist.org,Proxy\nDOMAIN-SUFFIX,thepiratebay.co.uk,Proxy\nDOMAIN-SUFFIX,www.krza.org,Proxy\nDOMAIN-SUFFIX,rojo.com,Proxy\nDOMAIN-SUFFIX,jbo84.com,Proxy\nDOMAIN-SUFFIX,www.myborderlife.com,Proxy\nDOMAIN-SUFFIX,iownyour.org,Proxy\nDOMAIN-SUFFIX,www.proxyguy.com,Proxy\nDOMAIN-SUFFIX,jingking.ca,Proxy\nDOMAIN-SUFFIX,mercadolibre.cl,Proxy\nDOMAIN-SUFFIX,h285.com,Proxy\nDOMAIN-SUFFIX,wexiaobo.org,Proxy\nDOMAIN-SUFFIX,facebook.it,Proxy\nDOMAIN-SUFFIX,seekbang.com,Proxy\nDOMAIN-SUFFIX,esudog.top,Proxy\nDOMAIN-SUFFIX,3tui.net,Proxy\nDOMAIN-SUFFIX,piratebay.com,Proxy\nDOMAIN-SUFFIX,www.concealme.com,Proxy\nDOMAIN-SUFFIX,www.hillhousecap.com,Proxy\nDOMAIN-SUFFIX,overcast.fm,Proxy\nDOMAIN-SUFFIX,www.cnusgfx.com,Proxy\nDOMAIN-SUFFIX,rosenheim24.de,Proxy\nDOMAIN-SUFFIX,api.path.com,Proxy\nDOMAIN-SUFFIX,www.sina.com.hk,Proxy\nDOMAIN-SUFFIX,gourmetkc.blogspot.hk,Proxy\nDOMAIN-SUFFIX,neverware.com,Proxy\nDOMAIN-SUFFIX,cclife.ca,Proxy\nDOMAIN-SUFFIX,entirelyorange.com,Proxy\nDOMAIN-SUFFIX,i999.life,Proxy\nDOMAIN-SUFFIX,teleshow.org,Proxy\nDOMAIN-SUFFIX,p7666.com,Proxy\nDOMAIN-SUFFIX,www.juneesoutherncross.com.au,Proxy\nDOMAIN-SUFFIX,www.baixingse.com,Proxy\nDOMAIN-SUFFIX,genius.com,Proxy\nDOMAIN-SUFFIX,sodopee.org,Proxy\nDOMAIN-SUFFIX,invidious.garudalinux.org,Proxy\nDOMAIN-SUFFIX,ww611.net,Proxy\nDOMAIN-SUFFIX,fulltilt.com,Proxy\nDOMAIN-SUFFIX,am1799.com,Proxy\nDOMAIN-SUFFIX,chinacenter.net,Proxy\nDOMAIN-SUFFIX,www.onlinetvrecorder.com,Proxy\nDOMAIN-SUFFIX,www.bb-live.de,Proxy\nDOMAIN-SUFFIX,proxy-free.org,Proxy\nDOMAIN-SUFFIX,51ani.net,Proxy\nDOMAIN-SUFFIX,fingerdaily.com,Proxy\nDOMAIN-SUFFIX,www.rlcinvest.com,Proxy\nDOMAIN-SUFFIX,www.lddb.com,Proxy\nDOMAIN-SUFFIX,diasp.org,Proxy\nDOMAIN-SUFFIX,aff.ptw8.com,Proxy\nDOMAIN-SUFFIX,www.ys7000.com,Proxy\nDOMAIN-SUFFIX,www.dafastory.com,Proxy\nDOMAIN-SUFFIX,newscn.org,Proxy\nDOMAIN-SUFFIX,marianwoods.gq,Proxy\nDOMAIN-SUFFIX,pride.google,Proxy\nDOMAIN-SUFFIX,spaceboop.com,Proxy\nDOMAIN-SUFFIX,www.lzjscript.com,Proxy\nDOMAIN-SUFFIX,tweepmag.com,Proxy\nDOMAIN-SUFFIX,inpho.ie,Proxy\nDOMAIN-SUFFIX,a5.com.ru,Proxy\nDOMAIN-SUFFIX,ma.twimg.com,Proxy\nDOMAIN-SUFFIX,hidecloud.com,Proxy\nDOMAIN-SUFFIX,socialism.org.tw,Proxy\nDOMAIN-SUFFIX,www.catandthefiddle.com,Proxy\nDOMAIN-SUFFIX,aoxvpn.com,Proxy\nDOMAIN-SUFFIX,www.youtube.com.my,Proxy\nDOMAIN-SUFFIX,holybiblesays.org,Proxy\nDOMAIN-SUFFIX,www.faceapp.com,Proxy\nDOMAIN-SUFFIX,wiksa.com,Proxy\nDOMAIN-SUFFIX,www.3728a.com,Proxy\nDOMAIN-SUFFIX,www.limevpn.com,Proxy\nDOMAIN-SUFFIX,sciosigma.com,Proxy\nDOMAIN-SUFFIX,yeeyi.com,Proxy\nDOMAIN-SUFFIX,mypornstarblogs.com,Proxy\nDOMAIN-SUFFIX,ted.com,Proxy\nDOMAIN-SUFFIX,stanford.edu,Proxy\nDOMAIN-SUFFIX,newsblur.com,Proxy\nDOMAIN-SUFFIX,night12.cc,Proxy\nDOMAIN-SUFFIX,zattoo.com,Proxy\nDOMAIN-SUFFIX,3bmmavpm.life,Proxy\nDOMAIN-SUFFIX,www.tca.org.tw,Proxy\nDOMAIN-SUFFIX,ms88444.com,Proxy\nDOMAIN-SUFFIX,dailysignal.com,Proxy\nDOMAIN-SUFFIX,gcore.jsdelivr.net,Proxy\nDOMAIN-SUFFIX,www.linkingbooks.com.tw,Proxy\nDOMAIN-SUFFIX,www.jintian.net,Proxy\nDOMAIN-SUFFIX,wikileaks.ch,Proxy\nDOMAIN-SUFFIX,fc2live.us,Proxy\nDOMAIN-SUFFIX,fun024.com,Proxy\nDOMAIN-SUFFIX,iii337.net,Proxy\nDOMAIN-SUFFIX,www.1914152.com,Proxy\nDOMAIN-SUFFIX,www.18lib.com,Proxy\nDOMAIN-SUFFIX,hon.net.au,Proxy\nDOMAIN-SUFFIX,www.sciencenets.com,Proxy\nDOMAIN-SUFFIX,www.altria.com,Proxy\nDOMAIN-SUFFIX,bmwso.com,Proxy\nDOMAIN-SUFFIX,lhakar.org,Proxy\nDOMAIN-SUFFIX,dlercloud.me,Proxy\nDOMAIN-SUFFIX,dotplane.com,Proxy\nDOMAIN-SUFFIX,justmysocks2.net,Proxy\nDOMAIN-SUFFIX,www.uyghurcultuurcentrum.com,Proxy\nDOMAIN-SUFFIX,steamcommunity.com,Proxy\nDOMAIN-SUFFIX,pc.gr,Proxy\nDOMAIN-SUFFIX,clocate.com,Proxy\nDOMAIN-SUFFIX,tui.orzdream.com,Proxy\nDOMAIN-SUFFIX,linux.org.hk,Proxy\nDOMAIN-SUFFIX,twtrland.com,Proxy\nDOMAIN-SUFFIX,linktr.ee,Proxy\nDOMAIN-SUFFIX,141jj.com,Proxy\nDOMAIN-SUFFIX,d3lpzzqt0dwkuv.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.fdzeta.com,Proxy\nDOMAIN-SUFFIX,y9f5i6q5.stackpathcdn.com,Proxy\nDOMAIN-SUFFIX,885xx.me,Proxy\nDOMAIN-SUFFIX,pa.wikimedia.us,Proxy\nDOMAIN-SUFFIX,searchenginewatch.com,Proxy\nDOMAIN-SUFFIX,go-pki.com,Proxy\nDOMAIN-SUFFIX,www.uncledos.com,Proxy\nDOMAIN-SUFFIX,jezets.com,Proxy\nDOMAIN-SUFFIX,www.kyoto-np.co.jp,Proxy\nDOMAIN-SUFFIX,69.run,Proxy\nDOMAIN-SUFFIX,weiboleak.com,Proxy\nDOMAIN-SUFFIX,mwds.co.za,Proxy\nDOMAIN-SUFFIX,www5017.com,Proxy\nDOMAIN-SUFFIX,ismaelan.com,Proxy\nDOMAIN-SUFFIX,www.xfinity.net,Proxy\nDOMAIN-SUFFIX,rr4---sn-i5f5ppuxa-ioal.gvt1.com,Proxy\nDOMAIN-SUFFIX,orient-doll.com,Proxy\nDOMAIN-SUFFIX,fanwen.5article.com,Proxy\nDOMAIN-SUFFIX,www.redflag.org.au,Proxy\nDOMAIN-SUFFIX,h695.com,Proxy\nDOMAIN-SUFFIX,www.bway889900.com,Proxy\nDOMAIN-SUFFIX,list.glype.com,Proxy\nDOMAIN-SUFFIX,taiwanjustice.com,Proxy\nDOMAIN-SUFFIX,www.tim.it,Proxy\nDOMAIN-SUFFIX,www.myflare.com,Proxy\nDOMAIN-SUFFIX,www.penguin.co.uk,Proxy\nDOMAIN-SUFFIX,conversations.im,Proxy\nDOMAIN-SUFFIX,tb9904.com,Proxy\nDOMAIN-SUFFIX,googlecommerce.com,Proxy\nDOMAIN-SUFFIX,bgvpn.com,Proxy\nDOMAIN-SUFFIX,d2.dhcp.biz,Proxy\nDOMAIN-SUFFIX,ssu.tw,Proxy\nDOMAIN-SUFFIX,douhokanko.net,Proxy\nDOMAIN-SUFFIX,d6w1gd3k8phsc.cloudfront.net,Proxy\nDOMAIN-SUFFIX,qlf-doh.inria.fr,Proxy\nDOMAIN-SUFFIX,freespiritfestival.com,Proxy\nDOMAIN-SUFFIX,zh9.epizy.com,Proxy\nDOMAIN-SUFFIX,beerolympics.se,Proxy\nDOMAIN-SUFFIX,cao.im,Proxy\nDOMAIN-SUFFIX,d1.x8e9ft7k.com,Proxy\nDOMAIN-SUFFIX,syjidh1.xyz,Proxy\nDOMAIN-SUFFIX,apigee.com,Proxy\nDOMAIN-SUFFIX,defcon.org,Proxy\nDOMAIN-SUFFIX,jmcomic1.love,Proxy\nDOMAIN-SUFFIX,feature.hodo.jiji.com,Proxy\nDOMAIN-SUFFIX,alive.bar,Proxy\nDOMAIN-SUFFIX,uploaded.to,Proxy\nDOMAIN-SUFFIX,www.cchere.com,Proxy\nDOMAIN-SUFFIX,iqqtv2.one,Proxy\nDOMAIN-SUFFIX,www.songkimo.com,Proxy\nDOMAIN-SUFFIX,safeyoutube.com,Proxy\nDOMAIN-SUFFIX,google.com.ua,Proxy\nDOMAIN-SUFFIX,orientaldaily.com.my,Proxy\nDOMAIN-SUFFIX,tibetaid.org,Proxy\nDOMAIN-SUFFIX,dictatorwatch.org,Proxy\nDOMAIN-SUFFIX,yuren22.com,Proxy\nDOMAIN-SUFFIX,gfbv.de,Proxy\nDOMAIN-SUFFIX,bloombergbriefs.com,Proxy\nDOMAIN-SUFFIX,www.autohdforyoutube.com,Proxy\nDOMAIN-SUFFIX,3022.com,Proxy\nDOMAIN-SUFFIX,srocket.us,Proxy\nDOMAIN-SUFFIX,www.thlib.org,Proxy\nDOMAIN-SUFFIX,libreswan.org,Proxy\nDOMAIN-SUFFIX,ahpan.com,Proxy\nDOMAIN-SUFFIX,8587s.cc,Proxy\nDOMAIN-SUFFIX,genesisg.com.ar,Proxy\nDOMAIN-SUFFIX,1056435.com,Proxy\nDOMAIN-SUFFIX,hcs.faceheart.com,Proxy\nDOMAIN-SUFFIX,ampoll.com,Proxy\nDOMAIN-SUFFIX,cdn.cospuri.com,Proxy\nDOMAIN-SUFFIX,sujiawei.howbbs.com,Proxy\nDOMAIN-SUFFIX,www.cpb.nl,Proxy\nDOMAIN-SUFFIX,www.fttt-dt.org,Proxy\nDOMAIN-SUFFIX,www.getgreenjsq.com,Proxy\nDOMAIN-SUFFIX,llss.me,Proxy\nDOMAIN-SUFFIX,cuzo.org,Proxy\nDOMAIN-SUFFIX,bdsmtv.cc,Proxy\nDOMAIN-SUFFIX,nic.cz.cc,Proxy\nDOMAIN-SUFFIX,sndcdn.com,Proxy\nDOMAIN-SUFFIX,ticketmonster.co.kr,Proxy\nDOMAIN-SUFFIX,docker.com,Proxy\nDOMAIN-SUFFIX,doh.mili.one,Proxy\nDOMAIN-SUFFIX,d2p0i88pslike9.cloudfront.net,Proxy\nDOMAIN-SUFFIX,astraios.hohai.cf,Proxy\nDOMAIN-SUFFIX,trownsoft.starfree.jp,Proxy\nDOMAIN-SUFFIX,job.achi.idv.tw,Proxy\nDOMAIN-SUFFIX,huobipro.com,Proxy\nDOMAIN-SUFFIX,www.erito.com,Proxy\nDOMAIN-SUFFIX,freeradical.zone,Proxy\nDOMAIN-SUFFIX,makkahlive.net,Proxy\nDOMAIN-SUFFIX,chatnook.com,Proxy\nDOMAIN-SUFFIX,chihan.tv,Proxy\nDOMAIN-SUFFIX,6j6.top,Proxy\nDOMAIN-SUFFIX,www.lanouvellerepublique.fr,Proxy\nDOMAIN-SUFFIX,beachcom.org,Proxy\nDOMAIN-SUFFIX,633ca.com,Proxy\nDOMAIN-SUFFIX,d23kw0xzsxgmkz.cloudfront.net,Proxy\nDOMAIN-SUFFIX,is-very-good.org,Proxy\nDOMAIN-SUFFIX,ddjppt.shop,Proxy\nDOMAIN-SUFFIX,pizzadude.ca,Proxy\nDOMAIN-SUFFIX,nepusoku.com,Proxy\nDOMAIN-SUFFIX,yyg.deptofhealth.xyz,Proxy\nDOMAIN-SUFFIX,blog.soylent.com,Proxy\nDOMAIN-SUFFIX,soylentnews.org,Proxy\nDOMAIN-SUFFIX,ehtracker.org,Proxy\nDOMAIN-SUFFIX,pornairav.com,Proxy\nDOMAIN-SUFFIX,doubleclick.net,Proxy\nDOMAIN-SUFFIX,bittorrent.am,Proxy\nDOMAIN-SUFFIX,www.musicacopyleft.es,Proxy\nDOMAIN-SUFFIX,a-lib.net,Proxy\nDOMAIN-SUFFIX,memehk.com,Proxy\nDOMAIN-SUFFIX,www.taiwanonline.cc,Proxy\nDOMAIN-SUFFIX,zeobit.com,Proxy\nDOMAIN-SUFFIX,tuesdayroad.com,Proxy\nDOMAIN-SUFFIX,www.fuldaerzeitung.de,Proxy\nDOMAIN-SUFFIX,thkphoto.com,Proxy\nDOMAIN-SUFFIX,totally-wild.com,Proxy\nDOMAIN-SUFFIX,www.thetarimnetwork.com,Proxy\nDOMAIN-SUFFIX,www.9ssr.com,Proxy\nDOMAIN-SUFFIX,24smile.org,Proxy\nDOMAIN-SUFFIX,blogspot.tw,Proxy\nDOMAIN-SUFFIX,www.2-vpn1.com,Proxy\nDOMAIN-SUFFIX,google.co.ck,Proxy\nDOMAIN-SUFFIX,google.af,Proxy\nDOMAIN-SUFFIX,andygod.com,Proxy\nDOMAIN-SUFFIX,bookos-z1.org,Proxy\nDOMAIN-SUFFIX,boyboy1.xyz,Proxy\nDOMAIN-SUFFIX,weathtown.com,Proxy\nDOMAIN-SUFFIX,akademiye.org,Proxy\nDOMAIN-SUFFIX,gmhz.org,Proxy\nDOMAIN-SUFFIX,jpopforum.net,Proxy\nDOMAIN-SUFFIX,sarmiento.cl,Proxy\nDOMAIN-SUFFIX,1688.com.au,Proxy\nDOMAIN-SUFFIX,powerphoto.org,Proxy\nDOMAIN-SUFFIX,rb881.com,Proxy\nDOMAIN-SUFFIX,tv.jumpingcrab.com,Proxy\nDOMAIN-SUFFIX,www.raidcall.com.tw,Proxy\nDOMAIN-SUFFIX,www.cssa.org.tw,Proxy\nDOMAIN-SUFFIX,ca932.com,Proxy\nDOMAIN-SUFFIX,www.ero-guide.com,Proxy\nDOMAIN-SUFFIX,caitlin.top,Proxy\nDOMAIN-SUFFIX,vpnfan.com,Proxy\nDOMAIN-SUFFIX,glp.tv,Proxy\nDOMAIN-SUFFIX,scatrina.com,Proxy\nDOMAIN-SUFFIX,scriptspot.com,Proxy\nDOMAIN-SUFFIX,www.jiayouyabeijing.com,Proxy\nDOMAIN-SUFFIX,www.folgariaski.com,Proxy\nDOMAIN-SUFFIX,gg.gg,Proxy\nDOMAIN-SUFFIX,d22weoaxwadxjh.cloudfront.net,Proxy\nDOMAIN-SUFFIX,martinoticias.com,Proxy\nDOMAIN-SUFFIX,www.tivysideadvertiser.co.uk,Proxy\nDOMAIN-SUFFIX,sinaga.id,Proxy\nDOMAIN-SUFFIX,uorcharity.wixsite.com,Proxy\nDOMAIN-SUFFIX,trendhunter.com,Proxy\nDOMAIN-SUFFIX,www.mingpaosf.com,Proxy\nDOMAIN-SUFFIX,www.mj-sp.com,Proxy\nDOMAIN-SUFFIX,vivthomas.com,Proxy\nDOMAIN-SUFFIX,icegay.tv,Proxy\nDOMAIN-SUFFIX,isasecret.com,Proxy\nDOMAIN-SUFFIX,polishdating.co.uk,Proxy\nDOMAIN-SUFFIX,00899a.com,Proxy\nDOMAIN-SUFFIX,iris.to,Proxy\nDOMAIN-SUFFIX,eltondisney.com,Proxy\nDOMAIN-SUFFIX,memedia.cn,Proxy\nDOMAIN-SUFFIX,www.409x.com,Proxy\nDOMAIN-SUFFIX,3dxtras.com,Proxy\nDOMAIN-SUFFIX,ddns.mobi,Proxy\nDOMAIN-SUFFIX,newstral.com,Proxy\nDOMAIN-SUFFIX,cs.cc.st,Proxy\nDOMAIN-SUFFIX,gkelite.com,Proxy\nDOMAIN-SUFFIX,www.jbo13.com,Proxy\nDOMAIN-SUFFIX,www.gotrusted.com,Proxy\nDOMAIN-SUFFIX,oculuscdn.com,Proxy\nDOMAIN-SUFFIX,thehimalayantimes.com,Proxy\nDOMAIN-SUFFIX,betvictor.com,Proxy\nDOMAIN-SUFFIX,proxyhub.ru,Proxy\nDOMAIN-SUFFIX,turkistantimes.com,Proxy\nDOMAIN-SUFFIX,chinaaid.net,Proxy\nDOMAIN-SUFFIX,www.gkfx.com,Proxy\nDOMAIN-SUFFIX,www.avoidfiltering.com,Proxy\nDOMAIN-SUFFIX,cervecerosdf.mx,Proxy\nDOMAIN-SUFFIX,xx-book.xyz,Proxy\nDOMAIN-SUFFIX,towervpn.com,Proxy\nDOMAIN-SUFFIX,moefuns1.cc,Proxy\nDOMAIN-SUFFIX,darktoy.net,Proxy\nDOMAIN-SUFFIX,ingress.com,Proxy\nDOMAIN-SUFFIX,www.flameracing.net,Proxy\nDOMAIN-SUFFIX,myip.com,Proxy\nDOMAIN-SUFFIX,asiafind.com,Proxy\nDOMAIN-SUFFIX,applestore.co.za,Proxy\nDOMAIN-SUFFIX,techspot.com,Proxy\nDOMAIN-SUFFIX,iblogserv-f.net,Proxy\nDOMAIN-SUFFIX,youjizz.com,Proxy\nDOMAIN-SUFFIX,shiatv.net,Proxy\nDOMAIN-SUFFIX,tmhk.org,Proxy\nDOMAIN-SUFFIX,endpoint915698.azureedge.net,Proxy\nDOMAIN-SUFFIX,huobi.sc,Proxy\nDOMAIN-SUFFIX,fuligirls.net,Proxy\nDOMAIN-SUFFIX,dongtidemimi.org,Proxy\nDOMAIN-SUFFIX,www.yh0106.com,Proxy\nDOMAIN-SUFFIX,www.hop.co.il,Proxy\nDOMAIN-SUFFIX,northcoastprep.org,Proxy\nDOMAIN-SUFFIX,shareeasy.xyz,Proxy\nDOMAIN-SUFFIX,qieyz.com,Proxy\nDOMAIN-SUFFIX,cdd.me,Proxy\nDOMAIN-SUFFIX,djdamon.com,Proxy\nDOMAIN-SUFFIX,goldmedalflour.com,Proxy\nDOMAIN-SUFFIX,wforum.com,Proxy\nDOMAIN-SUFFIX,registry.google,Proxy\nDOMAIN-SUFFIX,ccavgirl.com,Proxy\nDOMAIN-SUFFIX,www.jsbranding.com,Proxy\nDOMAIN-SUFFIX,iqqtv.one,Proxy\nDOMAIN-SUFFIX,rentmen.com,Proxy\nDOMAIN-SUFFIX,tcpspeed.co,Proxy\nDOMAIN-SUFFIX,banorte.com,Proxy\nDOMAIN-SUFFIX,niu.moe,Proxy\nDOMAIN-SUFFIX,nitter.platypush.tech,Proxy\nDOMAIN-SUFFIX,efs1.dhcp.biz,Proxy\nDOMAIN-SUFFIX,www.compellingtruth.org,Proxy\nDOMAIN-SUFFIX,hstern.net,Proxy\nDOMAIN-SUFFIX,izles.net,Proxy\nDOMAIN-SUFFIX,www.caribbeancompr.com,Proxy\nDOMAIN-SUFFIX,archives.gov,Proxy\nDOMAIN-SUFFIX,junior-idol-u15.eu,Proxy\nDOMAIN-SUFFIX,wuso.52lu.app,Proxy\nDOMAIN-SUFFIX,www.zonaoeste.com.do,Proxy\nDOMAIN-SUFFIX,laowaixiaohan.bloguje.com,Proxy\nDOMAIN-SUFFIX,uu.com,Proxy\nDOMAIN-SUFFIX,bandcamp.com,Proxy\nDOMAIN-SUFFIX,ingmtv.site,Proxy\nDOMAIN-SUFFIX,moblog.bradleyit.com,Proxy\nDOMAIN-SUFFIX,bigsound.org,Proxy\nDOMAIN-SUFFIX,heathnews.xyz,Proxy\nDOMAIN-SUFFIX,tcdr.com,Proxy\nDOMAIN-SUFFIX,www.tribuneindia.com,Proxy\nDOMAIN-SUFFIX,www.17lutu.com,Proxy\nDOMAIN-SUFFIX,www.alt.com,Proxy\nDOMAIN-SUFFIX,streetsamurai.com,Proxy\nDOMAIN-SUFFIX,av.qkav.co,Proxy\nDOMAIN-SUFFIX,2proxy.de,Proxy\nDOMAIN-SUFFIX,wingate.com,Proxy\nDOMAIN-SUFFIX,www.gotovy.com,Proxy\nDOMAIN-SUFFIX,ferdaus.net,Proxy\nDOMAIN-SUFFIX,dohsbq9npz1a9.cloudfront.net,Proxy\nDOMAIN-SUFFIX,xvideos.org.ua,Proxy\nDOMAIN-SUFFIX,legsjapan.com,Proxy\nDOMAIN-SUFFIX,heyzo.com,Proxy\nDOMAIN-SUFFIX,www.tpof.org,Proxy\nDOMAIN-SUFFIX,ae.hao123.com,Proxy\nDOMAIN-SUFFIX,bestvpn.jp,Proxy\nDOMAIN-SUFFIX,www.saferpay.com,Proxy\nDOMAIN-SUFFIX,bw8558.com,Proxy\nDOMAIN-SUFFIX,learn-ap-southeast-2-test-fleet01-xythos.s3.ap-southeast-2.amazonaws.com,Proxy\nDOMAIN-SUFFIX,55ky44.com,Proxy\nDOMAIN-SUFFIX,tdna.me,Proxy\nDOMAIN-SUFFIX,rfimundo.com,Proxy\nDOMAIN-SUFFIX,www.myetudes.org,Proxy\nDOMAIN-SUFFIX,touhao1995.com,Proxy\nDOMAIN-SUFFIX,godoc.org,Proxy\nDOMAIN-SUFFIX,wtop.com,Proxy\nDOMAIN-SUFFIX,dns.hostux.net,Proxy\nDOMAIN-SUFFIX,www.neuxo.com,Proxy\nDOMAIN-SUFFIX,kelvin.com.ar,Proxy\nDOMAIN-SUFFIX,freebeacon.com,Proxy\nDOMAIN-SUFFIX,neurotracker.net,Proxy\nDOMAIN-SUFFIX,njcu.edu,Proxy\nDOMAIN-SUFFIX,heyuedi.com,Proxy\nDOMAIN-SUFFIX,tanzil.net,Proxy\nDOMAIN-SUFFIX,unblockproxy.us,Proxy\nDOMAIN-SUFFIX,swissinfo.ch,Proxy\nDOMAIN-SUFFIX,506.cleansite.us,Proxy\nDOMAIN-SUFFIX,www.taiwanese-oki.idv.tw,Proxy\nDOMAIN-SUFFIX,ca6055.com,Proxy\nDOMAIN-SUFFIX,www.oclearningteam.com,Proxy\nDOMAIN-SUFFIX,api.openai.com,Proxy\nDOMAIN-SUFFIX,fanbox.cc,Proxy\nDOMAIN-SUFFIX,v952.ccdior.com,Proxy\nDOMAIN-SUFFIX,bbcdn.fun,Proxy\nDOMAIN-SUFFIX,rolia.net,Proxy\nDOMAIN-SUFFIX,hkbn-a.nsl-node.ml,Proxy\nDOMAIN-SUFFIX,www.moon-bbs.com,Proxy\nDOMAIN-SUFFIX,i999.live,Proxy\nDOMAIN-SUFFIX,channelchk.com,Proxy\nDOMAIN-SUFFIX,markmiraglia.com,Proxy\nDOMAIN-SUFFIX,gci.agent1818.com,Proxy\nDOMAIN-SUFFIX,reddit.co,Proxy\nDOMAIN-SUFFIX,yp.com,Proxy\nDOMAIN-SUFFIX,roro.su,Proxy\nDOMAIN-SUFFIX,twiends.com,Proxy\nDOMAIN-SUFFIX,www.fleshlight.com,Proxy\nDOMAIN-SUFFIX,www.sgreennet.com,Proxy\nDOMAIN-SUFFIX,www.razor947.com,Proxy\nDOMAIN-SUFFIX,htkou.net,Proxy\nDOMAIN-SUFFIX,d38v3a6wllozjb.cloudfront.net,Proxy\nDOMAIN-SUFFIX,irn.red,Proxy\nDOMAIN-SUFFIX,normalpornfornormalpeople.com,Proxy\nDOMAIN-SUFFIX,www.modules.pl,Proxy\nDOMAIN-SUFFIX,beatmybox.com,Proxy\nDOMAIN-SUFFIX,hp.af.cm,Proxy\nDOMAIN-SUFFIX,w.tv333.us,Proxy\nDOMAIN-SUFFIX,cninvestorist.com,Proxy\nDOMAIN-SUFFIX,youtube.com.hk,Proxy\nDOMAIN-SUFFIX,revista.gostosanovinha.com,Proxy\nDOMAIN-SUFFIX,link.storjshare.io,Proxy\nDOMAIN-SUFFIX,tv72.tk,Proxy\nDOMAIN-SUFFIX,movelbus.com.br,Proxy\nDOMAIN-SUFFIX,toomics.com,Proxy\nDOMAIN-SUFFIX,www.amateur-blogs.com,Proxy\nDOMAIN-SUFFIX,unocoin.com,Proxy\nDOMAIN-SUFFIX,passionhdfan.com,Proxy\nDOMAIN-SUFFIX,websurfingproxies.net,Proxy\nDOMAIN-SUFFIX,solos.gr,Proxy\nDOMAIN-SUFFIX,www.netflav1.com,Proxy\nDOMAIN-SUFFIX,vjav.com,Proxy\nDOMAIN-SUFFIX,olivetree.com,Proxy\nDOMAIN-SUFFIX,jmvbt.com,Proxy\nDOMAIN-SUFFIX,great-firewall.com,Proxy\nDOMAIN-SUFFIX,www.hksinolink.com.hk,Proxy\nDOMAIN-SUFFIX,lutube.me,Proxy\nDOMAIN-SUFFIX,mh4u.org,Proxy\nDOMAIN-SUFFIX,871.gr8domain.biz,Proxy\nDOMAIN-SUFFIX,mygsi.eu,Proxy\nDOMAIN-SUFFIX,virtualactivism.org,Proxy\nDOMAIN-SUFFIX,wpdiscuz.com,Proxy\nDOMAIN-SUFFIX,www.p333aa.com,Proxy\nDOMAIN-SUFFIX,www.mbmcmalaysia.org,Proxy\nDOMAIN-SUFFIX,clb.org.hk,Proxy\nDOMAIN-SUFFIX,www.chinazhw.com,Proxy\nDOMAIN-SUFFIX,snaptu.com,Proxy\nDOMAIN-SUFFIX,www.fr24news.com,Proxy\nDOMAIN-SUFFIX,anontext.com,Proxy\nDOMAIN-SUFFIX,15youtube.com,Proxy\nDOMAIN-SUFFIX,bangkokpost.com,Proxy\nDOMAIN-SUFFIX,www.005088.com,Proxy\nDOMAIN-SUFFIX,codemancy.com,Proxy\nDOMAIN-SUFFIX,openai.com,Proxy\nDOMAIN-SUFFIX,st.idv.tw,Proxy\nDOMAIN-SUFFIX,ebtcbank.com,Proxy\nDOMAIN-SUFFIX,nypost.com,Proxy\nDOMAIN-SUFFIX,ingdes.cl,Proxy\nDOMAIN-SUFFIX,www.5pool.com,Proxy\nDOMAIN-SUFFIX,g-area.org,Proxy\nDOMAIN-SUFFIX,ja.whotwi.com,Proxy\nDOMAIN-SUFFIX,lbombs.com,Proxy\nDOMAIN-SUFFIX,amarylliss.idv.tw,Proxy\nDOMAIN-SUFFIX,www.pinterest.co.uk,Proxy\nDOMAIN-SUFFIX,blog.jpmahjong.net,Proxy\nDOMAIN-SUFFIX,netfreerouter.com,Proxy\nDOMAIN-SUFFIX,mail.cod.edu,Proxy\nDOMAIN-SUFFIX,www.bestknew.com,Proxy\nDOMAIN-SUFFIX,zh.wikisource.org,Proxy\nDOMAIN-SUFFIX,eromanga-kingdom.com,Proxy\nDOMAIN-SUFFIX,centralnation.com,Proxy\nDOMAIN-SUFFIX,linktv.org,Proxy\nDOMAIN-SUFFIX,www.pureland-buddhism.org,Proxy\nDOMAIN-SUFFIX,easyinstagram.com,Proxy\nDOMAIN-SUFFIX,de.cam4.com,Proxy\nDOMAIN-SUFFIX,jansolo.com,Proxy\nDOMAIN-SUFFIX,jiangweiping.com,Proxy\nDOMAIN-SUFFIX,www.merics.de,Proxy\nDOMAIN-SUFFIX,gzm.tv,Proxy\nDOMAIN-SUFFIX,wealth.com.tw,Proxy\nDOMAIN-SUFFIX,www.avatrade.cn,Proxy\nDOMAIN-SUFFIX,webproxy-service.de,Proxy\nDOMAIN-SUFFIX,bird.so,Proxy\nDOMAIN-SUFFIX,www.guomoo.co,Proxy\nDOMAIN-SUFFIX,proton.me,Proxy\nDOMAIN-SUFFIX,torrentleech.org,Proxy\nDOMAIN-SUFFIX,bnews.co,Proxy\nDOMAIN-SUFFIX,www.sr-71.org,Proxy\nDOMAIN-SUFFIX,08charter-tw.pbworks.com,Proxy\nDOMAIN-SUFFIX,iamtopone.com,Proxy\nDOMAIN-SUFFIX,yoyoav.net,Proxy\nDOMAIN-SUFFIX,frommers.com,Proxy\nDOMAIN-SUFFIX,www.ebony-beauty.com,Proxy\nDOMAIN-SUFFIX,dsn1151a.com,Proxy\nDOMAIN-SUFFIX,web23.ga,Proxy\nDOMAIN-SUFFIX,mediapeers.com,Proxy\nDOMAIN-SUFFIX,asiatoday.us,Proxy\nDOMAIN-SUFFIX,aoxvpn.co,Proxy\nDOMAIN-SUFFIX,gpsutton.co.uk,Proxy\nDOMAIN-SUFFIX,theprint.com,Proxy\nDOMAIN-SUFFIX,img.sg99.ws,Proxy\nDOMAIN-SUFFIX,zifaner.com,Proxy\nDOMAIN-SUFFIX,washingtonpost.com,Proxy\nDOMAIN-SUFFIX,www.btdx8.com,Proxy\nDOMAIN-SUFFIX,www.sim-outhouse.com,Proxy\nDOMAIN-SUFFIX,mygsi.gr,Proxy\nDOMAIN-SUFFIX,keqippoi.com,Proxy\nDOMAIN-SUFFIX,seed4.me,Proxy\nDOMAIN-SUFFIX,ssrshare.com,Proxy\nDOMAIN-SUFFIX,powercx.com,Proxy\nDOMAIN-SUFFIX,khabdha.org,Proxy\nDOMAIN-SUFFIX,wow.com,Proxy\nDOMAIN-SUFFIX,grandcentralmarket.com,Proxy\nDOMAIN-SUFFIX,bodyiglobjong.com,Proxy\nDOMAIN-SUFFIX,google.kz,Proxy\nDOMAIN-SUFFIX,www.purevpn.com.tw,Proxy\nDOMAIN-SUFFIX,vf.freepac.pw,Proxy\nDOMAIN-SUFFIX,www.theherald.com.au,Proxy\nDOMAIN-SUFFIX,sherig.org,Proxy\nDOMAIN-SUFFIX,www.google.ae,Proxy\nDOMAIN-SUFFIX,soulcaliburhentai.net,Proxy\nDOMAIN-SUFFIX,vraiesagesse.net,Proxy\nDOMAIN-SUFFIX,www.xh6789.com,Proxy\nDOMAIN-SUFFIX,aovpn.com,Proxy\nDOMAIN-SUFFIX,tcsofbc.org,Proxy\nDOMAIN-SUFFIX,yunzhanggui.strikingly.com,Proxy\nDOMAIN-SUFFIX,app365.ga,Proxy\nDOMAIN-SUFFIX,tel.meet,Proxy\nDOMAIN-SUFFIX,www.shangwaiwang.com,Proxy\nDOMAIN-SUFFIX,999601.com,Proxy\nDOMAIN-SUFFIX,netsgoes.com.br,Proxy\nDOMAIN-SUFFIX,www.kinetin.com.tw,Proxy\nDOMAIN-SUFFIX,globo.com,Proxy\nDOMAIN-SUFFIX,google.ph,Proxy\nDOMAIN-SUFFIX,53.etowns.net,Proxy\nDOMAIN-SUFFIX,26.effers.com,Proxy\nDOMAIN-SUFFIX,bodyig.tibetangeeks.com,Proxy\nDOMAIN-SUFFIX,tondalove.com,Proxy\nDOMAIN-SUFFIX,fragstore.org,Proxy\nDOMAIN-SUFFIX,bestgore.com,Proxy\nDOMAIN-SUFFIX,heix.pp.ru,Proxy\nDOMAIN-SUFFIX,platform.sshz.org,Proxy\nDOMAIN-SUFFIX,youtubetool.com,Proxy\nDOMAIN-SUFFIX,whooshkaa.com,Proxy\nDOMAIN-SUFFIX,an.1x.net,Proxy\nDOMAIN-SUFFIX,www.binancezh.co,Proxy\nDOMAIN-SUFFIX,www.youtube.co.uk,Proxy\nDOMAIN-SUFFIX,www.m88asia.com,Proxy\nDOMAIN-SUFFIX,dtdns.net,Proxy\nDOMAIN-SUFFIX,www.8899063.com,Proxy\nDOMAIN-SUFFIX,www.azg.am,Proxy\nDOMAIN-SUFFIX,e8830.com,Proxy\nDOMAIN-SUFFIX,wien.arbeiterkammer.at,Proxy\nDOMAIN-SUFFIX,chinalaborwatch.org,Proxy\nDOMAIN-SUFFIX,av77999.com,Proxy\nDOMAIN-SUFFIX,jizzmontu.com,Proxy\nDOMAIN-SUFFIX,2.cr.rs,Proxy\nDOMAIN-SUFFIX,quannengshen.org,Proxy\nDOMAIN-SUFFIX,www.fhjtchn.com,Proxy\nDOMAIN-SUFFIX,pk.com,Proxy\nDOMAIN-SUFFIX,txmao.xyz,Proxy\nDOMAIN-SUFFIX,gufeng521.spaces.live.com,Proxy\nDOMAIN-SUFFIX,shenbibi.com,Proxy\nDOMAIN-SUFFIX,di-ve.com.ar,Proxy\nDOMAIN-SUFFIX,vod.wwe.com,Proxy\nDOMAIN-SUFFIX,rui1688.com,Proxy\nDOMAIN-SUFFIX,killwall.com,Proxy\nDOMAIN-SUFFIX,lci.fr,Proxy\nDOMAIN-SUFFIX,margot.ro,Proxy\nDOMAIN-SUFFIX,02-26263428.strikingly.com,Proxy\nDOMAIN-SUFFIX,456dslr.blogspot.jp,Proxy\nDOMAIN-SUFFIX,www.navweaps.com,Proxy\nDOMAIN-SUFFIX,dgyqr055mfays.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.tubeshemales.com,Proxy\nDOMAIN-SUFFIX,youyoutube.com,Proxy\nDOMAIN-SUFFIX,mail.ru,Proxy\nDOMAIN-SUFFIX,www.monterrasol.com,Proxy\nDOMAIN-SUFFIX,share.america.gov,Proxy\nDOMAIN-SUFFIX,91porn.com,Proxy\nDOMAIN-SUFFIX,zh.liberapay.com,Proxy\nDOMAIN-SUFFIX,www.leaderlive.co.uk,Proxy\nDOMAIN-SUFFIX,av.com,Proxy\nDOMAIN-SUFFIX,ld.hao123img.com,Proxy\nDOMAIN-SUFFIX,www.independent.org,Proxy\nDOMAIN-SUFFIX,unblockall.com,Proxy\nDOMAIN-SUFFIX,lonlife.net,Proxy\nDOMAIN-SUFFIX,darrenliuwei.com,Proxy\nDOMAIN-SUFFIX,m.188betkr.com,Proxy\nDOMAIN-SUFFIX,www.kibase.com,Proxy\nDOMAIN-SUFFIX,thecrazylife.com,Proxy\nDOMAIN-SUFFIX,ys85.net,Proxy\nDOMAIN-SUFFIX,google.com.vn,Proxy\nDOMAIN-SUFFIX,blabber.im,Proxy\nDOMAIN-SUFFIX,imqtech.droppages.com,Proxy\nDOMAIN-SUFFIX,whiteteensblackcocks.com,Proxy\nDOMAIN-SUFFIX,www.amnesty.or.kr,Proxy\nDOMAIN-SUFFIX,ccaudi.com,Proxy\nDOMAIN-SUFFIX,h3399.com,Proxy\nDOMAIN-SUFFIX,communities.win,Proxy\nDOMAIN-SUFFIX,unholyknight.com,Proxy\nDOMAIN-SUFFIX,newsolidinvite.com,Proxy\nDOMAIN-SUFFIX,agvpn.com,Proxy\nDOMAIN-SUFFIX,d13j19k2elmn04.cloudfront.net,Proxy\nDOMAIN-SUFFIX,reachlocal.com,Proxy\nDOMAIN-SUFFIX,tomp3.cc,Proxy\nDOMAIN-SUFFIX,vpn.fuillc.com,Proxy\nDOMAIN-SUFFIX,wallornot.org,Proxy\nDOMAIN-SUFFIX,gonline.com,Proxy\nDOMAIN-SUFFIX,material.io,Proxy\nDOMAIN-SUFFIX,spcnwiki.top,Proxy\nDOMAIN-SUFFIX,hyperrate.com,Proxy\nDOMAIN-SUFFIX,bs-c.ntwppj.com,Proxy\nDOMAIN-SUFFIX,www.vipjs9900.com,Proxy\nDOMAIN-SUFFIX,presidentlee.tw,Proxy\nDOMAIN-SUFFIX,dynamicdns.biz,Proxy\nDOMAIN-SUFFIX,secretgarden.no,Proxy\nDOMAIN-SUFFIX,furhhdl.org,Proxy\nDOMAIN-SUFFIX,kanqj.com,Proxy\nDOMAIN-SUFFIX,63ff.net,Proxy\nDOMAIN-SUFFIX,tttan.com,Proxy\nDOMAIN-SUFFIX,my.gfw.cat,Proxy\nDOMAIN-SUFFIX,maxisito.it,Proxy\nDOMAIN-SUFFIX,airav.cc,Proxy\nDOMAIN-SUFFIX,www.mogafx.com,Proxy\nDOMAIN-SUFFIX,www.jsjt-trading.com,Proxy\nDOMAIN-SUFFIX,uruguayvpn.com,Proxy\nDOMAIN-SUFFIX,www.av28.com,Proxy\nDOMAIN-SUFFIX,magdeburg.de,Proxy\nDOMAIN-SUFFIX,www.makthes.gr,Proxy\nDOMAIN-SUFFIX,couchit.net,Proxy\nDOMAIN-SUFFIX,www.roundandbrown.com,Proxy\nDOMAIN-SUFFIX,amnistia.me,Proxy\nDOMAIN-SUFFIX,www.google.com.co,Proxy\nDOMAIN-SUFFIX,8dgo.com,Proxy\nDOMAIN-SUFFIX,intermatch.com,Proxy\nDOMAIN-SUFFIX,fe-ver.com,Proxy\nDOMAIN-SUFFIX,tb7775.com,Proxy\nDOMAIN-SUFFIX,www.kimosong.com,Proxy\nDOMAIN-SUFFIX,rocketvpn.net,Proxy\nDOMAIN-SUFFIX,bypassy.com,Proxy\nDOMAIN-SUFFIX,1337x.is,Proxy\nDOMAIN-SUFFIX,wearn.com,Proxy\nDOMAIN-SUFFIX,new-proxy.com.de,Proxy\nDOMAIN-SUFFIX,d1bgcxp91frokk.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.calgarychinese.ca,Proxy\nDOMAIN-SUFFIX,wzyboy.im,Proxy\nDOMAIN-SUFFIX,monkeywerks.net,Proxy\nDOMAIN-SUFFIX,www.mcloudware.com,Proxy\nDOMAIN-SUFFIX,aebn.net,Proxy\nDOMAIN-SUFFIX,buddhahouse.org,Proxy\nDOMAIN-SUFFIX,tw.daigobang.com,Proxy\nDOMAIN-SUFFIX,www.lendacademy.com,Proxy\nDOMAIN-SUFFIX,iwara.tv,Proxy\nDOMAIN-SUFFIX,javfor.me,Proxy\nDOMAIN-SUFFIX,toyoutube.com,Proxy\nDOMAIN-SUFFIX,blvpn.com,Proxy\nDOMAIN-SUFFIX,east.moe,Proxy\nDOMAIN-SUFFIX,www.ifunvegas.com,Proxy\nDOMAIN-SUFFIX,cs068.com,Proxy\nDOMAIN-SUFFIX,fochk.org,Proxy\nDOMAIN-SUFFIX,b3988.com,Proxy\nDOMAIN-SUFFIX,huanyin.org,Proxy\nDOMAIN-SUFFIX,mcfog.com,Proxy\nDOMAIN-SUFFIX,yyty.live,Proxy\nDOMAIN-SUFFIX,kwd.blog.jp,Proxy\nDOMAIN-SUFFIX,rebeat.it,Proxy\nDOMAIN-SUFFIX,qqjlb7.com,Proxy\nDOMAIN-SUFFIX,xvideos-field.com,Proxy\nDOMAIN-SUFFIX,822522.com,Proxy\nDOMAIN-SUFFIX,tgcomics.com,Proxy\nDOMAIN-SUFFIX,nitter.tiekoetter.com,Proxy\nDOMAIN-SUFFIX,www.psiphonsessions.com,Proxy\nDOMAIN-SUFFIX,ancsconf.org,Proxy\nDOMAIN-SUFFIX,solarsystem.nasa.gov,Proxy\nDOMAIN-SUFFIX,hj102.com,Proxy\nDOMAIN-SUFFIX,3bmm.com,Proxy\nDOMAIN-SUFFIX,33c07.com,Proxy\nDOMAIN-SUFFIX,assets.bwbx.io,Proxy\nDOMAIN-SUFFIX,cn.bongacams.sexy,Proxy\nDOMAIN-SUFFIX,www.mikalnews.com,Proxy\nDOMAIN-SUFFIX,caxata.com,Proxy\nDOMAIN-SUFFIX,7652.com,Proxy\nDOMAIN-SUFFIX,d2q1d0nryavku6.cloudfront.net,Proxy\nDOMAIN-SUFFIX,lobbyiowa.com,Proxy\nDOMAIN-SUFFIX,www.kuniao.com-1,Proxy\nDOMAIN-SUFFIX,15051100.com,Proxy\nDOMAIN-SUFFIX,jsw-deep.com,Proxy\nDOMAIN-SUFFIX,www.hongxing.in,Proxy\nDOMAIN-SUFFIX,internetfreedom.org,Proxy\nDOMAIN-SUFFIX,www.5dias.com,Proxy\nDOMAIN-SUFFIX,jhoppy.us,Proxy\nDOMAIN-SUFFIX,loli.help,Proxy\nDOMAIN-SUFFIX,shou-tv.firebaseio.com,Proxy\nDOMAIN-SUFFIX,www.e8287.com,Proxy\nDOMAIN-SUFFIX,18moe.co,Proxy\nDOMAIN-SUFFIX,jmcomic4.cc,Proxy\nDOMAIN-SUFFIX,www.tzuchi.org.nz,Proxy\nDOMAIN-SUFFIX,happysocks.com,Proxy\nDOMAIN-SUFFIX,xj5778.com,Proxy\nDOMAIN-SUFFIX,www.ji8.cc,Proxy\nDOMAIN-SUFFIX,kyofun.com,Proxy\nDOMAIN-SUFFIX,www.javl10.com,Proxy\nDOMAIN-SUFFIX,sex-11.com,Proxy\nDOMAIN-SUFFIX,feelssh.com,Proxy\nDOMAIN-SUFFIX,588999.vip,Proxy\nDOMAIN-SUFFIX,www.fuhuichinese.com,Proxy\nDOMAIN-SUFFIX,camtogays.com,Proxy\nDOMAIN-SUFFIX,facbook.com,Proxy\nDOMAIN-SUFFIX,www.ry111.com,Proxy\nDOMAIN-SUFFIX,zuqiu.la,Proxy\nDOMAIN-SUFFIX,noblock.ru,Proxy\nDOMAIN-SUFFIX,www.domaintools.com,Proxy\nDOMAIN-SUFFIX,lamar.com,Proxy\nDOMAIN-SUFFIX,www.bozhidao.com,Proxy\nDOMAIN-SUFFIX,22115.com,Proxy\nDOMAIN-SUFFIX,mercyprophet.org,Proxy\nDOMAIN-SUFFIX,18andabused.com,Proxy\nDOMAIN-SUFFIX,www.ispionline.it,Proxy\nDOMAIN-SUFFIX,ipgphotonics.box.com,Proxy\nDOMAIN-SUFFIX,forum.udn.com,Proxy\nDOMAIN-SUFFIX,siebert.cl,Proxy\nDOMAIN-SUFFIX,itemdb.com,Proxy\nDOMAIN-SUFFIX,radionz.co.nz,Proxy\nDOMAIN-SUFFIX,chocolatkey.com,Proxy\nDOMAIN-SUFFIX,ciproxy.de,Proxy\nDOMAIN-SUFFIX,agah.com,Proxy\nDOMAIN-SUFFIX,qbaby.tv,Proxy\nDOMAIN-SUFFIX,cn.hwazan.org,Proxy\nDOMAIN-SUFFIX,xijinping.fr,Proxy\nDOMAIN-SUFFIX,mybbs.us,Proxy\nDOMAIN-SUFFIX,jxvpn.com,Proxy\nDOMAIN-SUFFIX,44003885.com,Proxy\nDOMAIN-SUFFIX,223jj.net,Proxy\nDOMAIN-SUFFIX,youfinamil.redirectme.net,Proxy\nDOMAIN-SUFFIX,uy500.com,Proxy\nDOMAIN-SUFFIX,dsm9427.com,Proxy\nDOMAIN-SUFFIX,nydus.ca,Proxy\nDOMAIN-SUFFIX,desichain.com,Proxy\nDOMAIN-SUFFIX,app.flnet.org,Proxy\nDOMAIN-SUFFIX,wrchristian.com,Proxy\nDOMAIN-SUFFIX,www.aleteia.org,Proxy\nDOMAIN-SUFFIX,zuirt.cc,Proxy\nDOMAIN-SUFFIX,incloak.es,Proxy\nDOMAIN-SUFFIX,lebtimnetz.de,Proxy\nDOMAIN-SUFFIX,uzwb.fat.flnet.org,Proxy\nDOMAIN-SUFFIX,wf22.ga,Proxy\nDOMAIN-SUFFIX,mcleodganj.com,Proxy\nDOMAIN-SUFFIX,cloudstorage.naver.com,Proxy\nDOMAIN-SUFFIX,d2rdpw23tn7qg8.cloudfront.net,Proxy\nDOMAIN-SUFFIX,lamrim.com,Proxy\nDOMAIN-SUFFIX,ark.to,Proxy\nDOMAIN-SUFFIX,www.shenlaoxi.com,Proxy\nDOMAIN-SUFFIX,www.voh.com.tw,Proxy\nDOMAIN-SUFFIX,d30jn71yl63eky.cloudfront.net,Proxy\nDOMAIN-SUFFIX,puconparagliding.cl,Proxy\nDOMAIN-SUFFIX,www.0dayporno.com,Proxy\nDOMAIN-SUFFIX,stephencosgrove.com,Proxy\nDOMAIN-SUFFIX,zh.wikiepdia.org,Proxy\nDOMAIN-SUFFIX,ftv.com,Proxy\nDOMAIN-SUFFIX,mailyahoo.com,Proxy\nDOMAIN-SUFFIX,yorkbbs.ca,Proxy\nDOMAIN-SUFFIX,www.baidu.com.com,Proxy\nDOMAIN-SUFFIX,ardila.es,Proxy\nDOMAIN-SUFFIX,arunachalassembly.gov.in,Proxy\nDOMAIN-SUFFIX,viewmorepics.myspace.com,Proxy\nDOMAIN-SUFFIX,cf3.h18ani.xyz,Proxy\nDOMAIN-SUFFIX,zzx.healthsection.xyz,Proxy\nDOMAIN-SUFFIX,we-cc.xyz,Proxy\nDOMAIN-SUFFIX,on-the-web.tv,Proxy\nDOMAIN-SUFFIX,twimi.net,Proxy\nDOMAIN-SUFFIX,hwadzan.tw,Proxy\nDOMAIN-SUFFIX,googleapps.rug.nl,Proxy\nDOMAIN-SUFFIX,sub.kyapi.xyz,Proxy\nDOMAIN-SUFFIX,vpn.sv.cmu.edu,Proxy\nDOMAIN-SUFFIX,www.kckm1330.com,Proxy\nDOMAIN-SUFFIX,astrillvpn.com,Proxy\nDOMAIN-SUFFIX,wikipedia.com,Proxy\nDOMAIN-SUFFIX,paxlicense.org,Proxy\nDOMAIN-SUFFIX,www.skyvpn.us,Proxy\nDOMAIN-SUFFIX,voachinese.org,Proxy\nDOMAIN-SUFFIX,pda.ch,Proxy\nDOMAIN-SUFFIX,home.saxo,Proxy\nDOMAIN-SUFFIX,www.promostyl.com,Proxy\nDOMAIN-SUFFIX,j838.com,Proxy\nDOMAIN-SUFFIX,martinoticias.org,Proxy\nDOMAIN-SUFFIX,asstr.org,Proxy\nDOMAIN-SUFFIX,www.85porn.net,Proxy\nDOMAIN-SUFFIX,www.dorcelclub.com,Proxy\nDOMAIN-SUFFIX,hidedoor.com,Proxy\nDOMAIN-SUFFIX,cyberghostvpn.com,Proxy\nDOMAIN-SUFFIX,ecfilos.we-know.net,Proxy\nDOMAIN-SUFFIX,www.yuhuage.biz,Proxy\nDOMAIN-SUFFIX,dns04.com,Proxy\nDOMAIN-SUFFIX,www.chagtong.org,Proxy\nDOMAIN-SUFFIX,ezpeer.com,Proxy\nDOMAIN-SUFFIX,v2556.com,Proxy\nDOMAIN-SUFFIX,bbs.junglobal.net,Proxy\nDOMAIN-SUFFIX,blog.koppi.me,Proxy\nDOMAIN-SUFFIX,icams.com,Proxy\nDOMAIN-SUFFIX,lse.ac.uk,Proxy\nDOMAIN-SUFFIX,www.hkgoodjobs.com,Proxy\nDOMAIN-SUFFIX,extremeasses.com,Proxy\nDOMAIN-SUFFIX,falungong.de,Proxy\nDOMAIN-SUFFIX,www.iwxss.com,Proxy\nDOMAIN-SUFFIX,5278bbs.com,Proxy\nDOMAIN-SUFFIX,e-traderland.net,Proxy\nDOMAIN-SUFFIX,umardia.com.mx,Proxy\nDOMAIN-SUFFIX,clearharmony.net,Proxy\nDOMAIN-SUFFIX,xihua.es,Proxy\nDOMAIN-SUFFIX,zh.vpnclub.cc,Proxy\nDOMAIN-SUFFIX,ruralgenius.com,Proxy\nDOMAIN-SUFFIX,d1syczzia18ipx.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.topproxies.org,Proxy\nDOMAIN-SUFFIX,lovpn.com,Proxy\nDOMAIN-SUFFIX,9833jeep.jigsy.com,Proxy\nDOMAIN-SUFFIX,possessed.us,Proxy\nDOMAIN-SUFFIX,www.play-asia.com,Proxy\nDOMAIN-SUFFIX,6youtube.com,Proxy\nDOMAIN-SUFFIX,ngam.natixis.com,Proxy\nDOMAIN-SUFFIX,www.cnpronvpn.com,Proxy\nDOMAIN-SUFFIX,nbcbayarea.com,Proxy\nDOMAIN-SUFFIX,hen8.fat.flnet.org,Proxy\nDOMAIN-SUFFIX,realsexpass.com,Proxy\nDOMAIN-SUFFIX,hughjcatalano.com,Proxy\nDOMAIN-SUFFIX,20180l.net,Proxy\nDOMAIN-SUFFIX,findtubes.com,Proxy\nDOMAIN-SUFFIX,blog.momo.com.tw,Proxy\nDOMAIN-SUFFIX,searchtruth.com,Proxy\nDOMAIN-SUFFIX,hi5.tv,Proxy\nDOMAIN-SUFFIX,28.etowns.net,Proxy\nDOMAIN-SUFFIX,yddc1888.com,Proxy\nDOMAIN-SUFFIX,hanmanziyuan.com,Proxy\nDOMAIN-SUFFIX,freetibet.org,Proxy\nDOMAIN-SUFFIX,www.ddsqq.idv.tw,Proxy\nDOMAIN-SUFFIX,casacook.com,Proxy\nDOMAIN-SUFFIX,meridian-trust.org,Proxy\nDOMAIN-SUFFIX,www.1365365.xyz,Proxy\nDOMAIN-SUFFIX,www.ddmmelbourne.org.au,Proxy\nDOMAIN-SUFFIX,art1lib.org,Proxy\nDOMAIN-SUFFIX,www.riwi.com,Proxy\nDOMAIN-SUFFIX,www.voa.org,Proxy\nDOMAIN-SUFFIX,hkhoitong.com,Proxy\nDOMAIN-SUFFIX,freegpt.one,Proxy\nDOMAIN-SUFFIX,rho9.cleansite.us,Proxy\nDOMAIN-SUFFIX,mpettis.com,Proxy\nDOMAIN-SUFFIX,www.jrf.org.tw,Proxy\nDOMAIN-SUFFIX,www.worldlymusings.com,Proxy\nDOMAIN-SUFFIX,336.slyip.net,Proxy\nDOMAIN-SUFFIX,souleader-cn.strikingly.com,Proxy\nDOMAIN-SUFFIX,androidplus.co,Proxy\nDOMAIN-SUFFIX,www.freeyoutubeproxy.org,Proxy\nDOMAIN-SUFFIX,ishr.org,Proxy\nDOMAIN-SUFFIX,uscode.house.gov,Proxy\nDOMAIN-SUFFIX,guides.yoosecurity.com,Proxy\nDOMAIN-SUFFIX,news.seehua.com,Proxy\nDOMAIN-SUFFIX,www.gettyimages.com.au,Proxy\nDOMAIN-SUFFIX,m.sina.com.hk,Proxy\nDOMAIN-SUFFIX,ccim.org,Proxy\nDOMAIN-SUFFIX,m.dafa888.com,Proxy\nDOMAIN-SUFFIX,3dporn-pics.com,Proxy\nDOMAIN-SUFFIX,got-game.org,Proxy\nDOMAIN-SUFFIX,eroticperfection.com,Proxy\nDOMAIN-SUFFIX,agefans.net,Proxy\nDOMAIN-SUFFIX,android.jlelse.eu,Proxy\nDOMAIN-SUFFIX,www.ssi.gouv.fr,Proxy\nDOMAIN-SUFFIX,browsec.com,Proxy\nDOMAIN-SUFFIX,qporno.com,Proxy\nDOMAIN-SUFFIX,22.gotgeeks.com,Proxy\nDOMAIN-SUFFIX,www.beautifulmosque.com,Proxy\nDOMAIN-SUFFIX,hd.port0.org,Proxy\nDOMAIN-SUFFIX,www.24winbet.com,Proxy\nDOMAIN-SUFFIX,osikko.jp,Proxy\nDOMAIN-SUFFIX,jpl.nasa.gov,Proxy\nDOMAIN-SUFFIX,1e100.net,Proxy\nDOMAIN-SUFFIX,mengtingli.strikingly.com,Proxy\nDOMAIN-SUFFIX,730bm.com,Proxy\nDOMAIN-SUFFIX,ubf.kr,Proxy\nDOMAIN-SUFFIX,blog.lester850.info,Proxy\nDOMAIN-SUFFIX,bzvpn.com,Proxy\nDOMAIN-SUFFIX,bdg909.com,Proxy\nDOMAIN-SUFFIX,moo.flnet.org,Proxy\nDOMAIN-SUFFIX,m.111xfhcp.com,Proxy\nDOMAIN-SUFFIX,668p668.com,Proxy\nDOMAIN-SUFFIX,dkx996pbduw6l.cloudfront.net,Proxy\nDOMAIN-SUFFIX,carfax.com,Proxy\nDOMAIN-SUFFIX,cs586.com,Proxy\nDOMAIN-SUFFIX,www.ow.ly,Proxy\nDOMAIN-SUFFIX,theguardian.co.uk,Proxy\nDOMAIN-SUFFIX,www.portstephensexaminer.com.au,Proxy\nDOMAIN-SUFFIX,lee.easymall.com.tw,Proxy\nDOMAIN-SUFFIX,milfmovs.com,Proxy\nDOMAIN-SUFFIX,dawnwillis.ga,Proxy\nDOMAIN-SUFFIX,huaxiabao.org,Proxy\nDOMAIN-SUFFIX,xj773.com,Proxy\nDOMAIN-SUFFIX,www.google.bf,Proxy\nDOMAIN-SUFFIX,www.coastalleader.com.au,Proxy\nDOMAIN-SUFFIX,silverstructure.com,Proxy\nDOMAIN-SUFFIX,sfvpn.com,Proxy\nDOMAIN-SUFFIX,serveusers.com,Proxy\nDOMAIN-SUFFIX,wikipedia.pl,Proxy\nDOMAIN-SUFFIX,weboas.is,Proxy\nDOMAIN-SUFFIX,www.person.com,Proxy\nDOMAIN-SUFFIX,mansionpoker.com,Proxy\nDOMAIN-SUFFIX,airasia.com,Proxy\nDOMAIN-SUFFIX,ez.bnaz.org,Proxy\nDOMAIN-SUFFIX,li.t168.ml,Proxy\nDOMAIN-SUFFIX,pig7.instanthq.com,Proxy\nDOMAIN-SUFFIX,fa.gov.tw,Proxy\nDOMAIN-SUFFIX,customvideosclub.com,Proxy\nDOMAIN-SUFFIX,i2.ytimg.com,Proxy\nDOMAIN-SUFFIX,www.vcupbox.net,Proxy\nDOMAIN-SUFFIX,xp301.net,Proxy\nDOMAIN-SUFFIX,xh8702.com,Proxy\nDOMAIN-SUFFIX,fangeqiang.com,Proxy\nDOMAIN-SUFFIX,www.slcairport.com,Proxy\nDOMAIN-SUFFIX,purepdf.com,Proxy\nDOMAIN-SUFFIX,api.ai,Proxy\nDOMAIN-SUFFIX,cs155.com,Proxy\nDOMAIN-SUFFIX,www.hd-wheels.com,Proxy\nDOMAIN-SUFFIX,tiananmenuniv.com,Proxy\nDOMAIN-SUFFIX,images.comico.tw,Proxy\nDOMAIN-SUFFIX,www.lotusgardens.org,Proxy\nDOMAIN-SUFFIX,invidious.esmailelbob.xyz,Proxy\nDOMAIN-SUFFIX,givpn.com,Proxy\nDOMAIN-SUFFIX,9746001.com,Proxy\nDOMAIN-SUFFIX,doub.io,Proxy\nDOMAIN-SUFFIX,y1965.com,Proxy\nDOMAIN-SUFFIX,whoer.net,Proxy\nDOMAIN-SUFFIX,webbyawards.com,Proxy\nDOMAIN-SUFFIX,18comic1.art,Proxy\nDOMAIN-SUFFIX,limnology.org,Proxy\nDOMAIN-SUFFIX,www.500pix.com,Proxy\nDOMAIN-SUFFIX,porntrex.com,Proxy\nDOMAIN-SUFFIX,cdn-l-cyberpunk.cdprojektred.com,Proxy\nDOMAIN-SUFFIX,getastrill.com,Proxy\nDOMAIN-SUFFIX,is-a-rockstar.com,Proxy\nDOMAIN-SUFFIX,substack.com,Proxy\nDOMAIN-SUFFIX,website--4210285482279019401133-hostel.business.site,Proxy\nDOMAIN-SUFFIX,www.googto.net,Proxy\nDOMAIN-SUFFIX,tibet.hu,Proxy\nDOMAIN-SUFFIX,www.danmeila.com,Proxy\nDOMAIN-SUFFIX,aicai66.com,Proxy\nDOMAIN-SUFFIX,usa-proxy.org,Proxy\nDOMAIN-SUFFIX,moefuns.org,Proxy\nDOMAIN-SUFFIX,www.progenic.co.nz,Proxy\nDOMAIN-SUFFIX,www1.ehtcdn.xyz,Proxy\nDOMAIN-SUFFIX,www.bbraun.de,Proxy\nDOMAIN-SUFFIX,gainsy.com,Proxy\nDOMAIN-SUFFIX,yts.ag,Proxy\nDOMAIN-SUFFIX,niftyaccessory.com,Proxy\nDOMAIN-SUFFIX,ytchannelembed.com,Proxy\nDOMAIN-SUFFIX,yddc5888.com,Proxy\nDOMAIN-SUFFIX,igotmail.com.tw,Proxy\nDOMAIN-SUFFIX,tv100.ga,Proxy\nDOMAIN-SUFFIX,sg.news.yahoo.com,Proxy\nDOMAIN-SUFFIX,www.boxun.com,Proxy\nDOMAIN-SUFFIX,www.viatech.com,Proxy\nDOMAIN-SUFFIX,www.gfb.com.au,Proxy\nDOMAIN-SUFFIX,simplecd.org,Proxy\nDOMAIN-SUFFIX,df8l.com,Proxy\nDOMAIN-SUFFIX,myvnc.com,Proxy\nDOMAIN-SUFFIX,n2.flnet.org,Proxy\nDOMAIN-SUFFIX,ironbigfools.compython.net,Proxy\nDOMAIN-SUFFIX,vocativ.com,Proxy\nDOMAIN-SUFFIX,libraryreserve.com,Proxy\nDOMAIN-SUFFIX,hidein.net,Proxy\nDOMAIN-SUFFIX,givemegay.com,Proxy\nDOMAIN-SUFFIX,falundafa-srilanka.org,Proxy\nDOMAIN-SUFFIX,erights.net,Proxy\nDOMAIN-SUFFIX,wormholevpn.com,Proxy\nDOMAIN-SUFFIX,www.dryav.com,Proxy\nDOMAIN-SUFFIX,qc1n.66.flnet.org,Proxy\nDOMAIN-SUFFIX,pornogramxxx.com,Proxy\nDOMAIN-SUFFIX,news24.co.za,Proxy\nDOMAIN-SUFFIX,mk5000.com,Proxy\nDOMAIN-SUFFIX,getwalls.org,Proxy\nDOMAIN-SUFFIX,feedburner.com,Proxy\nDOMAIN-SUFFIX,picaccomic.com,Proxy\nDOMAIN-SUFFIX,govsm.com,Proxy\nDOMAIN-SUFFIX,ice-gay.com,Proxy\nDOMAIN-SUFFIX,wmflabs.org,Proxy\nDOMAIN-SUFFIX,ni.ewise.pw,Proxy\nDOMAIN-SUFFIX,bbs.mychat.to,Proxy\nDOMAIN-SUFFIX,cn2.rti.tw,Proxy\nDOMAIN-SUFFIX,3445.ca232.com,Proxy\nDOMAIN-SUFFIX,dncsite.xyz,Proxy\nDOMAIN-SUFFIX,in99.org,Proxy\nDOMAIN-SUFFIX,codeshare.io,Proxy\nDOMAIN-SUFFIX,gt.com,Proxy\nDOMAIN-SUFFIX,xn--vjqt50bik1b.com,Proxy\nDOMAIN-SUFFIX,www.yzc216.com,Proxy\nDOMAIN-SUFFIX,tails.boum.org,Proxy\nDOMAIN-SUFFIX,getprice.com.au,Proxy\nDOMAIN-SUFFIX,www.news.yahoo.com,Proxy\nDOMAIN-SUFFIX,karmapa-teachings.org,Proxy\nDOMAIN-SUFFIX,d7203y8eitivv.cloudfront.net,Proxy\nDOMAIN-SUFFIX,latestpornstar.com,Proxy\nDOMAIN-SUFFIX,www.jufu55.com,Proxy\nDOMAIN-SUFFIX,www.islam-center.net,Proxy\nDOMAIN-SUFFIX,maa1811.com,Proxy\nDOMAIN-SUFFIX,boxcryptor.com,Proxy\nDOMAIN-SUFFIX,twistory.net,Proxy\nDOMAIN-SUFFIX,www.china-gay.net,Proxy\nDOMAIN-SUFFIX,jaysfinancial.com,Proxy\nDOMAIN-SUFFIX,6644buyu.com,Proxy\nDOMAIN-SUFFIX,gh0028.com,Proxy\nDOMAIN-SUFFIX,order.shadowsocks.at,Proxy\nDOMAIN-SUFFIX,ask.com,Proxy\nDOMAIN-SUFFIX,pen.io,Proxy\nDOMAIN-SUFFIX,www.gamousa.com,Proxy\nDOMAIN-SUFFIX,puppetlabs.com,Proxy\nDOMAIN-SUFFIX,blm3.net,Proxy\nDOMAIN-SUFFIX,asianscreens.com,Proxy\nDOMAIN-SUFFIX,hk.32-b.it,Proxy\nDOMAIN-SUFFIX,burn.tips,Proxy\nDOMAIN-SUFFIX,proxy-list.org,Proxy\nDOMAIN-SUFFIX,www.want.im,Proxy\nDOMAIN-SUFFIX,maclachlan.ca,Proxy\nDOMAIN-SUFFIX,betfair.com,Proxy\nDOMAIN-SUFFIX,qeexo.com,Proxy\nDOMAIN-SUFFIX,zend2.com,Proxy\nDOMAIN-SUFFIX,cum4k.com,Proxy\nDOMAIN-SUFFIX,btdb.eu,Proxy\nDOMAIN-SUFFIX,kickasstorrents.kat.cr,Proxy\nDOMAIN-SUFFIX,kurashsultan.com,Proxy\nDOMAIN-SUFFIX,voyageonline.co.uk,Proxy\nDOMAIN-SUFFIX,turbobit.net,Proxy\nDOMAIN-SUFFIX,qunfu1.strikingly.com,Proxy\nDOMAIN-SUFFIX,fuckmeplease.com,Proxy\nDOMAIN-SUFFIX,usno.navy.mil,Proxy\nDOMAIN-SUFFIX,css5.gq,Proxy\nDOMAIN-SUFFIX,xmatch.com,Proxy\nDOMAIN-SUFFIX,free.shadowsocks8.org,Proxy\nDOMAIN-SUFFIX,taiwanyes.ning.com,Proxy\nDOMAIN-SUFFIX,www.alanleong.com,Proxy\nDOMAIN-SUFFIX,gravatar.com,Proxy\nDOMAIN-SUFFIX,b2208.com,Proxy\nDOMAIN-SUFFIX,sinoants.com,Proxy\nDOMAIN-SUFFIX,flgg.us,Proxy\nDOMAIN-SUFFIX,maxing.jp,Proxy\nDOMAIN-SUFFIX,myfriendshotmom.com,Proxy\nDOMAIN-SUFFIX,b631.com,Proxy\nDOMAIN-SUFFIX,sef.idv.tw,Proxy\nDOMAIN-SUFFIX,shu.ac.uk,Proxy\nDOMAIN-SUFFIX,sex169.net,Proxy\nDOMAIN-SUFFIX,expasset.com,Proxy\nDOMAIN-SUFFIX,dl.wolframcdn.com,Proxy\nDOMAIN-SUFFIX,www.nctu.edu.tw,Proxy\nDOMAIN-SUFFIX,dockerhub.com,Proxy\nDOMAIN-SUFFIX,accreditedschoolsonline.org,Proxy\nDOMAIN-SUFFIX,www.heraldscotland.com,Proxy\nDOMAIN-SUFFIX,www.autoin.us,Proxy\nDOMAIN-SUFFIX,limeside.co.uk,Proxy\nDOMAIN-SUFFIX,www.homeproxy.com,Proxy\nDOMAIN-SUFFIX,www.elladodelmal.com,Proxy\nDOMAIN-SUFFIX,haruhi.fr,Proxy\nDOMAIN-SUFFIX,ag88.com,Proxy\nDOMAIN-SUFFIX,www.eisbb.com,Proxy\nDOMAIN-SUFFIX,accesscam.org,Proxy\nDOMAIN-SUFFIX,b5959.com,Proxy\nDOMAIN-SUFFIX,www.hmv.co.jp,Proxy\nDOMAIN-SUFFIX,btcturk.com,Proxy\nDOMAIN-SUFFIX,qooqlevideo.com,Proxy\nDOMAIN-SUFFIX,www.getgreenjsq.co,Proxy\nDOMAIN-SUFFIX,www.hmg-mosaic.idv.tw,Proxy\nDOMAIN-SUFFIX,www.repian.com,Proxy\nDOMAIN-SUFFIX,tgstat.com,Proxy\nDOMAIN-SUFFIX,freemasonry.org,Proxy\nDOMAIN-SUFFIX,nuovomegavideo.com,Proxy\nDOMAIN-SUFFIX,tw.gov.org,Proxy\nDOMAIN-SUFFIX,www.exocams.com,Proxy\nDOMAIN-SUFFIX,www.whaleblue.io,Proxy\nDOMAIN-SUFFIX,cabet356.com,Proxy\nDOMAIN-SUFFIX,spfun.org,Proxy\nDOMAIN-SUFFIX,291090.xyz,Proxy\nDOMAIN-SUFFIX,wefightcensorship.org,Proxy\nDOMAIN-SUFFIX,www.tt1069.com,Proxy\nDOMAIN-SUFFIX,www.insidethegames.biz,Proxy\nDOMAIN-SUFFIX,acmetoy.com,Proxy\nDOMAIN-SUFFIX,oiobbs.com,Proxy\nDOMAIN-SUFFIX,tryclimb.org,Proxy\nDOMAIN-SUFFIX,oneindia.in,Proxy\nDOMAIN-SUFFIX,www.metronews.fr,Proxy\nDOMAIN-SUFFIX,hoxx.com,Proxy\nDOMAIN-SUFFIX,dyndns-remote.com,Proxy\nDOMAIN-SUFFIX,www.poynter.org,Proxy\nDOMAIN-SUFFIX,www.indiewire.com,Proxy\nDOMAIN-SUFFIX,thepiratebay.org,Proxy\nDOMAIN-SUFFIX,25.wtf.im,Proxy\nDOMAIN-SUFFIX,google.com.cy,Proxy\nDOMAIN-SUFFIX,dmhy.anoneko.com,Proxy\nDOMAIN-SUFFIX,posambient.com,Proxy\nDOMAIN-SUFFIX,m.bookbao.com,Proxy\nDOMAIN-SUFFIX,rosa.blue,Proxy\nDOMAIN-SUFFIX,www.anchorfree.com,Proxy\nDOMAIN-SUFFIX,edgecastcdn.net,Proxy\nDOMAIN-SUFFIX,hujan-info.blogspot.hk,Proxy\nDOMAIN-SUFFIX,lubinscy.pl,Proxy\nDOMAIN-SUFFIX,musictibet.com,Proxy\nDOMAIN-SUFFIX,clip.dj,Proxy\nDOMAIN-SUFFIX,yodayo.com,Proxy\nDOMAIN-SUFFIX,shotachan.net,Proxy\nDOMAIN-SUFFIX,chat.ichatlink.net,Proxy\nDOMAIN-SUFFIX,jie.idv.tw,Proxy\nDOMAIN-SUFFIX,bet888.us,Proxy\nDOMAIN-SUFFIX,fir-experiment-bbcd0.firebaseio.com,Proxy\nDOMAIN-SUFFIX,sysresccd.org,Proxy\nDOMAIN-SUFFIX,xmbs1.xyz,Proxy\nDOMAIN-SUFFIX,c1b.spacetechnology.net,Proxy\nDOMAIN-SUFFIX,ikk.gr,Proxy\nDOMAIN-SUFFIX,www.vpnproxymaster.com,Proxy\nDOMAIN-SUFFIX,fd09.ddns.me,Proxy\nDOMAIN-SUFFIX,elephantvpn.com,Proxy\nDOMAIN-SUFFIX,c.ios9.us,Proxy\nDOMAIN-SUFFIX,gaeproxy.com,Proxy\nDOMAIN-SUFFIX,endlessmovie.com,Proxy\nDOMAIN-SUFFIX,video.pbs.org,Proxy\nDOMAIN-SUFFIX,www.nix.cz,Proxy\nDOMAIN-SUFFIX,greenpeace.org,Proxy\nDOMAIN-SUFFIX,usagym.org,Proxy\nDOMAIN-SUFFIX,9gag.com,Proxy\nDOMAIN-SUFFIX,b2625.com,Proxy\nDOMAIN-SUFFIX,tuxservice.com.ar,Proxy\nDOMAIN-SUFFIX,twitiq.com,Proxy\nDOMAIN-SUFFIX,groups.yahoo.com,Proxy\nDOMAIN-SUFFIX,viqmedia.com,Proxy\nDOMAIN-SUFFIX,theporndude.com,Proxy\nDOMAIN-SUFFIX,yx51.net,Proxy\nDOMAIN-SUFFIX,zemisu.de.rs,Proxy\nDOMAIN-SUFFIX,chat.yqcloud.top,Proxy\nDOMAIN-SUFFIX,blewpass.com,Proxy\nDOMAIN-SUFFIX,poskotanews.com,Proxy\nDOMAIN-SUFFIX,l-mesh.de,Proxy\nDOMAIN-SUFFIX,onisionfans.com,Proxy\nDOMAIN-SUFFIX,9001700.com,Proxy\nDOMAIN-SUFFIX,elpais.com.uy,Proxy\nDOMAIN-SUFFIX,tv365.cf,Proxy\nDOMAIN-SUFFIX,www.learningsigns.com,Proxy\nDOMAIN-SUFFIX,humandesignasia.org,Proxy\nDOMAIN-SUFFIX,www.vpn38.com,Proxy\nDOMAIN-SUFFIX,teenport.com,Proxy\nDOMAIN-SUFFIX,karupspc.com,Proxy\nDOMAIN-SUFFIX,adnmb1.com,Proxy\nDOMAIN-SUFFIX,cartoonsexx.net,Proxy\nDOMAIN-SUFFIX,dvbt.kennykuo.idv.tw,Proxy\nDOMAIN-SUFFIX,google.cat,Proxy\nDOMAIN-SUFFIX,rokuhentai.com,Proxy\nDOMAIN-SUFFIX,www.888ylc.com,Proxy\nDOMAIN-SUFFIX,wiki.cnitter.com,Proxy\nDOMAIN-SUFFIX,travelicious.ch,Proxy\nDOMAIN-SUFFIX,osaifushikibu.blog.jp,Proxy\nDOMAIN-SUFFIX,fi11.com,Proxy\nDOMAIN-SUFFIX,kimai2.solamec.com,Proxy\nDOMAIN-SUFFIX,0203.org,Proxy\nDOMAIN-SUFFIX,google.co.za,Proxy\nDOMAIN-SUFFIX,de1.vpnme.me,Proxy\nDOMAIN-SUFFIX,flyzy2005.win,Proxy\nDOMAIN-SUFFIX,vds.rightster.com,Proxy\nDOMAIN-SUFFIX,xxxdiver.com,Proxy\nDOMAIN-SUFFIX,www.boder.idv.tw,Proxy\nDOMAIN-SUFFIX,ent.siteintelgroup.com,Proxy\nDOMAIN-SUFFIX,metart1.com,Proxy\nDOMAIN-SUFFIX,census.gov,Proxy\nDOMAIN-SUFFIX,cdn4.telesco.pe,Proxy\nDOMAIN-SUFFIX,bag-online.com,Proxy\nDOMAIN-SUFFIX,fun183.com,Proxy\nDOMAIN-SUFFIX,nobodycanstop.us,Proxy\nDOMAIN-SUFFIX,dnzdol7b8bzms.cloudfront.net,Proxy\nDOMAIN-SUFFIX,perkd.me,Proxy\nDOMAIN-SUFFIX,china-review.com.ua,Proxy\nDOMAIN-SUFFIX,bitterwinter.org,Proxy\nDOMAIN-SUFFIX,gfw.me,Proxy\nDOMAIN-SUFFIX,betteq.com,Proxy\nDOMAIN-SUFFIX,gazotube.com,Proxy\nDOMAIN-SUFFIX,googlevideo.com,Proxy\nDOMAIN-SUFFIX,www.stackpathcdn.com,Proxy\nDOMAIN-SUFFIX,static-cdn1.ustream.tv,Proxy\nDOMAIN-SUFFIX,m.isle.moe,Proxy\nDOMAIN-SUFFIX,mnvpn.com,Proxy\nDOMAIN-SUFFIX,mail.york.ac.uk,Proxy\nDOMAIN-SUFFIX,bonjourshanghai.fr,Proxy\nDOMAIN-SUFFIX,www.livewire-asiapacific.com,Proxy\nDOMAIN-SUFFIX,stitcher.com,Proxy\nDOMAIN-SUFFIX,bird.habedieeh.re,Proxy\nDOMAIN-SUFFIX,www.hjdc95.com,Proxy\nDOMAIN-SUFFIX,ruai.lesile.net,Proxy\nDOMAIN-SUFFIX,test.5w8.cc,Proxy\nDOMAIN-SUFFIX,www.nowshenzhen.com,Proxy\nDOMAIN-SUFFIX,www.toplinks.cc,Proxy\nDOMAIN-SUFFIX,m.btok.com,Proxy\nDOMAIN-SUFFIX,uniswap.org,Proxy\nDOMAIN-SUFFIX,8youtube.com,Proxy\nDOMAIN-SUFFIX,static.cdprojektred.com,Proxy\nDOMAIN-SUFFIX,acevpn.com,Proxy\nDOMAIN-SUFFIX,gov.jm,Proxy\nDOMAIN-SUFFIX,www.sextoyvideos.com,Proxy\nDOMAIN-SUFFIX,897.quantumidiot.com,Proxy\nDOMAIN-SUFFIX,www.linepost.com,Proxy\nDOMAIN-SUFFIX,ltnibr.ro,Proxy\nDOMAIN-SUFFIX,www.festival-cannes.com,Proxy\nDOMAIN-SUFFIX,www.humanedgetech.com,Proxy\nDOMAIN-SUFFIX,www.bne6430.org,Proxy\nDOMAIN-SUFFIX,plunder.com,Proxy\nDOMAIN-SUFFIX,rigpa.org,Proxy\nDOMAIN-SUFFIX,jump.xsky.us,Proxy\nDOMAIN-SUFFIX,pacificpoker.com,Proxy\nDOMAIN-SUFFIX,busytrade.com,Proxy\nDOMAIN-SUFFIX,detroitnews.com,Proxy\nDOMAIN-SUFFIX,www.songza.com,Proxy\nDOMAIN-SUFFIX,sprite.org,Proxy\nDOMAIN-SUFFIX,www.falundafa.ch,Proxy\nDOMAIN-SUFFIX,jgjs.pro,Proxy\nDOMAIN-SUFFIX,ds8210.securefilepro.com,Proxy\nDOMAIN-SUFFIX,vat9.dhcp.biz,Proxy\nDOMAIN-SUFFIX,www.guruin.com,Proxy\nDOMAIN-SUFFIX,hrweb.org,Proxy\nDOMAIN-SUFFIX,pu6644.com,Proxy\nDOMAIN-SUFFIX,vpnforchina.com,Proxy\nDOMAIN-SUFFIX,f1286.com,Proxy\nDOMAIN-SUFFIX,gci.viking99.com,Proxy\nDOMAIN-SUFFIX,www.stream.ps8318.com,Proxy\nDOMAIN-SUFFIX,foofle.com,Proxy\nDOMAIN-SUFFIX,apartments.com,Proxy\nDOMAIN-SUFFIX,jav68.me,Proxy\nDOMAIN-SUFFIX,fu8.life,Proxy\nDOMAIN-SUFFIX,wengewang.org,Proxy\nDOMAIN-SUFFIX,ddxzp.com,Proxy\nDOMAIN-SUFFIX,n.cr.rs,Proxy\nDOMAIN-SUFFIX,osakamotion.net,Proxy\nDOMAIN-SUFFIX,twitchcdn.net,Proxy\nDOMAIN-SUFFIX,www.fingerdaily.com,Proxy\nDOMAIN-SUFFIX,tor-exit-63.for-privacy.net,Proxy\nDOMAIN-SUFFIX,skymirror-cirple-guard.firebaseio.com,Proxy\nDOMAIN-SUFFIX,lpvpn.com,Proxy\nDOMAIN-SUFFIX,www.qq-av.com,Proxy\nDOMAIN-SUFFIX,nwanime.com,Proxy\nDOMAIN-SUFFIX,tmsnrt.rs,Proxy\nDOMAIN-SUFFIX,www.charentelibre.fr,Proxy\nDOMAIN-SUFFIX,878g.cc,Proxy\nDOMAIN-SUFFIX,www.hapolife.com,Proxy\nDOMAIN-SUFFIX,heathwebsite.xyz,Proxy\nDOMAIN-SUFFIX,releaseinternational.org,Proxy\nDOMAIN-SUFFIX,lovetibet.ti-da.net,Proxy\nDOMAIN-SUFFIX,pixegram.com,Proxy\nDOMAIN-SUFFIX,shanghaiist.com,Proxy\nDOMAIN-SUFFIX,ai.xinanmom.com,Proxy\nDOMAIN-SUFFIX,avatars4.githubusercontent.com,Proxy\nDOMAIN-SUFFIX,s2133.slyip.net,Proxy\nDOMAIN-SUFFIX,www.96tang.site,Proxy\nDOMAIN-SUFFIX,neo-miracle.com,Proxy\nDOMAIN-SUFFIX,39170003.com,Proxy\nDOMAIN-SUFFIX,www.jdb168.net,Proxy\nDOMAIN-SUFFIX,www.sohfrance.org,Proxy\nDOMAIN-SUFFIX,jgjs.co,Proxy\nDOMAIN-SUFFIX,orangeapp.cc,Proxy\nDOMAIN-SUFFIX,www.7716xh.com,Proxy\nDOMAIN-SUFFIX,du3ghxbmxci1k.cloudfront.net,Proxy\nDOMAIN-SUFFIX,dzcp8555.com,Proxy\nDOMAIN-SUFFIX,opus-gaming.com,Proxy\nDOMAIN-SUFFIX,www.yahoo.com.ph,Proxy\nDOMAIN-SUFFIX,iysse.com,Proxy\nDOMAIN-SUFFIX,www.onlinecha.com,Proxy\nDOMAIN-SUFFIX,bi-si888.xyz,Proxy\nDOMAIN-SUFFIX,www.wanz-factory.com,Proxy\nDOMAIN-SUFFIX,dapao888.com,Proxy\nDOMAIN-SUFFIX,sexu.com,Proxy\nDOMAIN-SUFFIX,goldenspoon.com,Proxy\nDOMAIN-SUFFIX,m.otatop.app,Proxy\nDOMAIN-SUFFIX,50webs.com,Proxy\nDOMAIN-SUFFIX,www.ehgbooks.com,Proxy\nDOMAIN-SUFFIX,mine.bz,Proxy\nDOMAIN-SUFFIX,www.readingtimes.com.tw,Proxy\nDOMAIN-SUFFIX,m5ssc.com,Proxy\nDOMAIN-SUFFIX,ketk.com,Proxy\nDOMAIN-SUFFIX,maizhong.org,Proxy\nDOMAIN-SUFFIX,21naturals.com,Proxy\nDOMAIN-SUFFIX,mmm-office.co,Proxy\nDOMAIN-SUFFIX,puremature.com,Proxy\nDOMAIN-SUFFIX,yasni.com,Proxy\nDOMAIN-SUFFIX,hk.futu5.com,Proxy\nDOMAIN-SUFFIX,www.epochcar.com,Proxy\nDOMAIN-SUFFIX,www.johnlui.com,Proxy\nDOMAIN-SUFFIX,gutenberg.us,Proxy\nDOMAIN-SUFFIX,shift1978.mybbs.us,Proxy\nDOMAIN-SUFFIX,teendreams.com,Proxy\nDOMAIN-SUFFIX,mingjinglishi.com,Proxy\nDOMAIN-SUFFIX,probux.com,Proxy\nDOMAIN-SUFFIX,hide-me.org,Proxy\nDOMAIN-SUFFIX,www.gopax.co.kr,Proxy\nDOMAIN-SUFFIX,www.jbo03.com,Proxy\nDOMAIN-SUFFIX,getchu.com,Proxy\nDOMAIN-SUFFIX,famunion.com,Proxy\nDOMAIN-SUFFIX,www.clickschool.eu,Proxy\nDOMAIN-SUFFIX,timedip.net,Proxy\nDOMAIN-SUFFIX,7765aa.com,Proxy\nDOMAIN-SUFFIX,s.vos.io,Proxy\nDOMAIN-SUFFIX,g.twimg.com,Proxy\nDOMAIN-SUFFIX,regabri.cl,Proxy\nDOMAIN-SUFFIX,delta.tugatech.com.pt,Proxy\nDOMAIN-SUFFIX,888xjs.net,Proxy\nDOMAIN-SUFFIX,g.bd.to,Proxy\nDOMAIN-SUFFIX,yidali.huarenjie.com,Proxy\nDOMAIN-SUFFIX,ddhw.info,Proxy\nDOMAIN-SUFFIX,sxyprn.com,Proxy\nDOMAIN-SUFFIX,norislam.com,Proxy\nDOMAIN-SUFFIX,sciowl.net,Proxy\nDOMAIN-SUFFIX,binaryden.net,Proxy\nDOMAIN-SUFFIX,heavenly-bumpy-dolomite.glitch.me,Proxy\nDOMAIN-SUFFIX,savetibet.fr,Proxy\nDOMAIN-SUFFIX,www.ittfdream.com,Proxy\nDOMAIN-SUFFIX,www.lt666.xyz,Proxy\nDOMAIN-SUFFIX,gynocentrism.com,Proxy\nDOMAIN-SUFFIX,vid.mint.lgbt,Proxy\nDOMAIN-SUFFIX,chinammm.la,Proxy\nDOMAIN-SUFFIX,hoovers.com,Proxy\nDOMAIN-SUFFIX,pay.pay111.vip,Proxy\nDOMAIN-SUFFIX,www.ugcloud.ca,Proxy\nDOMAIN-SUFFIX,sogclub.com,Proxy\nDOMAIN-SUFFIX,www.stvid.com,Proxy\nDOMAIN-SUFFIX,www.shellfire.net,Proxy\nDOMAIN-SUFFIX,gutteruncensored.com,Proxy\nDOMAIN-SUFFIX,m1.xxgirls2.vip,Proxy\nDOMAIN-SUFFIX,bonzo.xyz,Proxy\nDOMAIN-SUFFIX,www.wallpaperengineapi.com,Proxy\nDOMAIN-SUFFIX,yj1.f6404070.com,Proxy\nDOMAIN-SUFFIX,hajimekikaku.com,Proxy\nDOMAIN-SUFFIX,gnbccarson.com,Proxy\nDOMAIN-SUFFIX,vpnmentor.com,Proxy\nDOMAIN-SUFFIX,campaignmonitor.com,Proxy\nDOMAIN-SUFFIX,ss.ccc.moe,Proxy\nDOMAIN-SUFFIX,daliulian.org,Proxy\nDOMAIN-SUFFIX,rjcxso.site,Proxy\nDOMAIN-SUFFIX,chinachannel.hk,Proxy\nDOMAIN-SUFFIX,www.bbh.com,Proxy\nDOMAIN-SUFFIX,www.xcoyote.com,Proxy\nDOMAIN-SUFFIX,khi.3d-game.com,Proxy\nDOMAIN-SUFFIX,scribd.com,Proxy\nDOMAIN-SUFFIX,99files.net,Proxy\nDOMAIN-SUFFIX,xn--72c9a1bxazc4m.com,Proxy\nDOMAIN-SUFFIX,community.live2d.com,Proxy\nDOMAIN-SUFFIX,www.3088.com,Proxy\nDOMAIN-SUFFIX,tsemtulku.com,Proxy\nDOMAIN-SUFFIX,bway938.com,Proxy\nDOMAIN-SUFFIX,twurl.nl,Proxy\nDOMAIN-SUFFIX,qamoe.cyou,Proxy\nDOMAIN-SUFFIX,www.hoover.org,Proxy\nDOMAIN-SUFFIX,flanintheface.com,Proxy\nDOMAIN-SUFFIX,vpnlite.net,Proxy\nDOMAIN-SUFFIX,www.coinfloor.co.uk,Proxy\nDOMAIN-SUFFIX,imperialpalace.fun6868.com,Proxy\nDOMAIN-SUFFIX,discoins.com,Proxy\nDOMAIN-SUFFIX,rich98.com,Proxy\nDOMAIN-SUFFIX,watchmygf.net,Proxy\nDOMAIN-SUFFIX,acadiz.cl,Proxy\nDOMAIN-SUFFIX,www.voilahomebakery.com,Proxy\nDOMAIN-SUFFIX,iwss.com.au,Proxy\nDOMAIN-SUFFIX,mywebtunnel.com,Proxy\nDOMAIN-SUFFIX,tv123.cf,Proxy\nDOMAIN-SUFFIX,alazingo.com,Proxy\nDOMAIN-SUFFIX,peterhessler.com,Proxy\nDOMAIN-SUFFIX,afantibbs.com,Proxy\nDOMAIN-SUFFIX,www.fuhui-zhs.com,Proxy\nDOMAIN-SUFFIX,www.hantecfx.com,Proxy\nDOMAIN-SUFFIX,ytprivate.com,Proxy\nDOMAIN-SUFFIX,www.bitcoin.co.id,Proxy\nDOMAIN-SUFFIX,hd.now-ip.net,Proxy\nDOMAIN-SUFFIX,clovervpn.com,Proxy\nDOMAIN-SUFFIX,jvpn.com,Proxy\nDOMAIN-SUFFIX,m.pc500.cc,Proxy\nDOMAIN-SUFFIX,23fv75.com,Proxy\nDOMAIN-SUFFIX,ovh.es,Proxy\nDOMAIN-SUFFIX,hbrowse.com,Proxy\nDOMAIN-SUFFIX,www.ttl.com.tw,Proxy\nDOMAIN-SUFFIX,webwarper.net,Proxy\nDOMAIN-SUFFIX,yukmedia.com,Proxy\nDOMAIN-SUFFIX,webmasters.googleblog.com,Proxy\nDOMAIN-SUFFIX,www.hegre.com,Proxy\nDOMAIN-SUFFIX,slaytizle.com,Proxy\nDOMAIN-SUFFIX,www.strikingly.com,Proxy\nDOMAIN-SUFFIX,zzq.whodns.xyz,Proxy\nDOMAIN-SUFFIX,www.kidderminstershuttle.co.uk,Proxy\nDOMAIN-SUFFIX,actimes.com.au,Proxy\nDOMAIN-SUFFIX,www.gaytorrent.ru,Proxy\nDOMAIN-SUFFIX,michaelgough.net,Proxy\nDOMAIN-SUFFIX,kyro.co,Proxy\nDOMAIN-SUFFIX,dbwt.net,Proxy\nDOMAIN-SUFFIX,yy022.com,Proxy\nDOMAIN-SUFFIX,indiansexstories.net,Proxy\nDOMAIN-SUFFIX,www.occupiedlondon.org,Proxy\nDOMAIN-SUFFIX,gfycatporn.com,Proxy\nDOMAIN-SUFFIX,www.xf966.com,Proxy\nDOMAIN-SUFFIX,btno1.com,Proxy\nDOMAIN-SUFFIX,twt.funami.tech,Proxy\nDOMAIN-SUFFIX,gardennetworks.org,Proxy\nDOMAIN-SUFFIX,www.hack.com,Proxy\nDOMAIN-SUFFIX,boomporntube.com,Proxy\nDOMAIN-SUFFIX,ms6588.com,Proxy\nDOMAIN-SUFFIX,674.ddnsking.com,Proxy\nDOMAIN-SUFFIX,56869.com,Proxy\nDOMAIN-SUFFIX,maildns.xyz,Proxy\nDOMAIN-SUFFIX,www.crossvpn.net,Proxy\nDOMAIN-SUFFIX,ppyq3.com,Proxy\nDOMAIN-SUFFIX,sinopitt.info,Proxy\nDOMAIN-SUFFIX,falun-ny.net,Proxy\nDOMAIN-SUFFIX,www.upi.com,Proxy\nDOMAIN-SUFFIX,vfacai.com,Proxy\nDOMAIN-SUFFIX,www.astrologyweekly.com,Proxy\nDOMAIN-SUFFIX,vw686.com,Proxy\nDOMAIN-SUFFIX,www.drtuber.com,Proxy\nDOMAIN-SUFFIX,1989report.hkja.org.hk,Proxy\nDOMAIN-SUFFIX,www.homemoon.net,Proxy\nDOMAIN-SUFFIX,tibetcity.com,Proxy\nDOMAIN-SUFFIX,on.ft.com,Proxy\nDOMAIN-SUFFIX,maomiav.com,Proxy\nDOMAIN-SUFFIX,xt.com,Proxy\nDOMAIN-SUFFIX,le873.com,Proxy\nDOMAIN-SUFFIX,trustwallet.com,Proxy\nDOMAIN-SUFFIX,495772460901.pwastore.com,Proxy\nDOMAIN-SUFFIX,epochbelt.com,Proxy\nDOMAIN-SUFFIX,china-chats.net,Proxy\nDOMAIN-SUFFIX,fannation.com,Proxy\nDOMAIN-SUFFIX,applecottages.co.za,Proxy\nDOMAIN-SUFFIX,pinterst.com,Proxy\nDOMAIN-SUFFIX,wangjinbo.org,Proxy\nDOMAIN-SUFFIX,www.iwish888.com,Proxy\nDOMAIN-SUFFIX,fxclub.cn,Proxy\nDOMAIN-SUFFIX,www.pandavpn.pro,Proxy\nDOMAIN-SUFFIX,www.joymii.com,Proxy\nDOMAIN-SUFFIX,earlytibet.com,Proxy\nDOMAIN-SUFFIX,nano.org,Proxy\nDOMAIN-SUFFIX,vpndh.com,Proxy\nDOMAIN-SUFFIX,assetshare.box.com,Proxy\nDOMAIN-SUFFIX,yui930.blog.shinobi.jp,Proxy\nDOMAIN-SUFFIX,xuv.be,Proxy\nDOMAIN-SUFFIX,citizenpowerforchina.com,Proxy\nDOMAIN-SUFFIX,newslab.withgoogle.com,Proxy\nDOMAIN-SUFFIX,xinbigl.com,Proxy\nDOMAIN-SUFFIX,5kqqum.live,Proxy\nDOMAIN-SUFFIX,cm33.cf,Proxy\nDOMAIN-SUFFIX,pchome.com.tw,Proxy\nDOMAIN-SUFFIX,c1166.com,Proxy\nDOMAIN-SUFFIX,spon.de,Proxy\nDOMAIN-SUFFIX,serveftp.com,Proxy\nDOMAIN-SUFFIX,www.yf77744.com,Proxy\nDOMAIN-SUFFIX,mymail.eslite.com,Proxy\nDOMAIN-SUFFIX,a2zapk.com,Proxy\nDOMAIN-SUFFIX,www.ming-jian.net,Proxy\nDOMAIN-SUFFIX,newmediarights.org,Proxy\nDOMAIN-SUFFIX,www.51wanqiu.net,Proxy\nDOMAIN-SUFFIX,mainpaste.com,Proxy\nDOMAIN-SUFFIX,usfuli.co,Proxy\nDOMAIN-SUFFIX,hao123.cc,Proxy\nDOMAIN-SUFFIX,internetpopculture.com,Proxy\nDOMAIN-SUFFIX,gateway.jbo03.com,Proxy\nDOMAIN-SUFFIX,chinesenewsgroup.com,Proxy\nDOMAIN-SUFFIX,sushiswap.org,Proxy\nDOMAIN-SUFFIX,esurance.com,Proxy\nDOMAIN-SUFFIX,www.sftindia.org,Proxy\nDOMAIN-SUFFIX,javmoo.net,Proxy\nDOMAIN-SUFFIX,tripadvisor.it,Proxy\nDOMAIN-SUFFIX,www.websitevpn.com,Proxy\nDOMAIN-SUFFIX,pengyulong.com,Proxy\nDOMAIN-SUFFIX,wtbn.org,Proxy\nDOMAIN-SUFFIX,www.2020shoufeivpn.com,Proxy\nDOMAIN-SUFFIX,codigohexa.com.br,Proxy\nDOMAIN-SUFFIX,aktifhaber.com,Proxy\nDOMAIN-SUFFIX,xiaoheimi.net,Proxy\nDOMAIN-SUFFIX,1502999.com,Proxy\nDOMAIN-SUFFIX,zh.wikipedia-on-ipfs.org,Proxy\nDOMAIN-SUFFIX,www.v113.net,Proxy\nDOMAIN-SUFFIX,etoro.cn,Proxy\nDOMAIN-SUFFIX,syndication.twimg.com,Proxy\nDOMAIN-SUFFIX,uderzo.it,Proxy\nDOMAIN-SUFFIX,on.mktw.net,Proxy\nDOMAIN-SUFFIX,www.coolkid.win,Proxy\nDOMAIN-SUFFIX,www.fhtrader.com,Proxy\nDOMAIN-SUFFIX,worldpress.com,Proxy\nDOMAIN-SUFFIX,haho.moe,Proxy\nDOMAIN-SUFFIX,jukujo-club.com,Proxy\nDOMAIN-SUFFIX,inquirer.net,Proxy\nDOMAIN-SUFFIX,www.pinterest.nz,Proxy\nDOMAIN-SUFFIX,letemps.ch,Proxy\nDOMAIN-SUFFIX,www.123rf.com,Proxy\nDOMAIN-SUFFIX,www.dchome.net,Proxy\nDOMAIN-SUFFIX,www.yc5023.com,Proxy\nDOMAIN-SUFFIX,buyu1100.com,Proxy\nDOMAIN-SUFFIX,www.liberalparty.org,Proxy\nDOMAIN-SUFFIX,ktsf.com,Proxy\nDOMAIN-SUFFIX,dennyindrayana.com,Proxy\nDOMAIN-SUFFIX,luoti.biz,Proxy\nDOMAIN-SUFFIX,601vip.cc,Proxy\nDOMAIN-SUFFIX,teraprint.us,Proxy\nDOMAIN-SUFFIX,www.nbc.com,Proxy\nDOMAIN-SUFFIX,nowall.effers.com,Proxy\nDOMAIN-SUFFIX,chsport.ch,Proxy\nDOMAIN-SUFFIX,toolforge.org,Proxy\nDOMAIN-SUFFIX,hola.com,Proxy\nDOMAIN-SUFFIX,persiankitty.com,Proxy\nDOMAIN-SUFFIX,www.xj6611.com,Proxy\nDOMAIN-SUFFIX,plugins.longtailvideo.com,Proxy\nDOMAIN-SUFFIX,www.itsapenalty.com,Proxy\nDOMAIN-SUFFIX,thehongkongermovie.com,Proxy\nDOMAIN-SUFFIX,leftbehind.wikia.com,Proxy\nDOMAIN-SUFFIX,jmcomic1.bet,Proxy\nDOMAIN-SUFFIX,h5.ld093.com,Proxy\nDOMAIN-SUFFIX,dyndns-server.com,Proxy\nDOMAIN-SUFFIX,appagg.com,Proxy\nDOMAIN-SUFFIX,www.expressvpn.pm,Proxy\nDOMAIN-SUFFIX,df8cc.com,Proxy\nDOMAIN-SUFFIX,asiansister.com,Proxy\nDOMAIN-SUFFIX,www.trtchinese.com,Proxy\nDOMAIN-SUFFIX,highpower.me,Proxy\nDOMAIN-SUFFIX,fts.me,Proxy\nDOMAIN-SUFFIX,xinbi588.com,Proxy\nDOMAIN-SUFFIX,12vpn.net,Proxy\nDOMAIN-SUFFIX,link.gkfxprime.com,Proxy\nDOMAIN-SUFFIX,etadult.com,Proxy\nDOMAIN-SUFFIX,330707.com,Proxy\nDOMAIN-SUFFIX,sbs.com.au,Proxy\nDOMAIN-SUFFIX,yournews.com,Proxy\nDOMAIN-SUFFIX,www.lt333.xyz,Proxy\nDOMAIN-SUFFIX,xs99.com,Proxy\nDOMAIN-SUFFIX,98298d.com,Proxy\nDOMAIN-SUFFIX,clip2ni.com,Proxy\nDOMAIN-SUFFIX,iwantporn.net,Proxy\nDOMAIN-SUFFIX,www.colegioceusevilla.es,Proxy\nDOMAIN-SUFFIX,4480sp.com,Proxy\nDOMAIN-SUFFIX,www.merit-times.com.tw,Proxy\nDOMAIN-SUFFIX,fc2blog.net,Proxy\nDOMAIN-SUFFIX,ottofaster.xyz,Proxy\nDOMAIN-SUFFIX,tricycle.com,Proxy\nDOMAIN-SUFFIX,voyeurweb.com,Proxy\nDOMAIN-SUFFIX,mygraybar.graybar.com,Proxy\nDOMAIN-SUFFIX,wikis.pro,Proxy\nDOMAIN-SUFFIX,www.fun88city.com,Proxy\nDOMAIN-SUFFIX,www.myforum.com.hk,Proxy\nDOMAIN-SUFFIX,www.cdph.ca.gov,Proxy\nDOMAIN-SUFFIX,switchvpn.com,Proxy\nDOMAIN-SUFFIX,lifequestwellness.com,Proxy\nDOMAIN-SUFFIX,cc5912.com,Proxy\nDOMAIN-SUFFIX,i2pd.xyz,Proxy\nDOMAIN-SUFFIX,torproject.org,Proxy\nDOMAIN-SUFFIX,eworking.net,Proxy\nDOMAIN-SUFFIX,tiger111hk.com,Proxy\nDOMAIN-SUFFIX,tweetdeck.com,Proxy\nDOMAIN-SUFFIX,london.neighborhoodr.com,Proxy\nDOMAIN-SUFFIX,www.sex8.net,Proxy\nDOMAIN-SUFFIX,say2.info,Proxy\nDOMAIN-SUFFIX,m.imomoe.ai,Proxy\nDOMAIN-SUFFIX,wowporn.com,Proxy\nDOMAIN-SUFFIX,h5galgame.me,Proxy\nDOMAIN-SUFFIX,tagwa.org.au,Proxy\nDOMAIN-SUFFIX,itsgood.us,Proxy\nDOMAIN-SUFFIX,news.ebc.net.tw,Proxy\nDOMAIN-SUFFIX,mezzoforte.be,Proxy\nDOMAIN-SUFFIX,www.118tlc.com,Proxy\nDOMAIN-SUFFIX,www.usawebproxy.net,Proxy\nDOMAIN-SUFFIX,optimus.com.ve,Proxy\nDOMAIN-SUFFIX,mynetav.org,Proxy\nDOMAIN-SUFFIX,dexknows.com,Proxy\nDOMAIN-SUFFIX,non-fakenews.org,Proxy\nDOMAIN-SUFFIX,bbg.gov,Proxy\nDOMAIN-SUFFIX,www.xinbi676.com,Proxy\nDOMAIN-SUFFIX,vppp.cn,Proxy\nDOMAIN-SUFFIX,animemusicquiz.com,Proxy\nDOMAIN-SUFFIX,blog.cotten.io,Proxy\nDOMAIN-SUFFIX,wlcnew.jigsy.com,Proxy\nDOMAIN-SUFFIX,blacksonblondes.com,Proxy\nDOMAIN-SUFFIX,fanfou.im,Proxy\nDOMAIN-SUFFIX,www.oldje.com,Proxy\nDOMAIN-SUFFIX,www.camfrog.com,Proxy\nDOMAIN-SUFFIX,apkfollow.com,Proxy\nDOMAIN-SUFFIX,all4mom.org,Proxy\nDOMAIN-SUFFIX,aftenposten.no,Proxy\nDOMAIN-KEYWORD,aHR0cHM6Ly95ZWNsLm5ldA,Proxy\nDOMAIN-SUFFIX,06966vip.com,Proxy\nDOMAIN-SUFFIX,order.shadowsocks.ch,Proxy\nDOMAIN-SUFFIX,www.spankingtube.com,Proxy\nDOMAIN-SUFFIX,tcnynj.org,Proxy\nDOMAIN-SUFFIX,tw.myrenta.com,Proxy\nDOMAIN-SUFFIX,inlinedownhill.ch,Proxy\nDOMAIN-SUFFIX,to.pbs.org,Proxy\nDOMAIN-SUFFIX,www.firstbiz.com,Proxy\nDOMAIN-SUFFIX,fugas.pl,Proxy\nDOMAIN-SUFFIX,mgoon.com,Proxy\nDOMAIN-SUFFIX,expressvpn.org,Proxy\nDOMAIN-SUFFIX,pewglobal.org,Proxy\nDOMAIN-SUFFIX,win123.ml,Proxy\nDOMAIN-SUFFIX,blogspot.it,Proxy\nDOMAIN-SUFFIX,95.ddnsking.com,Proxy\nDOMAIN-SUFFIX,www.indiemerch.com,Proxy\nDOMAIN-SUFFIX,pornerbros.com,Proxy\nDOMAIN-SUFFIX,sexinsex.net,Proxy\nDOMAIN-SUFFIX,rejecttheccp.com,Proxy\nDOMAIN-SUFFIX,www.citizen.org,Proxy\nDOMAIN-SUFFIX,chinagfw.org,Proxy\nDOMAIN-SUFFIX,grep-in.net,Proxy\nDOMAIN-SUFFIX,secure.logmein.com,Proxy\nDOMAIN-SUFFIX,638.com,Proxy\nDOMAIN-SUFFIX,docs.oracle.com,Proxy\nDOMAIN-SUFFIX,51570066.com,Proxy\nDOMAIN-SUFFIX,fanqiangyakexi.net,Proxy\nDOMAIN-SUFFIX,falundafa-br.org,Proxy\nDOMAIN-SUFFIX,www.own3d.tv,Proxy\nDOMAIN-SUFFIX,svita.cz,Proxy\nDOMAIN-SUFFIX,ewam.it,Proxy\nDOMAIN-SUFFIX,galenwu.com,Proxy\nDOMAIN-SUFFIX,search.gmx.com,Proxy\nDOMAIN-SUFFIX,www.wfgold.com,Proxy\nDOMAIN-SUFFIX,1788bw.com,Proxy\nDOMAIN-SUFFIX,www.nztdbbs.com,Proxy\nDOMAIN-SUFFIX,www.perfektegirls.com,Proxy\nDOMAIN-SUFFIX,www.bcube.net,Proxy\nDOMAIN-SUFFIX,2proxy.pw,Proxy\nDOMAIN-SUFFIX,mastodon.xyz,Proxy\nDOMAIN-SUFFIX,sexpreviews.eu,Proxy\nDOMAIN-SUFFIX,arlen.io,Proxy\nDOMAIN-SUFFIX,www.safe138.com,Proxy\nDOMAIN-SUFFIX,www.tlc178.com,Proxy\nDOMAIN-SUFFIX,raidtalk.com.tw,Proxy\nDOMAIN-SUFFIX,cloakpoint.com,Proxy\nDOMAIN-SUFFIX,zackblock.com,Proxy\nDOMAIN-SUFFIX,1906999.com,Proxy\nDOMAIN-SUFFIX,thetend.com,Proxy\nDOMAIN-SUFFIX,www.raburabu-rochu.com,Proxy\nDOMAIN-SUFFIX,expecthim.com,Proxy\nDOMAIN-SUFFIX,staticx1.dditscdn.com,Proxy\nDOMAIN-SUFFIX,www.pilio.idv.tw,Proxy\nDOMAIN-SUFFIX,rb128.com,Proxy\nDOMAIN-SUFFIX,playboard.co,Proxy\nDOMAIN-SUFFIX,www.roskam.nl,Proxy\nDOMAIN-SUFFIX,www.zfoo.com,Proxy\nDOMAIN-SUFFIX,ww4.sldao.us,Proxy\nDOMAIN-SUFFIX,yobo66.com,Proxy\nDOMAIN-SUFFIX,d2tc2mq5qug58a.cloudfront.net,Proxy\nDOMAIN-SUFFIX,3ren.blog,Proxy\nDOMAIN-SUFFIX,tibetonline.com,Proxy\nDOMAIN-SUFFIX,eucasino.com,Proxy\nDOMAIN-SUFFIX,www.bedsonline.com,Proxy\nDOMAIN-SUFFIX,freewallpaper4.me,Proxy\nDOMAIN-SUFFIX,cloudy.asusrouter.cf,Proxy\nDOMAIN-SUFFIX,latelinenews.com,Proxy\nDOMAIN-SUFFIX,soundwith.in,Proxy\nDOMAIN-SUFFIX,www.pamojaeducation.com,Proxy\nDOMAIN-SUFFIX,www.google.ci,Proxy\nDOMAIN-SUFFIX,tnaflix.com,Proxy\nDOMAIN-SUFFIX,notrebiere.com,Proxy\nDOMAIN-SUFFIX,a1777.com,Proxy\nDOMAIN-SUFFIX,deqmgur9wakvx.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.rosiyy.com,Proxy\nDOMAIN-SUFFIX,www.cksl.in,Proxy\nDOMAIN-SUFFIX,3.aa1122.ws,Proxy\nDOMAIN-SUFFIX,aniscartujo.com,Proxy\nDOMAIN-SUFFIX,news.laborinfocn.com,Proxy\nDOMAIN-SUFFIX,contest.1654168.com,Proxy\nDOMAIN-SUFFIX,www.instructure.com,Proxy\nDOMAIN-SUFFIX,emuparadise.me,Proxy\nDOMAIN-SUFFIX,b8282.com,Proxy\nDOMAIN-SUFFIX,h.dd.dnsrd.com,Proxy\nDOMAIN-SUFFIX,28harbor.com,Proxy\nDOMAIN-SUFFIX,fur2.lflink.com,Proxy\nDOMAIN-SUFFIX,ozvpn.com,Proxy\nDOMAIN-SUFFIX,www.falun-dafa.net,Proxy\nDOMAIN-SUFFIX,getjump.org,Proxy\nDOMAIN-SUFFIX,virtuagirl2.com,Proxy\nDOMAIN-SUFFIX,docs.majesticseagull.com.tw,Proxy\nDOMAIN-SUFFIX,sametband.com.ar,Proxy\nDOMAIN-SUFFIX,btbook.net,Proxy\nDOMAIN-SUFFIX,momoxzp.com,Proxy\nDOMAIN-SUFFIX,www.rhyljournal.co.uk,Proxy\nDOMAIN-SUFFIX,onlineproxy.us,Proxy\nDOMAIN-SUFFIX,prompthero.com,Proxy\nDOMAIN-SUFFIX,sss999777.com,Proxy\nDOMAIN-SUFFIX,bbs.imoutolove.me,Proxy\nDOMAIN-SUFFIX,fan-qiang.com,Proxy\nDOMAIN-SUFFIX,packagist.org,Proxy\nDOMAIN-SUFFIX,www.dyvip9.com,Proxy\nDOMAIN-SUFFIX,macrovpn.com,Proxy\nDOMAIN-SUFFIX,macvidcards.com,Proxy\nDOMAIN-SUFFIX,ws.webgis.ro,Proxy\nDOMAIN-SUFFIX,wisdompubs.org,Proxy\nDOMAIN-SUFFIX,bloomfortune.com,Proxy\nDOMAIN-SUFFIX,cafepress.com,Proxy\nDOMAIN-SUFFIX,jm-comic2.cc,Proxy\nDOMAIN-SUFFIX,wp1.com,Proxy\nDOMAIN-SUFFIX,cumlouder.com,Proxy\nDOMAIN-SUFFIX,westkit.net,Proxy\nDOMAIN-SUFFIX,dht.transmissionbt.com,Proxy\nDOMAIN-SUFFIX,oopsforum.com,Proxy\nDOMAIN-SUFFIX,ductran.com,Proxy\nDOMAIN-SUFFIX,scotusblog.org,Proxy\nDOMAIN-SUFFIX,www.wivesinpantyhose.com,Proxy\nDOMAIN-SUFFIX,6565y.com,Proxy\nDOMAIN-SUFFIX,heaven.17mh.app,Proxy\nDOMAIN-SUFFIX,d1semk8tb8h8fg.cloudfront.net,Proxy\nDOMAIN-SUFFIX,lama.com.tw,Proxy\nDOMAIN-SUFFIX,sun033.com,Proxy\nDOMAIN-SUFFIX,winnie.org,Proxy\nDOMAIN-SUFFIX,hs8882.com,Proxy\nDOMAIN-SUFFIX,x831.com,Proxy\nDOMAIN-SUFFIX,nifty.org,Proxy\nDOMAIN-SUFFIX,nicozon.net,Proxy\nDOMAIN-SUFFIX,www.unblockdmm.com,Proxy\nDOMAIN-SUFFIX,band.com.br,Proxy\nDOMAIN-SUFFIX,www.ohix.com,Proxy\nDOMAIN-SUFFIX,www.zello.com,Proxy\nDOMAIN-SUFFIX,ufc-weiden.at,Proxy\nDOMAIN-SUFFIX,chromercise.com,Proxy\nDOMAIN-SUFFIX,gtinfo.com.ar,Proxy\nDOMAIN-SUFFIX,www.fh-chinese.com,Proxy\nDOMAIN-SUFFIX,www.ccta.me,Proxy\nDOMAIN-SUFFIX,uybbb.com,Proxy\nDOMAIN-SUFFIX,qianmo.tw,Proxy\nDOMAIN-SUFFIX,mec.gov.br,Proxy\nDOMAIN-SUFFIX,www.qwqjsq.com,Proxy\nDOMAIN-SUFFIX,5best1.com,Proxy\nDOMAIN-SUFFIX,www.facebook.ca,Proxy\nDOMAIN-SUFFIX,ipld.io,Proxy\nDOMAIN-SUFFIX,sax.flnet.org,Proxy\nDOMAIN-SUFFIX,cn.voa.mobi,Proxy\nDOMAIN-SUFFIX,www.zhoushuguang.com,Proxy\nDOMAIN-SUFFIX,sts1069.com,Proxy\nDOMAIN-SUFFIX,getrelax.club,Proxy\nDOMAIN-SUFFIX,npa.gov.tw,Proxy\nDOMAIN-SUFFIX,www.6070k.com,Proxy\nDOMAIN-SUFFIX,rubberduck.net,Proxy\nDOMAIN-SUFFIX,unblockbook.biz,Proxy\nDOMAIN-SUFFIX,anti.anti.cnn.googlepages.com,Proxy\nDOMAIN-SUFFIX,bcc.com.tw,Proxy\nDOMAIN-SUFFIX,medleyads.com,Proxy\nDOMAIN-SUFFIX,abbywinters.com,Proxy\nDOMAIN-SUFFIX,random.idv.tw,Proxy\nDOMAIN-SUFFIX,www.wilmott.com,Proxy\nDOMAIN-SUFFIX,humanrights.gov.au,Proxy\nDOMAIN-SUFFIX,prsfl6.com,Proxy\nDOMAIN-SUFFIX,wordfence.com,Proxy\nDOMAIN-SUFFIX,diigo.com,Proxy\nDOMAIN-SUFFIX,kabochan.blog.jp,Proxy\nDOMAIN-SUFFIX,btsow.rest,Proxy\nDOMAIN-SUFFIX,spin803.com,Proxy\nDOMAIN-SUFFIX,ee0414d419c35a20.puck1.com,Proxy\nDOMAIN-SUFFIX,savetibet.us,Proxy\nDOMAIN-SUFFIX,taoyuan-aerotropolis.com,Proxy\nDOMAIN-SUFFIX,www.peclass.net,Proxy\nDOMAIN-SUFFIX,heerser.com,Proxy\nDOMAIN-SUFFIX,icu-project.org,Proxy\nDOMAIN-SUFFIX,oldyounganal.com,Proxy\nDOMAIN-SUFFIX,xxxpussyvideo.com,Proxy\nDOMAIN-SUFFIX,communistcrimes.org,Proxy\nDOMAIN-SUFFIX,www.bryanboy.com,Proxy\nDOMAIN-SUFFIX,creader.com,Proxy\nDOMAIN-SUFFIX,iqlink1.us,Proxy\nDOMAIN-SUFFIX,vct.news,Proxy\nDOMAIN-SUFFIX,zxcvbnm777.site,Proxy\nDOMAIN-SUFFIX,like.com,Proxy\nDOMAIN-SUFFIX,winndixie.com,Proxy\nDOMAIN-SUFFIX,storj.io,Proxy\nDOMAIN-SUFFIX,css3.gq,Proxy\nDOMAIN-SUFFIX,furl.net,Proxy\nDOMAIN-SUFFIX,alhourriah.org,Proxy\nDOMAIN-SUFFIX,cooproriz.pt,Proxy\nDOMAIN-SUFFIX,daftporn.com,Proxy\nDOMAIN-SUFFIX,michiriqui.com,Proxy\nDOMAIN-SUFFIX,apkcombo.com,Proxy\nDOMAIN-SUFFIX,pd.com,Proxy\nDOMAIN-SUFFIX,ebans.byethost7.com,Proxy\nDOMAIN-SUFFIX,vanemu.cn,Proxy\nDOMAIN-SUFFIX,frischdraws.com,Proxy\nDOMAIN-SUFFIX,10bo1008.com,Proxy\nDOMAIN-SUFFIX,data.gov.tw,Proxy\nDOMAIN-SUFFIX,nytco.com,Proxy\nDOMAIN-SUFFIX,wfwp.org,Proxy\nDOMAIN-SUFFIX,paulmccune.com,Proxy\nDOMAIN-SUFFIX,alesso.net,Proxy\nDOMAIN-SUFFIX,ntdtv.cz,Proxy\nDOMAIN-SUFFIX,amblm22.com,Proxy\nDOMAIN-SUFFIX,www.rpm.com,Proxy\nDOMAIN-SUFFIX,rfi.my,Proxy\nDOMAIN-SUFFIX,d1mh7il84qxl6t.cloudfront.net,Proxy\nDOMAIN-SUFFIX,tkcs-collins.com,Proxy\nDOMAIN-SUFFIX,www.kinokuniya.co.jp,Proxy\nDOMAIN-SUFFIX,www.canbet.com,Proxy\nDOMAIN-SUFFIX,argent.xyz,Proxy\nDOMAIN-SUFFIX,yc2363.com,Proxy\nDOMAIN-SUFFIX,dogfartnetwork.com,Proxy\nDOMAIN-SUFFIX,pinimg.com,Proxy\nDOMAIN-SUFFIX,www.tsecy.com,Proxy\nDOMAIN-SUFFIX,www.twitter.de,Proxy\nDOMAIN-SUFFIX,mpst.org,Proxy\nDOMAIN-SUFFIX,www.pinterets.com,Proxy\nDOMAIN-SUFFIX,ulchq.com,Proxy\nDOMAIN-SUFFIX,www.agemys.com,Proxy\nDOMAIN-SUFFIX,jmcomic1.win,Proxy\nDOMAIN-SUFFIX,www.cpu.edu.tw,Proxy\nDOMAIN-SUFFIX,syriaa2z.blogspot.hk,Proxy\nDOMAIN-SUFFIX,wevxv.com,Proxy\nDOMAIN-SUFFIX,about.google,Proxy\nDOMAIN-SUFFIX,nitter.privacydev.net,Proxy\nDOMAIN-SUFFIX,gzhanyou.org,Proxy\nDOMAIN-SUFFIX,phun.org,Proxy\nDOMAIN-SUFFIX,1505999.com,Proxy\nDOMAIN-SUFFIX,in.appcenter.ms,Proxy\nDOMAIN-SUFFIX,auntmia.com,Proxy\nDOMAIN-SUFFIX,pixiv.me,Proxy\nDOMAIN-SUFFIX,gongmeng.info,Proxy\nDOMAIN-SUFFIX,www.tsdm.net,Proxy\nDOMAIN-SUFFIX,sinocism.com,Proxy\nDOMAIN-SUFFIX,1731788.com,Proxy\nDOMAIN-SUFFIX,cn.targray.com,Proxy\nDOMAIN-SUFFIX,plus.codes,Proxy\nDOMAIN-SUFFIX,wikispecies.org,Proxy\nDOMAIN-SUFFIX,www.7i13n565.com,Proxy\nDOMAIN-SUFFIX,www.lovetvshow.com,Proxy\nDOMAIN-SUFFIX,mswe1.org,Proxy\nDOMAIN-SUFFIX,yyituan.com,Proxy\nDOMAIN-SUFFIX,wenzhao.ca,Proxy\nDOMAIN-SUFFIX,hiload.com,Proxy\nDOMAIN-SUFFIX,mitchellday.gq,Proxy\nDOMAIN-SUFFIX,xxxfuckmom.com,Proxy\nDOMAIN-SUFFIX,manhwahentai.me,Proxy\nDOMAIN-SUFFIX,www.3kliksphilip.com,Proxy\nDOMAIN-SUFFIX,d26lpscf8ih2bz.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.youngsprocleaning.co.uk,Proxy\nDOMAIN-SUFFIX,rock.porn,Proxy\nDOMAIN-SUFFIX,vot.org,Proxy\nDOMAIN-SUFFIX,veooz.com,Proxy\nDOMAIN-SUFFIX,efcc.org.hk,Proxy\nDOMAIN-SUFFIX,889701.com,Proxy\nDOMAIN-SUFFIX,www.new7.com.tw,Proxy\nDOMAIN-SUFFIX,www.football365.co.uk,Proxy\nDOMAIN-SUFFIX,795.got-game.org,Proxy\nDOMAIN-SUFFIX,63ee.net,Proxy\nDOMAIN-SUFFIX,www.hj6855.com,Proxy\nDOMAIN-SUFFIX,abdu-green.blogspot.hk,Proxy\nDOMAIN-SUFFIX,ns03.gq,Proxy\nDOMAIN-SUFFIX,my03.com,Proxy\nDOMAIN-SUFFIX,www.mutekimuteki.com,Proxy\nDOMAIN-SUFFIX,abigailtorres.ga,Proxy\nDOMAIN-SUFFIX,radio.es,Proxy\nDOMAIN-SUFFIX,kerenua.xyz,Proxy\nDOMAIN-SUFFIX,ikunyun.link,Proxy\nDOMAIN-SUFFIX,limiao.net,Proxy\nDOMAIN-SUFFIX,mas.to,Proxy\nDOMAIN-SUFFIX,www.westwoodone.com,Proxy\nDOMAIN-SUFFIX,ch.jumpingcrab.com,Proxy\nDOMAIN-SUFFIX,sis.hk-wesee.xyz,Proxy\nDOMAIN-SUFFIX,peekier.com,Proxy\nDOMAIN-SUFFIX,mangmang.run,Proxy\nDOMAIN-SUFFIX,www.chudaili.com,Proxy\nDOMAIN-SUFFIX,www.amnesty.ca,Proxy\nDOMAIN-SUFFIX,theoatmeal.com,Proxy\nDOMAIN-SUFFIX,api.feedbin.com,Proxy\nDOMAIN-SUFFIX,loudtronix.me,Proxy\nDOMAIN-SUFFIX,x-wall.org,Proxy\nDOMAIN-SUFFIX,xpdo.net,Proxy\nDOMAIN-SUFFIX,vipdf8.com,Proxy\nDOMAIN-SUFFIX,tenpage.net,Proxy\nDOMAIN-SUFFIX,dafagood.com,Proxy\nDOMAIN-SUFFIX,northpinedonkeys.com,Proxy\nDOMAIN-SUFFIX,38851122.com,Proxy\nDOMAIN-SUFFIX,asianscandal.net,Proxy\nDOMAIN-SUFFIX,thevisiontimes.com,Proxy\nDOMAIN-SUFFIX,www.openervpn.in,Proxy\nDOMAIN-SUFFIX,ipfs.oceanprotocol.com,Proxy\nDOMAIN-SUFFIX,mcusercontent.com,Proxy\nDOMAIN-SUFFIX,www.247sports.com,Proxy\nDOMAIN-SUFFIX,www.gmailvpn.com,Proxy\nDOMAIN-SUFFIX,tune-up.com,Proxy\nDOMAIN-SUFFIX,search.yahoo.com,Proxy\nDOMAIN-SUFFIX,cdpeu.org,Proxy\nDOMAIN-SUFFIX,57138.com,Proxy\nDOMAIN-SUFFIX,proxy.cool,Proxy\nDOMAIN-SUFFIX,proxite.me,Proxy\nDOMAIN-SUFFIX,keecha.com,Proxy\nDOMAIN-SUFFIX,chinese.engadget.com,Proxy\nDOMAIN-SUFFIX,fentanes.com.ar,Proxy\nDOMAIN-SUFFIX,qostube.com,Proxy\nDOMAIN-SUFFIX,gab.com,Proxy\nDOMAIN-SUFFIX,www.dpes.hcc.edu.tw,Proxy\nDOMAIN-SUFFIX,gfx47.com,Proxy\nDOMAIN-SUFFIX,info-care.pt,Proxy\nDOMAIN-SUFFIX,maa1806.com,Proxy\nDOMAIN-SUFFIX,3206320.com,Proxy\nDOMAIN-SUFFIX,audiko.net,Proxy\nDOMAIN-SUFFIX,www.searchtech.com,Proxy\nDOMAIN-SUFFIX,www.hustlermagazine.com,Proxy\nDOMAIN-SUFFIX,gitcafe.io,Proxy\nDOMAIN-SUFFIX,tibetanreview.net,Proxy\nDOMAIN-SUFFIX,www.jazzradio.fr,Proxy\nDOMAIN-SUFFIX,gayhub.com,Proxy\nDOMAIN-SUFFIX,www.cimp-paris.fr,Proxy\nDOMAIN-SUFFIX,dadi360.com,Proxy\nDOMAIN-SUFFIX,di1cx2shgigsi.cloudfront.net,Proxy\nDOMAIN-SUFFIX,voatiengviet.com,Proxy\nDOMAIN-SUFFIX,mp3quran.net,Proxy\nDOMAIN-SUFFIX,d25am4jn3jtwv.cloudfront.net,Proxy\nDOMAIN-SUFFIX,biogens.com.ar,Proxy\nDOMAIN-SUFFIX,mail.asianmenusauces.com,Proxy\nDOMAIN-SUFFIX,rks-gov.net,Proxy\nDOMAIN-SUFFIX,n88880.com,Proxy\nDOMAIN-SUFFIX,technetcal.com,Proxy\nDOMAIN-SUFFIX,calameo.com,Proxy\nDOMAIN-SUFFIX,watvaward.org,Proxy\nDOMAIN-SUFFIX,jjcavideography.com,Proxy\nDOMAIN-SUFFIX,xmbs3.live,Proxy\nDOMAIN-SUFFIX,cherrymyle.pt,Proxy\nDOMAIN-SUFFIX,blackbullmarkets.com,Proxy\nDOMAIN-SUFFIX,shop.fcbayern.de,Proxy\nDOMAIN-SUFFIX,www.laahaa.com,Proxy\nDOMAIN-SUFFIX,gvmodel.com,Proxy\nDOMAIN-SUFFIX,api.plagscan.com,Proxy\nDOMAIN-SUFFIX,www.udn.com,Proxy\nDOMAIN-SUFFIX,politicususa.com,Proxy\nDOMAIN-SUFFIX,zuo8.live,Proxy\nDOMAIN-SUFFIX,mybloglog.com,Proxy\nDOMAIN-SUFFIX,bw.vc,Proxy\nDOMAIN-SUFFIX,www.publictv.com,Proxy\nDOMAIN-SUFFIX,icsin.org,Proxy\nDOMAIN-SUFFIX,chinaresearchgroup.org,Proxy\nDOMAIN-SUFFIX,ohporntube.com,Proxy\nDOMAIN-SUFFIX,fzxjxkb.com,Proxy\nDOMAIN-SUFFIX,hk-pic.net,Proxy\nDOMAIN-SUFFIX,www.atrandys.com,Proxy\nDOMAIN-SUFFIX,jav123.com,Proxy\nDOMAIN-SUFFIX,terminus2049.github.io,Proxy\nDOMAIN-SUFFIX,wechat.kanfb.com,Proxy\nDOMAIN-SUFFIX,feebee.com.tw,Proxy\nDOMAIN-SUFFIX,98ddt.xyz,Proxy\nDOMAIN-SUFFIX,jeanyim.com,Proxy\nDOMAIN-SUFFIX,4233008.com,Proxy\nDOMAIN-SUFFIX,cdn.tophatch.com,Proxy\nDOMAIN-SUFFIX,tube.kissr.com,Proxy\nDOMAIN-SUFFIX,zhwp.org,Proxy\nDOMAIN-SUFFIX,intermargins.net,Proxy\nDOMAIN-SUFFIX,webnode.se,Proxy\nDOMAIN-SUFFIX,dd57625.cq11.net,Proxy\nDOMAIN-SUFFIX,pure18.com,Proxy\nDOMAIN-SUFFIX,www.177picyy.com,Proxy\nDOMAIN-SUFFIX,www.curaful.com,Proxy\nDOMAIN-SUFFIX,artibet.com,Proxy\nDOMAIN-SUFFIX,wdly002.com,Proxy\nDOMAIN-SUFFIX,www.radio.de,Proxy\nDOMAIN-SUFFIX,oneyoutube.com,Proxy\nDOMAIN-SUFFIX,getlantern.com,Proxy\nDOMAIN-SUFFIX,adidas-group.com,Proxy\nDOMAIN-SUFFIX,smhric.org,Proxy\nDOMAIN-SUFFIX,www.ozhome.com.au,Proxy\nDOMAIN-SUFFIX,r2pro.net,Proxy\nDOMAIN-SUFFIX,nord-help.com,Proxy\nDOMAIN-SUFFIX,www.goodnet98.com,Proxy\nDOMAIN-SUFFIX,infoser.com.ar,Proxy\nDOMAIN-SUFFIX,365ahri.com,Proxy\nDOMAIN-SUFFIX,8kun.top,Proxy\nDOMAIN-SUFFIX,tabtter.jp,Proxy\nDOMAIN-SUFFIX,ukipvpn.com,Proxy\nDOMAIN-SUFFIX,allfinegirls.com,Proxy\nDOMAIN-SUFFIX,jtizyl.net,Proxy\nDOMAIN-SUFFIX,staglin.hr,Proxy\nDOMAIN-SUFFIX,tubesla.com,Proxy\nDOMAIN-SUFFIX,majorleaguegaming.com,Proxy\nDOMAIN-SUFFIX,pbxes.com,Proxy\nDOMAIN-SUFFIX,comsonor.blogspot.hk,Proxy\nDOMAIN-SUFFIX,radiosoh.com,Proxy\nDOMAIN-SUFFIX,56a4x.73.podzone.org,Proxy\nDOMAIN-SUFFIX,www.jonatin.com,Proxy\nDOMAIN-SUFFIX,vvw19.com,Proxy\nDOMAIN-SUFFIX,bigjockcock.com,Proxy\nDOMAIN-SUFFIX,m2.188asia.com,Proxy\nDOMAIN-SUFFIX,www.masitv.site,Proxy\nDOMAIN-SUFFIX,qqoocc.com,Proxy\nDOMAIN-SUFFIX,saidit.net,Proxy\nDOMAIN-SUFFIX,tin.it,Proxy\nDOMAIN-SUFFIX,zqzhibo.com,Proxy\nDOMAIN-SUFFIX,maicloud.io,Proxy\nDOMAIN-SUFFIX,www.mywanbo.com,Proxy\nDOMAIN-SUFFIX,chouftv.ma,Proxy\nDOMAIN-SUFFIX,taolun.info,Proxy\nDOMAIN-SUFFIX,dnrwheels.com,Proxy\nDOMAIN-SUFFIX,granular.net.au,Proxy\nDOMAIN-SUFFIX,sszhanghao.com,Proxy\nDOMAIN-SUFFIX,dm-princexiaowangzibenpu.webnode.tw,Proxy\nDOMAIN-SUFFIX,jeremylin.net,Proxy\nDOMAIN-SUFFIX,www.edwincheong.com,Proxy\nDOMAIN-SUFFIX,iqq4.net,Proxy\nDOMAIN-SUFFIX,casinoking.com,Proxy\nDOMAIN-SUFFIX,k-lab.tk,Proxy\nDOMAIN-SUFFIX,sspro.ml,Proxy\nDOMAIN-SUFFIX,vcfbuilder.org,Proxy\nDOMAIN-SUFFIX,www.reversedfront.tw,Proxy\nDOMAIN-SUFFIX,vpnwl.com,Proxy\nDOMAIN-KEYWORD,64memo,Proxy\nDOMAIN-SUFFIX,kimmert.com,Proxy\nDOMAIN-SUFFIX,weblagu.com,Proxy\nDOMAIN-SUFFIX,freyr.futurecdn.net,Proxy\nDOMAIN-SUFFIX,9bis.net,Proxy\nDOMAIN-SUFFIX,okx.com,Proxy\nDOMAIN-SUFFIX,fpmt-osel.org,Proxy\nDOMAIN-SUFFIX,runoutfor.life,Proxy\nDOMAIN-SUFFIX,sueddeutsche.de,Proxy\nDOMAIN-SUFFIX,dnsit.xyz,Proxy\nDOMAIN-SUFFIX,justpaste.it,Proxy\nDOMAIN-SUFFIX,lapatilla.com,Proxy\nDOMAIN-SUFFIX,d.cr.rs,Proxy\nDOMAIN-SUFFIX,mercdn.net,Proxy\nDOMAIN-SUFFIX,sweepfrequencydissolved.com,Proxy\nDOMAIN-SUFFIX,ssrshare.us,Proxy\nDOMAIN-SUFFIX,nitter.pufe.org,Proxy\nDOMAIN-SUFFIX,family.acethon.com,Proxy\nDOMAIN-SUFFIX,d92hdf7ptxcml.cloudfront.net,Proxy\nDOMAIN-SUFFIX,expressvpn.com,Proxy\nDOMAIN-SUFFIX,adult-empire.com,Proxy\nDOMAIN-SUFFIX,godaddy.ca,Proxy\nDOMAIN-SUFFIX,www.book18.org,Proxy\nDOMAIN-SUFFIX,www.fun281.com,Proxy\nDOMAIN-SUFFIX,webs.com,Proxy\nDOMAIN-SUFFIX,www.semana.com,Proxy\nDOMAIN-SUFFIX,brucewang.net,Proxy\nDOMAIN-SUFFIX,xizhutou.com,Proxy\nDOMAIN-SUFFIX,assitport.co.za,Proxy\nDOMAIN-SUFFIX,ssnode.net,Proxy\nDOMAIN-SUFFIX,mocospace.com,Proxy\nDOMAIN-SUFFIX,www.bmfinn.com,Proxy\nDOMAIN-SUFFIX,www.ca991.com,Proxy\nDOMAIN-SUFFIX,www.freedl.org,Proxy\nDOMAIN-SUFFIX,4dq.com,Proxy\nDOMAIN-SUFFIX,keepandshare.com,Proxy\nDOMAIN-SUFFIX,www.tizianarubini.com,Proxy\nDOMAIN-SUFFIX,falun-co.org,Proxy\nDOMAIN-SUFFIX,herobakery.com,Proxy\nDOMAIN-SUFFIX,wowgirls.xxx,Proxy\nDOMAIN-SUFFIX,login.sina.com.cn,Proxy\nDOMAIN-SUFFIX,hepcats.net,Proxy\nDOMAIN-SUFFIX,hahaxixi.github.io,Proxy\nDOMAIN-SUFFIX,bondage.com,Proxy\nDOMAIN-SUFFIX,bloomberg.cn,Proxy\nDOMAIN-SUFFIX,readmoo.com,Proxy\nDOMAIN-SUFFIX,althouse.blogspot.hk,Proxy\nDOMAIN-SUFFIX,www.juwai.com,Proxy\nDOMAIN-SUFFIX,peachy18.com,Proxy\nDOMAIN-SUFFIX,deboyace.com,Proxy\nDOMAIN-SUFFIX,56.flnet.org,Proxy\nDOMAIN-SUFFIX,www.zyxel.com,Proxy\nDOMAIN-SUFFIX,spicehunter.com,Proxy\nDOMAIN-SUFFIX,226.slyip.net,Proxy\nDOMAIN-SUFFIX,googel.com,Proxy\nDOMAIN-SUFFIX,jitouch.com,Proxy\nDOMAIN-SUFFIX,www.bcw70.com,Proxy\nDOMAIN-SUFFIX,venetianmacao.com,Proxy\nDOMAIN-SUFFIX,mi.minecraftnoob.com,Proxy\nDOMAIN-SUFFIX,aobo888.com,Proxy\nDOMAIN-SUFFIX,ee9841.com,Proxy\nDOMAIN-SUFFIX,airfrance.com,Proxy\nDOMAIN-SUFFIX,nationalreview.com,Proxy\nDOMAIN-SUFFIX,iwem2020.npu.edu.tw,Proxy\nDOMAIN-SUFFIX,www.eporner.com,Proxy\nDOMAIN-SUFFIX,jav18.xyz,Proxy\nDOMAIN-SUFFIX,clubtengen.cl,Proxy\nDOMAIN-SUFFIX,scratch.mit.edu,Proxy\nDOMAIN-SUFFIX,www.sy0606.com,Proxy\nDOMAIN-SUFFIX,youhdjizz.com,Proxy\nDOMAIN-SUFFIX,s3-ap-southeast-2.amazonaws.com,Proxy\nDOMAIN-SUFFIX,www.maya-house.idv.tw,Proxy\nDOMAIN-SUFFIX,wantyoutube.com,Proxy\nDOMAIN-SUFFIX,sexyandfunny.com,Proxy\nDOMAIN-SUFFIX,zz2159.com,Proxy\nDOMAIN-SUFFIX,www.fun903.com,Proxy\nDOMAIN-SUFFIX,www.clubcreate.com,Proxy\nDOMAIN-SUFFIX,www.kaskus.com,Proxy\nDOMAIN-SUFFIX,www.xavduf.com,Proxy\nDOMAIN-SUFFIX,potterybarnkids.com,Proxy\nDOMAIN-SUFFIX,dok-forum.net,Proxy\nDOMAIN-SUFFIX,tfc-taiwan.org.tw,Proxy\nDOMAIN-SUFFIX,blogdelnarco.com,Proxy\nDOMAIN-SUFFIX,141tube.com,Proxy\nDOMAIN-SUFFIX,d.ns02.top,Proxy\nDOMAIN-SUFFIX,smtp.live.com,Proxy\nDOMAIN-SUFFIX,88laohu.com,Proxy\nDOMAIN-SUFFIX,x12express.com,Proxy\nDOMAIN-SUFFIX,www.androidnova.org,Proxy\nDOMAIN-SUFFIX,booming.com.br,Proxy\nDOMAIN-SUFFIX,port.putaoswing.com,Proxy\nDOMAIN-SUFFIX,7mmtv.sx,Proxy\nDOMAIN-SUFFIX,miaoss.com,Proxy\nDOMAIN-SUFFIX,www.vimedo.com,Proxy\nDOMAIN-SUFFIX,agi.com,Proxy\nDOMAIN-SUFFIX,www.lelefarley.com,Proxy\nDOMAIN-SUFFIX,yy74114.com,Proxy\nDOMAIN-SUFFIX,blogimg.jp,Proxy\nDOMAIN-SUFFIX,simpleinfo.cc,Proxy\nDOMAIN-SUFFIX,vpnks.com,Proxy\nDOMAIN-SUFFIX,blockcn.com,Proxy\nDOMAIN-SUFFIX,elticoin.com,Proxy\nDOMAIN-SUFFIX,metropolis.co.jp,Proxy\nDOMAIN-SUFFIX,pokerstars.com,Proxy\nDOMAIN-SUFFIX,slutload.com,Proxy\nDOMAIN-SUFFIX,wxw.moe,Proxy\nDOMAIN-SUFFIX,www.moeyo.com,Proxy\nDOMAIN-SUFFIX,monvpn.com,Proxy\nDOMAIN-SUFFIX,154.ddnsking.com,Proxy\nDOMAIN-SUFFIX,www.streamvia.com,Proxy\nDOMAIN-SUFFIX,ilga-europe.org,Proxy\nDOMAIN-SUFFIX,my188bet.com,Proxy\nDOMAIN-SUFFIX,p6.zdassets.com,Proxy\nDOMAIN-SUFFIX,ukuleleshop.com.tw,Proxy\nDOMAIN-SUFFIX,www.myfxcm.com,Proxy\nDOMAIN-SUFFIX,www.sourcemap.com,Proxy\nDOMAIN-SUFFIX,southafricatoday.net,Proxy\nDOMAIN-SUFFIX,fg9000.com,Proxy\nDOMAIN-SUFFIX,855126.com,Proxy\nDOMAIN-SUFFIX,dnsco.xyz,Proxy\nDOMAIN-SUFFIX,vpn.mozilla.org,Proxy\nDOMAIN-SUFFIX,asg.to,Proxy\nDOMAIN-SUFFIX,bonn.de,Proxy\nDOMAIN-SUFFIX,politicalchina.org,Proxy\nDOMAIN-SUFFIX,frc.org,Proxy\nDOMAIN-SUFFIX,nb8.com,Proxy\nDOMAIN-SUFFIX,bellasaparts.cl,Proxy\nDOMAIN-SUFFIX,expo-peru.com,Proxy\nDOMAIN-SUFFIX,esccc.org.au,Proxy\nDOMAIN-SUFFIX,tdm.com.mo,Proxy\nDOMAIN-SUFFIX,wolfax.com,Proxy\nDOMAIN-SUFFIX,hk-pic5.xyz,Proxy\nDOMAIN-SUFFIX,panamapapers.sueddeutsche.de,Proxy\nDOMAIN-SUFFIX,dx1djqjpnvurw.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.hillsnews.com.au,Proxy\nDOMAIN-SUFFIX,dex582tcn7be8.cloudfront.net,Proxy\nDOMAIN-SUFFIX,igfw.net,Proxy\nDOMAIN-SUFFIX,news.yam.com,Proxy\nDOMAIN-SUFFIX,www.chicagotitle.com,Proxy\nDOMAIN-SUFFIX,ag.hga050.com,Proxy\nDOMAIN-SUFFIX,lfvpn.com,Proxy\nDOMAIN-SUFFIX,google.com.gi,Proxy\nDOMAIN-SUFFIX,wadi.desertfish.be,Proxy\nDOMAIN-SUFFIX,www.ak47fuli.com,Proxy\nDOMAIN-SUFFIX,quota.com,Proxy\nDOMAIN-SUFFIX,ctcwall.com,Proxy\nDOMAIN-SUFFIX,faststone.org,Proxy\nDOMAIN-SUFFIX,qpoe.com,Proxy\nDOMAIN-SUFFIX,rgbhu.xmx-134.com,Proxy\nDOMAIN-SUFFIX,shitaotv.org,Proxy\nDOMAIN-SUFFIX,wiki.moegirl.org,Proxy\nDOMAIN-SUFFIX,www.hexatechvpn.com,Proxy\nDOMAIN-SUFFIX,hegreart.com,Proxy\nDOMAIN-SUFFIX,cenews.eu,Proxy\nDOMAIN-SUFFIX,b.hd36.win,Proxy\nDOMAIN-SUFFIX,anyurl.org,Proxy\nDOMAIN-SUFFIX,www.independentreserve.com,Proxy\nDOMAIN-SUFFIX,www.scandhome-furniture.com,Proxy\nDOMAIN-SUFFIX,blogspot.ie,Proxy\nDOMAIN-SUFFIX,earthvpn.com,Proxy\nDOMAIN-SUFFIX,h5.ldzhibo40.pro,Proxy\nDOMAIN-SUFFIX,libredd.it,Proxy\nDOMAIN-SUFFIX,c6660.com,Proxy\nDOMAIN-SUFFIX,adult.noodlemagazine.com,Proxy\nDOMAIN-SUFFIX,ao3.org,Proxy\nDOMAIN-SUFFIX,www.mahamudracenter.org,Proxy\nDOMAIN-SUFFIX,datjm7i8cdphw.cloudfront.net,Proxy\nDOMAIN-SUFFIX,reviewcentre.com,Proxy\nDOMAIN-SUFFIX,namgyal.org,Proxy\nDOMAIN-SUFFIX,h5.ld11111.com,Proxy\nDOMAIN-SUFFIX,blogspot.co.za,Proxy\nDOMAIN-SUFFIX,www.54647.org,Proxy\nDOMAIN-SUFFIX,filefactory.com,Proxy\nDOMAIN-SUFFIX,breakwa11.blogspot.ca,Proxy\nDOMAIN-SUFFIX,paykanhunter.com,Proxy\nDOMAIN-SUFFIX,vwin116.com,Proxy\nDOMAIN-SUFFIX,www.cat-world.com.au,Proxy\nDOMAIN-SUFFIX,daidostup.ru,Proxy\nDOMAIN-SUFFIX,freehk.live,Proxy\nDOMAIN-SUFFIX,caorun.net,Proxy\nDOMAIN-SUFFIX,nude.tv,Proxy\nDOMAIN-SUFFIX,www.buypass.no,Proxy\nDOMAIN-SUFFIX,www.netpas.cc,Proxy\nDOMAIN-SUFFIX,leeshailemish.com,Proxy\nDOMAIN-SUFFIX,cn.akinator.mobi,Proxy\nDOMAIN-SUFFIX,www.e8810.com,Proxy\nDOMAIN-SUFFIX,xvideos.cn,Proxy\nDOMAIN-SUFFIX,store.sprite.org,Proxy\nDOMAIN-SUFFIX,www.dmm.com,Proxy\nDOMAIN-SUFFIX,allaround.cc,Proxy\nDOMAIN-SUFFIX,uighurbiz.net,Proxy\nDOMAIN-SUFFIX,yzc329.com,Proxy\nDOMAIN-SUFFIX,cn.dayabook.com,Proxy\nDOMAIN-SUFFIX,tpn.flnet.org,Proxy\nDOMAIN-SUFFIX,rhvpn.com,Proxy\nDOMAIN-SUFFIX,hg3088.com,Proxy\nDOMAIN-SUFFIX,mi557.com,Proxy\nDOMAIN-SUFFIX,vancitybuzz.ca,Proxy\nDOMAIN-SUFFIX,unlocator.com,Proxy\nDOMAIN-SUFFIX,wtfast.com,Proxy\nDOMAIN-SUFFIX,gaybubble.com,Proxy\nDOMAIN-SUFFIX,cipfg.org,Proxy\nDOMAIN-SUFFIX,euronatura.pt,Proxy\nDOMAIN-SUFFIX,hantec.com,Proxy\nDOMAIN-SUFFIX,www.azernews.net,Proxy\nDOMAIN-SUFFIX,www.qiandaoribao.com,Proxy\nDOMAIN-SUFFIX,www.dudu-sex.biz,Proxy\nDOMAIN-SUFFIX,nineteen19.tv,Proxy\nDOMAIN-SUFFIX,elpais.com.sv,Proxy\nDOMAIN-SUFFIX,bs-cdn.xyz,Proxy\nDOMAIN-SUFFIX,zzp.familyhealth.xyz,Proxy\nDOMAIN-SUFFIX,jav.me,Proxy\nDOMAIN-SUFFIX,manta.com,Proxy\nDOMAIN-SUFFIX,zjvpn.com,Proxy\nDOMAIN-SUFFIX,movieproxy.com,Proxy\nDOMAIN-SUFFIX,aa5000.com,Proxy\nDOMAIN-SUFFIX,ezil.me,Proxy\nDOMAIN-SUFFIX,3d48.com,Proxy\nDOMAIN-SUFFIX,social.tchncs.de,Proxy\nDOMAIN-SUFFIX,www.jav2be.com,Proxy\nDOMAIN-SUFFIX,easternstouch.co.za,Proxy\nDOMAIN-SUFFIX,provpnaccounts.com,Proxy\nDOMAIN-SUFFIX,bwin668892.com,Proxy\nDOMAIN-SUFFIX,jasoncoyne.com,Proxy\nDOMAIN-SUFFIX,ssr.tools,Proxy\nDOMAIN-SUFFIX,www.bjl2022.com,Proxy\nDOMAIN-SUFFIX,greenvpn.net,Proxy\nDOMAIN-SUFFIX,pjbar.xyz,Proxy\nDOMAIN-SUFFIX,www.inconso.de,Proxy\nDOMAIN-SUFFIX,www.acgft.net,Proxy\nDOMAIN-SUFFIX,godns.work,Proxy\nDOMAIN-SUFFIX,media.lanecrawford.com,Proxy\nDOMAIN-SUFFIX,www.biwei8668.com,Proxy\nDOMAIN-SUFFIX,docs.withdraft.com,Proxy\nDOMAIN-SUFFIX,freessh.us,Proxy\nDOMAIN-SUFFIX,dongtaiwang.com,Proxy\nDOMAIN-SUFFIX,gqfx.com,Proxy\nDOMAIN-SUFFIX,www.seo-run.co.il,Proxy\nDOMAIN-SUFFIX,genocidewatch.org,Proxy\nDOMAIN-SUFFIX,x3.1024lualu.club,Proxy\nDOMAIN-SUFFIX,2poi.jp,Proxy\nDOMAIN-SUFFIX,crmx.us,Proxy\nDOMAIN-SUFFIX,6hch.com,Proxy\nDOMAIN-SUFFIX,sf-2019.com,Proxy\nDOMAIN-SUFFIX,utorrent.com,Proxy\nDOMAIN-SUFFIX,www.fleetboard.com,Proxy\nDOMAIN-SUFFIX,www.cna.com.tw,Proxy\nDOMAIN-SUFFIX,certei.com.br,Proxy\nDOMAIN-SUFFIX,tcewf.org,Proxy\nDOMAIN-SUFFIX,vpn.blackvpn.lt,Proxy\nDOMAIN-SUFFIX,fetlife.com,Proxy\nDOMAIN-SUFFIX,www.faceboom.com,Proxy\nDOMAIN-SUFFIX,bb366.net,Proxy\nDOMAIN-SUFFIX,de1lib.org,Proxy\nDOMAIN-SUFFIX,slideshare.com,Proxy\nDOMAIN-SUFFIX,myz.info,Proxy\nDOMAIN-SUFFIX,twitch.com,Proxy\nDOMAIN-SUFFIX,b16.tv,Proxy\nDOMAIN-SUFFIX,carmotorshow.com,Proxy\nDOMAIN-SUFFIX,unwall2012.com,Proxy\nDOMAIN-SUFFIX,738284.com,Proxy\nDOMAIN-SUFFIX,treasureweb.net,Proxy\nDOMAIN-SUFFIX,www.eklablog.com,Proxy\nDOMAIN-SUFFIX,twitoaster.com,Proxy\nDOMAIN-SUFFIX,www.teenporntube.com,Proxy\nDOMAIN-SUFFIX,falunhr.org,Proxy\nDOMAIN-SUFFIX,shadowsocks.la,Proxy\nDOMAIN-SUFFIX,1680177.com,Proxy\nDOMAIN-SUFFIX,www.jumav.com,Proxy\nDOMAIN-SUFFIX,393.microcycas.com,Proxy\nDOMAIN-SUFFIX,www.theentertaineronline.com,Proxy\nDOMAIN-SUFFIX,actiongirls.com,Proxy\nDOMAIN-SUFFIX,d1bp73dar08jgr.cloudfront.net,Proxy\nDOMAIN-SUFFIX,005852.cc,Proxy\nDOMAIN-SUFFIX,zeutch.com,Proxy\nDOMAIN-SUFFIX,myaccount.infinox-asia.com,Proxy\nDOMAIN-SUFFIX,www.vg088.com,Proxy\nDOMAIN-SUFFIX,www.andong.org.tw,Proxy\nDOMAIN-SUFFIX,kissingerassoc.com,Proxy\nDOMAIN-SUFFIX,pptp.kr,Proxy\nDOMAIN-SUFFIX,christianheadlines.com,Proxy\nDOMAIN-SUFFIX,woman.udn.com,Proxy\nDOMAIN-SUFFIX,great-roc.org,Proxy\nDOMAIN-SUFFIX,adrianato.com.br,Proxy\nDOMAIN-SUFFIX,035007.com,Proxy\nDOMAIN-SUFFIX,porn2.com,Proxy\nDOMAIN-SUFFIX,google.ms,Proxy\nDOMAIN-SUFFIX,lcvpn.com,Proxy\nDOMAIN-SUFFIX,vpnfree.com,Proxy\nDOMAIN-SUFFIX,fiberprox.eu,Proxy\nDOMAIN-SUFFIX,wattpad.com,Proxy\nDOMAIN-SUFFIX,tredding.net,Proxy\nDOMAIN-SUFFIX,mariocollin.com,Proxy\nDOMAIN-SUFFIX,sdk3.cf,Proxy\nDOMAIN-SUFFIX,javseen.com,Proxy\nDOMAIN-SUFFIX,twerkingbutt.com,Proxy\nDOMAIN-SUFFIX,ssfree.top,Proxy\nDOMAIN-SUFFIX,www.u-mall.com.tw,Proxy\nDOMAIN-SUFFIX,odoh-target.alekberg.net,Proxy\nDOMAIN-SUFFIX,tarr.uspto.gov,Proxy\nDOMAIN-SUFFIX,enajurov.com,Proxy\nDOMAIN-SUFFIX,97.net,Proxy\nDOMAIN-SUFFIX,live.pncle8.com,Proxy\nDOMAIN-SUFFIX,delgetscom.blogspot.hk,Proxy\nDOMAIN-SUFFIX,cool18.com,Proxy\nDOMAIN-SUFFIX,huaxia-news.com,Proxy\nDOMAIN-SUFFIX,freebrowser.org,Proxy\nDOMAIN-SUFFIX,byt707.com,Proxy\nDOMAIN-SUFFIX,www.dailystar.com.lb,Proxy\nDOMAIN-SUFFIX,buddhism.ie,Proxy\nDOMAIN-SUFFIX,web.telegram.im,Proxy\nDOMAIN-SUFFIX,ukshaolintemple.com,Proxy\nDOMAIN-SUFFIX,china.buzzsprout.com,Proxy\nDOMAIN-SUFFIX,blog.onahole.eu,Proxy\nDOMAIN-SUFFIX,hackmd.io,Proxy\nDOMAIN-SUFFIX,depositphotos.com,Proxy\nDOMAIN-SUFFIX,www.falun-houston.org,Proxy\nDOMAIN-SUFFIX,www.binance.org,Proxy\nDOMAIN-SUFFIX,cn.fibogroup.com,Proxy\nDOMAIN-SUFFIX,www.p21p.com,Proxy\nDOMAIN-SUFFIX,bmhl.xyz,Proxy\nDOMAIN-SUFFIX,xiaav.cc,Proxy\nDOMAIN-SUFFIX,xh8705.com,Proxy\nDOMAIN-SUFFIX,jinpian.org,Proxy\nDOMAIN-SUFFIX,ws.freepac.pw,Proxy\nDOMAIN-SUFFIX,xinbi696.com,Proxy\nDOMAIN-SUFFIX,www.bilanz.ch,Proxy\nDOMAIN-SUFFIX,greatroc.tw,Proxy\nDOMAIN-SUFFIX,www.picogear.com,Proxy\nDOMAIN-SUFFIX,fthemes.com,Proxy\nDOMAIN-SUFFIX,j513.site,Proxy\nDOMAIN-SUFFIX,hhli.art.b0ne.com,Proxy\nDOMAIN-SUFFIX,google.com.my,Proxy\nDOMAIN-SUFFIX,g.libnull.com,Proxy\nDOMAIN-SUFFIX,75866qq.com,Proxy\nDOMAIN-SUFFIX,6020.vip,Proxy\nDOMAIN-SUFFIX,mine.nu,Proxy\nDOMAIN-SUFFIX,google.sk,Proxy\nDOMAIN-SUFFIX,w3.n4t.co,Proxy\nDOMAIN-SUFFIX,www.onevpn.com,Proxy\nDOMAIN-SUFFIX,chinainformation.com.au,Proxy\nDOMAIN-SUFFIX,tibethouse.jp,Proxy\nDOMAIN-SUFFIX,77167c.com,Proxy\nDOMAIN-SUFFIX,throughnightsfire.com,Proxy\nDOMAIN-SUFFIX,ywpw.com,Proxy\nDOMAIN-SUFFIX,googleyoutube.com,Proxy\nDOMAIN-SUFFIX,burningangel.com,Proxy\nDOMAIN-SUFFIX,cn55.cc,Proxy\nDOMAIN-SUFFIX,zavio.nl,Proxy\nDOMAIN-SUFFIX,new.naked.com,Proxy\nDOMAIN-SUFFIX,miyou.es,Proxy\nDOMAIN-SUFFIX,bushiroad-anime.com,Proxy\nDOMAIN-SUFFIX,beijingsquare.com,Proxy\nDOMAIN-SUFFIX,sola.idv.tw,Proxy\nDOMAIN-SUFFIX,freevpn4you.net,Proxy\nDOMAIN-SUFFIX,localbitcoins.net,Proxy\nDOMAIN-SUFFIX,aa911.xyz,Proxy\nDOMAIN-SUFFIX,mapp-web.r88app03.com,Proxy\nDOMAIN-SUFFIX,liquid.com,Proxy\nDOMAIN-SUFFIX,vel.velikiyustyug.ru,Proxy\nDOMAIN-SUFFIX,sam.my.id,Proxy\nDOMAIN-SUFFIX,dtwang.org,Proxy\nDOMAIN-SUFFIX,www.liuqian.org,Proxy\nDOMAIN-SUFFIX,dy.li.vc,Proxy\nDOMAIN-SUFFIX,asahi.com,Proxy\nDOMAIN-SUFFIX,hdarea.co,Proxy\nDOMAIN-SUFFIX,dragtimes.com,Proxy\nDOMAIN-SUFFIX,doorbrowse.com,Proxy\nDOMAIN-SUFFIX,66630.com,Proxy\nDOMAIN-SUFFIX,sun0365.com,Proxy\nDOMAIN-SUFFIX,pye6.dhcp.biz,Proxy\nDOMAIN-SUFFIX,168.cr.rs,Proxy\nDOMAIN-SUFFIX,xxxymovies.com,Proxy\nDOMAIN-SUFFIX,www.btctrade.im,Proxy\nDOMAIN-SUFFIX,pwnyoutube.com,Proxy\nDOMAIN-SUFFIX,dbzhu.com,Proxy\nDOMAIN-SUFFIX,www.google.bt,Proxy\nDOMAIN-SUFFIX,d82kg0g43e1bu.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.cs.ccu.edu.tw,Proxy\nDOMAIN-SUFFIX,vipbw88.com,Proxy\nDOMAIN-SUFFIX,gmail.com.br,Proxy\nDOMAIN-SUFFIX,www.e8play.com,Proxy\nDOMAIN-SUFFIX,tor-exit-37.for-privacy.net,Proxy\nDOMAIN-SUFFIX,gnews.org,Proxy\nDOMAIN-SUFFIX,winzogames.com,Proxy\nDOMAIN-SUFFIX,pin.it,Proxy\nDOMAIN-SUFFIX,soundalerts.com,Proxy\nDOMAIN-SUFFIX,site725608-7388-434.strikingly.com,Proxy\nDOMAIN-SUFFIX,newsolid.me,Proxy\nDOMAIN-SUFFIX,yevpn.com,Proxy\nDOMAIN-SUFFIX,searx.be,Proxy\nDOMAIN-SUFFIX,m.ca821.com,Proxy\nDOMAIN-SUFFIX,home.shadowsocks.ch,Proxy\nDOMAIN-SUFFIX,taiwanlife.org,Proxy\nDOMAIN-SUFFIX,www.dimsumdaily.hk,Proxy\nDOMAIN-SUFFIX,trt.net.tr,Proxy\nDOMAIN-SUFFIX,xvideos3.com,Proxy\nDOMAIN-SUFFIX,a.bnaz.org,Proxy\nDOMAIN-SUFFIX,luscious.net,Proxy\nDOMAIN-SUFFIX,www.dag333.net,Proxy\nDOMAIN-SUFFIX,nicehash.com,Proxy\nDOMAIN-SUFFIX,us.ishadowx.net,Proxy\nDOMAIN-SUFFIX,c9988.com,Proxy\nDOMAIN-SUFFIX,redheroes.forumcommunity.net,Proxy\nDOMAIN-SUFFIX,www.thec.org.tw,Proxy\nDOMAIN-SUFFIX,proandroiddev.com,Proxy\nDOMAIN-SUFFIX,bbs.kanshifang.com,Proxy\nDOMAIN-SUFFIX,www.internetnews.com,Proxy\nDOMAIN-SUFFIX,night02.live,Proxy\nDOMAIN-SUFFIX,mobileways.de,Proxy\nDOMAIN-SUFFIX,hkbbcc.com,Proxy\nDOMAIN-SUFFIX,www.haohan001.com,Proxy\nDOMAIN-SUFFIX,cloverfoodlab.com,Proxy\nDOMAIN-SUFFIX,0003tyc.com,Proxy\nDOMAIN-SUFFIX,discordapi.com,Proxy\nDOMAIN-SUFFIX,minhhue.net,Proxy\nDOMAIN-SUFFIX,landofjoy.co.uk,Proxy\nDOMAIN-SUFFIX,dcard.hk,Proxy\nDOMAIN-SUFFIX,btcc.com,Proxy\nDOMAIN-SUFFIX,www.javcloud.com,Proxy\nDOMAIN-SUFFIX,bdsmlr.com,Proxy\nDOMAIN-SUFFIX,springwood.me,Proxy\nDOMAIN-SUFFIX,aaakk.org,Proxy\nDOMAIN-SUFFIX,736.slyip.net,Proxy\nDOMAIN-SUFFIX,nm128.com,Proxy\nDOMAIN-SUFFIX,blessinfo.com.br,Proxy\nDOMAIN-SUFFIX,poie.top,Proxy\nDOMAIN-SUFFIX,www.shireyishunjian.org,Proxy\nDOMAIN-SUFFIX,www.foebud.org,Proxy\nDOMAIN-SUFFIX,yuan.idv.tw,Proxy\nDOMAIN-SUFFIX,www.xinha.win,Proxy\nDOMAIN-SUFFIX,91app.tv,Proxy\nDOMAIN-SUFFIX,kiwifarms.net,Proxy\nDOMAIN-SUFFIX,91vps.win,Proxy\nDOMAIN-SUFFIX,acg.ci,Proxy\nDOMAIN-SUFFIX,anarchistsoccermom.blogspot.hk,Proxy\nDOMAIN-SUFFIX,pcstore.com.tw,Proxy\nDOMAIN-SUFFIX,ultrasn0w.com,Proxy\nDOMAIN-SUFFIX,nbtvpn.com,Proxy\nDOMAIN-SUFFIX,unlockacgweb.galstars.net,Proxy\nDOMAIN-SUFFIX,gmail.com,Proxy\nDOMAIN-SUFFIX,dsnextgen.com,Proxy\nDOMAIN-SUFFIX,um.freepac.pw,Proxy\nDOMAIN-SUFFIX,mainnet.infura.io,Proxy\nDOMAIN-SUFFIX,b311455.com,Proxy\nDOMAIN-SUFFIX,yoplait.com,Proxy\nDOMAIN-SUFFIX,cs089.com,Proxy\nDOMAIN-SUFFIX,d5226.com,Proxy\nDOMAIN-SUFFIX,tds7.net,Proxy\nDOMAIN-SUFFIX,tageschau.de,Proxy\nDOMAIN-SUFFIX,5kk.am,Proxy\nDOMAIN-SUFFIX,fll.cc,Proxy\nDOMAIN-SUFFIX,sondaggibidimedia.com,Proxy\nDOMAIN-SUFFIX,lek2.ddns.us,Proxy\nDOMAIN-SUFFIX,1187003aa.com,Proxy\nDOMAIN-SUFFIX,basketball.fantasysports.yahoo.com,Proxy\nDOMAIN-SUFFIX,www.klook.com,Proxy\nDOMAIN-SUFFIX,gaytube.com,Proxy\nDOMAIN-SUFFIX,220808.com,Proxy\nDOMAIN-SUFFIX,nua.one,Proxy\nDOMAIN-SUFFIX,webun.jp,Proxy\nDOMAIN-SUFFIX,icili.net,Proxy\nDOMAIN-SUFFIX,www.vw012.com,Proxy\nDOMAIN-SUFFIX,vercammen.org,Proxy\nDOMAIN-SUFFIX,kaiz.jp,Proxy\nDOMAIN-SUFFIX,www.delicate.idv.tw,Proxy\nDOMAIN-SUFFIX,lflinkup.com,Proxy\nDOMAIN-SUFFIX,ca8077.com,Proxy\nDOMAIN-SUFFIX,www.socketpro.net,Proxy\nDOMAIN-SUFFIX,openvpn.org,Proxy\nDOMAIN-SUFFIX,vc33.tk,Proxy\nDOMAIN-SUFFIX,eriversoft.com,Proxy\nDOMAIN-SUFFIX,edwardsalem.com,Proxy\nDOMAIN-SUFFIX,www.nthlink.com,Proxy\nDOMAIN-SUFFIX,top2.life,Proxy\nDOMAIN-SUFFIX,sg.iabc.com.tw,Proxy\nDOMAIN-SUFFIX,d8sgdg9sdzglz.cloudfront.net,Proxy\nDOMAIN-SUFFIX,cs.xiaomitv.cc,Proxy\nDOMAIN-SUFFIX,rabb.it,Proxy\nDOMAIN-SUFFIX,www.zeenews.com,Proxy\nDOMAIN-SUFFIX,wig.dhcp.biz,Proxy\nDOMAIN-SUFFIX,proxite.net,Proxy\nDOMAIN-SUFFIX,jadebuddha.org,Proxy\nDOMAIN-SUFFIX,ca153.com,Proxy\nDOMAIN-SUFFIX,waltermartin.com,Proxy\nDOMAIN-SUFFIX,zlibrary-global.se,Proxy\nDOMAIN-SUFFIX,alioda.ro,Proxy\nDOMAIN-SUFFIX,s1.nordcdn.com,Proxy\nDOMAIN-SUFFIX,sby-doh.limotelu.org,Proxy\nDOMAIN-SUFFIX,bcwzp.com,Proxy\nDOMAIN-SUFFIX,cdn2.av1top.com,Proxy\nDOMAIN-SUFFIX,nowqiu.com,Proxy\nDOMAIN-SUFFIX,fantasymassage.com,Proxy\nDOMAIN-SUFFIX,lbgj3.com,Proxy\nDOMAIN-SUFFIX,www.quicksnapper.com,Proxy\nDOMAIN-SUFFIX,soundcloud.hs.llnwd.net,Proxy\nDOMAIN-SUFFIX,epochtimes.ru,Proxy\nDOMAIN-SUFFIX,97365.com,Proxy\nDOMAIN-SUFFIX,waikeung.org,Proxy\nDOMAIN-SUFFIX,meetav.com,Proxy\nDOMAIN-SUFFIX,vegas.williamhill.com,Proxy\nDOMAIN-SUFFIX,tor-exit-36.for-privacy.net,Proxy\nDOMAIN-SUFFIX,murasakiji.blogspot.hk,Proxy\nDOMAIN-SUFFIX,google.vu,Proxy\nDOMAIN-SUFFIX,taup.net,Proxy\nDOMAIN-SUFFIX,www.cfos.de,Proxy\nDOMAIN-SUFFIX,www.t2201.com,Proxy\nDOMAIN-SUFFIX,3animalsextube.com,Proxy\nDOMAIN-SUFFIX,leechenyang.com,Proxy\nDOMAIN-SUFFIX,statigr.am,Proxy\nDOMAIN-SUFFIX,oao.idv.tw,Proxy\nDOMAIN-SUFFIX,radio.fr,Proxy\nDOMAIN-SUFFIX,falundafapersian.org,Proxy\nDOMAIN-SUFFIX,odprava.si,Proxy\nDOMAIN-SUFFIX,www.nj-falundafa.org,Proxy\nDOMAIN-SUFFIX,developer.petalmaps.com,Proxy\nDOMAIN-SUFFIX,from-mi.com,Proxy\nDOMAIN-SUFFIX,zacebook.com,Proxy\nDOMAIN-SUFFIX,wiki.kfd.me,Proxy\nDOMAIN-SUFFIX,bbkz.com,Proxy\nDOMAIN-SUFFIX,ww4report.com,Proxy\nDOMAIN-SUFFIX,ohcam.net,Proxy\nDOMAIN-SUFFIX,tre.9bar1.com,Proxy\nDOMAIN-SUFFIX,tv.google,Proxy\nDOMAIN-SUFFIX,3166602.com,Proxy\nDOMAIN-SUFFIX,www.y66i.com,Proxy\nDOMAIN-SUFFIX,libgen.lc,Proxy\nDOMAIN-SUFFIX,wknews.org,Proxy\nDOMAIN-SUFFIX,www.internationalrivers.org,Proxy\nDOMAIN-SUFFIX,chinesenewsnet.com,Proxy\nDOMAIN-SUFFIX,breaking911.com,Proxy\nDOMAIN-SUFFIX,cardinalkungfoundation.org,Proxy\nDOMAIN-SUFFIX,kodingen.com,Proxy\nDOMAIN-SUFFIX,porngo.com,Proxy\nDOMAIN-SUFFIX,from-ar.com,Proxy\nDOMAIN-SUFFIX,www.muslimtents.com,Proxy\nDOMAIN-SUFFIX,bitvise.com,Proxy\nDOMAIN-SUFFIX,servecentral.org,Proxy\nDOMAIN-SUFFIX,shopping.yahoo.co.jp,Proxy\nDOMAIN-SUFFIX,www.dfn.org,Proxy\nDOMAIN-SUFFIX,www.1eighty8.com,Proxy\nDOMAIN-SUFFIX,yun5888.com,Proxy\nDOMAIN-SUFFIX,indianrealestateforum.com,Proxy\nDOMAIN-SUFFIX,healththe.xyz,Proxy\nDOMAIN-SUFFIX,safety.google,Proxy\nDOMAIN-SUFFIX,b.spagettitoast.com,Proxy\nDOMAIN-SUFFIX,www.chaspik.spb.ru,Proxy\nDOMAIN-SUFFIX,43110.cf,Proxy\nDOMAIN-SUFFIX,dance.com,Proxy\nDOMAIN-SUFFIX,699696.xyz,Proxy\nDOMAIN-SUFFIX,imageglass.org,Proxy\nDOMAIN-SUFFIX,westernbotanicals.com,Proxy\nDOMAIN-SUFFIX,kendatire.com,Proxy\nDOMAIN-SUFFIX,rnz.co.nz,Proxy\nDOMAIN-SUFFIX,mofa.gov.tw,Proxy\nDOMAIN-SUFFIX,www.wingyios.com,Proxy\nDOMAIN-SUFFIX,72.cr.rs,Proxy\nDOMAIN-SUFFIX,porhub.com,Proxy\nDOMAIN-SUFFIX,comhealth.xyz,Proxy\nDOMAIN-SUFFIX,ahri.site,Proxy\nDOMAIN-SUFFIX,www.koreapas.com,Proxy\nDOMAIN-SUFFIX,chinaeweekly.com,Proxy\nDOMAIN-SUFFIX,kagyu.org,Proxy\nDOMAIN-SUFFIX,coppersurfer.tk,Proxy\nDOMAIN-SUFFIX,xh2666.com,Proxy\nDOMAIN-SUFFIX,bigdongdongclub.github.io,Proxy\nDOMAIN-SUFFIX,www.paperclip.tk,Proxy\nDOMAIN-SUFFIX,errotica-archives.com,Proxy\nDOMAIN-SUFFIX,moneydodo.idv.tw,Proxy\nDOMAIN-SUFFIX,m.dy9907.com,Proxy\nDOMAIN-SUFFIX,conspecconstruct.ro,Proxy\nDOMAIN-SUFFIX,www.kenti.jp,Proxy\nDOMAIN-SUFFIX,etvonline.hk,Proxy\nDOMAIN-SUFFIX,webhop.org,Proxy\nDOMAIN-SUFFIX,www.mimi.ooo,Proxy\nDOMAIN-SUFFIX,19947018.com,Proxy\nDOMAIN-SUFFIX,sss.xxx,Proxy\nDOMAIN-SUFFIX,derekhsu.homeip.net,Proxy\nDOMAIN-SUFFIX,rapidsharedata.com,Proxy\nDOMAIN-SUFFIX,www.linkuswell.com,Proxy\nDOMAIN-SUFFIX,codingdrama.com,Proxy\nDOMAIN-SUFFIX,gaoming.net,Proxy\nDOMAIN-SUFFIX,84493300.com,Proxy\nDOMAIN-SUFFIX,selifan.com,Proxy\nDOMAIN-SUFFIX,giftflip.com,Proxy\nDOMAIN-SUFFIX,www.bluemountainsgazette.com.au,Proxy\nDOMAIN-SUFFIX,yddc4888.com,Proxy\nDOMAIN-SUFFIX,www.zuruling.org,Proxy\nDOMAIN-SUFFIX,api.linksalpha.com,Proxy\nDOMAIN-SUFFIX,tubaholic.com,Proxy\nDOMAIN-SUFFIX,khanhquynh.vn,Proxy\nDOMAIN-SUFFIX,167ooo.net,Proxy\nDOMAIN-SUFFIX,health6.icu,Proxy\nDOMAIN-SUFFIX,bell.wiki,Proxy\nDOMAIN-SUFFIX,watchchina.com,Proxy\nDOMAIN-SUFFIX,sjtk.app,Proxy\nDOMAIN-SUFFIX,pornrabbit.com,Proxy\nDOMAIN-SUFFIX,www.lighthonestyhrd.org,Proxy\nDOMAIN-SUFFIX,xbtx88.com,Proxy\nDOMAIN-SUFFIX,twitter.076.ne.jp,Proxy\nDOMAIN-SUFFIX,strongvpn.com.mx,Proxy\nDOMAIN-SUFFIX,is-a-personaltrainer.com,Proxy\nDOMAIN-SUFFIX,generated.photos,Proxy\nDOMAIN-SUFFIX,freedome-de-gw.fd.f-secure.com,Proxy\nDOMAIN-SUFFIX,multiply.com,Proxy\nDOMAIN-SUFFIX,civit.ai,Proxy\nDOMAIN-SUFFIX,silverdaddies-videos.com,Proxy\nDOMAIN-SUFFIX,xfinity.com,Proxy\nDOMAIN-SUFFIX,gtplanet.net,Proxy\nDOMAIN-SUFFIX,www.twitturly.com,Proxy\nDOMAIN-SUFFIX,fense888.com,Proxy\nDOMAIN-SUFFIX,www.160tu.com,Proxy\nDOMAIN-SUFFIX,www.gb255.com,Proxy\nDOMAIN-SUFFIX,puba.com,Proxy\nDOMAIN-SUFFIX,00899i.com,Proxy\nDOMAIN-SUFFIX,avmoo.pw,Proxy\nDOMAIN-SUFFIX,xiaxiaoqiang.net,Proxy\nDOMAIN-SUFFIX,shi-magazine.com,Proxy\nDOMAIN-SUFFIX,m.188live.net,Proxy\nDOMAIN-SUFFIX,jcomicwin.xyz,Proxy\nDOMAIN-SUFFIX,www.wikifunctions.org,Proxy\nDOMAIN-SUFFIX,www.angelatheangel.com.tw,Proxy\nDOMAIN-SUFFIX,lolo.pro,Proxy\nDOMAIN-SUFFIX,gpt.eamclan.com,Proxy\nDOMAIN-SUFFIX,is-an-artist.com,Proxy\nDOMAIN-SUFFIX,www.us.penguingroup.com,Proxy\nDOMAIN-SUFFIX,setupvpn.com,Proxy\nDOMAIN-SUFFIX,bet9477.com,Proxy\nDOMAIN-SUFFIX,www.thestupidnetwork.fr,Proxy\nDOMAIN-SUFFIX,geocities.jp,Proxy\nDOMAIN-SUFFIX,redlightcenter.com,Proxy\nDOMAIN-SUFFIX,kk-whys.co.jp,Proxy\nDOMAIN-SUFFIX,thomasbernhard.org,Proxy\nDOMAIN-SUFFIX,zz383.net,Proxy\nDOMAIN-SUFFIX,99u.adobe.com,Proxy\nDOMAIN-SUFFIX,tpprc.org,Proxy\nDOMAIN-SUFFIX,video.foxnews.com,Proxy\nDOMAIN-SUFFIX,www.popscreen.com,Proxy\nDOMAIN-SUFFIX,cn.theaustralian.com.au,Proxy\nDOMAIN-SUFFIX,nyt8.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,caijinglengyan.com,Proxy\nDOMAIN-SUFFIX,tb0083.com,Proxy\nDOMAIN-SUFFIX,ddns.info,Proxy\nDOMAIN-SUFFIX,h.w3cx.us,Proxy\nDOMAIN-SUFFIX,ingtv.me,Proxy\nDOMAIN-SUFFIX,chinanewscenter.com,Proxy\nDOMAIN-SUFFIX,goldbet.com,Proxy\nDOMAIN-SUFFIX,www.lavavpn.com,Proxy\nDOMAIN-SUFFIX,hittt.blogspot.hk,Proxy\nDOMAIN-SUFFIX,gati.org.tw,Proxy\nDOMAIN-SUFFIX,pinstake.com,Proxy\nDOMAIN-SUFFIX,awc7.com,Proxy\nDOMAIN-SUFFIX,pximg.net,Proxy\nDOMAIN-SUFFIX,www.pwndefend.com,Proxy\nDOMAIN-SUFFIX,manosx.com,Proxy\nDOMAIN-SUFFIX,www.fuhuistocks.com,Proxy\nDOMAIN-SUFFIX,mastodon.fun,Proxy\nDOMAIN-SUFFIX,freecanadavpn.com,Proxy\nDOMAIN-SUFFIX,www.gettyimages.co.uk,Proxy\nDOMAIN-SUFFIX,www.vox.de,Proxy\nDOMAIN-SUFFIX,www.faroo.com,Proxy\nDOMAIN-SUFFIX,www.leafyvpn.net,Proxy\nDOMAIN-SUFFIX,sbf335.com,Proxy\nDOMAIN-SUFFIX,chinaaid.me,Proxy\nDOMAIN-SUFFIX,n47s.ras.flnet.org,Proxy\nDOMAIN-SUFFIX,www.buildwithchrome.com,Proxy\nDOMAIN-SUFFIX,fzlm.com,Proxy\nDOMAIN-SUFFIX,serbiavpn.com,Proxy\nDOMAIN-SUFFIX,celebritymovieblog.com,Proxy\nDOMAIN-SUFFIX,avyahoo.com,Proxy\nDOMAIN-SUFFIX,mynewsolid.xyz,Proxy\nDOMAIN-SUFFIX,blogspot.co.uk,Proxy\nDOMAIN-SUFFIX,qi-gong.me,Proxy\nDOMAIN-SUFFIX,lh4.ggpht.com,Proxy\nDOMAIN-SUFFIX,iafd.com,Proxy\nDOMAIN-SUFFIX,www.mt1016.com,Proxy\nDOMAIN-SUFFIX,mail.dataoncloud.com,Proxy\nDOMAIN-SUFFIX,wowlegacy.ml,Proxy\nDOMAIN-SUFFIX,mms333.cf,Proxy\nDOMAIN-SUFFIX,trademe.co.nz,Proxy\nDOMAIN-SUFFIX,wqyd.org,Proxy\nDOMAIN-SUFFIX,www.e8832.com,Proxy\nDOMAIN-SUFFIX,aljazeera.com,Proxy\nDOMAIN-SUFFIX,s1188.cc,Proxy\nDOMAIN-SUFFIX,rushbee.com,Proxy\nDOMAIN-SUFFIX,bbs.cangku.one,Proxy\nDOMAIN-SUFFIX,tparents.org,Proxy\nDOMAIN-SUFFIX,www.jinsa.org,Proxy\nDOMAIN-SUFFIX,98.effers.com,Proxy\nDOMAIN-SUFFIX,www.xiexingwen.com,Proxy\nDOMAIN-SUFFIX,manwa.vip,Proxy\nDOMAIN-SUFFIX,m583.com,Proxy\nDOMAIN-SUFFIX,www.instamp3.live,Proxy\nDOMAIN-SUFFIX,www.ovhcloud.com,Proxy\nDOMAIN-SUFFIX,launchgood.com,Proxy\nDOMAIN-SUFFIX,smh.com.au,Proxy\nDOMAIN-SUFFIX,tibetsun.com,Proxy\nDOMAIN-SUFFIX,wtfpeople.com,Proxy\nDOMAIN-SUFFIX,tlc163.com,Proxy\nDOMAIN-SUFFIX,se.etowns.net,Proxy\nDOMAIN-SUFFIX,euroname.cn,Proxy\nDOMAIN-SUFFIX,www.vps168.tk,Proxy\nDOMAIN-SUFFIX,desipapa.com,Proxy\nDOMAIN-SUFFIX,g2.twimg.com,Proxy\nDOMAIN-SUFFIX,barenghi.com.ar,Proxy\nDOMAIN-SUFFIX,www.105sihu.com,Proxy\nDOMAIN-SUFFIX,97xae.com,Proxy\nDOMAIN-SUFFIX,whyx.org,Proxy\nDOMAIN-SUFFIX,hrcchina.org,Proxy\nDOMAIN-SUFFIX,3aazb.com,Proxy\nDOMAIN-SUFFIX,hka8964.wordpress.com,Proxy\nDOMAIN-SUFFIX,cfos.de,Proxy\nDOMAIN-SUFFIX,zh.wikinews.org,Proxy\nDOMAIN-SUFFIX,1512367.com,Proxy\nDOMAIN-SUFFIX,cobinhood.com,Proxy\nDOMAIN-SUFFIX,idex.io,Proxy\nDOMAIN-SUFFIX,www.ptlaohu.com,Proxy\nDOMAIN-SUFFIX,www.dy2090.com,Proxy\nDOMAIN-SUFFIX,buyu8007.com,Proxy\nDOMAIN-SUFFIX,kms.03k.org,Proxy\nDOMAIN-SUFFIX,en.godfootsteps.org,Proxy\nDOMAIN-SUFFIX,iphonix.fr,Proxy\nDOMAIN-SUFFIX,sinchew-i.com,Proxy\nDOMAIN-SUFFIX,star-advertising.com,Proxy\nDOMAIN-SUFFIX,tibetancommunity.org,Proxy\nDOMAIN-SUFFIX,freehostia.com,Proxy\nDOMAIN-SUFFIX,vanweb.harland.net,Proxy\nDOMAIN-SUFFIX,nf.id.au,Proxy\nDOMAIN-SUFFIX,php3.ga,Proxy\nDOMAIN-SUFFIX,radiocanada.ca,Proxy\nDOMAIN-SUFFIX,www.datibike.com,Proxy\nDOMAIN-SUFFIX,www.hj252.com,Proxy\nDOMAIN-SUFFIX,freelotto.com,Proxy\nDOMAIN-SUFFIX,1224.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,just-ping.com,Proxy\nDOMAIN-SUFFIX,soompi.com,Proxy\nDOMAIN-SUFFIX,dd9871.com,Proxy\nDOMAIN-SUFFIX,www.fun712.com,Proxy\nDOMAIN-SUFFIX,www.471678.com,Proxy\nDOMAIN-SUFFIX,www.pikiran-rakyat.com,Proxy\nDOMAIN-SUFFIX,www.ski-red.com,Proxy\nDOMAIN-SUFFIX,uaevpn.com,Proxy\nDOMAIN-SUFFIX,lanota-67543202.firebaseio.com,Proxy\nDOMAIN-SUFFIX,eeas.europa.eu,Proxy\nDOMAIN-SUFFIX,withgoogle.com,Proxy\nDOMAIN-SUFFIX,www.ecotibet.org,Proxy\nDOMAIN-SUFFIX,helloyoutube.com,Proxy\nDOMAIN-SUFFIX,samaritanspurse.org,Proxy\nDOMAIN-SUFFIX,ftchinese.com.com,Proxy\nDOMAIN-SUFFIX,h5.ledong847.cc,Proxy\nDOMAIN-SUFFIX,anime.bliav-1.com,Proxy\nDOMAIN-SUFFIX,pc.onmypc.net,Proxy\nDOMAIN-SUFFIX,www.asmr.one,Proxy\nDOMAIN-SUFFIX,furinkan.com,Proxy\nDOMAIN-SUFFIX,seqing911.com,Proxy\nDOMAIN-SUFFIX,www.australianalmonds.com.au,Proxy\nDOMAIN-SUFFIX,www.comicun.com,Proxy\nDOMAIN-SUFFIX,www.visitbasis.com,Proxy\nDOMAIN-SUFFIX,orientalradio.com.sg,Proxy\nDOMAIN-SUFFIX,atlas.valenciacollege.edu,Proxy\nDOMAIN-SUFFIX,storm.mg,Proxy\nDOMAIN-SUFFIX,hitbtc.com,Proxy\nDOMAIN-SUFFIX,www.e8033.com,Proxy\nDOMAIN-SUFFIX,gty.im,Proxy\nDOMAIN-SUFFIX,www.lantiantian.com,Proxy\nDOMAIN-SUFFIX,gadgetz.net,Proxy\nDOMAIN-SUFFIX,relatedusa.com,Proxy\nDOMAIN-SUFFIX,vpnland.com,Proxy\nDOMAIN-SUFFIX,zuola.com,Proxy\nDOMAIN-SUFFIX,h5.402ld.com,Proxy\nDOMAIN-SUFFIX,ccmusa.org,Proxy\nDOMAIN-SUFFIX,m.manhuatai.net,Proxy\nDOMAIN-SUFFIX,portal.meomiao.xyz,Proxy\nDOMAIN-SUFFIX,falundafa-dc.org,Proxy\nDOMAIN-SUFFIX,www.christophehuet.com,Proxy\nDOMAIN-SUFFIX,428428bb.com,Proxy\nDOMAIN-SUFFIX,a50e791daf7240cfa83d58f58a64b871.azureedge.net,Proxy\nDOMAIN-SUFFIX,ssh.id.lv,Proxy\nDOMAIN-SUFFIX,nitter.cz,Proxy\nDOMAIN-SUFFIX,387.quantumidiot.com,Proxy\nDOMAIN-SUFFIX,www.itmck.com,Proxy\nDOMAIN-SUFFIX,nchrd.org,Proxy\nDOMAIN-SUFFIX,www.expressen.se,Proxy\nDOMAIN-SUFFIX,beeg.com,Proxy\nDOMAIN-SUFFIX,piring.com,Proxy\nDOMAIN-SUFFIX,bellagamba.net.ar,Proxy\nDOMAIN-SUFFIX,australsports.cl,Proxy\nDOMAIN-SUFFIX,627.flnet.org,Proxy\nDOMAIN-SUFFIX,dafa186.com,Proxy\nDOMAIN-SUFFIX,fvnc.pat.flnet.org,Proxy\nDOMAIN-SUFFIX,d19g1tkerpkn1x.cloudfront.net,Proxy\nDOMAIN-SUFFIX,6000.vip,Proxy\nDOMAIN-SUFFIX,10bo8118.com,Proxy\nDOMAIN-SUFFIX,gunsamerica.com,Proxy\nDOMAIN-SUFFIX,www.japonx.tv,Proxy\nDOMAIN-SUFFIX,www.contrepoints.org,Proxy\nDOMAIN-SUFFIX,cablegatesearch.net,Proxy\nDOMAIN-SUFFIX,hidemyipaddress.org,Proxy\nDOMAIN-SUFFIX,s.sh22.us,Proxy\nDOMAIN-SUFFIX,api.themoviedb.org,Proxy\nDOMAIN-SUFFIX,warrenandjan.com,Proxy\nDOMAIN-SUFFIX,google.com.bh,Proxy\nDOMAIN-SUFFIX,bitstamp.net,Proxy\nDOMAIN-SUFFIX,27qk.cn,Proxy\nDOMAIN-SUFFIX,la-croix.com,Proxy\nDOMAIN-SUFFIX,xanga.com,Proxy\nDOMAIN-SUFFIX,edoors.com,Proxy\nDOMAIN-SUFFIX,9546774.com,Proxy\nDOMAIN-SUFFIX,eskimotube.com,Proxy\nDOMAIN-SUFFIX,creepshots.org,Proxy\nDOMAIN-SUFFIX,e-constient.ro,Proxy\nDOMAIN-SUFFIX,vpnsg.com,Proxy\nDOMAIN-SUFFIX,piquette-et-co.fr,Proxy\nDOMAIN-SUFFIX,pegle.com,Proxy\nDOMAIN-SUFFIX,unblockit.uno,Proxy\nDOMAIN-SUFFIX,wc6q.com,Proxy\nDOMAIN-SUFFIX,racingvpn.com,Proxy\nDOMAIN-SUFFIX,google.net,Proxy\nDOMAIN-SUFFIX,www.tinder.com,Proxy\nDOMAIN-SUFFIX,www.pi88.com,Proxy\nDOMAIN-SUFFIX,motivarq.cl,Proxy\nDOMAIN-SUFFIX,trustedreviews.com,Proxy\nDOMAIN-SUFFIX,www.jav321.com,Proxy\nDOMAIN-SUFFIX,www.tv.com.pk,Proxy\nDOMAIN-SUFFIX,www.urban-vpn.com,Proxy\nDOMAIN-SUFFIX,m.1687200.com,Proxy\nDOMAIN-SUFFIX,asis-sugianto.blogspot.hk,Proxy\nDOMAIN-SUFFIX,pisswasser.ch,Proxy\nDOMAIN-SUFFIX,www.bet8835.com,Proxy\nDOMAIN-SUFFIX,www.204bb.com,Proxy\nDOMAIN-SUFFIX,silobreaker.com,Proxy\nDOMAIN-SUFFIX,bypass.pw,Proxy\nDOMAIN-SUFFIX,fiete.eu,Proxy\nDOMAIN-SUFFIX,xvideos-cdn.com,Proxy\nDOMAIN-SUFFIX,kaopu.news,Proxy\nDOMAIN-SUFFIX,apktada.com,Proxy\nDOMAIN-SUFFIX,6162.cc,Proxy\nDOMAIN-SUFFIX,hear-movie.blogspot.hk,Proxy\nDOMAIN-SUFFIX,9797263.com,Proxy\nDOMAIN-SUFFIX,www.radiotelevisionmarti.com,Proxy\nDOMAIN-SUFFIX,www.milfordmercury.co.uk,Proxy\nDOMAIN-SUFFIX,gotdns.ch,Proxy\nDOMAIN-SUFFIX,fromosis.blogspot.hk,Proxy\nDOMAIN-SUFFIX,shadeyouvpn.com,Proxy\nDOMAIN-SUFFIX,youmaker.com,Proxy\nDOMAIN-SUFFIX,thuhole.com,Proxy\nDOMAIN-SUFFIX,4275.yzc622.com,Proxy\nDOMAIN-SUFFIX,www.serajeyrigzodchenmo.org,Proxy\nDOMAIN-SUFFIX,63pp.net,Proxy\nDOMAIN-SUFFIX,nintendium.com,Proxy\nDOMAIN-SUFFIX,33kj.com,Proxy\nDOMAIN-SUFFIX,spiegelonline.de,Proxy\nDOMAIN-SUFFIX,saffie.ca,Proxy\nDOMAIN-SUFFIX,tunnel.shellmix.com.nyud.net,Proxy\nDOMAIN-SUFFIX,tortoisesvn.net,Proxy\nDOMAIN-SUFFIX,lixing3.com,Proxy\nDOMAIN-SUFFIX,brooklynyarncafe.com,Proxy\nDOMAIN-SUFFIX,putty.org,Proxy\nDOMAIN-SUFFIX,chinese.irib.ir,Proxy\nDOMAIN-SUFFIX,runbtx.com,Proxy\nDOMAIN-SUFFIX,www.ababa.us,Proxy\nDOMAIN-SUFFIX,zh-hk.hongkong.wikia.com,Proxy\nDOMAIN-SUFFIX,capsagm.com.ar,Proxy\nDOMAIN-SUFFIX,fanhaodang.com,Proxy\nDOMAIN-SUFFIX,slate.com,Proxy\nDOMAIN-SUFFIX,lazymind.me,Proxy\nDOMAIN-SUFFIX,kenmitton.com,Proxy\nDOMAIN-SUFFIX,invidious.io,Proxy\nDOMAIN-SUFFIX,www.e8737.com,Proxy\nDOMAIN-SUFFIX,www.terasurf.com,Proxy\nDOMAIN-SUFFIX,secure.raxcdn.com,Proxy\nDOMAIN-SUFFIX,lerosua.org,Proxy\nDOMAIN-SUFFIX,f513.tk,Proxy\nDOMAIN-SUFFIX,tbssqh.org,Proxy\nDOMAIN-SUFFIX,tenor.com,Proxy\nDOMAIN-SUFFIX,letscorp.net,Proxy\nDOMAIN-SUFFIX,www.ywcachicago.org,Proxy\nDOMAIN-SUFFIX,gogo2sex.com,Proxy\nDOMAIN-SUFFIX,cclw.net,Proxy\nDOMAIN-SUFFIX,pinterest.ca,Proxy\nDOMAIN-SUFFIX,h5.ld68.tv,Proxy\nDOMAIN-SUFFIX,www.juxtaflux.com,Proxy\nDOMAIN-SUFFIX,aerotaxi.cl,Proxy\nDOMAIN-SUFFIX,tw789.net,Proxy\nDOMAIN-SUFFIX,tucao.cc,Proxy\nDOMAIN-SUFFIX,websitegeeks.net,Proxy\nDOMAIN-SUFFIX,uocn.groupsite.com,Proxy\nDOMAIN-SUFFIX,godsdirectcontact.org.tw,Proxy\nDOMAIN-SUFFIX,www.news24.com,Proxy\nDOMAIN-SUFFIX,watch8x.com,Proxy\nDOMAIN-SUFFIX,hkanews.wordpress.com,Proxy\nDOMAIN-SUFFIX,www.bjcluestarvpn.tk,Proxy\nDOMAIN-SUFFIX,www.musicade.net,Proxy\nDOMAIN-SUFFIX,matters.town,Proxy\nDOMAIN-SUFFIX,zzcartoon.com,Proxy\nDOMAIN-SUFFIX,www.911asians.com,Proxy\nDOMAIN-SUFFIX,spwvpn.com,Proxy\nDOMAIN-SUFFIX,55.effers.com,Proxy\nDOMAIN-SUFFIX,www.beebyte.io,Proxy\nDOMAIN-SUFFIX,gammalikker.net,Proxy\nDOMAIN-SUFFIX,p2.55.lt,Proxy\nDOMAIN-SUFFIX,www.rapidvpn.com,Proxy\nDOMAIN-SUFFIX,bestpornstardb.com,Proxy\nDOMAIN-SUFFIX,11008.ero02mh.site,Proxy\nDOMAIN-SUFFIX,gun999.tv,Proxy\nDOMAIN-SUFFIX,google.as,Proxy\nDOMAIN-SUFFIX,jiuping.net,Proxy\nDOMAIN-SUFFIX,lantern5.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,8964museum.com,Proxy\nDOMAIN-SUFFIX,jornaldacidadeonline.com.br,Proxy\nDOMAIN-SUFFIX,systemgenie.com,Proxy\nDOMAIN-SUFFIX,bird.trom.tf,Proxy\nDOMAIN-SUFFIX,tdxmv.site,Proxy\nDOMAIN-SUFFIX,www.sxweq.com,Proxy\nDOMAIN-SUFFIX,hq-youporn.net,Proxy\nDOMAIN-SUFFIX,money-link.com.tw,Proxy\nDOMAIN-SUFFIX,xc6633.com,Proxy\nDOMAIN-SUFFIX,www.northwaleschronicle.co.uk,Proxy\nDOMAIN-SUFFIX,lhfbet.com,Proxy\nDOMAIN-SUFFIX,xunluvpn.org,Proxy\nDOMAIN-SUFFIX,wasel.pro,Proxy\nDOMAIN-SUFFIX,mofaxiehui.com,Proxy\nDOMAIN-SUFFIX,hk-pub.com,Proxy\nDOMAIN-SUFFIX,free.com.tw,Proxy\nDOMAIN-SUFFIX,wer.4irc.com,Proxy\nDOMAIN-SUFFIX,www.2ways.net,Proxy\nDOMAIN-SUFFIX,www-98198.tw,Proxy\nDOMAIN-SUFFIX,www.diariovasco.com,Proxy\nDOMAIN-SUFFIX,www.zhuatube.com,Proxy\nDOMAIN-SUFFIX,www.stranabg.com,Proxy\nDOMAIN-SUFFIX,www.yhdmwz.com,Proxy\nDOMAIN-SUFFIX,www.motor0.net,Proxy\nDOMAIN-SUFFIX,tuta.io,Proxy\nDOMAIN-SUFFIX,d2ic5hlxxg46ag.cloudfront.net,Proxy\nDOMAIN-SUFFIX,cp.u9un.com,Proxy\nDOMAIN-SUFFIX,2021hkcharter.com,Proxy\nDOMAIN-SUFFIX,justdied.com,Proxy\nDOMAIN-SUFFIX,85cc.net,Proxy\nDOMAIN-SUFFIX,nickjapan.com,Proxy\nDOMAIN-SUFFIX,somcloud.com,Proxy\nDOMAIN-SUFFIX,trezor.io,Proxy\nDOMAIN-SUFFIX,viyoutube.com,Proxy\nDOMAIN-SUFFIX,blog.delouw.ch,Proxy\nDOMAIN-SUFFIX,hkswgu.org.hk,Proxy\nDOMAIN-SUFFIX,d1e7a03292k4s0.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.geocities.co.jp,Proxy\nDOMAIN-SUFFIX,doubmirror.cf,Proxy\nDOMAIN-SUFFIX,www.tme.org,Proxy\nDOMAIN-SUFFIX,www.begadistrictnews.com.au,Proxy\nDOMAIN-SUFFIX,d5202.com,Proxy\nDOMAIN-SUFFIX,www.thinkmarkets.com.cn,Proxy\nDOMAIN-SUFFIX,key.ketubruk.biz,Proxy\nDOMAIN-SUFFIX,ns.tv333.us,Proxy\nDOMAIN-SUFFIX,www.likuoo.com,Proxy\nDOMAIN-SUFFIX,onmypc.us,Proxy\nDOMAIN-SUFFIX,ifcss.org,Proxy\nDOMAIN-SUFFIX,sltrib.com,Proxy\nDOMAIN-SUFFIX,nicovideo.jp,Proxy\nDOMAIN-SUFFIX,niusnews.com,Proxy\nDOMAIN-SUFFIX,vipergirls.to,Proxy\nDOMAIN-SUFFIX,m.w889889.com,Proxy\nDOMAIN-SUFFIX,shipcamouflage.com,Proxy\nDOMAIN-SUFFIX,pytecdesign.com,Proxy\nDOMAIN-SUFFIX,weavers.ws,Proxy\nDOMAIN-SUFFIX,ns3.name,Proxy\nDOMAIN-SUFFIX,oanda.cn,Proxy\nDOMAIN-SUFFIX,acai.active-ns.com,Proxy\nDOMAIN-SUFFIX,dumb1.com,Proxy\nDOMAIN-SUFFIX,henryjacksonsociety.org,Proxy\nDOMAIN-SUFFIX,d.line-scdn.net,Proxy\nDOMAIN-SUFFIX,angola.org,Proxy\nDOMAIN-SUFFIX,hotfrog.com.tw,Proxy\nDOMAIN-SUFFIX,qhvpn.com,Proxy\nDOMAIN-SUFFIX,h2.etowns.net,Proxy\nDOMAIN-SUFFIX,hotair.com,Proxy\nDOMAIN-SUFFIX,localnews8.com,Proxy\nDOMAIN-SUFFIX,www.colex.com.tw,Proxy\nDOMAIN-SUFFIX,xj530.com,Proxy\nDOMAIN-SUFFIX,graphic-line.at,Proxy\nDOMAIN-SUFFIX,rutnerspazzacamino.ch,Proxy\nDOMAIN-SUFFIX,ghcdn.rawgit.org,Proxy\nDOMAIN-SUFFIX,www.milk.com.hk,Proxy\nDOMAIN-SUFFIX,www.indiagetonline.in,Proxy\nDOMAIN-SUFFIX,www.heygen.com,Proxy\nDOMAIN-SUFFIX,www.charlesmok.hk,Proxy\nDOMAIN-SUFFIX,javamateur.com,Proxy\nDOMAIN-SUFFIX,eromangadouzin.com,Proxy\nDOMAIN-SUFFIX,www.3666564.com,Proxy\nDOMAIN-SUFFIX,jplulu.com,Proxy\nDOMAIN-SUFFIX,jm-comic.org,Proxy\nDOMAIN-SUFFIX,juliereyc.com,Proxy\nDOMAIN-SUFFIX,raelianews.org,Proxy\nDOMAIN-SUFFIX,pjbar02.bar,Proxy\nDOMAIN-SUFFIX,b3133.com,Proxy\nDOMAIN-SUFFIX,mediainitiative.eu,Proxy\nDOMAIN-SUFFIX,anespo.pt,Proxy\nDOMAIN-SUFFIX,mail.wbs.ac.uk,Proxy\nDOMAIN-SUFFIX,gmvpn.com,Proxy\nDOMAIN-SUFFIX,579.flnet.org,Proxy\nDOMAIN-SUFFIX,jmcomic.bet,Proxy\nDOMAIN-SUFFIX,mesotw.com,Proxy\nDOMAIN-SUFFIX,momon-ga.com,Proxy\nDOMAIN-SUFFIX,muchoporno.xxx,Proxy\nDOMAIN-SUFFIX,tareasplus.com,Proxy\nDOMAIN-SUFFIX,dailyrapid.com,Proxy\nDOMAIN-SUFFIX,nine99.me,Proxy\nDOMAIN-SUFFIX,ayg.cl,Proxy\nDOMAIN-SUFFIX,anilos.com,Proxy\nDOMAIN-SUFFIX,westworldss.com,Proxy\nDOMAIN-SUFFIX,yeyeclub.com,Proxy\nDOMAIN-SUFFIX,aelitis.com,Proxy\nDOMAIN-SUFFIX,radiotaiwan.tw,Proxy\nDOMAIN-SUFFIX,www.maostudy.org,Proxy\nDOMAIN-SUFFIX,eurasiagroup.net,Proxy\nDOMAIN-SUFFIX,ca775.com,Proxy\nDOMAIN-SUFFIX,comdotgame.com,Proxy\nDOMAIN-SUFFIX,fosstodon.org,Proxy\nDOMAIN-SUFFIX,ww-cc.xyz,Proxy\nDOMAIN-SUFFIX,yingmang.com,Proxy\nDOMAIN-SUFFIX,fanqiang.tk,Proxy\nDOMAIN-SUFFIX,dnssite.xyz,Proxy\nDOMAIN-SUFFIX,google.nl,Proxy\nDOMAIN-SUFFIX,www.igreenjsq.org,Proxy\nDOMAIN-SUFFIX,syriavpn.com,Proxy\nDOMAIN-SUFFIX,dukou.dev,Proxy\nDOMAIN-SUFFIX,hcomic.in,Proxy\nDOMAIN-SUFFIX,truthontour.org,Proxy\nDOMAIN-SUFFIX,juhuaren.com,Proxy\nDOMAIN-SUFFIX,mianvpn.com,Proxy\nDOMAIN-SUFFIX,portal.wallless.xyz,Proxy\nDOMAIN-SUFFIX,vpncompany.com,Proxy\nDOMAIN-SUFFIX,fanqiang-vpn.github.io,Proxy\nDOMAIN-SUFFIX,proxtube.com,Proxy\nDOMAIN-SUFFIX,www.strinkingly.com,Proxy\nDOMAIN-SUFFIX,www.wall-baby.com,Proxy\nDOMAIN-SUFFIX,cdn.javmodel.com,Proxy\nDOMAIN-SUFFIX,matrix.org,Proxy\nDOMAIN-SUFFIX,119.hk.am,Proxy\nDOMAIN-SUFFIX,www.opencourseware.com,Proxy\nDOMAIN-SUFFIX,zb9899.com,Proxy\nDOMAIN-SUFFIX,goattomypc.com,Proxy\nDOMAIN-SUFFIX,iconosquare.com,Proxy\nDOMAIN-SUFFIX,indianrail.gov.in,Proxy\nDOMAIN-SUFFIX,taiwankiss.com,Proxy\nDOMAIN-SUFFIX,www.freeyellow.com,Proxy\nDOMAIN-SUFFIX,www.51jsq.net,Proxy\nDOMAIN-SUFFIX,hotshame.com,Proxy\nDOMAIN-SUFFIX,friends-of-tibet.org,Proxy\nDOMAIN-SUFFIX,bitporno.com,Proxy\nDOMAIN-SUFFIX,jg520.com,Proxy\nDOMAIN-SUFFIX,www.integratedsales.org,Proxy\nDOMAIN-SUFFIX,speedify.com,Proxy\nDOMAIN-SUFFIX,twimbow.com,Proxy\nDOMAIN-SUFFIX,getlantern.cn,Proxy\nDOMAIN-SUFFIX,steganos.com,Proxy\nDOMAIN-SUFFIX,laqingdan.net,Proxy\nDOMAIN-SUFFIX,1950044.com,Proxy\nDOMAIN-SUFFIX,ibvpn.com,Proxy\nDOMAIN-SUFFIX,fap69.com,Proxy\nDOMAIN-SUFFIX,kan-be.com,Proxy\nDOMAIN-SUFFIX,chrismarquis.com,Proxy\nDOMAIN-SUFFIX,manyvoices.news,Proxy\nDOMAIN-SUFFIX,paste.plurk.com,Proxy\nDOMAIN-SUFFIX,www.fun88-kk.com,Proxy\nDOMAIN-SUFFIX,www.19599222.com,Proxy\nDOMAIN-SUFFIX,aneisa.com,Proxy\nDOMAIN-SUFFIX,0099.tv,Proxy\nDOMAIN-SUFFIX,publons.com,Proxy\nDOMAIN-SUFFIX,27.wtf.im,Proxy\nDOMAIN-SUFFIX,www.f686u.com,Proxy\nDOMAIN-SUFFIX,convertisseur-youtube.com,Proxy\nDOMAIN-SUFFIX,raidcall.com.tw,Proxy\nDOMAIN-SUFFIX,php5.idv.tw,Proxy\nDOMAIN-SUFFIX,www.crifan.com,Proxy\nDOMAIN-SUFFIX,canvasopedia.org,Proxy\nDOMAIN-SUFFIX,aff.shalong365.com,Proxy\nDOMAIN-SUFFIX,uitzendinggemist.nl,Proxy\nDOMAIN-SUFFIX,wisegeek.com,Proxy\nDOMAIN-SUFFIX,tibetfocus.com,Proxy\nDOMAIN-SUFFIX,dl1gkkomie22y.cloudfront.net,Proxy\nDOMAIN-SUFFIX,share.ovi.com,Proxy\nDOMAIN-SUFFIX,www.pikkur.com,Proxy\nDOMAIN-SUFFIX,197888.com,Proxy\nDOMAIN-SUFFIX,documentcloud.org,Proxy\nDOMAIN-SUFFIX,hnntube.com,Proxy\nDOMAIN-SUFFIX,tmi.me,Proxy\nDOMAIN-SUFFIX,www.cessnockadvertiser.com.au,Proxy\nDOMAIN-SUFFIX,6parker.com,Proxy\nDOMAIN-SUFFIX,d28ov23nx0c7ze.cloudfront.net,Proxy\nDOMAIN-SUFFIX,goldenfrog.com,Proxy\nDOMAIN-SUFFIX,www.hogtied.com,Proxy\nDOMAIN-SUFFIX,www.myfriendsfeet.com,Proxy\nDOMAIN-SUFFIX,cdn1.avksyntec.com,Proxy\nDOMAIN-SUFFIX,www.anttisointu.com,Proxy\nDOMAIN-SUFFIX,ekolay.net,Proxy\nDOMAIN-SUFFIX,888t.vip,Proxy\nDOMAIN-SUFFIX,xhgt.com,Proxy\nDOMAIN-SUFFIX,rsgamen.org,Proxy\nDOMAIN-SUFFIX,xxbbx.com,Proxy\nDOMAIN-SUFFIX,bbs.tianshi2.com,Proxy\nDOMAIN-SUFFIX,www.lucasentertainment.com,Proxy\nDOMAIN-SUFFIX,writelonger.com,Proxy\nDOMAIN-SUFFIX,line-scdn.net,Proxy\nDOMAIN-SUFFIX,centurys.net,Proxy\nDOMAIN-SUFFIX,lmacedo.eti.br,Proxy\nDOMAIN-SUFFIX,60005.me,Proxy\nDOMAIN-SUFFIX,www.voaafaanoromoo.com,Proxy\nDOMAIN-SUFFIX,am8599.com,Proxy\nDOMAIN-SUFFIX,1314.4irc.com,Proxy\nDOMAIN-SUFFIX,www.slutroulette.com,Proxy\nDOMAIN-SUFFIX,jewishjournal.com,Proxy\nDOMAIN-SUFFIX,rd.com,Proxy\nDOMAIN-SUFFIX,almrosi.com,Proxy\nDOMAIN-SUFFIX,www.603yf.com,Proxy\nDOMAIN-SUFFIX,www.projectstardust.org,Proxy\nDOMAIN-SUFFIX,airfrance.com.tw,Proxy\nDOMAIN-SUFFIX,xvideo.cc,Proxy\nDOMAIN-SUFFIX,chinasmile.net,Proxy\nDOMAIN-SUFFIX,125.effers.com,Proxy\nDOMAIN-SUFFIX,sm-miracle.com,Proxy\nDOMAIN-SUFFIX,ac.jiruan.net,Proxy\nDOMAIN-SUFFIX,savetibet.at,Proxy\nDOMAIN-SUFFIX,otakuss.com,Proxy\nDOMAIN-SUFFIX,www.cepa.org,Proxy\nDOMAIN-SUFFIX,www.tucsonrealty.com,Proxy\nDOMAIN-SUFFIX,bbs.qmzdd.com,Proxy\nDOMAIN-SUFFIX,mechatronics.maori.nz,Proxy\nDOMAIN-SUFFIX,newcenturymc.com,Proxy\nDOMAIN-SUFFIX,esg.t91y.com,Proxy\nDOMAIN-SUFFIX,biec.us,Proxy\nDOMAIN-SUFFIX,nitter.dcs0.hu,Proxy\nDOMAIN-SUFFIX,ns1.cg.net,Proxy\nDOMAIN-SUFFIX,settour-tldr-app.firebaseio.com,Proxy\nDOMAIN-SUFFIX,lhfplay.com,Proxy\nDOMAIN-SUFFIX,pizzaisgod.com,Proxy\nDOMAIN-SUFFIX,heritage.org,Proxy\nDOMAIN-SUFFIX,nitter.pw,Proxy\nDOMAIN-SUFFIX,www.cheapchinavpn.com,Proxy\nDOMAIN-SUFFIX,dingchin.com.tw,Proxy\nDOMAIN-SUFFIX,la4065.com,Proxy\nDOMAIN-SUFFIX,d5303.com,Proxy\nDOMAIN-SUFFIX,webmproject.org,Proxy\nDOMAIN-SUFFIX,zhenlibu.info,Proxy\nDOMAIN-SUFFIX,367.ddnsking.com,Proxy\nDOMAIN-SUFFIX,www.iwin993.com,Proxy\nDOMAIN-SUFFIX,523.ddnsking.com,Proxy\nDOMAIN-SUFFIX,tw.jiepang.com,Proxy\nDOMAIN-SUFFIX,www.womenresources.org,Proxy\nDOMAIN-SUFFIX,instgram.com,Proxy\nDOMAIN-SUFFIX,bangumi.moe,Proxy\nDOMAIN-SUFFIX,yobl.cc,Proxy\nDOMAIN-SUFFIX,allmusic.com,Proxy\nDOMAIN-SUFFIX,hottopic.com.com,Proxy\nDOMAIN-SUFFIX,jilili.top,Proxy\nDOMAIN-SUFFIX,d2eikhd9e83v81.cloudfront.net,Proxy\nDOMAIN-SUFFIX,spectator.org,Proxy\nDOMAIN-SUFFIX,facebok.com,Proxy\nDOMAIN-SUFFIX,cm365.xyz,Proxy\nDOMAIN-SUFFIX,www.tawhed.ws,Proxy\nDOMAIN-SUFFIX,www.fastvpns.com,Proxy\nDOMAIN-SUFFIX,www.605d.com,Proxy\nDOMAIN-SUFFIX,1998cdp.org,Proxy\nDOMAIN-SUFFIX,cm.spacetechnology.net,Proxy\nDOMAIN-SUFFIX,new-3lunch.net,Proxy\nDOMAIN-SUFFIX,qixianglu.cn,Proxy\nDOMAIN-SUFFIX,ez.access.ly,Proxy\nDOMAIN-SUFFIX,tibetanculture.org,Proxy\nDOMAIN-SUFFIX,demo.ai4t.com,Proxy\nDOMAIN-SUFFIX,s541722682.onlinehome.us,Proxy\nDOMAIN-SUFFIX,d3zww.com,Proxy\nDOMAIN-SUFFIX,haodoo.net,Proxy\nDOMAIN-SUFFIX,waze.com,Proxy\nDOMAIN-SUFFIX,roboforexchina.com,Proxy\nDOMAIN-SUFFIX,tilt-industrialdesign.com,Proxy\nDOMAIN-SUFFIX,gojet.krtco.com.tw,Proxy\nDOMAIN-SUFFIX,r3.cr.rs,Proxy\nDOMAIN-SUFFIX,epochtimes.de,Proxy\nDOMAIN-SUFFIX,tor.updatestar.com,Proxy\nDOMAIN-SUFFIX,smartdnsproxy.com,Proxy\nDOMAIN-SUFFIX,cullasanmarcoamici.ch,Proxy\nDOMAIN-SUFFIX,999.6100888.com,Proxy\nDOMAIN-SUFFIX,naturevalley.com,Proxy\nDOMAIN-SUFFIX,italiatibet.org,Proxy\nDOMAIN-SUFFIX,557.uk.to,Proxy\nDOMAIN-SUFFIX,v5.connect-link.com,Proxy\nDOMAIN-SUFFIX,www.dfnba.com,Proxy\nDOMAIN-SUFFIX,peternorth.com,Proxy\nDOMAIN-SUFFIX,www.shireyishunjian.club,Proxy\nDOMAIN-SUFFIX,dqjfk9xcvbmj9.cloudfront.net,Proxy\nDOMAIN-SUFFIX,motherless.com,Proxy\nDOMAIN-SUFFIX,reddit.it,Proxy\nDOMAIN-SUFFIX,hellotalk.com,Proxy\nDOMAIN-SUFFIX,pinterest.de,Proxy\nDOMAIN-SUFFIX,proxywebsite.org,Proxy\nDOMAIN-SUFFIX,chinagonet.com,Proxy\nDOMAIN-SUFFIX,roydonng.net,Proxy\nDOMAIN-SUFFIX,topgunge.com,Proxy\nDOMAIN-SUFFIX,pki.goog,Proxy\nDOMAIN-SUFFIX,www.araratadvertiser.com.au,Proxy\nDOMAIN-SUFFIX,818pb.com,Proxy\nDOMAIN-SUFFIX,cntube.net,Proxy\nDOMAIN-SUFFIX,hkg12s09-in-f17.1e100.net,Proxy\nDOMAIN-SUFFIX,www.jianhuadaily.com,Proxy\nDOMAIN-SUFFIX,www.sanguosha.com,Proxy\nDOMAIN-SUFFIX,dance-africa.com,Proxy\nDOMAIN-SUFFIX,carabinasypistolas.com,Proxy\nDOMAIN-SUFFIX,ping.fm,Proxy\nDOMAIN-SUFFIX,luo.bo,Proxy\nDOMAIN-SUFFIX,webevade.com,Proxy\nDOMAIN-SUFFIX,pornhub.com,Proxy\nDOMAIN-SUFFIX,www.evilangel.com,Proxy\nDOMAIN-SUFFIX,pu0039.com,Proxy\nDOMAIN-SUFFIX,whereiswerner.com,Proxy\nDOMAIN-SUFFIX,ibiblio.org,Proxy\nDOMAIN-SUFFIX,farxian.com,Proxy\nDOMAIN-SUFFIX,www.aidsfreeworld.org,Proxy\nDOMAIN-SUFFIX,www.appsheet.com,Proxy\nDOMAIN-SUFFIX,www.hentaiheroes.com,Proxy\nDOMAIN-SUFFIX,www.fun88223.com,Proxy\nDOMAIN-SUFFIX,nztexgroup.com,Proxy\nDOMAIN-SUFFIX,www.savingcranes.org,Proxy\nDOMAIN-SUFFIX,www.venetianmacau.com,Proxy\nDOMAIN-SUFFIX,xinsheng.net,Proxy\nDOMAIN-SUFFIX,esmtp.biz,Proxy\nDOMAIN-SUFFIX,news.mingpao.com,Proxy\nDOMAIN-SUFFIX,robfuscate.com,Proxy\nDOMAIN-SUFFIX,www.nzz.ch,Proxy\nDOMAIN-SUFFIX,nanzao.com,Proxy\nDOMAIN-SUFFIX,lagrandeepoque.com,Proxy\nDOMAIN-SUFFIX,www.borderchronicle.com.au,Proxy\nDOMAIN-SUFFIX,agoda.com,Proxy\nDOMAIN-SUFFIX,www.taaze.tw,Proxy\nDOMAIN-SUFFIX,vidz.com,Proxy\nDOMAIN-SUFFIX,sape.ru,Proxy\nDOMAIN-SUFFIX,kuma-academy.oen.tw,Proxy\nDOMAIN-SUFFIX,vimieo.com,Proxy\nDOMAIN-SUFFIX,a0415704157.byethost7.com,Proxy\nDOMAIN-SUFFIX,w9869.com,Proxy\nDOMAIN-SUFFIX,fun88asia.com,Proxy\nDOMAIN-SUFFIX,twittbot.net,Proxy\nDOMAIN-SUFFIX,instructure-uploads-apse2.s3.ap-southeast-2.amazonaws.com,Proxy\nDOMAIN-SUFFIX,proxypy.net,Proxy\nDOMAIN-SUFFIX,blogunions.com,Proxy\nDOMAIN-SUFFIX,chat97.com,Proxy\nDOMAIN-SUFFIX,a4.nu,Proxy\nDOMAIN-SUFFIX,proxpn.com,Proxy\nDOMAIN-SUFFIX,www.santasporngirls.com,Proxy\nDOMAIN-SUFFIX,avno1.playno1.com,Proxy\nDOMAIN-SUFFIX,slacker.com,Proxy\nDOMAIN-SUFFIX,let77.net,Proxy\nDOMAIN-SUFFIX,bind2.com,Proxy\nDOMAIN-SUFFIX,murmurcn.com,Proxy\nDOMAIN-SUFFIX,btsow.surf,Proxy\nDOMAIN-SUFFIX,www.canvio.jp,Proxy\nDOMAIN-SUFFIX,ulop.net,Proxy\nDOMAIN-SUFFIX,bad.mn,Proxy\nDOMAIN-SUFFIX,onthehunt.com,Proxy\nDOMAIN-SUFFIX,www.google.com.cn,Proxy\nDOMAIN-SUFFIX,tibetmuseum.org,Proxy\nDOMAIN-SUFFIX,unification.org.tw,Proxy\nDOMAIN-SUFFIX,lexmarket.com.tr,Proxy\nDOMAIN-SUFFIX,paysimple.com.com,Proxy\nDOMAIN-SUFFIX,www.andreas-fuchs.net,Proxy\nDOMAIN-SUFFIX,www.myxvids.com,Proxy\nDOMAIN-SUFFIX,chinafree.org,Proxy\nDOMAIN-SUFFIX,tiananmenduizhi.com,Proxy\nDOMAIN-SUFFIX,www.av.com,Proxy\nDOMAIN-SUFFIX,paste.0xfc.de,Proxy\nDOMAIN-SUFFIX,www.tara.org,Proxy\nDOMAIN-SUFFIX,titantv.com,Proxy\nDOMAIN-SUFFIX,rangzen.com,Proxy\nDOMAIN-SUFFIX,kuaixian.me,Proxy\nDOMAIN-SUFFIX,instibaires.com.ar,Proxy\nDOMAIN-SUFFIX,345wnsr.com,Proxy\nDOMAIN-SUFFIX,www.avday18.com,Proxy\nDOMAIN-SUFFIX,www.biofos.com,Proxy\nDOMAIN-SUFFIX,www.bumingbai.net,Proxy\nDOMAIN-SUFFIX,jen.jiji.com,Proxy\nDOMAIN-SUFFIX,www.pz-news.de,Proxy\nDOMAIN-SUFFIX,labnol.blogspot.hk,Proxy\nDOMAIN-SUFFIX,amandala.com.bz,Proxy\nDOMAIN-SUFFIX,apotekkeluarga.id,Proxy\nDOMAIN-SUFFIX,av-movie1.xyz,Proxy\nDOMAIN-SUFFIX,ilovexjp.pages.dev,Proxy\nDOMAIN-SUFFIX,cpk04.com,Proxy\nDOMAIN-SUFFIX,8world.com,Proxy\nDOMAIN-SUFFIX,www.88879.com,Proxy\nDOMAIN-SUFFIX,gts-vpn.com,Proxy\nDOMAIN-SUFFIX,www.google.co.hu,Proxy\nDOMAIN-SUFFIX,ctao.org,Proxy\nDOMAIN-SUFFIX,ssnode.co,Proxy\nDOMAIN-SUFFIX,www.vickyxu.com,Proxy\nDOMAIN-SUFFIX,22.ddos.im,Proxy\nDOMAIN-SUFFIX,dailypoliticalreview.com,Proxy\nDOMAIN-SUFFIX,inbanban.com,Proxy\nDOMAIN-SUFFIX,undofilters.com,Proxy\nDOMAIN-SUFFIX,avfantasy.com,Proxy\nDOMAIN-SUFFIX,qq31666.com,Proxy\nDOMAIN-SUFFIX,form.jotform.us,Proxy\nDOMAIN-SUFFIX,realmomexposed.com,Proxy\nDOMAIN-SUFFIX,theblaze.com,Proxy\nDOMAIN-SUFFIX,facebook.org,Proxy\nDOMAIN-SUFFIX,vaughngass.com,Proxy\nDOMAIN-SUFFIX,yzc263.com,Proxy\nDOMAIN-SUFFIX,www.hk-ebc.edu,Proxy\nDOMAIN-SUFFIX,d2cymee3oy9kh3.cloudfront.net,Proxy\nDOMAIN-SUFFIX,creadersnet.com,Proxy\nDOMAIN-SUFFIX,manmin.org,Proxy\nDOMAIN-SUFFIX,maa01.ongitv.site,Proxy\nDOMAIN-SUFFIX,www.yicfff.tw,Proxy\nDOMAIN-SUFFIX,bullguard.com,Proxy\nDOMAIN-SUFFIX,f2pool.com,Proxy\nDOMAIN-SUFFIX,junefourth-20.net,Proxy\nDOMAIN-SUFFIX,wikivoyage.org,Proxy\nDOMAIN-SUFFIX,starworldmacau.com,Proxy\nDOMAIN-SUFFIX,creampiethais.com,Proxy\nDOMAIN-SUFFIX,fbworkmail.com,Proxy\nDOMAIN-SUFFIX,aulavirtual.mx,Proxy\nDOMAIN-SUFFIX,www.tutou.tw,Proxy\nDOMAIN-SUFFIX,freevpnworld.com,Proxy\nDOMAIN-SUFFIX,www.cbplus.com,Proxy\nDOMAIN-SUFFIX,inbox.alumni.utoronto.ca,Proxy\nDOMAIN-SUFFIX,002008.com,Proxy\nDOMAIN-SUFFIX,kajihara.net.br,Proxy\nDOMAIN-SUFFIX,muchohentai.com,Proxy\nDOMAIN-SUFFIX,wbtcopy.cf,Proxy\nDOMAIN-SUFFIX,www.china-duebro.com,Proxy\nDOMAIN-SUFFIX,www.esperanto-gb.org,Proxy\nDOMAIN-SUFFIX,www.nagchinese.com,Proxy\nDOMAIN-SUFFIX,chrome.com,Proxy\nDOMAIN-SUFFIX,scharp.org,Proxy\nDOMAIN-SUFFIX,uwants.net,Proxy\nDOMAIN-SUFFIX,mail.gavekal.com,Proxy\nDOMAIN-SUFFIX,38850033.com,Proxy\nDOMAIN-SUFFIX,smyxy.org,Proxy\nDOMAIN-SUFFIX,tumblr.agardenday.com,Proxy\nDOMAIN-SUFFIX,cdpuk.co.uk,Proxy\nDOMAIN-SUFFIX,bookibg.com.br,Proxy\nDOMAIN-SUFFIX,ept.ms,Proxy\nDOMAIN-SUFFIX,passiontimes.hk,Proxy\nDOMAIN-SUFFIX,post852.com,Proxy\nDOMAIN-SUFFIX,flickrhivemind.net,Proxy\nDOMAIN-SUFFIX,wildafrica.tourister.ru,Proxy\nDOMAIN-SUFFIX,cn.yahoo.com,Proxy\nDOMAIN-SUFFIX,www.javbus5.com,Proxy\nDOMAIN-SUFFIX,bitmex.com,Proxy\nDOMAIN-SUFFIX,www.seselah.com,Proxy\nDOMAIN-SUFFIX,pttdata.com,Proxy\nDOMAIN-SUFFIX,bien.com,Proxy\nDOMAIN-SUFFIX,hongmeimei.com,Proxy\nDOMAIN-SUFFIX,logos.com,Proxy\nDOMAIN-SUFFIX,www.myinstants.com,Proxy\nDOMAIN-SUFFIX,ut888.com.tw,Proxy\nDOMAIN-SUFFIX,shaggyselectmast.com,Proxy\nDOMAIN-SUFFIX,tuzaijidi.com,Proxy\nDOMAIN-SUFFIX,vyprofficial.com,Proxy\nDOMAIN-SUFFIX,wemigrate.org,Proxy\nDOMAIN-SUFFIX,www.proxpn.biz,Proxy\nDOMAIN-SUFFIX,electric-titanium-poison.glitch.me,Proxy\nDOMAIN-SUFFIX,yuming.flnet.org,Proxy\nDOMAIN-SUFFIX,chinainterimgov.org,Proxy\nDOMAIN-SUFFIX,dailybasis.com,Proxy\nDOMAIN-SUFFIX,www.esbline.net,Proxy\nDOMAIN-SUFFIX,www.thinkchina.sg,Proxy\nDOMAIN-SUFFIX,bbs.ozchinese.com,Proxy\nDOMAIN-SUFFIX,freemonsterporn.com,Proxy\nDOMAIN-SUFFIX,www.bestvpnanalysis.com,Proxy\nDOMAIN-SUFFIX,www.bug.hr,Proxy\nDOMAIN-SUFFIX,u9un.com,Proxy\nDOMAIN-SUFFIX,bjork.com,Proxy\nDOMAIN-SUFFIX,blockcast.it,Proxy\nDOMAIN-SUFFIX,girlbanker.com,Proxy\nDOMAIN-SUFFIX,doh.seby.io,Proxy\nDOMAIN-SUFFIX,boxun5.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,www.fxpro.cn,Proxy\nDOMAIN-SUFFIX,twicountry.org,Proxy\nDOMAIN-SUFFIX,zxfast.com,Proxy\nDOMAIN-SUFFIX,you2be.wzfou.me,Proxy\nDOMAIN-SUFFIX,cp98.com,Proxy\nDOMAIN-SUFFIX,tutanota.de,Proxy\nDOMAIN-SUFFIX,bufalopedia.net,Proxy\nDOMAIN-SUFFIX,textfiles.com,Proxy\nDOMAIN-SUFFIX,bmf.peerx-press.org,Proxy\nDOMAIN-SUFFIX,xn--9kq078ca.com,Proxy\nDOMAIN-SUFFIX,installiq.com,Proxy\nDOMAIN-SUFFIX,www.westca.com,Proxy\nDOMAIN-SUFFIX,ilovelongtoes.com,Proxy\nDOMAIN-SUFFIX,19av.tv,Proxy\nDOMAIN-SUFFIX,www.nelnet.com,Proxy\nDOMAIN-SUFFIX,www.hjhs01.com,Proxy\nDOMAIN-SUFFIX,cloudwall.io,Proxy\nDOMAIN-SUFFIX,plurk.com,Proxy\nDOMAIN-SUFFIX,post76.com,Proxy\nDOMAIN-SUFFIX,tangren.us,Proxy\nDOMAIN-SUFFIX,wangchengxi.com,Proxy\nDOMAIN-SUFFIX,preciouslilium.blogspot.jp,Proxy\nDOMAIN-SUFFIX,mocovideo.jp,Proxy\nDOMAIN-SUFFIX,liwangyang.com,Proxy\nDOMAIN-SUFFIX,jared.se,Proxy\nDOMAIN-SUFFIX,send.zcyph.cc,Proxy\nDOMAIN-SUFFIX,v1.t168.ml,Proxy\nDOMAIN-SUFFIX,hdxxnxx.com,Proxy\nDOMAIN-SUFFIX,whytibet.org,Proxy\nDOMAIN-SUFFIX,www.auto7inc.com,Proxy\nDOMAIN-SUFFIX,www.tiscali.it,Proxy\nDOMAIN-SUFFIX,makkahnewspaper.com,Proxy\nDOMAIN-SUFFIX,www.xiu8.com,Proxy\nDOMAIN-SUFFIX,mm-cgnews.com,Proxy\nDOMAIN-SUFFIX,getflix.com.au,Proxy\nDOMAIN-SUFFIX,d9wr7o84hwzcy.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.globecartoon.com,Proxy\nDOMAIN-SUFFIX,hg308.com,Proxy\nDOMAIN-SUFFIX,www.indianporn365.net,Proxy\nDOMAIN-SUFFIX,www.huayuel.com,Proxy\nDOMAIN-SUFFIX,umei.fun,Proxy\nDOMAIN-SUFFIX,libredns.gr,Proxy\nDOMAIN-SUFFIX,www.china-proxy.org,Proxy\nDOMAIN-SUFFIX,m.jf8822.com,Proxy\nDOMAIN-SUFFIX,mog.com,Proxy\nDOMAIN-SUFFIX,qpby0055.com,Proxy\nDOMAIN-SUFFIX,www.google.bj,Proxy\nDOMAIN-SUFFIX,archive.ph,Proxy\nDOMAIN-SUFFIX,redmaplenews.com,Proxy\nDOMAIN-SUFFIX,ccn.la,Proxy\nDOMAIN-SUFFIX,dw.de,Proxy\nDOMAIN-SUFFIX,javdove9.xyz,Proxy\nDOMAIN-SUFFIX,32.freegamepc.org,Proxy\nDOMAIN-SUFFIX,ele.uri.edu,Proxy\nDOMAIN-SUFFIX,myddns.com,Proxy\nDOMAIN-SUFFIX,247workinghost.com,Proxy\nDOMAIN-SUFFIX,tv100.gq,Proxy\nDOMAIN-SUFFIX,wiki.gd,Proxy\nDOMAIN-SUFFIX,win.hicam.net,Proxy\nDOMAIN-SUFFIX,avatars.githubusercontent.com,Proxy\nDOMAIN-SUFFIX,renzhecloud.com,Proxy\nDOMAIN-SUFFIX,jenniereyes.ml,Proxy\nDOMAIN-SUFFIX,www.manningrivertimes.com.au,Proxy\nDOMAIN-SUFFIX,qusi8.net,Proxy\nDOMAIN-SUFFIX,bittrex.com,Proxy\nDOMAIN-SUFFIX,www.mendix.com,Proxy\nDOMAIN-SUFFIX,www.bok88.com,Proxy\nDOMAIN-SUFFIX,dsgstng.com,Proxy\nDOMAIN-SUFFIX,trunklocker.blogspot.hk,Proxy\nDOMAIN-SUFFIX,hkex.la,Proxy\nDOMAIN-SUFFIX,www.iltk.org,Proxy\nDOMAIN-SUFFIX,uploadstation.com,Proxy\nDOMAIN-SUFFIX,eroges.com,Proxy\nDOMAIN-SUFFIX,mp3li.net,Proxy\nDOMAIN-SUFFIX,www.xbluray.cc,Proxy\nDOMAIN-SUFFIX,tubexclips.com,Proxy\nDOMAIN-SUFFIX,738bm.com,Proxy\nDOMAIN-SUFFIX,www.elhelowgroup.com,Proxy\nDOMAIN-SUFFIX,proxyb.com,Proxy\nDOMAIN-SUFFIX,e-hentai.eu,Proxy\nDOMAIN-SUFFIX,fgh00.com,Proxy\nDOMAIN-SUFFIX,www.weltwoche.ch,Proxy\nDOMAIN-SUFFIX,jb288.com,Proxy\nDOMAIN-SUFFIX,xh88879.com,Proxy\nDOMAIN-SUFFIX,helpcn.fun315.com,Proxy\nDOMAIN-SUFFIX,s235w.etowns.net,Proxy\nDOMAIN-SUFFIX,madou.club,Proxy\nDOMAIN-SUFFIX,kznbadminton.co.za,Proxy\nDOMAIN-SUFFIX,www.shooshtime.com,Proxy\nDOMAIN-SUFFIX,infmeta.com,Proxy\nDOMAIN-SUFFIX,spaces.hightail.com,Proxy\nDOMAIN-SUFFIX,yankthetank.com,Proxy\nDOMAIN-SUFFIX,02.servebbs.org,Proxy\nDOMAIN-SUFFIX,www.inmall.com.tw,Proxy\nDOMAIN-SUFFIX,vpn.furnas.com.br,Proxy\nDOMAIN-SUFFIX,ca972.com,Proxy\nDOMAIN-SUFFIX,pornxs.com,Proxy\nDOMAIN-SUFFIX,wikileaks.de,Proxy\nDOMAIN-SUFFIX,www.cincinnatizencenter.org,Proxy\nDOMAIN-SUFFIX,hycgame2.xyz,Proxy\nDOMAIN-SUFFIX,www.cnhelloavgirls.com,Proxy\nDOMAIN-SUFFIX,idope.se,Proxy\nDOMAIN-SUFFIX,brandiron.co.za,Proxy\nDOMAIN-SUFFIX,mikocon.com,Proxy\nDOMAIN-SUFFIX,versavpn.com,Proxy\nDOMAIN-SUFFIX,austinjardinera.com,Proxy\nDOMAIN-SUFFIX,https443.org,Proxy\nDOMAIN-SUFFIX,reward.ggcarry888.com,Proxy\nDOMAIN-SUFFIX,www.leduo111.com,Proxy\nDOMAIN-SUFFIX,boundgangbangs.com,Proxy\nDOMAIN-SUFFIX,bangbrosfreetrial.com,Proxy\nDOMAIN-SUFFIX,pornoadler.com,Proxy\nDOMAIN-SUFFIX,orxtv.com,Proxy\nDOMAIN-SUFFIX,amnesty.org.uk,Proxy\nDOMAIN-SUFFIX,ip5005.co,Proxy\nDOMAIN-SUFFIX,85st.5lxtv.com,Proxy\nDOMAIN-SUFFIX,invidious.0011.lt,Proxy\nDOMAIN-SUFFIX,stickam.com,Proxy\nDOMAIN-SUFFIX,vpnintouch.in,Proxy\nDOMAIN-SUFFIX,www.yahoo.it,Proxy\nDOMAIN-SUFFIX,5uproxy.net,Proxy\nDOMAIN-SUFFIX,baixing.me,Proxy\nDOMAIN-SUFFIX,charuhas.in,Proxy\nDOMAIN-SUFFIX,maa1813.com,Proxy\nDOMAIN-SUFFIX,setn.com,Proxy\nDOMAIN-SUFFIX,www.piccollage.com,Proxy\nDOMAIN-SUFFIX,apptopia.com,Proxy\nDOMAIN-SUFFIX,www.tbtbfamily.com,Proxy\nDOMAIN-SUFFIX,maa1818.com,Proxy\nDOMAIN-SUFFIX,jokey.org,Proxy\nDOMAIN-SUFFIX,9544.com,Proxy\nDOMAIN-SUFFIX,www.houseoffreedom.org,Proxy\nDOMAIN-SUFFIX,brunellefamily.ca,Proxy\nDOMAIN-SUFFIX,mjib.gov.tw,Proxy\nDOMAIN-SUFFIX,fun780.com,Proxy\nDOMAIN-SUFFIX,ujian.cc,Proxy\nDOMAIN-SUFFIX,namgyalmonastery.org,Proxy\nDOMAIN-SUFFIX,nwhobby.com,Proxy\nDOMAIN-SUFFIX,lostmypass.com,Proxy\nDOMAIN-SUFFIX,data.flurry.com,Proxy\nDOMAIN-SUFFIX,porn.goshow.tv,Proxy\nDOMAIN-SUFFIX,javfilm.com,Proxy\nDOMAIN-SUFFIX,flipkart.com,Proxy\nDOMAIN-SUFFIX,b7979.com,Proxy\nDOMAIN-SUFFIX,jinian64.org,Proxy\nDOMAIN-SUFFIX,secure.hustler.com,Proxy\nDOMAIN-SUFFIX,www.nudevista.com,Proxy\nDOMAIN-SUFFIX,toh.info,Proxy\nDOMAIN-SUFFIX,www.eightandfour.com,Proxy\nDOMAIN-SUFFIX,faceboo.com,Proxy\nDOMAIN-SUFFIX,luminati-china.io,Proxy\nDOMAIN-SUFFIX,www.wix.org,Proxy\nDOMAIN-SUFFIX,qt.v99hub.com,Proxy\nDOMAIN-SUFFIX,topshareware.com,Proxy\nDOMAIN-SUFFIX,xpj88826.com,Proxy\nDOMAIN-SUFFIX,x.xcity.jp,Proxy\nDOMAIN-SUFFIX,gamedun.github.io,Proxy\nDOMAIN-SUFFIX,www.mxjiasu.com,Proxy\nDOMAIN-SUFFIX,co.gtasia777.com,Proxy\nDOMAIN-SUFFIX,invidious.osi.kr,Proxy\nDOMAIN-SUFFIX,u.graylady.in,Proxy\nDOMAIN-SUFFIX,g.codery.ga,Proxy\nDOMAIN-SUFFIX,video-sport.pl,Proxy\nDOMAIN-SUFFIX,xj3322.com,Proxy\nDOMAIN-SUFFIX,699aa.net,Proxy\nDOMAIN-SUFFIX,guaika.cc,Proxy\nDOMAIN-SUFFIX,hq898.com,Proxy\nDOMAIN-SUFFIX,youtubecn.com,Proxy\nDOMAIN-SUFFIX,idriis.com,Proxy\nDOMAIN-SUFFIX,in07.icu,Proxy\nDOMAIN-SUFFIX,keithobrien.org,Proxy\nDOMAIN-SUFFIX,www.posterous.com,Proxy\nDOMAIN-SUFFIX,globalmon.org.hk,Proxy\nDOMAIN-SUFFIX,www.jpolrisk.com,Proxy\nDOMAIN-SUFFIX,yogaalliance.in,Proxy\nDOMAIN-SUFFIX,njav.tv,Proxy\nDOMAIN-SUFFIX,www.hcss.com,Proxy\nDOMAIN-SUFFIX,cybersharq.com,Proxy\nDOMAIN-SUFFIX,pascalau.ro,Proxy\nDOMAIN-SUFFIX,tb6602.com,Proxy\nDOMAIN-SUFFIX,www.99kav.com,Proxy\nDOMAIN-SUFFIX,tracealyzer.com,Proxy\nDOMAIN-SUFFIX,newstapa.org,Proxy\nDOMAIN-SUFFIX,maggi.in,Proxy\nDOMAIN-SUFFIX,news.ycombinator.com,Proxy\nDOMAIN-SUFFIX,www.torrent-invites.com,Proxy\nDOMAIN-SUFFIX,www.premierproducts.com.tw,Proxy\nDOMAIN-SUFFIX,36rain.com,Proxy\nDOMAIN-SUFFIX,openid.net,Proxy\nDOMAIN-SUFFIX,www.iltk.it,Proxy\nDOMAIN-SUFFIX,bitstamp.com,Proxy\nDOMAIN-SUFFIX,www.almadi.it,Proxy\nDOMAIN-SUFFIX,freehongkong.org,Proxy\nDOMAIN-SUFFIX,www.physiotherapie-salameh.de,Proxy\nDOMAIN-SUFFIX,iwancai.com,Proxy\nDOMAIN-SUFFIX,shop2000.com.tw,Proxy\nDOMAIN-SUFFIX,www.gate.io,Proxy\nDOMAIN-SUFFIX,booking.infoflot.com,Proxy\nDOMAIN-SUFFIX,prisoneralert.com,Proxy\nDOMAIN-SUFFIX,mash.to,Proxy\nDOMAIN-SUFFIX,ecar.jlr-apps.com,Proxy\nDOMAIN-SUFFIX,bestvpn.org,Proxy\nDOMAIN-SUFFIX,shes.lflinkup.net,Proxy\nDOMAIN-SUFFIX,chromedata.com,Proxy\nDOMAIN-SUFFIX,about.me,Proxy\nDOMAIN-SUFFIX,www.bit-z.com,Proxy\nDOMAIN-SUFFIX,lt68.cc,Proxy\nDOMAIN-SUFFIX,spb.com,Proxy\nDOMAIN-SUFFIX,kimonet.okk.tw,Proxy\nDOMAIN-SUFFIX,ogate.org,Proxy\nDOMAIN-SUFFIX,kxsw.us,Proxy\nDOMAIN-SUFFIX,91sp.vido.ws,Proxy\nDOMAIN-SUFFIX,cn.4irc.com,Proxy\nDOMAIN-SUFFIX,dsb.mingma.fun,Proxy\nDOMAIN-SUFFIX,cdp.org,Proxy\nDOMAIN-SUFFIX,japtem.com,Proxy\nDOMAIN-SUFFIX,ashasanctuary.com,Proxy\nDOMAIN-SUFFIX,porntack.com,Proxy\nDOMAIN-SUFFIX,news.dmhk.net,Proxy\nDOMAIN-SUFFIX,teleobs.nouvelobs.com,Proxy\nDOMAIN-SUFFIX,blogspot.com.ng,Proxy\nDOMAIN-SUFFIX,wessonhardware.com,Proxy\nDOMAIN-SUFFIX,fl.wheredreams.com,Proxy\nDOMAIN-SUFFIX,hrgj52.com,Proxy\nDOMAIN-SUFFIX,gg911.xyz,Proxy\nDOMAIN-SUFFIX,zyxel.com,Proxy\nDOMAIN-SUFFIX,bmh005.com,Proxy\nDOMAIN-SUFFIX,flyproxy.com,Proxy\nDOMAIN-SUFFIX,archiveofourown.ga,Proxy\nDOMAIN-SUFFIX,www.aeromatasia.com,Proxy\nDOMAIN-SUFFIX,bing.vcanbb.top,Proxy\nDOMAIN-SUFFIX,nowbet.com,Proxy\nDOMAIN-SUFFIX,www.kitzanzeiger.at,Proxy\nDOMAIN-SUFFIX,twdvd.com,Proxy\nDOMAIN-SUFFIX,s-usc1c-nss-207.firebaseio.com,Proxy\nDOMAIN-SUFFIX,39.suroot.com,Proxy\nDOMAIN-SUFFIX,picnik.com,Proxy\nDOMAIN-SUFFIX,www.fpri.org,Proxy\nDOMAIN-SUFFIX,figprayer.com,Proxy\nDOMAIN-SUFFIX,www.aachener-nachrichten.de,Proxy\nDOMAIN-SUFFIX,top3.cf,Proxy\nDOMAIN-SUFFIX,adultrental.com,Proxy\nDOMAIN-SUFFIX,coinbase.com,Proxy\nDOMAIN-SUFFIX,forum.businessweekly.com.tw,Proxy\nDOMAIN-SUFFIX,picknchoose.com,Proxy\nDOMAIN-SUFFIX,nfscdict.com,Proxy\nDOMAIN-SUFFIX,resumerighters.com,Proxy\nDOMAIN-SUFFIX,cdninstagram.com,Proxy\nDOMAIN-SUFFIX,www.rakuten.co.jp,Proxy\nDOMAIN-SUFFIX,y2mate.com,Proxy\nDOMAIN-SUFFIX,nat.moe,Proxy\nDOMAIN-SUFFIX,www.hometied.com,Proxy\nDOMAIN-SUFFIX,javynow.com,Proxy\nDOMAIN-SUFFIX,wicked.com,Proxy\nDOMAIN-SUFFIX,www.newsjs.com,Proxy\nDOMAIN-SUFFIX,liimov.com,Proxy\nDOMAIN-SUFFIX,kty77.com,Proxy\nDOMAIN-SUFFIX,global.ishadowx.net,Proxy\nDOMAIN-SUFFIX,www.htai.me,Proxy\nDOMAIN-SUFFIX,www.jemmagura.com,Proxy\nDOMAIN-SUFFIX,juwelo.de,Proxy\nDOMAIN-SUFFIX,ekd.me,Proxy\nDOMAIN-SUFFIX,feckers.net,Proxy\nDOMAIN-SUFFIX,goki2.blogspot.jp,Proxy\nDOMAIN-SUFFIX,bellingcat.com,Proxy\nDOMAIN-SUFFIX,eu.org,Proxy\nDOMAIN-SUFFIX,www.idouga.com,Proxy\nDOMAIN-SUFFIX,laird.tw,Proxy\nDOMAIN-SUFFIX,g.bestirnte.com,Proxy\nDOMAIN-SUFFIX,www.raleighinternational.org,Proxy\nDOMAIN-SUFFIX,livingonline.us,Proxy\nDOMAIN-SUFFIX,xanimeporn.com,Proxy\nDOMAIN-SUFFIX,calgarysun.com,Proxy\nDOMAIN-SUFFIX,d32kn01rfn0r98.cloudfront.net,Proxy\nDOMAIN-SUFFIX,95xab.com,Proxy\nDOMAIN-SUFFIX,addictedtocoffee.de,Proxy\nDOMAIN-SUFFIX,www.jsjt-global.com,Proxy\nDOMAIN-SUFFIX,www.sege55.com,Proxy\nDOMAIN-SUFFIX,b15.compucase.com,Proxy\nDOMAIN-SUFFIX,b.etowns.net,Proxy\nDOMAIN-SUFFIX,www.huarenjie.com,Proxy\nDOMAIN-SUFFIX,y8tc.14.iamallama.com,Proxy\nDOMAIN-SUFFIX,07678.com,Proxy\nDOMAIN-SUFFIX,srv55.clipconverter.cc,Proxy\nDOMAIN-SUFFIX,knowsky.com,Proxy\nDOMAIN-SUFFIX,masqulin.com,Proxy\nDOMAIN-SUFFIX,p6552.com,Proxy\nDOMAIN-SUFFIX,efhc.mx,Proxy\nDOMAIN-SUFFIX,ked.b0ne.com,Proxy\nDOMAIN-SUFFIX,www.hepburnadvocate.com.au,Proxy\nDOMAIN-SUFFIX,pvvyfx.site,Proxy\nDOMAIN-SUFFIX,agpf.de,Proxy\nDOMAIN-SUFFIX,events.mapbox.com,Proxy\nDOMAIN-SUFFIX,d304dwl7tgk9ix.cloudfront.net,Proxy\nDOMAIN-SUFFIX,forusex.com,Proxy\nDOMAIN-SUFFIX,www.41hgvip.com,Proxy\nDOMAIN-SUFFIX,d1wmozxt3u3xb6.cloudfront.net,Proxy\nDOMAIN-SUFFIX,openjob.hk,Proxy\nDOMAIN-SUFFIX,www.lzj.org,Proxy\nDOMAIN-SUFFIX,4freemam.myfw.us,Proxy\nDOMAIN-SUFFIX,xnxx2.com,Proxy\nDOMAIN-SUFFIX,qpby2266.com,Proxy\nDOMAIN-SUFFIX,furbo.org,Proxy\nDOMAIN-SUFFIX,dontfilter.us,Proxy\nDOMAIN-SUFFIX,atimes.com,Proxy\nDOMAIN-SUFFIX,ecofibras.cl,Proxy\nDOMAIN-SUFFIX,i2p2.de,Proxy\nDOMAIN-SUFFIX,namsisi.com,Proxy\nDOMAIN-SUFFIX,18girlssex.com,Proxy\nDOMAIN-SUFFIX,www.xiumima.com,Proxy\nDOMAIN-SUFFIX,www.hacker.org,Proxy\nDOMAIN-SUFFIX,ray1001.com,Proxy\nDOMAIN-SUFFIX,64899.com,Proxy\nDOMAIN-SUFFIX,www.warnermedia.com,Proxy\nDOMAIN-SUFFIX,iicns.com,Proxy\nDOMAIN-SUFFIX,freeweibo.s3.amazonaws.com,Proxy\nDOMAIN-SUFFIX,laod.cn,Proxy\nDOMAIN-SUFFIX,src.ca,Proxy\nDOMAIN-SUFFIX,cdn.tranquilli.org,Proxy\nDOMAIN-SUFFIX,cache.wdcdn.net,Proxy\nDOMAIN-SUFFIX,freelysurf.cf,Proxy\nDOMAIN-SUFFIX,p5525.com,Proxy\nDOMAIN-SUFFIX,ipvm.com,Proxy\nDOMAIN-SUFFIX,freeproxyserver.net,Proxy\nDOMAIN-SUFFIX,www.seeker.com,Proxy\nDOMAIN-SUFFIX,sphard.com,Proxy\nDOMAIN-SUFFIX,1337x.to,Proxy\nDOMAIN-SUFFIX,12001.com,Proxy\nDOMAIN-SUFFIX,aisex.com,Proxy\nDOMAIN-SUFFIX,zzr.familyhealth.xyz,Proxy\nDOMAIN-SUFFIX,voanews.mobi,Proxy\nDOMAIN-SUFFIX,redcandlegames.com,Proxy\nDOMAIN-SUFFIX,europroxy.eu,Proxy\nDOMAIN-SUFFIX,aolchannels.aol.com,Proxy\nDOMAIN-SUFFIX,static.ads-twitter.com,Proxy\nDOMAIN-SUFFIX,vpngates.com,Proxy\nDOMAIN-SUFFIX,hjdc05.com,Proxy\nDOMAIN-SUFFIX,ding-hao.blogspot.ca,Proxy\nDOMAIN-SUFFIX,kwfq.tk,Proxy\nDOMAIN-SUFFIX,xvideos08.com,Proxy\nDOMAIN-SUFFIX,chiemtinhviet.com,Proxy\nDOMAIN-SUFFIX,backpackers.com.tw,Proxy\nDOMAIN-SUFFIX,rcover.net,Proxy\nDOMAIN-SUFFIX,k-starhk.blogspot.hk,Proxy\nDOMAIN-SUFFIX,www.dalailamaquotes.org,Proxy\nDOMAIN-SUFFIX,www.ntmetro.com.tw,Proxy\nDOMAIN-SUFFIX,i.lithium.com,Proxy\nDOMAIN-SUFFIX,sesawe.net,Proxy\nDOMAIN-SUFFIX,avhot.cc,Proxy\nDOMAIN-SUFFIX,in.flnet.org,Proxy\nDOMAIN-SUFFIX,china.fptbb.com,Proxy\nDOMAIN-SUFFIX,cryptocat.com,Proxy\nDOMAIN-SUFFIX,www.xxxshake.com,Proxy\nDOMAIN-SUFFIX,zophar.net,Proxy\nDOMAIN-SUFFIX,500ish.com,Proxy\nDOMAIN-SUFFIX,jpay.com,Proxy\nDOMAIN-SUFFIX,friproxy0.biz,Proxy\nDOMAIN-SUFFIX,www.church.org.tw,Proxy\nDOMAIN-SUFFIX,duev25b3a4sjl.cloudfront.net,Proxy\nDOMAIN-SUFFIX,google.gr,Proxy\nDOMAIN-SUFFIX,onion.ws,Proxy\nDOMAIN-SUFFIX,jinshagt888.com,Proxy\nDOMAIN-SUFFIX,dabr.mobi,Proxy\nDOMAIN-SUFFIX,b5977.com,Proxy\nDOMAIN-SUFFIX,hy88889.com,Proxy\nDOMAIN-SUFFIX,yidio.com,Proxy\nDOMAIN-SUFFIX,rich888.cc,Proxy\nDOMAIN-SUFFIX,shakfu.com,Proxy\nDOMAIN-SUFFIX,cheaper1.work,Proxy\nDOMAIN-SUFFIX,bjs.org,Proxy\nDOMAIN-SUFFIX,vobas.com,Proxy\nDOMAIN-SUFFIX,fangmincn.org,Proxy\nDOMAIN-SUFFIX,azerimix.com,Proxy\nDOMAIN-SUFFIX,trsiyengar.com,Proxy\nDOMAIN-SUFFIX,zkaip.com,Proxy\nDOMAIN-SUFFIX,mthruf.com,Proxy\nDOMAIN-SUFFIX,8587y.cc,Proxy\nDOMAIN-SUFFIX,nitter.dafriser.be,Proxy\nDOMAIN-SUFFIX,moeshare.com,Proxy\nDOMAIN-SUFFIX,rossvideo.com,Proxy\nDOMAIN-SUFFIX,gohappy.com.tw,Proxy\nDOMAIN-SUFFIX,pbet123.com,Proxy\nDOMAIN-SUFFIX,datafilehost.com,Proxy\nDOMAIN-SUFFIX,c3pool.com,Proxy\nDOMAIN-SUFFIX,asacp.org,Proxy\nDOMAIN-SUFFIX,lataayoutube.com,Proxy\nDOMAIN-SUFFIX,ifunny.mobi,Proxy\nDOMAIN-SUFFIX,freeones.ca,Proxy\nDOMAIN-SUFFIX,m.mbetxapp28.com,Proxy\nDOMAIN-SUFFIX,www.ecologic.eu,Proxy\nDOMAIN-SUFFIX,dwelle.de,Proxy\nDOMAIN-SUFFIX,pttgame.com,Proxy\nDOMAIN-SUFFIX,error.comlu.com,Proxy\nDOMAIN-SUFFIX,gexo.com,Proxy\nDOMAIN-SUFFIX,nordwebsite.net,Proxy\nDOMAIN-SUFFIX,pressplay.cc,Proxy\nDOMAIN-SUFFIX,www.ylib.com,Proxy\nDOMAIN-SUFFIX,u.is,Proxy\nDOMAIN-SUFFIX,d2ppeatpexoo56.cloudfront.net,Proxy\nDOMAIN-SUFFIX,instagram.de,Proxy\nDOMAIN-SUFFIX,www.n6396.com,Proxy\nDOMAIN-SUFFIX,xxxporn.com,Proxy\nDOMAIN-SUFFIX,easygals.com,Proxy\nDOMAIN-SUFFIX,nbcnews.to,Proxy\nDOMAIN-SUFFIX,booksc.xyz,Proxy\nDOMAIN-SUFFIX,www.asia-jiasheng.com,Proxy\nDOMAIN-SUFFIX,unblockyouku.com,Proxy\nDOMAIN-SUFFIX,shinyproxy.com,Proxy\nDOMAIN-SUFFIX,gci.xbet777.com,Proxy\nDOMAIN-SUFFIX,apps.jw.org,Proxy\nDOMAIN-SUFFIX,securevpn.to,Proxy\nDOMAIN-SUFFIX,moodyz.com,Proxy\nDOMAIN-SUFFIX,replyphoto.hatogen.hi.cn,Proxy\nDOMAIN-SUFFIX,www.yanyuge.net,Proxy\nDOMAIN-SUFFIX,bt95.com,Proxy\nDOMAIN-SUFFIX,556.slyip.com,Proxy\nDOMAIN-SUFFIX,www.play88angel.com,Proxy\nDOMAIN-SUFFIX,youngspiration.hk,Proxy\nDOMAIN-SUFFIX,twibase.com,Proxy\nDOMAIN-SUFFIX,32.ns22.ru,Proxy\nDOMAIN-SUFFIX,rixcloud.me,Proxy\nDOMAIN-SUFFIX,jeth.tk,Proxy\nDOMAIN-SUFFIX,livestation.com,Proxy\nDOMAIN-SUFFIX,www.ccn.com,Proxy\nDOMAIN-SUFFIX,pluton.plan9-dns.com,Proxy\nDOMAIN-SUFFIX,www.listennotes.com,Proxy\nDOMAIN-SUFFIX,chartestube.ch,Proxy\nDOMAIN-SUFFIX,iqq2.xyz,Proxy\nDOMAIN-SUFFIX,mailboxapp.com,Proxy\nDOMAIN-SUFFIX,rcinet.ca,Proxy\nDOMAIN-SUFFIX,57686.com,Proxy\nDOMAIN-SUFFIX,vpnas.com,Proxy\nDOMAIN-SUFFIX,bbs.netbig.com,Proxy\nDOMAIN-SUFFIX,web.102604.icu,Proxy\nDOMAIN-SUFFIX,churchworldservice.org,Proxy\nDOMAIN-SUFFIX,turntable.fm,Proxy\nDOMAIN-SUFFIX,theprospect.com,Proxy\nDOMAIN-SUFFIX,mprnews.org,Proxy\nDOMAIN-SUFFIX,forum.loginchina.org,Proxy\nDOMAIN-SUFFIX,facebook.es,Proxy\nDOMAIN-SUFFIX,www.narinjara.com,Proxy\nDOMAIN-SUFFIX,www.puff123.com,Proxy\nDOMAIN-SUFFIX,66vid.com,Proxy\nDOMAIN-SUFFIX,api.pureapk.com,Proxy\nDOMAIN-SUFFIX,www.erase.bg,Proxy\nDOMAIN-SUFFIX,paranormalmist.com,Proxy\nDOMAIN-SUFFIX,googlesile.com,Proxy\nDOMAIN-SUFFIX,jav777.me,Proxy\nDOMAIN-SUFFIX,w2898.com,Proxy\nDOMAIN-SUFFIX,m.plixi.com,Proxy\nDOMAIN-SUFFIX,mineirinhanalemanha.de,Proxy\nDOMAIN-SUFFIX,is-a-student.com,Proxy\nDOMAIN-SUFFIX,yin012.com,Proxy\nDOMAIN-SUFFIX,77.ddnsking.com,Proxy\nDOMAIN-SUFFIX,gamer-cds.cdn.hinet.net,Proxy\nDOMAIN-SUFFIX,metrolife.ca,Proxy\nDOMAIN-SUFFIX,streamie.org,Proxy\nDOMAIN-SUFFIX,qkshare.com,Proxy\nDOMAIN-SUFFIX,uw.com,Proxy\nDOMAIN-SUFFIX,breakingdefense.com,Proxy\nDOMAIN-SUFFIX,zom.im,Proxy\nDOMAIN-SUFFIX,godsdirectcontact.co.uk,Proxy\nDOMAIN-SUFFIX,googlemail.com,Proxy\nDOMAIN-SUFFIX,94xag.com,Proxy\nDOMAIN-SUFFIX,32.effers.com,Proxy\nDOMAIN-SUFFIX,msl.mt.gov,Proxy\nDOMAIN-SUFFIX,foodwishes.blogspot.hk,Proxy\nDOMAIN-SUFFIX,ytvpn.com,Proxy\nDOMAIN-SUFFIX,falundafautah.org,Proxy\nDOMAIN-SUFFIX,2712s.com,Proxy\nDOMAIN-SUFFIX,ydy.com,Proxy\nDOMAIN-SUFFIX,tweetwally.com,Proxy\nDOMAIN-SUFFIX,imanhua.com,Proxy\nDOMAIN-SUFFIX,21newyouth.net,Proxy\nDOMAIN-SUFFIX,2anonymousproxy.com,Proxy\nDOMAIN-SUFFIX,www.pursuestar.com,Proxy\nDOMAIN-SUFFIX,djack.ca,Proxy\nDOMAIN-SUFFIX,iheartradio.com,Proxy\nDOMAIN-SUFFIX,midnightfever.com,Proxy\nDOMAIN-SUFFIX,nodebe4.github.io,Proxy\nDOMAIN-SUFFIX,geocities.com,Proxy\nDOMAIN-SUFFIX,avhd101.com,Proxy\nDOMAIN-SUFFIX,www.maaii.com,Proxy\nDOMAIN-SUFFIX,gvt1.com,Proxy\nDOMAIN-SUFFIX,fugletrading.esunsec.com.tw,Proxy\nDOMAIN-SUFFIX,d2xsp42qjlbe5v.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.yysub.net,Proxy\nDOMAIN-SUFFIX,smzb.io,Proxy\nDOMAIN-SUFFIX,www.redwap.me,Proxy\nDOMAIN-SUFFIX,zebnet.coloraccounting.com,Proxy\nDOMAIN-SUFFIX,www.fast.fm,Proxy\nDOMAIN-SUFFIX,jbtalks.com,Proxy\nDOMAIN-SUFFIX,newschinacomment.org,Proxy\nDOMAIN-SUFFIX,ddns.name,Proxy\nDOMAIN-SUFFIX,www.america.gov,Proxy\nDOMAIN-SUFFIX,faapy.com,Proxy\nDOMAIN-SUFFIX,www.netmotionsoftware.com,Proxy\nDOMAIN-SUFFIX,prdelb.flytalk.net,Proxy\nDOMAIN-SUFFIX,litenews.hk,Proxy\nDOMAIN-SUFFIX,pct.org.tw,Proxy\nDOMAIN-SUFFIX,manchukuo.net,Proxy\nDOMAIN-SUFFIX,citizenlab.ca,Proxy\nDOMAIN-SUFFIX,dnscom.work,Proxy\nDOMAIN-SUFFIX,www.thechinastory.org,Proxy\nDOMAIN-SUFFIX,twitter.com,Proxy\nDOMAIN-SUFFIX,k.css5.pw,Proxy\nDOMAIN-SUFFIX,jingking.net,Proxy\nDOMAIN-SUFFIX,fulijiejie.com,Proxy\nDOMAIN-SUFFIX,incloak.com,Proxy\nDOMAIN-SUFFIX,bdg987.com,Proxy\nDOMAIN-SUFFIX,redtude.com,Proxy\nDOMAIN-SUFFIX,falundafa.org.il,Proxy\nDOMAIN-SUFFIX,www.macau-slot.com,Proxy\nDOMAIN-SUFFIX,toythieves.com,Proxy\nDOMAIN-SUFFIX,www.729914.com,Proxy\nDOMAIN-SUFFIX,www.qimiqimi.co,Proxy\nDOMAIN-SUFFIX,mfs-shatel-training.maaii.com,Proxy\nDOMAIN-SUFFIX,www.javpee.com,Proxy\nDOMAIN-SUFFIX,www.express-vpn.com,Proxy\nDOMAIN-SUFFIX,www.bauhaus.se,Proxy\nDOMAIN-SUFFIX,avaaz.org,Proxy\nDOMAIN-SUFFIX,jubt.net,Proxy\nDOMAIN-SUFFIX,www.epochtimes.com.tw,Proxy\nDOMAIN-SUFFIX,1z2x1z.blogspot.hk,Proxy\nDOMAIN-SUFFIX,incometaxindia.gov.in,Proxy\nDOMAIN-SUFFIX,www.afreeca.com,Proxy\nDOMAIN-SUFFIX,www.tnbt1.xyz,Proxy\nDOMAIN-SUFFIX,www.betaa58.com,Proxy\nDOMAIN-SUFFIX,sbs3366.com,Proxy\nDOMAIN-SUFFIX,www.secretbrowser.net,Proxy\nDOMAIN-SUFFIX,www.16bifa.com,Proxy\nDOMAIN-SUFFIX,www.paribu.com,Proxy\nDOMAIN-SUFFIX,ayoutube.com,Proxy\nDOMAIN-SUFFIX,www.filepoodles.com,Proxy\nDOMAIN-SUFFIX,ruuh.com,Proxy\nDOMAIN-SUFFIX,www.xmember.com,Proxy\nDOMAIN-SUFFIX,www.liudapeng.com,Proxy\nDOMAIN-SUFFIX,legendvps.net,Proxy\nDOMAIN-SUFFIX,www.activtrades.com,Proxy\nDOMAIN-SUFFIX,www1.american.edu,Proxy\nDOMAIN-SUFFIX,lubl.xyz,Proxy\nDOMAIN-SUFFIX,9aep1.com,Proxy\nDOMAIN-SUFFIX,www.pornhat.com,Proxy\nDOMAIN-SUFFIX,kukuku.fun,Proxy\nDOMAIN-SUFFIX,ppyq5.com,Proxy\nDOMAIN-SUFFIX,tameikegoro.jp,Proxy\nDOMAIN-SUFFIX,rtalabel.org,Proxy\nDOMAIN-SUFFIX,www.btb.com.bt,Proxy\nDOMAIN-SUFFIX,tw.yahoo.com,Proxy\nDOMAIN-SUFFIX,boylov.xyz,Proxy\nDOMAIN-SUFFIX,pu0030.com,Proxy\nDOMAIN-SUFFIX,rztcapital.com,Proxy\nDOMAIN-SUFFIX,teflonline.teachaway.com,Proxy\nDOMAIN-SUFFIX,zhreader.com,Proxy\nDOMAIN-SUFFIX,bellamysorganic.com,Proxy\nDOMAIN-SUFFIX,malimao.blogspot.hk,Proxy\nDOMAIN-SUFFIX,solutemplates.com,Proxy\nDOMAIN-SUFFIX,theporn.cc,Proxy\nDOMAIN-SUFFIX,www.html5rocks.com,Proxy\nDOMAIN-SUFFIX,gay.xtapes.to,Proxy\nDOMAIN-SUFFIX,proxy-site.com.de,Proxy\nDOMAIN-SUFFIX,elektroluks.si,Proxy\nDOMAIN-SUFFIX,golang.org,Proxy\nDOMAIN-SUFFIX,jyav.com,Proxy\nDOMAIN-SUFFIX,realitykings.com,Proxy\nDOMAIN-SUFFIX,xkeezmovies.com,Proxy\nDOMAIN-SUFFIX,luflosi.de,Proxy\nDOMAIN-SUFFIX,www.e8993.com,Proxy\nDOMAIN-SUFFIX,m.cabet588.com,Proxy\nDOMAIN-SUFFIX,s1.nudezz.com,Proxy\nDOMAIN-SUFFIX,www.taiwansig.tw,Proxy\nDOMAIN-SUFFIX,tienve.org,Proxy\nDOMAIN-SUFFIX,xys.org,Proxy\nDOMAIN-SUFFIX,www.hwa-shin.com,Proxy\nDOMAIN-SUFFIX,sacred-texts.org,Proxy\nDOMAIN-SUFFIX,edinn.com,Proxy\nDOMAIN-SUFFIX,jm-comic3.club,Proxy\nDOMAIN-SUFFIX,mrgate.co.za,Proxy\nDOMAIN-SUFFIX,myanniu.com,Proxy\nDOMAIN-SUFFIX,w2.yay.3d-game.com,Proxy\nDOMAIN-SUFFIX,yespornplease.com,Proxy\nDOMAIN-SUFFIX,www.mtco.com,Proxy\nDOMAIN-SUFFIX,javvan.cc,Proxy\nDOMAIN-SUFFIX,stex.com,Proxy\nDOMAIN-SUFFIX,top2.gq,Proxy\nDOMAIN-SUFFIX,loli.net,Proxy\nDOMAIN-SUFFIX,www.wow.com,Proxy\nDOMAIN-SUFFIX,giga-web.jp,Proxy\nDOMAIN-SUFFIX,b10f.jp,Proxy\nDOMAIN-SUFFIX,popgare.pt,Proxy\nDOMAIN-SUFFIX,iktalks.com,Proxy\nDOMAIN-SUFFIX,blog.ulifestyle.com.hk,Proxy\nDOMAIN-SUFFIX,ts-778.com,Proxy\nDOMAIN-SUFFIX,ulmf.org,Proxy\nDOMAIN-SUFFIX,spacesat.com,Proxy\nDOMAIN-SUFFIX,sdarabia.com,Proxy\nDOMAIN-SUFFIX,happyyoutube.com,Proxy\nDOMAIN-SUFFIX,agefans.com,Proxy\nDOMAIN-SUFFIX,google.mk,Proxy\nDOMAIN-SUFFIX,firearmsworld.net,Proxy\nDOMAIN-SUFFIX,d1xdpmm84fa9xh.cloudfront.net,Proxy\nDOMAIN-SUFFIX,juicygifs.com,Proxy\nDOMAIN-SUFFIX,kk2267.com,Proxy\nDOMAIN-SUFFIX,chinavpn.net,Proxy\nDOMAIN-SUFFIX,33331.com,Proxy\nDOMAIN-SUFFIX,zz2143.com,Proxy\nDOMAIN-SUFFIX,dong8.mywww.biz,Proxy\nDOMAIN-SUFFIX,www.ccu.edu.tw,Proxy\nDOMAIN-SUFFIX,ts2t.com,Proxy\nDOMAIN-SUFFIX,prnhub.com,Proxy\nDOMAIN-SUFFIX,sb.wixsite.com,Proxy\nDOMAIN-SUFFIX,cs145.com,Proxy\nDOMAIN-SUFFIX,00663885.com,Proxy\nDOMAIN-SUFFIX,4pu.com,Proxy\nDOMAIN-SUFFIX,bbs.morbell.com,Proxy\nDOMAIN-SUFFIX,f33.flnet.org,Proxy\nDOMAIN-SUFFIX,blockchina.com,Proxy\nDOMAIN-SUFFIX,www.torlock2.com,Proxy\nDOMAIN-SUFFIX,jojofx.com,Proxy\nDOMAIN-SUFFIX,ardill.com,Proxy\nDOMAIN-SUFFIX,google.co.jp,Proxy\nDOMAIN-SUFFIX,hboutique.ro,Proxy\nDOMAIN-SUFFIX,www.easternriverinachronicle.com.au,Proxy\nDOMAIN-SUFFIX,blinkx.com,Proxy\nDOMAIN-SUFFIX,velase.com,Proxy\nDOMAIN-SUFFIX,8587j.cc,Proxy\nDOMAIN-SUFFIX,keepsolid.com,Proxy\nDOMAIN-SUFFIX,az668014.vo.msecnd.net,Proxy\nDOMAIN-SUFFIX,pinterest.com,Proxy\nDOMAIN-SUFFIX,www.donki.com,Proxy\nDOMAIN-SUFFIX,nitter.simpleprivacy.fr,Proxy\nDOMAIN-SUFFIX,api.totallyacdn.com,Proxy\nDOMAIN-SUFFIX,1053678.com,Proxy\nDOMAIN-SUFFIX,my.now-ip.net,Proxy\nDOMAIN-SUFFIX,blog.g-sec.lu,Proxy\nDOMAIN-SUFFIX,wasd.tv,Proxy\nDOMAIN-SUFFIX,huobi.co,Proxy\nDOMAIN-SUFFIX,swoongoods.com,Proxy\nDOMAIN-SUFFIX,fb.watch,Proxy\nDOMAIN-SUFFIX,av30.net,Proxy\nDOMAIN-SUFFIX,akahoshitakuya.com,Proxy\nDOMAIN-SUFFIX,hacg.me,Proxy\nDOMAIN-SUFFIX,tunein.streamguys1.com,Proxy\nDOMAIN-SUFFIX,www.bbin.com,Proxy\nDOMAIN-SUFFIX,360xpj.com,Proxy\nDOMAIN-SUFFIX,www.88gpz.com,Proxy\nDOMAIN-SUFFIX,zoidson.com,Proxy\nDOMAIN-SUFFIX,90033.cc,Proxy\nDOMAIN-SUFFIX,euronewsradio.com,Proxy\nDOMAIN-SUFFIX,erodaizensyu.com,Proxy\nDOMAIN-SUFFIX,ban.grclan.net,Proxy\nDOMAIN-SUFFIX,goforhealth.xyz,Proxy\nDOMAIN-SUFFIX,fnac.com,Proxy\nDOMAIN-SUFFIX,download.apkplz.com,Proxy\nDOMAIN-SUFFIX,parklu.com,Proxy\nDOMAIN-SUFFIX,oho.slyip.net,Proxy\nDOMAIN-SUFFIX,www.69park.com,Proxy\nDOMAIN-SUFFIX,www.jukujo-club.com,Proxy\nDOMAIN-SUFFIX,colorado-photo.com,Proxy\nDOMAIN-SUFFIX,dilber.se,Proxy\nDOMAIN-SUFFIX,lpsg.com,Proxy\nDOMAIN-SUFFIX,quarem.net,Proxy\nDOMAIN-SUFFIX,heavy-r.com,Proxy\nDOMAIN-SUFFIX,dfh48.com,Proxy\nDOMAIN-SUFFIX,1024gc.com,Proxy\nDOMAIN-SUFFIX,ws.dnsserv.xyz,Proxy\nDOMAIN-SUFFIX,hacg.in,Proxy\nDOMAIN-SUFFIX,999ycw.com,Proxy\nDOMAIN-SUFFIX,d1o0w9vg6wcyne.cloudfront.net,Proxy\nDOMAIN-SUFFIX,ofoc.sec.b0ne.com,Proxy\nDOMAIN-SUFFIX,bitcoinworld.com,Proxy\nDOMAIN-SUFFIX,coolstuffinc.com,Proxy\nDOMAIN-SUFFIX,tgirljapan.com,Proxy\nDOMAIN-SUFFIX,xk.freepac.pw,Proxy\nDOMAIN-SUFFIX,aisqj.com,Proxy\nDOMAIN-SUFFIX,buffered.com,Proxy\nDOMAIN-SUFFIX,gtv1.org,Proxy\nDOMAIN-SUFFIX,jandyx.com,Proxy\nDOMAIN-SUFFIX,ilovexjp.com,Proxy\nDOMAIN-SUFFIX,me5268.mybbs.us,Proxy\nDOMAIN-SUFFIX,reutersmedia.net,Proxy\nDOMAIN-SUFFIX,globeandmail.com,Proxy\nDOMAIN-SUFFIX,bigfools.com,Proxy\nDOMAIN-SUFFIX,tw.tomonews.net,Proxy\nDOMAIN-SUFFIX,oolala.xyz,Proxy\nDOMAIN-SUFFIX,aslbeauty.byethost7.com,Proxy\nDOMAIN-SUFFIX,gu05s6570.tudouser.com,Proxy\nDOMAIN-SUFFIX,1561666.com,Proxy\nDOMAIN-SUFFIX,facebook.no,Proxy\nDOMAIN-SUFFIX,perfectvpn.net,Proxy\nDOMAIN-SUFFIX,2.inc.gs,Proxy\nDOMAIN-SUFFIX,iliensale.com,Proxy\nDOMAIN-SUFFIX,epochtimes.jp,Proxy\nDOMAIN-SUFFIX,ig.com,Proxy\nDOMAIN-SUFFIX,www.ssglobal.co,Proxy\nDOMAIN-SUFFIX,wcloud.hk,Proxy\nDOMAIN-SUFFIX,shit.com,Proxy\nDOMAIN-SUFFIX,google.dev,Proxy\nDOMAIN-SUFFIX,deutsche-welle.de,Proxy\nDOMAIN-SUFFIX,gelbooru.com,Proxy\nDOMAIN-SUFFIX,www.e8play.cc,Proxy\nDOMAIN-SUFFIX,uivmtv.site,Proxy\nDOMAIN-SUFFIX,www.falanxi.org,Proxy\nDOMAIN-SUFFIX,227227201.com,Proxy\nDOMAIN-SUFFIX,eros.com,Proxy\nDOMAIN-SUFFIX,hujiachina.spaces.live.com,Proxy\nDOMAIN-SUFFIX,iheartorganizing.blogspot.hk,Proxy\nDOMAIN-SUFFIX,xhamster.com,Proxy\nDOMAIN-SUFFIX,us-central1-kirichilli-cart.cloudfunctions.net,Proxy\nDOMAIN-SUFFIX,sgforums.com,Proxy\nDOMAIN-SUFFIX,33770.com,Proxy\nDOMAIN-SUFFIX,www.drama321.com,Proxy\nDOMAIN-SUFFIX,china101.com,Proxy\nDOMAIN-SUFFIX,tiavastube.com,Proxy\nDOMAIN-SUFFIX,hardcore.com,Proxy\nDOMAIN-SUFFIX,pu0036.com,Proxy\nDOMAIN-SUFFIX,x.company,Proxy\nDOMAIN-SUFFIX,xinjiangpolicefiles.org,Proxy\nDOMAIN-SUFFIX,ent.cari.com.my,Proxy\nDOMAIN-SUFFIX,dirtywivesclub.com,Proxy\nDOMAIN-SUFFIX,www.fun888city.net,Proxy\nDOMAIN-SUFFIX,ecsm.vs.com,Proxy\nDOMAIN-SUFFIX,tango.me,Proxy\nDOMAIN-SUFFIX,d23nscda4f4lvy.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.cdm.me,Proxy\nDOMAIN-SUFFIX,tb111.com,Proxy\nDOMAIN-SUFFIX,demconvention.com,Proxy\nDOMAIN-SUFFIX,corn.chowder.land,Proxy\nDOMAIN-SUFFIX,tasci.biz,Proxy\nDOMAIN-SUFFIX,ebb.b0ne.com,Proxy\nDOMAIN-SUFFIX,techviz.net,Proxy\nDOMAIN-SUFFIX,jorn.net,Proxy\nDOMAIN-SUFFIX,www.661316.com,Proxy\nDOMAIN-SUFFIX,www.unblockfacebook.com,Proxy\nDOMAIN-SUFFIX,gradeproof.com,Proxy\nDOMAIN-SUFFIX,ss.gfw.host,Proxy\nDOMAIN-SUFFIX,localbitcoins.com,Proxy\nDOMAIN-SUFFIX,ss.gate-project.com,Proxy\nDOMAIN-SUFFIX,translate.goog,Proxy\nDOMAIN-SUFFIX,dalailama.org,Proxy\nDOMAIN-SUFFIX,www.blubrry.com,Proxy\nDOMAIN-SUFFIX,mvg.jp,Proxy\nDOMAIN-SUFFIX,hometubeporn.com,Proxy\nDOMAIN-SUFFIX,qiwenlu.blogspot.hk,Proxy\nDOMAIN-SUFFIX,sjxxhtlm.gain.tw,Proxy\nDOMAIN-SUFFIX,asiansexdiary.com,Proxy\nDOMAIN-SUFFIX,www.silverchair.com,Proxy\nDOMAIN-SUFFIX,vpnba.com,Proxy\nDOMAIN-SUFFIX,drvpgrhib1ucs.cloudfront.net,Proxy\nDOMAIN-SUFFIX,help.linksalpha.com,Proxy\nDOMAIN-SUFFIX,google.dk,Proxy\nDOMAIN-SUFFIX,www.gmail.cm,Proxy\nDOMAIN-SUFFIX,kazakisfamily.com,Proxy\nDOMAIN-SUFFIX,www.theartnewspaper.com,Proxy\nDOMAIN-SUFFIX,twimg.com,Proxy\nDOMAIN-SUFFIX,sijihuisuo.com,Proxy\nDOMAIN-SUFFIX,chinareviewed.co.uk,Proxy\nDOMAIN-SUFFIX,www.jeromecohen.net,Proxy\nDOMAIN-SUFFIX,lelangac.uk,Proxy\nDOMAIN-SUFFIX,indiemerch.com,Proxy\nDOMAIN-SUFFIX,www.hqringenieria.cl,Proxy\nDOMAIN-SUFFIX,toukuike.com,Proxy\nDOMAIN-SUFFIX,teamtest.in,Proxy\nDOMAIN-SUFFIX,www.webproxy2.com,Proxy\nDOMAIN-SUFFIX,roigtaxi.es,Proxy\nDOMAIN-SUFFIX,www.destinationexplorers.com,Proxy\nDOMAIN-SUFFIX,wikaba.com,Proxy\nDOMAIN-SUFFIX,edwingomez.com,Proxy\nDOMAIN-SUFFIX,www.hetzner.fi,Proxy\nDOMAIN-SUFFIX,wiki.phonegap.com,Proxy\nDOMAIN-SUFFIX,n.cdn22.xyz,Proxy\nDOMAIN-SUFFIX,twitthat.com,Proxy\nDOMAIN-SUFFIX,urlparser.com,Proxy\nDOMAIN-SUFFIX,vpnhq.com,Proxy\nDOMAIN-SUFFIX,2793.sbf9988.com,Proxy\nDOMAIN-SUFFIX,alohatube.com,Proxy\nDOMAIN-SUFFIX,gdnonline.com,Proxy\nDOMAIN-SUFFIX,pureinsight.org,Proxy\nDOMAIN-SUFFIX,clubhouseapi.com,Proxy\nDOMAIN-SUFFIX,85299.com,Proxy\nDOMAIN-SUFFIX,vip.luroupeixun.com,Proxy\nDOMAIN-SUFFIX,www.zhuxia.com,Proxy\nDOMAIN-SUFFIX,rrr112.net,Proxy\nDOMAIN-SUFFIX,nazi.net,Proxy\nDOMAIN-SUFFIX,transmissionzero.co.uk,Proxy\nDOMAIN-SUFFIX,setdns.work,Proxy\nDOMAIN-SUFFIX,www.ipinator.com,Proxy\nDOMAIN-SUFFIX,juniper.net,Proxy\nDOMAIN-SUFFIX,browsehappy.com,Proxy\nDOMAIN-SUFFIX,pandapow.com,Proxy\nDOMAIN-SUFFIX,tongil.or.kr,Proxy\nDOMAIN-SUFFIX,breachforums.is,Proxy\nDOMAIN-SUFFIX,mariusl.com,Proxy\nDOMAIN-SUFFIX,d2lut0s7ldy2gm.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.successfn.com,Proxy\nDOMAIN-SUFFIX,ee.etowns.net,Proxy\nDOMAIN-SUFFIX,mohubackup.github.io,Proxy\nDOMAIN-SUFFIX,openloadfreetv.me,Proxy\nDOMAIN-SUFFIX,pinnaclesports.com,Proxy\nDOMAIN-SUFFIX,hr8751.com,Proxy\nDOMAIN-SUFFIX,api-secure.recaptcha.net,Proxy\nDOMAIN-SUFFIX,nyt6.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,liu-xiaobo.org,Proxy\nDOMAIN-SUFFIX,www.barracudanetworks.com,Proxy\nDOMAIN-SUFFIX,dnsnl.alekberg.net,Proxy\nDOMAIN-SUFFIX,angelwind.tw,Proxy\nDOMAIN-SUFFIX,blogspot.kr,Proxy\nDOMAIN-SUFFIX,goipaula.com,Proxy\nDOMAIN-SUFFIX,leaver.me,Proxy\nDOMAIN-SUFFIX,mixer.com,Proxy\nDOMAIN-SUFFIX,ethanology.net,Proxy\nDOMAIN-SUFFIX,do-essential-oils.com,Proxy\nDOMAIN-SUFFIX,coinabul.com,Proxy\nDOMAIN-SUFFIX,g.effers.com,Proxy\nDOMAIN-SUFFIX,yellowpages.com,Proxy\nDOMAIN-SUFFIX,www.freechinaxxx.com,Proxy\nDOMAIN-SUFFIX,www.hokkoku.co.jp,Proxy\nDOMAIN-SUFFIX,allcoin.com,Proxy\nDOMAIN-SUFFIX,sexgangsters.com,Proxy\nDOMAIN-SUFFIX,khmusic.com.tw,Proxy\nDOMAIN-SUFFIX,guidaili.com,Proxy\nDOMAIN-SUFFIX,pornhubselect.com,Proxy\nDOMAIN-SUFFIX,d5055.com,Proxy\nDOMAIN-SUFFIX,ltou88.net,Proxy\nDOMAIN-SUFFIX,ngocn2.org,Proxy\nDOMAIN-SUFFIX,voyeurhit.com,Proxy\nDOMAIN-SUFFIX,video-edge-32a855.pdx01.abs.hls.ttvnw.net,Proxy\nDOMAIN-SUFFIX,family-lo.com,Proxy\nDOMAIN-SUFFIX,myxperia.sonymobile.com,Proxy\nDOMAIN-SUFFIX,nitter.ir,Proxy\nDOMAIN-SUFFIX,n6matome.blog.jp,Proxy\nDOMAIN-SUFFIX,ironna.jp,Proxy\nDOMAIN-SUFFIX,www.intralot.it,Proxy\nDOMAIN-SUFFIX,mox.moe,Proxy\nDOMAIN-SUFFIX,google.sn,Proxy\nDOMAIN-SUFFIX,amccsm.org,Proxy\nDOMAIN-SUFFIX,52youji.org,Proxy\nDOMAIN-SUFFIX,mp3gratis.us,Proxy\nDOMAIN-SUFFIX,chinalaborunion.org,Proxy\nDOMAIN-SUFFIX,time.is,Proxy\nDOMAIN-SUFFIX,guardian.co.uk,Proxy\nDOMAIN-SUFFIX,allmovie.com,Proxy\nDOMAIN-SUFFIX,raremovie.cc,Proxy\nDOMAIN-SUFFIX,eitherchoice.com,Proxy\nDOMAIN-SUFFIX,bot.nu,Proxy\nDOMAIN-SUFFIX,www.beijingpm25.com,Proxy\nDOMAIN-SUFFIX,e061.com,Proxy\nDOMAIN-SUFFIX,iloli.us,Proxy\nDOMAIN-SUFFIX,blog.udn.com,Proxy\nDOMAIN-SUFFIX,pronhub.com,Proxy\nDOMAIN-SUFFIX,maturejp.com,Proxy\nDOMAIN-SUFFIX,k7209.com,Proxy\nDOMAIN-SUFFIX,liquidvpn.com,Proxy\nDOMAIN-SUFFIX,www.blacktownsun.com.au,Proxy\nDOMAIN-SUFFIX,caspio.com,Proxy\nDOMAIN-SUFFIX,issuu.com,Proxy\nDOMAIN-SUFFIX,googleusercontent.com,Proxy\nDOMAIN-SUFFIX,twelvetribes.com,Proxy\nDOMAIN-SUFFIX,www.docverify.com,Proxy\nDOMAIN-SUFFIX,tkfoot.com,Proxy\nDOMAIN-SUFFIX,ylg40.com,Proxy\nDOMAIN-SUFFIX,yakyulive.blogspot.jp,Proxy\nDOMAIN-SUFFIX,men.com,Proxy\nDOMAIN-SUFFIX,eastasiaforum.org,Proxy\nDOMAIN-SUFFIX,www.sssis.com,Proxy\nDOMAIN-SUFFIX,brewster.kahle.org,Proxy\nDOMAIN-SUFFIX,onfastspring.com,Proxy\nDOMAIN-SUFFIX,monde-diplomatique.fr,Proxy\nDOMAIN-SUFFIX,unblocker.net,Proxy\nDOMAIN-SUFFIX,www.abclite.net,Proxy\nDOMAIN-SUFFIX,www.iviviv.com,Proxy\nDOMAIN-SUFFIX,ku18.net,Proxy\nDOMAIN-SUFFIX,americanthinker.com,Proxy\nDOMAIN-SUFFIX,gfkari.blog.jp,Proxy\nDOMAIN-SUFFIX,piratebay.org,Proxy\nDOMAIN-SUFFIX,a00788.com,Proxy\nDOMAIN-SUFFIX,www.8ssr.com,Proxy\nDOMAIN-SUFFIX,d2ttun5f2fnvfj.cloudfront.net,Proxy\nDOMAIN-SUFFIX,galaxymacau.com,Proxy\nDOMAIN-SUFFIX,commonsense.org,Proxy\nDOMAIN-SUFFIX,commonshk.com,Proxy\nDOMAIN-SUFFIX,www.tuo8.cc,Proxy\nDOMAIN-SUFFIX,freeopenvpn.com,Proxy\nDOMAIN-SUFFIX,freeoz.org,Proxy\nDOMAIN-SUFFIX,unicat.org,Proxy\nDOMAIN-SUFFIX,www.cabet222.com,Proxy\nDOMAIN-SUFFIX,gvtube.com,Proxy\nDOMAIN-SUFFIX,ntrqq.com,Proxy\nDOMAIN-SUFFIX,blogspot.com.au,Proxy\nDOMAIN-SUFFIX,falundafa-sacramento.org,Proxy\nDOMAIN-SUFFIX,blog.syx86.cn,Proxy\nDOMAIN-SUFFIX,freepanchenlama.org,Proxy\nDOMAIN-SUFFIX,hepsiburada.com,Proxy\nDOMAIN-SUFFIX,gmozomg.izihost.org,Proxy\nDOMAIN-SUFFIX,m.lt127.com,Proxy\nDOMAIN-SUFFIX,chromeenterprise.google,Proxy\nDOMAIN-SUFFIX,www.18vpn.biz,Proxy\nDOMAIN-SUFFIX,www.gongzishen.com,Proxy\nDOMAIN-SUFFIX,manporn.xxx,Proxy\nDOMAIN-SUFFIX,mule.com,Proxy\nDOMAIN-SUFFIX,bamfordwatchdepartment.com,Proxy\nDOMAIN-SUFFIX,www.chanpureland.org,Proxy\nDOMAIN-SUFFIX,38850055.com,Proxy\nDOMAIN-SUFFIX,proxybig.net,Proxy\nDOMAIN-SUFFIX,pmonradio.nic.in,Proxy\nDOMAIN-SUFFIX,www.ca295.com,Proxy\nDOMAIN-SUFFIX,ctitv.com.tw,Proxy\nDOMAIN-SUFFIX,www.2n15.com,Proxy\nDOMAIN-SUFFIX,bd182.com,Proxy\nDOMAIN-SUFFIX,www.relay.com.tw,Proxy\nDOMAIN-SUFFIX,092999111.com,Proxy\nDOMAIN-SUFFIX,danlambaovn.blogspot.hk,Proxy\nDOMAIN-SUFFIX,12vpn.com,Proxy\nDOMAIN-SUFFIX,souncloud.com,Proxy\nDOMAIN-SUFFIX,bk8r3dod.com,Proxy\nDOMAIN-SUFFIX,anchor.fm,Proxy\nDOMAIN-SUFFIX,ayurvedicherbsdirect.com,Proxy\nDOMAIN-SUFFIX,212766.com,Proxy\nDOMAIN-SUFFIX,www.vicivision.com,Proxy\nDOMAIN-SUFFIX,serrabraga.com,Proxy\nDOMAIN-SUFFIX,openwebster.com,Proxy\nDOMAIN-SUFFIX,voanews.com,Proxy\nDOMAIN-SUFFIX,hl.co.uk,Proxy\nDOMAIN-SUFFIX,project-syndicate.org,Proxy\nDOMAIN-SUFFIX,cholayil.com,Proxy\nDOMAIN-SUFFIX,talkonly.net,Proxy\nDOMAIN-SUFFIX,eroex.com,Proxy\nDOMAIN-SUFFIX,08.kik.cl,Proxy\nDOMAIN-SUFFIX,682140.com,Proxy\nDOMAIN-SUFFIX,mkxzp.com,Proxy\nDOMAIN-SUFFIX,westword.com,Proxy\nDOMAIN-SUFFIX,www.malaysianow.com,Proxy\nDOMAIN-SUFFIX,chinatimeline.github.io,Proxy\nDOMAIN-SUFFIX,av100fun.com,Proxy\nDOMAIN-SUFFIX,brazzers.com,Proxy\nDOMAIN-SUFFIX,goofind.com,Proxy\nDOMAIN-SUFFIX,as.sogo.eu.org,Proxy\nDOMAIN-SUFFIX,fc2cn.com,Proxy\nDOMAIN-SUFFIX,vpn.ht,Proxy\nDOMAIN-SUFFIX,91xag.com,Proxy\nDOMAIN-SUFFIX,pinterest.co.in,Proxy\nDOMAIN-SUFFIX,picasa.com,Proxy\nDOMAIN-SUFFIX,phncdn.com,Proxy\nDOMAIN-SUFFIX,xiaod.in,Proxy\nDOMAIN-SUFFIX,fyt579.com,Proxy\nDOMAIN-SUFFIX,lingualeo.com,Proxy\nDOMAIN-SUFFIX,amnestyusa.org,Proxy\nDOMAIN-SUFFIX,www.shibo8888.com,Proxy\nDOMAIN-SUFFIX,vless.flashcs6.eu.org,Proxy\nDOMAIN-SUFFIX,91vpn.com,Proxy\nDOMAIN-SUFFIX,mylftv.com,Proxy\nDOMAIN-SUFFIX,songyyy.xyz,Proxy\nDOMAIN-SUFFIX,www.lyjhc.com,Proxy\nDOMAIN-SUFFIX,mondomedia.com,Proxy\nDOMAIN-SUFFIX,www.recovery.org.tw,Proxy\nDOMAIN-SUFFIX,bbcnews.co.uk,Proxy\nDOMAIN-SUFFIX,eddimer.blogspot.ca,Proxy\nDOMAIN-SUFFIX,riviere.cat,Proxy\nDOMAIN-SUFFIX,usvpn.com,Proxy\nDOMAIN-SUFFIX,18mcy.com,Proxy\nDOMAIN-SUFFIX,twaitter.com,Proxy\nDOMAIN-SUFFIX,greyling.org.za,Proxy\nDOMAIN-SUFFIX,www.wuaitao.org,Proxy\nDOMAIN-SUFFIX,mystartsearch.com,Proxy\nDOMAIN-SUFFIX,blog.sina.com.tw,Proxy\nDOMAIN-SUFFIX,soundofhope.org,Proxy\nDOMAIN-SUFFIX,www.sexyvideos.co,Proxy\nDOMAIN-SUFFIX,hi-on.org.tw,Proxy\nDOMAIN-SUFFIX,dipity.com,Proxy\nDOMAIN-SUFFIX,gatecoin.com,Proxy\nDOMAIN-SUFFIX,fishome.tw,Proxy\nDOMAIN-SUFFIX,pw.fiddlefish.net,Proxy\nDOMAIN-SUFFIX,163.slyip.net,Proxy\nDOMAIN-SUFFIX,www.sweetim.com,Proxy\nDOMAIN-SUFFIX,boy104.com,Proxy\nDOMAIN-SUFFIX,scientology.org.tw,Proxy\nDOMAIN-SUFFIX,markets.com.cn,Proxy\nDOMAIN-SUFFIX,srsman.com,Proxy\nDOMAIN-SUFFIX,autoimpuls.ro,Proxy\nDOMAIN-SUFFIX,new.ltshk.net,Proxy\nDOMAIN-SUFFIX,xerotica.com,Proxy\nDOMAIN-SUFFIX,tartsandcrafts.ca,Proxy\nDOMAIN-SUFFIX,jh5.ballbet4.com,Proxy\nDOMAIN-SUFFIX,www.maniaj.com,Proxy\nDOMAIN-SUFFIX,horrorporn.com,Proxy\nDOMAIN-SUFFIX,www.608411.com,Proxy\nDOMAIN-SUFFIX,yourube.com,Proxy\nDOMAIN-SUFFIX,vpnbrowse.com,Proxy\nDOMAIN-SUFFIX,line36.ga,Proxy\nDOMAIN-SUFFIX,www.richards-realm.com,Proxy\nDOMAIN-SUFFIX,321youtube.com,Proxy\nDOMAIN-SUFFIX,bnext.com.tw,Proxy\nDOMAIN-SUFFIX,www.flynnscoaches.com,Proxy\nDOMAIN-SUFFIX,www.betway88.com,Proxy\nDOMAIN-SUFFIX,thomsonreuters.com,Proxy\nDOMAIN-SUFFIX,dot.b0ne.com,Proxy\nDOMAIN-SUFFIX,sscube5.com,Proxy\nDOMAIN-SUFFIX,kujsq.com,Proxy\nDOMAIN-SUFFIX,www.ets.edu.hk,Proxy\nDOMAIN-SUFFIX,qianbai.tw,Proxy\nDOMAIN-SUFFIX,jjcbdccq.com,Proxy\nDOMAIN-SUFFIX,cotweet.com,Proxy\nDOMAIN-SUFFIX,pornfun.com,Proxy\nDOMAIN-SUFFIX,25573333.com,Proxy\nDOMAIN-SUFFIX,madouse.la,Proxy\nDOMAIN-SUFFIX,www.7g.tv,Proxy\nDOMAIN-SUFFIX,elashi.ca,Proxy\nDOMAIN-SUFFIX,rfi.fr,Proxy\nDOMAIN-SUFFIX,weiimg.clsj365.com,Proxy\nDOMAIN-SUFFIX,www.novoerotica.com,Proxy\nDOMAIN-SUFFIX,shaogood.com,Proxy\nDOMAIN-SUFFIX,raizoji.or.jp,Proxy\nDOMAIN-SUFFIX,cmmnts.com,Proxy\nDOMAIN-SUFFIX,c2mt.blogspot.hk,Proxy\nDOMAIN-SUFFIX,hiveminds.net,Proxy\nDOMAIN-SUFFIX,www.ivideo6630.0fees.us,Proxy\nDOMAIN-SUFFIX,wwitv.com,Proxy\nDOMAIN-SUFFIX,chordboard.com,Proxy\nDOMAIN-SUFFIX,www.sf590.com,Proxy\nDOMAIN-SUFFIX,yh22305.com,Proxy\nDOMAIN-SUFFIX,www.hentaimg.com,Proxy\nDOMAIN-SUFFIX,www.proxyeye.com,Proxy\nDOMAIN-SUFFIX,winandmac.com,Proxy\nDOMAIN-SUFFIX,wordstream.com,Proxy\nDOMAIN-SUFFIX,gkav.net,Proxy\nDOMAIN-SUFFIX,weareunited.com.my,Proxy\nDOMAIN-SUFFIX,socloud.fun,Proxy\nDOMAIN-SUFFIX,internationalviewpoint.org,Proxy\nDOMAIN-SUFFIX,newsweek.com,Proxy\nDOMAIN-SUFFIX,www.jct.org.tw,Proxy\nDOMAIN-SUFFIX,cn.giganews.com,Proxy\nDOMAIN-SUFFIX,20058822.com,Proxy\nDOMAIN-SUFFIX,video.foxbusiness.com,Proxy\nDOMAIN-SUFFIX,network54.com,Proxy\nDOMAIN-SUFFIX,thetvdb.com,Proxy\nDOMAIN-SUFFIX,newsnetwork.tv,Proxy\nDOMAIN-SUFFIX,www.sacred-texts.com,Proxy\nDOMAIN-SUFFIX,joe.slyip.net,Proxy\nDOMAIN-SUFFIX,gjfanzha.ga,Proxy\nDOMAIN-SUFFIX,ss.arily.moe,Proxy\nDOMAIN-SUFFIX,salvation.org.hk,Proxy\nDOMAIN-SUFFIX,778833333.com,Proxy\nDOMAIN-SUFFIX,agnitio.com.ar,Proxy\nDOMAIN-SUFFIX,www.crsna2015.tk,Proxy\nDOMAIN-SUFFIX,sg1lib.org,Proxy\nDOMAIN-SUFFIX,unir.net,Proxy\nDOMAIN-SUFFIX,freeoneslive.nl,Proxy\nDOMAIN-SUFFIX,openloadmovie.me,Proxy\nDOMAIN-SUFFIX,utopia.cool,Proxy\nDOMAIN-SUFFIX,franceculture.fr,Proxy\nDOMAIN-SUFFIX,www.znaturalfoods.com,Proxy\nDOMAIN-SUFFIX,b16.com,Proxy\nDOMAIN-SUFFIX,www.kchld.com,Proxy\nDOMAIN-SUFFIX,www.gugesou.com,Proxy\nDOMAIN-SUFFIX,xxmap1.site,Proxy\nDOMAIN-SUFFIX,csdc1111.com,Proxy\nDOMAIN-SUFFIX,ent.appledaily.com.tw,Proxy\nDOMAIN-SUFFIX,periscope.tv,Proxy\nDOMAIN-SUFFIX,835rrr.net,Proxy\nDOMAIN-SUFFIX,naacoalition.org,Proxy\nDOMAIN-SUFFIX,littledengsubs.org,Proxy\nDOMAIN-SUFFIX,69school.com,Proxy\nDOMAIN-SUFFIX,newca.org,Proxy\nDOMAIN-SUFFIX,www.interactivebrokers.com.hk,Proxy\nDOMAIN-SUFFIX,www.vw689.com,Proxy\nDOMAIN-SUFFIX,inoa.cl,Proxy\nDOMAIN-SUFFIX,www.xinsheng.net,Proxy\nDOMAIN-SUFFIX,ows2.cat.flnet.org,Proxy\nDOMAIN-SUFFIX,www.pandavpn-jp.com,Proxy\nDOMAIN-SUFFIX,en.boxun.com,Proxy\nDOMAIN-SUFFIX,jinsha88088.com,Proxy\nDOMAIN-SUFFIX,sipgate.com,Proxy\nDOMAIN-SUFFIX,bigly.us,Proxy\nDOMAIN-SUFFIX,zgsddh.com,Proxy\nDOMAIN-SUFFIX,redditlist.com,Proxy\nDOMAIN-SUFFIX,flvpn.com,Proxy\nDOMAIN-SUFFIX,webdesignledger.com,Proxy\nDOMAIN-SUFFIX,newsweekjapan.jp,Proxy\nDOMAIN-SUFFIX,www.elatec.com,Proxy\nDOMAIN-SUFFIX,securevpn.com,Proxy\nDOMAIN-SUFFIX,mario-lopes.pt,Proxy\nDOMAIN-SUFFIX,watchpeopledie.tv,Proxy\nDOMAIN-SUFFIX,beijingspring.com,Proxy\nDOMAIN-SUFFIX,www.1point3acres.com,Proxy\nDOMAIN-SUFFIX,rapid-search-engine.com,Proxy\nDOMAIN-SUFFIX,dedelu.com,Proxy\nDOMAIN-SUFFIX,firstcalgary.com,Proxy\nDOMAIN-SUFFIX,machines.asia,Proxy\nDOMAIN-SUFFIX,www.xh033.com,Proxy\nDOMAIN-SUFFIX,www.pchomeskype.com.tw,Proxy\nDOMAIN-SUFFIX,726.com,Proxy\nDOMAIN-SUFFIX,ige.es,Proxy\nDOMAIN-SUFFIX,bangdream.space,Proxy\nDOMAIN-SUFFIX,18comic.live,Proxy\nDOMAIN-SUFFIX,autodata.net,Proxy\nDOMAIN-SUFFIX,www.nagmarketschn.com,Proxy\nDOMAIN-SUFFIX,sandcherry.ca,Proxy\nDOMAIN-SUFFIX,myforum.com.uk,Proxy\nDOMAIN-SUFFIX,www.candysoft.jp,Proxy\nDOMAIN-SUFFIX,showlive-api.com,Proxy\nDOMAIN-SUFFIX,nztd.me,Proxy\nDOMAIN-SUFFIX,us-central1-invue-live.cloudfunctions.net,Proxy\nDOMAIN-SUFFIX,www.zimuku.cn,Proxy\nDOMAIN-SUFFIX,falundafa.org.hk,Proxy\nDOMAIN-SUFFIX,doh.eastus.pi-dns.com,Proxy\nDOMAIN-SUFFIX,sunvpn.net,Proxy\nDOMAIN-SUFFIX,ifreewares.com,Proxy\nDOMAIN-SUFFIX,tenacy.link,Proxy\nDOMAIN-SUFFIX,veporns.com,Proxy\nDOMAIN-SUFFIX,for-some.biz,Proxy\nDOMAIN-SUFFIX,www.boma365.net,Proxy\nDOMAIN-SUFFIX,www.thewirechina.com,Proxy\nDOMAIN-SUFFIX,1507999.com,Proxy\nDOMAIN-SUFFIX,volunteerminister.org,Proxy\nDOMAIN-SUFFIX,androidvpn.com,Proxy\nDOMAIN-SUFFIX,tintucntdtv.com,Proxy\nDOMAIN-SUFFIX,bcex.ca,Proxy\nDOMAIN-SUFFIX,taiwanbible.com,Proxy\nDOMAIN-SUFFIX,zh.hotels.com,Proxy\nDOMAIN-SUFFIX,www.ballbustingtube.com,Proxy\nDOMAIN-SUFFIX,0235mm.com,Proxy\nDOMAIN-SUFFIX,c-spanvideo.org,Proxy\nDOMAIN-SUFFIX,www.bm502.cc,Proxy\nDOMAIN-SUFFIX,moby.to,Proxy\nDOMAIN-SUFFIX,www.xfree.com,Proxy\nDOMAIN-SUFFIX,smarthide.com,Proxy\nDOMAIN-SUFFIX,gif-porn.net,Proxy\nDOMAIN-SUFFIX,www.sremskenovine.co.rs,Proxy\nDOMAIN-SUFFIX,assisass.com,Proxy\nDOMAIN-SUFFIX,yes24.com,Proxy\nDOMAIN-SUFFIX,minergate.com,Proxy\nDOMAIN-SUFFIX,www.noacsc.org,Proxy\nDOMAIN-SUFFIX,www.sanshinji.org,Proxy\nDOMAIN-SUFFIX,chickenbarrel.org,Proxy\nDOMAIN-SUFFIX,www.fun307.com,Proxy\nDOMAIN-SUFFIX,i1.hk,Proxy\nDOMAIN-SUFFIX,rebrand.ly,Proxy\nDOMAIN-SUFFIX,www.yddc788.com,Proxy\nDOMAIN-SUFFIX,tor-exit-40.for-privacy.net,Proxy\nDOMAIN-SUFFIX,ikwb.com,Proxy\nDOMAIN-SUFFIX,karkhung.cn,Proxy\nDOMAIN-SUFFIX,yaledailynews.com,Proxy\nDOMAIN-SUFFIX,pinterest.jp,Proxy\nDOMAIN-SUFFIX,tlc88uk.co.uk,Proxy\nDOMAIN-SUFFIX,3332.gq,Proxy\nDOMAIN-SUFFIX,api.pncle8.com,Proxy\nDOMAIN-SUFFIX,mihr.com,Proxy\nDOMAIN-SUFFIX,pritunl.com,Proxy\nDOMAIN-SUFFIX,dyndns-mail.com,Proxy\nDOMAIN-SUFFIX,ingtv.co,Proxy\nDOMAIN-SUFFIX,dbgjd.com,Proxy\nDOMAIN-SUFFIX,adxpansion.com,Proxy\nDOMAIN-SUFFIX,fuhuiasia.com,Proxy\nDOMAIN-SUFFIX,oiktv.com,Proxy\nDOMAIN-SUFFIX,thestandnews.com,Proxy\nDOMAIN-SUFFIX,linkideo.com,Proxy\nDOMAIN-SUFFIX,conco.ca,Proxy\nDOMAIN-SUFFIX,enanyang.my,Proxy\nDOMAIN-SUFFIX,www.saloncs.com,Proxy\nDOMAIN-SUFFIX,d2zfqthxsdq309.cloudfront.net,Proxy\nDOMAIN-SUFFIX,3proxy.de,Proxy\nDOMAIN-SUFFIX,niconode.net,Proxy\nDOMAIN-SUFFIX,dje3ss5qxbw5k.cloudfront.net,Proxy\nDOMAIN-SUFFIX,mysistershotfriend.com,Proxy\nDOMAIN-SUFFIX,www.webrush.net,Proxy\nDOMAIN-SUFFIX,foxsports.com.au,Proxy\nDOMAIN-SUFFIX,skyoyue.com,Proxy\nDOMAIN-SUFFIX,d1ec920sj2hill.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.ecocn.org,Proxy\nDOMAIN-SUFFIX,www.puffss.me,Proxy\nDOMAIN-SUFFIX,www.ldzhibo999.pro,Proxy\nDOMAIN-SUFFIX,nitter.hu,Proxy\nDOMAIN-SUFFIX,realcourage.org,Proxy\nDOMAIN-SUFFIX,torrentz2.eu,Proxy\nDOMAIN-SUFFIX,asxhulcw.azureedge.net,Proxy\nDOMAIN-SUFFIX,h.mon33.us,Proxy\nDOMAIN-SUFFIX,ourtv.hk,Proxy\nDOMAIN-SUFFIX,zorrovpn.com,Proxy\nDOMAIN-SUFFIX,spencertipping.com,Proxy\nDOMAIN-SUFFIX,800c.xyz,Proxy\nDOMAIN-SUFFIX,maggiebears.com,Proxy\nDOMAIN-SUFFIX,www.wallsttv.com,Proxy\nDOMAIN-SUFFIX,telegramindex.com,Proxy\nDOMAIN-SUFFIX,8587x.cc,Proxy\nDOMAIN-SUFFIX,commentshk.com,Proxy\nDOMAIN-SUFFIX,assistenzetecniche.it,Proxy\nDOMAIN-SUFFIX,nytsyn.com,Proxy\nDOMAIN-SUFFIX,greenmetis.com,Proxy\nDOMAIN-SUFFIX,ssh91.com,Proxy\nDOMAIN-SUFFIX,lt012.com,Proxy\nDOMAIN-SUFFIX,v2ex.com,Proxy\nDOMAIN-SUFFIX,demosystems-assets.cdn-apple.com,Proxy\nDOMAIN-SUFFIX,blacklogic.com,Proxy\nDOMAIN-SUFFIX,shemale-porn-galls.com,Proxy\nDOMAIN-SUFFIX,yzvpn.com,Proxy\nDOMAIN-SUFFIX,2captcha.com,Proxy\nDOMAIN-SUFFIX,ke2.fengherili.cc,Proxy\nDOMAIN-SUFFIX,alice.xfu.jp,Proxy\nDOMAIN-SUFFIX,tabletmag.com,Proxy\nDOMAIN-SUFFIX,thehousenewsbloggers.net,Proxy\nDOMAIN-SUFFIX,www.cwbook.com.tw,Proxy\nDOMAIN-SUFFIX,www.world-sci.com,Proxy\nDOMAIN-SUFFIX,gbgb.eu,Proxy\nDOMAIN-SUFFIX,uuvpn.com,Proxy\nDOMAIN-SUFFIX,afr.com.au,Proxy\nDOMAIN-SUFFIX,anonproxy.eu,Proxy\nDOMAIN-SUFFIX,unpkg.com,Proxy\nDOMAIN-SUFFIX,blofficial.com,Proxy\nDOMAIN-SUFFIX,srm-files.s3.ap-southeast-2.amazonaws.com,Proxy\nDOMAIN-SUFFIX,d2ptlmbtufy2u3.cloudfront.net,Proxy\nDOMAIN-SUFFIX,s.ytimg.com,Proxy\nDOMAIN-SUFFIX,reading.udn.com,Proxy\nDOMAIN-SUFFIX,tianti.io,Proxy\nDOMAIN-SUFFIX,vipviasila.com,Proxy\nDOMAIN-SUFFIX,magic-net.info,Proxy\nDOMAIN-SUFFIX,hengjing.org,Proxy\nDOMAIN-SUFFIX,669a.tv,Proxy\nDOMAIN-SUFFIX,dnsfree.xyz,Proxy\nDOMAIN-SUFFIX,dkqodo9uwue0p.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.jbo05.com,Proxy\nDOMAIN-SUFFIX,12345proxy.org,Proxy\nDOMAIN-SUFFIX,qqmemberships.serveuser.com,Proxy\nDOMAIN-SUFFIX,www.bwtiyu.com,Proxy\nDOMAIN-SUFFIX,gotrusted.com,Proxy\nDOMAIN-SUFFIX,proxy4free.me,Proxy\nDOMAIN-SUFFIX,www.frontpagetech.com,Proxy\nDOMAIN-SUFFIX,btsow.work,Proxy\nDOMAIN-SUFFIX,wingolds.com,Proxy\nDOMAIN-SUFFIX,v9639.com,Proxy\nDOMAIN-SUFFIX,email.decisal.com,Proxy\nDOMAIN-SUFFIX,www.privatecams.com,Proxy\nDOMAIN-SUFFIX,www.6396f.com,Proxy\nDOMAIN-SUFFIX,www.mishalov.com,Proxy\nDOMAIN-SUFFIX,winkdex.com,Proxy\nDOMAIN-SUFFIX,saifeng3.com,Proxy\nDOMAIN-SUFFIX,www.ihktv.com,Proxy\nDOMAIN-SUFFIX,guangnianvpn.com,Proxy\nDOMAIN-SUFFIX,udndata.com,Proxy\nDOMAIN-SUFFIX,jmcomic3.me,Proxy\nDOMAIN-SUFFIX,baid.ws,Proxy\nDOMAIN-SUFFIX,www.kochinews.co.jp,Proxy\nDOMAIN-SUFFIX,d25q7jt91m0aw8.cloudfront.net,Proxy\nDOMAIN-SUFFIX,aliyahdewi.com,Proxy\nDOMAIN-SUFFIX,studentsforafreetibet.org,Proxy\nDOMAIN-SUFFIX,www.conceptdoppler.org,Proxy\nDOMAIN-SUFFIX,hy1.com,Proxy\nDOMAIN-SUFFIX,www.f88vip111.com,Proxy\nDOMAIN-SUFFIX,on.cx,Proxy\nDOMAIN-SUFFIX,www.100ke.org,Proxy\nDOMAIN-SUFFIX,www.psiphonapkdownload.net,Proxy\nDOMAIN-SUFFIX,tastethedream.com,Proxy\nDOMAIN-SUFFIX,breached.vc,Proxy\nDOMAIN-SUFFIX,gt7h.fat.flnet.org,Proxy\nDOMAIN-SUFFIX,giantessnight.com,Proxy\nDOMAIN-SUFFIX,www.26fun.com,Proxy\nDOMAIN-SUFFIX,www.helium.com,Proxy\nDOMAIN-SUFFIX,fucd.com,Proxy\nDOMAIN-SUFFIX,sleazydream.com,Proxy\nDOMAIN-SUFFIX,vanaja.com.au,Proxy\nDOMAIN-SUFFIX,starfares.com,Proxy\nDOMAIN-SUFFIX,guaihan.com,Proxy\nDOMAIN-SUFFIX,m879.com,Proxy\nDOMAIN-SUFFIX,doh.lv,Proxy\nDOMAIN-SUFFIX,thefoss.net,Proxy\nDOMAIN-SUFFIX,www.madaili.com,Proxy\nDOMAIN-SUFFIX,porntubeparty.com,Proxy\nDOMAIN-SUFFIX,ivyseeds.cf,Proxy\nDOMAIN-SUFFIX,fun530.com,Proxy\nDOMAIN-SUFFIX,crocotube.com,Proxy\nDOMAIN-SUFFIX,gum.co,Proxy\nDOMAIN-SUFFIX,ca.ms.justdied.com,Proxy\nDOMAIN-SUFFIX,totalvpn.com,Proxy\nDOMAIN-SUFFIX,catbox.moe,Proxy\nDOMAIN-SUFFIX,visiontimes.com,Proxy\nDOMAIN-SUFFIX,tubecup.com,Proxy\nDOMAIN-SUFFIX,newfinex.com,Proxy\nDOMAIN-SUFFIX,www.1234.com,Proxy\nDOMAIN-SUFFIX,www.apkleecher.com,Proxy\nDOMAIN-SUFFIX,cnys.tv,Proxy\nDOMAIN-SUFFIX,mycould.com,Proxy\nDOMAIN-SUFFIX,sync2it.com,Proxy\nDOMAIN-SUFFIX,mzl.la,Proxy\nDOMAIN-SUFFIX,moticonci.com,Proxy\nDOMAIN-SUFFIX,nhentai.net,Proxy\nDOMAIN-SUFFIX,25.qc.to,Proxy\nDOMAIN-SUFFIX,javme.me,Proxy\nDOMAIN-SUFFIX,www.freeukvpn.com,Proxy\nDOMAIN-SUFFIX,open.com.hk,Proxy\nDOMAIN-SUFFIX,www.bw888555.com,Proxy\nDOMAIN-SUFFIX,www.palgrave.com,Proxy\nDOMAIN-SUFFIX,www.prestige-av.com,Proxy\nDOMAIN-SUFFIX,you.com,Proxy\nDOMAIN-SUFFIX,tribit-field.jp,Proxy\nDOMAIN-SUFFIX,twibble.de,Proxy\nDOMAIN-SUFFIX,gmail.roche.com,Proxy\nDOMAIN-SUFFIX,chinatibettrain.com,Proxy\nDOMAIN-SUFFIX,translate.google.se,Proxy\nDOMAIN-SUFFIX,tibetansports.org,Proxy\nDOMAIN-SUFFIX,falundafa.at,Proxy\nDOMAIN-SUFFIX,d22if0ngl5too8.cloudfront.net,Proxy\nDOMAIN-SUFFIX,inv.vern.cc,Proxy\nDOMAIN-SUFFIX,twcnn.net,Proxy\nDOMAIN-SUFFIX,freechinamovie.com,Proxy\nDOMAIN-SUFFIX,hotgirl.biz,Proxy\nDOMAIN-SUFFIX,ihao.org,Proxy\nDOMAIN-KEYWORD,ultrasurf,Proxy\nDOMAIN-SUFFIX,goo.gl,Proxy\nDOMAIN-SUFFIX,kagyu.org.nz,Proxy\nDOMAIN-SUFFIX,google.rw,Proxy\nDOMAIN-SUFFIX,ipfs.io,Proxy\nDOMAIN-SUFFIX,bakgeekhome.tk,Proxy\nDOMAIN-SUFFIX,lightss.xyz,Proxy\nDOMAIN-SUFFIX,indastro.com,Proxy\nDOMAIN-SUFFIX,quitccp.com,Proxy\nDOMAIN-SUFFIX,www.wailaike.net,Proxy\nDOMAIN-SUFFIX,logos.com.hk,Proxy\nDOMAIN-SUFFIX,sunmedia.ca,Proxy\nDOMAIN-SUFFIX,99kjy.com,Proxy\nDOMAIN-SUFFIX,webs-tv.net,Proxy\nDOMAIN-SUFFIX,851facebook.com,Proxy\nDOMAIN-SUFFIX,subito.it,Proxy\nDOMAIN-SUFFIX,iphonehacks.com,Proxy\nDOMAIN-SUFFIX,cdn-telegram.org,Proxy\nDOMAIN-SUFFIX,goldstep.net,Proxy\nDOMAIN-SUFFIX,www.hentaifox.com,Proxy\nDOMAIN-SUFFIX,viatun.com,Proxy\nDOMAIN-SUFFIX,joinmastodon.org,Proxy\nDOMAIN-SUFFIX,boxun2.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,downloads.sourceforge.net,Proxy\nDOMAIN-SUFFIX,sousebar7.xyz,Proxy\nDOMAIN-SUFFIX,www.aaadream.com,Proxy\nDOMAIN-SUFFIX,www.svipshowlive.xyz,Proxy\nDOMAIN-SUFFIX,dcwg.org,Proxy\nDOMAIN-SUFFIX,www.betvictor52.com,Proxy\nDOMAIN-SUFFIX,vpnaccount.com,Proxy\nDOMAIN-SUFFIX,www.buzzsprout.com,Proxy\nDOMAIN-SUFFIX,lh3.ggpht.com,Proxy\nDOMAIN-SUFFIX,yy.etowns.net,Proxy\nDOMAIN-SUFFIX,savestation.de,Proxy\nDOMAIN-SUFFIX,participants.allianceabroad.com,Proxy\nDOMAIN-SUFFIX,nytalk.net,Proxy\nDOMAIN-SUFFIX,jojoxtv.com,Proxy\nDOMAIN-SUFFIX,www.yupmedia.com,Proxy\nDOMAIN-SUFFIX,tapanwap.com,Proxy\nDOMAIN-SUFFIX,scache.vzw.com,Proxy\nDOMAIN-SUFFIX,www.7dias.com.do,Proxy\nDOMAIN-SUFFIX,le19.net,Proxy\nDOMAIN-SUFFIX,hzsmails.org,Proxy\nDOMAIN-SUFFIX,www.vip1577.com,Proxy\nDOMAIN-SUFFIX,www.toutou128.com,Proxy\nDOMAIN-SUFFIX,tx2.travian.tw,Proxy\nDOMAIN-SUFFIX,friendsoftibet.org,Proxy\nDOMAIN-SUFFIX,zzx.dnsdyn.xyz,Proxy\nDOMAIN-SUFFIX,dns2go.com,Proxy\nDOMAIN-SUFFIX,aaex.uk,Proxy\nDOMAIN-SUFFIX,www.domaintoday.com.au,Proxy\nDOMAIN-SUFFIX,bjzc.org,Proxy\nDOMAIN-SUFFIX,poopeegirls.com,Proxy\nDOMAIN-SUFFIX,d2nnie5ujgntpx.cloudfront.net,Proxy\nDOMAIN-SUFFIX,latino.foxnews.com,Proxy\nDOMAIN-SUFFIX,shan9.x24hr.com,Proxy\nDOMAIN-SUFFIX,royalty7.com,Proxy\nDOMAIN-SUFFIX,gurushree.com,Proxy\nDOMAIN-SUFFIX,lionsroar.com,Proxy\nDOMAIN-SUFFIX,nytchina.com,Proxy\nDOMAIN-SUFFIX,bbcworldnews.com,Proxy\nDOMAIN-SUFFIX,hentaivideoworld.com,Proxy\nDOMAIN-SUFFIX,geph.io,Proxy\nDOMAIN-SUFFIX,crypto.com,Proxy\nDOMAIN-SUFFIX,www.eximbank.com.tw,Proxy\nDOMAIN-SUFFIX,vw088.com,Proxy\nDOMAIN-SUFFIX,freechina.net,Proxy\nDOMAIN-SUFFIX,www.agemys.vip,Proxy\nDOMAIN-SUFFIX,1lib.ph,Proxy\nDOMAIN-SUFFIX,ability.kir.jp,Proxy\nDOMAIN-SUFFIX,yzc577.com,Proxy\nDOMAIN-SUFFIX,gooddns.xyz,Proxy\nDOMAIN-SUFFIX,slideshare.net,Proxy\nDOMAIN-SUFFIX,lionfree.net,Proxy\nDOMAIN-SUFFIX,www.iblogs.com,Proxy\nDOMAIN-SUFFIX,www.google.se,Proxy\nDOMAIN-SUFFIX,api.meomiao.me,Proxy\nDOMAIN-SUFFIX,dowei.org,Proxy\nDOMAIN-SUFFIX,epidemiology.education.nl,Proxy\nDOMAIN-SUFFIX,wdvpn.com,Proxy\nDOMAIN-SUFFIX,feitian.edu,Proxy\nDOMAIN-SUFFIX,azhar.edu.eg,Proxy\nDOMAIN-SUFFIX,www.s4miniarchive.com,Proxy\nDOMAIN-SUFFIX,zombags.com,Proxy\nDOMAIN-SUFFIX,terminaldirect.com,Proxy\nDOMAIN-SUFFIX,aikeji.tk,Proxy\nDOMAIN-SUFFIX,onehallyu.com,Proxy\nDOMAIN-SUFFIX,00899f.com,Proxy\nDOMAIN-SUFFIX,vpngate.jp,Proxy\nDOMAIN-SUFFIX,www.tubemales.com,Proxy\nDOMAIN-SUFFIX,annatam.com,Proxy\nDOMAIN-SUFFIX,hjdc02.com,Proxy\nDOMAIN-SUFFIX,nextbigfuture.com,Proxy\nDOMAIN-SUFFIX,tibettelegraph.com,Proxy\nDOMAIN-SUFFIX,startpage.com,Proxy\nDOMAIN-SUFFIX,www.aifo.it,Proxy\nDOMAIN-SUFFIX,bk.cylab.org,Proxy\nDOMAIN-SUFFIX,defence.pk,Proxy\nDOMAIN-SUFFIX,porn5f4.xyz,Proxy\nDOMAIN-SUFFIX,mail.calipercorp.com,Proxy\nDOMAIN-SUFFIX,getiton.com,Proxy\nDOMAIN-SUFFIX,p2532.com,Proxy\nDOMAIN-SUFFIX,ksks.4irc.com,Proxy\nDOMAIN-SUFFIX,sitenable.org,Proxy\nDOMAIN-SUFFIX,www.gamesofdesire.com,Proxy\nDOMAIN-SUFFIX,elektroda.pl,Proxy\nDOMAIN-SUFFIX,williamlong.spaces.live.com,Proxy\nDOMAIN-SUFFIX,zh.bangumi.wikia.com,Proxy\nDOMAIN-SUFFIX,saintmail.st-andrews.ac.uk,Proxy\nDOMAIN-SUFFIX,epochtimes.it,Proxy\nDOMAIN-SUFFIX,ns02.gq,Proxy\nDOMAIN-SUFFIX,pascual.nz,Proxy\nDOMAIN-SUFFIX,www.shukousha.com,Proxy\nDOMAIN-SUFFIX,band.us,Proxy\nDOMAIN-SUFFIX,21.etowns.net,Proxy\nDOMAIN-SUFFIX,facesofnyfw.com,Proxy\nDOMAIN-SUFFIX,searchengineland.com,Proxy\nDOMAIN-SUFFIX,1inch.io,Proxy\nDOMAIN-SUFFIX,staridol.net,Proxy\nDOMAIN-SUFFIX,www.cpc.com.tw,Proxy\nDOMAIN-SUFFIX,pad.flnet.org,Proxy\nDOMAIN-SUFFIX,www.hau.edu.ph,Proxy\nDOMAIN-SUFFIX,luke54.org,Proxy\nDOMAIN-SUFFIX,escortguide.co.uk,Proxy\nDOMAIN-SUFFIX,www.hm61881.vip,Proxy\nDOMAIN-SUFFIX,extras.gr,Proxy\nDOMAIN-SUFFIX,www.landeng-appss.com,Proxy\nDOMAIN-SUFFIX,www.hotfrog.com.tw,Proxy\nDOMAIN-SUFFIX,soaps.sheknows.com,Proxy\nDOMAIN-SUFFIX,clgperformance.com,Proxy\nDOMAIN-SUFFIX,bbc5.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,ton.twimg.com,Proxy\nDOMAIN-SUFFIX,himalayanglacier.com,Proxy\nDOMAIN-SUFFIX,republicworld.com,Proxy\nDOMAIN-SUFFIX,www.openlife.com.hk,Proxy\nDOMAIN-SUFFIX,hk-wesi1.xyz,Proxy\nDOMAIN-SUFFIX,anonymouse.org,Proxy\nDOMAIN-SUFFIX,4040.idv.tw,Proxy\nDOMAIN-SUFFIX,youpai.org,Proxy\nDOMAIN-SUFFIX,kk.etowns.net,Proxy\nDOMAIN-SUFFIX,teddysun.com,Proxy\nDOMAIN-SUFFIX,home.sina.com,Proxy\nDOMAIN-SUFFIX,pu6611.com,Proxy\nDOMAIN-SUFFIX,prideplay.com,Proxy\nDOMAIN-SUFFIX,vmdkhosting.com,Proxy\nDOMAIN-SUFFIX,trinita.tv,Proxy\nDOMAIN-SUFFIX,dansmovies.com,Proxy\nDOMAIN-SUFFIX,hbvpn.com,Proxy\nDOMAIN-SUFFIX,porn300.com,Proxy\nDOMAIN-SUFFIX,download-pdf-ebooks.in,Proxy\nDOMAIN-SUFFIX,hex.win,Proxy\nDOMAIN-SUFFIX,rf599.com,Proxy\nDOMAIN-SUFFIX,asiantolick.com,Proxy\nDOMAIN-SUFFIX,www01.ktzhk.com,Proxy\nDOMAIN-SUFFIX,gooogle.com,Proxy\nDOMAIN-SUFFIX,routledge.com,Proxy\nDOMAIN-SUFFIX,jzvpn.com,Proxy\nDOMAIN-SUFFIX,profibux.com,Proxy\nDOMAIN-SUFFIX,jigglegifs.com,Proxy\nDOMAIN-SUFFIX,wangruoshui.net,Proxy\nDOMAIN-SUFFIX,fk-book.com,Proxy\nDOMAIN-SUFFIX,hk6.com,Proxy\nDOMAIN-SUFFIX,youtubefreeproxy.com,Proxy\nDOMAIN-SUFFIX,fooooo.com,Proxy\nDOMAIN-SUFFIX,tnpsc.gov.in,Proxy\nDOMAIN-SUFFIX,go.slyip.net,Proxy\nDOMAIN-SUFFIX,75.qc.to,Proxy\nDOMAIN-SUFFIX,youtube.com,Proxy\nDOMAIN-SUFFIX,willw.net,Proxy\nDOMAIN-SUFFIX,anyi8.com,Proxy\nDOMAIN-SUFFIX,xiao776.com,Proxy\nDOMAIN-SUFFIX,chengmingmag.com,Proxy\nDOMAIN-SUFFIX,www.kadokawagakugei.com,Proxy\nDOMAIN-SUFFIX,vf.domain888.pw,Proxy\nDOMAIN-SUFFIX,www.victorharbortimes.com.au,Proxy\nDOMAIN-SUFFIX,www.vpn4tw.com,Proxy\nDOMAIN-SUFFIX,www.aurora-pro.com,Proxy\nDOMAIN-SUFFIX,imagination.cf,Proxy\nDOMAIN-SUFFIX,weiki.esu.zone,Proxy\nDOMAIN-SUFFIX,www.if.ufrj.br,Proxy\nDOMAIN-SUFFIX,yasni.co.uk,Proxy\nDOMAIN-SUFFIX,fembed.com,Proxy\nDOMAIN-SUFFIX,d1bnedp0b8ur13.cloudfront.net,Proxy\nDOMAIN-SUFFIX,vwin000.com,Proxy\nDOMAIN-SUFFIX,rf1616.com,Proxy\nDOMAIN-SUFFIX,qbaby.one,Proxy\nDOMAIN-SUFFIX,madebony.com,Proxy\nDOMAIN-SUFFIX,kissjav.com,Proxy\nDOMAIN-SUFFIX,passion.com,Proxy\nDOMAIN-SUFFIX,www.55cc.cc,Proxy\nDOMAIN-SUFFIX,v-learn.cna.com.tw,Proxy\nDOMAIN-SUFFIX,waybackmachine.org,Proxy\nDOMAIN-SUFFIX,japanfirst.asianfreeforum.com,Proxy\nDOMAIN-SUFFIX,www.rrys2020.com,Proxy\nDOMAIN-SUFFIX,www.74ti9pa9.com,Proxy\nDOMAIN-SUFFIX,web3.ga,Proxy\nDOMAIN-SUFFIX,red5.co.uk,Proxy\nDOMAIN-SUFFIX,nowlink.xyz,Proxy\nDOMAIN-SUFFIX,backchina.com,Proxy\nDOMAIN-SUFFIX,ustibetcommittee.org,Proxy\nDOMAIN-SUFFIX,macovich.cl,Proxy\nDOMAIN-SUFFIX,equitydefault.com,Proxy\nDOMAIN-SUFFIX,www.proxyboost.net,Proxy\nDOMAIN-SUFFIX,t.5article.com,Proxy\nDOMAIN-SUFFIX,tainster.com,Proxy\nDOMAIN-SUFFIX,listen.radioking.com,Proxy\nDOMAIN-SUFFIX,www.transocks.com,Proxy\nDOMAIN-SUFFIX,sdk3.ga,Proxy\nDOMAIN-SUFFIX,5504z.com,Proxy\nDOMAIN-SUFFIX,www.hj8998.com,Proxy\nDOMAIN-SUFFIX,alldata.io,Proxy\nDOMAIN-SUFFIX,j2976.com,Proxy\nDOMAIN-SUFFIX,search.snopyta.org,Proxy\nDOMAIN-SUFFIX,sammyboyforum.com,Proxy\nDOMAIN-SUFFIX,uraban.me,Proxy\nDOMAIN-SUFFIX,southpark.com,Proxy\nDOMAIN-SUFFIX,www.mihiepa.com,Proxy\nDOMAIN-SUFFIX,www.rsdlmonitor.com,Proxy\nDOMAIN-SUFFIX,anonimus.ro,Proxy\nDOMAIN-SUFFIX,w.koogay.com,Proxy\nDOMAIN-SUFFIX,drhze47qtq2xs.cloudfront.net,Proxy\nDOMAIN-SUFFIX,southwest.com,Proxy\nDOMAIN-SUFFIX,344663.com,Proxy\nDOMAIN-SUFFIX,naitik.net,Proxy\nDOMAIN-SUFFIX,cs.chromium.org,Proxy\nDOMAIN-SUFFIX,quantumbooter.net,Proxy\nDOMAIN-SUFFIX,wk13.ddns.me,Proxy\nDOMAIN-SUFFIX,4cbd1.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,188522.com,Proxy\nDOMAIN-SUFFIX,www.ijopmed.org,Proxy\nDOMAIN-SUFFIX,9988333.com,Proxy\nDOMAIN-SUFFIX,vmpsoft.com,Proxy\nDOMAIN-SUFFIX,mypop3.org,Proxy\nDOMAIN-SUFFIX,qubit.com,Proxy\nDOMAIN-SUFFIX,30375599.com,Proxy\nDOMAIN-SUFFIX,currys.co.uk,Proxy\nDOMAIN-SUFFIX,fun120.com,Proxy\nDOMAIN-SUFFIX,aff.1eighty8.com,Proxy\nDOMAIN-SUFFIX,www.iu45.me,Proxy\nDOMAIN-SUFFIX,minghui-b.org,Proxy\nDOMAIN-SUFFIX,probit.com,Proxy\nDOMAIN-SUFFIX,poro.cc,Proxy\nDOMAIN-SUFFIX,www.rawtube.com,Proxy\nDOMAIN-SUFFIX,altpress.com,Proxy\nDOMAIN-SUFFIX,www.wankspider.com,Proxy\nDOMAIN-SUFFIX,anczxsz.blogspot.ca,Proxy\nDOMAIN-SUFFIX,gjczz.com,Proxy\nDOMAIN-SUFFIX,7.hk.am,Proxy\nDOMAIN-SUFFIX,www.osimtv.site,Proxy\nDOMAIN-SUFFIX,evolvelawyers.com.au,Proxy\nDOMAIN-SUFFIX,steel-storm.com,Proxy\nDOMAIN-SUFFIX,www.obama.com,Proxy\nDOMAIN-SUFFIX,icij.org,Proxy\nDOMAIN-SUFFIX,tibet.ca,Proxy\nDOMAIN-SUFFIX,besl.us,Proxy\nDOMAIN-SUFFIX,bangspank.pro,Proxy\nDOMAIN-SUFFIX,ihteam.net,Proxy\nDOMAIN-SUFFIX,bit-z.com,Proxy\nDOMAIN-SUFFIX,feer.com,Proxy\nDOMAIN-SUFFIX,www.alabamagazette.com,Proxy\nDOMAIN-SUFFIX,china.ucanews.com,Proxy\nDOMAIN-SUFFIX,api.zhis.cc,Proxy\nDOMAIN-SUFFIX,www.rb108.com,Proxy\nDOMAIN-SUFFIX,libyavpn.com,Proxy\nDOMAIN-SUFFIX,jcbl.be,Proxy\nDOMAIN-SUFFIX,blog.pentalogic.net,Proxy\nDOMAIN-SUFFIX,falundafa-sd.org,Proxy\nDOMAIN-SUFFIX,vpnzoom.com,Proxy\nDOMAIN-SUFFIX,d2xg0kpm6z915y.cloudfront.net,Proxy\nDOMAIN-SUFFIX,bergherz.ch,Proxy\nDOMAIN-SUFFIX,psso.org,Proxy\nDOMAIN-SUFFIX,zzx.healthgov.xyz,Proxy\nDOMAIN-SUFFIX,322.effers.com,Proxy\nDOMAIN-SUFFIX,d3ri8bptqier6y.cloudfront.net,Proxy\nDOMAIN-SUFFIX,mratme.com,Proxy\nDOMAIN-SUFFIX,setheory.xyz,Proxy\nDOMAIN-SUFFIX,buyastrill.com,Proxy\nDOMAIN-SUFFIX,www.nieuwsuur.nl,Proxy\nDOMAIN-SUFFIX,www.yihs.net,Proxy\nDOMAIN-SUFFIX,www.davesesl.com,Proxy\nDOMAIN-SUFFIX,xuzhiyong.net,Proxy\nDOMAIN-SUFFIX,07.homeip.net,Proxy\nDOMAIN-SUFFIX,peoplebookcafe.com,Proxy\nDOMAIN-SUFFIX,52040r.com,Proxy\nDOMAIN-SUFFIX,s.yimg.com,Proxy\nDOMAIN-SUFFIX,kkkk99.net,Proxy\nDOMAIN-SUFFIX,new-akiba.com,Proxy\nDOMAIN-SUFFIX,60702j.com,Proxy\nDOMAIN-SUFFIX,xiaomi8.dele88.com,Proxy\nDOMAIN-SUFFIX,www.ehn.io,Proxy\nDOMAIN-SUFFIX,xvxxtube.com,Proxy\nDOMAIN-SUFFIX,expo.com,Proxy\nDOMAIN-SUFFIX,www.gayforit.eu,Proxy\nDOMAIN-SUFFIX,d1c37gjwa26taa.cloudfront.net,Proxy\nDOMAIN-SUFFIX,fufuder.me,Proxy\nDOMAIN-SUFFIX,shmu.sk,Proxy\nDOMAIN-SUFFIX,www.f8188.com,Proxy\nDOMAIN-SUFFIX,8419.com,Proxy\nDOMAIN-SUFFIX,fasilegend.de,Proxy\nDOMAIN-SUFFIX,theorchid.chickenkiller.com,Proxy\nDOMAIN-SUFFIX,mymedia.yam.com,Proxy\nDOMAIN-SUFFIX,1666aa.com,Proxy\nDOMAIN-SUFFIX,www.ncat.edu,Proxy\nDOMAIN-SUFFIX,ajo.prod.reuters.tv,Proxy\nDOMAIN-SUFFIX,lms.equityinitiative.org,Proxy\nDOMAIN-SUFFIX,www.rxhj.org,Proxy\nDOMAIN-SUFFIX,www.guandang.com,Proxy\nDOMAIN-SUFFIX,www.bypasscensorship.org,Proxy\nDOMAIN-SUFFIX,nightcord.de,Proxy\nDOMAIN-SUFFIX,bscdn.xyz,Proxy\nDOMAIN-SUFFIX,www.prettysun.tw,Proxy\nDOMAIN-SUFFIX,willyrent.com,Proxy\nDOMAIN-SUFFIX,www.303xvideos.com,Proxy\nDOMAIN-SUFFIX,tjournal.ru,Proxy\nDOMAIN-SUFFIX,www.taolin.com.tw,Proxy\nDOMAIN-SUFFIX,www.changsenxue.idv.tw,Proxy\nDOMAIN-SUFFIX,extmatrix.com,Proxy\nDOMAIN-SUFFIX,gate.io,Proxy\nDOMAIN-SUFFIX,www.denbighshirefreepress.co.uk,Proxy\nDOMAIN-SUFFIX,oovpn.com,Proxy\nDOMAIN-SUFFIX,www.google.com.mm,Proxy\nDOMAIN-SUFFIX,www.wantgoo.com,Proxy\nDOMAIN-SUFFIX,wikipedia.org,Proxy\nDOMAIN-SUFFIX,flirt4free.com,Proxy\nDOMAIN-SUFFIX,miaoin.me,Proxy\nDOMAIN-SUFFIX,p2646.com,Proxy\nDOMAIN-SUFFIX,resort.tv,Proxy\nDOMAIN-SUFFIX,yqz.yqz555.com,Proxy\nDOMAIN-SUFFIX,twilightparadox.com,Proxy\nDOMAIN-SUFFIX,www.vampirebund.com,Proxy\nDOMAIN-SUFFIX,oblong.com,Proxy\nDOMAIN-SUFFIX,delias.com,Proxy\nDOMAIN-SUFFIX,www.mxvpn.cn,Proxy\nDOMAIN-SUFFIX,falundafamuseum.com,Proxy\nDOMAIN-SUFFIX,thedalailamamovie.com,Proxy\nDOMAIN-SUFFIX,ky123123.com,Proxy\nDOMAIN-SUFFIX,google.co.zw,Proxy\nDOMAIN-SUFFIX,tooting.ch,Proxy\nDOMAIN-SUFFIX,portal.thinkforex.com,Proxy\nDOMAIN-SUFFIX,calvinciw.ddns.net,Proxy\nDOMAIN-SUFFIX,owltail.com,Proxy\nDOMAIN-SUFFIX,www.ndmctsgh.edu.tw,Proxy\nDOMAIN-SUFFIX,pornhost.com,Proxy\nDOMAIN-SUFFIX,woxinghuiguo.com,Proxy\nDOMAIN-SUFFIX,everythinginbudget.blogspot.hk,Proxy\nDOMAIN-SUFFIX,johnham.com,Proxy\nDOMAIN-SUFFIX,157.fullcoveronline.com,Proxy\nDOMAIN-SUFFIX,cwbbooks.com,Proxy\nDOMAIN-SUFFIX,9cache.com,Proxy\nDOMAIN-SUFFIX,mamingzhe.com,Proxy\nDOMAIN-SUFFIX,www.dumisa.tv,Proxy\nDOMAIN-SUFFIX,wan-hk.earthvpn.com,Proxy\nDOMAIN-SUFFIX,mesca.ro,Proxy\nDOMAIN-SUFFIX,ruyiseek.com,Proxy\nDOMAIN-SUFFIX,gt5.332k.tk,Proxy\nDOMAIN-SUFFIX,wiki5.gq,Proxy\nDOMAIN-SUFFIX,raresupply.com,Proxy\nDOMAIN-SUFFIX,goagent.org,Proxy\nDOMAIN-SUFFIX,ktwr.org,Proxy\nDOMAIN-SUFFIX,shadowsky.xyz,Proxy\nDOMAIN-SUFFIX,ixxx.com,Proxy\nDOMAIN-SUFFIX,531.tw,Proxy\nDOMAIN-SUFFIX,a8adeba27e6ef953b.awsglobalaccelerator.com,Proxy\nDOMAIN-SUFFIX,www.leduo88.com,Proxy\nDOMAIN-SUFFIX,expatliving.hk,Proxy\nDOMAIN-SUFFIX,telegram.dog,Proxy\nDOMAIN-SUFFIX,www.northghost.com,Proxy\nDOMAIN-SUFFIX,zhina.sb,Proxy\nDOMAIN-SUFFIX,www.cliphunter.com,Proxy\nDOMAIN-SUFFIX,motor4ik.ru,Proxy\nDOMAIN-SUFFIX,ryanforcongress.com,Proxy\nDOMAIN-SUFFIX,d3ddcxy6cvcuq8.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.voaspecialenglish.com,Proxy\nDOMAIN-SUFFIX,www.b328.com,Proxy\nDOMAIN-SUFFIX,writer.zoho.com,Proxy\nDOMAIN-SUFFIX,nch.com.tw,Proxy\nDOMAIN-SUFFIX,www.g-area.org,Proxy\nDOMAIN-SUFFIX,920vpn.com,Proxy\nDOMAIN-SUFFIX,3.32top.xyz,Proxy\nDOMAIN-SUFFIX,053.dhcp.biz,Proxy\nDOMAIN-SUFFIX,carpauto.ca,Proxy\nDOMAIN-SUFFIX,rch88.com,Proxy\nDOMAIN-SUFFIX,ecrans.fr,Proxy\nDOMAIN-SUFFIX,luke54.net,Proxy\nDOMAIN-SUFFIX,alternet.co.il,Proxy\nDOMAIN-SUFFIX,www.seekingarrangement.com,Proxy\nDOMAIN-SUFFIX,www.militaryphotos.net,Proxy\nDOMAIN-SUFFIX,www.dialoguechina.com,Proxy\nDOMAIN-SUFFIX,chinacomments.org,Proxy\nDOMAIN-SUFFIX,nord-in-china.org,Proxy\nDOMAIN-SUFFIX,photofocus.com,Proxy\nDOMAIN-SUFFIX,sep.org.au,Proxy\nDOMAIN-SUFFIX,www.93sihu.com,Proxy\nDOMAIN-SUFFIX,lantern.io,Proxy\nDOMAIN-SUFFIX,egida.org,Proxy\nDOMAIN-SUFFIX,book.com.tw,Proxy\nDOMAIN-SUFFIX,javdove2.me,Proxy\nDOMAIN-SUFFIX,img.hgamecn.com,Proxy\nDOMAIN-SUFFIX,www.objectif-tibet.org,Proxy\nDOMAIN-SUFFIX,www.newsnow.co.uk,Proxy\nDOMAIN-SUFFIX,hk-bici.com,Proxy\nDOMAIN-SUFFIX,www.vpnss.com,Proxy\nDOMAIN-SUFFIX,humanrightshouse.org,Proxy\nDOMAIN-SUFFIX,www.nbclearn.com,Proxy\nDOMAIN-SUFFIX,www.thinkstockphotos.com.pt,Proxy\nDOMAIN-SUFFIX,pds.nasa.gov,Proxy\nDOMAIN-SUFFIX,tickling-videos.com,Proxy\nDOMAIN-SUFFIX,bifa006.com,Proxy\nDOMAIN-SUFFIX,grupocompre.com.br,Proxy\nDOMAIN-SUFFIX,bjnewlife.org,Proxy\nDOMAIN-SUFFIX,fy563.com,Proxy\nDOMAIN-SUFFIX,1mynews.asia,Proxy\nDOMAIN-SUFFIX,tourbuilder.withgoogle.com,Proxy\nDOMAIN-SUFFIX,torcn.com,Proxy\nDOMAIN-SUFFIX,d2zq1a70sj4zks.cloudfront.net,Proxy\nDOMAIN-SUFFIX,chatroom.dsn00.co,Proxy\nDOMAIN-SUFFIX,kameli.org,Proxy\nDOMAIN-SUFFIX,gemometrics.com,Proxy\nDOMAIN-SUFFIX,www.harderradio.de,Proxy\nDOMAIN-SUFFIX,businessinsider.com.au,Proxy\nDOMAIN-SUFFIX,bankofbaroda.com,Proxy\nDOMAIN-SUFFIX,91dizhi.com,Proxy\nDOMAIN-SUFFIX,doh.sb,Proxy\nDOMAIN-SUFFIX,ucpnz.co.nz,Proxy\nDOMAIN-SUFFIX,w3.3d-game.com,Proxy\nDOMAIN-SUFFIX,uk.uk7.org,Proxy\nDOMAIN-SUFFIX,fast-proxy.com.de,Proxy\nDOMAIN-SUFFIX,chi.fat.flnet.org,Proxy\nDOMAIN-SUFFIX,pose.com,Proxy\nDOMAIN-SUFFIX,23ikr.com,Proxy\nDOMAIN-SUFFIX,bf9558.com,Proxy\nDOMAIN-SUFFIX,rangwang.biz,Proxy\nDOMAIN-SUFFIX,nim.3d-game.com,Proxy\nDOMAIN-SUFFIX,catholic.org.tw,Proxy\nDOMAIN-SUFFIX,www.playno1.com,Proxy\nDOMAIN-SUFFIX,www.assembla.com,Proxy\nDOMAIN-SUFFIX,kyoyue.com,Proxy\nDOMAIN-SUFFIX,2859o.com,Proxy\nDOMAIN-SUFFIX,trimleng.org,Proxy\nDOMAIN-SUFFIX,kenh88.com,Proxy\nDOMAIN-SUFFIX,gov.tw,Proxy\nDOMAIN-SUFFIX,pornmm.net,Proxy\nDOMAIN-SUFFIX,www.linksalpha.com,Proxy\nDOMAIN-SUFFIX,964.net,Proxy\nDOMAIN-SUFFIX,adv2.s8bbs.com,Proxy\nDOMAIN-SUFFIX,unification.net,Proxy\nDOMAIN-SUFFIX,mormonchannel.org,Proxy\nDOMAIN-SUFFIX,zx-fly.com,Proxy\nDOMAIN-SUFFIX,tom.suroot.com,Proxy\nDOMAIN-SUFFIX,lib.ebookservice.tw,Proxy\nDOMAIN-SUFFIX,emofid.com,Proxy\nDOMAIN-SUFFIX,www.39879.com,Proxy\nDOMAIN-SUFFIX,www.eddie.idv.tw,Proxy\nDOMAIN-SUFFIX,duping.net,Proxy\nDOMAIN-SUFFIX,twibes.com,Proxy\nDOMAIN-SUFFIX,rolve.org,Proxy\nDOMAIN-SUFFIX,pomf.cat,Proxy\nDOMAIN-SUFFIX,my-rainbow-arts.com,Proxy\nDOMAIN-SUFFIX,dnslow.me,Proxy\nDOMAIN-SUFFIX,seexzp.com,Proxy\nDOMAIN-SUFFIX,1234.as,Proxy\nDOMAIN-SUFFIX,veritasifa.co.uk,Proxy\nDOMAIN-SUFFIX,www.sexrank2000.com,Proxy\nDOMAIN-SUFFIX,projectsecretidentity.org,Proxy\nDOMAIN-SUFFIX,ftx.com,Proxy\nDOMAIN-SUFFIX,lovebo.atwebpages.com,Proxy\nDOMAIN-SUFFIX,williamhiggins.com,Proxy\nDOMAIN-SUFFIX,n1g.org,Proxy\nDOMAIN-SUFFIX,progress.org,Proxy\nDOMAIN-SUFFIX,onair.kbs.co.kr,Proxy\nDOMAIN-SUFFIX,www.chaosinternational.com,Proxy\nDOMAIN-SUFFIX,cdt3.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,www.fischerinsel.org,Proxy\nDOMAIN-SUFFIX,bemyeyes.com,Proxy\nDOMAIN-SUFFIX,bookgb.bfnn.org,Proxy\nDOMAIN-SUFFIX,teensinasia.com,Proxy\nDOMAIN-SUFFIX,www.stfa-yyc.edu.hk,Proxy\nDOMAIN-SUFFIX,bergfiles.com,Proxy\nDOMAIN-SUFFIX,xc.com,Proxy\nDOMAIN-SUFFIX,nestopia.softonic.cn,Proxy\nDOMAIN-SUFFIX,hmarkets.com,Proxy\nDOMAIN-SUFFIX,adultism.com,Proxy\nDOMAIN-SUFFIX,members.common.org,Proxy\nDOMAIN-SUFFIX,d23hlq7yv8w2zs.cloudfront.net,Proxy\nDOMAIN-SUFFIX,musculus.xyz,Proxy\nDOMAIN-SUFFIX,n9909.com,Proxy\nDOMAIN-SUFFIX,p.inkcat.net,Proxy\nDOMAIN-SUFFIX,news100.com.tw,Proxy\nDOMAIN-SUFFIX,ericslezak.com,Proxy\nDOMAIN-SUFFIX,google.hk.cn,Proxy\nDOMAIN-SUFFIX,www.nau.ch,Proxy\nDOMAIN-SUFFIX,www.wsdc990.com,Proxy\nDOMAIN-SUFFIX,newsonair.nic.in,Proxy\nDOMAIN-SUFFIX,laogairesearch.org,Proxy\nDOMAIN-SUFFIX,obutu.com,Proxy\nDOMAIN-SUFFIX,www.xhuom.com,Proxy\nDOMAIN-SUFFIX,www.powerpointninja.com,Proxy\nDOMAIN-SUFFIX,w3373.com,Proxy\nDOMAIN-SUFFIX,liangchenyun.xyz,Proxy\nDOMAIN-SUFFIX,e6bet.com,Proxy\nDOMAIN-SUFFIX,etherscan.io,Proxy\nDOMAIN-SUFFIX,jp2.678889.xyz,Proxy\nDOMAIN-SUFFIX,www.tianhui.org.tw,Proxy\nDOMAIN-SUFFIX,s1.longs1.vip,Proxy\nDOMAIN-SUFFIX,ns02.tk,Proxy\nDOMAIN-SUFFIX,s85.slyip.net,Proxy\nDOMAIN-SUFFIX,ift.tt,Proxy\nDOMAIN-SUFFIX,xianchawang.net,Proxy\nDOMAIN-SUFFIX,go5.dev,Proxy\nDOMAIN-SUFFIX,kuese.com,Proxy\nDOMAIN-SUFFIX,tbsn.org,Proxy\nDOMAIN-SUFFIX,entunn.com,Proxy\nDOMAIN-SUFFIX,bearteach.com,Proxy\nDOMAIN-SUFFIX,thechinabeat.org,Proxy\nDOMAIN-SUFFIX,usmgtcg.ning.com,Proxy\nDOMAIN-SUFFIX,voa.gov,Proxy\nDOMAIN-SUFFIX,iiita.ac.in,Proxy\nDOMAIN-SUFFIX,chinaafricarealstory.com,Proxy\nDOMAIN-SUFFIX,www.tuancai.net,Proxy\nDOMAIN-SUFFIX,app.livestorm.co,Proxy\nDOMAIN-SUFFIX,musictostopthepersecution.org,Proxy\nDOMAIN-SUFFIX,riki.si,Proxy\nDOMAIN-SUFFIX,www.acgnz.cc,Proxy\nDOMAIN-SUFFIX,x99av.com,Proxy\nDOMAIN-SUFFIX,jxcpw.com,Proxy\nDOMAIN-SUFFIX,75522.com,Proxy\nDOMAIN-SUFFIX,googleideas.com,Proxy\nDOMAIN-SUFFIX,www.xitenow.com,Proxy\nDOMAIN-SUFFIX,healthysite.xyz,Proxy\nDOMAIN-SUFFIX,goagent.11go.net,Proxy\nDOMAIN-SUFFIX,aff.betezee.com,Proxy\nDOMAIN-SUFFIX,www.bbclearningenglish.com,Proxy\nDOMAIN-SUFFIX,ouokt.com,Proxy\nDOMAIN-SUFFIX,clearwisdom.net,Proxy\nDOMAIN-SUFFIX,foxxv.com,Proxy\nDOMAIN-SUFFIX,d19tl7r1win8lc.cloudfront.net,Proxy\nDOMAIN-SUFFIX,gather.com,Proxy\nDOMAIN-SUFFIX,www.fh97.com,Proxy\nDOMAIN-SUFFIX,mattiemorgan.cf,Proxy\nDOMAIN-SUFFIX,teddit.net,Proxy\nDOMAIN-SUFFIX,www.haixiainfo.com.tw,Proxy\nDOMAIN-SUFFIX,heywalnut.com,Proxy\nDOMAIN-SUFFIX,321292.xyz,Proxy\nDOMAIN-SUFFIX,valu.us,Proxy\nDOMAIN-SUFFIX,soutong.men,Proxy\nDOMAIN-SUFFIX,www.lebronjames.com,Proxy\nDOMAIN-SUFFIX,gallery.mailchimp.com,Proxy\nDOMAIN-SUFFIX,708.microcycas.com,Proxy\nDOMAIN-SUFFIX,dtunnel.com,Proxy\nDOMAIN-SUFFIX,liuli.pw,Proxy\nDOMAIN-SUFFIX,google.com.om,Proxy\nDOMAIN-SUFFIX,mihua.org,Proxy\nDOMAIN-SUFFIX,hk.vbkr.com,Proxy\nDOMAIN-SUFFIX,sinaapp.co,Proxy\nDOMAIN-SUFFIX,freesstpvpn.com,Proxy\nDOMAIN-SUFFIX,www.vastitude.org,Proxy\nDOMAIN-SUFFIX,pcmarket.com.hk,Proxy\nDOMAIN-SUFFIX,wwddxv.com,Proxy\nDOMAIN-SUFFIX,file2.yzdgzw.com,Proxy\nDOMAIN-SUFFIX,d2x2lb1thnk7sv.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.b2959.com,Proxy\nDOMAIN-SUFFIX,guatemalavpn.com,Proxy\nDOMAIN-SUFFIX,365667.com,Proxy\nDOMAIN-SUFFIX,mh12.cf,Proxy\nDOMAIN-SUFFIX,neopets.com,Proxy\nDOMAIN-SUFFIX,lastcombat.com,Proxy\nDOMAIN-SUFFIX,godfootsteps.org,Proxy\nDOMAIN-SUFFIX,googl.com,Proxy\nDOMAIN-SUFFIX,finet.hk,Proxy\nDOMAIN-SUFFIX,game88city.com,Proxy\nDOMAIN-SUFFIX,w3.001www.com,Proxy\nDOMAIN-SUFFIX,www.ixlzs.me,Proxy\nDOMAIN-SUFFIX,google.com.np,Proxy\nDOMAIN-SUFFIX,iswellhung.com,Proxy\nDOMAIN-SUFFIX,nittereu.moomoo.me,Proxy\nDOMAIN-SUFFIX,taconet.com.tw,Proxy\nDOMAIN-SUFFIX,getlantern.org,Proxy\nDOMAIN-SUFFIX,biglychee.com,Proxy\nDOMAIN-SUFFIX,findmespot.com,Proxy\nDOMAIN-SUFFIX,cogipas.com,Proxy\nDOMAIN-SUFFIX,incomeon.com,Proxy\nDOMAIN-SUFFIX,rfa.org,Proxy\nDOMAIN-SUFFIX,cn.chaum.net,Proxy\nDOMAIN-SUFFIX,sweltering-inferno-6276.firebaseio.com,Proxy\nDOMAIN-SUFFIX,zoopla.co.uk,Proxy\nDOMAIN-SUFFIX,517pj.com,Proxy\nDOMAIN-SUFFIX,g.alexyang.me,Proxy\nDOMAIN-SUFFIX,angelinavalentine.com,Proxy\nDOMAIN-SUFFIX,www.foxporns.com,Proxy\nDOMAIN-SUFFIX,www.pickyuhome.net,Proxy\nDOMAIN-SUFFIX,www.sport988.com,Proxy\nDOMAIN-SUFFIX,18comic.life,Proxy\nDOMAIN-SUFFIX,cai950.com,Proxy\nDOMAIN-SUFFIX,tweets.seraph.me,Proxy\nDOMAIN-SUFFIX,blogspot.ru,Proxy\nDOMAIN-SUFFIX,xvideos.jp,Proxy\nDOMAIN-SUFFIX,apk.enemyterritory.org,Proxy\nDOMAIN-SUFFIX,pcij.org,Proxy\nDOMAIN-SUFFIX,877790.com,Proxy\nDOMAIN-SUFFIX,shawn-lin-chinese-wedding.strikingly.com,Proxy\nDOMAIN-SUFFIX,marxist.org,Proxy\nDOMAIN-SUFFIX,tuk-tuk.co.uk,Proxy\nDOMAIN-SUFFIX,keimlinge.net,Proxy\nDOMAIN-SUFFIX,www.nme.com,Proxy\nDOMAIN-SUFFIX,pshvpn.com,Proxy\nDOMAIN-SUFFIX,lim.gotgeeks.com,Proxy\nDOMAIN-SUFFIX,hi-on.org,Proxy\nDOMAIN-SUFFIX,premproxy.com,Proxy\nDOMAIN-SUFFIX,ktwr.net,Proxy\nDOMAIN-SUFFIX,adrindia.org,Proxy\nDOMAIN-SUFFIX,fbcdn.net,Proxy\nDOMAIN-SUFFIX,chat.openai.com,Proxy\nDOMAIN-SUFFIX,anonymitynetwork.com,Proxy\nDOMAIN-SUFFIX,in.gov,Proxy\nDOMAIN-SUFFIX,rtv99.xyz,Proxy\nDOMAIN-SUFFIX,21sextreme.com,Proxy\nDOMAIN-SUFFIX,packetix.net,Proxy\nDOMAIN-SUFFIX,www.melspring.com,Proxy\nDOMAIN-SUFFIX,science4all.org,Proxy\nDOMAIN-SUFFIX,www.souguge.net,Proxy\nDOMAIN-SUFFIX,www.verkkouutiset.fi,Proxy\nDOMAIN-SUFFIX,ys138.win,Proxy\nDOMAIN-SUFFIX,pornhubdeutsch.net,Proxy\nDOMAIN-SUFFIX,gatestoneinstitute.org,Proxy\nDOMAIN-SUFFIX,lemarche920.synology.me,Proxy\nDOMAIN-SUFFIX,ocsp.int-x3.letsencrypt.org,Proxy\nDOMAIN-SUFFIX,vadoo.tv,Proxy\nDOMAIN-SUFFIX,www.lifespacex.com,Proxy\nDOMAIN-SUFFIX,server15.kproxy.com,Proxy\nDOMAIN-SUFFIX,www.singpao.com.hk,Proxy\nDOMAIN-SUFFIX,freevpnssh.com,Proxy\nDOMAIN-SUFFIX,horan.id.au,Proxy\nDOMAIN-SUFFIX,yourepeat.com,Proxy\nDOMAIN-SUFFIX,wikibooks.org,Proxy\nDOMAIN-SUFFIX,t.tv321.pw,Proxy\nDOMAIN-SUFFIX,chinaperspectives.revues.org,Proxy\nDOMAIN-SUFFIX,phpbb-tw.net,Proxy\nDOMAIN-SUFFIX,ozibatla.com,Proxy\nDOMAIN-SUFFIX,vbsf2.n56b.com,Proxy\nDOMAIN-SUFFIX,prospectmagazine.co.uk,Proxy\nDOMAIN-SUFFIX,top21.blocktempo.com,Proxy\nDOMAIN-SUFFIX,hsfo.dk,Proxy\nDOMAIN-SUFFIX,www.wan-press.org,Proxy\nDOMAIN-SUFFIX,777.ctjdb166.com,Proxy\nDOMAIN-SUFFIX,dotheybang.com,Proxy\nDOMAIN-SUFFIX,updates.tdesktop.com,Proxy\nDOMAIN-SUFFIX,d2ye0lxorqum8y.cloudfront.net,Proxy\nDOMAIN-SUFFIX,7sur7.be,Proxy\nDOMAIN-SUFFIX,www.youtube.co.za,Proxy\nDOMAIN-SUFFIX,workers.dev,Proxy\nDOMAIN-SUFFIX,fivestarvpn.com,Proxy\nDOMAIN-SUFFIX,enboarder.com,Proxy\nDOMAIN-SUFFIX,d1hpxc3moct63a.cloudfront.net,Proxy\nDOMAIN-SUFFIX,gb.udn.com,Proxy\nDOMAIN-SUFFIX,www.npmshops.com,Proxy\nDOMAIN-SUFFIX,internetretailer.com,Proxy\nDOMAIN-SUFFIX,0235.com,Proxy\nDOMAIN-SUFFIX,hj939.com,Proxy\nDOMAIN-SUFFIX,www.expecthim.com,Proxy\nDOMAIN-SUFFIX,dsmtp.com,Proxy\nDOMAIN-SUFFIX,slegat.eu,Proxy\nDOMAIN-SUFFIX,nuexpo.com,Proxy\nDOMAIN-SUFFIX,www.wireguard.io,Proxy\nDOMAIN-SUFFIX,listentoyoutube.com,Proxy\nDOMAIN-SUFFIX,redbubble.com,Proxy\nDOMAIN-SUFFIX,tonightsgirlfriend.com,Proxy\nDOMAIN-SUFFIX,content.fosterandpartners.com,Proxy\nDOMAIN-SUFFIX,from-il.com,Proxy\nDOMAIN-SUFFIX,bazarartelar.net,Proxy\nDOMAIN-SUFFIX,ww.daliulian.net,Proxy\nDOMAIN-SUFFIX,233.wtf,Proxy\nDOMAIN-SUFFIX,cacnews.ca,Proxy\nDOMAIN-SUFFIX,12youtube.com,Proxy\nDOMAIN-SUFFIX,indianarrative.com,Proxy\nDOMAIN-SUFFIX,www.hcdiagnostics.com,Proxy\nDOMAIN-SUFFIX,rutracker.nl,Proxy\nDOMAIN-SUFFIX,www.the-cloak.com,Proxy\nDOMAIN-SUFFIX,googlehelper.net,Proxy\nDOMAIN-SUFFIX,w2.myredirect.us,Proxy\nDOMAIN-SUFFIX,moefuns.cc,Proxy\nDOMAIN-SUFFIX,www.kutogroup.com,Proxy\nDOMAIN-SUFFIX,ipfsgateway.makersplace.com,Proxy\nDOMAIN-SUFFIX,www.grandeast.com.tw,Proxy\nDOMAIN-SUFFIX,ffeae02d-51bb-4209-b018-95f6fa81f719.realclearprivacy.biz,Proxy\nDOMAIN-SUFFIX,www.theintercept.com,Proxy\nDOMAIN-SUFFIX,www.bw8863.com,Proxy\nDOMAIN-SUFFIX,betternet.co,Proxy\nDOMAIN-SUFFIX,maturetubeporn.com,Proxy\nDOMAIN-SUFFIX,www.x1360.com,Proxy\nDOMAIN-SUFFIX,netsarang.com,Proxy\nDOMAIN-SUFFIX,ojbkss.win,Proxy\nDOMAIN-SUFFIX,www.dlacalle.com,Proxy\nDOMAIN-SUFFIX,www.tibetancommunityuk.org,Proxy\nDOMAIN-SUFFIX,zhichang.5article.com,Proxy\nDOMAIN-SUFFIX,glasskeys.com,Proxy\nDOMAIN-SUFFIX,dmit.io,Proxy\nDOMAIN-SUFFIX,movie.hkbisi.com,Proxy\nDOMAIN-SUFFIX,jfengtime.com,Proxy\nDOMAIN-SUFFIX,komatsu.palantirfoundry.com,Proxy\nDOMAIN-SUFFIX,wallpapercasa.com,Proxy\nDOMAIN-SUFFIX,www.2000vip6.com,Proxy\nDOMAIN-SUFFIX,access-oriental.com,Proxy\nDOMAIN-SUFFIX,ca6022.com,Proxy\nDOMAIN-SUFFIX,skyking.com.tw,Proxy\nDOMAIN-SUFFIX,hindilyrics.net,Proxy\nDOMAIN-SUFFIX,cloud.wabisabi.site,Proxy\nDOMAIN-SUFFIX,unblockit.llc,Proxy\nDOMAIN-SUFFIX,www.tlc816.com,Proxy\nDOMAIN-SUFFIX,arph.org,Proxy\nDOMAIN-SUFFIX,73.slyip.net,Proxy\nDOMAIN-SUFFIX,groundskeeper.us,Proxy\nDOMAIN-SUFFIX,cannonballapp.io,Proxy\nDOMAIN-SUFFIX,4455599.com,Proxy\nDOMAIN-SUFFIX,hackerne.ws,Proxy\nDOMAIN-SUFFIX,naol.ca,Proxy\nDOMAIN-SUFFIX,h.bd.to,Proxy\nDOMAIN-SUFFIX,jm-comic.cc,Proxy\nDOMAIN-SUFFIX,zze.healthsites.xyz,Proxy\nDOMAIN-SUFFIX,djxwyulo5z299.cloudfront.net,Proxy\nDOMAIN-SUFFIX,juziyue.com,Proxy\nDOMAIN-SUFFIX,whore.com,Proxy\nDOMAIN-SUFFIX,mail.swatfame.com,Proxy\nDOMAIN-SUFFIX,www.g6hentai.com,Proxy\nDOMAIN-SUFFIX,xjs111.com,Proxy\nDOMAIN-SUFFIX,chinesecommunistparty.org,Proxy\nDOMAIN-SUFFIX,saverthk.org,Proxy\nDOMAIN-SUFFIX,anonyproxy.biz,Proxy\nDOMAIN-SUFFIX,vidinfo.org,Proxy\nDOMAIN-SUFFIX,www.cwahi.net,Proxy\nDOMAIN-SUFFIX,icoco.com,Proxy\nDOMAIN-SUFFIX,bitpower.us,Proxy\nDOMAIN-SUFFIX,bbgyy.net,Proxy\nDOMAIN-SUFFIX,473688.com,Proxy\nDOMAIN-SUFFIX,www.myanmar.gov.mm,Proxy\nDOMAIN-SUFFIX,www.nutsvpn.net,Proxy\nDOMAIN-SUFFIX,xxxhd.sex,Proxy\nDOMAIN-SUFFIX,darkfall.org,Proxy\nDOMAIN-SUFFIX,webshite.com,Proxy\nDOMAIN-SUFFIX,xkiwi.tk,Proxy\nDOMAIN-SUFFIX,mail.barrowsonline.com,Proxy\nDOMAIN-SUFFIX,googleapis.com,Proxy\nDOMAIN-SUFFIX,world-for-fun.com,Proxy\nDOMAIN-SUFFIX,btrend.amassly.com,Proxy\nDOMAIN-SUFFIX,inyt.com,Proxy\nDOMAIN-SUFFIX,forum.idsam.com,Proxy\nDOMAIN-SUFFIX,pantherprotocol.io,Proxy\nDOMAIN-SUFFIX,yi.gs,Proxy\nDOMAIN-SUFFIX,downloadhelper.net,Proxy\nDOMAIN-SUFFIX,droidvpn.com,Proxy\nDOMAIN-SUFFIX,www.everipedia.com,Proxy\nDOMAIN-SUFFIX,boxunblog.com,Proxy\nDOMAIN-SUFFIX,25.cr.rs,Proxy\nDOMAIN-SUFFIX,coinrail.co.kr,Proxy\nDOMAIN-SUFFIX,churchinhongkong.org,Proxy\nDOMAIN-SUFFIX,chinagreenparty.org,Proxy\nDOMAIN-SUFFIX,www.delawareonline.com,Proxy\nDOMAIN-SUFFIX,fqnews.net,Proxy\nDOMAIN-SUFFIX,friedmann.co.il,Proxy\nDOMAIN-SUFFIX,fling.com,Proxy\nDOMAIN-SUFFIX,phab.wmfusercontent.org,Proxy\nDOMAIN-SUFFIX,abematv.akamaized.net,Proxy\nDOMAIN-SUFFIX,toplistproxy.com,Proxy\nDOMAIN-SUFFIX,www.ltyyb.com,Proxy\nDOMAIN-SUFFIX,proxysurfs.com,Proxy\nDOMAIN-SUFFIX,ginaharrison.ga,Proxy\nDOMAIN-SUFFIX,jensrb.blogger.de,Proxy\nDOMAIN-SUFFIX,www.kindleren.com,Proxy\nDOMAIN-SUFFIX,www.investor.bg,Proxy\nDOMAIN-SUFFIX,s.sne.jp,Proxy\nDOMAIN-SUFFIX,mandelbaerli.org,Proxy\nDOMAIN-SUFFIX,56.serveirc.com,Proxy\nDOMAIN-SUFFIX,www.fhjtzhs.com,Proxy\nDOMAIN-SUFFIX,www.ghostpath.com,Proxy\nDOMAIN-SUFFIX,dj9djk795d5ob.cloudfront.net,Proxy\nDOMAIN-SUFFIX,theyearshouse.webnode.tw,Proxy\nDOMAIN-SUFFIX,ktxp.com,Proxy\nDOMAIN-SUFFIX,buff.ly,Proxy\nDOMAIN-SUFFIX,6220066.com,Proxy\nDOMAIN-SUFFIX,wangafu.net,Proxy\nDOMAIN-SUFFIX,acg.mn,Proxy\nDOMAIN-SUFFIX,free4u.com.ar,Proxy\nDOMAIN-SUFFIX,bgp.he.net,Proxy\nDOMAIN-SUFFIX,ss2wall.com,Proxy\nDOMAIN-SUFFIX,macauslot.com,Proxy\nDOMAIN-SUFFIX,tibetonline.tv,Proxy\nDOMAIN-SUFFIX,www.finchvpn.org,Proxy\nDOMAIN-SUFFIX,kagyu.org.za,Proxy\nDOMAIN-SUFFIX,image.slidesharecdn.com,Proxy\nDOMAIN-SUFFIX,www.christianstudy.com,Proxy\nDOMAIN-SUFFIX,falundafa.or.kr,Proxy\nDOMAIN-SUFFIX,androidebook.org,Proxy\nDOMAIN-SUFFIX,tinc-vpn.org,Proxy\nDOMAIN-SUFFIX,biubiu.com,Proxy\nDOMAIN-SUFFIX,kineox.free.fr,Proxy\nDOMAIN-SUFFIX,mathmodels.org,Proxy\nDOMAIN-SUFFIX,www.cartoon18.com,Proxy\nDOMAIN-SUFFIX,poofx.com,Proxy\nDOMAIN-SUFFIX,podolski.org,Proxy\nDOMAIN-SUFFIX,www.max-a.co.jp,Proxy\nDOMAIN-SUFFIX,xinbi008.com,Proxy\nDOMAIN-SUFFIX,breast-taiwan.com,Proxy\nDOMAIN-SUFFIX,culture.tw,Proxy\nDOMAIN-SUFFIX,zzu.healthsection.xyz,Proxy\nDOMAIN-SUFFIX,we22.ml,Proxy\nDOMAIN-SUFFIX,strongvpn.net,Proxy\nDOMAIN-SUFFIX,eol.cn,Proxy\nDOMAIN-SUFFIX,www.antwerpen.be,Proxy\nDOMAIN-SUFFIX,mycloud.bz,Proxy\nDOMAIN-SUFFIX,erolord.com,Proxy\nDOMAIN-SUFFIX,archiveofourown.me,Proxy\nDOMAIN-SUFFIX,www.pomiav.com,Proxy\nDOMAIN-SUFFIX,b2bcn.eslite.com,Proxy\nDOMAIN-SUFFIX,www.golfzon.cn,Proxy\nDOMAIN-SUFFIX,bmfinn.com,Proxy\nDOMAIN-SUFFIX,vpnintouch.com,Proxy\nDOMAIN-SUFFIX,sinoturcica.org,Proxy\nDOMAIN-SUFFIX,r18.com,Proxy\nDOMAIN-SUFFIX,haratulisanah.com,Proxy\nDOMAIN-SUFFIX,hopetv.org,Proxy\nDOMAIN-SUFFIX,cn1069.org,Proxy\nDOMAIN-SUFFIX,hotforex.com,Proxy\nDOMAIN-SUFFIX,www.rapidnovor.com,Proxy\nDOMAIN-SUFFIX,voachinese.com,Proxy\nDOMAIN-SUFFIX,russiavpn.com,Proxy\nDOMAIN-SUFFIX,yuka.idv.tw,Proxy\nDOMAIN-SUFFIX,26.slyip.net,Proxy\nDOMAIN-SUFFIX,bluesurface.bolab.net,Proxy\nDOMAIN-SUFFIX,metarthunter.com,Proxy\nDOMAIN-SUFFIX,archives.gov.tw,Proxy\nDOMAIN-SUFFIX,geekheart.info,Proxy\nDOMAIN-SUFFIX,sinonet.ca,Proxy\nDOMAIN-SUFFIX,online.recoveryversion.org,Proxy\nDOMAIN-SUFFIX,d2tno2zvt3semc.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.zimuzu.io,Proxy\nDOMAIN-SUFFIX,globalvpn.net,Proxy\nDOMAIN-SUFFIX,www.66cp.cc,Proxy\nDOMAIN-SUFFIX,www.av8d.tv,Proxy\nDOMAIN-SUFFIX,rus.azattyq.org,Proxy\nDOMAIN-SUFFIX,pay00001.bo88pay01.com,Proxy\nDOMAIN-SUFFIX,moneyhome.biz,Proxy\nDOMAIN-SUFFIX,invidious.slipfox.xyz,Proxy\nDOMAIN-SUFFIX,ngensis.com,Proxy\nDOMAIN-SUFFIX,potvpn.com,Proxy\nDOMAIN-SUFFIX,www.originalmindzen.com,Proxy\nDOMAIN-SUFFIX,vpnjz.com,Proxy\nDOMAIN-SUFFIX,momoshop.com.tw,Proxy\nDOMAIN-SUFFIX,voatibetan.com,Proxy\nDOMAIN-SUFFIX,noblequran.com,Proxy\nDOMAIN-SUFFIX,duckduckgo-owned-server.yahoo.net,Proxy\nDOMAIN-SUFFIX,cdn5.cdn-telegram.org,Proxy\nDOMAIN-SUFFIX,as.mr,Proxy\nDOMAIN-SUFFIX,www.rostones.com,Proxy\nDOMAIN-SUFFIX,fleek.co,Proxy\nDOMAIN-SUFFIX,www.allcoin.com,Proxy\nDOMAIN-SUFFIX,www.pictoa.com,Proxy\nDOMAIN-SUFFIX,www.tibet-hamburg.de,Proxy\nDOMAIN-SUFFIX,stentwood.com.au,Proxy\nDOMAIN-SUFFIX,www.newindianexpress.com,Proxy\nDOMAIN-SUFFIX,hottube.me,Proxy\nDOMAIN-SUFFIX,gaw.flnet.org,Proxy\nDOMAIN-SUFFIX,akitahandball.net,Proxy\nDOMAIN-SUFFIX,free4allsw.com,Proxy\nDOMAIN-SUFFIX,s4a-bo-pda-in-stores-dev.firebaseio.com,Proxy\nDOMAIN-SUFFIX,xite.ws,Proxy\nDOMAIN-SUFFIX,upstract.com,Proxy\nDOMAIN-SUFFIX,sismonda.com,Proxy\nDOMAIN-SUFFIX,mdnkids.com,Proxy\nDOMAIN-SUFFIX,7509607.com,Proxy\nDOMAIN-SUFFIX,www.tianshi2.com,Proxy\nDOMAIN-SUFFIX,www.yzlhb607.com,Proxy\nDOMAIN-SUFFIX,fbdownloader.com,Proxy\nDOMAIN-SUFFIX,www.vk.nl,Proxy\nDOMAIN-SUFFIX,xnxx.tv,Proxy\nDOMAIN-SUFFIX,henhenlu.com,Proxy\nDOMAIN-SUFFIX,hkecl.redirectme.net,Proxy\nDOMAIN-SUFFIX,anti-coco.top,Proxy\nDOMAIN-SUFFIX,www.caita66.com,Proxy\nDOMAIN-SUFFIX,ltunnel.com,Proxy\nDOMAIN-SUFFIX,www.hustler.com,Proxy\nDOMAIN-SUFFIX,mycrypto.com,Proxy\nDOMAIN-SUFFIX,b997.com,Proxy\nDOMAIN-SUFFIX,d2h5dkhxvxyg97.cloudfront.net,Proxy\nDOMAIN-SUFFIX,americanradiohistory.com,Proxy\nDOMAIN-SUFFIX,twittervideodownloader.com,Proxy\nDOMAIN-SUFFIX,www.huffingtonpost.it,Proxy\nDOMAIN-SUFFIX,www.niigata-nippo.co.jp,Proxy\nDOMAIN-SUFFIX,tw.vonvon.me,Proxy\nDOMAIN-SUFFIX,n.hd36.win,Proxy\nDOMAIN-SUFFIX,www.noticiasdenavarra.com,Proxy\nDOMAIN-SUFFIX,sangye.it,Proxy\nDOMAIN-SUFFIX,8587v.cc,Proxy\nDOMAIN-SUFFIX,jmcomic.me,Proxy\nDOMAIN-SUFFIX,enwp.org,Proxy\nDOMAIN-SUFFIX,yj1122.com,Proxy\nDOMAIN-SUFFIX,sodgo.com,Proxy\nDOMAIN-SUFFIX,rogueflash.com,Proxy\nDOMAIN-SUFFIX,sweetpacks-search.com,Proxy\nDOMAIN-SUFFIX,delicyus.com,Proxy\nDOMAIN-SUFFIX,ag579sx.com,Proxy\nDOMAIN-SUFFIX,922tp.com,Proxy\nDOMAIN-SUFFIX,duihua.org,Proxy\nDOMAIN-SUFFIX,proxysite.pro,Proxy\nDOMAIN-SUFFIX,www.shenzhenparty.com,Proxy\nDOMAIN-SUFFIX,businessinsider.co.id,Proxy\nDOMAIN-SUFFIX,ii9955.com,Proxy\nDOMAIN-SUFFIX,signupv2.popmediainc.com,Proxy\nDOMAIN-SUFFIX,asiafreexxx.com,Proxy\nDOMAIN-SUFFIX,hkwesi6.xyz,Proxy\nDOMAIN-SUFFIX,program-think.blogspot.ch,Proxy\nDOMAIN-SUFFIX,www.colliemail.com.au,Proxy\nDOMAIN-SUFFIX,new-winner-trading.myshopify.com,Proxy\nDOMAIN-SUFFIX,www.ttshow.tw,Proxy\nDOMAIN-SUFFIX,www.fun501.com,Proxy\nDOMAIN-SUFFIX,tibet.org.au,Proxy\nDOMAIN-SUFFIX,jinbo666.com,Proxy\nDOMAIN-SUFFIX,comparitech.com,Proxy\nDOMAIN-SUFFIX,android-apk.org,Proxy\nDOMAIN-SUFFIX,noen.cx,Proxy\nDOMAIN-SUFFIX,d1gvoah09ki5t2.cloudfront.net,Proxy\nDOMAIN-SUFFIX,jbtxtv.site,Proxy\nDOMAIN-SUFFIX,blm569.com,Proxy\nDOMAIN-SUFFIX,spike.com,Proxy\nDOMAIN-SUFFIX,www.betezee.com,Proxy\nDOMAIN-SUFFIX,appadvice.com,Proxy\nDOMAIN-SUFFIX,www.hrgj44.com,Proxy\nDOMAIN-SUFFIX,towards.fi,Proxy\nDOMAIN-SUFFIX,alalin.me,Proxy\nDOMAIN-SUFFIX,www.activtrades.cn,Proxy\nDOMAIN-SUFFIX,shanghainationalparty.com,Proxy\nDOMAIN-SUFFIX,m.ca181.com,Proxy\nDOMAIN-SUFFIX,zhenxiang.biz,Proxy\nDOMAIN-SUFFIX,www.jbl8002.com,Proxy\nDOMAIN-SUFFIX,www.30660.com,Proxy\nDOMAIN-SUFFIX,d3im9fxhrapv1a.cloudfront.net,Proxy\nDOMAIN-SUFFIX,ts788.net,Proxy\nDOMAIN-SUFFIX,workshop.idv.tw,Proxy\nDOMAIN-SUFFIX,dajusha.baywords.com,Proxy\nDOMAIN-SUFFIX,duosuccess.com,Proxy\nDOMAIN-SUFFIX,art4tibet1998.org,Proxy\nDOMAIN-SUFFIX,bad-data.net,Proxy\nDOMAIN-SUFFIX,www.susuky.net,Proxy\nDOMAIN-SUFFIX,borquezyburr.cl,Proxy\nDOMAIN-SUFFIX,silkroad.net,Proxy\nDOMAIN-SUFFIX,highmowing.org,Proxy\nDOMAIN-SUFFIX,tibettimes.net,Proxy\nDOMAIN-SUFFIX,www.f88ok103.com,Proxy\nDOMAIN-SUFFIX,www.digitalplayground.com,Proxy\nDOMAIN-SUFFIX,securityandtechnology.org,Proxy\nDOMAIN-SUFFIX,www.rakuten.com.tw,Proxy\nDOMAIN-SUFFIX,hsjp.net,Proxy\nDOMAIN-SUFFIX,semanariotransmontano.com,Proxy\nDOMAIN-SUFFIX,www.northy.de,Proxy\nDOMAIN-SUFFIX,zomato.com,Proxy\nDOMAIN-SUFFIX,ssbook.com,Proxy\nDOMAIN-SUFFIX,www.lf318.com,Proxy\nDOMAIN-SUFFIX,streamable.com,Proxy\nDOMAIN-SUFFIX,xiaochengzaji.com,Proxy\nDOMAIN-SUFFIX,pca-express.org,Proxy\nDOMAIN-SUFFIX,yale.box.com,Proxy\nDOMAIN-SUFFIX,shutterstock.com,Proxy\nDOMAIN-SUFFIX,cdn-main.plus500.com,Proxy\nDOMAIN-SUFFIX,www.numberoptions.com,Proxy\nDOMAIN-SUFFIX,www.ifeelmyself.com,Proxy\nDOMAIN-SUFFIX,buyu722.com,Proxy\nDOMAIN-SUFFIX,innasicard.com,Proxy\nDOMAIN-SUFFIX,www.skynews.com.au,Proxy\nDOMAIN-SUFFIX,chat.okis.dev,Proxy\nDOMAIN-SUFFIX,python.com.tw,Proxy\nDOMAIN-SUFFIX,scmp.hk,Proxy\nDOMAIN-SUFFIX,www.jsss.site,Proxy\nDOMAIN-SUFFIX,organcare.org.tw,Proxy\nDOMAIN-SUFFIX,dsn5558.com,Proxy\nDOMAIN-SUFFIX,www.airasia.com,Proxy\nDOMAIN-SUFFIX,a11.jumpingcrab.com,Proxy\nDOMAIN-SUFFIX,favstar.fm,Proxy\nDOMAIN-SUFFIX,acfxcn.com,Proxy\nDOMAIN-SUFFIX,www.biweibw88.com,Proxy\nDOMAIN-SUFFIX,uyghurunion.org,Proxy\nDOMAIN-SUFFIX,chhongbi.org,Proxy\nDOMAIN-SUFFIX,www.100sihu.com,Proxy\nDOMAIN-SUFFIX,edenrules.com,Proxy\nDOMAIN-SUFFIX,ufunr.net,Proxy\nDOMAIN-SUFFIX,www.teenmoviesworld.com,Proxy\nDOMAIN-SUFFIX,southnews.com.tw,Proxy\nDOMAIN-SUFFIX,missav.com,Proxy\nDOMAIN-SUFFIX,uukanshu.com,Proxy\nDOMAIN-SUFFIX,proxylisty.com,Proxy\nDOMAIN-SUFFIX,829.flnet.org,Proxy\nDOMAIN-SUFFIX,335511.cc,Proxy\nDOMAIN-SUFFIX,taiwantt.org.tw,Proxy\nDOMAIN-SUFFIX,fandom.com,Proxy\nDOMAIN-SUFFIX,web.app,Proxy\nDOMAIN-SUFFIX,c074c.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,break.com,Proxy\nDOMAIN-SUFFIX,win777.me,Proxy\nDOMAIN-SUFFIX,daiphapinfo.net,Proxy\nDOMAIN-SUFFIX,eztv.io,Proxy\nDOMAIN-SUFFIX,lists.w3.org,Proxy\nDOMAIN-SUFFIX,vpndada.com,Proxy\nDOMAIN-SUFFIX,gfgold.com.hk,Proxy\nDOMAIN-SUFFIX,loveyoutube.com,Proxy\nDOMAIN-SUFFIX,ecube.us,Proxy\nDOMAIN-SUFFIX,www.owind.com,Proxy\nDOMAIN-SUFFIX,m.kcai969.com,Proxy\nDOMAIN-SUFFIX,chinaelections.org,Proxy\nDOMAIN-SUFFIX,arieltorres.com.ar,Proxy\nDOMAIN-SUFFIX,fl0000.com,Proxy\nDOMAIN-SUFFIX,psychoporntw.com,Proxy\nDOMAIN-SUFFIX,www.kanaloco.jp,Proxy\nDOMAIN-SUFFIX,greatproxies.com,Proxy\nDOMAIN-SUFFIX,haroprocloset.blog.jp,Proxy\nDOMAIN-SUFFIX,1035kissfm.com,Proxy\nDOMAIN-SUFFIX,www.aramex.com,Proxy\nDOMAIN-SUFFIX,paopao13.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,chat1.fastgpt.me,Proxy\nDOMAIN-SUFFIX,www.feng.jp,Proxy\nDOMAIN-SUFFIX,d148iytvv31f8f.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.f88vip743.com,Proxy\nDOMAIN-SUFFIX,goa.minecraftnoob.com,Proxy\nDOMAIN-SUFFIX,vpnreviewz.com,Proxy\nDOMAIN-SUFFIX,google.com.jm,Proxy\nDOMAIN-SUFFIX,wha.la,Proxy\nDOMAIN-SUFFIX,173ng.com,Proxy\nDOMAIN-SUFFIX,www.fcbayern.telekom.de,Proxy\nDOMAIN-SUFFIX,ee699.net,Proxy\nDOMAIN-SUFFIX,hpjav.com,Proxy\nDOMAIN-SUFFIX,www.fun605.com,Proxy\nDOMAIN-SUFFIX,brandonhutchinson.com,Proxy\nDOMAIN-SUFFIX,languagelog.ldc.upenn.edu,Proxy\nDOMAIN-SUFFIX,85.flnet.org,Proxy\nDOMAIN-SUFFIX,peepacquisitionavalanche.com,Proxy\nDOMAIN-SUFFIX,advertisercommunity.com,Proxy\nDOMAIN-SUFFIX,treasureweb.com,Proxy\nDOMAIN-SUFFIX,vcard.ameba.jp,Proxy\nDOMAIN-SUFFIX,85euro.com,Proxy\nDOMAIN-SUFFIX,bw1199.com,Proxy\nDOMAIN-SUFFIX,softs.wtf,Proxy\nDOMAIN-SUFFIX,99b28.com,Proxy\nDOMAIN-SUFFIX,www.ganggarrison.com,Proxy\nDOMAIN-SUFFIX,wokkxv.com,Proxy\nDOMAIN-SUFFIX,translate.google.co.il,Proxy\nDOMAIN-SUFFIX,vpnceping.com,Proxy\nDOMAIN-SUFFIX,commons.wikipeida.org,Proxy\nDOMAIN-SUFFIX,www.myfreevpn.org,Proxy\nDOMAIN-SUFFIX,www.483447.com,Proxy\nDOMAIN-SUFFIX,bityun.org,Proxy\nDOMAIN-SUFFIX,dajiyuan.de,Proxy\nDOMAIN-SUFFIX,vip8.ltyyxb.com,Proxy\nDOMAIN-SUFFIX,hentaiverse.org,Proxy\nDOMAIN-SUFFIX,7209.ca917.com,Proxy\nDOMAIN-SUFFIX,basicframes.com,Proxy\nDOMAIN-SUFFIX,himalaya-exchange.zendesk.com,Proxy\nDOMAIN-SUFFIX,invidio.us,Proxy\nDOMAIN-SUFFIX,www.artsculture.club,Proxy\nDOMAIN-SUFFIX,wallsttv.com,Proxy\nDOMAIN-SUFFIX,dental-tribune.com,Proxy\nDOMAIN-SUFFIX,4lib.org,Proxy\nDOMAIN-SUFFIX,pr23.eu.org,Proxy\nDOMAIN-SUFFIX,www.linux.org,Proxy\nDOMAIN-SUFFIX,146881.com,Proxy\nDOMAIN-SUFFIX,ccue.ca,Proxy\nDOMAIN-SUFFIX,id.oculus.com,Proxy\nDOMAIN-SUFFIX,example.firebaseio.com,Proxy\nDOMAIN-SUFFIX,neowin.net,Proxy\nDOMAIN-SUFFIX,nhentai.com,Proxy\nDOMAIN-SUFFIX,38666876.com,Proxy\nDOMAIN-SUFFIX,cc18tv.com,Proxy\nDOMAIN-SUFFIX,goproxing.net,Proxy\nDOMAIN-SUFFIX,sqy002.jigsy.com,Proxy\nDOMAIN-SUFFIX,221.etowns.net,Proxy\nDOMAIN-SUFFIX,ca7066.com,Proxy\nDOMAIN-SUFFIX,doh.syshero.org,Proxy\nDOMAIN-SUFFIX,tianyinmusic.com,Proxy\nDOMAIN-SUFFIX,www.useetv.com,Proxy\nDOMAIN-SUFFIX,fanhexie.tk,Proxy\nDOMAIN-SUFFIX,fir3beast.com,Proxy\nDOMAIN-SUFFIX,clearsurance.com,Proxy\nDOMAIN-SUFFIX,d3g0izzo2b03j6.cloudfront.net,Proxy\nDOMAIN-SUFFIX,d2ldydr4hn3zon.cloudfront.net,Proxy\nDOMAIN-SUFFIX,xyv6.com,Proxy\nDOMAIN-SUFFIX,casacam.net,Proxy\nDOMAIN-SUFFIX,www.oneplusnews.com,Proxy\nDOMAIN-SUFFIX,isgreat.org,Proxy\nDOMAIN-SUFFIX,eulam.com,Proxy\nDOMAIN-SUFFIX,www.ag9.com,Proxy\nDOMAIN-SUFFIX,chinese.christianpost.com,Proxy\nDOMAIN-SUFFIX,www.tokvtom.xyz,Proxy\nDOMAIN-SUFFIX,store.ui.com.cn,Proxy\nDOMAIN-SUFFIX,oneintranet.veolia.com,Proxy\nDOMAIN-SUFFIX,22.flnet.org,Proxy\nDOMAIN-SUFFIX,wikipedia.vern.cc,Proxy\nDOMAIN-SUFFIX,ladakhkalachakra2014.com,Proxy\nDOMAIN-SUFFIX,sdw1111.com,Proxy\nDOMAIN-SUFFIX,kanata.ro,Proxy\nDOMAIN-SUFFIX,citizenlab.org,Proxy\nDOMAIN-SUFFIX,www.ph158nb.com,Proxy\nDOMAIN-SUFFIX,cn.ibtimes.com,Proxy\nDOMAIN-SUFFIX,tinkoff.ru,Proxy\nDOMAIN-SUFFIX,ghidra-sre.org,Proxy\nDOMAIN-SUFFIX,www.bway88688.com,Proxy\nDOMAIN-SUFFIX,darkcavern.com,Proxy\nDOMAIN-SUFFIX,www.agensir.it,Proxy\nDOMAIN-SUFFIX,vpnbaron.com,Proxy\nDOMAIN-SUFFIX,gcr.io,Proxy\nDOMAIN-SUFFIX,5youtube.com,Proxy\nDOMAIN-SUFFIX,udel.edu,Proxy\nDOMAIN-SUFFIX,lefootix.lescigales.org,Proxy\nDOMAIN-SUFFIX,chinman.net,Proxy\nDOMAIN-SUFFIX,www.aishedes.com,Proxy\nDOMAIN-SUFFIX,addic7ed.com,Proxy\nDOMAIN-SUFFIX,time.com,Proxy\nDOMAIN-SUFFIX,jbtalks.my,Proxy\nDOMAIN-SUFFIX,www.milffox.com,Proxy\nDOMAIN-SUFFIX,thestandard.com.hk,Proxy\nDOMAIN-SUFFIX,n8fwn9fwe.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,memorybbs.com,Proxy\nDOMAIN-SUFFIX,anonymizer.com,Proxy\nDOMAIN-SUFFIX,vote16sf.org,Proxy\nDOMAIN-SUFFIX,xh6666.com,Proxy\nDOMAIN-SUFFIX,boki2.com,Proxy\nDOMAIN-SUFFIX,rv55.com,Proxy\nDOMAIN-SUFFIX,pc.blive.vip,Proxy\nDOMAIN-SUFFIX,www.australianchinesedaily.com.au,Proxy\nDOMAIN-SUFFIX,doh-2.seby.io,Proxy\nDOMAIN-SUFFIX,metacafe.com,Proxy\nDOMAIN-SUFFIX,9afr1.com,Proxy\nDOMAIN-SUFFIX,square-mile-87ba2.firebaseio.com,Proxy\nDOMAIN-SUFFIX,vpngg.com,Proxy\nDOMAIN-SUFFIX,aventertainments.com,Proxy\nDOMAIN-SUFFIX,cupdf.com,Proxy\nDOMAIN-SUFFIX,perplexity.ai,Proxy\nDOMAIN-SUFFIX,b4e2.4.688.org,Proxy\nDOMAIN-SUFFIX,kingminer.com,Proxy\nDOMAIN-SUFFIX,waikeung.net,Proxy\nDOMAIN-SUFFIX,d1uewohueuzm4f.cloudfront.net,Proxy\nDOMAIN-SUFFIX,jmcomic2.mobi,Proxy\nDOMAIN-SUFFIX,sexhdxxx.com,Proxy\nDOMAIN-SUFFIX,pornvpn.com,Proxy\nDOMAIN-SUFFIX,google.tw,Proxy\nDOMAIN-SUFFIX,d2x9xuqj179vf8.cloudfront.net,Proxy\nDOMAIN-SUFFIX,soon.it,Proxy\nDOMAIN-SUFFIX,epochweekly.com,Proxy\nDOMAIN-SUFFIX,t91y.com,Proxy\nDOMAIN-SUFFIX,songri.com,Proxy\nDOMAIN-SUFFIX,accim.org,Proxy\nDOMAIN-SUFFIX,92522u.com,Proxy\nDOMAIN-SUFFIX,ntdtv.jp,Proxy\nDOMAIN-SUFFIX,omco.org,Proxy\nDOMAIN-SUFFIX,51532.ongitv.site,Proxy\nDOMAIN-SUFFIX,www.allsport365.com,Proxy\nDOMAIN-SUFFIX,w.wiki,Proxy\nDOMAIN-SUFFIX,lehu.io,Proxy\nDOMAIN-SUFFIX,wrchina.org,Proxy\nDOMAIN-SUFFIX,google.ng,Proxy\nDOMAIN-SUFFIX,animeidhentai.com,Proxy\nDOMAIN-SUFFIX,yzc853.com,Proxy\nDOMAIN-SUFFIX,ja.erocool.com,Proxy\nDOMAIN-SUFFIX,www.afteroffice.tw,Proxy\nDOMAIN-SUFFIX,nyegroup.org,Proxy\nDOMAIN-SUFFIX,d36d3255o612ec.cloudfront.net,Proxy\nDOMAIN-SUFFIX,y58zt.com,Proxy\nDOMAIN-SUFFIX,srhalloween.com,Proxy\nDOMAIN-SUFFIX,triagrama.cl,Proxy\nDOMAIN-SUFFIX,93xae.com,Proxy\nDOMAIN-SUFFIX,bbs.2dkf.com,Proxy\nDOMAIN-SUFFIX,ikimi.me,Proxy\nDOMAIN-SUFFIX,pixiv.net,Proxy\nDOMAIN-SUFFIX,eurocommerce.biz,Proxy\nDOMAIN-SUFFIX,bullogs.com,Proxy\nDOMAIN-SUFFIX,statsroyale.com,Proxy\nDOMAIN-SUFFIX,razyboard.com,Proxy\nDOMAIN-SUFFIX,sun035.com,Proxy\nDOMAIN-SUFFIX,huan.moe,Proxy\nDOMAIN-SUFFIX,www.takebackyourinternet.com,Proxy\nDOMAIN-SUFFIX,0.wacky-path.xyz,Proxy\nDOMAIN-SUFFIX,jm-comic3.xyz,Proxy\nDOMAIN-SUFFIX,www.taiwan-un-alliance.org.tw,Proxy\nDOMAIN-SUFFIX,www.edninfo.com,Proxy\nDOMAIN-SUFFIX,webhop.me,Proxy\nDOMAIN-SUFFIX,bodog88.com,Proxy\nDOMAIN-SUFFIX,liujianshu.com,Proxy\nDOMAIN-SUFFIX,mvdis.gov.tw,Proxy\nDOMAIN-SUFFIX,www.ymcahk.org.hk,Proxy\nDOMAIN-SUFFIX,plkcy.blogspot.hk,Proxy\nDOMAIN-SUFFIX,smzb.cn,Proxy\nDOMAIN-SUFFIX,se849.com,Proxy\nDOMAIN-SUFFIX,zonghexinwen.net,Proxy\nDOMAIN-SUFFIX,enduyghurforcedlabour.org,Proxy\nDOMAIN-SUFFIX,duckduckhack.com,Proxy\nDOMAIN-SUFFIX,teenporn.com,Proxy\nDOMAIN-SUFFIX,www.445xh.com,Proxy\nDOMAIN-SUFFIX,udn.com.tw,Proxy\nDOMAIN-SUFFIX,dontmovetochina.com,Proxy\nDOMAIN-SUFFIX,porndig.com,Proxy\nDOMAIN-SUFFIX,310359.web.ioshow.com,Proxy\nDOMAIN-SUFFIX,lehuzlak.strikingly.com,Proxy\nDOMAIN-SUFFIX,testcdn.incgate.com,Proxy\nDOMAIN-SUFFIX,eye.flnet.org,Proxy\nDOMAIN-SUFFIX,www.coinbit.co.kr,Proxy\nDOMAIN-SUFFIX,bloom.bg,Proxy\nDOMAIN-SUFFIX,img.sg88.ws,Proxy\nDOMAIN-SUFFIX,siddharthasintent.org,Proxy\nDOMAIN-SUFFIX,videojug.com,Proxy\nDOMAIN-SUFFIX,column.cari.com.my,Proxy\nDOMAIN-SUFFIX,mainprox.com,Proxy\nDOMAIN-SUFFIX,blog.instapaper.com,Proxy\nDOMAIN-SUFFIX,www.volocommerce.com,Proxy\nDOMAIN-SUFFIX,www.holyspiritspeaks.org,Proxy\nDOMAIN-SUFFIX,www.lifevpn.com,Proxy\nDOMAIN-SUFFIX,occupytiananmen.com,Proxy\nDOMAIN-SUFFIX,pornotube.com,Proxy\nDOMAIN-SUFFIX,news.pts.org.tw,Proxy\nDOMAIN-SUFFIX,guided.gg,Proxy\nDOMAIN-SUFFIX,uforadio.com.tw,Proxy\nDOMAIN-SUFFIX,redditstatic.com,Proxy\nDOMAIN-SUFFIX,cdn.shopify.com,Proxy\nDOMAIN-SUFFIX,sop.org,Proxy\nDOMAIN-SUFFIX,hide.me,Proxy\nDOMAIN-SUFFIX,falunthai.org,Proxy\nDOMAIN-SUFFIX,bl-doujinsouko.com,Proxy\nDOMAIN-SUFFIX,566.biz,Proxy\nDOMAIN-SUFFIX,license.uat.widevine.com,Proxy\nDOMAIN-SUFFIX,rthk.org.hk,Proxy\nDOMAIN-SUFFIX,lgvjobs.co.uk,Proxy\nDOMAIN-SUFFIX,sitebro.tw,Proxy\nDOMAIN-SUFFIX,lurex.com.br,Proxy\nDOMAIN-SUFFIX,www.google.com.lb,Proxy\nDOMAIN-SUFFIX,6996add.com,Proxy\nDOMAIN-SUFFIX,tt513.com,Proxy\nDOMAIN-SUFFIX,bythehive.com,Proxy\nDOMAIN-SUFFIX,truelig.co.za,Proxy\nDOMAIN-SUFFIX,graphql.org,Proxy\nDOMAIN-SUFFIX,thirdeyetech.com,Proxy\nDOMAIN-SUFFIX,valuetainment.com,Proxy\nDOMAIN-SUFFIX,reginaandrew.com,Proxy\nDOMAIN-SUFFIX,madonna-av.com,Proxy\nDOMAIN-SUFFIX,w.idaiwan.com,Proxy\nDOMAIN-SUFFIX,voipfone.net,Proxy\nDOMAIN-SUFFIX,news.hk.msn.com,Proxy\nDOMAIN-SUFFIX,mysinablog.com,Proxy\nDOMAIN-SUFFIX,rael.org,Proxy\nDOMAIN-SUFFIX,www.xinjiecloud.com,Proxy\nDOMAIN-SUFFIX,axiao.tw,Proxy\nDOMAIN-SUFFIX,mod.io,Proxy\nDOMAIN-SUFFIX,unblockthatsite.net,Proxy\nDOMAIN-SUFFIX,apk2.tk,Proxy\nDOMAIN-SUFFIX,f-droid.org,Proxy\nDOMAIN-SUFFIX,www.y00123.com,Proxy\nDOMAIN-SUFFIX,www.saturngod.net,Proxy\nDOMAIN-SUFFIX,hopechannel.eu,Proxy\nDOMAIN-SUFFIX,eroticbeauties.net,Proxy\nDOMAIN-SUFFIX,wlrn.org,Proxy\nDOMAIN-SUFFIX,5504q.com,Proxy\nDOMAIN-SUFFIX,www.thinkstockphotos.es,Proxy\nDOMAIN-SUFFIX,bbcurdu.com,Proxy\nDOMAIN-SUFFIX,www.youtubeunblocked.live,Proxy\nDOMAIN-SUFFIX,iqqtv.org,Proxy\nDOMAIN-SUFFIX,bfnn.org,Proxy\nDOMAIN-SUFFIX,eminescusm.ro,Proxy\nDOMAIN-SUFFIX,dkn.tv,Proxy\nDOMAIN-SUFFIX,wizcase.com,Proxy\nDOMAIN-SUFFIX,cn.wsjhk.com,Proxy\nDOMAIN-SUFFIX,blm222.com,Proxy\nDOMAIN-SUFFIX,lrip.org,Proxy\nDOMAIN-SUFFIX,us.to,Proxy\nDOMAIN-SUFFIX,in.us.dwg.us.in,Proxy\nDOMAIN-SUFFIX,freeilhamtohti.org,Proxy\nDOMAIN-SUFFIX,ripple-3dc2d.firebaseio.com,Proxy\nDOMAIN-SUFFIX,blbest.xyz,Proxy\nDOMAIN-SUFFIX,xn--czq75pvv1aj5c.org,Proxy\nDOMAIN-SUFFIX,ozyoyo.com,Proxy\nDOMAIN-SUFFIX,www.yc2357.com,Proxy\nDOMAIN-SUFFIX,nytnow.com,Proxy\nDOMAIN-SUFFIX,tellyawards.com,Proxy\nDOMAIN-SUFFIX,forum.kaiyuan.de,Proxy\nDOMAIN-SUFFIX,paragoncity.com.pk,Proxy\nDOMAIN-SUFFIX,trulyergonomic.com,Proxy\nDOMAIN-SUFFIX,owl.li,Proxy\nDOMAIN-SUFFIX,avdb.tv,Proxy\nDOMAIN-SUFFIX,freeforums.org,Proxy\nDOMAIN-SUFFIX,88095.com,Proxy\nDOMAIN-SUFFIX,ebook.longmabook.com,Proxy\nDOMAIN-SUFFIX,mail.yahoo.co.jp,Proxy\nDOMAIN-SUFFIX,foxsub.com,Proxy\nDOMAIN-SUFFIX,file.flytalk.net,Proxy\nDOMAIN-SUFFIX,rizzolibookstore.com,Proxy\nDOMAIN-SUFFIX,www.jewishpolicycenter.org,Proxy\nDOMAIN-SUFFIX,china21.com,Proxy\nDOMAIN-SUFFIX,google.fm,Proxy\nDOMAIN-SUFFIX,91122jb.com,Proxy\nDOMAIN-SUFFIX,lilith.com.au,Proxy\nDOMAIN-SUFFIX,jacobinmag.com,Proxy\nDOMAIN-SUFFIX,webindia123.com,Proxy\nDOMAIN-SUFFIX,pornsake.com,Proxy\nDOMAIN-SUFFIX,d5j970totype8.cloudfront.net,Proxy\nDOMAIN-SUFFIX,balmey.cl,Proxy\nDOMAIN-SUFFIX,721.deaftone.com,Proxy\nDOMAIN-SUFFIX,nolimitdronez.com,Proxy\nDOMAIN-SUFFIX,nationalpost.com,Proxy\nDOMAIN-SUFFIX,lavozdenicaragua.blogspot.hk,Proxy\nDOMAIN-SUFFIX,ogaoga.org,Proxy\nDOMAIN-SUFFIX,www.google.hu,Proxy\nDOMAIN-SUFFIX,cdcparty.com,Proxy\nDOMAIN-SUFFIX,thegrouplet.com,Proxy\nDOMAIN-SUFFIX,www.funnycat.tv,Proxy\nDOMAIN-SUFFIX,feeds.fileforum.com,Proxy\nDOMAIN-SUFFIX,www.dzcp3555.com,Proxy\nDOMAIN-SUFFIX,aapks.com,Proxy\nDOMAIN-SUFFIX,mytuitui.com,Proxy\nDOMAIN-SUFFIX,www.alexanderforbes.co.za,Proxy\nDOMAIN-SUFFIX,www.24proxy.com,Proxy\nDOMAIN-SUFFIX,epochtimestr.com,Proxy\nDOMAIN-SUFFIX,redwolfairsoft.com,Proxy\nDOMAIN-SUFFIX,qjvpn.com,Proxy\nDOMAIN-SUFFIX,www.coolux.be,Proxy\nDOMAIN-SUFFIX,bbcchinese.com,Proxy\nDOMAIN-SUFFIX,handiyan.web.id,Proxy\nDOMAIN-SUFFIX,www.northerndailyleader.com.au,Proxy\nDOMAIN-SUFFIX,pornhub.it,Proxy\nDOMAIN-SUFFIX,d1zv7wo1ggoi6k.cloudfront.net,Proxy\nDOMAIN-SUFFIX,sg.pampered-chefs.com,Proxy\nDOMAIN-SUFFIX,globalvoicesonline.org,Proxy\nDOMAIN-SUFFIX,metroride.hk,Proxy\nDOMAIN-SUFFIX,s3-ap-northeast-1.amazonaws.com,Proxy\nDOMAIN-SUFFIX,typora.io,Proxy\nDOMAIN-SUFFIX,www.14rabbits.dojin.com,Proxy\nDOMAIN-SUFFIX,devilsfilm.com,Proxy\nDOMAIN-SUFFIX,52ssr.cn,Proxy\nDOMAIN-SUFFIX,bdsmtv.co,Proxy\nDOMAIN-SUFFIX,bbbcca.com,Proxy\nDOMAIN-SUFFIX,m.j35568.com,Proxy\nDOMAIN-SUFFIX,virtual.uniacc.cl,Proxy\nDOMAIN-SUFFIX,sodopee.com,Proxy\nDOMAIN-SUFFIX,serasaexperian.net,Proxy\nDOMAIN-SUFFIX,crisco.com,Proxy\nDOMAIN-SUFFIX,tubeteen18.com,Proxy\nDOMAIN-SUFFIX,www.kuaichuanmirror.com,Proxy\nDOMAIN-SUFFIX,01234js.com,Proxy\nDOMAIN-SUFFIX,ladykd.com,Proxy\nDOMAIN-SUFFIX,www.hak5.org,Proxy\nDOMAIN-SUFFIX,pjmedia.com,Proxy\nDOMAIN-SUFFIX,168kai.com,Proxy\nDOMAIN-SUFFIX,thetinhat.com,Proxy\nDOMAIN-SUFFIX,aabc.gq,Proxy\nDOMAIN-SUFFIX,vpn.nestle.com,Proxy\nDOMAIN-SUFFIX,uyghur.co.uk,Proxy\nDOMAIN-SUFFIX,prediki.com,Proxy\nDOMAIN-SUFFIX,filmy.olabloga.pl,Proxy\nDOMAIN-SUFFIX,caoliu.la,Proxy\nDOMAIN-SUFFIX,photonmedia.net,Proxy\nDOMAIN-SUFFIX,voaafrica.com,Proxy\nDOMAIN-SUFFIX,breakwa11.github.io,Proxy\nDOMAIN-SUFFIX,bryantpark.org,Proxy\nDOMAIN-SUFFIX,1000nik.blogspot.hk,Proxy\nDOMAIN-SUFFIX,coinut.com,Proxy\nDOMAIN-SUFFIX,33pk9.com,Proxy\nDOMAIN-SUFFIX,casino.williamhill.com,Proxy\nDOMAIN-SUFFIX,bbwoftheyear.com,Proxy\nDOMAIN-SUFFIX,web.respondus.com,Proxy\nDOMAIN-SUFFIX,bic2011.org,Proxy\nDOMAIN-SUFFIX,news.godsdirectcontact.net,Proxy\nDOMAIN-SUFFIX,www.thecourier.com.au,Proxy\nDOMAIN-SUFFIX,www.mirrormediagroup.com,Proxy\nDOMAIN-SUFFIX,xh7b.com,Proxy\nDOMAIN-SUFFIX,minghui.cc,Proxy\nDOMAIN-SUFFIX,us-central1-ecai2020-prod.cloudfunctions.net,Proxy\nDOMAIN-SUFFIX,todayonline.com,Proxy\nDOMAIN-SUFFIX,sohografica.com,Proxy\nDOMAIN-SUFFIX,saunaguide88.com,Proxy\nDOMAIN-SUFFIX,mondex.org,Proxy\nDOMAIN-SUFFIX,www.kose.co.jp,Proxy\nDOMAIN-SUFFIX,perlproxy.com,Proxy\nDOMAIN-SUFFIX,udnbkk.com,Proxy\nDOMAIN-SUFFIX,scopemarkets.com,Proxy\nDOMAIN-SUFFIX,www.jbo073.com,Proxy\nDOMAIN-SUFFIX,timtales.com,Proxy\nDOMAIN-SUFFIX,gqt20.jdz.ro,Proxy\nDOMAIN-SUFFIX,travel.ulifestyle.com.hk,Proxy\nDOMAIN-SUFFIX,droupnir.com,Proxy\nDOMAIN-SUFFIX,dpr.info,Proxy\nDOMAIN-SUFFIX,www.5zuo2.com,Proxy\nDOMAIN-SUFFIX,faluncanada.net,Proxy\nDOMAIN-SUFFIX,shahit.biz,Proxy\nDOMAIN-SUFFIX,haaretz.co.il,Proxy\nDOMAIN-SUFFIX,juanjoseflores.com.ar,Proxy\nDOMAIN-SUFFIX,www.188games.net,Proxy\nDOMAIN-SUFFIX,shotasekai.club,Proxy\nDOMAIN-SUFFIX,799740.cc,Proxy\nDOMAIN-SUFFIX,www.cabet165.com,Proxy\nDOMAIN-SUFFIX,thisav.tw,Proxy\nDOMAIN-SUFFIX,myworkday.com,Proxy\nDOMAIN-SUFFIX,www.triquanta.nl.global.prod.fastly.net,Proxy\nDOMAIN-SUFFIX,vwin199.com,Proxy\nDOMAIN-SUFFIX,berlintwitterwall.com,Proxy\nDOMAIN-SUFFIX,dnsshop.xyz,Proxy\nDOMAIN-SUFFIX,beta.osmobot.com,Proxy\nDOMAIN-SUFFIX,www.hj183.com,Proxy\nDOMAIN-SUFFIX,mapp-web.rapawfm.com,Proxy\nDOMAIN-SUFFIX,www.xglory.tk,Proxy\nDOMAIN-SUFFIX,tuiqiangfoundation.org,Proxy\nDOMAIN-SUFFIX,bookstore.emome.net,Proxy\nDOMAIN-SUFFIX,1pondo.tv,Proxy\nDOMAIN-SUFFIX,tiny.cc,Proxy\nDOMAIN-SUFFIX,faithweb.com,Proxy\nDOMAIN-SUFFIX,xn--2qe.com,Proxy\nDOMAIN-SUFFIX,deviantart.com.com,Proxy\nDOMAIN-SUFFIX,forum.culteducation.com,Proxy\nDOMAIN-SUFFIX,extremescatporn.com,Proxy\nDOMAIN-SUFFIX,freepst.com,Proxy\nDOMAIN-SUFFIX,circlethebayfortibet.org,Proxy\nDOMAIN-SUFFIX,hdzone.me,Proxy\nDOMAIN-SUFFIX,antichristendom.com,Proxy\nDOMAIN-SUFFIX,vajrapani.org,Proxy\nDOMAIN-SUFFIX,080.34c.cc,Proxy\nDOMAIN-SUFFIX,www.fun371.com,Proxy\nDOMAIN-SUFFIX,nyt7.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,6.gw.lt,Proxy\nDOMAIN-SUFFIX,apidocs.linksalpha.com,Proxy\nDOMAIN-SUFFIX,retweetrank.com,Proxy\nDOMAIN-SUFFIX,d1oar7wgo49p2u.cloudfront.net,Proxy\nDOMAIN-SUFFIX,jappy.us,Proxy\nDOMAIN-SUFFIX,peace.ca,Proxy\nDOMAIN-SUFFIX,www.haoli797.com,Proxy\nDOMAIN-SUFFIX,self.gutenberg.org,Proxy\nDOMAIN-SUFFIX,gci.jdbebook.com,Proxy\nDOMAIN-SUFFIX,1dpw.com,Proxy\nDOMAIN-SUFFIX,bbsfeed.com,Proxy\nDOMAIN-SUFFIX,wwwhost.biz,Proxy\nDOMAIN-SUFFIX,www.tvs-spa.it,Proxy\nDOMAIN-SUFFIX,lci.tf1.fr,Proxy\nDOMAIN-SUFFIX,go2win.vip,Proxy\nDOMAIN-SUFFIX,twtich.com,Proxy\nDOMAIN-SUFFIX,cam4.sg,Proxy\nDOMAIN-SUFFIX,bounceme.net,Proxy\nDOMAIN-SUFFIX,sipml5.org,Proxy\nDOMAIN-SUFFIX,www.dreamtripslife.com,Proxy\nDOMAIN-SUFFIX,1113mm.com,Proxy\nDOMAIN-SUFFIX,www.june4.org,Proxy\nDOMAIN-SUFFIX,business-standard.com,Proxy\nDOMAIN-SUFFIX,www.dungogchronicle.com.au,Proxy\nDOMAIN-SUFFIX,reuters.it,Proxy\nDOMAIN-SUFFIX,5ll.am,Proxy\nDOMAIN-SUFFIX,chinayuanmin.org,Proxy\nDOMAIN-SUFFIX,btok.co,Proxy\nDOMAIN-SUFFIX,www.e8076.com,Proxy\nDOMAIN-SUFFIX,www.cafepress.com.au,Proxy\nDOMAIN-SUFFIX,ooo36.net,Proxy\nDOMAIN-SUFFIX,d3cjyraq8e5hkz.cloudfront.net,Proxy\nDOMAIN-SUFFIX,serveris.id.lv,Proxy\nDOMAIN-SUFFIX,jiduvpn.com,Proxy\nDOMAIN-SUFFIX,bnn.co,Proxy\nDOMAIN-SUFFIX,my.nintendo.com,Proxy\nDOMAIN-SUFFIX,szzd1.github.io,Proxy\nDOMAIN-SUFFIX,glype.com,Proxy\nDOMAIN-SUFFIX,wordpress.youran.me,Proxy\nDOMAIN-SUFFIX,affiliates.letou.com,Proxy\nDOMAIN-SUFFIX,telegram-cdn.org,Proxy\nDOMAIN-SUFFIX,tv.3w12.com,Proxy\nDOMAIN-SUFFIX,www.equinenow.com,Proxy\nDOMAIN-SUFFIX,d1uomndotjm500.cloudfront.net,Proxy\nDOMAIN-SUFFIX,schaadstoff.ch,Proxy\nDOMAIN-SUFFIX,go.ss-get.com,Proxy\nDOMAIN-SUFFIX,macauhr.com,Proxy\nDOMAIN-SUFFIX,www.danmuji.org,Proxy\nDOMAIN-SUFFIX,rumenite.ro,Proxy\nDOMAIN-SUFFIX,wyd2.com.tw,Proxy\nDOMAIN-SUFFIX,xbookcn.com,Proxy\nDOMAIN-SUFFIX,ucos.ro,Proxy\nDOMAIN-SUFFIX,nanopool.org,Proxy\nDOMAIN-SUFFIX,www.amnesty.tw,Proxy\nDOMAIN-SUFFIX,www.eightcap.com,Proxy\nDOMAIN-SUFFIX,989222888.com,Proxy\nDOMAIN-SUFFIX,proxytunnel.net,Proxy\nDOMAIN-SUFFIX,webproxy.yt,Proxy\nDOMAIN-SUFFIX,ry-ss.tk,Proxy\nDOMAIN-SUFFIX,daftsex.com,Proxy\nDOMAIN-SUFFIX,newyorker.com,Proxy\nDOMAIN-SUFFIX,www.macarthuradvertiser.com.au,Proxy\nDOMAIN-SUFFIX,www.plurk.com,Proxy\nDOMAIN-SUFFIX,vdi.cmegroup.com,Proxy\nDOMAIN-SUFFIX,48929.com,Proxy\nDOMAIN-SUFFIX,d2xwei62kcqq25.cloudfront.net,Proxy\nDOMAIN-SUFFIX,acgbuster.net,Proxy\nDOMAIN-SUFFIX,016006.com,Proxy\nDOMAIN-SUFFIX,www.5360a.com,Proxy\nDOMAIN-SUFFIX,www.941hd.com,Proxy\nDOMAIN-SUFFIX,activpn.com,Proxy\nDOMAIN-SUFFIX,www.gvhouse.com,Proxy\nDOMAIN-SUFFIX,graham.ws,Proxy\nDOMAIN-SUFFIX,www.ssgamer.cn,Proxy\nDOMAIN-SUFFIX,ppvpn.com,Proxy\nDOMAIN-SUFFIX,yggdrasil-map.cwinfo.org,Proxy\nDOMAIN-SUFFIX,tbsec.org,Proxy\nDOMAIN-SUFFIX,www.rightheart.org,Proxy\nDOMAIN-SUFFIX,ug.domain888.pw,Proxy\nDOMAIN-SUFFIX,x210165.com,Proxy\nDOMAIN-SUFFIX,apksum.com,Proxy\nDOMAIN-SUFFIX,avhub.tv,Proxy\nDOMAIN-SUFFIX,reuters.pl,Proxy\nDOMAIN-SUFFIX,mainichi.jp,Proxy\nDOMAIN-SUFFIX,www.staxus.com,Proxy\nDOMAIN-SUFFIX,hpa.gov.tw,Proxy\nDOMAIN-SUFFIX,gumroad.helpscoutdocs.com,Proxy\nDOMAIN-SUFFIX,guojiang.site,Proxy\nDOMAIN-SUFFIX,fxdd.com,Proxy\nDOMAIN-SUFFIX,paulsin.blogspot.hk,Proxy\nDOMAIN-SUFFIX,kroomi.com,Proxy\nDOMAIN-SUFFIX,sft-canada.org,Proxy\nDOMAIN-SUFFIX,wellplacedpixels.com,Proxy\nDOMAIN-SUFFIX,radioline.co,Proxy\nDOMAIN-SUFFIX,erogames.com,Proxy\nDOMAIN-SUFFIX,tw.news.yahoo.com,Proxy\nDOMAIN-SUFFIX,jingsim.org,Proxy\nDOMAIN-SUFFIX,clinch.io,Proxy\nDOMAIN-SUFFIX,maa1807.com,Proxy\nDOMAIN-SUFFIX,zzx.dnsmail.xyz,Proxy\nDOMAIN-SUFFIX,gongyiluntan.org,Proxy\nDOMAIN-SUFFIX,zh66.xp3.biz,Proxy\nDOMAIN-SUFFIX,pu6633.com,Proxy\nDOMAIN-SUFFIX,valid.x86.fr,Proxy\nDOMAIN-SUFFIX,scri.siena.edu,Proxy\nDOMAIN-SUFFIX,www.reabble.com,Proxy\nDOMAIN-SUFFIX,t69y.com,Proxy\nDOMAIN-SUFFIX,d3vmmtgdwgp8tk.cloudfront.net,Proxy\nDOMAIN-SUFFIX,civitai.com,Proxy\nDOMAIN-SUFFIX,freess.pw,Proxy\nDOMAIN-SUFFIX,cdpwu.org,Proxy\nDOMAIN-SUFFIX,google.com.ly,Proxy\nDOMAIN-SUFFIX,server.surespot.me,Proxy\nDOMAIN-SUFFIX,eveonline-pvp.es.tl,Proxy\nDOMAIN-SUFFIX,www.toonippo.co.jp,Proxy\nDOMAIN-SUFFIX,intl.fender.com,Proxy\nDOMAIN-SUFFIX,docsplayer.com,Proxy\nDOMAIN-SUFFIX,www.audm.com,Proxy\nDOMAIN-SUFFIX,nitter.foss.wtf,Proxy\nDOMAIN-SUFFIX,www.maximilianhoeppler.com,Proxy\nDOMAIN-SUFFIX,crystal-energy-kai.blogspot.ca,Proxy\nDOMAIN-SUFFIX,lds.about.com,Proxy\nDOMAIN-SUFFIX,www.usechicagotitle.com,Proxy\nDOMAIN-SUFFIX,www.lo222.com,Proxy\nDOMAIN-SUFFIX,cms.jgg18.me,Proxy\nDOMAIN-SUFFIX,pilihan-anda.blogspot.hk,Proxy\nDOMAIN-SUFFIX,6134684.com,Proxy\nDOMAIN-SUFFIX,gci.138789.com,Proxy\nDOMAIN-SUFFIX,yahoogroups.com,Proxy\nDOMAIN-SUFFIX,www.141jav.com,Proxy\nDOMAIN-SUFFIX,glorystar.me,Proxy\nDOMAIN-SUFFIX,googlechinawebmaster.com,Proxy\nDOMAIN-SUFFIX,www.thinkstockphotos.jp,Proxy\nDOMAIN-SUFFIX,23.etowns.net,Proxy\nDOMAIN-SUFFIX,www.jkforum.net,Proxy\nDOMAIN-SUFFIX,s3.ap-south-1.amazonaws.com,Proxy\nDOMAIN-SUFFIX,amtb-taipei.org,Proxy\nDOMAIN-SUFFIX,sports.188betkr.com,Proxy\nDOMAIN-SUFFIX,www.blooket.com,Proxy\nDOMAIN-SUFFIX,bypasscensorship.org,Proxy\nDOMAIN-SUFFIX,02xam.com,Proxy\nDOMAIN-SUFFIX,tor-exit-60.for-privacy.net,Proxy\nDOMAIN-SUFFIX,blogspot.com.br,Proxy\nDOMAIN-SUFFIX,www.ginmon.de,Proxy\nDOMAIN-SUFFIX,www.boyangu.com,Proxy\nDOMAIN-SUFFIX,chatgpt.nextweb.fun,Proxy\nDOMAIN-SUFFIX,fubo.com,Proxy\nDOMAIN-SUFFIX,p2es.com,Proxy\nDOMAIN-SUFFIX,www.iri.org,Proxy\nDOMAIN-SUFFIX,www.mygopen.com,Proxy\nDOMAIN-SUFFIX,www.catchgod.com,Proxy\nDOMAIN-SUFFIX,goge.ml,Proxy\nDOMAIN-SUFFIX,dimevpn.com,Proxy\nDOMAIN-SUFFIX,mct188.com,Proxy\nDOMAIN-SUFFIX,qoshe.com,Proxy\nDOMAIN-SUFFIX,jieduanxin.com,Proxy\nDOMAIN-SUFFIX,chromium.woolyss.com,Proxy\nDOMAIN-SUFFIX,ssl.panoramio.com,Proxy\nDOMAIN-SUFFIX,creaders.net,Proxy\nDOMAIN-SUFFIX,wheelockslatin.com,Proxy\nDOMAIN-SUFFIX,runtrax.net,Proxy\nDOMAIN-SUFFIX,www.factchecklab.org,Proxy\nDOMAIN-SUFFIX,svencoop.fr,Proxy\nDOMAIN-SUFFIX,news.sina.com.hk,Proxy\nDOMAIN-SUFFIX,catpro.io,Proxy\nDOMAIN-SUFFIX,us.weibo.com,Proxy\nDOMAIN-SUFFIX,www.disscuss.com,Proxy\nDOMAIN-SUFFIX,18comic1.biz,Proxy\nDOMAIN-SUFFIX,cangku.moe,Proxy\nDOMAIN-SUFFIX,5278.cc,Proxy\nDOMAIN-SUFFIX,pandavpnpro.com,Proxy\nDOMAIN-SUFFIX,beeminder.com,Proxy\nDOMAIN-SUFFIX,zzt.healthgov.xyz,Proxy\nDOMAIN-SUFFIX,worldvegetarianday.org,Proxy\nDOMAIN-SUFFIX,www.hmoe11.net,Proxy\nDOMAIN-SUFFIX,216.slyip.com,Proxy\nDOMAIN-SUFFIX,m1.rm-845.com,Proxy\nDOMAIN-SUFFIX,streamusea1su021.azureedge.net,Proxy\nDOMAIN-SUFFIX,mplol.com,Proxy\nDOMAIN-SUFFIX,pronounsday.org,Proxy\nDOMAIN-SUFFIX,menhdv.com,Proxy\nDOMAIN-SUFFIX,viva-rev2.github.io,Proxy\nDOMAIN-SUFFIX,www.wixsite.com,Proxy\nDOMAIN-SUFFIX,xv202106.xyz,Proxy\nDOMAIN-SUFFIX,www.iheart.com,Proxy\nDOMAIN-SUFFIX,googleplus.com,Proxy\nDOMAIN-SUFFIX,uighur.nl,Proxy\nDOMAIN-SUFFIX,www.vomkorea.kr,Proxy\nDOMAIN-SUFFIX,is-a-soxfan.org,Proxy\nDOMAIN-SUFFIX,jyxf.net,Proxy\nDOMAIN-SUFFIX,www.mysinchew.com,Proxy\nDOMAIN-SUFFIX,d2x2nunjal7182.cloudfront.net,Proxy\nDOMAIN-SUFFIX,ihearttibet.org,Proxy\nDOMAIN-SUFFIX,www.bustedandexposed.com,Proxy\nDOMAIN-SUFFIX,www.hacg.la,Proxy\nDOMAIN-SUFFIX,731bm.com,Proxy\nDOMAIN-SUFFIX,iqq1.one,Proxy\nDOMAIN-SUFFIX,ywam.org,Proxy\nDOMAIN-SUFFIX,netdb.i2p2.de,Proxy\nDOMAIN-SUFFIX,paopao16.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,lzhwp.org,Proxy\nDOMAIN-SUFFIX,knowyourcustomer.com,Proxy\nDOMAIN-SUFFIX,sproxy.info,Proxy\nDOMAIN-SUFFIX,29044.net,Proxy\nDOMAIN-SUFFIX,ondaxv.xyz,Proxy\nDOMAIN-SUFFIX,www.iwantclips.com,Proxy\nDOMAIN-SUFFIX,cq99.us,Proxy\nDOMAIN-SUFFIX,bf5888.com,Proxy\nDOMAIN-SUFFIX,meebo.com,Proxy\nDOMAIN-SUFFIX,webproxyusa.com,Proxy\nDOMAIN-SUFFIX,jpname.blogspot.hk,Proxy\nDOMAIN-SUFFIX,purevpn.com,Proxy\nDOMAIN-SUFFIX,english.astroawani.com,Proxy\nDOMAIN-SUFFIX,streamer.radio.co,Proxy\nDOMAIN-SUFFIX,gougoubt.org,Proxy\nDOMAIN-SUFFIX,pinoy-n.com,Proxy\nDOMAIN-SUFFIX,cnnmon.ie,Proxy\nDOMAIN-SUFFIX,freenetproject.org,Proxy\nDOMAIN-SUFFIX,defenddemocracy.org,Proxy\nDOMAIN-SUFFIX,percy.in,Proxy\nDOMAIN-SUFFIX,d2l8qurxdxsct3.cloudfront.net,Proxy\nDOMAIN-SUFFIX,sourceforge.net,Proxy\nDOMAIN-SUFFIX,www.gamebase.com.tw,Proxy\nDOMAIN-SUFFIX,ausnz.net,Proxy\nDOMAIN-SUFFIX,blip.tv,Proxy\nDOMAIN-SUFFIX,shu9.gr8domain.biz,Proxy\nDOMAIN-SUFFIX,bigfishgames.com,Proxy\nDOMAIN-SUFFIX,hexieshe.xyz,Proxy\nDOMAIN-SUFFIX,pwmn.net,Proxy\nDOMAIN-SUFFIX,www.fsebookstore.com,Proxy\nDOMAIN-SUFFIX,sibylcloud.com,Proxy\nDOMAIN-SUFFIX,juegosdiarios.com,Proxy\nDOMAIN-SUFFIX,www.a202.net,Proxy\nDOMAIN-SUFFIX,www.fakingnews.firstpost.com,Proxy\nDOMAIN-SUFFIX,kinkcult.com,Proxy\nDOMAIN-SUFFIX,www.mi-lorenteggio.com,Proxy\nDOMAIN-SUFFIX,www.op-online.de,Proxy\nDOMAIN-SUFFIX,dinsound.net,Proxy\nDOMAIN-SUFFIX,asiatgp.com,Proxy\nDOMAIN-SUFFIX,piraattilahti.org,Proxy\nDOMAIN-SUFFIX,www.shikoto.com,Proxy\nDOMAIN-SUFFIX,jumptalking.com,Proxy\nDOMAIN-SUFFIX,qz.com,Proxy\nDOMAIN-SUFFIX,speed.wyqn.net,Proxy\nDOMAIN-SUFFIX,www.chqvpn.com,Proxy\nDOMAIN-SUFFIX,baid.us,Proxy\nDOMAIN-SUFFIX,nl.proxfree.com,Proxy\nDOMAIN-SUFFIX,signbucks.com,Proxy\nDOMAIN-SUFFIX,r3---sn-uxa0n-t8gz.xn--ngstr-lra8j.com,Proxy\nDOMAIN-SUFFIX,logmein.com,Proxy\nDOMAIN-SUFFIX,www.sislovesme.com,Proxy\nDOMAIN-SUFFIX,lotuslight.org.tw,Proxy\nDOMAIN-SUFFIX,javdude.com,Proxy\nDOMAIN-SUFFIX,weihuo.org,Proxy\nDOMAIN-SUFFIX,www.sologirlpussy.com,Proxy\nDOMAIN-SUFFIX,d1pc6kn84br5w.cloudfront.net,Proxy\nDOMAIN-SUFFIX,f1880.com,Proxy\nDOMAIN-SUFFIX,www.cf0009.com,Proxy\nDOMAIN-SUFFIX,immoral.jp,Proxy\nDOMAIN-SUFFIX,www.btspread.com,Proxy\nDOMAIN-SUFFIX,www.cup.com.hk,Proxy\nDOMAIN-SUFFIX,www.uschamber.com,Proxy\nDOMAIN-SUFFIX,bookepub.com,Proxy\nDOMAIN-SUFFIX,bronzfederation.org.nz,Proxy\nDOMAIN-SUFFIX,covertproxy.net,Proxy\nDOMAIN-SUFFIX,df319.com,Proxy\nDOMAIN-SUFFIX,myuni.adelaide.edu.au,Proxy\nDOMAIN-SUFFIX,irn.com,Proxy\nDOMAIN-SUFFIX,netme.cc,Proxy\nDOMAIN-SUFFIX,laoyang.info,Proxy\nDOMAIN-SUFFIX,durnyi.blog.shinobi.jp,Proxy\nDOMAIN-SUFFIX,www.wit-gelekruisvlaamsbrabant.be,Proxy\nDOMAIN-SUFFIX,canalisystem.org,Proxy\nDOMAIN-SUFFIX,hongkongerscharacter.blogspot.hk,Proxy\nDOMAIN-SUFFIX,k-doujin.net,Proxy\nDOMAIN-SUFFIX,plsqx.com,Proxy\nDOMAIN-SUFFIX,murcia.es,Proxy\nDOMAIN-SUFFIX,tibetanbuddhistcentre.org.nz,Proxy\nDOMAIN-SUFFIX,valdo.co.id,Proxy\nDOMAIN-SUFFIX,humanrightstorch.org,Proxy\nDOMAIN-SUFFIX,9xbuddy.com,Proxy\nDOMAIN-SUFFIX,bookbeat.com,Proxy\nDOMAIN-SUFFIX,zzw.healthonsite.xyz,Proxy\nDOMAIN-SUFFIX,22.cr.rs,Proxy\nDOMAIN-SUFFIX,insidemaps.com,Proxy\nDOMAIN-SUFFIX,opensea.io,Proxy\nDOMAIN-SUFFIX,a7conf.com,Proxy\nDOMAIN-SUFFIX,w3p.la,Proxy\nDOMAIN-SUFFIX,www.yuntipub.com,Proxy\nDOMAIN-SUFFIX,cthia.net,Proxy\nDOMAIN-SUFFIX,warontherocks.com,Proxy\nDOMAIN-SUFFIX,zzy.healthcon.xyz,Proxy\nDOMAIN-SUFFIX,a-laiturit.fi,Proxy\nDOMAIN-SUFFIX,rue89.com,Proxy\nDOMAIN-SUFFIX,risuntravel.com,Proxy\nDOMAIN-SUFFIX,synoserver.com,Proxy\nDOMAIN-SUFFIX,www.reedexpovip.com,Proxy\nDOMAIN-SUFFIX,google.kr,Proxy\nDOMAIN-SUFFIX,www.ocschools.org,Proxy\nDOMAIN-SUFFIX,www.qishivpn.com,Proxy\nDOMAIN-SUFFIX,blog.0x427567.com,Proxy\nDOMAIN-SUFFIX,91xab.com,Proxy\nDOMAIN-SUFFIX,cinemashop.com,Proxy\nDOMAIN-SUFFIX,wb.aeweb.xyz,Proxy\nDOMAIN-SUFFIX,sidelinesnews.com,Proxy\nDOMAIN-SUFFIX,www.salamwatandar.com,Proxy\nDOMAIN-SUFFIX,kai8.com,Proxy\nDOMAIN-SUFFIX,www1.biz,Proxy\nDOMAIN-SUFFIX,natbees.cl,Proxy\nDOMAIN-SUFFIX,fuqvids.com,Proxy\nDOMAIN-SUFFIX,tube8freeporn.com,Proxy\nDOMAIN-SUFFIX,vincentkwok.hk,Proxy\nDOMAIN-SUFFIX,www.sunskyforum.com,Proxy\nDOMAIN-SUFFIX,zh.buzzhand.com,Proxy\nDOMAIN-SUFFIX,d2zdx6kvd7pln6.cloudfront.net,Proxy\nDOMAIN-SUFFIX,gate-project.com,Proxy\nDOMAIN-SUFFIX,next11.co.jp,Proxy\nDOMAIN-SUFFIX,www.unashamedimpact.com,Proxy\nDOMAIN-SUFFIX,x.com,Proxy\nDOMAIN-SUFFIX,vpnpm.com,Proxy\nDOMAIN-SUFFIX,www.thefrontierpost.com,Proxy\nDOMAIN-SUFFIX,xxx.manhattansez.com,Proxy\nDOMAIN-SUFFIX,www.bookwalker.com.tw,Proxy\nDOMAIN-SUFFIX,bbs.hostevaluate.com,Proxy\nDOMAIN-SUFFIX,rasbihari.com,Proxy\nDOMAIN-SUFFIX,888.sy0606.com,Proxy\nDOMAIN-SUFFIX,sexy.com,Proxy\nDOMAIN-SUFFIX,www.vozchina.org,Proxy\nDOMAIN-SUFFIX,cnyoutube.com,Proxy\nDOMAIN-SUFFIX,venbbs.com,Proxy\nDOMAIN-SUFFIX,rei5.cleansite.us,Proxy\nDOMAIN-SUFFIX,ultimate-guitar.com,Proxy\nDOMAIN-SUFFIX,www.e8532.com,Proxy\nDOMAIN-SUFFIX,rapleaf.com,Proxy\nDOMAIN-SUFFIX,www.usechinavpn.com,Proxy\nDOMAIN-SUFFIX,xh0778.com,Proxy\nDOMAIN-SUFFIX,anugrah-steel.com,Proxy\nDOMAIN-SUFFIX,uyghurcanadian.ca,Proxy\nDOMAIN-SUFFIX,getipintel.com,Proxy\nDOMAIN-SUFFIX,ticsur.cl,Proxy\nDOMAIN-SUFFIX,www.lockchou.idv.tw,Proxy\nDOMAIN-SUFFIX,www.yrcr8.com,Proxy\nDOMAIN-SUFFIX,pictame.com,Proxy\nDOMAIN-SUFFIX,www.bway883.com,Proxy\nDOMAIN-SUFFIX,www.tiananmen1989.net,Proxy\nDOMAIN-SUFFIX,freewebs.com,Proxy\nDOMAIN-SUFFIX,eletrica.eng.br,Proxy\nDOMAIN-SUFFIX,pastebin.com,Proxy\nDOMAIN-SUFFIX,dhcp.biz,Proxy\nDOMAIN-SUFFIX,redxxxvideo.org,Proxy\nDOMAIN-SUFFIX,1919com.app,Proxy\nDOMAIN-SUFFIX,rx40.com,Proxy\nDOMAIN-SUFFIX,www.52ssr.net,Proxy\nDOMAIN-SUFFIX,y2care.com,Proxy\nDOMAIN-SUFFIX,avslot.com,Proxy\nDOMAIN-SUFFIX,priv.au,Proxy\nDOMAIN-SUFFIX,overplay.net,Proxy\nDOMAIN-SUFFIX,www.expatsurfer.co.uk,Proxy\nDOMAIN-SUFFIX,itasoftware.com,Proxy\nDOMAIN-SUFFIX,dns05.com,Proxy\nDOMAIN-SUFFIX,haoli777.com,Proxy\nDOMAIN-SUFFIX,ophandbook.e-shepherding.org,Proxy\nDOMAIN-SUFFIX,red.org,Proxy\nDOMAIN-SUFFIX,michaelabieri.com,Proxy\nDOMAIN-SUFFIX,chinesedemocracy.com,Proxy\nDOMAIN-SUFFIX,twiffo.com,Proxy\nDOMAIN-SUFFIX,wjvpn.com,Proxy\nDOMAIN-SUFFIX,disp.cc,Proxy\nDOMAIN-SUFFIX,shanghai.china-tripnavi.com,Proxy\nDOMAIN-SUFFIX,yigeni.com,Proxy\nDOMAIN-SUFFIX,nztd2.com,Proxy\nDOMAIN-SUFFIX,goosz.com,Proxy\nDOMAIN-SUFFIX,mj.yarnowl.com,Proxy\nDOMAIN-SUFFIX,voagd.com,Proxy\nDOMAIN-SUFFIX,bfvpn.com,Proxy\nDOMAIN-SUFFIX,fulibl.net,Proxy\nDOMAIN-SUFFIX,barton.de,Proxy\nDOMAIN-SUFFIX,economist.com,Proxy\nDOMAIN-SUFFIX,uncyclopedia.hk,Proxy\nDOMAIN-SUFFIX,avdb.in,Proxy\nDOMAIN-SUFFIX,www.jamawarnews.com,Proxy\nDOMAIN-SUFFIX,foxdie.us,Proxy\nDOMAIN-SUFFIX,42842824.com,Proxy\nDOMAIN-SUFFIX,hentaitube.tv,Proxy\nDOMAIN-SUFFIX,viber.com,Proxy\nDOMAIN-SUFFIX,www.wethehongkongers.org,Proxy\nDOMAIN-SUFFIX,xx-map.com,Proxy\nDOMAIN-SUFFIX,caviexpress.net,Proxy\nDOMAIN-SUFFIX,shejav.com,Proxy\nDOMAIN-SUFFIX,bcp.instructure.com,Proxy\nDOMAIN-SUFFIX,freess.cx,Proxy\nDOMAIN-SUFFIX,lamatriz.org,Proxy\nDOMAIN-SUFFIX,www.kyleyan.com,Proxy\nDOMAIN-SUFFIX,globalmeet.com,Proxy\nDOMAIN-SUFFIX,www.vultur.com,Proxy\nDOMAIN-SUFFIX,www.javbus.co,Proxy\nDOMAIN-SUFFIX,tecnomuda.pt,Proxy\nDOMAIN-SUFFIX,goregrish.com,Proxy\nDOMAIN-SUFFIX,arzon.jp,Proxy\nDOMAIN-SUFFIX,www.hj6093.com,Proxy\nDOMAIN-SUFFIX,strangled.net,Proxy\nDOMAIN-SUFFIX,itnext.io,Proxy\nDOMAIN-SUFFIX,www.fun505.com,Proxy\nDOMAIN-SUFFIX,chinaview.wordpress.com,Proxy\nDOMAIN-SUFFIX,growthy-release-growthywebcollector-80.gcld-line.com,Proxy\nDOMAIN-SUFFIX,rxhj.net,Proxy\nDOMAIN-SUFFIX,google.rs,Proxy\nDOMAIN-SUFFIX,my7.cc,Proxy\nDOMAIN-SUFFIX,213808.app,Proxy\nDOMAIN-SUFFIX,musicade.net,Proxy\nDOMAIN-SUFFIX,nic.google,Proxy\nDOMAIN-SUFFIX,ilookchina.net,Proxy\nDOMAIN-SUFFIX,bdg88.com,Proxy\nDOMAIN-SUFFIX,fun8011.com,Proxy\nDOMAIN-SUFFIX,elojoesceptico.com.ar,Proxy\nDOMAIN-SUFFIX,www.randyblue.com,Proxy\nDOMAIN-SUFFIX,d32pt9ivjjofmj.cloudfront.net,Proxy\nDOMAIN-SUFFIX,telecomix.org,Proxy\nDOMAIN-SUFFIX,bb9617.pw,Proxy\nDOMAIN-SUFFIX,mcadforums.com,Proxy\nDOMAIN-SUFFIX,take-a-screenshot.org,Proxy\nDOMAIN-SUFFIX,uocn.org,Proxy\nDOMAIN-SUFFIX,guaneryu.com,Proxy\nDOMAIN-SUFFIX,www.cgview.com.tw,Proxy\nDOMAIN-SUFFIX,www.irsem.fr,Proxy\nDOMAIN-SUFFIX,www.oculus.com,Proxy\nDOMAIN-SUFFIX,nottinghampost.com,Proxy\nDOMAIN-SUFFIX,www.ogrish.tv,Proxy\nDOMAIN-SUFFIX,799299.com,Proxy\nDOMAIN-SUFFIX,nytstyle.com,Proxy\nDOMAIN-SUFFIX,apps.evozi.com,Proxy\nDOMAIN-SUFFIX,dl.discordapp.net,Proxy\nDOMAIN-SUFFIX,t.cn,Proxy\nDOMAIN-SUFFIX,www.reutersagency.cn,Proxy\nDOMAIN-SUFFIX,benaughty.com,Proxy\nDOMAIN-SUFFIX,www.saveclipbro.com,Proxy\nDOMAIN-SUFFIX,mymediarom.com,Proxy\nDOMAIN-SUFFIX,tucao.one,Proxy\nDOMAIN-SUFFIX,nokola.com,Proxy\nDOMAIN-SUFFIX,p67z.com,Proxy\nDOMAIN-SUFFIX,wailaike.net,Proxy\nDOMAIN-SUFFIX,gclooney.com,Proxy\nDOMAIN-SUFFIX,www.wikipedia.shutcm.cf,Proxy\nDOMAIN-SUFFIX,cyprus-mail.com,Proxy\nDOMAIN-SUFFIX,www.xf836.com,Proxy\nDOMAIN-SUFFIX,izismile.com,Proxy\nDOMAIN-SUFFIX,daniellaw.me,Proxy\nDOMAIN-SUFFIX,lilyspadd.com,Proxy\nDOMAIN-SUFFIX,www.youtube.nl,Proxy\nDOMAIN-SUFFIX,realgfporn.com,Proxy\nDOMAIN-SUFFIX,www.worldnetdaily.com,Proxy\nDOMAIN-SUFFIX,otaku13.howbbs.com,Proxy\nDOMAIN-SUFFIX,cc18.tv,Proxy\nDOMAIN-SUFFIX,um.domain888.pw,Proxy\nDOMAIN-SUFFIX,apec.fr,Proxy\nDOMAIN-SUFFIX,www.cabet88.com,Proxy\nDOMAIN-SUFFIX,bestvpnchina.net,Proxy\nDOMAIN-SUFFIX,cdn.mobileread.com,Proxy\nDOMAIN-SUFFIX,d1u7in0wxzcgn5.cloudfront.net,Proxy\nDOMAIN-SUFFIX,mirmooi.net,Proxy\nDOMAIN-SUFFIX,pincong.org,Proxy\nDOMAIN-SUFFIX,ppt.privatedns.org,Proxy\nDOMAIN-SUFFIX,en.akinator.com,Proxy\nDOMAIN-SUFFIX,nc.slyip.net,Proxy\nDOMAIN-SUFFIX,m.53358d.com,Proxy\nDOMAIN-SUFFIX,llbnsa.tv,Proxy\nDOMAIN-SUFFIX,eluniversal.com.mx,Proxy\nDOMAIN-SUFFIX,668277777.com,Proxy\nDOMAIN-SUFFIX,91vid.com,Proxy\nDOMAIN-SUFFIX,mponline.hk,Proxy\nDOMAIN-SUFFIX,www.diaosisou.com,Proxy\nDOMAIN-SUFFIX,anonasurf.com,Proxy\nDOMAIN-SUFFIX,asnebula.cf,Proxy\nDOMAIN-SUFFIX,gaozhisheng.net,Proxy\nDOMAIN-SUFFIX,voicedaily.com,Proxy\nDOMAIN-SUFFIX,twelve.today,Proxy\nDOMAIN-SUFFIX,www.betvictor12.com,Proxy\nDOMAIN-SUFFIX,unfiltered.adguard-dns.com,Proxy\nDOMAIN-SUFFIX,35.ubddns.org,Proxy\nDOMAIN-SUFFIX,www.cqu.com,Proxy\nDOMAIN-SUFFIX,zzw.dnsserv.xyz,Proxy\nDOMAIN-SUFFIX,d35daqrh0putnm.cloudfront.net,Proxy\nDOMAIN-SUFFIX,poemhunter.com,Proxy\nDOMAIN-SUFFIX,blmdc55.com,Proxy\nDOMAIN-SUFFIX,communitypower.org,Proxy\nDOMAIN-SUFFIX,vascular-diagnostics.com,Proxy\nDOMAIN-SUFFIX,www.bestvpnforchina.net,Proxy\nDOMAIN-SUFFIX,myyearbook.com,Proxy\nDOMAIN-SUFFIX,life.com.tw,Proxy\nDOMAIN-SUFFIX,dt28h6qs3zp33.cloudfront.net,Proxy\nDOMAIN-SUFFIX,vinniev.com,Proxy\nDOMAIN-SUFFIX,josephrock.net,Proxy\nDOMAIN-SUFFIX,protonvpn.ch,Proxy\nDOMAIN-SUFFIX,682153.com,Proxy\nDOMAIN-SUFFIX,englishpen.org,Proxy\nDOMAIN-SUFFIX,prayforchina.net,Proxy\nDOMAIN-SUFFIX,thetibetmuseum.org,Proxy\nDOMAIN-SUFFIX,d205y6qjd5u38f.cloudfront.net,Proxy\nDOMAIN-SUFFIX,longhu99.com,Proxy\nDOMAIN-SUFFIX,mathiew-badimon.com,Proxy\nDOMAIN-SUFFIX,www.ffeap.com,Proxy\nDOMAIN-SUFFIX,bi-si2.xyz,Proxy\nDOMAIN-SUFFIX,yuhaotech.blogspot.jp,Proxy\nDOMAIN-SUFFIX,d1n7qfbcprvx1.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.mmav44.com,Proxy\nDOMAIN-SUFFIX,rightwingtribune.com,Proxy\nDOMAIN-SUFFIX,6582696.com,Proxy\nDOMAIN-SUFFIX,hackyoutube.com,Proxy\nDOMAIN-SUFFIX,ys3302.com,Proxy\nDOMAIN-SUFFIX,forums.mvgroup.org,Proxy\nDOMAIN-SUFFIX,hkhkhk.com,Proxy\nDOMAIN-SUFFIX,www.55qqxx.com,Proxy\nDOMAIN-SUFFIX,www.ccvoice.ca,Proxy\nDOMAIN-SUFFIX,www.avdb.im,Proxy\nDOMAIN-SUFFIX,cresset-group.com,Proxy\nDOMAIN-SUFFIX,aspectgaming.com,Proxy\nDOMAIN-SUFFIX,gd.king10.com,Proxy\nDOMAIN-SUFFIX,www.projun.com,Proxy\nDOMAIN-SUFFIX,we-cc1.xyz,Proxy\nDOMAIN-SUFFIX,18pps.com,Proxy\nDOMAIN-SUFFIX,ddinews.gov.in,Proxy\nDOMAIN-SUFFIX,cg-in-f90.1e100.net,Proxy\nDOMAIN-SUFFIX,jkub.com,Proxy\nDOMAIN-SUFFIX,vmoptions.com,Proxy\nDOMAIN-SUFFIX,markquart.com,Proxy\nDOMAIN-SUFFIX,d31a7c1svrvq65.cloudfront.net,Proxy\nDOMAIN-SUFFIX,ashens.com,Proxy\nDOMAIN-SUFFIX,newsu.org,Proxy\nDOMAIN-SUFFIX,x8cc.net,Proxy\nDOMAIN-SUFFIX,presentdangerchina.org,Proxy\nDOMAIN-SUFFIX,7067d.com,Proxy\nDOMAIN-SUFFIX,www.imgspice.com,Proxy\nDOMAIN-SUFFIX,thebulwark.com,Proxy\nDOMAIN-SUFFIX,www.kxlatv.com,Proxy\nDOMAIN-SUFFIX,dimnhsinmkdwq.cloudfront.net,Proxy\nDOMAIN-SUFFIX,28.effers.com,Proxy\nDOMAIN-SUFFIX,togetter.com,Proxy\nDOMAIN-SUFFIX,233abc.com,Proxy\nDOMAIN-SUFFIX,roodo.com,Proxy\nDOMAIN-SUFFIX,ame-life.com,Proxy\nDOMAIN-SUFFIX,api.quickbase.com,Proxy\nDOMAIN-SUFFIX,e-developer.com.ve,Proxy\nDOMAIN-SUFFIX,payza.org,Proxy\nDOMAIN-SUFFIX,apkollen.se,Proxy\nDOMAIN-SUFFIX,dcard.cc,Proxy\nDOMAIN-SUFFIX,hj00.com,Proxy\nDOMAIN-SUFFIX,www.tojgallery.com,Proxy\nDOMAIN-SUFFIX,6h089.com,Proxy\nDOMAIN-SUFFIX,realvision.com,Proxy\nDOMAIN-SUFFIX,04647.xyz,Proxy\nDOMAIN-SUFFIX,4048.com,Proxy\nDOMAIN-SUFFIX,desc.se,Proxy\nDOMAIN-SUFFIX,mikeamoore.net,Proxy\nDOMAIN-SUFFIX,blacksonmoms.com,Proxy\nDOMAIN-SUFFIX,menck.com,Proxy\nDOMAIN-SUFFIX,38859900.com,Proxy\nDOMAIN-SUFFIX,tv.itver.cc,Proxy\nDOMAIN-SUFFIX,gr8domain.biz,Proxy\nDOMAIN-SUFFIX,bechtle.com,Proxy\nDOMAIN-SUFFIX,www.mikahakkinen.com,Proxy\nDOMAIN-SUFFIX,wlvpn.com,Proxy\nDOMAIN-SUFFIX,rayer.idv.tw,Proxy\nDOMAIN-SUFFIX,www.wsbtv.com,Proxy\nDOMAIN-SUFFIX,maikou.com,Proxy\nDOMAIN-SUFFIX,www.kollect.com.tw,Proxy\nDOMAIN-SUFFIX,perfspot.com,Proxy\nDOMAIN-SUFFIX,37.homeip.net,Proxy\nDOMAIN-SUFFIX,vrmtr.com,Proxy\nDOMAIN-SUFFIX,1login.to,Proxy\nDOMAIN-SUFFIX,epochhk.com,Proxy\nDOMAIN-SUFFIX,vudu.com,Proxy\nDOMAIN-SUFFIX,vocus.cc,Proxy\nDOMAIN-SUFFIX,www.bilifl.com,Proxy\nDOMAIN-SUFFIX,pusacg.org,Proxy\nDOMAIN-SUFFIX,6584304.com,Proxy\nDOMAIN-SUFFIX,spreadshirt.es,Proxy\nDOMAIN-SUFFIX,openaked.com,Proxy\nDOMAIN-SUFFIX,runonflux.io,Proxy\nDOMAIN-SUFFIX,megalodon.jp,Proxy\nDOMAIN-SUFFIX,www.fxcmpro.com,Proxy\nDOMAIN-SUFFIX,xiuren.org,Proxy\nDOMAIN-SUFFIX,un.na.tl,Proxy\nDOMAIN-SUFFIX,palpung.org.tw,Proxy\nDOMAIN-SUFFIX,shopbuy.us,Proxy\nDOMAIN-SUFFIX,ezua.com,Proxy\nDOMAIN-SUFFIX,vincisrl.com.ar,Proxy\nDOMAIN-SUFFIX,www.yuvutu.com,Proxy\nDOMAIN-SUFFIX,www.valeursactuelles.com,Proxy\nDOMAIN-SUFFIX,farwestchina.com,Proxy\nDOMAIN-SUFFIX,laogai.org,Proxy\nDOMAIN-SUFFIX,xinbi558.com,Proxy\nDOMAIN-SUFFIX,winwhispers.info,Proxy\nDOMAIN-SUFFIX,zh.hentai-image.com,Proxy\nDOMAIN-SUFFIX,gyalwarinpoche.com,Proxy\nDOMAIN-SUFFIX,istockimg.com,Proxy\nDOMAIN-SUFFIX,dqmobile5.po888.net,Proxy\nDOMAIN-SUFFIX,nexttv.com.tw,Proxy\nDOMAIN-SUFFIX,www.llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch.co.uk,Proxy\nDOMAIN-SUFFIX,hkepc.com,Proxy\nDOMAIN-SUFFIX,www.yes123.com.tw,Proxy\nDOMAIN-SUFFIX,firstimage.biz,Proxy\nDOMAIN-SUFFIX,xbtce.com,Proxy\nDOMAIN-SUFFIX,vaananen.fi,Proxy\nDOMAIN-SUFFIX,htvpn.com,Proxy\nDOMAIN-SUFFIX,animoto.com,Proxy\nDOMAIN-SUFFIX,779788.com,Proxy\nDOMAIN-SUFFIX,scholarsatrisk.org,Proxy\nDOMAIN-SUFFIX,dqmobile.po888.net,Proxy\nDOMAIN-SUFFIX,whatblocked.com,Proxy\nDOMAIN-SUFFIX,h.el.gy,Proxy\nDOMAIN-SUFFIX,1129988.net,Proxy\nDOMAIN-SUFFIX,j-proxy.net,Proxy\nDOMAIN-SUFFIX,www.lookfantastic.com,Proxy\nDOMAIN-SUFFIX,www.neihan8.com,Proxy\nDOMAIN-SUFFIX,www.kingstar.com,Proxy\nDOMAIN-SUFFIX,youbeli.com,Proxy\nDOMAIN-SUFFIX,handelsblatt.com,Proxy\nDOMAIN-SUFFIX,tibetkomite.dk,Proxy\nDOMAIN-SUFFIX,www.werich.idv.tw,Proxy\nDOMAIN-SUFFIX,www.trademax.com.au,Proxy\nDOMAIN-SUFFIX,www.goondiwindiargus.com.au,Proxy\nDOMAIN-SUFFIX,www.zyxel.com.tw,Proxy\nDOMAIN-SUFFIX,berlin01.tor-exit.artikel10.org,Proxy\nDOMAIN-SUFFIX,www.vacounh.com,Proxy\nDOMAIN-SUFFIX,zattinni.com.br,Proxy\nDOMAIN-SUFFIX,amxj5577.com,Proxy\nDOMAIN-SUFFIX,nztdsm.com,Proxy\nDOMAIN-SUFFIX,eduvpn.com,Proxy\nDOMAIN-SUFFIX,upload-thai.com,Proxy\nDOMAIN-SUFFIX,pictures.playboy.com,Proxy\nDOMAIN-SUFFIX,centurylink.net,Proxy\nDOMAIN-SUFFIX,checkerproxy.net,Proxy\nDOMAIN-SUFFIX,cjr.org,Proxy\nDOMAIN-SUFFIX,lnksr.com,Proxy\nDOMAIN-SUFFIX,00666989.com,Proxy\nDOMAIN-SUFFIX,739bm.com,Proxy\nDOMAIN-SUFFIX,wildhardsex.com,Proxy\nDOMAIN-SUFFIX,323.slyip.net,Proxy\nDOMAIN-SUFFIX,mrfence.co.za,Proxy\nDOMAIN-SUFFIX,vpncup.us,Proxy\nDOMAIN-SUFFIX,email.umich.edu,Proxy\nDOMAIN-SUFFIX,www.visitmonmouth.com,Proxy\nDOMAIN-SUFFIX,882110077.com,Proxy\nDOMAIN-SUFFIX,xu.effers.com,Proxy\nDOMAIN-SUFFIX,hzbi.org,Proxy\nDOMAIN-SUFFIX,shenzhoufilm.com,Proxy\nDOMAIN-SUFFIX,www.asiae.co.kr,Proxy\nDOMAIN-SUFFIX,socialwhale.com,Proxy\nDOMAIN-SUFFIX,d22973nbsok3dd.cloudfront.net,Proxy\nDOMAIN-SUFFIX,3hedashen.com,Proxy\nDOMAIN-SUFFIX,www.ggfwzs.com,Proxy\nDOMAIN-SUFFIX,postimg.org,Proxy\nDOMAIN-SUFFIX,www.mansion.com,Proxy\nDOMAIN-SUFFIX,www.wgsn.com,Proxy\nDOMAIN-SUFFIX,mauerspecht.org,Proxy\nDOMAIN-SUFFIX,mrcentertainment.com,Proxy\nDOMAIN-SUFFIX,aff.188betkr.com,Proxy\nDOMAIN-SUFFIX,gaycn.net,Proxy\nDOMAIN-SUFFIX,avatars3.githubusercontent.com,Proxy\nDOMAIN-SUFFIX,a58955.com,Proxy\nDOMAIN-SUFFIX,buddhism-controversy-blog.com,Proxy\nDOMAIN-SUFFIX,animal-photos.org,Proxy\nDOMAIN-SUFFIX,justhideme.com,Proxy\nDOMAIN-SUFFIX,decodet.co,Proxy\nDOMAIN-SUFFIX,xj17777.com,Proxy\nDOMAIN-SUFFIX,klsp.fun,Proxy\nDOMAIN-SUFFIX,dalailama.ru,Proxy\nDOMAIN-SUFFIX,yuyanzhibo.vip,Proxy\nDOMAIN-SUFFIX,k2999.com,Proxy\nDOMAIN-SUFFIX,kissanime.com,Proxy\nDOMAIN-SUFFIX,trade.z.com,Proxy\nDOMAIN-SUFFIX,www.ikta.com,Proxy\nDOMAIN-SUFFIX,048738.com,Proxy\nDOMAIN-SUFFIX,metafilter.com,Proxy\nDOMAIN-SUFFIX,www.top-proxies.co.uk,Proxy\nDOMAIN-SUFFIX,acgbox.org,Proxy\nDOMAIN-SUFFIX,securityinabox.org,Proxy\nDOMAIN-SUFFIX,sslproxyserver.com,Proxy\nDOMAIN-SUFFIX,www.brenda88.idv.tw,Proxy\nDOMAIN-SUFFIX,cmcn.org,Proxy\nDOMAIN-SUFFIX,ge.flnet.org,Proxy\nDOMAIN-SUFFIX,www.thenational.ae,Proxy\nDOMAIN-SUFFIX,www.1843magazine.com,Proxy\nDOMAIN-SUFFIX,xiaolan.me,Proxy\nDOMAIN-SUFFIX,timc.idv.tw,Proxy\nDOMAIN-SUFFIX,topsy.com,Proxy\nDOMAIN-SUFFIX,cn.freeones.com,Proxy\nDOMAIN-SUFFIX,d1crmek4rmrq5c.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.enel.com,Proxy\nDOMAIN-SUFFIX,5379803.com,Proxy\nDOMAIN-SUFFIX,grrrgraphics.com,Proxy\nDOMAIN-SUFFIX,xw66.cc,Proxy\nDOMAIN-SUFFIX,leeleelin.blogspot.hk,Proxy\nDOMAIN-SUFFIX,dsn501.co,Proxy\nDOMAIN-SUFFIX,www.pastebin.com,Proxy\nDOMAIN-SUFFIX,columbiaepiscopal.org,Proxy\nDOMAIN-SUFFIX,tubidy.mobi,Proxy\nDOMAIN-SUFFIX,crazymonstercock.com,Proxy\nDOMAIN-SUFFIX,my.shadowsocksr.vip,Proxy\nDOMAIN-SUFFIX,openproxy.co.uk,Proxy\nDOMAIN-SUFFIX,mixi.jp,Proxy\nDOMAIN-SUFFIX,aiweiwei.com,Proxy\nDOMAIN-SUFFIX,sogrady.me,Proxy\nDOMAIN-SUFFIX,www.yc6425.com,Proxy\nDOMAIN-SUFFIX,www.milulucn.com,Proxy\nDOMAIN-SUFFIX,www.houtroos.com,Proxy\nDOMAIN-SUFFIX,chinainperspective.com,Proxy\nDOMAIN-SUFFIX,aplusvpn.com,Proxy\nDOMAIN-SUFFIX,4sex4.com,Proxy\nDOMAIN-SUFFIX,www.beplay.com,Proxy\nDOMAIN-SUFFIX,weboproxy.com,Proxy\nDOMAIN-SUFFIX,6137b.com,Proxy\nDOMAIN-SUFFIX,www.livemint.com,Proxy\nDOMAIN-SUFFIX,torrentgalaxy.to,Proxy\nDOMAIN-SUFFIX,ntdtv.co,Proxy\nDOMAIN-SUFFIX,kotalampi.com,Proxy\nDOMAIN-SUFFIX,chatroom.156222.co,Proxy\nDOMAIN-SUFFIX,mbetwaycdn.agent1818.com,Proxy\nDOMAIN-SUFFIX,giantesswaltz.org,Proxy\nDOMAIN-SUFFIX,zgzcjj.net,Proxy\nDOMAIN-SUFFIX,somamatha.org,Proxy\nDOMAIN-SUFFIX,imggmi.com,Proxy\nDOMAIN-SUFFIX,reves.cl,Proxy\nDOMAIN-SUFFIX,tw.mssi.pw,Proxy\nDOMAIN-SUFFIX,www.jizzonline.com,Proxy\nDOMAIN-SUFFIX,www.macerichtourism.com,Proxy\nDOMAIN-SUFFIX,www.ca518.com,Proxy\nDOMAIN-SUFFIX,google.ai,Proxy\nDOMAIN-SUFFIX,42842821.com,Proxy\nDOMAIN-SUFFIX,bigjapanesesex.com,Proxy\nDOMAIN-SUFFIX,ginx.com,Proxy\nDOMAIN-SUFFIX,vidol.tv,Proxy\nDOMAIN-SUFFIX,bixin.com,Proxy\nDOMAIN-SUFFIX,libgen.li,Proxy\nDOMAIN-SUFFIX,betway1118.com,Proxy\nDOMAIN-SUFFIX,yahaha.xyz,Proxy\nDOMAIN-SUFFIX,cattt.com,Proxy\nDOMAIN-SUFFIX,feeds.buzzsprout.com,Proxy\nDOMAIN-SUFFIX,www.theamericanconservative.com,Proxy\nDOMAIN-SUFFIX,zmk.pw,Proxy\nDOMAIN-SUFFIX,vrbangers.com,Proxy\nDOMAIN-SUFFIX,citytalk.tw,Proxy\nDOMAIN-SUFFIX,cia.gov,Proxy\nDOMAIN-SUFFIX,maozhuyi.home.blog,Proxy\nDOMAIN-SUFFIX,www.shiatv.net,Proxy\nDOMAIN-SUFFIX,thisvid.com,Proxy\nDOMAIN-SUFFIX,www.hetzner.de,Proxy\nDOMAIN-SUFFIX,bestvpn-china.com,Proxy\nDOMAIN-SUFFIX,globaleconomicanalysis.blogspot.hk,Proxy\nDOMAIN-SUFFIX,amvpn.com,Proxy\nDOMAIN-SUFFIX,innermongolia.org,Proxy\nDOMAIN-SUFFIX,18comic.org,Proxy\nDOMAIN-SUFFIX,y66zz.com,Proxy\nDOMAIN-SUFFIX,88223885.com,Proxy\nDOMAIN-SUFFIX,amamasstory.com,Proxy\nDOMAIN-SUFFIX,manjongmari.blogspot.hk,Proxy\nDOMAIN-SUFFIX,stock.nlog.cc,Proxy\nDOMAIN-SUFFIX,www.express-links.com,Proxy\nDOMAIN-SUFFIX,117708.com,Proxy\nDOMAIN-SUFFIX,32134.com,Proxy\nDOMAIN-SUFFIX,kevinvuilleumier.net,Proxy\nDOMAIN-SUFFIX,www.outlook.co.uk,Proxy\nDOMAIN-SUFFIX,b2828.com,Proxy\nDOMAIN-SUFFIX,vpn.ac,Proxy\nDOMAIN-SUFFIX,tidyread.com,Proxy\nDOMAIN-SUFFIX,www.oglaf.com,Proxy\nDOMAIN-SUFFIX,www.bbptz.com,Proxy\nDOMAIN-SUFFIX,www.surveycake.com,Proxy\nDOMAIN-SUFFIX,bokking.com.br,Proxy\nDOMAIN-SUFFIX,independent.co.uk,Proxy\nDOMAIN-SUFFIX,scientology.org,Proxy\nDOMAIN-SUFFIX,18comic2.one,Proxy\nDOMAIN-SUFFIX,www.theeuropean.de,Proxy\nDOMAIN-SUFFIX,ubxyz.com,Proxy\nDOMAIN-SUFFIX,china-week.com,Proxy\nDOMAIN-SUFFIX,sonyandy123.moreforum.com,Proxy\nDOMAIN-SUFFIX,www.sciencemag.org,Proxy\nDOMAIN-SUFFIX,flyovercities.com,Proxy\nDOMAIN-SUFFIX,487.microcycas.com,Proxy\nDOMAIN-SUFFIX,medium.com.com,Proxy\nDOMAIN-SUFFIX,nordforme.net,Proxy\nDOMAIN-SUFFIX,api.arcadia.818psb.com,Proxy\nDOMAIN-SUFFIX,dreamland.im,Proxy\nDOMAIN-SUFFIX,falundafa.it,Proxy\nDOMAIN-SUFFIX,www.hayatnuri.biz,Proxy\nDOMAIN-SUFFIX,www.limetorrents.pro,Proxy\nDOMAIN-SUFFIX,fayaa.com,Proxy\nDOMAIN-SUFFIX,www.voacambodia.com,Proxy\nDOMAIN-SUFFIX,dng0kyy973rtj.cloudfront.net,Proxy\nDOMAIN-SUFFIX,shahed4u.buzz,Proxy\nDOMAIN-SUFFIX,gaviti.com,Proxy\nDOMAIN-SUFFIX,pu9900.com,Proxy\nDOMAIN-SUFFIX,www.bw8tiyu.com,Proxy\nDOMAIN-SUFFIX,rotter.net,Proxy\nDOMAIN-SUFFIX,vischeck.homeip.net,Proxy\nDOMAIN-SUFFIX,aidshealth.org,Proxy\nDOMAIN-SUFFIX,sosreader.com,Proxy\nDOMAIN-SUFFIX,daf4fsa6m92ni.cloudfront.net,Proxy\nDOMAIN-SUFFIX,mephistonet.nl,Proxy\nDOMAIN-SUFFIX,tktube.com,Proxy\nDOMAIN-SUFFIX,fangeming.com,Proxy\nDOMAIN-SUFFIX,www.jyun.fun,Proxy\nDOMAIN-SUFFIX,fleursdeslettres.com,Proxy\nDOMAIN-SUFFIX,adrism.com.cn,Proxy\nDOMAIN-SUFFIX,kfc2003.com,Proxy\nDOMAIN-SUFFIX,samkoeh.com,Proxy\nDOMAIN-SUFFIX,www.alice.it,Proxy\nDOMAIN-SUFFIX,18-comic.work,Proxy\nDOMAIN-SUFFIX,affcny.lbbet.com,Proxy\nDOMAIN-SUFFIX,deepthroatfrenzy.com,Proxy\nDOMAIN-SUFFIX,itshidden.com,Proxy\nDOMAIN-SUFFIX,padchinesesite.blogspot.hk,Proxy\nDOMAIN-SUFFIX,mrcong.com,Proxy\nDOMAIN-SUFFIX,free-proxy-list.net,Proxy\nDOMAIN-SUFFIX,intranet.e21magicmedia.com.tw,Proxy\nDOMAIN-SUFFIX,srcpan.com,Proxy\nDOMAIN-SUFFIX,www.iforex.com,Proxy\nDOMAIN-SUFFIX,radiovncr.com,Proxy\nDOMAIN-SUFFIX,d1x9ai1m90zg00.cloudfront.net,Proxy\nDOMAIN-SUFFIX,saveliuxiaobo.com,Proxy\nDOMAIN-SUFFIX,europornstar.com,Proxy\nDOMAIN-SUFFIX,grsm.org,Proxy\nDOMAIN-SUFFIX,hkacg.net,Proxy\nDOMAIN-SUFFIX,www.301hk.com,Proxy\nDOMAIN-SUFFIX,nextjav.com,Proxy\nDOMAIN-SUFFIX,www.nambuccaguardian.com.au,Proxy\nDOMAIN-SUFFIX,qs.etowns.net,Proxy\nDOMAIN-SUFFIX,fun242.com,Proxy\nDOMAIN-SUFFIX,www.xv-horezeedipaif.com,Proxy\nDOMAIN-SUFFIX,ubddns.org,Proxy\nDOMAIN-SUFFIX,wimbledon.com,Proxy\nDOMAIN-SUFFIX,animecrazy.net,Proxy\nDOMAIN-SUFFIX,fxcm.news,Proxy\nDOMAIN-SUFFIX,jzplay888.com,Proxy\nDOMAIN-SUFFIX,ovh.eu,Proxy\nDOMAIN-SUFFIX,668000010.com,Proxy\nDOMAIN-SUFFIX,10b111.com,Proxy\nDOMAIN-SUFFIX,908taiwan.org,Proxy\nDOMAIN-SUFFIX,cooking.stackexchange.com,Proxy\nDOMAIN-SUFFIX,ww21.q22w.com,Proxy\nDOMAIN-SUFFIX,shanghaiexpat.com,Proxy\nDOMAIN-SUFFIX,vpnsf.com,Proxy\nDOMAIN-SUFFIX,www.khmertimeskh.com,Proxy\nDOMAIN-SUFFIX,php.32-b.it,Proxy\nDOMAIN-SUFFIX,chat.gpt.bz,Proxy\nDOMAIN-SUFFIX,discord.com,Proxy\nDOMAIN-SUFFIX,709068.com,Proxy\nDOMAIN-SUFFIX,ittybaby.com.au,Proxy\nDOMAIN-SUFFIX,norcomsystemsinc.com,Proxy\nDOMAIN-SUFFIX,ameblo.jp,Proxy\nDOMAIN-SUFFIX,dimoskaipoliteia.blogspot.hk,Proxy\nDOMAIN-SUFFIX,4chan.com,Proxy\nDOMAIN-SUFFIX,1665kf.com,Proxy\nDOMAIN-SUFFIX,procopytips.com,Proxy\nDOMAIN-SUFFIX,tv72.cf,Proxy\nDOMAIN-SUFFIX,www.banjuan.net,Proxy\nDOMAIN-SUFFIX,ettego.com,Proxy\nDOMAIN-SUFFIX,z.cash,Proxy\nDOMAIN-SUFFIX,ag.xw283.com,Proxy\nDOMAIN-SUFFIX,khatrimaza.org,Proxy\nDOMAIN-SUFFIX,www.bergtoys.com,Proxy\nDOMAIN-SUFFIX,huaze.org,Proxy\nDOMAIN-SUFFIX,hk.myblog.yahoo.com,Proxy\nDOMAIN-SUFFIX,best-proxy.com.de,Proxy\nDOMAIN-SUFFIX,mountainfuckfest.com,Proxy\nDOMAIN-SUFFIX,www.shorturl.com,Proxy\nDOMAIN-SUFFIX,www.shiwuzq.com,Proxy\nDOMAIN-SUFFIX,www.orchidbbs.com,Proxy\nDOMAIN-SUFFIX,www.braidwoodtimes.com.au,Proxy\nDOMAIN-SUFFIX,youtube.076.ne.jp,Proxy\nDOMAIN-SUFFIX,scientologie.fr,Proxy\nDOMAIN-SUFFIX,hostingbulk.com,Proxy\nDOMAIN-SUFFIX,atlasofassistedreproduction.com,Proxy\nDOMAIN-SUFFIX,thechinacorner.org,Proxy\nDOMAIN-SUFFIX,www.cf2r.org,Proxy\nDOMAIN-SUFFIX,catalogue.nlb.gov.sg,Proxy\nDOMAIN-SUFFIX,bm00000.com,Proxy\nDOMAIN-SUFFIX,frigment.com,Proxy\nDOMAIN-SUFFIX,blogspot.si,Proxy\nDOMAIN-SUFFIX,typical.pt,Proxy\nDOMAIN-SUFFIX,www.proporn.com,Proxy\nDOMAIN-SUFFIX,blog.pathtosharepoint.com,Proxy\nDOMAIN-SUFFIX,lifehacker.co.in,Proxy\nDOMAIN-SUFFIX,lilian.ro,Proxy\nDOMAIN-SUFFIX,scrolller.com,Proxy\nDOMAIN-SUFFIX,www.azattyk.org,Proxy\nDOMAIN-SUFFIX,tv123.ga,Proxy\nDOMAIN-SUFFIX,wsj.net,Proxy\nDOMAIN-SUFFIX,securityboulevard.com,Proxy\nDOMAIN-SUFFIX,tw.icej.org,Proxy\nDOMAIN-SUFFIX,www.behindkink.com,Proxy\nDOMAIN-SUFFIX,www.bt4kyy.com,Proxy\nDOMAIN-SUFFIX,pa.swpa.us,Proxy\nDOMAIN-SUFFIX,blogspaper.org,Proxy\nDOMAIN-SUFFIX,d2.sku117.pw,Proxy\nDOMAIN-SUFFIX,fttechnologies.com,Proxy\nDOMAIN-SUFFIX,peacehall.com,Proxy\nDOMAIN-SUFFIX,kinkykink.com,Proxy\nDOMAIN-SUFFIX,www.kimo.com,Proxy\nDOMAIN-SUFFIX,www.ctp.org,Proxy\nDOMAIN-SUFFIX,mrtweet.com,Proxy\nDOMAIN-SUFFIX,wahas.com,Proxy\nDOMAIN-SUFFIX,scasino.com,Proxy\nDOMAIN-SUFFIX,jf2204.com,Proxy\nDOMAIN-SUFFIX,www.liberation.fr,Proxy\nDOMAIN-SUFFIX,ghcr.io,Proxy\nDOMAIN-SUFFIX,annas-archive.se,Proxy\nDOMAIN-SUFFIX,www.t2u.cc,Proxy\nDOMAIN-SUFFIX,www.sheetzuchin.com,Proxy\nDOMAIN-SUFFIX,www.zionladder.com,Proxy\nDOMAIN-SUFFIX,145ld.cc,Proxy\nDOMAIN-SUFFIX,www.kanjukumania.com,Proxy\nDOMAIN-SUFFIX,clipsyndicate.com,Proxy\nDOMAIN-SUFFIX,g.eeload.com,Proxy\nDOMAIN-SUFFIX,tw-blog.com,Proxy\nDOMAIN-SUFFIX,hanunyi.com,Proxy\nDOMAIN-SUFFIX,thewgo.org,Proxy\nDOMAIN-SUFFIX,www.idf.il,Proxy\nDOMAIN-SUFFIX,3p-link.com,Proxy\nDOMAIN-SUFFIX,gravador.com,Proxy\nDOMAIN-SUFFIX,famehosted.com,Proxy\nDOMAIN-SUFFIX,vpnvip.org,Proxy\nDOMAIN-SUFFIX,infocux.com,Proxy\nDOMAIN-SUFFIX,jarnjak.com,Proxy\nDOMAIN-SUFFIX,www.wacao.org,Proxy\nDOMAIN-SUFFIX,bloombergpolitics.com,Proxy\nDOMAIN-SUFFIX,psiphon.ca,Proxy\nDOMAIN-SUFFIX,gsp.target.com,Proxy\nDOMAIN-SUFFIX,zfreet.com,Proxy\nDOMAIN-SUFFIX,www.crazytradeonline.com,Proxy\nDOMAIN-SUFFIX,www.pusstv.com,Proxy\nDOMAIN-SUFFIX,www.kao-calligraphy.idv.tw,Proxy\nDOMAIN-SUFFIX,8587d.cc,Proxy\nDOMAIN-SUFFIX,www.twnorth.org.tw,Proxy\nDOMAIN-SUFFIX,rfibrasil.com,Proxy\nDOMAIN-SUFFIX,tr.com,Proxy\nDOMAIN-SUFFIX,shenzhouzhengdao.org,Proxy\nDOMAIN-SUFFIX,tyc3335.com,Proxy\nDOMAIN-SUFFIX,dnswho.xyz,Proxy\nDOMAIN-SUFFIX,samuelponce.cl,Proxy\nDOMAIN-SUFFIX,w.3mon.xyz,Proxy\nDOMAIN-SUFFIX,hp.nard.ca,Proxy\nDOMAIN-SUFFIX,www.8535.org,Proxy\nDOMAIN-SUFFIX,read.5article.com,Proxy\nDOMAIN-SUFFIX,dczn9on5fqkkt.cloudfront.net,Proxy\nDOMAIN-SUFFIX,shadowproxy.net,Proxy\nDOMAIN-SUFFIX,chiaweivi.strikingly.com,Proxy\nDOMAIN-SUFFIX,stormy.co.za,Proxy\nDOMAIN-SUFFIX,www.guge.link,Proxy\nDOMAIN-SUFFIX,www.18acg.vip,Proxy\nDOMAIN-SUFFIX,doubleclickbygoogle.com,Proxy\nDOMAIN-SUFFIX,aidbayarea.org,Proxy\nDOMAIN-SUFFIX,proxysubmit.com,Proxy\nDOMAIN-SUFFIX,event.webcasts.com,Proxy\nDOMAIN-SUFFIX,www.travel4u.com.tw,Proxy\nDOMAIN-SUFFIX,ios.jumpingcrab.com,Proxy\nDOMAIN-SUFFIX,gers.co,Proxy\nDOMAIN-SUFFIX,www.lt100.vip,Proxy\nDOMAIN-SUFFIX,emol.cl,Proxy\nDOMAIN-SUFFIX,torrentkitty.tv,Proxy\nDOMAIN-SUFFIX,thehaunt.org,Proxy\nDOMAIN-SUFFIX,ndr.de,Proxy\nDOMAIN-SUFFIX,d2o8j61n9jvv5u.cloudfront.net,Proxy\nDOMAIN-SUFFIX,ne.4u.pass.fm,Proxy\nDOMAIN-SUFFIX,visitor.pixplug.in,Proxy\nDOMAIN-SUFFIX,falundafa.org.nz,Proxy\nDOMAIN-SUFFIX,haodiao.org,Proxy\nDOMAIN-SUFFIX,orioncity.virtualave.net,Proxy\nDOMAIN-SUFFIX,5525hao.comli.com,Proxy\nDOMAIN-SUFFIX,odnoklassniki.ru,Proxy\nDOMAIN-SUFFIX,bestvpnanalysis.com,Proxy\nDOMAIN-SUFFIX,www.misstransstarinternational.com,Proxy\nDOMAIN-SUFFIX,xtve.5lxtv.com,Proxy\nDOMAIN-SUFFIX,citizenscommission.hk,Proxy\nDOMAIN-SUFFIX,cdn.assets.lfpcontent.com,Proxy\nDOMAIN-SUFFIX,radiovatikan.de,Proxy\nDOMAIN-SUFFIX,fl010.com,Proxy\nDOMAIN-SUFFIX,ashtrono.my,Proxy\nDOMAIN-SUFFIX,chaoex.com,Proxy\nDOMAIN-SUFFIX,texstudio.org,Proxy\nDOMAIN-SUFFIX,d26f07zpczl4rx.cloudfront.net,Proxy\nDOMAIN-SUFFIX,monitorchina.org,Proxy\nDOMAIN-SUFFIX,firstfivefollowers.com,Proxy\nDOMAIN-SUFFIX,dsx.uk,Proxy\nDOMAIN-SUFFIX,cling.omy.sg,Proxy\nDOMAIN-SUFFIX,naturalhairlatina.blogspot.hk,Proxy\nDOMAIN-SUFFIX,blue9.com.au,Proxy\nDOMAIN-SUFFIX,www.gdot.me,Proxy\nDOMAIN-SUFFIX,brujulajuridica.cl,Proxy\nDOMAIN-SUFFIX,google.com.kh,Proxy\nDOMAIN-SUFFIX,e.spagettitoast.com,Proxy\nDOMAIN-SUFFIX,spys.ru,Proxy\nDOMAIN-SUFFIX,teleradiopadrepio.it,Proxy\nDOMAIN-SUFFIX,www.xj1996.com,Proxy\nDOMAIN-SUFFIX,youtubegaming.com,Proxy\nDOMAIN-SUFFIX,qingqing.freebbs.tw,Proxy\nDOMAIN-SUFFIX,welcome.gofoton.com,Proxy\nDOMAIN-SUFFIX,pingify.me,Proxy\nDOMAIN-SUFFIX,mandelbaerli.asia,Proxy\nDOMAIN-SUFFIX,hkict.net,Proxy\nDOMAIN-SUFFIX,ks7799.com,Proxy\nDOMAIN-SUFFIX,d3ie9li8ral8o.cloudfront.net,Proxy\nDOMAIN-SUFFIX,blog.nightly.mozilla.org,Proxy\nDOMAIN-SUFFIX,jwmusic.org,Proxy\nDOMAIN-SUFFIX,sehuatang.net,Proxy\nDOMAIN-SUFFIX,pornvisit.com,Proxy\nDOMAIN-SUFFIX,857zhibo.cc,Proxy\nDOMAIN-SUFFIX,wikis.paradoxplaza.com,Proxy\nDOMAIN-SUFFIX,hut2.ru,Proxy\nDOMAIN-SUFFIX,www.hotgaylist.com,Proxy\nDOMAIN-SUFFIX,treemall.com.tw,Proxy\nDOMAIN-SUFFIX,www.pirkka.fi,Proxy\nDOMAIN-SUFFIX,www.tmdyx.com,Proxy\nDOMAIN-SUFFIX,piss.com,Proxy\nDOMAIN-SUFFIX,www.chengpou.com.mo,Proxy\nDOMAIN-SUFFIX,moefuns.net,Proxy\nDOMAIN-SUFFIX,tracker.openwebtorrent.com,Proxy\nDOMAIN-SUFFIX,chatrandom.com,Proxy\nDOMAIN-SUFFIX,www.m2698.com,Proxy\nDOMAIN-SUFFIX,pjdc9900.com,Proxy\nDOMAIN-SUFFIX,codemode.cl,Proxy\nDOMAIN-SUFFIX,mattermost.com,Proxy\nDOMAIN-SUFFIX,nextdns.com,Proxy\nDOMAIN-SUFFIX,wsdc4433.com,Proxy\nDOMAIN-SUFFIX,www.cocktailsforever.com,Proxy\nDOMAIN-SUFFIX,google.am,Proxy\nDOMAIN-SUFFIX,cdn.revjet.com,Proxy\nDOMAIN-SUFFIX,ixxzp.com,Proxy\nDOMAIN-SUFFIX,freechina.news,Proxy\nDOMAIN-SUFFIX,www.torrentmac.net,Proxy\nDOMAIN-SUFFIX,xy.domain888.pw,Proxy\nDOMAIN-SUFFIX,av88.tv,Proxy\nDOMAIN-SUFFIX,big2wt.com,Proxy\nDOMAIN-SUFFIX,t.huhaitai.com,Proxy\nDOMAIN-SUFFIX,radhakrishnarecords.com,Proxy\nDOMAIN-SUFFIX,www.oppmtv.site,Proxy\nDOMAIN-SUFFIX,cn.caserandom.com,Proxy\nDOMAIN-SUFFIX,mastodon.lol,Proxy\nDOMAIN-SUFFIX,mymoe.moe,Proxy\nDOMAIN-SUFFIX,www.eracom.com.tw,Proxy\nDOMAIN-SUFFIX,alunsalt.com,Proxy\nDOMAIN-SUFFIX,getmalus.com,Proxy\nDOMAIN-SUFFIX,openwrt.org.cn,Proxy\nDOMAIN-SUFFIX,funnymoo.blogspot.hk,Proxy\nDOMAIN-SUFFIX,entnt.com,Proxy\nDOMAIN-SUFFIX,panel.putaoswing.site,Proxy\nDOMAIN-SUFFIX,hanknetwork.com,Proxy\nDOMAIN-SUFFIX,837889.com,Proxy\nDOMAIN-SUFFIX,lvhai.org,Proxy\nDOMAIN-SUFFIX,quickleft.net,Proxy\nDOMAIN-SUFFIX,d1ot4iop71k9iu.cloudfront.net,Proxy\nDOMAIN-SUFFIX,d211pmzzrifda8.cloudfront.net,Proxy\nDOMAIN-SUFFIX,zifaner.top,Proxy\nDOMAIN-SUFFIX,sexfinder.com,Proxy\nDOMAIN-SUFFIX,dynalias.com,Proxy\nDOMAIN-SUFFIX,ccenter.cl,Proxy\nDOMAIN-SUFFIX,www.freevpnsakura.com,Proxy\nDOMAIN-SUFFIX,joinpeertube.org,Proxy\nDOMAIN-SUFFIX,bigbird18.com,Proxy\nDOMAIN-SUFFIX,ablo.live,Proxy\nDOMAIN-SUFFIX,www.prudentman.idv.tw,Proxy\nDOMAIN-SUFFIX,b6711.com,Proxy\nDOMAIN-SUFFIX,polyu.edu.hk,Proxy\nDOMAIN-SUFFIX,vpntw.com,Proxy\nDOMAIN-SUFFIX,mzfast.live,Proxy\nDOMAIN-SUFFIX,mezclados.cl,Proxy\nDOMAIN-SUFFIX,www.nature.fr,Proxy\nDOMAIN-SUFFIX,pornpics.com,Proxy\nDOMAIN-SUFFIX,wq.dnstool.xyz,Proxy\nDOMAIN-SUFFIX,www.b988cp.cc,Proxy\nDOMAIN-SUFFIX,usc.edu,Proxy\nDOMAIN-SUFFIX,en.wikipedia.njau.cf,Proxy\nDOMAIN-SUFFIX,fasmtv.site,Proxy\nDOMAIN-SUFFIX,vpnzh.com,Proxy\nDOMAIN-SUFFIX,taiwancon.com,Proxy\nDOMAIN-SUFFIX,www.toobigforemail.com,Proxy\nDOMAIN-SUFFIX,mm15.zyuntv.site,Proxy\nDOMAIN-SUFFIX,c4rt-girl.es,Proxy\nDOMAIN-SUFFIX,cn.ft.com,Proxy\nDOMAIN-SUFFIX,www.sbf138.com,Proxy\nDOMAIN-SUFFIX,zeil.top,Proxy\nDOMAIN-SUFFIX,99864.com,Proxy\nDOMAIN-SUFFIX,a1577.dspb.akamai.net,Proxy\nDOMAIN-SUFFIX,p2.sp6128.com,Proxy\nDOMAIN-SUFFIX,thessr.tk,Proxy\nDOMAIN-SUFFIX,bsc-dataseed.binance.org,Proxy\nDOMAIN-SUFFIX,gongminliliang.com,Proxy\nDOMAIN-SUFFIX,tw.voa.mobi,Proxy\nDOMAIN-SUFFIX,marfdisegno.com,Proxy\nDOMAIN-SUFFIX,www.pinnacle.com,Proxy\nDOMAIN-SUFFIX,qinimg.com,Proxy\nDOMAIN-SUFFIX,kultpavillonblog.blogspot.ch,Proxy\nDOMAIN-SUFFIX,big-cup.tv,Proxy\nDOMAIN-SUFFIX,retorte.ch,Proxy\nDOMAIN-SUFFIX,n.hk.rs,Proxy\nDOMAIN-SUFFIX,istockphoto.com,Proxy\nDOMAIN-SUFFIX,hkpic.us,Proxy\nDOMAIN-SUFFIX,www.e8084.com,Proxy\nDOMAIN-SUFFIX,bxvpn.com,Proxy\nDOMAIN-SUFFIX,tgraph.io,Proxy\nDOMAIN-SUFFIX,vercel.app,Proxy\nDOMAIN-SUFFIX,xn--oiq.cc,Proxy\nDOMAIN-SUFFIX,say-move.org,Proxy\nDOMAIN-SUFFIX,dotblogs.com.tw,Proxy\nDOMAIN-SUFFIX,taigi.pts.org.tw,Proxy\nDOMAIN-SUFFIX,uu-gg.com,Proxy\nDOMAIN-SUFFIX,hentaicloud.com,Proxy\nDOMAIN-SUFFIX,buyu359.com,Proxy\nDOMAIN-SUFFIX,www.egaleonews.bravehost.com,Proxy\nDOMAIN-SUFFIX,www.rocknroar.news,Proxy\nDOMAIN-SUFFIX,218.net,Proxy\nDOMAIN-SUFFIX,vpninfo.dk,Proxy\nDOMAIN-SUFFIX,research.google,Proxy\nDOMAIN-SUFFIX,healthproduct.xyz,Proxy\nDOMAIN-SUFFIX,hj373.com,Proxy\nDOMAIN-SUFFIX,twbbs.tw,Proxy\nDOMAIN-SUFFIX,yourtrap.com,Proxy\nDOMAIN-SUFFIX,dailysabah.com,Proxy\nDOMAIN-SUFFIX,tuitt.ch,Proxy\nDOMAIN-SUFFIX,lib.nqu.edu.tw,Proxy\nDOMAIN-SUFFIX,memes.tw,Proxy\nDOMAIN-SUFFIX,www.ok-tw.com,Proxy\nDOMAIN-SUFFIX,www.hanroc.com,Proxy\nDOMAIN-SUFFIX,rapidvideo.ws,Proxy\nDOMAIN-SUFFIX,d1zth51wcp6yqd.cloudfront.net,Proxy\nDOMAIN-SUFFIX,kentstudios.net,Proxy\nDOMAIN-SUFFIX,wetpussygames.com,Proxy\nDOMAIN-SUFFIX,virtualtour.bham.ac.uk,Proxy\nDOMAIN-SUFFIX,ff.im,Proxy\nDOMAIN-SUFFIX,www.streema.com,Proxy\nDOMAIN-SUFFIX,bdsmtips.com,Proxy\nDOMAIN-SUFFIX,williamhill138.com,Proxy\nDOMAIN-SUFFIX,www.wayfarer.idv.tw,Proxy\nDOMAIN-SUFFIX,www.itslean.com,Proxy\nDOMAIN-SUFFIX,jiangzemin.com,Proxy\nDOMAIN-SUFFIX,mqtt-gw.pushnotifs.com,Proxy\nDOMAIN-SUFFIX,hidethisip.net,Proxy\nDOMAIN-SUFFIX,xardas.eu,Proxy\nDOMAIN-SUFFIX,uyghurtribunal.com,Proxy\nDOMAIN-SUFFIX,whatsonweibo.com,Proxy\nDOMAIN-SUFFIX,bmvpn.com,Proxy\nDOMAIN-SUFFIX,www.happygocard.com.tw,Proxy\nDOMAIN-SUFFIX,5567.slyip.net,Proxy\nDOMAIN-SUFFIX,www.myfreevpn.com,Proxy\nDOMAIN-SUFFIX,m.wikidata.org,Proxy\nDOMAIN-SUFFIX,previous.quran.com,Proxy\nDOMAIN-SUFFIX,myosia.com.my,Proxy\nDOMAIN-SUFFIX,nnews.eu,Proxy\nDOMAIN-SUFFIX,us1.campaign-archive2.com,Proxy\nDOMAIN-SUFFIX,www.p4578.com,Proxy\nDOMAIN-SUFFIX,bad.news,Proxy\nDOMAIN-SUFFIX,truebuddha-md.org,Proxy\nDOMAIN-SUFFIX,mydad.info,Proxy\nDOMAIN-SUFFIX,ricknet.ch,Proxy\nDOMAIN-SUFFIX,nanyang.com.my,Proxy\nDOMAIN-SUFFIX,www.t5505.com,Proxy\nDOMAIN-SUFFIX,www.oliver-konow.de,Proxy\nDOMAIN-SUFFIX,pepperstone.com,Proxy\nDOMAIN-SUFFIX,rethink.fr,Proxy\nDOMAIN-SUFFIX,www.nara-yakushiji.com,Proxy\nDOMAIN-SUFFIX,www.betvictor25.com,Proxy\nDOMAIN-SUFFIX,vidtomp3.com,Proxy\nDOMAIN-SUFFIX,icedrive.net,Proxy\nDOMAIN-SUFFIX,illusionfactory.com,Proxy\nDOMAIN-SUFFIX,pts.org.tw,Proxy\nDOMAIN-SUFFIX,adpl.org.hk,Proxy\nDOMAIN-SUFFIX,trend.hk,Proxy\nDOMAIN-SUFFIX,free18.net,Proxy\nDOMAIN-SUFFIX,pinsta.me,Proxy\nDOMAIN-SUFFIX,www.sbf322.com,Proxy\nDOMAIN-SUFFIX,aiwin188.com,Proxy\nDOMAIN-SUFFIX,hdtvb.net,Proxy\nDOMAIN-SUFFIX,xinyubbs.net,Proxy\nDOMAIN-SUFFIX,sockboom.com,Proxy\nDOMAIN-SUFFIX,surrenderat20.net,Proxy\nDOMAIN-SUFFIX,www.httpsme.com,Proxy\nDOMAIN-SUFFIX,99.from-al.com,Proxy\nDOMAIN-SUFFIX,adidas.de,Proxy\nDOMAIN-SUFFIX,www.llss.fun,Proxy\nDOMAIN-SUFFIX,haosf999.com,Proxy\nDOMAIN-SUFFIX,hellporno.com,Proxy\nDOMAIN-SUFFIX,www.asiantribune.com,Proxy\nDOMAIN-SUFFIX,epochtimes-bg.com,Proxy\nDOMAIN-SUFFIX,tv.spacetechnology.net,Proxy\nDOMAIN-SUFFIX,www.kahnacademy.com,Proxy\nDOMAIN-SUFFIX,jmply.com,Proxy\nDOMAIN-SUFFIX,gengtube.com,Proxy\nDOMAIN-SUFFIX,hjdc29.com,Proxy\nDOMAIN-SUFFIX,mrnews.cc,Proxy\nDOMAIN-SUFFIX,video.eyny.com,Proxy\nDOMAIN-SUFFIX,dsn01.co,Proxy\nDOMAIN-SUFFIX,db8866.com,Proxy\nDOMAIN-SUFFIX,anit.ro,Proxy\nDOMAIN-SUFFIX,user.littleputao.com,Proxy\nDOMAIN-SUFFIX,avemariaradio.net,Proxy\nDOMAIN-SUFFIX,piratebayproxy.co,Proxy\nDOMAIN-SUFFIX,wn.dnsmail.xyz,Proxy\nDOMAIN-SUFFIX,66ky009.com,Proxy\nDOMAIN-SUFFIX,www.archerie.com,Proxy\nDOMAIN-SUFFIX,canaloop.ca,Proxy\nDOMAIN-SUFFIX,bipic.net,Proxy\nDOMAIN-SUFFIX,www.doorzo.com,Proxy\nDOMAIN-SUFFIX,www.youtube.co.id,Proxy\nDOMAIN-SUFFIX,www.westerntelegraph.co.uk,Proxy\nDOMAIN-SUFFIX,securityawareness.usalearning.gov,Proxy\nDOMAIN-SUFFIX,google.co.kr,Proxy\nDOMAIN-SUFFIX,thepiratebay.org.es,Proxy\nDOMAIN-SUFFIX,wuzuowei.com,Proxy\nDOMAIN-SUFFIX,million-movies.com,Proxy\nDOMAIN-SUFFIX,kanqiu.vip,Proxy\nDOMAIN-SUFFIX,d2lbug5019cy9v.cloudfront.net,Proxy\nDOMAIN-SUFFIX,wenrou888.com,Proxy\nDOMAIN-SUFFIX,rocaway.com,Proxy\nDOMAIN-SUFFIX,www.w88ap.com,Proxy\nDOMAIN-SUFFIX,menoopiu.it,Proxy\nDOMAIN-SUFFIX,www.cjcjournal.com,Proxy\nDOMAIN-SUFFIX,chinasocialdemocraticparty.com,Proxy\nDOMAIN-SUFFIX,ctinews.com,Proxy\nDOMAIN-SUFFIX,www.signguard.se,Proxy\nDOMAIN-SUFFIX,www.gamecopyworld.com,Proxy\nDOMAIN-SUFFIX,google.be,Proxy\nDOMAIN-SUFFIX,macao-jc.com,Proxy\nDOMAIN-SUFFIX,clubthaichix.com,Proxy\nDOMAIN-SUFFIX,www.rousehillcourier.com.au,Proxy\nDOMAIN-SUFFIX,wapedia.mobi,Proxy\nDOMAIN-SUFFIX,t.orzdream.com,Proxy\nDOMAIN-SUFFIX,udn22.ga,Proxy\nDOMAIN-SUFFIX,xa.yimg.com,Proxy\nDOMAIN-SUFFIX,search.torrends.to,Proxy\nDOMAIN-SUFFIX,nitter.uni-sonia.com,Proxy\nDOMAIN-SUFFIX,art.sy,Proxy\nDOMAIN-SUFFIX,sexvids.porn,Proxy\nDOMAIN-SUFFIX,bbs-tw.com,Proxy\nDOMAIN-SUFFIX,we.b0ne.com,Proxy\nDOMAIN-SUFFIX,taller.cl,Proxy\nDOMAIN-SUFFIX,bc5288.com,Proxy\nDOMAIN-SUFFIX,ifaner.org,Proxy\nDOMAIN-SUFFIX,nywb.fat.flnet.org,Proxy\nDOMAIN-SUFFIX,lehmanns.de,Proxy\nDOMAIN-SUFFIX,www.moneynet.com.tw,Proxy\nDOMAIN-SUFFIX,zzju.22.4irc.com,Proxy\nDOMAIN-SUFFIX,mixero.com,Proxy\nDOMAIN-SUFFIX,pubu.com.tw,Proxy\nDOMAIN-SUFFIX,pmo.gov.sg,Proxy\nDOMAIN-SUFFIX,223kk.net,Proxy\nDOMAIN-SUFFIX,www.greatwisdommeditationcenter.org,Proxy\nDOMAIN-SUFFIX,www.witnessleeteaching.com,Proxy\nDOMAIN-SUFFIX,ca6088.com,Proxy\nDOMAIN-SUFFIX,anti1984.com,Proxy\nDOMAIN-SUFFIX,www.2020spaces.com,Proxy\nDOMAIN-SUFFIX,torrentz.eu,Proxy\nDOMAIN-SUFFIX,coolncute.com,Proxy\nDOMAIN-SUFFIX,mygod.firebaseio.com,Proxy\nDOMAIN-SUFFIX,justproxy.us,Proxy\nDOMAIN-SUFFIX,accessify.com,Proxy\nDOMAIN-SUFFIX,www-sk99.com,Proxy\nDOMAIN-SUFFIX,www.skype.com,Proxy\nDOMAIN-SUFFIX,akow.org,Proxy\nDOMAIN-SUFFIX,www.guchusum.in,Proxy\nDOMAIN-SUFFIX,dd.dhcp.biz,Proxy\nDOMAIN-SUFFIX,gospelforasia.com,Proxy\nDOMAIN-SUFFIX,toko.chinkchinkgo.cf,Proxy\nDOMAIN-SUFFIX,yaboepi.magichhw.com,Proxy\nDOMAIN-SUFFIX,bd302.com,Proxy\nDOMAIN-SUFFIX,www.snowaqi.de,Proxy\nDOMAIN-SUFFIX,koranmandarin.com,Proxy\nDOMAIN-SUFFIX,taiwanus.net,Proxy\nDOMAIN-SUFFIX,www.italia.it,Proxy\nDOMAIN-SUFFIX,kun.im,Proxy\nDOMAIN-SUFFIX,wufi.org.tw,Proxy\nDOMAIN-SUFFIX,mapsofworld.com,Proxy\nDOMAIN-SUFFIX,hosts.huhamhire.com,Proxy\nDOMAIN-SUFFIX,1680180.com,Proxy\nDOMAIN-SUFFIX,www.brenau.edu,Proxy\nDOMAIN-SUFFIX,cdn.we-cc6.xyz,Proxy\nDOMAIN-SUFFIX,hungyatw.com,Proxy\nDOMAIN-SUFFIX,gt8f.4u.cr.rs,Proxy\nDOMAIN-SUFFIX,recordhistory.org,Proxy\nDOMAIN-SUFFIX,saiq.me,Proxy\nDOMAIN-SUFFIX,bismio.com,Proxy\nDOMAIN-SUFFIX,photodharma.net,Proxy\nDOMAIN-SUFFIX,www.facebook.cz,Proxy\nDOMAIN-SUFFIX,c6396.com,Proxy\nDOMAIN-SUFFIX,filmingfortibet.org,Proxy\nDOMAIN-SUFFIX,seccionamarilla.com.mx,Proxy\nDOMAIN-SUFFIX,thejakartapost.com,Proxy\nDOMAIN-SUFFIX,www.theleader.com.au,Proxy\nDOMAIN-SUFFIX,ezachieve.com,Proxy\nDOMAIN-SUFFIX,kohq.rhy.dtdns.net,Proxy\nDOMAIN-SUFFIX,alarab.qa,Proxy\nDOMAIN-SUFFIX,nobelprize.org,Proxy\nDOMAIN-SUFFIX,kinghungip.org,Proxy\nDOMAIN-SUFFIX,openmindgroup.ro,Proxy\nDOMAIN-SUFFIX,nb33.cf,Proxy\nDOMAIN-SUFFIX,www.edsaplan.com,Proxy\nDOMAIN-SUFFIX,web.xieshenglin.com,Proxy\nDOMAIN-SUFFIX,stars.udn.com,Proxy\nDOMAIN-SUFFIX,proxy.googlezip.net,Proxy\nDOMAIN-SUFFIX,www.rolexpassionreport.com,Proxy\nDOMAIN-SUFFIX,www.naughtymachinima.com,Proxy\nDOMAIN-SUFFIX,namyuekok.freeforums.org,Proxy\nDOMAIN-SUFFIX,javbus2.com,Proxy\nDOMAIN-SUFFIX,outernet.is,Proxy\nDOMAIN-SUFFIX,nigger.land,Proxy\nDOMAIN-SUFFIX,edesk.mobi,Proxy\nDOMAIN-SUFFIX,evpn.me,Proxy\nDOMAIN-SUFFIX,znrw.4.688.org,Proxy\nDOMAIN-SUFFIX,b-ok.xyz,Proxy\nDOMAIN-SUFFIX,newrepublic.com,Proxy\nDOMAIN-SUFFIX,groupmax.hk,Proxy\nDOMAIN-SUFFIX,neptun.byethost7.com,Proxy\nDOMAIN-SUFFIX,mychart.ochin.org,Proxy\nDOMAIN-SUFFIX,richkindle.com,Proxy\nDOMAIN-SUFFIX,www.107sihu.com,Proxy\nDOMAIN-SUFFIX,oldgoesyoung.com,Proxy\nDOMAIN-SUFFIX,picacg2022.com,Proxy\nDOMAIN-SUFFIX,bt36365.com,Proxy\nDOMAIN-SUFFIX,tor-exit-59.for-privacy.net,Proxy\nDOMAIN-SUFFIX,www.wunanbooks.com.tw,Proxy\nDOMAIN-SUFFIX,www.covertbrowsing.com,Proxy\nDOMAIN-SUFFIX,foundation.app,Proxy\nDOMAIN-SUFFIX,hardsextube.com,Proxy\nDOMAIN-SUFFIX,www.flyingjizz.com,Proxy\nDOMAIN-SUFFIX,schooxy.com,Proxy\nDOMAIN-SUFFIX,google.com.sa,Proxy\nDOMAIN-SUFFIX,plm.org.hk,Proxy\nDOMAIN-SUFFIX,www.pidaiy.biz,Proxy\nDOMAIN-SUFFIX,www.hlshe.com,Proxy\nDOMAIN-SUFFIX,zongmei.cc,Proxy\nDOMAIN-SUFFIX,mqxd.org,Proxy\nDOMAIN-SUFFIX,tarab-institute.org,Proxy\nDOMAIN-SUFFIX,www.chnfree.com,Proxy\nDOMAIN-SUFFIX,www.asianinvestor.net,Proxy\nDOMAIN-SUFFIX,cachefly.com,Proxy\nDOMAIN-SUFFIX,cockyboys.com,Proxy\nDOMAIN-SUFFIX,fafa68.com,Proxy\nDOMAIN-SUFFIX,philborges.com,Proxy\nDOMAIN-SUFFIX,ow.ly,Proxy\nDOMAIN-SUFFIX,gwins.org,Proxy\nDOMAIN-SUFFIX,b33r.us,Proxy\nDOMAIN-SUFFIX,twgreatdaily.com,Proxy\nDOMAIN-SUFFIX,vmixcore.com,Proxy\nDOMAIN-SUFFIX,plexporn.com,Proxy\nDOMAIN-SUFFIX,meek.bamsoftware.com,Proxy\nDOMAIN-SUFFIX,www.cmcmarkets.co.uk,Proxy\nDOMAIN-SUFFIX,vllcs.org,Proxy\nDOMAIN-SUFFIX,j9505.com,Proxy\nDOMAIN-SUFFIX,chinu.com,Proxy\nDOMAIN-SUFFIX,google.com.uy,Proxy\nDOMAIN-SUFFIX,dnsweb.xyz,Proxy\nDOMAIN-SUFFIX,europeanvoice.com,Proxy\nDOMAIN-SUFFIX,buddhistchannel.tv,Proxy\nDOMAIN-SUFFIX,wwwdaili.com,Proxy\nDOMAIN-SUFFIX,1090ys1.com,Proxy\nDOMAIN-SUFFIX,www.cili8.org,Proxy\nDOMAIN-SUFFIX,civildisobediencemovement.org,Proxy\nDOMAIN-SUFFIX,freevpn.me,Proxy\nDOMAIN-SUFFIX,tibetheritagefund.org,Proxy\nDOMAIN-SUFFIX,www.hrea.org,Proxy\nDOMAIN-SUFFIX,sex.xxx,Proxy\nDOMAIN-SUFFIX,orallagos.pt,Proxy\nDOMAIN-SUFFIX,512.tv321.pw,Proxy\nDOMAIN-SUFFIX,liangyou.nissigz.com,Proxy\nDOMAIN-SUFFIX,linkcrypt.ws,Proxy\nDOMAIN-SUFFIX,marxist.net,Proxy\nDOMAIN-SUFFIX,jm365.biz,Proxy\nDOMAIN-SUFFIX,sherabgyaltsen.com,Proxy\nDOMAIN-SUFFIX,freevpngo.com,Proxy\nDOMAIN-SUFFIX,javhub.net,Proxy\nDOMAIN-SUFFIX,getcocoon.com,Proxy\nDOMAIN-SUFFIX,lassiet.com,Proxy\nDOMAIN-SUFFIX,epochtimes-romania.com,Proxy\nDOMAIN-SUFFIX,elpais.es,Proxy\nDOMAIN-SUFFIX,collateralmurder.org,Proxy\nDOMAIN-SUFFIX,mnewstv.com,Proxy\nDOMAIN-SUFFIX,vpnvip.com,Proxy\nDOMAIN-SUFFIX,gevpn.com,Proxy\nDOMAIN-SUFFIX,dc182.com,Proxy\nDOMAIN-SUFFIX,deck.ly,Proxy\nDOMAIN-SUFFIX,memrieconomicblog.org,Proxy\nDOMAIN-SUFFIX,4mydomain.com,Proxy\nDOMAIN-SUFFIX,258.microcycas.com,Proxy\nDOMAIN-SUFFIX,support.skype.com,Proxy\nDOMAIN-SUFFIX,qumu.com,Proxy\nDOMAIN-SUFFIX,d1or3zq9s4ius3.cloudfront.net,Proxy\nDOMAIN-SUFFIX,ddns.ms,Proxy\nDOMAIN-SUFFIX,newsroom.ap.org,Proxy\nDOMAIN-SUFFIX,www.ufula.com,Proxy\nDOMAIN-SUFFIX,www.guanacastehoy.com,Proxy\nDOMAIN-SUFFIX,avbody.tv,Proxy\nDOMAIN-SUFFIX,dsgant.dixinjh.com,Proxy\nDOMAIN-SUFFIX,google.vn,Proxy\nDOMAIN-SUFFIX,gv104.com,Proxy\nDOMAIN-SUFFIX,qk1c2exelm.enghu.shop,Proxy\nDOMAIN-SUFFIX,www.travelgayasia.com,Proxy\nDOMAIN-SUFFIX,www.everystudent.com.tw,Proxy\nDOMAIN-SUFFIX,www.bkk006.com,Proxy\nDOMAIN-SUFFIX,twistar.cc,Proxy\nDOMAIN-SUFFIX,gvt3.com,Proxy\nDOMAIN-SUFFIX,53900a.com,Proxy\nDOMAIN-SUFFIX,www.secouchermoinsbete.fr,Proxy\nDOMAIN-SUFFIX,www.hardenexpress.com.au,Proxy\nDOMAIN-SUFFIX,china-szenarien.bertelsmann-stiftung.de,Proxy\nDOMAIN-SUFFIX,ecomm.one-line.com,Proxy\nDOMAIN-SUFFIX,inmediahk.org,Proxy\nDOMAIN-SUFFIX,eurasianet.org,Proxy\nDOMAIN-SUFFIX,content.business.hahow.in,Proxy\nDOMAIN-SUFFIX,myactimes.com,Proxy\nDOMAIN-SUFFIX,canalporno.com,Proxy\nDOMAIN-SUFFIX,ddoo.cc,Proxy\nDOMAIN-SUFFIX,freemalaysiatoday.com,Proxy\nDOMAIN-SUFFIX,singlelogin.re,Proxy\nDOMAIN-SUFFIX,ne00s8783.tudouser.com,Proxy\nDOMAIN-SUFFIX,topnews.in,Proxy\nDOMAIN-SUFFIX,ebony-beauty.com,Proxy\nDOMAIN-SUFFIX,cleansite.info,Proxy\nDOMAIN-SUFFIX,tunnelbear.com,Proxy\nDOMAIN-SUFFIX,b9233.com,Proxy\nDOMAIN-SUFFIX,fireofliberty.org,Proxy\nDOMAIN-SUFFIX,imgapi.000714.xyz,Proxy\nDOMAIN-SUFFIX,www.furnas.com.br,Proxy\nDOMAIN-SUFFIX,www.ms3388.com,Proxy\nDOMAIN-SUFFIX,online.ivytech.edu,Proxy\nDOMAIN-SUFFIX,hz8804.com,Proxy\nDOMAIN-SUFFIX,blogspot.no,Proxy\nDOMAIN-SUFFIX,japorn.tv,Proxy\nDOMAIN-SUFFIX,rakusu.org,Proxy\nDOMAIN-SUFFIX,miss-no1.com,Proxy\nDOMAIN-SUFFIX,dms-av.com,Proxy\nDOMAIN-SUFFIX,141545.com,Proxy\nDOMAIN-SUFFIX,chutz.ch,Proxy\nDOMAIN-SUFFIX,cuihua.org,Proxy\nDOMAIN-SUFFIX,typesafe.com,Proxy\nDOMAIN-SUFFIX,k6965.com,Proxy\nDOMAIN-SUFFIX,bx.tl,Proxy\nDOMAIN-SUFFIX,headlinefinance.hk,Proxy\nDOMAIN-SUFFIX,mediasp.kir.jp.hypestat.com,Proxy\nDOMAIN-SUFFIX,16888vpn.com,Proxy\nDOMAIN-SUFFIX,cbsnews.com,Proxy\nDOMAIN-SUFFIX,d1.e6ad19eg3c2.xyz,Proxy\nDOMAIN-SUFFIX,qoos.com,Proxy\nDOMAIN-SUFFIX,zzz789.com,Proxy\nDOMAIN-SUFFIX,searx.run,Proxy\nDOMAIN-SUFFIX,porngals4.com,Proxy\nDOMAIN-SUFFIX,libertytimes.com.tw,Proxy\nDOMAIN-SUFFIX,googlegroups.com,Proxy\nDOMAIN-SUFFIX,seinig.ch,Proxy\nDOMAIN-SUFFIX,christusrex.org,Proxy\nDOMAIN-SUFFIX,tian051011.me,Proxy\nDOMAIN-SUFFIX,igvita.com,Proxy\nDOMAIN-SUFFIX,vpnat.com,Proxy\nDOMAIN-SUFFIX,www.frstrategie.org,Proxy\nDOMAIN-SUFFIX,badoink.com,Proxy\nDOMAIN-SUFFIX,chn.the-liberty.com,Proxy\nDOMAIN-SUFFIX,www.dafapoker.com,Proxy\nDOMAIN-SUFFIX,thewirecutter.com,Proxy\nDOMAIN-SUFFIX,gg9527.com,Proxy\nDOMAIN-SUFFIX,microvpn.com,Proxy\nDOMAIN-SUFFIX,www.neican.org,Proxy\nDOMAIN-SUFFIX,i-ab.com,Proxy\nDOMAIN-SUFFIX,mychinese.news,Proxy\nDOMAIN-SUFFIX,openlibrary.org,Proxy\nDOMAIN-SUFFIX,www.akiba-online.com,Proxy\nDOMAIN-SUFFIX,www.nationalawakening.org,Proxy\nDOMAIN-SUFFIX,tunsafe.com,Proxy\nDOMAIN-SUFFIX,show.tca.org.tw,Proxy\nDOMAIN-SUFFIX,www.2859h.com,Proxy\nDOMAIN-SUFFIX,getsync.com,Proxy\nDOMAIN-SUFFIX,youtu.be,Proxy\nDOMAIN-SUFFIX,familyporn.tv,Proxy\nDOMAIN-SUFFIX,www.momomall.com.tw,Proxy\nDOMAIN-SUFFIX,lady.5article.com,Proxy\nDOMAIN-SUFFIX,z78888.com,Proxy\nDOMAIN-SUFFIX,sunyaxiao.blogspot.hk,Proxy\nDOMAIN-SUFFIX,itland.xyz,Proxy\nDOMAIN-SUFFIX,daxa.cn,Proxy\nDOMAIN-SUFFIX,notescrypt.com,Proxy\nDOMAIN-SUFFIX,www60246242.eyny.com,Proxy\nDOMAIN-SUFFIX,applequ.com,Proxy\nDOMAIN-SUFFIX,clodi.org,Proxy\nDOMAIN-SUFFIX,s1.reutersmedia.net,Proxy\nDOMAIN-SUFFIX,dianetics.tw,Proxy\nDOMAIN-SUFFIX,tuidang.net,Proxy\nDOMAIN-SUFFIX,muslimvideo.com,Proxy\nDOMAIN-SUFFIX,d88.com,Proxy\nDOMAIN-SUFFIX,tibetsupportgroup.org,Proxy\nDOMAIN-SUFFIX,chenpokongvip.com,Proxy\nDOMAIN-SUFFIX,javlibrary.com,Proxy\nDOMAIN-SUFFIX,aaa836.net,Proxy\nDOMAIN-SUFFIX,64qna.blogspot.hk,Proxy\nDOMAIN-SUFFIX,efmoe.com,Proxy\nDOMAIN-SUFFIX,king6969.com,Proxy\nDOMAIN-SUFFIX,uhaul.com,Proxy\nDOMAIN-SUFFIX,11dream.com,Proxy\nDOMAIN-SUFFIX,teck.in,Proxy\nDOMAIN-SUFFIX,euronews.com,Proxy\nDOMAIN-SUFFIX,lanzul.com,Proxy\nDOMAIN-SUFFIX,fuli.ba,Proxy\nDOMAIN-SUFFIX,brandonvogt.com,Proxy\nDOMAIN-SUFFIX,www.zuonline.ch,Proxy\nDOMAIN-SUFFIX,www.league-funny.com,Proxy\nDOMAIN-SUFFIX,dy.jimaoyun.top,Proxy\nDOMAIN-SUFFIX,m789.net,Proxy\nDOMAIN-SUFFIX,bullog.org,Proxy\nDOMAIN-SUFFIX,q52040.com,Proxy\nDOMAIN-SUFFIX,vip.n56b.com,Proxy\nDOMAIN-SUFFIX,sfileydy.com,Proxy\nDOMAIN-SUFFIX,businessinsider.sg,Proxy\nDOMAIN-SUFFIX,google.kfd.me,Proxy\nDOMAIN-SUFFIX,proxylists.me,Proxy\nDOMAIN-SUFFIX,niubowang.com,Proxy\nDOMAIN-SUFFIX,xvbelink.com,Proxy\nDOMAIN-SUFFIX,d50vnmvifp2bs.cloudfront.net,Proxy\nDOMAIN-SUFFIX,chathamhouse.org,Proxy\nDOMAIN-SUFFIX,javnost.com,Proxy\nDOMAIN-SUFFIX,zdnet.com.tw,Proxy\nDOMAIN-SUFFIX,tor-exit-57.for-privacy.net,Proxy\nDOMAIN-SUFFIX,dynu.com,Proxy\nDOMAIN-SUFFIX,meifu.com,Proxy\nDOMAIN-SUFFIX,chinauncensored.com,Proxy\nDOMAIN-SUFFIX,vpnua.com,Proxy\nDOMAIN-SUFFIX,tv2016.ml,Proxy\nDOMAIN-SUFFIX,www.maddw.com,Proxy\nDOMAIN-SUFFIX,a66.com,Proxy\nDOMAIN-SUFFIX,kir.jp,Proxy\nDOMAIN-SUFFIX,alternate-tools.com,Proxy\nDOMAIN-SUFFIX,fyof.com,Proxy\nDOMAIN-SUFFIX,tmp.link,Proxy\nDOMAIN-SUFFIX,cs968.com,Proxy\nDOMAIN-SUFFIX,pussy.com,Proxy\nDOMAIN-SUFFIX,nitter.42l.fr,Proxy\nDOMAIN-SUFFIX,roupacaipira.com.br,Proxy\nDOMAIN-SUFFIX,seee-74977.firebaseio.com,Proxy\nDOMAIN-SUFFIX,megasesso.com,Proxy\nDOMAIN-SUFFIX,youngleak.com,Proxy\nDOMAIN-SUFFIX,bbc.co.uk,Proxy\nDOMAIN-SUFFIX,pen.org,Proxy\nDOMAIN-SUFFIX,www.95h.org.tw,Proxy\nDOMAIN-SUFFIX,acmarine.com,Proxy\nDOMAIN-SUFFIX,www.meinthw.de,Proxy\nDOMAIN-SUFFIX,cn.suroot.com,Proxy\nDOMAIN-SUFFIX,www.der-postillion.de,Proxy\nDOMAIN-SUFFIX,fffff.at,Proxy\nDOMAIN-SUFFIX,thesaturdaypaper.com.au,Proxy\nDOMAIN-SUFFIX,venchina.com,Proxy\nDOMAIN-SUFFIX,busik24.kiev.ua,Proxy\nDOMAIN-SUFFIX,qrqroo.com,Proxy\nDOMAIN-SUFFIX,www.discountbank.co.il,Proxy\nDOMAIN-SUFFIX,buddhism.about.com,Proxy\nDOMAIN-SUFFIX,open.firstory.me,Proxy\nDOMAIN-SUFFIX,dfas.mil,Proxy\nDOMAIN-SUFFIX,yh88304.com,Proxy\nDOMAIN-SUFFIX,d249ewt9w1yjhv.cloudfront.net,Proxy\nDOMAIN-SUFFIX,cmx.dyn.ch,Proxy\nDOMAIN-SUFFIX,bestroc.org,Proxy\nDOMAIN-SUFFIX,vicky2001.com,Proxy\nDOMAIN-SUFFIX,maps.google.se,Proxy\nDOMAIN-SUFFIX,steco.net,Proxy\nDOMAIN-SUFFIX,amctheatres.com,Proxy\nDOMAIN-SUFFIX,ecfa.org.tw,Proxy\nDOMAIN-SUFFIX,matevpn.com,Proxy\nDOMAIN-SUFFIX,www.kgieworld.com,Proxy\nDOMAIN-SUFFIX,sos.org,Proxy\nDOMAIN-SUFFIX,pacificquorum.com,Proxy\nDOMAIN-SUFFIX,www.faceporn.com,Proxy\nDOMAIN-SUFFIX,d2q7xz8xn8azab.cloudfront.net,Proxy\nDOMAIN-SUFFIX,vevo.com,Proxy\nDOMAIN-SUFFIX,s.us.pe,Proxy\nDOMAIN-SUFFIX,bb383.net,Proxy\nDOMAIN-SUFFIX,tjvpn.com,Proxy\nDOMAIN-SUFFIX,www.wy-777.com,Proxy\nDOMAIN-SUFFIX,chaturbate.com,Proxy\nDOMAIN-SUFFIX,winnity.ro,Proxy\nDOMAIN-SUFFIX,lotuslight.org.hk,Proxy\nDOMAIN-SUFFIX,jingzhoushi1.xyz,Proxy\nDOMAIN-SUFFIX,d1xwtayb96febg.cloudfront.net,Proxy\nDOMAIN-SUFFIX,hiitch.com,Proxy\nDOMAIN-SUFFIX,www.tnp.sg,Proxy\nDOMAIN-SUFFIX,thetrotskymovie.com,Proxy\nDOMAIN-SUFFIX,ispunblock.com,Proxy\nDOMAIN-SUFFIX,myhafiezers.blogspot.hk,Proxy\nDOMAIN-SUFFIX,iff.deaftone.com,Proxy\nDOMAIN-SUFFIX,h1665.com,Proxy\nDOMAIN-SUFFIX,www.allatvkanaler.se,Proxy\nDOMAIN-SUFFIX,www.atlanticcouncil.org,Proxy\nDOMAIN-SUFFIX,www.mediafactory.co.jp,Proxy\nDOMAIN-SUFFIX,j51.net,Proxy\nDOMAIN-SUFFIX,superssr.net,Proxy\nDOMAIN-SUFFIX,lensaterkini.web.id,Proxy\nDOMAIN-SUFFIX,xcafe.in,Proxy\nDOMAIN-SUFFIX,lflinkup.org,Proxy\nDOMAIN-SUFFIX,wagingnonviolence.org,Proxy\nDOMAIN-SUFFIX,bang-movies.com,Proxy\nDOMAIN-SUFFIX,proall-ar.blogspot.hk,Proxy\nDOMAIN-SUFFIX,twittermail.com,Proxy\nDOMAIN-SUFFIX,topbtc.com,Proxy\nDOMAIN-SUFFIX,youpak.com,Proxy\nDOMAIN-SUFFIX,kalachakralugano.org,Proxy\nDOMAIN-SUFFIX,qiangwaikan.com,Proxy\nDOMAIN-SUFFIX,www.liberalstudies.hk,Proxy\nDOMAIN-SUFFIX,www.withgoogle.com,Proxy\nDOMAIN-SUFFIX,mabo138.com,Proxy\nDOMAIN-SUFFIX,www.tovpn.net,Proxy\nDOMAIN-SUFFIX,hammerstorm.com,Proxy\nDOMAIN-SUFFIX,a88.us,Proxy\nDOMAIN-SUFFIX,www.east-plus.net,Proxy\nDOMAIN-SUFFIX,harting.com,Proxy\nDOMAIN-SUFFIX,beiboqq.com,Proxy\nDOMAIN-SUFFIX,codein.withgoogle.com,Proxy\nDOMAIN-SUFFIX,pahaunts.com,Proxy\nDOMAIN-SUFFIX,redgifs.com,Proxy\nDOMAIN-SUFFIX,we-cc2.xyz,Proxy\nDOMAIN-SUFFIX,www.18luck.com,Proxy\nDOMAIN-SUFFIX,spritvogel.de,Proxy\nDOMAIN-SUFFIX,www.kunzang.org,Proxy\nDOMAIN-SUFFIX,www.k8.com,Proxy\nDOMAIN-SUFFIX,iing.tw,Proxy\nDOMAIN-SUFFIX,americanpressinstitute.org,Proxy\nDOMAIN-SUFFIX,vw500.com,Proxy\nDOMAIN-SUFFIX,anonymous-proxy.com.de,Proxy\nDOMAIN-SUFFIX,bible.com,Proxy\nDOMAIN-SUFFIX,b2929.com,Proxy\nDOMAIN-SUFFIX,iskconnj.com,Proxy\nDOMAIN-SUFFIX,topscoliauto.ro,Proxy\nDOMAIN-SUFFIX,ldvip17.com,Proxy\nDOMAIN-SUFFIX,cubby.com,Proxy\nDOMAIN-SUFFIX,wn.com,Proxy\nDOMAIN-SUFFIX,hotbox.com,Proxy\nDOMAIN-SUFFIX,av6k.com,Proxy\nDOMAIN-SUFFIX,limsico.com,Proxy\nDOMAIN-SUFFIX,www.countytimes.co.uk,Proxy\nDOMAIN-SUFFIX,sensortower.com,Proxy\nDOMAIN-SUFFIX,bhcarroll.instructure.com,Proxy\nDOMAIN-SUFFIX,ruanyifeng.com,Proxy\nDOMAIN-SUFFIX,successfn.com,Proxy\nDOMAIN-SUFFIX,archive.istio.io,Proxy\nDOMAIN-SUFFIX,arxiv-web.arxiv.org,Proxy\nDOMAIN-SUFFIX,karayou.com,Proxy\nDOMAIN-SUFFIX,www.b44.com,Proxy\nDOMAIN-SUFFIX,www.xmail.net,Proxy\nDOMAIN-SUFFIX,zodgame.xyz,Proxy\nDOMAIN-SUFFIX,www.polestargo.com,Proxy\nDOMAIN-SUFFIX,reviewcamp.com,Proxy\nDOMAIN-SUFFIX,pornxvideos247.com,Proxy\nDOMAIN-SUFFIX,zhuanxing.cn,Proxy\nDOMAIN-SUFFIX,guangming.org,Proxy\nDOMAIN-SUFFIX,portal.shadowsocks.se,Proxy\nDOMAIN-SUFFIX,www.laozhang.tk,Proxy\nDOMAIN-SUFFIX,d3rhr7kgmtrq1v.cloudfront.net,Proxy\nDOMAIN-SUFFIX,us-central1.cloudfunctions.net,Proxy\nDOMAIN-SUFFIX,www.netsarang.com,Proxy\nDOMAIN-SUFFIX,instantfap.com,Proxy\nDOMAIN-SUFFIX,vpnpie.org,Proxy\nDOMAIN-SUFFIX,www.peoplenews.tw,Proxy\nDOMAIN-SUFFIX,adelaidebbs.com,Proxy\nDOMAIN-SUFFIX,personal.cityu.edu.hk,Proxy\nDOMAIN-SUFFIX,store.bicon.com,Proxy\nDOMAIN-SUFFIX,hotcoin.com,Proxy\nDOMAIN-SUFFIX,tkj.jp,Proxy\nDOMAIN-SUFFIX,c.pc322.xyz,Proxy\nDOMAIN-SUFFIX,www.harrisbricken.com,Proxy\nDOMAIN-SUFFIX,okyoutube.com,Proxy\nDOMAIN-SUFFIX,www.zenmind.org,Proxy\nDOMAIN-SUFFIX,mdvpn.com,Proxy\nDOMAIN-SUFFIX,media.transformativeworks.org,Proxy\nDOMAIN-SUFFIX,phoneburnia.com,Proxy\nDOMAIN-SUFFIX,www.pacificpoker.com,Proxy\nDOMAIN-SUFFIX,eng.majalla.com,Proxy\nDOMAIN-SUFFIX,sweetkiss.me,Proxy\nDOMAIN-SUFFIX,wp.com,Proxy\nDOMAIN-SUFFIX,www.94fq.net,Proxy\nDOMAIN-SUFFIX,www.filthdump.com,Proxy\nDOMAIN-SUFFIX,dwqrxvq4oij1s.cloudfront.net,Proxy\nDOMAIN-SUFFIX,info-care.org,Proxy\nDOMAIN-SUFFIX,gakkispy.github.io,Proxy\nDOMAIN-SUFFIX,static.iwincdn.com,Proxy\nDOMAIN-SUFFIX,koornk.com,Proxy\nDOMAIN-SUFFIX,www.oberpfalznetz.de,Proxy\nDOMAIN-SUFFIX,www.northwalespioneer.co.uk,Proxy\nDOMAIN-SUFFIX,moyu2.com,Proxy\nDOMAIN-SUFFIX,27.homeip.net,Proxy\nDOMAIN-SUFFIX,owa.wrinklefreeit.com,Proxy\nDOMAIN-SUFFIX,www.chatroulette.com,Proxy\nDOMAIN-SUFFIX,a823.com,Proxy\nDOMAIN-SUFFIX,stellarterm.com,Proxy\nDOMAIN-SUFFIX,jangchuplamrim.org,Proxy\nDOMAIN-SUFFIX,xvideos5.com,Proxy\nDOMAIN-SUFFIX,jacksfree.lookin.at,Proxy\nDOMAIN-SUFFIX,taylorfamily.net,Proxy\nDOMAIN-SUFFIX,www.eshowcasex.com,Proxy\nDOMAIN-SUFFIX,www.queensnake.com,Proxy\nDOMAIN-SUFFIX,lixing1.com,Proxy\nDOMAIN-SUFFIX,christiantatelu.blogspot.hk,Proxy\nDOMAIN-SUFFIX,hu.dj88dj.com,Proxy\nDOMAIN-SUFFIX,www.taxidrivermovie.com,Proxy\nDOMAIN-SUFFIX,anobii.com,Proxy\nDOMAIN-SUFFIX,www.playforceone.com,Proxy\nDOMAIN-SUFFIX,edah.us,Proxy\nDOMAIN-SUFFIX,technik-specials.de,Proxy\nDOMAIN-SUFFIX,www.csbcnet.com.tw,Proxy\nDOMAIN-SUFFIX,o.po18.tw,Proxy\nDOMAIN-SUFFIX,gudulvyou.com,Proxy\nDOMAIN-SUFFIX,18p2p.com,Proxy\nDOMAIN-SUFFIX,www.nunuyy.top,Proxy\nDOMAIN-SUFFIX,fineproxy.org,Proxy\nDOMAIN-SUFFIX,tim-chen.com,Proxy\nDOMAIN-SUFFIX,from-va.com,Proxy\nDOMAIN-SUFFIX,8870.com,Proxy\nDOMAIN-SUFFIX,clubx.org,Proxy\nDOMAIN-SUFFIX,likes-pie.com,Proxy\nDOMAIN-SUFFIX,www.jicloud.site,Proxy\nDOMAIN-SUFFIX,istmein.de,Proxy\nDOMAIN-SUFFIX,bbb26.net,Proxy\nDOMAIN-SUFFIX,zyzjma.site,Proxy\nDOMAIN-SUFFIX,www.yahoo.co.in,Proxy\nDOMAIN-SUFFIX,www.rthk.org.hk,Proxy\nDOMAIN-SUFFIX,wanip.ch,Proxy\nDOMAIN-SUFFIX,google.com.pe,Proxy\nDOMAIN-SUFFIX,javimdb.com,Proxy\nDOMAIN-SUFFIX,www.vids.net,Proxy\nDOMAIN-SUFFIX,to.ly,Proxy\nDOMAIN-SUFFIX,lirekit.ch,Proxy\nDOMAIN-SUFFIX,ns.ms.justdied.com,Proxy\nDOMAIN-SUFFIX,sketchappsources.com,Proxy\nDOMAIN-SUFFIX,wuzoii.site,Proxy\nDOMAIN-SUFFIX,www.onlyjizz.com,Proxy\nDOMAIN-SUFFIX,globalrescue.net,Proxy\nDOMAIN-SUFFIX,myway.com,Proxy\nDOMAIN-SUFFIX,thelifestyleelite.com,Proxy\nDOMAIN-SUFFIX,coqnu.com,Proxy\nDOMAIN-SUFFIX,webmail.mtco.com,Proxy\nDOMAIN-SUFFIX,www.2235h.com,Proxy\nDOMAIN-SUFFIX,cdn.we-cc7.xyz,Proxy\nDOMAIN-SUFFIX,service.sbh.idv.tw,Proxy\nDOMAIN-SUFFIX,www.jsok789.com,Proxy\nDOMAIN-SUFFIX,dalailamatrust.org,Proxy\nDOMAIN-SUFFIX,feitian-california.org,Proxy\nDOMAIN-SUFFIX,youtube.ca,Proxy\nDOMAIN-SUFFIX,furcanada.com,Proxy\nDOMAIN-SUFFIX,macau-jc.com,Proxy\nDOMAIN-SUFFIX,esu.wiki,Proxy\nDOMAIN-SUFFIX,xam000000.com,Proxy\nDOMAIN-SUFFIX,google.ac,Proxy\nDOMAIN-SUFFIX,www.koding.com,Proxy\nDOMAIN-SUFFIX,huhaitai.com,Proxy\nDOMAIN-SUFFIX,www.clipconverter.cc,Proxy\nDOMAIN-SUFFIX,superfreevpn.com,Proxy\nDOMAIN-SUFFIX,388123r.com,Proxy\nDOMAIN-SUFFIX,selfip.org,Proxy\nDOMAIN-SUFFIX,tipo.gov.tw,Proxy\nDOMAIN-SUFFIX,deviantart.net,Proxy\nDOMAIN-SUFFIX,d2d1zfqgifngbh.cloudfront.net,Proxy\nDOMAIN-SUFFIX,hkptu.org,Proxy\nDOMAIN-SUFFIX,china.aiddata.org,Proxy\nDOMAIN-SUFFIX,mandelengel.ch,Proxy\nDOMAIN-SUFFIX,huping.net,Proxy\nDOMAIN-SUFFIX,dns.dnswarden.com,Proxy\nDOMAIN-SUFFIX,www.humanrightsdefenders.org,Proxy\nDOMAIN-SUFFIX,www.notarypublic.idv.tw,Proxy\nDOMAIN-SUFFIX,reuters.fr,Proxy\nDOMAIN-SUFFIX,ddvpn.com,Proxy\nDOMAIN-SUFFIX,skypost.hk,Proxy\nDOMAIN-SUFFIX,8maple.8dgo.net,Proxy\nDOMAIN-SUFFIX,globalmeet.webcasts.com,Proxy\nDOMAIN-SUFFIX,nds69.com,Proxy\nDOMAIN-SUFFIX,nexon.com,Proxy\nDOMAIN-SUFFIX,d1px0u29yrtpxd.cloudfront.net,Proxy\nDOMAIN-SUFFIX,tb9995.com,Proxy\nDOMAIN-SUFFIX,www.unblockaccess.com,Proxy\nDOMAIN-SUFFIX,lindapp.com,Proxy\nDOMAIN-SUFFIX,waymo.com,Proxy\nDOMAIN-SUFFIX,e87171.com,Proxy\nDOMAIN-SUFFIX,www.tibetfreunde.ch,Proxy\nDOMAIN-SUFFIX,tay.instanthq.com,Proxy\nDOMAIN-SUFFIX,rpc.hentaiathome.net,Proxy\nDOMAIN-SUFFIX,metartx.com,Proxy\nDOMAIN-SUFFIX,studioluxfm.com,Proxy\nDOMAIN-SUFFIX,papeling.org,Proxy\nDOMAIN-SUFFIX,www.a-wha.idv.tw,Proxy\nDOMAIN-SUFFIX,www.facebook.jp,Proxy\nDOMAIN-SUFFIX,o8ky.14.iamallama.com,Proxy\nDOMAIN-SUFFIX,rmbl.ws,Proxy\nDOMAIN-SUFFIX,a20309999.byethost9.com,Proxy\nDOMAIN-SUFFIX,bbcpersian.com,Proxy\nDOMAIN-SUFFIX,www.tw18.com,Proxy\nDOMAIN-SUFFIX,airav.vip,Proxy\nDOMAIN-SUFFIX,secureservercdn.net,Proxy\nDOMAIN-SUFFIX,newjrs.xyz,Proxy\nDOMAIN-SUFFIX,junauza.com,Proxy\nDOMAIN-SUFFIX,www.motifart.com,Proxy\nDOMAIN-SUFFIX,romel.lt,Proxy\nDOMAIN-SUFFIX,www.grenfellrecord.com.au,Proxy\nDOMAIN-SUFFIX,gloryhole.com,Proxy\nDOMAIN-SUFFIX,1lib.org,Proxy\nDOMAIN-SUFFIX,aeriesnet.murrieta.k12.ca.us,Proxy\nDOMAIN-SUFFIX,cc.eye.rs,Proxy\nDOMAIN-SUFFIX,o20.colafile.com,Proxy\nDOMAIN-SUFFIX,www.youbiyao.xyz,Proxy\nDOMAIN-SUFFIX,www.vmagazine.com,Proxy\nDOMAIN-SUFFIX,j9502.com,Proxy\nDOMAIN-SUFFIX,hideipvpn.com,Proxy\nDOMAIN-SUFFIX,www.colatour.com.tw,Proxy\nDOMAIN-SUFFIX,bdg510.com,Proxy\nDOMAIN-SUFFIX,luminati.io,Proxy\nDOMAIN-SUFFIX,nimmsis.net,Proxy\nDOMAIN-SUFFIX,destiny.to,Proxy\nDOMAIN-SUFFIX,save02.gamefast666.com,Proxy\nDOMAIN-SUFFIX,maison.kose.co.jp,Proxy\nDOMAIN-SUFFIX,csdc8888.com,Proxy\nDOMAIN-SUFFIX,vichoste.cl,Proxy\nDOMAIN-SUFFIX,mrslove.com,Proxy\nDOMAIN-SUFFIX,ed.gov,Proxy\nDOMAIN-SUFFIX,kmarstructures.com,Proxy\nDOMAIN-SUFFIX,www.letscorp.net,Proxy\nDOMAIN-SUFFIX,piavpn.com,Proxy\nDOMAIN-SUFFIX,psiphon3.net,Proxy\nDOMAIN-SUFFIX,ncxv.xyz,Proxy\nDOMAIN-SUFFIX,cucumbertube.com,Proxy\nDOMAIN-SUFFIX,www.vpnmaster.com,Proxy\nDOMAIN-SUFFIX,hello-hk.blogspot.hk,Proxy\nDOMAIN-SUFFIX,croxy.org,Proxy\nDOMAIN-SUFFIX,hkvaliant.org,Proxy\nDOMAIN-SUFFIX,starp2p.com,Proxy\nDOMAIN-SUFFIX,destatevi.org,Proxy\nDOMAIN-SUFFIX,lanterncn.org,Proxy\nDOMAIN-SUFFIX,fulcrumapp.com,Proxy\nDOMAIN-SUFFIX,milosvillas.gr,Proxy\nDOMAIN-SUFFIX,gnci.org.hk,Proxy\nDOMAIN-SUFFIX,notreallyblocked.telex.cc,Proxy\nDOMAIN-SUFFIX,www.nifty.com,Proxy\nDOMAIN-SUFFIX,pixivsketch.net,Proxy\nDOMAIN-SUFFIX,blog.yandere.moe,Proxy\nDOMAIN-SUFFIX,drive.ru,Proxy\nDOMAIN-SUFFIX,502porn.com,Proxy\nDOMAIN-SUFFIX,gt9933.com,Proxy\nDOMAIN-SUFFIX,bszet.de,Proxy\nDOMAIN-SUFFIX,91avv.cc,Proxy\nDOMAIN-SUFFIX,ww-cc4.xyz,Proxy\nDOMAIN-SUFFIX,dns-dns.com,Proxy\nDOMAIN-SUFFIX,fudasege.us,Proxy\nDOMAIN-SUFFIX,bbs.fallenark.com,Proxy\nDOMAIN-SUFFIX,codehouse.co.kr,Proxy\nDOMAIN-SUFFIX,fast.wistia.com,Proxy\nDOMAIN-SUFFIX,adult.friendfinder.com,Proxy\nDOMAIN-SUFFIX,atn.co.za,Proxy\nDOMAIN-SUFFIX,www.getabstract.com,Proxy\nDOMAIN-SUFFIX,cnsnews.com,Proxy\nDOMAIN-SUFFIX,subscription.ft.com,Proxy\nDOMAIN-SUFFIX,esports.ggcarry888.com,Proxy\nDOMAIN-SUFFIX,accessvpn.com,Proxy\nDOMAIN-SUFFIX,change.org,Proxy\nDOMAIN-SUFFIX,b203.com,Proxy\nDOMAIN-SUFFIX,pausedmemories.com,Proxy\nDOMAIN-SUFFIX,harvard.edu,Proxy\nDOMAIN-SUFFIX,www.webpage.idv.tw,Proxy\nDOMAIN-SUFFIX,www.cathaysite.com.tw,Proxy\nDOMAIN-SUFFIX,f3338.com,Proxy\nDOMAIN-SUFFIX,steemit.com,Proxy\nDOMAIN-SUFFIX,www.idlcoyote.com,Proxy\nDOMAIN-SUFFIX,www.ulifestyle.com.hk,Proxy\nDOMAIN-SUFFIX,mtrfoods.com,Proxy\nDOMAIN-SUFFIX,nsc.gov.tw,Proxy\nDOMAIN-SUFFIX,special.miffyliye.org,Proxy\nDOMAIN-SUFFIX,www.iprivo.com,Proxy\nDOMAIN-SUFFIX,forum.doctorvoice.org,Proxy\nDOMAIN-SUFFIX,mariodesigns.uk,Proxy\nDOMAIN-SUFFIX,geekproxy.com,Proxy\nDOMAIN-SUFFIX,acg18.org,Proxy\nDOMAIN-SUFFIX,66.cr.rs,Proxy\nDOMAIN-SUFFIX,websitepulse.com,Proxy\nDOMAIN-SUFFIX,nothinghere.tk,Proxy\nDOMAIN-SUFFIX,yull-2.myshopify.com,Proxy\nDOMAIN-SUFFIX,pornovideoshub.com,Proxy\nDOMAIN-SUFFIX,aamacau.com,Proxy\nDOMAIN-SUFFIX,austrodiesel.me,Proxy\nDOMAIN-SUFFIX,exway.us,Proxy\nDOMAIN-SUFFIX,xp303.com,Proxy\nDOMAIN-SUFFIX,a.idm.host,Proxy\nDOMAIN-SUFFIX,nicebowl.moe,Proxy\nDOMAIN-SUFFIX,acx.io,Proxy\nDOMAIN-SUFFIX,jeepcenter.gr,Proxy\nDOMAIN-SUFFIX,quora.fr,Proxy\nDOMAIN-SUFFIX,ssyoutube.com,Proxy\nDOMAIN-SUFFIX,sbf363.com,Proxy\nDOMAIN-SUFFIX,obsession.co.ve,Proxy\nDOMAIN-SUFFIX,cash-168.com,Proxy\nDOMAIN-SUFFIX,shwchurch.org,Proxy\nDOMAIN-SUFFIX,www.yahoo.com.br,Proxy\nDOMAIN-SUFFIX,haima888.com,Proxy\nDOMAIN-SUFFIX,hullcham.strikingly.com,Proxy\nDOMAIN-SUFFIX,nitter.salastil.com,Proxy\nDOMAIN-SUFFIX,rabita.fi,Proxy\nDOMAIN-SUFFIX,chinanews.sina.com,Proxy\nDOMAIN-SUFFIX,yahooyoutube.com,Proxy\nDOMAIN-SUFFIX,amittal.in,Proxy\nDOMAIN-SUFFIX,ca762.com,Proxy\nDOMAIN-SUFFIX,chinascope.org,Proxy\nDOMAIN-SUFFIX,my.krypt.com,Proxy\nDOMAIN-SUFFIX,yin016.com,Proxy\nDOMAIN-SUFFIX,iphone14.com,Proxy\nDOMAIN-SUFFIX,magazinulcudetoate.ro,Proxy\nDOMAIN-SUFFIX,fisipa.com.ar,Proxy\nDOMAIN-SUFFIX,sohografica.ro,Proxy\nDOMAIN-SUFFIX,www.etas.com,Proxy\nDOMAIN-SUFFIX,sha0001.com,Proxy\nDOMAIN-SUFFIX,www.wahahafactory.com,Proxy\nDOMAIN-SUFFIX,d3nahm1llsrjst.cloudfront.net,Proxy\nDOMAIN-SUFFIX,hk.geocities.com,Proxy\nDOMAIN-SUFFIX,tt1366.com,Proxy\nDOMAIN-SUFFIX,nhk-ondemand.jp,Proxy\nDOMAIN-SUFFIX,4r12.gl.grr.io,Proxy\nDOMAIN-SUFFIX,www.cutegaytwink.com,Proxy\nDOMAIN-SUFFIX,thinkgeek.com,Proxy\nDOMAIN-SUFFIX,hells.pl,Proxy\nDOMAIN-SUFFIX,winnipegsun.com,Proxy\nDOMAIN-SUFFIX,www.googlechinablog.com,Proxy\nDOMAIN-SUFFIX,www.ritsumei-arsvi.org,Proxy\nDOMAIN-SUFFIX,note.meetcafe.net,Proxy\nDOMAIN-SUFFIX,brauclub.ch,Proxy\nDOMAIN-SUFFIX,zfreez.com,Proxy\nDOMAIN-SUFFIX,myocn.net,Proxy\nDOMAIN-SUFFIX,ratedporntube.com,Proxy\nDOMAIN-SUFFIX,hlw66.com,Proxy\nDOMAIN-SUFFIX,urlborg.com,Proxy\nDOMAIN-SUFFIX,vip1615.com,Proxy\nDOMAIN-SUFFIX,aaaspanking.com,Proxy\nDOMAIN-SUFFIX,social.lol,Proxy\nDOMAIN-SUFFIX,xh3555.com,Proxy\nDOMAIN-SUFFIX,tb6605.com,Proxy\nDOMAIN-SUFFIX,alsupnet.com,Proxy\nDOMAIN-SUFFIX,javzoo.com,Proxy\nDOMAIN-SUFFIX,cmx.pp.ua,Proxy\nDOMAIN-SUFFIX,modelhub.com,Proxy\nDOMAIN-SUFFIX,cokesoft.com,Proxy\nDOMAIN-SUFFIX,tbicn.org,Proxy\nDOMAIN-SUFFIX,w2.xggfgczh781.xyz,Proxy\nDOMAIN-SUFFIX,rovio.com,Proxy\nDOMAIN-SUFFIX,free-web-proxy.de,Proxy\nDOMAIN-SUFFIX,hao.news,Proxy\nDOMAIN-SUFFIX,www.azattyk.kg,Proxy\nDOMAIN-SUFFIX,0528.cc,Proxy\nDOMAIN-SUFFIX,blog.bengmugenr.com,Proxy\nDOMAIN-SUFFIX,tor.thecthulhu.com,Proxy\nDOMAIN-SUFFIX,www.rbc.idv.tw,Proxy\nDOMAIN-SUFFIX,bbsdigest.com,Proxy\nDOMAIN-SUFFIX,maktoob.yahoo.com,Proxy\nDOMAIN-SUFFIX,rdv.com.co,Proxy\nDOMAIN-SUFFIX,1000giri.net,Proxy\nDOMAIN-SUFFIX,g04.8899321.com,Proxy\nDOMAIN-SUFFIX,sundayguardianlive.com,Proxy\nDOMAIN-SUFFIX,n.ramle.be,Proxy\nDOMAIN-SUFFIX,tibetchild.org,Proxy\nDOMAIN-SUFFIX,koreanfriendfinder.com,Proxy\nDOMAIN-SUFFIX,podbooks.tw,Proxy\nDOMAIN-SUFFIX,www.v2351.com,Proxy\nDOMAIN-SUFFIX,www.google.co.ve,Proxy\nDOMAIN-SUFFIX,bbs.flash2u.com.tw,Proxy\nDOMAIN-SUFFIX,dailymail.co.uk,Proxy\nDOMAIN-SUFFIX,www.1980.org.tw,Proxy\nDOMAIN-SUFFIX,www.e8716.com,Proxy\nDOMAIN-SUFFIX,captainstabbin.com,Proxy\nDOMAIN-SUFFIX,www.filtersneak.com,Proxy\nDOMAIN-SUFFIX,ugvmtw.site,Proxy\nDOMAIN-SUFFIX,enanyang.com.my,Proxy\nDOMAIN-SUFFIX,www.twport.com.tw,Proxy\nDOMAIN-SUFFIX,xjp.cc,Proxy\nDOMAIN-SUFFIX,tradeadexchange.com,Proxy\nDOMAIN-SUFFIX,www.cyberpunked.org,Proxy\nDOMAIN-SUFFIX,iecology.org,Proxy\nDOMAIN-SUFFIX,tf18.com,Proxy\nDOMAIN-SUFFIX,www.twra.org.tw,Proxy\nDOMAIN-SUFFIX,osaka69.com,Proxy\nDOMAIN-SUFFIX,vpnov.com,Proxy\nDOMAIN-SUFFIX,strawberrynet.com,Proxy\nDOMAIN-SUFFIX,5182228.com,Proxy\nDOMAIN-SUFFIX,rumbatan.com,Proxy\nDOMAIN-SUFFIX,x.zgjznkyy.com,Proxy\nDOMAIN-SUFFIX,googleinsidesearch.com,Proxy\nDOMAIN-SUFFIX,tibetanlanguage.org,Proxy\nDOMAIN-SUFFIX,www.nyt.net,Proxy\nDOMAIN-SUFFIX,www.baramangaonline.com,Proxy\nDOMAIN-SUFFIX,www.4hu55.com,Proxy\nDOMAIN-SUFFIX,dxkde5k4indt6.cloudfront.net,Proxy\nDOMAIN-SUFFIX,game.7xing.me,Proxy\nDOMAIN-SUFFIX,18virginsex.com,Proxy\nDOMAIN-SUFFIX,www-7775678.com,Proxy\nDOMAIN-SUFFIX,video.aol.ca,Proxy\nDOMAIN-SUFFIX,www.pinview.com.tw,Proxy\nDOMAIN-SUFFIX,nko.navy.mil,Proxy\nDOMAIN-SUFFIX,northvilleschools.org,Proxy\nDOMAIN-SUFFIX,get-express-vpn.com,Proxy\nDOMAIN-SUFFIX,blog.myorz.com,Proxy\nDOMAIN-SUFFIX,tmpp.org,Proxy\nDOMAIN-SUFFIX,www.wsdc554.com,Proxy\nDOMAIN-SUFFIX,bangbrothers.com,Proxy\nDOMAIN-SUFFIX,mymom.info,Proxy\nDOMAIN-SUFFIX,www.socks-proxy.net,Proxy\nDOMAIN-SUFFIX,blm856.com,Proxy\nDOMAIN-SUFFIX,chinese.net.au,Proxy\nDOMAIN-SUFFIX,www.nubank.com.br,Proxy\nDOMAIN-SUFFIX,www.googto.com,Proxy\nDOMAIN-SUFFIX,mummysgold.com,Proxy\nDOMAIN-SUFFIX,baidu-av.com,Proxy\nDOMAIN-SUFFIX,gotv.ctitv.com.tw,Proxy\nDOMAIN-SUFFIX,www.goldpay.com,Proxy\nDOMAIN-SUFFIX,pecelmadiun.web.id,Proxy\nDOMAIN-SUFFIX,williamhill.com,Proxy\nDOMAIN-SUFFIX,90x40.cl,Proxy\nDOMAIN-SUFFIX,szs.net,Proxy\nDOMAIN-SUFFIX,www.google.vu,Proxy\nDOMAIN-SUFFIX,monica.im,Proxy\nDOMAIN-SUFFIX,episcopalchurch.org,Proxy\nDOMAIN-SUFFIX,autobild.de,Proxy\nDOMAIN-SUFFIX,www.postbank.de,Proxy\nDOMAIN-SUFFIX,trans.wenweipo.com,Proxy\nDOMAIN-SUFFIX,cheaperapp1.work,Proxy\nDOMAIN-SUFFIX,gcntv.org,Proxy\nDOMAIN-SUFFIX,maitripa.org,Proxy\nDOMAIN-SUFFIX,fafa19.com,Proxy\nDOMAIN-SUFFIX,snacky.longluntan.com,Proxy\nDOMAIN-SUFFIX,yuktha.com,Proxy\nDOMAIN-SUFFIX,ld12.pro,Proxy\nDOMAIN-SUFFIX,www.supervpn.net,Proxy\nDOMAIN-SUFFIX,usability.com,Proxy\nDOMAIN-SUFFIX,77n77.cc,Proxy\nDOMAIN-SUFFIX,www.redlandcitybulletin.com.au,Proxy\nDOMAIN-SUFFIX,dbmws10dbd2dl.cloudfront.net,Proxy\nDOMAIN-SUFFIX,25.effers.com,Proxy\nDOMAIN-SUFFIX,dns.google,Proxy\nDOMAIN-SUFFIX,americangreencard.com,Proxy\nDOMAIN-SUFFIX,vdi.water.ca.gov,Proxy\nDOMAIN-SUFFIX,puritan.com,Proxy\nDOMAIN-SUFFIX,recapcha.net,Proxy\nDOMAIN-SUFFIX,lindadevries.com,Proxy\nDOMAIN-SUFFIX,asiasociety.org.hk,Proxy\nDOMAIN-SUFFIX,amnesty.tw,Proxy\nDOMAIN-SUFFIX,glodls.to,Proxy\nDOMAIN-SUFFIX,www.internationalaffairs.org.au,Proxy\nDOMAIN-SUFFIX,fame.gonzolabs.org,Proxy\nDOMAIN-SUFFIX,www.dataliberation.org,Proxy\nDOMAIN-SUFFIX,mmmglobal.org,Proxy\nDOMAIN-SUFFIX,hayatnuri.com,Proxy\nDOMAIN-SUFFIX,wikileaks.pl,Proxy\nDOMAIN-SUFFIX,jgg18.com,Proxy\nDOMAIN-SUFFIX,in.appcenter.me,Proxy\nDOMAIN-SUFFIX,ghostery.com,Proxy\nDOMAIN-SUFFIX,28.slyip.net,Proxy\nDOMAIN-SUFFIX,inglot.pt,Proxy\nDOMAIN-SUFFIX,ricochet.im,Proxy\nDOMAIN-SUFFIX,www.hacg.in,Proxy\nDOMAIN-SUFFIX,mycenturylink.com,Proxy\nDOMAIN-SUFFIX,liverpoolfc.tv,Proxy\nDOMAIN-SUFFIX,xh1666.com,Proxy\nDOMAIN-SUFFIX,www.gvlibrary.com,Proxy\nDOMAIN-SUFFIX,streamingthe.net,Proxy\nDOMAIN-SUFFIX,www.zhongwen.com,Proxy\nDOMAIN-SUFFIX,thywords.com.tw,Proxy\nDOMAIN-SUFFIX,gospelforasia.org,Proxy\nDOMAIN-SUFFIX,aiweiweiblog.com,Proxy\nDOMAIN-SUFFIX,ss.welsmann.com,Proxy\nDOMAIN-SUFFIX,mail.coldjet.com,Proxy\nDOMAIN-SUFFIX,youfreeproxytube.com,Proxy\nDOMAIN-SUFFIX,www.internetmodeling.com,Proxy\nDOMAIN-SUFFIX,store.sstuan.net,Proxy\nDOMAIN-SUFFIX,godaddy.com,Proxy\nDOMAIN-SUFFIX,www.meijumi.top,Proxy\nDOMAIN-SUFFIX,ecministry.net,Proxy\nDOMAIN-SUFFIX,ftv.com.tw,Proxy\nDOMAIN-SUFFIX,advertfan.com,Proxy\nDOMAIN-SUFFIX,p01.x.dropbox-plus.tk,Proxy\nDOMAIN-SUFFIX,ithelp.ithome.com.tw,Proxy\nDOMAIN-SUFFIX,pachosting.com,Proxy\nDOMAIN-SUFFIX,americanunfinished.com,Proxy\nDOMAIN-SUFFIX,tono-oka.jp,Proxy\nDOMAIN-SUFFIX,www.mag2.com,Proxy\nDOMAIN-SUFFIX,brazzersnetwork.com,Proxy\nDOMAIN-SUFFIX,sifangcai.com,Proxy\nDOMAIN-SUFFIX,b.cowoo.win,Proxy\nDOMAIN-SUFFIX,angela-merkel.de,Proxy\nDOMAIN-SUFFIX,socaltibet.org,Proxy\nDOMAIN-SUFFIX,yezimary.spaces.live.com,Proxy\nDOMAIN-SUFFIX,www.wizproxy.com,Proxy\nDOMAIN-SUFFIX,homedepot.com,Proxy\nDOMAIN-SUFFIX,search.stinpriza.org,Proxy\nDOMAIN-SUFFIX,bungertstrasse.ch,Proxy\nDOMAIN-SUFFIX,www.1365tu.com,Proxy\nDOMAIN-SUFFIX,1950033.com,Proxy\nDOMAIN-SUFFIX,b8677.com,Proxy\nDOMAIN-SUFFIX,radio-canada.ca,Proxy\nDOMAIN-SUFFIX,jav68.tv,Proxy\nDOMAIN-SUFFIX,www.rightbtc.com,Proxy\nDOMAIN-SUFFIX,blog.yam.com,Proxy\nDOMAIN-SUFFIX,www.axjhd.com,Proxy\nDOMAIN-SUFFIX,xh3678.com,Proxy\nDOMAIN-SUFFIX,assembla.com,Proxy\nDOMAIN-SUFFIX,societymatters.org,Proxy\nDOMAIN-SUFFIX,www.magiaados.com,Proxy\nDOMAIN-SUFFIX,www.manchukuo.org,Proxy\nDOMAIN-SUFFIX,755.gotgeeks.com,Proxy\nDOMAIN-SUFFIX,litmos.com,Proxy\nDOMAIN-SUFFIX,www.xh8708.com,Proxy\nDOMAIN-SUFFIX,social.edu.ci,Proxy\nDOMAIN-SUFFIX,www.freesexrus.com,Proxy\nDOMAIN-SUFFIX,gstatic.com,Proxy\nDOMAIN-SUFFIX,m.12manapp.com,Proxy\nDOMAIN-SUFFIX,s1.yimg.com,Proxy\nDOMAIN-SUFFIX,88888money.com,Proxy\nDOMAIN-SUFFIX,chapm25.com,Proxy\nDOMAIN-SUFFIX,www.valu-trades.com,Proxy\nDOMAIN-SUFFIX,d3jzyhzdnubato.cloudfront.net,Proxy\nDOMAIN-SUFFIX,xiuxiqu.org,Proxy\nDOMAIN-SUFFIX,console.marsix.net,Proxy\nDOMAIN-SUFFIX,cs.com,Proxy\nDOMAIN-SUFFIX,abvpn.com,Proxy\nDOMAIN-SUFFIX,mhradio.org,Proxy\nDOMAIN-SUFFIX,myssx.com,Proxy\nDOMAIN-SUFFIX,trader.lcg.com,Proxy\nDOMAIN-SUFFIX,chatzy.com,Proxy\nDOMAIN-SUFFIX,hgbc.co.uk,Proxy\nDOMAIN-SUFFIX,vpnmonster.ru,Proxy\nDOMAIN-SUFFIX,www.brazzers-girls.com,Proxy\nDOMAIN-SUFFIX,muramura.tv,Proxy\nDOMAIN-SUFFIX,www.imssx.com,Proxy\nDOMAIN-SUFFIX,freedominfonetweb.wordpress.com,Proxy\nDOMAIN-SUFFIX,cccat.co,Proxy\nDOMAIN-SUFFIX,75866yy.com,Proxy\nDOMAIN-SUFFIX,lhasapost.com,Proxy\nDOMAIN-SUFFIX,bc8829.com,Proxy\nDOMAIN-SUFFIX,ozxw.com,Proxy\nDOMAIN-SUFFIX,thompent.com,Proxy\nDOMAIN-SUFFIX,41.co.uk,Proxy\nDOMAIN-SUFFIX,www.econlib.org,Proxy\nDOMAIN-SUFFIX,is-a-nurse.com,Proxy\nDOMAIN-SUFFIX,baijie.org,Proxy\nDOMAIN-SUFFIX,www.eastturkistan.net,Proxy\nDOMAIN-SUFFIX,85cc.us,Proxy\nDOMAIN-SUFFIX,sellsyourhome.org,Proxy\nDOMAIN-SUFFIX,oxg1.gor.b0ne.com,Proxy\nDOMAIN-SUFFIX,www.zccp40.com,Proxy\nDOMAIN-SUFFIX,www.bababam.com,Proxy\nDOMAIN-SUFFIX,autoshipment.com,Proxy\nDOMAIN-SUFFIX,soundcloud.com,Proxy\nDOMAIN-SUFFIX,tickmill.com,Proxy\nDOMAIN-SUFFIX,www.thedailymail.com,Proxy\nDOMAIN-SUFFIX,is-a-knight.org,Proxy\nDOMAIN-SUFFIX,antiwave.net,Proxy\nDOMAIN-SUFFIX,www.razor.tv,Proxy\nDOMAIN-SUFFIX,sm.slyip.net,Proxy\nDOMAIN-SUFFIX,cdjp.org,Proxy\nDOMAIN-SUFFIX,google.md,Proxy\nDOMAIN-SUFFIX,storytaiwan.tw,Proxy\nDOMAIN-SUFFIX,www.thetvnet.com,Proxy\nDOMAIN-SUFFIX,masago.kir.jp,Proxy\nDOMAIN-SUFFIX,tra.tvbjjj.com,Proxy\nDOMAIN-SUFFIX,www.n-tv.de,Proxy\nDOMAIN-SUFFIX,xbabe.com,Proxy\nDOMAIN-SUFFIX,zh.singlelogin.re-1,Proxy\nDOMAIN-SUFFIX,casinoriva.com,Proxy\nDOMAIN-SUFFIX,hwakang.org.tw,Proxy\nDOMAIN-SUFFIX,d2g74y4xy50ozi.cloudfront.net,Proxy\nDOMAIN-SUFFIX,downyoutube.com,Proxy\nDOMAIN-SUFFIX,taipeisociety.org,Proxy\nDOMAIN-SUFFIX,dicmusic.club,Proxy\nDOMAIN-SUFFIX,submityourtapes.com,Proxy\nDOMAIN-SUFFIX,penguinvids.com,Proxy\nDOMAIN-SUFFIX,sanqianying004.jigsy.com,Proxy\nDOMAIN-SUFFIX,www.dalailamanola.com,Proxy\nDOMAIN-SUFFIX,china21.org,Proxy\nDOMAIN-SUFFIX,google.gl,Proxy\nDOMAIN-SUFFIX,kinmen.travel,Proxy\nDOMAIN-SUFFIX,imgchili.net,Proxy\nDOMAIN-SUFFIX,www.petervink.nl,Proxy\nDOMAIN-SUFFIX,info-graf.fr,Proxy\nDOMAIN-SUFFIX,itspay.com,Proxy\nDOMAIN-SUFFIX,monstercurves.com,Proxy\nDOMAIN-SUFFIX,4927.com,Proxy\nDOMAIN-SUFFIX,649.net,Proxy\nDOMAIN-SUFFIX,www.bravotube.net,Proxy\nDOMAIN-SUFFIX,free-xueq-jianb.github.io,Proxy\nDOMAIN-SUFFIX,uploaded.net,Proxy\nDOMAIN-SUFFIX,crikey.com.au,Proxy\nDOMAIN-SUFFIX,www.ttmeiju.com,Proxy\nDOMAIN-SUFFIX,vporn.com,Proxy\nDOMAIN-SUFFIX,cd22.gq,Proxy\nDOMAIN-SUFFIX,ncregister.com,Proxy\nDOMAIN-SUFFIX,466453.com,Proxy\nDOMAIN-SUFFIX,fiddle.jshell.net,Proxy\nDOMAIN-SUFFIX,xianjian.tw,Proxy\nDOMAIN-SUFFIX,theatrum-belli.com,Proxy\nDOMAIN-SUFFIX,blacked.com,Proxy\nDOMAIN-SUFFIX,310128.com,Proxy\nDOMAIN-SUFFIX,dns.vinnyp.xyz,Proxy\nDOMAIN-SUFFIX,www.taiwannews.com.tw,Proxy\nDOMAIN-SUFFIX,doh.42l.fr,Proxy\nDOMAIN-SUFFIX,shadowx.win,Proxy\nDOMAIN-SUFFIX,www.fxopen.ru,Proxy\nDOMAIN-SUFFIX,chinadailymail.com,Proxy\nDOMAIN-SUFFIX,6663011.com,Proxy\nDOMAIN-SUFFIX,indiatimes.com,Proxy\nDOMAIN-SUFFIX,electionsmeter.com,Proxy\nDOMAIN-SUFFIX,privateinternetaccess.com,Proxy\nDOMAIN-SUFFIX,carcano.me,Proxy\nDOMAIN-SUFFIX,rh.com,Proxy\nDOMAIN-SUFFIX,992.flnet.org,Proxy\nDOMAIN-SUFFIX,justporno.tv,Proxy\nDOMAIN-SUFFIX,www.hxcpp22.com,Proxy\nDOMAIN-SUFFIX,huaglad.com,Proxy\nDOMAIN-SUFFIX,oikos.com.tw,Proxy\nDOMAIN-SUFFIX,www2.unotelly.com,Proxy\nDOMAIN-SUFFIX,cfan.xyz,Proxy\nDOMAIN-SUFFIX,appledaily.com,Proxy\nDOMAIN-SUFFIX,www.levanto.be,Proxy\nDOMAIN-SUFFIX,www.skaffold.com,Proxy\nDOMAIN-SUFFIX,jjco.in,Proxy\nDOMAIN-SUFFIX,www.ntue.edu.tw,Proxy\nDOMAIN-SUFFIX,322722.com,Proxy\nDOMAIN-SUFFIX,195663.com,Proxy\nDOMAIN-SUFFIX,www.vpngeeks.com,Proxy\nDOMAIN-SUFFIX,xxmap1.one,Proxy\nDOMAIN-SUFFIX,simbolostwitter.com,Proxy\nDOMAIN-SUFFIX,uberproxy.net,Proxy\nDOMAIN-SUFFIX,uopeople.edu,Proxy\nDOMAIN-SUFFIX,china.tg,Proxy\nDOMAIN-SUFFIX,d9662.com,Proxy\nDOMAIN-SUFFIX,punishtube.com,Proxy\nDOMAIN-SUFFIX,www.mexc.com,Proxy\nDOMAIN-SUFFIX,liecut.net,Proxy\nDOMAIN-SUFFIX,www.liu-xiaobo.org,Proxy\nDOMAIN-SUFFIX,uygur.org,Proxy\nDOMAIN-SUFFIX,28fdc.com,Proxy\nDOMAIN-SUFFIX,cn.man715.com,Proxy\nDOMAIN-SUFFIX,news.laborinfocn2.com,Proxy\nDOMAIN-SUFFIX,www.jejer.net,Proxy\nDOMAIN-SUFFIX,www.loliget.com,Proxy\nDOMAIN-SUFFIX,www.southcoastregister.com.au,Proxy\nDOMAIN-SUFFIX,infinitumx.io,Proxy\nDOMAIN-SUFFIX,twittergadget.com,Proxy\nDOMAIN-SUFFIX,catchgod.com,Proxy\nDOMAIN-SUFFIX,surgitools.net,Proxy\nDOMAIN-SUFFIX,twiggit.org,Proxy\nDOMAIN-SUFFIX,ddns.us,Proxy\nDOMAIN-SUFFIX,sincai2.com,Proxy\nDOMAIN-SUFFIX,manwa.site,Proxy\nDOMAIN-SUFFIX,ftopx.com,Proxy\nDOMAIN-SUFFIX,chocmod.com,Proxy\nDOMAIN-SUFFIX,www.51jsq.biz,Proxy\nDOMAIN-SUFFIX,www.lambmusic.org,Proxy\nDOMAIN-SUFFIX,www.qwe18.com,Proxy\nDOMAIN-SUFFIX,club1069.com,Proxy\nDOMAIN-SUFFIX,sex.com,Proxy\nDOMAIN-SUFFIX,voohk.com,Proxy\nDOMAIN-SUFFIX,wqgm.org,Proxy\nDOMAIN-SUFFIX,www.arnsic.nic.in,Proxy\nDOMAIN-SUFFIX,de.yahoo.com,Proxy\nDOMAIN-SUFFIX,www.cloudorg.uk,Proxy\nDOMAIN-SUFFIX,cdn.entelectonline.co.za,Proxy\nDOMAIN-SUFFIX,jmcomic8.cc,Proxy\nDOMAIN-SUFFIX,webmail.oakland.edu,Proxy\nDOMAIN-SUFFIX,muzi.net,Proxy\nDOMAIN-SUFFIX,51jav.org,Proxy\nDOMAIN-SUFFIX,6.deaftone.com,Proxy\nDOMAIN-SUFFIX,goodhope.school,Proxy\nDOMAIN-SUFFIX,freewww.info,Proxy\nDOMAIN-SUFFIX,get.how,Proxy\nDOMAIN-SUFFIX,www.merkur.de,Proxy\nDOMAIN-SUFFIX,bananaboat.com,Proxy\nDOMAIN-SUFFIX,boxun9.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,b822.com,Proxy\nDOMAIN-SUFFIX,wh20.xyz,Proxy\nDOMAIN-SUFFIX,www.sukhihotu.com,Proxy\nDOMAIN-SUFFIX,www.vtvan.com,Proxy\nDOMAIN-SUFFIX,handsup.shop,Proxy\nDOMAIN-SUFFIX,noodlevpn.com,Proxy\nDOMAIN-SUFFIX,pt.im,Proxy\nDOMAIN-SUFFIX,h796.com,Proxy\nDOMAIN-SUFFIX,www.crackle.com,Proxy\nDOMAIN-SUFFIX,solacemedia.co.nz,Proxy\nDOMAIN-SUFFIX,www.mbvans.com,Proxy\nDOMAIN-SUFFIX,multiproxy.org,Proxy\nDOMAIN-SUFFIX,www.bitfinex.com,Proxy\nDOMAIN-SUFFIX,lowyinterpreter.org,Proxy\nDOMAIN-SUFFIX,xh9111.com,Proxy\nDOMAIN-SUFFIX,voice.ai,Proxy\nDOMAIN-SUFFIX,netsneak.com,Proxy\nDOMAIN-SUFFIX,dailynews.sina.com,Proxy\nDOMAIN-SUFFIX,falungongbrasil.net,Proxy\nDOMAIN-SUFFIX,8qr7.authorizeddns.us,Proxy\nDOMAIN-SUFFIX,chinauncensored.tv,Proxy\nDOMAIN-SUFFIX,ladbrokes.com,Proxy\nDOMAIN-SUFFIX,torrentcrazy.com,Proxy\nDOMAIN-SUFFIX,sockboom.org,Proxy\nDOMAIN-SUFFIX,www.nordvnp.net,Proxy\nDOMAIN-SUFFIX,s3-ap-southeast-1.amazonaws.com,Proxy\nDOMAIN-SUFFIX,free-lance.ru,Proxy\nDOMAIN-SUFFIX,www.fulltiltpoker.com,Proxy\nDOMAIN-SUFFIX,yolasite.com,Proxy\nDOMAIN-SUFFIX,18comic2.art,Proxy\nDOMAIN-SUFFIX,wonderproxy.com,Proxy\nDOMAIN-SUFFIX,supplyrussia.com,Proxy\nDOMAIN-SUFFIX,www.toyvpn.com,Proxy\nDOMAIN-SUFFIX,kbsworld.kbs.co.kr,Proxy\nDOMAIN-SUFFIX,geometrica.net,Proxy\nDOMAIN-SUFFIX,german-proxy.com.de,Proxy\nDOMAIN-SUFFIX,vicon.box.com,Proxy\nDOMAIN-SUFFIX,nextdigital.com.hk,Proxy\nDOMAIN-SUFFIX,www.bookzone.com.tw,Proxy\nDOMAIN-SUFFIX,vivatube.com,Proxy\nDOMAIN-SUFFIX,dd935.net,Proxy\nDOMAIN-SUFFIX,forbes.com,Proxy\nDOMAIN-SUFFIX,journalchretien.net,Proxy\nDOMAIN-SUFFIX,litv.tv,Proxy\nDOMAIN-SUFFIX,expressvpn.biz,Proxy\nDOMAIN-SUFFIX,rti.org.tw,Proxy\nDOMAIN-SUFFIX,1lib.sk,Proxy\nDOMAIN-SUFFIX,www.jiasheng-jituan.com,Proxy\nDOMAIN-SUFFIX,chineseradioseattle.com,Proxy\nDOMAIN-SUFFIX,www.yzc578.com,Proxy\nDOMAIN-SUFFIX,yuetwanlauseng.com,Proxy\nDOMAIN-SUFFIX,creditpay.myfxcm.com,Proxy\nDOMAIN-SUFFIX,www.ziliaozhan.org,Proxy\nDOMAIN-SUFFIX,simenerji.com.tr,Proxy\nDOMAIN-SUFFIX,www.rabbitsreviews.com,Proxy\nDOMAIN-SUFFIX,s.boomssr.com,Proxy\nDOMAIN-SUFFIX,es-visiontimes.com,Proxy\nDOMAIN-SUFFIX,taa-usa.org,Proxy\nDOMAIN-SUFFIX,www.bloombergsef.com,Proxy\nDOMAIN-SUFFIX,www.yzlhb597.com,Proxy\nDOMAIN-SUFFIX,standwithfreedom.org,Proxy\nDOMAIN-SUFFIX,cbfoot.com,Proxy\nDOMAIN-SUFFIX,freetashi.org,Proxy\nDOMAIN-SUFFIX,guardiansofhk.com,Proxy\nDOMAIN-SUFFIX,www.youutube.com,Proxy\nDOMAIN-SUFFIX,zh.fanqiang.wikia.com,Proxy\nDOMAIN-SUFFIX,www.elnuevodia.com,Proxy\nDOMAIN-SUFFIX,weeklyworldnews.com,Proxy\nDOMAIN-SUFFIX,www.bloomberg.co.jp,Proxy\nDOMAIN-SUFFIX,ingtv.cc,Proxy\nDOMAIN-SUFFIX,m.hkgalden.com,Proxy\nDOMAIN-SUFFIX,www.roboforex.ae,Proxy\nDOMAIN-SUFFIX,www.waz.de,Proxy\nDOMAIN-SUFFIX,d2qze7ou8n69d0.cloudfront.net,Proxy\nDOMAIN-SUFFIX,torrentkitty.com,Proxy\nDOMAIN-SUFFIX,j.joe.dj,Proxy\nDOMAIN-SUFFIX,cy.cynaver.com,Proxy\nDOMAIN-SUFFIX,facebook.design,Proxy\nDOMAIN-SUFFIX,google.com.mx,Proxy\nDOMAIN-SUFFIX,www.idax.pro,Proxy\nDOMAIN-SUFFIX,www.xvbelink.com,Proxy\nDOMAIN-SUFFIX,yangzhi.org,Proxy\nDOMAIN-SUFFIX,ukvpn.com,Proxy\nDOMAIN-SUFFIX,youtubemp3.scriptscraft.com,Proxy\nDOMAIN-SUFFIX,vpnfy.com,Proxy\nDOMAIN-SUFFIX,nu3.de,Proxy\nDOMAIN-SUFFIX,www.sorinc.com,Proxy\nDOMAIN-SUFFIX,www.fuckgfw.org,Proxy\nDOMAIN-SUFFIX,nexosalud.com,Proxy\nDOMAIN-SUFFIX,green-n-fresh.com,Proxy\nDOMAIN-SUFFIX,cccda.net,Proxy\nDOMAIN-SUFFIX,8587f.cc,Proxy\nDOMAIN-SUFFIX,d2m3csuekob1tb.cloudfront.net,Proxy\nDOMAIN-SUFFIX,line.vn,Proxy\nDOMAIN-SUFFIX,bbs.north-plus.net,Proxy\nDOMAIN-SUFFIX,ee33.jdao.tk,Proxy\nDOMAIN-SUFFIX,mihari.ir,Proxy\nDOMAIN-SUFFIX,www.hideallip.com,Proxy\nDOMAIN-SUFFIX,thetrist.com,Proxy\nDOMAIN-SUFFIX,www.uuu.com,Proxy\nDOMAIN-SUFFIX,www.organcare.org.tw,Proxy\nDOMAIN-SUFFIX,ohssr.me,Proxy\nDOMAIN-SUFFIX,staticflickr.com,Proxy\nDOMAIN-SUFFIX,www.pandaindex.com,Proxy\nDOMAIN-SUFFIX,www.yyy228.com,Proxy\nDOMAIN-SUFFIX,braumeister.org,Proxy\nDOMAIN-SUFFIX,lobsterbay.hk,Proxy\nDOMAIN-SUFFIX,ns02.ga,Proxy\nDOMAIN-SUFFIX,yourezweb.com,Proxy\nDOMAIN-SUFFIX,orsoon.com,Proxy\nDOMAIN-SUFFIX,www.jbo057.com,Proxy\nDOMAIN-SUFFIX,hk.news.yahoo.com,Proxy\nDOMAIN-SUFFIX,jgjsvip.com,Proxy\nDOMAIN-SUFFIX,fanhaolou.com,Proxy\nDOMAIN-SUFFIX,2047.one,Proxy\nDOMAIN-SUFFIX,bet3658802.com,Proxy\nDOMAIN-SUFFIX,djdj868.com,Proxy\nDOMAIN-SUFFIX,perfectgirls.es,Proxy\nDOMAIN-SUFFIX,encrypt.me,Proxy\nDOMAIN-SUFFIX,yes104.com,Proxy\nDOMAIN-SUFFIX,fivefacesofxi.org,Proxy\nDOMAIN-SUFFIX,bead.tk,Proxy\nDOMAIN-SUFFIX,s3.amazonaws.com,Proxy\nDOMAIN-SUFFIX,www.itbit.com,Proxy\nDOMAIN-SUFFIX,eits.zyxel.com,Proxy\nDOMAIN-SUFFIX,hudatoriq.web.id,Proxy\nDOMAIN-SUFFIX,zhs.fyi,Proxy\nDOMAIN-SUFFIX,22.ra.rs,Proxy\nDOMAIN-SUFFIX,zhuatieba.com,Proxy\nDOMAIN-SUFFIX,ninjacloak.com,Proxy\nDOMAIN-SUFFIX,googlescholar.com,Proxy\nDOMAIN-SUFFIX,hkusu.net,Proxy\nDOMAIN-SUFFIX,voicettank.org,Proxy\nDOMAIN-SUFFIX,tibetoffice.com.au,Proxy\nDOMAIN-SUFFIX,protectyourelection.withgoogle.com,Proxy\nDOMAIN-SUFFIX,bh.com,Proxy\nDOMAIN-SUFFIX,hmt.org.au,Proxy\nDOMAIN-SUFFIX,nanyangpost.com,Proxy\nDOMAIN-SUFFIX,blacknesskeepplan.com,Proxy\nDOMAIN-SUFFIX,allaboutalpha.com,Proxy\nDOMAIN-SUFFIX,olympicwatch.org,Proxy\nDOMAIN-SUFFIX,www.choi-waru.com,Proxy\nDOMAIN-SUFFIX,8x8x.com,Proxy\nDOMAIN-SUFFIX,falunorlando.org,Proxy\nDOMAIN-SUFFIX,site90.net,Proxy\nDOMAIN-SUFFIX,andi-techno.blogspot.hk,Proxy\nDOMAIN-SUFFIX,biedian.me,Proxy\nDOMAIN-SUFFIX,newchen.com,Proxy\nDOMAIN-SUFFIX,xsijishe.net,Proxy\nDOMAIN-SUFFIX,life.different.idv.tw,Proxy\nDOMAIN-SUFFIX,mattwilcox.net,Proxy\nDOMAIN-SUFFIX,portableappc.com,Proxy\nDOMAIN-SUFFIX,www.teco-mo.org,Proxy\nDOMAIN-SUFFIX,xu291.github.io,Proxy\nDOMAIN-SUFFIX,toppornsites.com,Proxy\nDOMAIN-SUFFIX,58vod.me,Proxy\nDOMAIN-SUFFIX,adultdvdmarketplace.com,Proxy\nDOMAIN-SUFFIX,christianstudy.com,Proxy\nDOMAIN-SUFFIX,tor-exit-58.for-privacy.net,Proxy\nDOMAIN-SUFFIX,d1vbs98g5pc2bl.cloudfront.net,Proxy\nDOMAIN-SUFFIX,oppai-av.com,Proxy\nDOMAIN-SUFFIX,lutupu.com,Proxy\nDOMAIN-SUFFIX,app365.gq,Proxy\nDOMAIN-SUFFIX,windowsphoneme.com,Proxy\nDOMAIN-SUFFIX,collection.news,Proxy\nDOMAIN-SUFFIX,www.5w8.cc,Proxy\nDOMAIN-SUFFIX,poland.pl,Proxy\nDOMAIN-SUFFIX,mail.mouseketrips.com,Proxy\nDOMAIN-SUFFIX,www.ruralhousewife.com,Proxy\nDOMAIN-SUFFIX,xh812.com,Proxy\nDOMAIN-SUFFIX,zfx-asia.com,Proxy\nDOMAIN-SUFFIX,www.abs.edu,Proxy\nDOMAIN-SUFFIX,www.jbo106.com,Proxy\nDOMAIN-SUFFIX,notepad.pw,Proxy\nDOMAIN-SUFFIX,javdove2.site,Proxy\nDOMAIN-SUFFIX,usawebproxy.com,Proxy\nDOMAIN-SUFFIX,www.timesnow.in,Proxy\nDOMAIN-SUFFIX,www.99xx.com,Proxy\nDOMAIN-SUFFIX,www.cairnspost.com.au,Proxy\nDOMAIN-SUFFIX,xxmap.xyz,Proxy\nDOMAIN-SUFFIX,judysart.com,Proxy\nDOMAIN-SUFFIX,jbpress.ismedia.jp,Proxy\nDOMAIN-SUFFIX,definefetish.com,Proxy\nDOMAIN-SUFFIX,www.ufxmarkets.com,Proxy\nDOMAIN-SUFFIX,assets.strikingly.com,Proxy\nDOMAIN-SUFFIX,colacu.ro,Proxy\nDOMAIN-SUFFIX,www.xlfmcity.com,Proxy\nDOMAIN-SUFFIX,98198x.com,Proxy\nDOMAIN-SUFFIX,pornmd.com,Proxy\nDOMAIN-SUFFIX,ustinka.org,Proxy\nDOMAIN-SUFFIX,www.fpmtabc.org,Proxy\nDOMAIN-SUFFIX,bestgore.fun,Proxy\nDOMAIN-SUFFIX,868lb.com,Proxy\nDOMAIN-SUFFIX,mp.miaopu.xyz,Proxy\nDOMAIN-SUFFIX,256.now-ip.net,Proxy\nDOMAIN-SUFFIX,skyking.net-tv.tw,Proxy\nDOMAIN-SUFFIX,www.gtloli.gay,Proxy\nDOMAIN-SUFFIX,mstdn.moe,Proxy\nDOMAIN-SUFFIX,windhamdrifters.com,Proxy\nDOMAIN-SUFFIX,boomssr.com,Proxy\nDOMAIN-SUFFIX,www.toutou808.com,Proxy\nDOMAIN-SUFFIX,wa.domain888.pw,Proxy\nDOMAIN-SUFFIX,chumadventist.org,Proxy\nDOMAIN-SUFFIX,google.com.bn,Proxy\nDOMAIN-SUFFIX,www.empfil.com,Proxy\nDOMAIN-SUFFIX,fotomoments4u.gr,Proxy\nDOMAIN-SUFFIX,www.tockq.com,Proxy\nDOMAIN-SUFFIX,zhuichaguoji.org,Proxy\nDOMAIN-SUFFIX,radioinsight.com,Proxy\nDOMAIN-SUFFIX,imdb.com,Proxy\nDOMAIN-SUFFIX,fxprimus.com,Proxy\nDOMAIN-SUFFIX,chinatown.com.au,Proxy\nDOMAIN-SUFFIX,savetibetwebshop.nl,Proxy\nDOMAIN-SUFFIX,d5520.com,Proxy\nDOMAIN-SUFFIX,goproxing.com,Proxy\nDOMAIN-SUFFIX,dynamicdns.me.uk,Proxy\nDOMAIN-SUFFIX,apk.co.uk,Proxy\nDOMAIN-SUFFIX,k5222.com,Proxy\nDOMAIN-SUFFIX,bmo.ca,Proxy\nDOMAIN-SUFFIX,557.slyip.net,Proxy\nDOMAIN-SUFFIX,googlebot.com,Proxy\nDOMAIN-SUFFIX,innuendo.one,Proxy\nDOMAIN-SUFFIX,opersa.com.ar,Proxy\nDOMAIN-SUFFIX,hdm2011.com,Proxy\nDOMAIN-SUFFIX,0403.ca,Proxy\nDOMAIN-SUFFIX,flicker.com,Proxy\nDOMAIN-SUFFIX,coursehero.com,Proxy\nDOMAIN-SUFFIX,mh23.cf,Proxy\nDOMAIN-SUFFIX,62.slyip.com,Proxy\nDOMAIN-SUFFIX,forevergreen.org,Proxy\nDOMAIN-SUFFIX,s3.99hiya.net,Proxy\nDOMAIN-SUFFIX,nflxext.com,Proxy\nDOMAIN-SUFFIX,teacat2.com,Proxy\nDOMAIN-SUFFIX,pinkrod.com,Proxy\nDOMAIN-SUFFIX,expressvpn.xyz,Proxy\nDOMAIN-SUFFIX,top10vpn.com,Proxy\nDOMAIN-SUFFIX,gcgc8.com,Proxy\nDOMAIN-SUFFIX,bluearchive.nexon.com,Proxy\nDOMAIN-SUFFIX,unblock.to,Proxy\nDOMAIN-SUFFIX,howtoforge.com,Proxy\nDOMAIN-SUFFIX,backendless.com,Proxy\nDOMAIN-SUFFIX,slyip.com,Proxy\nDOMAIN-SUFFIX,mail.ttuhsc.edu,Proxy\nDOMAIN-SUFFIX,nas.overock.com,Proxy\nDOMAIN-SUFFIX,cambridgeenglish.cn,Proxy\nDOMAIN-SUFFIX,hk.jiepang.com,Proxy\nDOMAIN-SUFFIX,tf2dl.000webhostapp.com,Proxy\nDOMAIN-SUFFIX,wsdc6600.com,Proxy\nDOMAIN-SUFFIX,newsbeezer.com,Proxy\nDOMAIN-SUFFIX,www.papalah.com,Proxy\nDOMAIN-SUFFIX,hotspotshield.com,Proxy\nDOMAIN-SUFFIX,websdr.org,Proxy\nDOMAIN-SUFFIX,issamichuzi.blogspot.hk,Proxy\nDOMAIN-SUFFIX,fastlink.sytes.net,Proxy\nDOMAIN-SUFFIX,dushi.ca,Proxy\nDOMAIN-SUFFIX,www.imomoe.io,Proxy\nDOMAIN-SUFFIX,tested.com,Proxy\nDOMAIN-SUFFIX,777905p.com,Proxy\nDOMAIN-SUFFIX,phosphation13.rssing.com,Proxy\nDOMAIN-SUFFIX,hj164.com,Proxy\nDOMAIN-SUFFIX,www.wg388.com,Proxy\nDOMAIN-SUFFIX,pix.ie,Proxy\nDOMAIN-SUFFIX,xbrowser.me,Proxy\nDOMAIN-SUFFIX,wikiunblocked.org,Proxy\nDOMAIN-SUFFIX,float4.com,Proxy\nDOMAIN-SUFFIX,prohub.com,Proxy\nDOMAIN-SUFFIX,securitykiss.com,Proxy\nDOMAIN-SUFFIX,www.google.nu,Proxy\nDOMAIN-SUFFIX,net5.ga,Proxy\nDOMAIN-SUFFIX,google.com.af,Proxy\nDOMAIN-SUFFIX,dnvod.tv,Proxy\nDOMAIN-SUFFIX,t3gamers.com,Proxy\nDOMAIN-SUFFIX,turbovpn.co,Proxy\nDOMAIN-SUFFIX,www.dang.idv.tw,Proxy\nDOMAIN-SUFFIX,www.dj0020.com,Proxy\nDOMAIN-SUFFIX,dav4mbastv8a0.cloudfront.net,Proxy\nDOMAIN-SUFFIX,zaobao.com,Proxy\nDOMAIN-SUFFIX,betterwings.net,Proxy\nDOMAIN-SUFFIX,ss.carryzhou.com,Proxy\nDOMAIN-SUFFIX,www.fxpro.com,Proxy\nDOMAIN-SUFFIX,d1rfqhu7csv441.cloudfront.net,Proxy\nDOMAIN-SUFFIX,toom.kir.jp,Proxy\nDOMAIN-SUFFIX,metrohk.com.hk,Proxy\nDOMAIN-SUFFIX,kedahkekl.blogspot.hk,Proxy\nDOMAIN-SUFFIX,nyan.live,Proxy\nDOMAIN-SUFFIX,www.w88cn.com,Proxy\nDOMAIN-SUFFIX,bigfile.to,Proxy\nDOMAIN-SUFFIX,withyoutube.com,Proxy\nDOMAIN-SUFFIX,share.xsky.us,Proxy\nDOMAIN-SUFFIX,www.twavtv.com,Proxy\nDOMAIN-SUFFIX,hjclub.info,Proxy\nDOMAIN-SUFFIX,hostner.ru,Proxy\nDOMAIN-SUFFIX,news.nationalgeographic.com,Proxy\nDOMAIN-SUFFIX,game.fun88721.com,Proxy\nDOMAIN-SUFFIX,challenger.org,Proxy\nDOMAIN-SUFFIX,adam-modellbau.pl,Proxy\nDOMAIN-SUFFIX,spankbang.com,Proxy\nDOMAIN-SUFFIX,www.onefinancialmarkets.com,Proxy\nDOMAIN-SUFFIX,tibet.se,Proxy\nDOMAIN-SUFFIX,826national.org,Proxy\nDOMAIN-SUFFIX,95xae.com,Proxy\nDOMAIN-SUFFIX,tensor.art,Proxy\nDOMAIN-SUFFIX,huangyiyu.com,Proxy\nDOMAIN-SUFFIX,sinodefenceforum.com,Proxy\nDOMAIN-SUFFIX,q84567.com,Proxy\nDOMAIN-SUFFIX,62877.com,Proxy\nDOMAIN-SUFFIX,twitter.org,Proxy\nDOMAIN-SUFFIX,fltr.org,Proxy\nDOMAIN-SUFFIX,falungong.cz,Proxy\nDOMAIN-SUFFIX,x-arthd.com,Proxy\nDOMAIN-SUFFIX,www.wanweibaike.com,Proxy\nDOMAIN-SUFFIX,hqbabes.com,Proxy\nDOMAIN-SUFFIX,www.quantros.com,Proxy\nDOMAIN-SUFFIX,xnzt666.com,Proxy\nDOMAIN-SUFFIX,greece-lawyer.com,Proxy\nDOMAIN-SUFFIX,practicaldigitalprotection.com,Proxy\nDOMAIN-SUFFIX,sdk3.tk,Proxy\nDOMAIN-SUFFIX,xyy69.com,Proxy\nDOMAIN-SUFFIX,qiuqiu.sg,Proxy\nDOMAIN-SUFFIX,netmap.su,Proxy\nDOMAIN-SUFFIX,falundafa-nc.org,Proxy\nDOMAIN-SUFFIX,proksyfree.com,Proxy\nDOMAIN-SUFFIX,tweetree.com,Proxy\nDOMAIN-SUFFIX,startv.com.tr,Proxy\nDOMAIN-SUFFIX,hkej.com,Proxy\nDOMAIN-SUFFIX,faluninfo.de,Proxy\nDOMAIN-SUFFIX,d18fi1bveml0t5.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.eddidzq.com,Proxy\nDOMAIN-SUFFIX,vpnspecial.com,Proxy\nDOMAIN-SUFFIX,cdn.printfriendly.com,Proxy\nDOMAIN-SUFFIX,ios.gd.ddns.name,Proxy\nDOMAIN-SUFFIX,zh.pttpedia.wikia.com,Proxy\nDOMAIN-SUFFIX,www.createspace.com,Proxy\nDOMAIN-SUFFIX,igoogle.com,Proxy\nDOMAIN-SUFFIX,pwfrance.com,Proxy\nDOMAIN-SUFFIX,damon-baker.com,Proxy\nDOMAIN-SUFFIX,xx7411.com,Proxy\nDOMAIN-SUFFIX,corp.rakuten.co.jp,Proxy\nDOMAIN-SUFFIX,299299.com,Proxy\nDOMAIN-SUFFIX,sbf688.com,Proxy\nDOMAIN-SUFFIX,ataxiaontario.ca,Proxy\nDOMAIN-SUFFIX,cmx-im.work,Proxy\nDOMAIN-SUFFIX,dizdiaz.com.ar,Proxy\nDOMAIN-SUFFIX,blooloop.com,Proxy\nDOMAIN-SUFFIX,coomber.co.za,Proxy\nDOMAIN-SUFFIX,browserify.org,Proxy\nDOMAIN-SUFFIX,asianage.com,Proxy\nDOMAIN-SUFFIX,networkedblogs.com,Proxy\nDOMAIN-SUFFIX,www.gmiddle.net,Proxy\nDOMAIN-SUFFIX,c19check.com,Proxy\nDOMAIN-SUFFIX,unofficialbird.com,Proxy\nDOMAIN-SUFFIX,fofldfradio.org,Proxy\nDOMAIN-SUFFIX,faceless.me,Proxy\nDOMAIN-SUFFIX,tubewolf.com,Proxy\nDOMAIN-SUFFIX,tiandixing.org,Proxy\nDOMAIN-SUFFIX,propub.li,Proxy\nDOMAIN-SUFFIX,www.seguridadapple.com,Proxy\nDOMAIN-SUFFIX,pegida.de,Proxy\nDOMAIN-SUFFIX,gsmarena.gr,Proxy\nDOMAIN-SUFFIX,ur.com,Proxy\nDOMAIN-SUFFIX,gestionlw.ca,Proxy\nDOMAIN-SUFFIX,servicesdirectory.withyoutube.com,Proxy\nDOMAIN-SUFFIX,renqiwuxi.com,Proxy\nDOMAIN-SUFFIX,nordvpn.com,Proxy\nDOMAIN-SUFFIX,d21celjm481wiw.cloudfront.net,Proxy\nDOMAIN-SUFFIX,bc990.com,Proxy\nDOMAIN-SUFFIX,briancon05urgencetibet.over-blog.com,Proxy\nDOMAIN-SUFFIX,ee9497.com,Proxy\nDOMAIN-SUFFIX,filthdump.com,Proxy\nDOMAIN-SUFFIX,hacg.club,Proxy\nDOMAIN-SUFFIX,321.slyip.net,Proxy\nDOMAIN-SUFFIX,guilty-soft.com,Proxy\nDOMAIN-SUFFIX,korenan2.com,Proxy\nDOMAIN-SUFFIX,paradise-films.com,Proxy\nDOMAIN-SUFFIX,hoover.org,Proxy\nDOMAIN-SUFFIX,zemtv.com,Proxy\nDOMAIN-SUFFIX,www.h2porn.com,Proxy\nDOMAIN-SUFFIX,www.pokerstars.net,Proxy\nDOMAIN-SUFFIX,www.tcv.org.in,Proxy\nDOMAIN-SUFFIX,hothk.com,Proxy\nDOMAIN-SUFFIX,hkreporter.loved.hk,Proxy\nDOMAIN-SUFFIX,solidfiles.com,Proxy\nDOMAIN-SUFFIX,www.blaken.com,Proxy\nDOMAIN-SUFFIX,openid2.colife.org.tw,Proxy\nDOMAIN-SUFFIX,shellmix.com,Proxy\nDOMAIN-SUFFIX,azubu.tv,Proxy\nDOMAIN-SUFFIX,wmd.org,Proxy\nDOMAIN-SUFFIX,www.two2s.com,Proxy\nDOMAIN-SUFFIX,iaavv.com,Proxy\nDOMAIN-SUFFIX,www.bbsyouba.com,Proxy\nDOMAIN-SUFFIX,fyt365.vip,Proxy\nDOMAIN-SUFFIX,jckcworld.com,Proxy\nDOMAIN-SUFFIX,www.yourlifeyourvoice.org,Proxy\nDOMAIN-SUFFIX,whippedass.com,Proxy\nDOMAIN-SUFFIX,cartermatt.com,Proxy\nDOMAIN-SUFFIX,gcpnews.com,Proxy\nDOMAIN-SUFFIX,webssearches.com,Proxy\nDOMAIN-SUFFIX,1503999.com,Proxy\nDOMAIN-SUFFIX,www.dafawin.com,Proxy\nDOMAIN-SUFFIX,vpnpro.com,Proxy\nDOMAIN-SUFFIX,ww5833.com,Proxy\nDOMAIN-SUFFIX,duihuahrjournal.org,Proxy\nDOMAIN-SUFFIX,program-think.spaces.live.com,Proxy\nDOMAIN-SUFFIX,b572.com,Proxy\nDOMAIN-SUFFIX,895069.com,Proxy\nDOMAIN-SUFFIX,healthstories.xyz,Proxy\nDOMAIN-SUFFIX,www.gcmasia.com,Proxy\nDOMAIN-SUFFIX,qm4949.com,Proxy\nDOMAIN-SUFFIX,d2j7xnjc6e2r20.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.fintv.hk,Proxy\nDOMAIN-SUFFIX,buyee.jp,Proxy\nDOMAIN-SUFFIX,mysecondarydns.com,Proxy\nDOMAIN-SUFFIX,cd5.duga.jp,Proxy\nDOMAIN-SUFFIX,easycanada.net,Proxy\nDOMAIN-SUFFIX,www.potala.cz,Proxy\nDOMAIN-SUFFIX,socialnomad.com,Proxy\nDOMAIN-SUFFIX,fyt365.bet,Proxy\nDOMAIN-SUFFIX,hk-pic.com,Proxy\nDOMAIN-SUFFIX,www.poems.com.sg,Proxy\nDOMAIN-SUFFIX,www.symedialab.org.hk,Proxy\nDOMAIN-SUFFIX,ucbirelandradio.com,Proxy\nDOMAIN-SUFFIX,www.kanxi123.com,Proxy\nDOMAIN-SUFFIX,pyntsquare.com,Proxy\nDOMAIN-SUFFIX,https443.net,Proxy\nDOMAIN-SUFFIX,www.pullcm.com,Proxy\nDOMAIN-SUFFIX,greenbed.com,Proxy\nDOMAIN-SUFFIX,proxyscrape.com,Proxy\nDOMAIN-SUFFIX,vid.puffyan.us,Proxy\nDOMAIN-SUFFIX,imilfs.com,Proxy\nDOMAIN-SUFFIX,www.palpung.org,Proxy\nDOMAIN-SUFFIX,centron.de,Proxy\nDOMAIN-SUFFIX,hotasianz.com,Proxy\nDOMAIN-SUFFIX,www.swimfun.us,Proxy\nDOMAIN-SUFFIX,www.zeroak.com,Proxy\nDOMAIN-SUFFIX,jamaat.org,Proxy\nDOMAIN-SUFFIX,www.korbit.co.kr,Proxy\nDOMAIN-SUFFIX,www.spendee.com,Proxy\nDOMAIN-SUFFIX,touchvpn.net,Proxy\nDOMAIN-SUFFIX,paopao18.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,vppn.us,Proxy\nDOMAIN-SUFFIX,weinasi899.com,Proxy\nDOMAIN-SUFFIX,www.08sal.com,Proxy\nDOMAIN-SUFFIX,ntbna.gov.tw,Proxy\nDOMAIN-SUFFIX,webet88.com,Proxy\nDOMAIN-SUFFIX,hjc111.com,Proxy\nDOMAIN-SUFFIX,matome-plus.com,Proxy\nDOMAIN-SUFFIX,amcp500.com,Proxy\nDOMAIN-SUFFIX,newnews.ca,Proxy\nDOMAIN-SUFFIX,posthentai.com,Proxy\nDOMAIN-SUFFIX,www.keiraknightley.com,Proxy\nDOMAIN-SUFFIX,heydouga.com,Proxy\nDOMAIN-SUFFIX,matomen6ch.blog.jp,Proxy\nDOMAIN-SUFFIX,cbsn.ws,Proxy\nDOMAIN-SUFFIX,n.na.tl,Proxy\nDOMAIN-SUFFIX,yy011.com,Proxy\nDOMAIN-SUFFIX,www.online.hk,Proxy\nDOMAIN-SUFFIX,cleanadulthost.com,Proxy\nDOMAIN-SUFFIX,xuan.com.my,Proxy\nDOMAIN-SUFFIX,plbgaimacam.blogspot.hk,Proxy\nDOMAIN-SUFFIX,compress.to,Proxy\nDOMAIN-SUFFIX,fantasti.cc,Proxy\nDOMAIN-SUFFIX,misacampo.com,Proxy\nDOMAIN-SUFFIX,sf16-sg.tiktokcdn.com,Proxy\nDOMAIN-SUFFIX,redamateurtube.com,Proxy\nDOMAIN-SUFFIX,ytn.co.kr,Proxy\nDOMAIN-SUFFIX,www.kingcan.tw,Proxy\nDOMAIN-SUFFIX,www.yu-house.com,Proxy\nDOMAIN-SUFFIX,keycdn.com,Proxy\nDOMAIN-SUFFIX,tiantibooks.org,Proxy\nDOMAIN-SUFFIX,underwoodammo.com,Proxy\nDOMAIN-SUFFIX,v122.net,Proxy\nDOMAIN-SUFFIX,www.kyoyue.org,Proxy\nDOMAIN-SUFFIX,stripchat.com,Proxy\nDOMAIN-SUFFIX,lama.tw,Proxy\nDOMAIN-SUFFIX,askjeeves.net,Proxy\nDOMAIN-SUFFIX,superzeta.it,Proxy\nDOMAIN-SUFFIX,www.ymgal.com,Proxy\nDOMAIN-SUFFIX,qm717.com,Proxy\nDOMAIN-SUFFIX,www.ggcarry888.com,Proxy\nDOMAIN-SUFFIX,liebretortuga.cl,Proxy\nDOMAIN-SUFFIX,unblocksurfproxy.com,Proxy\nDOMAIN-SUFFIX,pj4977.com,Proxy\nDOMAIN-SUFFIX,www.jsh911.com,Proxy\nDOMAIN-SUFFIX,thcal.us,Proxy\nDOMAIN-SUFFIX,june4commemoration.org,Proxy\nDOMAIN-SUFFIX,fpmt.org,Proxy\nDOMAIN-SUFFIX,d1zg4pcthrwbwl.cloudfront.net,Proxy\nDOMAIN-SUFFIX,outrightinternational.org,Proxy\nDOMAIN-SUFFIX,m.milulucn.com,Proxy\nDOMAIN-SUFFIX,84612.vip,Proxy\nDOMAIN-SUFFIX,bc-bc.site,Proxy\nDOMAIN-SUFFIX,luckydesigner.space,Proxy\nDOMAIN-SUFFIX,maa1812.com,Proxy\nDOMAIN-SUFFIX,www.usagm.gov,Proxy\nDOMAIN-SUFFIX,tweepguide.com,Proxy\nDOMAIN-SUFFIX,zh.uncyclopedia.wikia.com,Proxy\nDOMAIN-SUFFIX,www.15zhu.com,Proxy\nDOMAIN-SUFFIX,www.motls.blogspot.ch,Proxy\nDOMAIN-SUFFIX,bulletin.nna.jp,Proxy\nDOMAIN-SUFFIX,support.steampowered.com,Proxy\nDOMAIN-SUFFIX,sxvpn.com,Proxy\nDOMAIN-SUFFIX,multilan.com,Proxy\nDOMAIN-SUFFIX,adidas.com.cn,Proxy\nDOMAIN-SUFFIX,fxcm-chinese.com,Proxy\nDOMAIN-SUFFIX,xlovecam.com,Proxy\nDOMAIN-SUFFIX,is-a-green.com,Proxy\nDOMAIN-SUFFIX,www.tucao.cam,Proxy\nDOMAIN-SUFFIX,zensur.freerk.com,Proxy\nDOMAIN-SUFFIX,ncs.norwoodma.gov,Proxy\nDOMAIN-SUFFIX,obxtv.com,Proxy\nDOMAIN-SUFFIX,la988.com,Proxy\nDOMAIN-SUFFIX,globalmuslim.web.id,Proxy\nDOMAIN-SUFFIX,niyaodeziyou.fun,Proxy\nDOMAIN-SUFFIX,a52.privatedns.org,Proxy\nDOMAIN-SUFFIX,top.tv,Proxy\nDOMAIN-SUFFIX,sdparty.tw,Proxy\nDOMAIN-SUFFIX,pranceworld.com,Proxy\nDOMAIN-SUFFIX,lifecoach.tw,Proxy\nDOMAIN-SUFFIX,dalailamahindi.com,Proxy\nDOMAIN-SUFFIX,dpaxwwk0x1o6o.cloudfront.net,Proxy\nDOMAIN-SUFFIX,omanvpn.com,Proxy\nDOMAIN-SUFFIX,www.zxproxy.com,Proxy\nDOMAIN-SUFFIX,a.1u2u3u4u.com,Proxy\nDOMAIN-SUFFIX,s16.tiktokcdn.com,Proxy\nDOMAIN-SUFFIX,www.fun327.com,Proxy\nDOMAIN-SUFFIX,www.wikipedia.aufe.cf,Proxy\nDOMAIN-SUFFIX,vpsxb.net,Proxy\nDOMAIN-SUFFIX,handsonhardcore.com,Proxy\nDOMAIN-SUFFIX,yf188.org,Proxy\nDOMAIN-SUFFIX,freekwonpyong.org,Proxy\nDOMAIN-SUFFIX,stevekoch.ca,Proxy\nDOMAIN-SUFFIX,taxalia.blogspot.hk,Proxy\nDOMAIN-SUFFIX,hougaige.com,Proxy\nDOMAIN-SUFFIX,www.bway886.com,Proxy\nDOMAIN-SUFFIX,www.vpnshazam.com,Proxy\nDOMAIN-SUFFIX,dvqhxpqjxle57.cloudfront.net,Proxy\nDOMAIN-SUFFIX,viewyoutube.net,Proxy\nDOMAIN-SUFFIX,www.antd.org,Proxy\nDOMAIN-SUFFIX,americantec.com.ar,Proxy\nDOMAIN-SUFFIX,proxydb.org,Proxy\nDOMAIN-SUFFIX,twittercounter.com,Proxy\nDOMAIN-SUFFIX,www.tmd123.com,Proxy\nDOMAIN-SUFFIX,demo.opera-mini.net,Proxy\nDOMAIN-SUFFIX,falundafa.org.tw,Proxy\nDOMAIN-SUFFIX,mymusclevideo.com,Proxy\nDOMAIN-SUFFIX,storyslab.com,Proxy\nDOMAIN-SUFFIX,awkafau.org,Proxy\nDOMAIN-SUFFIX,bbs.sina.com,Proxy\nDOMAIN-SUFFIX,nitter.perennialte.ch,Proxy\nDOMAIN-SUFFIX,paopao9.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,honnaka.jp,Proxy\nDOMAIN-SUFFIX,ns.16-b.it,Proxy\nDOMAIN-SUFFIX,line-apps.com,Proxy\nDOMAIN-SUFFIX,www.yahoo.in,Proxy\nDOMAIN-SUFFIX,d93lf6jiuqxto.cloudfront.net,Proxy\nDOMAIN-SUFFIX,watsonmail.org,Proxy\nDOMAIN-SUFFIX,www.boyztube.com,Proxy\nDOMAIN-SUFFIX,18h.tv,Proxy\nDOMAIN-SUFFIX,soymikael.blogspot.mx,Proxy\nDOMAIN-SUFFIX,thumbzilla.com,Proxy\nDOMAIN-SUFFIX,www.canadakent.com,Proxy\nDOMAIN-SUFFIX,www.oneworld.cz,Proxy\nDOMAIN-SUFFIX,cf.gs,Proxy\nDOMAIN-SUFFIX,neverforget8964.org,Proxy\nDOMAIN-SUFFIX,www.ztod.com,Proxy\nDOMAIN-SUFFIX,www.amtb.tw,Proxy\nDOMAIN-SUFFIX,p5z8l.r5.cr.rs,Proxy\nDOMAIN-SUFFIX,aku-tak-peduli.blogspot.hk,Proxy\nDOMAIN-SUFFIX,jable.tv,Proxy\nDOMAIN-SUFFIX,englishfromengland.co.uk,Proxy\nDOMAIN-SUFFIX,www.dayspring.org.tw,Proxy\nDOMAIN-SUFFIX,www.friends-of-tibet.org.nz,Proxy\nDOMAIN-SUFFIX,backupme.wasap.my,Proxy\nDOMAIN-SUFFIX,www.we680.com,Proxy\nDOMAIN-SUFFIX,h2.ns22.ru,Proxy\nDOMAIN-SUFFIX,willhaben.at,Proxy\nDOMAIN-SUFFIX,tasexy.com,Proxy\nDOMAIN-SUFFIX,www.fhm.com.tw,Proxy\nDOMAIN-SUFFIX,cnn.com,Proxy\nDOMAIN-SUFFIX,midcenturymodernmag.com,Proxy\nDOMAIN-SUFFIX,canalisystem.it,Proxy\nDOMAIN-SUFFIX,www.555456.com,Proxy\nDOMAIN-SUFFIX,lt118.com,Proxy\nDOMAIN-SUFFIX,spendee.com,Proxy\nDOMAIN-SUFFIX,www.newsy.com,Proxy\nDOMAIN-SUFFIX,ma.hao123.com,Proxy\nDOMAIN-SUFFIX,akvpn.com,Proxy\nDOMAIN-SUFFIX,blog.radi.ws,Proxy\nDOMAIN-SUFFIX,ironfx.com,Proxy\nDOMAIN-SUFFIX,www.ascf.us,Proxy\nDOMAIN-SUFFIX,waterstones.com,Proxy\nDOMAIN-SUFFIX,aznmovies.com,Proxy\nDOMAIN-SUFFIX,hurriyet.com.tr,Proxy\nDOMAIN-SUFFIX,p5562.com,Proxy\nDOMAIN-SUFFIX,taiwanjobs.gov.tw,Proxy\nDOMAIN-SUFFIX,louislegrand.org,Proxy\nDOMAIN-SUFFIX,cn5.rti.tw,Proxy\nDOMAIN-SUFFIX,tor-exit-62.for-privacy.net,Proxy\nDOMAIN-SUFFIX,www.happysky.com,Proxy\nDOMAIN-SUFFIX,api1.huajian-china.com,Proxy\nDOMAIN-SUFFIX,www5.javmost.com,Proxy\nDOMAIN-SUFFIX,zhongmeng.org,Proxy\nDOMAIN-SUFFIX,18schoolgirlz.com,Proxy\nDOMAIN-SUFFIX,424.cc,Proxy\nDOMAIN-SUFFIX,a1007.dspw43.akamai.net,Proxy\nDOMAIN-SUFFIX,www.hucus.org,Proxy\nDOMAIN-SUFFIX,d21dp3t3hq3sp6.cloudfront.net,Proxy\nDOMAIN-SUFFIX,380mm380.com,Proxy\nDOMAIN-SUFFIX,porbhub.com,Proxy\nDOMAIN-SUFFIX,sitekreator.com,Proxy\nDOMAIN-SUFFIX,dorcel.com,Proxy\nDOMAIN-SUFFIX,jungleheart.com,Proxy\nDOMAIN-SUFFIX,www.kinokuniya.com,Proxy\nDOMAIN-SUFFIX,cdtimes.s3.amazonaws.com,Proxy\nDOMAIN-SUFFIX,shizhao.org,Proxy\nDOMAIN-SUFFIX,xj.domain888.pw,Proxy\nDOMAIN-SUFFIX,archive.is,Proxy\nDOMAIN-SUFFIX,www.yrcr7.com,Proxy\nDOMAIN-SUFFIX,www.busseltonmail.com.au,Proxy\nDOMAIN-SUFFIX,baramangaonline.com,Proxy\nDOMAIN-SUFFIX,reallifeprogramming.com,Proxy\nDOMAIN-SUFFIX,www.goodtv.org,Proxy\nDOMAIN-SUFFIX,www.iglu.com.au,Proxy\nDOMAIN-SUFFIX,www18.eyny.com,Proxy\nDOMAIN-SUFFIX,idv.tw,Proxy\nDOMAIN-SUFFIX,www.1935yabo.com,Proxy\nDOMAIN-SUFFIX,www.comicbox.xyz,Proxy\nDOMAIN-SUFFIX,amandaandshawn.com,Proxy\nDOMAIN-SUFFIX,pu0035.com,Proxy\nDOMAIN-SUFFIX,mobileyoutube.com,Proxy\nDOMAIN-SUFFIX,hu1lib.org,Proxy\nDOMAIN-SUFFIX,blm898.com,Proxy\nDOMAIN-SUFFIX,facesoftibetanselfimmolators.info,Proxy\nDOMAIN-SUFFIX,www.internetsanscrainte.fr,Proxy\nDOMAIN-SUFFIX,www.nuvid.com,Proxy\nDOMAIN-SUFFIX,www.k2.com,Proxy\nDOMAIN-SUFFIX,rocketmiles.com,Proxy\nDOMAIN-SUFFIX,falungong-wa.org,Proxy\nDOMAIN-SUFFIX,topshop.al,Proxy\nDOMAIN-SUFFIX,onion.city,Proxy\nDOMAIN-SUFFIX,click2.com.br,Proxy\nDOMAIN-SUFFIX,elephantcs.nl,Proxy\nDOMAIN-SUFFIX,shapeservices.com,Proxy\nDOMAIN-SUFFIX,messenger.providesupport.com,Proxy\nDOMAIN-SUFFIX,fangbinxing.com,Proxy\nDOMAIN-SUFFIX,members.po18.tw,Proxy\nDOMAIN-SUFFIX,d1vt414593lcr7.cloudfront.net,Proxy\nDOMAIN-SUFFIX,mee.3d-game.com,Proxy\nDOMAIN-SUFFIX,8teenxxx.com,Proxy\nDOMAIN-SUFFIX,statefarm.com,Proxy\nDOMAIN-SUFFIX,www.rb8081.com,Proxy\nDOMAIN-SUFFIX,coolinet.com,Proxy\nDOMAIN-SUFFIX,newlandmagazine.com.au,Proxy\nDOMAIN-SUFFIX,download1.ub8fun.com,Proxy\nDOMAIN-SUFFIX,my.ps8318.com,Proxy\nDOMAIN-SUFFIX,chinese.cari.com.my,Proxy\nDOMAIN-SUFFIX,femjoy.com,Proxy\nDOMAIN-SUFFIX,b.mb2.host,Proxy\nDOMAIN-SUFFIX,nga.mil,Proxy\nDOMAIN-SUFFIX,whogovernstw.org,Proxy\nDOMAIN-SUFFIX,littlestyle.com.au,Proxy\nDOMAIN-SUFFIX,firetweet.io,Proxy\nDOMAIN-SUFFIX,liuxiaotong.com,Proxy\nDOMAIN-SUFFIX,persopo.com,Proxy\nDOMAIN-SUFFIX,upmedia.mg,Proxy\nDOMAIN-SUFFIX,www.regione.basilicata.it,Proxy\nDOMAIN-SUFFIX,www.legion.org,Proxy\nDOMAIN-SUFFIX,55552557.com,Proxy\nDOMAIN-SUFFIX,www.wrn.org,Proxy\nDOMAIN-SUFFIX,yayabay.com,Proxy\nDOMAIN-SUFFIX,ottof.xyz,Proxy\nDOMAIN-SUFFIX,udomain.hk,Proxy\nDOMAIN-SUFFIX,98902222.com,Proxy\nDOMAIN-SUFFIX,d391rxfxl1sz8s.cloudfront.net,Proxy\nDOMAIN-SUFFIX,d000000.com,Proxy\nDOMAIN-SUFFIX,psotc.org,Proxy\nDOMAIN-SUFFIX,tweetrans.com,Proxy\nDOMAIN-SUFFIX,xinqimeng.over-blog.com,Proxy\nDOMAIN-SUFFIX,djmajoratoradea.ro,Proxy\nDOMAIN-SUFFIX,left21.hk,Proxy\nDOMAIN-SUFFIX,exigo-capital.com,Proxy\nDOMAIN-SUFFIX,sourcewadio.com,Proxy\nDOMAIN-SUFFIX,mail.vxabc.com,Proxy\nDOMAIN-SUFFIX,funtvcom.com,Proxy\nDOMAIN-SUFFIX,zh.jinzhao.wiki,Proxy\nDOMAIN-SUFFIX,biotx.biz,Proxy\nDOMAIN-SUFFIX,singtao.ca,Proxy\nDOMAIN-SUFFIX,epic.com.tw,Proxy\nDOMAIN-SUFFIX,www.vcup365.com,Proxy\nDOMAIN-SUFFIX,twitter.beparanoid.de,Proxy\nDOMAIN-SUFFIX,as.llsif.moe,Proxy\nDOMAIN-SUFFIX,misstibet.com,Proxy\nDOMAIN-SUFFIX,ns01.tk,Proxy\nDOMAIN-SUFFIX,htspor.com,Proxy\nDOMAIN-SUFFIX,www.chaojidianshi.net,Proxy\nDOMAIN-SUFFIX,6-4.net,Proxy\nDOMAIN-SUFFIX,poponclick.com,Proxy\nDOMAIN-SUFFIX,www.w88988.com,Proxy\nDOMAIN-SUFFIX,moresci.sale,Proxy\nDOMAIN-SUFFIX,videosdetetas.com,Proxy\nDOMAIN-SUFFIX,google.gg,Proxy\nDOMAIN-SUFFIX,www.youtubexyoutube.com,Proxy\nDOMAIN-SUFFIX,amnyemachen.org,Proxy\nDOMAIN-SUFFIX,bmw40000.com,Proxy\nDOMAIN-SUFFIX,q3285.net,Proxy\nDOMAIN-SUFFIX,djorz.com,Proxy\nDOMAIN-SUFFIX,www.gayspa.com.tw,Proxy\nDOMAIN-SUFFIX,beforeitsnews.com,Proxy\nDOMAIN-SUFFIX,ai780.com,Proxy\nDOMAIN-SUFFIX,he2911.com,Proxy\nDOMAIN-SUFFIX,worldheritage.org,Proxy\nDOMAIN-SUFFIX,aozora.sizuku.moe,Proxy\nDOMAIN-SUFFIX,100ke.org,Proxy\nDOMAIN-SUFFIX,www.cospuri.com,Proxy\nDOMAIN-SUFFIX,103.hk,Proxy\nDOMAIN-SUFFIX,unknownproxy.com,Proxy\nDOMAIN-SUFFIX,usawinsgold.com,Proxy\nDOMAIN-SUFFIX,a3n2g4b3.stackpathcdn.com,Proxy\nDOMAIN-SUFFIX,mo138.com,Proxy\nDOMAIN-SUFFIX,moefuns.co,Proxy\nDOMAIN-SUFFIX,setiantang.com,Proxy\nDOMAIN-SUFFIX,amateurs-gone-wild.com,Proxy\nDOMAIN-SUFFIX,15avav.xyz,Proxy\nDOMAIN-SUFFIX,ahri.pro,Proxy\nDOMAIN-SUFFIX,akiba-web.com,Proxy\nDOMAIN-SUFFIX,croissancedeseglisesoutils.blogspot.ca,Proxy\nDOMAIN-SUFFIX,b2b.sinopac.com,Proxy\nDOMAIN-SUFFIX,monocloud.me,Proxy\nDOMAIN-SUFFIX,559.flnet.org,Proxy\nDOMAIN-SUFFIX,fancentro.com,Proxy\nDOMAIN-SUFFIX,theage.com.au,Proxy\nDOMAIN-SUFFIX,ssrxxjc.cc,Proxy\nDOMAIN-SUFFIX,languagemo.strikingly.com,Proxy\nDOMAIN-SUFFIX,comunefiessoro.it,Proxy\nDOMAIN-SUFFIX,www.momotai.com,Proxy\nDOMAIN-SUFFIX,atc.org.au,Proxy\nDOMAIN-SUFFIX,blog.controlspace.org,Proxy\nDOMAIN-SUFFIX,hooters.com,Proxy\nDOMAIN-SUFFIX,www.bbcradioint.com,Proxy\nDOMAIN-SUFFIX,apksos.com,Proxy\nDOMAIN-SUFFIX,www.gloryministries.org.tw,Proxy\nDOMAIN-SUFFIX,www.plus500.com,Proxy\nDOMAIN-SUFFIX,briefdream.com,Proxy\nDOMAIN-SUFFIX,tr.im,Proxy\nDOMAIN-SUFFIX,w2668.com,Proxy\nDOMAIN-SUFFIX,stockintl.ca,Proxy\nDOMAIN-SUFFIX,app6.ga,Proxy\nDOMAIN-SUFFIX,matome.naver.jp,Proxy\nDOMAIN-SUFFIX,mediachinese.com,Proxy\nDOMAIN-SUFFIX,coachingforleaders.com,Proxy\nDOMAIN-SUFFIX,www.adj.idv.tw,Proxy\nDOMAIN-SUFFIX,persistence.biatalk.cc,Proxy\nDOMAIN-SUFFIX,shop.easymall.com.tw,Proxy\nDOMAIN-SUFFIX,google.ro,Proxy\nDOMAIN-SUFFIX,www.perthsystems.com.au,Proxy\nDOMAIN-SUFFIX,ag.xw363.com,Proxy\nDOMAIN-SUFFIX,pu148.com,Proxy\nDOMAIN-SUFFIX,t-hole.github.io,Proxy\nDOMAIN-SUFFIX,apkmirror.com,Proxy\nDOMAIN-SUFFIX,www.e-zone.com.hk,Proxy\nDOMAIN-SUFFIX,es.beta.qualityready.de,Proxy\nDOMAIN-SUFFIX,senretto.com,Proxy\nDOMAIN-SUFFIX,api.zdqp11.com,Proxy\nDOMAIN-SUFFIX,shouderhome.ir,Proxy\nDOMAIN-SUFFIX,www.cazila.com,Proxy\nDOMAIN-SUFFIX,www.trican.com.tw,Proxy\nDOMAIN-SUFFIX,ipdisguiser.com,Proxy\nDOMAIN-SUFFIX,y68123.com,Proxy\nDOMAIN-SUFFIX,myftp.biz,Proxy\nDOMAIN-SUFFIX,ss2wall.net,Proxy\nDOMAIN-SUFFIX,nianhuo.tmall.com,Proxy\nDOMAIN-SUFFIX,gospelforasia.net,Proxy\nDOMAIN-SUFFIX,sharpdaily.com.hk,Proxy\nDOMAIN-SUFFIX,hornywife.com,Proxy\nDOMAIN-SUFFIX,9032.ddnsking.com,Proxy\nDOMAIN-SUFFIX,tunnelblick.net,Proxy\nDOMAIN-SUFFIX,www.tb2266.com,Proxy\nDOMAIN-SUFFIX,plotioglobal.com,Proxy\nDOMAIN-SUFFIX,sravastiabbey.org,Proxy\nDOMAIN-SUFFIX,peliculasyonkis.com,Proxy\nDOMAIN-SUFFIX,my3xxx.com,Proxy\nDOMAIN-SUFFIX,parapentemanquehue.cl,Proxy\nDOMAIN-SUFFIX,nakido.com,Proxy\nDOMAIN-SUFFIX,plus.fuhuimkt.com,Proxy\nDOMAIN-SUFFIX,h5.457ld.com,Proxy\nDOMAIN-SUFFIX,rb277.com,Proxy\nDOMAIN-SUFFIX,www.555768.com,Proxy\nDOMAIN-SUFFIX,d23hlwijd437bo.cloudfront.net,Proxy\nDOMAIN-SUFFIX,lbank.info,Proxy\nDOMAIN-SUFFIX,www.31666cc.com,Proxy\nDOMAIN-SUFFIX,gmofreeusa.org,Proxy\nDOMAIN-SUFFIX,www.expressvpn.tv,Proxy\nDOMAIN-SUFFIX,www.eduweb.idv.tw,Proxy\nDOMAIN-SUFFIX,dropboxusercontent.com,Proxy\nDOMAIN-SUFFIX,msguancha.com,Proxy\nDOMAIN-SUFFIX,lantern3.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,baidufl.tk,Proxy\nDOMAIN-SUFFIX,www.cparptw.org,Proxy\nDOMAIN-SUFFIX,www.devopsish.com,Proxy\nDOMAIN-SUFFIX,globaljihad.net,Proxy\nDOMAIN-SUFFIX,freefuckvids.com,Proxy\nDOMAIN-SUFFIX,deainx.net,Proxy\nDOMAIN-SUFFIX,excretekings.com,Proxy\nDOMAIN-SUFFIX,38850066.com,Proxy\nDOMAIN-SUFFIX,vs4422.com,Proxy\nDOMAIN-SUFFIX,01.buyshouses.net,Proxy\nDOMAIN-SUFFIX,pgc-lb.org,Proxy\nDOMAIN-SUFFIX,youtube.de,Proxy\nDOMAIN-SUFFIX,1qqtv.me,Proxy\nDOMAIN-SUFFIX,www.dossiertibet.it,Proxy\nDOMAIN-SUFFIX,mizzmona.com,Proxy\nDOMAIN-SUFFIX,kyoutube.com,Proxy\nDOMAIN-SUFFIX,catchvideo.net,Proxy\nDOMAIN-SUFFIX,appsocks.net,Proxy\nDOMAIN-SUFFIX,www.daftarblog.com,Proxy\nDOMAIN-SUFFIX,vtje.org,Proxy\nDOMAIN-SUFFIX,www.liverpoolchampion.com.au,Proxy\nDOMAIN-SUFFIX,kiwifarms.hk,Proxy\nDOMAIN-SUFFIX,delcamp.net,Proxy\nDOMAIN-SUFFIX,www.aviusofficial.com,Proxy\nDOMAIN-SUFFIX,penchinese.net,Proxy\nDOMAIN-SUFFIX,switchvpn.asia,Proxy\nDOMAIN-SUFFIX,braavos.app,Proxy\nDOMAIN-SUFFIX,www.fuhuiapac.com,Proxy\nDOMAIN-SUFFIX,guaguass.com,Proxy\nDOMAIN-SUFFIX,yf676.com,Proxy\nDOMAIN-SUFFIX,www.cryptvline.com,Proxy\nDOMAIN-SUFFIX,minjian-danganguan.org,Proxy\nDOMAIN-SUFFIX,ausnznet.com,Proxy\nDOMAIN-SUFFIX,yin014.com,Proxy\nDOMAIN-SUFFIX,serx.ml,Proxy\nDOMAIN-SUFFIX,www.rfimusic.com,Proxy\nDOMAIN-SUFFIX,binux.me,Proxy\nDOMAIN-SUFFIX,coingecko.com,Proxy\nDOMAIN-SUFFIX,22find.com,Proxy\nDOMAIN-SUFFIX,jinniumovie.be,Proxy\nDOMAIN-SUFFIX,www.otw.im,Proxy\nDOMAIN-SUFFIX,blogspot.com.co,Proxy\nDOMAIN-SUFFIX,chineselabourparty.org,Proxy\nDOMAIN-SUFFIX,tv72.ga,Proxy\nDOMAIN-SUFFIX,tvider.com,Proxy\nDOMAIN-SUFFIX,3201380.com,Proxy\nDOMAIN-SUFFIX,www.scmpgroup.com,Proxy\nDOMAIN-SUFFIX,www.ca788.com,Proxy\nDOMAIN-SUFFIX,dragonex.io,Proxy\nDOMAIN-SUFFIX,raindrop.io,Proxy\nDOMAIN-SUFFIX,www.cideon.com,Proxy\nDOMAIN-SUFFIX,oik.instanthq.com,Proxy\nDOMAIN-SUFFIX,allgirlmassage.com,Proxy\nDOMAIN-SUFFIX,derpibooru.org,Proxy\nDOMAIN-SUFFIX,from-ga.com,Proxy\nDOMAIN-SUFFIX,www.lasegunda.com,Proxy\nDOMAIN-SUFFIX,p.ota.to,Proxy\nDOMAIN-SUFFIX,www.google-ch.com,Proxy\nDOMAIN-SUFFIX,clubhouse.com,Proxy\nDOMAIN-SUFFIX,www.volkskrant.nl,Proxy\nDOMAIN-SUFFIX,friendsofshenyun.org,Proxy\nDOMAIN-SUFFIX,manchuv3.i8system.com,Proxy\nDOMAIN-SUFFIX,a9688.com,Proxy\nDOMAIN-SUFFIX,62.etowns.net,Proxy\nDOMAIN-SUFFIX,javfinder.is,Proxy\nDOMAIN-SUFFIX,reut-institute.org,Proxy\nDOMAIN-SUFFIX,tellme.pw,Proxy\nDOMAIN-SUFFIX,cs77555.com,Proxy\nDOMAIN-SUFFIX,sj011.91xtv.com,Proxy\nDOMAIN-SUFFIX,chinalawtranslate.com,Proxy\nDOMAIN-SUFFIX,m.cliphunter.com,Proxy\nDOMAIN-SUFFIX,beacons4.gvt2.com,Proxy\nDOMAIN-SUFFIX,taipei.gov.tw,Proxy\nDOMAIN-SUFFIX,pley.gg,Proxy\nDOMAIN-SUFFIX,vaporizedbook.com,Proxy\nDOMAIN-SUFFIX,guggisberg.com.ar,Proxy\nDOMAIN-SUFFIX,www.icilix.com,Proxy\nDOMAIN-SUFFIX,google.com.pk,Proxy\nDOMAIN-SUFFIX,8696.cc,Proxy\nDOMAIN-SUFFIX,99xxtv.com,Proxy\nDOMAIN-SUFFIX,sexav.tv,Proxy\nDOMAIN-SUFFIX,invidious.tiekoetter.com,Proxy\nDOMAIN-SUFFIX,nyt9.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,www.hacg.li,Proxy\nDOMAIN-SUFFIX,www.jica88.com,Proxy\nDOMAIN-SUFFIX,blackvpn.com,Proxy\nDOMAIN-SUFFIX,vpnhack.com,Proxy\nDOMAIN-SUFFIX,yt.artemislena.eu,Proxy\nDOMAIN-SUFFIX,audiobro.com,Proxy\nDOMAIN-SUFFIX,changeip.org,Proxy\nDOMAIN-SUFFIX,www.mhgold.com,Proxy\nDOMAIN-SUFFIX,kwcg.ca,Proxy\nDOMAIN-SUFFIX,www.dropbox.de,Proxy\nDOMAIN-SUFFIX,adult168.com,Proxy\nDOMAIN-SUFFIX,www.haijiaoshequ.com,Proxy\nDOMAIN-SUFFIX,www.kia.com,Proxy\nDOMAIN-SUFFIX,av9.cc,Proxy\nDOMAIN-SUFFIX,yuelushuyuan.com,Proxy\nDOMAIN-SUFFIX,yesvpn.com,Proxy\nDOMAIN-SUFFIX,crossvpn.net,Proxy\nDOMAIN-SUFFIX,privatevpn.app,Proxy\nDOMAIN-SUFFIX,www.cabet588.com,Proxy\nDOMAIN-SUFFIX,m.mv33.xyz,Proxy\nDOMAIN-SUFFIX,2.4.je,Proxy\nDOMAIN-SUFFIX,spencerbosworth.com,Proxy\nDOMAIN-SUFFIX,www.tsdm39.net,Proxy\nDOMAIN-SUFFIX,www.vennews.com,Proxy\nDOMAIN-SUFFIX,www.thequint.com,Proxy\nDOMAIN-SUFFIX,www.passworld.cc,Proxy\nDOMAIN-SUFFIX,spectrumlocalnews.com,Proxy\nDOMAIN-SUFFIX,coinw.com,Proxy\nDOMAIN-SUFFIX,www.okex.me,Proxy\nDOMAIN-SUFFIX,mychinanews.com,Proxy\nDOMAIN-SUFFIX,www.91530.com,Proxy\nDOMAIN-SUFFIX,jizztogo.com,Proxy\nDOMAIN-SUFFIX,cyoutube.com,Proxy\nDOMAIN-SUFFIX,xxxy.biz,Proxy\nDOMAIN-SUFFIX,21.flnet.org,Proxy\nDOMAIN-SUFFIX,reconsidera.github.io,Proxy\nDOMAIN-SUFFIX,bifa780.com,Proxy\nDOMAIN-SUFFIX,live173.com,Proxy\nDOMAIN-SUFFIX,googlescholar.comUSA,Proxy\nDOMAIN-SUFFIX,xrn3.cat.flnet.org,Proxy\nDOMAIN-SUFFIX,www.99re.com,Proxy\nDOMAIN-SUFFIX,yi8222.com,Proxy\nDOMAIN-SUFFIX,huobi.pro,Proxy\nDOMAIN-SUFFIX,falunasia.info,Proxy\nDOMAIN-SUFFIX,honven.xyz,Proxy\nDOMAIN-SUFFIX,www.markets.com,Proxy\nDOMAIN-SUFFIX,static.palgrave.com,Proxy\nDOMAIN-SUFFIX,ntbk.gov.tw,Proxy\nDOMAIN-SUFFIX,www.win365.com,Proxy\nDOMAIN-SUFFIX,123.suroot.com,Proxy\nDOMAIN-SUFFIX,slickvpn.com,Proxy\nDOMAIN-SUFFIX,www.mecloud.fun,Proxy\nDOMAIN-SUFFIX,702338.com,Proxy\nDOMAIN-SUFFIX,vovo2000.com,Proxy\nDOMAIN-SUFFIX,publinedita.pt,Proxy\nDOMAIN-SUFFIX,ntdtv.tk,Proxy\nDOMAIN-SUFFIX,dropbox.com,Proxy\nDOMAIN-SUFFIX,cengrao.com,Proxy\nDOMAIN-SUFFIX,tw.yaho.com,Proxy\nDOMAIN-SUFFIX,www.123451a.com,Proxy\nDOMAIN-SUFFIX,malapersona.cl,Proxy\nDOMAIN-SUFFIX,266660.com,Proxy\nDOMAIN-SUFFIX,jochgvofd.a0001.net,Proxy\nDOMAIN-SUFFIX,apk2.cf,Proxy\nDOMAIN-SUFFIX,www.jteach.com,Proxy\nDOMAIN-SUFFIX,www.e8775.com,Proxy\nDOMAIN-SUFFIX,hidemy.name,Proxy\nDOMAIN-SUFFIX,839.tuoitrevn.es,Proxy\nDOMAIN-SUFFIX,www.topvantagedubai.com,Proxy\nDOMAIN-SUFFIX,blpink.xyz,Proxy\nDOMAIN-SUFFIX,ip5002.co,Proxy\nDOMAIN-SUFFIX,paljorpublications.com,Proxy\nDOMAIN-SUFFIX,bangss.tk,Proxy\nDOMAIN-SUFFIX,cleansite.biz,Proxy\nDOMAIN-SUFFIX,cdn.mxpnl.com,Proxy\nDOMAIN-SUFFIX,ca7022.com,Proxy\nDOMAIN-SUFFIX,cs392.com,Proxy\nDOMAIN-SUFFIX,api.proxlet.com,Proxy\nDOMAIN-SUFFIX,qukun8.xyz,Proxy\nDOMAIN-SUFFIX,qoto.org,Proxy\nDOMAIN-SUFFIX,www.getdropbox.com,Proxy\nDOMAIN-SUFFIX,m.000aa.com,Proxy\nDOMAIN-SUFFIX,d1sshl1phruito.cloudfront.net,Proxy\nDOMAIN-SUFFIX,stephaniered.com,Proxy\nDOMAIN-SUFFIX,nuovelle.ee,Proxy\nDOMAIN-SUFFIX,www.70966b.com,Proxy\nDOMAIN-SUFFIX,beyondfirewall-big5.blogspot.hk,Proxy\nDOMAIN-SUFFIX,bikramyogaeastharlem.com,Proxy\nDOMAIN-SUFFIX,hentaiplay.net,Proxy\nDOMAIN-SUFFIX,fastpic.ru,Proxy\nDOMAIN-SUFFIX,averagemohamed.com,Proxy\nDOMAIN-SUFFIX,hwinfo.com,Proxy\nDOMAIN-SUFFIX,4bluestones.biz,Proxy\nDOMAIN-SUFFIX,www.bway928.com,Proxy\nDOMAIN-SUFFIX,lilaoshibushinilaoshi.com,Proxy\nDOMAIN-SUFFIX,ww10.sonyyoutube.com,Proxy\nDOMAIN-SUFFIX,www.aier.org,Proxy\nDOMAIN-SUFFIX,mousebreaker.com,Proxy\nDOMAIN-SUFFIX,tails.boom.org,Proxy\nDOMAIN-SUFFIX,vizvaz.com,Proxy\nDOMAIN-SUFFIX,fuyu.org.tw,Proxy\nDOMAIN-SUFFIX,digg.com,Proxy\nDOMAIN-SUFFIX,1111dav.com,Proxy\nDOMAIN-SUFFIX,de-plaja.ro,Proxy\nDOMAIN-SUFFIX,www.mousebreaker.com,Proxy\nDOMAIN-SUFFIX,www.kmsskj.com,Proxy\nDOMAIN-SUFFIX,yzz0090.wix.org,Proxy\nDOMAIN-SUFFIX,graph.org,Proxy\nDOMAIN-SUFFIX,xqmobile.po888.net,Proxy\nDOMAIN-SUFFIX,onlineyoutube.com,Proxy\nDOMAIN-SUFFIX,www.openlettersmonthly.com,Proxy\nDOMAIN-SUFFIX,octanevpn.com,Proxy\nDOMAIN-SUFFIX,211.effers.com,Proxy\nDOMAIN-SUFFIX,33.xxgirls.org,Proxy\nDOMAIN-SUFFIX,www.fhjituan-zhs.com,Proxy\nDOMAIN-SUFFIX,alforattv.net,Proxy\nDOMAIN-SUFFIX,www.cryptocoinsnews.com,Proxy\nDOMAIN-SUFFIX,bbs.huasing.org,Proxy\nDOMAIN-SUFFIX,nntime.com,Proxy\nDOMAIN-SUFFIX,a859.g4.akamai.net,Proxy\nDOMAIN-SUFFIX,mycp233.com,Proxy\nDOMAIN-SUFFIX,w3.myftp.name,Proxy\nDOMAIN-SUFFIX,hartnady.com,Proxy\nDOMAIN-SUFFIX,stexv.com,Proxy\nDOMAIN-SUFFIX,huberwood.com,Proxy\nDOMAIN-SUFFIX,jackhou.com,Proxy\nDOMAIN-SUFFIX,line.me,Proxy\nDOMAIN-SUFFIX,d3u6a1seuyd3r3.cloudfront.net,Proxy\nDOMAIN-SUFFIX,fbsbx.com,Proxy\nDOMAIN-SUFFIX,www.e8588.com,Proxy\nDOMAIN-SUFFIX,intouchg.com,Proxy\nDOMAIN-SUFFIX,tb9903.com,Proxy\nDOMAIN-SUFFIX,mbs.188asia.com,Proxy\nDOMAIN-SUFFIX,wfhlifelab.com,Proxy\nDOMAIN-SUFFIX,www.18dao.com,Proxy\nDOMAIN-SUFFIX,d1ssxz857pc9da.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.esb999.com,Proxy\nDOMAIN-SUFFIX,portal.shadowsocks.club,Proxy\nDOMAIN-SUFFIX,buddhanet.com.tw,Proxy\nDOMAIN-SUFFIX,bitrue.com,Proxy\nDOMAIN-SUFFIX,i-part.com.tw,Proxy\nDOMAIN-SUFFIX,www.powerlineblog.com,Proxy\nDOMAIN-SUFFIX,m-orig.discoverhongkong.com,Proxy\nDOMAIN-SUFFIX,www.youthforhumanrights.org,Proxy\nDOMAIN-SUFFIX,clicporn.com,Proxy\nDOMAIN-SUFFIX,archive.fo,Proxy\nDOMAIN-SUFFIX,gallery.io,Proxy\nDOMAIN-SUFFIX,epochtimes.com.br,Proxy\nDOMAIN-SUFFIX,okay.cf,Proxy\nDOMAIN-SUFFIX,bifa007.com,Proxy\nDOMAIN-SUFFIX,chat.lwd-temp.top,Proxy\nDOMAIN-SUFFIX,bway311.com,Proxy\nDOMAIN-SUFFIX,www.iwin963.com,Proxy\nDOMAIN-SUFFIX,tibetnature.net,Proxy\nDOMAIN-SUFFIX,www.ghostme.org,Proxy\nDOMAIN-SUFFIX,xn--flw351e.ml,Proxy\nDOMAIN-SUFFIX,www.riaa.com,Proxy\nDOMAIN-SUFFIX,pdomo.me,Proxy\nDOMAIN-SUFFIX,hotpot.hk,Proxy\nDOMAIN-SUFFIX,hrwf.net,Proxy\nDOMAIN-SUFFIX,bestvpnusa.com,Proxy\nDOMAIN-SUFFIX,kumparan.com,Proxy\nDOMAIN-SUFFIX,cyberfusion.com.au,Proxy\nDOMAIN-SUFFIX,forum.bodybuilding.com,Proxy\nDOMAIN-SUFFIX,we22.ga,Proxy\nDOMAIN-SUFFIX,www.ap.no,Proxy\nDOMAIN-SUFFIX,www.ssm.fun,Proxy\nDOMAIN-SUFFIX,buypass.com,Proxy\nDOMAIN-SUFFIX,www.anonymox.net,Proxy\nDOMAIN-SUFFIX,yegle.net,Proxy\nDOMAIN-SUFFIX,rk.com,Proxy\nDOMAIN-SUFFIX,www.077269.com,Proxy\nDOMAIN-SUFFIX,myyoutube.com,Proxy\nDOMAIN-SUFFIX,whatsapp.com,Proxy\nDOMAIN-SUFFIX,cosmicspark49.wixsite.com,Proxy\nDOMAIN-SUFFIX,yes.xxx,Proxy\nDOMAIN-SUFFIX,km.1024ky.biz,Proxy\nDOMAIN-SUFFIX,tigerchef.com,Proxy\nDOMAIN-SUFFIX,seedoubleyou.org,Proxy\nDOMAIN-SUFFIX,ag2019.net,Proxy\nDOMAIN-SUFFIX,toarumajutsunoindex.wikia.com,Proxy\nDOMAIN-SUFFIX,hentaiz.org,Proxy\nDOMAIN-SUFFIX,igate.ro,Proxy\nDOMAIN-SUFFIX,www.feiyangtravel.com,Proxy\nDOMAIN-SUFFIX,thereallove.kr,Proxy\nDOMAIN-SUFFIX,d3oxa4tn14287p.cloudfront.net,Proxy\nDOMAIN-SUFFIX,bm60000.com,Proxy\nDOMAIN-SUFFIX,zh.cam4.com,Proxy\nDOMAIN-SUFFIX,memrijttm.org,Proxy\nDOMAIN-SUFFIX,www.fondsprofessionell.at,Proxy\nDOMAIN-SUFFIX,m.lyqp.com,Proxy\nDOMAIN-SUFFIX,lockify.com,Proxy\nDOMAIN-SUFFIX,835mmm.net,Proxy\nDOMAIN-SUFFIX,laomiu.com,Proxy\nDOMAIN-SUFFIX,sex520.net,Proxy\nDOMAIN-SUFFIX,www.promotoradeturismo.com,Proxy\nDOMAIN-SUFFIX,blog.usejournal.com,Proxy\nDOMAIN-SUFFIX,91yun.org,Proxy\nDOMAIN-SUFFIX,hotlegsandfeet.com,Proxy\nDOMAIN-SUFFIX,dukevpn.com,Proxy\nDOMAIN-SUFFIX,paxful.com,Proxy\nDOMAIN-SUFFIX,d1gmqe1mlq4xp3.cloudfront.net,Proxy\nDOMAIN-SUFFIX,cyperghost.com,Proxy\nDOMAIN-SUFFIX,sync-cloud.com,Proxy\nDOMAIN-SUFFIX,dagelijksestandaard.nl,Proxy\nDOMAIN-SUFFIX,lightyearvpn.com,Proxy\nDOMAIN-SUFFIX,duplicati.com,Proxy\nDOMAIN-SUFFIX,proxyhide.org,Proxy\nDOMAIN-SUFFIX,www.websunday.net,Proxy\nDOMAIN-SUFFIX,mp3truck.net,Proxy\nDOMAIN-SUFFIX,wealth4allteam.com,Proxy\nDOMAIN-SUFFIX,downloadatoz.com,Proxy\nDOMAIN-SUFFIX,lesoir.be,Proxy\nDOMAIN-SUFFIX,fullrip.net,Proxy\nDOMAIN-SUFFIX,wsvn.com,Proxy\nDOMAIN-SUFFIX,www.warnermediagroup.com,Proxy\nDOMAIN-SUFFIX,mo.nightlife141.com,Proxy\nDOMAIN-SUFFIX,exblog.jp,Proxy\nDOMAIN-SUFFIX,xvdada.com,Proxy\nDOMAIN-SUFFIX,yfgc.fgtv.com,Proxy\nDOMAIN-SUFFIX,redtv.cc,Proxy\nDOMAIN-SUFFIX,fileguru.com,Proxy\nDOMAIN-SUFFIX,animeshow.tv,Proxy\nDOMAIN-SUFFIX,new96.ca,Proxy\nDOMAIN-SUFFIX,apx99.com,Proxy\nDOMAIN-SUFFIX,shadowsocksr.com,Proxy\nDOMAIN-SUFFIX,jamyangleeds.co.uk,Proxy\nDOMAIN-SUFFIX,iav19.com,Proxy\nDOMAIN-SUFFIX,uu.163.com,Proxy\nDOMAIN-SUFFIX,21372220.com,Proxy\nDOMAIN-SUFFIX,holmgren.xyz,Proxy\nDOMAIN-SUFFIX,www.jb203.com,Proxy\nDOMAIN-SUFFIX,gaywatch.com,Proxy\nDOMAIN-SUFFIX,www.vpn-for-china.net,Proxy\nDOMAIN-SUFFIX,kuki.idv.tw,Proxy\nDOMAIN-SUFFIX,rule34.booru.org,Proxy\nDOMAIN-SUFFIX,www.asg.to,Proxy\nDOMAIN-SUFFIX,dogenationhk.github.io,Proxy\nDOMAIN-SUFFIX,traeumtgerade.de,Proxy\nDOMAIN-SUFFIX,www.gagaoolala.com,Proxy\nDOMAIN-SUFFIX,bjtongyu.com,Proxy\nDOMAIN-SUFFIX,www.cloudpn.top,Proxy\nDOMAIN-SUFFIX,www.ero-labs.com,Proxy\nDOMAIN-SUFFIX,twtr2src.ogaoga.org,Proxy\nDOMAIN-SUFFIX,worldofwarcraft.com,Proxy\nDOMAIN-SUFFIX,directmirror.com,Proxy\nDOMAIN-SUFFIX,arweave.net,Proxy\nDOMAIN-SUFFIX,yizhihongxing.com,Proxy\nDOMAIN-SUFFIX,www.naroomanewsonline.com.au,Proxy\nDOMAIN-SUFFIX,thespec.com,Proxy\nDOMAIN-SUFFIX,disk.yandex.ru,Proxy\nDOMAIN-SUFFIX,ftp.cc,Proxy\nDOMAIN-SUFFIX,www.iese.ac.mz,Proxy\nDOMAIN-SUFFIX,nobita6910.com,Proxy\nDOMAIN-SUFFIX,1666600.com,Proxy\nDOMAIN-SUFFIX,www.aafnation.com,Proxy\nDOMAIN-SUFFIX,quran.com,Proxy\nDOMAIN-SUFFIX,lantosfoundation.org,Proxy\nDOMAIN-SUFFIX,yddc3888.com,Proxy\nDOMAIN-SUFFIX,dataresearch.ai,Proxy\nDOMAIN-SUFFIX,etsy.com,Proxy\nDOMAIN-SUFFIX,haaretz.com,Proxy\nDOMAIN-SUFFIX,www.gainexpress.com,Proxy\nDOMAIN-SUFFIX,2333666.xyz,Proxy\nDOMAIN-SUFFIX,whitmail.whitman.edu,Proxy\nDOMAIN-SUFFIX,kuaichedao.org,Proxy\nDOMAIN-SUFFIX,www.interlocals.net,Proxy\nDOMAIN-SUFFIX,phi-thinking.blogspot.hk,Proxy\nDOMAIN-SUFFIX,asrarlhebdo.blogspot.hk,Proxy\nDOMAIN-SUFFIX,bbb.zgjznkyy.com,Proxy\nDOMAIN-SUFFIX,cos-moe.com,Proxy\nDOMAIN-SUFFIX,haotian22.top,Proxy\nDOMAIN-SUFFIX,wewin88.com,Proxy\nDOMAIN-SUFFIX,www.fun88126.com,Proxy\nDOMAIN-SUFFIX,skg-tech.com,Proxy\nDOMAIN-SUFFIX,izlet.com.ar,Proxy\nDOMAIN-SUFFIX,ets.cc,Proxy\nDOMAIN-SUFFIX,www.mediawave.de,Proxy\nDOMAIN-SUFFIX,www.chineseconferenceinterpreters.com,Proxy\nDOMAIN-SUFFIX,falundafaradio.org,Proxy\nDOMAIN-SUFFIX,vpngate.org,Proxy\nDOMAIN-SUFFIX,mediamart.com.sg,Proxy\nDOMAIN-SUFFIX,sjum.cn,Proxy\nDOMAIN-SUFFIX,4022011.com,Proxy\nDOMAIN-SUFFIX,hitekrecruiting.net,Proxy\nDOMAIN-SUFFIX,sis.xxx,Proxy\nDOMAIN-SUFFIX,econlog.econlib.org,Proxy\nDOMAIN-SUFFIX,bradar.cl,Proxy\nDOMAIN-SUFFIX,ns5240.com,Proxy\nDOMAIN-SUFFIX,www.kaka1234.net,Proxy\nDOMAIN-SUFFIX,vpnpronet.com,Proxy\nDOMAIN-SUFFIX,wandering-small-research.bsc.quiknode.pro,Proxy\nDOMAIN-SUFFIX,jobnewera.wordpress.com,Proxy\nDOMAIN-SUFFIX,proxy1.0a1t.com,Proxy\nDOMAIN-SUFFIX,tianyantong.org.cn,Proxy\nDOMAIN-SUFFIX,gbe88.com,Proxy\nDOMAIN-SUFFIX,www.thinkstockphotos.de,Proxy\nDOMAIN-SUFFIX,hhdcb3office.org,Proxy\nDOMAIN-SUFFIX,a.ssd2.bid,Proxy\nDOMAIN-SUFFIX,bidmc.org,Proxy\nDOMAIN-SUFFIX,mobifcuk.com,Proxy\nDOMAIN-SUFFIX,hk.video.news.yahoo.com,Proxy\nDOMAIN-SUFFIX,www.opensc.ws,Proxy\nDOMAIN-SUFFIX,ansoft.cl,Proxy\nDOMAIN-SUFFIX,sports.188games.net,Proxy\nDOMAIN-SUFFIX,domain.club.tw,Proxy\nDOMAIN-SUFFIX,bbs.tuitui.info,Proxy\nDOMAIN-SUFFIX,aaxpro.com,Proxy\nDOMAIN-SUFFIX,myplan.powayusd.com,Proxy\nDOMAIN-SUFFIX,okgo.xyz,Proxy\nDOMAIN-SUFFIX,www.appleholiday.com,Proxy\nDOMAIN-SUFFIX,tngrnow.net,Proxy\nDOMAIN-SUFFIX,bitz.ai,Proxy\nDOMAIN-SUFFIX,maiplus.com,Proxy\nDOMAIN-SUFFIX,p.w3cx.us,Proxy\nDOMAIN-SUFFIX,fastusaproxy.com,Proxy\nDOMAIN-SUFFIX,popo.tw,Proxy\nDOMAIN-SUFFIX,beemtube.com,Proxy\nDOMAIN-SUFFIX,www.t6.com,Proxy\nDOMAIN-SUFFIX,flvto.biz,Proxy\nDOMAIN-SUFFIX,hklts.org.hk,Proxy\nDOMAIN-SUFFIX,www.777b.com,Proxy\nDOMAIN-SUFFIX,glock.com,Proxy\nDOMAIN-SUFFIX,dvrdns.org,Proxy\nDOMAIN-SUFFIX,yaksi.name.tr,Proxy\nDOMAIN-SUFFIX,ogj.com,Proxy\nDOMAIN-SUFFIX,zetify.com,Proxy\nDOMAIN-SUFFIX,4proxy.de,Proxy\nDOMAIN-SUFFIX,nvwaterandfire.com,Proxy\nDOMAIN-SUFFIX,www.mittelbayerische.de,Proxy\nDOMAIN-SUFFIX,vota.net,Proxy\nDOMAIN-SUFFIX,zhongguorenquan.org,Proxy\nDOMAIN-SUFFIX,racing.turfclub.com.sg,Proxy\nDOMAIN-SUFFIX,oanda.sg,Proxy\nDOMAIN-SUFFIX,darinmohr.com,Proxy\nDOMAIN-SUFFIX,www.asiavpn.net,Proxy\nDOMAIN-SUFFIX,d9883.com,Proxy\nDOMAIN-SUFFIX,www.bifa3333.com,Proxy\nDOMAIN-SUFFIX,www.thinkstockphotos.com.au,Proxy\nDOMAIN-SUFFIX,chinesesaints.org,Proxy\nDOMAIN-SUFFIX,novaramedia.com,Proxy\nDOMAIN-SUFFIX,chinesepen.org,Proxy\nDOMAIN-SUFFIX,mv.aeweb.xyz,Proxy\nDOMAIN-SUFFIX,www.bestvpnrating.com,Proxy\nDOMAIN-SUFFIX,city365.ca,Proxy\nDOMAIN-SUFFIX,otzo.com,Proxy\nDOMAIN-SUFFIX,secure.adultfriendfinder.com,Proxy\nDOMAIN-SUFFIX,bannednews.org,Proxy\nDOMAIN-SUFFIX,doubleclick.com,Proxy\nDOMAIN-SUFFIX,www.alicespringsnews.com.au,Proxy\nDOMAIN-SUFFIX,duliziyou.com,Proxy\nDOMAIN-SUFFIX,bway885056.com,Proxy\nDOMAIN-SUFFIX,hustlerhollywood.com,Proxy\nDOMAIN-SUFFIX,minghui.or.kr,Proxy\nDOMAIN-SUFFIX,timesnownews.com,Proxy\nDOMAIN-SUFFIX,www.lilith-soft.com,Proxy\nDOMAIN-SUFFIX,hmongjob.com,Proxy\nDOMAIN-SUFFIX,by.ddns.name,Proxy\nDOMAIN-SUFFIX,cating.tw,Proxy\nDOMAIN-SUFFIX,cursor.so,Proxy\nDOMAIN-SUFFIX,www.hkcnews.com,Proxy\nDOMAIN-SUFFIX,charliehebdo.fr,Proxy\nDOMAIN-SUFFIX,71588.com,Proxy\nDOMAIN-SUFFIX,jinbushe.org,Proxy\nDOMAIN-SUFFIX,my-private-network.co.uk,Proxy\nDOMAIN-SUFFIX,www.mychinese.news,Proxy\nDOMAIN-SUFFIX,cdp1989.org,Proxy\nDOMAIN-SUFFIX,seifert.com.ar,Proxy\nDOMAIN-SUFFIX,google.com.tw,Proxy\nDOMAIN-SUFFIX,xn--mxaaaah3ch9d.gr,Proxy\nDOMAIN-SUFFIX,lsxszzg.com,Proxy\nDOMAIN-SUFFIX,www.just-make.com.tw,Proxy\nDOMAIN-SUFFIX,swingbop.ch,Proxy\nDOMAIN-SUFFIX,shadoworld.me,Proxy\nDOMAIN-SUFFIX,wordpandit.com,Proxy\nDOMAIN-SUFFIX,www.almightywind.com,Proxy\nDOMAIN-SUFFIX,theqingyun.org,Proxy\nDOMAIN-SUFFIX,atmarkit.co.jp,Proxy\nDOMAIN-SUFFIX,google.com.gh,Proxy\nDOMAIN-SUFFIX,jmcomic1.me,Proxy\nDOMAIN-SUFFIX,www.wealth.com.tw,Proxy\nDOMAIN-SUFFIX,komica2.net,Proxy\nDOMAIN-SUFFIX,rb.gy,Proxy\nDOMAIN-SUFFIX,v997.net,Proxy\nDOMAIN-SUFFIX,busroig.es,Proxy\nDOMAIN-SUFFIX,fanglizhi.info,Proxy\nDOMAIN-SUFFIX,de.ahava.com,Proxy\nDOMAIN-SUFFIX,google.gy,Proxy\nDOMAIN-SUFFIX,sudoproxy.net,Proxy\nDOMAIN-SUFFIX,zaobao.com.sg,Proxy\nDOMAIN-SUFFIX,7870.cabet111.com,Proxy\nDOMAIN-SUFFIX,asaakira.com,Proxy\nDOMAIN-SUFFIX,facebook.fr,Proxy\nDOMAIN-SUFFIX,websitetonight.com,Proxy\nDOMAIN-SUFFIX,www.hawaiichinesenews.net,Proxy\nDOMAIN-SUFFIX,a.temporaryrecord.com,Proxy\nDOMAIN-SUFFIX,eryue888.com,Proxy\nDOMAIN-SUFFIX,fastproxynetwork.com,Proxy\nDOMAIN-SUFFIX,gotporn.com,Proxy\nDOMAIN-SUFFIX,openvpn.se,Proxy\nDOMAIN-SUFFIX,531u.com,Proxy\nDOMAIN-SUFFIX,6hcc.com,Proxy\nDOMAIN-SUFFIX,kumanichi.com,Proxy\nDOMAIN-SUFFIX,www.laboratoriofriki.com,Proxy\nDOMAIN-SUFFIX,ngodupdongchung.com,Proxy\nDOMAIN-SUFFIX,glemte.no,Proxy\nDOMAIN-SUFFIX,download.pdfforge.org,Proxy\nDOMAIN-SUFFIX,freeparking.co.nz,Proxy\nDOMAIN-SUFFIX,older4me.com,Proxy\nDOMAIN-SUFFIX,2youtube.com,Proxy\nDOMAIN-SUFFIX,phhhoto.com,Proxy\nDOMAIN-SUFFIX,mp.truth.gq,Proxy\nDOMAIN-SUFFIX,youtubepp.com,Proxy\nDOMAIN-SUFFIX,appweb.cna.com.tw,Proxy\nDOMAIN-SUFFIX,janevim.cz,Proxy\nDOMAIN-SUFFIX,www.greatlakesadvocate.com.au,Proxy\nDOMAIN-SUFFIX,vodcache019.dmc.nico,Proxy\nDOMAIN-SUFFIX,bobwills4homes.com,Proxy\nDOMAIN-SUFFIX,wpoforum.com,Proxy\nDOMAIN-SUFFIX,gxsna.com,Proxy\nDOMAIN-SUFFIX,0668.cc,Proxy\nDOMAIN-SUFFIX,piratebrowser.com,Proxy\nDOMAIN-SUFFIX,allasians.com,Proxy\nDOMAIN-SUFFIX,www.gamenet.it,Proxy\nDOMAIN-SUFFIX,www6.eyny.com,Proxy\nDOMAIN-SUFFIX,dmcdn.net,Proxy\nDOMAIN-SUFFIX,box123456.strikingly.com,Proxy\nDOMAIN-SUFFIX,fw8.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,typepad.com,Proxy\nDOMAIN-SUFFIX,vpn4all.com,Proxy\nDOMAIN-SUFFIX,bol.com,Proxy\nDOMAIN-SUFFIX,8bqapp.site,Proxy\nDOMAIN-SUFFIX,www.sdyl88.com,Proxy\nDOMAIN-SUFFIX,www.987733.com,Proxy\nDOMAIN-SUFFIX,www.tainyi.idv.tw,Proxy\nDOMAIN-SUFFIX,sshkit.com,Proxy\nDOMAIN-SUFFIX,anses.gov.ar,Proxy\nDOMAIN-SUFFIX,bulkyoutube.com,Proxy\nDOMAIN-SUFFIX,ipadio.com,Proxy\nDOMAIN-SUFFIX,mywife.cc,Proxy\nDOMAIN-SUFFIX,vn.hao123.com,Proxy\nDOMAIN-SUFFIX,www.tr-radio.com,Proxy\nDOMAIN-SUFFIX,draiveda.lt,Proxy\nDOMAIN-SUFFIX,www.huobi.pr,Proxy\nDOMAIN-SUFFIX,lockestek.com,Proxy\nDOMAIN-SUFFIX,royalssl.com,Proxy\nDOMAIN-SUFFIX,shadowsocks.com,Proxy\nDOMAIN-SUFFIX,torrentkitty.org,Proxy\nDOMAIN-SUFFIX,xiaobaiwu.com,Proxy\nDOMAIN-SUFFIX,hemanmusique.com,Proxy\nDOMAIN-SUFFIX,waltermartin.org,Proxy\nDOMAIN-SUFFIX,ma3loooma.blogspot.hk,Proxy\nDOMAIN-SUFFIX,sendvid.com,Proxy\nDOMAIN-SUFFIX,telecomspace.com,Proxy\nDOMAIN-SUFFIX,tibetancommunityuk.net,Proxy\nDOMAIN-SUFFIX,www.victorinox.com,Proxy\nDOMAIN-SUFFIX,wikinews.org,Proxy\nDOMAIN-SUFFIX,tunein.com,Proxy\nDOMAIN-SUFFIX,onmoon.com,Proxy\nDOMAIN-SUFFIX,www.maitlandmercury.com.au,Proxy\nDOMAIN-SUFFIX,xbxbbet.com,Proxy\nDOMAIN-SUFFIX,www.proxyfort.com,Proxy\nDOMAIN-SUFFIX,gta777.net,Proxy\nDOMAIN-SUFFIX,moviefap.com,Proxy\nDOMAIN-SUFFIX,www.totalvpn.com,Proxy\nDOMAIN-SUFFIX,177pic.info,Proxy\nDOMAIN-SUFFIX,haptic.al,Proxy\nDOMAIN-SUFFIX,www.exp5redir5.com,Proxy\nDOMAIN-SUFFIX,sexxxy.biz,Proxy\nDOMAIN-SUFFIX,www.spin969.com,Proxy\nDOMAIN-SUFFIX,sexuhot.com,Proxy\nDOMAIN-SUFFIX,londonchinese.ca,Proxy\nDOMAIN-SUFFIX,sc-jpl.com,Proxy\nDOMAIN-SUFFIX,www.nyapass.com,Proxy\nDOMAIN-SUFFIX,kima66.net,Proxy\nDOMAIN-SUFFIX,www.haiwaitoutiao.com,Proxy\nDOMAIN-SUFFIX,geti2p.net,Proxy\nDOMAIN-SUFFIX,from-dc.com,Proxy\nDOMAIN-SUFFIX,yayabay.net,Proxy\nDOMAIN-SUFFIX,china21century.org,Proxy\nDOMAIN-SUFFIX,jimtonti.com,Proxy\nDOMAIN-SUFFIX,win2day.at,Proxy\nDOMAIN-SUFFIX,piss.jp,Proxy\nDOMAIN-SUFFIX,feedblitz.com,Proxy\nDOMAIN-SUFFIX,www.intersport88.com,Proxy\nDOMAIN-SUFFIX,www.campaignseries.co.uk,Proxy\nDOMAIN-SUFFIX,thinkflown.000webhostapp.com,Proxy\nDOMAIN-SUFFIX,goblinrefuge.com,Proxy\nDOMAIN-SUFFIX,www.waonetwork.net,Proxy\nDOMAIN-SUFFIX,diva-portal.org,Proxy\nDOMAIN-SUFFIX,imugr.com,Proxy\nDOMAIN-SUFFIX,iescentral.com,Proxy\nDOMAIN-SUFFIX,y68357.com,Proxy\nDOMAIN-SUFFIX,www.ca232.com,Proxy\nDOMAIN-SUFFIX,www.zfshe1.com,Proxy\nDOMAIN-SUFFIX,813.tuoitrevn.es,Proxy\nDOMAIN-SUFFIX,search.westca.com,Proxy\nDOMAIN-SUFFIX,www.vicomi.com,Proxy\nDOMAIN-SUFFIX,pu0020.com,Proxy\nDOMAIN-SUFFIX,www.examiner.com.au,Proxy\nDOMAIN-SUFFIX,jacobin.com,Proxy\nDOMAIN-SUFFIX,canyu.org,Proxy\nDOMAIN-SUFFIX,exrates.me,Proxy\nDOMAIN-SUFFIX,ideapocket.com,Proxy\nDOMAIN-SUFFIX,djyavdj3p2yvj.cloudfront.net,Proxy\nDOMAIN-SUFFIX,infoservice.inf.tu-dresden.de,Proxy\nDOMAIN-SUFFIX,www.sungard.com,Proxy\nDOMAIN-SUFFIX,twbbs.org,Proxy\nDOMAIN-SUFFIX,illinois.gov,Proxy\nDOMAIN-SUFFIX,yobit.net,Proxy\nDOMAIN-SUFFIX,seminars.tca.org.tw,Proxy\nDOMAIN-SUFFIX,www.daliulian.net,Proxy\nDOMAIN-SUFFIX,4shared.com,Proxy\nDOMAIN-SUFFIX,stingle.org,Proxy\nDOMAIN-SUFFIX,www.china-chatgpt.com,Proxy\nDOMAIN-SUFFIX,googlehosted.com,Proxy\nDOMAIN-SUFFIX,twitr.gq,Proxy\nDOMAIN-SUFFIX,pytorch.org,Proxy\nDOMAIN-SUFFIX,www.mrcat166.com,Proxy\nDOMAIN-SUFFIX,50559.com,Proxy\nDOMAIN-SUFFIX,youav.com,Proxy\nDOMAIN-SUFFIX,22.dhcp.biz,Proxy\nDOMAIN-SUFFIX,hrtsea.com,Proxy\nDOMAIN-SUFFIX,www.aolnews.com,Proxy\nDOMAIN-SUFFIX,www.ysifx.com,Proxy\nDOMAIN-SUFFIX,117899.com,Proxy\nDOMAIN-SUFFIX,777ue.com,Proxy\nDOMAIN-SUFFIX,bdg190.com,Proxy\nDOMAIN-SUFFIX,kuaishangche.live,Proxy\nDOMAIN-SUFFIX,ironsocket.com,Proxy\nDOMAIN-SUFFIX,b311450.com,Proxy\nDOMAIN-SUFFIX,spacedrain.com,Proxy\nDOMAIN-SUFFIX,aikidobravo.wixsite.com,Proxy\nDOMAIN-SUFFIX,freeproxylists.net,Proxy\nDOMAIN-SUFFIX,hmvdigital.ca,Proxy\nDOMAIN-SUFFIX,seezone.net,Proxy\nDOMAIN-SUFFIX,japanesethumbs.com,Proxy\nDOMAIN-SUFFIX,ix.com,Proxy\nDOMAIN-SUFFIX,fagsmut.net,Proxy\nDOMAIN-SUFFIX,d2dz57s22kludp.cloudfront.net,Proxy\nDOMAIN-SUFFIX,i999.me,Proxy\nDOMAIN-SUFFIX,azirevpn.com,Proxy\nDOMAIN-SUFFIX,www.saponeworld.com,Proxy\nDOMAIN-SUFFIX,gethotspotshield.com,Proxy\nDOMAIN-SUFFIX,livestre.am,Proxy\nDOMAIN-SUFFIX,0800.4irc.com,Proxy\nDOMAIN-SUFFIX,jsdelivr.net,Proxy\nDOMAIN-SUFFIX,404museum.com,Proxy\nDOMAIN-SUFFIX,perma.cc,Proxy\nDOMAIN-SUFFIX,www.moxing.dog,Proxy\nDOMAIN-SUFFIX,www.taiwancon.com,Proxy\nDOMAIN-SUFFIX,alhs.fun,Proxy\nDOMAIN-SUFFIX,androidtv.com,Proxy\nDOMAIN-SUFFIX,candidhominid.com,Proxy\nDOMAIN-SUFFIX,www.g818city.com,Proxy\nDOMAIN-SUFFIX,p2662.com,Proxy\nDOMAIN-SUFFIX,v2raycn.com,Proxy\nDOMAIN-SUFFIX,a-0014.a-msedge.net,Proxy\nDOMAIN-SUFFIX,wechatlawsuit.com,Proxy\nDOMAIN-SUFFIX,ieji.de,Proxy\nDOMAIN-SUFFIX,tcrn.ch,Proxy\nDOMAIN-SUFFIX,lexiekier.com,Proxy\nDOMAIN-SUFFIX,sdatum.com,Proxy\nDOMAIN-SUFFIX,shambalapost.com,Proxy\nDOMAIN-SUFFIX,wiki.gamerp.jp,Proxy\nDOMAIN-SUFFIX,certificate-transparency.org,Proxy\nDOMAIN-SUFFIX,7067e.com,Proxy\nDOMAIN-SUFFIX,jarrellguitars.com,Proxy\nDOMAIN-SUFFIX,wetinim.com,Proxy\nDOMAIN-SUFFIX,www.lhasadaily.com,Proxy\nDOMAIN-SUFFIX,zb.com,Proxy\nDOMAIN-SUFFIX,root.sx,Proxy\nDOMAIN-SUFFIX,singtao.com.au,Proxy\nDOMAIN-SUFFIX,gigantclips.com,Proxy\nDOMAIN-SUFFIX,xsden.org,Proxy\nDOMAIN-SUFFIX,indiablooms.com,Proxy\nDOMAIN-SUFFIX,i100.co.uk,Proxy\nDOMAIN-SUFFIX,turk.life,Proxy\nDOMAIN-SUFFIX,www.nbcdfw.com,Proxy\nDOMAIN-SUFFIX,ifan.cz.cc,Proxy\nDOMAIN-SUFFIX,chinahistorypodcast.com,Proxy\nDOMAIN-SUFFIX,www.gic.com.sg,Proxy\nDOMAIN-SUFFIX,invidio.xamh.de,Proxy\nDOMAIN-SUFFIX,showtime.jp,Proxy\nDOMAIN-SUFFIX,gladiabots.com,Proxy\nDOMAIN-SUFFIX,labiennale.org,Proxy\nDOMAIN-SUFFIX,jtbc.joins.com,Proxy\nDOMAIN-SUFFIX,wo3ttt.wordpress.com,Proxy\nDOMAIN-SUFFIX,murmur.tw,Proxy\nDOMAIN-SUFFIX,en.ishadowx.net,Proxy\nDOMAIN-SUFFIX,dznm1muq30trd.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.blm12.net,Proxy\nDOMAIN-SUFFIX,9sp5.icu,Proxy\nDOMAIN-SUFFIX,www.superxstory.com,Proxy\nDOMAIN-SUFFIX,skylikesun.blogspot.my,Proxy\nDOMAIN-SUFFIX,bomler.com,Proxy\nDOMAIN-SUFFIX,www.wjsnr.com,Proxy\nDOMAIN-SUFFIX,www.falungonginfo.net,Proxy\nDOMAIN-SUFFIX,fun688.com,Proxy\nDOMAIN-SUFFIX,sk2sk.xyz,Proxy\nDOMAIN-SUFFIX,chenpokong.com,Proxy\nDOMAIN-SUFFIX,qwant.com,Proxy\nDOMAIN-SUFFIX,www.idrivesync.com,Proxy\nDOMAIN-SUFFIX,www.stthuset.com,Proxy\nDOMAIN-SUFFIX,www.farangdingdong.com,Proxy\nDOMAIN-SUFFIX,lawofhongkong.com,Proxy\nDOMAIN-SUFFIX,3830225.com,Proxy\nDOMAIN-SUFFIX,jbtalks.cc,Proxy\nDOMAIN-SUFFIX,bf638.com,Proxy\nDOMAIN-SUFFIX,dinkys.ws,Proxy\nDOMAIN-SUFFIX,xj.freepac.pw,Proxy\nDOMAIN-SUFFIX,www.513vpn.com,Proxy\nDOMAIN-SUFFIX,54.from-al.com,Proxy\nDOMAIN-SUFFIX,privatepaste.com,Proxy\nDOMAIN-SUFFIX,toypark.in,Proxy\nDOMAIN-SUFFIX,mp3quack.live,Proxy\nDOMAIN-SUFFIX,flyvpn.net,Proxy\nDOMAIN-SUFFIX,d39l9va7udgle8.cloudfront.net,Proxy\nDOMAIN-SUFFIX,eng.taiwan.net.tw,Proxy\nDOMAIN-SUFFIX,www.bluecad.com,Proxy\nDOMAIN-SUFFIX,92xag.com,Proxy\nDOMAIN-SUFFIX,gospelherald.com,Proxy\nDOMAIN-SUFFIX,simplex.chat,Proxy\nDOMAIN-SUFFIX,www.hb528.com,Proxy\nDOMAIN-SUFFIX,sports-bb.ipistech471.com,Proxy\nDOMAIN-SUFFIX,ethics.moe.edu.tw,Proxy\nDOMAIN-SUFFIX,flgjustice.org,Proxy\nDOMAIN-SUFFIX,www.txvip888.com,Proxy\nDOMAIN-SUFFIX,dalailamafellows.org,Proxy\nDOMAIN-SUFFIX,aa2.app,Proxy\nDOMAIN-SUFFIX,apkmonk.com,Proxy\nDOMAIN-SUFFIX,ca8088.com,Proxy\nDOMAIN-SUFFIX,charlesworth.nom.za,Proxy\nDOMAIN-SUFFIX,lbs6.com,Proxy\nDOMAIN-SUFFIX,regs.be,Proxy\nDOMAIN-SUFFIX,bridgethewise.net,Proxy\nDOMAIN-SUFFIX,rmcasinos.com,Proxy\nDOMAIN-SUFFIX,hj011.com,Proxy\nDOMAIN-SUFFIX,privacybox.de,Proxy\nDOMAIN-SUFFIX,00133.com,Proxy\nDOMAIN-SUFFIX,www.shayunet.net,Proxy\nDOMAIN-SUFFIX,www.macgn.com,Proxy\nDOMAIN-SUFFIX,ca979.com,Proxy\nDOMAIN-SUFFIX,theseattleschool.edu,Proxy\nDOMAIN-SUFFIX,xixitalk.top,Proxy\nDOMAIN-SUFFIX,adultporntube.xxx,Proxy\nDOMAIN-SUFFIX,justicefortenzin.org,Proxy\nDOMAIN-SUFFIX,cdw.com,Proxy\nDOMAIN-SUFFIX,zhidao.dyj168.info,Proxy\nDOMAIN-SUFFIX,chinese.yahoo.com,Proxy\nDOMAIN-SUFFIX,www.slantedeyes.com,Proxy\nDOMAIN-SUFFIX,symfony.com,Proxy\nDOMAIN-SUFFIX,churchinmarlboro.org,Proxy\nDOMAIN-SUFFIX,feignthat.com,Proxy\nDOMAIN-SUFFIX,ca161.com,Proxy\nDOMAIN-SUFFIX,ip6868.com,Proxy\nDOMAIN-SUFFIX,dtvideo.com,Proxy\nDOMAIN-SUFFIX,folio.nzz.ch,Proxy\nDOMAIN-SUFFIX,wuyanblog.com,Proxy\nDOMAIN-SUFFIX,janwongphoto.com,Proxy\nDOMAIN-SUFFIX,mohu.ml,Proxy\nDOMAIN-SUFFIX,www.moe-li.com,Proxy\nDOMAIN-SUFFIX,xinbi656.com,Proxy\nDOMAIN-SUFFIX,www.pornicom.com,Proxy\nDOMAIN-SUFFIX,google.com.na,Proxy\nDOMAIN-SUFFIX,x.xxgirls2.org,Proxy\nDOMAIN-SUFFIX,qqwljs.buzz,Proxy\nDOMAIN-SUFFIX,ngdproject.com,Proxy\nDOMAIN-SUFFIX,greenpeace.com.tw,Proxy\nDOMAIN-SUFFIX,www.173js.cn,Proxy\nDOMAIN-SUFFIX,l.main.getrevue.co,Proxy\nDOMAIN-SUFFIX,canadameet.com,Proxy\nDOMAIN-SUFFIX,www.vns5252.com,Proxy\nDOMAIN-SUFFIX,www.newstapa.com,Proxy\nDOMAIN-SUFFIX,www.01bz.net,Proxy\nDOMAIN-SUFFIX,666876.com,Proxy\nDOMAIN-SUFFIX,m.0000hg.com,Proxy\nDOMAIN-SUFFIX,anonymus.us,Proxy\nDOMAIN-SUFFIX,www.eu99999.com,Proxy\nDOMAIN-SUFFIX,www.liverail.com,Proxy\nDOMAIN-SUFFIX,library.usc.cuhk.edu.hk,Proxy\nDOMAIN-SUFFIX,codepush.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,www.70079.com,Proxy\nDOMAIN-SUFFIX,669d.net,Proxy\nDOMAIN-SUFFIX,eurekavpt.com,Proxy\nDOMAIN-SUFFIX,www.ddm.org.au,Proxy\nDOMAIN-SUFFIX,mbetway88.agent1818.com,Proxy\nDOMAIN-SUFFIX,www.xj2238.com,Proxy\nDOMAIN-SUFFIX,catfan.me,Proxy\nDOMAIN-SUFFIX,feed.laborinfocn2.com,Proxy\nDOMAIN-SUFFIX,tntt.org,Proxy\nDOMAIN-SUFFIX,www.rsi.sk,Proxy\nDOMAIN-SUFFIX,el-ladies.com,Proxy\nDOMAIN-SUFFIX,blog.qooza.hk,Proxy\nDOMAIN-SUFFIX,sierrafriendsoftibet.org,Proxy\nDOMAIN-SUFFIX,roupacaipira.com,Proxy\nDOMAIN-SUFFIX,dz6cptgoro33r.cloudfront.net,Proxy\nDOMAIN-SUFFIX,mangovpn.com,Proxy\nDOMAIN-SUFFIX,1024.hlork9.com,Proxy\nDOMAIN-SUFFIX,cochina.co,Proxy\nDOMAIN-SUFFIX,nsgalleries.com,Proxy\nDOMAIN-SUFFIX,www.motorola.com,Proxy\nDOMAIN-SUFFIX,swc888.com,Proxy\nDOMAIN-SUFFIX,goodreads.com,Proxy\nDOMAIN-SUFFIX,shop.cwbook.com.tw,Proxy\nDOMAIN-SUFFIX,531051a.com,Proxy\nDOMAIN-SUFFIX,b67833.com,Proxy\nDOMAIN-SUFFIX,imageflea.com,Proxy\nDOMAIN-SUFFIX,timesofindia.com,Proxy\nDOMAIN-SUFFIX,surfagain.com,Proxy\nDOMAIN-SUFFIX,www.catcatforum.com,Proxy\nDOMAIN-SUFFIX,www.ytbit.com,Proxy\nDOMAIN-SUFFIX,www.youngmm.com,Proxy\nDOMAIN-SUFFIX,addyoutube.com,Proxy\nDOMAIN-SUFFIX,eanut.com,Proxy\nDOMAIN-SUFFIX,tibetswiss.ch,Proxy\nDOMAIN-SUFFIX,www.lei.com.tw,Proxy\nDOMAIN-SUFFIX,beta.character.ai,Proxy\nDOMAIN-SUFFIX,chinarightsia.org,Proxy\nDOMAIN-SUFFIX,d1iehmrcgpeq4c.cloudfront.net,Proxy\nDOMAIN-SUFFIX,d2zeivqodro67a.cloudfront.net,Proxy\nDOMAIN-SUFFIX,177704444.com,Proxy\nDOMAIN-SUFFIX,afcp.com,Proxy\nDOMAIN-SUFFIX,www.nmall.fun,Proxy\nDOMAIN-SUFFIX,ca957.com,Proxy\nDOMAIN-SUFFIX,porn.com,Proxy\nDOMAIN-SUFFIX,lovecreampie.com,Proxy\nDOMAIN-SUFFIX,blog.expofutures.com,Proxy\nDOMAIN-SUFFIX,cts.com.tw,Proxy\nDOMAIN-SUFFIX,hqporner.com,Proxy\nDOMAIN-SUFFIX,www.greycoder.com,Proxy\nDOMAIN-SUFFIX,proxy-topsite.com,Proxy\nDOMAIN-SUFFIX,nm.btqilingbaliu.com,Proxy\nDOMAIN-SUFFIX,static.cdninstagram.com,Proxy\nDOMAIN-SUFFIX,www.mansurfer.com,Proxy\nDOMAIN-SUFFIX,www.tokyoteenies.com,Proxy\nDOMAIN-SUFFIX,mx.hao123.com,Proxy\nDOMAIN-SUFFIX,joefrance.org,Proxy\nDOMAIN-SUFFIX,www.mingpaovan.com,Proxy\nDOMAIN-SUFFIX,gru14s19-in-f11.1e100.net,Proxy\nDOMAIN-SUFFIX,tv365.ga,Proxy\nDOMAIN-SUFFIX,bayvoice.net,Proxy\nDOMAIN-SUFFIX,d2t99c5pxqndf4.cloudfront.net,Proxy\nDOMAIN-SUFFIX,tibet-info.net,Proxy\nDOMAIN-SUFFIX,1mynews.net,Proxy\nDOMAIN-SUFFIX,mail.kcdgs.com,Proxy\nDOMAIN-SUFFIX,sunta.com.tw,Proxy\nDOMAIN-SUFFIX,computerweekly.com,Proxy\nDOMAIN-SUFFIX,azirevpn.net,Proxy\nDOMAIN-SUFFIX,www.9rti.org,Proxy\nDOMAIN-SUFFIX,www.iconeye.com,Proxy\nDOMAIN-SUFFIX,notify.dropboxapi.com,Proxy\nDOMAIN-SUFFIX,www.vllcs.org,Proxy\nDOMAIN-SUFFIX,info-cn.github.io,Proxy\nDOMAIN-SUFFIX,www.juji.tv,Proxy\nDOMAIN-SUFFIX,goodtv.com.tw,Proxy\nDOMAIN-SUFFIX,gunnerkrigg.com,Proxy\nDOMAIN-SUFFIX,unblocksit.es,Proxy\nDOMAIN-SUFFIX,liangzhichuanmei.com,Proxy\nDOMAIN-SUFFIX,www.244.cc,Proxy\nDOMAIN-SUFFIX,xc.domain888.pw,Proxy\nDOMAIN-SUFFIX,www.f88vip10.com,Proxy\nDOMAIN-SUFFIX,ylg111.com,Proxy\nDOMAIN-SUFFIX,hqcdp.org,Proxy\nDOMAIN-SUFFIX,d3jzzqzcyx77gi.cloudfront.net,Proxy\nDOMAIN-SUFFIX,fun580.com,Proxy\nDOMAIN-SUFFIX,oeea.org,Proxy\nDOMAIN-SUFFIX,savemedia.com,Proxy\nDOMAIN-SUFFIX,www.iwin996.com,Proxy\nDOMAIN-SUFFIX,asiaharvest.org,Proxy\nDOMAIN-SUFFIX,hanmail.net,Proxy\nDOMAIN-SUFFIX,chenpokong.net,Proxy\nDOMAIN-SUFFIX,buyu7777.com,Proxy\nDOMAIN-SUFFIX,tibetwebdesign.com,Proxy\nDOMAIN-SUFFIX,scope.co.id,Proxy\nDOMAIN-SUFFIX,mdanieltays.com,Proxy\nDOMAIN-SUFFIX,136.microcycas.com,Proxy\nDOMAIN-SUFFIX,underhentai.net,Proxy\nDOMAIN-SUFFIX,weiming.info,Proxy\nDOMAIN-SUFFIX,www.tfd.org.tw,Proxy\nDOMAIN-SUFFIX,web.1mynews.com,Proxy\nDOMAIN-SUFFIX,www.floridadharma.org,Proxy\nDOMAIN-SUFFIX,www.upenn.edu,Proxy\nDOMAIN-SUFFIX,ignitedetroit.net,Proxy\nDOMAIN-SUFFIX,5141.mmavday.com,Proxy\nDOMAIN-SUFFIX,2nyz.org,Proxy\nDOMAIN-SUFFIX,bewww.net,Proxy\nDOMAIN-SUFFIX,rmjdw.com,Proxy\nDOMAIN-SUFFIX,1kcp.com,Proxy\nDOMAIN-SUFFIX,is-a-conservative.com,Proxy\nDOMAIN-SUFFIX,ipfs-search.com,Proxy\nDOMAIN-SUFFIX,maquiabella.com.ar,Proxy\nDOMAIN-SUFFIX,mag.udn.com,Proxy\nDOMAIN-SUFFIX,www.tokyoporn.com,Proxy\nDOMAIN-SUFFIX,link.fzgyh.com,Proxy\nDOMAIN-SUFFIX,commentshk.blogspot.hk,Proxy\nDOMAIN-SUFFIX,vpnwg.com,Proxy\nDOMAIN-SUFFIX,wowana.me,Proxy\nDOMAIN-SUFFIX,ufcxv.xyz,Proxy\nDOMAIN-SUFFIX,cordcloud.org,Proxy\nDOMAIN-SUFFIX,towngain.com,Proxy\nDOMAIN-SUFFIX,www.pearmac.com,Proxy\nDOMAIN-SUFFIX,prdelb.yzdgzw.com,Proxy\nDOMAIN-SUFFIX,www.worldvpn.net,Proxy\nDOMAIN-SUFFIX,sthoo.com,Proxy\nDOMAIN-SUFFIX,regardschine.com,Proxy\nDOMAIN-SUFFIX,www06.eyny.com,Proxy\nDOMAIN-SUFFIX,wwa.nvcx.work,Proxy\nDOMAIN-SUFFIX,blog.taragana.com,Proxy\nDOMAIN-SUFFIX,www.gate-project.com,Proxy\nDOMAIN-SUFFIX,bbtoystore.com,Proxy\nDOMAIN-SUFFIX,www.18xl.in,Proxy\nDOMAIN-SUFFIX,volafile.org,Proxy\nDOMAIN-SUFFIX,www.screencrush.com,Proxy\nDOMAIN-SUFFIX,hk.mobi.yahoo.com,Proxy\nDOMAIN-SUFFIX,gaxycloud.ml,Proxy\nDOMAIN-SUFFIX,vpn-accounts.com,Proxy\nDOMAIN-SUFFIX,www.notary.net,Proxy\nDOMAIN-SUFFIX,www.reclaimhosting.com,Proxy\nDOMAIN-SUFFIX,www.ultimedia.com,Proxy\nDOMAIN-SUFFIX,closers.nexon.com,Proxy\nDOMAIN-SUFFIX,www.nuovaperiferia.it,Proxy\nDOMAIN-SUFFIX,oursteps.com.au,Proxy\nDOMAIN-SUFFIX,friends.pts.org.tw,Proxy\nDOMAIN-SUFFIX,hackthatphone.net,Proxy\nDOMAIN-SUFFIX,stmartininthefields.org,Proxy\nDOMAIN-SUFFIX,www.folioinvesting.co,Proxy\nDOMAIN-SUFFIX,18avtube.com,Proxy\nDOMAIN-SUFFIX,www.hjdc98.com,Proxy\nDOMAIN-SUFFIX,chaturbute.com,Proxy\nDOMAIN-SUFFIX,www.jgg18.io,Proxy\nDOMAIN-SUFFIX,patinia.gr,Proxy\nDOMAIN-SUFFIX,www.birdbeep.net,Proxy\nDOMAIN-SUFFIX,www.971678.com,Proxy\nDOMAIN-SUFFIX,www.youtube.iq,Proxy\nDOMAIN-SUFFIX,summify.com,Proxy\nDOMAIN-SUFFIX,www.wellbuying.com.tw,Proxy\nDOMAIN-SUFFIX,search.aust.cf,Proxy\nDOMAIN-SUFFIX,meeow.io,Proxy\nDOMAIN-SUFFIX,javeu.com,Proxy\nDOMAIN-SUFFIX,mklegaladvice.com,Proxy\nDOMAIN-SUFFIX,www.scramble.nl,Proxy\nDOMAIN-SUFFIX,staging.cryptographyengineering.com,Proxy\nDOMAIN-SUFFIX,chengrense.com,Proxy\nDOMAIN-SUFFIX,nationsonline.org,Proxy\nDOMAIN-SUFFIX,soumo.info,Proxy\nDOMAIN-SUFFIX,kkvpn.com,Proxy\nDOMAIN-SUFFIX,umcbc.ca,Proxy\nDOMAIN-SUFFIX,www.bet1665bet.com,Proxy\nDOMAIN-SUFFIX,qq404.cf,Proxy\nDOMAIN-SUFFIX,mytalkbox.com,Proxy\nDOMAIN-SUFFIX,chinagate.com,Proxy\nDOMAIN-SUFFIX,online-anonymizer.com,Proxy\nDOMAIN-SUFFIX,tools.keycdn.com,Proxy\nDOMAIN-SUFFIX,hj5855.com,Proxy\nDOMAIN-SUFFIX,w2.tg333.net,Proxy\nDOMAIN-SUFFIX,cabletv.com.hk,Proxy\nDOMAIN-SUFFIX,softarchive.la,Proxy\nDOMAIN-SUFFIX,trombi.com,Proxy\nDOMAIN-SUFFIX,cdn.xn--b6gac.eu.org,Proxy\nDOMAIN-SUFFIX,asiabet168.com,Proxy\nDOMAIN-SUFFIX,gotgeeks.com,Proxy\nDOMAIN-SUFFIX,tamiaode.tk,Proxy\nDOMAIN-SUFFIX,wsjhk.com,Proxy\nDOMAIN-SUFFIX,elad.ca,Proxy\nDOMAIN-SUFFIX,xxx.com,Proxy\nDOMAIN-SUFFIX,www.publicproxyservers.com,Proxy\nDOMAIN-SUFFIX,paradisehill.tv,Proxy\nDOMAIN-SUFFIX,lefora.com,Proxy\nDOMAIN-SUFFIX,greengelato.ro,Proxy\nDOMAIN-SUFFIX,flog.tw,Proxy\nDOMAIN-SUFFIX,avlulu001.com,Proxy\nDOMAIN-SUFFIX,genmirror.com,Proxy\nDOMAIN-SUFFIX,byoutube.com,Proxy\nDOMAIN-SUFFIX,coinburn.org,Proxy\nDOMAIN-SUFFIX,liux.us,Proxy\nDOMAIN-SUFFIX,www.newsclick.in,Proxy\nDOMAIN-SUFFIX,www.fulao2.com,Proxy\nDOMAIN-SUFFIX,edns.biz,Proxy\nDOMAIN-SUFFIX,brandnewproxy.net,Proxy\nDOMAIN-SUFFIX,hhh337.net,Proxy\nDOMAIN-SUFFIX,hutianyi.net,Proxy\nDOMAIN-SUFFIX,home.life.cafe,Proxy\nDOMAIN-SUFFIX,www.mandurahmail.com.au,Proxy\nDOMAIN-SUFFIX,www.ju111.co,Proxy\nDOMAIN-SUFFIX,rateyourmusic.com,Proxy\nDOMAIN-SUFFIX,www.projectfreetv.ch,Proxy\nDOMAIN-SUFFIX,stepchina.com,Proxy\nDOMAIN-SUFFIX,tube8.es,Proxy\nDOMAIN-SUFFIX,ch5.cc,Proxy\nDOMAIN-SUFFIX,soportemdq.com.ar,Proxy\nDOMAIN-SUFFIX,3.32.ddns.name,Proxy\nDOMAIN-SUFFIX,d2l9pherk8j8b5.cloudfront.net,Proxy\nDOMAIN-SUFFIX,freebrowser.net,Proxy\nDOMAIN-SUFFIX,getsession.org,Proxy\nDOMAIN-SUFFIX,www.doubigjd.com,Proxy\nDOMAIN-SUFFIX,sspanel.net,Proxy\nDOMAIN-SUFFIX,code1984.com,Proxy\nDOMAIN-SUFFIX,pandia.njust.cf,Proxy\nDOMAIN-SUFFIX,www.courts.state.co.us,Proxy\nDOMAIN-SUFFIX,zlbqfj.cn,Proxy\nDOMAIN-SUFFIX,www.365616.com,Proxy\nDOMAIN-SUFFIX,deuxje7t39utb.cloudfront.net,Proxy\nDOMAIN-SUFFIX,mydati.com,Proxy\nDOMAIN-SUFFIX,foreignaffairs.com,Proxy\nDOMAIN-SUFFIX,2834762.jigsy.com,Proxy\nDOMAIN-SUFFIX,www.fxstreet.cn,Proxy\nDOMAIN-SUFFIX,sinocast.com,Proxy\nDOMAIN-SUFFIX,32red.com,Proxy\nDOMAIN-SUFFIX,pisosflotante.cl,Proxy\nDOMAIN-SUFFIX,www.nytec.org,Proxy\nDOMAIN-SUFFIX,011000001.com,Proxy\nDOMAIN-SUFFIX,dafiti.com.br,Proxy\nDOMAIN-SUFFIX,www.stammdvb.de,Proxy\nDOMAIN-SUFFIX,e-gold.com,Proxy\nDOMAIN-SUFFIX,b9113.com,Proxy\nDOMAIN-SUFFIX,falundafamuseum.org,Proxy\nDOMAIN-SUFFIX,pt2.org,Proxy\nDOMAIN-SUFFIX,711.nets.hk,Proxy\nDOMAIN-SUFFIX,www.fuliba.net,Proxy\nDOMAIN-SUFFIX,9kb.me,Proxy\nDOMAIN-SUFFIX,www.comparitech.com,Proxy\nDOMAIN-SUFFIX,shemalexxxporn.com,Proxy\nDOMAIN-SUFFIX,life.mingpao.com,Proxy\nDOMAIN-SUFFIX,hkcnews.com,Proxy\nDOMAIN-SUFFIX,beetouched-tw.shop.rakuten.tw,Proxy\nDOMAIN-SUFFIX,citylab.com,Proxy\nDOMAIN-SUFFIX,gamestorrents.com,Proxy\nDOMAIN-SUFFIX,www.sod.co.jp,Proxy\nDOMAIN-SUFFIX,www.asmr8.org,Proxy\nDOMAIN-SUFFIX,itaiwan.gov.tw,Proxy\nDOMAIN-SUFFIX,yzzk.com,Proxy\nDOMAIN-SUFFIX,www.gazeta-shqip.com,Proxy\nDOMAIN-SUFFIX,xxx-porn-fuck.com,Proxy\nDOMAIN-SUFFIX,aklist.xyz,Proxy\nDOMAIN-SUFFIX,levpn.com,Proxy\nDOMAIN-SUFFIX,www.pdci.it,Proxy\nDOMAIN-SUFFIX,www.laddervpn.com,Proxy\nDOMAIN-SUFFIX,porn-w.org,Proxy\nDOMAIN-SUFFIX,eromon.net,Proxy\nDOMAIN-SUFFIX,chinahush.com,Proxy\nDOMAIN-SUFFIX,xcw1111.com,Proxy\nDOMAIN-SUFFIX,www.38823388.com,Proxy\nDOMAIN-SUFFIX,dickdorm.com,Proxy\nDOMAIN-SUFFIX,dsn00.com,Proxy\nDOMAIN-SUFFIX,proxize.com,Proxy\nDOMAIN-SUFFIX,lt797.com,Proxy\nDOMAIN-SUFFIX,33.homeip.net,Proxy\nDOMAIN-SUFFIX,autodraw.com,Proxy\nDOMAIN-SUFFIX,www.techhi.com.tw,Proxy\nDOMAIN-SUFFIX,www.islamhouse.com,Proxy\nDOMAIN-SUFFIX,mouthshut.com,Proxy\nDOMAIN-SUFFIX,d1z9mvfm4pfq77.cloudfront.net,Proxy\nDOMAIN-SUFFIX,cc8166cc.com,Proxy\nDOMAIN-SUFFIX,bw1658.com,Proxy\nDOMAIN-SUFFIX,dermatolog-cluj.ro,Proxy\nDOMAIN-SUFFIX,blogs.libraryinformationtechnology.com,Proxy\nDOMAIN-SUFFIX,oktw.one,Proxy\nDOMAIN-SUFFIX,softfamous.com,Proxy\nDOMAIN-SUFFIX,we-cc3.xyz,Proxy\nDOMAIN-SUFFIX,mapi.udn.com,Proxy\nDOMAIN-SUFFIX,www.asialyst.com,Proxy\nDOMAIN-SUFFIX,goodnewsnetwork.org,Proxy\nDOMAIN-SUFFIX,www.efcloud.cc,Proxy\nDOMAIN-SUFFIX,tascn.com.au,Proxy\nDOMAIN-SUFFIX,cn.swissquote.com,Proxy\nDOMAIN-SUFFIX,cup.slyip.net,Proxy\nDOMAIN-SUFFIX,shellfire.de,Proxy\nDOMAIN-SUFFIX,yesterweb.org,Proxy\nDOMAIN-SUFFIX,yourko.org,Proxy\nDOMAIN-SUFFIX,podvpn9.com,Proxy\nDOMAIN-SUFFIX,18avx.com,Proxy\nDOMAIN-SUFFIX,550098.com,Proxy\nDOMAIN-SUFFIX,zoldhaz.ro,Proxy\nDOMAIN-SUFFIX,thatguywiththeglasses.com,Proxy\nDOMAIN-SUFFIX,op.com,Proxy\nDOMAIN-SUFFIX,tacc.cwb.gov.tw,Proxy\nDOMAIN-SUFFIX,www.sovpn.net,Proxy\nDOMAIN-SUFFIX,www.cellsystech.net,Proxy\nDOMAIN-SUFFIX,www.saintfish.com,Proxy\nDOMAIN-SUFFIX,xocat.com,Proxy\nDOMAIN-SUFFIX,sure.im,Proxy\nDOMAIN-SUFFIX,7pa95i4.impervadns.net,Proxy\nDOMAIN-SUFFIX,13youtube.com,Proxy\nDOMAIN-SUFFIX,www.hentai-foundry.com,Proxy\nDOMAIN-SUFFIX,8z1.net,Proxy\nDOMAIN-SUFFIX,www.deacons.com.hk,Proxy\nDOMAIN-SUFFIX,vps.id.lv,Proxy\nDOMAIN-SUFFIX,cdn-txweb.transifex.com,Proxy\nDOMAIN-SUFFIX,www.shouldianswer.com,Proxy\nDOMAIN-SUFFIX,us2.vpnme.me,Proxy\nDOMAIN-SUFFIX,www.ehornbill.com,Proxy\nDOMAIN-SUFFIX,twitgether.com,Proxy\nDOMAIN-SUFFIX,www.gfgold.com.hk,Proxy\nDOMAIN-SUFFIX,antiyoutube.com,Proxy\nDOMAIN-SUFFIX,tripcard.pages.dev,Proxy\nDOMAIN-SUFFIX,kmuh.org.tw,Proxy\nDOMAIN-SUFFIX,www.shineling-retreat.org,Proxy\nDOMAIN-SUFFIX,ca1lib.org,Proxy\nDOMAIN-SUFFIX,cf7.com,Proxy\nDOMAIN-SUFFIX,5maodang.com,Proxy\nDOMAIN-SUFFIX,sbf741.com,Proxy\nDOMAIN-SUFFIX,6366r.com,Proxy\nDOMAIN-SUFFIX,www.aboluowang.com,Proxy\nDOMAIN-SUFFIX,softether.org,Proxy\nDOMAIN-SUFFIX,macdonaldlaurier.ca,Proxy\nDOMAIN-SUFFIX,gonghao51.github.io,Proxy\nDOMAIN-SUFFIX,www.vpnworldwide.com,Proxy\nDOMAIN-SUFFIX,www.kiamaindependent.com.au,Proxy\nDOMAIN-SUFFIX,sex8.cc,Proxy\nDOMAIN-SUFFIX,freenet-china.org,Proxy\nDOMAIN-SUFFIX,h5.ld095.com,Proxy\nDOMAIN-SUFFIX,www.goseasbox.com,Proxy\nDOMAIN-SUFFIX,master-insight.com,Proxy\nDOMAIN-SUFFIX,689901133.com,Proxy\nDOMAIN-SUFFIX,store.diver-x.jp,Proxy\nDOMAIN-SUFFIX,wz555.com,Proxy\nDOMAIN-SUFFIX,csdparty.com,Proxy\nDOMAIN-SUFFIX,pazou.org,Proxy\nDOMAIN-SUFFIX,ftpserver.biz,Proxy\nDOMAIN-SUFFIX,www.wickedin.it,Proxy\nDOMAIN-SUFFIX,amws1122.com,Proxy\nDOMAIN-SUFFIX,unblockchina.org,Proxy\nDOMAIN-SUFFIX,dukascopy.com,Proxy\nDOMAIN-SUFFIX,x365x.com,Proxy\nDOMAIN-SUFFIX,youtubeproxy.org,Proxy\nDOMAIN-SUFFIX,www.ssrotume.com,Proxy\nDOMAIN-SUFFIX,emilylau.org.hk,Proxy\nDOMAIN-SUFFIX,thinkwithgoogle.com,Proxy\nDOMAIN-SUFFIX,beautiful.im,Proxy\nDOMAIN-SUFFIX,xj5859.com,Proxy\nDOMAIN-SUFFIX,www.inbeijing.se,Proxy\nDOMAIN-SUFFIX,research.jmsc.hku.hk,Proxy\nDOMAIN-SUFFIX,www.oba.org.tw,Proxy\nDOMAIN-SUFFIX,midland.com.hk,Proxy\nDOMAIN-SUFFIX,mypopescu.com,Proxy\nDOMAIN-SUFFIX,zillionk.com,Proxy\nDOMAIN-SUFFIX,21uscity.com,Proxy\nDOMAIN-SUFFIX,cn.happymarian.com,Proxy\nDOMAIN-SUFFIX,rfaweb.org,Proxy\nDOMAIN-SUFFIX,macau-explorer-cultural-travel.business.site,Proxy\nDOMAIN-SUFFIX,albanyktc.org,Proxy\nDOMAIN-SUFFIX,tibettruth.com,Proxy\nDOMAIN-SUFFIX,console.api.ai,Proxy\nDOMAIN-SUFFIX,navient.in,Proxy\nDOMAIN-SUFFIX,s0017.com,Proxy\nDOMAIN-SUFFIX,veja.com.br,Proxy\nDOMAIN-SUFFIX,livehdcams.com,Proxy\nDOMAIN-SUFFIX,hiwifi.com,Proxy\nDOMAIN-SUFFIX,ctotw.tw,Proxy\nDOMAIN-SUFFIX,lyfhk.net,Proxy\nDOMAIN-SUFFIX,zhina.wiki,Proxy\nDOMAIN-SUFFIX,app.cloudcone.com,Proxy\nDOMAIN-SUFFIX,mms333.ga,Proxy\nDOMAIN-SUFFIX,www.1919gogo.com,Proxy\nDOMAIN-SUFFIX,chinabooksreview.com,Proxy\nDOMAIN-SUFFIX,www.sxx.com,Proxy\nDOMAIN-SUFFIX,c.holmesmind.com,Proxy\nDOMAIN-SUFFIX,kagyunews.com.hk,Proxy\nDOMAIN-SUFFIX,catholic.org.hk,Proxy\nDOMAIN-SUFFIX,augustgermar.com,Proxy\nDOMAIN-SUFFIX,sstmlt.com,Proxy\nDOMAIN-SUFFIX,mup.gov.hr,Proxy\nDOMAIN-SUFFIX,hk-pic1.xyz,Proxy\nDOMAIN-SUFFIX,submit.jotform.us,Proxy\nDOMAIN-SUFFIX,at.laborinfocn2.com,Proxy\nDOMAIN-SUFFIX,cinemex.com,Proxy\nDOMAIN-SUFFIX,md233.com,Proxy\nDOMAIN-SUFFIX,www.rationalwiki.com,Proxy\nDOMAIN-SUFFIX,youngpornvideos.com,Proxy\nDOMAIN-SUFFIX,zhgpl.com,Proxy\nDOMAIN-SUFFIX,doh.westus.pi-dns.com,Proxy\nDOMAIN-SUFFIX,www.clevelandzen.org,Proxy\nDOMAIN-SUFFIX,www.okinawatimes.co.jp,Proxy\nDOMAIN-SUFFIX,sp.m.jiji.com,Proxy\nDOMAIN-SUFFIX,123.effers.com,Proxy\nDOMAIN-SUFFIX,tripadvisor.es,Proxy\nDOMAIN-SUFFIX,redian.news,Proxy\nDOMAIN-SUFFIX,www.sstuan.net,Proxy\nDOMAIN-SUFFIX,77772557.com,Proxy\nDOMAIN-SUFFIX,www.msbet888.com,Proxy\nDOMAIN-SUFFIX,paopao8.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,web2project.net,Proxy\nDOMAIN-SUFFIX,www.tagesthemen.de,Proxy\nDOMAIN-SUFFIX,appsto.re,Proxy\nDOMAIN-SUFFIX,ditu.gdgdocs.org,Proxy\nDOMAIN-SUFFIX,bi-si.xyz,Proxy\nDOMAIN-SUFFIX,tibet-aid.org,Proxy\nDOMAIN-SUFFIX,isuntv.com,Proxy\nDOMAIN-SUFFIX,d1z269x44ovtxp.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.chode.com,Proxy\nDOMAIN-SUFFIX,6i7mwo7.x.incapdns.net,Proxy\nDOMAIN-SUFFIX,chinesehope.tv,Proxy\nDOMAIN-SUFFIX,jmcomic1.cafe,Proxy\nDOMAIN-SUFFIX,kendincos.net,Proxy\nDOMAIN-SUFFIX,actfortibet.org,Proxy\nDOMAIN-SUFFIX,starcom.pro,Proxy\nDOMAIN-SUFFIX,twitter.jp,Proxy\nDOMAIN-SUFFIX,pressreader.com,Proxy\nDOMAIN-SUFFIX,bbs.juyuange.org,Proxy\nDOMAIN-SUFFIX,jacklockwood.net,Proxy\nDOMAIN-SUFFIX,b-ok.cc,Proxy\nDOMAIN-SUFFIX,zhshi.win,Proxy\nDOMAIN-SUFFIX,www.utusan.com.my,Proxy\nDOMAIN-SUFFIX,riku.me,Proxy\nDOMAIN-SUFFIX,institut-numerique.org,Proxy\nDOMAIN-SUFFIX,t3.shwchurch.org,Proxy\nDOMAIN-SUFFIX,franklc.com,Proxy\nDOMAIN-SUFFIX,komodojantan.com,Proxy\nDOMAIN-SUFFIX,applovin.com,Proxy\nDOMAIN-SUFFIX,d27yacd48fd8pu.cloudfront.net,Proxy\nDOMAIN-SUFFIX,hayatnuri.app,Proxy\nDOMAIN-SUFFIX,bcmorning.com,Proxy\nDOMAIN-SUFFIX,www.lineinchina.com,Proxy\nDOMAIN-SUFFIX,cwsglobal.org,Proxy\nDOMAIN-SUFFIX,gw1275.wixsite.com,Proxy\nDOMAIN-SUFFIX,atnext.com,Proxy\nDOMAIN-SUFFIX,rmb.li,Proxy\nDOMAIN-SUFFIX,wh.domain888.pw,Proxy\nDOMAIN-SUFFIX,99k.dns-dns.com,Proxy\nDOMAIN-SUFFIX,toutiaoabc.com,Proxy\nDOMAIN-SUFFIX,ts5278.tv,Proxy\nDOMAIN-SUFFIX,www.menupapa.com,Proxy\nDOMAIN-SUFFIX,timsah.com,Proxy\nDOMAIN-SUFFIX,www.rnz.de,Proxy\nDOMAIN-SUFFIX,ghettotube.com,Proxy\nDOMAIN-SUFFIX,xmovies.com,Proxy\nDOMAIN-SUFFIX,coat.co.jp,Proxy\nDOMAIN-SUFFIX,depositfiles.com,Proxy\nDOMAIN-SUFFIX,telegramdownload.com,Proxy\nDOMAIN-SUFFIX,xxxhdd.com,Proxy\nDOMAIN-SUFFIX,cikepal06.blogspot.hk,Proxy\nDOMAIN-SUFFIX,www.netjapan.eu,Proxy\nDOMAIN-SUFFIX,bestchange.ru,Proxy\nDOMAIN-SUFFIX,xu.freepac.pw,Proxy\nDOMAIN-SUFFIX,www.clipfish.com,Proxy\nDOMAIN-SUFFIX,iqq2.work,Proxy\nDOMAIN-SUFFIX,wlfdroc.org.tw,Proxy\nDOMAIN-SUFFIX,greatestherbsonearth.com,Proxy\nDOMAIN-SUFFIX,wanyi888.com,Proxy\nDOMAIN-SUFFIX,ahnsahnghong.com,Proxy\nDOMAIN-SUFFIX,design.google,Proxy\nDOMAIN-SUFFIX,www.dyvip699.com,Proxy\nDOMAIN-SUFFIX,85.slyip.com,Proxy\nDOMAIN-SUFFIX,openervpn.in,Proxy\nDOMAIN-SUFFIX,affiliate.sss999888.com,Proxy\nDOMAIN-SUFFIX,mail.jwpub.org,Proxy\nDOMAIN-SUFFIX,leisurepro.com,Proxy\nDOMAIN-SUFFIX,deaftone.com,Proxy\nDOMAIN-SUFFIX,voa-lh.akamaihd.net,Proxy\nDOMAIN-SUFFIX,sitaci.com,Proxy\nDOMAIN-SUFFIX,www.hoki8bet.com,Proxy\nDOMAIN-SUFFIX,sexy-word.com,Proxy\nDOMAIN-SUFFIX,kanepress.com,Proxy\nDOMAIN-SUFFIX,maa1805.com,Proxy\nDOMAIN-SUFFIX,duck.com,Proxy\nDOMAIN-SUFFIX,twtradition.akamaized.net,Proxy\nDOMAIN-SUFFIX,mhelpdesk.com,Proxy\nDOMAIN-SUFFIX,wtleungco.com,Proxy\nDOMAIN-SUFFIX,google.com.gt,Proxy\nDOMAIN-SUFFIX,www.ptcff666.com,Proxy\nDOMAIN-SUFFIX,hkvwet.com,Proxy\nDOMAIN-SUFFIX,r.hunnur.com,Proxy\nDOMAIN-SUFFIX,from-wa.com,Proxy\nDOMAIN-SUFFIX,www.chara-ani.com,Proxy\nDOMAIN-SUFFIX,www.b9999.tw,Proxy\nDOMAIN-SUFFIX,www.3movs.com,Proxy\nDOMAIN-SUFFIX,dailymotion.cn,Proxy\nDOMAIN-SUFFIX,kh.f13.in,Proxy\nDOMAIN-SUFFIX,nzchinese.com,Proxy\nDOMAIN-SUFFIX,www.ethicalpsychology.com,Proxy\nDOMAIN-SUFFIX,bookshome.net,Proxy\nDOMAIN-SUFFIX,s3db.org,Proxy\nDOMAIN-SUFFIX,aebo.pt,Proxy\nDOMAIN-SUFFIX,twittertim.es,Proxy\nDOMAIN-SUFFIX,www.jtassetcompensation.com,Proxy\nDOMAIN-SUFFIX,proxydns.com,Proxy\nDOMAIN-SUFFIX,www.phototruth.net,Proxy\nDOMAIN-SUFFIX,44883885.com,Proxy\nDOMAIN-SUFFIX,vpnez.com,Proxy\nDOMAIN-SUFFIX,aryadeva.spb.ru,Proxy\nDOMAIN-SUFFIX,uymaarip.com,Proxy\nDOMAIN-SUFFIX,www.1125577.net,Proxy\nDOMAIN-SUFFIX,launchpad.proxy.ustclug.org,Proxy\nDOMAIN-SUFFIX,fullssh.com,Proxy\nDOMAIN-SUFFIX,nitter.services.woodland.cafe,Proxy\nDOMAIN-SUFFIX,templeinstitute.org,Proxy\nDOMAIN-SUFFIX,ucptt.com,Proxy\nDOMAIN-SUFFIX,sin.fat.flnet.org,Proxy\nDOMAIN-SUFFIX,guolicheng.cc,Proxy\nDOMAIN-SUFFIX,pururin.to,Proxy\nDOMAIN-SUFFIX,lighting.fuse.arup.com,Proxy\nDOMAIN-SUFFIX,bibeltv.de,Proxy\nDOMAIN-SUFFIX,www.b16.bet,Proxy\nDOMAIN-SUFFIX,www.metrodaily.com,Proxy\nDOMAIN-SUFFIX,global.ssl.fastly.net,Proxy\nDOMAIN-SUFFIX,www.dagen.no,Proxy\nDOMAIN-SUFFIX,b5968.com,Proxy\nDOMAIN-SUFFIX,remi.flamary.com,Proxy\nDOMAIN-SUFFIX,atomiccamel.com,Proxy\nDOMAIN-SUFFIX,simplechat-21e6a.firebaseio.com,Proxy\nDOMAIN-SUFFIX,reading.zhudehuifu.com,Proxy\nDOMAIN-SUFFIX,btspread.com,Proxy\nDOMAIN-SUFFIX,afr.com,Proxy\nDOMAIN-SUFFIX,vod.com,Proxy\nDOMAIN-SUFFIX,pullfolio.com,Proxy\nDOMAIN-SUFFIX,i999.site,Proxy\nDOMAIN-SUFFIX,sapikachu.net,Proxy\nDOMAIN-SUFFIX,www.po18.tw,Proxy\nDOMAIN-SUFFIX,chinadialogue.net,Proxy\nDOMAIN-SUFFIX,shinychan.com,Proxy\nDOMAIN-SUFFIX,radicalparty.org,Proxy\nDOMAIN-SUFFIX,perezhilton.com,Proxy\nDOMAIN-SUFFIX,hauntedorange.com,Proxy\nDOMAIN-SUFFIX,pewdiepie.com,Proxy\nDOMAIN-SUFFIX,falundafa.jp,Proxy\nDOMAIN-SUFFIX,gfbrowser.com,Proxy\nDOMAIN-SUFFIX,valpak.com,Proxy\nDOMAIN-SUFFIX,www.storetorrent.com,Proxy\nDOMAIN-SUFFIX,free-movie.be,Proxy\nDOMAIN-SUFFIX,openlanguage.com,Proxy\nDOMAIN-SUFFIX,www.cloudmedia.com,Proxy\nDOMAIN-SUFFIX,nemesis2.qx.net,Proxy\nDOMAIN-SUFFIX,quranforkids.org,Proxy\nDOMAIN-SUFFIX,ban365.com,Proxy\nDOMAIN-SUFFIX,inis.iaea.org,Proxy\nDOMAIN-SUFFIX,en.howbbs.com,Proxy\nDOMAIN-SUFFIX,www.ctwant.com,Proxy\nDOMAIN-SUFFIX,www.manager-magazin.de,Proxy\nDOMAIN-SUFFIX,26268888.com,Proxy\nDOMAIN-SUFFIX,bg789.com,Proxy\nDOMAIN-SUFFIX,sg5021.vip,Proxy\nDOMAIN-SUFFIX,pixiv.com,Proxy\nDOMAIN-SUFFIX,notabug.io,Proxy\nDOMAIN-SUFFIX,bumingbai.net,Proxy\nDOMAIN-SUFFIX,instagr.am,Proxy\nDOMAIN-SUFFIX,memos.idv.tw,Proxy\nDOMAIN-SUFFIX,health2.cc,Proxy\nDOMAIN-SUFFIX,feuchtefotzen.de,Proxy\nDOMAIN-SUFFIX,ddex.io,Proxy\nDOMAIN-SUFFIX,mxihan.xyz,Proxy\nDOMAIN-SUFFIX,www.businesstoday.com.tw,Proxy\nDOMAIN-SUFFIX,www.englishdaily626.com,Proxy\nDOMAIN-SUFFIX,www.pin2288.com,Proxy\nDOMAIN-SUFFIX,ketyi28.nguyenhoabinh.org,Proxy\nDOMAIN-SUFFIX,08099.com,Proxy\nDOMAIN-SUFFIX,friedmann.xyz,Proxy\nDOMAIN-SUFFIX,ziddu.com,Proxy\nDOMAIN-SUFFIX,falunaz.net,Proxy\nDOMAIN-SUFFIX,www.yingpianqu.com,Proxy\nDOMAIN-SUFFIX,javhub.me,Proxy\nDOMAIN-SUFFIX,pornocarioca.com,Proxy\nDOMAIN-SUFFIX,qidian.ca,Proxy\nDOMAIN-SUFFIX,jellyfishcapital.com,Proxy\nDOMAIN-SUFFIX,mypets.ws,Proxy\nDOMAIN-SUFFIX,bragg.com,Proxy\nDOMAIN-SUFFIX,thenational.scot,Proxy\nDOMAIN-SUFFIX,tails.net,Proxy\nDOMAIN-SUFFIX,unpo.org,Proxy\nDOMAIN-SUFFIX,xp.freepac.pw,Proxy\nDOMAIN-SUFFIX,sbvtdhamma.wixsite.com,Proxy\nDOMAIN-SUFFIX,programagol.cl,Proxy\nDOMAIN-SUFFIX,hcomicbook.com,Proxy\nDOMAIN-SUFFIX,www.echinanews.com.tw,Proxy\nDOMAIN-SUFFIX,webmail.akhwien.at,Proxy\nDOMAIN-SUFFIX,betak.net,Proxy\nDOMAIN-SUFFIX,mspcorporate.com,Proxy\nDOMAIN-SUFFIX,zero.dns0.eu,Proxy\nDOMAIN-SUFFIX,jiehua.cz,Proxy\nDOMAIN-SUFFIX,atishacentre.org.au,Proxy\nDOMAIN-SUFFIX,topologytravel.com,Proxy\nDOMAIN-SUFFIX,www.p888678.com,Proxy\nDOMAIN-SUFFIX,wuwei.ca,Proxy\nDOMAIN-SUFFIX,bonbonsex.com,Proxy\nDOMAIN-SUFFIX,ashevillainy.com,Proxy\nDOMAIN-SUFFIX,se-books.com,Proxy\nDOMAIN-SUFFIX,wi.wcar.us,Proxy\nDOMAIN-SUFFIX,u.cc.st,Proxy\nDOMAIN-SUFFIX,livedoor.jp,Proxy\nDOMAIN-SUFFIX,modernchinastudies.org,Proxy\nDOMAIN-SUFFIX,bodenwart.at,Proxy\nDOMAIN-SUFFIX,light-dark.net,Proxy\nDOMAIN-SUFFIX,binancezh.biz,Proxy\nDOMAIN-SUFFIX,www.holland.idv.tw,Proxy\nDOMAIN-SUFFIX,qqaccelerator.com,Proxy\nDOMAIN-SUFFIX,cbc.ca,Proxy\nDOMAIN-SUFFIX,5i01.com,Proxy\nDOMAIN-SUFFIX,gluckman.com,Proxy\nDOMAIN-SUFFIX,la-forum.org,Proxy\nDOMAIN-SUFFIX,whatbrowser.org,Proxy\nDOMAIN-SUFFIX,www.humanrights.com,Proxy\nDOMAIN-SUFFIX,news.cnyes.com,Proxy\nDOMAIN-SUFFIX,cartoonpornvideos.com,Proxy\nDOMAIN-SUFFIX,hidden-advent.org,Proxy\nDOMAIN-SUFFIX,w88info.com,Proxy\nDOMAIN-SUFFIX,luminatesec.com,Proxy\nDOMAIN-SUFFIX,syosetu.com,Proxy\nDOMAIN-SUFFIX,altavista.com,Proxy\nDOMAIN-SUFFIX,nitter.dark.fail,Proxy\nDOMAIN-SUFFIX,8868k31.com,Proxy\nDOMAIN-SUFFIX,www.rsf.fr,Proxy\nDOMAIN-SUFFIX,livedoor.blogimg.jp,Proxy\nDOMAIN-SUFFIX,apkhere.com,Proxy\nDOMAIN-SUFFIX,www.novipnoad.com,Proxy\nDOMAIN-SUFFIX,dq-gh.com,Proxy\nDOMAIN-SUFFIX,ifs.slyip.net,Proxy\nDOMAIN-SUFFIX,community.windy.com,Proxy\nDOMAIN-SUFFIX,www.saigao.me,Proxy\nDOMAIN-SUFFIX,xxxchurch.com,Proxy\nDOMAIN-SUFFIX,vox.instanthq.com,Proxy\nDOMAIN-SUFFIX,pvfb.org.nz,Proxy\nDOMAIN-SUFFIX,wexzp.com,Proxy\nDOMAIN-SUFFIX,phandroid.com,Proxy\nDOMAIN-SUFFIX,recovery.org.tw,Proxy\nDOMAIN-SUFFIX,dokumen.pub,Proxy\nDOMAIN-SUFFIX,www.ugo.com,Proxy\nDOMAIN-SUFFIX,iqlinkus.com,Proxy\nDOMAIN-SUFFIX,smashwords.com,Proxy\nDOMAIN-SUFFIX,sstmlt.moe,Proxy\nDOMAIN-SUFFIX,qbxs8.com,Proxy\nDOMAIN-SUFFIX,www.mp4ba.com,Proxy\nDOMAIN-SUFFIX,www.youss.org,Proxy\nDOMAIN-SUFFIX,d19ysv8o6fv16v.cloudfront.net,Proxy\nDOMAIN-SUFFIX,zb8988.com,Proxy\nDOMAIN-SUFFIX,www.skyportsystems.com,Proxy\nDOMAIN-SUFFIX,tradiio.com,Proxy\nDOMAIN-SUFFIX,af.mil,Proxy\nDOMAIN-SUFFIX,game88city.net,Proxy\nDOMAIN-SUFFIX,www.dcb68.com,Proxy\nDOMAIN-SUFFIX,lawyerpu.com,Proxy\nDOMAIN-SUFFIX,itsourceconsulting.com,Proxy\nDOMAIN-SUFFIX,porntvblog.com,Proxy\nDOMAIN-SUFFIX,safe.moe,Proxy\nDOMAIN-SUFFIX,oogate.com,Proxy\nDOMAIN-SUFFIX,yopqnw1.000webhostapp.com,Proxy\nDOMAIN-SUFFIX,www.visiontimes.com.au,Proxy\nDOMAIN-SUFFIX,doh.nl.ahadns.net,Proxy\nDOMAIN-SUFFIX,hwtime.6te.net,Proxy\nDOMAIN-SUFFIX,mm831.com,Proxy\nDOMAIN-SUFFIX,xn--mandelbr-6za.com,Proxy\nDOMAIN-SUFFIX,am1430.net,Proxy\nDOMAIN-SUFFIX,www.listvpn.net,Proxy\nDOMAIN-SUFFIX,yoyoav.org,Proxy\nDOMAIN-SUFFIX,18board.info,Proxy\nDOMAIN-SUFFIX,oeth.webcomm.com.tw,Proxy\nDOMAIN-SUFFIX,foguckyourself.com,Proxy\nDOMAIN-SUFFIX,synergyse.com,Proxy\nDOMAIN-SUFFIX,cokeconsolidated.com,Proxy\nDOMAIN-SUFFIX,liangyou.net,Proxy\nDOMAIN-SUFFIX,bitdownloader.com,Proxy\nDOMAIN-SUFFIX,christiantimes.org.hk,Proxy\nDOMAIN-SUFFIX,chushigangdrug.ch,Proxy\nDOMAIN-SUFFIX,www.reconquista.pt,Proxy\nDOMAIN-SUFFIX,0885299.com,Proxy\nDOMAIN-SUFFIX,nord-me.com,Proxy\nDOMAIN-SUFFIX,www.blakes.com,Proxy\nDOMAIN-SUFFIX,www.goodtvusa.tv,Proxy\nDOMAIN-SUFFIX,powertothepen.com,Proxy\nDOMAIN-SUFFIX,www.bennu-solar.com,Proxy\nDOMAIN-SUFFIX,www.twfhc.com.tw,Proxy\nDOMAIN-SUFFIX,btbtdy.com,Proxy\nDOMAIN-SUFFIX,you-get.org,Proxy\nDOMAIN-SUFFIX,teshe.glitch.me,Proxy\nDOMAIN-SUFFIX,734.com,Proxy\nDOMAIN-SUFFIX,perfect-privacy.com,Proxy\nDOMAIN-SUFFIX,dailymaverick.com,Proxy\nDOMAIN-SUFFIX,want-daily.com,Proxy\nDOMAIN-SUFFIX,arduino.cc,Proxy\nDOMAIN-SUFFIX,feministteacher.com,Proxy\nDOMAIN-SUFFIX,wlx.sowiki.net,Proxy\nDOMAIN-SUFFIX,shadowsocks5.com,Proxy\nDOMAIN-SUFFIX,d22cny1051ekp2.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.ntyou.cc,Proxy\nDOMAIN-SUFFIX,zootube365.com,Proxy\nDOMAIN-SUFFIX,googleblog.com,Proxy\nDOMAIN-SUFFIX,exoget.com,Proxy\nDOMAIN-SUFFIX,webmasters.ru,Proxy\nDOMAIN-SUFFIX,york.mba.global.prod.fastly.net,Proxy\nDOMAIN-SUFFIX,www.228.net.tw,Proxy\nDOMAIN-SUFFIX,videopediaworld.com,Proxy\nDOMAIN-SUFFIX,ovpn.net,Proxy\nDOMAIN-SUFFIX,scoreland.com,Proxy\nDOMAIN-SUFFIX,jameswong.sg,Proxy\nDOMAIN-SUFFIX,xxxy.info,Proxy\nDOMAIN-SUFFIX,tw.money.yahoo.com,Proxy\nDOMAIN-SUFFIX,twitterfeed.com,Proxy\nDOMAIN-SUFFIX,www.crabtree-evelyn.co.uk,Proxy\nDOMAIN-SUFFIX,gcmasia.com,Proxy\nDOMAIN-SUFFIX,news.siteintelgroup.com,Proxy\nDOMAIN-SUFFIX,kr.linz.host,Proxy\nDOMAIN-SUFFIX,yyhbet.com,Proxy\nDOMAIN-SUFFIX,i.pximg.net,Proxy\nDOMAIN-SUFFIX,forum.slime.com.tw,Proxy\nDOMAIN-SUFFIX,486486.com,Proxy\nDOMAIN-SUFFIX,crbug.com,Proxy\nDOMAIN-SUFFIX,xijinping.com,Proxy\nDOMAIN-SUFFIX,alephnullresearch.com,Proxy\nDOMAIN-SUFFIX,hstt.net,Proxy\nDOMAIN-SUFFIX,www.brickstuff.com,Proxy\nDOMAIN-SUFFIX,whentai.com,Proxy\nDOMAIN-SUFFIX,w88.com,Proxy\nDOMAIN-SUFFIX,freedomcollection.org,Proxy\nDOMAIN-SUFFIX,ggtxv.com,Proxy\nDOMAIN-SUFFIX,www.hot8.tv,Proxy\nDOMAIN-SUFFIX,tsdr.uspto.gov,Proxy\nDOMAIN-SUFFIX,d2w9qp2kn7udcg.cloudfront.net,Proxy\nDOMAIN-SUFFIX,bobalyworks.com,Proxy\nDOMAIN-SUFFIX,laogai.it,Proxy\nDOMAIN-SUFFIX,calendarz.com,Proxy\nDOMAIN-SUFFIX,dc7766.com,Proxy\nDOMAIN-SUFFIX,yuyanzq.com,Proxy\nDOMAIN-SUFFIX,sis001.com,Proxy\nDOMAIN-SUFFIX,bookofsex.com,Proxy\nDOMAIN-SUFFIX,cirosantilli.com,Proxy\nDOMAIN-SUFFIX,email.tomellington.com,Proxy\nDOMAIN-SUFFIX,dj7855.com,Proxy\nDOMAIN-SUFFIX,myspacecdn.com,Proxy\nDOMAIN-SUFFIX,xiaohexie.com,Proxy\nDOMAIN-SUFFIX,episcopalchurch.org.tw,Proxy\nDOMAIN-SUFFIX,longhair.hk,Proxy\nDOMAIN-SUFFIX,blogspot.co.il,Proxy\nDOMAIN-SUFFIX,twskype.com,Proxy\nDOMAIN-SUFFIX,wmfield.idv.tw,Proxy\nDOMAIN-SUFFIX,22707.mmavday.com,Proxy\nDOMAIN-SUFFIX,efan.app,Proxy\nDOMAIN-SUFFIX,ting2255.com,Proxy\nDOMAIN-SUFFIX,brightkite.com,Proxy\nDOMAIN-SUFFIX,studiodata.com.ar,Proxy\nDOMAIN-SUFFIX,musikipedia.dk,Proxy\nDOMAIN-SUFFIX,lrb.co.uk,Proxy\nDOMAIN-SUFFIX,jhalderm.com,Proxy\nDOMAIN-SUFFIX,mx.linkedin.com,Proxy\nDOMAIN-SUFFIX,securetunnel.com,Proxy\nDOMAIN-SUFFIX,www.people.com,Proxy\nDOMAIN-SUFFIX,91vaa.com,Proxy\nDOMAIN-SUFFIX,sb.188188188188b.com,Proxy\nDOMAIN-SUFFIX,bm80000.com,Proxy\nDOMAIN-SUFFIX,chaosmen.com,Proxy\nDOMAIN-SUFFIX,vpnmaster.co,Proxy\nDOMAIN-SUFFIX,unodedos.com,Proxy\nDOMAIN-SUFFIX,www.educationcity.com,Proxy\nDOMAIN-SUFFIX,acg18.us,Proxy\nDOMAIN-SUFFIX,mic9.com,Proxy\nDOMAIN-SUFFIX,dakaba.xyz,Proxy\nDOMAIN-SUFFIX,melasta.com,Proxy\nDOMAIN-SUFFIX,jihadology.net,Proxy\nDOMAIN-SUFFIX,www.toursforfun.com,Proxy\nDOMAIN-SUFFIX,metcn.com,Proxy\nDOMAIN-SUFFIX,waffle1999.com,Proxy\nDOMAIN-SUFFIX,iqq.one,Proxy\nDOMAIN-SUFFIX,7sco.me.b0ne.com,Proxy\nDOMAIN-SUFFIX,decentraland.org,Proxy\nDOMAIN-SUFFIX,anyi555.com,Proxy\nDOMAIN-SUFFIX,muzu.tv,Proxy\nDOMAIN-SUFFIX,iphonetaiwan.org,Proxy\nDOMAIN-SUFFIX,www.hj269.com,Proxy\nDOMAIN-SUFFIX,sgtsourcing.box.com,Proxy\nDOMAIN-SUFFIX,www.agemys.cc,Proxy\nDOMAIN-SUFFIX,qpt.anyirn.cn,Proxy\nDOMAIN-SUFFIX,jbl55.com,Proxy\nDOMAIN-SUFFIX,deviantart.com,Proxy\nDOMAIN-SUFFIX,javdove3.club,Proxy\nDOMAIN-SUFFIX,baytalmasadir.com,Proxy\nDOMAIN-SUFFIX,www.jvid.com,Proxy\nDOMAIN-SUFFIX,www.letu.life,Proxy\nDOMAIN-SUFFIX,ddd.po888.net,Proxy\nDOMAIN-SUFFIX,makzhou.warehouse333.com,Proxy\nDOMAIN-SUFFIX,cgst.edu,Proxy\nDOMAIN-SUFFIX,bcvpn.com,Proxy\nDOMAIN-SUFFIX,www.dnscrypt.org,Proxy\nDOMAIN-SUFFIX,freevpn.zone,Proxy\nDOMAIN-SUFFIX,www.nti.world.com,Proxy\nDOMAIN-SUFFIX,guojiteshe.org,Proxy\nDOMAIN-SUFFIX,www.bordermail.com.au,Proxy\nDOMAIN-SUFFIX,xxxpanda.com,Proxy\nDOMAIN-SUFFIX,miobt.com,Proxy\nDOMAIN-SUFFIX,tanhuawangluo.7958.com,Proxy\nDOMAIN-SUFFIX,google.co.ma,Proxy\nDOMAIN-SUFFIX,www.occrp.org,Proxy\nDOMAIN-SUFFIX,38.ddnsking.com,Proxy\nDOMAIN-SUFFIX,cde3.net,Proxy\nDOMAIN-SUFFIX,ipchameleon.com,Proxy\nDOMAIN-SUFFIX,mummy.com,Proxy\nDOMAIN-SUFFIX,marmaramalakates.gr,Proxy\nDOMAIN-SUFFIX,zhao-visualized.netlify.app,Proxy\nDOMAIN-SUFFIX,www.bloombergindexes.com,Proxy\nDOMAIN-SUFFIX,9p12.com,Proxy\nDOMAIN-SUFFIX,email.collegeplanning.com,Proxy\nDOMAIN-SUFFIX,washingtontibet.org,Proxy\nDOMAIN-SUFFIX,www.k7d.com,Proxy\nDOMAIN-SUFFIX,iwon88.com,Proxy\nDOMAIN-SUFFIX,minghui-a.org,Proxy\nDOMAIN-SUFFIX,klimat.cl,Proxy\nDOMAIN-SUFFIX,visibletweets.com,Proxy\nDOMAIN-SUFFIX,openleaks.org,Proxy\nDOMAIN-SUFFIX,rapidvpn.com,Proxy\nDOMAIN-SUFFIX,ww1.silent-screams.com,Proxy\nDOMAIN-SUFFIX,yyf.me,Proxy\nDOMAIN-SUFFIX,chodientu.vn,Proxy\nDOMAIN-SUFFIX,darpa.mil,Proxy\nDOMAIN-SUFFIX,www.yzc369.com,Proxy\nDOMAIN-SUFFIX,redhotlabs.com,Proxy\nDOMAIN-SUFFIX,domaintoday.com.au,Proxy\nDOMAIN-SUFFIX,ovt.com,Proxy\nDOMAIN-SUFFIX,www.camdenadvertiser.com.au,Proxy\nDOMAIN-SUFFIX,carmita-bonita.com,Proxy\nDOMAIN-SUFFIX,tuoshuidu.com,Proxy\nDOMAIN-SUFFIX,developertalk.de,Proxy\nDOMAIN-SUFFIX,burberry.com,Proxy\nDOMAIN-SUFFIX,stop-hate-crimes.com,Proxy\nDOMAIN-SUFFIX,www.inspirit1938.com.tw,Proxy\nDOMAIN-SUFFIX,xx36230u.com,Proxy\nDOMAIN-SUFFIX,buugaa.com,Proxy\nDOMAIN-SUFFIX,tiava.com,Proxy\nDOMAIN-SUFFIX,www.mapmyride.com,Proxy\nDOMAIN-SUFFIX,wi.64-b.it,Proxy\nDOMAIN-SUFFIX,25.inc.gs,Proxy\nDOMAIN-SUFFIX,www.indiegala.com,Proxy\nDOMAIN-SUFFIX,shinjiru.com.cn,Proxy\nDOMAIN-SUFFIX,tibetfund.org,Proxy\nDOMAIN-SUFFIX,bufalopedia.com,Proxy\nDOMAIN-SUFFIX,www.kproxy.com,Proxy\nDOMAIN-SUFFIX,dazdu2iuzl72b.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.da555.org,Proxy\nDOMAIN-SUFFIX,humanrightsfoundation.org,Proxy\nDOMAIN-SUFFIX,www.fun767.com,Proxy\nDOMAIN-SUFFIX,paperb.us,Proxy\nDOMAIN-SUFFIX,www.bbv-net.de,Proxy\nDOMAIN-SUFFIX,www.xsvc.xyz,Proxy\nDOMAIN-SUFFIX,messenger.yahoo.com,Proxy\nDOMAIN-SUFFIX,expertarom.ro,Proxy\nDOMAIN-SUFFIX,proxy4free.pl,Proxy\nDOMAIN-SUFFIX,www.cc161.com,Proxy\nDOMAIN-SUFFIX,google.com.tr,Proxy\nDOMAIN-SUFFIX,buyu356.com,Proxy\nDOMAIN-SUFFIX,jy202.com,Proxy\nDOMAIN-SUFFIX,www.xiuren.org,Proxy\nDOMAIN-SUFFIX,api.dmc.nico,Proxy\nDOMAIN-SUFFIX,yuanzone.no-ip.net,Proxy\nDOMAIN-SUFFIX,1901999.com,Proxy\nDOMAIN-SUFFIX,ifschool.nuk.edu.tw,Proxy\nDOMAIN-SUFFIX,ero-video.net,Proxy\nDOMAIN-SUFFIX,global.bing.com,Proxy\nDOMAIN-SUFFIX,hdtube.porn,Proxy\nDOMAIN-SUFFIX,fanqiang.network,Proxy\nDOMAIN-SUFFIX,00899k.com,Proxy\nDOMAIN-SUFFIX,archive.4plebs.org,Proxy\nDOMAIN-SUFFIX,api.dropboxapi.com,Proxy\nDOMAIN-SUFFIX,www.dubaichronicle.com,Proxy\nDOMAIN-SUFFIX,495.ddnsking.com,Proxy\nDOMAIN-SUFFIX,mail.pon.com,Proxy\nDOMAIN-SUFFIX,fotile.me,Proxy\nDOMAIN-SUFFIX,www.16sihu.com,Proxy\nDOMAIN-SUFFIX,v66612.com,Proxy\nDOMAIN-SUFFIX,cn3.rti.tw,Proxy\nDOMAIN-SUFFIX,xam39999.com,Proxy\nDOMAIN-SUFFIX,www.torrentz.com,Proxy\nDOMAIN-SUFFIX,www.s-cute.com,Proxy\nDOMAIN-SUFFIX,888diao.com,Proxy\nDOMAIN-SUFFIX,ytmp3.cc,Proxy\nDOMAIN-SUFFIX,corriere.it,Proxy\nDOMAIN-SUFFIX,chelseaherbert.com,Proxy\nDOMAIN-SUFFIX,chesta.com,Proxy\nDOMAIN-SUFFIX,tiananmenmother.org,Proxy\nDOMAIN-SUFFIX,mynaughtymassage.com,Proxy\nDOMAIN-SUFFIX,erodoujinworld.com,Proxy\nDOMAIN-SUFFIX,reallifecam.com,Proxy\nDOMAIN-SUFFIX,c.ai,Proxy\nDOMAIN-SUFFIX,0235kk.com,Proxy\nDOMAIN-SUFFIX,atriumesoteric.org,Proxy\nDOMAIN-SUFFIX,doh-de.blahdns.com,Proxy\nDOMAIN-SUFFIX,wh.freepac.pw,Proxy\nDOMAIN-SUFFIX,netdb.i2p2.no,Proxy\nDOMAIN-SUFFIX,douglaslander.com,Proxy\nDOMAIN-SUFFIX,www.mdc.idv.tw,Proxy\nDOMAIN-SUFFIX,tafm.org,Proxy\nDOMAIN-SUFFIX,isa-hockeynut.com,Proxy\nDOMAIN-SUFFIX,utah.gov,Proxy\nDOMAIN-SUFFIX,inistagram.com,Proxy\nDOMAIN-SUFFIX,javtorrent.re,Proxy\nDOMAIN-SUFFIX,www.belfercenter.org,Proxy\nDOMAIN-SUFFIX,defendthe.us,Proxy\nDOMAIN-SUFFIX,etaiwannews.com,Proxy\nDOMAIN-SUFFIX,b2.b0ne.com,Proxy\nDOMAIN-SUFFIX,www.scckc.org.hk,Proxy\nDOMAIN-SUFFIX,buddhismnow.com,Proxy\nDOMAIN-SUFFIX,jma.go.jp,Proxy\nDOMAIN-SUFFIX,www.cten.com.tw,Proxy\nDOMAIN-SUFFIX,wheelpics.com,Proxy\nDOMAIN-SUFFIX,m.leduo111.com,Proxy\nDOMAIN-SUFFIX,dnshttp.xyz,Proxy\nDOMAIN-SUFFIX,us-desktop-premium.zenmateuser.com,Proxy\nDOMAIN-SUFFIX,www.cari.com.my,Proxy\nDOMAIN-SUFFIX,733bm.com,Proxy\nDOMAIN-SUFFIX,npsboost.com,Proxy\nDOMAIN-SUFFIX,dd29phatc5jr3.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.lockout.com.tw,Proxy\nDOMAIN-SUFFIX,nm.sex787.com,Proxy\nDOMAIN-SUFFIX,oppc.tk,Proxy\nDOMAIN-SUFFIX,theguardian.co,Proxy\nDOMAIN-SUFFIX,my.keso.cn,Proxy\nDOMAIN-SUFFIX,www.ssrxxjc.com,Proxy\nDOMAIN-SUFFIX,www.gdgdocs.org,Proxy\nDOMAIN-SUFFIX,proxysites.net,Proxy\nDOMAIN-SUFFIX,dalailama.usc.edu,Proxy\nDOMAIN-SUFFIX,phimvideo.org,Proxy\nDOMAIN-SUFFIX,nytimes.map.fastly.net,Proxy\nDOMAIN-SUFFIX,av-adult.com,Proxy\nDOMAIN-SUFFIX,999.aoke66.com,Proxy\nDOMAIN-SUFFIX,3434.com,Proxy\nDOMAIN-SUFFIX,004vic.com,Proxy\nDOMAIN-SUFFIX,66066e.com,Proxy\nDOMAIN-SUFFIX,thaichix.com,Proxy\nDOMAIN-SUFFIX,18av.91xxmm.com,Proxy\nDOMAIN-SUFFIX,www.istock.com,Proxy\nDOMAIN-SUFFIX,s99bet.com,Proxy\nDOMAIN-SUFFIX,li822.com,Proxy\nDOMAIN-SUFFIX,www.unicornblog.cn,Proxy\nDOMAIN-SUFFIX,blogger.googleblog.com,Proxy\nDOMAIN-SUFFIX,www.itiger.com,Proxy\nDOMAIN-SUFFIX,cyberia.is,Proxy\nDOMAIN-SUFFIX,paulgo.io,Proxy\nDOMAIN-SUFFIX,skyvegas.com,Proxy\nDOMAIN-SUFFIX,enjoytrader89.com,Proxy\nDOMAIN-SUFFIX,nybooks.com,Proxy\nDOMAIN-SUFFIX,px.mystakidis.gr,Proxy\nDOMAIN-SUFFIX,hj676.com,Proxy\nDOMAIN-SUFFIX,playssh.com,Proxy\nDOMAIN-SUFFIX,theinitium.com,Proxy\nDOMAIN-SUFFIX,garberi.cl,Proxy\nDOMAIN-SUFFIX,www.kaspersky.ru,Proxy\nDOMAIN-SUFFIX,mulher.net.br,Proxy\nDOMAIN-SUFFIX,55bet.com,Proxy\nDOMAIN-SUFFIX,pbs.org,Proxy\nDOMAIN-SUFFIX,yaoi.site,Proxy\nDOMAIN-SUFFIX,wen.ru,Proxy\nDOMAIN-SUFFIX,www.hibet.com,Proxy\nDOMAIN-SUFFIX,www.deluxevanity.com,Proxy\nDOMAIN-SUFFIX,rolsociety.org,Proxy\nDOMAIN-SUFFIX,easystore.co,Proxy\nDOMAIN-SUFFIX,h598.com,Proxy\nDOMAIN-SUFFIX,a-e-t.org,Proxy\nDOMAIN-SUFFIX,api.huobi.de.com,Proxy\nDOMAIN-SUFFIX,javdove9.club,Proxy\nIP-CIDR,72.52.81.22/32,Proxy\nDOMAIN-SUFFIX,hj233.com,Proxy\nDOMAIN-SUFFIX,v2ray.live,Proxy\nDOMAIN-SUFFIX,supjav.com,Proxy\nDOMAIN-SUFFIX,cv.ceuandalucia.es,Proxy\nDOMAIN-SUFFIX,savetibet.org,Proxy\nDOMAIN-SUFFIX,ultrasurfing.com,Proxy\nDOMAIN-SUFFIX,xmbs2.live,Proxy\nDOMAIN-SUFFIX,getipintel.net,Proxy\nDOMAIN-SUFFIX,liuhanyu.com,Proxy\nDOMAIN-SUFFIX,voncop.tk,Proxy\nDOMAIN-SUFFIX,www.katherinetimes.com.au,Proxy\nDOMAIN-SUFFIX,blog.meteor.com,Proxy\nDOMAIN-SUFFIX,anonymoussurf.us,Proxy\nDOMAIN-SUFFIX,www.youiv.com,Proxy\nDOMAIN-SUFFIX,giaiphapxanh.com,Proxy\nDOMAIN-SUFFIX,uxvpn.com,Proxy\nDOMAIN-SUFFIX,thehun.com,Proxy\nDOMAIN-SUFFIX,www.pentoy.hk,Proxy\nDOMAIN-SUFFIX,objektpapier.ch,Proxy\nDOMAIN-SUFFIX,d2s8qxo7hs115t.cloudfront.net,Proxy\nDOMAIN-SUFFIX,ip5008.co,Proxy\nDOMAIN-SUFFIX,mehrpress.com,Proxy\nDOMAIN-SUFFIX,3a5a.com,Proxy\nDOMAIN-SUFFIX,mpweekly.com,Proxy\nDOMAIN-SUFFIX,twstar.net,Proxy\nDOMAIN-SUFFIX,52hy88.com,Proxy\nDOMAIN-SUFFIX,www.steamedfish.org,Proxy\nDOMAIN-SUFFIX,mastodon.siliconfilter.com,Proxy\nDOMAIN-SUFFIX,www.library.ac.cn,Proxy\nDOMAIN-SUFFIX,danielriquelme.cl,Proxy\nDOMAIN-SUFFIX,m200260.com,Proxy\nDOMAIN-SUFFIX,kiedere.com.mx,Proxy\nDOMAIN-SUFFIX,wmsxwd999.men,Proxy\nDOMAIN-SUFFIX,gvm.com.tw,Proxy\nDOMAIN-SUFFIX,olcl.com,Proxy\nDOMAIN-SUFFIX,hkmshanghai.com,Proxy\nDOMAIN-SUFFIX,lzvpn.com,Proxy\nDOMAIN-SUFFIX,somee.com,Proxy\nDOMAIN-SUFFIX,5kc1.2256.eu.org,Proxy\nDOMAIN-SUFFIX,fixedfloat.com,Proxy\nDOMAIN-SUFFIX,me-gay.com,Proxy\nDOMAIN-SUFFIX,boundhub.com,Proxy\nDOMAIN-SUFFIX,nytimg.com,Proxy\nDOMAIN-SUFFIX,blog.netsarang.com,Proxy\nDOMAIN-SUFFIX,www.buddhism.blisswisdom.org,Proxy\nDOMAIN-SUFFIX,www.hycmcn.com,Proxy\nDOMAIN-SUFFIX,navpn.com,Proxy\nDOMAIN-SUFFIX,jmpdirect01.com,Proxy\nDOMAIN-SUFFIX,studylink.govt.nz,Proxy\nDOMAIN-SUFFIX,www.705244.com,Proxy\nDOMAIN-SUFFIX,www.voy.com,Proxy\nDOMAIN-SUFFIX,542.freegamepc.org,Proxy\nDOMAIN-SUFFIX,definebabe.com,Proxy\nDOMAIN-SUFFIX,istars.co.nz,Proxy\nDOMAIN-SUFFIX,sueddeutschezeitung.de,Proxy\nDOMAIN-SUFFIX,nanyang.com,Proxy\nDOMAIN-SUFFIX,adult.com,Proxy\nDOMAIN-SUFFIX,bfvip888.com,Proxy\nDOMAIN-SUFFIX,co568.com,Proxy\nDOMAIN-SUFFIX,bbs.soul-plus.net,Proxy\nDOMAIN-SUFFIX,bway88725.com,Proxy\nDOMAIN-SUFFIX,eeeeesile.com,Proxy\nDOMAIN-SUFFIX,dalailamaquotes.org,Proxy\nDOMAIN-SUFFIX,epochtimes.co.il,Proxy\nDOMAIN-SUFFIX,smith.edu,Proxy\nDOMAIN-SUFFIX,ite.wdd.idv.tw,Proxy\nDOMAIN-SUFFIX,bangchen.net,Proxy\nDOMAIN-SUFFIX,www.shengui666.com,Proxy\nDOMAIN-SUFFIX,www.novel101.com,Proxy\nDOMAIN-SUFFIX,mandiant.com,Proxy\nDOMAIN-SUFFIX,creativelab5.com,Proxy\nDOMAIN-SUFFIX,ffvpn.com,Proxy\nDOMAIN-SUFFIX,vpnia.com,Proxy\nDOMAIN-SUFFIX,basil.idv.tw,Proxy\nDOMAIN-SUFFIX,mathewossja.com,Proxy\nDOMAIN-SUFFIX,ms88333.com,Proxy\nDOMAIN-SUFFIX,www.590566.com,Proxy\nDOMAIN-SUFFIX,u15.info,Proxy\nDOMAIN-SUFFIX,suxzp.com,Proxy\nDOMAIN-SUFFIX,pj22.cc,Proxy\nDOMAIN-SUFFIX,wo.tc,Proxy\nDOMAIN-SUFFIX,hojemacau.com.mo,Proxy\nDOMAIN-SUFFIX,twoapp.com,Proxy\nDOMAIN-SUFFIX,hkpic-forum.com,Proxy\nDOMAIN-SUFFIX,albawaba.com,Proxy\nDOMAIN-SUFFIX,youtubeeducation.com,Proxy\nDOMAIN-SUFFIX,dlercloud.org,Proxy\nDOMAIN-SUFFIX,www.e8078.com,Proxy\nDOMAIN-SUFFIX,wdc00.com,Proxy\nDOMAIN-SUFFIX,vyohyke.fi,Proxy\nDOMAIN-SUFFIX,blinw.com,Proxy\nDOMAIN-SUFFIX,greatfirewallofchina.net,Proxy\nDOMAIN-SUFFIX,dioguitar23.me,Proxy\nDOMAIN-SUFFIX,google.by,Proxy\nDOMAIN-SUFFIX,hotladsworld.com,Proxy\nDOMAIN-SUFFIX,uyghuraa.org,Proxy\nDOMAIN-SUFFIX,18itv.com,Proxy\nDOMAIN-SUFFIX,kzqzb.com,Proxy\nDOMAIN-SUFFIX,hga.008.com,Proxy\nDOMAIN-SUFFIX,d1224lpo8z77xp.cloudfront.net,Proxy\nDOMAIN-SUFFIX,gruppuso.com,Proxy\nDOMAIN-SUFFIX,mywire.org,Proxy\nDOMAIN-SUFFIX,www.hkip.org.uk,Proxy\nDOMAIN-SUFFIX,prnptch.com,Proxy\nDOMAIN-SUFFIX,chinayouth.org.hk,Proxy\nDOMAIN-SUFFIX,rooseveltinstitute.org,Proxy\nDOMAIN-SUFFIX,mynetav.net,Proxy\nDOMAIN-SUFFIX,iqqtv.xyz,Proxy\nDOMAIN-SUFFIX,cn1lib.club,Proxy\nDOMAIN-SUFFIX,dtic.mil,Proxy\nDOMAIN-SUFFIX,petroconsult.my,Proxy\nDOMAIN-SUFFIX,hk-magazine.com,Proxy\nDOMAIN-SUFFIX,www.yd88n.com,Proxy\nDOMAIN-SUFFIX,youtobe.com,Proxy\nDOMAIN-SUFFIX,experianserasa.net,Proxy\nDOMAIN-SUFFIX,webrush.net,Proxy\nDOMAIN-SUFFIX,adult-sex-games.com,Proxy\nDOMAIN-SUFFIX,goosevpn.com,Proxy\nDOMAIN-SUFFIX,scmp.com,Proxy\nDOMAIN-SUFFIX,cache.qkdjj.com,Proxy\nDOMAIN-SUFFIX,searx.me,Proxy\nDOMAIN-SUFFIX,ss.agro.hk,Proxy\nDOMAIN-SUFFIX,www.uw78.com,Proxy\nDOMAIN-SUFFIX,plotioglobal-cn.com,Proxy\nDOMAIN-SUFFIX,vero.co,Proxy\nDOMAIN-SUFFIX,cpk222.com,Proxy\nDOMAIN-SUFFIX,ae.org,Proxy\nDOMAIN-SUFFIX,www.newtime.idv.tw,Proxy\nDOMAIN-SUFFIX,epochtim.es,Proxy\nDOMAIN-SUFFIX,www.deephentai.com,Proxy\nDOMAIN-SUFFIX,x777.co,Proxy\nDOMAIN-SUFFIX,wjbookny.com,Proxy\nDOMAIN-SUFFIX,cl.d0z.net,Proxy\nDOMAIN-SUFFIX,dmyoutube.com,Proxy\nDOMAIN-SUFFIX,cellulo.info,Proxy\nDOMAIN-SUFFIX,mysite.verizon.net,Proxy\nDOMAIN-SUFFIX,livescience.com,Proxy\nDOMAIN-SUFFIX,wmmail.ru,Proxy\nDOMAIN-SUFFIX,c.css5.pw,Proxy\nDOMAIN-SUFFIX,buddhism.kharkov.ua,Proxy\nDOMAIN-SUFFIX,roc-taiwan.org,Proxy\nDOMAIN-SUFFIX,thebobs.com,Proxy\nDOMAIN-SUFFIX,www.lejsq.net,Proxy\nDOMAIN-SUFFIX,clarkm.com,Proxy\nDOMAIN-SUFFIX,api-ws.rhysc.net,Proxy\nDOMAIN-SUFFIX,taiwannichigo.greater.jp,Proxy\nDOMAIN-SUFFIX,sabrari.ro,Proxy\nDOMAIN-SUFFIX,zora.co,Proxy\nDOMAIN-SUFFIX,jhakhang.com,Proxy\nDOMAIN-SUFFIX,www.99yh.com,Proxy\nDOMAIN-SUFFIX,www.ss-fast.net,Proxy\nDOMAIN-SUFFIX,pixia.com,Proxy\nDOMAIN-SUFFIX,www.bobbiandthestrays.org,Proxy\nDOMAIN-SUFFIX,twitbrowser.net,Proxy\nDOMAIN-SUFFIX,m.status.ws,Proxy\nDOMAIN-SUFFIX,metalhead.club,Proxy\nDOMAIN-SUFFIX,free8.com,Proxy\nDOMAIN-SUFFIX,www.39171122.com,Proxy\nDOMAIN-SUFFIX,dotunnel001.com,Proxy\nDOMAIN-SUFFIX,hubblotech.com,Proxy\nDOMAIN-SUFFIX,www.bookssd.com,Proxy\nDOMAIN-SUFFIX,dalailamaprotesters.info,Proxy\nDOMAIN-SUFFIX,dcard.tw,Proxy\nDOMAIN-SUFFIX,keontech.net,Proxy\nDOMAIN-SUFFIX,hidemycomp.com,Proxy\nDOMAIN-SUFFIX,newhighlandvision.com,Proxy\nDOMAIN-SUFFIX,gratisproxy.nl,Proxy\nDOMAIN-SUFFIX,youyun0.net,Proxy\nDOMAIN-SUFFIX,d3osdf9ihj16qb.cloudfront.net,Proxy\nDOMAIN-SUFFIX,media.discordapp.net,Proxy\nDOMAIN-SUFFIX,freedome.f-secure.com,Proxy\nDOMAIN-SUFFIX,www.36dm.com,Proxy\nDOMAIN-SUFFIX,k.3mon.xyz,Proxy\nDOMAIN-SUFFIX,fucked-tube.com,Proxy\nDOMAIN-SUFFIX,russianproxy.ru,Proxy\nDOMAIN-SUFFIX,am1h11.com,Proxy\nDOMAIN-SUFFIX,fuhuiyazhou.com,Proxy\nDOMAIN-SUFFIX,www.mnews.tw,Proxy\nDOMAIN-SUFFIX,bovpn.com,Proxy\nDOMAIN-SUFFIX,netflix.com,Proxy\nDOMAIN-SUFFIX,plaza.rakuten.co.jp,Proxy\nDOMAIN-SUFFIX,8587a.cc,Proxy\nDOMAIN-SUFFIX,d27vzj7laf5lcl.cloudfront.net,Proxy\nDOMAIN-SUFFIX,ky5545.com,Proxy\nDOMAIN-SUFFIX,www.ilovelongtoes.com,Proxy\nDOMAIN-SUFFIX,836ooo.net,Proxy\nDOMAIN-SUFFIX,cbseresults.nic.in,Proxy\nDOMAIN-SUFFIX,hkcah-np.blogspot.hk,Proxy\nDOMAIN-SUFFIX,lughot.blogspot.hk,Proxy\nDOMAIN-SUFFIX,www.muswellbrookchronicle.com.au,Proxy\nDOMAIN-SUFFIX,verizonwireless.com,Proxy\nDOMAIN-SUFFIX,eunited.com.my,Proxy\nDOMAIN-SUFFIX,www.watch4beauty.com,Proxy\nDOMAIN-SUFFIX,ourdearamy.com,Proxy\nDOMAIN-SUFFIX,youtubeunblocked.com,Proxy\nDOMAIN-SUFFIX,www.diarco.cl,Proxy\nDOMAIN-SUFFIX,sshocean.com,Proxy\nDOMAIN-SUFFIX,icwa.in,Proxy\nDOMAIN-SUFFIX,bearpost.org,Proxy\nDOMAIN-SUFFIX,www.metamuse.net,Proxy\nDOMAIN-SUFFIX,kopanmonastery.com,Proxy\nDOMAIN-SUFFIX,www.safasti.net,Proxy\nDOMAIN-SUFFIX,d2x67mfj6bj3l1.cloudfront.net,Proxy\nDOMAIN-SUFFIX,moegirl.xyz,Proxy\nDOMAIN-SUFFIX,zb8088.com,Proxy\nDOMAIN-SUFFIX,shuangtv.net,Proxy\nDOMAIN-SUFFIX,asianpornmovies.org,Proxy\nDOMAIN-SUFFIX,www.bitopro.com,Proxy\nDOMAIN-SUFFIX,ysb88cn.com,Proxy\nDOMAIN-SUFFIX,126.dtdns.net,Proxy\nDOMAIN-SUFFIX,hola.org,Proxy\nDOMAIN-SUFFIX,nikkisixx.net,Proxy\nDOMAIN-SUFFIX,rsf-chinese.org,Proxy\nDOMAIN-SUFFIX,www.thelallantop.com,Proxy\nDOMAIN-SUFFIX,680132.com,Proxy\nDOMAIN-SUFFIX,kuvia.eu,Proxy\nDOMAIN-SUFFIX,libcom.org,Proxy\nDOMAIN-SUFFIX,nine99.live,Proxy\nDOMAIN-SUFFIX,eesti.ee,Proxy\nDOMAIN-SUFFIX,reborn.kaochang.ltd,Proxy\nDOMAIN-SUFFIX,urchin.com,Proxy\nDOMAIN-SUFFIX,niconode.com,Proxy\nDOMAIN-SUFFIX,www.ghacks.net,Proxy\nDOMAIN-SUFFIX,v6ss.xyz,Proxy\nDOMAIN-SUFFIX,8-d.com,Proxy\nDOMAIN-SUFFIX,from-in.com,Proxy\nDOMAIN-SUFFIX,hkheadline.com,Proxy\nDOMAIN-SUFFIX,www.phuketwalk.com,Proxy\nDOMAIN-SUFFIX,kaskus.co.id,Proxy\nDOMAIN-SUFFIX,exdigital.xyz,Proxy\nDOMAIN-SUFFIX,www.powerpress.com,Proxy\nDOMAIN-SUFFIX,svip5888.com,Proxy\nDOMAIN-SUFFIX,config.getiantem.org,Proxy\nDOMAIN-SUFFIX,www.selectusconsulting.com,Proxy\nDOMAIN-SUFFIX,cadal.org,Proxy\nDOMAIN-SUFFIX,chinamz.org,Proxy\nDOMAIN-SUFFIX,www.carabinasypistolas.com,Proxy\nDOMAIN-SUFFIX,198qiu.com,Proxy\nDOMAIN-SUFFIX,astrumpeople.com,Proxy\nDOMAIN-SUFFIX,samair.ru,Proxy\nDOMAIN-SUFFIX,nanmuxuan.com,Proxy\nDOMAIN-SUFFIX,www.xmsite.site,Proxy\nDOMAIN-SUFFIX,catsoncrack.com,Proxy\nDOMAIN-SUFFIX,line.naver.jp,Proxy\nDOMAIN-SUFFIX,xian618.com,Proxy\nDOMAIN-SUFFIX,pegasusvpn.com,Proxy\nDOMAIN-SUFFIX,yiyechat.com,Proxy\nDOMAIN-SUFFIX,immorallive.com,Proxy\nDOMAIN-SUFFIX,austinforpresident.com.com,Proxy\nDOMAIN-SUFFIX,dns-unfiltered.adguard.com,Proxy\nDOMAIN-SUFFIX,settv.com.tw,Proxy\nDOMAIN-SUFFIX,img.ly,Proxy\nDOMAIN-SUFFIX,ninjaproxy.ninja,Proxy\nDOMAIN-SUFFIX,xing.com,Proxy\nDOMAIN-SUFFIX,vpnto.com,Proxy\nDOMAIN-SUFFIX,www.wikipedia.aust.cf,Proxy\nDOMAIN-SUFFIX,ofoxj.com,Proxy\nDOMAIN-SUFFIX,168kai.net,Proxy\nDOMAIN-SUFFIX,tronlink.org,Proxy\nDOMAIN-SUFFIX,appround.us,Proxy\nDOMAIN-SUFFIX,www.f88vip13.com,Proxy\nDOMAIN-SUFFIX,www.tiffanyarment.com,Proxy\nDOMAIN-SUFFIX,bbc4.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,hit3.cf,Proxy\nDOMAIN-SUFFIX,www.tweetmeme.com,Proxy\nDOMAIN-SUFFIX,m.pncle8.com,Proxy\nDOMAIN-SUFFIX,sxahz.com,Proxy\nDOMAIN-SUFFIX,paxex.aero,Proxy\nDOMAIN-SUFFIX,international-news.newsmagazine.asia,Proxy\nDOMAIN-SUFFIX,ehentai.org,Proxy\nDOMAIN-SUFFIX,wuguoguang.com,Proxy\nDOMAIN-SUFFIX,www.iset.com.tw,Proxy\nDOMAIN-SUFFIX,spizoo.com,Proxy\nDOMAIN-SUFFIX,www.minyu-net.com,Proxy\nDOMAIN-SUFFIX,fdc64.org,Proxy\nDOMAIN-SUFFIX,www.voanews.us,Proxy\nDOMAIN-SUFFIX,amakings.com,Proxy\nDOMAIN-SUFFIX,onmoon.net,Proxy\nDOMAIN-SUFFIX,google.no,Proxy\nDOMAIN-SUFFIX,www.yc6329.com,Proxy\nDOMAIN-SUFFIX,weekendhk.com,Proxy\nDOMAIN-SUFFIX,anonfiles.com,Proxy\nDOMAIN-SUFFIX,accountkit.com,Proxy\nDOMAIN-SUFFIX,twbbs.aboluowang.com,Proxy\nDOMAIN-SUFFIX,october-review.org,Proxy\nDOMAIN-SUFFIX,creativecloud.adobe.com,Proxy\nDOMAIN-SUFFIX,pharmacie-monge.fr,Proxy\nDOMAIN-SUFFIX,zoosex.cc,Proxy\nDOMAIN-SUFFIX,51499.com,Proxy\nDOMAIN-SUFFIX,pt88.vip,Proxy\nDOMAIN-SUFFIX,ramcity.com.au,Proxy\nDOMAIN-SUFFIX,vbet.com,Proxy\nDOMAIN-SUFFIX,www.streamnation.com,Proxy\nDOMAIN-SUFFIX,www.bbtv.site,Proxy\nDOMAIN-SUFFIX,www.itsover9000.com,Proxy\nDOMAIN-SUFFIX,h528.com,Proxy\nDOMAIN-SUFFIX,jinshagt88.com,Proxy\nDOMAIN-SUFFIX,authentic-campaigner.com,Proxy\nDOMAIN-SUFFIX,pryorda.net,Proxy\nDOMAIN-SUFFIX,www.chenjack.com,Proxy\nDOMAIN-SUFFIX,arweave.org,Proxy\nDOMAIN-SUFFIX,imagepost.com,Proxy\nDOMAIN-SUFFIX,50187.53xtv.com,Proxy\nDOMAIN-SUFFIX,frama.io,Proxy\nDOMAIN-SUFFIX,hongkong-s02-i02.cg-dialup.net,Proxy\nDOMAIN-SUFFIX,arlingtoncemetery.mil,Proxy\nDOMAIN-SUFFIX,music.amazon.com,Proxy\nDOMAIN-SUFFIX,blog.timshan.idv.tw,Proxy\nDOMAIN-SUFFIX,woam1350.com,Proxy\nDOMAIN-SUFFIX,fav.me,Proxy\nDOMAIN-SUFFIX,airav.life,Proxy\nDOMAIN-SUFFIX,newstatesman.com,Proxy\nDOMAIN-SUFFIX,ky61772.app,Proxy\nDOMAIN-SUFFIX,falundafa-florida.org,Proxy\nDOMAIN-SUFFIX,www.ssrshare.com,Proxy\nDOMAIN-SUFFIX,language.ws,Proxy\nDOMAIN-SUFFIX,hkpeanut.com,Proxy\nDOMAIN-SUFFIX,ganjingworld.com,Proxy\nDOMAIN-SUFFIX,stanford.io,Proxy\nDOMAIN-SUFFIX,www.lesker.com,Proxy\nDOMAIN-SUFFIX,www.lookatgame.ru,Proxy\nDOMAIN-SUFFIX,meax.net,Proxy\nDOMAIN-SUFFIX,strobeck.se,Proxy\nDOMAIN-SUFFIX,vns2004.com,Proxy\nDOMAIN-SUFFIX,waigaobu.com,Proxy\nDOMAIN-SUFFIX,www.thirdmovies.com,Proxy\nDOMAIN-SUFFIX,fevernet.com,Proxy\nDOMAIN-SUFFIX,www.moeacg.cc,Proxy\nDOMAIN-SUFFIX,lqqtv.net,Proxy\nDOMAIN-SUFFIX,pri4.fat.flnet.org,Proxy\nDOMAIN-SUFFIX,uu1234.pw,Proxy\nDOMAIN-SUFFIX,www.torrentkitty.tv,Proxy\nDOMAIN-SUFFIX,snapchat.com,Proxy\nDOMAIN-SUFFIX,mintable.app,Proxy\nDOMAIN-SUFFIX,eroticsaloon.net,Proxy\nDOMAIN-SUFFIX,auction.rakuten.co.jp,Proxy\nDOMAIN-SUFFIX,www.furnacemountainzen.org,Proxy\nDOMAIN-SUFFIX,anon.inf.tu-dresden.de,Proxy\nDOMAIN-SUFFIX,tiananmenuniv.net,Proxy\nDOMAIN-SUFFIX,www.e8833.com,Proxy\nDOMAIN-SUFFIX,www.fafa99.com,Proxy\nDOMAIN-SUFFIX,ba572.cq11.net,Proxy\nDOMAIN-SUFFIX,fritchy.com,Proxy\nDOMAIN-SUFFIX,222977.com,Proxy\nDOMAIN-SUFFIX,www.vixen.com,Proxy\nDOMAIN-SUFFIX,cnseqingwang.com,Proxy\nDOMAIN-SUFFIX,d1emgxxou2di91.cloudfront.net,Proxy\nDOMAIN-SUFFIX,bd953.com,Proxy\nDOMAIN-SUFFIX,theatlantic.com,Proxy\nDOMAIN-SUFFIX,mypornbible.com,Proxy\nDOMAIN-SUFFIX,www.js0505.com,Proxy\nDOMAIN-SUFFIX,clipfish.de,Proxy\nDOMAIN-SUFFIX,ooni.io,Proxy\nDOMAIN-SUFFIX,urbansurvival.com,Proxy\nDOMAIN-SUFFIX,maa03.fcxtv.site,Proxy\nDOMAIN-SUFFIX,cn42.ga,Proxy\nDOMAIN-SUFFIX,flushingcn.com,Proxy\nDOMAIN-SUFFIX,hczx33.com,Proxy\nDOMAIN-SUFFIX,www.dnaav.com,Proxy\nDOMAIN-SUFFIX,tsumino.com,Proxy\nDOMAIN-SUFFIX,51homes.ca,Proxy\nDOMAIN-SUFFIX,www.simplidoc.io,Proxy\nDOMAIN-SUFFIX,bg1239.com,Proxy\nDOMAIN-SUFFIX,www.proxypy.org,Proxy\nDOMAIN-SUFFIX,k6.7086bb.net,Proxy\nDOMAIN-SUFFIX,mdhspices.com,Proxy\nDOMAIN-SUFFIX,www.liaolainow.com,Proxy\nDOMAIN-SUFFIX,dc.com,Proxy\nDOMAIN-SUFFIX,vpnforchina.github.io,Proxy\nDOMAIN-SUFFIX,t.24mk.xyz,Proxy\nDOMAIN-SUFFIX,nul4.tax.flnet.org,Proxy\nDOMAIN-SUFFIX,epicquail.co.uk,Proxy\nDOMAIN-SUFFIX,www.hardcorepunishments.com,Proxy\nDOMAIN-SUFFIX,baidu.jp,Proxy\nDOMAIN-SUFFIX,fanguangxin.com,Proxy\nDOMAIN-SUFFIX,xh8999.com,Proxy\nDOMAIN-SUFFIX,blog.goo.ne.jp,Proxy\nDOMAIN-SUFFIX,lowlander.cl,Proxy\nDOMAIN-SUFFIX,simpletut.net,Proxy\nDOMAIN-SUFFIX,www.126688.com,Proxy\nDOMAIN-SUFFIX,zhenghui.org,Proxy\nDOMAIN-SUFFIX,270011v.com,Proxy\nDOMAIN-SUFFIX,youtube.at,Proxy\nDOMAIN-SUFFIX,x24hr.com,Proxy\nDOMAIN-SUFFIX,tpe.com,Proxy\nDOMAIN-SUFFIX,www.dyvip976.com,Proxy\nDOMAIN-SUFFIX,hkwcc.org.hk,Proxy\nDOMAIN-SUFFIX,whichphone.withgoogle.com,Proxy\nDOMAIN-SUFFIX,4632.2.36.3.ys.usoba.com,Proxy\nDOMAIN-SUFFIX,txappnet.com,Proxy\nDOMAIN-SUFFIX,ultimarkets.com,Proxy\nDOMAIN-SUFFIX,tibetnews.de,Proxy\nDOMAIN-SUFFIX,sinchew.com.my,Proxy\nDOMAIN-SUFFIX,sharefile.com,Proxy\nDOMAIN-SUFFIX,vpn123.com,Proxy\nDOMAIN-SUFFIX,crossclave.com,Proxy\nDOMAIN-SUFFIX,biggo.com.tw,Proxy\nDOMAIN-SUFFIX,cn.nytstyle.com,Proxy\nDOMAIN-SUFFIX,www.bookbao8.com,Proxy\nDOMAIN-SUFFIX,www.633.com,Proxy\nDOMAIN-SUFFIX,showwe.tw,Proxy\nDOMAIN-SUFFIX,caochangqing.com,Proxy\nDOMAIN-SUFFIX,asoch.cl,Proxy\nDOMAIN-SUFFIX,yazhouseba.com,Proxy\nDOMAIN-SUFFIX,nmsl.website,Proxy\nDOMAIN-SUFFIX,clubpremier.com,Proxy\nDOMAIN-SUFFIX,bbs.hasi.wang,Proxy\nDOMAIN-SUFFIX,833.microcycas.com,Proxy\nDOMAIN-SUFFIX,dfn.org,Proxy\nDOMAIN-SUFFIX,kb.monitorware.com,Proxy\nDOMAIN-SUFFIX,www.areca.com.tw,Proxy\nDOMAIN-SUFFIX,www.uyghurvoice.com,Proxy\nDOMAIN-SUFFIX,www.onlypost.com,Proxy\nDOMAIN-SUFFIX,h2.flnet.org,Proxy\nDOMAIN-SUFFIX,jla-takarakuji.or.jp,Proxy\nDOMAIN-SUFFIX,news.msn.com.tw,Proxy\nDOMAIN-SUFFIX,muslimmatters.org,Proxy\nDOMAIN-SUFFIX,youcaring.com,Proxy\nDOMAIN-SUFFIX,www.nick20.com,Proxy\nDOMAIN-SUFFIX,puredns.org,Proxy\nDOMAIN-SUFFIX,newmove.com,Proxy\nDOMAIN-SUFFIX,xkb.com.au,Proxy\nDOMAIN-SUFFIX,porntube24.com,Proxy\nDOMAIN-SUFFIX,bibox.com,Proxy\nDOMAIN-SUFFIX,cathnews.com,Proxy\nDOMAIN-SUFFIX,91.88mu.net,Proxy\nDOMAIN-SUFFIX,giganews.com,Proxy\nDOMAIN-SUFFIX,twitpic.com,Proxy\nDOMAIN-SUFFIX,xbsj7654.xyz,Proxy\nDOMAIN-SUFFIX,luke54.com,Proxy\nDOMAIN-SUFFIX,nrcdiscovery.com,Proxy\nDOMAIN-SUFFIX,fun5500.com,Proxy\nDOMAIN-SUFFIX,teepr.com,Proxy\nDOMAIN-SUFFIX,www.b713.net,Proxy\nDOMAIN-SUFFIX,aa.com.tr,Proxy\nDOMAIN-SUFFIX,job853.com,Proxy\nDOMAIN-SUFFIX,css5.ml,Proxy\nDOMAIN-SUFFIX,mp3wifie.com,Proxy\nDOMAIN-SUFFIX,www.cartoonmovement.com,Proxy\nDOMAIN-SUFFIX,lyricsmania.com,Proxy\nDOMAIN-SUFFIX,www.kmeiju.net,Proxy\nDOMAIN-SUFFIX,lordmarty.com,Proxy\nDOMAIN-SUFFIX,www.penguinrandomhouse.com,Proxy\nDOMAIN-SUFFIX,sinistracritica.org,Proxy\nDOMAIN-SUFFIX,berm.co.nz,Proxy\nDOMAIN-SUFFIX,ipcommission.org,Proxy\nDOMAIN-SUFFIX,www.lightningmaps.org,Proxy\nDOMAIN-SUFFIX,d6cswopzzvdu8.cloudfront.net,Proxy\nDOMAIN-SUFFIX,es.yahoo.com,Proxy\nDOMAIN-SUFFIX,youwin.com,Proxy\nDOMAIN-SUFFIX,facebook.hu,Proxy\nDOMAIN-SUFFIX,cn.rti.tw,Proxy\nDOMAIN-SUFFIX,fanswong.com,Proxy\nDOMAIN-SUFFIX,qq9741.com,Proxy\nDOMAIN-SUFFIX,power.com,Proxy\nDOMAIN-SUFFIX,dafiti.com.mx,Proxy\nDOMAIN-SUFFIX,www.thousandvideo.com,Proxy\nDOMAIN-SUFFIX,archbalt.org,Proxy\nDOMAIN-SUFFIX,www.mimemi.org,Proxy\nDOMAIN-SUFFIX,ubint.net,Proxy\nDOMAIN-SUFFIX,uygur.fc2web.com,Proxy\nDOMAIN-SUFFIX,163.flnet.org,Proxy\nDOMAIN-SUFFIX,sharky.co.uk,Proxy\nDOMAIN-SUFFIX,www.music-education-abroad.com,Proxy\nDOMAIN-SUFFIX,www.91300sc.com,Proxy\nDOMAIN-SUFFIX,fdc64.de,Proxy\nDOMAIN-SUFFIX,ldkrsi.blogspot.jp,Proxy\nDOMAIN-SUFFIX,mail.nyxus.com,Proxy\nDOMAIN-SUFFIX,www.wikipedia.nl,Proxy\nDOMAIN-SUFFIX,future-of-tibet.org,Proxy\nDOMAIN-SUFFIX,38853333.com,Proxy\nDOMAIN-SUFFIX,d1h4atp2pi0ddt.cloudfront.net,Proxy\nDOMAIN-SUFFIX,ourhobby.com,Proxy\nDOMAIN-SUFFIX,www.555dy.com,Proxy\nDOMAIN-SUFFIX,d3ov659vjlv5qc.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.mesubuta.net,Proxy\nDOMAIN-SUFFIX,read100.com,Proxy\nDOMAIN-SUFFIX,xiongmao.biz,Proxy\nDOMAIN-SUFFIX,www.52letou.com,Proxy\nDOMAIN-SUFFIX,yyy336.com,Proxy\nDOMAIN-SUFFIX,file-lounge.com,Proxy\nDOMAIN-SUFFIX,d3g2m135xim03j.cloudfront.net,Proxy\nDOMAIN-SUFFIX,ggav.co,Proxy\nDOMAIN-SUFFIX,0235zz.com,Proxy\nDOMAIN-SUFFIX,mycanadanow.com,Proxy\nDOMAIN-SUFFIX,88appxiazai.com,Proxy\nDOMAIN-SUFFIX,youtube.jp,Proxy\nDOMAIN-SUFFIX,www.cathayglory.com,Proxy\nDOMAIN-SUFFIX,freeyellow.com,Proxy\nDOMAIN-SUFFIX,www.kayako.com,Proxy\nDOMAIN-SUFFIX,44k44.cc,Proxy\nDOMAIN-SUFFIX,ntrfun.com,Proxy\nDOMAIN-SUFFIX,uyghuramerican.org,Proxy\nDOMAIN-SUFFIX,netpas.net,Proxy\nDOMAIN-SUFFIX,zoozle.net,Proxy\nDOMAIN-SUFFIX,caopeng.org,Proxy\nDOMAIN-SUFFIX,democracynow.org,Proxy\nDOMAIN-SUFFIX,www.font-face.com,Proxy\nDOMAIN-SUFFIX,galecsy.com,Proxy\nDOMAIN-SUFFIX,deli28.com,Proxy\nDOMAIN-SUFFIX,vuku.ru,Proxy\nDOMAIN-SUFFIX,bond-adventures.com,Proxy\nDOMAIN-SUFFIX,kucoin.com,Proxy\nDOMAIN-SUFFIX,www.chromeba.net,Proxy\nDOMAIN-SUFFIX,www.nzbesthealth.com,Proxy\nDOMAIN-SUFFIX,ssc.nic.in,Proxy\nDOMAIN-SUFFIX,h5galgame.com,Proxy\nDOMAIN-SUFFIX,betteryoutube.com,Proxy\nDOMAIN-SUFFIX,d2zykabwxz74e2.cloudfront.net,Proxy\nDOMAIN-SUFFIX,download.bluesprig.com,Proxy\nDOMAIN-SUFFIX,apetube.com,Proxy\nDOMAIN-SUFFIX,ip6855.com,Proxy\nDOMAIN-SUFFIX,civic.com,Proxy\nDOMAIN-SUFFIX,roupasjuninas.com,Proxy\nDOMAIN-SUFFIX,filedir.com,Proxy\nDOMAIN-SUFFIX,dr-wall.com,Proxy\nDOMAIN-SUFFIX,gayboystube.com,Proxy\nDOMAIN-SUFFIX,hornytrip.com,Proxy\nDOMAIN-SUFFIX,www.18xl.biz,Proxy\nDOMAIN-SUFFIX,lecloud.net,Proxy\nDOMAIN-SUFFIX,weeklystandard.com,Proxy\nDOMAIN-SUFFIX,nydn.us,Proxy\nDOMAIN-SUFFIX,www.ivacycn.com,Proxy\nDOMAIN-SUFFIX,seronline.com.br,Proxy\nDOMAIN-SUFFIX,is-a-teacher.com,Proxy\nDOMAIN-SUFFIX,www.90030su.com,Proxy\nDOMAIN-SUFFIX,alwaysvpn.com,Proxy\nDOMAIN-SUFFIX,www.zumodrive.com,Proxy\nDOMAIN-SUFFIX,drsunacademy.com,Proxy\nDOMAIN-SUFFIX,bloomberg.fr,Proxy\nDOMAIN-SUFFIX,941novel.com,Proxy\nDOMAIN-SUFFIX,www.ztunnel.com,Proxy\nDOMAIN-SUFFIX,directcreative.com,Proxy\nDOMAIN-SUFFIX,www.ftf.org,Proxy\nDOMAIN-SUFFIX,zhengjian.org,Proxy\nDOMAIN-SUFFIX,darknet.org.uk,Proxy\nDOMAIN-SUFFIX,tuberb.com,Proxy\nDOMAIN-SUFFIX,rqq.co,Proxy\nDOMAIN-SUFFIX,www.laodengchuanmei.com,Proxy\nDOMAIN-SUFFIX,propelrr.com,Proxy\nDOMAIN-SUFFIX,xlive.tv,Proxy\nDOMAIN-SUFFIX,8values.github.io,Proxy\nDOMAIN-SUFFIX,ptt.cc,Proxy\nDOMAIN-SUFFIX,weinixiong.cf,Proxy\nDOMAIN-SUFFIX,01.ffm.deu.ygg.yt,Proxy\nDOMAIN-SUFFIX,www.buddhism.dp.ua,Proxy\nDOMAIN-SUFFIX,www.fh-jituan.com,Proxy\nDOMAIN-SUFFIX,ub0.cc,Proxy\nDOMAIN-SUFFIX,cervetoria.pt,Proxy\nDOMAIN-SUFFIX,lemonparty.com,Proxy\nDOMAIN-SUFFIX,soundon.fm,Proxy\nDOMAIN-SUFFIX,dif9.lflink.com,Proxy\nDOMAIN-SUFFIX,www.vpnoneclick.com,Proxy\nDOMAIN-SUFFIX,maga.nz,Proxy\nDOMAIN-SUFFIX,bjl6777.com,Proxy\nDOMAIN-SUFFIX,indianrailways.gov.in,Proxy\nDOMAIN-SUFFIX,ddd836.net,Proxy\nDOMAIN-SUFFIX,sv.domain888.pw,Proxy\nDOMAIN-SUFFIX,toodoc.com,Proxy\nDOMAIN-SUFFIX,xgmyd.com,Proxy\nDOMAIN-SUFFIX,elpais.com,Proxy\nDOMAIN-SUFFIX,sorting-algorithms.com,Proxy\nDOMAIN-SUFFIX,www.arte.de,Proxy\nDOMAIN-SUFFIX,www.f88vip33.com,Proxy\nDOMAIN-SUFFIX,www.hkcities.com,Proxy\nDOMAIN-SUFFIX,d2wyl5qgfaffk1.cloudfront.net,Proxy\nDOMAIN-SUFFIX,tejaratnews.com,Proxy\nDOMAIN-SUFFIX,dailyfriend.co.za,Proxy\nDOMAIN-SUFFIX,www.google.lk,Proxy\nDOMAIN-SUFFIX,e8605.com,Proxy\nDOMAIN-SUFFIX,from-pr.com,Proxy\nDOMAIN-SUFFIX,goagent.biz,Proxy\nDOMAIN-SUFFIX,funu.club,Proxy\nDOMAIN-SUFFIX,asiatimes.com,Proxy\nDOMAIN-SUFFIX,kmdsew.deaftone.com,Proxy\nDOMAIN-SUFFIX,cn.bluepointleadership.com,Proxy\nDOMAIN-SUFFIX,hkcmi.edu,Proxy\nDOMAIN-SUFFIX,y68ss.com,Proxy\nDOMAIN-SUFFIX,www.macleayargus.com.au,Proxy\nDOMAIN-SUFFIX,weirlawyers.com,Proxy\nDOMAIN-SUFFIX,www.k886.net,Proxy\nDOMAIN-SUFFIX,m.cc777.com,Proxy\nDOMAIN-SUFFIX,www.drchen888.com,Proxy\nDOMAIN-SUFFIX,nstagram.com,Proxy\nDOMAIN-SUFFIX,daylife.com,Proxy\nDOMAIN-SUFFIX,bd107.com,Proxy\nDOMAIN-SUFFIX,yinlei.org,Proxy\nDOMAIN-SUFFIX,4444.net,Proxy\nDOMAIN-SUFFIX,www.newhavenzen.org,Proxy\nDOMAIN-SUFFIX,google.ag,Proxy\nDOMAIN-SUFFIX,www.k821.com,Proxy\nDOMAIN-SUFFIX,ny66.cc,Proxy\nDOMAIN-SUFFIX,seedboxes.cc,Proxy\nDOMAIN-SUFFIX,feeder.co,Proxy\nDOMAIN-SUFFIX,affsal365.com,Proxy\nDOMAIN-SUFFIX,scoopertino.com,Proxy\nDOMAIN-SUFFIX,loader.to,Proxy\nDOMAIN-SUFFIX,lamayeshe.com,Proxy\nDOMAIN-SUFFIX,ct.org.tw,Proxy\nDOMAIN-SUFFIX,eyny.com,Proxy\nDOMAIN-SUFFIX,dwarsxej7uvpt.cloudfront.net,Proxy\nDOMAIN-SUFFIX,ador.sg,Proxy\nDOMAIN-SUFFIX,www.tinydate.net,Proxy\nDOMAIN-SUFFIX,himalayan-foundation.org,Proxy\nDOMAIN-SUFFIX,kanui.com.br,Proxy\nDOMAIN-SUFFIX,www.hj1566.com,Proxy\nDOMAIN-SUFFIX,www.dylangauthier.com,Proxy\nDOMAIN-SUFFIX,punked.us,Proxy\nDOMAIN-SUFFIX,fanyue.info,Proxy\nDOMAIN-SUFFIX,dalailamany.org,Proxy\nDOMAIN-SUFFIX,zedo.com,Proxy\nDOMAIN-SUFFIX,h5.ld33.tv,Proxy\nDOMAIN-SUFFIX,globalcareimpact.org,Proxy\nDOMAIN-SUFFIX,feiniaoyun.life,Proxy\nDOMAIN-SUFFIX,pedgyal.org,Proxy\nDOMAIN-SUFFIX,d3t8jz6506hbdb.cloudfront.net,Proxy\nDOMAIN-SUFFIX,behance.com,Proxy\nDOMAIN-SUFFIX,www.freepressseries.co.uk,Proxy\nDOMAIN-SUFFIX,www.hornytrip.com,Proxy\nDOMAIN-SUFFIX,lipuman.com,Proxy\nDOMAIN-SUFFIX,www.empornium.is,Proxy\nDOMAIN-SUFFIX,ub66.com,Proxy\nDOMAIN-SUFFIX,fourface.nodesnoop.com,Proxy\nDOMAIN-SUFFIX,civilmedia.tw,Proxy\nDOMAIN-SUFFIX,www.discowax.com,Proxy\nDOMAIN-SUFFIX,www.metart.com,Proxy\nDOMAIN-SUFFIX,www.ijobio.com,Proxy\nDOMAIN-SUFFIX,www.f88vip23.com,Proxy\nDOMAIN-SUFFIX,zenmate.com,Proxy\nDOMAIN-SUFFIX,velolife.co.za,Proxy\nDOMAIN-SUFFIX,konami.jp,Proxy\nDOMAIN-SUFFIX,nikkan-spa.jp,Proxy\nDOMAIN-SUFFIX,hurgokbayrak.com,Proxy\nDOMAIN-SUFFIX,puffin.com,Proxy\nDOMAIN-SUFFIX,www.rhein-zeitung.de,Proxy\nDOMAIN-SUFFIX,revleft.com,Proxy\nDOMAIN-SUFFIX,steve.id.au,Proxy\nDOMAIN-SUFFIX,iphone4hongkong.com,Proxy\nDOMAIN-SUFFIX,netflav.com,Proxy\nDOMAIN-SUFFIX,cato.org,Proxy\nDOMAIN-SUFFIX,seoni.nic.in,Proxy\nDOMAIN-SUFFIX,inthecrack.com,Proxy\nDOMAIN-SUFFIX,jpattiz.com,Proxy\nDOMAIN-SUFFIX,www.gta-expert.it,Proxy\nDOMAIN-SUFFIX,imgur.com,Proxy\nDOMAIN-SUFFIX,www.yahaha.club,Proxy\nDOMAIN-SUFFIX,google.us,Proxy\nDOMAIN-SUFFIX,iav99.com,Proxy\nDOMAIN-SUFFIX,wwang.strikingly.com,Proxy\nDOMAIN-SUFFIX,uptodown.com,Proxy\nDOMAIN-SUFFIX,vv2069.pw,Proxy\nDOMAIN-SUFFIX,zh.foxtube.com,Proxy\nDOMAIN-SUFFIX,jbbbet.com,Proxy\nDOMAIN-SUFFIX,www.blogimg.jp,Proxy\nDOMAIN-SUFFIX,www.runox.net,Proxy\nDOMAIN-SUFFIX,goenglish.me,Proxy\nDOMAIN-SUFFIX,netalert.me,Proxy\nDOMAIN-SUFFIX,hetzner.com,Proxy\nDOMAIN-SUFFIX,s.mobileread.com,Proxy\nDOMAIN-SUFFIX,atyoutube.com,Proxy\nDOMAIN-SUFFIX,224888333.com,Proxy\nDOMAIN-SUFFIX,hgc.fat.flnet.org,Proxy\nDOMAIN-SUFFIX,z-lib.org,Proxy\nDOMAIN-SUFFIX,duckmylife.com,Proxy\nDOMAIN-SUFFIX,dc9966.com,Proxy\nDOMAIN-SUFFIX,rmjdw132.info,Proxy\nDOMAIN-SUFFIX,nifbeauty.com,Proxy\nDOMAIN-SUFFIX,yahoo.com.tw,Proxy\nDOMAIN-SUFFIX,dreamamateurs.com,Proxy\nDOMAIN-SUFFIX,smchbooks.com,Proxy\nDOMAIN-SUFFIX,wearechange.org,Proxy\nDOMAIN-SUFFIX,tibet-munich.de,Proxy\nDOMAIN-SUFFIX,hayvip.com,Proxy\nDOMAIN-SUFFIX,byb70.app,Proxy\nDOMAIN-SUFFIX,youpornteens.com,Proxy\nDOMAIN-SUFFIX,kyvpn.com,Proxy\nDOMAIN-SUFFIX,totheglory.im,Proxy\nDOMAIN-SUFFIX,www.georgesoros.com,Proxy\nDOMAIN-SUFFIX,worldvpn.net,Proxy\nDOMAIN-SUFFIX,mimivv.com,Proxy\nDOMAIN-SUFFIX,ndemiccreations.com,Proxy\nDOMAIN-SUFFIX,32.slyip.com,Proxy\nDOMAIN-SUFFIX,alqp14.com,Proxy\nDOMAIN-SUFFIX,tibet.org.za,Proxy\nDOMAIN-SUFFIX,zuo.la,Proxy\nDOMAIN-SUFFIX,sijihuisuo.club,Proxy\nDOMAIN-SUFFIX,www.hkppa.net,Proxy\nDOMAIN-SUFFIX,www.planetsuzy.org,Proxy\nDOMAIN-SUFFIX,uighur.narod.ru,Proxy\nDOMAIN-SUFFIX,quran.nu,Proxy\nDOMAIN-SUFFIX,www.freesafeip.com,Proxy\nDOMAIN-SUFFIX,modfetish.com,Proxy\nDOMAIN-SUFFIX,mychinamyhome.com,Proxy\nDOMAIN-SUFFIX,cryptoriem.com,Proxy\nDOMAIN-SUFFIX,4hedonism.com,Proxy\nDOMAIN-SUFFIX,manicur4ik.ru,Proxy\nDOMAIN-SUFFIX,sp.slyip.net,Proxy\nDOMAIN-SUFFIX,www.ygdy8.net,Proxy\nDOMAIN-SUFFIX,dc9977.com,Proxy\nDOMAIN-SUFFIX,flexlinex.com,Proxy\nDOMAIN-SUFFIX,buzzhand.net,Proxy\nDOMAIN-SUFFIX,d1tyqdysmirshx.cloudfront.net,Proxy\nDOMAIN-SUFFIX,sxxbl.org,Proxy\nDOMAIN-SUFFIX,lflink.com,Proxy\nDOMAIN-SUFFIX,www.fuqizy.com,Proxy\nDOMAIN-SUFFIX,www.huffingtonpost.jp,Proxy\nDOMAIN-SUFFIX,reddit.com,Proxy\nDOMAIN-SUFFIX,www.5lxtv.com,Proxy\nDOMAIN-SUFFIX,zh.vpnpros.com,Proxy\nDOMAIN-SUFFIX,www.hide-my-ip.com,Proxy\nDOMAIN-SUFFIX,dasoertliche.de,Proxy\nDOMAIN-SUFFIX,spacemakers.com,Proxy\nDOMAIN-SUFFIX,chinacheatsheets.com,Proxy\nDOMAIN-SUFFIX,73999.app,Proxy\nDOMAIN-SUFFIX,ifei.com.tw,Proxy\nDOMAIN-SUFFIX,longmusic.com,Proxy\nDOMAIN-SUFFIX,thenewslens.com,Proxy\nDOMAIN-SUFFIX,qpl.9960.com,Proxy\nDOMAIN-SUFFIX,38857766.com,Proxy\nDOMAIN-SUFFIX,google.co.id,Proxy\nDOMAIN-SUFFIX,jzplay.com,Proxy\nDOMAIN-SUFFIX,wniogeruguer.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,imo.im,Proxy\nDOMAIN-SUFFIX,snowlionpub.com,Proxy\nDOMAIN-SUFFIX,gen2.dns-dns.com,Proxy\nDOMAIN-SUFFIX,shenjiying004.jigsy.com,Proxy\nDOMAIN-SUFFIX,spdh.bar,Proxy\nDOMAIN-SUFFIX,quanben-xiaoshuo.com,Proxy\nDOMAIN-SUFFIX,1111bj.com,Proxy\nDOMAIN-SUFFIX,artpay.biz,Proxy\nDOMAIN-SUFFIX,shenjiying.jigsy.com,Proxy\nDOMAIN-SUFFIX,persecution.net,Proxy\nDOMAIN-SUFFIX,pornbase.org,Proxy\nDOMAIN-SUFFIX,www.institutmontaigne.org,Proxy\nDOMAIN-SUFFIX,www.dfctaiwan.org,Proxy\nDOMAIN-SUFFIX,dipes.com.np,Proxy\nDOMAIN-SUFFIX,india.conairgroup.com,Proxy\nDOMAIN-SUFFIX,d2jhcs4j6i12sz.cloudfront.net,Proxy\nDOMAIN-SUFFIX,av.labxi.com,Proxy\nDOMAIN-SUFFIX,jksp03.cc,Proxy\nDOMAIN-SUFFIX,18comic.pro,Proxy\nDOMAIN-SUFFIX,jcstreetmission.com,Proxy\nDOMAIN-SUFFIX,www.nqu.edu.tw,Proxy\nDOMAIN-SUFFIX,emanna.com,Proxy\nDOMAIN-SUFFIX,wp83.com,Proxy\nDOMAIN-SUFFIX,cnineu.com,Proxy\nDOMAIN-SUFFIX,photos.dailyme.com,Proxy\nDOMAIN-SUFFIX,nextmedia.com,Proxy\nDOMAIN-SUFFIX,bizhat.com,Proxy\nDOMAIN-SUFFIX,www.fnp.de,Proxy\nDOMAIN-SUFFIX,www.nineforbrands.com.au,Proxy\nDOMAIN-SUFFIX,ifsa-butler.org,Proxy\nDOMAIN-SUFFIX,d2zfkvdgbai6l1.cloudfront.net,Proxy\nDOMAIN-SUFFIX,google.ee,Proxy\nDOMAIN-SUFFIX,jimdo.com,Proxy\nDOMAIN-SUFFIX,zyzc9.com,Proxy\nDOMAIN-SUFFIX,7067f.com,Proxy\nDOMAIN-SUFFIX,sosv.com,Proxy\nDOMAIN-SUFFIX,dns.aquilenet.fr,Proxy\nDOMAIN-SUFFIX,www.medworxx.com,Proxy\nDOMAIN-SUFFIX,tofo.me,Proxy\nDOMAIN-SUFFIX,am357.com,Proxy\nDOMAIN-SUFFIX,www.publicvpn.com,Proxy\nDOMAIN-SUFFIX,latinwildparties.com,Proxy\nDOMAIN-SUFFIX,elite-magazine.com,Proxy\nDOMAIN-SUFFIX,domains.google,Proxy\nDOMAIN-SUFFIX,hub.fastgit.org,Proxy\nDOMAIN-SUFFIX,www.gvm.com.tw,Proxy\nDOMAIN-SUFFIX,dajiyuan.com,Proxy\nDOMAIN-SUFFIX,file.gdaily.org,Proxy\nDOMAIN-SUFFIX,www.blpcareers.com,Proxy\nDOMAIN-SUFFIX,www.wionews.com,Proxy\nDOMAIN-SUFFIX,mail.ihg.com,Proxy\nDOMAIN-SUFFIX,oversea.istarshine.com,Proxy\nDOMAIN-SUFFIX,who.int,Proxy\nDOMAIN-SUFFIX,d1o8fblspbo6zh.cloudfront.net,Proxy\nDOMAIN-SUFFIX,quickpornsearch.com,Proxy\nDOMAIN-SUFFIX,www.hdxxtv.com,Proxy\nDOMAIN-SUFFIX,towardsdatascience.com,Proxy\nDOMAIN-SUFFIX,www.thestatesman.com,Proxy\nDOMAIN-SUFFIX,vtrspeed.com,Proxy\nDOMAIN-SUFFIX,morningsun.org,Proxy\nDOMAIN-SUFFIX,richbelson.co.uk,Proxy\nDOMAIN-SUFFIX,www.sungirlbaby.com,Proxy\nDOMAIN-SUFFIX,strongvpn.me,Proxy\nDOMAIN-SUFFIX,etvpn.com,Proxy\nDOMAIN-SUFFIX,www.intervalzero.com,Proxy\nDOMAIN-SUFFIX,55557193.com,Proxy\nDOMAIN-SUFFIX,windbest.com,Proxy\nDOMAIN-SUFFIX,blacktowhite.net,Proxy\nDOMAIN-SUFFIX,falungong.org.uk,Proxy\nDOMAIN-SUFFIX,moviesguy.com,Proxy\nDOMAIN-SUFFIX,forum.uscreditcardguide.com,Proxy\nDOMAIN-SUFFIX,m.me,Proxy\nDOMAIN-SUFFIX,catalog.nypl.org,Proxy\nDOMAIN-SUFFIX,facebook.be,Proxy\nDOMAIN-SUFFIX,www.bismarck-besmart.com.tw,Proxy\nDOMAIN-SUFFIX,fatapk.com,Proxy\nDOMAIN-SUFFIX,doub.bid,Proxy\nDOMAIN-SUFFIX,today.code4.hk,Proxy\nDOMAIN-SUFFIX,1384kai.com,Proxy\nDOMAIN-SUFFIX,nexitally.com,Proxy\nDOMAIN-SUFFIX,www.robinchow.net,Proxy\nDOMAIN-SUFFIX,oursogo.com,Proxy\nDOMAIN-SUFFIX,coupangsupport.zendesk.com,Proxy\nDOMAIN-SUFFIX,shaman.ai,Proxy\nDOMAIN-SUFFIX,www.vivud.com,Proxy\nDOMAIN-SUFFIX,yqxs.com,Proxy\nDOMAIN-SUFFIX,orzkoo.com,Proxy\nDOMAIN-SUFFIX,e621.net,Proxy\nDOMAIN-SUFFIX,dabus.xyz,Proxy\nDOMAIN-SUFFIX,www.xh8720.com,Proxy\nDOMAIN-SUFFIX,redchinacn.net,Proxy\nDOMAIN-SUFFIX,nmasr.com,Proxy\nDOMAIN-SUFFIX,porngladiator.com,Proxy\nDOMAIN-SUFFIX,wcnc.com,Proxy\nDOMAIN-SUFFIX,www.buyukhome.com,Proxy\nDOMAIN-SUFFIX,www.590103.idv.tw,Proxy\nDOMAIN-SUFFIX,www.runos.us,Proxy\nDOMAIN-SUFFIX,app2.atmovies.com.tw,Proxy\nDOMAIN-SUFFIX,exmormon.org,Proxy\nDOMAIN-SUFFIX,scientology.tv,Proxy\nDOMAIN-SUFFIX,sesawe.org,Proxy\nDOMAIN-SUFFIX,lers.google,Proxy\nDOMAIN-SUFFIX,translessa.com.br,Proxy\nDOMAIN-SUFFIX,sexasian18.com,Proxy\nDOMAIN-SUFFIX,eroticax.com,Proxy\nDOMAIN-SUFFIX,liangchenyun.io,Proxy\nDOMAIN-SUFFIX,tiktok.com,Proxy\nDOMAIN-SUFFIX,fzh999.com,Proxy\nDOMAIN-SUFFIX,lessonsindemocracy.org,Proxy\nDOMAIN-SUFFIX,coral.twomini.com,Proxy\nDOMAIN-SUFFIX,nitter.bird.froth.zone,Proxy\nDOMAIN-SUFFIX,uyghur-archive.com,Proxy\nDOMAIN-SUFFIX,395.dynamicdns.biz,Proxy\nDOMAIN-SUFFIX,www.muzik-online.com,Proxy\nDOMAIN-SUFFIX,jsdd15.jigsy.com,Proxy\nDOMAIN-SUFFIX,www.tv51xapp.com,Proxy\nDOMAIN-SUFFIX,www.eslite.com,Proxy\nDOMAIN-SUFFIX,tw.bid.yahoo.com,Proxy\nDOMAIN-SUFFIX,naughtyamerica.com,Proxy\nDOMAIN-SUFFIX,winsi.cl,Proxy\nDOMAIN-SUFFIX,bbyxv.xyz,Proxy\nDOMAIN-SUFFIX,www.e8682.com,Proxy\nDOMAIN-SUFFIX,www.bi-av.com,Proxy\nDOMAIN-SUFFIX,www.rapidswitch.com,Proxy\nDOMAIN-SUFFIX,adidas.co.kr,Proxy\nDOMAIN-SUFFIX,ccef.org,Proxy\nDOMAIN-SUFFIX,vecv.in,Proxy\nDOMAIN-SUFFIX,ww-cc2.xyz,Proxy\nDOMAIN-SUFFIX,pinbet88.com,Proxy\nDOMAIN-SUFFIX,www.art-und-weise.org,Proxy\nDOMAIN-SUFFIX,yurenmatou9.com,Proxy\nDOMAIN-SUFFIX,vidmax.com,Proxy\nDOMAIN-SUFFIX,www.blo5szx.xyz,Proxy\nDOMAIN-SUFFIX,porsar.com,Proxy\nDOMAIN-SUFFIX,php3.cf,Proxy\nDOMAIN-SUFFIX,zuobiao.me,Proxy\nDOMAIN-SUFFIX,lik.cl,Proxy\nDOMAIN-SUFFIX,gratispeliculas.org,Proxy\nDOMAIN-SUFFIX,55557.com,Proxy\nDOMAIN-SUFFIX,www.purevpn.net,Proxy\nDOMAIN-SUFFIX,xzvpn.com,Proxy\nDOMAIN-SUFFIX,stillwaterexpress.com,Proxy\nDOMAIN-SUFFIX,fw1.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,vedaadvantage.com,Proxy\nDOMAIN-SUFFIX,gardennetworks.com,Proxy\nDOMAIN-SUFFIX,www.mobogenie.com,Proxy\nDOMAIN-SUFFIX,have8.com,Proxy\nDOMAIN-SUFFIX,www.maturetube.com,Proxy\nDOMAIN-SUFFIX,d1cfkbm1sjgrub.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.cpbltv.com,Proxy\nDOMAIN-SUFFIX,www.mapillary.com,Proxy\nDOMAIN-SUFFIX,d1ldnl69khq89z.cloudfront.net,Proxy\nDOMAIN-SUFFIX,opciondragon.cl,Proxy\nDOMAIN-SUFFIX,psiphon.civisec.org,Proxy\nDOMAIN-SUFFIX,xinbi268.com,Proxy\nDOMAIN-SUFFIX,photo.5article.com,Proxy\nDOMAIN-SUFFIX,bet365.com,Proxy\nDOMAIN-SUFFIX,icecast.org,Proxy\nDOMAIN-SUFFIX,5353481.com,Proxy\nDOMAIN-SUFFIX,v.3w12.com,Proxy\nDOMAIN-SUFFIX,www.448hk.com,Proxy\nDOMAIN-SUFFIX,tianlawoffice.com,Proxy\nDOMAIN-SUFFIX,www.google.ch,Proxy\nDOMAIN-SUFFIX,twelvemore.com,Proxy\nDOMAIN-SUFFIX,onion.ly,Proxy\nDOMAIN-SUFFIX,yx1101.com,Proxy\nDOMAIN-SUFFIX,firsttimeauditions.com,Proxy\nDOMAIN-SUFFIX,chithu.org,Proxy\nDOMAIN-SUFFIX,nd.com,Proxy\nDOMAIN-SUFFIX,wiktionary.org,Proxy\nDOMAIN-SUFFIX,crazys.cc,Proxy\nDOMAIN-SUFFIX,moviebk.tk,Proxy\nDOMAIN-SUFFIX,www.standard.co.uk,Proxy\nDOMAIN-SUFFIX,www.deepriversangha.org,Proxy\nDOMAIN-SUFFIX,witnessleeteaching.com,Proxy\nDOMAIN-SUFFIX,btkittyok.co,Proxy\nDOMAIN-SUFFIX,www.fx110.com,Proxy\nDOMAIN-SUFFIX,porntubemovs.net,Proxy\nDOMAIN-SUFFIX,seniorexpress.org,Proxy\nDOMAIN-SUFFIX,www.lagazettedeberlin.com,Proxy\nDOMAIN-SUFFIX,github.co,Proxy\nDOMAIN-SUFFIX,www.foi.se,Proxy\nIP-CIDR,67.220.91.15/32,Proxy\nDOMAIN-SUFFIX,kfrmm.com,Proxy\nDOMAIN-SUFFIX,u1lib.org,Proxy\nDOMAIN-SUFFIX,smartproxy.me,Proxy\nDOMAIN-SUFFIX,d30gekvu7qkolw.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.widescreen-wallpaper.eu,Proxy\nDOMAIN-SUFFIX,betb88.net,Proxy\nDOMAIN-SUFFIX,www.admissionadviser.com,Proxy\nDOMAIN-SUFFIX,rossadamson.net,Proxy\nDOMAIN-SUFFIX,xinlingfamen.org,Proxy\nDOMAIN-SUFFIX,bw88tiyu.com,Proxy\nDOMAIN-SUFFIX,unblockit.dev,Proxy\nDOMAIN-SUFFIX,mofosex.com,Proxy\nDOMAIN-SUFFIX,filelisting.com,Proxy\nDOMAIN-SUFFIX,cbcnews.ca,Proxy\nDOMAIN-SUFFIX,88599.cc,Proxy\nDOMAIN-SUFFIX,tokumei10.blogspot.jp,Proxy\nDOMAIN-SUFFIX,wikileaks.eu,Proxy\nDOMAIN-SUFFIX,bb866.com,Proxy\nDOMAIN-SUFFIX,b.hatena.ne.jp,Proxy\nDOMAIN-SUFFIX,chenyehao.spaces.live.com,Proxy\nDOMAIN-SUFFIX,wikpedia.org,Proxy\nDOMAIN-SUFFIX,www.mofun.com.tw,Proxy\nDOMAIN-SUFFIX,ourplay.com,Proxy\nDOMAIN-SUFFIX,zhoushuguang.com,Proxy\nDOMAIN-SUFFIX,torrenteditor.com,Proxy\nDOMAIN-SUFFIX,feiji888.com,Proxy\nDOMAIN-SUFFIX,hazelgrovepac.ca,Proxy\nDOMAIN-SUFFIX,dotvpn.com,Proxy\nDOMAIN-SUFFIX,gz2299.com,Proxy\nDOMAIN-SUFFIX,widih.com,Proxy\nDOMAIN-SUFFIX,asiamoviepass.com,Proxy\nDOMAIN-SUFFIX,brazilianerotic.com,Proxy\nDOMAIN-SUFFIX,36.flnet.org,Proxy\nDOMAIN-SUFFIX,m.7ou7ou.com,Proxy\nDOMAIN-SUFFIX,www.aipa520.com,Proxy\nDOMAIN-SUFFIX,hizb-ut-tahrir.org,Proxy\nDOMAIN-SUFFIX,tvi.iol.pt,Proxy\nDOMAIN-SUFFIX,supra-elektronik.com,Proxy\nDOMAIN-SUFFIX,ahui.us,Proxy\nDOMAIN-SUFFIX,gyatsostudio.com,Proxy\nDOMAIN-SUFFIX,sciencenewsdaily.com,Proxy\nDOMAIN-SUFFIX,pmli.it,Proxy\nDOMAIN-SUFFIX,peeasian.com,Proxy\nDOMAIN-SUFFIX,proxyshore.org,Proxy\nDOMAIN-SUFFIX,y2090.com,Proxy\nDOMAIN-SUFFIX,bostontibet.org,Proxy\nDOMAIN-SUFFIX,www.xf636.com,Proxy\nDOMAIN-SUFFIX,cloudup.com,Proxy\nDOMAIN-SUFFIX,f6.com,Proxy\nDOMAIN-SUFFIX,ai.google,Proxy\nDOMAIN-SUFFIX,lamnia.co.uk,Proxy\nDOMAIN-SUFFIX,www.githubip.xyz,Proxy\nDOMAIN-SUFFIX,caoliushequ.org,Proxy\nDOMAIN-SUFFIX,muyzorras.com,Proxy\nDOMAIN-SUFFIX,bitcointalk.org,Proxy\nDOMAIN-SUFFIX,ticket.com.tw,Proxy\nDOMAIN-SUFFIX,sinoquebec.com,Proxy\nDOMAIN-SUFFIX,www.lt2022.xyz,Proxy\nDOMAIN-SUFFIX,gma.abc,Proxy\nDOMAIN-SUFFIX,images.prismic.io,Proxy\nDOMAIN-SUFFIX,www.hidefap.com,Proxy\nDOMAIN-SUFFIX,d2nm3w2ltn97dw.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www2.hele888.com,Proxy\nDOMAIN-SUFFIX,ca978.com,Proxy\nDOMAIN-SUFFIX,get.dev,Proxy\nDOMAIN-SUFFIX,gogle.com,Proxy\nDOMAIN-SUFFIX,www.pinterest.jp,Proxy\nDOMAIN-SUFFIX,h5.ledong895.cc,Proxy\nDOMAIN-SUFFIX,kingdomsalvation.org,Proxy\nDOMAIN-SUFFIX,knorr.com,Proxy\nDOMAIN-SUFFIX,naciodigital.cat,Proxy\nDOMAIN-SUFFIX,nbbty.com,Proxy\nDOMAIN-SUFFIX,blog.cyaontheroad.com,Proxy\nDOMAIN-SUFFIX,www.222654.com,Proxy\nDOMAIN-SUFFIX,www.corbacho.net,Proxy\nDOMAIN-SUFFIX,18comic.bet,Proxy\nDOMAIN-SUFFIX,2646m.com,Proxy\nDOMAIN-SUFFIX,www.sinoeurovoices.com,Proxy\nDOMAIN-SUFFIX,ofo91.com,Proxy\nDOMAIN-SUFFIX,uptown.pw,Proxy\nDOMAIN-SUFFIX,kaiyuan.de,Proxy\nDOMAIN-SUFFIX,surf-in-china.com,Proxy\nDOMAIN-SUFFIX,paper.udn.com,Proxy\nDOMAIN-SUFFIX,starlightbg.net,Proxy\nDOMAIN-SUFFIX,www.cdu.de,Proxy\nDOMAIN-SUFFIX,www.hj1766.com,Proxy\nDOMAIN-SUFFIX,mo.be,Proxy\nDOMAIN-SUFFIX,asm.com.ar,Proxy\nDOMAIN-SUFFIX,avoiceformen.com,Proxy\nDOMAIN-SUFFIX,citizenpowerforchina.org,Proxy\nDOMAIN-SUFFIX,sss.camp,Proxy\nDOMAIN-SUFFIX,thehots.info,Proxy\nDOMAIN-SUFFIX,reason.com,Proxy\nDOMAIN-SUFFIX,minepi.com,Proxy\nDOMAIN-SUFFIX,ca227.com,Proxy\nDOMAIN-SUFFIX,choubb.com,Proxy\nDOMAIN-SUFFIX,guilded.gg,Proxy\nDOMAIN-SUFFIX,www.citizenvpn.com,Proxy\nDOMAIN-SUFFIX,www.s98m.com,Proxy\nDOMAIN-SUFFIX,atozproxy.com,Proxy\nDOMAIN-SUFFIX,guardian.ng,Proxy\nDOMAIN-SUFFIX,k3.hk303.c8763.com,Proxy\nDOMAIN-SUFFIX,scholar.glgoo.com,Proxy\nDOMAIN-SUFFIX,greenvpn.org,Proxy\nDOMAIN-SUFFIX,ttv.com.tw,Proxy\nDOMAIN-SUFFIX,www.edenmagnet.com.au,Proxy\nDOMAIN-SUFFIX,nexus-models.cl,Proxy\nDOMAIN-SUFFIX,www.telekom.com,Proxy\nDOMAIN-SUFFIX,hkgreenradio.org,Proxy\nDOMAIN-SUFFIX,tube.connect.cafe,Proxy\nDOMAIN-SUFFIX,u9a9.cc,Proxy\nDOMAIN-SUFFIX,www.bomao66.com,Proxy\nDOMAIN-SUFFIX,mixlr.com,Proxy\nDOMAIN-SUFFIX,www.omci.it,Proxy\nDOMAIN-SUFFIX,www.smh.com.au,Proxy\nDOMAIN-SUFFIX,uncensoredlibrary.com,Proxy\nDOMAIN-SUFFIX,roigrentacar.com,Proxy\nDOMAIN-SUFFIX,hb287.com,Proxy\nDOMAIN-SUFFIX,llbn.tv,Proxy\nDOMAIN-SUFFIX,cointobe.com,Proxy\nDOMAIN-SUFFIX,joinmastodon.com,Proxy\nDOMAIN-SUFFIX,www.predictit.org,Proxy\nDOMAIN-SUFFIX,bdsmtv.me,Proxy\nDOMAIN-SUFFIX,ilogica-soluciones.cl,Proxy\nDOMAIN-SUFFIX,ru.paradisehill.cc,Proxy\nDOMAIN-SUFFIX,www.voncop.top,Proxy\nDOMAIN-SUFFIX,bartarinha.ir,Proxy\nDOMAIN-SUFFIX,miaoss.cat,Proxy\nDOMAIN-SUFFIX,globalcash.cl,Proxy\nDOMAIN-SUFFIX,word-play.com,Proxy\nDOMAIN-SUFFIX,d3nkhhtdsbru8g.cloudfront.net,Proxy\nDOMAIN-SUFFIX,privacy.aiuys.com,Proxy\nDOMAIN-SUFFIX,skoletube.dk,Proxy\nDOMAIN-SUFFIX,taiwanhot.net,Proxy\nDOMAIN-SUFFIX,www.7-zip.fr,Proxy\nDOMAIN-SUFFIX,mgm555.cd77.net,Proxy\nDOMAIN-SUFFIX,www.king5.com,Proxy\nDOMAIN-SUFFIX,www.turfclub.com.sg,Proxy\nDOMAIN-SUFFIX,ledger.com,Proxy\nDOMAIN-SUFFIX,aidol.asia,Proxy\nDOMAIN-SUFFIX,d3enll2f0oipyj.cloudfront.net,Proxy\nDOMAIN-SUFFIX,d2o6gab9w1xdwf.cloudfront.net,Proxy\nDOMAIN-SUFFIX,www.comixology.com,Proxy\nDOMAIN-SUFFIX,www.cbart.net,Proxy\nDOMAIN-SUFFIX,www.getkeepsafe.com,Proxy\nDOMAIN-SUFFIX,tmdfish.com,Proxy\nDOMAIN-SUFFIX,www.boorowanewsonline.com.au,Proxy\nDOMAIN-SUFFIX,www.ra9094.com,Proxy\nDOMAIN-SUFFIX,www.caithyorganics.com,Proxy\nDOMAIN-SUFFIX,amh8888.com,Proxy\nDOMAIN-SUFFIX,hentaigasm.com,Proxy\nDOMAIN-SUFFIX,d1kr9ubbg59ob6.cloudfront.net,Proxy\nDOMAIN-SUFFIX,moon.fm,Proxy\nDOMAIN-SUFFIX,258.fullcoveronline.com,Proxy\nDOMAIN-SUFFIX,www.chareidio.com,Proxy\nDOMAIN-SUFFIX,anime.eroterest.net,Proxy\nDOMAIN-SUFFIX,fow.kr,Proxy\nDOMAIN-SUFFIX,daol8yb47gnd3.cloudfront.net,Proxy\nDOMAIN-SUFFIX,app63.ga,Proxy\nDOMAIN-SUFFIX,twibs.com,Proxy\nDOMAIN-SUFFIX,ww5877.com,Proxy\nDOMAIN-SUFFIX,dpmd.ai,Proxy\nDOMAIN-SUFFIX,gsearch.media,Proxy\nDOMAIN-SUFFIX,abet.cc,Proxy\nDOMAIN-SUFFIX,letstalk-mobile.com,Proxy\nDOMAIN-SUFFIX,yenmingtemple.org.au,Proxy\nDOMAIN-SUFFIX,10jsq.com,Proxy\nDOMAIN-SUFFIX,av.nightlife141.com,Proxy\nDOMAIN-SUFFIX,premeforwindows7.com,Proxy\nDOMAIN-SUFFIX,tpi.org.tw,Proxy\nDOMAIN-SUFFIX,www.ddc.com.tw,Proxy\nDOMAIN-SUFFIX,dropbooks.tv,Proxy\nDOMAIN-SUFFIX,worldbull.com,Proxy\nDOMAIN-SUFFIX,worldcrunch.com,Proxy\nDOMAIN-SUFFIX,ypmate.com,Proxy\nDOMAIN-SUFFIX,vpoint.jp,Proxy\nDOMAIN-SUFFIX,golang.com,Proxy\nDOMAIN-SUFFIX,rssradar.com,Proxy\nDOMAIN-SUFFIX,32.pics.mu,Proxy\nDOMAIN-SUFFIX,giize.com,Proxy\nDOMAIN-SUFFIX,hacg.cat,Proxy\nDOMAIN-SUFFIX,percepio.com,Proxy\nDOMAIN-SUFFIX,www.xw511.com,Proxy\nDOMAIN-SUFFIX,btsow.us,Proxy\nDOMAIN-SUFFIX,guiltless-aware-hydrogen.glitch.me,Proxy\nDOMAIN-SUFFIX,unwire.hk,Proxy\nDOMAIN-SUFFIX,webmediacom.com,Proxy\nDOMAIN-SUFFIX,screen.yahoo.com,Proxy\nDOMAIN-SUFFIX,ggg.eeload.com,Proxy\nDOMAIN-SUFFIX,botcyb.org,Proxy\nDOMAIN-SUFFIX,mojim.com,Proxy\nDOMAIN-SUFFIX,springwise.com,Proxy\nDOMAIN-SUFFIX,nm.com,Proxy\nDOMAIN-SUFFIX,motiyun.com,Proxy\nDOMAIN-SUFFIX,therock.net.nz,Proxy\nDOMAIN-SUFFIX,rohd.tv,Proxy\nDOMAIN-SUFFIX,nextgenvpn.com,Proxy\nDOMAIN-SUFFIX,tw.streetvoice.com,Proxy\nDOMAIN-SUFFIX,dastrassi.org,Proxy\nDOMAIN-SUFFIX,arizona-friends-of-tibet.org,Proxy\nDOMAIN-SUFFIX,tw.hao123.com,Proxy\nDOMAIN-SUFFIX,publicinvasion.com,Proxy\nDOMAIN-SUFFIX,www.krugmantoday.com,Proxy\nDOMAIN-SUFFIX,eastturkistangovernmentinexile.us,Proxy\nDOMAIN-SUFFIX,www.141hh.com,Proxy\nDOMAIN-SUFFIX,fgq5.com,Proxy\nDOMAIN-SUFFIX,galletasparati.cl,Proxy\nDOMAIN-SUFFIX,8587o.cc,Proxy\nDOMAIN-SUFFIX,hdpornmovie.red,Proxy\nDOMAIN-SUFFIX,m.epochtimes.com.tw,Proxy\nDOMAIN-SUFFIX,www.itb88.com,Proxy\nDOMAIN-SUFFIX,www.adidas.cm,Proxy\nDOMAIN-SUFFIX,www.saira.com,Proxy\nDOMAIN-SUFFIX,626ccc.net,Proxy\nDOMAIN-SUFFIX,www.virtualworldland.com,Proxy\nDOMAIN-SUFFIX,hkgalden.com,Proxy\nDOMAIN-SUFFIX,tianhuayuan.com,Proxy\nDOMAIN-SUFFIX,p333.com,Proxy\nDOMAIN-SUFFIX,vpnsu.com,Proxy\nDOMAIN-SUFFIX,www.cite.com.tw,Proxy\nDOMAIN-SUFFIX,juzi80.net,Proxy\nDOMAIN-SUFFIX,www.highresolutiontechnologies.com,Proxy\nDOMAIN-SUFFIX,y1835.com,Proxy\nDOMAIN-SUFFIX,free.ssru.date,Proxy\nDOMAIN-SUFFIX,sakuralive.com,Proxy\nDOMAIN-SUFFIX,tibetcharity.dk,Proxy\nDOMAIN-SUFFIX,www.aparchive.com,Proxy\nDOMAIN-SUFFIX,slidingsync.yanxun.org,Proxy\nDOMAIN-SUFFIX,shixiao.org,Proxy\nDOMAIN-SUFFIX,m.588a2.com,Proxy\nDOMAIN-SUFFIX,d18qrsaquic9cz.cloudfront.net,Proxy\nDOMAIN-SUFFIX,no36.ga,Proxy\nDOMAIN-SUFFIX,freegao.com,Proxy\nDOMAIN-SUFFIX,xinbi600.com,Proxy\nDOMAIN-SUFFIX,f555.flnet.org,Proxy\nDOMAIN-SUFFIX,ifanqiang.com,Proxy\nDOMAIN-SUFFIX,m.sh22.us,Proxy\nDOMAIN-SUFFIX,proxybrowsing.com,Proxy\nDOMAIN-SUFFIX,94.podzone.org,Proxy\nDOMAIN-SUFFIX,888ylg.com,Proxy\nDOMAIN-SUFFIX,anpopo.com,Proxy\nDOMAIN-SUFFIX,baizhi.org,Proxy\nDOMAIN-SUFFIX,d33zs0szg2w108.cloudfront.net,Proxy\nDOMAIN-SUFFIX,fulue.com,Proxy\nDOMAIN-SUFFIX,streetblowjobs.com,Proxy\nDOMAIN-SUFFIX,webfallout.net,Proxy\nDOMAIN-SUFFIX,analytics.blogspot.hk,Proxy\nDOMAIN-SUFFIX,saito.im,Proxy\nDOMAIN-SUFFIX,veesecurity.com,Proxy\nDOMAIN-SUFFIX,www.imq.es,Proxy\nDOMAIN-SUFFIX,933.my03.com,Proxy\nDOMAIN-SUFFIX,cmyip.com,Proxy\nDOMAIN-SUFFIX,www.coinbene.com,Proxy\nDOMAIN-SUFFIX,mail.cyberpower.com,Proxy\nDOMAIN-SUFFIX,t28.net,Proxy\nDOMAIN-SUFFIX,vcdn.ssdm.me,Proxy\nDOMAIN-SUFFIX,doh.disconnect.app,Proxy\nDOMAIN-SUFFIX,wiwiwiki.kfd.me,Proxy\nDOMAIN-SUFFIX,845099.com,Proxy\nDOMAIN-SUFFIX,otri.ujaen.es,Proxy\nDOMAIN-SUFFIX,actionjav.com,Proxy\nDOMAIN-SUFFIX,s-dragon.org,Proxy\nDOMAIN-SUFFIX,wujunying004.jigsy.com,Proxy\nDOMAIN-SUFFIX,paopao12.azurewebsites.net,Proxy\nDOMAIN-SUFFIX,friendz.sk,Proxy\nDOMAIN-SUFFIX,citytv-74bf2.firebaseio.com,Proxy\nDOMAIN-SUFFIX,inside.com.tw,Proxy\nDOMAIN-SUFFIX,maying.co,Proxy\nDOMAIN-SUFFIX,netshies.com.br,Proxy\nDOMAIN-SUFFIX,schumacher.ws,Proxy\nDOMAIN-SUFFIX,freevpn.nl,Proxy\nDOMAIN-SUFFIX,bugbounty.xyz,Proxy\nDOMAIN-SUFFIX,www.8886669999.com,Proxy\nDOMAIN-SUFFIX,notblocked.telex.cc,Proxy\nDOMAIN-SUFFIX,f4.flnet.org,Proxy\nDOMAIN-SUFFIX,5251a.com,Proxy\nDOMAIN-SUFFIX,matthewdgreen.wordpress.com,Proxy\nDOMAIN-SUFFIX,www.chickenkiller.com,Proxy\nDOMAIN-SUFFIX,twitter4j.org,Proxy\nDOMAIN-SUFFIX,www.41478.com,Proxy\nDOMAIN-SUFFIX,d2e6hgycn2t9tz.cloudfront.net,Proxy\nDOMAIN-SUFFIX,sexpixbox.com,Proxy\nDOMAIN-SUFFIX,go141.com,Proxy\nDOMAIN-SUFFIX,cederfeldt.se,Proxy\nDOMAIN-SUFFIX,humanevents.com,Proxy\nDOMAIN-SUFFIX,magazines.com,Proxy\nDOMAIN-SUFFIX,ccycenter.ning.com,Proxy\nDOMAIN-SUFFIX,www.tlc819.com,Proxy\nDOMAIN-SUFFIX,ernestmandel.org,Proxy\nDOMAIN-SUFFIX,hentailist.com,Proxy\nDOMAIN-SUFFIX,www.yddc888.com,Proxy\nDOMAIN-SUFFIX,kechara.com,Proxy\nDOMAIN-SUFFIX,33vid.com,Proxy\nDOMAIN-SUFFIX,www.webnode.tw,Proxy\nDOMAIN-SUFFIX,newstalkzb.co.nz,Proxy\nDOMAIN-SUFFIX,auliving.com.au,Proxy\nDOMAIN-SUFFIX,www.1mynews.tech,Proxy\nDOMAIN-SUFFIX,taobonfu.com,Proxy\nDOMAIN-SUFFIX,puuko.com,Proxy\nDOMAIN-SUFFIX,twitterrific.com,Proxy\nDOMAIN-SUFFIX,www.vunion.com.tw,Proxy\nDOMAIN-SUFFIX,stickerpipe.com,Proxy\nDOMAIN-SUFFIX,roboy.me,Proxy\nDOMAIN-SUFFIX,fb.co,Proxy\nDOMAIN-SUFFIX,aaa5200.com,Proxy\nDOMAIN-SUFFIX,fruitbird.net,Proxy\nDOMAIN-SUFFIX,www.cnacargo.com,Proxy\nDOMAIN-SUFFIX,zzy.dnsmail.xyz,Proxy\nDOMAIN-SUFFIX,437.cleansite.us,Proxy\nDOMAIN-SUFFIX,japanesefuck.com,Proxy\nDOMAIN-SUFFIX,myaudiocast.com,Proxy\nDOMAIN-SUFFIX,tkacz.tk,Proxy\nDOMAIN-SUFFIX,proxyie.cn,Proxy\nDOMAIN-SUFFIX,proxyroad.com,Proxy\nDOMAIN-SUFFIX,dcdn.de,Proxy\nDOMAIN-SUFFIX,secundaria.eu,Proxy\nDOMAIN-SUFFIX,vwin888.com,Proxy\nDOMAIN-SUFFIX,puertoricovpn.com-1,Proxy\nDOMAIN-SUFFIX,www.iclicker.com,Proxy\nDOMAIN-SUFFIX,from-la.net,Proxy\nDOMAIN-SUFFIX,nnn26.net,Proxy\nDOMAIN-SUFFIX,89.com,Proxy\nDOMAIN-SUFFIX,www.taco.idv.tw,Proxy\nDOMAIN-SUFFIX,miijqghk1.dtd999.com,Proxy\nDOMAIN-SUFFIX,kevinquiatkowski.de,Proxy\nDOMAIN-SUFFIX,8760268.com,Proxy\nDOMAIN-SUFFIX,sis001.us,Proxy\nDOMAIN-SUFFIX,big.one,Proxy\nDOMAIN-SUFFIX,yaypetiteteens.com,Proxy\nDOMAIN-SUFFIX,www.artisu.com,Proxy\nDOMAIN-SUFFIX,www.dailyadvertiser.com.au,Proxy\nDOMAIN-SUFFIX,www.yc5015.com,Proxy\nDOMAIN-SUFFIX,bitcoinsqatar.com,Proxy\nDOMAIN-SUFFIX,rarbgprx.org,Proxy\nDOMAIN-SUFFIX,video-proxy.com,Proxy\nDOMAIN-SUFFIX,newsolidshare.com,Proxy\nDOMAIN-SUFFIX,sd.sino.tw,Proxy\nDOMAIN-SUFFIX,eee773.net,Proxy\nDOMAIN-SUFFIX,nwen.net,Proxy\nDOMAIN-SUFFIX,madsextube.com,Proxy\nDOMAIN-SUFFIX,discreetmilf.com,Proxy\nDOMAIN-SUFFIX,bi-si9.xyz,Proxy\nDOMAIN-SUFFIX,readydown.com,Proxy\nDOMAIN-SUFFIX,blog.thunderbird.net,Proxy\nDOMAIN-SUFFIX,brookings.edu,Proxy\nDOMAIN-SUFFIX,madanichannel.com,Proxy\nDOMAIN-SUFFIX,russel053.ddns.net,Proxy\nDOMAIN-SUFFIX,cdn.scrollmotion.com,Proxy\nDOMAIN-SUFFIX,javpark.net,Proxy\nDOMAIN-SUFFIX,wnd.com,Proxy\nDOMAIN-SUFFIX,es-kanzhongguo.com,Proxy\nDOMAIN-SUFFIX,jimoparty.com,Proxy\nDOMAIN-SUFFIX,www.89925.com,Proxy\nDOMAIN-SUFFIX,nanrenvip.net,Proxy\nDOMAIN-SUFFIX,info.tm,Proxy\nDOMAIN-SUFFIX,5299.tv,Proxy\nDOMAIN-SUFFIX,www.hustlertube.com,Proxy\nDOMAIN-SUFFIX,acgkj.com,Proxy\nDOMAIN-SUFFIX,knolskape.com,Proxy\nDOMAIN-SUFFIX,www.mobypicture.com,Proxy\nDOMAIN-SUFFIX,3068.yzc257.com,Proxy\nDOMAIN-SUFFIX,future.pncle8.com,Proxy\nDOMAIN-SUFFIX,tb6607.com,Proxy\nDOMAIN-SUFFIX,gfwatch.org,Proxy\nDOMAIN-SUFFIX,d9693.com,Proxy\nDOMAIN-SUFFIX,www.multibankfx.com,Proxy\nDOMAIN-SUFFIX,www.moorburn.com,Proxy\nDOMAIN-SUFFIX,kankan.today,Proxy\nDOMAIN-SUFFIX,ug.freepac.pw,Proxy\nDOMAIN-SUFFIX,zofxmh.site,Proxy\nDOMAIN-SUFFIX,icochecker.com,Proxy\nDOMAIN-SUFFIX,www.vpn5207.com,Proxy\nDOMAIN-SUFFIX,infodns.xyz,Proxy\nDOMAIN-SUFFIX,4youtube.com,Proxy\nDOMAIN-SUFFIX,17xtv.com,Proxy\nDOMAIN-SUFFIX,www.wanktube.com,Proxy\nDOMAIN-SUFFIX,c.htcc.us,Proxy\nDOMAIN-SUFFIX,ibros.org,Proxy\nDOMAIN-SUFFIX,main-ecnpaper-economist.content.pugpig.com,Proxy\nDOMAIN-SUFFIX,chinacity.be,Proxy\nDOMAIN-SUFFIX,moonbbs.com,Proxy\nDOMAIN-SUFFIX,www.topshop.sk,Proxy\nDOMAIN-SUFFIX,www.taiwanpetshop.com,Proxy\nDOMAIN-SUFFIX,xvideos2.com,Proxy\nDOMAIN-SUFFIX,drk.de,Proxy\nDOMAIN-SUFFIX,xn--ngstr-lra8j.com,Proxy\nDOMAIN-SUFFIX,qcman.net,Proxy\nDOMAIN-SUFFIX,vilavpn.com,Proxy\nDOMAIN-SUFFIX,ddownr.com,Proxy\nDOMAIN-SUFFIX,cat.dhcp.biz,Proxy\nDOMAIN-SUFFIX,my.cloudnx.cc,Proxy\nDOMAIN-SUFFIX,emaw.com.br,Proxy\nDOMAIN-SUFFIX,vrt.be,Proxy\nDOMAIN-SUFFIX,expekt.com,Proxy\nDOMAIN-SUFFIX,e37555.com,Proxy\nDOMAIN-SUFFIX,hqsbonline.wordpress.com,Proxy\nDOMAIN-SUFFIX,www.myheritage.nl,Proxy\nDOMAIN-SUFFIX,jm-comic1.club,Proxy\nDOMAIN-SUFFIX,zion-corp.net,Proxy\nDOMAIN-SUFFIX,www.kendes.nl,Proxy\nDOMAIN-SUFFIX,s8forum.com,Proxy\nDOMAIN-SUFFIX,anqingshi.xyz,Proxy\nDOMAIN-SUFFIX,css5.ga,Proxy\nDOMAIN-SUFFIX,roboforex.tw,Proxy\nDOMAIN-SUFFIX,generals.org,Proxy\nDOMAIN-SUFFIX,berzinarchives.com,Proxy\nDOMAIN-SUFFIX,sino-monthly.com,Proxy\nDOMAIN-SUFFIX,honto.jp,Proxy\nDOMAIN-SUFFIX,fhy123.org,Proxy\nDOMAIN-SUFFIX,donttrack.us,Proxy\nDOMAIN-SUFFIX,www.fun88369.com,Proxy\nDOMAIN-SUFFIX,www.malaymail.com,Proxy\nDOMAIN-SUFFIX,tibetsites.com,Proxy\nDOMAIN-SUFFIX,bbs.18wos.org,Proxy\nDOMAIN-SUFFIX,abebooks.com,Proxy\nDOMAIN-SUFFIX,unix100.com,Proxy\nDOMAIN-SUFFIX,freechal.com,Proxy\nDOMAIN-SUFFIX,abc92.ru,Proxy\nDOMAIN-SUFFIX,imagevenue.com,Proxy\nDOMAIN-SUFFIX,ddvpn.net,Proxy\nDOMAIN-SUFFIX,openstreetmaps.org,Proxy\nDOMAIN-SUFFIX,tor.stalkr.net,Proxy\nDOMAIN-SUFFIX,10.tt,Proxy\nDOMAIN-SUFFIX,authorizeddns.us,Proxy\nDOMAIN-SUFFIX,ddxs.com,Proxy\nDOMAIN-SUFFIX,fireconf.net,Proxy\nDOMAIN-SUFFIX,bubendorf.net,Proxy\nDOMAIN-SUFFIX,cementscience.com,Proxy\nDOMAIN-SUFFIX,chinatimes.com,Proxy\nDOMAIN-SUFFIX,xvideos.org,Proxy\nDOMAIN-SUFFIX,www.unblock-anything.com,Proxy\nDOMAIN-SUFFIX,iproxysite.com,Proxy\nDOMAIN-SUFFIX,www.amnesty.se,Proxy\nDOMAIN-SUFFIX,humanrightspressawards.org,Proxy\nDOMAIN-SUFFIX,b423.com,Proxy\nDOMAIN-SUFFIX,builds.garudalinux.org,Proxy\nDOMAIN-SUFFIX,baus.ec,Proxy\nDOMAIN-SUFFIX,3xplanet.com,Proxy\nDOMAIN-SUFFIX,analteenangels.com,Proxy\nDOMAIN-SUFFIX,bryantville.net,Proxy\nDOMAIN-SUFFIX,www.fting.comuf.com,Proxy\nDOMAIN-SUFFIX,www.leduo123.com,Proxy\nDOMAIN-SUFFIX,www.233mr.com,Proxy\nDOMAIN-SUFFIX,www.18luck18.club,Proxy\nDOMAIN-SUFFIX,facebookquotes4u.com,Proxy\nDOMAIN-SUFFIX,porndex.com,Proxy\nDOMAIN-SUFFIX,gso.hk,Proxy\nDOMAIN-SUFFIX,unitedsocialpress.com,Proxy\nDOMAIN-SUFFIX,ie.privatedns.org,Proxy\nDOMAIN-SUFFIX,669m.app,Proxy\nDOMAIN-SUFFIX,tommubahamw.com,Proxy\nDOMAIN-SUFFIX,b7736.com,Proxy\nDOMAIN-SUFFIX,christophrehage.com,Proxy\nDOMAIN-SUFFIX,godsdirectcontact.org,Proxy\nDOMAIN-SUFFIX,d2t8jyna999dpv.cloudfront.net,Proxy\nDOMAIN-SUFFIX,revolutionfm.net,Proxy\nDOMAIN-SUFFIX,wandersnap.co,Proxy\nDOMAIN-SUFFIX,www.moodle.com,Proxy\nDOMAIN-SUFFIX,hide-ip.us,Proxy\nDOMAIN-SUFFIX,88818.com,Proxy\nDOMAIN-SUFFIX,civicforum.github.io,Proxy\nDOMAIN-SUFFIX,bi-si10.xyz,Proxy\nDOMAIN-SUFFIX,www.aafmua.org,Proxy\nDOMAIN-SUFFIX,strongvpn.com,Proxy\nDOMAIN-SUFFIX,fxopen.com,Proxy\nDOMAIN-SUFFIX,www.17-js.com,Proxy\nDOMAIN-SUFFIX,www.tssdnews.com.tw,Proxy\nDOMAIN-SUFFIX,9bis.com,Proxy\nDOMAIN-SUFFIX,macgamestore.com,Proxy\nDOMAIN-SUFFIX,iqqtv.net,Proxy\nDOMAIN-SUFFIX,www.lejsl.com,Proxy\nDOMAIN-SUFFIX,vigilantcitizen.com,Proxy\nDOMAIN-SUFFIX,lunarnewyear.withgoogle.com,Proxy\nDOMAIN-SUFFIX,guruonline.hk,Proxy\nDOMAIN-SUFFIX,networkworld.com,Proxy\nDOMAIN-SUFFIX,eastturkistancc.org,Proxy\nDOMAIN-SUFFIX,www.zenkaisen.fr,Proxy\nDOMAIN-SUFFIX,38850004.com,Proxy\nDOMAIN-SUFFIX,blogs.springeropen.com,Proxy\nDOMAIN-SUFFIX,www.programthinkmirror.xyz,Proxy\nDOMAIN-SUFFIX,koreavpn.com,Proxy\nDOMAIN-SUFFIX,core-os.net,Proxy\nDOMAIN-SUFFIX,litecoin.org,Proxy\nDOMAIN-SUFFIX,www.aidc.com.tw,Proxy\nDOMAIN-SUFFIX,www.lotcai.com,Proxy\nDOMAIN-SUFFIX,t-g.com,Proxy\nDOMAIN-SUFFIX,showbiz.omy.sg,Proxy\nDOMAIN-SUFFIX,2365444888.com,Proxy\nDOMAIN-SUFFIX,mol.gov.tw,Proxy\nDOMAIN-SUFFIX,stcath.net,Proxy\nDOMAIN-SUFFIX,mail.gfgold.com.hk,Proxy\nDOMAIN-SUFFIX,matorral.cl,Proxy\nDOMAIN-SUFFIX,blogs.yahoo.co.jp,Proxy\nDOMAIN-SUFFIX,popularyoutube.com,Proxy\nDOMAIN-SUFFIX,changsa.net,Proxy\nDOMAIN-SUFFIX,xk.domain888.pw,Proxy\nDOMAIN-SUFFIX,www.chenghuang.me,Proxy\nDOMAIN-SUFFIX,pool-hk.supportxmr.com,Proxy\nDOMAIN-SUFFIX,bodog.help,Proxy\nDOMAIN-SUFFIX,docs-examples.firebaseio.com,Proxy\nDOMAIN-SUFFIX,yujiri.xyz,Proxy\nDOMAIN-SUFFIX,zh-hans.cfsh99.com,Proxy\nDOMAIN-SUFFIX,varcopruden.com,Proxy\nDOMAIN-SUFFIX,jm-comic1.art,Proxy\nDOMAIN-SUFFIX,aofa678.com,Proxy\nDOMAIN-SUFFIX,chouzakeil.com.ar,Proxy\nDOMAIN-SUFFIX,perfectgirls.net,Proxy\nDOMAIN-SUFFIX,zyvpn.com,Proxy\nDOMAIN-SUFFIX,hkwesi.com,Proxy\nDOMAIN-SUFFIX,crackle.com,Proxy\nDOMAIN-SUFFIX,abase.me,Proxy\nDOMAIN-SUFFIX,001.100du.us,Proxy\nDOMAIN-SUFFIX,eu1lib.org,Proxy\nDOMAIN-SUFFIX,vilavpn6.club,Proxy\nDOMAIN-SUFFIX,www.caus.com,Proxy\nDOMAIN-SUFFIX,www.freechinaweibo.com,Proxy\nDOMAIN-SUFFIX,www.breakwall.org,Proxy\nDOMAIN-SUFFIX,79796y.com,Proxy\nDOMAIN-SUFFIX,upsangel.com,Proxy\nDOMAIN-SUFFIX,luxuryroig.es,Proxy\nDOMAIN-SUFFIX,inoreader.com,Proxy\nDOMAIN-SUFFIX,3.cr.rs,Proxy\nDOMAIN-SUFFIX,nobita1069.com,Proxy\nDOMAIN-SUFFIX,pimg.tw,Proxy\nDOMAIN-SUFFIX,khabdha.com,Proxy\nDOMAIN-SUFFIX,perplex.at,Proxy\nDOMAIN-SUFFIX,siteks.uk.to,Proxy\nDOMAIN-SUFFIX,www.beingpeacefully.com,Proxy\nDOMAIN-SUFFIX,canview.com,Proxy\nDOMAIN-SUFFIX,theglobalmarketeer.com,Proxy\nDOMAIN-SUFFIX,myfritz.net,Proxy\nDOMAIN-SUFFIX,www.purecharity.com,Proxy\nDOMAIN-SUFFIX,nirx.net,Proxy\nDOMAIN-SUFFIX,hottv.cc,Proxy\nDOMAIN-SUFFIX,www.schoolbuscity.com,Proxy\nDOMAIN-SUFFIX,soft4fun.net,Proxy\nDOMAIN-SUFFIX,eic-av.com,Proxy\nDOMAIN-SUFFIX,vibiznews.com,Proxy\nDOMAIN-SUFFIX,rsiapparel.box.com,Proxy\nDOMAIN-SUFFIX,breached.to,Proxy\nDOMAIN-SUFFIX,www.intrum.com,Proxy\nDOMAIN-SUFFIX,014622.cc,Proxy\nDOMAIN-SUFFIX,a9v.dyndns.work,Proxy\nDOMAIN-SUFFIX,nytmediakit.com,Proxy\nDOMAIN-SUFFIX,tlc189.com,Proxy\nDOMAIN-SUFFIX,711ddd.net,Proxy\nDOMAIN-SUFFIX,torguard.net,Proxy\nDOMAIN-SUFFIX,www.nytstore.com,Proxy\nDOMAIN-SUFFIX,tor-exit-43.for-privacy.net,Proxy\nDOMAIN-SUFFIX,aiph.net,Proxy\nDOMAIN-SUFFIX,syniumsoftware.com,Proxy\nDOMAIN-SUFFIX,d1ltch2mfdfkfm.cloudfront.net,Proxy\nDOMAIN-SUFFIX,faketaxi.com,Proxy\nDOMAIN-SUFFIX,www.forumdaily.com,Proxy\nDOMAIN-SUFFIX,businessweek.com,Proxy\nDOMAIN-SUFFIX,bet5877.com,Proxy\nDOMAIN-SUFFIX,uyghurislam.com,Proxy\nDOMAIN-SUFFIX,gozetto.com.br,Proxy\nDOMAIN-SUFFIX,jav.com,Proxy\nDOMAIN-SUFFIX,mingdemedia.org,Proxy\nDOMAIN-SUFFIX,kriptosoft.com,Proxy\nDOMAIN-SUFFIX,chrlawyers.jrf.org.tw,Proxy\nDOMAIN-SUFFIX,lishuhang.com,Proxy\nDOMAIN-SUFFIX,sakya.org,Proxy\nDOMAIN-SUFFIX,www.loudersound.com,Proxy\nDOMAIN-SUFFIX,vpntt.com,Proxy\nDOMAIN-SUFFIX,xuehua.us,Proxy\nDOMAIN-SUFFIX,uyghurche.com,Proxy\nDOMAIN-SUFFIX,write.as,Proxy\nDOMAIN-SUFFIX,q66.compucase.com,Proxy\nDOMAIN-SUFFIX,www.hxlives.com,Proxy\nDOMAIN-SUFFIX,www.elgoog.im,Proxy\nDOMAIN-SUFFIX,yahoo.com.sg,Proxy\nDOMAIN-SUFFIX,fh801.com,Proxy\nDOMAIN-SUFFIX,www.adidas.co.in,Proxy\nDOMAIN-SUFFIX,cfl.re,Proxy\nDOMAIN-SUFFIX,www.getavpn.org,Proxy\nDOMAIN-SUFFIX,ryanblog.myshopify.com,Proxy\nDOMAIN-SUFFIX,channelnewsasia.com,Proxy\nDOMAIN-SUFFIX,shangfang.org,Proxy\nDOMAIN-SUFFIX,pay8.dhcp.biz,Proxy\nDOMAIN-SUFFIX,www.kokthai.com,Proxy\nDOMAIN-SUFFIX,xinbi368.com,Proxy\nDOMAIN-SUFFIX,kksod.com,Proxy\nDOMAIN-SUFFIX,kink.com,Proxy\nDOMAIN-SUFFIX,wsdc338.com,Proxy\nDOMAIN-SUFFIX,www.wauchopegazette.com.au,Proxy\nDOMAIN-SUFFIX,66955.com,Proxy\nDOMAIN-SUFFIX,mondo.happytreefriends.com,Proxy\nDOMAIN-SUFFIX,buzzhand.com,Proxy\nDOMAIN-SUFFIX,coincola.com,Proxy\nDOMAIN-SUFFIX,201you.me,Proxy\nDOMAIN-SUFFIX,aelmos.ro,Proxy\nDOMAIN-SUFFIX,dd0066.com,Proxy\nDOMAIN-SUFFIX,91598s.com,Proxy\nDOMAIN-SUFFIX,www.filmikiporno.tv,Proxy\nDOMAIN-SUFFIX,www.czwcm.net,Proxy\nDOMAIN-SUFFIX,youtube.ch,Proxy\nDOMAIN-SUFFIX,songs.pk,Proxy\nDOMAIN-SUFFIX,890724.com,Proxy\nDOMAIN-SUFFIX,magicbroccoli.de,Proxy\nDOMAIN-SUFFIX,radio.nogi46.me,Proxy\nDOMAIN-SUFFIX,windy.com,Proxy\nDOMAIN-SUFFIX,reuters.co.jp,Proxy\nDOMAIN-SUFFIX,healthwebsite.xyz,Proxy\nDOMAIN-SUFFIX,380222111.com,Proxy\nDOMAIN-SUFFIX,pewresearch.org,Proxy\nDOMAIN-SUFFIX,static.slidesharecdn.com,Proxy\nDOMAIN-SUFFIX,www.eiuperspectives.com,Proxy\nDOMAIN-SUFFIX,curvefish.com,Proxy\nDOMAIN-SUFFIX,huggingface.co,Proxy\nDOMAIN-SUFFIX,www.buchbach.at,Proxy\nDOMAIN-SUFFIX,cap.org.hk,Proxy\nDOMAIN-SUFFIX,xhamsterlive.com,Proxy\nDOMAIN-SUFFIX,twister.net.co,Proxy\nDOMAIN-SUFFIX,p9332.com,Proxy\nDOMAIN-SUFFIX,btbtt9.com,Proxy\nDOMAIN-SUFFIX,erwinmarin.cl,Proxy\nDOMAIN-SUFFIX,avatars0.githubusercontent.com,Proxy\nDOMAIN-SUFFIX,grubbystuff.com,Proxy\nDOMAIN-SUFFIX,maa1802.com,Proxy\nDOMAIN-SUFFIX,www.bk.com,Proxy\nDOMAIN-SUFFIX,hentaistream.com,Proxy\nDOMAIN-SUFFIX,blogspot.fi,Proxy\nDOMAIN-SUFFIX,sven21.com,Proxy\nDOMAIN-SUFFIX,16563377.com,Proxy\nDOMAIN-SUFFIX,boylove1.cc,Proxy\nDOMAIN-SUFFIX,www.googlestore.com,Proxy\nDOMAIN-SUFFIX,intersectalliance.com,Proxy\nDOMAIN-SUFFIX,sdertyu87123mk.unusualperson.com,Proxy\nDOMAIN-SUFFIX,www.adobe.com,Proxy\nDOMAIN-SUFFIX,www.cryxw.com,Proxy\nDOMAIN-SUFFIX,www.ixhot.com,Proxy\nDOMAIN-SUFFIX,gpme.ro,Proxy\nDOMAIN-SUFFIX,hk1lib.org,Proxy\nDOMAIN-SUFFIX,chinese-memorial.org,Proxy\nDOMAIN-SUFFIX,h5.ledong838.cc,Proxy\nDOMAIN-SUFFIX,nickelsen.cl,Proxy\nDOMAIN-SUFFIX,www.fun809.com,Proxy\nDOMAIN-SUFFIX,spiegel-online.de,Proxy\nDOMAIN-SUFFIX,searx.mha.fi,Proxy\nDOMAIN-SUFFIX,kaltimpost.co.id,Proxy\nDOMAIN-SUFFIX,fpmt.tw,Proxy\nDOMAIN-SUFFIX,actionforhealthykids.org,Proxy\nDOMAIN-SUFFIX,asiaone.com,Proxy\nDOMAIN-SUFFIX,sjhs03.com,Proxy\nDOMAIN-SUFFIX,dwz.pm,Proxy\nDOMAIN-SUFFIX,booksamillion.com,Proxy\nDOMAIN-SUFFIX,kanzhongguo.eu,Proxy\nDOMAIN-SUFFIX,bitznet.app,Proxy\nDOMAIN-SUFFIX,dlive.tv,Proxy\nDOMAIN-SUFFIX,duoweitimes.com,Proxy\nDOMAIN-SUFFIX,wc.yooooo.us,Proxy\nDOMAIN-SUFFIX,www.xtend-life.cn,Proxy\nDOMAIN-SUFFIX,alexlur.org,Proxy\nDOMAIN-SUFFIX,giftedhomeschoolers.org,Proxy\nDOMAIN-SUFFIX,city9x.com,Proxy\nDOMAIN-SUFFIX,cedit.io,Proxy\nDOMAIN-SUFFIX,tuo8.org,Proxy\nDOMAIN-SUFFIX,brandibelle.com,Proxy\nDOMAIN-SUFFIX,dz3fhb1y09rad.cloudfront.net,Proxy\nDOMAIN-SUFFIX,google.cd,Proxy\nDOMAIN-SUFFIX,www.ntv.de,Proxy\n# GFWList 不能无损转换为 SR 规则，所以这里是对 GFWList 的补充\nDOMAIN-SUFFIX,i-scmp.com,Proxy\nDOMAIN-SUFFIX,search.xxx,Proxy\nIP-CIDR,50.7.31.230/32,Proxy\nDOMAIN-KEYWORD,blogspot,Proxy\nDOMAIN-KEYWORD,google,Proxy\nDOMAIN-SUFFIX,akamaihd.net,Proxy\nDOMAIN-SUFFIX,azurewebsites.net,Proxy\n# /twimg\\.edgesuite\\.net\\/\\/?appledaily\nDOMAIN-SUFFIX,4sqi.net,Proxy\n# hkheadline.com*blog\nDOMAIN-SUFFIX,news.now.com,Proxy\nDOMAIN-SUFFIX,picturedip.com,Proxy\n# bbs.sina.com%2F\n# dailynews.sina.com%2F\nDOMAIN-SUFFIX,uchicago.edu,Proxy\nDOMAIN-SUFFIX,xda-developers.com,Proxy\n# google.*/falun\nDOMAIN-KEYWORD,phobos,Proxy\n# q=freedom\n# q%3Dfreedom\n# search*safeweb\n# q=triangle\n# q%3DTriangle\n# 修复 Telegram #105\nIP-CIDR,67.198.55.0/24,Proxy\nIP-CIDR,91.108.4.0/22,Proxy\nIP-CIDR,91.108.8.0/22,Proxy\nIP-CIDR,91.108.12.0/22,Proxy\nIP-CIDR,91.108.16.0/22,Proxy\nIP-CIDR,91.108.56.0/22,Proxy\nIP-CIDR,109.239.140.0/24,Proxy\nIP-CIDR,149.154.160.0/20,Proxy\nIP-CIDR,149.154.164.0/22,Proxy\nIP-CIDR,149.154.168.0/22,Proxy\nIP-CIDR,149.154.172.0/22,Proxy\n# 修复 google voice #112\nIP-CIDR,74.125.23.127/32,Proxy\n# hacker news web site\nDOMAIN-SUFFIX,news.ycombinator.com,Proxy\n#TrustWallet\nDOMAIN-SUFFIX,trustwallet.com,Proxy\nDOMAIN-SUFFIX,walletconnect.org,Proxy\n\n\nRULE-SET,https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Shadowrocket/AppleNews/AppleNews.list,PROXY\n\nFINAL,direct\n\n[URL Rewrite]\n^https?://(www.)?(g|google)\\.cn https://www.google.com 302\n\n\n[MITM]\nhostname = *.google.cn,*.googlevideo.com\n\n# Made with Love from https://github.com/Johnshall/Shadowrocket-ADBlock-Rules-Forever\n"
  },
  {
    "path": "code/default/smart_router/local/user_rules.py",
    "content": "#!/usr/bin/env python\n# coding:utf-8\n\n\nimport os\n\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nroot_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))\n\nimport env_info\nimport utils\nfrom xlog import getLogger\nxlog = getLogger(\"smart_router\")\ndata_path = os.path.join(env_info.data_path, \"smart_router\")\n\n\nclass Config(object):\n    rule_list = [\"direct\", \"gae\", \"socks\", \"black\", \"redirect_https\"]\n\n    def __init__(self):\n        self.rule_lists = {}\n        self.host_rules = {}\n        self.end_rules = {}\n\n        self.redirect_https_host_rules = ()\n        self.redirect_https_end_rules = ()\n\n        self.load()\n\n    def save(self, rules_info):\n        for section in self.rule_list:\n            if section not in rules_info:\n                continue\n\n            value = rules_info[section]\n            fn = os.path.join(data_path, \"%s_list.txt\" % section)\n            with open(fn, \"w\") as fd:\n                fd.write(value)\n\n    def get_rules(self):\n        rules_info = {\n        }\n\n        for section in self.rule_list:\n            fn = os.path.join(data_path, \"%s_list.txt\" % section)\n            if not os.path.isfile(fn):\n                rules_info[section] = b\"\"\n                continue\n\n            with open(fn, \"r\") as fd:\n                content = fd.read()\n                rules_info[section] = content\n\n        return rules_info\n\n    def parse_rules(self, content):\n        end_fix = []\n        hosts = []\n\n        content = utils.to_bytes(content)\n\n        content = content.replace(b\",\", b\"\\n\").replace(b\";\", b\"\\n\")\n        lines = content.split(b\"\\n\")\n        for line in lines:\n            line = line.strip()\n            if not line:\n                continue\n\n            if b\"=\" in line:\n                lp = line.split(b\"=\")\n                left = lp[0].strip()\n                right = lp[1].strip()\n            else:\n                left = line\n                right = None\n\n            if left.startswith(b\"http://\"):\n                left = left[7:]\n            if left.startswith(b\"https://\"):\n                left = left[8:]\n            if left.startswith(b\"*\"):\n                left = left[1:]\n            if b\"/\" in left:\n                p = left.find(b\"/\")\n                host = left[:p]\n            else:\n                host = left\n\n            if host.startswith(b\".\"):\n                end_fix.append(host)\n            elif host.startswith(b\"*.\"):\n                end_fix.append(host[1:])\n            else:\n                hosts.append(host)\n\n        return hosts, end_fix\n\n    def load(self):\n        self.host_rules = {}\n        self.end_rules = {}\n\n        for section in self.rule_list:\n            self.rule_lists[section] = tuple()\n            fn = os.path.join(data_path, \"%s_list.txt\" % section)\n            if not os.path.isfile(fn):\n                continue\n\n            with open(fn, \"r\") as fd:\n                content = fd.read()\n                hosts, end_fix = self.parse_rules(content)\n                self.rule_lists[section] = tuple(hosts + end_fix)\n                if section == \"redirect_https\":\n                    self.redirect_https_host_rules = tuple(utils.to_bytes(hosts))\n                    self.redirect_https_end_rules = tuple(utils.to_bytes(end_fix))\n                else:\n                    for host in hosts:\n                        self.host_rules[host] = section\n\n                    if len(end_fix):\n                        self.end_rules[section] = tuple(utils.to_bytes(end_fix))\n\n    def check_host(self, domain, port=None):\n        domain = utils.to_bytes(domain)\n        if port == 80:\n            if domain in self.redirect_https_host_rules or domain.endswith(self.redirect_https_end_rules):\n                return \"redirect_https\"\n\n        if domain in self.host_rules:\n            return self.host_rules[domain]\n\n        for sec in self.end_rules:\n            try:\n                if domain.endswith(self.end_rules[sec]):\n                    return sec\n            except Exception as e:\n                xlog.exception(\"check_host domain:%s sec:%s self.end_rules[sec]\", domain, sec, self.end_rules[sec])\n"
  },
  {
    "path": "code/default/smart_router/local/web_control.py",
    "content": "#!/usr/bin/env python\n# coding:utf-8\n\nimport os\n\ntry:\n    from urllib.parse import urlparse, parse_qs\nexcept ImportError:\n    from urlparse import urlparse, parse_qs\n\nfrom xlog import getLogger\nxlog = getLogger(\"smart_router\")\n\nimport simple_http_server\nfrom . import pac_server\nfrom . import global_var as g\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nroot_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))\nweb_ui_path = os.path.join(current_path, os.path.pardir, \"web_ui\")\n\n\nclass ControlHandler(simple_http_server.HttpServerHandler):\n    def __init__(self, client_address, headers, command, path, rfile, wfile):\n        self.client_address = client_address\n        self.headers = headers\n        self.command = command\n        self.path = path\n        self.rfile = rfile\n        self.wfile = wfile\n\n    def do_GET(self):\n        path = urlparse(self.path).path\n        if path == \"/log\":\n            return self.req_log_handler()\n        elif path == \"/status\":\n            return self.req_status()\n        else:\n            xlog.warn('Control Req %s %s %s ', self.address_string(), self.command, self.path)\n\n    def do_POST(self):\n        xlog.debug('Web_control %s %s %s ', self.address_string(), self.command, self.path)\n\n        path = urlparse(self.path).path\n        if path == '/rules':\n            return self.req_rules_handler()\n        elif path == \"/cache\":\n            return self.req_cache_handler()\n        elif path == \"/config\":\n            return self.req_config_handler()\n        else:\n            xlog.info('%s \"%s %s HTTP/1.1\" 404 -', self.address_string(), self.command, self.path)\n            return self.send_not_found()\n\n    def req_log_handler(self):\n        req = urlparse(self.path).query\n        reqs = self.unpack_reqs(parse_qs(req, keep_blank_values=True))\n        data = ''\n\n        if reqs[\"cmd\"]:\n            cmd = reqs[\"cmd\"]\n        else:\n            cmd = \"get_last\"\n\n        if cmd == \"get_last\":\n            max_line = int(reqs[\"max_line\"])\n            data = xlog.get_last_lines(max_line)\n        elif cmd == \"get_new\":\n            last_no = int(reqs[\"last_no\"])\n            data = xlog.get_new_lines(last_no)\n        else:\n            xlog.error('xtunnel log cmd:%s', cmd)\n\n        mimetype = 'text/plain'\n        self.send_response(mimetype, data)\n\n    def req_rules_handler(self):\n        reqs = self.postvars\n\n        if \"cmd\" in reqs and reqs[\"cmd\"]:\n            cmd = reqs[\"cmd\"]\n        else:\n            cmd = \"get\"\n\n        if cmd == \"get\":\n            rules = g.user_rules.get_rules()\n            rules[\"res\"] = \"success\"\n            return self.response_json(rules)\n        elif cmd == \"set\":\n            g.user_rules.save(reqs)\n            g.user_rules.load()\n            return self.response_json({\"res\": \"OK\"})\n\n    def req_config_handler(self):\n        reqs = self.postvars\n        if \"cmd\" in reqs and reqs[\"cmd\"]:\n            cmd = reqs[\"cmd\"]\n        else:\n            cmd = \"get\"\n\n        if cmd == \"get\":\n            data = {\n                \"gae_enabled\": g.gae_proxy is not None,\n                \"pac_policy\": g.config.pac_policy,\n                \"country\": g.config.country_code,\n                \"auto_direct\":g.config.auto_direct,\n                \"auto_direct6\":g.config.auto_direct6,\n                \"auto_gae\": g.config.auto_gae,\n                \"enable_fake_ca\": g.config.enable_fake_ca,\n                \"bypass_speedtest\": g.config.bypass_speedtest,\n                \"block_advertisement\": g.config.block_advertisement\n            }\n            return self.response_json(data)\n        elif cmd == \"set\":\n            if \"pac_policy\" in reqs:\n                pac_policy = reqs[\"pac_policy\"]\n                if pac_policy not in pac_server.allow_policy:\n                    return self.response_json({\"res\": \"fail\", \"reason\": \"policy not allow\"})\n\n                g.config.pac_policy = pac_policy\n            if \"country\" in reqs:\n                g.config.country_code = reqs[\"country\"]\n            if \"auto_direct\" in reqs:\n                g.config.auto_direct = int(reqs[\"auto_direct\"])\n            if \"auto_direct6\" in reqs:\n                g.config.auto_direct6 = int(reqs[\"auto_direct6\"])\n            if \"auto_gae\" in reqs:\n                g.config.auto_gae = int(reqs[\"auto_gae\"])\n            if \"enable_fake_ca\" in reqs:\n                g.config.enable_fake_ca = int(reqs[\"enable_fake_ca\"])\n            if \"bypass_speedtest\" in reqs:\n                g.config.bypass_speedtest = int(reqs[\"bypass_speedtest\"])\n            if \"block_advertisement\" in reqs:\n                g.config.block_advertisement = int(reqs[\"block_advertisement\"])\n            g.config.save()\n            return self.response_json({\"res\": \"success\"}, headers={\"Access-Control-Allow-Origin\": \"*\"})\n\n    def req_cache_handler(self):\n        reqs = self.postvars\n        if \"cmd\" in reqs and reqs[\"cmd\"]:\n            cmd = reqs[\"cmd\"]\n        else:\n            cmd = \"get\"\n\n        if cmd == \"get\":\n            g.domain_cache.save(True)\n            g.ip_cache.save(True)\n            data = {\n                \"domain_cache_list\": g.domain_cache.get_content(),\n                \"ip_cache_list\": g.ip_cache.get_content(),\n                \"res\": \"success\"\n            }\n            return self.response_json(data)\n        elif cmd == \"clean\":\n            g.domain_cache.clean()\n            g.ip_cache.clean()\n            return self.response_json({\"res\": \"success\"})\n\n    def req_status(self):\n        out_str = \"pipe status:\\n\" + str(g.pipe_socks)\n        self.send_response(\"text/plain\", out_str)\n\n"
  },
  {
    "path": "code/default/smart_router/scripts/update_domain_list.py",
    "content": "import os\nimport sys\nfrom os.path import join\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nlocal_path = os.path.abspath( os.path.join(current_path, os.pardir, \"local\"))\nroot_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))\nnoarch_path = join(root_path, \"lib\", \"noarch\")\nsys.path.append(noarch_path)\n\n\nimport simple_http_client\nimport utils\n\n\ndef download_list(url):\n    res = simple_http_client.request(\"GET\", url)\n    content = res.text\n    return utils.to_str(content)\n\n\ndef parse_list(content):\n    black_suffix = []\n    black_keyword = []\n    black_ipmask = []\n    for line in content.split():\n        if not line or line.startswith(\"#\"):\n            continue\n\n        if line.startswith(\"DOMAIN-SUFFIX,\") and line.endswith(\",Proxy\"):\n            _, suffix, _ = line.split(\",\")[0:3]\n            black_suffix.append(suffix)\n\n        if line.startswith(\"DOMAIN-KEYWORD,\") and line.endswith(\",Proxy\"):\n            _, keyword, _ = line.split(\",\")[0:3]\n            black_keyword.append(keyword)\n\n        if line.startswith(\"IP-CIDR,\") and line.endswith(\",Proxy\"):\n            _, ipmask, _ = line.split(\",\")[0:3]\n            black_ipmask.append(ipmask)\n\n    black_suffix.sort()\n    black_keyword.sort()\n    black_ipmask.sort()\n\n    return black_suffix, black_keyword, black_ipmask\n\n\ndef update_blacklist():\n    # url = \"https://github.com/Johnshall/Shadowrocket-ADBlock-Rules-Forever/raw/release/sr_top500_banlist.conf\"\n    url = \"https://raw.githubusercontent.com/Johnshall/Shadowrocket-ADBlock-Rules-Forever/release/sr_top500_banlist.conf\"\n    content = download_list(url)\n    black_suffix, black_keyword, black_ipmask = parse_list(content)\n\n    with open(join(local_path, \"gfw_black_list.txt\"), \"w\") as fd:\n        fd.write(\"\\r\\n\".join(black_suffix))\n\n    with open(join(local_path, \"gfw_black_keywords.txt\"), \"w\") as fd:\n        fd.write(\"\\r\\n\".join(black_keyword))\n\n\nif __name__ == \"__main__\":\n    update_blacklist()\n"
  },
  {
    "path": "code/default/smart_router/tests/test_black_list.py",
    "content": "import os\nfrom os.path import join\nimport sys\nimport unittest\n\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nsmart_route_path = os.path.abspath(os.path.join(current_path, os.path.pardir))\nlocal_path = os.path.join(smart_route_path, \"local\")\nsys.path.append(local_path)\n\ndefault_path = os.path.abspath(join(smart_route_path, os.path.pardir))\nnoarch_path = join(default_path, \"lib\", \"noarch\")\nsys.path.append(noarch_path)\n\nimport gfwlist\n\n\nclass TestGFW(unittest.TestCase):\n    def test_Ip_Mask(self):\n        ip = \"1.2.3.4\"\n        ip_mask = \"1.2.3.0/24\"\n        ip_masks = [ip_mask]\n        subnets = gfwlist.IpMask(ip_masks)\n        c = subnets.check_ip(ip)\n        print(c)\n\n        print(subnets.check_ip(\"1.2.3.5\"))\n        print(subnets.check_ip(\"1.2.4.5\"))\n        print(subnets.check_ip(\"1.3.4.5\"))\n\n    def test_domain(self):\n        gfw = gfwlist.GfwList()\n        print(gfw.ip_in_black_list(\"91.108.56.1\"))\n        print(gfw.ip_in_black_list(\"1.1.1.1\"))\n\n    def test_keyword(self):\n        gfw = gfwlist.GfwList()\n        print(gfw.in_block_list(b\"www.amazon.com\"))\n        print(gfw.in_block_list(b\"www.apple.com\"))\n"
  },
  {
    "path": "code/default/smart_router/tests/test_dns_query.py",
    "content": "import json\nimport time\nfrom unittest import TestCase\nimport os\nimport sys\n\nimport requests\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\ndefault_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))\nnoarch_path = os.path.abspath(os.path.join(default_path, 'lib', \"noarch\"))\nsys.path.append(noarch_path)\nsys.path.append(default_path)\n\nfrom dnslib.dns import DNSRecord, DNSQuestion, QTYPE\nfrom smart_router.local.dns_query import LocalDnsQuery, DnsOverHttpsQuery, g\n\n\nclass MockConfig(object):\n    def __init__(self):\n        self.PROXY_ENABLE = False\n\nclass TestDnsQuery(TestCase):\n    def test_local_udp_query(self):\n\n        qr = LocalDnsQuery()\n        ips = qr.query('www.microsoft.com', timeout=1000)\n        self.assertTrue(len(ips) > 0)\n        qr.stop()\n\n    # def test_dns_server(self):\n    #     query = DNSRecord(q=DNSQuestion(\"mtalk.google.com\", getattr(QTYPE, \"AAAA\")))\n    #     a_pkt = query.send(\"127.0.0.1\", 53, tcp=False, timeout=5)\n    #     a = DNSRecord.parse(a_pkt)\n    #     print(a)\n\n    def test_DoH_json_query(self):\n        servers = [\n            # \"https://1.1.1.1/dns-query\",\n            # \"https://dns10.quad9.net/dns-query\",\n            # \"https://dns.aa.net.uk/dns-query\",\n            \"https://doh.la.ahadns.net/dns-query\"\n        ]\n        domain = \"vs6.85po.com\"\n        for server in servers:\n            url = server + \"?name=\" + domain + \"&type=A\"  # type need to map to Text.\n            r = requests.request(\"GET\", url, headers={\"accept\": \"application/dns-json\"})\n            ips = []\n            if not r:\n                print(f\"{server} failed\")\n                continue\n\n            t = r.text.encode(\"utf-8\")\n\n            data = json.loads(t)\n            for answer in data[\"Answer\"]:\n                ips.append(answer[\"data\"])\n\n            print(f\"server:{server} ips: {ips}\")\n\n    def test_DoH_query(self):\n        g.config = MockConfig()\n        qr = DnsOverHttpsQuery()\n        domain = \"vs6.85po.com\"\n        for url in [\n            \"https://1.1.1.1/dns-query\",\n            \"https://dns10.quad9.net/dns-query\",\n            \"https://dns.aa.net.uk/dns-query\",\n            \"https://freedns.controld.com/p0\"\n        ]:\n            t0 = time.time()\n            ips = qr.query(domain, url=url)\n            t1 = time.time()\n            print(f\"use {url} ips:{ips} cost:{t1-t0}\")\n"
  },
  {
    "path": "code/default/smart_router/tests/test_set_policy.py",
    "content": "import requests\nimport re\nfrom unittest import TestCase\n\n\nclass TestSetPolicy(TestCase):\n    def test_set_global(self):\n        url = \"http://localhost:8085/module/smart_router/control/config\"\n        headers = {\n            \"Content-Type\": \"application/json\"\n        }\n        data = {\n            \"cmd\": \"set\",\n            \"pac_policy\": \"all_X-Tunnel\"\n        }\n        r = requests.post(url, json=data, headers=headers)\n        print(r.text)\n\n    def test_set_smart(self):\n        url = \"http://localhost:8085/module/smart_router/control/config\"\n        headers = {\n            \"Content-Type\": \"application/json\"\n        }\n        data = {\n            \"cmd\": \"set\",\n            \"pac_policy\": \"smart-router\"\n        }\n        r = requests.post(url, json=data, headers=headers)\n        print(r.text)\n\n    def test_match(self):\n        r = re.compile(\"google|apple\")\n        s1 = \"www.google.com\"\n        s2 = \"www.apple.com\"\n        s3 = \"www.ms.com\"\n        g1 = r.search(s1)\n        print(g1)\n        g2 = r.search(s2)\n        print(g2)\n        g3 = r.search(s3)\n        print(g3)\n\n    def test_re(self):\n        strs = 'Test result 1: Not Ok -31.08'\n        g = re.search(r'\\bNot Ok\\b', strs).group(0)\n        print(g)"
  },
  {
    "path": "code/default/smart_router/web_ui/config.html",
    "content": "\n<ul class=\"nav nav-tabs\">\n    <li class=\"active\"><a class=\"config_tab\" id=\"general\" data-toggle=\"tab\">{{ _( \"General\" ) }}</a></li>\n    <li><a class=\"config_tab\" id=\"rules\" data-toggle=\"tab\">{{ _( \"Rules\" ) }}</a></li>\n    <li><a class=\"config_tab\" id=\"cache\" data-toggle=\"tab\">{{ _( \"Cache\" ) }}</a></li>\n</ul>\n\n<div id=\"config_content\" class=\"tab-content\">\n    <div id=\"tab_content\" class=\"tab-pane fade in active\">\n    </div>\n</div>\n\n\n<!-- JavaScript -->\n<script type=\"text/javascript\">\n    title('{{ _( \"Smart Router Configuration\" ) }}');\n</script>\n<script type=\"text/javascript\">\n    $(\".config_tab\").click(function () {\n        var id = $(this).attr('id');\n        var url = \"/module/smart_router/config_\" + id + \".html\";\n        $(\"#tab_content\").load(url);\n    });\n    $(\"#tab_content\").load(\"/module/smart_router/config_general.html\");\n</script>\n"
  },
  {
    "path": "code/default/smart_router/web_ui/config_cache.html",
    "content": "<form method=\"POST\" onSubmit=\"onSubmit(); return false;\">\n\n    <div class=\"row-fluid\">\n        <div class=\"span12\">\n            <button class=\"btn btn-primary btn-block\" type=\"submit\">{{ _( \"Clean Cache\" ) }}</button>\n        </div> <!-- .span12 -->\n    </div> <!-- .row-fluid -->\n\n    <div class=\"row-fluid\">\n        <div class=\"span2\">\n            <label for=\"domain-cache-list\">{{ _( \"Domain Cache\" ) }}</label>\n        </div> <!-- .span2 -->\n        <div class=\"span10\">\n            <textarea id=\"domain-cache-list\" rows=\"50\" wrap=\"off\"></textarea>\n        </div> <!-- .span10 -->\n    </div> <!-- .row-fluid -->\n\n    <div class=\"row-fluid\">\n        <div class=\"span2\">\n            <label for=\"ip-cache-list\">{{ _( \"IP Cache\" ) }}</label>\n        </div> <!-- .span2 -->\n        <div class=\"span10\">\n            <textarea id=\"ip-cache-list\" rows=\"50\" wrap=\"off\"></textarea>\n        </div> <!-- .span10 -->\n    </div> <!-- .row-fluid -->\n\n</form> <!-- #import-export-ip -->\n\n<script type=\"text/javascript\">\n    function loadCacheList() {\n        $.ajax({\n            type: 'POST',\n            url: '/module/smart_router/control/cache',\n            data: {},\n            dataType: 'JSON',\n            success: function (result) {\n                if (result['res'] == 'success') {\n                    {\n                        $('#domain-cache-list').val(result['domain_cache_list']);\n                        $('#ip-cache-list').val(result['ip_cache_list']);\n                    }\n                } else {\n                    displayErrorMessage();\n                }\n            },\n            error: function () {\n                displayErrorMessage();\n            }\n        });\n    }\n\n    loadCacheList();\n\n    function onSubmit() {\n        var postData = {\n            'cmd': \"clean\"\n        };\n        $.ajax({\n            type: 'POST',\n            url: '/module/smart_router/control/cache',\n            data: postData,\n            dataType: 'JSON',\n            success: function (result) {\n                loadCacheList();\n                tip('{{ _( \"Clean Cache successfully.\" ) }}', 'success');\n            },\n            error: function () {\n                displayErrorMessage();\n            }\n        });\n    }\n</script>\n"
  },
  {
    "path": "code/default/smart_router/web_ui/config_general.html",
    "content": "<div id=\"options\">\n\n    <div class=\"row-fluid\">\n        <div class=\"span4\">\n            <label for=\"country\">{{ _( \"Country\" ) }}</label>\n        </div>\n        <div class=\"span4\">\n            <select id=\"country\">\n                <!-- <option value=\"de_DE\">Deutsch</option> -->\n                <option value=\"CN\">{{ _(\"China\" ) }}</option>\n                <!-- <option value=\"es_VE\">Español</option> -->\n                <option value=\"XX\">{{ _(\"Other\" ) }}</option>\n            </select>\n        </div>\n    </div>\n\n    <div class=\"row-fluid\">\n        <div class=\"span4\">\n            <label for=\"pac-policy\">{{ _( \"Route Policy\" ) }}</label>\n        </div>\n        <div class=\"span4\">\n            <select id=\"pac-policy\">\n<!--                <option value=\"black_X-Tunnel\">{{ _(\"Black->X-Tunnel\" ) }}</option>-->\n                <option value=\"smart-router\">{{ _(\"All Smart-Router\" ) }}</option>\n                <option value=\"all_X-Tunnel\">{{ _(\"All->X-Tunnel\" ) }}</option>\n                <option value=\"all_Direct\">{{ _(\"All->Direct\" ) }}</option>\n            </select>\n        </div>\n    </div>\n\n    <div class=\"row-fluid\">\n        <div class=\"config_label\">{{ _( \"Auto-Try Direct\" ) }}</div> <!-- .span4 -->\n        <div class=\"config_switch\">\n            <input id=\"auto-direct\" type=\"checkbox\" data-toggle=\"switch\"/>\n        </div> <!-- .span8 -->\n    </div> <!-- .row-fluid -->\n\n    <div class=\"row-fluid\">\n        <div class=\"config_label\">{{ _( \"Use IPv6 preferentially when Auto-Try Direct\" ) }}</div> <!-- .span4 -->\n        <div class=\"config_switch\">\n            <input id=\"auto-direct6\" type=\"checkbox\" data-toggle=\"switch\"/>\n        </div> <!-- .span8 -->\n    </div> <!-- .row-fluid -->\n\n    <div class=\"row-fluid\" id=\"auto_try_gae_proxy_div\" hidden>\n        <div class=\"config_label\">{{ _( \"Auto-Try GAEProxy\" ) }}</div> <!-- .span4 -->\n        <div class=\"config_switch\">\n            <input id=\"auto-gae\" type=\"checkbox\" data-toggle=\"switch\"/>\n        </div> <!-- .span8 -->\n    </div> <!-- .row-fluid -->\n\n    <div class=\"row-fluid\" id=\"enable_fake_ca_div\" hidden>\n        <div class=\"config_label\">{{ _( \"Enable Fake CA\" ) }}</div> <!-- .span4 -->\n        <div class=\"config_switch\">\n            <input id=\"enable_fake_ca\" type=\"checkbox\" data-toggle=\"switch\"/>\n        </div> <!-- .span8 -->\n    </div> <!-- .row-fluid -->\n\n    <div class=\"row-fluid\">\n        <div class=\"config_label\">{{ _( \"Bypass Speed Test Sites\" ) }}</div> <!-- .span4 -->\n        <div class=\"config_switch\">\n            <input id=\"bypass_speedtest\" type=\"checkbox\" data-toggle=\"switch\"/>\n        </div> <!-- .span8 -->\n    </div> <!-- .row-fluid -->\n\n    <div class=\"row-fluid\">\n        <div class=\"config_label\">{{ _( \"Block Advertisement\" ) }}</div> <!-- .span4 -->\n        <div class=\"config_switch\">\n            <input id=\"block_advertisement\" type=\"checkbox\" data-toggle=\"switch\"/>\n        </div> <!-- .span8 -->\n    </div> <!-- .row-fluid -->\n</div>\n\n\n<script type=\"text/javascript\">\n    $(function () {\n        $('[data-toggle=switch]').wrap('<div class=\"switch\" />').parent().bootstrapSwitch();\n    });\n</script>\n<script type=\"text/javascript\">\n    if (gae_enabled){\n        var new_option = document.getElementById(\"pac-policy\").appendChild(document.createElement(\"option\"));\n        new_option.value = \"{{ _(\"Black->GAEProxy\" ) }}\";\n        new_option.text = \"black_GAE\";\n\n        $(\"#auto_try_gae_proxy_div\").show();\n        $(\"#enable_fake_ca_div\").show();\n    }\n\n    function getSmartRouterConfig() {\n        $.ajax({\n            type: 'POST',\n            url: '/module/smart_router/control/config',\n            success: function (result) {\n                if (result['auto_direct'] != 0) {\n                    $(\"#auto-direct\").parent().removeClass('switch-off');\n                    $(\"#auto-direct\").parent().addClass('switch-on');\n\n                    $(\"#auto-direct\").prop('checked', true);\n                }\n                if (result['auto_direct6'] != 0) {\n                    $(\"#auto-direct6\").parent().removeClass('switch-off');\n                    $(\"#auto-direct6\").parent().addClass('switch-on');\n\n                    $(\"#auto-direct6\").prop('checked', true);\n                }\n\n                if (result['auto_gae'] != 0) {\n                    $(\"#auto-gae\").parent().removeClass('switch-off');\n                    $(\"#auto-gae\").parent().addClass('switch-on');\n\n                    $(\"#auto-gae\").prop('checked', true);\n                }\n                if (result['enable_fake_ca'] != 0) {\n                    $(\"#enable_fake_ca\").parent().removeClass('switch-off');\n                    $(\"#enable_fake_ca\").parent().addClass('switch-on');\n\n                    $(\"#enable_fake_ca\").prop('checked', true);\n                }\n                if (result['bypass_speedtest'] != 0) {\n                    $(\"#bypass_speedtest\").parent().removeClass('switch-off');\n                    $(\"#bypass_speedtest\").parent().addClass('switch-on');\n\n                    $(\"#bypass_speedtest\").prop('checked', true);\n                }\n                if (result['block_advertisement'] != 0) {\n                    $(\"#block_advertisement\").parent().removeClass('switch-off');\n                    $(\"#block_advertisement\").parent().addClass('switch-on');\n\n                    $(\"#block_advertisement\").prop('checked', true);\n                }\n                $(\"#country\").val(result['country']);\n                $(\"#pac-policy\").val(result['pac_policy']);\n            },\n            error: function () {\n                displayErrorMessage();\n            }\n        });\n    }\n\n    getSmartRouterConfig();\n</script>\n<script type=\"text/javascript\">\n    function setSmartRouterConfig(key, value) {\n        var pageRequests = {\n            'cmd': 'set'\n        };\n        pageRequests[key] = value;\n\n        $.ajax({\n            type: 'POST',\n            url: '/module/smart_router/control/config',\n            data: pageRequests,\n            dataType: 'JSON',\n            success: function (result) {\n                if (result['res'] == 'success') {\n                    tip('{{ _( \"Settings saved successfully.\" ) }}', 'success');\n                } else {\n                    displayErrorMessage();\n                }\n            },\n            error: function () {\n                displayErrorMessage();\n            }\n        });\n    }\n\n    $('#country').change(function () {\n        setSmartRouterConfig(\"country\", $('#country').val());\n    });\n\n    $('#pac-policy').change(function () {\n        setSmartRouterConfig(\"pac_policy\", $('#pac-policy').val());\n    });\n\n    $('#auto-direct').change(function () {\n        setSmartRouterConfig(\"auto_direct\", $(this).is(':checked') ? 1 : 0);\n    });\n\n    $('#auto-direct6').change(function () {\n        setSmartRouterConfig(\"auto_direct6\", $(this).is(':checked') ? 1 : 0);\n    });\n\n    $('#auto-gae').change(function () {\n        setSmartRouterConfig(\"auto_gae\", $(this).is(':checked') ? 1 : 0);\n    });\n\n    $('#enable_fake_ca').change(function () {\n        setSmartRouterConfig(\"enable_fake_ca\", $(this).is(':checked') ? 1 : 0);\n    });\n\n    $('#bypass_speedtest').change(function () {\n        setSmartRouterConfig(\"bypass_speedtest\", $(this).is(':checked') ? 1 : 0);\n    });\n\n    $('#block_advertisement').change(function () {\n        setSmartRouterConfig(\"block_advertisement\", $(this).is(':checked') ? 1 : 0);\n    });\n</script>\n"
  },
  {
    "path": "code/default/smart_router/web_ui/config_rules.html",
    "content": "<form method=\"POST\" onSubmit=\"onSubmit(); return false;\">\n    <a href=\"{{ _( \"https://github.com/XX-net/XX-Net/wiki/SmartRouter_rules_en\" ) }}\" target=\"_blank\">{{ _( \"Help documents\" ) }}</a>\n    <div class=\"row-fluid\">\n        <div class=\"span2\">\n            <label for=\"direct-list\">{{ _( \"Direct List\" ) }}</label>\n        </div> <!-- .span2 -->\n        <div class=\"span10\">\n            <textarea id=\"direct-list\" rows=\"10\"></textarea>\n        </div> <!-- .span10 -->\n    </div> <!-- .row-fluid -->\n\n    <div class=\"row-fluid\" id=\"gae-list-div\" hidden>\n        <div class=\"span2\">\n            <label for=\"gae-list\">{{ _( \"GAEProxy List\" ) }}</label>\n        </div> <!-- .span2 -->\n        <div class=\"span10\">\n            <textarea id=\"gae-list\" rows=\"10\"></textarea>\n        </div> <!-- .span10 -->\n    </div> <!-- .row-fluid -->\n\n    <div class=\"row-fluid\">\n        <div class=\"span2\">\n            <label for=\"socks-list\">{{ _( \"X-Tunnel List\" ) }}</label>\n        </div> <!-- .span2 -->\n        <div class=\"span10\">\n            <textarea id=\"socks-list\" rows=\"10\"></textarea>\n        </div> <!-- .span10 -->\n    </div> <!-- .row-fluid -->\n\n    <div class=\"row-fluid\" hidden>\n        <div class=\"span2\">\n            <label for=\"redirect-https-list\">{{ _( \"Redirect HTTPS\" ) }}</label>\n        </div> <!-- .span2 -->\n        <div class=\"span10\">\n            <textarea id=\"redirect-https-list\" rows=\"10\"></textarea>\n        </div> <!-- .span10 -->\n    </div> <!-- .row-fluid -->\n\n    <div class=\"row-fluid\">\n        <div class=\"span2\">\n            <label for=\"black-list\">{{ _( \"Advertisement Black List\" ) }}</label>\n        </div> <!-- .span2 -->\n        <div class=\"span10\">\n            <textarea id=\"black-list\" rows=\"10\"></textarea>\n        </div> <!-- .span10 -->\n    </div> <!-- .row-fluid -->\n\n    <div class=\"row-fluid\">\n        <div class=\"span12\">\n            <button class=\"btn btn-primary btn-block\" type=\"submit\">{{ _( \"Submit\" ) }}</button>\n        </div> <!-- .span12 -->\n    </div> <!-- .row-fluid -->\n\n</form> <!-- #import-export-ip -->\n\n<script type=\"text/javascript\">\n\n    if (gae_enabled){\n        $(\"#gae-list-div\").show();\n    }\n    $.ajax({\n        type: 'POST',\n        url: '/module/smart_router/control/rules',\n        data: {},\n        dataType: 'JSON',\n        success: function (result) {\n            if (result['res'] == 'success') {\n                {\n                    $('#direct-list').val(result['direct']);\n                    $('#gae-list').val(result['gae']);\n                    $('#socks-list').val(result['socks']);\n                    $('#black-list').val(result['black']);\n                    $('#redirect-https-list').val(result['redirect_https']);\n                }\n            } else {\n                displayErrorMessage();\n            }\n        },\n        error: function () {\n            displayErrorMessage();\n        }\n    });\n\n    function onSubmit() {\n        var postData = {\n            'direct': $('#direct-list').val(),\n            'gae': $('#gae-list').val(),\n            'socks': $('#socks-list').val(),\n            'black': $('#black-list').val(),\n            'redirect_https': $('#redirect-https-list').val(),\n            'cmd': \"set\"\n        };\n\n        $.ajax({\n            type: 'POST',\n            url: '/module/smart_router/control/rules',\n            data: postData,\n            dataType: 'JSON',\n            success: function (result) {\n                tip('{{ _( \"Settings saved successfully.\" ) }}', 'success');\n            },\n            error: function () {\n                displayErrorMessage();\n            }\n        });\n    }\n</script>\n"
  },
  {
    "path": "code/default/smart_router/web_ui/logging.html",
    "content": "<div id=\"log-container\" class=\"row-fluid\">\n    <div id=\"log\" class=\"span12\"></div> <!-- #log -->\n</div> <!-- #log-container -->\n\n<script type=\"text/javascript\">\n    title('{{ _(\"Smart Router Log\") }}');\n</script>\n<style type=\"text/css\">\n    .DUMMY { color: black }\n    .DEBUG { color: #21610b }\n    .INFO { color: blue }\n    .WARNING { color: #ff8000 }\n    .ERROR { color: #fe2e2e }\n    .CRITICAL { color: #d7df01 }\n</style>\n<script type=\"text/javascript\">\n    $(function () {\n        resizeLogWindow();\n    });\n\n    $(window).resize(function () {\n        resizeLogWindow();\n    });\n</script>\n<script type=\"text/javascript\">\n    function resizeLogWindow() {\n        var windowHeight    = $(window).height(),\n            preservedHeight = 170;\n\n        $('#log').css('height', windowHeight - preservedHeight);\n    }\n</script>\n<script type=\"text/javascript\">\n    $(function () {\n        window.previousOffset     = 0;\n        window.offset             = 1;\n        window.logLineNum         = 0;\n        window.isAutoScrollLog    = true;\n        window.isgetLogProcessing = false;\n\n        var timer = $.timer(function () {\n            getLog();\n        });\n        timer.set({\n            time: 500,\n            autostart: true\n        });\n    });\n</script>\n<script type=\"text/javascript\">\n    $(function () {\n        getLog();\n    });\n</script>\n<script type=\"text/javascript\">\n    $('#log').scroll(function () {\n        var preservedHeight = $('#log').height() + 10,\n            scrollHeight    = $('#log')[0].scrollHeight,\n            scrollTop       = $('#log').scrollTop();\n\n        window.isAutoScrollLog = (scrollTop + preservedHeight === scrollHeight);\n    });\n</script>\n<script type=\"text/javascript\">\n    function scrollLog() {\n        if (window.isAutoScrollLog) {\n            $('#log').scrollTop($('#log')[0].scrollHeight);\n        }\n    }\n</script>\n<script type=\"text/javascript\">\n    function getLog() {\n        if (window.isgetLogProcessing) {\n            return;\n        }\n        if (!window.isAutoScrollLog) {\n            return;\n        }\n        window.isgetLogProcessing = true;\n\n        var pageRequests = {\n            'cmd': 'get_new',\n            'last_no': offset\n        };\n        $.ajax({\n            type: 'GET',\n            url: '/module/smart_router/control/log',\n            data: pageRequests,\n            dataType: 'JSON',\n            success: function (result) {\n                var newlines = document.createDocumentFragment();\n                var newlineNum = 0;\n                $.each(result, function (lineNumber, log) {\n                    window.offset = lineNumber;\n\n                    var logTemplate = '<p class=\"%s\">%s</p>\\n';\n                    if (window.previousOffset != window.offset) {\n                        var newline = $(logTemplate.format(getLogLevel(log), log));\n                        $(newlines).append(newline);\n                        newlineNum += 1;\n                    }\n                });\n                window.logLineNum += newlineNum;\n                $('#log').append(newlines);\n                var maxLineNum = 1000;\n                var cutStep = 10;\n                if (window.logLineNum > maxLineNum + cutStep) {\n                    var numToCut = window.logLineNum - maxLineNum;\n                    var textblock = $('#log').html();\n                    var lines = textblock.split('\\n');\n                    lines.splice(0, numToCut);\n                    var newtext = lines.join('\\n');\n                    $('#log').html(newtext);\n                    window.logLineNum -= numToCut;\n                }\n\n                scrollLog();\n                window.previousOffset = window.offset;\n                window.isgetLogProcessing = false;\n            },\n            error: function (xml, info, obj) {\n                window.isgetLogProcessing = false;\n            }\n        });\n    }\n</script>\n<script type=\"text/javascript\">\n    function getLogLevel(log) {\n        if (log.indexOf('[DEBUG]') != -1) {\n            return 'DEBUG';\n        } else if (log.indexOf('[INFO]') != -1) {\n            return 'INFO';\n        } else if (log.indexOf('[WARNING]') != -1) {\n            return 'WARNING';\n        } else if (log.indexOf('[ERROR]') != -1) {\n            return 'ERROR';\n        } else if (log.indexOf('[CRITICAL]') != -1) {\n            return 'CRITICAL';\n        } else return 'DUMMY';\n    }\n</script>\n"
  },
  {
    "path": "code/default/smart_router/web_ui/menu.json",
    "content": "{\n  \"module_title\": \"{{ _( \"Smart Router\" ) }}\",\n  \"menu_sort_id\": 6,\n  \"sub_menus\": {\n    \"1\":{\n      \"title\": \"{{ _( \"Configuration\" ) }}\",\n      \"url\": \"config\"\n    },\n    \"2\":{\n      \"title\": \"{{ _(\"Log\") }}\",\n      \"url\": \"logging\"\n    }\n  }\n}"
  },
  {
    "path": "code/default/update_v5.txt",
    "content": "\n## 升级(Update)：\n测试版(Test)：\nhttps://codeload.github.com/XX-net/XX-Net/zip/5.9.0 215cbf9091c2ba852528630ce9c668d20bd92687cf7c87dbe31440d131369cb8\n\n\n\n稳定版(Stable)：\nhttps://codeload.github.com/XX-net/XX-Net/zip/5.9.0 215cbf9091c2ba852528630ce9c668d20bd92687cf7c87dbe31440d131369cb8\n"
  },
  {
    "path": "code/default/version.txt",
    "content": "5.16.6"
  },
  {
    "path": "code/default/x_tunnel/__init__.py",
    "content": "__all__ = [\"local\"]"
  },
  {
    "path": "code/default/x_tunnel/babel.config",
    "content": "# Extraction from Python source files\n#[python: **.py]\n\n# Extraction from HTML and YAML templates\n[jinja2: **/web_ui/**.html]\n[jinja2: **/web_ui/**.yaml]\n\nencoding = utf-8\n"
  },
  {
    "path": "code/default/x_tunnel/lang/fa_IR/LC_MESSAGES/messages.po",
    "content": "\n\nmsgid \"Cloudflare\"\nmsgstr \"ابری\"\n\nmsgid \"Front\"\nmsgstr \"جلو\"\n\nmsgid \"Log\"\nmsgstr \"ورود به سیستم\"\n\nmsgid \"Cloudfront\"\nmsgstr \"خطوط ابری\"\n\nmsgid \"Account\"\nmsgstr \"حساب\"\n\nmsgid \"Settings\"\nmsgstr \"تنظیمات\"\n\nmsgid \"Plans\"\nmsgstr \"برنامه\"\n\nmsgid \"History\"\nmsgstr \"تاریخ\"\n\nmsgid \"Help\"\nmsgstr \"کمک\"\n\nmsgid \"Login\"\nmsgstr \"وارد شدن\"\n\nmsgid \"Token Login\"\nmsgstr \"ورود به سیستم\"\n\nmsgid \"Input login token from https://xx-net.com.\"\nmsgstr \"نشانه ورود به سیستم از https://xx-net.com.\"\n\nmsgid \"Token\"\nmsgstr \"نشانه\"\n\nmsgid \"Password Login\"\nmsgstr \"ورود رمز عبور\"\n\nmsgid \"Email\"\nmsgstr \"پست الکترونیک\"\n\nmsgid \"Password\"\nmsgstr \"کلمه عبور\"\n\nmsgid \"Haven't an account?\"\nmsgstr \"حساب کاربری ندارید؟\"\n\nmsgid \"Forget password?\"\nmsgstr \"فراموشی رمز عبور؟\"\n\nmsgid \"Reset password\"\nmsgstr \"رمزعبور بازنشانی\"\n\nmsgid \"Next\"\nmsgstr \"بعد\"\n\nmsgid \"Input confirmation code\"\nmsgstr \"کد تأیید ورودی\"\n\nmsgid \"\"\n\"The confirmation code has sent to your email, please check your email box.\"\nmsgstr \"\"\n\"کد تأیید به ایمیل شما ارسال شده است ، لطفاً کادر ایمیل خود را بررسی کنید.\"\n\nmsgid \"Confirmation Code\"\nmsgstr \"کد تایید\"\n\nmsgid \"Set new password\"\nmsgstr \"تنظیم رمز جدید\"\n\nmsgid \"Please input your new password.\"\nmsgstr \"لطفا رمز ورود جدید خود را وارد کنید.\"\n\nmsgid \"Confirm your password\"\nmsgstr \"رمز ورود خود را تأیید کنید\"\n\nmsgid \"Submit\"\nmsgstr \"ارسال\"\n\nmsgid \"Your password has reset successfully.\"\nmsgstr \"رمز عبور شما با موفقیت تنظیم مجدد شده است.\"\n\nmsgid \"Please use your new password to login.\"\nmsgstr \"لطفاً برای ورود به سیستم از رمز عبور جدید خود استفاده کنید.\"\n\nmsgid \"Login failed, please try login using token.\"\nmsgstr \"\"\n\"ورود به سیستم انجام نشد ، لطفاً با استفاده از Token ورود را امتحان کنید.\"\n\nmsgid \"Register\"\nmsgstr \"ثبت نام\"\n\nmsgid \"Promoter(Optional)\"\nmsgstr \"پروموتر (اختیاری)\"\n\nmsgid \"Already have an account?\"\nmsgstr \"در حال حاضر یک حساب کاربری دارید؟\"\n\nmsgid \"Summary\"\nmsgstr \"خلاصه\"\n\nmsgid \"Account\"\nmsgstr \"حساب\"\n\nmsgid \"Logout\"\nmsgstr \"خروج\"\n\nmsgid \"Credit\"\nmsgstr \"اعتبار\"\n\nmsgid \"Charge\"\nmsgstr \"شارژ\"\n\nmsgid \"Transfer\"\nmsgstr \"انتقال\"\n\nmsgid \"Available Plan\"\nmsgstr \"برنامه موجود\"\n\nmsgid \"No Valid Plan available.\"\nmsgstr \"هیچ برنامه معتبری در دسترس نیست.\"\n\nmsgid \"No bandwidth available.\"\nmsgstr \"پهنای باند موجود نیست.\"\n\nmsgid \"Expire Time\"\nmsgstr \"تاریخ انقضاء\"\n\nmsgid \"Left Bandwidth\"\nmsgstr \"پهنای باند سمت چپ\"\n\nmsgid \"server\"\nmsgstr \"سرور\"\n\nmsgid \"AUTO\"\nmsgstr \"خودکار\"\n\nmsgid \"\"\n\"Promoter (<a href='https://github.com/XX-net/XX-Net/wiki/X-Tunnel-Promote-\"\n\"Plan'>Help</a>)\"\nmsgstr \"\"\n\"مروج (<a href='https://github.com/xx-net/xx-net/wiki/x-tunnel-promote-plan'>\"\n\" راهنما </a>)\"\n\nmsgid \"Plans and Pricing\"\nmsgstr \"برنامه ها و قیمت گذاری\"\n\nmsgid \"Billing History\"\nmsgstr \"تاریخچه صورتحساب\"\n\nmsgid \"No billing history.\"\nmsgstr \"بدون سابقه صورتحساب.\"\n\nmsgid \"Time\"\nmsgstr \"زمان\"\n\nmsgid \"Description\"\nmsgstr \"شرح\"\n\nmsgid \"Get\"\nmsgstr \"گرفتن\"\n\nmsgid \"Action\"\nmsgstr \"عمل\"\n\nmsgid \"https://github.com/XX-net/XX-Net/wiki/How-to-use-XTunnel\"\nmsgstr \"\"\n\nmsgid \"\"\n\"Promote Code (<a href='https://github.com/XX-net/XX-Net/wiki/X-Tunnel-\"\n\"Promote-Plan'>Help</a>)\"\nmsgstr \"\"\n\"تبلیغ کد (<a href='https://github.com/xx-net/xx-net/wiki/x-tunnel-promote-\"\n\"plan'> راهنما </a>)\"\n\nmsgid \"You haven't enough credit. Please charge first.\"\nmsgstr \"شما اعتبار کافی نداریدلطفا ابتدا شارژ کنید.\"\n\nmsgid \"Plan\"\nmsgstr \"طرح\"\n\nmsgid \"Close\"\nmsgstr \"بستن\"\n\nmsgid \"Buy Now\"\nmsgstr \"هم اکنون خریداری کنید\"\n\nmsgid \"Transfer Credit\"\nmsgstr \"اعتبار انتقال\"\n\nmsgid \"Username transfer to\"\nmsgstr \"انتقال نام کاربری به\"\n\nmsgid \"Email Address\"\nmsgstr \"آدرس ایمیل\"\n\nmsgid \"Credit to transfer\"\nmsgstr \"اعتبار برای انتقال\"\n\nmsgid \"Transfer Bandwidth\"\nmsgstr \"پهنای باند\"\n\nmsgid \"Bandwidth to transfer\"\nmsgstr \"پهنای باند برای انتقال\"\n\nmsgid \"X-Tunnel Configuration\"\nmsgstr \"پیکربندی X-Tunnel\"\n\nmsgid \"Configuration\"\nmsgstr \"پیکربندی\"\n\nmsgid \"Status\"\nmsgstr \"وضعیت\"\n\nmsgid \"Logining ...\"\nmsgstr \"گودال\"\n\nmsgid \"Please wait ...\"\nmsgstr \"لطفا صبر کنید ...\"\n\nmsgid \"Promote Code copied to Clipboard.\"\nmsgstr \"کد کپی شده در کلیپ بورد را تبلیغ کنید.\"\n\nmsgid \"Connect to server fail:\"\nmsgstr \"اتصال به سرور شکست:\"\n\nmsgid \"Per Month\"\nmsgstr \"هر ماه\"\n\nmsgid \"Months\"\nmsgstr \"ماه ها\"\n\nmsgid \"Total\"\nmsgstr \"جمع\"\n\nmsgid \"Email seems invalid.\"\nmsgstr \"ایمیل نامعتبر به نظر می رسد.\"\n\nmsgid \"Password needs at least 6 characters, and no more than 20.\"\nmsgstr \"رمز عبور حداقل به 6 نویسه و بیش از 20 نیاز ندارد.\"\n\nmsgid \"Loading ...\"\nmsgstr \"بارگذاری ...\"\n\nmsgid \"Please input invalid confirmation code.\"\nmsgstr \"لطفاً کد تأیید نامعتبر را وارد کنید.\"\n\nmsgid \"Passwords are not match.\"\nmsgstr \"رمزهای عبور مطابقت ندارند.\"\n\nmsgid \"Connect to server fail, check Front log first.\"\nmsgstr \"به سرور متصل شوید ، ابتدا ورود به سیستم جلو را بررسی کنید.\"\n\nmsgid \"Incorrect Email or password.\"\nmsgstr \"کلمه عبور یا ایمیل اشتباه است.\"\n\nmsgid \"Login fail:\"\nmsgstr \"ورود به سیستم شکست:\"\n\nmsgid \"Account not exist.\"\nmsgstr \"حساب وجود ندارد\"\n\nmsgid \"Try again later.\"\nmsgstr \"بعدا دوباره تلاش کنید.\"\n\nmsgid \"Request fail:\"\nmsgstr \"درخواست شکست:\"\n\nmsgid \"Confirmation code expired, please restart again.\"\nmsgstr \"کد تأیید منقضی شد ، لطفاً دوباره مجدداً راه اندازی کنید.\"\n\nmsgid \"You have exceeded the retry limitation.\"\nmsgstr \"شما از محدودیت آزمایش مجدد فراتر رفته اید.\"\n\nmsgid \"The code is not match, please check your code.\"\nmsgstr \"کد مطابقت ندارد ، لطفاً کد خود را بررسی کنید.\"\n\nmsgid \"Do NOT use Chinese-service-provider's Email!\"\nmsgstr \"از ایمیل ارائه دهنده خدمات چینی استفاده نکنید!\"\n\nmsgid \"Password needs at least 6 charactors, and no more than 20.\"\nmsgstr \"رمز عبور حداقل به 6 نویسه و بیش از 20 نیاز ندارد.\"\n\nmsgid \"Password seems invalid.\"\nmsgstr \"رمز عبور نامعتبر به نظر می رسد.\"\n\nmsgid \"Promoter is invalid.\"\nmsgstr \"مروج نامعتبر است.\"\n\nmsgid \"Registered successfully, \"\nmsgstr \"با موفقیت ثبت شد،\"\n\nmsgid \"Email has been taken by another user.\"\nmsgstr \"ایمیل توسط کاربر دیگری گرفته شده است.\"\n\nmsgid \"Promoter not exist, check it or keep it empty.\"\nmsgstr \"مروج وجود ندارد ، آن را بررسی کنید یا آن را خالی نگه دارید.\"\n\nmsgid \"Unknown error occurred.\"\nmsgstr \"خطای ناشناخته رخ داده است.\"\n\nmsgid \"previously selected server nolonger available, automatically try \"\nmsgstr \"سرور انتخاب شده قبلی دیگر در دسترس نیست ، به طور خودکار امتحان کنید\"\n\nmsgid \"Can't promote yourself.\"\nmsgstr \"نمی تواند خود را تبلیغ کند.\"\n\nmsgid \"Settings saved successfully.\"\nmsgstr \"تنظیمات با موفقیت ذخیره شد.\"\n\nmsgid \"Failed saving settings: \"\nmsgstr \"تنظیمات ذخیره ناموفق:\"\n\nmsgid \"Failed to log out.\"\nmsgstr \"ورود به سیستم انجام نشد.\"\n\nmsgid \"Please refresh page.\"\nmsgstr \"لطفا صفحه را تازه کنید.\"\n\nmsgid \"Transfer username seems not a valid Email address.\"\nmsgstr \"به نظر می رسد نام کاربری انتقال یک آدرس ایمیل معتبر نیست.\"\n\nmsgid \"Error occurred: \"\nmsgstr \"خطا رخ داده است:\"\n\nmsgid \"Max Available Bandwidth: \"\nmsgstr \"پهنای باند موجود:\"\n\nmsgid \"Unit should be M or G.\"\nmsgstr \"واحد باید M یا G باشد.\"\n\nmsgid \"Transfer amount should not more than 2 decimal places.\"\nmsgstr \"مقدار انتقال نباید بیش از 2 مکان اعشاری باشد.\"\n\nmsgid \"Failed to order: \"\nmsgstr \"سفارش انجام نشد:\"\n\nmsgid \"Order successfully complete.\"\nmsgstr \"سفارش را با موفقیت کامل کنید.\"\n\nmsgid \"Get Fail:\"\nmsgstr \"FAIL:\"\n\nmsgid \"Heroku\"\nmsgstr \"هروکو\"\n\nmsgid \"X-Tunnel\"\nmsgstr \"تونل ایکس\"\n\nmsgid \"Your browser is obsolete. Partial functionality will not be available.\"\nmsgstr \"مرورگر شما منسوخ است.عملکرد جزئی در دسترس نخواهد بود.\"\n\nmsgid \"The latest Chrome browser is recommended.\"\nmsgstr \"آخرین مرورگر Chrome توصیه می شود.\"\n\nmsgid \"Global\"\nmsgstr \"جهانی\"\n\nmsgid \"Property\"\nmsgstr \"ویژگی\"\n\nmsgid \"Value\"\nmsgstr \"ارزش\"\n\nmsgid \"Handle num\"\nmsgstr \"رسیدگی به تعداد\"\n\nmsgid \"Response time\"\nmsgstr \"زمان پاسخ\"\n\nmsgid \"Roundtrip num\"\nmsgstr \"گردباد شماره\"\n\nmsgid \"Slow roundtrip\"\nmsgstr \"دورگرد آهسته\"\n\nmsgid \"Resend\"\nmsgstr \"ارسال مجدد\"\n\nmsgid \"Timeout roundtrip\"\nmsgstr \"میزگرد تایم\"\n\nmsgid \"Speed\"\nmsgstr \"سرعت\"\n\nmsgid \"Total use\"\nmsgstr \"کل استفاده\"\n\nmsgid \"GAE\"\nmsgstr \"گود\"\n\nmsgid \"Score\"\nmsgstr \"نمره\"\n\nmsgid \"Success num\"\nmsgstr \"شماره موفقیت\"\n\nmsgid \"Fail num\"\nmsgstr \"NUM\"\n\nmsgid \"Worker num\"\nmsgstr \"شماره کارگر\"\n\nmsgid \"TLS_Relay\"\nmsgstr \"tls_reelay\"\n\nmsgid \"X-Tunnel Status Info\"\nmsgstr \"اطلاعات وضعیت تونل ایکس\"\n\nmsgid \"The status page is empty. Highly likely that \"\nmsgstr \"صفحه وضعیت خالی است.بسیار محتمل که\"\n\nmsgid \" failed getting started. Please follow \"\nmsgstr \"شروع به کار نشدلطفا دنبال کنید\"\n\nmsgid \"guide\"\nmsgstr \"راهنما\"\n\nmsgid \" to troubleshoot.\"\nmsgstr \"عیب یابی\"\n\nmsgid \"ChatGPT Manual\"\nmsgstr \"کتابچه راهنمای chatgpt\"\n\nmsgid \"https://github.com/XX-net/XX-Net/wiki/ChatGPT_EN\"\nmsgstr \"\"\n"
  },
  {
    "path": "code/default/x_tunnel/lang/ru_RU/LC_MESSAGES/messages.po",
    "content": "#\nmsgid \"\"\nmsgstr \"\"\n\nmsgid \"Cloudflare\"\nmsgstr \"Cloudflare\"\n\nmsgid \"Front\"\nmsgstr \"Передний\"\n\nmsgid \"Log\"\nmsgstr \"Бревно\"\n\nmsgid \"Cloudfront\"\nmsgstr \"Cloudfront\"\n\nmsgid \"Account\"\nmsgstr \"Счет\"\n\nmsgid \"Settings\"\nmsgstr \"Настройки\"\n\nmsgid \"Plans\"\nmsgstr \"Планы\"\n\nmsgid \"History\"\nmsgstr \"История\"\n\nmsgid \"Help\"\nmsgstr \"Помощь\"\n\nmsgid \"Login\"\nmsgstr \"Авторизоваться\"\n\nmsgid \"Token Login\"\nmsgstr \"Вход в знак токена\"\n\nmsgid \"Input login token from https://xx-net.com.\"\nmsgstr \"Токен ввода ввода от https://xx-net.com.\"\n\nmsgid \"Token\"\nmsgstr \"Токен\"\n\nmsgid \"Password Login\"\nmsgstr \"Вход в систему пароля\"\n\nmsgid \"Email\"\nmsgstr \"Электронная почта\"\n\nmsgid \"Password\"\nmsgstr \"Пароль\"\n\nmsgid \"Haven't an account?\"\nmsgstr \"Нет аккаунта?\"\n\nmsgid \"Forget password?\"\nmsgstr \"Забыть пароль?\"\n\nmsgid \"Reset password\"\nmsgstr \"Сброс пароля\"\n\nmsgid \"Next\"\nmsgstr \"Следующий\"\n\nmsgid \"Input confirmation code\"\nmsgstr \"Код подтверждения ввода\"\n\nmsgid \"\"\n\"The confirmation code has sent to your email, please check your email box.\"\nmsgstr \"\"\n\"Код подтверждения отправился на ваше электронное письмо, пожалуйста, \"\n\"ознакомьтесь с вашим письмом.\"\n\nmsgid \"Confirmation Code\"\nmsgstr \"Код подтверждения\"\n\nmsgid \"Set new password\"\nmsgstr \"Установите новый пароль\"\n\nmsgid \"Please input your new password.\"\nmsgstr \"Пожалуйста, введите свой новый пароль.\"\n\nmsgid \"Confirm your password\"\nmsgstr \"Подтвердите ваш пароль\"\n\nmsgid \"Submit\"\nmsgstr \"Представлять на рассмотрение\"\n\nmsgid \"Your password has reset successfully.\"\nmsgstr \"Ваш пароль успешно сброшен.\"\n\nmsgid \"Please use your new password to login.\"\nmsgstr \"Пожалуйста, используйте свой новый пароль для входа в систему.\"\n\nmsgid \"Login failed, please try login using token.\"\nmsgstr \"Вход не удался, попробуйте войти в систему с помощью токена.\"\n\nmsgid \"Register\"\nmsgstr \"регистр\"\n\nmsgid \"Promoter(Optional)\"\nmsgstr \"Промоутер (необязательно)\"\n\nmsgid \"Already have an account?\"\nmsgstr \"Уже есть аккаунт?\"\n\nmsgid \"Summary\"\nmsgstr \"Краткое содержание\"\n\nmsgid \"Account\"\nmsgstr \"Счет\"\n\nmsgid \"Logout\"\nmsgstr \"Выйти\"\n\nmsgid \"Credit\"\nmsgstr \"Кредит\"\n\nmsgid \"Charge\"\nmsgstr \"Заряжать\"\n\nmsgid \"Transfer\"\nmsgstr \"Передача\"\n\nmsgid \"Available Plan\"\nmsgstr \"Доступный план\"\n\nmsgid \"No Valid Plan available.\"\nmsgstr \"Нет достоверного плана.\"\n\nmsgid \"No bandwidth available.\"\nmsgstr \"Нет пропускной способности.\"\n\nmsgid \"Expire Time\"\nmsgstr \"Истекает время\"\n\nmsgid \"Left Bandwidth\"\nmsgstr \"Левая полоса пропускания\"\n\nmsgid \"server\"\nmsgstr \"сервер\"\n\nmsgid \"AUTO\"\nmsgstr \"\"\n\nmsgid \"\"\n\"Promoter (<a href='https://github.com/XX-net/XX-Net/wiki/X-Tunnel-Promote-\"\n\"Plan'>Help</a>)\"\nmsgstr \"\"\n\"Промотор (<a href='https://github.com/xx-net/xx-net/wiki/x-tunnel-promote-\"\n\"plan'> help </a>)\"\n\nmsgid \"Plans and Pricing\"\nmsgstr \"\"\n\nmsgid \"Billing History\"\nmsgstr \"Биллинг История\"\n\nmsgid \"No billing history.\"\nmsgstr \"Нет истории выставления счетов.\"\n\nmsgid \"Time\"\nmsgstr \"Время\"\n\nmsgid \"Description\"\nmsgstr \"Описание\"\n\nmsgid \"Get\"\nmsgstr \"Получать\"\n\nmsgid \"Action\"\nmsgstr \"Действие\"\n\nmsgid \"https://github.com/XX-net/XX-Net/wiki/How-to-use-XTunnel\"\nmsgstr \"\"\n\nmsgid \"\"\n\"Promote Code (<a href='https://github.com/XX-net/XX-Net/wiki/X-Tunnel-\"\n\"Promote-Plan'>Help</a>)\"\nmsgstr \"\"\n\"PROMOTE CODE (<a href='https://github.com/xx-net/xx-net/wiki/x-tunnel-\"\n\"promote-plan'> справка </a>)\"\n\nmsgid \"You haven't enough credit. Please charge first.\"\nmsgstr \"Вам не хватает кредита.Пожалуйста, зарядите первым.\"\n\nmsgid \"Plan\"\nmsgstr \"План\"\n\nmsgid \"Close\"\nmsgstr \"Закрывать\"\n\nmsgid \"Buy Now\"\nmsgstr \"Купить сейчас\"\n\nmsgid \"Transfer Credit\"\nmsgstr \"Трансферный кредит\"\n\nmsgid \"Username transfer to\"\nmsgstr \"Перенос имени пользователя в\"\n\nmsgid \"Email Address\"\nmsgstr \"Адрес электронной почты\"\n\nmsgid \"Credit to transfer\"\nmsgstr \"Кредит на передачу\"\n\nmsgid \"Transfer Bandwidth\"\nmsgstr \"Перевод полосы пропускания\"\n\nmsgid \"Bandwidth to transfer\"\nmsgstr \"Пропускная способность передачи\"\n\nmsgid \"X-Tunnel Configuration\"\nmsgstr \"Конфигурация X-Tunnel\"\n\nmsgid \"Configuration\"\nmsgstr \"Конфигурация\"\n\nmsgid \"Status\"\nmsgstr \"Положение дел\"\n\nmsgid \"Logining ...\"\nmsgstr \"Логика\"\n\nmsgid \"Please wait ...\"\nmsgstr \"Пожалуйста, подождите ...\"\n\nmsgid \"Promote Code copied to Clipboard.\"\nmsgstr \"Продвигайте код, скопированный в буфер обмена.\"\n\nmsgid \"Connect to server fail:\"\nmsgstr \"Подключиться к отказу от сервера:\"\n\nmsgid \"Per Month\"\nmsgstr \"В месяц\"\n\nmsgid \"Months\"\nmsgstr \"Месяцы\"\n\nmsgid \"Total\"\nmsgstr \"Общий\"\n\nmsgid \"Email seems invalid.\"\nmsgstr \"Электронная почта кажется недействительной.\"\n\nmsgid \"Password needs at least 6 characters, and no more than 20.\"\nmsgstr \"Пароль требует не менее 6 символов и не более 20.\"\n\nmsgid \"Loading ...\"\nmsgstr \"Загрузка ...\"\n\nmsgid \"Please input invalid confirmation code.\"\nmsgstr \"Пожалуйста, введите недопустимый код подтверждения.\"\n\nmsgid \"Passwords are not match.\"\nmsgstr \"Пароли не совпадают.\"\n\nmsgid \"Connect to server fail, check Front log first.\"\nmsgstr \"Сначала подключитесь к серверу, сначала проверьте фронт.\"\n\nmsgid \"Incorrect Email or password.\"\nmsgstr \"Неверный адрес электронной почты или пароль.\"\n\nmsgid \"Login fail:\"\nmsgstr \"Неверный логин:\"\n\nmsgid \"Account not exist.\"\nmsgstr \"Аккаунт не существует.\"\n\nmsgid \"Try again later.\"\nmsgstr \"Попробуйте позже.\"\n\nmsgid \"Request fail:\"\nmsgstr \"Запрос неудачный:\"\n\nmsgid \"Confirmation code expired, please restart again.\"\nmsgstr \"\"\n\"Срок действия кода подтверждения истек, пожалуйста, перезапустите снова.\"\n\nmsgid \"You have exceeded the retry limitation.\"\nmsgstr \"Вы превзошли ограничение повторной попытки.\"\n\nmsgid \"The code is not match, please check your code.\"\nmsgstr \"Код не соответствует, пожалуйста, проверьте свой код.\"\n\nmsgid \"Do NOT use Chinese-service-provider's Email!\"\nmsgstr \"Не используйте электронную почту Китая-Сервиса-Провидера!\"\n\nmsgid \"Password needs at least 6 charactors, and no more than 20.\"\nmsgstr \"Пароль требует не менее 6 символов и не более 20.\"\n\nmsgid \"Password seems invalid.\"\nmsgstr \"Пароль кажется недействительным.\"\n\nmsgid \"Promoter is invalid.\"\nmsgstr \"Промоутер недействителен.\"\n\nmsgid \"Registered successfully, \"\nmsgstr \"Регистрация прошла успешно,\"\n\nmsgid \"Email has been taken by another user.\"\nmsgstr \"Электронная почта была взята другим пользователем.\"\n\nmsgid \"Promoter not exist, check it or keep it empty.\"\nmsgstr \"Промоутер не существует, проверьте его или оставьте его пустым.\"\n\nmsgid \"Unknown error occurred.\"\nmsgstr \"Произошла неизвестная ошибка.\"\n\nmsgid \"previously selected server nolonger available, automatically try \"\nmsgstr \"Ранее выбранный сервер больше не доступен, автоматически попробуйте\"\n\nmsgid \"Can't promote yourself.\"\nmsgstr \"Не могу продвигать себя.\"\n\nmsgid \"Settings saved successfully.\"\nmsgstr \"Настройки успешно сохранились.\"\n\nmsgid \"Failed saving settings: \"\nmsgstr \"Неудачные настройки сохранения:\"\n\nmsgid \"Failed to log out.\"\nmsgstr \"Не удалось выйти.\"\n\nmsgid \"Please refresh page.\"\nmsgstr \"Пожалуйста, обновите страницу.\"\n\nmsgid \"Transfer username seems not a valid Email address.\"\nmsgstr \"\"\n\"Передача пользователя не является действительным адресом электронной почты.\"\n\nmsgid \"Error occurred: \"\nmsgstr \"Возникла ошибка:\"\n\nmsgid \"Max Available Bandwidth: \"\nmsgstr \"Максимальный доступный пропускная способность:\"\n\nmsgid \"Unit should be M or G.\"\nmsgstr \"Единица должна быть M или G.\"\n\nmsgid \"Transfer amount should not more than 2 decimal places.\"\nmsgstr \"Сумма передачи должна не более 2 десятичных знаков.\"\n\nmsgid \"Failed to order: \"\nmsgstr \"Не удалось заказать:\"\n\nmsgid \"Order successfully complete.\"\nmsgstr \"Заказ успешно завершен.\"\n\nmsgid \"Get Fail:\"\nmsgstr \"Получите неудачу:\"\n\nmsgid \"Heroku\"\nmsgstr \"Хероку\"\n\nmsgid \"X-Tunnel\"\nmsgstr \"X-Tunnel\"\n\nmsgid \"Your browser is obsolete. Partial functionality will not be available.\"\nmsgstr \"Ваш браузер устарел.Частичная функциональность не будет доступна.\"\n\nmsgid \"The latest Chrome browser is recommended.\"\nmsgstr \"Рекомендуется последний Chrome Browser.\"\n\nmsgid \"Global\"\nmsgstr \"Глобальный\"\n\nmsgid \"Property\"\nmsgstr \"Свойство\"\n\nmsgid \"Value\"\nmsgstr \"Ценить\"\n\nmsgid \"Handle num\"\nmsgstr \"Обрабатывать num\"\n\nmsgid \"Response time\"\nmsgstr \"Время отклика\"\n\nmsgid \"Roundtrip num\"\nmsgstr \"Обратная полет\"\n\nmsgid \"Slow roundtrip\"\nmsgstr \"Медленная обработка\"\n\nmsgid \"Resend\"\nmsgstr \"Отправить\"\n\nmsgid \"Timeout roundtrip\"\nmsgstr \"Тайм -аут\"\n\nmsgid \"Speed\"\nmsgstr \"Скорость\"\n\nmsgid \"Total use\"\nmsgstr \"Общее использование\"\n\nmsgid \"GAE\"\nmsgstr \"Газо\"\n\nmsgid \"Score\"\nmsgstr \"Счет\"\n\nmsgid \"Success num\"\nmsgstr \"Номер успеха\"\n\nmsgid \"Fail num\"\nmsgstr \"Неудача num\"\n\nmsgid \"Worker num\"\nmsgstr \"Работник num\"\n\nmsgid \"TLS_Relay\"\nmsgstr \"TLS_RELAY\"\n\nmsgid \"X-Tunnel Status Info\"\nmsgstr \"Информация о статусе X-Tunnel\"\n\nmsgid \"The status page is empty. Highly likely that \"\nmsgstr \"Страница статуса пуста.Весьма вероятно, что\"\n\nmsgid \" failed getting started. Please follow \"\nmsgstr \"Не удалось начать.Пожалуйста, следуйте\"\n\nmsgid \"guide\"\nmsgstr \"гид\"\n\nmsgid \" to troubleshoot.\"\nmsgstr \"Устранение неполадок.\"\n\nmsgid \"ChatGPT Manual\"\nmsgstr \"Руководство по чате\"\n\nmsgid \"https://github.com/XX-net/XX-Net/wiki/ChatGPT_EN\"\nmsgstr \"\"\n"
  },
  {
    "path": "code/default/x_tunnel/lang/zh_CN/LC_MESSAGES/messages.po",
    "content": "\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: PROJECT VERSION\\n\"\n\"Report-Msgid-Bugs-To: xxnet.dev@gmail.com\\n\"\n\"POT-Creation-Date: 2022-05-06 21:04-0400\\n\"\n\"PO-Revision-Date: 2017-12-29 12:00+0800\\n\"\n\"Last-Translator: Emphasia@github\\n\"\n\"Language: zh_Hans_CN\\n\"\n\"Language-Team: zh_Hans_CN <LL@li.org>\\n\"\n\"Plural-Forms: nplurals=2; plural=(n != 1)\\n\"\n\"MIME-Version: 1.0\\n\"\n\"Content-Type: text/plain; charset=utf-8\\n\"\n\"Content-Transfer-Encoding: 8bit\\n\"\n\"Generated-By: Babel 2.9.1\\n\"\n\nmsgid \"Cloudflare\"\nmsgstr \"\"\n\nmsgid \"Front\"\nmsgstr \"前端\"\n\nmsgid \"Log\"\nmsgstr \"日志\"\n\nmsgid \"Cloudfront\"\nmsgstr \"\"\n\nmsgid \"Account\"\nmsgstr \"账户\"\n\nmsgid \"Settings\"\nmsgstr \"设置\"\n\nmsgid \"Plans\"\nmsgstr \"购买套餐\"\n\nmsgid \"History\"\nmsgstr \"历史\"\n\nmsgid \"Help\"\nmsgstr \"帮助\"\n\nmsgid \"Login\"\nmsgstr \"登录\"\n\nmsgid \"Token Login\"\nmsgstr \"令牌登录\"\n\nmsgid \"Input login token from https://xx-net.com.\"\nmsgstr \"请从 https://xx-net.com 获取令牌登录:\"\n\nmsgid \"Token\"\nmsgstr \"令牌\"\n\nmsgid \"Password Login\"\nmsgstr \"密码登录\"\n\nmsgid \"Email\"\nmsgstr \"电子邮件地址\"\n\nmsgid \"Password\"\nmsgstr \"密码\"\n\nmsgid \"Haven't an account?\"\nmsgstr \"没有账户？\"\n\nmsgid \"Forget password?\"\nmsgstr \"忘记密码？\"\n\nmsgid \"Reset password\"\nmsgstr \"复位密码\"\n\nmsgid \"Next\"\nmsgstr \"下一步\"\n\nmsgid \"Input confirmation code\"\nmsgstr \"输入验证码\"\n\nmsgid \"The confirmation code has sent to your email, please check your email box.\"\nmsgstr \"验证码已经发送到您的E-mail，请检查您的邮箱。\"\n\nmsgid \"Confirmation Code\"\nmsgstr \"验证码\"\n\nmsgid \"Set new password\"\nmsgstr \"设置新的密码\"\n\nmsgid \"Please input your new password.\"\nmsgstr \"请输入您的新密码。\"\n\nmsgid \"Confirm your password\"\nmsgstr \"确认您的密码。\"\n\nmsgid \"Submit\"\nmsgstr \"提交\"\n\nmsgid \"Your password has reset successfully.\"\nmsgstr \"您的密码已经复位成功。\"\n\nmsgid \"Please use your new password to login.\"\nmsgstr \"请使用您的新密码登陆。\"\n\nmsgid \"Login failed, please try login using token.\"\nmsgstr \"登陆失败，请尝试使用令牌登陆。\"\n\nmsgid \"Register\"\nmsgstr \"注册\"\n\nmsgid \"Promoter(Optional)\"\nmsgstr \"推荐码(可选)\"\n\nmsgid \"Already have an account?\"\nmsgstr \"已有账户？\"\n\nmsgid \"Summary\"\nmsgstr \"概况\"\n\nmsgid \"Account\"\nmsgstr \"账户\"\n\nmsgid \"Logout\"\nmsgstr \"退出登陆\"\n\nmsgid \"Credit\"\nmsgstr \"余额\"\n\nmsgid \"Charge\"\nmsgstr \"充值\"\n\nmsgid \"Transfer\"\nmsgstr \"转让\"\n\nmsgid \"Available Plan\"\nmsgstr \"有效套餐\"\n\nmsgid \"No Valid Plan available.\"\nmsgstr \"无有效套餐。\"\n\nmsgid \"No bandwidth available.\"\nmsgstr \"暂无可用流量。\"\n\nmsgid \"Expire Time\"\nmsgstr \"到期时间\"\n\nmsgid \"Left Bandwidth\"\nmsgstr \"剩余流量\"\n\nmsgid \"server\"\nmsgstr \"服务器\"\n\nmsgid \"AUTO\"\nmsgstr \"自动\"\n\nmsgid \"\"\n\"Promoter (<a href='https://github.com/XX-net/XX-Net/wiki/X-Tunnel-\"\n\"Promote-Plan'>Help</a>)\"\nmsgstr \"\"\n\"推荐人(<a href='https://github.com/XX-net/XX-\"\n\"Net/wiki/X-Tunnel-%E6%8E%A8%E5%B9%BF%E8%AE%A1%E5%88%92'>帮助</a>)\"\n\nmsgid \"Plans and Pricing\"\nmsgstr \"套餐和价格\"\n\nmsgid \"Billing History\"\nmsgstr \"历史账单\"\n\nmsgid \"No billing history.\"\nmsgstr \"暂无历史账单。\"\n\nmsgid \"Time\"\nmsgstr \"时间\"\n\nmsgid \"Description\"\nmsgstr \"描述\"\n\nmsgid \"Get\"\nmsgstr \"获取\"\n\nmsgid \"Action\"\nmsgstr \"操作\"\n\nmsgid \"https://github.com/XX-net/XX-Net/wiki/How-to-use-XTunnel\"\nmsgstr \"\"\n\"https://github.com/XX-net/XX-\"\n\"Net/wiki/x-tunnel%E4%BD%BF%E7%94%A8%E6%95%99%E7%A8%8B\"\n\nmsgid \"\"\n\"Promote Code (<a href='https://github.com/XX-net/XX-Net/wiki/X-Tunnel-\"\n\"Promote-Plan'>Help</a>)\"\nmsgstr \"\"\n\"给别人的推荐码(<a href='https://github.com/XX-net/XX-\"\n\"Net/wiki/X-Tunnel-%E6%8E%A8%E5%B9%BF%E8%AE%A1%E5%88%92'>帮助</a>)\"\n\nmsgid \"You haven't enough credit. Please charge first.\"\nmsgstr \"您的余额不足，请先充值。\"\n\nmsgid \"Plan\"\nmsgstr \"套餐\"\n\nmsgid \"Close\"\nmsgstr \"关闭\"\n\nmsgid \"Buy Now\"\nmsgstr \"立即购买\"\n\nmsgid \"Transfer Credit\"\nmsgstr \"余额转账\"\n\nmsgid \"Username transfer to\"\nmsgstr \"转账用户名\"\n\nmsgid \"Email Address\"\nmsgstr \"电子邮件地址\"\n\nmsgid \"Credit to transfer\"\nmsgstr \"转账金额\"\n\nmsgid \"Transfer Bandwidth\"\nmsgstr \"流量转账\"\n\nmsgid \"Bandwidth to transfer\"\nmsgstr \"转账流量\"\n\nmsgid \"X-Tunnel Configuration\"\nmsgstr \"X-Tunnel 配置\"\n\nmsgid \"Configuration\"\nmsgstr \"配置\"\n\nmsgid \"Status\"\nmsgstr \"状态\"\n\nmsgid \"Logining ...\"\nmsgstr \"正在登录...\"\n\nmsgid \"Please wait ...\"\nmsgstr \"请稍侯...\"\n\nmsgid \"Promote Code copied to Clipboard.\"\nmsgstr \"推荐码已拷贝到剪贴板\"\n\nmsgid \"Connect to server fail:\"\nmsgstr \"连接服务器失败：\"\n\nmsgid \"Per Month\"\nmsgstr \"每个月\"\n\nmsgid \"Months\"\nmsgstr \"个月\"\n\nmsgid \"Total\"\nmsgstr \"总共\"\n\nmsgid \"Email seems invalid.\"\nmsgstr \"电子邮件地址似乎是无效的。\"\n\nmsgid \"Password needs at least 6 characters, and no more than 20.\"\nmsgstr \"密码需要6~20个字符。\"\n\nmsgid \"Loading ...\"\nmsgstr \"正在加载...\"\n\nmsgid \"Please input invalid confirmation code.\"\nmsgstr \"请输入有效的验证码\"\n\nmsgid \"Passwords are not match.\"\nmsgstr \"密码不一致！\"\n\nmsgid \"Connect to server fail, check Front log first.\"\nmsgstr \"连接服务器失败，请检查前端日志。\"\n\nmsgid \"Incorrect Email or password.\"\nmsgstr \"用户名或密码不正确。\"\n\nmsgid \"Login fail:\"\nmsgstr \"登录失败：\"\n\nmsgid \"Account not exist.\"\nmsgstr \"账户不存在\"\n\nmsgid \"Try again later.\"\nmsgstr \"请稍后重试\"\n\nmsgid \"Request fail:\"\nmsgstr \"获取失败：\"\n\nmsgid \"Confirmation code expired, please restart again.\"\nmsgstr \"验证码已经过期，请重新申请。\"\n\nmsgid \"You have exceeded the retry limitation.\"\nmsgstr \"您已经超过重试限制次数。\"\n\nmsgid \"The code is not match, please check your code.\"\nmsgstr \"验证码不匹配，请重新输入您的验证码。\"\n\nmsgid \"Do NOT use Chinese-service-provider's Email!\"\nmsgstr \"请勿使用国内服务提供商的邮件地址！\"\n\nmsgid \"Password needs at least 6 charactors, and no more than 20.\"\nmsgstr \"密码需要6~20个字符。\"\n\nmsgid \"Password seems invalid.\"\nmsgstr \"密码似乎是无效的。\"\n\nmsgid \"Promoter is invalid.\"\nmsgstr \"推荐码无效\"\n\nmsgid \"Registered successfully, \"\nmsgstr \"注册成功，\"\n\nmsgid \"Email has been taken by another user.\"\nmsgstr \"电子邮件地址已被他人使用。\"\n\nmsgid \"Promoter not exist, check it or keep it empty.\"\nmsgstr \"推荐人不存在，请确认推荐码或清空推荐码。\"\n\nmsgid \"Unknown error occurred.\"\nmsgstr \"发生未知错误。\"\n\nmsgid \"previously selected server nolonger available, automatically try \"\nmsgstr \"先前所选服务器不再可用，尝试 \"\n\nmsgid \"Can't promote yourself.\"\nmsgstr \"不能推荐自己\"\n\nmsgid \"Settings saved successfully.\"\nmsgstr \"设置保存成功。\"\n\nmsgid \"Failed saving settings: \"\nmsgstr \"设置保存失败：\"\n\nmsgid \"Failed to log out.\"\nmsgstr \"注销失败。\"\n\nmsgid \"Please refresh page.\"\nmsgstr \"请刷新页面。\"\n\nmsgid \"Transfer username seems not a valid Email address.\"\nmsgstr \"转账用户名似乎不是有效的电子邮件地址。\"\n\nmsgid \"Error occurred: \"\nmsgstr \"发生错误：\"\n\nmsgid \"Max Available Bandwidth: \"\nmsgstr \"最大可用流量：\"\n\nmsgid \"Unit should be M or G.\"\nmsgstr \"单位可以是 M 或者 G\"\n\nmsgid \"Transfer amount should not more than 2 decimal places.\"\nmsgstr \"转账金额不得超过2位小数。\"\n\nmsgid \"Failed to order: \"\nmsgstr \"订购失败：\"\n\nmsgid \"Order successfully complete.\"\nmsgstr \"订购成功完成。\"\n\nmsgid \"Get Fail:\"\nmsgstr \"获取失败：\"\n\nmsgid \"Heroku\"\nmsgstr \"\"\n\nmsgid \"X-Tunnel\"\nmsgstr \"\"\n\nmsgid \"Your browser is obsolete. Partial functionality will not be available.\"\nmsgstr \"您的浏览器版本过低，部分功能无法工作。\"\n\nmsgid \"The latest Chrome browser is recommended.\"\nmsgstr \"建议使用新版的Chrome浏览器。\"\n\nmsgid \"Global\"\nmsgstr \"全局\"\n\nmsgid \"Property\"\nmsgstr \"属性\"\n\nmsgid \"Value\"\nmsgstr \"值\"\n\nmsgid \"Handle num\"\nmsgstr \"请求数\"\n\nmsgid \"Response time\"\nmsgstr \"响应时间\"\n\nmsgid \"Roundtrip num\"\nmsgstr \"往返数\"\n\nmsgid \"Slow roundtrip\"\nmsgstr \"较慢\"\n\nmsgid \"Resend\"\nmsgstr \"重传\"\n\nmsgid \"Timeout roundtrip\"\nmsgstr \"超时\"\n\nmsgid \"Speed\"\nmsgstr \"当前速度\"\n\nmsgid \"Total use\"\nmsgstr \"使用总量\"\n\nmsgid \"GAE\"\nmsgstr \"GAE\"\n\nmsgid \"Score\"\nmsgstr \"\"\n\nmsgid \"Success num\"\nmsgstr \"成功数\"\n\nmsgid \"Fail num\"\nmsgstr \"失败数\"\n\nmsgid \"Worker num\"\nmsgstr \"工作数\"\n\nmsgid \"TLS_Relay\"\nmsgstr \"\"\n\nmsgid \"X-Tunnel Status Info\"\nmsgstr \"X-Tunnel 状态信息\"\n\nmsgid \"The status page is empty. Highly likely that \"\nmsgstr \"状态页显示空白, 很可能 \"\n\nmsgid \" failed getting started. Please follow \"\nmsgstr \" 启动失败, 请按 \"\n\nmsgid \"guide\"\nmsgstr \"指导\"\n\nmsgid \" to troubleshoot.\"\nmsgstr \"去解决。\"\n\nmsgid \"ChatGPT Manual\"\nmsgstr \"ChatGPT指南 \"\n\nmsgid \"https://github.com/XX-net/XX-Net/wiki/ChatGPT_EN\"\nmsgstr \"https://github.com/XX-net/XX-Net/wiki/ChatGPT_CN \""
  },
  {
    "path": "code/default/x_tunnel/local/__init__.py",
    "content": "__all__ = [\"local\", \"start\"]\n\n\nfrom . import client\nfrom . import apis\nfrom . import web_control\n\n\ndef is_ready():\n    return client.ready\n\n\ndef start(args):\n    client.start(args)\n\n\ndef stop():\n    client.stop()\n"
  },
  {
    "path": "code/default/x_tunnel/local/apis.py",
    "content": "import time\n\nfrom . import global_var as g\nfrom . import front_dispatcher\n\nfrom xlog import getLogger\nxlog = getLogger(\"x_tunnel\")\n\n\nworkable_call_times = 0\n\n\ndef set_proxy(args):\n    xlog.info(\"set_proxy:%s\", args)\n    for front in front_dispatcher.all_fronts:\n        try:\n            front.set_proxy(args)\n        except Exception as e:\n            xlog.exception(\"set_proxy except:%r\", e)\n\n\ndef is_workable():\n    global workable_call_times\n    if workable_call_times == 0:\n        loop_num = 8\n    else:\n        loop_num = 1\n\n    workable_call_times += 1\n    for i in range(0, loop_num):\n        for front in front_dispatcher.session_fronts:\n            score = front.get_dispatcher().get_score()\n            if score is None:\n                continue\n            else:\n                return True\n\n        if loop_num > 1:\n            time.sleep(1)\n\n    return False\n\n\ndef set_bind_ip(args):\n    xlog.info(\"set_bind_ip:%s\", args)\n\n    g.config.socks_host = args[\"ip\"]\n    g.config.save()\n"
  },
  {
    "path": "code/default/x_tunnel/local/base_container.py",
    "content": "import os\nimport sys\nimport threading\nimport time\nimport socket\nimport xstruct as struct\nfrom datetime import datetime\n\nimport selectors2 as selectors\n\nimport utils\n\nfrom xlog import getLogger\nxlog = getLogger(\"x_tunnel\")\n\n\nclass WriteBuffer(object):\n    def __init__(self, s=None):\n        if isinstance(s, bytes):\n            self.string_len = len(s)\n            self.buffer_list = [s]\n        elif s is None:\n            self.reset()\n        else:\n            raise Exception(\"WriteBuffer init not bytes or StringBuffer\")\n\n    def reset(self):\n        self.buffer_list = []\n        self.string_len = 0\n\n    def __len__(self):\n        return self.string_len\n\n    def __add__(self, other):\n        self.append(other)\n        return self\n\n    def insert(self, s):\n        if isinstance(s, WriteBuffer):\n            self.buffer_list = s.buffer_list + self.buffer_list\n            self.string_len += s.string_len\n        elif isinstance(s, bytes):\n            self.buffer_list.insert(0, s)\n            self.string_len += len(s)\n        else:\n            raise Exception(\"WriteBuffer append not string or StringBuffer\")\n\n    def append(self, s):\n        if isinstance(s, WriteBuffer):\n            self.buffer_list.extend(s.buffer_list)\n            self.string_len += s.string_len\n        elif isinstance(s, bytes):\n            self.buffer_list.append(s)\n            self.string_len += len(s)\n        else:\n            raise Exception(\"WriteBuffer append not bytes or StringBuffer\")\n\n    def to_bytes(self):\n        return b\"\".join(self.buffer_list)\n\n    def __bytes__(self):\n        return self.to_bytes()\n\n    def __str__(self):\n        return self.to_bytes().decode(\"ascii\")\n\n\nclass ReadBuffer(object):\n    def __init__(self, buf, begin=0, size=None):\n        buf_len = len(buf)\n        if size is None:\n            if begin > buf_len:\n                raise Exception(\"ReadBuffer buf_len:%d, start:%d\" % (buf_len, begin))\n            size = buf_len - begin\n        elif begin + size > buf_len:\n            raise Exception(\"ReadBuffer buf_len:%d, start:%d len:%d\" % (buf_len, begin, size))\n\n        self.size = size\n        self.buf = memoryview(buf)\n        self.begin = begin\n\n    def __len__(self):\n        return self.size\n\n    def get(self, size=None):\n        if size is None:\n            size = self.size\n        elif size > self.size:\n            raise Exception(\"ReadBuffer get %d but left %d\" % (size, self.size))\n\n        data = self.buf[self.begin:self.begin + size]\n        self.begin += size\n        self.size -= size\n        return data\n\n    def get_buf(self, size=None):\n        if size is None:\n            size = self.size\n        elif size > self.size:\n            raise Exception(\"ReadBuffer get %d but left %d\" % (size, self.size))\n\n        buf = ReadBuffer(self.buf, self.begin, size)\n\n        self.begin += size\n        self.size -= size\n        return buf\n\n    def __bytes__(self):\n        return bytes(self.buf[self.begin:self.begin+self.size])\n\n    def __str__(self):\n        return (bytes(self.buf[self.begin:self.begin+self.size])).decode(\"ascii\")\n\n\nclass AckPool():\n    def __init__(self):\n        self.mutex = threading.Lock()\n        self.reset()\n\n    def reset(self):\n        # xlog.info(\"Ack_pool reset\")\n        with self.mutex:\n            self.ack_buffer = WriteBuffer()\n\n        # xlog.info(\"Ack_pool reset finished\")\n\n    def put(self, data):\n        # xlog.debug(\"Ack_pool put len:%d\", len(data))\n        with self.mutex:\n            self.ack_buffer.append(data)\n\n    def get(self):\n        with self.mutex:\n            data = self.ack_buffer\n            self.ack_buffer = WriteBuffer()\n\n        # xlog.debug(\"Ack_pool get len:%d\", len(data))\n        return data\n\n    def status(self):\n        out_string = \"Ack_pool:len %d\\r\\n\" % len(self.ack_buffer)\n        return out_string\n\n\nclass WaitQueue():\n    def __init__(self):\n        self.lock = threading.Lock()\n        self.waiters = []\n        # (end_time, Lock())\n\n        self.running = True\n\n    def stop(self):\n        self.running = False\n        xlog.info(\"WaitQueue stop\")\n        for end_time, lock in self.waiters:\n            lock.release()\n        self.waiters = []\n        xlog.info(\"WaitQueue stop finished\")\n\n    def notify(self):\n        # xlog.debug(\"notify\")\n        if len(self.waiters) == 0:\n            # xlog.debug(\"notify none.\")\n            return\n\n        try:\n            end_time, lock = self.waiters.pop(0)\n            lock.release()\n        except:\n            pass\n\n    def wait(self, wait_order):\n        with self.lock:\n            lock = threading.Lock()\n            lock.acquire()\n\n            if len(self.waiters) == 0:\n                self.waiters.append((wait_order, lock))\n            else:\n                is_max = True\n                for i in range(0, len(self.waiters)):\n                    try:\n                        i_wait_order, ilock = self.waiters[i]\n                        if i_wait_order > wait_order:\n                            is_max = False\n                            break\n                    except Exception as e:\n                        if i >= len(self.waiters):\n                            break\n                        xlog.warn(\"get %d from size:%d fail.\", i, len(self.waiters))\n                        continue\n\n                if is_max:\n                    self.waiters.append((wait_order, lock))\n                else:\n                    self.waiters.insert(i, (wait_order, lock))\n\n        lock.acquire()\n\n    def status(self):\n        out_string = \"waiters[%d]:\\n\" % len(self.waiters)\n        for i in range(0, len(self.waiters)):\n            end_time, lock = self.waiters[i]\n            out_string += \"%d\\r\\n\" % (end_time)\n\n        return out_string\n\n\nclass SendBuffer():\n    def __init__(self, max_payload):\n        self.mutex = threading.Lock()\n        self.max_payload = max_payload\n        self.reset()\n\n    def reset(self):\n        xlog.debug(\"SendBuffer reset\")\n        self.pool_size = 0\n        self.last_put_time = time.time()\n        with self.mutex:\n            self.head_sn = 1\n            self.tail_sn = 1\n            self.block_list = {}\n            self.last_block = WriteBuffer()\n\n    def put(self, data):\n        dlen = len(data)\n        # xlog.debug(\"SendBuffer len:%d\", dlen)\n        if dlen == 0:\n            xlog.warn(\"SendBuffer put 0\")\n            return False\n\n        # xlog.debug(\"SendBuffer put len:%d\", len(data))\n        self.last_put_time = time.time()\n        with self.mutex:\n            self.pool_size += dlen\n            self.last_block.append(data)\n\n            if len(self.last_block) > self.max_payload:\n                self.block_list[self.head_sn] = self.last_block\n                self.last_block = WriteBuffer()\n                self.head_sn += 1\n        return True\n\n    def get(self):\n        with self.mutex:\n            if self.tail_sn < self.head_sn:\n                data = self.block_list[self.tail_sn]\n                del self.block_list[self.tail_sn]\n                sn = self.tail_sn\n                self.tail_sn += 1\n\n                self.pool_size -= len(data)\n                # xlog.debug(\"send_pool get, sn:%r len:%d \", sn, len(data))\n                return data, sn\n\n            if len(self.last_block) > 0:\n                data = self.last_block\n                sn = self.tail_sn\n                self.last_block = WriteBuffer()\n                self.head_sn += 1\n                self.tail_sn += 1\n\n                self.pool_size -= len(data)\n                # xlog.debug(\"send_pool get, sn:%r len:%d \", sn, len(data))\n                return data, sn\n\n        #xlog.debug(\"Get:%s\", utils.str2hex(data))\n        # xlog.debug(\"SendBuffer get wake after no data, tail:%d\", self.tail_sn)\n        return \"\", 0\n\n    def status(self):\n        out_string = \"SendBuffer:\\n\"\n        out_string += \" size:%d\\n\" % self.pool_size\n        out_string += \" last_put_time:%f\\n\" % (time.time() - self.last_put_time)\n        out_string += \" head_sn:%d\\n\" % self.head_sn\n        out_string += \" tail_sn:%d\\n\" % self.tail_sn\n        out_string += \"block_list:[%d]\\n\" % len(self.block_list)\n        for sn in sorted(self.block_list.keys()):\n            data = self.block_list[sn]\n            out_string += \"[%d] len:%d\\r\\n\" % (sn, len(data))\n\n        return out_string\n\n\nclass BlockReceivePool():\n    def __init__(self, process_callback, logger):\n        self.lock = threading.Lock()\n        self.process_callback = process_callback\n        self.logger = logger\n        self.reset()\n\n    def reset(self):\n        # xlog.info(\"recv_pool reset\")\n        self.next_sn = 1\n        self.block_list = []\n        self.timeout_sn_list = {}\n\n    def put(self, sn, data):\n        # xlog.debug(\"recv_pool put sn:%d len:%d\", sn, len(data))\n        self.lock.acquire()\n        try:\n            if sn in self.timeout_sn_list:\n                del self.timeout_sn_list[sn]\n\n            if sn < self.next_sn:\n                # xlog.warn(\"recv_pool put timeout sn:%d\", sn)\n                return False\n            elif sn > self.next_sn:\n                # xlog.debug(\"recv_pool put disorder sn:%d\", sn)\n                if sn in self.block_list:\n                    # xlog.warn(\"recv_pool put sn:%d exist\", sn)\n                    return False\n                else:\n                    self.block_list.append(sn)\n                    self.process_callback(data)\n                    return True\n            else:\n                # xlog.debug(\"recv_pool put sn:%d in order\", sn)\n                self.process_callback(data)\n                self.next_sn += 1\n\n                while self.next_sn in self.block_list:\n                    # xlog.debug(\"recv_pool sn:%d processed\", sn)\n                    self.block_list.remove(self.next_sn)\n                    self.next_sn += 1\n                return True\n        except Exception as e:\n            raise Exception(\"recv_pool put sn:%d len:%d error:%r\" % (sn, len(data), e))\n        finally:\n            self.lock.release()\n\n    def mark_sn_timeout(self, sn, t, server_time):\n        # xlog.warn(\"mark_sn_timeout down_sn:%d\", sn)\n        with self.lock:\n            if sn not in self.timeout_sn_list:\n                self.logger.warn(\"mark_sn_timeout sn:%d t:%f\", sn, server_time - t)\n                self.timeout_sn_list[sn] = {\n                    \"server_send_time\": t,\n                }\n            elif t > self.timeout_sn_list[sn][\"server_send_time\"]:\n                self.logger.warn(\"mark_sn_timeout renew sn:%d t:%f\", sn, server_time - t)\n                self.timeout_sn_list[sn][\"server_send_time\"] = t\n\n    def get_timeout_list(self, server_time, timeout):\n        sn_list = []\n        with self.lock:\n            for sn, info in self.timeout_sn_list.items():\n                if server_time - info[\"server_send_time\"] < timeout:\n                    continue\n\n                if server_time - info.get(\"retry_time\", server_time) < timeout:\n                    continue\n\n                self.logger.warn(\"get_timeout_list sn:%d sent:%f retry:%f\", sn, server_time - info[\"server_send_time\"],\n                                 server_time - info.get(\"retry_time\", server_time))\n                info[\"retry_time\"] = server_time\n                sn_list.append(sn)\n\n        return sn_list\n\n    def is_received(self, sn):\n        if sn < self.next_sn:\n            return True\n\n        if sn in self.block_list:\n            return True\n\n        return False\n\n    def status(self):\n        out_string = \"Block_receive_pool:\\r\\n\"\n        out_string += \" next_sn:%d\\r\\n\" % self.next_sn\n        for sn in sorted(self.block_list):\n            out_string += \"[%d] \\r\\n\" % (sn)\n\n        return out_string\n\n\nclass ConnectionPipe(object):\n    def __init__(self, session, xlog):\n        self.session = session\n        self.xlog = xlog\n        self.running = True\n        self.th = None\n        self.select2 = selectors.DefaultSelector()\n        self.sock_conn_map = {}\n        self._lock = threading.RLock()\n\n        if sys.platform == \"win32\":\n            self.slow_wait = 0.05\n        else:\n            self.slow_wait = 3\n            # self.slow_wait = 0.05\n\n    def status(self):\n        out_string = \"ConnectionPipe:\\r\\n\"\n        out_string += \" running: %s\\r\\n\" % self.running\n        out_string += \" thread: %s\\r\\n\" % self.th\n        out_string += \" conn: \"\n        for conn in self.sock_conn_map.values():\n            out_string += \"%d,\" % (conn.conn_id)\n        out_string += \"\\r\\n\"\n\n        return out_string\n\n    def start(self):\n        self.running = True\n        self.sock_conn_map = {}\n\n    def stop(self):\n        self.running = False\n        self._debug_log(\"ConnectionPipe stop\")\n\n    def _debug_log(self, fmt, *args, **kwargs):\n        if not self.session or not self.session.config.show_debug:\n            return\n        self.xlog.debug(fmt, *args, **kwargs)\n\n    def add_sock_event(self, sock, conn, event):\n        # this function can repeat without through an error.\n\n        if not sock:\n            return\n\n        with self._lock:\n            self._debug_log(\"add_sock_event conn:%d event:%s\", conn.conn_id, event)\n            try:\n                self.select2.register_event(sock, event, conn)\n            except Exception as e:\n                self.xlog.warn(\"add_sock_event %s conn:%d e:%r\", sock, conn.conn_id, e)\n                self.close_sock(sock, str(e) + \"_when_add_sock_event\")\n                return\n\n            # if sys.platform == \"win32\" and (sock not in self.sock_conn_map or event == selectors.EVENT_WRITE):\n            #     self.notice_select()\n\n            self.sock_conn_map[sock] = conn\n\n            if not self.th:\n                self.th = threading.Thread(target=self.pipe_worker, name=\"x_tunnel_pipe_worker\")\n                self.th.start()\n                self._debug_log(\"ConnectionPipe start\")\n\n    def remove_sock_event(self, sock, event):\n        # this function can repeat without through an error.\n\n        with self._lock:\n            if sock not in self.sock_conn_map:\n                return\n\n            try:\n                conn = self.sock_conn_map[sock]\n                self._debug_log(\"remove_sock_event conn:%d event:%s\", conn.conn_id, event)\n                res = self.select2.unregister_event(sock, event)\n                if not res:\n                    # self.xlog.debug(\"remove_sock_event %s conn:%d event:%s removed all\", sock, conn.conn_id, event)\n                    del self.sock_conn_map[sock]\n            except Exception as e:\n                self.xlog.exception(\"remove_sock_event %s event:%s e:%r\", sock, event, e)\n\n    def remove_sock(self, sock):\n        with self._lock:\n            if sock not in self.sock_conn_map:\n                return\n\n            try:\n                conn = self.sock_conn_map[sock]\n                self._debug_log(\"remove_sock all events conn:%d\", conn.conn_id)\n                del self.sock_conn_map[sock]\n                self.select2.unregister(sock)\n            except Exception as e:\n                # error will happen when sock closed\n                self.xlog.warn(\"ConnectionPipe remove sock e:%r\", e)\n\n    def close_sock(self, sock, reason):\n        if sock not in self.sock_conn_map:\n            return\n\n        try:\n            conn = self.sock_conn_map[sock]\n            # self.xlog.info(\"close conn:%d\", conn.conn_id)\n            self.remove_sock(sock)\n\n            conn.transfer_peer_close(reason)\n            conn.do_stop(reason=reason)\n        except Exception as e:\n            self.xlog.exception(\"close_sock %s e:%r\", sock, e)\n\n    def reset_all_connections(self):\n        for sock, conn in dict(self.sock_conn_map).items():\n            self.close_sock(sock, \"reset_all\")\n\n        self.sock_conn_map = {}\n        self.select2 = selectors.DefaultSelector()\n\n    def notice_select(self):\n        self.xlog.debug(\"notice select\")\n\n    def read_notify(self):\n        self.xlog.debug(\"read_notify\")\n\n    def pipe_worker(self):\n        timeout = 0.001\n        while self.running:\n            if not self.sock_conn_map:\n                break\n\n            try:\n                try:\n                    events = self.select2.select(timeout=timeout)\n                    if not events:\n                        # self.xlog.debug(\"%s session check_upload\", random_id)\n                        has_data = self.session.check_upload()\n                        if has_data:\n                            timeout = 0.01\n                        else:\n                            timeout = self.slow_wait\n\n                        # self.xlog.debug(\"%s recv select timeout switch to %f\", random_id, timeout)\n                        continue\n                    else:\n                        # self.xlog.debug(\"%s recv select timeout switch to 0.001\", random_id)\n                        timeout = 0.001\n                except Exception as e:\n                    self.xlog.exception(\"Conn session:%s select except:%r\", self.session.session_id, e)\n                    if \"Invalid argument\" in str(e):\n                        self.reset_all_connections()\n                    time.sleep(1)\n                    continue\n\n                now = time.time()\n                for key, event in events:\n                    sock = key.fileobj\n                    conn = key.data\n                    if not conn:\n                        self.xlog.debug(\"get notice\")\n                        self.read_notify()\n                        continue\n\n                    if event & selectors.EVENT_READ:\n                        try:\n                            data = sock.recv(65535)\n                        except Exception as e:\n                            self._debug_log(\"conn:%d recv e:%r\", conn.conn_id, e)\n                            data = \"\"\n\n                        data_len = len(data)\n                        if data_len == 0:\n                            # self.xlog.debug(\"Conn conn:%d recv zero\", conn.conn_id)\n                            self.close_sock(sock, \"receive\")\n                            continue\n                        else:\n                            conn.last_active = now\n                            self._debug_log(\"Conn session:%s conn:%d local recv len:%d pos:%d\",\n                                            self.session.session_id, conn.conn_id, data_len, conn.received_position)\n\n                            conn.transfer_received_data(data)\n                    elif event & selectors.EVENT_WRITE:\n                        conn.blocked = False\n                        conn.process_cmd()\n                    else:\n                        self.xlog.debug(\"no event for conn:%d\", conn.conn_id)\n                        self.close_sock(sock, \"no_event\")\n\n            except Exception as e:\n                xlog.exception(\"recv_worker e:%r\", e)\n\n        for sock in dict(self.sock_conn_map):\n            try:\n                self.select2.unregister(sock)\n            except Exception as e:\n                xlog.warn(\"unregister %s e:%r\", sock, e)\n        self.sock_conn_map = {}\n        self._debug_log(\"ConnectionPipe stop\")\n        self.th = None\n        self.session.check_upload()\n\n\nclass Conn(object):\n    def __init__(self, session, conn_id, sock, host, port, windows_size, windows_ack, is_client, xlog):\n        # xlog.info(\"session:%s conn:%d host:%s port:%d\", session.session_id, conn_id, host, port)\n        self.host = host\n        self.port = port\n        self.session = session\n        self.conn_id = conn_id\n        self.sock = sock\n        self.windows_size = windows_size\n        self.windows_ack = windows_ack\n        self.is_client = is_client\n\n        self.connection_pipe = session.connection_pipe\n        self.xlog = xlog\n\n        self.cmd_queue = {}\n        self.running = True\n        self.blocked = False\n        self.send_buffer = b\"\"\n        self.received_position = 0\n        self.remote_acked_position = 0\n        self.sended_position = 0\n        self.sent_window_position = 0\n        self.create_time = time.time()\n        self.last_active = time.time()\n        self._lock = threading.Lock()\n\n        self.transferred_close_to_peer = False\n        if sock:\n            self.next_cmd_seq = 1\n            self._fd = sock.fileno()\n            # self.xlog.debug(\"conn:%d init fd:%d\", conn_id, self._fd)\n        else:\n            self.next_cmd_seq = 0\n\n        self.next_recv_seq = 1\n\n    def start(self, block):\n        if self.sock:\n            self.connection_pipe.add_sock_event(self.sock, self, selectors.EVENT_READ)\n\n    def status(self):\n        out_string = \"Conn[%d]: %s:%d\\n\" % (self.conn_id, self.host, self.port)\n        out_string += \" received_position:%d/ Ack:%d \\n\" % (self.received_position, self.remote_acked_position)\n        out_string += \" sended_position:%d/ win:%d\\n\" % (self.sended_position, self.sent_window_position)\n        out_string += \" next_cmd_seq:%d\\n\" % self.next_cmd_seq\n        out_string += \" next_recv_seq:%d\\n\" % self.next_recv_seq\n        out_string += \" running:%r\\n\" % self.running\n        out_string += \" blocked: %s\\n\" % self.blocked\n        if self.send_buffer:\n            out_string += \" send_buffer: %d\\n\" % len(self.send_buffer)\n        out_string += \" transferred_close_to_peer:%r\\n\" % self.transferred_close_to_peer\n        out_string += \" sock:%r\\n\" % (self.sock is not None)\n        out_string += \" cmd_queue.len:%d\\n\" % len(self.cmd_queue)\n        out_string += \" create time: %s\\n\" % datetime.fromtimestamp(self.create_time).strftime('%Y-%m-%d %H:%M:%S.%f')\n        out_string += \" last active: %s\\n\" % datetime.fromtimestamp(self.last_active).strftime('%Y-%m-%d %H:%M:%S.%f')\n        for seq in self.cmd_queue:\n            out_string += \"[%d],\" % seq\n        out_string += \"\\n\"\n\n        return out_string\n\n    def stop(self, reason=\"\"):\n        threading.Thread(target=self.do_stop, args=(reason,),\n                         name=\"do_stop_%s:%d\" % (self.host, self.port)).start()\n\n    def do_stop(self, reason=\"unknown\"):\n        self.xlog.debug(\"Conn session:%s %s:%d conn:%d fd:%d stop:%s\", utils.to_str(self.session.session_id),\n                        self.host, self.port, self.conn_id, self._fd, reason)\n        self.running = False\n\n        self.connection_pipe.remove_sock(self.sock)\n\n        self.cmd_queue = {}\n\n        if self.sock is not None:\n            try:\n                self.sock.close()\n            except:\n                pass\n            self.sock = None\n\n        # self.xlog.debug(\"Conn session:%s conn:%d stopped\", self.session.session_id, self.conn_id)\n        self.session.remove_conn(self.conn_id)\n\n    def do_connect(self, host, port):\n        # self.xlog.info(\"session_id:%s create_conn conn:%d %s:%d\", self.session.session_id, self.conn_id, host, port)\n        connect_timeout = 30\n        sock = None\n        start_time = time.time()\n        ip = \"\"\n        try:\n            if ':' in host:\n                # IPV6\n                ip = host\n            elif utils.check_ip_valid4(host):\n                # IPV4\n                ip = host\n            else:\n                # self.xlog.debug(\"getting ip of %s\", host)\n                ip = socket.gethostbyname(host)\n                # self.xlog.debug(\"resolve %s to %s\", host, ip)\n            sock = socket.socket(socket.AF_INET if ':' not in ip else socket.AF_INET6)\n            # set reuseaddr option to avoid 10048 socket error\n            sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)\n            # resize socket recv buffer ->256K to improve browser releated application performance\n            sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 262144)\n            # disable negal algorithm to send http request quickly.\n            sock.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, True)\n            # set a short timeout to trigger timeout retry more quickly.\n            sock.settimeout(connect_timeout)\n\n            sock.connect((ip, port))\n\n            # record TCP connection time\n            # conn_time = time.time() - start_time\n            # self.xlog.debug(\"tcp conn %s %s time:%d\", host, ip, conn_time * 1000)\n\n            return sock, True\n        except Exception as e:\n            conn_time = int((time.time() - start_time) * 1000)\n            self.xlog.debug(\"tcp conn host:%s %s:%d fail t:%d %r\", host, ip, port, conn_time, e)\n            if sock:\n                sock.close()\n            return e, False\n\n    def put_cmd_data(self, data):\n        if not self.running:\n            return\n\n        seq = struct.unpack(\"<I\", data.get(4))[0]\n        if seq < self.next_cmd_seq:\n            self.xlog.warn(\"put_send_data %s conn:%d seq:%d next:%d\",\n                           self.session.session_id, self.conn_id,\n                           seq, self.next_cmd_seq)\n            return\n\n        self._debug_log(\"conn:%d put data seq:%d len:%d\", self.conn_id, seq, len(data))\n\n        with self._lock:\n            self.cmd_queue[seq] = data.get_buf()\n            if seq == self.next_cmd_seq:\n                if self.sock:\n                    self.connection_pipe.add_sock_event(self.sock, self, selectors.EVENT_WRITE)\n                else:\n                    self.process_cmd()\n\n    def get_cmd_data(self):\n        if self.next_cmd_seq not in self.cmd_queue:\n            self._debug_log(\"get_cmd_data conn:%d no data, next_cmd_seq:%d\", self.conn_id, self.next_cmd_seq)\n            return None\n\n        payload = self.cmd_queue[self.next_cmd_seq]\n        del self.cmd_queue[self.next_cmd_seq]\n        # self.xlog.debug(\"Conn session:%s conn:%d get data sn:%d len:%d \",\n        #                self.session.session_id, self.conn_id, self.next_cmd_seq, len(payload))\n        self.next_cmd_seq += 1\n        return payload\n\n    def _debug_log(self, fmt, *args, **kwargs):\n        if not self.session.config.show_debug:\n            return\n        self.xlog.debug(fmt, *args, **kwargs)\n\n    def process_cmd(self):\n        while self.running:\n            if self.blocked:\n                return\n\n            if self.send_buffer:\n                if not self.send_to_sock(self.send_buffer):\n                    return\n\n            with self._lock:\n                data = self.get_cmd_data()\n                if not data:\n                    self._debug_log(\"conn:%d no data\", self.conn_id)\n                    self.connection_pipe.remove_sock_event(self.sock, selectors.EVENT_WRITE)\n                    break\n\n            self.last_active = time.time()\n            cmd_id = struct.unpack(\"<B\", data.get(1))[0]\n            if cmd_id == 1:  # data\n                self._debug_log(\"conn:%d download len:%d pos:%d\", self.conn_id, len(data), self.sended_position)\n                self.send_to_sock(data.get())\n\n            elif cmd_id == 3:  # ack:\n                position = struct.unpack(\"<Q\", data.get(8))[0]\n                self._debug_log(\"Conn session:%s conn:%d ACK:%d\", self.session.session_id, self.conn_id, position)\n                if position > self.remote_acked_position:\n                    self.remote_acked_position = position\n\n                    self.connection_pipe.add_sock_event(self.sock, self, selectors.EVENT_READ)\n\n            elif cmd_id == 2:  # Closed\n                dat = data.get()\n                if isinstance(dat, memoryview):\n                    dat = dat.tobytes()\n                self.xlog.debug(\"Conn session:%s conn:%d Peer Close:%s\", self.session.session_id, self.conn_id, dat)\n                if self.is_client:\n                    self.transfer_peer_close(\"finish\")\n                    if b\"exceed the max connection\" in dat:\n                        self.session.reset()\n                self.stop(\"peer close\")\n\n            elif cmd_id == 0:  # Create connect\n                if self.port or len(self.host) or self.next_cmd_seq != 1 or self.sock:\n                    raise Exception(\"put_send_data %s conn:%d Create but host:%s port:%d next seq:%d\" % (\n                        self.session.session_id, self.conn_id,\n                        self.host, self.port, self.next_cmd_seq))\n\n                self.sock_type = struct.unpack(\"<B\", data.get(1))[0]\n                host_len = struct.unpack(\"<H\", data.get(2))[0]\n                self.host = data.get(host_len)\n                self.port = struct.unpack(\"<H\", data.get(2))[0]\n\n                sock, res = self.do_connect(self.host, self.port)\n                if res is False:\n                    self.xlog.debug(\"Conn session:%s conn:%d %s:%d Create fail\", self.session.session_id, self.conn_id,\n                               self.host, self.port)\n                    self.transfer_peer_close(\"connect fail\")\n                else:\n                    self.xlog.info(\"Conn session:%s conn:%d %s:%d\", self.session.session_id, self.conn_id, self.host,\n                              self.port)\n                    self.sock = sock\n                    self.connection_pipe.add_sock_event(self.sock, self, selectors.EVENT_READ)\n            else:\n                self.xlog.error(\"Conn session:%s conn:%d unknown cmd_id:%d\",\n                                self.session.session_id, self.conn_id, cmd_id)\n                raise Exception(\"put_send_data unknown cmd_id:%d\" % cmd_id)\n\n    def send_to_sock(self, data):\n        # return True when not blocked, can send more data\n\n        self._debug_log(\"Conn send_to_sock conn:%d len:%d\", self.conn_id, len(data))\n        sock = self.sock\n        if not sock:\n            return False\n\n        payload_len = len(data)\n        start = 0\n        end = payload_len\n        while start < end:\n            send_size = min(end - start, 65535)\n            try:\n                sended = sock.send(data[start:start + send_size])\n            except Exception as e:\n                self.xlog.info(\"%s conn:%d send closed: %r\", self.session.session_id, self.conn_id, e)\n                if self.is_client:\n                    self.transfer_peer_close(\"send fail.\")\n                    self.do_stop(reason=\"send fail.\")\n                return False\n\n            start += sended\n\n            if sended == 0:\n                self.connection_pipe.add_sock_event(sock, self, selectors.EVENT_WRITE)\n                self.send_buffer = data[start:]\n                self.blocked = True\n                break\n\n        if start == end:\n            self.send_buffer = None\n\n        self.sended_position += start\n        if self.sended_position - self.sent_window_position > self.windows_ack:\n            self.sent_window_position = self.sended_position\n            self.transfer_ack(self.sended_position)\n            self._debug_log(\"Conn:%d ack:%d\", self.conn_id, self.sent_window_position)\n\n        return not self.blocked\n\n    def transfer_peer_close(self, reason=\"\"):\n        if self.transferred_close_to_peer:\n            return\n\n        self.transferred_close_to_peer = True\n\n        cmd = struct.pack(\"<IB\", self.next_recv_seq, 2)\n        if isinstance(reason, str):\n            reason = reason.encode(\"utf-8\")\n        self.session.send_conn_data(self.conn_id, cmd + reason)\n        self.next_recv_seq += 1\n\n    def transfer_received_data(self, data):\n        if self.transferred_close_to_peer:\n            return\n\n        buf = WriteBuffer(struct.pack(\"<IB\", self.next_recv_seq, 1))\n        buf.append(data)\n        self.next_recv_seq += 1\n        self.received_position += len(data)\n\n        self.session.send_conn_data(self.conn_id, buf)\n\n        if self.received_position > self.remote_acked_position + self.windows_size:\n            self.xlog.debug(\"Conn session:%s conn:%d recv blocked, rcv:%d, ack:%d\", self.session.session_id,\n                            self.conn_id, self.received_position, self.remote_acked_position)\n            self.connection_pipe.remove_sock_event(self.sock, selectors.EVENT_READ)\n\n    def transfer_ack(self, position):\n        if self.transferred_close_to_peer:\n            return\n\n        cmd_position = struct.pack(\"<IBQ\", self.next_recv_seq, 3, position)\n        self.session.send_conn_data(self.conn_id, cmd_position)\n        self.next_recv_seq += 1\n"
  },
  {
    "path": "code/default/x_tunnel/local/client.py",
    "content": "import os\nimport sys\nimport json\nimport platform\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\npython_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))\n\nnoarch_lib = os.path.abspath(os.path.join(python_path, 'lib', 'noarch'))\nsys.path.append(noarch_lib)\n\nroot_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))\nsys.path.append(root_path)\n\nimport env_info\ndata_path = env_info.data_path\ndata_xtunnel_path = os.path.join(data_path, 'x_tunnel')\n\nlib_path = os.path.abspath(os.path.join(current_path, os.pardir, 'common'))\nsys.path.append(lib_path)\n\nready = False\n# don't remove, launcher web_control need it.\n\n\ndef create_data_path():\n    if not os.path.isdir(data_path):\n        os.mkdir(data_path)\n\n    if not os.path.isdir(data_xtunnel_path):\n        os.mkdir(data_xtunnel_path)\n\n\ncreate_data_path()\n\nfrom xlog import getLogger\nxlog = getLogger(\"x_tunnel\", log_path=data_xtunnel_path, save_start_log=1500, save_warning_log=True)\n\nimport os_platform\nfrom x_tunnel.local.proxy_handler import Socks5Server\nfrom x_tunnel.local import global_var as g\nfrom x_tunnel.local import proxy_session\nimport simple_http_server\nfrom x_tunnel.local import front_dispatcher\nfrom x_tunnel.local import config\n\nfrom x_tunnel.local import web_control\n# don't remove, launcher web_control need it.\n\n\ndef xxnet_version():\n    version_file = os.path.join(root_path, \"version.txt\")\n    try:\n        with open(version_file, \"r\") as fd:\n            version = fd.read()\n        return version\n    except Exception as e:\n        xlog.exception(\"get version fail\")\n    return \"get_version_fail\"\n\n\ndef get_launcher_uuid():\n    launcher_config_fn = os.path.join(data_path, \"launcher\", \"config.json\")\n    try:\n        with open(launcher_config_fn, \"r\", encoding='utf-8') as fd:\n            info = json.load(fd)\n            return info.get(\"update_uuid\")\n    except Exception as e:\n        xlog.exception(\"get_launcher_uuid except:%r\", e)\n        return \"\"\n\n\ndef start(args):\n    global ready\n\n    g.xxnet_version = xxnet_version()\n    g.client_uuid = get_launcher_uuid()\n    g.system = os_platform.platform + \"|\" + platform.version() + \"|\" + str(platform.architecture()) + \"|\" + sys.version\n\n    g.config = config.load_config()\n    front_dispatcher.init()\n    g.data_path = data_path\n\n    xlog.info(\"version:%s\", g.xxnet_version)\n\n    g.running = True\n    if not g.server_host or not g.server_port:\n        if g.config.server_host and g.config.server_port == 443:\n            xlog.info(\"Session Server:%s:%d\", g.config.server_host, g.config.server_port)\n            g.server_host = g.config.server_host\n            g.server_port = g.config.server_port\n            g.balance = 99999999\n        elif g.config.api_server:\n            pass\n        else:\n            xlog.debug(\"please check x-tunnel server in config\")\n\n    g.http_client = front_dispatcher\n\n    g.session = proxy_session.ProxySession()\n\n    allow_remote = args.get(\"allow_remote\", 0)\n\n    listen_ips = g.config.socks_host\n    if isinstance(listen_ips, str):\n        listen_ips = [listen_ips]\n    else:\n        listen_ips = list(listen_ips)\n\n    if allow_remote and (\"0.0.0.0\" not in listen_ips or \"::\" not in listen_ips):\n        listen_ips = [(\"0.0.0.0\"),]\n\n    for port in range(g.config.socks_port, g.config.socks_port + 2000):\n        addresses = [(listen_ip, port) for listen_ip in listen_ips]\n        try:\n            g.socks5_server = simple_http_server.HTTPServer(addresses, Socks5Server, logger=xlog)\n            g.socks5_server.init_socket()\n            g.bind_port = port\n        except:\n            continue\n        xlog.info(\"Socks5 server listen:%s:%d.\", g.config.socks_host, port)\n        break\n\n    ready = True\n    g.socks5_server.serve_forever()\n\n\ndef stop():\n    global ready\n    g.running = False\n    g.http_client.stop()\n    front_dispatcher.stop()\n\n    if g.socks5_server:\n        xlog.info(\"Close Socks5 server \")\n        g.socks5_server.shutdown()\n        g.socks5_server = None\n\n    if g.session:\n        xlog.info(\"Stopping session\")\n        g.session.stop()\n        g.session = None\n    ready = False\n\n\nif __name__ == '__main__':\n    try:\n        start({})\n    except KeyboardInterrupt:\n        stop()\n        import sys\n\n        sys.exit()\n"
  },
  {
    "path": "code/default/x_tunnel/local/cloudflare_front/__init__.py",
    "content": "\nfrom .front import front"
  },
  {
    "path": "code/default/x_tunnel/local/cloudflare_front/cacert.pem",
    "content": "##\n## Bundle of CA Root Certificates\n##\n## Certificate data from Mozilla as of: Wed Jul 22 03:12:14 2020 GMT\n##\n## This is a bundle of X.509 certificates of public Certificate Authorities\n## (CA). These were automatically extracted from Mozilla's root certificates\n## file (certdata.txt).  This file can be found in the mozilla source tree:\n## https://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt\n##\n## It contains the certificates in PEM format and therefore\n## can be directly used with curl / libcurl / php_curl, or with\n## an Apache+mod_ssl webserver for SSL client authentication.\n## Just configure this file as the SSLCACertificateFile.\n##\n## Conversion done with mk-ca-bundle.pl version 1.28.\n## SHA256: cc6408bd4be7fbfb8699bdb40ccb7f6de5780d681d87785ea362646e4dad5e8e\n##\n\n\nGlobalSign Root CA\n==================\n-----BEGIN CERTIFICATE-----\nMIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx\nGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds\nb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV\nBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD\nVQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa\nDuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc\nTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb\nKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP\nc1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX\ngzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV\nHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF\nAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj\nY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG\nj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH\nhm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC\nX4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==\n-----END CERTIFICATE-----\n\nGlobalSign Root CA - R2\n=======================\n-----BEGIN CERTIFICATE-----\nMIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4GA1UECxMXR2xv\nYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh\nbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT\naWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln\nbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6\nErPLv4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8eoLrvozp\ns6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklqtTleiDTsvHgMCJiEbKjN\nS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzdC9XZzPnqJworc5HGnRusyMvo4KD0L5CL\nTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pazq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6C\nygPCm48CAwEAAaOBnDCBmTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E\nFgQUm+IHV2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5nbG9i\nYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG3lm0mi3f3BmGLjAN\nBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4GsJ0/WwbgcQ3izDJr86iw8bmEbTUsp\n9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu\n01yiPqFbQfXf5WRDLenVOavSot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG7\n9G+dwfCMNYxdAfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7\nTBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==\n-----END CERTIFICATE-----\n\nEntrust.net Premium 2048 Secure Server CA\n=========================================\n-----BEGIN CERTIFICATE-----\nMIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChMLRW50cnVzdC5u\nZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBpbmNvcnAuIGJ5IHJlZi4gKGxp\nbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNV\nBAMTKkVudHJ1c3QubmV0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQx\nNzUwNTFaFw0yOTA3MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3\nd3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTEl\nMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5u\nZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\nMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQqK0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOL\nGp18EzoOH1u3Hs/lJBQesYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSr\nhRSGlVuXMlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVTXTzW\nnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/HoZdenoVve8AjhUi\nVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH4QIDAQABo0IwQDAOBgNVHQ8BAf8E\nBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJ\nKoZIhvcNAQEFBQADggEBADubj1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPy\nT/4xmf3IDExoU8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf\nzX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5bu/8j72gZyxKT\nJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+bYQLCIt+jerXmCHG8+c8eS9e\nnNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/ErfF6adulZkMV8gzURZVE=\n-----END CERTIFICATE-----\n\nBaltimore CyberTrust Root\n=========================\n-----BEGIN CERTIFICATE-----\nMIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJRTESMBAGA1UE\nChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3li\nZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoXDTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMC\nSUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFs\ndGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKME\nuyKrmD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsB\nUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/C\nG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9\nXbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjpr\nl3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoI\nVDaGezq1BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEB\nBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT929hkTI7gQCvlYpNRh\ncL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3WgxjkzSswF07r51XgdIGn9w/xZchMB5\nhbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsa\nY71k5h+3zvDyny67G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H\nRCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp\n-----END CERTIFICATE-----\n\nEntrust Root Certification Authority\n====================================\n-----BEGIN CERTIFICATE-----\nMIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMCVVMxFjAUBgNV\nBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0Lm5ldC9DUFMgaXMgaW5jb3Jw\nb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMWKGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsG\nA1UEAxMkRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0\nMloXDTI2MTEyNzIwNTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMu\nMTkwNwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSByZWZlcmVu\nY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNVBAMTJEVudHJ1c3QgUm9v\ndCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\nALaVtkNC+sZtKm9I35RMOVcF7sN5EUFoNu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYsz\nA9u3g3s+IIRe7bJWKKf44LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOww\nCj0Yzfv9KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGIrb68\nj6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi94DkZfs0Nw4pgHBN\nrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOBsDCBrTAOBgNVHQ8BAf8EBAMCAQYw\nDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAigA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1\nMzQyWjAfBgNVHSMEGDAWgBRokORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DH\nhmak8fdLQ/uEvW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA\nA4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9tO1KzKtvn1ISM\nY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6ZuaAGAT/3B+XxFNSRuzFVJ7yVTa\nv52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTS\nW3iDVuycNsMm4hH2Z0kdkquM++v/eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0\ntHuu2guQOHXvgR1m0vdXcDazv/wor3ElhVsT/h5/WrQ8\n-----END CERTIFICATE-----\n\nGeoTrust Global CA\n==================\n-----BEGIN CERTIFICATE-----\nMIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVTMRYwFAYDVQQK\nEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9iYWwgQ0EwHhcNMDIwNTIxMDQw\nMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j\nLjEbMBkGA1UEAxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB\nCgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjo\nBbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDviS2Aelet\n8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU1XupGc1V3sjs0l44U+Vc\nT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagU\nvTLrGAMoUgRx5aszPeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTAD\nAQH/MB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVk\nDBF9qn1luMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKInZ57Q\nzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfStQWVYrmm3ok9Nns4\nd0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcFPseKUgzbFbS9bZvlxrFUaKnjaZC2\nmqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Unhw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6p\nXE0zX5IJL4hmXXeXxx12E6nV5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvm\nMw==\n-----END CERTIFICATE-----\n\nGeoTrust Universal CA\n=====================\n-----BEGIN CERTIFICATE-----\nMIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN\nR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVyc2FsIENBMB4XDTA0MDMwNDA1\nMDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu\nYy4xHjAcBgNVBAMTFUdlb1RydXN0IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIP\nADCCAgoCggIBAKYVVaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9t\nJPi8cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTTQjOgNB0e\nRXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFhF7em6fgemdtzbvQKoiFs\n7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2vc7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d\n8Lsrlh/eezJS/R27tQahsiFepdaVaH/wmZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7V\nqnJNk22CDtucvc+081xdVHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3Cga\nRr0BHdCXteGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZf9hB\nZ3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfReBi9Fi1jUIxaS5BZu\nKGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+nhutxx9z3SxPGWX9f5NAEC7S8O08\nni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0\nXG0D08DYj3rWMB8GA1UdIwQYMBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIB\nhjANBgkqhkiG9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc\naanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fXIwjhmF7DWgh2\nqaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzynANXH/KttgCJwpQzgXQQpAvvL\noJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0zuzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsK\nxr2EoyNB3tZ3b4XUhRxQ4K5RirqNPnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxF\nKyDuSN/n3QmOGKjaQI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2\nDFKWkoRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9ER/frslK\nxfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQtDF4JbAiXfKM9fJP/P6EU\np8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/SfuvmbJxPgWp6ZKy7PtXny3YuxadIwVyQD8vI\nP/rmMuGNG2+k5o7Y+SlIis5z/iw=\n-----END CERTIFICATE-----\n\nGeoTrust Universal CA 2\n=======================\n-----BEGIN CERTIFICATE-----\nMIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN\nR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwHhcNMDQwMzA0\nMDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3Qg\nSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUA\nA4ICDwAwggIKAoICAQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0\nDE81WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUGFF+3Qs17\nj1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdqXbboW0W63MOhBW9Wjo8Q\nJqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxLse4YuU6W3Nx2/zu+z18DwPw76L5GG//a\nQMJS9/7jOvdqdzXQ2o3rXhhqMcceujwbKNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2\nWP0+GfPtDCapkzj4T8FdIgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP\n20gaXT73y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRthAAn\nZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgocQIgfksILAAX/8sgC\nSqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4Lt1ZrtmhN79UNdxzMk+MBB4zsslG\n8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2\n+/CfXGJx7Tz0RzgQKzAfBgNVHSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8E\nBAMCAYYwDQYJKoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z\ndXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQL1EuxBRa3ugZ\n4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgrFg5fNuH8KrUwJM/gYwx7WBr+\nmbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSoag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpq\nA1Ihn0CoZ1Dy81of398j9tx4TuaYT1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpg\nY+RdM4kX2TGq2tbzGDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiP\npm8m1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJVOCiNUW7d\nFGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH6aLcr34YEoP9VhdBLtUp\ngn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwXQMAJKOSLakhT2+zNVVXxxvjpoixMptEm\nX36vWkzaH6byHCx+rgIW0lbQL1dTR+iS\n-----END CERTIFICATE-----\n\nComodo AAA Services root\n========================\n-----BEGIN CERTIFICATE-----\nMIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS\nR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg\nTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAw\nMFoXDTI4MTIzMTIzNTk1OVowezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hl\nc3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNV\nBAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\nggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQuaBtDFcCLNSS1UY8y2bmhG\nC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe3M/vg4aijJRPn2jymJBGhCfHdr/jzDUs\ni14HZGWCwEiwqJH5YZ92IFCokcdmtet4YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszW\nY19zjNoFmag4qMsXeDZRrOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjH\nYpy+g8cmez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQUoBEK\nIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wewYDVR0f\nBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNl\ncy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29tb2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2Vz\nLmNybDANBgkqhkiG9w0BAQUFAAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm\n7l3sAg9g1o1QGE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz\nRt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2G9w84FoVxp7Z\n8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsil2D4kF501KKaU73yqWjgom7C\n12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==\n-----END CERTIFICATE-----\n\nQuoVadis Root CA\n================\n-----BEGIN CERTIFICATE-----\nMIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJCTTEZMBcGA1UE\nChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0\neTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAz\nMTkxODMzMzNaFw0yMTAzMTcxODMzMzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRp\ncyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQD\nEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF\nAAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Ypli4kVEAkOPcahdxYTMuk\nJ0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2DrOpm2RgbaIr1VxqYuvXtdj182d6UajtL\nF8HVj71lODqV0D1VNk7feVcxKh7YWWVJWCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeL\nYzcS19Dsw3sgQUSj7cugF+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWen\nAScOospUxbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCCAk4w\nPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVvdmFkaXNvZmZzaG9y\nZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREwggENMIIBCQYJKwYBBAG+WAABMIH7\nMIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNlIG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmlj\nYXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJs\nZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh\nY3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYIKwYBBQUHAgEW\nFmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3TKbkGGew5Oanwl4Rqy+/fMIGu\nBgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rqy+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkw\nFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0\naG9yaXR5MS4wLAYDVQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6\ntlCLMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSkfnIYj9lo\nfFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf87C9TqnN7Az10buYWnuul\nLsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1RcHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2x\ngI4JVrmcGmD+XcHXetwReNDWXcG31a0ymQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi\n5upZIof4l/UO/erMkqQWxFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi\n5nrQNiOKSnQ2+Q==\n-----END CERTIFICATE-----\n\nQuoVadis Root CA 2\n==================\n-----BEGIN CERTIFICATE-----\nMIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT\nEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMjAeFw0wNjExMjQx\nODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM\naW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4IC\nDwAwggIKAoICAQCaGMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6\nXJxgFyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55JWpzmM+Yk\nlvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bBrrcCaoF6qUWD4gXmuVbB\nlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp+ARz8un+XJiM9XOva7R+zdRcAitMOeGy\nlZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt\n66/3FsvbzSUr5R/7mp/iUcw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1Jdxn\nwQ5hYIizPtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og/zOh\nD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UHoycR7hYQe7xFSkyy\nBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuIyV77zGHcizN300QyNQliBJIWENie\nJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1Ud\nDgQWBBQahGK8SEwzJQTU7tD2A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGU\na6FJpEcwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT\nElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2fBluornFdLwUv\nZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzng/iN/Ae42l9NLmeyhP3ZRPx3\nUIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2BlfF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodm\nVjB3pjd4M1IQWK4/YY7yarHvGH5KWWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK\n+JDSV6IZUaUtl0HaB0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrW\nIozchLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPRTUIZ3Ph1\nWVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWDmbA4CD/pXvk1B+TJYm5X\nf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0ZohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II\n4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8\nVCLAAVBpQ570su9t+Oza8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u\n-----END CERTIFICATE-----\n\nQuoVadis Root CA 3\n==================\n-----BEGIN CERTIFICATE-----\nMIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT\nEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMzAeFw0wNjExMjQx\nOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM\naW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4IC\nDwAwggIKAoICAQDMV0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNgg\nDhoB4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUrH556VOij\nKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd8lyyBTNvijbO0BNO/79K\nDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9CabwvvWhDFlaJKjdhkf2mrk7AyxRllDdLkgbv\nBNDInIjbC3uBr7E9KsRlOni27tyAsdLTmZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwp\np5ijJUMv7/FfJuGITfhebtfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8\nnT8KKdjcT5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDtWAEX\nMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZc6tsgLjoC2SToJyM\nGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A4iLItLRkT9a6fUg+qGkM17uGcclz\nuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYDVR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHT\nBgkrBgEEAb5YAAMwgcUwgZMGCCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmlj\nYXRlIGNvbnN0aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0\naWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVudC4wLQYIKwYB\nBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2NwczALBgNVHQ8EBAMCAQYwHQYD\nVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4GA1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4\nywLQoUmkRzBFMQswCQYDVQQGEwJCTTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UE\nAxMSUXVvVmFkaXMgUm9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZV\nqyM07ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSemd1o417+s\nhvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd+LJ2w/w4E6oM3kJpK27z\nPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2\nPb+iSwwQHYaZTKrzchGT5Or2m9qoXadNt54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp\n8kokUvd0/bpO5qgdAm6xDYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBC\nbjPsMZ57k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6szHXu\ng/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0jWy10QJLZYxkNc91p\nvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeTmJlglFwjz1onl14LBQaTNx47aTbr\nqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK4SVhM7JZG+Ju1zdXtg2pEto=\n-----END CERTIFICATE-----\n\nSecurity Communication Root CA\n==============================\n-----BEGIN CERTIFICATE-----\nMIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP\nU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw\nHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP\nU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw\nggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw\n8yl89f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJDKaVv0uM\nDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9Ms+k2Y7CI9eNqPPYJayX\n5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/NQV3Is00qVUarH9oe4kA92819uZKAnDfd\nDJZkndwi92SL32HeFZRSFaB9UslLqCHJxrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2\nJChzAgMBAAGjPzA9MB0GA1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYw\nDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vGkl3g\n0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfrUj94nK9NrvjVT8+a\nmCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5Bw+SUEmK3TGXX8npN6o7WWWXlDLJ\ns58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJUJRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ\n6rBK+1YWc26sTfcioU+tHXotRSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAi\nFL39vmwLAw==\n-----END CERTIFICATE-----\n\nSonera Class 2 Root CA\n======================\n-----BEGIN CERTIFICATE-----\nMIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEPMA0GA1UEChMG\nU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAxMDQwNjA3Mjk0MFoXDTIxMDQw\nNjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNVBAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJh\nIENsYXNzMiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3\n/Ei9vX+ALTU74W+oZ6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybT\ndXnt5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s3TmVToMG\nf+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2EjvOr7nQKV0ba5cTppCD8P\ntOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu8nYybieDwnPz3BjotJPqdURrBGAgcVeH\nnfO+oJAjPYok4doh28MCAwEAAaMzMDEwDwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITT\nXjwwCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt\n0jSv9zilzqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/3DEI\ncbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvDFNr450kkkdAdavph\nOe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6Tk6ezAyNlNzZRZxe7EJQY670XcSx\nEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLH\nllpwrN9M\n-----END CERTIFICATE-----\n\nXRamp Global CA Root\n====================\n-----BEGIN CERTIFICATE-----\nMIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UE\nBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2Vj\ndXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB\ndXRob3JpdHkwHhcNMDQxMTAxMTcxNDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMx\nHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkg\nU2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3Jp\ndHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS638eMpSe2OAtp87ZOqCwu\nIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCPKZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMx\nfoArtYzAQDsRhtDLooY2YKTVMIJt2W7QDxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FE\nzG+gSqmUsE3a56k0enI4qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqs\nAxcZZPRaJSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNViPvry\nxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud\nEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASsjVy16bYbMDYGA1UdHwQvMC0wK6Ap\noCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMC\nAQEwDQYJKoZIhvcNAQEFBQADggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc\n/Kh4ZzXxHfARvbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt\nqZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLaIR9NmXmd4c8n\nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSyi6mx5O+aGtA9aZnuqCij4Tyz\n8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQO+7ETPTsJ3xCwnR8gooJybQDJbw=\n-----END CERTIFICATE-----\n\nGo Daddy Class 2 CA\n===================\n-----BEGIN CERTIFICATE-----\nMIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMY\nVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRp\nZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkG\nA1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g\nRGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQAD\nggENADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv\n2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+qN1j3hybX2C32\nqRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiOr18SPaAIBQi2XKVlOARFmR6j\nYGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmY\nvLEHZ6IVDd2gWMZEewo+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0O\nBBYEFNLEsNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h/t2o\natTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMu\nMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwG\nA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wim\nPQoZ+YeAEW5p5JYXMP80kWNyOO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKt\nI3lpjbi2Tc7PTMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ\nHmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mERdEr/VxqHD3VI\nLs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5CufReYNnyicsbkqWletNw+vHX/b\nvZ8=\n-----END CERTIFICATE-----\n\nStarfield Class 2 CA\n====================\n-----BEGIN CERTIFICATE-----\nMIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzElMCMGA1UEChMc\nU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZpZWxkIENsYXNzIDIg\nQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBo\nMQswCQYDVQQGEwJVUzElMCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAG\nA1UECxMpU3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqG\nSIb3DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf8MOh2tTY\nbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN+lq2cwQlZut3f+dZxkqZ\nJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVm\nepsZGD3/cVE8MC5fvj13c7JdBmzDI1aaK4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSN\nF4Azbl5KXZnJHoe0nRrA1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HF\nMIHCMB0GA1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fRzt0f\nhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNo\nbm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBDbGFzcyAyIENlcnRpZmljYXRpb24g\nQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGs\nafPzWdqbAYcaT1epoXkJKtv3L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLM\nPUxA2IGvd56Deruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl\nxy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynpVSJYACPq4xJD\nKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEYWQPJIrSPnNVeKtelttQKbfi3\nQBFGmh95DmK/D5fs4C8fF5Q=\n-----END CERTIFICATE-----\n\nTaiwan GRCA\n===========\n-----BEGIN CERTIFICATE-----\nMIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/MQswCQYDVQQG\nEwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4X\nDTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1owPzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dv\ndmVybm1lbnQgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQAD\nggIPADCCAgoCggIBAJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qN\nw8XRIePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1qgQdW8or5\nBtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKyyhwOeYHWtXBiCAEuTk8O\n1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAtsF/tnyMKtsc2AtJfcdgEWFelq16TheEfO\nhtX7MfP6Mb40qij7cEwdScevLJ1tZqa2jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wov\nJ5pGfaENda1UhhXcSTvxls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7\nQ3hub/FCVGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHKYS1t\nB6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoHEgKXTiCQ8P8NHuJB\nO9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThNXo+EHWbNxWCWtFJaBYmOlXqYwZE8\nlSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1UdDgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNV\nHRMEBTADAQH/MDkGBGcqBwAEMTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg2\n09yewDL7MTqKUWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ\nTulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyfqzvS/3WXy6Tj\nZwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaKZEk9GhiHkASfQlK3T8v+R0F2\nNe//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFEJPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlU\nD7gsL0u8qV1bYH+Mh6XgUmMqvtg7hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6Qz\nDxARvBMB1uUO07+1EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+Hbk\nZ6MmnD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WXudpVBrkk\n7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44VbnzssQwmSNOXfJIoRIM3BKQ\nCZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDeLMDDav7v3Aun+kbfYNucpllQdSNpc5Oy\n+fwC00fmcc4QAu4njIT/rEUNE1yDMuAlpYYsfPQS\n-----END CERTIFICATE-----\n\nDigiCert Assured ID Root CA\n===========================\n-----BEGIN CERTIFICATE-----\nMIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQG\nEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw\nIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzEx\nMTEwMDAwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL\nExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0Ew\nggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7cJpSIqvTO\n9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYPmDI2dsze3Tyoou9q+yHy\nUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW\n/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpy\noeb6pNnVFzF1roV9Iq4/AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whf\nGHdPAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRF\n66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkq\nhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRCdWKuh+vy1dneVrOfzM4UKLkNl2Bc\nEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTffwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38Fn\nSbNd67IJKusm7Xi+fT8r87cmNW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i\n8b5QZ7dsvfPxH2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe\n+o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==\n-----END CERTIFICATE-----\n\nDigiCert Global Root CA\n=======================\n-----BEGIN CERTIFICATE-----\nMIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQG\nEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw\nHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAw\nMDAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3\ndy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkq\nhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsBCSDMAZOn\nTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97nh6Vfe63SKMI2tavegw5\nBmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt43C/dxC//AH2hdmoRBBYMql1GNXRor5H\n4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7PT19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y\n7vrTC0LUq7dBMtoM1O/4gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQAB\no2MwYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbRTLtm\n8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJKoZIhvcNAQEF\nBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/EsrhMAtudXH/vTBH1jLuG2cenTnmCmr\nEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIt\ntep3Sp+dWOIrWcBAI+0tKIJFPnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886\nUAb3LujEV0lsYSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk\nCAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=\n-----END CERTIFICATE-----\n\nDigiCert High Assurance EV Root CA\n==================================\n-----BEGIN CERTIFICATE-----\nMIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQG\nEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSsw\nKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAw\nMFoXDTMxMTExMDAwMDAwMFowbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ\nMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFu\nY2UgRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm+9S75S0t\nMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTWPNt0OKRKzE0lgvdKpVMS\nOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEMxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3\nMRuNs8ckRZqnrG0AFFoEt7oT61EKmEFBIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQ\nNAQTXKFx01p8VdteZOE3hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUe\nh10aUAsgEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB\nAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSY\nJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3NecnzyIZgYIVyHbIUf4KmeqvxgydkAQ\nV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6zeM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFp\nmyPInngiK3BD41VHMWEZ71jFhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkK\nmNEVX58Svnw2Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe\nvEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep+OkuE6N36B9K\n-----END CERTIFICATE-----\n\nDST Root CA X3\n==============\n-----BEGIN CERTIFICATE-----\nMIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/MSQwIgYDVQQK\nExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMTDkRTVCBSb290IENBIFgzMB4X\nDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVowPzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1\ncmUgVHJ1c3QgQ28uMRcwFQYDVQQDEw5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQAD\nggEPADCCAQoCggEBAN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmT\nrE4Orz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEqOLl5CjH9\nUL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9bxiqKqy69cK3FCxolkHRy\nxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40d\nutolucbY38EVAjqr2m7xPi71XAicPNaDaeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0T\nAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQ\nMA0GCSqGSIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69ikug\ndB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXrAvHRAosZy5Q6XkjE\nGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZzR8srzJmwN0jP41ZL9c8PDHIyh8bw\nRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubS\nfZGL+T0yjWW06XyxV3bqxbYoOb8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ\n-----END CERTIFICATE-----\n\nSwissSign Gold CA - G2\n======================\n-----BEGIN CERTIFICATE-----\nMIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkNIMRUw\nEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2lnbiBHb2xkIENBIC0gRzIwHhcN\nMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBFMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dp\nc3NTaWduIEFHMR8wHQYDVQQDExZTd2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0B\nAQEFAAOCAg8AMIICCgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUq\nt2/876LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+bbqBHH5C\njCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c6bM8K8vzARO/Ws/BtQpg\nvd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqEemA8atufK+ze3gE/bk3lUIbLtK/tREDF\nylqM2tIrfKjuvqblCqoOpd8FUrdVxyJdMmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvR\nAiTysybUa9oEVeXBCsdtMDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuend\njIj3o02yMszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69yFGkO\npeUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPiaG59je883WX0XaxR\n7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxMgI93e2CaHt+28kgeDrpOVG2Y4OGi\nGqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw\nAwEB/zAdBgNVHQ4EFgQUWyV7lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64\nOfPAeGZe6Drn8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov\nL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe645R88a7A3hfm\n5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczOUYrHUDFu4Up+GC9pWbY9ZIEr\n44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOf\nMke6UiI0HTJ6CVanfCU2qT1L2sCCbwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6m\nGu6uLftIdxf+u+yvGPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxp\nmo/a77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCChdiDyyJk\nvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid392qgQmwLOM7XdVAyksLf\nKzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEppLd6leNcG2mqeSz53OiATIgHQv2ieY2Br\nNU0LbbqhPcCT4H8js1WtciVORvnSFu+wZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6Lqj\nviOvrv1vA+ACOzB2+httQc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ\n-----END CERTIFICATE-----\n\nSwissSign Silver CA - G2\n========================\n-----BEGIN CERTIFICATE-----\nMIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCQ0gxFTAT\nBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMB4X\nDTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0NlowRzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3\naXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG\n9w0BAQEFAAOCAg8AMIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644\nN0MvFz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7brYT7QbNHm\n+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieFnbAVlDLaYQ1HTWBCrpJH\n6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH6ATK72oxh9TAtvmUcXtnZLi2kUpCe2Uu\nMGoM9ZDulebyzYLs2aFK7PayS+VFheZteJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5h\nqAaEuSh6XzjZG6k4sIN/c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5\nFZGkECwJMoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRHHTBs\nROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTfjNFusB3hB48IHpmc\ncelM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb65i/4z3GcRm25xBWNOHkDRUjvxF3X\nCO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/\nBAUwAwEB/zAdBgNVHQ4EFgQUF6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRB\ntjpbO8tFnb0cwpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0\ncDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBAHPGgeAn0i0P\n4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShpWJHckRE1qTodvBqlYJ7YH39F\nkWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L\n3XWgwF15kIwb4FDm3jH+mHtwX6WQ2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx\n/uNncqCxv1yL5PqZIseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFa\nDGi8aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2Xem1ZqSqP\ne97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQRdAtq/gsD/KNVV4n+Ssuu\nWxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJ\nDIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ub\nDgEj8Z+7fNzcbBGXJbLytGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u\n-----END CERTIFICATE-----\n\nGeoTrust Primary Certification Authority\n========================================\n-----BEGIN CERTIFICATE-----\nMIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQG\nEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMoR2VvVHJ1c3QgUHJpbWFyeSBD\nZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgx\nCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQ\ncmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB\nCgKCAQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9AWbK7hWN\nb6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjAZIVcFU2Ix7e64HXprQU9\nnceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE07e9GceBrAqg1cmuXm2bgyxx5X9gaBGge\nRwLmnWDiNpcB3841kt++Z8dtd1k7j53WkBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGt\ntm/81w7a4DSwDRp35+MImO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD\nAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJKoZI\nhvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ16CePbJC/kRYkRj5K\nTs4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl4b7UVXGYNTq+k+qurUKykG/g/CFN\nNWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6KoKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHa\nFloxt/m0cYASSJlyc1pZU8FjUjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG\n1riR/aYNKxoUAT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk=\n-----END CERTIFICATE-----\n\nthawte Primary Root CA\n======================\n-----BEGIN CERTIFICATE-----\nMIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCBqTELMAkGA1UE\nBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2\naWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv\ncml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3\nMDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwg\nSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMv\nKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMT\nFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCs\noPD7gFnUnMekz52hWXMJEEUMDSxuaPFsW0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ\n1CRfBsDMRJSUjQJib+ta3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGc\nq/gcfomk6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6Sk/K\naAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94JNqR32HuHUETVPm4p\nafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD\nVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XPr87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUF\nAAOCAQEAeRHAS7ORtvzw6WfUDW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeE\nuzLlQRHAd9mzYJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX\nxPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2/qxAeeWsEG89\njxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/LHbTY5xZ3Y+m4Q6gLkH3LpVH\nz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7jVaMaA==\n-----END CERTIFICATE-----\n\nVeriSign Class 3 Public Primary Certification Authority - G5\n============================================================\n-----BEGIN CERTIFICATE-----\nMIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE\nBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO\nZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk\nIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRp\nZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCB\nyjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln\nbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBh\ndXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmlt\nYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw\nggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKz\nj/i5Vbext0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhD\nY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/\nArr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNHiDxpg8v+R70r\nfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/\nBAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2Uv\nZ2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy\naXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG\nSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzEp6B4Eq1iDkVwZMXnl2YtmAl+\nX6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKE\nKQsTb47bDN0lAtukixlE0kF6BWlKWE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiC\nKm0oHw0LxOXnGiYZ4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vE\nZV8NhnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq\n-----END CERTIFICATE-----\n\nSecureTrust CA\n==============\n-----BEGIN CERTIFICATE-----\nMIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBIMQswCQYDVQQG\nEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xFzAVBgNVBAMTDlNlY3VyZVRy\ndXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIzMTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAe\nBgNVBAoTF1NlY3VyZVRydXN0IENvcnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCC\nASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQX\nOZEzZum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO0gMdA+9t\nDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIaowW8xQmxSPmjL8xk037uH\nGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b\n01k/unK8RCSc43Oz969XL0Imnal0ugBS8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmH\nursCAwEAAaOBnTCBmjATBgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/\nBAUwAwEB/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCegJYYj\naHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ\nKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt36Z3q059c4EVlew3KW+JwULKUBRSu\nSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHf\nmbx8IVQr5Fiiu1cprp6poxkmD5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZ\nnMUFdAvnZyPSCPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR\n3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE=\n-----END CERTIFICATE-----\n\nSecure Global CA\n================\n-----BEGIN CERTIFICATE-----\nMIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQG\nEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBH\nbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkxMjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEg\nMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwg\nQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jx\nYDiJiQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa/FHtaMbQ\nbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJjnIFHovdRIWCQtBJwB1g\n8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnIHmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYV\nHDGA76oYa8J719rO+TMg1fW9ajMtgQT7sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi\n0XPnj3pDAgMBAAGjgZ0wgZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud\nEwEB/wQFMAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCswKaAn\noCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsGAQQBgjcVAQQDAgEA\nMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0LURYD7xh8yOOvaliTFGCRsoTciE6+\nOYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXOH0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cn\nCDpOGR86p1hcF895P4vkp9MmI50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/5\n3CYNv6ZHdAbYiNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc\nf8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW\n-----END CERTIFICATE-----\n\nCOMODO Certification Authority\n==============================\n-----BEGIN CERTIFICATE-----\nMIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCBgTELMAkGA1UE\nBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG\nA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNVBAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1\ndGhvcml0eTAeFw0wNjEyMDEwMDAwMDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEb\nMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFD\nT01PRE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0aG9yaXR5\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3UcEbVASY06m/weaKXTuH\n+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI2GqGd0S7WWaXUF601CxwRM/aN5VCaTww\nxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV\n4EajcNxo2f8ESIl33rXp+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA\n1KGzqSX+DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5OnKVI\nrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW/zAOBgNVHQ8BAf8E\nBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLmNvbW9k\nb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOC\nAQEAPpiem/Yb6dc5t3iuHXIYSdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CP\nOGEIqB6BCsAvIC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/\nRxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4zJVSk/BwJVmc\nIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5ddBA6+C4OmF4O5MBKgxTMVBbkN\n+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IBZQ==\n-----END CERTIFICATE-----\n\nNetwork Solutions Certificate Authority\n=======================================\n-----BEGIN CERTIFICATE-----\nMIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQG\nEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydOZXR3b3Jr\nIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMx\nMjM1OTU5WjBiMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu\nMTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G\nCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwzc7MEL7xx\njOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPPOCwGJgl6cvf6UDL4wpPT\naaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rlmGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXT\ncrA/vGp97Eh/jcOrqnErU2lBUzS1sLnFBgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc\n/Qzpf14Dl847ABSHJ3A4qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMB\nAAGjgZcwgZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIBBjAP\nBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwubmV0c29sc3NsLmNv\nbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3JpdHkuY3JsMA0GCSqGSIb3DQEBBQUA\nA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc86fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q\n4LqILPxFzBiwmZVRDuwduIj/h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/\nGGUsyfJj4akH/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv\nwKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHNpGxlaKFJdlxD\nydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey\n-----END CERTIFICATE-----\n\nCOMODO ECC Certification Authority\n==================================\n-----BEGIN CERTIFICATE-----\nMIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTELMAkGA1UEBhMC\nR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE\nChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBB\ndXRob3JpdHkwHhcNMDgwMzA2MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0Ix\nGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR\nQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRo\nb3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSRFtSrYpn1PlILBs5BAH+X\n4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0JcfRK9ChQtP6IHG4/bC8vCVlbpVsLM5ni\nwz2J+Wos77LTBumjQjBAMB0GA1UdDgQWBBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8E\nBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VG\nFAkK+qDmfQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdvGDeA\nU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY=\n-----END CERTIFICATE-----\n\nOISTE WISeKey Global Root GA CA\n===============================\n-----BEGIN CERTIFICATE-----\nMIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCBijELMAkGA1UE\nBhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHlyaWdodCAoYykgMjAwNTEiMCAG\nA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBH\nbG9iYWwgUm9vdCBHQSBDQTAeFw0wNTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYD\nVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIw\nIAYDVQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5\nIEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy0+zAJs9\nNt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxRVVuuk+g3/ytr6dTqvirdqFEr12bDYVxg\nAsj1znJ7O7jyTmUIms2kahnBAbtzptf2w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbD\nd50kc3vkDIzh2TbhmYsFmQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ\n/yxViJGg4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t94B3R\nLoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw\nAwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ\nKoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOxSPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vIm\nMMkQyh2I+3QZH4VFvbBsUfk2ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4\n+vg1YFkCExh8vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa\nhNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZiFj4A4xylNoEY\nokxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ/L7fCg0=\n-----END CERTIFICATE-----\n\nCertigna\n========\n-----BEGIN CERTIFICATE-----\nMIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNVBAYTAkZSMRIw\nEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4XDTA3MDYyOTE1MTMwNVoXDTI3\nMDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwI\nQ2VydGlnbmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7q\nXOEm7RFHYeGifBZ4QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyH\nGxnygQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbwzBfsV1/p\nogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q130yGLMLLGq/jj8UEYkg\nDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKf\nIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQ\ntCRZvgHyUtVF9lo53BEwZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJ\nBgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzjAQ/J\nSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG9w0BAQUFAAOCAQEA\nhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8hbV6lUmPOEvjvKtpv6zf+EwLHyzs+\nImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFncfca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1klu\nPBS1xp81HlDQwY9qcEQCYsuuHWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY\n1gkIl2PlwS6wt0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw\nWyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg==\n-----END CERTIFICATE-----\n\nCybertrust Global Root\n======================\n-----BEGIN CERTIFICATE-----\nMIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYGA1UEChMPQ3li\nZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBSb290MB4XDTA2MTIxNTA4\nMDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQD\nExZDeWJlcnRydXN0IEdsb2JhbCBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA\n+Mi8vRRQZhP/8NN57CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW\n0ozSJ8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2yHLtgwEZL\nAfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iPt3sMpTjr3kfb1V05/Iin\n89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNzFtApD0mpSPCzqrdsxacwOUBdrsTiXSZT\n8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAYXSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAP\nBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2\nMDSgMqAwhi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3JsMB8G\nA1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUAA4IBAQBW7wojoFRO\nlZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMjWqd8BfP9IjsO0QbE2zZMcwSO5bAi\n5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUxXOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2\nhO0j9n0Hq0V+09+zv+mKts2oomcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+T\nX3EJIrduPuocA06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW\nWL1WMRJOEcgh4LMRkWXbtKaIOM5V\n-----END CERTIFICATE-----\n\nePKI Root Certification Authority\n=================================\n-----BEGIN CERTIFICATE-----\nMIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQG\nEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0ZC4xKjAoBgNVBAsMIWVQS0kg\nUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMx\nMjdaMF4xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEq\nMCgGA1UECwwhZVBLSSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0B\nAQEFAAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAHSyZbCUNs\nIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAhijHyl3SJCRImHJ7K2RKi\nlTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3XDZoTM1PRYfl61dd4s5oz9wCGzh1NlDiv\nqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX\n12ruOzjjK9SXDrkb5wdJfzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0O\nWQqraffAsgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uUWH1+\nETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLSnT0IFaUQAS2zMnao\nlQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pHdmX2Os+PYhcZewoozRrSgx4hxyy/\nvv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJipNiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXi\nZo1jDiVN1Rmy5nk3pyKdVDECAwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/Qkqi\nMAwGA1UdEwQFMAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH\nClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGBuvl2ICO1J2B0\n1GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6YlPwZpVnPDimZI+ymBV3QGypzq\nKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkPJXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdV\nxrsStZf0X4OFunHB2WyBEXYKCrC/gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEP\nNXubrjlpC2JgQCA2j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+r\nGNm65ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUBo2M3IUxE\nxJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS/jQ6fbjpKdx2qcgw+BRx\ngMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2zGp1iro2C6pSe3VkQw63d4k3jMdXH7Ojy\nsP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTEW9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmOD\nBCEIZ43ygknQW/2xzQ+DhNQ+IIX3Sj0rnP0qCglN6oH4EZw=\n-----END CERTIFICATE-----\n\ncertSIGN ROOT CA\n================\n-----BEGIN CERTIFICATE-----\nMIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYTAlJPMREwDwYD\nVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTAeFw0wNjA3MDQxNzIwMDRa\nFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UE\nCxMQY2VydFNJR04gUk9PVCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7I\nJUqOtdu0KBuqV5Do0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHH\nrfAQUySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5dRdY4zTW2\nssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQOA7+j0xbm0bqQfWwCHTD\n0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwvJoIQ4uNllAoEwF73XVv4EOLQunpL+943\nAAAaWyjj0pxzPjKHmKHJUS/X3qwzs08CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B\nAf8EBAMCAcYwHQYDVR0OBBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IB\nAQA+0hyJLjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecYMnQ8\nSG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ44gx+FkagQnIl6Z0\nx2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6IJd1hJyMctTEHBDa0GpC9oHRxUIlt\nvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNwi/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7Nz\nTogVZ96edhBiIL5VaZVDADlN9u6wWk5JRFRYX0KD\n-----END CERTIFICATE-----\n\nGeoTrust Primary Certification Authority - G3\n=============================================\n-----BEGIN CERTIFICATE-----\nMIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UE\nBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA4IEdlb1RydXN0\nIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFy\neSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIz\nNTk1OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAo\nYykgMjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMT\nLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZI\nhvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz+uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5j\nK/BGvESyiaHAKAxJcCGVn2TAppMSAmUmhsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdE\nc5IiaacDiGydY8hS2pgn5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3C\nIShwiP/WJmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exALDmKu\ndlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZChuOl1UcCAwEAAaNC\nMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMR5yo6hTgMdHNxr\n2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IBAQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9\ncr5HqQ6XErhK8WTTOd8lNNTBzU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbE\nAp7aDHdlDkQNkv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD\nAWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUHSJsMC8tJP33s\nt/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2Gspki4cErx5z481+oghLrGREt\n-----END CERTIFICATE-----\n\nthawte Primary Root CA - G2\n===========================\n-----BEGIN CERTIFICATE-----\nMIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDELMAkGA1UEBhMC\nVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMpIDIwMDcgdGhhd3RlLCBJbmMu\nIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3Qg\nQ0EgLSBHMjAeFw0wNzExMDUwMDAwMDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEV\nMBMGA1UEChMMdGhhd3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBG\nb3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAt\nIEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/BebfowJPDQfGAFG6DAJS\nLSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6papu+7qzcMBniKI11KOasf2twu8x+qi5\n8/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU\nmtgAMADna3+FGO6Lts6KDPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUN\nG4k8VIZ3KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41oxXZ3K\nrr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg==\n-----END CERTIFICATE-----\n\nthawte Primary Root CA - G3\n===========================\n-----BEGIN CERTIFICATE-----\nMIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCBrjELMAkGA1UE\nBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2\naWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv\ncml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0w\nODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh\nd3RlLCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uMTgwNgYD\nVQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIG\nA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\nMIIBCgKCAQEAsr8nLPvb2FvdeHsbnndmgcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2At\nP0LMqmsywCPLLEHd5N/8YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC\n+BsUa0Lfb1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS99irY\n7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2SzhkGcuYMXDhpxwTW\nvGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUkOQIDAQABo0IwQDAPBgNVHRMBAf8E\nBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJ\nKoZIhvcNAQELBQADggEBABpA2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweK\nA3rD6z8KLFIWoCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu\nt8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7cKUGRIjxpp7sC\n8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fMm7v/OeZWYdMKp8RcTGB7BXcm\ner/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZuMdRAGmI0Nj81Aa6sY6A=\n-----END CERTIFICATE-----\n\nGeoTrust Primary Certification Authority - G2\n=============================================\n-----BEGIN CERTIFICATE-----\nMIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDELMAkGA1UEBhMC\nVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA3IEdlb1RydXN0IElu\nYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBD\nZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1\nOVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg\nMjAwNyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMTLUdl\nb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjB2MBAGByqGSM49AgEG\nBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcLSo17VDs6bl8VAsBQps8lL33KSLjHUGMc\nKiEIfJo22Av+0SbFWDEwKCXzXV2juLaltJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYD\nVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+\nEVXVMAoGCCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGTqQ7m\nndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBuczrD6ogRLQy7rQkgu2\nnpaqBA+K\n-----END CERTIFICATE-----\n\nVeriSign Universal Root Certification Authority\n===============================================\n-----BEGIN CERTIFICATE-----\nMIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCBvTELMAkGA1UE\nBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO\nZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk\nIHVzZSBvbmx5MTgwNgYDVQQDEy9WZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9u\nIEF1dGhvcml0eTAeFw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJV\nUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv\ncmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl\nIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0\naG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj\n1mCOkdeQmIN65lgZOIzF9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGP\nMiJhgsWHH26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+HLL72\n9fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN/BMReYTtXlT2NJ8I\nAfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPTrJ9VAMf2CGqUuV/c4DPxhGD5WycR\ntPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0G\nCCsGAQUFBwEMBGEwX6FdoFswWTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2O\na8PPgGrUSBgsexkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud\nDgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4sAPmLGd75JR3\nY8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+seQxIcaBlVZaDrHC1LGmWazx\nY8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTx\nP/jgdFcrGJ2BtMQo2pSXpXDrrB2+BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+P\nwGZsY6rp2aQW9IHRlRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4\nmJO37M2CYfE45k+XmCpajQ==\n-----END CERTIFICATE-----\n\nVeriSign Class 3 Public Primary Certification Authority - G4\n============================================================\n-----BEGIN CERTIFICATE-----\nMIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjELMAkGA1UEBhMC\nVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3\nb3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVz\nZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmlj\nYXRpb24gQXV0aG9yaXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjEL\nMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBU\ncnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRo\nb3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5\nIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8\nUtpkmw4tXNherJI9/gHmGUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGz\nrl0Bp3vefLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUwAwEB\n/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEw\nHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24u\nY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMWkf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMD\nA2gAMGUCMGYhDBgmYFo4e1ZC4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIx\nAJw9SDkjOVgaFRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA==\n-----END CERTIFICATE-----\n\nNetLock Arany (Class Gold) Főtanúsítvány\n========================================\n-----BEGIN CERTIFICATE-----\nMIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQGEwJIVTERMA8G\nA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3MDUGA1UECwwuVGFuw7pzw610\ndsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBB\ncmFueSAoQ2xhc3MgR29sZCkgRsWRdGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgx\nMjA2MTUwODIxWjCBpzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxO\nZXRMb2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlmaWNhdGlv\nbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNzIEdvbGQpIEbFkXRhbsO6\nc8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxCRec75LbRTDofTjl5Bu\n0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrTlF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw\n/HpYzY6b7cNGbIRwXdrzAZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAk\nH3B5r9s5VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRGILdw\nfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2BJtr+UBdADTHLpl1\nneWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAGAQH/AgEEMA4GA1UdDwEB/wQEAwIB\nBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2MU9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwW\nqZw8UQCgwBEIBaeZ5m8BiFRhbvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTta\nYtOUZcTh5m2C+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC\nbLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2FuLjbvrW5Kfna\nNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu\ndZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E=\n-----END CERTIFICATE-----\n\nHongkong Post Root CA 1\n=======================\n-----BEGIN CERTIFICATE-----\nMIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoT\nDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMB4XDTAzMDUx\nNTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25n\nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEF\nAAOCAQ8AMIIBCgKCAQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1\nApzQjVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEnPzlTCeqr\nauh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjhZY4bXSNmO7ilMlHIhqqh\nqZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9nnV0ttgCXjqQesBCNnLsak3c78QA3xMY\nV18meMjWCnl3v/evt3a5pQuEF10Q6m/hq5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNV\nHRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7i\nh9legYsCmEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI37pio\nl7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clBoiMBdDhViw+5Lmei\nIAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJsEhTkYY2sEJCehFC78JZvRZ+K88ps\nT/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpOfMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilT\nc4afU9hDDl3WY4JxHYB0yvbiAmvZWg==\n-----END CERTIFICATE-----\n\nSecureSign RootCA11\n===================\n-----BEGIN CERTIFICATE-----\nMIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDErMCkGA1UEChMi\nSmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoGA1UEAxMTU2VjdXJlU2lnbiBS\nb290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSsw\nKQYDVQQKEyJKYXBhbiBDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1\ncmVTaWduIFJvb3RDQTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvL\nTJszi1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8h9uuywGO\nwvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOVMdrAG/LuYpmGYz+/3ZMq\ng6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rP\nO7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitA\nbpSACW22s293bzUIUPsCh8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZX\nt94wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAKCh\nOBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xmKbabfSVSSUOrTC4r\nbnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQX5Ucv+2rIrVls4W6ng+4reV6G4pQ\nOh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWrQbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01\ny8hSyn+B/tlr0/cR7SXf+Of5pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061\nlgeLKBObjBmNQSdJQO7e5iNEOdyhIta6A/I=\n-----END CERTIFICATE-----\n\nMicrosec e-Szigno Root CA 2009\n==============================\n-----BEGIN CERTIFICATE-----\nMIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYDVQQGEwJIVTER\nMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jv\nc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o\ndTAeFw0wOTA2MTYxMTMwMThaFw0yOTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UE\nBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUt\nU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTCCASIw\nDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvPkd6mJviZpWNwrZuuyjNA\nfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tccbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG\n0IMZfcChEhyVbUr02MelTTMuhTlAdX4UfIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKA\npxn1ntxVUwOXewdI/5n7N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm\n1HxdrtbCxkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1+rUC\nAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTLD8bf\nQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAbBgNVHREE\nFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqGSIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0o\nlZMEyL/azXm4Q5DwpL7v8u8hmLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfX\nI/OMn74dseGkddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775\ntyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c2Pm2G2JwCz02\nyULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5tHMN1Rq41Bab2XD0h7lbwyYIi\nLXpUq3DDfSJlgnCW\n-----END CERTIFICATE-----\n\nGlobalSign Root CA - R3\n=======================\n-----BEGIN CERTIFICATE-----\nMIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4GA1UECxMXR2xv\nYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh\nbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT\naWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln\nbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWt\niHL8RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsTgHeMCOFJ\n0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmmKPZpO/bLyCiR5Z2KYVc3\nrHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zdQQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjl\nOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZXriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2\nxmmFghcCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE\nFI/wS3+oLkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZURUm7\nlgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMpjjM5RcOO5LlXbKr8\nEpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK6fBdRoyV3XpYKBovHd7NADdBj+1E\nbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQXmcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18\nYIvDQVETI53O9zJrlAGomecsMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7r\nkpeDMdmztcpHWD9f\n-----END CERTIFICATE-----\n\nAutoridad de Certificacion Firmaprofesional CIF A62634068\n=========================================================\n-----BEGIN CERTIFICATE-----\nMIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UEBhMCRVMxQjBA\nBgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2\nMjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEyMzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIw\nQAYDVQQDDDlBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBB\nNjI2MzQwNjgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDD\nUtd9thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQMcas9UX4P\nB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefGL9ItWY16Ck6WaVICqjaY\n7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15iNA9wBj4gGFrO93IbJWyTdBSTo3OxDqqH\nECNZXyAFGUftaI6SEspd/NYrspI8IM/hX68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyI\nplD9amML9ZMWGxmPsu2bm8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctX\nMbScyJCyZ/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirjaEbsX\nLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/TKI8xWVvTyQKmtFLK\nbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF6NkBiDkal4ZkQdU7hwxu+g/GvUgU\nvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVhOSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1Ud\nEwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNH\nDhpkLzCBpgYDVR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp\ncm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBvACAAZABlACAA\nbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBlAGwAbwBuAGEAIAAwADgAMAAx\nADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx\n51tkljYyGOylMnfX40S2wBEqgLk9am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qk\nR71kMrv2JYSiJ0L1ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaP\nT481PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS3a/DTg4f\nJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5kSeTy36LssUzAKh3ntLFl\nosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF3dvd6qJ2gHN99ZwExEWN57kci57q13XR\ncrHedUTnQn3iV2t93Jm8PYMo6oCTjcVMZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoR\nsaS8I8nkvof/uZS2+F0gStRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTD\nKCOM/iczQ0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQBjLMi\n6Et8Vcad+qMUu2WFbm5PEn4KPJ2V\n-----END CERTIFICATE-----\n\nIzenpe.com\n==========\n-----BEGIN CERTIFICATE-----\nMIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4MQswCQYDVQQG\nEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wHhcNMDcxMjEz\nMTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMu\nQS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ\n03rKDx6sp4boFmVqscIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAK\nClaOxdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6HLmYRY2xU\n+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFXuaOKmMPsOzTFlUFpfnXC\nPCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQDyCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxT\nOTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbK\nF7jJeodWLBoBHmy+E60QrLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK\n0GqfvEyNBjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8Lhij+\n0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIBQFqNeb+Lz0vPqhbB\nleStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+HMh3/1uaD7euBUbl8agW7EekFwID\nAQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2luZm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+\nSVpFTlBFIFMuQS4gLSBDSUYgQTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBG\nNjIgUzgxQzBBBgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx\nMCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O\nBBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUAA4ICAQB4pgwWSp9MiDrAyw6l\nFn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWblaQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbga\nkEyrkgPH7UIBzg/YsfqikuFgba56awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8q\nhT/AQKM6WfxZSzwoJNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Cs\ng1lwLDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCTVyvehQP5\naTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGkLhObNA5me0mrZJfQRsN5\nnXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJbUjWumDqtujWTI6cfSN01RpiyEGjkpTHC\nClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZo\nQ0iy2+tzJOeRf1SktoA+naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1Z\nWrOZyGlsQyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw==\n-----END CERTIFICATE-----\n\nChambers of Commerce Root - 2008\n================================\n-----BEGIN CERTIFICATE-----\nMIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYDVQQGEwJFVTFD\nMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv\nbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu\nQS4xKTAnBgNVBAMTIENoYW1iZXJzIG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEy\nMjk1MFoXDTM4MDczMTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNl\nZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQF\nEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJl\ncnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC\nAQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW928sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKA\nXuFixrYp4YFs8r/lfTJqVKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorj\nh40G072QDuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR5gN/\nikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfLZEFHcpOrUMPrCXZk\nNNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05aSd+pZgvMPMZ4fKecHePOjlO+Bd5g\nD2vlGts/4+EhySnB8esHnFIbAURRPHsl18TlUlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331\nlubKgdaX8ZSD6e2wsWsSaR6s+12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ\n0wlf2eOKNcx5Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj\nya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAxhduub+84Mxh2\nEQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNVHQ4EFgQU+SSsD7K1+HnA+mCI\nG8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1+HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJ\nBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNh\nbWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENh\nbWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDiC\nCQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUH\nAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAJASryI1\nwqM58C7e6bXpeHxIvj99RZJe6dqxGfwWPJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH\n3qLPaYRgM+gQDROpI9CF5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbU\nRWpGqOt1glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaHFoI6\nM6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2pSB7+R5KBWIBpih1\nYJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MDxvbxrN8y8NmBGuScvfaAFPDRLLmF\n9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QGtjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcK\nzBIKinmwPQN/aUv0NCB9szTqjktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvG\nnrDQWzilm1DefhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg\nOGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZd0jQ\n-----END CERTIFICATE-----\n\nGlobal Chambersign Root - 2008\n==============================\n-----BEGIN CERTIFICATE-----\nMIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYDVQQGEwJFVTFD\nMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv\nbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu\nQS4xJzAlBgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMx\nNDBaFw0zODA3MzExMjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUg\nY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJ\nQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD\naGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDf\nVtPkOpt2RbQT2//BthmLN0EYlVJH6xedKYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXf\nXjaOcNFccUMd2drvXNL7G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0\nZJJ0YPP2zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4ddPB\n/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyGHoiMvvKRhI9lNNgA\nTH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2Id3UwD2ln58fQ1DJu7xsepeY7s2M\nH/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3VyJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfe\nOx2YItaswTXbo6Al/3K1dh3ebeksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSF\nHTynyQbehP9r6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh\nwZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsogzCtLkykPAgMB\nAAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQWBBS5CcqcHtvTbDprru1U8VuT\nBjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDprru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UE\nBhMCRVUxQzBBBgNVBAcTOk1hZHJpZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJm\naXJtYS5jb20vYWRkcmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJm\naXJtYSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiCCQDJzdPp\n1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0\ndHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAICIf3DekijZBZRG\n/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZUohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6\nReAJ3spED8IXDneRRXozX1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/s\ndZ7LoR/xfxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVza2Mg\n9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yydYhz2rXzdpjEetrHH\nfoUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMdSqlapskD7+3056huirRXhOukP9Du\nqqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9OAP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETr\nP3iZ8ntxPjzxmKfFGBI/5rsoM0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVq\nc5iJWzouE4gev8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z\n09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B\n-----END CERTIFICATE-----\n\nGo Daddy Root Certificate Authority - G2\n========================================\n-----BEGIN CERTIFICATE-----\nMIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT\nB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHkuY29tLCBJbmMu\nMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5\nMDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6\nb25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8G\nA1UEAxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI\nhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKDE6bFIEMBO4Tx5oVJnyfq\n9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD\n+qK+ihVqf94Lw7YZFAXK6sOoBJQ7RnwyDfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutd\nfMh8+7ArU6SSYmlRJQVhGkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMl\nNAJWJwGRtDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEAAaNC\nMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9\nBUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmXWWcDYfF+OwYxdS2hII5PZYe096ac\nvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r\n5N9ss4UXnT3ZJE95kTXWXwTrgIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYV\nN8Gb5DKj7Tjo2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO\nLPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI4uJEvlz36hz1\n-----END CERTIFICATE-----\n\nStarfield Root Certificate Authority - G2\n=========================================\n-----BEGIN CERTIFICATE-----\nMIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT\nB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s\nb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVsZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0\neSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAw\nDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQg\nVGVjaG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZpY2F0ZSBB\ndXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3twQP89o/8ArFv\nW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMgnLRJdzIpVv257IzdIvpy3Cdhl+72WoTs\nbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNk\nN3mSwOxGXn/hbVNMYq/NHwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7Nf\nZTD4p7dNdloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0HZbU\nJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\nAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0GCSqGSIb3DQEBCwUAA4IBAQARWfol\nTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjUsHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx\n4mcujJUDJi5DnUox9g61DLu34jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUw\nF5okxBDgBPfg8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K\npL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1mMpYjn0q7pBZ\nc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0\n-----END CERTIFICATE-----\n\nStarfield Services Root Certificate Authority - G2\n==================================================\n-----BEGIN CERTIFICATE-----\nMIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMxEDAOBgNVBAgT\nB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s\nb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVsZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRl\nIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNV\nBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxT\ndGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2VydmljZXMg\nUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC\nAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20pOsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2\nh/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm28xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4Pa\nhHQUw2eeBGg6345AWh1KTs9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLP\nLJGmpufehRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk6mFB\nrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAwDwYDVR0TAQH/BAUw\nAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+qAdcwKziIorhtSpzyEZGDMA0GCSqG\nSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMIbw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPP\nE95Dz+I0swSdHynVv/heyNXBve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTy\nxQGjhdByPq1zqwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd\niEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn0q23KXB56jza\nYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCNsSi6\n-----END CERTIFICATE-----\n\nAffirmTrust Commercial\n======================\n-----BEGIN CERTIFICATE-----\nMIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCVVMxFDAS\nBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMB4XDTEw\nMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly\nbVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEF\nAAOCAQ8AMIIBCgKCAQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6Eqdb\nDuKPHx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yrba0F8PrV\nC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPALMeIrJmqbTFeurCA+ukV6\nBfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1yHp52UKqK39c/s4mT6NmgTWvRLpUHhww\nMmWd5jyTXlBOeuM61G7MGvv50jeuJCqrVwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNV\nHQ4EFgQUnZPGU4teyq8/nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\nAQYwDQYJKoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYGXUPG\nhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNjvbz4YYCanrHOQnDi\nqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivtZ8SOyUOyXGsViQK8YvxO8rUzqrJv\n0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9gN53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0kh\nsUlHRUe072o0EclNmsxZt9YCnlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8=\n-----END CERTIFICATE-----\n\nAffirmTrust Networking\n======================\n-----BEGIN CERTIFICATE-----\nMIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UEBhMCVVMxFDAS\nBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMB4XDTEw\nMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly\nbVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEF\nAAOCAQ8AMIIBCgKCAQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SE\nHi3yYJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbuakCNrmreI\ndIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRLQESxG9fhwoXA3hA/Pe24\n/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gb\nh+0t+nvujArjqWaJGctB+d1ENmHP4ndGyH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNV\nHQ4EFgQUBx/S55zawm6iQLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\nAQYwDQYJKoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfOtDIu\nUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzuQY0x2+c06lkh1QF6\n12S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZLgo/bNjR9eUJtGxUAArgFU2HdW23\nWJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4uolu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9\n/ZFvgrG+CJPbFEfxojfHRZ48x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s=\n-----END CERTIFICATE-----\n\nAffirmTrust Premium\n===================\n-----BEGIN CERTIFICATE-----\nMIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UEBhMCVVMxFDAS\nBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMB4XDTEwMDEy\nOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRy\ndXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A\nMIICCgKCAgEAxBLfqV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtn\nBKAQJG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ+jjeRFcV\n5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrSs8PhaJyJ+HoAVt70VZVs\n+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmd\nGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d770O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5R\np9EixAqnOEhss/n/fauGV+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NI\nS+LI+H+SqHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S5u04\n6uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4IaC1nEWTJ3s7xgaVY5\n/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TXOwF0lkLgAOIua+rF7nKsu7/+6qqo\n+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYEFJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB\n/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByv\nMiPIs0laUZx2KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg\nNt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B8OWycvpEgjNC\n6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQMKSOyARiqcTtNd56l+0OOF6S\nL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK\n+4w1IX2COPKpVJEZNZOUbWo6xbLQu4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmV\nBtWVyuEklut89pMFu+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFg\nIxpHYoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8GKa1qF60\ng2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaORtGdFNrHF+QFlozEJLUb\nzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6eKeC2uAloGRwYQw==\n-----END CERTIFICATE-----\n\nAffirmTrust Premium ECC\n=======================\n-----BEGIN CERTIFICATE-----\nMIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMCVVMxFDASBgNV\nBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQcmVtaXVtIEVDQzAeFw0xMDAx\nMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1U\ncnVzdDEgMB4GA1UEAwwXQWZmaXJtVHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQA\nIgNiAAQNMF4bFZ0D0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQ\nN8O9ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0GA1UdDgQW\nBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAK\nBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/VsaobgxCd05DhT1wV/GzTjxi+zygk8N53X\n57hG8f2h4nECMEJZh0PUUd+60wkyWs6Iflc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKM\neQ==\n-----END CERTIFICATE-----\n\nCertum Trusted Network CA\n=========================\n-----BEGIN CERTIFICATE-----\nMIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBMMSIwIAYDVQQK\nExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlv\nbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBUcnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIy\nMTIwNzM3WhcNMjkxMjMxMTIwNzM3WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBU\nZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5\nMSIwIAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC\nAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rHUV+rpDKmYYe2bg+G0jAC\nl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LMTXPb865Px1bVWqeWifrzq2jUI4ZZJ88J\nJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVUBBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4\nfOQtf/WsX+sWn7Et0brMkUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0\ncvW0QM8xAcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNVHRMB\nAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNVHQ8BAf8EBAMCAQYw\nDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15ysHhE49wcrwn9I0j6vSrEuVUEtRCj\njSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfLI9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1\nmS1FhIrlQgnXdAIv94nYmem8J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5aj\nZt3hrvJBW8qYVoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI\n03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw=\n-----END CERTIFICATE-----\n\nTWCA Root Certification Authority\n=================================\n-----BEGIN CERTIFICATE-----\nMIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJ\nVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlmaWNh\ndGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMzWhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQG\nEwJUVzESMBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NB\nIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK\nAoIBAQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFEAcK0HMMx\nQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HHK3XLfJ+utdGdIzdjp9xC\noi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeXRfwZVzsrb+RH9JlF/h3x+JejiB03HFyP\n4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/zrX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1r\ny+UPizgN7gr8/g+YnzAx3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIB\nBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkqhkiG\n9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeCMErJk/9q56YAf4lC\nmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdlsXebQ79NqZp4VKIV66IIArB6nCWlW\nQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62Dlhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVY\nT0bf+215WfKEIlKuD8z7fDvnaspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocny\nYh0igzyXxfkZYiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw==\n-----END CERTIFICATE-----\n\nSecurity Communication RootCA2\n==============================\n-----BEGIN CERTIFICATE-----\nMIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDElMCMGA1UEChMc\nU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMeU2VjdXJpdHkgQ29tbXVuaWNh\ndGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoXDTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMC\nSlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3Vy\naXR5IENvbW11bmljYXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\nANAVOVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGrzbl+dp++\n+T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVMVAX3NuRFg3sUZdbcDE3R\n3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQhNBqyjoGADdH5H5XTz+L62e4iKrFvlNV\nspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWOojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1K\nEOtOghY6rCcMU/Gt1SSwawNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8\nQIH4D5csOPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB\nCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpFcoJxDjrSzG+ntKEj\nu/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXcokgfGT+Ok+vx+hfuzU7jBBJV1uXk\n3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6q\ntnRGEmyR7jTV7JqR50S+kDFy1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29\nmvVXIwAHIRc/SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03\n-----END CERTIFICATE-----\n\nEC-ACC\n======\n-----BEGIN CERTIFICATE-----\nMIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB8zELMAkGA1UE\nBhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2VydGlmaWNhY2lvIChOSUYgUS0w\nODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYD\nVQQLEyxWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UE\nCxMsSmVyYXJxdWlhIEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMT\nBkVDLUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQGEwJFUzE7\nMDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8gKE5JRiBRLTA4MDExNzYt\nSSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBDZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZl\nZ2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQubmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJh\ncnF1aWEgRW50aXRhdHMgZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUND\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R85iK\nw5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm4CgPukLjbo73FCeT\nae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaVHMf5NLWUhdWZXqBIoH7nF2W4onW4\nHvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNdQlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0a\nE9jD2z3Il3rucO2n5nzbcc8tlGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw\n0JDnJwIDAQABo4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E\nBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4opvpXY0wfwYD\nVR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBodHRwczovL3d3dy5jYXRjZXJ0\nLm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5l\ndC92ZXJhcnJlbCAwDQYJKoZIhvcNAQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJ\nlF7W2u++AVtd0x7Y/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNa\nAl6kSBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhyRp/7SNVe\nl+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOSAgu+TGbrIP65y7WZf+a2\nE/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xlnJ2lYJU6Un/10asIbvPuW/mIPX64b24D\n5EI=\n-----END CERTIFICATE-----\n\nHellenic Academic and Research Institutions RootCA 2011\n=======================================================\n-----BEGIN CERTIFICATE-----\nMIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1IxRDBCBgNVBAoT\nO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9y\naXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z\nIFJvb3RDQSAyMDExMB4XDTExMTIwNjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYT\nAkdSMUQwQgYDVQQKEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z\nIENlcnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNo\nIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\nAKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPzdYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI\n1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJfel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa\n71HFK9+WXesyHgLacEnsbgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u\n8yBRQlqD75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSPFEDH\n3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNVHRMBAf8EBTADAQH/\nMAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp5dgTBCPuQSUwRwYDVR0eBEAwPqA8\nMAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQub3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQu\nb3JnMA0GCSqGSIb3DQEBBQUAA4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVt\nXdMiKahsog2p6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8\nTqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7dIsXRSZMFpGD\n/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8AcysNnq/onN694/BtZqhFLKPM58N\n7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXIl7WdmplNsDz4SgCbZN2fOUvRJ9e4\n-----END CERTIFICATE-----\n\nActalis Authentication Root CA\n==============================\n-----BEGIN CERTIFICATE-----\nMIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UEBhMCSVQxDjAM\nBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UE\nAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDky\nMjExMjIwMlowazELMAkGA1UEBhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlz\nIFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290\nIENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNvUTufClrJ\nwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX4ay8IMKx4INRimlNAJZa\nby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9KK3giq0itFZljoZUj5NDKd45RnijMCO6\nzfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1f\nYVEiVRvjRuPjPdA1YprbrxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2\noxgkg4YQ51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2Fbe8l\nEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxeKF+w6D9Fz8+vm2/7\nhNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4Fv6MGn8i1zeQf1xcGDXqVdFUNaBr8\nEBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbnfpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5\njF66CyCU3nuDuP/jVo23Eek7jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLY\niDrIn3hm7YnzezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt\nifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQALe3KHwGCmSUyI\nWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70jsNjLiNmsGe+b7bAEzlgqqI0\nJZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDzWochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKx\nK3JCaKygvU5a2hi/a5iB0P2avl4VSM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+\nXlff1ANATIGk0k9jpwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC\n4yyXX04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+OkfcvHlXHo\n2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7RK4X9p2jIugErsWx0Hbhz\nlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btUZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXem\nOR/qnuOf0GZvBeyqdn6/axag67XH/JJULysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9\nvwGYT7JZVEc+NHt4bVaTLnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg==\n-----END CERTIFICATE-----\n\nTrustis FPS Root CA\n===================\n-----BEGIN CERTIFICATE-----\nMIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQG\nEwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQLExNUcnVzdGlzIEZQUyBSb290\nIENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTExMzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNV\nBAoTD1RydXN0aXMgTGltaXRlZDEcMBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJ\nKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQ\nRUN+AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihHiTHcDnlk\nH5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjjvSkCqPoc4Vu5g6hBSLwa\ncY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zt\no3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlBOrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEA\nAaNTMFEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAd\nBgNVHQ4EFgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01GX2c\nGE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmWzaD+vkAMXBJV+JOC\nyinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP41BIy+Q7DsdwyhEQsb8tGD+pmQQ9P\n8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZEf1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHV\nl/9D7S3B2l0pKoU/rGXuhg8FjZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYl\niB6XzCGcKQENZetX2fNXlrtIzYE=\n-----END CERTIFICATE-----\n\nBuypass Class 2 Root CA\n=======================\n-----BEGIN CERTIFICATE-----\nMIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU\nQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMiBSb290IENBMB4X\nDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1owTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1\neXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIw\nDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1\ng1Lr6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPVL4O2fuPn\n9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC911K2GScuVr1QGbNgGE41b\n/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHxMlAQTn/0hpPshNOOvEu/XAFOBz3cFIqU\nCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZQmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeff\nawrbD02TTqigzXsu8lkBarcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgI\nzRFo1clrUs3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLiFRhn\nBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRSP/TizPJhk9H9Z2vX\nUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN9SG9dKpN6nIDSdvHXx1iY8f93ZHs\nM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxPAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD\nVR0OBBYEFMmAd+BikoL1RpzzuvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF\nAAOCAgEAU18h9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s\nA20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3tOluwlN5E40EI\nosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo+fsicdl9sz1Gv7SEr5AcD48S\naq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYd\nDnkM/crqJIByw5c/8nerQyIKx+u2DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWD\nLfJ6v9r9jv6ly0UsH8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0\noyLQI+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK75t98biGC\nwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h3PFaTWwyI0PurKju7koS\nCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPzY11aWOIv4x3kqdbQCtCev9eBCfHJxyYN\nrJgWVqA=\n-----END CERTIFICATE-----\n\nBuypass Class 3 Root CA\n=======================\n-----BEGIN CERTIFICATE-----\nMIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU\nQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMyBSb290IENBMB4X\nDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFowTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1\neXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIw\nDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRH\nsJ8YZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3EN3coTRiR\n5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9tznDDgFHmV0ST9tD+leh\n7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX0DJq1l1sDPGzbjniazEuOQAnFN44wOwZ\nZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH\n2xc519woe2v1n/MuwU8XKhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV\n/afmiSTYzIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvSO1UQ\nRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D34xFMFbG02SrZvPA\nXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgPK9Dx2hzLabjKSWJtyNBjYt1gD1iq\nj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD\nVR0OBBYEFEe4zf/lb+74suwvTg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF\nAAOCAgEAACAjQTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV\ncSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXSIGrs/CIBKM+G\nuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2HJLw5QY33KbmkJs4j1xrG0aG\nQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsaO5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8\nZORK15FTAaggiG6cX0S5y2CBNOxv033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2\nKSb12tjE8nVhz36udmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz\n6MkEkbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg413OEMXbug\nUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvDu79leNKGef9JOxqDDPDe\neOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq4/g7u9xN12TyUb7mqqta6THuBrxzvxNi\nCp/HuZc=\n-----END CERTIFICATE-----\n\nT-TeleSec GlobalRoot Class 3\n============================\n-----BEGIN CERTIFICATE-----\nMIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM\nIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU\ncnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgx\nMDAxMTAyOTU2WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz\ndGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD\nZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0GCSqGSIb3\nDQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN8ELg63iIVl6bmlQdTQyK\n9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/RLyTPWGrTs0NvvAgJ1gORH8EGoel15YU\nNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZF\niP0Zf3WHHx+xGwpzJFu5ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W\n0eDrXltMEnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGjQjBA\nMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1A/d2O2GCahKqGFPr\nAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOyWL6ukK2YJ5f+AbGwUgC4TeQbIXQb\nfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzT\nucpH9sry9uetuUg/vBa3wW306gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7h\nP0HHRwA11fXT91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml\ne9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4pTpPDpFQUWw==\n-----END CERTIFICATE-----\n\nEE Certification Centre Root CA\n===============================\n-----BEGIN CERTIFICATE-----\nMIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQG\nEwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1czEoMCYGA1UEAwwfRUUgQ2Vy\ndGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYGCSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIw\nMTAxMDMwMTAxMDMwWhgPMjAzMDEyMTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlB\nUyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRy\nZSBSb290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEBAQUAA4IB\nDwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUyeuuOF0+W2Ap7kaJjbMeM\nTC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvObntl8jixwKIy72KyaOBhU8E2lf/slLo2\nrpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIwWFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw\n93X2PaRka9ZP585ArQ/dMtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtN\nP2MbRMNE1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYDVR0T\nAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/zQas8fElyalL1BSZ\nMEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEF\nBQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEFBQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+Rj\nxY6hUFaTlrg4wCQiZrxTFGGVv9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqM\nlIpPnTX/dqQGE5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u\nuSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIWiAYLtqZLICjU\n3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/vGVCJYMzpJJUPwssd8m92kMfM\ndcGWxZ0=\n-----END CERTIFICATE-----\n\nD-TRUST Root Class 3 CA 2 2009\n==============================\n-----BEGIN CERTIFICATE-----\nMIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQK\nDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTAe\nFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NThaME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxE\nLVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIw\nDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOAD\nER03UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42tSHKXzlA\nBF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9RySPocq60vFYJfxLLHLGv\nKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsMlFqVlNpQmvH/pStmMaTJOKDfHR+4CS7z\np+hnUquVH+BGPtikw8paxTGA6Eian5Rp/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUC\nAwEAAaOCARowggEWMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ\n4PGEMA4GA1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVjdG9y\neS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUyMENBJTIwMiUyMDIw\nMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRlcmV2b2NhdGlvbmxpc3QwQ6BBoD+G\nPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAw\nOS5jcmwwDQYJKoZIhvcNAQELBQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm\n2H6NMLVwMeniacfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0\no3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4KzCUqNQT4YJEV\ndT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8PIWmawomDeCTmGCufsYkl4ph\nX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3YJohw1+qRzT65ysCQblrGXnRl11z+o+I=\n-----END CERTIFICATE-----\n\nD-TRUST Root Class 3 CA 2 EV 2009\n=================================\n-----BEGIN CERTIFICATE-----\nMIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK\nDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw\nOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUwNDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK\nDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw\nOTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfS\negpnljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM03TP1YtHh\nzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6ZqQTMFexgaDbtCHu39b+T\n7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lRp75mpoo6Kr3HGrHhFPC+Oh25z1uxav60\nsUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure35\n11H3a6UCAwEAAaOCASQwggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyv\ncop9NteaHNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFwOi8v\nZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xhc3MlMjAzJTIwQ0El\nMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1ERT9jZXJ0aWZpY2F0ZXJldm9jYXRp\nb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xh\nc3NfM19jYV8yX2V2XzIwMDkuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+\nPPoeUSbrh/Yp3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05\nnsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNFCSuGdXzfX2lX\nANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7naxpeG0ILD5EJt/rDiZE4OJudA\nNCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqXKVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVv\nw9y4AyHqnxbxLFS1\n-----END CERTIFICATE-----\n\nCA Disig Root R2\n================\n-----BEGIN CERTIFICATE-----\nMIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNVBAYTAlNLMRMw\nEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMuMRkwFwYDVQQDExBDQSBEaXNp\nZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQyMDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sx\nEzARBgNVBAcTCkJyYXRpc2xhdmExEzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERp\nc2lnIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbC\nw3OeNcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNHPWSb6Wia\nxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3Ix2ymrdMxp7zo5eFm1tL7\nA7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbeQTg06ov80egEFGEtQX6sx3dOy1FU+16S\nGBsEWmjGycT6txOgmLcRK7fWV8x8nhfRyyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqV\ng8NTEQxzHQuyRpDRQjrOQG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa\n5Beny912H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJQfYE\nkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUDi/ZnWejBBhG93c+A\nAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORsnLMOPReisjQS1n6yqEm70XooQL6i\nFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNV\nHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5u\nQu0wDQYJKoZIhvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM\ntCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqfGopTpti72TVV\nsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkblvdhuDvEK7Z4bLQjb/D907Je\ndR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka+elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W8\n1k/BfDxujRNt+3vrMNDcTa/F1balTFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjx\nmHHEt38OFdAlab0inSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01\nutI3gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18DrG5gPcFw0\nsorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3OszMOl6W8KjptlwlCFtaOg\nUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8xL4ysEr3vQCj8KWefshNPZiTEUxnpHikV\n7+ZtsH8tZ/3zbBt1RqPlShfppNcL\n-----END CERTIFICATE-----\n\nACCVRAIZ1\n=========\n-----BEGIN CERTIFICATE-----\nMIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UEAwwJQUNDVlJB\nSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQswCQYDVQQGEwJFUzAeFw0xMTA1\nMDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQBgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwH\nUEtJQUNDVjENMAsGA1UECgwEQUNDVjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4IC\nDwAwggIKAoICAQCbqau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gM\njmoYHtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWoG2ioPej0\nRGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpAlHPrzg5XPAOBOp0KoVdD\naaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhrIA8wKFSVf+DuzgpmndFALW4ir50awQUZ\n0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDG\nWuzndN9wrqODJerWx5eHk6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs7\n8yM2x/474KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMOm3WR\n5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpacXpkatcnYGMN285J\n9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPluUsXQA+xtrn13k/c4LOsOxFwYIRK\nQ26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYIKwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRw\nOi8vd3d3LmFjY3YuZXMvZmlsZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEu\nY3J0MB8GCCsGAQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2\nVuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeTVfZW6oHlNsyM\nHj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIGCCsGAQUFBwICMIIBFB6CARAA\nQQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUAcgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBh\nAO0AegAgAGQAZQAgAGwAYQAgAEEAQwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUA\nYwBuAG8AbABvAGcA7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBj\nAHQAcgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAAQwBQAFMA\nIABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUAczAwBggrBgEFBQcCARYk\naHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2MuaHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0\ndHA6Ly93d3cuYWNjdi5lcy9maWxlYWRtaW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2\nMV9kZXIuY3JsMA4GA1UdDwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZI\nhvcNAQEFBQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdpD70E\nR9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gUJyCpZET/LtZ1qmxN\nYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+mAM/EKXMRNt6GGT6d7hmKG9Ww7Y49\nnCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepDvV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJ\nTS+xJlsndQAJxGJ3KQhfnlmstn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3\nsCPdK6jT2iWH7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h\nI6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szAh1xA2syVP1Xg\nNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xFd3+YJ5oyXSrjhO7FmGYvliAd\n3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2HpPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3p\nEfbRD0tVNEYqi4Y7\n-----END CERTIFICATE-----\n\nTWCA Global Root CA\n===================\n-----BEGIN CERTIFICATE-----\nMIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcxEjAQBgNVBAoT\nCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMTVFdDQSBHbG9iYWwgUm9vdCBD\nQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQK\nEwlUQUlXQU4tQ0ExEDAOBgNVBAsTB1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3Qg\nQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2C\nnJfF10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz0ALfUPZV\nr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfChMBwqoJimFb3u/Rk28OKR\nQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbHzIh1HrtsBv+baz4X7GGqcXzGHaL3SekV\ntTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1W\nKKD+u4ZqyPpcC1jcxkt2yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99\nsy2sbZCilaLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYPoA/p\nyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQABDzfuBSO6N+pjWxn\nkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcEqYSjMq+u7msXi7Kx/mzhkIyIqJdI\nzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMC\nAQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6g\ncFGn90xHNcgL1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn\nLhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WFH6vPNOw/KP4M\n8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNoRI2T9GRwoD2dKAXDOXC4Ynsg\n/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlg\nlPx4mI88k1HtQJAH32RjJMtOcQWh15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryP\nA9gK8kxkRr05YuWW6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3m\ni4TWnsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5jwa19hAM8\nEHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWzaGHQRiapIVJpLesux+t3\nzqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmyKwbQBM0=\n-----END CERTIFICATE-----\n\nTeliaSonera Root CA v1\n======================\n-----BEGIN CERTIFICATE-----\nMIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAwNzEUMBIGA1UE\nCgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJvb3QgQ0EgdjEwHhcNMDcxMDE4\nMTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYDVQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwW\nVGVsaWFTb25lcmEgUm9vdCBDQSB2MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+\n6yfwIaPzaSZVfp3FVRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA\n3GV17CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+XZ75Ljo1k\nB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+/jXh7VB7qTCNGdMJjmhn\nXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxH\noLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkmdtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3\nF0fUTPHSiXk+TT2YqGHeOh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJ\noWjiUIMusDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4pgd7\ngUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fsslESl1MpWtTwEhDc\nTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQarMCpgKIv7NHfirZ1fpoeDVNAgMB\nAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qW\nDNXr+nuqF+gTEjANBgkqhkiG9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNm\nzqjMDfz1mgbldxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx\n0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1TjTQpgcmLNkQfW\npb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBedY2gea+zDTYa4EzAvXUYNR0PV\nG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpc\nc41teyWRyu5FrgZLAMzTsVlQ2jqIOylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOT\nJsjrDNYmiLbAJM+7vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2\nqReWt88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcnHL/EVlP6\nY2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVxSK236thZiNSQvxaz2ems\nWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY=\n-----END CERTIFICATE-----\n\nE-Tugra Certification Authority\n===============================\n-----BEGIN CERTIFICATE-----\nMIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNVBAYTAlRSMQ8w\nDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamls\nZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN\nZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMw\nNTEyMDk0OFoXDTIzMDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmEx\nQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxl\ncmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQD\nDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A\nMIICCgKCAgEA4vU/kwVRHoViVF56C/UYB4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vd\nhQd2h8y/L5VMzH2nPbxHD5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5K\nCKpbknSFQ9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEoq1+g\nElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3Dk14opz8n8Y4e0ypQ\nBaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcHfC425lAcP9tDJMW/hkd5s3kc91r0\nE+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsutdEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gz\nrt48Ue7LE3wBf4QOXVGUnhMMti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAq\njqFGOjGY5RH8zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn\nrFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUXU8u3Zg5mTPj5\ndUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6Jyr+zE7S6E5UMA8GA1UdEwEB\n/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEG\nMA0GCSqGSIb3DQEBCwUAA4ICAQAFNzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAK\nkEh47U6YA5n+KGCRHTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jO\nXKqYGwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c77NCR807\nVRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3+GbHeJAAFS6LrVE1Uweo\na2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WKvJUawSg5TB9D0pH0clmKuVb8P7Sd2nCc\ndlqMQ1DujjByTd//SffGqWfZbawCEeI6FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEV\nKV0jq9BgoRJP3vQXzTLlyb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gT\nDx4JnW2PAJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpDy4Q0\n8ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8dNL/+I5c30jn6PQ0G\nC7TbO6Orb1wdtn7os4I07QZcJA==\n-----END CERTIFICATE-----\n\nT-TeleSec GlobalRoot Class 2\n============================\n-----BEGIN CERTIFICATE-----\nMIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM\nIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU\ncnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgx\nMDAxMTA0MDE0WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz\ndGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD\nZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0GCSqGSIb3\nDQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUdAqSzm1nzHoqvNK38DcLZ\nSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiCFoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/F\nvudocP05l03Sx5iRUKrERLMjfTlH6VJi1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx970\n2cu+fjOlbpSD8DT6IavqjnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGV\nWOHAD3bZwI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGjQjBA\nMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/WSA2AHmgoCJrjNXy\nYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhyNsZt+U2e+iKo4YFWz827n+qrkRk4\nr6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPACuvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNf\nvNoBYimipidx5joifsFvHZVwIEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR\n3p1m0IvVVGb6g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN\n9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlPBSeOE6Fuwg==\n-----END CERTIFICATE-----\n\nAtos TrustedRoot 2011\n=====================\n-----BEGIN CERTIFICATE-----\nMIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UEAwwVQXRvcyBU\ncnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0xMTA3MDcxNDU4\nMzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMMFUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsG\nA1UECgwEQXRvczELMAkGA1UEBhMCREUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCV\nhTuXbyo7LjvPpvMpNb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr\n54rMVD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+SZFhyBH+\nDgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ4J7sVaE3IqKHBAUsR320\nHLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0Lcp2AMBYHlT8oDv3FdU9T1nSatCQujgKR\nz3bFmx5VdJx4IbHwLfELn8LVlhgf8FQieowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7R\nl+lwrrw7GWzbITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZ\nbNshMBgGA1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB\nCwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8jvZfza1zv7v1Apt+h\nk6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kPDpFrdRbhIfzYJsdHt6bPWHJxfrrh\nTZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pcmaHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a9\n61qn8FYiqTxlVMYVqL2Gns2Dlmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G\n3mB/ufNPRJLvKrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed\n-----END CERTIFICATE-----\n\nQuoVadis Root CA 1 G3\n=====================\n-----BEGIN CERTIFICATE-----\nMIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQELBQAwSDELMAkG\nA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv\nb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJN\nMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEg\nRzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakE\nPBtVwedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWerNrwU8lm\nPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF34168Xfuw6cwI2H44g4hWf6\nPser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh4Pw5qlPafX7PGglTvF0FBM+hSo+LdoIN\nofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXpUhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/l\ng6AnhF4EwfWQvTA9xO+oabw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV\n7qJZjqlc3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/GKubX\n9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSthfbZxbGL0eUQMk1f\niyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KOTk0k+17kBL5yG6YnLUlamXrXXAkg\nt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOtzCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTAD\nAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZI\nhvcNAQELBQADggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC\nMTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2cDMT/uFPpiN3\nGPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUNqXsCHKnQO18LwIE6PWThv6ct\nTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP\n+V04ikkwj+3x6xn0dxoxGE1nVGwvb2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh\n3jRJjehZrJ3ydlo28hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fa\nwx/kNSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNjZgKAvQU6\nO0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhpq1467HxpvMc7hU6eFbm0\nFU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFtnh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOV\nhMJKzRwuJIczYOXD\n-----END CERTIFICATE-----\n\nQuoVadis Root CA 2 G3\n=====================\n-----BEGIN CERTIFICATE-----\nMIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQELBQAwSDELMAkG\nA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv\nb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJN\nMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIg\nRzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFh\nZiFfqq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMWn4rjyduY\nNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ymc5GQYaYDFCDy54ejiK2t\noIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+O7q414AB+6XrW7PFXmAqMaCvN+ggOp+o\nMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+l\nV0POKa2Mq1W/xPtbAd0jIaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZo\nL1NesNKqIcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz8eQQ\nsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43ehvNURG3YBZwjgQQvD\n6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l7ZizlWNof/k19N+IxWA1ksB8aRxh\nlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALGcC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTAD\nAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZI\nhvcNAQELBQADggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66\nAarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RCroijQ1h5fq7K\npVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0GaW/ZZGYjeVYg3UQt4XAoeo0L9\nx52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4nlv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgz\ndWqTHBLmYF5vHX/JHyPLhGGfHoJE+V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6X\nU/IyAgkwo1jwDQHVcsaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+Nw\nmNtddbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNgKCLjsZWD\nzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeMHVOyToV7BjjHLPj4sHKN\nJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4WSr2Rz0ZiC3oheGe7IUIarFsNMkd7Egr\nO3jtZsSOeWmD3n+M\n-----END CERTIFICATE-----\n\nQuoVadis Root CA 3 G3\n=====================\n-----BEGIN CERTIFICATE-----\nMIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQELBQAwSDELMAkG\nA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv\nb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJN\nMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMg\nRzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286\nIxSR/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNuFoM7pmRL\nMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXRU7Ox7sWTaYI+FrUoRqHe\n6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+cra1AdHkrAj80//ogaX3T7mH1urPnMNA3\nI4ZyYUUpSFlob3emLoG+B01vr87ERRORFHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3U\nVDmrJqMz6nWB2i3ND0/kA9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f7\n5li59wzweyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634RylsSqi\nMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBpVzgeAVuNVejH38DM\ndyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0QA4XN8f+MFrXBsj6IbGB/kE+V9/Yt\nrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD\nAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZI\nhvcNAQELBQADggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px\nKGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnIFUBhynLWcKzS\nt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5WvvoxXqA/4Ti2Tk08HS6IT7SdEQ\nTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFgu/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9Du\nDcpmvJRPpq3t/O5jrFc/ZSXPsoaP0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGib\nIh6BJpsQBJFxwAYf3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmD\nhPbl8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+DhcI00iX\n0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HNPlopNLk9hM6xZdRZkZFW\ndSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ywaZWWDYWGWVjUTR939+J399roD1B0y2\nPpxxVJkES/1Y+Zj0\n-----END CERTIFICATE-----\n\nDigiCert Assured ID Root G2\n===========================\n-----BEGIN CERTIFICATE-----\nMIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBlMQswCQYDVQQG\nEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw\nIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgw\nMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL\nExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIw\nggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSAn61UQbVH\n35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4HteccbiJVMWWXvdMX0h5i89vq\nbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9HpEgjAALAcKxHad3A2m67OeYfcgnDmCXRw\nVWmvo2ifv922ebPynXApVfSr/5Vh88lAbx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OP\nYLfykqGxvYmJHzDNw6YuYjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+Rn\nlTGNAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTO\nw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPIQW5pJ6d1Ee88hjZv\n0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I0jJmwYrA8y8678Dj1JGG0VDjA9tz\nd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4GnilmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAW\nhsI6yLETcDbYz+70CjTVW0z9B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0M\njomZmWzwPDCvON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo\nIhNzbM8m9Yop5w==\n-----END CERTIFICATE-----\n\nDigiCert Assured ID Root G3\n===========================\n-----BEGIN CERTIFICATE-----\nMIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQswCQYDVQQGEwJV\nUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYD\nVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1\nMTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\nd3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQ\nBgcqhkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJfZn4f5dwb\nRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17QRSAPWXYQ1qAk8C3eNvJs\nKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgF\nUaFNN6KDec6NHSrkhDAKBggqhkjOPQQDAwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5Fy\nYZ5eEJJZVrmDxxDnOOlYJjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy\n1vUhZscv6pZjamVFkpUBtA==\n-----END CERTIFICATE-----\n\nDigiCert Global Root G2\n=======================\n-----BEGIN CERTIFICATE-----\nMIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQG\nEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw\nHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUx\nMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3\ndy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkq\nhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI2/Ou8jqJ\nkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx1x7e/dfgy5SDN67sH0NO\n3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQq2EGnI/yuum06ZIya7XzV+hdG82MHauV\nBJVJ8zUtluNJbd134/tJS7SsVQepj5WztCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyM\nUNGPHgm+F6HmIcr9g+UQvIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQAB\no0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV5uNu\n5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY1Yl9PMWLSn/pvtsr\nF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4NeF22d+mQrvHRAiGfzZ0JFrabA0U\nWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NGFdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBH\nQRFXGU7Aj64GxJUTFy8bJZ918rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/\niyK5S9kJRaTepLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl\nMrY=\n-----END CERTIFICATE-----\n\nDigiCert Global Root G3\n=======================\n-----BEGIN CERTIFICATE-----\nMIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQswCQYDVQQGEwJV\nUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAwHgYD\nVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAw\nMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k\naWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0C\nAQYFK4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FGfp4tn+6O\nYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPOZ9wj/wMco+I+o0IwQDAP\nBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNp\nYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIxAK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y\n3maTD/HMsQmP3Wyr+mt/oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34\nVOKa5Vt8sycX\n-----END CERTIFICATE-----\n\nDigiCert Trusted Root G4\n========================\n-----BEGIN CERTIFICATE-----\nMIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBiMQswCQYDVQQG\nEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEw\nHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1\nMTIwMDAwWjBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\nd3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0G\nCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3yithZwuEp\npz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1Ifxp4VpX6+n6lXFllVcq9o\nk3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDVySAdYyktzuxeTsiT+CFhmzTrBcZe7Fsa\nvOvJz82sNEBfsXpm7nfISKhmV1efVFiODCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGY\nQJB5w3jHtrHEtWoYOAMQjdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6\nMUSaM0C/CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCiEhtm\nmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADMfRyVw4/3IbKyEbe7\nf/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QYuKZ3AeEPlAwhHbJUKSWJbOUOUlFH\ndL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXKchYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8\noR7FwI+isX4KJpn15GkvmB0t9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud\nDwEB/wQEAwIBhjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD\nggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2SV1EY+CtnJYY\nZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd+SeuMIW59mdNOj6PWTkiU0Tr\nyF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWcfFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy\n7zBZLq7gcfJW5GqXb5JQbZaNaHqasjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iah\nixTXTBmyUEFxPT9NcCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN\n5r5N0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie4u1Ki7wb\n/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mIr/OSmbaz5mEP0oUA51Aa\n5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tK\nG48BtieVU+i2iW1bvGjUI+iLUaJW+fCmgKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP\n82Z+\n-----END CERTIFICATE-----\n\nCOMODO RSA Certification Authority\n==================================\n-----BEGIN CERTIFICATE-----\nMIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCBhTELMAkGA1UE\nBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG\nA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlv\nbiBBdXRob3JpdHkwHhcNMTAwMTE5MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMC\nR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE\nChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBB\ndXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR6FSS0gpWsawNJN3Fz0Rn\ndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8Xpz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZ\nFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+\n5eNu/Nio5JIk2kNrYrhV/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pG\nx8cgoLEfZd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z+pUX\n2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7wqP/0uK3pN/u6uPQL\nOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZahSL0896+1DSJMwBGB7FY79tOi4lu3\nsgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVICu9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+C\nGCe01a60y1Dma/RMhnEw6abfFobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5\nWdYgGq/yapiqcrxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E\nFgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w\nDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvlwFTPoCWOAvn9sKIN9SCYPBMt\nrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+\nnq6PK7o9mfjYcwlYRm6mnPTXJ9OV2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSg\ntZx8jb8uk2IntznaFxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwW\nsRqZCuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiKboHGhfKp\npC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmckejkk9u+UJueBPSZI9FoJA\nzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yLS0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHq\nZJx64SIDqZxubw5lT2yHh17zbqD5daWbQOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk52\n7RH89elWsn2/x20Kk4yl0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7I\nLaZRfyHBNVOFBkpdn627G190\n-----END CERTIFICATE-----\n\nUSERTrust RSA Certification Authority\n=====================================\n-----BEGIN CERTIFICATE-----\nMIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCBiDELMAkGA1UE\nBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQK\nExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh\ndGlvbiBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UE\nBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQK\nExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh\ndGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCAEmUXNg7D2wiz\n0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2j\nY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkYtJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFn\nRghRy4YUVD+8M/5+bJz/Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O\n+T23LLb2VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT79uq\n/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6c0Plfg6lZrEpfDKE\nY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmTYo61Zs8liM2EuLE/pDkP2QKe6xJM\nlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97lc6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8\nyexDJtC/QV9AqURE9JnnV4eeUB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+\neLf8ZxXhyVeEHg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd\nBgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF\nMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPFUp/L+M+ZBn8b2kMVn54CVVeW\nFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KOVWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ\n7l8wXEskEVX/JJpuXior7gtNn3/3ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQ\nEg9zKC7F4iRO/Fjs8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM\n8WcRiQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYzeSf7dNXGi\nFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZXHlKYC6SQK5MNyosycdi\nyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9c\nJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRBVXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGw\nsAvgnEzDHNb842m1R0aBL6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gx\nQ+6IHdfGjjxDah2nGN59PRbxYvnKkKj9\n-----END CERTIFICATE-----\n\nUSERTrust ECC Certification Authority\n=====================================\n-----BEGIN CERTIFICATE-----\nMIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDELMAkGA1UEBhMC\nVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU\naGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv\nbiBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMC\nVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU\naGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv\nbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqfloI+d61SRvU8Za2EurxtW2\n0eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinngo4N+LZfQYcTxmdwlkWOrfzCjtHDix6Ez\nnPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0GA1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNV\nHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBB\nHU6+4WMBzzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbWRNZu\n9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg=\n-----END CERTIFICATE-----\n\nGlobalSign ECC Root CA - R4\n===========================\n-----BEGIN CERTIFICATE-----\nMIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEkMCIGA1UECxMb\nR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD\nEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoXDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMb\nR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD\nEwpHbG9iYWxTaWduMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprl\nOQcJFspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAwDgYDVR0P\nAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61FuOJAf/sKbvu+M8k8o4TV\nMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGXkPoUVy0D7O48027KqGx2vKLeuwIgJ6iF\nJzWbVsaj8kfSt24bAgAXqmemFZHe+pTsewv4n4Q=\n-----END CERTIFICATE-----\n\nGlobalSign ECC Root CA - R5\n===========================\n-----BEGIN CERTIFICATE-----\nMIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEkMCIGA1UECxMb\nR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD\nEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoXDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMb\nR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD\nEwpHbG9iYWxTaWduMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6\nSFkc8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8kehOvRnkmS\nh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd\nBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYIKoZIzj0EAwMDaAAwZQIxAOVpEslu28Yx\nuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7\nyFz9SO8NdCKoCOJuxUnOxwy8p2Fp8fc74SrL+SvzZpA3\n-----END CERTIFICATE-----\n\nStaat der Nederlanden Root CA - G3\n==================================\n-----BEGIN CERTIFICATE-----\nMIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJOTDEeMBwGA1UE\nCgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFhdCBkZXIgTmVkZXJsYW5kZW4g\nUm9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloXDTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMC\nTkwxHjAcBgNVBAoMFVN0YWF0IGRlciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5l\nZGVybGFuZGVuIFJvb3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4y\nolQPcPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WWIkYFsO2t\nx1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqXxz8ecAgwoNzFs21v0IJy\nEavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFyKJLZWyNtZrVtB0LrpjPOktvA9mxjeM3K\nTj215VKb8b475lRgsGYeCasH/lSJEULR9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUur\nmkVLoR9BvUhTFXFkC4az5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU5\n1nus6+N86U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7Ngzp\n07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHPbMk7ccHViLVlvMDo\nFxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXtBznaqB16nzaeErAMZRKQFWDZJkBE\n41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTtXUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMB\nAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleu\nyjWcLhL75LpdINyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD\nU5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwpLiniyMMB8jPq\nKqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8Ipf3YF3qKS9Ysr1YvY2WTxB1\nv0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixpgZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA\n8KCWAg8zxXHzniN9lLf9OtMJgwYh/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b\n8KKaa8MFSu1BYBQw0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0r\nmj1AfsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq4BZ+Extq\n1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR1VmiiXTTn74eS9fGbbeI\nJG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/QFH1T/U67cjF68IeHRaVesd+QnGTbksV\ntzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM94B7IWcnMFk=\n-----END CERTIFICATE-----\n\nStaat der Nederlanden EV Root CA\n================================\n-----BEGIN CERTIFICATE-----\nMIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJOTDEeMBwGA1UE\nCgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFhdCBkZXIgTmVkZXJsYW5kZW4g\nRVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0yMjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5M\nMR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRl\ncmxhbmRlbiBFViBSb290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkk\nSzrSM4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nCUiY4iKTW\nO0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3dZ//BYY1jTw+bbRcwJu+r\n0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46prfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8\nKj6GyzyDOvnJDdrFmeK8eEEzduG/L13lpJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gV\nXJrm0w912fxBmJc+qiXbj5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr\n08C+eKxCKFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS/ZbV\n0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0XcgOPvZuM5l5Tnrmd\n74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH1vI4gnPah1vlPNOePqc7nvQDs/nx\nfRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrPpx9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNC\nMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwa\nivsnuL8wbqg7MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI\neK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u2dfOWBfoqSmu\nc0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHSv4ilf0X8rLiltTMMgsT7B/Zq\n5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTCwPTxGfARKbalGAKb12NMcIxHowNDXLldRqAN\nb/9Zjr7dn3LDWyvfjFvO5QxGbJKyCqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tN\nf1zuacpzEPuKqf2evTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi\n5Dp6Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIaGl6I6lD4\nWeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeLeG9QgkRQP2YGiqtDhFZK\nDyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGy\neUN51q1veieQA6TqJIc/2b3Z6fJfUEkc7uzXLg==\n-----END CERTIFICATE-----\n\nIdenTrust Commercial Root CA 1\n==============================\n-----BEGIN CERTIFICATE-----\nMIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBKMQswCQYDVQQG\nEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBS\nb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQwMTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzES\nMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENB\nIDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ld\nhNlT3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU+ehcCuz/\nmNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gpS0l4PJNgiCL8mdo2yMKi\n1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1bVoE/c40yiTcdCMbXTMTEl3EASX2MN0C\nXZ/g1Ue9tOsbobtJSdifWwLziuQkkORiT0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl\n3ZBWzvurpWCdxJ35UrCLvYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzy\nNeVJSQjKVsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZKdHzV\nWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHTc+XvvqDtMwt0viAg\nxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hvl7yTmvmcEpB4eoCHFddydJxVdHix\nuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5NiGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMC\nAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZI\nhvcNAQELBQADggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH\n6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwtLRvM7Kqas6pg\nghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93nAbowacYXVKV7cndJZ5t+qnt\nozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3+wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmV\nYjzlVYA211QC//G5Xc7UI2/YRYRKW2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUX\nfeu+h1sXIFRRk0pTAwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/ro\nkTLql1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG4iZZRHUe\n2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZmUlO+KWA2yUPHGNiiskz\nZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7R\ncGzM7vRX+Bi6hG6H\n-----END CERTIFICATE-----\n\nIdenTrust Public Sector Root CA 1\n=================================\n-----BEGIN CERTIFICATE-----\nMIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBNMQswCQYDVQQG\nEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3Rv\nciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcNMzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJV\nUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBS\nb290IENBIDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTy\nP4o7ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGyRBb06tD6\nHi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlSbdsHyo+1W/CD80/HLaXI\nrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF/YTLNiCBWS2ab21ISGHKTN9T0a9SvESf\nqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoS\nmJxZZoY+rfGwyj4GD3vwEUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFn\nol57plzy9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9VGxyh\nLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ2fjXctscvG29ZV/v\niDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsVWaFHVCkugyhfHMKiq3IXAAaOReyL\n4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gDW/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8B\nAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMw\nDQYJKoZIhvcNAQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj\nt2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHVDRDtfULAj+7A\nmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9TaDKQGXSc3z1i9kKlT/YPyNt\nGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8GlwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFt\nm6/n6J91eEyrRjuazr8FGF1NFTwWmhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMx\nNRF4eKLg6TCMf4DfWN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4\nMhn5+bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJtshquDDI\najjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhAGaQdp/lLQzfcaFpPz+vC\nZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ\n3Wl9af0AVqW3rLatt8o+Ae+c\n-----END CERTIFICATE-----\n\nEntrust Root Certification Authority - G2\n=========================================\n-----BEGIN CERTIFICATE-----\nMIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMCVVMxFjAUBgNV\nBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVy\nbXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ug\nb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIw\nHhcNMDkwNzA3MTcyNTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoT\nDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMx\nOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25s\neTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwggEi\nMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP\n/vaCeb9zYQYKpSfYs1/TRU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXz\nHHfV1IWNcCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hWwcKU\ns/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1U1+cPvQXLOZprE4y\nTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0jaWvYkxN4FisZDQSA/i2jZRjJKRx\nAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ6\n0B7vfec7aVHUbI2fkBJmqzANBgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5Z\niXMRrEPR9RP/jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ\nRkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v1fN2D807iDgi\nnWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4RnAuknZoh8/CbCzB428Hch0P+\nvGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmHVHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xO\ne4pIb4tF9g==\n-----END CERTIFICATE-----\n\nEntrust Root Certification Authority - EC1\n==========================================\n-----BEGIN CERTIFICATE-----\nMIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkGA1UEBhMCVVMx\nFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVn\nYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXpl\nZCB1c2Ugb25seTEzMDEGA1UEAxMqRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5\nIC0gRUMxMB4XDTEyMTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYw\nFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2Fs\nLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQg\ndXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAt\nIEVDMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHy\nAsWfoPZb1YsGGYZPUxBtByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef\n9eNi1KlHBz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE\nFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVCR98crlOZF7ZvHH3h\nvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nXhTcGtXsI/esni0qU+eH6p44mCOh8\nkmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G\n-----END CERTIFICATE-----\n\nCFCA EV ROOT\n============\n-----BEGIN CERTIFICATE-----\nMIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJDTjEwMC4GA1UE\nCgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNB\nIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkxMjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEw\nMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQD\nDAxDRkNBIEVWIFJPT1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnV\nBU03sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpLTIpTUnrD\n7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5/ZOkVIBMUtRSqy5J35DN\nuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp7hZZLDRJGqgG16iI0gNyejLi6mhNbiyW\nZXvKWfry4t3uMCz7zEasxGPrb382KzRzEpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7\nxzbh72fROdOXW3NiGUgthxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9f\npy25IGvPa931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqotaK8K\ngWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNgTnYGmE69g60dWIol\nhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfVPKPtl8MeNPo4+QgO48BdK4PRVmrJ\ntqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hvcWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAf\nBgNVHSMEGDAWgBTj/i39KNALtbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB\n/wQEAwIBBjAdBgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB\nACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObTej/tUxPQ4i9q\necsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdLjOztUmCypAbqTuv0axn96/Ua\n4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBSESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sG\nE5uPhnEFtC+NiWYzKXZUmhH4J/qyP5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfX\nBDrDMlI1Dlb4pd19xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjn\naH9dCi77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN5mydLIhy\nPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe/v5WOaHIz16eGWRGENoX\nkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+ZAAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3C\nekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su\n-----END CERTIFICATE-----\n\nOISTE WISeKey Global Root GB CA\n===============================\n-----BEGIN CERTIFICATE-----\nMIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBtMQswCQYDVQQG\nEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl\nZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAw\nMzJaFw0zOTEyMDExNTEwMzFaMG0xCzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYD\nVQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEds\nb2JhbCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3HEokKtaX\nscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGxWuR51jIjK+FTzJlFXHtP\nrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk\n9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNku7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4o\nQnc/nSMbsrY9gBQHTC5P99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvg\nGUpuuy9rM2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB\n/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZI\nhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrghcViXfa43FK8+5/ea4n32cZiZBKpD\ndHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0\nVQreUGdNZtGn//3ZwLWoo4rOZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEui\nHZeeevJuQHHfaPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic\nNc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM=\n-----END CERTIFICATE-----\n\nSZAFIR ROOT CA2\n===============\n-----BEGIN CERTIFICATE-----\nMIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQELBQAwUTELMAkG\nA1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6ZW5pb3dhIFMuQS4xGDAWBgNV\nBAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkwNzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJ\nBgNVBAYTAlBMMSgwJgYDVQQKDB9LcmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYD\nVQQDDA9TWkFGSVIgUk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5Q\nqEvNQLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT3PSQ1hNK\nDJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw3gAeqDRHu5rr/gsUvTaE\n2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr63fE9biCloBK0TXC5ztdyO4mTp4CEHCdJ\nckm1/zuVnsHMyAHs6A6KCpbns6aH5db5BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwi\nieDhZNRnvDF5YTy7ykHNXGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P\nAQH/BAQDAgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsFAAOC\nAQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw8PRBEew/R40/cof5\nO/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOGnXkZ7/e7DDWQw4rtTw/1zBLZpD67\noPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCPoky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul\n4+vJhaAlIDf7js4MNIThPIGyd05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6\n+/NNIxuZMzSgLvWpCz/UXeHPhJ/iGcJfitYgHuNztw==\n-----END CERTIFICATE-----\n\nCertum Trusted Network CA 2\n===========================\n-----BEGIN CERTIFICATE-----\nMIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCBgDELMAkGA1UE\nBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMuQS4xJzAlBgNVBAsTHkNlcnR1\nbSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIGA1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29y\nayBDQSAyMCIYDzIwMTExMDA2MDgzOTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQ\nTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENl\ncnRpZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENB\nIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWADGSdhhuWZGc/IjoedQF9\n7/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+o\nCgCXhVqqndwpyeI1B+twTUrWwbNWuKFBOJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40b\nRr5HMNUuctHFY9rnY3lEfktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2p\nuTRZCr+ESv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1mo130\nGO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02isx7QBlrd9pPPV3WZ\n9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOWOZV7bIBaTxNyxtd9KXpEulKkKtVB\nRgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgezTv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pye\nhizKV/Ma5ciSixqClnrDvFASadgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vM\nBhBgu4M1t15n3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD\nAQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZI\nhvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQF/xlhMcQSZDe28cmk4gmb3DW\nAl45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTfCVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuA\nL55MYIR4PSFk1vtBHxgP58l1cb29XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMo\nclm2q8KMZiYcdywmdjWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tM\npkT/WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jbAoJnwTnb\nw3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksqP/ujmv5zMnHCnsZy4Ypo\nJ/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Kob7a6bINDd82Kkhehnlt4Fj1F4jNy3eFm\nypnTycUm/Q1oBEauttmbjL4ZvrHG8hnjXALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLX\nis7VmFxWlgPF7ncGNf/P5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7\nzAYspsbiDrW5viSP\n-----END CERTIFICATE-----\n\nHellenic Academic and Research Institutions RootCA 2015\n=======================================================\n-----BEGIN CERTIFICATE-----\nMIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1IxDzANBgNVBAcT\nBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0\naW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNl\nYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAx\nMTIxWjCBpjELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMg\nQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNV\nBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIw\nMTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDC+Kk/G4n8PDwEXT2QNrCROnk8Zlrv\nbTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+eh\niGsxr/CL0BgzuNtFajT0AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+\n6PAQZe104S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06CojXd\nFPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV9Cz82XBST3i4vTwr\ni5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrDgfgXy5I2XdGj2HUb4Ysn6npIQf1F\nGQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2\nfu/Z8VFRfS0myGlZYeCsargqNhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9mu\niNX6hME6wGkoLfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc\nBw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNVHRMBAf8EBTAD\nAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVdctA4GGqd83EkVAswDQYJKoZI\nhvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0IXtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+\nD1hYc2Ryx+hFjtyp8iY/xnmMsVMIM4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrM\nd/K4kPFox/la/vot9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+y\nd+2VZ5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/eaj8GsGsVn\n82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnhX9izjFk0WaSrT2y7Hxjb\ndavYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQl033DlZdwJVqwjbDG2jJ9SrcR5q+ss7F\nJej6A7na+RZukYT1HCjI/CbM1xyQVqdfbzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVt\nJ94Cj8rDtSvK6evIIVM4pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGa\nJI7ZjnHKe7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0vm9q\np/UsQu0yrbYhnr68\n-----END CERTIFICATE-----\n\nHellenic Academic and Research Institutions ECC RootCA 2015\n===========================================================\n-----BEGIN CERTIFICATE-----\nMIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0\naGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9u\ncyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJj\naCBJbnN0aXR1dGlvbnMgRUNDIFJvb3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEw\nMzcxMlowgaoxCzAJBgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmlj\nIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUQwQgYD\nVQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIEVDQyBSb290\nQ0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKgQehLgoRc4vgxEZmGZE4JJS+dQS8KrjVP\ndJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJajq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoK\nVlp8aQuqgAkkbH7BRqNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O\nBBYEFLQiC4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaeplSTA\nGiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7SofTUwJCA3sS61kFyjn\ndc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR\n-----END CERTIFICATE-----\n\nISRG Root X1\n============\n-----BEGIN CERTIFICATE-----\nMIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAwTzELMAkGA1UE\nBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2VhcmNoIEdyb3VwMRUwEwYDVQQD\nEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQG\nEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMT\nDElTUkcgUm9vdCBYMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54r\nVygch77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+0TM8ukj1\n3Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6UA5/TR5d8mUgjU+g4rk8K\nb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sWT8KOEUt+zwvo/7V3LvSye0rgTBIlDHCN\nAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyHB5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ\n4Q7e2RCOFvu396j3x+UCB5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf\n1b0SHzUvKBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWnOlFu\nhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTnjh8BCNAw1FtxNrQH\nusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbwqHyGO0aoSCqI3Haadr8faqU9GY/r\nOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CIrU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4G\nA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY\n9umbbjANBgkqhkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL\nubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ3BebYhtF8GaV\n0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KKNFtY2PwByVS5uCbMiogziUwt\nhDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJw\nTdwJx4nLCgdNbOhdjsnvzqvHu7UrTkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nx\ne5AW0wdeRlN8NwdCjNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZA\nJzVcoyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq4RgqsahD\nYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPAmRGunUHBcnWEvgJBQl9n\nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57demyPxgcYxn/eR44/KJ4EBs+lVDR3veyJ\nm+kXQ99b21/+jh5Xos1AnX5iItreGCc=\n-----END CERTIFICATE-----\n\nAC RAIZ FNMT-RCM\n================\n-----BEGIN CERTIFICATE-----\nMIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsxCzAJBgNVBAYT\nAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTTAeFw0wODEw\nMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJD\nTTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC\nggIBALpxgHpMhm5/yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcf\nqQgfBBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAzWHFctPVr\nbtQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxFtBDXaEAUwED653cXeuYL\nj2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z374jNUUeAlz+taibmSXaXvMiwzn15Cou\n08YfxGyqxRxqAQVKL9LFwag0Jl1mpdICIfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mw\nWsXmo8RZZUc1g16p6DULmbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnT\ntOmlcYF7wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peSMKGJ\n47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2ZSysV4999AeU14EC\nll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMetUqIJ5G+GR4of6ygnXYMgrwTJbFaa\ni0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE\nFPd9xf3E6Jobd2Sn9R2gzL+HYJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1o\ndHRwOi8vd3d3LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD\nnFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1RXxlDPiyN8+s\nD8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYMLVN0V2Ue1bLdI4E7pWYjJ2cJ\nj+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrT\nQfv6MooqtyuGC2mDOL7Nii4LcK2NJpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW\n+YJF1DngoABd15jmfZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7\nIxjp6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp1txyM/1d\n8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B9kiABdcPUXmsEKvU7ANm\n5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wokRqEIr9baRRmW1FMdW4R58MD3R++Lj8UG\nrp1MYp3/RgT408m2ECVAdf4WqslKYIYvuu8wd+RU4riEmViAqhOLUTpPSPaLtrM=\n-----END CERTIFICATE-----\n\nAmazon Root CA 1\n================\n-----BEGIN CERTIFICATE-----\nMIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsFADA5MQswCQYD\nVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAxMB4XDTE1\nMDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv\nbjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\nggEBALJ4gHHKeNXjca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgH\nFzZM9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qwIFAGbHrQ\ngLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6VOujw5H5SNz/0egwLX0t\ndHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L93FcXmn/6pUCyziKrlA4b9v7LWIbxcce\nVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQmjgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB\n/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3\nDQEBCwUAA4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDIU5PM\nCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUsN+gDS63pYaACbvXy\n8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vvo/ufQJVtMVT8QtPHRh8jrdkPSHCa\n2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2\nxJNDd2ZhwLnoQdeXeGADbkpyrqXRfboQnoZsG4q5WTP468SQvvG5\n-----END CERTIFICATE-----\n\nAmazon Root CA 2\n================\n-----BEGIN CERTIFICATE-----\nMIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwFADA5MQswCQYD\nVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAyMB4XDTE1\nMDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv\nbjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC\nggIBAK2Wny2cSkxKgXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4\nkHbZW0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg1dKmSYXp\nN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K8nu+NQWpEjTj82R0Yiw9\nAElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvd\nfLC6HM783k81ds8P+HgfajZRRidhW+mez/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAEx\nkv8LV/SasrlX6avvDXbR8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSS\nbtqDT6ZjmUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz7Mt0\nQ5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6+XUyo05f7O0oYtlN\nc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI0u1ufm8/0i2BWSlmy5A5lREedCf+\n3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSw\nDPBMMPQFWAJI/TPlUq9LhONmUjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oA\nA7CXDpO8Wqj2LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY\n+gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kSk5Nrp+gvU5LE\nYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl7uxMMne0nxrpS10gxdr9HIcW\nxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygmbtmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQ\ngj9sAq+uEjonljYE1x2igGOpm/HlurR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbW\naQbLU8uz/mtBzUF+fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoV\nYh63n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE76KlXIx3\nKadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H9jVlpNMKVv/1F2Rs76gi\nJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT4PsJYGw=\n-----END CERTIFICATE-----\n\nAmazon Root CA 3\n================\n-----BEGIN CERTIFICATE-----\nMIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5MQswCQYDVQQG\nEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAzMB4XDTE1MDUy\nNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ\nMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZB\nf8ANm+gBG1bG8lKlui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjr\nZt6jQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSrttvXBp43\nrDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkrBqWTrBqYaGFy+uGh0Psc\neGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteMYyRIHN8wfdVoOw==\n-----END CERTIFICATE-----\n\nAmazon Root CA 4\n================\n-----BEGIN CERTIFICATE-----\nMIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5MQswCQYDVQQG\nEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSA0MB4XDTE1MDUy\nNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ\nMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN\n/sGKe0uoe0ZLY7Bi9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri\n83BkM6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV\nHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WBMAoGCCqGSM49BAMDA2gA\nMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlwCkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1\nAE47xDqUEpHJWEadIRNyp4iciuRMStuW1KyLa2tJElMzrdfkviT8tQp21KW8EA==\n-----END CERTIFICATE-----\n\nTUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1\n=============================================\n-----BEGIN CERTIFICATE-----\nMIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIxGDAWBgNVBAcT\nD0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxpbXNlbCB2ZSBUZWtub2xvamlr\nIEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0wKwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24g\nTWVya2V6aSAtIEthbXUgU00xNjA0BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRp\nZmlrYXNpIC0gU3VydW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYD\nVQQGEwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXllIEJpbGlt\nc2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklUQUsxLTArBgNVBAsTJEth\nbXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBTTTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11\nIFNNIFNTTCBLb2sgU2VydGlmaWthc2kgLSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\nMIIBCgKCAQEAr3UwM6q7a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y8\n6Ij5iySrLqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INrN3wc\nwv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2XYacQuFWQfw4tJzh0\n3+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/iSIzL+aFCr2lqBs23tPcLG07xxO9\nWSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4fAJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQU\nZT/HiobGPN08VFw1+DrtUgxHV8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJ\nKoZIhvcNAQELBQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh\nAHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPfIPP54+M638yc\nlNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4lzwDGrpDxpa5RXI4s6ehlj2R\ne37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0j\nq5Rm+K37DwhuJi1/FwcJsoz7UMCflo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM=\n-----END CERTIFICATE-----\n\nGDCA TrustAUTH R5 ROOT\n======================\n-----BEGIN CERTIFICATE-----\nMIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UEBhMCQ04xMjAw\nBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8wHQYDVQQD\nDBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0MTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVow\nYjELMAkGA1UEBhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ\nIENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0B\nAQEFAAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJjDp6L3TQs\nAlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBjTnnEt1u9ol2x8kECK62p\nOqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+uKU49tm7srsHwJ5uu4/Ts765/94Y9cnrr\npftZTqfrlYwiOXnhLQiPzLyRuEH3FMEjqcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ\n9Cy5WmYqsBebnh52nUpmMUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQ\nxXABZG12ZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloPzgsM\nR6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3GkL30SgLdTMEZeS1SZ\nD2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeCjGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4\noR24qoAATILnsn8JuLwwoC8N9VKejveSswoAHQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx\n9hoh49pwBiFYFIeFd3mqgnkCAwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlR\nMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg\np8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZmDRd9FBUb1Ov9\nH5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5COmSdI31R9KrO9b7eGZONn35\n6ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ryL3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd\n+PwyvzeG5LuOmCd+uh8W4XAR8gPfJWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQ\nHtZa37dG/OaG+svgIHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBD\nF8Io2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV09tL7ECQ\n8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQXR4EzzffHqhmsYzmIGrv\n/EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrqT8p+ck0LcIymSLumoRT2+1hEmRSuqguT\naaApJUqlyyvdimYHFngVV3Eb7PVHhPOeMTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g==\n-----END CERTIFICATE-----\n\nTrustCor RootCert CA-1\n======================\n-----BEGIN CERTIFICATE-----\nMIIEMDCCAxigAwIBAgIJANqb7HHzA7AZMA0GCSqGSIb3DQEBCwUAMIGkMQswCQYDVQQGEwJQQTEP\nMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEkMCIGA1UECgwbVHJ1c3RDb3Ig\nU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3Jp\ndHkxHzAdBgNVBAMMFlRydXN0Q29yIFJvb3RDZXJ0IENBLTEwHhcNMTYwMjA0MTIzMjE2WhcNMjkx\nMjMxMTcyMzE2WjCBpDELMAkGA1UEBhMCUEExDzANBgNVBAgMBlBhbmFtYTEUMBIGA1UEBwwLUGFu\nYW1hIENpdHkxJDAiBgNVBAoMG1RydXN0Q29yIFN5c3RlbXMgUy4gZGUgUi5MLjEnMCUGA1UECwwe\nVHJ1c3RDb3IgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR8wHQYDVQQDDBZUcnVzdENvciBSb290Q2Vy\ndCBDQS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv463leLCJhJrMxnHQFgKq1mq\njQCj/IDHUHuO1CAmujIS2CNUSSUQIpidRtLByZ5OGy4sDjjzGiVoHKZaBeYei0i/mJZ0PmnK6bV4\npQa81QBeCQryJ3pS/C3Vseq0iWEk8xoT26nPUu0MJLq5nux+AHT6k61sKZKuUbS701e/s/OojZz0\nJEsq1pme9J7+wH5COucLlVPat2gOkEz7cD+PSiyU8ybdY2mplNgQTsVHCJCZGxdNuWxu72CVEY4h\ngLW9oHPY0LJ3xEXqWib7ZnZ2+AYfYW0PVcWDtxBWcgYHpfOxGgMFZA6dWorWhnAbJN7+KIor0Gqw\n/Hqi3LJ5DotlDwIDAQABo2MwYTAdBgNVHQ4EFgQU7mtJPHo/DeOxCbeKyKsZn3MzUOcwHwYDVR0j\nBBgwFoAU7mtJPHo/DeOxCbeKyKsZn3MzUOcwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\nAYYwDQYJKoZIhvcNAQELBQADggEBACUY1JGPE+6PHh0RU9otRCkZoB5rMZ5NDp6tPVxBb5UrJKF5\nmDo4Nvu7Zp5I/5CQ7z3UuJu0h3U/IJvOcs+hVcFNZKIZBqEHMwwLKeXx6quj7LUKdJDHfXLy11yf\nke+Ri7fc7Waiz45mO7yfOgLgJ90WmMCV1Aqk5IGadZQ1nJBfiDcGrVmVCrDRZ9MZyonnMlo2HD6C\nqFqTvsbQZJG2z9m2GM/bftJlo6bEjhcxwft+dtvTheNYsnd6djtsL1Ac59v2Z3kf9YKVmgenFK+P\n3CghZwnS1k1aHBkcjndcw5QkPTJrS37UeJSDvjdNzl/HHk484IkzlQsPpTLWPFp5LBk=\n-----END CERTIFICATE-----\n\nTrustCor RootCert CA-2\n======================\n-----BEGIN CERTIFICATE-----\nMIIGLzCCBBegAwIBAgIIJaHfyjPLWQIwDQYJKoZIhvcNAQELBQAwgaQxCzAJBgNVBAYTAlBBMQ8w\nDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQwIgYDVQQKDBtUcnVzdENvciBT\neXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRydXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0\neTEfMB0GA1UEAwwWVHJ1c3RDb3IgUm9vdENlcnQgQ0EtMjAeFw0xNjAyMDQxMjMyMjNaFw0zNDEy\nMzExNzI2MzlaMIGkMQswCQYDVQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5h\nbWEgQ2l0eTEkMCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U\ncnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRydXN0Q29yIFJvb3RDZXJ0\nIENBLTIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCnIG7CKqJiJJWQdsg4foDSq8Gb\nZQWU9MEKENUCrO2fk8eHyLAnK0IMPQo+QVqedd2NyuCb7GgypGmSaIwLgQ5WoD4a3SwlFIIvl9Nk\nRvRUqdw6VC0xK5mC8tkq1+9xALgxpL56JAfDQiDyitSSBBtlVkxs1Pu2YVpHI7TYabS3OtB0PAx1\noYxOdqHp2yqlO/rOsP9+aij9JxzIsekp8VduZLTQwRVtDr4uDkbIXvRR/u8OYzo7cbrPb1nKDOOb\nXUm4TOJXsZiKQlecdu/vvdFoqNL0Cbt3Nb4lggjEFixEIFapRBF37120Hapeaz6LMvYHL1cEksr1\n/p3C6eizjkxLAjHZ5DxIgif3GIJ2SDpxsROhOdUuxTTCHWKF3wP+TfSvPd9cW436cOGlfifHhi5q\njxLGhF5DUVCcGZt45vz27Ud+ez1m7xMTiF88oWP7+ayHNZ/zgp6kPwqcMWmLmaSISo5uZk3vFsQP\neSghYA2FFn3XVDjxklb9tTNMg9zXEJ9L/cb4Qr26fHMC4P99zVvh1Kxhe1fVSntb1IVYJ12/+Ctg\nrKAmrhQhJ8Z3mjOAPF5GP/fDsaOGM8boXg25NSyqRsGFAnWAoOsk+xWq5Gd/bnc/9ASKL3x74xdh\n8N0JqSDIvgmk0H5Ew7IwSjiqqewYmgeCK9u4nBit2uBGF6zPXQIDAQABo2MwYTAdBgNVHQ4EFgQU\n2f4hQG6UnrybPZx9mCAZ5YwwYrIwHwYDVR0jBBgwFoAU2f4hQG6UnrybPZx9mCAZ5YwwYrIwDwYD\nVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBAJ5Fngw7tu/h\nOsh80QA9z+LqBrWyOrsGS2h60COXdKcs8AjYeVrXWoSK2BKaG9l9XE1wxaX5q+WjiYndAfrs3fnp\nkpfbsEZC89NiqpX+MWcUaViQCqoL7jcjx1BRtPV+nuN79+TMQjItSQzL/0kMmx40/W5ulop5A7Zv\n2wnL/V9lFDfhOPXzYRZY5LVtDQsEGz9QLX+zx3oaFoBg+Iof6Rsqxvm6ARppv9JYx1RXCI/hOWB3\nS6xZhBqI8d3LT3jX5+EzLfzuQfogsL7L9ziUwOHQhQ+77Sxzq+3+knYaZH9bDTMJBzN7Bj8RpFxw\nPIXAz+OQqIN3+tvmxYxoZxBnpVIt8MSZj3+/0WvitUfW2dCFmU2Umw9Lje4AWkcdEQOsQRivh7dv\nDDqPys/cA8GiCcjl/YBeyGBCARsaU1q7N6a3vLqE6R5sGtRk2tRD/pOLS/IseRYQ1JMLiI+h2IYU\nRpFHmygk71dSTlxCnKr3Sewn6EAes6aJInKc9Q0ztFijMDvd1GpUk74aTfOTlPf8hAs/hCBcNANE\nxdqtvArBAs8e5ZTZ845b2EzwnexhF7sUMlQMAimTHpKG9n/v55IFDlndmQguLvqcAFLTxWYp5KeX\nRKQOKIETNcX2b2TmQcTVL8w0RSXPQQCWPUouwpaYT05KnJe32x+SMsj/D1Fu1uwJ\n-----END CERTIFICATE-----\n\nTrustCor ECA-1\n==============\n-----BEGIN CERTIFICATE-----\nMIIEIDCCAwigAwIBAgIJAISCLF8cYtBAMA0GCSqGSIb3DQEBCwUAMIGcMQswCQYDVQQGEwJQQTEP\nMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEkMCIGA1UECgwbVHJ1c3RDb3Ig\nU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3Jp\ndHkxFzAVBgNVBAMMDlRydXN0Q29yIEVDQS0xMB4XDTE2MDIwNDEyMzIzM1oXDTI5MTIzMTE3Mjgw\nN1owgZwxCzAJBgNVBAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5\nMSQwIgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRydXN0Q29y\nIENlcnRpZmljYXRlIEF1dGhvcml0eTEXMBUGA1UEAwwOVHJ1c3RDb3IgRUNBLTEwggEiMA0GCSqG\nSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPj+ARtZ+odnbb3w9U73NjKYKtR8aja+3+XzP4Q1HpGjOR\nMRegdMTUpwHmspI+ap3tDvl0mEDTPwOABoJA6LHip1GnHYMma6ve+heRK9jGrB6xnhkB1Zem6g23\nxFUfJ3zSCNV2HykVh0A53ThFEXXQmqc04L/NyFIduUd+Dbi7xgz2c1cWWn5DkR9VOsZtRASqnKmc\np0yJF4OuowReUoCLHhIlERnXDH19MURB6tuvsBzvgdAsxZohmz3tQjtQJvLsznFhBmIhVE5/wZ0+\nfyCMgMsq2JdiyIMzkX2woloPV+g7zPIlstR8L+xNxqE6FXrntl019fZISjZFZtS6mFjBAgMBAAGj\nYzBhMB0GA1UdDgQWBBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAfBgNVHSMEGDAWgBREnkj1zG1I1KBL\nf/5ZJC+Dl5mahjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsF\nAAOCAQEABT41XBVwm8nHc2FvcivUwo/yQ10CzsSUuZQRg2dd4mdsdXa/uwyqNsatR5Nj3B5+1t4u\n/ukZMjgDfxT2AHMsWbEhBuH7rBiVDKP/mZb3Kyeb1STMHd3BOuCYRLDE5D53sXOpZCz2HAF8P11F\nhcCF5yWPldwX8zyfGm6wyuMdKulMY/okYWLW2n62HGz1Ah3UKt1VkOsqEUc8Ll50soIipX1TH0Xs\nJ5F95yIW6MBoNtjG8U+ARDL54dHRHareqKucBK+tIA5kmE2la8BIWJZpTdwHjFGTot+fDz2LYLSC\njaoITmJF4PkL0uDgPFveXHEnJcLmA4GLEFPjx1WitJ/X5g==\n-----END CERTIFICATE-----\n\nSSL.com Root Certification Authority RSA\n========================================\n-----BEGIN CERTIFICATE-----\nMIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxDjAM\nBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9TU0wgQ29ycG9yYXRpb24x\nMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYw\nMjEyMTczOTM5WhcNNDEwMjEyMTczOTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMx\nEDAOBgNVBAcMB0hvdXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NM\nLmNvbSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcNAQEBBQAD\nggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2RxFdHaxh3a3by/ZPkPQ/C\nFp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aXqhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8\nP2FI7bADFB0QDksZ4LtO7IZl/zbzXmcCC52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/ge\noeOy3ZExqysdBP+lSgQ36YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkp\nk8zruFvh/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrFYD3Z\nfBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93EJNyAKoFBbZQ+yODJ\ngUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVcUS4cK38acijnALXRdMbX5J+tB5O2\nUzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi8\n1xtZPCvM8hnIk2snYxnP/Okm+Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4s\nbE6x/c+cCbqiM+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV\nHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4GA1UdDwEB/wQE\nAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGVcpNxJK1ok1iOMq8bs3AD/CUr\ndIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBcHadm47GUBwwyOabqG7B52B2ccETjit3E+ZUf\nijhDPwGFpUenPUayvOUiaPd7nNgsPgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAsl\nu1OJD7OAUN5F7kR/q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjq\nerQ0cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jra6x+3uxj\nMxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90IH37hVZkLId6Tngr75qNJ\nvTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/YK9f1JmzJBjSWFupwWRoyeXkLtoh/D1JI\nPb9s2KJELtFOt3JY04kTlf5Eq/jXixtunLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406y\nwKBjYZC6VWg3dGq2ktufoYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NI\nWuuA8ShYIc2wBlX7Jz9TkHCpBB5XJ7k=\n-----END CERTIFICATE-----\n\nSSL.com Root Certification Authority ECC\n========================================\n-----BEGIN CERTIFICATE-----\nMIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMCVVMxDjAMBgNV\nBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9TU0wgQ29ycG9yYXRpb24xMTAv\nBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEy\nMTgxNDAzWhcNNDEwMjEyMTgxNDAzWjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAO\nBgNVBAcMB0hvdXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv\nbSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuBBAAiA2IA\nBEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI7Z4INcgn64mMU1jrYor+\n8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPgCemB+vNH06NjMGEwHQYDVR0OBBYEFILR\nhXMw5zUE044CkvvlpNHEIejNMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTT\njgKS++Wk0cQh6M0wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCW\ne+0F+S8Tkdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+gA0z\n5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl\n-----END CERTIFICATE-----\n\nSSL.com EV Root Certification Authority RSA R2\n==============================================\n-----BEGIN CERTIFICATE-----\nMIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNVBAYTAlVTMQ4w\nDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9u\nMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy\nMB4XDTE3MDUzMTE4MTQzN1oXDTQyMDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQI\nDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYD\nVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMIICIjAN\nBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvqM0fNTPl9fb69LT3w23jh\nhqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssufOePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7w\ncXHswxzpY6IXFJ3vG2fThVUCAtZJycxa4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTO\nZw+oz12WGQvE43LrrdF9HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+\nB6KjBSYRaZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcAb9Zh\nCBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQGp8hLH94t2S42Oim\n9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQVPWKchjgGAGYS5Fl2WlPAApiiECto\nRHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMOpgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+Slm\nJuwgUHfbSguPvuUCYHBBXtSuUDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48\n+qvWBkofZ6aYMBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV\nHSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa49QaAJadz20Zp\nqJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBWs47LCp1Jjr+kxJG7ZhcFUZh1\n++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nx\nY/hoLVUE0fKNsKTPvDxeH3jnpaAgcLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2G\nguDKBAdRUNf/ktUM79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDz\nOFSz/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXtll9ldDz7\nCTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEmKf7GUmG6sXP/wwyc5Wxq\nlD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKKQbNmC1r7fSOl8hqw/96bg5Qu0T/fkreR\nrwU7ZcegbLHNYhLDkBvjJc40vG93drEQw/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1\nhlMYegouCRw2n5H9gooiS9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX\n9hwJ1C07mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w==\n-----END CERTIFICATE-----\n\nSSL.com EV Root Certification Authority ECC\n===========================================\n-----BEGIN CERTIFICATE-----\nMIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMCVVMxDjAMBgNV\nBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9TU0wgQ29ycG9yYXRpb24xNDAy\nBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYw\nMjEyMTgxNTIzWhcNNDEwMjEyMTgxNTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMx\nEDAOBgNVBAcMB0hvdXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NM\nLmNvbSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB\nBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMAVIbc/R/fALhBYlzccBYy\n3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1KthkuWnBaBu2+8KGwytAJKaNjMGEwHQYDVR0O\nBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZPMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe\n5d7SgarNqC1kUbbZcpuX5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJ\nN+vp1RPZytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZgh5Mm\nm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg==\n-----END CERTIFICATE-----\n\nGlobalSign Root CA - R6\n=======================\n-----BEGIN CERTIFICATE-----\nMIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEgMB4GA1UECxMX\nR2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkds\nb2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQxMjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9i\nYWxTaWduIFJvb3QgQ0EgLSBSNjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFs\nU2lnbjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQss\ngrRIxutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1kZguSgMpE\n3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxDaNc9PIrFsmbVkJq3MQbF\nvuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJwLnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqM\nPKq0pPbzlUoSB239jLKJz9CgYXfIWHSw1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+\nazayOeSsJDa38O+2HBNXk7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05O\nWgtH8wY2SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/hbguy\nCLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4nWUx2OVvq+aWh2IMP\n0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpYrZxCRXluDocZXFSxZba/jJvcE+kN\nb7gu3GduyYsRtYQUigAZcIN5kZeR1BonvzceMgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQE\nAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNV\nHSMEGDAWgBSubAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN\nnsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGtIxg93eFyRJa0\nlV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr6155wsTLxDKZmOMNOsIeDjHfrY\nBzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLjvUYAGm0CuiVdjaExUd1URhxN25mW7xocBFym\nFe944Hn+Xds+qkxV/ZoVqW/hpvvfcDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr\n3TsTjxKM4kEaSHpzoHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB1\n0jZpnOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfspA9MRf/T\nuTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+vJJUEeKgDu+6B5dpffItK\noZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+t\nJDfLRVpOoERIyNiwmcUVhAn21klJwGW45hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA=\n-----END CERTIFICATE-----\n\nOISTE WISeKey Global Root GC CA\n===============================\n-----BEGIN CERTIFICATE-----\nMIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQswCQYDVQQGEwJD\nSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNlZDEo\nMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRa\nFw00MjA1MDkwOTU4MzNaMG0xCzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQL\nExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh\nbCBSb290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4nieUqjFqdr\nVCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4Wp2OQ0jnUsYd4XxiWD1Ab\nNTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd\nBgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7TrYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0E\nAwMDaAAwZQIwJsdpW9zV57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtk\nAjEA2zQgMgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9\n-----END CERTIFICATE-----\n\nGTS Root R1\n===========\n-----BEGIN CERTIFICATE-----\nMIIFWjCCA0KgAwIBAgIQbkepxUtHDA3sM9CJuRz04TANBgkqhkiG9w0BAQwFADBHMQswCQYDVQQG\nEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJv\nb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAG\nA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIi\nMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx\n9vaMf/vo27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7wCl7r\naKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjwTcLCeoiKu7rPWRnW\nr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0PfyblqAj+lug8aJRT7oM6iCsVlgmy4HqM\nLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaHszVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly\n4cpk9+aCEI3oncKKiPo4Zor8Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr\n06zqkUspzBmkMiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92\nwO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70paDPvOmbsB4om\n3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrNVjzRlwW5y0vtOUucxD/SVRNu\nJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD\nVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEM\nBQADggIBADiWCu49tJYeX++dnAsznyvgyv3SjgofQXSlfKqE1OXyHuY3UjKcC9FhHb8owbZEKTV1\nd5iyfNm9dKyKaOOpMQkpAWBz40d8U6iQSifvS9efk+eCNs6aaAyC58/UEBZvXw6ZXPYfcX3v73sv\nfuo21pdwCxXu11xWajOl40k4DLh9+42FpLFZXvRq4d2h9mREruZRgyFmxhE+885H7pwoHyXa/6xm\nld01D1zvICxi/ZG6qcz8WpyTgYMpl0p8WnK0OdC3d8t5/Wk6kjftbjhlRn7pYL15iJdfOBL07q9b\ngsiG1eGZbYwE8na6SfZu6W0eX6DvJ4J2QPim01hcDyxC2kLGe4g0x8HYRZvBPsVhHdljUEn2NIVq\n4BjFbkerQUIpm/ZgDdIx02OYI5NaAIFItO/Nis3Jz5nu2Z6qNuFoS3FJFDYoOj0dzpqPJeaAcWEr\ntXvM+SUWgeExX6GjfhaknBZqlxi9dnKlC54dNuYvoS++cJEPqOba+MSSQGwlfnuzCdyyF62ARPBo\npY+Udf90WuioAnwMCeKpSwughQtiue+hMZL77/ZRBIls6Kl0obsXs7X9SQ98POyDGCBDTtWTurQ0\nsR8WNh8M5mQ5Fkzc4P4dyKliPUDqysU0ArSuiYgzNdwsE3PYJ/HQcu51OyLemGhmW/HGY0dVHLql\nCFF1pkgl\n-----END CERTIFICATE-----\n\nGTS Root R2\n===========\n-----BEGIN CERTIFICATE-----\nMIIFWjCCA0KgAwIBAgIQbkepxlqz5yDFMJo/aFLybzANBgkqhkiG9w0BAQwFADBHMQswCQYDVQQG\nEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJv\nb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAG\nA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIi\nMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTuk\nk3LvCvptnfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3KgGjSY6Dlo\n7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9BuXvAuMC6C/Pq8tBcKSOWI\nm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOdre7kRXuJVfeKH2JShBKzwkCX44ofR5Gm\ndFrS+LFjKBC4swm4VndAoiaYecb+3yXuPuWgf9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbu\nak7MkogwTZq9TwtImoS1mKPV+3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscsz\ncTJGr61K8YzodDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqjx5RW\nIr9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsRnTKaG73Vululycsl\naVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0kzCqgc7dGtxRcw1PcOnlthYhGXmy\n5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9OktwIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD\nVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEM\nBQADggIBALZp8KZ3/p7uC4Gt4cCpx/k1HUCCq+YEtN/L9x0Pg/B+E02NjO7jMyLDOfxA325BS0JT\nvhaI8dI4XsRomRyYUpOM52jtG2pzegVATX9lO9ZY8c6DR2Dj/5epnGB3GFW1fgiTz9D2PGcDFWEJ\n+YF59exTpJ/JjwGLc8R3dtyDovUMSRqodt6Sm2T4syzFJ9MHwAiApJiS4wGWAqoC7o87xdFtCjMw\nc3i5T1QWvwsHoaRc5svJXISPD+AVdyx+Jn7axEvbpxZ3B7DNdehyQtaVhJ2Gg/LkkM0JR9SLA3Da\nWsYDQvTtN6LwG1BUSw7YhN4ZKJmBR64JGz9I0cNv4rBgF/XuIwKl2gBbbZCr7qLpGzvpx0QnRY5r\nn/WkhLx3+WuXrD5RRaIRpsyF7gpo8j5QOHokYh4XIDdtak23CZvJ/KRY9bb7nE4Yu5UC56Gtmwfu\nNmsk0jmGwZODUNKBRqhfYlcsu2xkiAhu7xNUX90txGdj08+JN7+dIPT7eoOboB6BAFDC5AwiWVIQ\n7UNWhwD4FFKnHYuTjKJNRn8nxnGbJN7k2oaLDX5rIMHAnuFl2GqjpuiFizoHCBy69Y9Vmhh1fuXs\ngWbRIXOhNUQLgD1bnF5vKheW0YMjiGZt5obicDIvUiLnyOd/xCxgXS/Dr55FBcOEArf9LAhST4Ld\no/DUhgkC\n-----END CERTIFICATE-----\n\nGTS Root R3\n===========\n-----BEGIN CERTIFICATE-----\nMIICDDCCAZGgAwIBAgIQbkepx2ypcyRAiQ8DVd2NHTAKBggqhkjOPQQDAzBHMQswCQYDVQQGEwJV\nUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3Qg\nUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UE\nChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcq\nhkjOPQIBBgUrgQQAIgNiAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUU\nRout736GjOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2ADDL24Cej\nQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTB8Sa6oC2uhYHP\n0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEAgFukfCPAlaUs3L6JbyO5o91lAFJekazInXJ0\nglMLfalAvWhgxeG4VDvBNhcl2MG9AjEAnjWSdIUlUfUk7GRSJFClH9voy8l27OyCbvWFGFPouOOa\nKaqW04MjyaR7YbPMAuhd\n-----END CERTIFICATE-----\n\nGTS Root R4\n===========\n-----BEGIN CERTIFICATE-----\nMIICCjCCAZGgAwIBAgIQbkepyIuUtui7OyrYorLBmTAKBggqhkjOPQQDAzBHMQswCQYDVQQGEwJV\nUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3Qg\nUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UE\nChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcq\nhkjOPQIBBgUrgQQAIgNiAATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa\n6zzuhXyiQHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/lxKvRHYqj\nQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSATNbrdP9JNqPV\n2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNnADBkAjBqUFJ0CMRw3J5QdCHojXohw0+WbhXRIjVhLfoI\nN+4Zba3bssx9BzT1YBkstTTZbyACMANxsbqjYAuG7ZoIapVon+Kz4ZNkfF6Tpt95LY2F45TPI11x\nzPKwTdb+mciUqXWi4w==\n-----END CERTIFICATE-----\n\nUCA Global G2 Root\n==================\n-----BEGIN CERTIFICATE-----\nMIIFRjCCAy6gAwIBAgIQXd+x2lqj7V2+WmUgZQOQ7zANBgkqhkiG9w0BAQsFADA9MQswCQYDVQQG\nEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxGzAZBgNVBAMMElVDQSBHbG9iYWwgRzIgUm9vdDAeFw0x\nNjAzMTEwMDAwMDBaFw00MDEyMzEwMDAwMDBaMD0xCzAJBgNVBAYTAkNOMREwDwYDVQQKDAhVbmlU\ncnVzdDEbMBkGA1UEAwwSVUNBIEdsb2JhbCBHMiBSb290MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A\nMIICCgKCAgEAxeYrb3zvJgUno4Ek2m/LAfmZmqkywiKHYUGRO8vDaBsGxUypK8FnFyIdK+35KYmT\noni9kmugow2ifsqTs6bRjDXVdfkX9s9FxeV67HeToI8jrg4aA3++1NDtLnurRiNb/yzmVHqUwCoV\n8MmNsHo7JOHXaOIxPAYzRrZUEaalLyJUKlgNAQLx+hVRZ2zA+te2G3/RVogvGjqNO7uCEeBHANBS\nh6v7hn4PJGtAnTRnvI3HLYZveT6OqTwXS3+wmeOwcWDcC/Vkw85DvG1xudLeJ1uK6NjGruFZfc8o\nLTW4lVYa8bJYS7cSN8h8s+1LgOGN+jIjtm+3SJUIsUROhYw6AlQgL9+/V087OpAh18EmNVQg7Mc/\nR+zvWr9LesGtOxdQXGLYD0tK3Cv6brxzks3sx1DoQZbXqX5t2Okdj4q1uViSukqSKwxW/YDrCPBe\nKW4bHAyvj5OJrdu9o54hyokZ7N+1wxrrFv54NkzWbtA+FxyQF2smuvt6L78RHBgOLXMDj6DlNaBa\n4kx1HXHhOThTeEDMg5PXCp6dW4+K5OXgSORIskfNTip1KnvyIvbJvgmRlld6iIis7nCs+dwp4wwc\nOxJORNanTrAmyPPZGpeRaOrvjUYG0lZFWJo8DA+DuAUlwznPO6Q0ibd5Ei9Hxeepl2n8pndntd97\n8XplFeRhVmUCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O\nBBYEFIHEjMz15DD/pQwIX4wVZyF0Ad/fMA0GCSqGSIb3DQEBCwUAA4ICAQATZSL1jiutROTL/7lo\n5sOASD0Ee/ojL3rtNtqyzm325p7lX1iPyzcyochltq44PTUbPrw7tgTQvPlJ9Zv3hcU2tsu8+Mg5\n1eRfB70VVJd0ysrtT7q6ZHafgbiERUlMjW+i67HM0cOU2kTC5uLqGOiiHycFutfl1qnN3e92mI0A\nDs0b+gO3joBYDic/UvuUospeZcnWhNq5NXHzJsBPd+aBJ9J3O5oUb3n09tDh05S60FdRvScFDcH9\nyBIw7m+NESsIndTUv4BFFJqIRNow6rSn4+7vW4LVPtateJLbXDzz2K36uGt/xDYotgIVilQsnLAX\nc47QN6MUPJiVAAwpBVueSUmxX8fjy88nZY41F7dXyDDZQVu5FLbowg+UMaeUmMxq67XhJ/UQqAHo\njhJi6IjMtX9Gl8CbEGY4GjZGXyJoPd/JxhMnq1MGrKI8hgZlb7F+sSlEmqO6SWkoaY/X5V+tBIZk\nbxqgDMUIYs6Ao9Dz7GjevjPHF1t/gMRMTLGmhIrDO7gJzRSBuhjjVFc2/tsvfEehOjPI+Vg7RE+x\nygKJBJYoaMVLuCaJu9YzL1DV/pqJuhgyklTGW+Cd+V7lDSKb9triyCGyYiGqhkCyLmTTX8jjfhFn\nRR8F/uOi77Oos/N9j/gMHyIfLXC0uAE0djAA5SN4p1bXUB+K+wb1whnw0A==\n-----END CERTIFICATE-----\n\nUCA Extended Validation Root\n============================\n-----BEGIN CERTIFICATE-----\nMIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBHMQswCQYDVQQG\nEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9u\nIFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMxMDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8G\nA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIi\nMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrs\niWogD4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvSsPGP2KxF\nRv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aopO2z6+I9tTcg1367r3CTu\neUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dksHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR\n59mzLC52LqGj3n5qiAno8geK+LLNEOfic0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH\n0mK1lTnj8/FtDw5lhIpjVMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KR\nel7sFsLzKuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/TuDv\nB0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41Gsx2VYVdWf6/wFlth\nWG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs1+lvK9JKBZP8nm9rZ/+I8U6laUpS\nNwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQDfwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS\n3H5aBZ8eNJr34RQwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQEL\nBQADggIBADaNl8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR\nap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQVBcZEhrxH9cM\naVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5c6sq1WnIeJEmMX3ixzDx/BR4\ndxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb\n+7lsq+KePRXBOy5nAliRn+/4Qh8st2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOW\nF3sGPjLtx7dCvHaj2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwi\nGpWOvpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2CxR9GUeOc\nGMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmxcmtpzyKEC2IPrNkZAJSi\ndjzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbMfjKaiJUINlK73nZfdklJrX+9ZSCyycEr\ndhh2n1ax\n-----END CERTIFICATE-----\n\nCertigna Root CA\n================\n-----BEGIN CERTIFICATE-----\nMIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAwWjELMAkGA1UE\nBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAwMiA0ODE0NjMwODEwMDAzNjEZ\nMBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0xMzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjda\nMFoxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYz\nMDgxMDAwMzYxGTAXBgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4IC\nDwAwggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sOty3tRQgX\nstmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9MCiBtnyN6tMbaLOQdLNyz\nKNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPuI9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8\nJXrJhFwLrN1CTivngqIkicuQstDuI7pmTLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16\nXdG+RCYyKfHx9WzMfgIhC59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq\n4NYKpkDfePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3YzIoej\nwpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWTCo/1VTp2lc5ZmIoJ\nlXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1kJWumIWmbat10TWuXekG9qxf5kBdI\njzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp/\n/TBt2dzhauH8XwIDAQABo4IBGjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw\nHQYDVR0OBBYEFBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of\n1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczovL3d3d3cuY2Vy\ndGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilodHRwOi8vY3JsLmNlcnRpZ25h\nLmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYraHR0cDovL2NybC5kaGlteW90aXMuY29tL2Nl\ncnRpZ25hcm9vdGNhLmNybDANBgkqhkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOIt\nOoldaDgvUSILSo3L6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxP\nTGRGHVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH60BGM+RFq\n7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncBlA2c5uk5jR+mUYyZDDl3\n4bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdio2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd\n8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS\n6Cvu5zHbugRqh5jnxV/vfaci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaY\ntlu3zM63Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayhjWZS\naX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw3kAP+HwV96LOPNde\nE4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0=\n-----END CERTIFICATE-----\n\nemSign Root CA - G1\n===================\n-----BEGIN CERTIFICATE-----\nMIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYDVQQGEwJJTjET\nMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9sb2dpZXMgTGltaXRl\nZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBHMTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgx\nODMwMDBaMGcxCzAJBgNVBAYTAklOMRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVk\naHJhIFRlY2hub2xvZ2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIB\nIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQzf2N4aLTN\nLnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO8oG0x5ZOrRkVUkr+PHB1\ncM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aqd7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHW\nDV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhMtTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ\n6DqS0hdW5TUaQBw+jSztOd9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrH\nhQIDAQABo0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQDAgEG\nMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31xPaOfG1vR2vjTnGs2\nvZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjMwiI/aTvFthUvozXGaCocV685743Q\nNcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6dGNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q\n+Mri/Tm3R7nrft8EI6/6nAYH6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeih\nU80Bv2noWgbyRQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx\niN66zB+Afko=\n-----END CERTIFICATE-----\n\nemSign ECC Root CA - G3\n=======================\n-----BEGIN CERTIFICATE-----\nMIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQGEwJJTjETMBEG\nA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9sb2dpZXMgTGltaXRlZDEg\nMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4\nMTgzMDAwWjBrMQswCQYDVQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11\nZGhyYSBUZWNobm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g\nRzMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0WXTsuwYc\n58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xySfvalY8L1X44uT6EYGQIr\nMgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuBzhccLikenEhjQjAOBgNVHQ8BAf8EBAMC\nAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+D\nCBeQyh+KTOgNG3qxrdWBCUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7\njHvrZQnD+JbNR6iC8hZVdyR+EhCVBCyj\n-----END CERTIFICATE-----\n\nemSign Root CA - C1\n===================\n-----BEGIN CERTIFICATE-----\nMIIDczCCAlugAwIBAgILAK7PALrEzzL4Q7IwDQYJKoZIhvcNAQELBQAwVjELMAkGA1UEBhMCVVMx\nEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQDExNlbVNp\nZ24gUm9vdCBDQSAtIEMxMB4XDTE4MDIxODE4MzAwMFoXDTQzMDIxODE4MzAwMFowVjELMAkGA1UE\nBhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQD\nExNlbVNpZ24gUm9vdCBDQSAtIEMxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz+up\nufGZBczYKCFK83M0UYRWEPWgTywS4/oTmifQz/l5GnRfHXk5/Fv4cI7gklL35CX5VIPZHdPIWoU/\nXse2B+4+wM6ar6xWQio5JXDWv7V7Nq2s9nPczdcdioOl+yuQFTdrHCZH3DspVpNqs8FqOp099cGX\nOFgFixwR4+S0uF2FHYP+eF8LRWgYSKVGczQ7/g/IdrvHGPMF0Ybzhe3nudkyrVWIzqa2kbBPrH4V\nI5b2P/AgNBbeCsbEBEV5f6f9vtKppa+cxSMq9zwhbL2vj07FOrLzNBL834AaSaTUqZX3noleooms\nlMuoaJuvimUnzYnu3Yy1aylwQ6BpC+S5DwIDAQABo0IwQDAdBgNVHQ4EFgQU/qHgcB4qAzlSWkK+\nXJGFehiqTbUwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQAD\nggEBAMJKVvoVIXsoounlHfv4LcQ5lkFMOycsxGwYFYDGrK9HWS8mC+M2sO87/kOXSTKZEhVb3xEp\n/6tT+LvBeA+snFOvV71ojD1pM/CjoCNjO2RnIkSt1XHLVip4kqNPEjE2NuLe/gDEo2APJ62gsIq1\nNnpSob0n9CAnYuhNlCQT5AoE6TyrLshDCUrGYQTlSTR+08TI9Q/Aqum6VF7zYytPT1DU/rl7mYw9\nwC68AivTxEDkigcxHpvOJpkT+xHqmiIMERnHXhuBUDDIlhJu58tBf5E7oke3VIAb3ADMmpDqw8NQ\nBmIMMMAVSKeoWXzhriKi4gp6D/piq1JM4fHfyr6DDUI=\n-----END CERTIFICATE-----\n\nemSign ECC Root CA - C3\n=======================\n-----BEGIN CERTIFICATE-----\nMIICKzCCAbGgAwIBAgIKe3G2gla4EnycqDAKBggqhkjOPQQDAzBaMQswCQYDVQQGEwJVUzETMBEG\nA1UECxMKZW1TaWduIFBLSTEUMBIGA1UEChMLZU11ZGhyYSBJbmMxIDAeBgNVBAMTF2VtU2lnbiBF\nQ0MgUm9vdCBDQSAtIEMzMB4XDTE4MDIxODE4MzAwMFoXDTQzMDIxODE4MzAwMFowWjELMAkGA1UE\nBhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMSAwHgYDVQQD\nExdlbVNpZ24gRUNDIFJvb3QgQ0EgLSBDMzB2MBAGByqGSM49AgEGBSuBBAAiA2IABP2lYa57JhAd\n6bciMK4G9IGzsUJxlTm801Ljr6/58pc1kjZGDoeVjbk5Wum739D+yAdBPLtVb4OjavtisIGJAnB9\nSMVK4+kiVCJNk7tCDK93nCOmfddhEc5lx/h//vXyqaNCMEAwHQYDVR0OBBYEFPtaSNCAIEDyqOkA\nB2kZd6fmw/TPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMDA2gA\nMGUCMQC02C8Cif22TGK6Q04ThHK1rt0c3ta13FaPWEBaLd4gTCKDypOofu4SQMfWh0/434UCMBwU\nZOR8loMRnLDRWmFLpg9J0wD8ofzkpf9/rdcw0Md3f76BB1UwUCAU9Vc4CqgxUQ==\n-----END CERTIFICATE-----\n\nHongkong Post Root CA 3\n=======================\n-----BEGIN CERTIFICATE-----\nMIIFzzCCA7egAwIBAgIUCBZfikyl7ADJk0DfxMauI7gcWqQwDQYJKoZIhvcNAQELBQAwbzELMAkG\nA1UEBhMCSEsxEjAQBgNVBAgTCUhvbmcgS29uZzESMBAGA1UEBxMJSG9uZyBLb25nMRYwFAYDVQQK\nEw1Ib25na29uZyBQb3N0MSAwHgYDVQQDExdIb25na29uZyBQb3N0IFJvb3QgQ0EgMzAeFw0xNzA2\nMDMwMjI5NDZaFw00MjA2MDMwMjI5NDZaMG8xCzAJBgNVBAYTAkhLMRIwEAYDVQQIEwlIb25nIEtv\nbmcxEjAQBgNVBAcTCUhvbmcgS29uZzEWMBQGA1UEChMNSG9uZ2tvbmcgUG9zdDEgMB4GA1UEAxMX\nSG9uZ2tvbmcgUG9zdCBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCz\niNfqzg8gTr7m1gNt7ln8wlffKWihgw4+aMdoWJwcYEuJQwy51BWy7sFOdem1p+/l6TWZ5Mwc50tf\njTMwIDNT2aa71T4Tjukfh0mtUC1Qyhi+AViiE3CWu4mIVoBc+L0sPOFMV4i707mV78vH9toxdCim\n5lSJ9UExyuUmGs2C4HDaOym71QP1mbpV9WTRYA6ziUm4ii8F0oRFKHyPaFASePwLtVPLwpgchKOe\nsL4jpNrcyCse2m5FHomY2vkALgbpDDtw1VAliJnLzXNg99X/NWfFobxeq81KuEXryGgeDQ0URhLj\n0mRiikKYvLTGCAj4/ahMZJx2Ab0vqWwzD9g/KLg8aQFChn5pwckGyuV6RmXpwtZQQS4/t+TtbNe/\nJgERohYpSms0BpDsE9K2+2p20jzt8NYt3eEV7KObLyzJPivkaTv/ciWxNoZbx39ri1UbSsUgYT2u\ny1DhCDq+sI9jQVMwCFk8mB13umOResoQUGC/8Ne8lYePl8X+l2oBlKN8W4UdKjk60FSh0Tlxnf0h\n+bV78OLgAo9uliQlLKAeLKjEiafv7ZkGL7YKTE/bosw3Gq9HhS2KX8Q0NEwA/RiTZxPRN+ZItIsG\nxVd7GYYKecsAyVKvQv83j+GjHno9UKtjBucVtT+2RTeUN7F+8kjDf8V1/peNRY8apxpyKBpADwID\nAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQXnc0e\ni9Y5K3DTXNSguB+wAPzFYTAdBgNVHQ4EFgQUF53NHovWOStw01zUoLgfsAD8xWEwDQYJKoZIhvcN\nAQELBQADggIBAFbVe27mIgHSQpsY1Q7XZiNc4/6gx5LS6ZStS6LG7BJ8dNVI0lkUmcDrudHr9Egw\nW62nV3OZqdPlt9EuWSRY3GguLmLYauRwCy0gUCCkMpXRAJi70/33MvJJrsZ64Ee+bs7Lo3I6LWld\ny8joRTnU+kLBEUx3XZL7av9YROXrgZ6voJmtvqkBZss4HTzfQx/0TW60uhdG/H39h4F5ag0zD/ov\n+BS5gLNdTaqX4fnkGMX41TiMJjz98iji7lpJiCzfeT2OnpA8vUFKOt1b9pq0zj8lMH8yfaIDlNDc\neqFS3m6TjRgm/VWsvY+b0s+v54Ysyx8Jb6NvqYTUc79NoXQbTiNg8swOqn+knEwlqLJmOzj/2ZQw\n9nKEvmhVEA/GcywWaZMH/rFF7buiVWqw2rVKAiUnhde3t4ZEFolsgCs+l6mc1X5VTMbeRRAc6uk7\nnwNT7u56AQIWeNTowr5GdogTPyK7SBIdUgC0An4hGh6cJfTzPV4e0hz5sy229zdcxsshTrD3mUcY\nhcErulWuBurQB7Lcq9CClnXO0lD+mefPL5/ndtFhKvshuzHQqp9HpLIiyhY6UFfEW0NnxWViA0kB\n60PZ2Pierc+xYw5F9KBaLJstxabArahH9CdMOA0uG0k7UvToiIMrVCjU8jVStDKDYmlkDJGcn5fq\ndBb9HxEGmpv0\n-----END CERTIFICATE-----\n\nEntrust Root Certification Authority - G4\n=========================================\n-----BEGIN CERTIFICATE-----\nMIIGSzCCBDOgAwIBAgIRANm1Q3+vqTkPAAAAAFVlrVgwDQYJKoZIhvcNAQELBQAwgb4xCzAJBgNV\nBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3Qu\nbmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1\ndGhvcml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1\ndGhvcml0eSAtIEc0MB4XDTE1MDUyNzExMTExNloXDTM3MTIyNzExNDExNlowgb4xCzAJBgNVBAYT\nAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0\nL2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhv\ncml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhv\ncml0eSAtIEc0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsewsQu7i0TD/pZJH4i3D\numSXbcr3DbVZwbPLqGgZ2K+EbTBwXX7zLtJTmeH+H17ZSK9dE43b/2MzTdMAArzE+NEGCJR5WIoV\n3imz/f3ET+iq4qA7ec2/a0My3dl0ELn39GjUu9CH1apLiipvKgS1sqbHoHrmSKvS0VnM1n4j5pds\n8ELl3FFLFUHtSUrJ3hCX1nbB76W1NhSXNdh4IjVS70O92yfbYVaCNNzLiGAMC1rlLAHGVK/XqsEQ\ne9IFWrhAnoanw5CGAlZSCXqc0ieCU0plUmr1POeo8pyvi73TDtTUXm6Hnmo9RR3RXRv06QqsYJn7\nibT/mCzPfB3pAqoEmh643IhuJbNsZvc8kPNXwbMv9W3y+8qh+CmdRouzavbmZwe+LGcKKh9asj5X\nxNMhIWNlUpEbsZmOeX7m640A2Vqq6nPopIICR5b+W45UYaPrL0swsIsjdXJ8ITzI9vF01Bx7owVV\n7rtNOzK+mndmnqxpkCIHH2E6lr7lmk/MBTwoWdPBDFSoWWG9yHJM6Nyfh3+9nEg2XpWjDrk4JFX8\ndWbrAuMINClKxuMrLzOg2qOGpRKX/YAr2hRC45K9PvJdXmd0LhyIRyk0X+IyqJwlN4y6mACXi0mW\nHv0liqzc2thddG5msP9E36EYxr5ILzeUePiVSj9/E15dWf10hkNjc0kCAwEAAaNCMEAwDwYDVR0T\nAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJ84xFYjwznooHFs6FRM5Og6sb9n\nMA0GCSqGSIb3DQEBCwUAA4ICAQAS5UKme4sPDORGpbZgQIeMJX6tuGguW8ZAdjwD+MlZ9POrYs4Q\njbRaZIxowLByQzTSGwv2LFPSypBLhmb8qoMi9IsabyZIrHZ3CL/FmFz0Jomee8O5ZDIBf9PD3Vht\n7LGrhFV0d4QEJ1JrhkzO3bll/9bGXp+aEJlLdWr+aumXIOTkdnrG0CSqkM0gkLpHZPt/B7NTeLUK\nYvJzQ85BK4FqLoUWlFPUa19yIqtRLULVAJyZv967lDtX/Zr1hstWO1uIAeV8KEsD+UmDfLJ/fOPt\njqF/YFOOVZ1QNBIPt5d7bIdKROf1beyAN/BYGW5KaHbwH5Lk6rWS02FREAutp9lfx1/cH6NcjKF+\nm7ee01ZvZl4HliDtC3T7Zk6LERXpgUl+b7DUUH8i119lAg2m9IUe2K4GS0qn0jFmwvjO5QimpAKW\nRGhXxNUzzxkvFMSUHHuk2fCfDrGA4tGeEWSpiBE6doLlYsKA2KSD7ZPvfC+QsDJMlhVoSFLUmQjA\nJOgc47OlIQ6SwJAfzyBfyjs4x7dtOvPmRLgOMWuIjnDrnBdSqEGULoe256YSxXXfW8AKbnuk5F6G\n+TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh7DE9ZapD8j3fcEThuk0mEDuYn/PIjhs4ViFqUZPT\nkcpG2om3PVODLAgfi49T3f+sHw==\n-----END CERTIFICATE-----\n\nMicrosoft ECC Root Certificate Authority 2017\n=============================================\n-----BEGIN CERTIFICATE-----\nMIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQswCQYDVQQGEwJV\nUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNyb3NvZnQgRUND\nIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwHhcNMTkxMjE4MjMwNjQ1WhcNNDIwNzE4\nMjMxNjA0WjBlMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw\nNAYDVQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwdjAQ\nBgcqhkjOPQIBBgUrgQQAIgNiAATUvD0CQnVBEyPNgASGAlEvaqiBYgtlzPbKnR5vSmZRogPZnZH6\nthaxjG7efM3beaYvzrvOcS/lpaso7GMEZpn4+vKTEAXhgShC48Zo9OYbhGBKia/teQ87zvH2RPUB\neMCjVDBSMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTIy5lycFIM\n+Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlf\nXu5gKcs68tvWMoQZP3zVL8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaR\neNtUjGUBiudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M=\n-----END CERTIFICATE-----\n\nMicrosoft RSA Root Certificate Authority 2017\n=============================================\n-----BEGIN CERTIFICATE-----\nMIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBlMQswCQYDVQQG\nEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNyb3NvZnQg\nUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIw\nNzE4MjMwMDIzWjBlMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9u\nMTYwNAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcw\nggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZNt9GkMml\n7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0ZdDMbRnMlfl7rEqUrQ7e\nS0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1HLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw7\n1VdyvD/IybLeS2v4I2wDwAW9lcfNcztmgGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+\ndkC0zVJhUXAoP8XFWvLJjEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49F\nyGcohJUcaDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaGYaRS\nMLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6W6IYZVcSn2i51BVr\nlMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4KUGsTuqwPN1q3ErWQgR5WrlcihtnJ\n0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH+FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJ\nClTUFLkqqNfs+avNJVgyeY+QW5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYw\nDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC\nNxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZCLgLNFgVZJ8og\n6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OCgMNPOsduET/m4xaRhPtthH80\ndK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6tZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk\n+ONVFT24bcMKpBLBaYVu32TxU5nhSnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex\n/2kskZGT4d9Mozd2TaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDy\nAmH3pvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGRxpl/j8nW\nZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiAppGWSZI1b7rCoucL5mxAyE\n7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKT\nc0QWbej09+CVgI+WXTik9KveCjCHk9hNAHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D\n5KbvtwEwXlGjefVwaaZBRA+GsCyRxj3qrg+E\n-----END CERTIFICATE-----\n\ne-Szigno Root CA 2017\n=====================\n-----BEGIN CERTIFICATE-----\nMIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNVBAYTAkhVMREw\nDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRkLjEXMBUGA1UEYQwOVkFUSFUt\nMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJvb3QgQ0EgMjAxNzAeFw0xNzA4MjIxMjA3MDZa\nFw00MjA4MjIxMjA3MDZaMHExCzAJBgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UE\nCgwNTWljcm9zZWMgTHRkLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3pp\nZ25vIFJvb3QgQ0EgMjAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJbcPYrYsHtvxie+RJCx\ns1YVe45DJH0ahFnuY2iyxl6H0BVIHqiQrb1TotreOpCmYF9oMrWGQd+HWyx7xf58etqjYzBhMA8G\nA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSHERUI0arBeAyxr87GyZDv\nvzAEwDAfBgNVHSMEGDAWgBSHERUI0arBeAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEA\ntVfd14pVCzbhhkT61NlojbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxO\nsvxyqltZ+efcMQ==\n-----END CERTIFICATE-----\n\ncertSIGN Root CA G2\n===================\n-----BEGIN CERTIFICATE-----\nMIIFRzCCAy+gAwIBAgIJEQA0tk7GNi02MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNVBAYTAlJPMRQw\nEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJR04gUk9PVCBDQSBHMjAeFw0xNzAy\nMDYwOTI3MzVaFw00MjAyMDYwOTI3MzVaMEExCzAJBgNVBAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lH\nTiBTQTEcMBoGA1UECxMTY2VydFNJR04gUk9PVCBDQSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIP\nADCCAgoCggIBAMDFdRmRfUR0dIf+DjuW3NgBFszuY5HnC2/OOwppGnzC46+CjobXXo9X69MhWf05\nN0IwvlDqtg+piNguLWkh59E3GE59kdUWX2tbAMI5Qw02hVK5U2UPHULlj88F0+7cDBrZuIt4Imfk\nabBoxTzkbFpG583H+u/E7Eu9aqSs/cwoUe+StCmrqzWaTOTECMYmzPhpn+Sc8CnTXPnGFiWeI8Mg\nwT0PPzhAsP6CRDiqWhqKa2NYOLQV07YRaXseVO6MGiKscpc/I1mbySKEwQdPzH/iV8oScLumZfNp\ndWO9lfsbl83kqK/20U6o2YpxJM02PbyWxPFsqa7lzw1uKA2wDrXKUXt4FMMgL3/7FFXhEZn91Qqh\nngLjYl/rNUssuHLoPj1PrCy7Lobio3aP5ZMqz6WryFyNSwb/EkaseMsUBzXgqd+L6a8VTxaJW732\njcZZroiFDsGJ6x9nxUWO/203Nit4ZoORUSs9/1F3dmKh7Gc+PoGD4FapUB8fepmrY7+EF3fxDTvf\n95xhszWYijqy7DwaNz9+j5LP2RIUZNoQAhVB/0/E6xyjyfqZ90bp4RjZsbgyLcsUDFDYg2WD7rlc\nz8sFWkz6GZdr1l0T08JcVLwyc6B49fFtHsufpaafItzRUZ6CeWRgKRM+o/1Pcmqr4tTluCRVLERL\niohEnMqE0yo7AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1Ud\nDgQWBBSCIS1mxteg4BXrzkwJd8RgnlRuAzANBgkqhkiG9w0BAQsFAAOCAgEAYN4auOfyYILVAzOB\nywaK8SJJ6ejqkX/GM15oGQOGO0MBzwdw5AgeZYWR5hEit/UCI46uuR59H35s5r0l1ZUa8gWmr4UC\nb6741jH/JclKyMeKqdmfS0mbEVeZkkMR3rYzpMzXjWR91M08KCy0mpbqTfXERMQlqiCA2ClV9+BB\n/AYm/7k29UMUA2Z44RGx2iBfRgB4ACGlHgAoYXhvqAEBj500mv/0OJD7uNGzcgbJceaBxXntC6Z5\n8hMLnPddDnskk7RI24Zf3lCGeOdA5jGokHZwYa+cNywRtYK3qq4kNFtyDGkNzVmf9nGvnAvRCjj5\nBiKDUyUM/FHE5r7iOZULJK2v0ZXkltd0ZGtxTgI8qoXzIKNDOXZbbFD+mpwUHmUUihW9o4JFWklW\natKcsWMy5WHgUyIOpwpJ6st+H6jiYoD2EEVSmAYY3qXNL3+q1Ok+CHLsIwMCPKaq2LxndD0UF/tU\nSxfj03k9bWtJySgOLnRQvwzZRjoQhsmnP+mg7H/rpXdYaXHmgwo38oZJar55CJD2AhZkPuXaTH4M\nNMn5X7azKFGnpyuqSfqNZSlO42sTp5SjLVFteAxEy9/eCG/Oo2Sr05WE1LlSVHJ7liXMvGnjSG4N\n0MedJ5qq+BOS3R7fY581qRY27Iy4g/Q9iY/NtBde17MXQRBdJ3NghVdJIgc=\n-----END CERTIFICATE-----\n"
  },
  {
    "path": "code/default/x_tunnel/local/cloudflare_front/check_ip.py",
    "content": "#!/usr/bin/env python3\n# coding:utf-8\nimport sys\nimport os\nimport threading\nimport json\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nroot_path = os.path.abspath( os.path.join(current_path, os.pardir, os.pardir, os.pardir))\nlocal_path = os.path.abspath( os.path.join(current_path, os.pardir))\nimport env_info\ndata_path = env_info.data_path\nmodule_data_path = os.path.join(data_path, 'x_tunnel')\npython_path = root_path\n\n\nif __name__ == \"__main__\":\n    sys.path.append(root_path)\n    sys.path.append(local_path)\n\n    noarch_lib = os.path.abspath( os.path.join(python_path, 'lib', 'noarch'))\n    sys.path.append(noarch_lib)\n\n    if sys.platform == \"win32\":\n        win32_lib = os.path.abspath( os.path.join(python_path, 'lib', 'win32'))\n        sys.path.append(win32_lib)\n    elif sys.platform.startswith(\"linux\"):\n        linux_lib = os.path.abspath( os.path.join(python_path, 'lib', 'linux'))\n        sys.path.append(linux_lib)\n    elif sys.platform == \"darwin\":\n        darwin_lib = os.path.abspath( os.path.join(python_path, 'lib', 'darwin'))\n        sys.path.append(darwin_lib)\n        extra_lib = \"/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python\"\n        sys.path.append(extra_lib)\n\n\n\nimport utils\nimport xlog\nlogger = xlog.getLogger(\"cloudflare_front\")\nlogger.set_buffer(500)\n\nfrom front_base.openssl_wrap import SSLContext\nfrom front_base.connect_creator import ConnectCreator\nfrom front_base.check_ip import CheckIp\nfrom front_base.host_manager import HostManagerBase\n\nfrom cloudflare_front.config import Config\nfrom cloudflare_front import front\nfrom cloudflare_front.host_manager import HostManager\n\n\ndef check_all_domain(check_ip):\n    with open(os.path.join(current_path, \"front_domains.json\"), \"r\") as fd:\n        content = fd.read()\n        cs = json.loads(content)\n        for host in cs:\n            host = \"scan1.\" + host\n            res = check_ip.check_ip(ip, host=host, wait_time=wait_time)\n            if not res or not res.ok:\n                xlog.warn(\"host:%s fail\", host)\n            else:\n                xlog.info(\"host:%s ok\", host)\n\n\nclass CheckAllIp(object):\n    def __init__(self, check_ip, host):\n        self.check_ip = check_ip\n        self.host = host\n        self.lock = threading.Lock()\n\n        self.in_fd = open(os.path.join(current_path, \"good_ip.txt\"), \"r\")\n        self.out_fd = open(\n            os.path.join(module_data_path, \"cloudflare_checked_ip.txt\"),\n            \"w\"\n        )\n\n    def get_ip(self):\n        with self.lock:\n            while True:\n                line = self.in_fd.readline()\n                if not line:\n                    raise Exception()\n\n                try:\n                    ip_infos = line.split()\n                    ip = ip_infos[0]\n                    handshake_time = ip_infos[3]\n                    return ip, handshake_time\n                except:\n                    continue\n\n    def write_ip(self, ip, host, handshake):\n        with self.lock:\n            self.out_fd.write(\"%s %s gws %s 0 0\\n\" % (ip, host, handshake))\n            self.out_fd.flush()\n\n    def checker(self):\n        while True:\n            try:\n                ip, handshake_time = self.get_ip()\n            except Exception as e:\n                xlog.info(\"no ip left\")\n                return\n\n            try:\n                res = self.check_ip.check_ip(ip, sni=host, host=host)\n            except Exception as e:\n                xlog.warn(\"check fail:%s except:%r\", e)\n                continue\n\n            if not res or not res.ok:\n                xlog.debug(\"check fail:%s fail\", ip)\n                continue\n\n            self.write_ip(ip, res.domain, handshake_time)\n\n    def run(self):\n        for i in range(0, 10):\n            threading.Thread(target=self.checker).start()\n\n\ndef check_all_ip(check_ip):\n\n    HostManager(config, logger, default_domain_fn, domain_fn, front)\n    check = CheckAllIp(check_ip, \"scan1.half.autos\")\n    check.run()\n\n\nif __name__ == \"__main__\":\n\n    config_path = os.path.join(module_data_path, \"cloudflare_front.json\")\n    config = Config(config_path)\n    default_domain_fn = os.path.join(current_path, \"front_domains.json\")\n    domain_fn = os.path.join(module_data_path, \"cloudflare_domains.json\")\n    # format: [ip] [domain [sni] ]\n\n    # case 1: only ip\n    # case 2: ip domain\n    # case 3: ip domain sni\n    # case 4: domain\n    # case 5: domain sni\n\n    # ip = \"141.101.120.131\"\n    ip = \"2a06:98c1:3120::1\"\n    host = \"v3.half.autos\"\n    sni = host\n\n    args = list(sys.argv[1:])\n\n    if len(args):\n        if utils.check_ip_valid(args[0]):\n            ip = args.pop(0)\n\n    if len(args):\n        host = args.pop(0)\n        sni = host\n\n    if len(args):\n        sni = args.pop(0)\n\n    # print(\"Usage: check_ip.py [ip] [top_domain] [wait_time=0]\")\n    xlog.info(\"test ip:%s\", ip)\n    xlog.info(\"host:%s\", host)\n    xlog.info(\"sni:%s\", sni)\n\n    wait_time = 0\n\n    ca_certs = os.path.join(current_path, \"cacert.pem\")\n    openssl_context = SSLContext(logger, ca_certs=ca_certs)\n    host_manager = HostManagerBase()\n    connect_creator = ConnectCreator(logger, config, openssl_context, host_manager, debug=True)\n    check_ip = CheckIp(logger, config, connect_creator)\n\n    #check_all_domain(check_ip)\n    #check_all_ip(check_ip)\n\n    res = check_ip.check_ip(ip, sni=sni, host=host, wait_time=wait_time)\n    if not res:\n        xlog.warn(\"connect fail\")\n    elif res.ok:\n        xlog.info(\"success, domain:%s handshake:%d\", res.host, res.handshake_time)\n    else:\n        xlog.warn(\"not support\")\n\n    front.stop()\n    sys.exit(0)\n"
  },
  {
    "path": "code/default/x_tunnel/local/cloudflare_front/config.py",
    "content": "\nfrom front_base.config import ConfigBase\n\n\nclass Config(ConfigBase):\n    def __init__(self, fn):\n        super(Config, self).__init__(fn)\n\n        # front\n        self.set_var(\"front_continue_fail_num\", 10)\n        self.set_var(\"front_continue_fail_block\", 20 * 60)\n\n        # http_dispatcher\n        self.set_var(\"dispather_min_idle_workers\", 0)\n        self.set_var(\"dispather_work_min_idle_time\", 0)\n        self.set_var(\"dispather_work_max_score\", 1)\n        self.set_var(\"dispather_min_workers\", 1)\n        self.set_var(\"dispather_max_workers\", 1)\n        self.set_var(\"dispather_score_factor\", 1)\n\n        # http 2 worker\n        self.set_var(\"http2_status_to_close\", [302, 400, 403, 404, 405])\n\n        # connect_manager\n        self.set_var(\"ssl_first_use_timeout\", 5)\n        self.set_var(\"connection_pool_min\", 0)\n        self.set_var(\"https_new_connect_num\", 0)\n        self.set_var(\"connect_create_interval\", 0)\n\n        # check_ip\n        self.set_var(\"check_ip_subdomain\", \"scan1\")\n        self.set_var(\"check_ip_content\", b\"OK\")\n\n        # connect_creator\n        self.set_var(\"check_sni\", 1)\n\n        # ip_manager\n        self.set_var(\"max_scan_ip_thread_num\", 0)\n        self.set_var(\"max_good_ip_num\", 100)\n        self.set_var(\"target_handshake_time\", 500)\n        self.set_var(\"active_connect_interval\", 3*60)\n        self.set_var(\"scan_ip_interval\", 10)\n        self.set_var(\"max_connection_per_domain\", 1)\n\n        # ip source\n        self.set_var(\"use_ipv6\", \"auto\")  # force_ipv4/force_ipv6/auto\n        self.set_var(\"ipv6_scan_ratio\", 40)  # 0 - 100\n\n        self.load()\n"
  },
  {
    "path": "code/default/x_tunnel/local/cloudflare_front/front.py",
    "content": "import os\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nroot_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir, os.pardir))\n\nimport env_info\nimport xlog\n\nfrom .config import Config\nfrom . import ip_manager\nfrom front_base.openssl_wrap import SSLContext\nfrom front_base.connect_creator import ConnectCreator\nfrom front_base.ip_source import Ipv4RangeSource, Ipv6PoolSource, IpCombineSource\nfrom front_base.http_dispatcher import HttpsDispatcher\nfrom front_base.connect_manager import ConnectManager\nfrom front_base.check_ip import CheckIp\nfrom .http2_connection import CloudflareHttp2Worker\nfrom gae_proxy.local import check_local_network\n\ndata_path = env_info.data_path\nmodule_data_path = os.path.join(data_path, 'x_tunnel')\n\nlogger = xlog.getLogger(\"cloudflare_front\", log_path=module_data_path, save_start_log=1500, save_warning_log=True)\nlogger.set_buffer(300)\n\n\nclass Front(object):\n    name = \"cloudflare_front\"\n\n    def __init__(self):\n        self.running = False\n        self.logger = logger\n        config_path = os.path.join(module_data_path, \"cloudflare_front.json\")\n        self.config = Config(config_path)\n        self.light_config = Config(config_path)\n        self.light_config.dispather_min_idle_workers = 0\n        self.light_config.dispather_min_workers = 1\n        self.light_config.dispather_max_workers = 1\n        self.light_config.max_good_ip_num = 10\n\n    def start(self):\n        self.running = True\n        self.last_host = \"center.xx-net.org\"\n\n        ca_certs = os.path.join(current_path, \"cacert.pem\")\n        default_domain_fn = os.path.join(current_path, \"front_domains.json\")\n        domain_fn = os.path.join(module_data_path, \"cloudflare_domains.json\")\n        ip_speed_fn = os.path.join(module_data_path, \"cloudflare_speed.json\")\n        self.ip_manager = ip_manager.IpManager(self.config, default_domain_fn, domain_fn, ip_speed_fn, self.logger)\n\n        openssl_context = SSLContext(logger, ca_certs=ca_certs)\n        self.connect_creator = ConnectCreator(logger, self.config, openssl_context, None)\n        self.check_ip = CheckIp(xlog.null, self.config, self.connect_creator)\n\n        self.ipv4_source = Ipv4RangeSource(\n            logger, self.config,\n            os.path.join(current_path, \"ip_range.txt\"),\n            os.path.join(module_data_path, \"cloudflare_ip_range.txt\")\n        )\n        self.ipv6_source = Ipv6PoolSource(\n            logger, self.config,\n            os.path.join(current_path, \"ipv6_list.txt\")\n        )\n        self.ip_source = IpCombineSource(\n            logger, self.config,\n            self.ipv4_source, self.ipv6_source\n        )\n\n        self.connect_manager = ConnectManager(\n            logger, self.config, self.connect_creator, self.ip_manager, check_local_network)\n\n        self.dispatchs = {}\n\n    def get_dispatcher(self, host=None):\n        if not host:\n            host = self.last_host\n        else:\n            self.last_host = host\n\n        if host not in self.dispatchs:\n            if host in [\"center.xx-net.org\", \"dns.xx-net.org\"]:\n                config = self.light_config\n            else:\n                config = self.config\n\n            http_dispatcher = HttpsDispatcher(\n                logger, config, self.ip_manager, self.connect_manager,\n                http2worker=CloudflareHttp2Worker)\n            self.dispatchs[host] = http_dispatcher\n\n        dispatcher = self.dispatchs[host]\n        return dispatcher\n\n    def request(self, method, host, path=\"/\", headers={}, data=\"\", timeout=120):\n        dispatcher = self.get_dispatcher(host)\n        response = dispatcher.request(method, host, path, dict(headers), data, timeout=timeout)\n        if not response:\n            self.logger.warn(\"req %s get response timeout\", path)\n            return \"\", 602, {}\n\n        status = response.status\n        content = response.task.read_all()\n        if status == 200:\n            logger.debug(\"%s %s%s send:%d recv:%d trace:%s\", method, host, path, len(data), len(content),\n                       response.task.get_trace())\n        else:\n            self.logger.warn(\"%s %s%s status:%d trace:%s\", method, response.worker.ssl_sock.host, path, status,\n                       response.task.get_trace())\n        return content, status, response\n\n    def stop(self):\n        logger.info(\"terminate\")\n        self.connect_manager.set_ssl_created_cb(None)\n        for host in self.dispatchs:\n            dispatcher = self.dispatchs[host]\n            dispatcher.stop()\n        self.connect_manager.stop()\n\n        self.running = False\n\n    def set_proxy(self, args):\n        logger.info(\"set_proxy:%s\", args)\n\n        self.config.PROXY_ENABLE = args[\"enable\"]\n        self.config.PROXY_TYPE = args[\"type\"]\n        self.config.PROXY_HOST = args[\"host\"]\n        self.config.PROXY_PORT = args[\"port\"]\n        self.config.PROXY_USER = args[\"user\"]\n        self.config.PROXY_PASSWD = args[\"passwd\"]\n\n        self.config.save()\n\n        self.connect_creator.update_config()\n\n\nfront = Front()"
  },
  {
    "path": "code/default/x_tunnel/local/cloudflare_front/front_domains.json",
    "content": "{\n}"
  },
  {
    "path": "code/default/x_tunnel/local/cloudflare_front/good_ip.txt",
    "content": "104.19.128.160 None gws 304 0 0\n104.16.152.97 None gws 301 0 0\n172.64.134.36 None gws 309 0 0\n172.64.131.130 None gws 331 0 0\n104.20.5.183 None gws 308 0 0\n104.23.113.179 None gws 335 0 0\n190.93.247.141 None gws 307 0 0\n172.64.106.31 None gws 288 0 0\n104.16.115.111 None gws 309 0 0\n198.41.221.229 None gws 333 0 0\n190.93.246.139 None gws 336 0 0\n104.27.25.192 None gws 338 0 0\n198.41.208.228 None gws 342 0 0\n104.24.179.142 None gws 349 0 0\n141.101.122.252 None gws 348 0 0\n104.24.187.159 None gws 351 0 0\n190.93.244.176 None gws 346 0 0\n190.93.247.123 None gws 350 0 0\n104.20.50.130 None gws 352 0 0\n104.16.107.138 None gws 349 0 0\n141.101.113.136 None gws 352 0 0\n141.101.121.155 None gws 353 0 0\n172.64.49.89 None gws 360 0 0\n198.41.209.113 None gws 357 0 0\n190.93.246.98 None gws 364 0 0\n198.41.223.190 None gws 369 0 0\n172.64.69.224 None gws 369 0 0\n104.25.31.47 None gws 371 0 0\n190.93.247.107 None gws 373 0 0\n198.41.222.191 None gws 355 0 0\n104.17.179.53 None gws 379 0 0\n190.93.245.48 None gws 382 0 0\n104.16.196.216 None gws 393 0 0\n104.19.78.148 None gws 414 0 0\n104.20.209.81 None gws 413 0 0\n190.93.246.146 None gws 396 0 0\n104.19.68.195 None gws 418 0 0\n104.27.196.93 None gws 422 0 0\n104.20.45.232 None gws 417 0 0\n141.101.115.20 None gws 422 0 0\n104.23.115.113 None gws 410 0 0\n190.93.245.76 None gws 425 0 0\n190.93.244.12 None gws 425 0 0\n190.93.246.135 None gws 437 0 0\n190.93.245.209 None gws 430 0 0\n104.16.55.95 None gws 439 0 0\n190.93.247.85 None gws 440 0 0\n104.27.61.45 None gws 446 0 0\n104.24.12.203 None gws 441 0 0\n190.93.245.165 None gws 485 0 0\n104.17.108.14 None gws 505 0 0\n190.93.244.171 None gws 515 0 0\n190.93.247.129 None gws 533 0 0\n104.20.21.78 None gws 554 0 0\n141.101.115.190 None gws 682 0 0\n104.20.206.124 None gws 721 0 0\n190.93.247.11 None gws 685 0 0\n190.93.245.183 None gws 796 0 0\n104.24.254.73 None gws 815 0 0\n172.64.50.59 None gws 773 0 0\n104.27.15.167 None gws 847 0 0\n141.101.120.197 None gws 867 0 0\n190.93.246.219 None gws 867 0 0\n141.101.115.10 None gws 886 0 0\n104.19.201.51 None gws 909 0 0\n141.101.122.94 None gws 971 0 0\n104.17.166.53 None gws 981 0 0\n104.27.37.131 None gws 1036 0 0\n141.101.114.208 None gws 1213 0 0\n104.18.54.33 None gws 886 0 0\n"
  },
  {
    "path": "code/default/x_tunnel/local/cloudflare_front/http2_connection.py",
    "content": "import utils\n\nfrom front_base.http2_connection import Http2Worker\n\n\nclass CloudflareHttp2Worker(Http2Worker):\n    def __init__(self, logger, ip_manager, config, ssl_sock, close_cb, retry_task_cb, idle_cb, log_debug_data,\n                 stream_class=None):\n        super(CloudflareHttp2Worker, self).__init__(\n            logger, ip_manager, config, ssl_sock, close_cb, retry_task_cb, idle_cb, log_debug_data, stream_class)\n        self.host = \"\"\n\n    def get_host(self, task_host):\n        if not self.host:\n            sub, top = utils.split_domain(task_host)\n            self.host = utils.to_str(sub) + \".\" + utils.to_str(self.ssl_sock.host)\n\n        return self.host"
  },
  {
    "path": "code/default/x_tunnel/local/cloudflare_front/ip_manager.py",
    "content": "import os\nimport json\nimport socket\nimport time\n\nimport utils\n\nfrom front_base.ip_manager import IpManagerBase\n\n\nclass IpManager(IpManagerBase):\n    def __init__(self, config, default_domain_fn, domain_fn, speed_fn, logger):\n        super(IpManager, self).__init__(config, None, logger, speed_fn)\n        self.default_domain_fn = default_domain_fn\n        self.domain_fn = domain_fn\n\n        self.domain_map = self.load_domains()\n        # top_domain -> {}\n\n    def __str__(self):\n        o = super().__str__()\n        o += \" domain_map: \\r\\n%s\\r\\n\" % json.dumps(self.domain_map, indent=2)\n        return o\n\n    def load_domains(self):\n        domain_map = {}  # top_domain -> {}\n        for fn in [self.domain_fn, self.default_domain_fn]:\n            if not os.path.isfile(fn):\n                continue\n\n            try:\n                with open(fn, \"r\") as fd:\n                    ds = json.load(fd)\n                    for top in ds:\n                        domain_map[str(top)] = {\n                            \"links\": 0,\n                            \"fail_times\": 0,\n                            \"last_try\": 0.0\n                        }\n                self.logger.info(\"load %s success\", fn)\n                break\n            except Exception as e:\n                self.logger.warn(\"load %s for host failed:%r\", fn, e)\n        return domain_map\n\n    def save_domains(self, domains):\n        ns = []\n        for top_domain, _ in self.domain_map.items():\n            ns.append(top_domain)\n\n        if ns == domains:\n            self.logger.debug(\"save domains not changed, ignore\")\n            return\n        else:\n            self.logger.info(\"save domains:%s\", domains)\n\n        dat = {}\n        for domain in domains:\n            dat[domain] = [\"www.\" + domain]\n\n        with open(self.domain_fn, \"w\") as fd:\n            json.dump(dat, fd)\n\n        self.domain_map = self.load_domains()\n\n    def get_ip_sni_host(self):\n        now = time.time()\n        for top_domain, info in self.domain_map.items():\n            if info[\"links\"] < 0:\n                info[\"links\"] = 0\n\n            if info[\"links\"] >= self.config.max_connection_per_domain:\n                continue\n\n            if info[\"fail_times\"] and now - info[\"last_try\"] < 60:\n                continue\n\n            sni = \"www.\" + top_domain\n            try:\n                ip = socket.gethostbyname(sni)\n            except Exception as e:\n                self.logger.warn(\"get ip for %s fail:%r\", sni, e)\n                continue\n\n            self.logger.debug(\"get ip:%s sni:%s\", ip, sni)\n            info[\"links\"] += 1\n            info[\"last_try\"] = now\n            return {\n                \"ip_str\": ip,\n                \"sni\": sni,\n                \"host\": top_domain,\n            }\n\n        return None\n\n    def _get_domain(self, top_domain):\n        self.domain_map.setdefault(top_domain, {\n                            \"links\": 0,\n                            \"fail_times\": 0,\n                            \"last_try\": 0.0\n                        })\n        return self.domain_map[top_domain]\n\n    def update_ip(self, ip_str, sni, handshake_time):\n        top_domain = \".\".join(sni.split(\".\")[1:])\n\n        info = self._get_domain(top_domain)\n        info[\"fail_times\"] = 0\n        info[\"last_try\"] = 0.0\n        # self.logger.debug(\"ip %s sni:%s connect success, rtt:%f\", ip, sni, handshake_time)\n\n    def report_connect_fail(self, ip_str, sni=None, reason=\"\", force_remove=True):\n        ip, _ = utils.get_ip_port(ip_str)\n        ip = utils.to_str(ip)\n        top_domain = \".\".join(sni.split(\".\")[1:])\n\n        info = self._get_domain(top_domain)\n        info[\"fail_times\"] += 1\n        if info[\"links\"] <= 0:\n            self.logger.error(\"report_connect_fail %s sni:%s links:%d reason:%s\", ip, sni, info[\"links\"], reason)\n        else:\n            info[\"links\"] -= 1\n        self.logger.debug(\"ip %s sni:%s connect fail, reason:%s\", ip, sni, reason)\n\n    def report_connect_closed(self, ip_str, sni=None, reason=\"\"):\n        ip, _ = utils.get_ip_port(ip_str)\n        ip = utils.to_str(ip)\n        top_domain = \".\".join(sni.split(\".\")[1:])\n\n        try:\n            info = self._get_domain(top_domain)\n            if info[\"links\"] <= 0:\n                self.logger.error(\"report_connect_closed %s sni:%s links:%d reason:%s\", ip, sni, info[\"links\"], reason)\n            else:\n                info[\"links\"] -= 1\n            self.logger.debug(\"ip %s sni:%s connect closed reason %s\", ip, sni, reason)\n        except Exception as e:\n            self.logger.warn(\"report_connect_closed %s sni:%s reason:%s except:%r\", ip_str, sni, reason, e)\n"
  },
  {
    "path": "code/default/x_tunnel/local/cloudflare_front/ip_range.txt",
    "content": "1.0.0.0/24\n1.1.1.0/24\n103.21.244.0/22\n103.22.200.0/22\n103.31.4.0/22\n104.16.0.0/12\n108.162.192.0/18\n131.0.72.0/22\n141.101.64.0/18\n162.158.0.0/15\n172.64.0.0/13\n173.245.48.0/20\n188.114.96.0/20\n190.93.240.0/20\n197.234.240.0/22\n198.41.128.0/17"
  },
  {
    "path": "code/default/x_tunnel/local/cloudflare_front/ipv6_list.txt",
    "content": "2606:4700:130:436c:6f75:6466:6c61:7265 google.com gws 100 0 0\n2606:4700:3030::6815:123f google.com gws 100 0 0\n2606:4700:3030::6815:1488 google.com gws 100 0 0\n2606:4700:3030::6815:1b17 google.com gws 100 0 0\n2606:4700:3030::6815:2824\n2606:4700:3030::6815:452f\n2606:4700:3030::6815:54e0\n2606:4700:3030::6815:5a18\n2606:4700:3030::ac43:8917\n2606:4700:3030::ac43:8a7e\n2606:4700:3030::ac43:8da9\n2606:4700:3030::ac43:956f\n2606:4700:3030::ac43:b454\n2606:4700:3030::ac43:b57c\n2606:4700:3031::6815:18ec\n2606:4700:3031::6815:1ca0\n2606:4700:3031::6815:1d9d\n2606:4700:3031::6815:461b\n2606:4700:3031::6815:4ce\n2606:4700:3031::6815:572f\n2606:4700:3031::ac43:8ced\n2606:4700:3031::ac43:cc57\n2606:4700:3031::ac43:d27f\n2606:4700:3031::ac43:dd07\n2606:4700:3032::6815:1cb1\n2606:4700:3032::6815:2846\n2606:4700:3032::6815:57b2\n2606:4700:3032::6815:5af8\n2606:4700:3032::6815:5e8c\n2606:4700:3032::6815:f8d\n2606:4700:3032::ac43:8536\n2606:4700:3032::ac43:888c\n2606:4700:3032::ac43:930c\n2606:4700:3032::ac43:9b34\n2606:4700:3032::ac43:9ec8\n2606:4700:3032::ac43:c9d5\n2606:4700:3032::ac43:ca84\n2606:4700:3032::ac43:daae\n2606:4700:3032::ac43:dcfc\n2606:4700:3033::6815:1610\n2606:4700:3033::6815:23f3\n2606:4700:3033::6815:29b0\n2606:4700:3033::6815:2df3\n2606:4700:3033::6815:56fd\n2606:4700:3033::6815:694\n2606:4700:3033::6815:d26\n2606:4700:3033::ac43:846f\n2606:4700:3033::ac43:8ade\n2606:4700:3033::ac43:9360\n2606:4700:3033::ac43:a4e7\n2606:4700:3033::ac43:c5ab\n2606:4700:3033::ac43:c97b\n2606:4700:3034::6815:40fb\n2606:4700:3034::6815:429c\n2606:4700:3034::6815:4cde\n2606:4700:3034::6815:50f\n2606:4700:3034::6815:51c3\n2606:4700:3034::ac43:8d80\n2606:4700:3034::ac43:ac28\n2606:4700:3034::ac43:dd24\n2606:4700:3035::6815:1769\n2606:4700:3035::6815:18e5\n2606:4700:3035::6815:1b36\n2606:4700:3035::6815:20ec\n2606:4700:3035::6815:2e5a\n2606:4700:3035::6815:2ec5\n2606:4700:3035::6815:369b\n2606:4700:3035::6815:46cc\n2606:4700:3035::6815:554\n2606:4700:3035::6815:91f\n2606:4700:3035::ac43:84bb\n2606:4700:3035::ac43:86e6\n2606:4700:3035::ac43:8906\n2606:4700:3035::ac43:a180\n2606:4700:3035::ac43:a3d4\n2606:4700:3035::ac43:aaec\n2606:4700:3036::6815:21a5\n2606:4700:3036::6815:2fc5\n2606:4700:3036::6815:39a2\n2606:4700:3036::6815:3ea3\n2606:4700:3036::6815:743\n2606:4700:3036::ac43:8aa3\n2606:4700:3036::ac43:8d75\n2606:4700:3036::ac43:9513\n2606:4700:3036::ac43:a036\n2606:4700:3036::ac43:aa7e\n2606:4700:3036::ac43:af2b\n2606:4700:3036::ac43:bb8a\n2606:4700:3036::ac43:c0ef\n2606:4700:3037::6815:413e\n2606:4700:3037::6815:4cfb\n2606:4700:3037::6815:5902\n2606:4700:3037::6815:598c\n2606:4700:3037::6815:844\n2606:4700:3037::ac43:8b49\n2606:4700:3037::ac43:8c2c\n2606:4700:3037::ac43:8d32\n2606:4700:3037::ac43:9771\n2606:4700:3037::ac43:a2c5\n2606:4700:3037::ac43:a358\n2606:4700:3037::ac43:b4b4\n2606:4700:3037::ac43:bc4a\n2606:4700:3037::ac43:c5b6\n2620:101:9000:53::55\n2a06:98c1:3120::\n2a06:98c1:3120::1\n2a06:98c1:3120::2\n2a06:98c1:3120::3\n2a06:98c1:3120::5\n2a06:98c1:3120::6\n2a06:98c1:3120::7\n2a06:98c1:3120::9\n2a06:98c1:3120::c\n2a06:98c1:3120::d\n2a06:98c1:3120::e\n2a06:98c1:3121::\n2a06:98c1:3121::1\n2a06:98c1:3121::2\n2a06:98c1:3121::3\n2a06:98c1:3121::5\n2a06:98c1:3121::6\n2a06:98c1:3121::7\n2a06:98c1:3121::9\n2a06:98c1:3121::c\n2a06:98c1:3121::d\n2a06:98c1:3121::e"
  },
  {
    "path": "code/default/x_tunnel/local/cloudflare_front/test.py",
    "content": "#!/usr/bin/env python2\n# coding:utf-8\n\nimport os\nimport sys\nimport time\n\nimport utils\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nroot_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir, os.pardir))\npython_path = root_path\n\nsys.path.append(root_path)\n\nnoarch_lib = os.path.abspath(os.path.join(python_path, 'lib', 'noarch'))\nsys.path.append(noarch_lib)\n\nif sys.platform == \"win32\":\n    win32_lib = os.path.abspath(os.path.join(python_path, 'lib', 'win32'))\n    sys.path.append(win32_lib)\nelif sys.platform.startswith(\"linux\"):\n    linux_lib = os.path.abspath(os.path.join(python_path, 'lib', 'linux'))\n    sys.path.append(linux_lib)\nelif sys.platform == \"darwin\":\n    darwin_lib = os.path.abspath(os.path.join(python_path, 'lib', 'darwin'))\n    sys.path.append(darwin_lib)\n    extra_lib = \"/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python\"\n    sys.path.append(extra_lib)\n\nimport x_tunnel.local.cloudflare_front as front\nimport env_info\n\nfrom xlog import getLogger\nxlog = getLogger(\"cloudflare_front\")\nxlog.set_buffer(2000)\n\ndata_path = env_info.data_path\nmodule_data_path = os.path.join(data_path, 'x_tunnel')\n\n\ndef get_dns():\n    start_time = time.time()\n    # content, status, response = front.request(\"GET\", \"scan1.xx-net.org\", \"/\", timeout=10)\n    content, status, response = front.front.request(\"GET\", \"dns.xx-net.org\", path=\"/query?domain=www.google.com\")\n\n    time_cost = time.time() - start_time\n    xlog.info(\"GET cost:%f\", time_cost)\n    xlog.info(\"status:%d content:%s\", status, content)\n    front.front.stop()\n\n\ndef post_data():\n    start_time = time.time()\n    data = utils.generate_random_lowercase(900 * 1024)\n    content, status, response = front.front.request(\"POST\", \"v3.xx-net.org\", path=\"/upload_logs?session_id=tyjiugru\",\n                                                    data=data,\n                                                    headers={\"Content-Length\": str(len(data))})\n\n    time_cost = time.time() - start_time\n    xlog.info(\"POST cost:%f\", time_cost)\n    xlog.info(\"status:%d content:%s\", status, content)\n    front.front.stop()\n\n\nif __name__ == '__main__':\n    import traceback\n\n    try:\n        # post_data()\n        get_dns()\n    except Exception:\n        traceback.print_exc(file=sys.stdout)\n    except KeyboardInterrupt:\n        front.stop()\n        sys.exit()\n"
  },
  {
    "path": "code/default/x_tunnel/local/cloudflare_front/web_control.py",
    "content": "#!/usr/bin/env python\n# coding:utf-8\n\n\nimport os\nimport time\n\ntry:\n    from urllib.parse import urlparse, parse_qs\nexcept ImportError:\n    from urlparse import urlparse, parse_qs\n\nimport simple_http_server\nfrom .front import front\n\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nroot_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))\ntop_path = os.path.abspath(os.path.join(root_path, os.pardir, os.pardir, os.pardir))\nweb_ui_path = os.path.join(current_path, os.path.pardir, \"web_ui\")\n\n\nclass ControlHandler(simple_http_server.HttpServerHandler):\n    def __init__(self, client_address, headers, command, path, rfile, wfile):\n        self.client_address = client_address\n        self.headers = headers\n        self.command = command\n        self.path = path\n        self.rfile = rfile\n        self.wfile = wfile\n\n    def do_GET(self):\n        path = urlparse(self.path).path\n        if path == \"/log\":\n            return self.req_log_handler()\n        elif path == \"/ip_list\":\n            return self.req_ip_list_handler()\n        elif path == \"/debug\":\n            return self.req_debug_handler()\n        else:\n            front.logger.warn('Control Req %s %s %s ', self.address_string(), self.command, self.path)\n\n        self.wfile.write(b'HTTP/1.1 404\\r\\nContent-Type: text/plain\\r\\nConnection: close\\r\\n\\r\\n404 Not Found')\n        front.logger.info('%s \"%s %s HTTP/1.1\" 404 -', self.address_string(), self.command, self.path)\n\n    def req_log_handler(self):\n        req = urlparse(self.path).query\n        reqs = self.unpack_reqs(parse_qs(req, keep_blank_values=True))\n        data = ''\n\n        cmd = \"get_last\"\n        if reqs[\"cmd\"]:\n            cmd = reqs[\"cmd\"]\n\n        if cmd == \"get_last\":\n            max_line = int(reqs[\"max_line\"])\n            data = front.logger.get_last_lines(max_line)\n        elif cmd == \"get_new\":\n            last_no = int(reqs[\"last_no\"])\n            data = front.logger.get_new_lines(last_no)\n        else:\n            front.logger.error('PAC %s %s %s ', self.address_string(), self.command, self.path)\n\n        mimetype = 'text/plain'\n        self.send_response_nc(mimetype, data)\n\n    def req_ip_list_handler(self):\n        time_now = time.time()\n        data = \"<html><body><div  style='float: left; white-space:nowrap;font-family: monospace;'>\"\n        data += \"time:%d  pointer:%d<br>\\r\\n\" % (time_now, front.ip_manager.ip_pointer)\n        data += \"<table><tr><th>N</th><th>IP</th><th>HS</th><th>Fails</th>\"\n        data += \"<th>down_fail</th><th>links</th>\"\n        data += \"<th>get_time</th><th>success_time</th><th>fail_time</th><th>down_fail_time</th>\"\n        data += \"<th>data_active</th><th>transfered_data</th><th>Trans</th>\"\n        data += \"<th>history</th></tr>\\n\"\n        i = 1\n        for ip in front.ip_manager.ip_list:\n            handshake_time = front.ip_manager.ip_dict[ip][\"handshake_time\"]\n\n            fail_times = front.ip_manager.ip_dict[ip][\"fail_times\"]\n            down_fail = front.ip_manager.ip_dict[ip][\"down_fail\"]\n            links = front.ip_manager.ip_dict[ip][\"links\"]\n\n            get_time = front.ip_manager.ip_dict[ip][\"get_time\"]\n            if get_time:\n                get_time = time_now - get_time\n\n            success_time = front.ip_manager.ip_dict[ip][\"success_time\"]\n            if success_time:\n                success_time = time_now - success_time\n\n            fail_time = front.ip_manager.ip_dict[ip][\"fail_time\"]\n            if fail_time:\n                fail_time = time_now - fail_time\n\n            down_fail_time = front.ip_manager.ip_dict[ip][\"down_fail_time\"]\n            if down_fail_time:\n                down_fail_time = time_now - down_fail_time\n\n            data_active = front.ip_manager.ip_dict[ip][\"data_active\"]\n            if data_active:\n                active_time = time_now - data_active\n            else:\n                active_time = 0\n\n            history = front.ip_manager.ip_dict[ip][\"history\"]\n            t0 = 0\n            str_out = ''\n            for item in history:\n                t = item[0]\n                v = item[1]\n                if t0 == 0:\n                    t0 = t\n                time_per = int((t - t0) * 1000)\n                t0 = t\n                str_out += \"%d(%s) \" % (time_per, v)\n            data += \"<tr><td>%d</td><td>%s</td><td>%d</td><td>%d</td><td>%d</td><td>%d</td><td>%d</td><td>%d</td><td>%d</td>\" \\\n                    \"<td>%d</td><td>%d</td><td>%s</td></tr>\\n\" % \\\n                    (i, ip, handshake_time, fail_times, down_fail, links, get_time, success_time, fail_time, down_fail_time, \\\n                    active_time, str_out)\n            i += 1\n\n        data += \"</table></div></body></html>\"\n        mimetype = 'text/html'\n        self.send_response_nc(mimetype, data)\n\n    def req_debug_handler(self):\n        if not front.running:\n            return self.send_response_nc('text/plain', \"Not running\")\n\n        data = \"\"\n        objs = [front.connect_manager] + list(front.dispatchs.values())\n        for obj in objs:\n\n            data += \"%s\\r\\n\" % obj.__class__\n            for attr in dir(obj):\n                if attr.startswith(\"__\"):\n                    continue\n                sub_obj = getattr(obj, attr)\n                if callable(sub_obj):\n                    continue\n\n                if isinstance(sub_obj, list):\n                    data += \"    %s:\\r\\n\" % (attr)\n                    for item in sub_obj:\n                        data += \"      %s\\r\\n\" % item\n                    data += \"\\r\\n\"\n                else:\n                    data += \"    %s = %s\\r\\n\" % (attr, sub_obj)\n            if hasattr(obj, \"to_string\"):\n                data += obj.to_string()\n\n        mimetype = 'text/plain'\n        self.send_response_nc(mimetype, data)"
  },
  {
    "path": "code/default/x_tunnel/local/cloudfront_front/__init__.py",
    "content": "\nfrom .front import front"
  },
  {
    "path": "code/default/x_tunnel/local/cloudfront_front/cacert.pem",
    "content": "##\n## Bundle of CA Root Certificates\n##\n## Certificate data from Mozilla as of: Wed Mar  7 04:12:06 2018 GMT\n##\n## This is a bundle of X.509 certificates of public Certificate Authorities\n## (CA). These were automatically extracted from Mozilla's root certificates\n## file (certdata.txt).  This file can be found in the mozilla source tree:\n## https://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt\n##\n## It contains the certificates in PEM format and therefore\n## can be directly used with curl / libcurl / php_curl, or with\n## an Apache+mod_ssl webserver for SSL client authentication.\n## Just configure this file as the SSLCACertificateFile.\n##\n## Conversion done with mk-ca-bundle.pl version 1.27.\n## SHA256: 704f02707ec6b4c4a7597a8c6039b020def11e64f3ef0605a9c3543d48038a57\n##\n\n\nGlobalSign Root CA\n==================\n-----BEGIN CERTIFICATE-----\nMIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx\nGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds\nb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV\nBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD\nVQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa\nDuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc\nTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb\nKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP\nc1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX\ngzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV\nHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF\nAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj\nY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG\nj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH\nhm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC\nX4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==\n-----END CERTIFICATE-----\n\nGlobalSign Root CA - R2\n=======================\n-----BEGIN CERTIFICATE-----\nMIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4GA1UECxMXR2xv\nYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh\nbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT\naWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln\nbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6\nErPLv4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8eoLrvozp\ns6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklqtTleiDTsvHgMCJiEbKjN\nS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzdC9XZzPnqJworc5HGnRusyMvo4KD0L5CL\nTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pazq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6C\nygPCm48CAwEAAaOBnDCBmTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E\nFgQUm+IHV2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5nbG9i\nYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG3lm0mi3f3BmGLjAN\nBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4GsJ0/WwbgcQ3izDJr86iw8bmEbTUsp\n9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu\n01yiPqFbQfXf5WRDLenVOavSot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG7\n9G+dwfCMNYxdAfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7\nTBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==\n-----END CERTIFICATE-----\n\nVerisign Class 3 Public Primary Certification Authority - G3\n============================================================\n-----BEGIN CERTIFICATE-----\nMIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV\nUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv\ncmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl\nIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh\ndGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw\nCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy\ndXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv\ncml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkg\nQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\nggEBAMu6nFL8eB8aHm8bN3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1\nEUGO+i2tKmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGukxUc\ncLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBmCC+Vk7+qRy+oRpfw\nEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJXwzw3sJ2zq/3avL6QaaiMxTJ5Xpj\n055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWuimi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA\nERSWwauSCPc/L8my/uRan2Te2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5f\nj267Cz3qWhMeDGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC\n/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565pF4ErWjfJXir0\nxuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGtTxzhT5yvDwyd93gN2PQ1VoDa\nt20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ==\n-----END CERTIFICATE-----\n\nEntrust.net Premium 2048 Secure Server CA\n=========================================\n-----BEGIN CERTIFICATE-----\nMIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChMLRW50cnVzdC5u\nZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBpbmNvcnAuIGJ5IHJlZi4gKGxp\nbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNV\nBAMTKkVudHJ1c3QubmV0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQx\nNzUwNTFaFw0yOTA3MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3\nd3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTEl\nMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5u\nZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\nMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQqK0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOL\nGp18EzoOH1u3Hs/lJBQesYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSr\nhRSGlVuXMlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVTXTzW\nnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/HoZdenoVve8AjhUi\nVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH4QIDAQABo0IwQDAOBgNVHQ8BAf8E\nBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJ\nKoZIhvcNAQEFBQADggEBADubj1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPy\nT/4xmf3IDExoU8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf\nzX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5bu/8j72gZyxKT\nJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+bYQLCIt+jerXmCHG8+c8eS9e\nnNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/ErfF6adulZkMV8gzURZVE=\n-----END CERTIFICATE-----\n\nBaltimore CyberTrust Root\n=========================\n-----BEGIN CERTIFICATE-----\nMIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJRTESMBAGA1UE\nChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3li\nZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoXDTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMC\nSUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFs\ndGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKME\nuyKrmD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsB\nUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/C\nG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9\nXbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjpr\nl3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoI\nVDaGezq1BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEB\nBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT929hkTI7gQCvlYpNRh\ncL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3WgxjkzSswF07r51XgdIGn9w/xZchMB5\nhbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsa\nY71k5h+3zvDyny67G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H\nRCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp\n-----END CERTIFICATE-----\n\nAddTrust External Root\n======================\n-----BEGIN CERTIFICATE-----\nMIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEUMBIGA1UEChML\nQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYD\nVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEw\nNDgzOFowbzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRU\ncnVzdCBFeHRlcm5hbCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0Eg\nUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvtH7xsD821\n+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9uMq/NzgtHj6RQa1wVsfw\nTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzXmk6vBbOmcZSccbNQYArHE504B4YCqOmo\naSYYkKtMsE8jqzpPhNjfzp/haW+710LXa0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy\n2xSoRcRdKn23tNbE7qzNE0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv7\n7+ldU9U0WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYDVR0P\nBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0Jvf6xCZU7wO94CTL\nVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRk\nVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENB\nIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZl\nj7DYd7usQWxHYINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5\n6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvCNr4TDea9Y355\ne6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEXc4g/VhsxOBi0cQ+azcgOno4u\nG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5amnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=\n-----END CERTIFICATE-----\n\nEntrust Root Certification Authority\n====================================\n-----BEGIN CERTIFICATE-----\nMIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMCVVMxFjAUBgNV\nBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0Lm5ldC9DUFMgaXMgaW5jb3Jw\nb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMWKGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsG\nA1UEAxMkRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0\nMloXDTI2MTEyNzIwNTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMu\nMTkwNwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSByZWZlcmVu\nY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNVBAMTJEVudHJ1c3QgUm9v\ndCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\nALaVtkNC+sZtKm9I35RMOVcF7sN5EUFoNu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYsz\nA9u3g3s+IIRe7bJWKKf44LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOww\nCj0Yzfv9KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGIrb68\nj6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi94DkZfs0Nw4pgHBN\nrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOBsDCBrTAOBgNVHQ8BAf8EBAMCAQYw\nDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAigA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1\nMzQyWjAfBgNVHSMEGDAWgBRokORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DH\nhmak8fdLQ/uEvW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA\nA4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9tO1KzKtvn1ISM\nY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6ZuaAGAT/3B+XxFNSRuzFVJ7yVTa\nv52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTS\nW3iDVuycNsMm4hH2Z0kdkquM++v/eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0\ntHuu2guQOHXvgR1m0vdXcDazv/wor3ElhVsT/h5/WrQ8\n-----END CERTIFICATE-----\n\nGeoTrust Global CA\n==================\n-----BEGIN CERTIFICATE-----\nMIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVTMRYwFAYDVQQK\nEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9iYWwgQ0EwHhcNMDIwNTIxMDQw\nMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j\nLjEbMBkGA1UEAxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB\nCgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjo\nBbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDviS2Aelet\n8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU1XupGc1V3sjs0l44U+Vc\nT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagU\nvTLrGAMoUgRx5aszPeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTAD\nAQH/MB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVk\nDBF9qn1luMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKInZ57Q\nzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfStQWVYrmm3ok9Nns4\nd0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcFPseKUgzbFbS9bZvlxrFUaKnjaZC2\nmqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Unhw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6p\nXE0zX5IJL4hmXXeXxx12E6nV5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvm\nMw==\n-----END CERTIFICATE-----\n\nGeoTrust Universal CA\n=====================\n-----BEGIN CERTIFICATE-----\nMIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN\nR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVyc2FsIENBMB4XDTA0MDMwNDA1\nMDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu\nYy4xHjAcBgNVBAMTFUdlb1RydXN0IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIP\nADCCAgoCggIBAKYVVaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9t\nJPi8cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTTQjOgNB0e\nRXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFhF7em6fgemdtzbvQKoiFs\n7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2vc7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d\n8Lsrlh/eezJS/R27tQahsiFepdaVaH/wmZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7V\nqnJNk22CDtucvc+081xdVHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3Cga\nRr0BHdCXteGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZf9hB\nZ3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfReBi9Fi1jUIxaS5BZu\nKGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+nhutxx9z3SxPGWX9f5NAEC7S8O08\nni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0\nXG0D08DYj3rWMB8GA1UdIwQYMBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIB\nhjANBgkqhkiG9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc\naanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fXIwjhmF7DWgh2\nqaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzynANXH/KttgCJwpQzgXQQpAvvL\noJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0zuzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsK\nxr2EoyNB3tZ3b4XUhRxQ4K5RirqNPnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxF\nKyDuSN/n3QmOGKjaQI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2\nDFKWkoRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9ER/frslK\nxfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQtDF4JbAiXfKM9fJP/P6EU\np8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/SfuvmbJxPgWp6ZKy7PtXny3YuxadIwVyQD8vI\nP/rmMuGNG2+k5o7Y+SlIis5z/iw=\n-----END CERTIFICATE-----\n\nGeoTrust Universal CA 2\n=======================\n-----BEGIN CERTIFICATE-----\nMIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN\nR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwHhcNMDQwMzA0\nMDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3Qg\nSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUA\nA4ICDwAwggIKAoICAQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0\nDE81WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUGFF+3Qs17\nj1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdqXbboW0W63MOhBW9Wjo8Q\nJqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxLse4YuU6W3Nx2/zu+z18DwPw76L5GG//a\nQMJS9/7jOvdqdzXQ2o3rXhhqMcceujwbKNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2\nWP0+GfPtDCapkzj4T8FdIgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP\n20gaXT73y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRthAAn\nZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgocQIgfksILAAX/8sgC\nSqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4Lt1ZrtmhN79UNdxzMk+MBB4zsslG\n8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2\n+/CfXGJx7Tz0RzgQKzAfBgNVHSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8E\nBAMCAYYwDQYJKoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z\ndXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQL1EuxBRa3ugZ\n4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgrFg5fNuH8KrUwJM/gYwx7WBr+\nmbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSoag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpq\nA1Ihn0CoZ1Dy81of398j9tx4TuaYT1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpg\nY+RdM4kX2TGq2tbzGDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiP\npm8m1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJVOCiNUW7d\nFGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH6aLcr34YEoP9VhdBLtUp\ngn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwXQMAJKOSLakhT2+zNVVXxxvjpoixMptEm\nX36vWkzaH6byHCx+rgIW0lbQL1dTR+iS\n-----END CERTIFICATE-----\n\nVisa eCommerce Root\n===================\n-----BEGIN CERTIFICATE-----\nMIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBrMQswCQYDVQQG\nEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2Ug\nQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2\nWhcNMjIwNjI0MDAxNjEyWjBrMQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMm\nVmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv\nbW1lcmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h2mCxlCfL\nF9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4ElpF7sDPwsRROEW+1QK8b\nRaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdVZqW1LS7YgFmypw23RuwhY/81q6UCzyr0\nTP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI\n/k4+oKsGGelT84ATB+0tvz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzs\nGHxBvfaLdXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEG\nMB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUFAAOCAQEAX/FBfXxc\nCLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcRzCSs00Rsca4BIGsDoo8Ytyk6feUW\nYFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pz\nzkWKsKZJ/0x9nXGIxHYdkFsd7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBu\nYQa7FkKMcPcw++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt\n398znM/jra6O1I7mT1GvFpLgXPYHDw==\n-----END CERTIFICATE-----\n\nComodo AAA Services root\n========================\n-----BEGIN CERTIFICATE-----\nMIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS\nR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg\nTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAw\nMFoXDTI4MTIzMTIzNTk1OVowezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hl\nc3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNV\nBAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\nggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQuaBtDFcCLNSS1UY8y2bmhG\nC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe3M/vg4aijJRPn2jymJBGhCfHdr/jzDUs\ni14HZGWCwEiwqJH5YZ92IFCokcdmtet4YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszW\nY19zjNoFmag4qMsXeDZRrOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjH\nYpy+g8cmez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQUoBEK\nIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wewYDVR0f\nBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNl\ncy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29tb2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2Vz\nLmNybDANBgkqhkiG9w0BAQUFAAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm\n7l3sAg9g1o1QGE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz\nRt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2G9w84FoVxp7Z\n8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsil2D4kF501KKaU73yqWjgom7C\n12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==\n-----END CERTIFICATE-----\n\nQuoVadis Root CA\n================\n-----BEGIN CERTIFICATE-----\nMIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJCTTEZMBcGA1UE\nChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0\neTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAz\nMTkxODMzMzNaFw0yMTAzMTcxODMzMzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRp\ncyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQD\nEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF\nAAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Ypli4kVEAkOPcahdxYTMuk\nJ0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2DrOpm2RgbaIr1VxqYuvXtdj182d6UajtL\nF8HVj71lODqV0D1VNk7feVcxKh7YWWVJWCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeL\nYzcS19Dsw3sgQUSj7cugF+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWen\nAScOospUxbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCCAk4w\nPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVvdmFkaXNvZmZzaG9y\nZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREwggENMIIBCQYJKwYBBAG+WAABMIH7\nMIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNlIG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmlj\nYXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJs\nZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh\nY3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYIKwYBBQUHAgEW\nFmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3TKbkGGew5Oanwl4Rqy+/fMIGu\nBgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rqy+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkw\nFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0\naG9yaXR5MS4wLAYDVQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6\ntlCLMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSkfnIYj9lo\nfFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf87C9TqnN7Az10buYWnuul\nLsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1RcHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2x\ngI4JVrmcGmD+XcHXetwReNDWXcG31a0ymQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi\n5upZIof4l/UO/erMkqQWxFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi\n5nrQNiOKSnQ2+Q==\n-----END CERTIFICATE-----\n\nQuoVadis Root CA 2\n==================\n-----BEGIN CERTIFICATE-----\nMIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT\nEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMjAeFw0wNjExMjQx\nODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM\naW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4IC\nDwAwggIKAoICAQCaGMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6\nXJxgFyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55JWpzmM+Yk\nlvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bBrrcCaoF6qUWD4gXmuVbB\nlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp+ARz8un+XJiM9XOva7R+zdRcAitMOeGy\nlZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt\n66/3FsvbzSUr5R/7mp/iUcw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1Jdxn\nwQ5hYIizPtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og/zOh\nD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UHoycR7hYQe7xFSkyy\nBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuIyV77zGHcizN300QyNQliBJIWENie\nJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1Ud\nDgQWBBQahGK8SEwzJQTU7tD2A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGU\na6FJpEcwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT\nElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2fBluornFdLwUv\nZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzng/iN/Ae42l9NLmeyhP3ZRPx3\nUIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2BlfF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodm\nVjB3pjd4M1IQWK4/YY7yarHvGH5KWWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK\n+JDSV6IZUaUtl0HaB0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrW\nIozchLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPRTUIZ3Ph1\nWVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWDmbA4CD/pXvk1B+TJYm5X\nf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0ZohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II\n4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8\nVCLAAVBpQ570su9t+Oza8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u\n-----END CERTIFICATE-----\n\nQuoVadis Root CA 3\n==================\n-----BEGIN CERTIFICATE-----\nMIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT\nEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMzAeFw0wNjExMjQx\nOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM\naW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4IC\nDwAwggIKAoICAQDMV0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNgg\nDhoB4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUrH556VOij\nKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd8lyyBTNvijbO0BNO/79K\nDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9CabwvvWhDFlaJKjdhkf2mrk7AyxRllDdLkgbv\nBNDInIjbC3uBr7E9KsRlOni27tyAsdLTmZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwp\np5ijJUMv7/FfJuGITfhebtfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8\nnT8KKdjcT5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDtWAEX\nMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZc6tsgLjoC2SToJyM\nGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A4iLItLRkT9a6fUg+qGkM17uGcclz\nuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYDVR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHT\nBgkrBgEEAb5YAAMwgcUwgZMGCCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmlj\nYXRlIGNvbnN0aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0\naWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVudC4wLQYIKwYB\nBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2NwczALBgNVHQ8EBAMCAQYwHQYD\nVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4GA1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4\nywLQoUmkRzBFMQswCQYDVQQGEwJCTTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UE\nAxMSUXVvVmFkaXMgUm9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZV\nqyM07ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSemd1o417+s\nhvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd+LJ2w/w4E6oM3kJpK27z\nPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2\nPb+iSwwQHYaZTKrzchGT5Or2m9qoXadNt54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp\n8kokUvd0/bpO5qgdAm6xDYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBC\nbjPsMZ57k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6szHXu\ng/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0jWy10QJLZYxkNc91p\nvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeTmJlglFwjz1onl14LBQaTNx47aTbr\nqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK4SVhM7JZG+Ju1zdXtg2pEto=\n-----END CERTIFICATE-----\n\nSecurity Communication Root CA\n==============================\n-----BEGIN CERTIFICATE-----\nMIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP\nU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw\nHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP\nU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw\nggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw\n8yl89f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJDKaVv0uM\nDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9Ms+k2Y7CI9eNqPPYJayX\n5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/NQV3Is00qVUarH9oe4kA92819uZKAnDfd\nDJZkndwi92SL32HeFZRSFaB9UslLqCHJxrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2\nJChzAgMBAAGjPzA9MB0GA1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYw\nDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vGkl3g\n0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfrUj94nK9NrvjVT8+a\nmCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5Bw+SUEmK3TGXX8npN6o7WWWXlDLJ\ns58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJUJRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ\n6rBK+1YWc26sTfcioU+tHXotRSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAi\nFL39vmwLAw==\n-----END CERTIFICATE-----\n\nSonera Class 2 Root CA\n======================\n-----BEGIN CERTIFICATE-----\nMIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEPMA0GA1UEChMG\nU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAxMDQwNjA3Mjk0MFoXDTIxMDQw\nNjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNVBAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJh\nIENsYXNzMiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3\n/Ei9vX+ALTU74W+oZ6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybT\ndXnt5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s3TmVToMG\nf+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2EjvOr7nQKV0ba5cTppCD8P\ntOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu8nYybieDwnPz3BjotJPqdURrBGAgcVeH\nnfO+oJAjPYok4doh28MCAwEAAaMzMDEwDwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITT\nXjwwCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt\n0jSv9zilzqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/3DEI\ncbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvDFNr450kkkdAdavph\nOe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6Tk6ezAyNlNzZRZxe7EJQY670XcSx\nEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLH\nllpwrN9M\n-----END CERTIFICATE-----\n\nXRamp Global CA Root\n====================\n-----BEGIN CERTIFICATE-----\nMIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UE\nBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2Vj\ndXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB\ndXRob3JpdHkwHhcNMDQxMTAxMTcxNDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMx\nHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkg\nU2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3Jp\ndHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS638eMpSe2OAtp87ZOqCwu\nIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCPKZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMx\nfoArtYzAQDsRhtDLooY2YKTVMIJt2W7QDxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FE\nzG+gSqmUsE3a56k0enI4qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqs\nAxcZZPRaJSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNViPvry\nxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud\nEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASsjVy16bYbMDYGA1UdHwQvMC0wK6Ap\noCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMC\nAQEwDQYJKoZIhvcNAQEFBQADggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc\n/Kh4ZzXxHfARvbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt\nqZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLaIR9NmXmd4c8n\nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSyi6mx5O+aGtA9aZnuqCij4Tyz\n8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQO+7ETPTsJ3xCwnR8gooJybQDJbw=\n-----END CERTIFICATE-----\n\nGo Daddy Class 2 CA\n===================\n-----BEGIN CERTIFICATE-----\nMIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMY\nVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRp\nZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkG\nA1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g\nRGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQAD\nggENADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv\n2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+qN1j3hybX2C32\nqRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiOr18SPaAIBQi2XKVlOARFmR6j\nYGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmY\nvLEHZ6IVDd2gWMZEewo+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0O\nBBYEFNLEsNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h/t2o\natTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMu\nMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwG\nA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wim\nPQoZ+YeAEW5p5JYXMP80kWNyOO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKt\nI3lpjbi2Tc7PTMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ\nHmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mERdEr/VxqHD3VI\nLs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5CufReYNnyicsbkqWletNw+vHX/b\nvZ8=\n-----END CERTIFICATE-----\n\nStarfield Class 2 CA\n====================\n-----BEGIN CERTIFICATE-----\nMIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzElMCMGA1UEChMc\nU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZpZWxkIENsYXNzIDIg\nQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBo\nMQswCQYDVQQGEwJVUzElMCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAG\nA1UECxMpU3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqG\nSIb3DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf8MOh2tTY\nbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN+lq2cwQlZut3f+dZxkqZ\nJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVm\nepsZGD3/cVE8MC5fvj13c7JdBmzDI1aaK4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSN\nF4Azbl5KXZnJHoe0nRrA1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HF\nMIHCMB0GA1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fRzt0f\nhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNo\nbm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBDbGFzcyAyIENlcnRpZmljYXRpb24g\nQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGs\nafPzWdqbAYcaT1epoXkJKtv3L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLM\nPUxA2IGvd56Deruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl\nxy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynpVSJYACPq4xJD\nKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEYWQPJIrSPnNVeKtelttQKbfi3\nQBFGmh95DmK/D5fs4C8fF5Q=\n-----END CERTIFICATE-----\n\nTaiwan GRCA\n===========\n-----BEGIN CERTIFICATE-----\nMIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/MQswCQYDVQQG\nEwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4X\nDTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1owPzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dv\ndmVybm1lbnQgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQAD\nggIPADCCAgoCggIBAJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qN\nw8XRIePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1qgQdW8or5\nBtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKyyhwOeYHWtXBiCAEuTk8O\n1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAtsF/tnyMKtsc2AtJfcdgEWFelq16TheEfO\nhtX7MfP6Mb40qij7cEwdScevLJ1tZqa2jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wov\nJ5pGfaENda1UhhXcSTvxls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7\nQ3hub/FCVGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHKYS1t\nB6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoHEgKXTiCQ8P8NHuJB\nO9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThNXo+EHWbNxWCWtFJaBYmOlXqYwZE8\nlSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1UdDgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNV\nHRMEBTADAQH/MDkGBGcqBwAEMTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg2\n09yewDL7MTqKUWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ\nTulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyfqzvS/3WXy6Tj\nZwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaKZEk9GhiHkASfQlK3T8v+R0F2\nNe//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFEJPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlU\nD7gsL0u8qV1bYH+Mh6XgUmMqvtg7hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6Qz\nDxARvBMB1uUO07+1EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+Hbk\nZ6MmnD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WXudpVBrkk\n7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44VbnzssQwmSNOXfJIoRIM3BKQ\nCZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDeLMDDav7v3Aun+kbfYNucpllQdSNpc5Oy\n+fwC00fmcc4QAu4njIT/rEUNE1yDMuAlpYYsfPQS\n-----END CERTIFICATE-----\n\nDigiCert Assured ID Root CA\n===========================\n-----BEGIN CERTIFICATE-----\nMIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQG\nEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw\nIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzEx\nMTEwMDAwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL\nExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0Ew\nggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7cJpSIqvTO\n9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYPmDI2dsze3Tyoou9q+yHy\nUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW\n/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpy\noeb6pNnVFzF1roV9Iq4/AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whf\nGHdPAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRF\n66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkq\nhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRCdWKuh+vy1dneVrOfzM4UKLkNl2Bc\nEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTffwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38Fn\nSbNd67IJKusm7Xi+fT8r87cmNW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i\n8b5QZ7dsvfPxH2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe\n+o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==\n-----END CERTIFICATE-----\n\nDigiCert Global Root CA\n=======================\n-----BEGIN CERTIFICATE-----\nMIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQG\nEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw\nHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAw\nMDAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3\ndy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkq\nhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsBCSDMAZOn\nTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97nh6Vfe63SKMI2tavegw5\nBmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt43C/dxC//AH2hdmoRBBYMql1GNXRor5H\n4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7PT19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y\n7vrTC0LUq7dBMtoM1O/4gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQAB\no2MwYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbRTLtm\n8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJKoZIhvcNAQEF\nBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/EsrhMAtudXH/vTBH1jLuG2cenTnmCmr\nEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIt\ntep3Sp+dWOIrWcBAI+0tKIJFPnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886\nUAb3LujEV0lsYSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk\nCAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=\n-----END CERTIFICATE-----\n\nDigiCert High Assurance EV Root CA\n==================================\n-----BEGIN CERTIFICATE-----\nMIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQG\nEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSsw\nKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAw\nMFoXDTMxMTExMDAwMDAwMFowbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ\nMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFu\nY2UgRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm+9S75S0t\nMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTWPNt0OKRKzE0lgvdKpVMS\nOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEMxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3\nMRuNs8ckRZqnrG0AFFoEt7oT61EKmEFBIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQ\nNAQTXKFx01p8VdteZOE3hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUe\nh10aUAsgEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB\nAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSY\nJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3NecnzyIZgYIVyHbIUf4KmeqvxgydkAQ\nV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6zeM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFp\nmyPInngiK3BD41VHMWEZ71jFhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkK\nmNEVX58Svnw2Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe\nvEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep+OkuE6N36B9K\n-----END CERTIFICATE-----\n\nCertplus Class 2 Primary CA\n===========================\n-----BEGIN CERTIFICATE-----\nMIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAwPTELMAkGA1UE\nBhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFzcyAyIFByaW1hcnkgQ0EwHhcN\nOTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2Vy\ndHBsdXMxGzAZBgNVBAMTEkNsYXNzIDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP\nADCCAQoCggEBANxQltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR\n5aiRVhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyLkcAbmXuZ\nVg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCdEgETjdyAYveVqUSISnFO\nYFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yasH7WLO7dDWWuwJKZtkIvEcupdM5i3y95e\ne++U8Rs+yskhwcWYAqqi9lt3m/V+llU0HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRME\nCDAGAQH/AgEKMAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJ\nYIZIAYb4QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMuY29t\nL0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/AN9WM2K191EBkOvD\nP9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8yfFC82x/xXp8HVGIutIKPidd3i1R\nTtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMRFcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+\n7UCmnYR0ObncHoUW2ikbhiMAybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW\n//1IMwrh3KWBkJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7\nl7+ijrRU\n-----END CERTIFICATE-----\n\nDST Root CA X3\n==============\n-----BEGIN CERTIFICATE-----\nMIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/MSQwIgYDVQQK\nExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMTDkRTVCBSb290IENBIFgzMB4X\nDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVowPzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1\ncmUgVHJ1c3QgQ28uMRcwFQYDVQQDEw5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQAD\nggEPADCCAQoCggEBAN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmT\nrE4Orz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEqOLl5CjH9\nUL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9bxiqKqy69cK3FCxolkHRy\nxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40d\nutolucbY38EVAjqr2m7xPi71XAicPNaDaeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0T\nAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQ\nMA0GCSqGSIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69ikug\ndB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXrAvHRAosZy5Q6XkjE\nGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZzR8srzJmwN0jP41ZL9c8PDHIyh8bw\nRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubS\nfZGL+T0yjWW06XyxV3bqxbYoOb8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ\n-----END CERTIFICATE-----\n\nSwissSign Gold CA - G2\n======================\n-----BEGIN CERTIFICATE-----\nMIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkNIMRUw\nEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2lnbiBHb2xkIENBIC0gRzIwHhcN\nMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBFMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dp\nc3NTaWduIEFHMR8wHQYDVQQDExZTd2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0B\nAQEFAAOCAg8AMIICCgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUq\nt2/876LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+bbqBHH5C\njCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c6bM8K8vzARO/Ws/BtQpg\nvd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqEemA8atufK+ze3gE/bk3lUIbLtK/tREDF\nylqM2tIrfKjuvqblCqoOpd8FUrdVxyJdMmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvR\nAiTysybUa9oEVeXBCsdtMDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuend\njIj3o02yMszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69yFGkO\npeUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPiaG59je883WX0XaxR\n7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxMgI93e2CaHt+28kgeDrpOVG2Y4OGi\nGqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw\nAwEB/zAdBgNVHQ4EFgQUWyV7lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64\nOfPAeGZe6Drn8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov\nL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe645R88a7A3hfm\n5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczOUYrHUDFu4Up+GC9pWbY9ZIEr\n44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOf\nMke6UiI0HTJ6CVanfCU2qT1L2sCCbwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6m\nGu6uLftIdxf+u+yvGPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxp\nmo/a77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCChdiDyyJk\nvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid392qgQmwLOM7XdVAyksLf\nKzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEppLd6leNcG2mqeSz53OiATIgHQv2ieY2Br\nNU0LbbqhPcCT4H8js1WtciVORvnSFu+wZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6Lqj\nviOvrv1vA+ACOzB2+httQc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ\n-----END CERTIFICATE-----\n\nSwissSign Silver CA - G2\n========================\n-----BEGIN CERTIFICATE-----\nMIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCQ0gxFTAT\nBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMB4X\nDTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0NlowRzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3\naXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG\n9w0BAQEFAAOCAg8AMIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644\nN0MvFz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7brYT7QbNHm\n+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieFnbAVlDLaYQ1HTWBCrpJH\n6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH6ATK72oxh9TAtvmUcXtnZLi2kUpCe2Uu\nMGoM9ZDulebyzYLs2aFK7PayS+VFheZteJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5h\nqAaEuSh6XzjZG6k4sIN/c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5\nFZGkECwJMoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRHHTBs\nROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTfjNFusB3hB48IHpmc\ncelM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb65i/4z3GcRm25xBWNOHkDRUjvxF3X\nCO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/\nBAUwAwEB/zAdBgNVHQ4EFgQUF6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRB\ntjpbO8tFnb0cwpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0\ncDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBAHPGgeAn0i0P\n4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShpWJHckRE1qTodvBqlYJ7YH39F\nkWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L\n3XWgwF15kIwb4FDm3jH+mHtwX6WQ2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx\n/uNncqCxv1yL5PqZIseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFa\nDGi8aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2Xem1ZqSqP\ne97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQRdAtq/gsD/KNVV4n+Ssuu\nWxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJ\nDIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ub\nDgEj8Z+7fNzcbBGXJbLytGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u\n-----END CERTIFICATE-----\n\nGeoTrust Primary Certification Authority\n========================================\n-----BEGIN CERTIFICATE-----\nMIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQG\nEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMoR2VvVHJ1c3QgUHJpbWFyeSBD\nZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgx\nCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQ\ncmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB\nCgKCAQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9AWbK7hWN\nb6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjAZIVcFU2Ix7e64HXprQU9\nnceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE07e9GceBrAqg1cmuXm2bgyxx5X9gaBGge\nRwLmnWDiNpcB3841kt++Z8dtd1k7j53WkBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGt\ntm/81w7a4DSwDRp35+MImO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD\nAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJKoZI\nhvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ16CePbJC/kRYkRj5K\nTs4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl4b7UVXGYNTq+k+qurUKykG/g/CFN\nNWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6KoKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHa\nFloxt/m0cYASSJlyc1pZU8FjUjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG\n1riR/aYNKxoUAT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk=\n-----END CERTIFICATE-----\n\nthawte Primary Root CA\n======================\n-----BEGIN CERTIFICATE-----\nMIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCBqTELMAkGA1UE\nBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2\naWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv\ncml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3\nMDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwg\nSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMv\nKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMT\nFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCs\noPD7gFnUnMekz52hWXMJEEUMDSxuaPFsW0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ\n1CRfBsDMRJSUjQJib+ta3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGc\nq/gcfomk6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6Sk/K\naAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94JNqR32HuHUETVPm4p\nafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD\nVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XPr87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUF\nAAOCAQEAeRHAS7ORtvzw6WfUDW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeE\nuzLlQRHAd9mzYJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX\nxPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2/qxAeeWsEG89\njxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/LHbTY5xZ3Y+m4Q6gLkH3LpVH\nz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7jVaMaA==\n-----END CERTIFICATE-----\n\nVeriSign Class 3 Public Primary Certification Authority - G5\n============================================================\n-----BEGIN CERTIFICATE-----\nMIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE\nBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO\nZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk\nIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRp\nZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCB\nyjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln\nbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBh\ndXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmlt\nYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw\nggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKz\nj/i5Vbext0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhD\nY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/\nArr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNHiDxpg8v+R70r\nfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/\nBAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2Uv\nZ2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy\naXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG\nSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzEp6B4Eq1iDkVwZMXnl2YtmAl+\nX6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKE\nKQsTb47bDN0lAtukixlE0kF6BWlKWE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiC\nKm0oHw0LxOXnGiYZ4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vE\nZV8NhnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq\n-----END CERTIFICATE-----\n\nSecureTrust CA\n==============\n-----BEGIN CERTIFICATE-----\nMIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBIMQswCQYDVQQG\nEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xFzAVBgNVBAMTDlNlY3VyZVRy\ndXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIzMTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAe\nBgNVBAoTF1NlY3VyZVRydXN0IENvcnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCC\nASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQX\nOZEzZum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO0gMdA+9t\nDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIaowW8xQmxSPmjL8xk037uH\nGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b\n01k/unK8RCSc43Oz969XL0Imnal0ugBS8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmH\nursCAwEAAaOBnTCBmjATBgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/\nBAUwAwEB/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCegJYYj\naHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ\nKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt36Z3q059c4EVlew3KW+JwULKUBRSu\nSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHf\nmbx8IVQr5Fiiu1cprp6poxkmD5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZ\nnMUFdAvnZyPSCPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR\n3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE=\n-----END CERTIFICATE-----\n\nSecure Global CA\n================\n-----BEGIN CERTIFICATE-----\nMIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQG\nEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBH\nbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkxMjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEg\nMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwg\nQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jx\nYDiJiQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa/FHtaMbQ\nbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJjnIFHovdRIWCQtBJwB1g\n8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnIHmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYV\nHDGA76oYa8J719rO+TMg1fW9ajMtgQT7sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi\n0XPnj3pDAgMBAAGjgZ0wgZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud\nEwEB/wQFMAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCswKaAn\noCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsGAQQBgjcVAQQDAgEA\nMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0LURYD7xh8yOOvaliTFGCRsoTciE6+\nOYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXOH0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cn\nCDpOGR86p1hcF895P4vkp9MmI50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/5\n3CYNv6ZHdAbYiNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc\nf8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW\n-----END CERTIFICATE-----\n\nCOMODO Certification Authority\n==============================\n-----BEGIN CERTIFICATE-----\nMIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCBgTELMAkGA1UE\nBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG\nA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNVBAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1\ndGhvcml0eTAeFw0wNjEyMDEwMDAwMDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEb\nMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFD\nT01PRE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0aG9yaXR5\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3UcEbVASY06m/weaKXTuH\n+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI2GqGd0S7WWaXUF601CxwRM/aN5VCaTww\nxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV\n4EajcNxo2f8ESIl33rXp+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA\n1KGzqSX+DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5OnKVI\nrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW/zAOBgNVHQ8BAf8E\nBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLmNvbW9k\nb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOC\nAQEAPpiem/Yb6dc5t3iuHXIYSdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CP\nOGEIqB6BCsAvIC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/\nRxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4zJVSk/BwJVmc\nIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5ddBA6+C4OmF4O5MBKgxTMVBbkN\n+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IBZQ==\n-----END CERTIFICATE-----\n\nNetwork Solutions Certificate Authority\n=======================================\n-----BEGIN CERTIFICATE-----\nMIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQG\nEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydOZXR3b3Jr\nIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMx\nMjM1OTU5WjBiMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu\nMTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G\nCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwzc7MEL7xx\njOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPPOCwGJgl6cvf6UDL4wpPT\naaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rlmGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXT\ncrA/vGp97Eh/jcOrqnErU2lBUzS1sLnFBgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc\n/Qzpf14Dl847ABSHJ3A4qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMB\nAAGjgZcwgZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIBBjAP\nBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwubmV0c29sc3NsLmNv\nbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3JpdHkuY3JsMA0GCSqGSIb3DQEBBQUA\nA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc86fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q\n4LqILPxFzBiwmZVRDuwduIj/h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/\nGGUsyfJj4akH/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv\nwKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHNpGxlaKFJdlxD\nydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey\n-----END CERTIFICATE-----\n\nCOMODO ECC Certification Authority\n==================================\n-----BEGIN CERTIFICATE-----\nMIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTELMAkGA1UEBhMC\nR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE\nChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBB\ndXRob3JpdHkwHhcNMDgwMzA2MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0Ix\nGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR\nQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRo\nb3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSRFtSrYpn1PlILBs5BAH+X\n4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0JcfRK9ChQtP6IHG4/bC8vCVlbpVsLM5ni\nwz2J+Wos77LTBumjQjBAMB0GA1UdDgQWBBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8E\nBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VG\nFAkK+qDmfQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdvGDeA\nU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY=\n-----END CERTIFICATE-----\n\nOISTE WISeKey Global Root GA CA\n===============================\n-----BEGIN CERTIFICATE-----\nMIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCBijELMAkGA1UE\nBhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHlyaWdodCAoYykgMjAwNTEiMCAG\nA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBH\nbG9iYWwgUm9vdCBHQSBDQTAeFw0wNTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYD\nVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIw\nIAYDVQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5\nIEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy0+zAJs9\nNt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxRVVuuk+g3/ytr6dTqvirdqFEr12bDYVxg\nAsj1znJ7O7jyTmUIms2kahnBAbtzptf2w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbD\nd50kc3vkDIzh2TbhmYsFmQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ\n/yxViJGg4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t94B3R\nLoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw\nAwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ\nKoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOxSPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vIm\nMMkQyh2I+3QZH4VFvbBsUfk2ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4\n+vg1YFkCExh8vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa\nhNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZiFj4A4xylNoEY\nokxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ/L7fCg0=\n-----END CERTIFICATE-----\n\nCertigna\n========\n-----BEGIN CERTIFICATE-----\nMIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNVBAYTAkZSMRIw\nEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4XDTA3MDYyOTE1MTMwNVoXDTI3\nMDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwI\nQ2VydGlnbmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7q\nXOEm7RFHYeGifBZ4QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyH\nGxnygQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbwzBfsV1/p\nogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q130yGLMLLGq/jj8UEYkg\nDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKf\nIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQ\ntCRZvgHyUtVF9lo53BEwZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJ\nBgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzjAQ/J\nSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG9w0BAQUFAAOCAQEA\nhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8hbV6lUmPOEvjvKtpv6zf+EwLHyzs+\nImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFncfca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1klu\nPBS1xp81HlDQwY9qcEQCYsuuHWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY\n1gkIl2PlwS6wt0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw\nWyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg==\n-----END CERTIFICATE-----\n\nDeutsche Telekom Root CA 2\n==========================\n-----BEGIN CERTIFICATE-----\nMIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMT\nRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEG\nA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENBIDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5\nMjM1OTAwWjBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0G\nA1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBS\nb290IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEUha88EOQ5\nbzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhCQN/Po7qCWWqSG6wcmtoI\nKyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1MjwrrFDa1sPeg5TKqAyZMg4ISFZbavva4VhY\nAUlfckE8FQYBjl2tqriTtM2e66foai1SNNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aK\nSe5TBY8ZTNXeWHmb0mocQqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTV\njlsB9WoHtxa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAPBgNV\nHRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAlGRZrTlk5ynr\nE/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756AbrsptJh6sTtU6zkXR34ajgv8HzFZMQSy\nzhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpaIzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8\nrZ7/gFnkm0W09juwzTkZmDLl6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4G\ndyd1Lx+4ivn+xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU\nCm26OWMohpLzGITY+9HPBVZkVw==\n-----END CERTIFICATE-----\n\nCybertrust Global Root\n======================\n-----BEGIN CERTIFICATE-----\nMIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYGA1UEChMPQ3li\nZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBSb290MB4XDTA2MTIxNTA4\nMDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQD\nExZDeWJlcnRydXN0IEdsb2JhbCBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA\n+Mi8vRRQZhP/8NN57CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW\n0ozSJ8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2yHLtgwEZL\nAfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iPt3sMpTjr3kfb1V05/Iin\n89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNzFtApD0mpSPCzqrdsxacwOUBdrsTiXSZT\n8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAYXSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAP\nBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2\nMDSgMqAwhi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3JsMB8G\nA1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUAA4IBAQBW7wojoFRO\nlZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMjWqd8BfP9IjsO0QbE2zZMcwSO5bAi\n5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUxXOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2\nhO0j9n0Hq0V+09+zv+mKts2oomcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+T\nX3EJIrduPuocA06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW\nWL1WMRJOEcgh4LMRkWXbtKaIOM5V\n-----END CERTIFICATE-----\n\nePKI Root Certification Authority\n=================================\n-----BEGIN CERTIFICATE-----\nMIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQG\nEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0ZC4xKjAoBgNVBAsMIWVQS0kg\nUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMx\nMjdaMF4xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEq\nMCgGA1UECwwhZVBLSSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0B\nAQEFAAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAHSyZbCUNs\nIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAhijHyl3SJCRImHJ7K2RKi\nlTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3XDZoTM1PRYfl61dd4s5oz9wCGzh1NlDiv\nqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX\n12ruOzjjK9SXDrkb5wdJfzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0O\nWQqraffAsgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uUWH1+\nETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLSnT0IFaUQAS2zMnao\nlQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pHdmX2Os+PYhcZewoozRrSgx4hxyy/\nvv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJipNiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXi\nZo1jDiVN1Rmy5nk3pyKdVDECAwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/Qkqi\nMAwGA1UdEwQFMAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH\nClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGBuvl2ICO1J2B0\n1GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6YlPwZpVnPDimZI+ymBV3QGypzq\nKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkPJXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdV\nxrsStZf0X4OFunHB2WyBEXYKCrC/gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEP\nNXubrjlpC2JgQCA2j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+r\nGNm65ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUBo2M3IUxE\nxJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS/jQ6fbjpKdx2qcgw+BRx\ngMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2zGp1iro2C6pSe3VkQw63d4k3jMdXH7Ojy\nsP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTEW9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmOD\nBCEIZ43ygknQW/2xzQ+DhNQ+IIX3Sj0rnP0qCglN6oH4EZw=\n-----END CERTIFICATE-----\n\ncertSIGN ROOT CA\n================\n-----BEGIN CERTIFICATE-----\nMIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYTAlJPMREwDwYD\nVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTAeFw0wNjA3MDQxNzIwMDRa\nFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UE\nCxMQY2VydFNJR04gUk9PVCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7I\nJUqOtdu0KBuqV5Do0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHH\nrfAQUySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5dRdY4zTW2\nssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQOA7+j0xbm0bqQfWwCHTD\n0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwvJoIQ4uNllAoEwF73XVv4EOLQunpL+943\nAAAaWyjj0pxzPjKHmKHJUS/X3qwzs08CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B\nAf8EBAMCAcYwHQYDVR0OBBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IB\nAQA+0hyJLjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecYMnQ8\nSG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ44gx+FkagQnIl6Z0\nx2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6IJd1hJyMctTEHBDa0GpC9oHRxUIlt\nvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNwi/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7Nz\nTogVZ96edhBiIL5VaZVDADlN9u6wWk5JRFRYX0KD\n-----END CERTIFICATE-----\n\nGeoTrust Primary Certification Authority - G3\n=============================================\n-----BEGIN CERTIFICATE-----\nMIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UE\nBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA4IEdlb1RydXN0\nIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFy\neSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIz\nNTk1OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAo\nYykgMjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMT\nLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZI\nhvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz+uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5j\nK/BGvESyiaHAKAxJcCGVn2TAppMSAmUmhsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdE\nc5IiaacDiGydY8hS2pgn5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3C\nIShwiP/WJmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exALDmKu\ndlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZChuOl1UcCAwEAAaNC\nMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMR5yo6hTgMdHNxr\n2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IBAQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9\ncr5HqQ6XErhK8WTTOd8lNNTBzU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbE\nAp7aDHdlDkQNkv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD\nAWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUHSJsMC8tJP33s\nt/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2Gspki4cErx5z481+oghLrGREt\n-----END CERTIFICATE-----\n\nthawte Primary Root CA - G2\n===========================\n-----BEGIN CERTIFICATE-----\nMIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDELMAkGA1UEBhMC\nVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMpIDIwMDcgdGhhd3RlLCBJbmMu\nIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3Qg\nQ0EgLSBHMjAeFw0wNzExMDUwMDAwMDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEV\nMBMGA1UEChMMdGhhd3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBG\nb3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAt\nIEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/BebfowJPDQfGAFG6DAJS\nLSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6papu+7qzcMBniKI11KOasf2twu8x+qi5\n8/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU\nmtgAMADna3+FGO6Lts6KDPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUN\nG4k8VIZ3KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41oxXZ3K\nrr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg==\n-----END CERTIFICATE-----\n\nthawte Primary Root CA - G3\n===========================\n-----BEGIN CERTIFICATE-----\nMIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCBrjELMAkGA1UE\nBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2\naWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv\ncml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0w\nODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh\nd3RlLCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uMTgwNgYD\nVQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIG\nA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\nMIIBCgKCAQEAsr8nLPvb2FvdeHsbnndmgcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2At\nP0LMqmsywCPLLEHd5N/8YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC\n+BsUa0Lfb1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS99irY\n7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2SzhkGcuYMXDhpxwTW\nvGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUkOQIDAQABo0IwQDAPBgNVHRMBAf8E\nBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJ\nKoZIhvcNAQELBQADggEBABpA2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweK\nA3rD6z8KLFIWoCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu\nt8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7cKUGRIjxpp7sC\n8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fMm7v/OeZWYdMKp8RcTGB7BXcm\ner/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZuMdRAGmI0Nj81Aa6sY6A=\n-----END CERTIFICATE-----\n\nGeoTrust Primary Certification Authority - G2\n=============================================\n-----BEGIN CERTIFICATE-----\nMIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDELMAkGA1UEBhMC\nVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA3IEdlb1RydXN0IElu\nYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBD\nZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1\nOVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg\nMjAwNyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMTLUdl\nb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjB2MBAGByqGSM49AgEG\nBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcLSo17VDs6bl8VAsBQps8lL33KSLjHUGMc\nKiEIfJo22Av+0SbFWDEwKCXzXV2juLaltJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYD\nVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+\nEVXVMAoGCCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGTqQ7m\nndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBuczrD6ogRLQy7rQkgu2\nnpaqBA+K\n-----END CERTIFICATE-----\n\nVeriSign Universal Root Certification Authority\n===============================================\n-----BEGIN CERTIFICATE-----\nMIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCBvTELMAkGA1UE\nBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO\nZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk\nIHVzZSBvbmx5MTgwNgYDVQQDEy9WZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9u\nIEF1dGhvcml0eTAeFw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJV\nUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv\ncmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl\nIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0\naG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj\n1mCOkdeQmIN65lgZOIzF9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGP\nMiJhgsWHH26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+HLL72\n9fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN/BMReYTtXlT2NJ8I\nAfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPTrJ9VAMf2CGqUuV/c4DPxhGD5WycR\ntPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0G\nCCsGAQUFBwEMBGEwX6FdoFswWTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2O\na8PPgGrUSBgsexkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud\nDgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4sAPmLGd75JR3\nY8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+seQxIcaBlVZaDrHC1LGmWazx\nY8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTx\nP/jgdFcrGJ2BtMQo2pSXpXDrrB2+BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+P\nwGZsY6rp2aQW9IHRlRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4\nmJO37M2CYfE45k+XmCpajQ==\n-----END CERTIFICATE-----\n\nVeriSign Class 3 Public Primary Certification Authority - G4\n============================================================\n-----BEGIN CERTIFICATE-----\nMIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjELMAkGA1UEBhMC\nVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3\nb3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVz\nZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmlj\nYXRpb24gQXV0aG9yaXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjEL\nMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBU\ncnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRo\nb3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5\nIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8\nUtpkmw4tXNherJI9/gHmGUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGz\nrl0Bp3vefLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUwAwEB\n/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEw\nHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24u\nY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMWkf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMD\nA2gAMGUCMGYhDBgmYFo4e1ZC4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIx\nAJw9SDkjOVgaFRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA==\n-----END CERTIFICATE-----\n\nNetLock Arany (Class Gold) Főtanúsítvány\n========================================\n-----BEGIN CERTIFICATE-----\nMIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQGEwJIVTERMA8G\nA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3MDUGA1UECwwuVGFuw7pzw610\ndsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBB\ncmFueSAoQ2xhc3MgR29sZCkgRsWRdGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgx\nMjA2MTUwODIxWjCBpzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxO\nZXRMb2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlmaWNhdGlv\nbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNzIEdvbGQpIEbFkXRhbsO6\nc8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxCRec75LbRTDofTjl5Bu\n0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrTlF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw\n/HpYzY6b7cNGbIRwXdrzAZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAk\nH3B5r9s5VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRGILdw\nfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2BJtr+UBdADTHLpl1\nneWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAGAQH/AgEEMA4GA1UdDwEB/wQEAwIB\nBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2MU9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwW\nqZw8UQCgwBEIBaeZ5m8BiFRhbvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTta\nYtOUZcTh5m2C+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC\nbLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2FuLjbvrW5Kfna\nNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu\ndZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E=\n-----END CERTIFICATE-----\n\nStaat der Nederlanden Root CA - G2\n==================================\n-----BEGIN CERTIFICATE-----\nMIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJOTDEeMBwGA1UE\nCgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFhdCBkZXIgTmVkZXJsYW5kZW4g\nUm9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oXDTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMC\nTkwxHjAcBgNVBAoMFVN0YWF0IGRlciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5l\nZGVybGFuZGVuIFJvb3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ\n5291qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8SpuOUfiUtn\nvWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPUZ5uW6M7XxgpT0GtJlvOj\nCwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvEpMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiil\ne7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCR\nOME4HYYEhLoaJXhena/MUGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpI\nCT0ugpTNGmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy5V65\n48r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv6q012iDTiIJh8BIi\ntrzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEKeN5KzlW/HdXZt1bv8Hb/C3m1r737\nqWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMB\nAAGjgZcwgZQwDwYDVR0TAQH/BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcC\nARYxaHR0cDovL3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV\nHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqGSIb3DQEBCwUA\nA4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLySCZa59sCrI2AGeYwRTlHSeYAz\n+51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwj\nf/ST7ZwaUb7dRUG/kSS0H4zpX897IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaN\nkqbG9AclVMwWVxJKgnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfk\nCpYL+63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxLvJxxcypF\nURmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkmbEgeqmiSBeGCc1qb3Adb\nCG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvkN1trSt8sV4pAWja63XVECDdCcAz+3F4h\noKOKwJCcaNpQ5kUQR3i2TtJlycM33+FCY7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoV\nIPVVYpbtbZNQvOSqeK3Zywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm\n66+KAQ==\n-----END CERTIFICATE-----\n\nHongkong Post Root CA 1\n=======================\n-----BEGIN CERTIFICATE-----\nMIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoT\nDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMB4XDTAzMDUx\nNTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25n\nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEF\nAAOCAQ8AMIIBCgKCAQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1\nApzQjVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEnPzlTCeqr\nauh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjhZY4bXSNmO7ilMlHIhqqh\nqZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9nnV0ttgCXjqQesBCNnLsak3c78QA3xMY\nV18meMjWCnl3v/evt3a5pQuEF10Q6m/hq5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNV\nHRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7i\nh9legYsCmEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI37pio\nl7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clBoiMBdDhViw+5Lmei\nIAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJsEhTkYY2sEJCehFC78JZvRZ+K88ps\nT/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpOfMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilT\nc4afU9hDDl3WY4JxHYB0yvbiAmvZWg==\n-----END CERTIFICATE-----\n\nSecureSign RootCA11\n===================\n-----BEGIN CERTIFICATE-----\nMIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDErMCkGA1UEChMi\nSmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoGA1UEAxMTU2VjdXJlU2lnbiBS\nb290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSsw\nKQYDVQQKEyJKYXBhbiBDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1\ncmVTaWduIFJvb3RDQTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvL\nTJszi1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8h9uuywGO\nwvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOVMdrAG/LuYpmGYz+/3ZMq\ng6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rP\nO7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitA\nbpSACW22s293bzUIUPsCh8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZX\nt94wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAKCh\nOBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xmKbabfSVSSUOrTC4r\nbnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQX5Ucv+2rIrVls4W6ng+4reV6G4pQ\nOh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWrQbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01\ny8hSyn+B/tlr0/cR7SXf+Of5pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061\nlgeLKBObjBmNQSdJQO7e5iNEOdyhIta6A/I=\n-----END CERTIFICATE-----\n\nMicrosec e-Szigno Root CA 2009\n==============================\n-----BEGIN CERTIFICATE-----\nMIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYDVQQGEwJIVTER\nMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jv\nc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o\ndTAeFw0wOTA2MTYxMTMwMThaFw0yOTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UE\nBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUt\nU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTCCASIw\nDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvPkd6mJviZpWNwrZuuyjNA\nfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tccbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG\n0IMZfcChEhyVbUr02MelTTMuhTlAdX4UfIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKA\npxn1ntxVUwOXewdI/5n7N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm\n1HxdrtbCxkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1+rUC\nAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTLD8bf\nQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAbBgNVHREE\nFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqGSIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0o\nlZMEyL/azXm4Q5DwpL7v8u8hmLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfX\nI/OMn74dseGkddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775\ntyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c2Pm2G2JwCz02\nyULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5tHMN1Rq41Bab2XD0h7lbwyYIi\nLXpUq3DDfSJlgnCW\n-----END CERTIFICATE-----\n\nGlobalSign Root CA - R3\n=======================\n-----BEGIN CERTIFICATE-----\nMIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4GA1UECxMXR2xv\nYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh\nbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT\naWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln\nbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWt\niHL8RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsTgHeMCOFJ\n0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmmKPZpO/bLyCiR5Z2KYVc3\nrHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zdQQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjl\nOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZXriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2\nxmmFghcCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE\nFI/wS3+oLkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZURUm7\nlgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMpjjM5RcOO5LlXbKr8\nEpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK6fBdRoyV3XpYKBovHd7NADdBj+1E\nbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQXmcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18\nYIvDQVETI53O9zJrlAGomecsMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7r\nkpeDMdmztcpHWD9f\n-----END CERTIFICATE-----\n\nAutoridad de Certificacion Firmaprofesional CIF A62634068\n=========================================================\n-----BEGIN CERTIFICATE-----\nMIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UEBhMCRVMxQjBA\nBgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2\nMjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEyMzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIw\nQAYDVQQDDDlBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBB\nNjI2MzQwNjgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDD\nUtd9thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQMcas9UX4P\nB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefGL9ItWY16Ck6WaVICqjaY\n7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15iNA9wBj4gGFrO93IbJWyTdBSTo3OxDqqH\nECNZXyAFGUftaI6SEspd/NYrspI8IM/hX68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyI\nplD9amML9ZMWGxmPsu2bm8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctX\nMbScyJCyZ/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirjaEbsX\nLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/TKI8xWVvTyQKmtFLK\nbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF6NkBiDkal4ZkQdU7hwxu+g/GvUgU\nvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVhOSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1Ud\nEwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNH\nDhpkLzCBpgYDVR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp\ncm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBvACAAZABlACAA\nbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBlAGwAbwBuAGEAIAAwADgAMAAx\nADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx\n51tkljYyGOylMnfX40S2wBEqgLk9am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qk\nR71kMrv2JYSiJ0L1ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaP\nT481PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS3a/DTg4f\nJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5kSeTy36LssUzAKh3ntLFl\nosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF3dvd6qJ2gHN99ZwExEWN57kci57q13XR\ncrHedUTnQn3iV2t93Jm8PYMo6oCTjcVMZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoR\nsaS8I8nkvof/uZS2+F0gStRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTD\nKCOM/iczQ0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQBjLMi\n6Et8Vcad+qMUu2WFbm5PEn4KPJ2V\n-----END CERTIFICATE-----\n\nIzenpe.com\n==========\n-----BEGIN CERTIFICATE-----\nMIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4MQswCQYDVQQG\nEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wHhcNMDcxMjEz\nMTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMu\nQS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ\n03rKDx6sp4boFmVqscIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAK\nClaOxdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6HLmYRY2xU\n+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFXuaOKmMPsOzTFlUFpfnXC\nPCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQDyCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxT\nOTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbK\nF7jJeodWLBoBHmy+E60QrLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK\n0GqfvEyNBjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8Lhij+\n0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIBQFqNeb+Lz0vPqhbB\nleStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+HMh3/1uaD7euBUbl8agW7EekFwID\nAQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2luZm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+\nSVpFTlBFIFMuQS4gLSBDSUYgQTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBG\nNjIgUzgxQzBBBgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx\nMCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O\nBBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUAA4ICAQB4pgwWSp9MiDrAyw6l\nFn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWblaQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbga\nkEyrkgPH7UIBzg/YsfqikuFgba56awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8q\nhT/AQKM6WfxZSzwoJNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Cs\ng1lwLDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCTVyvehQP5\naTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGkLhObNA5me0mrZJfQRsN5\nnXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJbUjWumDqtujWTI6cfSN01RpiyEGjkpTHC\nClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZo\nQ0iy2+tzJOeRf1SktoA+naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1Z\nWrOZyGlsQyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw==\n-----END CERTIFICATE-----\n\nChambers of Commerce Root - 2008\n================================\n-----BEGIN CERTIFICATE-----\nMIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYDVQQGEwJFVTFD\nMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv\nbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu\nQS4xKTAnBgNVBAMTIENoYW1iZXJzIG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEy\nMjk1MFoXDTM4MDczMTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNl\nZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQF\nEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJl\ncnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC\nAQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW928sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKA\nXuFixrYp4YFs8r/lfTJqVKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorj\nh40G072QDuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR5gN/\nikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfLZEFHcpOrUMPrCXZk\nNNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05aSd+pZgvMPMZ4fKecHePOjlO+Bd5g\nD2vlGts/4+EhySnB8esHnFIbAURRPHsl18TlUlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331\nlubKgdaX8ZSD6e2wsWsSaR6s+12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ\n0wlf2eOKNcx5Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj\nya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAxhduub+84Mxh2\nEQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNVHQ4EFgQU+SSsD7K1+HnA+mCI\nG8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1+HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJ\nBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNh\nbWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENh\nbWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDiC\nCQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUH\nAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAJASryI1\nwqM58C7e6bXpeHxIvj99RZJe6dqxGfwWPJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH\n3qLPaYRgM+gQDROpI9CF5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbU\nRWpGqOt1glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaHFoI6\nM6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2pSB7+R5KBWIBpih1\nYJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MDxvbxrN8y8NmBGuScvfaAFPDRLLmF\n9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QGtjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcK\nzBIKinmwPQN/aUv0NCB9szTqjktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvG\nnrDQWzilm1DefhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg\nOGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZd0jQ\n-----END CERTIFICATE-----\n\nGlobal Chambersign Root - 2008\n==============================\n-----BEGIN CERTIFICATE-----\nMIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYDVQQGEwJFVTFD\nMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv\nbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu\nQS4xJzAlBgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMx\nNDBaFw0zODA3MzExMjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUg\nY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJ\nQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD\naGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDf\nVtPkOpt2RbQT2//BthmLN0EYlVJH6xedKYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXf\nXjaOcNFccUMd2drvXNL7G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0\nZJJ0YPP2zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4ddPB\n/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyGHoiMvvKRhI9lNNgA\nTH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2Id3UwD2ln58fQ1DJu7xsepeY7s2M\nH/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3VyJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfe\nOx2YItaswTXbo6Al/3K1dh3ebeksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSF\nHTynyQbehP9r6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh\nwZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsogzCtLkykPAgMB\nAAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQWBBS5CcqcHtvTbDprru1U8VuT\nBjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDprru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UE\nBhMCRVUxQzBBBgNVBAcTOk1hZHJpZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJm\naXJtYS5jb20vYWRkcmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJm\naXJtYSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiCCQDJzdPp\n1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0\ndHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAICIf3DekijZBZRG\n/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZUohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6\nReAJ3spED8IXDneRRXozX1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/s\ndZ7LoR/xfxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVza2Mg\n9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yydYhz2rXzdpjEetrHH\nfoUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMdSqlapskD7+3056huirRXhOukP9Du\nqqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9OAP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETr\nP3iZ8ntxPjzxmKfFGBI/5rsoM0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVq\nc5iJWzouE4gev8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z\n09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B\n-----END CERTIFICATE-----\n\nGo Daddy Root Certificate Authority - G2\n========================================\n-----BEGIN CERTIFICATE-----\nMIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT\nB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHkuY29tLCBJbmMu\nMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5\nMDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6\nb25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8G\nA1UEAxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI\nhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKDE6bFIEMBO4Tx5oVJnyfq\n9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD\n+qK+ihVqf94Lw7YZFAXK6sOoBJQ7RnwyDfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutd\nfMh8+7ArU6SSYmlRJQVhGkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMl\nNAJWJwGRtDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEAAaNC\nMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9\nBUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmXWWcDYfF+OwYxdS2hII5PZYe096ac\nvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r\n5N9ss4UXnT3ZJE95kTXWXwTrgIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYV\nN8Gb5DKj7Tjo2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO\nLPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI4uJEvlz36hz1\n-----END CERTIFICATE-----\n\nStarfield Root Certificate Authority - G2\n=========================================\n-----BEGIN CERTIFICATE-----\nMIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT\nB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s\nb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVsZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0\neSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAw\nDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQg\nVGVjaG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZpY2F0ZSBB\ndXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3twQP89o/8ArFv\nW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMgnLRJdzIpVv257IzdIvpy3Cdhl+72WoTs\nbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNk\nN3mSwOxGXn/hbVNMYq/NHwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7Nf\nZTD4p7dNdloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0HZbU\nJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\nAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0GCSqGSIb3DQEBCwUAA4IBAQARWfol\nTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjUsHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx\n4mcujJUDJi5DnUox9g61DLu34jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUw\nF5okxBDgBPfg8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K\npL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1mMpYjn0q7pBZ\nc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0\n-----END CERTIFICATE-----\n\nStarfield Services Root Certificate Authority - G2\n==================================================\n-----BEGIN CERTIFICATE-----\nMIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMxEDAOBgNVBAgT\nB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s\nb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVsZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRl\nIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNV\nBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxT\ndGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2VydmljZXMg\nUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC\nAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20pOsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2\nh/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm28xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4Pa\nhHQUw2eeBGg6345AWh1KTs9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLP\nLJGmpufehRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk6mFB\nrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAwDwYDVR0TAQH/BAUw\nAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+qAdcwKziIorhtSpzyEZGDMA0GCSqG\nSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMIbw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPP\nE95Dz+I0swSdHynVv/heyNXBve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTy\nxQGjhdByPq1zqwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd\niEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn0q23KXB56jza\nYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCNsSi6\n-----END CERTIFICATE-----\n\nAffirmTrust Commercial\n======================\n-----BEGIN CERTIFICATE-----\nMIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCVVMxFDAS\nBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMB4XDTEw\nMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly\nbVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEF\nAAOCAQ8AMIIBCgKCAQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6Eqdb\nDuKPHx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yrba0F8PrV\nC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPALMeIrJmqbTFeurCA+ukV6\nBfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1yHp52UKqK39c/s4mT6NmgTWvRLpUHhww\nMmWd5jyTXlBOeuM61G7MGvv50jeuJCqrVwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNV\nHQ4EFgQUnZPGU4teyq8/nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\nAQYwDQYJKoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYGXUPG\nhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNjvbz4YYCanrHOQnDi\nqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivtZ8SOyUOyXGsViQK8YvxO8rUzqrJv\n0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9gN53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0kh\nsUlHRUe072o0EclNmsxZt9YCnlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8=\n-----END CERTIFICATE-----\n\nAffirmTrust Networking\n======================\n-----BEGIN CERTIFICATE-----\nMIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UEBhMCVVMxFDAS\nBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMB4XDTEw\nMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly\nbVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEF\nAAOCAQ8AMIIBCgKCAQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SE\nHi3yYJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbuakCNrmreI\ndIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRLQESxG9fhwoXA3hA/Pe24\n/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gb\nh+0t+nvujArjqWaJGctB+d1ENmHP4ndGyH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNV\nHQ4EFgQUBx/S55zawm6iQLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\nAQYwDQYJKoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfOtDIu\nUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzuQY0x2+c06lkh1QF6\n12S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZLgo/bNjR9eUJtGxUAArgFU2HdW23\nWJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4uolu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9\n/ZFvgrG+CJPbFEfxojfHRZ48x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s=\n-----END CERTIFICATE-----\n\nAffirmTrust Premium\n===================\n-----BEGIN CERTIFICATE-----\nMIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UEBhMCVVMxFDAS\nBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMB4XDTEwMDEy\nOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRy\ndXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A\nMIICCgKCAgEAxBLfqV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtn\nBKAQJG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ+jjeRFcV\n5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrSs8PhaJyJ+HoAVt70VZVs\n+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmd\nGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d770O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5R\np9EixAqnOEhss/n/fauGV+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NI\nS+LI+H+SqHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S5u04\n6uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4IaC1nEWTJ3s7xgaVY5\n/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TXOwF0lkLgAOIua+rF7nKsu7/+6qqo\n+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYEFJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB\n/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByv\nMiPIs0laUZx2KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg\nNt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B8OWycvpEgjNC\n6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQMKSOyARiqcTtNd56l+0OOF6S\nL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK\n+4w1IX2COPKpVJEZNZOUbWo6xbLQu4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmV\nBtWVyuEklut89pMFu+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFg\nIxpHYoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8GKa1qF60\ng2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaORtGdFNrHF+QFlozEJLUb\nzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6eKeC2uAloGRwYQw==\n-----END CERTIFICATE-----\n\nAffirmTrust Premium ECC\n=======================\n-----BEGIN CERTIFICATE-----\nMIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMCVVMxFDASBgNV\nBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQcmVtaXVtIEVDQzAeFw0xMDAx\nMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1U\ncnVzdDEgMB4GA1UEAwwXQWZmaXJtVHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQA\nIgNiAAQNMF4bFZ0D0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQ\nN8O9ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0GA1UdDgQW\nBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAK\nBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/VsaobgxCd05DhT1wV/GzTjxi+zygk8N53X\n57hG8f2h4nECMEJZh0PUUd+60wkyWs6Iflc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKM\neQ==\n-----END CERTIFICATE-----\n\nCertum Trusted Network CA\n=========================\n-----BEGIN CERTIFICATE-----\nMIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBMMSIwIAYDVQQK\nExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlv\nbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBUcnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIy\nMTIwNzM3WhcNMjkxMjMxMTIwNzM3WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBU\nZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5\nMSIwIAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC\nAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rHUV+rpDKmYYe2bg+G0jAC\nl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LMTXPb865Px1bVWqeWifrzq2jUI4ZZJ88J\nJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVUBBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4\nfOQtf/WsX+sWn7Et0brMkUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0\ncvW0QM8xAcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNVHRMB\nAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNVHQ8BAf8EBAMCAQYw\nDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15ysHhE49wcrwn9I0j6vSrEuVUEtRCj\njSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfLI9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1\nmS1FhIrlQgnXdAIv94nYmem8J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5aj\nZt3hrvJBW8qYVoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI\n03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw=\n-----END CERTIFICATE-----\n\nTWCA Root Certification Authority\n=================================\n-----BEGIN CERTIFICATE-----\nMIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJ\nVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlmaWNh\ndGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMzWhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQG\nEwJUVzESMBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NB\nIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK\nAoIBAQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFEAcK0HMMx\nQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HHK3XLfJ+utdGdIzdjp9xC\noi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeXRfwZVzsrb+RH9JlF/h3x+JejiB03HFyP\n4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/zrX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1r\ny+UPizgN7gr8/g+YnzAx3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIB\nBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkqhkiG\n9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeCMErJk/9q56YAf4lC\nmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdlsXebQ79NqZp4VKIV66IIArB6nCWlW\nQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62Dlhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVY\nT0bf+215WfKEIlKuD8z7fDvnaspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocny\nYh0igzyXxfkZYiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw==\n-----END CERTIFICATE-----\n\nSecurity Communication RootCA2\n==============================\n-----BEGIN CERTIFICATE-----\nMIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDElMCMGA1UEChMc\nU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMeU2VjdXJpdHkgQ29tbXVuaWNh\ndGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoXDTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMC\nSlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3Vy\naXR5IENvbW11bmljYXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\nANAVOVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGrzbl+dp++\n+T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVMVAX3NuRFg3sUZdbcDE3R\n3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQhNBqyjoGADdH5H5XTz+L62e4iKrFvlNV\nspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWOojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1K\nEOtOghY6rCcMU/Gt1SSwawNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8\nQIH4D5csOPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB\nCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpFcoJxDjrSzG+ntKEj\nu/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXcokgfGT+Ok+vx+hfuzU7jBBJV1uXk\n3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6q\ntnRGEmyR7jTV7JqR50S+kDFy1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29\nmvVXIwAHIRc/SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03\n-----END CERTIFICATE-----\n\nEC-ACC\n======\n-----BEGIN CERTIFICATE-----\nMIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB8zELMAkGA1UE\nBhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2VydGlmaWNhY2lvIChOSUYgUS0w\nODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYD\nVQQLEyxWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UE\nCxMsSmVyYXJxdWlhIEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMT\nBkVDLUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQGEwJFUzE7\nMDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8gKE5JRiBRLTA4MDExNzYt\nSSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBDZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZl\nZ2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQubmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJh\ncnF1aWEgRW50aXRhdHMgZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUND\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R85iK\nw5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm4CgPukLjbo73FCeT\nae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaVHMf5NLWUhdWZXqBIoH7nF2W4onW4\nHvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNdQlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0a\nE9jD2z3Il3rucO2n5nzbcc8tlGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw\n0JDnJwIDAQABo4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E\nBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4opvpXY0wfwYD\nVR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBodHRwczovL3d3dy5jYXRjZXJ0\nLm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5l\ndC92ZXJhcnJlbCAwDQYJKoZIhvcNAQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJ\nlF7W2u++AVtd0x7Y/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNa\nAl6kSBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhyRp/7SNVe\nl+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOSAgu+TGbrIP65y7WZf+a2\nE/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xlnJ2lYJU6Un/10asIbvPuW/mIPX64b24D\n5EI=\n-----END CERTIFICATE-----\n\nHellenic Academic and Research Institutions RootCA 2011\n=======================================================\n-----BEGIN CERTIFICATE-----\nMIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1IxRDBCBgNVBAoT\nO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9y\naXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z\nIFJvb3RDQSAyMDExMB4XDTExMTIwNjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYT\nAkdSMUQwQgYDVQQKEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z\nIENlcnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNo\nIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\nAKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPzdYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI\n1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJfel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa\n71HFK9+WXesyHgLacEnsbgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u\n8yBRQlqD75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSPFEDH\n3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNVHRMBAf8EBTADAQH/\nMAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp5dgTBCPuQSUwRwYDVR0eBEAwPqA8\nMAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQub3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQu\nb3JnMA0GCSqGSIb3DQEBBQUAA4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVt\nXdMiKahsog2p6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8\nTqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7dIsXRSZMFpGD\n/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8AcysNnq/onN694/BtZqhFLKPM58N\n7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXIl7WdmplNsDz4SgCbZN2fOUvRJ9e4\n-----END CERTIFICATE-----\n\nActalis Authentication Root CA\n==============================\n-----BEGIN CERTIFICATE-----\nMIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UEBhMCSVQxDjAM\nBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UE\nAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDky\nMjExMjIwMlowazELMAkGA1UEBhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlz\nIFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290\nIENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNvUTufClrJ\nwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX4ay8IMKx4INRimlNAJZa\nby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9KK3giq0itFZljoZUj5NDKd45RnijMCO6\nzfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1f\nYVEiVRvjRuPjPdA1YprbrxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2\noxgkg4YQ51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2Fbe8l\nEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxeKF+w6D9Fz8+vm2/7\nhNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4Fv6MGn8i1zeQf1xcGDXqVdFUNaBr8\nEBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbnfpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5\njF66CyCU3nuDuP/jVo23Eek7jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLY\niDrIn3hm7YnzezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt\nifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQALe3KHwGCmSUyI\nWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70jsNjLiNmsGe+b7bAEzlgqqI0\nJZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDzWochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKx\nK3JCaKygvU5a2hi/a5iB0P2avl4VSM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+\nXlff1ANATIGk0k9jpwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC\n4yyXX04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+OkfcvHlXHo\n2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7RK4X9p2jIugErsWx0Hbhz\nlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btUZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXem\nOR/qnuOf0GZvBeyqdn6/axag67XH/JJULysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9\nvwGYT7JZVEc+NHt4bVaTLnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg==\n-----END CERTIFICATE-----\n\nTrustis FPS Root CA\n===================\n-----BEGIN CERTIFICATE-----\nMIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQG\nEwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQLExNUcnVzdGlzIEZQUyBSb290\nIENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTExMzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNV\nBAoTD1RydXN0aXMgTGltaXRlZDEcMBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJ\nKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQ\nRUN+AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihHiTHcDnlk\nH5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjjvSkCqPoc4Vu5g6hBSLwa\ncY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zt\no3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlBOrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEA\nAaNTMFEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAd\nBgNVHQ4EFgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01GX2c\nGE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmWzaD+vkAMXBJV+JOC\nyinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP41BIy+Q7DsdwyhEQsb8tGD+pmQQ9P\n8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZEf1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHV\nl/9D7S3B2l0pKoU/rGXuhg8FjZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYl\niB6XzCGcKQENZetX2fNXlrtIzYE=\n-----END CERTIFICATE-----\n\nBuypass Class 2 Root CA\n=======================\n-----BEGIN CERTIFICATE-----\nMIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU\nQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMiBSb290IENBMB4X\nDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1owTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1\neXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIw\nDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1\ng1Lr6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPVL4O2fuPn\n9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC911K2GScuVr1QGbNgGE41b\n/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHxMlAQTn/0hpPshNOOvEu/XAFOBz3cFIqU\nCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZQmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeff\nawrbD02TTqigzXsu8lkBarcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgI\nzRFo1clrUs3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLiFRhn\nBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRSP/TizPJhk9H9Z2vX\nUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN9SG9dKpN6nIDSdvHXx1iY8f93ZHs\nM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxPAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD\nVR0OBBYEFMmAd+BikoL1RpzzuvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF\nAAOCAgEAU18h9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s\nA20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3tOluwlN5E40EI\nosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo+fsicdl9sz1Gv7SEr5AcD48S\naq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYd\nDnkM/crqJIByw5c/8nerQyIKx+u2DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWD\nLfJ6v9r9jv6ly0UsH8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0\noyLQI+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK75t98biGC\nwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h3PFaTWwyI0PurKju7koS\nCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPzY11aWOIv4x3kqdbQCtCev9eBCfHJxyYN\nrJgWVqA=\n-----END CERTIFICATE-----\n\nBuypass Class 3 Root CA\n=======================\n-----BEGIN CERTIFICATE-----\nMIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU\nQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMyBSb290IENBMB4X\nDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFowTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1\neXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIw\nDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRH\nsJ8YZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3EN3coTRiR\n5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9tznDDgFHmV0ST9tD+leh\n7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX0DJq1l1sDPGzbjniazEuOQAnFN44wOwZ\nZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH\n2xc519woe2v1n/MuwU8XKhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV\n/afmiSTYzIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvSO1UQ\nRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D34xFMFbG02SrZvPA\nXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgPK9Dx2hzLabjKSWJtyNBjYt1gD1iq\nj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD\nVR0OBBYEFEe4zf/lb+74suwvTg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF\nAAOCAgEAACAjQTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV\ncSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXSIGrs/CIBKM+G\nuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2HJLw5QY33KbmkJs4j1xrG0aG\nQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsaO5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8\nZORK15FTAaggiG6cX0S5y2CBNOxv033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2\nKSb12tjE8nVhz36udmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz\n6MkEkbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg413OEMXbug\nUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvDu79leNKGef9JOxqDDPDe\neOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq4/g7u9xN12TyUb7mqqta6THuBrxzvxNi\nCp/HuZc=\n-----END CERTIFICATE-----\n\nT-TeleSec GlobalRoot Class 3\n============================\n-----BEGIN CERTIFICATE-----\nMIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM\nIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU\ncnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgx\nMDAxMTAyOTU2WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz\ndGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD\nZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0GCSqGSIb3\nDQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN8ELg63iIVl6bmlQdTQyK\n9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/RLyTPWGrTs0NvvAgJ1gORH8EGoel15YU\nNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZF\niP0Zf3WHHx+xGwpzJFu5ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W\n0eDrXltMEnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGjQjBA\nMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1A/d2O2GCahKqGFPr\nAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOyWL6ukK2YJ5f+AbGwUgC4TeQbIXQb\nfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzT\nucpH9sry9uetuUg/vBa3wW306gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7h\nP0HHRwA11fXT91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml\ne9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4pTpPDpFQUWw==\n-----END CERTIFICATE-----\n\nEE Certification Centre Root CA\n===============================\n-----BEGIN CERTIFICATE-----\nMIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQG\nEwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1czEoMCYGA1UEAwwfRUUgQ2Vy\ndGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYGCSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIw\nMTAxMDMwMTAxMDMwWhgPMjAzMDEyMTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlB\nUyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRy\nZSBSb290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEBAQUAA4IB\nDwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUyeuuOF0+W2Ap7kaJjbMeM\nTC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvObntl8jixwKIy72KyaOBhU8E2lf/slLo2\nrpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIwWFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw\n93X2PaRka9ZP585ArQ/dMtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtN\nP2MbRMNE1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYDVR0T\nAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/zQas8fElyalL1BSZ\nMEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEF\nBQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEFBQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+Rj\nxY6hUFaTlrg4wCQiZrxTFGGVv9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqM\nlIpPnTX/dqQGE5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u\nuSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIWiAYLtqZLICjU\n3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/vGVCJYMzpJJUPwssd8m92kMfM\ndcGWxZ0=\n-----END CERTIFICATE-----\n\nD-TRUST Root Class 3 CA 2 2009\n==============================\n-----BEGIN CERTIFICATE-----\nMIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQK\nDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTAe\nFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NThaME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxE\nLVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIw\nDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOAD\nER03UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42tSHKXzlA\nBF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9RySPocq60vFYJfxLLHLGv\nKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsMlFqVlNpQmvH/pStmMaTJOKDfHR+4CS7z\np+hnUquVH+BGPtikw8paxTGA6Eian5Rp/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUC\nAwEAAaOCARowggEWMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ\n4PGEMA4GA1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVjdG9y\neS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUyMENBJTIwMiUyMDIw\nMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRlcmV2b2NhdGlvbmxpc3QwQ6BBoD+G\nPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAw\nOS5jcmwwDQYJKoZIhvcNAQELBQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm\n2H6NMLVwMeniacfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0\no3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4KzCUqNQT4YJEV\ndT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8PIWmawomDeCTmGCufsYkl4ph\nX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3YJohw1+qRzT65ysCQblrGXnRl11z+o+I=\n-----END CERTIFICATE-----\n\nD-TRUST Root Class 3 CA 2 EV 2009\n=================================\n-----BEGIN CERTIFICATE-----\nMIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK\nDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw\nOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUwNDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK\nDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw\nOTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfS\negpnljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM03TP1YtHh\nzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6ZqQTMFexgaDbtCHu39b+T\n7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lRp75mpoo6Kr3HGrHhFPC+Oh25z1uxav60\nsUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure35\n11H3a6UCAwEAAaOCASQwggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyv\ncop9NteaHNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFwOi8v\nZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xhc3MlMjAzJTIwQ0El\nMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1ERT9jZXJ0aWZpY2F0ZXJldm9jYXRp\nb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xh\nc3NfM19jYV8yX2V2XzIwMDkuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+\nPPoeUSbrh/Yp3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05\nnsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNFCSuGdXzfX2lX\nANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7naxpeG0ILD5EJt/rDiZE4OJudA\nNCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqXKVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVv\nw9y4AyHqnxbxLFS1\n-----END CERTIFICATE-----\n\nCA Disig Root R2\n================\n-----BEGIN CERTIFICATE-----\nMIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNVBAYTAlNLMRMw\nEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMuMRkwFwYDVQQDExBDQSBEaXNp\nZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQyMDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sx\nEzARBgNVBAcTCkJyYXRpc2xhdmExEzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERp\nc2lnIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbC\nw3OeNcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNHPWSb6Wia\nxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3Ix2ymrdMxp7zo5eFm1tL7\nA7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbeQTg06ov80egEFGEtQX6sx3dOy1FU+16S\nGBsEWmjGycT6txOgmLcRK7fWV8x8nhfRyyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqV\ng8NTEQxzHQuyRpDRQjrOQG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa\n5Beny912H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJQfYE\nkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUDi/ZnWejBBhG93c+A\nAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORsnLMOPReisjQS1n6yqEm70XooQL6i\nFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNV\nHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5u\nQu0wDQYJKoZIhvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM\ntCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqfGopTpti72TVV\nsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkblvdhuDvEK7Z4bLQjb/D907Je\ndR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka+elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W8\n1k/BfDxujRNt+3vrMNDcTa/F1balTFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjx\nmHHEt38OFdAlab0inSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01\nutI3gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18DrG5gPcFw0\nsorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3OszMOl6W8KjptlwlCFtaOg\nUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8xL4ysEr3vQCj8KWefshNPZiTEUxnpHikV\n7+ZtsH8tZ/3zbBt1RqPlShfppNcL\n-----END CERTIFICATE-----\n\nACCVRAIZ1\n=========\n-----BEGIN CERTIFICATE-----\nMIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UEAwwJQUNDVlJB\nSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQswCQYDVQQGEwJFUzAeFw0xMTA1\nMDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQBgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwH\nUEtJQUNDVjENMAsGA1UECgwEQUNDVjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4IC\nDwAwggIKAoICAQCbqau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gM\njmoYHtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWoG2ioPej0\nRGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpAlHPrzg5XPAOBOp0KoVdD\naaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhrIA8wKFSVf+DuzgpmndFALW4ir50awQUZ\n0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDG\nWuzndN9wrqODJerWx5eHk6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs7\n8yM2x/474KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMOm3WR\n5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpacXpkatcnYGMN285J\n9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPluUsXQA+xtrn13k/c4LOsOxFwYIRK\nQ26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYIKwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRw\nOi8vd3d3LmFjY3YuZXMvZmlsZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEu\nY3J0MB8GCCsGAQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2\nVuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeTVfZW6oHlNsyM\nHj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIGCCsGAQUFBwICMIIBFB6CARAA\nQQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUAcgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBh\nAO0AegAgAGQAZQAgAGwAYQAgAEEAQwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUA\nYwBuAG8AbABvAGcA7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBj\nAHQAcgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAAQwBQAFMA\nIABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUAczAwBggrBgEFBQcCARYk\naHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2MuaHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0\ndHA6Ly93d3cuYWNjdi5lcy9maWxlYWRtaW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2\nMV9kZXIuY3JsMA4GA1UdDwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZI\nhvcNAQEFBQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdpD70E\nR9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gUJyCpZET/LtZ1qmxN\nYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+mAM/EKXMRNt6GGT6d7hmKG9Ww7Y49\nnCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepDvV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJ\nTS+xJlsndQAJxGJ3KQhfnlmstn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3\nsCPdK6jT2iWH7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h\nI6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szAh1xA2syVP1Xg\nNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xFd3+YJ5oyXSrjhO7FmGYvliAd\n3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2HpPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3p\nEfbRD0tVNEYqi4Y7\n-----END CERTIFICATE-----\n\nTWCA Global Root CA\n===================\n-----BEGIN CERTIFICATE-----\nMIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcxEjAQBgNVBAoT\nCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMTVFdDQSBHbG9iYWwgUm9vdCBD\nQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQK\nEwlUQUlXQU4tQ0ExEDAOBgNVBAsTB1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3Qg\nQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2C\nnJfF10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz0ALfUPZV\nr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfChMBwqoJimFb3u/Rk28OKR\nQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbHzIh1HrtsBv+baz4X7GGqcXzGHaL3SekV\ntTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1W\nKKD+u4ZqyPpcC1jcxkt2yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99\nsy2sbZCilaLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYPoA/p\nyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQABDzfuBSO6N+pjWxn\nkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcEqYSjMq+u7msXi7Kx/mzhkIyIqJdI\nzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMC\nAQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6g\ncFGn90xHNcgL1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn\nLhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WFH6vPNOw/KP4M\n8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNoRI2T9GRwoD2dKAXDOXC4Ynsg\n/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlg\nlPx4mI88k1HtQJAH32RjJMtOcQWh15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryP\nA9gK8kxkRr05YuWW6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3m\ni4TWnsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5jwa19hAM8\nEHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWzaGHQRiapIVJpLesux+t3\nzqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmyKwbQBM0=\n-----END CERTIFICATE-----\n\nTeliaSonera Root CA v1\n======================\n-----BEGIN CERTIFICATE-----\nMIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAwNzEUMBIGA1UE\nCgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJvb3QgQ0EgdjEwHhcNMDcxMDE4\nMTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYDVQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwW\nVGVsaWFTb25lcmEgUm9vdCBDQSB2MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+\n6yfwIaPzaSZVfp3FVRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA\n3GV17CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+XZ75Ljo1k\nB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+/jXh7VB7qTCNGdMJjmhn\nXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxH\noLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkmdtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3\nF0fUTPHSiXk+TT2YqGHeOh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJ\noWjiUIMusDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4pgd7\ngUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fsslESl1MpWtTwEhDc\nTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQarMCpgKIv7NHfirZ1fpoeDVNAgMB\nAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qW\nDNXr+nuqF+gTEjANBgkqhkiG9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNm\nzqjMDfz1mgbldxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx\n0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1TjTQpgcmLNkQfW\npb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBedY2gea+zDTYa4EzAvXUYNR0PV\nG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpc\nc41teyWRyu5FrgZLAMzTsVlQ2jqIOylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOT\nJsjrDNYmiLbAJM+7vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2\nqReWt88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcnHL/EVlP6\nY2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVxSK236thZiNSQvxaz2ems\nWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY=\n-----END CERTIFICATE-----\n\nE-Tugra Certification Authority\n===============================\n-----BEGIN CERTIFICATE-----\nMIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNVBAYTAlRSMQ8w\nDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamls\nZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN\nZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMw\nNTEyMDk0OFoXDTIzMDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmEx\nQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxl\ncmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQD\nDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A\nMIICCgKCAgEA4vU/kwVRHoViVF56C/UYB4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vd\nhQd2h8y/L5VMzH2nPbxHD5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5K\nCKpbknSFQ9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEoq1+g\nElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3Dk14opz8n8Y4e0ypQ\nBaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcHfC425lAcP9tDJMW/hkd5s3kc91r0\nE+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsutdEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gz\nrt48Ue7LE3wBf4QOXVGUnhMMti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAq\njqFGOjGY5RH8zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn\nrFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUXU8u3Zg5mTPj5\ndUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6Jyr+zE7S6E5UMA8GA1UdEwEB\n/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEG\nMA0GCSqGSIb3DQEBCwUAA4ICAQAFNzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAK\nkEh47U6YA5n+KGCRHTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jO\nXKqYGwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c77NCR807\nVRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3+GbHeJAAFS6LrVE1Uweo\na2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WKvJUawSg5TB9D0pH0clmKuVb8P7Sd2nCc\ndlqMQ1DujjByTd//SffGqWfZbawCEeI6FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEV\nKV0jq9BgoRJP3vQXzTLlyb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gT\nDx4JnW2PAJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpDy4Q0\n8ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8dNL/+I5c30jn6PQ0G\nC7TbO6Orb1wdtn7os4I07QZcJA==\n-----END CERTIFICATE-----\n\nT-TeleSec GlobalRoot Class 2\n============================\n-----BEGIN CERTIFICATE-----\nMIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM\nIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU\ncnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgx\nMDAxMTA0MDE0WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz\ndGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD\nZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0GCSqGSIb3\nDQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUdAqSzm1nzHoqvNK38DcLZ\nSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiCFoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/F\nvudocP05l03Sx5iRUKrERLMjfTlH6VJi1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx970\n2cu+fjOlbpSD8DT6IavqjnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGV\nWOHAD3bZwI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGjQjBA\nMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/WSA2AHmgoCJrjNXy\nYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhyNsZt+U2e+iKo4YFWz827n+qrkRk4\nr6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPACuvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNf\nvNoBYimipidx5joifsFvHZVwIEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR\n3p1m0IvVVGb6g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN\n9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlPBSeOE6Fuwg==\n-----END CERTIFICATE-----\n\nAtos TrustedRoot 2011\n=====================\n-----BEGIN CERTIFICATE-----\nMIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UEAwwVQXRvcyBU\ncnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0xMTA3MDcxNDU4\nMzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMMFUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsG\nA1UECgwEQXRvczELMAkGA1UEBhMCREUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCV\nhTuXbyo7LjvPpvMpNb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr\n54rMVD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+SZFhyBH+\nDgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ4J7sVaE3IqKHBAUsR320\nHLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0Lcp2AMBYHlT8oDv3FdU9T1nSatCQujgKR\nz3bFmx5VdJx4IbHwLfELn8LVlhgf8FQieowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7R\nl+lwrrw7GWzbITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZ\nbNshMBgGA1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB\nCwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8jvZfza1zv7v1Apt+h\nk6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kPDpFrdRbhIfzYJsdHt6bPWHJxfrrh\nTZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pcmaHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a9\n61qn8FYiqTxlVMYVqL2Gns2Dlmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G\n3mB/ufNPRJLvKrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed\n-----END CERTIFICATE-----\n\nQuoVadis Root CA 1 G3\n=====================\n-----BEGIN CERTIFICATE-----\nMIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQELBQAwSDELMAkG\nA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv\nb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJN\nMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEg\nRzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakE\nPBtVwedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWerNrwU8lm\nPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF34168Xfuw6cwI2H44g4hWf6\nPser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh4Pw5qlPafX7PGglTvF0FBM+hSo+LdoIN\nofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXpUhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/l\ng6AnhF4EwfWQvTA9xO+oabw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV\n7qJZjqlc3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/GKubX\n9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSthfbZxbGL0eUQMk1f\niyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KOTk0k+17kBL5yG6YnLUlamXrXXAkg\nt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOtzCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTAD\nAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZI\nhvcNAQELBQADggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC\nMTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2cDMT/uFPpiN3\nGPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUNqXsCHKnQO18LwIE6PWThv6ct\nTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP\n+V04ikkwj+3x6xn0dxoxGE1nVGwvb2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh\n3jRJjehZrJ3ydlo28hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fa\nwx/kNSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNjZgKAvQU6\nO0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhpq1467HxpvMc7hU6eFbm0\nFU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFtnh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOV\nhMJKzRwuJIczYOXD\n-----END CERTIFICATE-----\n\nQuoVadis Root CA 2 G3\n=====================\n-----BEGIN CERTIFICATE-----\nMIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQELBQAwSDELMAkG\nA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv\nb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJN\nMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIg\nRzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFh\nZiFfqq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMWn4rjyduY\nNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ymc5GQYaYDFCDy54ejiK2t\noIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+O7q414AB+6XrW7PFXmAqMaCvN+ggOp+o\nMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+l\nV0POKa2Mq1W/xPtbAd0jIaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZo\nL1NesNKqIcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz8eQQ\nsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43ehvNURG3YBZwjgQQvD\n6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l7ZizlWNof/k19N+IxWA1ksB8aRxh\nlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALGcC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTAD\nAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZI\nhvcNAQELBQADggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66\nAarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RCroijQ1h5fq7K\npVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0GaW/ZZGYjeVYg3UQt4XAoeo0L9\nx52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4nlv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgz\ndWqTHBLmYF5vHX/JHyPLhGGfHoJE+V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6X\nU/IyAgkwo1jwDQHVcsaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+Nw\nmNtddbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNgKCLjsZWD\nzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeMHVOyToV7BjjHLPj4sHKN\nJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4WSr2Rz0ZiC3oheGe7IUIarFsNMkd7Egr\nO3jtZsSOeWmD3n+M\n-----END CERTIFICATE-----\n\nQuoVadis Root CA 3 G3\n=====================\n-----BEGIN CERTIFICATE-----\nMIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQELBQAwSDELMAkG\nA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv\nb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJN\nMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMg\nRzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286\nIxSR/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNuFoM7pmRL\nMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXRU7Ox7sWTaYI+FrUoRqHe\n6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+cra1AdHkrAj80//ogaX3T7mH1urPnMNA3\nI4ZyYUUpSFlob3emLoG+B01vr87ERRORFHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3U\nVDmrJqMz6nWB2i3ND0/kA9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f7\n5li59wzweyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634RylsSqi\nMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBpVzgeAVuNVejH38DM\ndyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0QA4XN8f+MFrXBsj6IbGB/kE+V9/Yt\nrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD\nAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZI\nhvcNAQELBQADggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px\nKGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnIFUBhynLWcKzS\nt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5WvvoxXqA/4Ti2Tk08HS6IT7SdEQ\nTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFgu/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9Du\nDcpmvJRPpq3t/O5jrFc/ZSXPsoaP0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGib\nIh6BJpsQBJFxwAYf3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmD\nhPbl8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+DhcI00iX\n0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HNPlopNLk9hM6xZdRZkZFW\ndSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ywaZWWDYWGWVjUTR939+J399roD1B0y2\nPpxxVJkES/1Y+Zj0\n-----END CERTIFICATE-----\n\nDigiCert Assured ID Root G2\n===========================\n-----BEGIN CERTIFICATE-----\nMIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBlMQswCQYDVQQG\nEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw\nIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgw\nMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL\nExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIw\nggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSAn61UQbVH\n35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4HteccbiJVMWWXvdMX0h5i89vq\nbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9HpEgjAALAcKxHad3A2m67OeYfcgnDmCXRw\nVWmvo2ifv922ebPynXApVfSr/5Vh88lAbx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OP\nYLfykqGxvYmJHzDNw6YuYjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+Rn\nlTGNAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTO\nw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPIQW5pJ6d1Ee88hjZv\n0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I0jJmwYrA8y8678Dj1JGG0VDjA9tz\nd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4GnilmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAW\nhsI6yLETcDbYz+70CjTVW0z9B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0M\njomZmWzwPDCvON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo\nIhNzbM8m9Yop5w==\n-----END CERTIFICATE-----\n\nDigiCert Assured ID Root G3\n===========================\n-----BEGIN CERTIFICATE-----\nMIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQswCQYDVQQGEwJV\nUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYD\nVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1\nMTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\nd3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQ\nBgcqhkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJfZn4f5dwb\nRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17QRSAPWXYQ1qAk8C3eNvJs\nKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgF\nUaFNN6KDec6NHSrkhDAKBggqhkjOPQQDAwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5Fy\nYZ5eEJJZVrmDxxDnOOlYJjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy\n1vUhZscv6pZjamVFkpUBtA==\n-----END CERTIFICATE-----\n\nDigiCert Global Root G2\n=======================\n-----BEGIN CERTIFICATE-----\nMIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQG\nEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw\nHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUx\nMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3\ndy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkq\nhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI2/Ou8jqJ\nkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx1x7e/dfgy5SDN67sH0NO\n3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQq2EGnI/yuum06ZIya7XzV+hdG82MHauV\nBJVJ8zUtluNJbd134/tJS7SsVQepj5WztCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyM\nUNGPHgm+F6HmIcr9g+UQvIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQAB\no0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV5uNu\n5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY1Yl9PMWLSn/pvtsr\nF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4NeF22d+mQrvHRAiGfzZ0JFrabA0U\nWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NGFdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBH\nQRFXGU7Aj64GxJUTFy8bJZ918rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/\niyK5S9kJRaTepLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl\nMrY=\n-----END CERTIFICATE-----\n\nDigiCert Global Root G3\n=======================\n-----BEGIN CERTIFICATE-----\nMIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQswCQYDVQQGEwJV\nUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAwHgYD\nVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAw\nMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k\naWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0C\nAQYFK4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FGfp4tn+6O\nYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPOZ9wj/wMco+I+o0IwQDAP\nBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNp\nYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIxAK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y\n3maTD/HMsQmP3Wyr+mt/oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34\nVOKa5Vt8sycX\n-----END CERTIFICATE-----\n\nDigiCert Trusted Root G4\n========================\n-----BEGIN CERTIFICATE-----\nMIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBiMQswCQYDVQQG\nEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEw\nHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1\nMTIwMDAwWjBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\nd3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0G\nCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3yithZwuEp\npz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1Ifxp4VpX6+n6lXFllVcq9o\nk3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDVySAdYyktzuxeTsiT+CFhmzTrBcZe7Fsa\nvOvJz82sNEBfsXpm7nfISKhmV1efVFiODCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGY\nQJB5w3jHtrHEtWoYOAMQjdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6\nMUSaM0C/CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCiEhtm\nmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADMfRyVw4/3IbKyEbe7\nf/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QYuKZ3AeEPlAwhHbJUKSWJbOUOUlFH\ndL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXKchYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8\noR7FwI+isX4KJpn15GkvmB0t9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud\nDwEB/wQEAwIBhjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD\nggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2SV1EY+CtnJYY\nZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd+SeuMIW59mdNOj6PWTkiU0Tr\nyF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWcfFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy\n7zBZLq7gcfJW5GqXb5JQbZaNaHqasjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iah\nixTXTBmyUEFxPT9NcCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN\n5r5N0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie4u1Ki7wb\n/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mIr/OSmbaz5mEP0oUA51Aa\n5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tK\nG48BtieVU+i2iW1bvGjUI+iLUaJW+fCmgKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP\n82Z+\n-----END CERTIFICATE-----\n\nCOMODO RSA Certification Authority\n==================================\n-----BEGIN CERTIFICATE-----\nMIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCBhTELMAkGA1UE\nBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG\nA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlv\nbiBBdXRob3JpdHkwHhcNMTAwMTE5MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMC\nR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE\nChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBB\ndXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR6FSS0gpWsawNJN3Fz0Rn\ndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8Xpz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZ\nFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+\n5eNu/Nio5JIk2kNrYrhV/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pG\nx8cgoLEfZd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z+pUX\n2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7wqP/0uK3pN/u6uPQL\nOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZahSL0896+1DSJMwBGB7FY79tOi4lu3\nsgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVICu9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+C\nGCe01a60y1Dma/RMhnEw6abfFobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5\nWdYgGq/yapiqcrxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E\nFgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w\nDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvlwFTPoCWOAvn9sKIN9SCYPBMt\nrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+\nnq6PK7o9mfjYcwlYRm6mnPTXJ9OV2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSg\ntZx8jb8uk2IntznaFxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwW\nsRqZCuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiKboHGhfKp\npC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmckejkk9u+UJueBPSZI9FoJA\nzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yLS0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHq\nZJx64SIDqZxubw5lT2yHh17zbqD5daWbQOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk52\n7RH89elWsn2/x20Kk4yl0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7I\nLaZRfyHBNVOFBkpdn627G190\n-----END CERTIFICATE-----\n\nUSERTrust RSA Certification Authority\n=====================================\n-----BEGIN CERTIFICATE-----\nMIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCBiDELMAkGA1UE\nBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQK\nExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh\ndGlvbiBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UE\nBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQK\nExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh\ndGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCAEmUXNg7D2wiz\n0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2j\nY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkYtJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFn\nRghRy4YUVD+8M/5+bJz/Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O\n+T23LLb2VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT79uq\n/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6c0Plfg6lZrEpfDKE\nY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmTYo61Zs8liM2EuLE/pDkP2QKe6xJM\nlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97lc6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8\nyexDJtC/QV9AqURE9JnnV4eeUB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+\neLf8ZxXhyVeEHg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd\nBgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF\nMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPFUp/L+M+ZBn8b2kMVn54CVVeW\nFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KOVWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ\n7l8wXEskEVX/JJpuXior7gtNn3/3ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQ\nEg9zKC7F4iRO/Fjs8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM\n8WcRiQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYzeSf7dNXGi\nFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZXHlKYC6SQK5MNyosycdi\nyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9c\nJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRBVXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGw\nsAvgnEzDHNb842m1R0aBL6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gx\nQ+6IHdfGjjxDah2nGN59PRbxYvnKkKj9\n-----END CERTIFICATE-----\n\nUSERTrust ECC Certification Authority\n=====================================\n-----BEGIN CERTIFICATE-----\nMIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDELMAkGA1UEBhMC\nVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU\naGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv\nbiBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMC\nVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU\naGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv\nbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqfloI+d61SRvU8Za2EurxtW2\n0eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinngo4N+LZfQYcTxmdwlkWOrfzCjtHDix6Ez\nnPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0GA1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNV\nHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBB\nHU6+4WMBzzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbWRNZu\n9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg=\n-----END CERTIFICATE-----\n\nGlobalSign ECC Root CA - R4\n===========================\n-----BEGIN CERTIFICATE-----\nMIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEkMCIGA1UECxMb\nR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD\nEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoXDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMb\nR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD\nEwpHbG9iYWxTaWduMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprl\nOQcJFspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAwDgYDVR0P\nAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61FuOJAf/sKbvu+M8k8o4TV\nMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGXkPoUVy0D7O48027KqGx2vKLeuwIgJ6iF\nJzWbVsaj8kfSt24bAgAXqmemFZHe+pTsewv4n4Q=\n-----END CERTIFICATE-----\n\nGlobalSign ECC Root CA - R5\n===========================\n-----BEGIN CERTIFICATE-----\nMIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEkMCIGA1UECxMb\nR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD\nEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoXDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMb\nR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD\nEwpHbG9iYWxTaWduMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6\nSFkc8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8kehOvRnkmS\nh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd\nBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYIKoZIzj0EAwMDaAAwZQIxAOVpEslu28Yx\nuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7\nyFz9SO8NdCKoCOJuxUnOxwy8p2Fp8fc74SrL+SvzZpA3\n-----END CERTIFICATE-----\n\nStaat der Nederlanden Root CA - G3\n==================================\n-----BEGIN CERTIFICATE-----\nMIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJOTDEeMBwGA1UE\nCgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFhdCBkZXIgTmVkZXJsYW5kZW4g\nUm9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloXDTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMC\nTkwxHjAcBgNVBAoMFVN0YWF0IGRlciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5l\nZGVybGFuZGVuIFJvb3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4y\nolQPcPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WWIkYFsO2t\nx1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqXxz8ecAgwoNzFs21v0IJy\nEavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFyKJLZWyNtZrVtB0LrpjPOktvA9mxjeM3K\nTj215VKb8b475lRgsGYeCasH/lSJEULR9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUur\nmkVLoR9BvUhTFXFkC4az5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU5\n1nus6+N86U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7Ngzp\n07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHPbMk7ccHViLVlvMDo\nFxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXtBznaqB16nzaeErAMZRKQFWDZJkBE\n41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTtXUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMB\nAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleu\nyjWcLhL75LpdINyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD\nU5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwpLiniyMMB8jPq\nKqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8Ipf3YF3qKS9Ysr1YvY2WTxB1\nv0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixpgZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA\n8KCWAg8zxXHzniN9lLf9OtMJgwYh/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b\n8KKaa8MFSu1BYBQw0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0r\nmj1AfsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq4BZ+Extq\n1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR1VmiiXTTn74eS9fGbbeI\nJG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/QFH1T/U67cjF68IeHRaVesd+QnGTbksV\ntzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM94B7IWcnMFk=\n-----END CERTIFICATE-----\n\nStaat der Nederlanden EV Root CA\n================================\n-----BEGIN CERTIFICATE-----\nMIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJOTDEeMBwGA1UE\nCgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFhdCBkZXIgTmVkZXJsYW5kZW4g\nRVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0yMjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5M\nMR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRl\ncmxhbmRlbiBFViBSb290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkk\nSzrSM4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nCUiY4iKTW\nO0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3dZ//BYY1jTw+bbRcwJu+r\n0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46prfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8\nKj6GyzyDOvnJDdrFmeK8eEEzduG/L13lpJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gV\nXJrm0w912fxBmJc+qiXbj5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr\n08C+eKxCKFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS/ZbV\n0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0XcgOPvZuM5l5Tnrmd\n74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH1vI4gnPah1vlPNOePqc7nvQDs/nx\nfRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrPpx9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNC\nMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwa\nivsnuL8wbqg7MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI\neK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u2dfOWBfoqSmu\nc0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHSv4ilf0X8rLiltTMMgsT7B/Zq\n5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTCwPTxGfARKbalGAKb12NMcIxHowNDXLldRqAN\nb/9Zjr7dn3LDWyvfjFvO5QxGbJKyCqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tN\nf1zuacpzEPuKqf2evTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi\n5Dp6Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIaGl6I6lD4\nWeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeLeG9QgkRQP2YGiqtDhFZK\nDyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGy\neUN51q1veieQA6TqJIc/2b3Z6fJfUEkc7uzXLg==\n-----END CERTIFICATE-----\n\nIdenTrust Commercial Root CA 1\n==============================\n-----BEGIN CERTIFICATE-----\nMIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBKMQswCQYDVQQG\nEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBS\nb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQwMTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzES\nMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENB\nIDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ld\nhNlT3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU+ehcCuz/\nmNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gpS0l4PJNgiCL8mdo2yMKi\n1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1bVoE/c40yiTcdCMbXTMTEl3EASX2MN0C\nXZ/g1Ue9tOsbobtJSdifWwLziuQkkORiT0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl\n3ZBWzvurpWCdxJ35UrCLvYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzy\nNeVJSQjKVsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZKdHzV\nWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHTc+XvvqDtMwt0viAg\nxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hvl7yTmvmcEpB4eoCHFddydJxVdHix\nuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5NiGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMC\nAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZI\nhvcNAQELBQADggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH\n6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwtLRvM7Kqas6pg\nghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93nAbowacYXVKV7cndJZ5t+qnt\nozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3+wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmV\nYjzlVYA211QC//G5Xc7UI2/YRYRKW2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUX\nfeu+h1sXIFRRk0pTAwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/ro\nkTLql1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG4iZZRHUe\n2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZmUlO+KWA2yUPHGNiiskz\nZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7R\ncGzM7vRX+Bi6hG6H\n-----END CERTIFICATE-----\n\nIdenTrust Public Sector Root CA 1\n=================================\n-----BEGIN CERTIFICATE-----\nMIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBNMQswCQYDVQQG\nEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3Rv\nciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcNMzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJV\nUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBS\nb290IENBIDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTy\nP4o7ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGyRBb06tD6\nHi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlSbdsHyo+1W/CD80/HLaXI\nrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF/YTLNiCBWS2ab21ISGHKTN9T0a9SvESf\nqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoS\nmJxZZoY+rfGwyj4GD3vwEUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFn\nol57plzy9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9VGxyh\nLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ2fjXctscvG29ZV/v\niDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsVWaFHVCkugyhfHMKiq3IXAAaOReyL\n4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gDW/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8B\nAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMw\nDQYJKoZIhvcNAQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj\nt2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHVDRDtfULAj+7A\nmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9TaDKQGXSc3z1i9kKlT/YPyNt\nGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8GlwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFt\nm6/n6J91eEyrRjuazr8FGF1NFTwWmhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMx\nNRF4eKLg6TCMf4DfWN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4\nMhn5+bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJtshquDDI\najjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhAGaQdp/lLQzfcaFpPz+vC\nZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ\n3Wl9af0AVqW3rLatt8o+Ae+c\n-----END CERTIFICATE-----\n\nEntrust Root Certification Authority - G2\n=========================================\n-----BEGIN CERTIFICATE-----\nMIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMCVVMxFjAUBgNV\nBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVy\nbXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ug\nb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIw\nHhcNMDkwNzA3MTcyNTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoT\nDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMx\nOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25s\neTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwggEi\nMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP\n/vaCeb9zYQYKpSfYs1/TRU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXz\nHHfV1IWNcCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hWwcKU\ns/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1U1+cPvQXLOZprE4y\nTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0jaWvYkxN4FisZDQSA/i2jZRjJKRx\nAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ6\n0B7vfec7aVHUbI2fkBJmqzANBgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5Z\niXMRrEPR9RP/jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ\nRkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v1fN2D807iDgi\nnWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4RnAuknZoh8/CbCzB428Hch0P+\nvGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmHVHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xO\ne4pIb4tF9g==\n-----END CERTIFICATE-----\n\nEntrust Root Certification Authority - EC1\n==========================================\n-----BEGIN CERTIFICATE-----\nMIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkGA1UEBhMCVVMx\nFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVn\nYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXpl\nZCB1c2Ugb25seTEzMDEGA1UEAxMqRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5\nIC0gRUMxMB4XDTEyMTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYw\nFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2Fs\nLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQg\ndXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAt\nIEVDMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHy\nAsWfoPZb1YsGGYZPUxBtByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef\n9eNi1KlHBz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE\nFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVCR98crlOZF7ZvHH3h\nvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nXhTcGtXsI/esni0qU+eH6p44mCOh8\nkmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G\n-----END CERTIFICATE-----\n\nCFCA EV ROOT\n============\n-----BEGIN CERTIFICATE-----\nMIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJDTjEwMC4GA1UE\nCgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNB\nIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkxMjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEw\nMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQD\nDAxDRkNBIEVWIFJPT1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnV\nBU03sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpLTIpTUnrD\n7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5/ZOkVIBMUtRSqy5J35DN\nuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp7hZZLDRJGqgG16iI0gNyejLi6mhNbiyW\nZXvKWfry4t3uMCz7zEasxGPrb382KzRzEpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7\nxzbh72fROdOXW3NiGUgthxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9f\npy25IGvPa931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqotaK8K\ngWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNgTnYGmE69g60dWIol\nhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfVPKPtl8MeNPo4+QgO48BdK4PRVmrJ\ntqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hvcWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAf\nBgNVHSMEGDAWgBTj/i39KNALtbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB\n/wQEAwIBBjAdBgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB\nACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObTej/tUxPQ4i9q\necsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdLjOztUmCypAbqTuv0axn96/Ua\n4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBSESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sG\nE5uPhnEFtC+NiWYzKXZUmhH4J/qyP5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfX\nBDrDMlI1Dlb4pd19xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjn\naH9dCi77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN5mydLIhy\nPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe/v5WOaHIz16eGWRGENoX\nkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+ZAAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3C\nekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su\n-----END CERTIFICATE-----\n\nTÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H5\n====================================================\n-----BEGIN CERTIFICATE-----\nMIIEJzCCAw+gAwIBAgIHAI4X/iQggTANBgkqhkiG9w0BAQsFADCBsTELMAkGA1UEBhMCVFIxDzAN\nBgNVBAcMBkFua2FyYTFNMEsGA1UECgxEVMOcUktUUlVTVCBCaWxnaSDEsGxldGnFn2ltIHZlIEJp\nbGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkgQS7Fni4xQjBABgNVBAMMOVTDnFJLVFJVU1Qg\nRWxla3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSBINTAeFw0xMzA0MzAw\nODA3MDFaFw0yMzA0MjgwODA3MDFaMIGxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMU0w\nSwYDVQQKDERUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnE\nn2kgSGl6bWV0bGVyaSBBLsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBFbGVrdHJvbmlrIFNlcnRp\nZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIEg1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB\nCgKCAQEApCUZ4WWe60ghUEoI5RHwWrom/4NZzkQqL/7hzmAD/I0Dpe3/a6i6zDQGn1k19uwsu537\njVJp45wnEFPzpALFp/kRGml1bsMdi9GYjZOHp3GXDSHHmflS0yxjXVW86B8BSLlg/kJK9siArs1m\nep5Fimh34khon6La8eHBEJ/rPCmBp+EyCNSgBbGM+42WAA4+Jd9ThiI7/PS98wl+d+yG6w8z5UNP\n9FR1bSmZLmZaQ9/LXMrI5Tjxfjs1nQ/0xVqhzPMggCTTV+wVunUlm+hkS7M0hO8EuPbJbKoCPrZV\n4jI3X/xml1/N1p7HIL9Nxqw/dV8c7TKcfGkAaZHjIxhT6QIDAQABo0IwQDAdBgNVHQ4EFgQUVpkH\nHtOsDGlktAxQR95DLL4gwPswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI\nhvcNAQELBQADggEBAJ5FdnsXSDLyOIspve6WSk6BGLFRRyDN0GSxDsnZAdkJzsiZ3GglE9Rc8qPo\nBP5yCccLqh0lVX6Wmle3usURehnmp349hQ71+S4pL+f5bFgWV1Al9j4uPqrtd3GqqpmWRgqujuwq\nURawXs3qZwQcWDD1YIq9pr1N5Za0/EKJAWv2cMhQOQwt1WbZyNKzMrcbGW3LM/nfpeYVhDfwwvJl\nlpKQd/Ct9JDpEXjXk4nAPQu6KfTomZ1yju2dL+6SfaHx/126M2CFYv4HAqGEVka+lgqaE9chTLd8\nB59OTj+RdPsnnRHM3eaxynFNExc5JsUpISuTKWqW+qtB4Uu2NQvAmxU=\n-----END CERTIFICATE-----\n\nCertinomis - Root CA\n====================\n-----BEGIN CERTIFICATE-----\nMIIFkjCCA3qgAwIBAgIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJGUjETMBEGA1UEChMK\nQ2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxHTAbBgNVBAMTFENlcnRpbm9taXMg\nLSBSb290IENBMB4XDTEzMTAyMTA5MTcxOFoXDTMzMTAyMTA5MTcxOFowWjELMAkGA1UEBhMCRlIx\nEzARBgNVBAoTCkNlcnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMR0wGwYDVQQDExRD\nZXJ0aW5vbWlzIC0gUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANTMCQos\nP5L2fxSeC5yaah1AMGT9qt8OHgZbn1CF6s2Nq0Nn3rD6foCWnoR4kkjW4znuzuRZWJflLieY6pOo\nd5tK8O90gC3rMB+12ceAnGInkYjwSond3IjmFPnVAy//ldu9n+ws+hQVWZUKxkd8aRi5pwP5ynap\nz8dvtF4F/u7BUrJ1Mofs7SlmO/NKFoL21prbcpjp3vDFTKWrteoB4owuZH9kb/2jJZOLyKIOSY00\n8B/sWEUuNKqEUL3nskoTuLAPrjhdsKkb5nPJWqHZZkCqqU2mNAKthH6yI8H7KsZn9DS2sJVqM09x\nRLWtwHkziOC/7aOgFLScCbAK42C++PhmiM1b8XcF4LVzbsF9Ri6OSyemzTUK/eVNfaoqoynHWmgE\n6OXWk6RiwsXm9E/G+Z8ajYJJGYrKWUM66A0ywfRMEwNvbqY/kXPLynNvEiCL7sCCeN5LLsJJwx3t\nFvYk9CcbXFcx3FXuqB5vbKziRcxXV4p1VxngtViZSTYxPDMBbRZKzbgqg4SGm/lg0h9tkQPTYKbV\nPZrdd5A9NaSfD171UkRpucC63M9933zZxKyGIjK8e2uR73r4F2iw4lNVYC2vPsKD2NkJK/DAZNuH\ni5HMkesE/Xa0lZrmFAYb1TQdvtj/dBxThZngWVJKYe2InmtJiUZ+IFrZ50rlau7SZRFDAgMBAAGj\nYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTvkUz1pcMw6C8I\n6tNxIqSSaHh02TAfBgNVHSMEGDAWgBTvkUz1pcMw6C8I6tNxIqSSaHh02TANBgkqhkiG9w0BAQsF\nAAOCAgEAfj1U2iJdGlg+O1QnurrMyOMaauo++RLrVl89UM7g6kgmJs95Vn6RHJk/0KGRHCwPT5iV\nWVO90CLYiF2cN/z7ZMF4jIuaYAnq1fohX9B0ZedQxb8uuQsLrbWwF6YSjNRieOpWauwK0kDDPAUw\nPk2Ut59KA9N9J0u2/kTO+hkzGm2kQtHdzMjI1xZSg081lLMSVX3l4kLr5JyTCcBMWwerx20RoFAX\nlCOotQqSD7J6wWAsOMwaplv/8gzjqh8c3LigkyfeY+N/IZ865Z764BNqdeuWXGKRlI5nU7aJ+BIJ\ny29SWwNyhlCVCNSNh4YVH5Uk2KRvms6knZtt0rJ2BobGVgjF6wnaNsIbW0G+YSrjcOa4pvi2WsS9\nIff/ql+hbHY5ZtbqTFXhADObE5hjyW/QASAJN1LnDE8+zbz1X5YnpyACleAu6AdBBR8Vbtaw5Bng\nDwKTACdyxYvRVB9dSsNAl35VpnzBMwQUAR1JIGkLGZOdblgi90AMRgwjY/M50n92Uaf0yKHxDHYi\nI0ZSKS3io0EHVmmY0gUJvGnHWmHNj4FgFU2A3ZDifcRQ8ow7bkrHxuaAKzyBvBGAFhAn1/DNP3nM\ncyrDflOR1m749fPH0FFNjkulW+YZFzvWgQncItzujrnEj1PhZ7szuIgVRs/taTX/dQ1G885x4cVr\nhkIGuUE=\n-----END CERTIFICATE-----\n\nOISTE WISeKey Global Root GB CA\n===============================\n-----BEGIN CERTIFICATE-----\nMIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBtMQswCQYDVQQG\nEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl\nZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAw\nMzJaFw0zOTEyMDExNTEwMzFaMG0xCzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYD\nVQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEds\nb2JhbCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3HEokKtaX\nscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGxWuR51jIjK+FTzJlFXHtP\nrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk\n9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNku7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4o\nQnc/nSMbsrY9gBQHTC5P99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvg\nGUpuuy9rM2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB\n/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZI\nhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrghcViXfa43FK8+5/ea4n32cZiZBKpD\ndHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0\nVQreUGdNZtGn//3ZwLWoo4rOZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEui\nHZeeevJuQHHfaPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic\nNc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM=\n-----END CERTIFICATE-----\n\nSZAFIR ROOT CA2\n===============\n-----BEGIN CERTIFICATE-----\nMIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQELBQAwUTELMAkG\nA1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6ZW5pb3dhIFMuQS4xGDAWBgNV\nBAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkwNzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJ\nBgNVBAYTAlBMMSgwJgYDVQQKDB9LcmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYD\nVQQDDA9TWkFGSVIgUk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5Q\nqEvNQLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT3PSQ1hNK\nDJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw3gAeqDRHu5rr/gsUvTaE\n2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr63fE9biCloBK0TXC5ztdyO4mTp4CEHCdJ\nckm1/zuVnsHMyAHs6A6KCpbns6aH5db5BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwi\nieDhZNRnvDF5YTy7ykHNXGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P\nAQH/BAQDAgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsFAAOC\nAQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw8PRBEew/R40/cof5\nO/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOGnXkZ7/e7DDWQw4rtTw/1zBLZpD67\noPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCPoky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul\n4+vJhaAlIDf7js4MNIThPIGyd05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6\n+/NNIxuZMzSgLvWpCz/UXeHPhJ/iGcJfitYgHuNztw==\n-----END CERTIFICATE-----\n\nCertum Trusted Network CA 2\n===========================\n-----BEGIN CERTIFICATE-----\nMIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCBgDELMAkGA1UE\nBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMuQS4xJzAlBgNVBAsTHkNlcnR1\nbSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIGA1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29y\nayBDQSAyMCIYDzIwMTExMDA2MDgzOTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQ\nTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENl\ncnRpZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENB\nIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWADGSdhhuWZGc/IjoedQF9\n7/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+o\nCgCXhVqqndwpyeI1B+twTUrWwbNWuKFBOJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40b\nRr5HMNUuctHFY9rnY3lEfktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2p\nuTRZCr+ESv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1mo130\nGO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02isx7QBlrd9pPPV3WZ\n9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOWOZV7bIBaTxNyxtd9KXpEulKkKtVB\nRgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgezTv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pye\nhizKV/Ma5ciSixqClnrDvFASadgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vM\nBhBgu4M1t15n3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD\nAQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZI\nhvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQF/xlhMcQSZDe28cmk4gmb3DW\nAl45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTfCVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuA\nL55MYIR4PSFk1vtBHxgP58l1cb29XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMo\nclm2q8KMZiYcdywmdjWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tM\npkT/WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jbAoJnwTnb\nw3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksqP/ujmv5zMnHCnsZy4Ypo\nJ/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Kob7a6bINDd82Kkhehnlt4Fj1F4jNy3eFm\nypnTycUm/Q1oBEauttmbjL4ZvrHG8hnjXALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLX\nis7VmFxWlgPF7ncGNf/P5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7\nzAYspsbiDrW5viSP\n-----END CERTIFICATE-----\n\nHellenic Academic and Research Institutions RootCA 2015\n=======================================================\n-----BEGIN CERTIFICATE-----\nMIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1IxDzANBgNVBAcT\nBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0\naW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNl\nYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAx\nMTIxWjCBpjELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMg\nQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNV\nBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIw\nMTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDC+Kk/G4n8PDwEXT2QNrCROnk8Zlrv\nbTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+eh\niGsxr/CL0BgzuNtFajT0AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+\n6PAQZe104S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06CojXd\nFPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV9Cz82XBST3i4vTwr\ni5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrDgfgXy5I2XdGj2HUb4Ysn6npIQf1F\nGQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2\nfu/Z8VFRfS0myGlZYeCsargqNhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9mu\niNX6hME6wGkoLfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc\nBw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNVHRMBAf8EBTAD\nAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVdctA4GGqd83EkVAswDQYJKoZI\nhvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0IXtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+\nD1hYc2Ryx+hFjtyp8iY/xnmMsVMIM4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrM\nd/K4kPFox/la/vot9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+y\nd+2VZ5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/eaj8GsGsVn\n82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnhX9izjFk0WaSrT2y7Hxjb\ndavYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQl033DlZdwJVqwjbDG2jJ9SrcR5q+ss7F\nJej6A7na+RZukYT1HCjI/CbM1xyQVqdfbzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVt\nJ94Cj8rDtSvK6evIIVM4pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGa\nJI7ZjnHKe7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0vm9q\np/UsQu0yrbYhnr68\n-----END CERTIFICATE-----\n\nHellenic Academic and Research Institutions ECC RootCA 2015\n===========================================================\n-----BEGIN CERTIFICATE-----\nMIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0\naGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9u\ncyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJj\naCBJbnN0aXR1dGlvbnMgRUNDIFJvb3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEw\nMzcxMlowgaoxCzAJBgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmlj\nIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUQwQgYD\nVQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIEVDQyBSb290\nQ0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKgQehLgoRc4vgxEZmGZE4JJS+dQS8KrjVP\ndJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJajq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoK\nVlp8aQuqgAkkbH7BRqNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O\nBBYEFLQiC4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaeplSTA\nGiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7SofTUwJCA3sS61kFyjn\ndc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR\n-----END CERTIFICATE-----\n\nCertplus Root CA G1\n===================\n-----BEGIN CERTIFICATE-----\nMIIFazCCA1OgAwIBAgISESBVg+QtPlRWhS2DN7cs3EYRMA0GCSqGSIb3DQEBDQUAMD4xCzAJBgNV\nBAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMTAe\nFw0xNDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBaMD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhD\nZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMTCCAiIwDQYJKoZIhvcNAQEBBQAD\nggIPADCCAgoCggIBANpQh7bauKk+nWT6VjOaVj0W5QOVsjQcmm1iBdTYj+eJZJ+622SLZOZ5KmHN\nr49aiZFluVj8tANfkT8tEBXgfs+8/H9DZ6itXjYj2JizTfNDnjl8KvzsiNWI7nC9hRYt6kuJPKNx\nQv4c/dMcLRC4hlTqQ7jbxofaqK6AJc96Jh2qkbBIb6613p7Y1/oA/caP0FG7Yn2ksYyy/yARujVj\nBYZHYEMzkPZHogNPlk2dT8Hq6pyi/jQu3rfKG3akt62f6ajUeD94/vI4CTYd0hYCyOwqaK/1jpTv\nLRN6HkJKHRUxrgwEV/xhc/MxVoYxgKDEEW4wduOU8F8ExKyHcomYxZ3MVwia9Az8fXoFOvpHgDm2\nz4QTd28n6v+WZxcIbekN1iNQMLAVdBM+5S//Ds3EC0pd8NgAM0lm66EYfFkuPSi5YXHLtaW6uOrc\n4nBvCGrch2c0798wct3zyT8j/zXhviEpIDCB5BmlIOklynMxdCm+4kLV87ImZsdo/Rmz5yCTmehd\n4F6H50boJZwKKSTUzViGUkAksnsPmBIgJPaQbEfIDbsYIC7Z/fyL8inqh3SV4EJQeIQEQWGw9CEj\njy3LKCHyamz0GqbFFLQ3ZU+V/YDI+HLlJWvEYLF7bY5KinPOWftwenMGE9nTdDckQQoRb5fc5+R+\nob0V8rqHDz1oihYHAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0G\nA1UdDgQWBBSowcCbkahDFXxdBie0KlHYlwuBsTAfBgNVHSMEGDAWgBSowcCbkahDFXxdBie0KlHY\nlwuBsTANBgkqhkiG9w0BAQ0FAAOCAgEAnFZvAX7RvUz1isbwJh/k4DgYzDLDKTudQSk0YcbX8ACh\n66Ryj5QXvBMsdbRX7gp8CXrc1cqh0DQT+Hern+X+2B50ioUHj3/MeXrKls3N/U/7/SMNkPX0XtPG\nYX2eEeAC7gkE2Qfdpoq3DIMku4NQkv5gdRE+2J2winq14J2by5BSS7CTKtQ+FjPlnsZlFT5kOwQ/\n2wyPX1wdaR+v8+khjPPvl/aatxm2hHSco1S1cE5j2FddUyGbQJJD+tZ3VTNPZNX70Cxqjm0lpu+F\n6ALEUz65noe8zDUa3qHpimOHZR4RKttjd5cUvpoUmRGywO6wT/gUITJDT5+rosuoD6o7BlXGEilX\nCNQ314cnrUlZp5GrRHpejXDbl85IULFzk/bwg2D5zfHhMf1bfHEhYxQUqq/F3pN+aLHsIqKqkHWe\ntUNy6mSjhEv9DKgma3GX7lZjZuhCVPnHHd/Qj1vfyDBviP4NxDMcU6ij/UgQ8uQKTuEVV/xuZDDC\nVRHc6qnNSlSsKWNEz0pAoNZoWRsz+e86i9sgktxChL8Bq4fA1SCC28a5g4VCXA9DO2pJNdWY9BW/\n+mGBDAkgGNLQFwzLSABQ6XaCjGTXOqAHVcweMcDvOrRl++O/QmueD6i9a5jc2NvLi6Td11n0bt3+\nqsOR0C5CB8AMTVPNJLFMWx5R9N/pkvo=\n-----END CERTIFICATE-----\n\nCertplus Root CA G2\n===================\n-----BEGIN CERTIFICATE-----\nMIICHDCCAaKgAwIBAgISESDZkc6uo+jF5//pAq/Pc7xVMAoGCCqGSM49BAMDMD4xCzAJBgNVBAYT\nAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMjAeFw0x\nNDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBaMD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0\ncGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMjB2MBAGByqGSM49AgEGBSuBBAAiA2IA\nBM0PW1aC3/BFGtat93nwHcmsltaeTpwftEIRyoa/bfuFo8XlGVzX7qY/aWfYeOKmycTbLXku54uN\nAm8xIk0G42ByRZ0OQneezs/lf4WbGOT8zC5y0xaTTsqZY1yhBSpsBqNjMGEwDgYDVR0PAQH/BAQD\nAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNqDYwJ5jtpMxjwjFNiPwyCrKGBZMB8GA1Ud\nIwQYMBaAFNqDYwJ5jtpMxjwjFNiPwyCrKGBZMAoGCCqGSM49BAMDA2gAMGUCMHD+sAvZ94OX7PNV\nHdTcswYO/jOYnYs5kGuUIe22113WTNchp+e/IQ8rzfcq3IUHnQIxAIYUFuXcsGXCwI4Un78kFmjl\nvPl5adytRSv3tjFzzAalU5ORGpOucGpnutee5WEaXw==\n-----END CERTIFICATE-----\n\nOpenTrust Root CA G1\n====================\n-----BEGIN CERTIFICATE-----\nMIIFbzCCA1egAwIBAgISESCzkFU5fX82bWTCp59rY45nMA0GCSqGSIb3DQEBCwUAMEAxCzAJBgNV\nBAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5UcnVzdCBSb290IENBIEcx\nMB4XDTE0MDUyNjA4NDU1MFoXDTM4MDExNTAwMDAwMFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoM\nCU9wZW5UcnVzdDEdMBsGA1UEAwwUT3BlblRydXN0IFJvb3QgQ0EgRzEwggIiMA0GCSqGSIb3DQEB\nAQUAA4ICDwAwggIKAoICAQD4eUbalsUwXopxAy1wpLuwxQjczeY1wICkES3d5oeuXT2R0odsN7fa\nYp6bwiTXj/HbpqbfRm9RpnHLPhsxZ2L3EVs0J9V5ToybWL0iEA1cJwzdMOWo010hOHQX/uMftk87\nay3bfWAfjH1MBcLrARYVmBSO0ZB3Ij/swjm4eTrwSSTilZHcYTSSjFR077F9jAHiOH3BX2pfJLKO\nYheteSCtqx234LSWSE9mQxAGFiQD4eCcjsZGT44ameGPuY4zbGneWK2gDqdkVBFpRGZPTBKnjix9\nxNRbxQA0MMHZmf4yzgeEtE7NCv82TWLxp2NX5Ntqp66/K7nJ5rInieV+mhxNaMbBGN4zK1FGSxyO\n9z0M+Yo0FMT7MzUj8czxKselu7Cizv5Ta01BG2Yospb6p64KTrk5M0ScdMGTHPjgniQlQ/GbI4Kq\n3ywgsNw2TgOzfALU5nsaqocTvz6hdLubDuHAk5/XpGbKuxs74zD0M1mKB3IDVedzagMxbm+WG+Oi\nn6+Sx+31QrclTDsTBM8clq8cIqPQqwWyTBIjUtz9GVsnnB47ev1CI9sjgBPwvFEVVJSmdz7QdFG9\nURQIOTfLHzSpMJ1ShC5VkLG631UAC9hWLbFJSXKAqWLXwPYYEQRVzXR7z2FwefR7LFxckvzluFqr\nTJOVoSfupb7PcSNCupt2LQIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB\n/zAdBgNVHQ4EFgQUl0YhVyE12jZVx/PxN3DlCPaTKbYwHwYDVR0jBBgwFoAUl0YhVyE12jZVx/Px\nN3DlCPaTKbYwDQYJKoZIhvcNAQELBQADggIBAB3dAmB84DWn5ph76kTOZ0BP8pNuZtQ5iSas000E\nPLuHIT839HEl2ku6q5aCgZG27dmxpGWX4m9kWaSW7mDKHyP7Rbr/jyTwyqkxf3kfgLMtMrpkZ2Cv\nuVnN35pJ06iCsfmYlIrM4LvgBBuZYLFGZdwIorJGnkSI6pN+VxbSFXJfLkur1J1juONI5f6ELlgK\nn0Md/rcYkoZDSw6cMoYsYPXpSOqV7XAp8dUv/TW0V8/bhUiZucJvbI/NeJWsZCj9VrDDb8O+WVLh\nX4SPgPL0DTatdrOjteFkdjpY3H1PXlZs5VVZV6Xf8YpmMIzUUmI4d7S+KNfKNsSbBfD4Fdvb8e80\nnR14SohWZ25g/4/Ii+GOvUKpMwpZQhISKvqxnUOOBZuZ2mKtVzazHbYNeS2WuOvyDEsMpZTGMKcm\nGS3tTAZQMPH9WD25SxdfGbRqhFS0OE85og2WaMMolP3tLR9Ka0OWLpABEPs4poEL0L9109S5zvE/\nbw4cHjdx5RiHdRk/ULlepEU0rbDK5uUTdg8xFKmOLZTW1YVNcxVPS/KyPu1svf0OnWZzsD2097+o\n4BGkxK51CUpjAEggpsadCwmKtODmzj7HPiY46SvepghJAwSQiumPv+i2tCqjI40cHLI5kqiPAlxA\nOXXUc0ECd97N4EOH1uS6SsNsEn/+KuYj1oxx\n-----END CERTIFICATE-----\n\nOpenTrust Root CA G2\n====================\n-----BEGIN CERTIFICATE-----\nMIIFbzCCA1egAwIBAgISESChaRu/vbm9UpaPI+hIvyYRMA0GCSqGSIb3DQEBDQUAMEAxCzAJBgNV\nBAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5UcnVzdCBSb290IENBIEcy\nMB4XDTE0MDUyNjAwMDAwMFoXDTM4MDExNTAwMDAwMFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoM\nCU9wZW5UcnVzdDEdMBsGA1UEAwwUT3BlblRydXN0IFJvb3QgQ0EgRzIwggIiMA0GCSqGSIb3DQEB\nAQUAA4ICDwAwggIKAoICAQDMtlelM5QQgTJT32F+D3Y5z1zCU3UdSXqWON2ic2rxb95eolq5cSG+\nNtmh/LzubKh8NBpxGuga2F8ORAbtp+Dz0mEL4DKiltE48MLaARf85KxP6O6JHnSrT78eCbY2albz\n4e6WiWYkBuTNQjpK3eCasMSCRbP+yatcfD7J6xcvDH1urqWPyKwlCm/61UWY0jUJ9gNDlP7ZvyCV\neYCYitmJNbtRG6Q3ffyZO6v/v6wNj0OxmXsWEH4db0fEFY8ElggGQgT4hNYdvJGmQr5J1WqIP7wt\nUdGejeBSzFfdNTVY27SPJIjki9/ca1TSgSuyzpJLHB9G+h3Ykst2Z7UJmQnlrBcUVXDGPKBWCgOz\n3GIZ38i1MH/1PCZ1Eb3XG7OHngevZXHloM8apwkQHZOJZlvoPGIytbU6bumFAYueQ4xncyhZW+vj\n3CzMpSZyYhK05pyDRPZRpOLAeiRXyg6lPzq1O4vldu5w5pLeFlwoW5cZJ5L+epJUzpM5ChaHvGOz\n9bGTXOBut9Dq+WIyiET7vycotjCVXRIouZW+j1MY5aIYFuJWpLIsEPUdN6b4t/bQWVyJ98LVtZR0\n0dX+G7bw5tYee9I8y6jj9RjzIR9u701oBnstXW5DiabA+aC/gh7PU3+06yzbXfZqfUAkBXKJOAGT\ny3HCOV0GEfZvePg3DTmEJwIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB\n/zAdBgNVHQ4EFgQUajn6QiL35okATV59M4PLuG53hq8wHwYDVR0jBBgwFoAUajn6QiL35okATV59\nM4PLuG53hq8wDQYJKoZIhvcNAQENBQADggIBAJjLq0A85TMCl38th6aP1F5Kr7ge57tx+4BkJamz\nGj5oXScmp7oq4fBXgwpkTx4idBvpkF/wrM//T2h6OKQQbA2xx6R3gBi2oihEdqc0nXGEL8pZ0keI\nmUEiyTCYYW49qKgFbdEfwFFEVn8nNQLdXpgKQuswv42hm1GqO+qTRmTFAHneIWv2V6CG1wZy7HBG\nS4tz3aAhdT7cHcCP009zHIXZ/n9iyJVvttN7jLpTwm+bREx50B1ws9efAvSyB7DH5fitIw6mVskp\nEndI2S9G/Tvw/HRwkqWOOAgfZDC2t0v7NqwQjqBSM2OdAzVWxWm9xiNaJ5T2pBL4LTM8oValX9YZ\n6e18CL13zSdkzJTaTkZQh+D5wVOAHrut+0dSixv9ovneDiK3PTNZbNTe9ZUGMg1RGUFcPk8G97kr\ngCf2o6p6fAbhQ8MTOWIaNr3gKC6UAuQpLmBVrkA9sHSSXvAgZJY/X0VdiLWK2gKgW0VU3jg9CcCo\nSmVGFvyqv1ROTVu+OEO3KMqLM6oaJbolXCkvW0pujOotnCr2BXbgd5eAiN1nE28daCSLT7d0geX0\nYJ96Vdc+N9oWaz53rK4YcJUIeSkDiv7BO7M/Gg+kO14fWKGVyasvc0rQLW6aWQ9VGHgtPFGml4vm\nu7JwqkwR3v98KzfUetF3NI/n+UL3PIEMS1IK\n-----END CERTIFICATE-----\n\nOpenTrust Root CA G3\n====================\n-----BEGIN CERTIFICATE-----\nMIICITCCAaagAwIBAgISESDm+Ez8JLC+BUCs2oMbNGA/MAoGCCqGSM49BAMDMEAxCzAJBgNVBAYT\nAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5UcnVzdCBSb290IENBIEczMB4X\nDTE0MDUyNjAwMDAwMFoXDTM4MDExNTAwMDAwMFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCU9w\nZW5UcnVzdDEdMBsGA1UEAwwUT3BlblRydXN0IFJvb3QgQ0EgRzMwdjAQBgcqhkjOPQIBBgUrgQQA\nIgNiAARK7liuTcpm3gY6oxH84Bjwbhy6LTAMidnW7ptzg6kjFYwvWYpa3RTqnVkrQ7cG7DK2uu5B\nta1doYXM6h0UZqNnfkbilPPntlahFVmhTzeXuSIevRHr9LIfXsMUmuXZl5mjYzBhMA4GA1UdDwEB\n/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRHd8MUi2I5DMlv4VBN0BBY3JWIbTAf\nBgNVHSMEGDAWgBRHd8MUi2I5DMlv4VBN0BBY3JWIbTAKBggqhkjOPQQDAwNpADBmAjEAj6jcnboM\nBBf6Fek9LykBl7+BFjNAk2z8+e2AcG+qj9uEwov1NcoG3GRvaBbhj5G5AjEA2Euly8LQCGzpGPta\n3U1fJAuwACEl74+nBCZx4nxp5V2a+EEfOzmTk51V6s2N8fvB\n-----END CERTIFICATE-----\n\nISRG Root X1\n============\n-----BEGIN CERTIFICATE-----\nMIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAwTzELMAkGA1UE\nBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2VhcmNoIEdyb3VwMRUwEwYDVQQD\nEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQG\nEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMT\nDElTUkcgUm9vdCBYMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54r\nVygch77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+0TM8ukj1\n3Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6UA5/TR5d8mUgjU+g4rk8K\nb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sWT8KOEUt+zwvo/7V3LvSye0rgTBIlDHCN\nAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyHB5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ\n4Q7e2RCOFvu396j3x+UCB5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf\n1b0SHzUvKBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWnOlFu\nhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTnjh8BCNAw1FtxNrQH\nusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbwqHyGO0aoSCqI3Haadr8faqU9GY/r\nOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CIrU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4G\nA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY\n9umbbjANBgkqhkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL\nubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ3BebYhtF8GaV\n0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KKNFtY2PwByVS5uCbMiogziUwt\nhDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJw\nTdwJx4nLCgdNbOhdjsnvzqvHu7UrTkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nx\ne5AW0wdeRlN8NwdCjNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZA\nJzVcoyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq4RgqsahD\nYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPAmRGunUHBcnWEvgJBQl9n\nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57demyPxgcYxn/eR44/KJ4EBs+lVDR3veyJ\nm+kXQ99b21/+jh5Xos1AnX5iItreGCc=\n-----END CERTIFICATE-----\n\nAC RAIZ FNMT-RCM\n================\n-----BEGIN CERTIFICATE-----\nMIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsxCzAJBgNVBAYT\nAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTTAeFw0wODEw\nMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJD\nTTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC\nggIBALpxgHpMhm5/yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcf\nqQgfBBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAzWHFctPVr\nbtQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxFtBDXaEAUwED653cXeuYL\nj2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z374jNUUeAlz+taibmSXaXvMiwzn15Cou\n08YfxGyqxRxqAQVKL9LFwag0Jl1mpdICIfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mw\nWsXmo8RZZUc1g16p6DULmbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnT\ntOmlcYF7wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peSMKGJ\n47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2ZSysV4999AeU14EC\nll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMetUqIJ5G+GR4of6ygnXYMgrwTJbFaa\ni0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE\nFPd9xf3E6Jobd2Sn9R2gzL+HYJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1o\ndHRwOi8vd3d3LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD\nnFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1RXxlDPiyN8+s\nD8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYMLVN0V2Ue1bLdI4E7pWYjJ2cJ\nj+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrT\nQfv6MooqtyuGC2mDOL7Nii4LcK2NJpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW\n+YJF1DngoABd15jmfZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7\nIxjp6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp1txyM/1d\n8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B9kiABdcPUXmsEKvU7ANm\n5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wokRqEIr9baRRmW1FMdW4R58MD3R++Lj8UG\nrp1MYp3/RgT408m2ECVAdf4WqslKYIYvuu8wd+RU4riEmViAqhOLUTpPSPaLtrM=\n-----END CERTIFICATE-----\n\nAmazon Root CA 1\n================\n-----BEGIN CERTIFICATE-----\nMIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsFADA5MQswCQYD\nVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAxMB4XDTE1\nMDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv\nbjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\nggEBALJ4gHHKeNXjca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgH\nFzZM9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qwIFAGbHrQ\ngLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6VOujw5H5SNz/0egwLX0t\ndHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L93FcXmn/6pUCyziKrlA4b9v7LWIbxcce\nVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQmjgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB\n/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3\nDQEBCwUAA4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDIU5PM\nCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUsN+gDS63pYaACbvXy\n8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vvo/ufQJVtMVT8QtPHRh8jrdkPSHCa\n2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2\nxJNDd2ZhwLnoQdeXeGADbkpyrqXRfboQnoZsG4q5WTP468SQvvG5\n-----END CERTIFICATE-----\n\nAmazon Root CA 2\n================\n-----BEGIN CERTIFICATE-----\nMIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwFADA5MQswCQYD\nVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAyMB4XDTE1\nMDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv\nbjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC\nggIBAK2Wny2cSkxKgXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4\nkHbZW0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg1dKmSYXp\nN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K8nu+NQWpEjTj82R0Yiw9\nAElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvd\nfLC6HM783k81ds8P+HgfajZRRidhW+mez/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAEx\nkv8LV/SasrlX6avvDXbR8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSS\nbtqDT6ZjmUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz7Mt0\nQ5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6+XUyo05f7O0oYtlN\nc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI0u1ufm8/0i2BWSlmy5A5lREedCf+\n3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSw\nDPBMMPQFWAJI/TPlUq9LhONmUjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oA\nA7CXDpO8Wqj2LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY\n+gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kSk5Nrp+gvU5LE\nYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl7uxMMne0nxrpS10gxdr9HIcW\nxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygmbtmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQ\ngj9sAq+uEjonljYE1x2igGOpm/HlurR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbW\naQbLU8uz/mtBzUF+fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoV\nYh63n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE76KlXIx3\nKadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H9jVlpNMKVv/1F2Rs76gi\nJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT4PsJYGw=\n-----END CERTIFICATE-----\n\nAmazon Root CA 3\n================\n-----BEGIN CERTIFICATE-----\nMIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5MQswCQYDVQQG\nEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAzMB4XDTE1MDUy\nNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ\nMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZB\nf8ANm+gBG1bG8lKlui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjr\nZt6jQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSrttvXBp43\nrDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkrBqWTrBqYaGFy+uGh0Psc\neGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteMYyRIHN8wfdVoOw==\n-----END CERTIFICATE-----\n\nAmazon Root CA 4\n================\n-----BEGIN CERTIFICATE-----\nMIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5MQswCQYDVQQG\nEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSA0MB4XDTE1MDUy\nNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ\nMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN\n/sGKe0uoe0ZLY7Bi9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri\n83BkM6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV\nHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WBMAoGCCqGSM49BAMDA2gA\nMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlwCkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1\nAE47xDqUEpHJWEadIRNyp4iciuRMStuW1KyLa2tJElMzrdfkviT8tQp21KW8EA==\n-----END CERTIFICATE-----\n\nLuxTrust Global Root 2\n======================\n-----BEGIN CERTIFICATE-----\nMIIFwzCCA6ugAwIBAgIUCn6m30tEntpqJIWe5rgV0xZ/u7EwDQYJKoZIhvcNAQELBQAwRjELMAkG\nA1UEBhMCTFUxFjAUBgNVBAoMDUx1eFRydXN0IFMuQS4xHzAdBgNVBAMMFkx1eFRydXN0IEdsb2Jh\nbCBSb290IDIwHhcNMTUwMzA1MTMyMTU3WhcNMzUwMzA1MTMyMTU3WjBGMQswCQYDVQQGEwJMVTEW\nMBQGA1UECgwNTHV4VHJ1c3QgUy5BLjEfMB0GA1UEAwwWTHV4VHJ1c3QgR2xvYmFsIFJvb3QgMjCC\nAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANeFl78RmOnwYoNMPIf5U2o3C/IPPIfOb9wm\nKb3FibrJgz337spbxm1Jc7TJRqMbNBM/wYlFV/TZsfs2ZUv7COJIcRHIbjuend+JZTemhfY7RBi2\nxjcwYkSSl2l9QjAk5A0MiWtj3sXh306pFGxT4GHO9hcvHTy95iJMHZP1EMShduxq3sVs35a0VkBC\nwGKSMKEtFZSg0iAGCW5qbeXrt77U8PEVfIvmTroTzEsnXpk8F12PgX8zPU/TPxvsXD/wPEx1bvKm\n1Z3aLQdjAsZy6ZS8TEmVT4hSyNvoaYL4zDRbIvCGp4m9SAptZoFtyMhk+wHh9OHe2Z7d21vUKpkm\nFRseTJIpgp7VkoGSQXAZ96Tlk0u8d2cx3Rz9MXANF5kM+Qw5GSoXtTBxVdUPrljhPS80m8+f9niF\nwpN6cj5mj5wWEWCPnolvZ77gR1o7DJpni89Gxq44o/KnvObWhWszJHAiS8sIm7vI+AIpHb4gDEa/\na4ebsypmQjVGbKq6rfmYe+lQVRQxv7HaLe2ArWgk+2mr2HETMOZns4dA/Yl+8kPREd8vZS9kzl8U\nubG/Mb2HeFpZZYiq/FkySIbWTLkpS5XTdvN3JW1CHDiDTf2jX5t/Lax5Gw5CMZdjpPuKadUiDTSQ\nMC6otOBttpSsvItO13D8xTiOZCXhTTmQzsmHhFhxAgMBAAGjgagwgaUwDwYDVR0TAQH/BAUwAwEB\n/zBCBgNVHSAEOzA5MDcGByuBKwEBAQowLDAqBggrBgEFBQcCARYeaHR0cHM6Ly9yZXBvc2l0b3J5\nLmx1eHRydXN0Lmx1MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBT/GCh2+UgFLKGu8SsbK7JT\n+Et8szAdBgNVHQ4EFgQU/xgodvlIBSyhrvErGyuyU/hLfLMwDQYJKoZIhvcNAQELBQADggIBAGoZ\nFO1uecEsh9QNcH7X9njJCwROxLHOk3D+sFTAMs2ZMGQXvw/l4jP9BzZAcg4atmpZ1gDlaCDdLnIN\nH2pkMSCEfUmmWjfrRcmF9dTHF5kH5ptV5AzoqbTOjFu1EVzPig4N1qx3gf4ynCSecs5U89BvolbW\n7MM3LGVYvlcAGvI1+ut7MV3CwRI9loGIlonBWVx65n9wNOeD4rHh4bhY79SV5GCc8JaXcozrhAIu\nZY+kt9J/Z93I055cqqmkoCUUBpvsT34tC38ddfEz2O3OuHVtPlu5mB0xDVbYQw8wkbIEa91WvpWA\nVWe+2M2D2RjuLg+GLZKecBPs3lHJQ3gCpU3I+V/EkVhGFndadKpAvAefMLmx9xIX3eP/JEAdemrR\nTxgKqpAd60Ae36EeRJIQmvKN4dFLRp7oRUKX6kWZ8+xm1QL68qZKJKrezrnK+T+Tb/mjuuqlPpmt\n/f97mfVl7vBZKGfXkJWkE4SphMHozs51k2MavDzq1WQfLSoSOcbDWjLtR5EWDrw4wVDej8oqkDQc\n7kGUnF4ZLvhFSZl0kbAEb+MEWrGrKqv+x9CWttrhSmQGbmBNvUJO/3jaJMobtNeWOWyu8Q6qp31I\niyBMz2TWuJdGsE7RKlY6oJO9r4Ak4Ap+58rVyuiFVdw2KuGUaJPHZnJED4AhMmwlxyOAgwrr\n-----END CERTIFICATE-----\n\nTUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1\n=============================================\n-----BEGIN CERTIFICATE-----\nMIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIxGDAWBgNVBAcT\nD0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxpbXNlbCB2ZSBUZWtub2xvamlr\nIEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0wKwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24g\nTWVya2V6aSAtIEthbXUgU00xNjA0BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRp\nZmlrYXNpIC0gU3VydW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYD\nVQQGEwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXllIEJpbGlt\nc2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklUQUsxLTArBgNVBAsTJEth\nbXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBTTTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11\nIFNNIFNTTCBLb2sgU2VydGlmaWthc2kgLSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\nMIIBCgKCAQEAr3UwM6q7a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y8\n6Ij5iySrLqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INrN3wc\nwv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2XYacQuFWQfw4tJzh0\n3+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/iSIzL+aFCr2lqBs23tPcLG07xxO9\nWSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4fAJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQU\nZT/HiobGPN08VFw1+DrtUgxHV8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJ\nKoZIhvcNAQELBQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh\nAHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPfIPP54+M638yc\nlNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4lzwDGrpDxpa5RXI4s6ehlj2R\ne37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0j\nq5Rm+K37DwhuJi1/FwcJsoz7UMCflo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM=\n-----END CERTIFICATE-----\n\nGDCA TrustAUTH R5 ROOT\n======================\n-----BEGIN CERTIFICATE-----\nMIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UEBhMCQ04xMjAw\nBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8wHQYDVQQD\nDBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0MTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVow\nYjELMAkGA1UEBhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ\nIENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0B\nAQEFAAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJjDp6L3TQs\nAlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBjTnnEt1u9ol2x8kECK62p\nOqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+uKU49tm7srsHwJ5uu4/Ts765/94Y9cnrr\npftZTqfrlYwiOXnhLQiPzLyRuEH3FMEjqcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ\n9Cy5WmYqsBebnh52nUpmMUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQ\nxXABZG12ZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloPzgsM\nR6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3GkL30SgLdTMEZeS1SZ\nD2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeCjGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4\noR24qoAATILnsn8JuLwwoC8N9VKejveSswoAHQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx\n9hoh49pwBiFYFIeFd3mqgnkCAwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlR\nMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg\np8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZmDRd9FBUb1Ov9\nH5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5COmSdI31R9KrO9b7eGZONn35\n6ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ryL3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd\n+PwyvzeG5LuOmCd+uh8W4XAR8gPfJWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQ\nHtZa37dG/OaG+svgIHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBD\nF8Io2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV09tL7ECQ\n8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQXR4EzzffHqhmsYzmIGrv\n/EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrqT8p+ck0LcIymSLumoRT2+1hEmRSuqguT\naaApJUqlyyvdimYHFngVV3Eb7PVHhPOeMTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g==\n-----END CERTIFICATE-----\n\nTrustCor RootCert CA-1\n======================\n-----BEGIN CERTIFICATE-----\nMIIEMDCCAxigAwIBAgIJANqb7HHzA7AZMA0GCSqGSIb3DQEBCwUAMIGkMQswCQYDVQQGEwJQQTEP\nMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEkMCIGA1UECgwbVHJ1c3RDb3Ig\nU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3Jp\ndHkxHzAdBgNVBAMMFlRydXN0Q29yIFJvb3RDZXJ0IENBLTEwHhcNMTYwMjA0MTIzMjE2WhcNMjkx\nMjMxMTcyMzE2WjCBpDELMAkGA1UEBhMCUEExDzANBgNVBAgMBlBhbmFtYTEUMBIGA1UEBwwLUGFu\nYW1hIENpdHkxJDAiBgNVBAoMG1RydXN0Q29yIFN5c3RlbXMgUy4gZGUgUi5MLjEnMCUGA1UECwwe\nVHJ1c3RDb3IgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR8wHQYDVQQDDBZUcnVzdENvciBSb290Q2Vy\ndCBDQS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv463leLCJhJrMxnHQFgKq1mq\njQCj/IDHUHuO1CAmujIS2CNUSSUQIpidRtLByZ5OGy4sDjjzGiVoHKZaBeYei0i/mJZ0PmnK6bV4\npQa81QBeCQryJ3pS/C3Vseq0iWEk8xoT26nPUu0MJLq5nux+AHT6k61sKZKuUbS701e/s/OojZz0\nJEsq1pme9J7+wH5COucLlVPat2gOkEz7cD+PSiyU8ybdY2mplNgQTsVHCJCZGxdNuWxu72CVEY4h\ngLW9oHPY0LJ3xEXqWib7ZnZ2+AYfYW0PVcWDtxBWcgYHpfOxGgMFZA6dWorWhnAbJN7+KIor0Gqw\n/Hqi3LJ5DotlDwIDAQABo2MwYTAdBgNVHQ4EFgQU7mtJPHo/DeOxCbeKyKsZn3MzUOcwHwYDVR0j\nBBgwFoAU7mtJPHo/DeOxCbeKyKsZn3MzUOcwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\nAYYwDQYJKoZIhvcNAQELBQADggEBACUY1JGPE+6PHh0RU9otRCkZoB5rMZ5NDp6tPVxBb5UrJKF5\nmDo4Nvu7Zp5I/5CQ7z3UuJu0h3U/IJvOcs+hVcFNZKIZBqEHMwwLKeXx6quj7LUKdJDHfXLy11yf\nke+Ri7fc7Waiz45mO7yfOgLgJ90WmMCV1Aqk5IGadZQ1nJBfiDcGrVmVCrDRZ9MZyonnMlo2HD6C\nqFqTvsbQZJG2z9m2GM/bftJlo6bEjhcxwft+dtvTheNYsnd6djtsL1Ac59v2Z3kf9YKVmgenFK+P\n3CghZwnS1k1aHBkcjndcw5QkPTJrS37UeJSDvjdNzl/HHk484IkzlQsPpTLWPFp5LBk=\n-----END CERTIFICATE-----\n\nTrustCor RootCert CA-2\n======================\n-----BEGIN CERTIFICATE-----\nMIIGLzCCBBegAwIBAgIIJaHfyjPLWQIwDQYJKoZIhvcNAQELBQAwgaQxCzAJBgNVBAYTAlBBMQ8w\nDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQwIgYDVQQKDBtUcnVzdENvciBT\neXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRydXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0\neTEfMB0GA1UEAwwWVHJ1c3RDb3IgUm9vdENlcnQgQ0EtMjAeFw0xNjAyMDQxMjMyMjNaFw0zNDEy\nMzExNzI2MzlaMIGkMQswCQYDVQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5h\nbWEgQ2l0eTEkMCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U\ncnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRydXN0Q29yIFJvb3RDZXJ0\nIENBLTIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCnIG7CKqJiJJWQdsg4foDSq8Gb\nZQWU9MEKENUCrO2fk8eHyLAnK0IMPQo+QVqedd2NyuCb7GgypGmSaIwLgQ5WoD4a3SwlFIIvl9Nk\nRvRUqdw6VC0xK5mC8tkq1+9xALgxpL56JAfDQiDyitSSBBtlVkxs1Pu2YVpHI7TYabS3OtB0PAx1\noYxOdqHp2yqlO/rOsP9+aij9JxzIsekp8VduZLTQwRVtDr4uDkbIXvRR/u8OYzo7cbrPb1nKDOOb\nXUm4TOJXsZiKQlecdu/vvdFoqNL0Cbt3Nb4lggjEFixEIFapRBF37120Hapeaz6LMvYHL1cEksr1\n/p3C6eizjkxLAjHZ5DxIgif3GIJ2SDpxsROhOdUuxTTCHWKF3wP+TfSvPd9cW436cOGlfifHhi5q\njxLGhF5DUVCcGZt45vz27Ud+ez1m7xMTiF88oWP7+ayHNZ/zgp6kPwqcMWmLmaSISo5uZk3vFsQP\neSghYA2FFn3XVDjxklb9tTNMg9zXEJ9L/cb4Qr26fHMC4P99zVvh1Kxhe1fVSntb1IVYJ12/+Ctg\nrKAmrhQhJ8Z3mjOAPF5GP/fDsaOGM8boXg25NSyqRsGFAnWAoOsk+xWq5Gd/bnc/9ASKL3x74xdh\n8N0JqSDIvgmk0H5Ew7IwSjiqqewYmgeCK9u4nBit2uBGF6zPXQIDAQABo2MwYTAdBgNVHQ4EFgQU\n2f4hQG6UnrybPZx9mCAZ5YwwYrIwHwYDVR0jBBgwFoAU2f4hQG6UnrybPZx9mCAZ5YwwYrIwDwYD\nVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBAJ5Fngw7tu/h\nOsh80QA9z+LqBrWyOrsGS2h60COXdKcs8AjYeVrXWoSK2BKaG9l9XE1wxaX5q+WjiYndAfrs3fnp\nkpfbsEZC89NiqpX+MWcUaViQCqoL7jcjx1BRtPV+nuN79+TMQjItSQzL/0kMmx40/W5ulop5A7Zv\n2wnL/V9lFDfhOPXzYRZY5LVtDQsEGz9QLX+zx3oaFoBg+Iof6Rsqxvm6ARppv9JYx1RXCI/hOWB3\nS6xZhBqI8d3LT3jX5+EzLfzuQfogsL7L9ziUwOHQhQ+77Sxzq+3+knYaZH9bDTMJBzN7Bj8RpFxw\nPIXAz+OQqIN3+tvmxYxoZxBnpVIt8MSZj3+/0WvitUfW2dCFmU2Umw9Lje4AWkcdEQOsQRivh7dv\nDDqPys/cA8GiCcjl/YBeyGBCARsaU1q7N6a3vLqE6R5sGtRk2tRD/pOLS/IseRYQ1JMLiI+h2IYU\nRpFHmygk71dSTlxCnKr3Sewn6EAes6aJInKc9Q0ztFijMDvd1GpUk74aTfOTlPf8hAs/hCBcNANE\nxdqtvArBAs8e5ZTZ845b2EzwnexhF7sUMlQMAimTHpKG9n/v55IFDlndmQguLvqcAFLTxWYp5KeX\nRKQOKIETNcX2b2TmQcTVL8w0RSXPQQCWPUouwpaYT05KnJe32x+SMsj/D1Fu1uwJ\n-----END CERTIFICATE-----\n\nTrustCor ECA-1\n==============\n-----BEGIN CERTIFICATE-----\nMIIEIDCCAwigAwIBAgIJAISCLF8cYtBAMA0GCSqGSIb3DQEBCwUAMIGcMQswCQYDVQQGEwJQQTEP\nMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEkMCIGA1UECgwbVHJ1c3RDb3Ig\nU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3Jp\ndHkxFzAVBgNVBAMMDlRydXN0Q29yIEVDQS0xMB4XDTE2MDIwNDEyMzIzM1oXDTI5MTIzMTE3Mjgw\nN1owgZwxCzAJBgNVBAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5\nMSQwIgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRydXN0Q29y\nIENlcnRpZmljYXRlIEF1dGhvcml0eTEXMBUGA1UEAwwOVHJ1c3RDb3IgRUNBLTEwggEiMA0GCSqG\nSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPj+ARtZ+odnbb3w9U73NjKYKtR8aja+3+XzP4Q1HpGjOR\nMRegdMTUpwHmspI+ap3tDvl0mEDTPwOABoJA6LHip1GnHYMma6ve+heRK9jGrB6xnhkB1Zem6g23\nxFUfJ3zSCNV2HykVh0A53ThFEXXQmqc04L/NyFIduUd+Dbi7xgz2c1cWWn5DkR9VOsZtRASqnKmc\np0yJF4OuowReUoCLHhIlERnXDH19MURB6tuvsBzvgdAsxZohmz3tQjtQJvLsznFhBmIhVE5/wZ0+\nfyCMgMsq2JdiyIMzkX2woloPV+g7zPIlstR8L+xNxqE6FXrntl019fZISjZFZtS6mFjBAgMBAAGj\nYzBhMB0GA1UdDgQWBBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAfBgNVHSMEGDAWgBREnkj1zG1I1KBL\nf/5ZJC+Dl5mahjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsF\nAAOCAQEABT41XBVwm8nHc2FvcivUwo/yQ10CzsSUuZQRg2dd4mdsdXa/uwyqNsatR5Nj3B5+1t4u\n/ukZMjgDfxT2AHMsWbEhBuH7rBiVDKP/mZb3Kyeb1STMHd3BOuCYRLDE5D53sXOpZCz2HAF8P11F\nhcCF5yWPldwX8zyfGm6wyuMdKulMY/okYWLW2n62HGz1Ah3UKt1VkOsqEUc8Ll50soIipX1TH0Xs\nJ5F95yIW6MBoNtjG8U+ARDL54dHRHareqKucBK+tIA5kmE2la8BIWJZpTdwHjFGTot+fDz2LYLSC\njaoITmJF4PkL0uDgPFveXHEnJcLmA4GLEFPjx1WitJ/X5g==\n-----END CERTIFICATE-----\n\nSSL.com Root Certification Authority RSA\n========================================\n-----BEGIN CERTIFICATE-----\nMIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxDjAM\nBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9TU0wgQ29ycG9yYXRpb24x\nMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYw\nMjEyMTczOTM5WhcNNDEwMjEyMTczOTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMx\nEDAOBgNVBAcMB0hvdXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NM\nLmNvbSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcNAQEBBQAD\nggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2RxFdHaxh3a3by/ZPkPQ/C\nFp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aXqhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8\nP2FI7bADFB0QDksZ4LtO7IZl/zbzXmcCC52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/ge\noeOy3ZExqysdBP+lSgQ36YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkp\nk8zruFvh/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrFYD3Z\nfBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93EJNyAKoFBbZQ+yODJ\ngUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVcUS4cK38acijnALXRdMbX5J+tB5O2\nUzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi8\n1xtZPCvM8hnIk2snYxnP/Okm+Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4s\nbE6x/c+cCbqiM+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV\nHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4GA1UdDwEB/wQE\nAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGVcpNxJK1ok1iOMq8bs3AD/CUr\ndIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBcHadm47GUBwwyOabqG7B52B2ccETjit3E+ZUf\nijhDPwGFpUenPUayvOUiaPd7nNgsPgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAsl\nu1OJD7OAUN5F7kR/q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjq\nerQ0cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jra6x+3uxj\nMxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90IH37hVZkLId6Tngr75qNJ\nvTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/YK9f1JmzJBjSWFupwWRoyeXkLtoh/D1JI\nPb9s2KJELtFOt3JY04kTlf5Eq/jXixtunLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406y\nwKBjYZC6VWg3dGq2ktufoYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NI\nWuuA8ShYIc2wBlX7Jz9TkHCpBB5XJ7k=\n-----END CERTIFICATE-----\n\nSSL.com Root Certification Authority ECC\n========================================\n-----BEGIN CERTIFICATE-----\nMIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMCVVMxDjAMBgNV\nBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9TU0wgQ29ycG9yYXRpb24xMTAv\nBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEy\nMTgxNDAzWhcNNDEwMjEyMTgxNDAzWjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAO\nBgNVBAcMB0hvdXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv\nbSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuBBAAiA2IA\nBEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI7Z4INcgn64mMU1jrYor+\n8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPgCemB+vNH06NjMGEwHQYDVR0OBBYEFILR\nhXMw5zUE044CkvvlpNHEIejNMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTT\njgKS++Wk0cQh6M0wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCW\ne+0F+S8Tkdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+gA0z\n5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl\n-----END CERTIFICATE-----\n\nSSL.com EV Root Certification Authority RSA R2\n==============================================\n-----BEGIN CERTIFICATE-----\nMIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNVBAYTAlVTMQ4w\nDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9u\nMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy\nMB4XDTE3MDUzMTE4MTQzN1oXDTQyMDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQI\nDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYD\nVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMIICIjAN\nBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvqM0fNTPl9fb69LT3w23jh\nhqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssufOePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7w\ncXHswxzpY6IXFJ3vG2fThVUCAtZJycxa4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTO\nZw+oz12WGQvE43LrrdF9HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+\nB6KjBSYRaZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcAb9Zh\nCBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQGp8hLH94t2S42Oim\n9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQVPWKchjgGAGYS5Fl2WlPAApiiECto\nRHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMOpgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+Slm\nJuwgUHfbSguPvuUCYHBBXtSuUDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48\n+qvWBkofZ6aYMBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV\nHSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa49QaAJadz20Zp\nqJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBWs47LCp1Jjr+kxJG7ZhcFUZh1\n++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nx\nY/hoLVUE0fKNsKTPvDxeH3jnpaAgcLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2G\nguDKBAdRUNf/ktUM79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDz\nOFSz/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXtll9ldDz7\nCTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEmKf7GUmG6sXP/wwyc5Wxq\nlD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKKQbNmC1r7fSOl8hqw/96bg5Qu0T/fkreR\nrwU7ZcegbLHNYhLDkBvjJc40vG93drEQw/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1\nhlMYegouCRw2n5H9gooiS9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX\n9hwJ1C07mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w==\n-----END CERTIFICATE-----\n\nSSL.com EV Root Certification Authority ECC\n===========================================\n-----BEGIN CERTIFICATE-----\nMIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMCVVMxDjAMBgNV\nBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9TU0wgQ29ycG9yYXRpb24xNDAy\nBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYw\nMjEyMTgxNTIzWhcNNDEwMjEyMTgxNTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMx\nEDAOBgNVBAcMB0hvdXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NM\nLmNvbSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB\nBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMAVIbc/R/fALhBYlzccBYy\n3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1KthkuWnBaBu2+8KGwytAJKaNjMGEwHQYDVR0O\nBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZPMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe\n5d7SgarNqC1kUbbZcpuX5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJ\nN+vp1RPZytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZgh5Mm\nm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg==\n-----END CERTIFICATE-----\n"
  },
  {
    "path": "code/default/x_tunnel/local/cloudfront_front/check_ip.py",
    "content": "#!/usr/bin/env python2\n# coding:utf-8\n\nimport sys\nimport os\nimport threading\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nroot_path = os.path.abspath( os.path.join(current_path, os.pardir, os.pardir, os.pardir))\npython_path = root_path\n\nsys.path.append(root_path)\n\nnoarch_lib = os.path.abspath( os.path.join(python_path, 'lib', 'noarch'))\nsys.path.append(noarch_lib)\n\nif sys.platform == \"win32\":\n    win32_lib = os.path.abspath( os.path.join(python_path, 'lib', 'win32'))\n    sys.path.append(win32_lib)\nelif sys.platform.startswith(\"linux\"):\n    linux_lib = os.path.abspath( os.path.join(python_path, 'lib', 'linux'))\n    sys.path.append(linux_lib)\nelif sys.platform == \"darwin\":\n    darwin_lib = os.path.abspath( os.path.join(python_path, 'lib', 'darwin'))\n    sys.path.append(darwin_lib)\n    extra_lib = \"/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python\"\n    sys.path.append(extra_lib)\n\n\nimport env_info\nimport utils\nimport xlog\nlogger = xlog.getLogger(\"cloudfront_front\")\nlogger.set_buffer(500)\n\nfrom front_base.openssl_wrap import SSLContext\nfrom .connect_creator import ConnectCreator\nfrom front_base.check_ip import CheckIp\nfrom front_base.host_manager import HostManagerBase\nfrom .config import Config\n\ndata_path = env_info.data_path\nmodule_data_path = os.path.join(data_path, 'x_tunnel')\n\n\nclass CheckAllIp(object):\n    def __init__(self, check_ip, host):\n        self.check_ip = check_ip\n        self.host = host\n        self.lock = threading.Lock()\n\n        self.in_fd = open(\"good_ip.txt\", \"r\")\n        self.out_fd = open(\n            os.path.join(module_data_path, \"cloudfront_checked_ip.txt\"),\n            \"w\"\n        )\n\n    def get_ip(self):\n        with self.lock:\n            while True:\n                line = self.in_fd.readline()\n                if not line:\n                    raise Exception()\n\n                try:\n                    ip = line.split()[0]\n                    return ip\n                except:\n                    continue\n\n    def write_ip(self, ip, host, handshake):\n        with self.lock:\n            self.out_fd.write(\"%s %s gws %d 0 0\\n\" % (ip, host, handshake))\n            self.out_fd.flush()\n\n    def checker(self):\n        while True:\n            try:\n                ip = self.get_ip()\n            except Exception as e:\n                xlog.info(\"no ip left\")\n                return\n\n            try:\n                res = self.check_ip.check_ip(ip, host=host)\n            except Exception as e:\n                xlog.warn(\"check fail:%s except:%r\", e)\n                continue\n\n            if not res or not res.ok:\n                xlog.debug(\"check fail:%s fail\", ip)\n                continue\n\n            self.write_ip(ip, res.domain, res.handshake_time)\n\n    def run(self):\n        for i in range(0, 10):\n            threading.Thread(target=self.checker).start()\n\n\ndef check_all_ip(check_ip):\n    check = CheckAllIp(check_ip, \"scan1.xx-net.org\")\n    check.run()\n\n\nif __name__ == \"__main__\":\n    # case 1: only ip\n    # case 2: ip + domain\n    #    connect use domain\n\n    default_ip = \"54.192.35.105\"\n\n    sni = \"dnn506yrbagrg.cloudfront.net\"\n    host = \"d14haayoytfxn1.cloudfront.net\"\n    if len(sys.argv) > 1:\n        ip = sys.argv[1]\n        if not utils.check_ip_valid(ip):\n            ip = default_ip\n            host = sys.argv[1]\n    else:\n        ip = default_ip\n        xlog.info(\"Usage: check_ip.py [ip] [top_domain] [wait_time=0]\")\n    xlog.info(\"test ip:%s\", ip)\n\n    if len(sys.argv) > 2:\n        host = sys.argv[2]\n    xlog.info(\"host:%s\", host)\n\n    if len(sys.argv) > 3:\n        wait_time = int(sys.argv[3])\n    else:\n        wait_time = 0\n\n    config_path = os.path.join(module_data_path, \"cloudfront_front.json\")\n    config = Config(config_path)\n\n    openssl_context = SSLContext(logger, support_http2=True)\n    host_manager = HostManagerBase()\n    connect_creator = ConnectCreator(logger, config, openssl_context, host_manager, debug=True)\n    check_ip = CheckIp(logger, config, connect_creator)\n\n    #check_all_ip(check_ip)\n    #exit(0)\n\n    res = check_ip.check_ip(ip, sni=sni, host=host, wait_time=wait_time)\n    if not res:\n        xlog.warn(\"connect fail\")\n    elif res.ok:\n        xlog.info(\"success, domain:%s handshake:%d\", res.host, res.handshake_time)\n        xlog.info(\"response:%s\",res.response.content)\n    else:\n        xlog.warn(\"not support\")"
  },
  {
    "path": "code/default/x_tunnel/local/cloudfront_front/config.py",
    "content": "\nfrom front_base.config import ConfigBase\n\n\nclass Config(ConfigBase):\n    def __init__(self, fn):\n        super(Config, self).__init__(fn)\n\n        # front\n        self.set_var(\"front_continue_fail_num\", 10)\n        self.set_var(\"front_continue_fail_block\", 180)\n\n        # http_dispatcher\n        self.set_var(\"dispather_min_idle_workers\", 0)\n        self.set_var(\"dispather_work_min_idle_time\", 0)\n        self.set_var(\"dispather_work_max_score\", 20000)\n        self.set_var(\"dispather_max_workers\", 3)\n        self.set_var(\"dispather_score_factor\", 1000)\n\n        # http 2 worker\n        self.set_var(\"http2_max_concurrent\", 40)\n        self.set_var(\"http2_status_to_close\", [403])\n\n        # connect_manager\n        self.set_var(\"ssl_first_use_timeout\", 5)\n        self.set_var(\"connection_pool_min\", 0)\n        self.set_var(\"https_new_connect_num\", 0)\n\n        # check_ip\n        self.set_var(\"check_ip_content\", \"OK\")\n\n        # connect_creator\n        self.set_var(\"check_sni\", 1)\n\n        # ip_manager\n        self.set_var(\"max_scan_ip_thread_num\", 1)\n        self.set_var(\"max_good_ip_num\", 50)\n        self.set_var(\"target_handshake_time\", 550)\n\n        self.load()"
  },
  {
    "path": "code/default/x_tunnel/local/cloudfront_front/connect_creator.py",
    "content": "\nimport socket\nfrom front_base.connect_creator import ConnectCreator as ConnectCreatorBase\n\n\nclass ConnectCreator(ConnectCreatorBase):\n    def check_cert(self, ssl_sock):\n        cert_chain = ssl_sock.get_peer_cert_chain()\n        if not cert_chain:\n            raise socket.error(' certificate is none, sni:%s' % ssl_sock.sni)\n\n        self.get_ssl_cert_domain(ssl_sock)\n        issuer_commonname = next((v for k, v in cert_chain[0].get_issuer().get_components() if k == 'CN'), '')\n        if self.debug:\n            for cert in cert_chain:\n                for k, v in cert.get_issuer().get_components():\n                    if k != \"CN\":\n                        continue\n                    cn = v\n                    self.logger.debug(\"cn:%s\", cn)\n\n            self.logger.debug(\"issued by:%s\", issuer_commonname)\n            self.logger.debug(\"Common Name:%s\", ssl_sock.domain)\n\n        if self.config.check_commonname and not issuer_commonname.startswith(self.config.check_commonname):\n            raise socket.error(' certficate is issued by %r' % (issuer_commonname))\n\n        if not self.config.check_sni:\n            return True\n\n        cert = ssl_sock.get_peer_certificate()\n        if not cert:\n            raise socket.error('certficate is none')\n\n        # get_subj_alt_name cost near 100ms. be careful.\n        try:\n            alt_names = ConnectCreator.get_subj_alt_name(cert)\n        except Exception as e:\n            # self.logger.warn(\"get_subj_alt_name fail:%r\", e)\n            alt_names = [\"\"]\n\n        if self.debug:\n            self.logger.debug('alt names: \"%s\"', '\", \"'.join(alt_names))\n\n        if 'cloudfront.net' in alt_names:\n            return True\n\n        alt_names = tuple(alt_names)\n        if ssl_sock.sni.endswith(alt_names):\n            return True\n\n        raise socket.error('check sni:%s fail, alt_names:%s' % (ssl_sock.sni, alt_names))\n"
  },
  {
    "path": "code/default/x_tunnel/local/cloudfront_front/front.py",
    "content": "import os\n\nimport xlog\nlogger = xlog.getLogger(\"cloudfront_front\")\nlogger.set_buffer(500)\n\nfrom front_base.openssl_wrap import SSLContext\nfrom front_base.ip_manager import IpManager\nfrom front_base.ip_source import Ipv4RangeSource\nfrom front_base.http_dispatcher import HttpsDispatcher\nfrom front_base.connect_manager import ConnectManager\nfrom front_base.check_ip import CheckIp\n\nfrom .connect_creator import ConnectCreator\nfrom .config import Config\nfrom . import host_manager\nfrom gae_proxy.local import check_local_network\nimport env_info\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nroot_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir, os.pardir))\ndata_path = env_info.data_path\nmodule_data_path = os.path.join(data_path, 'x_tunnel')\n\n\nclass Front(object):\n    name = \"cloudfront_front\"\n\n    def start(self):\n        self.running = True\n        self.last_host = \"www.xx-net.org\"\n\n        self.logger = logger\n        config_path = os.path.join(module_data_path, \"cloudfront_front.json\")\n        self.config = Config(config_path)\n\n        sni_fn = os.path.join(current_path, \"sni_list.txt\")\n        self.host_manager = host_manager.HostManager(fn=sni_fn, max_size=120)\n\n        ca_certs = os.path.join(current_path, \"cacert.pem\")\n        openssl_context = SSLContext(logger, ca_certs=ca_certs, support_http2=True)\n        self.connect_creator = ConnectCreator(logger, self.config, openssl_context, self.host_manager)\n        self.ip_checker = CheckIp(xlog.null, self.config, self.connect_creator)\n\n        ip_source = Ipv4RangeSource(\n            logger, self.config,\n            os.path.join(current_path, \"ip_range.txt\"),\n            os.path.join(module_data_path, \"cloudfront_ip_range.txt\")\n        )\n        self.ip_manager = IpManager(\n            logger, self.config, ip_source, self.host_manager, check_local_network,\n            self.check_ip,\n            os.path.join(current_path, \"good_ip.txt\"),\n            os.path.join(module_data_path, \"cloudfront_ip_list.txt\"),\n            scan_ip_log=None)\n\n        self.connect_manager = ConnectManager(\n            logger, self.config, self.connect_creator, self.ip_manager, check_local_network)\n\n        self.dispatchs = {}\n\n    def check_ip(self, ip):\n        sni, host = self.host_manager.get_sni_host(ip)\n        host = \"scan1.xx-net.org\"\n        return self.ip_checker.check_ip(ip, sni=sni, host=host)\n\n    def get_dispatcher(self, host=None):\n        if host is None:\n            host = self.last_host\n        else:\n            self.last_host = host\n\n        if host not in self.dispatchs:\n            http_dispatcher = HttpsDispatcher(\n                logger, self.config, self.ip_manager, self.connect_manager\n            )\n            self.dispatchs[host] = http_dispatcher\n\n        dispatcher = self.dispatchs[host]\n        return dispatcher\n\n    def request(self, method, host, path=\"/\", headers={}, data=\"\", timeout=120):\n        dispatcher = self.get_dispatcher(host)\n        headers = dict(headers)\n        response = dispatcher.request(method, host, path, headers, data, timeout=timeout)\n        if not response:\n            self.logger.warn(\"req %s get response timeout\", path)\n            return \"\", 602, {}\n\n        status = response.status\n        content = response.task.read_all()\n        if status == 200:\n            self.logger.debug(\"%s %s%s status:%d trace:%s\", method, response.worker.ssl_sock.host, path, status,\n                       response.task.get_trace())\n        else:\n            self.logger.warn(\"%s %s%s status:%d trace:%s\", method, response.worker.ssl_sock.host, path, status,\n                       response.task.get_trace())\n        return content, status, response\n\n    def stop(self):\n        logger.info(\"terminate\")\n        self.connect_manager.set_ssl_created_cb(None)\n        for host in self.dispatchs:\n            dispatcher = self.dispatchs[host]\n            dispatcher.stop()\n        self.connect_manager.stop()\n        self.ip_manager.stop()\n\n        self.running = False\n\n    def set_proxy(self, args):\n        logger.info(\"set_proxy:%s\", args)\n\n        self.config.PROXY_ENABLE = args[\"enable\"]\n        self.config.PROXY_TYPE = args[\"type\"]\n        self.config.PROXY_HOST = args[\"host\"]\n        self.config.PROXY_PORT = args[\"port\"]\n        self.config.PROXY_USER = args[\"user\"]\n        self.config.PROXY_PASSWD = args[\"passwd\"]\n\n        self.config.save()\n\n        self.connect_creator.update_config()\n\n\nfront = Front()"
  },
  {
    "path": "code/default/x_tunnel/local/cloudfront_front/good_ip.txt",
    "content": "54.192.37.222 sni200439.cloudflaressl.com gws 217 0 1\n52.85.76.223 horizonsetfs.com.hk gws 399 0 0\n13.32.201.11 cdnparap40.paragonrels.com gws 441 0 0\n52.222.213.62 cdn.portmandentalcare.com gws 464 0 0\n52.85.186.202 aeliadutyfree.co.nz gws 486 0 0\n52.84.98.224 pitchinvestorslive.com gws 489 0 0\n54.182.3.236 *.cloudfront.net gws 497 0 0\n54.239.168.30 *.loanhero.com gws 505 0 0\n54.230.53.209 cabet73.com gws 545 0 0\n52.85.205.250 smugmug.com gws 551 0 0\n54.192.15.87 *.cloudfront.net gws 553 0 0\n52.222.254.41 *.cloudfront.net gws 568 0 0\n54.239.221.234 *.lumahealth.io gws 576 0 0\n13.33.37.53 *.cicayda.net gws 577 0 0\n54.240.190.18 *.cloudfront.net gws 583 0 0\n13.33.186.188 *.hypermartialarts.com gws 585 0 0\n54.239.223.103 dev.portal.amalto.com gws 588 0 0\n216.137.39.228 *.adlip.me gws 602 0 0\n52.222.253.157 *.cloudfront.net gws 604 0 0\n13.32.244.70 *.lollapaloozaar.com gws 612 0 0\n54.192.35.105 kieser-training.com gws 615 0 0\n13.33.74.158 smugmug.com gws 618 0 0\n54.239.132.59 *.mokapos.com gws 624 0 0\n52.222.158.84 *.identitybridge.us gws 627 0 0\n52.222.151.156 soft32.com gws 633 0 0\n54.192.87.45 www.gov.hk gws 640 0 0\n54.192.19.148 *.pathable.com gws 642 0 0\n13.33.119.71 *.virgilio.it gws 645 0 0\n13.33.108.183 *.cloudfront.net gws 651 0 0\n54.239.219.173 *.destinationcanada.com gws 652 0 0\n54.192.97.125 *.motivosity.com gws 657 0 0\n13.33.224.98 *.tombola.com gws 658 0 0\n13.33.20.183 *.cloudfront.net gws 664 0 0\n13.32.29.8 *.simplesite.com gws 665 0 0\n13.32.155.7 *.vogue.in gws 676 0 0\n54.192.185.221 *.cloudfront.net gws 686 0 0\n52.46.36.67 *.scripbox.com gws 689 0 0\n54.230.61.56 smugmug.com gws 691 0 0\n216.137.43.92 courses.ed-era.com gws 696 0 0\n54.192.44.167 *.decathloncoach.com gws 698 0 0\n54.239.179.11 *.cloudfront.net gws 702 0 0\n52.222.215.66 smugmug.com gws 708 0 0\n13.32.144.186 smugmug.com gws 713 0 0\n52.84.8.178 smugmug.com gws 715 0 0\n13.32.255.107 *.cloudfront.net gws 715 0 0\n13.32.204.41 *.cloudfront.net gws 724 0 0\n13.33.136.237 *.simplesite.com gws 728 0 0\n54.192.135.186 *.cloudfront.net gws 728 0 0\n54.240.130.223 fronts.gutools.co.uk gws 734 0 0\n54.239.152.183 smugmug.com gws 735 0 0\n52.222.250.198 *.today.com gws 737 0 0\n13.32.4.44 smugmug.com gws 738 0 0\n216.137.61.32 smugmug.com gws 743 0 0\n52.222.179.121 *.cloudfront.net gws 745 0 0\n54.240.160.120 get.gotomeeting.com gws 747 0 0\n52.222.162.93 *.quiksite.com gws 751 0 0\n52.84.132.15 publishers.anzu.io gws 753 0 0\n52.222.200.57 *.wpforte.com gws 753 0 0\n52.46.48.94 *.cloudfront.net gws 756 0 0\n52.85.69.129 *.toolbox.com gws 757 0 0\n54.239.212.227 ronsuttonracetechnology.com gws 769 0 0\n52.222.194.163 staging.insights.remy.co gws 774 0 0\n52.85.245.73 www.japaneseapp.com gws 776 0 0\n52.222.176.126 smugmug.com gws 778 0 0\n54.192.235.40 *.terrenelabs.com gws 785 0 0\n54.240.170.230 smugmug.com gws 785 0 0\n54.182.2.62 *.pricewaiter.com gws 786 0 0\n13.33.13.233 smugmug.com gws 793 0 0\n216.137.36.138 training.saucelabs.com gws 800 0 0\n13.33.229.153 *.highwaterlabs.com gws 801 0 0\n54.240.129.40 smugmug.com gws 802 0 0\n54.240.186.235 *.cloudfront.net gws 810 0 0\n52.222.186.59 *.cloudfront.net gws 818 0 0\n54.230.133.199 cdn.pocketfives.com gws 830 0 0\n13.32.124.143 *.cloudfront.net gws 833 0 0\n216.137.39.219 *.cliffordchance.com gws 841 0 0\n52.222.152.54 smugmug.com gws 841 0 0\n52.85.223.42 *.chat-chat.io gws 850 0 0\n13.33.78.132 smugmug.com gws 855 0 0\n52.84.210.234 *.cloudfront.net gws 855 0 0\n54.230.136.204 *.123hjemmeside.dk gws 859 0 0\n54.239.210.198 academy.ethosgroup.com gws 862 0 0\n54.192.88.67 *.massgenie.com gws 865 0 0\n52.222.238.179 *.chippewaranchcamp.com gws 873 0 0\n52.84.166.224 *.gardensbythebay.com.sg gws 877 0 0\n13.33.177.156 stage.first4figures.com gws 886 0 0\n52.222.180.87 cabet04.com gws 889 0 0\n52.222.234.200 ventadirecta.offcorss.com gws 895 0 0\n52.85.125.84 *.cloudfront.net gws 898 0 0\n52.222.139.132 *.tszon.com gws 900 0 0\n52.84.110.204 *.simplesite.com gws 901 0 0\n216.137.39.239 smugmug.com gws 903 0 0\n52.85.154.102 images.hapisga.co.il gws 909 0 0\n52.222.203.79 *.launch27.com gws 922 0 0\n52.222.223.26 smugmug.com gws 923 0 0\n54.239.216.220 wilmington.will.k12.il.us gws 958 0 0\n54.230.232.97 devnet.jetbrains.com gws 960 0 0\n54.192.156.130 *.cloudfront.net gws 998 0 0\n54.239.223.124 *.cloudfront.net gws 1025 0 0\n54.239.221.183 *.cloudfront.net gws 1039 0 0\n"
  },
  {
    "path": "code/default/x_tunnel/local/cloudfront_front/host_manager.py",
    "content": "\nfrom front_base.random_get_slice import RandomGetSlice\n\n\nclass HostManager(RandomGetSlice):\n    def __init__(self, fn, max_size):\n        super(HostManager, self).__init__(fn, max_size)\n\n    def get_sni_host(self, ip):\n        sni = self.get()\n        top_domain = \"\"\n        return sni, top_domain\n"
  },
  {
    "path": "code/default/x_tunnel/local/cloudfront_front/ip_range.txt",
    "content": "13.32.0.0/15\n13.35.0.0/16\n52.46.0.0/18\n52.84.0.0/15\n52.222.128.0/17\n54.182.0.0/16\n54.192.0.0/16\n54.230.0.0/16\n54.239.128.0/18\n54.239.192.0/19\n54.240.128.0/18\n70.132.0.0/18\n143.204.0.0/16\n216.137.32.0/19\n13.59.250.0/26\n18.216.170.128/25\n34.195.252.0/24\n34.216.51.0/25\n34.226.14.0/24\n34.232.163.208/29\n35.158.136.0/24\n35.162.63.192/26\n35.167.191.128/26\n52.15.127.128/26\n52.47.139.0/24\n52.52.191.128/26\n52.56.127.0/25\n52.57.254.0/24\n52.222.238.0/24\n"
  },
  {
    "path": "code/default/x_tunnel/local/cloudfront_front/sni_list.txt",
    "content": "config.uca.cloud.unity3d.com\nimages-na.ssl-images-amazon.com\ndptr.areyouahuman.com\ncdn-gl.imrworldwide.com\ninjections.readcube.com\nedge.api.brightcove.com\nchoices.truste.com\n\no.ss2.us\nwww.binance.com\ndnn506yrbagrg.cloudfront.net\nrules.quantcount.com\nping.smyte.com\ngwiq.globalwebindex.net\nd18ky98rnyall9.cloudfront.net\nwidget.intercom.io\nd2ujflorbtfzji.cloudfront.net\nxslt.alexa.com\nacc.adobeoobe.com\ndjtflbt20bdde.cloudfront.net\nfirefox.settings.services.mozilla.com\nscreenshots.en.sftcdn.net\ndownload-installer.cdn.mozilla.net\nfirefoxusercontent.com\np.cpx.to\nactivity-stream-icons.services.mozilla.com\nresource.binance.com\nia.media-imdb.com\narticles-images.sftcdn.net\nshim.btrll.com\nmir-s3-cdn-cf.behance.net\ni1.rgstatic.net\nstatic.geetest.com\ncdn.insigit.com\ncdn.distiltag.com\nd2wy8f7a9ursnm.cloudfront.net\nwww.amazon.fr\ncertify.alexametrics.com\nscript.crazyegg.com\nhello.myfonts.net\nres.infoq.com\nchoices.trustarc.com\napi-gateway.readcube.com\nstatic.chartbeat.com\ncdn.heapanalytics.com\ninteractive-examples.mdn.mozilla.net\njs.intercomcdn.com\nmdn.mozillademos.org\napi.company-target.com\nmozorg.cdn.mozilla.net\nd39af2mgp1pqhg.cloudfront.net\ndeazs14tb5j7o.cloudfront.net\np.media-imdb.com\nads.admaru.com\nz-na.amazon-adsystem.com\nd6tizftlrpuof.cloudfront.net\nd1lxhc4jvstzrp.cloudfront.net\na5.behance.net\nib.3lift.com\nsjs.bizographics.com\ncrossmark-cdn.crossref.org\nintljs.rmtag.com\nconsent-st.truste.com\nd1f1eryiqyjs0r.cloudfront.net\ncdn-ffc.oobesaas.adobe.com\ncontent-signature.cdn.mozilla.net\nwww.amazon.co.jp\nd301sr5gafysq2.cloudfront.net\nstatic.arxiv.org\noup.silverchair-cdn.com\ngwiqcdn.globalwebindex.net\ntv-static.net\nstatic.parsely.com\ncdn-city.livere.com\ntrust-static.teamviewer.com\ntag.bounceexchange.com\ncdn.ghostery.com\nimages.gr-assets.com\nm.media-amazon.com\ntap-secure.rubiconproject.com\nd3njjcbhbojbot.cloudfront.net\nd33wubrfki0l68.cloudfront.net\ncontent.readcube.com\nb-code.liadm.com\nstubdownloader.cdn.mozilla.net\ndpstvy7p9whsy.cloudfront.net\nd2x3bkdslnxkuj.cloudfront.net\ndsms0mj1bbhn4.cloudfront.net\ndownload.cdn.mozilla.net\ntheme.zdassets.com\nm.sftcdn.net\nd3qdfnco3bamip.cloudfront.net\naddons-discovery.cdn.mozilla.net\nd1bxh8uas1mnw7.cloudfront.net\naddons.cdn.mozilla.net\naddons-amo.cdn.mozilla.net\nresources.jetbrains.com\ncdn.segment.com\njs-cdn.dynatrace.com\nsegments.company-target.com\npdfs.semanticscholar.org\nd3isfnyiuldmfu.cloudfront.net\nassets.bounceexchange.com\ngwiq-v2.globalwebindex.net\ncdn.mdn.mozilla.net\nsdfestaticassets-us-west-2.sciencedirectassets.com\nsnippets.cdn.mozilla.net\nd1z2jf7jlzjs58.cloudfront.net\nd3cv4a9a9wh0bt.cloudfront.net\nd3cbihxaqsuq0s.cloudfront.net\nocsp.sca1b.amazontrust.com\ndownload.docker.com\nd24n15hnbwhuhn.cloudfront.net\njs.adsrvr.org\npx.surveywall-api.survata.com\ncdn.siftscience.com\nwww.stack-sonar.com\ntracking-protection.cdn.mozilla.net\nsolutions-assets.sftcdn.net\nsdfestaticassets-us-east-1.sciencedirectassets.com\nd3tglifpd8whs6.cloudfront.net\nstatic.adobelogin.com\ncdn.elsevier.io\nnative.sharethrough.com\nstatic.twitchcdn.net\nc5.rgstatic.net\ndc8xl0ndzn2cb.cloudfront.net\nwww.coursera.org\nsidecar.gitter.im\nprod.adobeccstatic.com\ndl.pstmn.io\ncontent.jwplatform.com\nn-cdn.areyouahuman.com\nstatic.intercomassets.com\npx.airpr.com\naccounts-static.cdn.mozilla.net\napi.demandbase.com\ng-ecx.images-amazon.com\ncvp.twitch.tv\nd31qbv1cthcecs.cloudfront.net\nboudja.com\ncdn2.ghostery.com\nd1uo4w7k31k5mn.cloudfront.net\ncdn.captora.com\nanalytics.getpostman.com\nd2j3q9yua85jt3.cloudfront.net\nd2265nx4vomwra.cloudfront.net\nscripts.demandbase.com\ngallery.mailchimp.com\nc.amazon-adsystem.com\nnormandy-cloudfront.cdn.mozilla.net\ncdn.livefyre.com\n"
  },
  {
    "path": "code/default/x_tunnel/local/cloudfront_front/test.py",
    "content": "#!/usr/bin/env python2\n# coding:utf-8\n\nimport os\nimport sys\nimport time\nimport threading\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nroot_path = os.path.abspath( os.path.join(current_path, os.pardir, os.pardir, os.pardir))\npython_path = root_path\n\nsys.path.append(root_path)\n\nnoarch_lib = os.path.abspath( os.path.join(python_path, 'lib', 'noarch'))\nsys.path.append(noarch_lib)\n\nif sys.platform == \"win32\":\n    win32_lib = os.path.abspath( os.path.join(python_path, 'lib', 'win32'))\n    sys.path.append(win32_lib)\nelif sys.platform.startswith(\"linux\"):\n    linux_lib = os.path.abspath( os.path.join(python_path, 'lib', 'linux'))\n    sys.path.append(linux_lib)\nelif sys.platform == \"darwin\":\n    darwin_lib = os.path.abspath( os.path.join(python_path, 'lib', 'darwin'))\n    sys.path.append(darwin_lib)\n    extra_lib = \"/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python\"\n    sys.path.append(extra_lib)\n\n\nimport env_info\nfrom .front import front\nfrom xlog import getLogger\nxlog = getLogger(\"cloudfront_front\")\nxlog.set_buffer(2000)\n\ndata_path = env_info.data_path\nmodule_data_path = os.path.join(data_path, 'x_tunnel')\n\n\ndef get():\n    start_time = time.time()\n\n    content, status, response = front.request(\"GET\", \"scan1.xx-net.org\", \"/\", timeout=10)\n    #content, status, response = front.request(\"GET\", \"dns.xx-net.org\", path=\"/query?domain=www.google.com\")\n\n    if isinstance(content, memoryview):\n        content = content.tobytes()\n\n    time_cost = time.time() - start_time\n    xlog.info(\"GET cost:%f\", time_cost)\n    xlog.info(\"status:%d content:%s\", status, content)\n    front.stop()\n\n\nif __name__ == '__main__':\n    import traceback\n\n    try:\n        get()\n    except Exception:\n        traceback.print_exc(file=sys.stdout)\n    except KeyboardInterrupt:\n        front.stop()\n        sys.exit()\n"
  },
  {
    "path": "code/default/x_tunnel/local/cloudfront_front/web_control.py",
    "content": "#!/usr/bin/env python\n# coding:utf-8\n\n\nimport os\nimport time\n\ntry:\n    from urllib.parse import urlparse, parse_qs\nexcept ImportError:\n    from urlparse import urlparse, parse_qs\n\nimport simple_http_server\nfrom .front import front\n\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nroot_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))\ntop_path = os.path.abspath(os.path.join(root_path, os.pardir, os.pardir, os.pardir))\nweb_ui_path = os.path.join(current_path, os.path.pardir, \"web_ui\")\n\n\nclass ControlHandler(simple_http_server.HttpServerHandler):\n    def __init__(self, client_address, headers, command, path, rfile, wfile):\n        self.client_address = client_address\n        self.headers = headers\n        self.command = command\n        self.path = path\n        self.rfile = rfile\n        self.wfile = wfile\n\n    def do_GET(self):\n        path = urlparse(self.path).path\n        if path == \"/log\":\n            return self.req_log_handler()\n        elif path == \"/ip_list\":\n            return self.req_ip_list_handler()\n        elif path == \"/debug\":\n            return self.req_debug_handler()\n        else:\n            front.logger.warn('Control Req %s %s %s ', self.address_string(), self.command, self.path)\n\n        self.wfile.write(b'HTTP/1.1 404\\r\\nContent-Type: text/plain\\r\\nConnection: close\\r\\n\\r\\n404 Not Found')\n        front.logger.info('%s \"%s %s HTTP/1.1\" 404 -', self.address_string(), self.command, self.path)\n\n    def req_log_handler(self):\n        req = urlparse(self.path).query\n        reqs = parse_qs(req, keep_blank_values=True)\n        data = ''\n\n        cmd = \"get_last\"\n        if reqs[\"cmd\"]:\n            cmd = reqs[\"cmd\"][0]\n\n        if cmd == \"get_last\":\n            max_line = int(reqs[\"max_line\"][0])\n            data = front.logger.get_last_lines(max_line)\n        elif cmd == \"get_new\":\n            last_no = int(reqs[\"last_no\"][0])\n            data = front.logger.get_new_lines(last_no)\n        else:\n            front.logger.error('PAC %s %s %s ', self.address_string(), self.command, self.path)\n\n        mimetype = 'text/plain'\n        self.send_response_nc(mimetype, data)\n\n    def req_ip_list_handler(self):\n        time_now = time.time()\n        data = \"<html><body><div  style='float: left; white-space:nowrap;font-family: monospace;'>\"\n        data += \"time:%d  pointer:%d<br>\\r\\n\" % (time_now, front.ip_manager.ip_pointer)\n        data += \"<table><tr><th>N</th><th>IP</th><th>HS</th><th>Fails</th>\"\n        data += \"<th>down_fail</th><th>links</th>\"\n        data += \"<th>get_time</th><th>success_time</th><th>fail_time</th><th>down_fail_time</th>\"\n        data += \"<th>data_active</th><th>transfered_data</th><th>Trans</th>\"\n        data += \"<th>history</th></tr>\\n\"\n        i = 1\n        for ip in front.ip_manager.ip_list:\n            handshake_time = front.ip_manager.ip_dict[ip][\"handshake_time\"]\n\n            fail_times = front.ip_manager.ip_dict[ip][\"fail_times\"]\n            down_fail = front.ip_manager.ip_dict[ip][\"down_fail\"]\n            links = front.ip_manager.ip_dict[ip][\"links\"]\n\n            get_time = front.ip_manager.ip_dict[ip][\"get_time\"]\n            if get_time:\n                get_time = time_now - get_time\n\n            success_time = front.ip_manager.ip_dict[ip][\"success_time\"]\n            if success_time:\n                success_time = time_now - success_time\n\n            fail_time = front.ip_manager.ip_dict[ip][\"fail_time\"]\n            if fail_time:\n                fail_time = time_now - fail_time\n\n            down_fail_time = front.ip_manager.ip_dict[ip][\"down_fail_time\"]\n            if down_fail_time:\n                down_fail_time = time_now - down_fail_time\n\n            data_active = front.ip_manager.ip_dict[ip][\"data_active\"]\n            if data_active:\n                active_time = time_now - data_active\n            else:\n                active_time = 0\n\n            history = front.ip_manager.ip_dict[ip][\"history\"]\n            t0 = 0\n            str_out = ''\n            for item in history:\n                t = item[0]\n                v = item[1]\n                if t0 == 0:\n                    t0 = t\n                time_per = int((t - t0) * 1000)\n                t0 = t\n                str_out += \"%d(%s) \" % (time_per, v)\n            data += \"<tr><td>%d</td><td>%s</td><td>%d</td><td>%d</td><td>%d</td><td>%d</td><td>%d</td><td>%d</td><td>%d</td>\" \\\n                    \"<td>%d</td><td>%d</td><td>%s</td></tr>\\n\" % \\\n                    (i, ip, handshake_time, fail_times, down_fail, links, get_time, success_time, fail_time, down_fail_time, \\\n                    active_time, str_out)\n            i += 1\n\n        data += \"</table></div></body></html>\"\n        mimetype = 'text/html'\n        self.send_response_nc(mimetype, data)\n\n    def req_debug_handler(self):\n        data = \"\"\n        objs = [front.connect_manager] + list(front.dispatchs.values())\n        for obj in objs:\n\n            data += \"%s\\r\\n\" % obj.__class__\n            for attr in dir(obj):\n                if attr.startswith(\"__\"):\n                    continue\n                sub_obj = getattr(obj, attr)\n                if callable(sub_obj):\n                    continue\n                data += \"    %s = %s\\r\\n\" % (attr, sub_obj)\n            if hasattr(obj, \"to_string\"):\n                data += obj.to_string()\n\n        mimetype = 'text/plain'\n        self.send_response_nc(mimetype, data)"
  },
  {
    "path": "code/default/x_tunnel/local/config.py",
    "content": "import sys\nimport os\n\nimport env_info\ndata_path = env_info.data_path\ndata_xtunnel_path = os.path.join(data_path, 'x_tunnel')\n\nimport xconfig\nfrom xlog import getLogger\nxlog = getLogger(\"x_tunnel\")\n\n\ndef load_config():\n    if len(sys.argv) > 2 and sys.argv[1] == \"-f\":\n        config_path = sys.argv[2]\n    else:\n        config_path = os.path.join(data_xtunnel_path, 'client.json')\n\n    xlog.info(\"use config_path:%s\", config_path)\n\n    config = xconfig.Config(config_path)\n\n    config.set_var(\"log_level\", \"DEBUG\")\n    config.set_var(\"upload_logs\", True)\n    config.set_var(\"write_log_file\", 0)\n    config.set_var(\"save_start_log\", 1500)\n    config.set_var(\"show_debug\", 0)\n    config.set_var(\"delay_collect_log\", 3 * 60)\n    config.set_var(\"delay_collect_log2\", 30)\n\n    config.set_var(\"encrypt_data\", 0)\n    config.set_var(\"encrypt_password\", \"encrypt_pass\")\n    config.set_var(\"encrypt_method\", \"aes-256-cfb\")\n\n    config.set_var(\"api_server\", \"center.xx-net.org\")\n    config.set_var(\"scan_servers\", [\"scan1\"])\n    config.set_var(\"server_host\", \"\")\n    config.set_var(\"server_port\", 443)\n    config.set_var(\"use_https\", 1)\n    config.set_var(\"port_range\", 1)\n\n    config.set_var(\"login_account\", \"\")\n    config.set_var(\"login_password\", \"\")\n\n    config.set_var(\"conn_life\", 30)\n\n    config.set_var(\"socks_host\", \"127.0.0.1\")\n    config.set_var(\"socks_port\", 1080)\n    config.set_var(\"update_cloudflare_domains\", True)\n\n    # performance parameters\n    # range 2 - 100\n    config.set_var(\"concurent_thread_num\", 20)\n\n    # min roundtrip on road if connectoin exist\n    config.set_var(\"min_on_road\", 3)\n\n    config.set_var(\"server_time_max_deviation\", 0.6)\n\n    config.set_var(\"send_timeout_retry\", 4)\n\n    config.set_var(\"server_download_timeout_retry\", 4)\n\n    # range 1 - 1000, ms\n    config.set_var(\"send_delay\", 10)\n\n    # range 1 - 20000, ms\n    config.set_var(\"resend_timeout\", 5000)\n\n    # range 1 - resend_timeout, ms\n    config.set_var(\"ack_delay\", 300)\n\n    # max 10M\n    config.set_var(\"max_payload\", 256 * 1024)\n\n    # range 1 - 30\n    config.set_var(\"roundtrip_timeout\", 25)\n\n    config.set_var(\"network_timeout\", 5)\n\n    config.set_var(\"windows_size\", 10 * 1024 * 1024)  # will recalulate based on: max_payload * concurent_thread_num *2\n\n    # reporter\n    config.set_var(\"timeout_threshold\", 2)\n    config.set_var(\"report_interval\", 5 * 60)\n\n    config.set_var(\"enable_gae_proxy\", 0)\n    config.set_var(\"enable_cloudflare\", 1)\n    config.set_var(\"enable_cloudfront\", 0)\n    config.set_var(\"enable_seley\", 1)\n    config.set_var(\"enable_tls_relay\", 1)\n    config.set_var(\"enable_direct\", 0)\n    config.set_var(\"local_auto_front\", 1)\n\n    config.load()\n\n    config.windows_ack = 0.05 * config.windows_size\n    config.windows_size = config.max_payload * config.concurent_thread_num * 2\n    xlog.info(\"X-Tunnel window:%d\", config.windows_size)\n\n    if config.local_auto_front:\n        if \"localhost\" in config.server_host or \"127.0.0.1\" in config.server_host:\n            config.enable_cloudflare = 0\n            config.enable_tls_relay = 0\n            config.enable_seley = 0\n            config.enable_direct = 1\n            xlog.info(\"Only enable Direct front for localhost\")\n\n    if config.write_log_file:\n        xlog.log_to_file(os.path.join(data_path, \"client.log\"))\n\n    xlog.setLevel(config.log_level)\n    xlog.set_buffer(200)\n    xlog.save_start_log = config.save_start_log\n    return config\n"
  },
  {
    "path": "code/default/x_tunnel/local/direct_front.py",
    "content": "\n# This front is for debug\n\nimport time\nimport simple_http_client\n\nfrom xlog import getLogger\nxlog = getLogger(\"x_tunnel\")\n\nname = \"direct_front\"\nlast_success_time = 0\nlast_fail_time = 0\ncontinue_fail_num = 0\nsuccess_num = 0\nfail_num = 0\n\n\ndef init():\n    global last_success_time, last_fail_time, continue_fail_num\n\n\nclass FakeWorker(object):\n    def __init__(self):\n        self.ip_str = \"127.0.0.1\"\n\n    def update_debug_data(self, rtt, send_data_len, dlen, speed):\n        pass\n\n    def get_trace(self):\n        return \"\"\n\n\nclass FakeDispatcher(object):\n    def __init__(self):\n\n        self.success_num = 0\n        self.fail_num = 0\n        self.continue_fail_num = 0\n        self.last_fail_time = 0\n        self.rtts = []\n        self.last_sent = self.total_sent = 0\n        self.last_received = self.total_received = 0\n        self.second_stat = {\n            \"rtt\": 0,\n            \"sent\": 0,\n            \"received\": 0\n        }\n        self.minute_stat = {\n            \"rtt\": 0,\n            \"sent\": 0,\n            \"received\": 0\n        }\n\n    def get_score(self, host=\"\"):\n        return 10000000\n\n    def worker_num(self):\n        return 1\n\n    def statistic(self):\n        pass\n\n\nfake_dispatcher = FakeDispatcher()\n\n\ndef get_dispatcher(host=None):\n    return fake_dispatcher\n\n\ndef request(method, host, schema=\"http\", path=\"/\", headers={}, data=\"\", timeout=60):\n    global last_success_time, last_fail_time, continue_fail_num, success_num, fail_num\n\n    timeout = 30\n    # use http to avoid cert fail\n    url = \"http://\" + host + path\n    if data:\n        headers[\"Content-Length\"] = str(len(data))\n\n    # xlog.debug(\"gae_proxy %s %s\", method, url)\n    try:\n        response = simple_http_client.request(method, url, headers, data, timeout=timeout)\n        if response.status != 200:\n            raise Exception(\"Direct request fail\")\n    except Exception as e:\n        fail_num += 1\n        continue_fail_num += 1\n        last_fail_time = time.time()\n        time.sleep(1)\n        return \"\", 602, {}\n\n    last_success_time = time.time()\n    continue_fail_num = 0\n    success_num += 1\n    response.worker = FakeWorker()\n    response.task = response.worker\n    return response.text, response.status, response\n\n\ndef start():\n    pass\n\n\ndef stop():\n    pass\n\n\ndef set_proxy(args):\n    pass\n\n\ninit()\n"
  },
  {
    "path": "code/default/x_tunnel/local/front_dispatcher.py",
    "content": "import time\nimport threading\nimport os\nimport random\nfrom threading import Lock\n\nall_fronts = []\nlight_fronts = []\nsession_fronts = []\ncloudflare_front = None\n\nfrom . import global_var as g\nimport utils\nfrom xlog import getLogger\nimport env_info\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nroot_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))\ndata_path = env_info.data_path\ndata_xtunnel_path = os.path.join(data_path, 'x_tunnel')\n\nxlog = getLogger(\"x_tunnel\", log_path=data_xtunnel_path, save_start_log=500, save_warning_log=True)\n\n\ndef init():\n    global cloudflare_front\n\n    if g.config.enable_gae_proxy:\n        from . import gae_front\n        if gae_front.get_dispatcher():\n            all_fronts.append(gae_front)\n            session_fronts.append(gae_front)\n            light_fronts.append(gae_front)\n\n    if g.config.enable_cloudflare:\n        from .cloudflare_front.front import front as _cloudflare_front\n        cloudflare_front = _cloudflare_front\n        all_fronts.append(cloudflare_front)\n        session_fronts.append(cloudflare_front)\n        light_fronts.append(cloudflare_front)\n        g.cloudflare_front = cloudflare_front\n\n    if g.config.enable_cloudfront:\n        from .cloudfront_front.front import front as cloudfront_front\n        all_fronts.append(cloudfront_front)\n        session_fronts.append(cloudfront_front)\n        light_fronts.append(cloudfront_front)\n        g.cloudfront_front = cloudfront_front\n\n    if g.config.enable_seley:\n        from .seley_front.front import front as seley_front\n        all_fronts.append(seley_front)\n        session_fronts.append(seley_front)\n        light_fronts.append(seley_front)\n        g.seley_front = seley_front\n\n    if g.config.enable_tls_relay:\n        from .tls_relay_front.front import front as tls_relay_front\n        all_fronts.append(tls_relay_front)\n        session_fronts.append(tls_relay_front)\n        light_fronts.append(tls_relay_front)\n        g.tls_relay_front = tls_relay_front\n\n    if g.config.enable_direct:\n        from . import direct_front\n        all_fronts.append(direct_front)\n        session_fronts.append(direct_front)\n        light_fronts.append(direct_front)\n\n    for front in all_fronts:\n        front.start()\n\n    threading.Thread(target=front_staticstic_thread, name=\"front_statistic_thread\").start()\n\n\ndef save_cloudflare_domain(domains):\n    if not g.config.enable_cloudflare:\n        xlog.warn(\"save_cloudflare_domain but cloudflare front not enabled\")\n        return\n\n    for front in all_fronts:\n        if front.name != \"cloudflare_front\":\n            continue\n\n        front.ip_manager.save_domains(domains)\n\n\ndef front_staticstic_thread():\n    while g.running:\n        for front in all_fronts:\n            dispatcher = front.get_dispatcher()\n            if not dispatcher:\n                continue\n\n            dispatcher.statistic()\n\n        time.sleep(3)\n\nget_front_lock = Lock()\n\ndef get_front(host, timeout):\n    start_time = time.time()\n    if host in [\"dns.xx-net.org\", g.config.api_server]:\n        fronts = light_fronts\n    else:\n        fronts = session_fronts\n\n    with get_front_lock:\n        while time.time() - start_time < timeout:\n            best_front = None\n            best_score = 999999999\n            for front in fronts:\n                if host == \"dns.xx-net.org\" and front == cloudflare_front and g.server_host:\n                    # share the x-tunnel connection with dns.xx-net.org\n                    # x-tunnel server will forward the request to dns.xx-net.org\n                    host = g.server_host\n\n                dispatcher = front.get_dispatcher(host)\n                if not dispatcher:\n                    # xlog.warn(\"get dispatcher from %s fail for %s\", front.name, host)\n                    continue\n\n                score = dispatcher.get_score()\n                if not score:\n                    if front.config.show_state_debug:\n                        xlog.warn(\"get_front get_score failed for %s \", front.name)\n                    continue\n\n                if score < best_score:\n                    best_score = score\n                    best_front = front\n\n            if best_front is not None:\n                return best_front\n\n            time.sleep(0.005)\n\n    g.stat[\"timeout_roundtrip\"] += 5\n    return None\n\n\ndef count_connection(host):\n    fronts = session_fronts\n\n    num = 0\n    for front in fronts:\n        dispatcher = front.get_dispatcher(host)\n        if not dispatcher:\n            continue\n\n        num += len(dispatcher.workers)\n\n        num += dispatcher.connection_manager.new_conn_pool.qsize()\n\n    return num\n\n\ndef request(method, host, path=\"/\", headers={}, data=\"\", timeout=100):\n    # xlog.debug(\"front request %s timeout:%d\", path, timeout)\n    start_time = time.time()\n\n    content, status, response = \"\", 603, {}\n    while time.time() - start_time < timeout:\n        start_get_front = time.time()\n        front = get_front(host, timeout)\n        if not front:\n            xlog.warn(\"get_front fail\")\n            return \"\", 602, {}\n\n        finished_get_front = time.time()\n        get_front_time = finished_get_front - start_get_front\n        if get_front_time > 0.1:\n            xlog.warn(\"get_front_time: %f for %s %s %s\", get_front_time, method, host, path)\n\n        if host == \"dns.xx-net.org\" and front == cloudflare_front and g.server_host:\n            # share the x-tunnel connection with dns.xx-net.org\n            # x-tunnel server will forward the request to dns.xx-net.org\n            if g.server_host:\n                host = g.server_host\n\n        headers[\"X-Async\"] = \"1\"\n        if len(data) < 84:\n            padding = utils.to_str(utils.generate_random_lowercase(random.randint(8, 64)))\n            headers[\"Padding\"] = padding\n\n        content, status, response = front.request(\n            method, host=host, path=path, headers=dict(headers), data=data, timeout=timeout)\n\n        if status not in [200, 521, 400, 404]:\n            xlog.warn(\"front retry %s%s\", host, path)\n            time.sleep(1)\n            continue\n\n        header_len = int(response.headers.get(b\"Content-Length\", 0))\n        if header_len and len(content) != header_len:\n            xlog.warn(\"response length incorrect, head len:%s, content len:%d retry it\", header_len, len(content))\n            time.sleep(1)\n            continue\n\n        return content, status, response\n\n    return content, status, response\n\n\ndef set_session_host(host):\n    global session_fronts\n    for front in session_fronts:\n        dispatcher = front.get_dispatcher(host)\n        if not dispatcher:\n            continue\n\n        dispatcher.set_session_host(host)\n\n\ndef stop():\n    global all_fronts, light_fronts, session_fronts, cloudflare_front\n\n    for front in all_fronts:\n        front.stop()\n\n    all_fronts = []\n    light_fronts = []\n    session_fronts = []\n    cloudflare_front = None"
  },
  {
    "path": "code/default/x_tunnel/local/gae_front.py",
    "content": "import os\nimport sys\n\nfrom xlog import getLogger\nxlog = getLogger(\"x_tunnel\")\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nlauncher_path = os.path.abspath( os.path.join(current_path, os.pardir, os.pardir, \"launcher\"))\nif launcher_path not in sys.path:\n    sys.path.append(launcher_path)\n\nimport utils\n\ntry:\n    from module_init import proc_handler\nexcept:\n    xlog.info(\"launcher not running\")\n    proc_handler = None\n\nname = \"gae_front\"\ngae_proxy = None\n\n\ndef init():\n    global gae_proxy\n    if not proc_handler:\n        return False\n\n    if \"gae_proxy\" not in proc_handler:\n        xlog.debug(\"gae_proxy not running\")\n        return False\n\n    gae_proxy = proc_handler[\"gae_proxy\"][\"imp\"].local\n\n\ndef get_dispatcher(host=None):\n    if not gae_proxy:\n        return None\n\n    return gae_proxy.front.front.http_dispatcher\n\n\ndef request(method, host, schema=\"https\", path=\"/\", headers={}, data=\"\", timeout=60):\n    if not gae_proxy:\n        return \"\", 602, {}\n\n    method = utils.to_bytes(method)\n    host = utils.to_bytes(host)\n    schema = utils.to_bytes(schema)\n    path = utils.to_bytes(path)\n    headers = utils.to_bytes(headers)\n    data = utils.to_bytes(data)\n\n    # use http to avoid cert fail\n    url = b\"%s://%s%s\" % (schema, host, path)\n    if data:\n        headers[b\"Content-Length\"] = utils.to_bytes(str(len(data)))\n\n    # xlog.debug(\"gae_proxy %s %s\", method, url)\n    try:\n        response = gae_proxy.gae_handler.request_gae_proxy(method, url, headers, data, timeout=timeout)\n        if response.app_status != 200:\n            raise Exception(\"GAE request fail\")\n    except Exception as e:\n        return \"\", 602, {}\n\n    return response.task.read_all(), response.app_status, response\n\n\ndef stop():\n    pass\n\n\ndef set_proxy(args):\n    pass\n\n\ninit()"
  },
  {
    "path": "code/default/x_tunnel/local/global_var.py",
    "content": "xxnet_version = \"\"\nclient_uuid = \"\"\nsystem = \"\"\n\nrunning = True\nprotocol_version = 4\nbind_port = 0\nlast_refresh_time = 0\nlogin_process = False\ndata_path = None\n\nconfig = None\nhttp_client = None\ncloudflare_front = None\ncloudfront_front = None\ntls_relay_front = None\nseley_front = None\n\nsession = None\nsocks5_server = None\nlast_api_error = \"\"\n\npromote_code = \"\"\npromoter = \"\"\nquota_list = {}\nquota = 0\npaypal_button_id = \"\"\nplans = {}\n\nserver_host = \"\"\nserver_port = 0\nselectable = []\nbalance = 0\nopenai_balance = 0\nopenai_proxies = []\ntls_relays = {}\n\nstat = {\n    \"roundtrip_num\": 0,\n    \"slow_roundtrip\": 0,\n    \"timeout_roundtrip\": 0,\n    \"resend\": 0\n}"
  },
  {
    "path": "code/default/x_tunnel/local/openai_handler.py",
    "content": "import random\nimport json\nimport base64\nimport time\nimport zlib\n\nimport utils\n\nfrom . import global_var as g\nfrom . import front_dispatcher\nfrom . import proxy_session\n\nfrom xlog import getLogger\nxlog = getLogger(\"x_tunnel\")\n\nopenai_chat_token_price = 0.000002\nhost = None\n\ngzip_decompressor = zlib.decompressobj(16 + zlib.MAX_WBITS)\n\n\ndef get_auth_str():\n    info = {\n        \"login_account\": g.config.login_account,\n        \"login_password\": g.config.login_password\n    }\n    json_str = utils.to_bytes(json.dumps(info))\n    token = base64.b64encode(json_str)\n    return \"Bearer \" + utils.to_str(token)\n\n\nauth_str = None\n\n\ndef get_openai_proxy(get_next_one=False):\n    global host\n    if get_next_one or not host:\n\n        if not (g.config.login_account and g.config.login_password):\n            return False\n\n        for _ in range(0, 3):\n            res, reason = proxy_session.request_balance(g.config.login_account, g.config.login_password)\n            if not res:\n                xlog.warn(\"x-tunnel request_balance fail when create_conn:%s\", reason)\n                time.sleep(1)\n\n        if not g.openai_proxies:\n            return None\n\n        host = random.choice(g.openai_proxies)\n    return host\n\n\ndef handle_openai(method, path, headers, req_body, sock):\n    global auth_str\n    if not auth_str:\n        auth_str = get_auth_str()\n\n    host = get_openai_proxy()\n    if not host:\n        # return sock.send(b'HTTP/1.1 401 Fail\\r\\n\\r\\n')\n        return 401, {}, \"Service not available at current status.\"\n\n    path = utils.to_str(path[7:])\n    headers = utils.to_str(headers)\n    headers[\"Authorization\"] = auth_str\n    del headers[\"Host\"]\n    try:\n        del headers[\"Accept-Encoding\"]\n    except:\n        pass\n    content, status, response = front_dispatcher.request(method, host, path=path, headers=headers, data=req_body)\n\n    if status == 200:\n        try:\n            if response.headers.get(b\"Content-Encoding\") == b\"gzip\":\n                data = gzip_decompressor.decompress(content)\n            else:\n                data = content\n\n            dat = json.loads(data)\n            consumed_balance = dat[\"usage\"][\"consumed_balance\"]\n            g.openai_balance -= consumed_balance\n        except Exception as e1:\n            xlog.exception(\"cal tokens err:%r\", e1)\n\n    res_headers = {\n        \"Content-Type\": \"application/json\"\n    }\n    for key, value in response.headers.items():\n        if key.startswith(b\"Openai\"):\n            res_headers[key] = value\n\n    return status, res_headers, content\n"
  },
  {
    "path": "code/default/x_tunnel/local/proxy_handler.py",
    "content": "import time\nimport socket\nimport struct\n\ntry:\n    from urllib.parse import urlparse\nexcept ImportError:\n    from urlparse import urlparse\n\nimport utils\nfrom xlog import getLogger\nxlog = getLogger(\"x_tunnel\")\n\nfrom . import global_var as g\nfrom . import proxy_session\nfrom . import openai_handler\n\n\ndef netloc_to_host_port(netloc, default_port=80):\n    if isinstance(netloc, str):\n        netloc = netloc.encode(\"ascii\")\n\n    if b\":\" in netloc:\n        host, _, port = netloc.rpartition(b':')\n        port = int(port)\n    else:\n        host = netloc\n        port = default_port\n    return host, port\n\n\nclass Socks5Server():\n    handle_num = 0\n\n    def __init__(self, sock, client, args):\n        self.connection = sock\n        self.rfile = self.connection.makefile(\"rb\", -1)\n        self.wfile = self.connection.makefile(\"wb\", 0)\n        self.client_address = client\n        self.read_buffer = b\"\"\n        self.buffer_start = 0\n        self.args = args\n\n    def handle(self):\n        self.__class__.handle_num += 1\n        try:\n            socks_version = self.read_bytes(1)\n            if not socks_version:\n                return\n\n            if socks_version == b\"\\x04\":\n                self.socks4_handler()\n            elif socks_version == b\"\\x05\":\n                self.socks5_handler()\n            elif socks_version == b\"C\":\n                self.https_handler()\n            elif socks_version in [b\"G\", b\"P\", b\"D\", b\"O\", b\"H\", b\"T\"]:\n                self.http_handler(socks_version)\n                return\n            else:\n                xlog.warn(\"socks version:%s not supported\",  utils.str2hex(socks_version))\n                return\n\n        except socket.error as e:\n            xlog.warn('proxy handler read error %r', e)\n            self.connection.close()\n        except Exception as e:\n            xlog.exception(\"proxy handler err:%r\", e)\n            self.connection.close()\n\n    def read_null_end_line(self):\n        sock = self.connection\n        sock.setblocking(0)\n        try:\n            while True:\n                n1 = self.read_buffer.find(b\"\\x00\", self.buffer_start)\n                if n1 > -1:\n                    line = self.read_buffer[self.buffer_start:n1]\n                    self.buffer_start = n1 + 1\n                    return line\n\n                try:\n                    data = sock.recv(8192)\n                except socket.error as e:\n                    # logging.exception(\"e:%r\", e)\n                    if e.errno in [2, 11, 10035]:\n                        time.sleep(0.01)\n                        continue\n                    else:\n                        raise e\n\n                self.read_buffer += data\n        finally:\n            sock.setblocking(1)\n\n    def read_crlf_line(self):\n        sock = self.connection\n        sock.setblocking(0)\n        try:\n            while True:\n                n1 = self.read_buffer.find(b\"\\r\\n\", self.buffer_start)\n                if n1 > -1:\n                    line = self.read_buffer[self.buffer_start:n1]\n                    self.buffer_start = n1 + 2\n                    return line\n\n                try:\n                    data = sock.recv(8192)\n                except socket.error as e:\n                    # logging.exception(\"e:%r\", e)\n                    if e.errno in [2, 11, 10035]:\n                        time.sleep(0.01)\n                        continue\n                    else:\n                        raise e\n\n                self.read_buffer += data\n        finally:\n            sock.setblocking(1)\n\n    def read_headers(self):\n        sock = self.connection\n        sock.setblocking(0)\n        try:\n            while True:\n                if self.read_buffer[self.buffer_start:] == b\"\\r\\n\":\n                    self.buffer_start += 2\n                    return b\"\"\n\n                n1 = self.read_buffer.find(b\"\\r\\n\\r\\n\", self.buffer_start)\n                if n1 > -1:\n                    block = self.read_buffer[self.buffer_start:n1]\n                    self.buffer_start = n1 + 4\n                    return block\n\n                try:\n                    data = sock.recv(8192)\n                except socket.error as e:\n                    # logging.exception(\"e:%r\", e)\n                    if e.errno in [2, 11, 10035]:\n                        time.sleep(0.01)\n                        continue\n                    else:\n                        raise e\n\n                self.read_buffer += data\n        finally:\n            sock.setblocking(1)\n\n    def read_bytes(self, size):\n        sock = self.connection\n        sock.setblocking(1)\n        try:\n            while True:\n                left = len(self.read_buffer) - self.buffer_start\n                if left >= size:\n                    break\n\n                need = size - left\n\n                try:\n                    data = sock.recv(need)\n                except socket.error as e:\n                    # logging.exception(\"e:%r\", e)\n                    if e.errno in [2, 11, 10035]:\n                        time.sleep(0.01)\n                        continue\n                    else:\n                        raise e\n\n                if len(data):\n                    self.read_buffer += data\n                else:\n                    raise socket.error(\"recv fail\")\n        finally:\n            sock.setblocking(1)\n\n        data = self.read_buffer[self.buffer_start:self.buffer_start + size]\n        self.buffer_start += size\n        return data\n\n    def socks4_handler(self):\n        # Socks4 or Socks4a\n        sock = self.connection\n        cmd = ord(self.read_bytes(1))\n        if cmd != 1:\n            xlog.warn(\"Socks4 cmd:%d not supported\", cmd)\n            return\n\n        data = self.read_bytes(6)\n        port = struct.unpack(\">H\", data[0:2])[0]\n        addr_pack = data[2:6]\n        if addr_pack[0:3] == b'\\x00\\x00\\x00' and addr_pack[3] != b'\\x00':\n            domain_mode = True\n        else:\n            ip = socket.inet_ntoa(addr_pack)\n            domain_mode = False\n\n        user_id = self.read_null_end_line()\n        if len(user_id):\n            xlog.debug(\"Socks4 user_id:%s\", user_id)\n\n        if domain_mode:\n            addr = self.read_null_end_line()\n        else:\n            addr = ip\n\n        conn_id = proxy_session.create_conn(sock, addr, port)\n        if not conn_id:\n            xlog.warn(\"Socks4 connect fail, no conn_id\")\n            reply = b\"\\x00\\x5b\\x00\" + addr_pack + struct.pack(\">H\", port)\n            sock.send(reply)\n            return\n\n        xlog.info(\"Socks4:%r to %s:%d, conn:%d\", self.client_address, addr, port, conn_id)\n        reply = b\"\\x00\\x5a\" + addr_pack + struct.pack(\">H\", port)\n        sock.send(reply)\n\n        if len(self.read_buffer) - self.buffer_start:\n            g.session.conn_list[conn_id].transfer_received_data(self.read_buffer[self.buffer_start:])\n\n        g.session.conn_list[conn_id].start(block=True)\n\n    def socks5_handler(self):\n        sock = self.connection\n        auth_mode_num = ord(self.read_bytes(1))\n        data = self.read_bytes(auth_mode_num)\n\n        sock.send(b\"\\x05\\x00\")  # socks version 5, no auth needed.\n        try:\n            data = self.read_bytes(4)\n        except Exception as e:\n            xlog.debug(\"socks5 auth num:%d, list:%s\", auth_mode_num, utils.str2hex(data))\n            xlog.warn(\"socks5 protocol error:%r\", e)\n            return\n\n        socks_version = ord(data[0:1])\n        if socks_version != 5:\n            xlog.warn(\"request version:%d error\", socks_version)\n            return\n\n        command = ord(data[1:2])\n        if command != 1:  # 1. Tcp connect\n            xlog.warn(\"request not supported command mode:%d\", command)\n            sock.send(b\"\\x05\\x07\\x00\\x01\")  # Command not supported\n            return\n\n        addrtype_pack = data[3:4]\n        addrtype = ord(addrtype_pack)\n        if addrtype == 1:  # IPv4\n            addr_pack = self.read_bytes(4)\n            addr = socket.inet_ntoa(addr_pack)\n        elif addrtype == 3:  # Domain name\n            domain_len_pack = self.read_bytes(1)[0:1]\n            domain_len = ord(domain_len_pack)\n            domain = self.read_bytes(domain_len)\n            addr_pack = domain_len_pack + domain\n            addr = domain\n        elif addrtype == 4:  # IPv6\n            addr_pack = self.read_bytes(16)\n            addr = socket.inet_ntop(socket.AF_INET6, addr_pack)\n        else:\n            xlog.warn(\"request address type unknown:%d\", addrtype)\n            sock.send(b\"\\x05\\x07\\x00\\x01\")  # Command not supported\n            return\n\n        port = struct.unpack('>H', self.rfile.read(2))[0]\n\n        conn_id = proxy_session.create_conn(sock, addr, port)\n        if not conn_id:\n            xlog.warn(\"socks5 create conn to %s:%d fail\", addr, port)\n            reply = b\"\\x05\\x01\\x00\" + addrtype_pack + addr_pack + struct.pack(\">H\", port)\n            sock.send(reply)\n            return\n\n        xlog.info(\"socks5 %r connect to %s:%d conn:%d\", self.client_address, addr, port, conn_id)\n        reply = b\"\\x05\\x00\\x00\" + addrtype_pack + addr_pack + struct.pack(\">H\", port)\n        try:\n            sock.send(reply)\n        except Exception as e:\n            if conn_id in g.session.conn_list:\n                g.session.conn_list[conn_id].do_stop(\"close_on_Socks5_reply\")\n            xlog.warn(\"socks5 %r connect to %s:%d conn_id:%d closed:%r\", self.client_address, addr, port, conn_id, e)\n            return\n\n        if len(self.read_buffer) - self.buffer_start:\n            g.session.conn_list[conn_id].transfer_received_data(self.read_buffer[self.buffer_start:])\n\n        g.session.conn_list[conn_id].start(block=True)\n\n    def https_handler(self):\n        line = self.read_crlf_line()\n        line = line.decode('iso-8859-1')\n        words = line.split()\n        if len(words) == 3:\n            command, path, version = words\n        elif len(words) == 2:\n            command, path = words\n            version = b\"HTTP/1.1\"\n        else:\n            xlog.warn(\"https req line fail:%s\", line)\n            return\n\n        if command != \"ONNECT\":\n            xlog.warn(\"https req line fail:%s\", line)\n            return\n\n        host, _, port = path.rpartition(':')\n        host = host.encode()\n        port = int(port)\n\n        header_block = self.read_headers()\n\n        sock = self.connection\n        conn_id = proxy_session.create_conn(sock, host, port)\n        if not conn_id:\n            xlog.warn(\"https create conn to %s:%d fail\", host, port)\n            sock.send(b'HTTP/1.1 500 Fail\\r\\n\\r\\n')\n            return\n\n        xlog.info(\"https %r connect to %s:%d conn:%d\", self.client_address, host, port, conn_id)\n        try:\n            sock.send(b'HTTP/1.1 200 OK\\r\\n\\r\\n')\n        except:\n            xlog.warn(\"https %r connect to %s:%d conn:%d closed.\", self.client_address, host, port, conn_id)\n\n        if (len(self.read_buffer) - self.buffer_start) > 0:\n            g.session.conn_list[conn_id].transfer_received_data(self.read_buffer[self.buffer_start:])\n\n        g.session.conn_list[conn_id].start(block=True)\n\n    def http_handler(self, first_char):\n        req_line = self.read_crlf_line()\n        words = req_line.split()\n        if len(words) == 3:\n            method, url, http_version = words\n        elif len(words) == 2:\n            method, url = words\n            http_version = b\"HTTP/1.1\"\n        else:\n            xlog.warn(\"http req line fail:%s\", req_line)\n            return\n\n        method = first_char + method\n        # if method not in [\"GET\", \"HEAD\", \"POST\", \"PUT\", \"DELETE\", \"OPTIONS\", \"TRACE\", \"PATCH\"]:\n        #    xlog.warn(\"https req method not known:%s\", method)\n\n        if url.startswith(b\"http://\") or url.startswith(b\"HTTP://\"):\n            o = urlparse(url)\n            host, port = netloc_to_host_port(o.netloc)\n\n            p = url[7:].find(b\"/\")\n            if p >= 0:\n                path = url[7+p:]\n            else:\n                path = b\"/\"\n        else:\n            header_block = self.read_headers()\n            lines = header_block.split(b\"\\r\\n\")\n            path = url\n            host = None\n            headers = {}\n            for line in lines:\n                key, _, value = line.partition(b\":\")\n                headers[key] = value\n                if key.lower() == b\"host\":\n                    host, port = netloc_to_host_port(value)\n            if host is None:\n                xlog.warn(\"http proxy host can't parsed. %s %s\", req_line, header_block)\n                self.connection.send(b'HTTP/1.1 500 Fail\\r\\n\\r\\n')\n                return\n\n            if url.startswith(b\"/openai/\"):\n                content_length = int(headers.get(b\"Content-Length\", 0))\n                req_body = self.read_bytes(content_length)\n                return openai_handler.handle_openai(method, url, headers, req_body, self.connection)\n\n        sock = self.connection\n        conn_id = proxy_session.create_conn(sock, host, port)\n        if not conn_id:\n            xlog.warn(\"http create conn to %s:%d fail\", host, port)\n            sock.send(b'HTTP/1.1 500 Fail\\r\\n\\r\\n')\n            return\n\n        xlog.info(\"http %r connect to %s:%d conn:%d\", self.client_address, host, port, conn_id)\n\n        new_req_line = b\"%s %s %s\" % (method, path, http_version)\n        left_buf = new_req_line + self.read_buffer[(len(req_line) + 1):]\n        g.session.conn_list[conn_id].transfer_received_data(left_buf)\n\n        g.session.conn_list[conn_id].start(block=True)\n\n"
  },
  {
    "path": "code/default/x_tunnel/local/proxy_session.py",
    "content": "import os\nimport time\nimport json\nimport threading\nimport xstruct as struct\nimport hashlib\n\nfrom xlog import getLogger, keep_log\nxlog = getLogger(\"x_tunnel\")\n\nimport utils\nfrom . import base_container\nimport encrypt\nfrom . import global_var as g\nfrom gae_proxy.local import check_local_network\nfrom .upload_logs import upload_logs_thread\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nroot_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))\n\n\ndef encrypt_data(data):\n    if g.config.encrypt_data:\n        return encrypt.Encryptor(g.config.encrypt_password, g.config.encrypt_method).encrypt(data)\n    else:\n        return data\n\n\ndef decrypt_data(data):\n    if g.config.encrypt_data:\n        if isinstance(data, memoryview):\n            data = data.tobytes()\n        return encrypt.Encryptor(g.config.encrypt_password, g.config.encrypt_method).decrypt(data)\n    else:\n        return data\n\n\ndef traffic_readable(num, units=('B', 'KB', 'MB', 'GB')):\n    for unit in units:\n        if num >= 1024:\n            num /= 1024.0\n        else:\n            break\n    return '{:.1f} {}'.format(num, unit)\n\n\ndef sleep(t):\n    end_time = time.time() + t\n    while g.running:\n        if time.time() > end_time:\n            return\n\n        sleep_time = min(5, end_time - time.time())\n        if sleep_time > 0.01:\n            time.sleep(sleep_time)\n\n\nclass ProxySession(object):\n    def __init__(self):\n        self.config = g.config\n        self.wait_queue = base_container.WaitQueue()\n        self.send_buffer = base_container.SendBuffer(max_payload=g.config.max_payload)\n        self.receive_process = base_container.BlockReceivePool(self.download_data_processor, xlog)\n        self.connection_pipe = base_container.ConnectionPipe(self, xlog)\n        self.lock = threading.Lock()  # lock for conn_id, sn generation, on_road_num change,\n        self.get_data_lock = threading.Lock()\n\n        self.send_delay = g.config.send_delay / 1000.0\n        self.ack_delay = g.config.ack_delay / 1000.0\n        self.resend_timeout = g.config.resend_timeout / 1000.0\n\n        self.running = False\n        self.round_trip_thread = {}\n        self.session_id = utils.generate_random_lowercase(8)\n        self.last_conn_id = 0\n        self.last_transfer_no = 0\n        self.conn_list = {}\n        self.transfer_list = {}\n        self.on_road_num = 0\n        self.last_receive_time = 0\n        self.last_send_time = 0\n        self.server_send_buf_size = 0\n        self.target_on_roads = 0\n\n        # speed calculation\n        self.traffic_upload = 0\n        self.traffic_download = 0\n        self.last_traffic_upload = 0\n        self.last_traffic_download = 0\n        self.last_traffic_reset_time = time.time()\n        self.upload_speed = 0.0\n        self.download_speed = 0.0\n\n        # server time logic like NTP\n        self.server_time_offset = 0\n        self.server_time_deviation = 9999\n\n        # the receive time of the tail of the socket receive buffer\n        # if now - oldest_received_time > delay, then send.\n        # set only no data in receive buffer\n        # if no data left, set to 0\n        self.oldest_received_time = 0\n\n        self.last_state = {\n            \"timeout\": 0,\n        }\n        if g.config.enable_tls_relay:\n            threading.Thread(target=self.reporter, name=\"reporter\").start()\n\n        if g.config.upload_logs:\n            threading.Thread(target=upload_logs_thread, name=\"upload_logs\").start()\n\n        self.timeout_check_th = threading.Thread(target=self.timeout_checker, name=\"timeout_check\")\n        self.timeout_check_th.start()\n\n    def start(self):\n        with self.lock:\n            if self.running is True:\n                xlog.warn(\"session try to run but is running.\")\n                return True\n\n            self.session_id = utils.to_bytes(utils.generate_random_lowercase(8))\n            self.last_conn_id = 0\n            self.last_transfer_no = 0\n            self.conn_list = {}\n            self.transfer_list = {}\n            self.last_send_time = time.time()\n            self.last_receive_time = 0\n\n            # speed calculation\n            self.traffic_upload = 0\n            self.traffic_download = 0\n            self.last_traffic_upload = 0\n            self.last_traffic_download = 0\n            self.last_traffic_reset_time = time.time()\n\n            # sn => (payload, send_time)\n            # sn => ack\n            self.wait_ack_send_list = dict()\n            self.ack_send_continue_sn = 0\n\n            self.received_sn = []\n            self.receive_next_sn = 1\n            self.target_on_roads = 0\n            self.server_time_offset = 0\n            self.server_time_deviation = 9999\n\n            if not self.login_session():\n                xlog.warn(\"x-tunnel login_session fail, session not start\")\n                return False\n\n            self.running = True\n\n            for i in range(0, g.config.concurent_thread_num):\n                if i in self.round_trip_thread:\n                    continue\n\n                self.round_trip_thread[i] = threading.Thread(target=self.normal_round_trip_worker, args=(i,),\n                                                             name=\"roundtrip_%d\" % i)\n                self.round_trip_thread[i].start()\n\n            self.connection_pipe.start()\n            xlog.info(\"session started.\")\n            return True\n\n    def timeout_checker(self):\n        while self.running:\n            timeout_num = 0\n            with self.lock:\n                time_now = time.time()\n                for sn, data_info in self.transfer_list.items():\n                    if data_info[\"stat\"] != \"timeout\" and time_now - (data_info[\"start_time\"] + data_info[\"server_timeout\"]) > g.config.send_timeout_retry:\n                        data_info[\"stat\"] = \"timeout\"\n                        xlog.warn(\"timeout_checker found transfer_no:%d timeout:%f\", sn, time_now - data_info[\"start_time\"])\n                        timeout_num += 1\n\n            if timeout_num:\n                self.target_on_roads = \\\n                    min(g.config.concurent_thread_num - g.config.min_on_road, self.target_on_roads + timeout_num)\n                self.trigger_more()\n\n            time.sleep(1)\n\n    def traffic_speed_calculation(self):\n        now = time.time()\n        time_go = now - self.last_traffic_reset_time\n        if time_go > 0.5:\n            self.upload_speed = (self.traffic_upload - self.last_traffic_upload) / time_go\n            self.download_speed = (self.traffic_download - self.last_traffic_download) / time_go\n\n            self.last_traffic_reset_time = now\n            self.last_traffic_upload = self.traffic_upload\n            self.last_traffic_download = self.traffic_download\n\n            # xlog.debug(\"upload speed:%s download speed:%s\",\n            #            convert_data_size_easy_read(self.upload_speed),\n            #            convert_data_size_easy_read(self.download_speed)\n            #            )\n\n    def stop(self):\n        if not self.running:\n            # xlog.warn(\"session stop but not running\")\n            return\n\n        self.running = False\n        self.session_id = \"\"\n        self.target_on_roads = 0\n        with self.lock:\n            for i in range(0, g.config.concurent_thread_num):\n                self.wait_queue.notify()\n\n            self.close_all_connection()\n            self.send_buffer.reset()\n            self.receive_process.reset()\n            self.wait_queue.stop()\n            self.connection_pipe.stop()\n\n            xlog.debug(\"session stopped.\")\n\n    def reset(self):\n        xlog.debug(\"session reset\")\n        self.stop()\n        return self.start()\n\n    def is_idle(self):\n        return time.time() - self.last_send_time > 60\n\n    def check_upload(self):\n        # xlog.debug(\"check_upload send_buffer.pool_size:%d\", self.send_buffer.pool_size)\n        if self.send_buffer.pool_size > 0:\n            # xlog.debug(\"wait_queue notify\")\n            self.wait_queue.notify()\n            return True\n\n    def reporter(self):\n        sleep(5)\n        while g.running:\n            if not g.running:\n                break\n\n            self.check_report_status()\n            sleep(g.config.report_interval)\n\n    def check_report_status(self):\n        if self.is_idle() or not g.config.api_server:\n            return\n\n        good_ip_num = 0\n        for ip in g.tls_relay_front.ip_manager.ip_dict:\n            ip_state = g.tls_relay_front.ip_manager.ip_dict[ip]\n            fail_times = ip_state[\"fail_times\"]\n            if fail_times == 0:\n                good_ip_num += 1\n        if good_ip_num:\n            return\n\n        stat = self.get_stat(\"minute\")\n        stat[\"version\"] = g.xxnet_version\n        stat[\"client_uuid\"] = g.client_uuid\n        timeout_count = g.stat[\"timeout_roundtrip\"] - self.last_state[\"timeout\"]\n        if timeout_count == 0:\n            return\n\n        stat[\"global\"][\"timeout\"] = timeout_count\n        stat[\"global\"][\"ipv6\"] = check_local_network.IPv6.is_ok()\n        stat[\"tls_relay_front\"][\"ip_dict\"] = g.tls_relay_front.ip_manager.ip_dict\n\n        report_dat = {\n            \"account\": str(g.config.login_account),\n            \"password\": str(g.config.login_password),\n            \"stat\": stat,\n        }\n        xlog.debug(\"start report_stat\")\n        status, info = call_api(\"/report_stat\", report_dat)\n        if not status:\n            xlog.warn(\"report fail.\")\n            return\n\n        self.last_state[\"timeout\"] = g.stat[\"timeout_roundtrip\"]\n        data = info[\"data\"]\n        g.tls_relay_front.set_ips(data[\"ips\"])\n\n    def get_stat(self, type=\"second\"):\n        self.traffic_speed_calculation()\n\n        res = {}\n        rtt = 0\n        recent_sent = 0\n        recent_received = 0\n        total_sent = 0\n        total_received = 0\n        for front in g.http_client.all_fronts:\n            if not front:\n                continue\n            name = front.name\n            dispatcher = front.get_dispatcher(g.server_host)\n            if not dispatcher:\n                res[name] = {\n                    \"score\": \"False\",\n                    \"rtt\": 9999,\n                    \"success_num\": 0,\n                    \"fail_num\": 0,\n                    \"worker_num\": 0,\n                    \"total_traffics\": \"Up: 0 / Down: 0\"\n                }\n                continue\n            score = dispatcher.get_score()\n            if score is None:\n                score = \"False\"\n            else:\n                score = int(score)\n\n            if type == \"second\":\n                stat = dispatcher.second_stat\n            elif type == \"minute\":\n                stat = dispatcher.minute_stat\n            else:\n                raise Exception()\n\n            rtt = max(rtt, stat[\"rtt\"])\n            recent_sent += stat[\"sent\"]\n            recent_received += stat[\"received\"]\n            total_sent += dispatcher.total_sent\n            total_received += dispatcher.total_received\n            res[name] = {\n                \"score\": score,\n                \"rtt\": stat[\"rtt\"],\n                \"success_num\": dispatcher.success_num,\n                \"fail_num\": dispatcher.fail_num,\n                \"worker_num\": dispatcher.worker_num(),\n                \"total_traffics\": \"Up: %s / Down: %s\" % (\n                    traffic_readable(dispatcher.total_sent), traffic_readable(dispatcher.total_received))\n            }\n\n        res[\"global\"] = {\n            \"handle_num\": g.socks5_server.handler.handle_num,\n            \"rtt\": int(rtt),\n            \"roundtrip_num\": g.stat[\"roundtrip_num\"],\n            \"slow_roundtrip\": g.stat[\"slow_roundtrip\"],\n            \"timeout_roundtrip\": g.stat[\"timeout_roundtrip\"],\n            \"resend\": g.stat[\"resend\"],\n            \"speed\": \"Up: %s/s / Down: %s/s\" % (traffic_readable(self.upload_speed), traffic_readable(self.download_speed)),\n            \"total_traffics\": \"Up: %s / Down: %s\" % (traffic_readable(self.traffic_upload), traffic_readable(self.traffic_download))\n        }\n        return res\n\n    def status(self):\n        self.traffic_speed_calculation()\n\n        out_string = \"session_id: %s\\n\" % utils.to_str(self.session_id)\n        out_string += \"server: %s\\n\" % g.server_host\n        out_string += \"extra_info: %s\\n\" % json.dumps(json.loads(self.get_login_extra_info()), indent=2)\n        out_string += \"thread num: %d\\n\" % threading.active_count()\n        out_string += \"running: %d\\n\" % self.running\n        out_string += \"last_send_time: %f\\n\" % (time.time() - self.last_send_time)\n        out_string += \"last_receive_time: %f ago\\n\" % (time.time() - self.last_receive_time)\n        out_string += \"last_conn: %d\\n\" % self.last_conn_id\n        out_string += \"last_transfer_no: %d\\n\" % self.last_transfer_no\n        out_string += \"traffic_upload: %d\\n\" % self.traffic_upload\n        out_string += \"traffic_download: %d\\n\" % self.traffic_download\n        out_string += \"last_traffic_upload: %d\\n\" % self.last_traffic_upload\n        out_string += \"last_traffic_download: %d\\n\" % self.last_traffic_download\n        out_string += \"upload_speed: %f\\n\" % self.upload_speed\n        out_string += \"download_speed: %f\\n\" % self.download_speed\n        out_string += \"last_traffic_reset_time %f ago\\n\" % (time.time() - self.last_traffic_reset_time )\n        out_string += \"server_time_offset: %f\\n\" % self.server_time_offset\n        out_string += \"server_time_deviation: %f\\n\" % self.server_time_deviation\n        out_string += \"target_on_roads: %d\\n\" % self.target_on_roads\n        out_string += \"on_road_num:%d\\n\" % self.on_road_num\n        out_string += \"transfer_list: %d\\n\" % len(self.transfer_list)\n        for sn in sorted(self.transfer_list.keys()):\n            data_info = self.transfer_list[sn]\n            time_way = \" t:\" + str((time.time() - self.transfer_list[sn][\"start_time\"]))\n            out_string += f'[{sn}] stat:{data_info[\"stat\"]} server_timeout:{data_info[\"server_timeout\"]} retry:{data_info[\"retry\"]} {time_way}\\n'\n\n        out_string += \"\\n\" + self.wait_queue.status()\n        out_string += \"\\n\" + self.send_buffer.status()\n        out_string += \"\\n\" + self.receive_process.status()\n        out_string += \"\\n\" + self.connection_pipe.status()\n\n        for conn_id in self.conn_list:\n            out_string += \"\\n\" + self.conn_list[conn_id].status()\n\n        return out_string\n\n    @staticmethod\n    def get_login_extra_info():\n        data = {\n            \"version\": g.xxnet_version,\n            \"system\": g.system,\n            \"device\": g.client_uuid\n        }\n        return json.dumps(data)\n\n    def login_session(self):\n        if not g.server_host or len(g.server_host) == 0:\n            return False\n\n        start_time = time.time()\n        while time.time() - start_time < 30:\n            try:\n                magic = b\"P\"\n                pack_type = 1\n                upload_data_head = struct.pack(\"<cBB8sIHIIHH\", magic, g.protocol_version, pack_type,\n                                               self.session_id,\n                                               g.config.max_payload, g.config.send_delay, g.config.windows_size,\n                                               int(g.config.windows_ack), g.config.resend_timeout, g.config.ack_delay)\n                upload_data_head += struct.pack(\"<H\", len(g.config.login_account)) + utils.to_bytes(g.config.login_account)\n                upload_data_head += struct.pack(\"<H\", len(g.config.login_password)) + utils.to_bytes(g.config.login_password)\n                extra_info = self.get_login_extra_info()\n                upload_data_head += struct.pack(\"<H\", len(extra_info)) + utils.to_bytes(extra_info)\n\n                upload_post_data = encrypt_data(upload_data_head)\n\n                content, status, response = g.http_client.request(method=\"POST\", host=g.server_host, path=\"/data\",\n                                                                  data=upload_post_data,\n                                                                  timeout=g.config.network_timeout)\n\n                time_cost = time.time() - start_time\n\n                if status == 521:\n                    g.last_api_error = \"session server is down.\"\n                    xlog.warn(\"login session server is down, try get new server.\")\n                    g.server_host = None\n                    return False\n\n                if status != 200:\n                    g.last_api_error = \"session server login fail:%r\" % status\n                    xlog.warn(\"login session fail, status:%r\", status)\n                    continue\n\n                if len(content) < 6:\n                    g.last_api_error = \"session server protocol fail, login res len:%d\" % len(content)\n                    xlog.error(\"login data len:%d fail\", len(content))\n                    continue\n\n                info = decrypt_data(content)\n                magic, protocol_version, pack_type, res, message_len = struct.unpack(\"<cBBBH\", info[:6])\n                message = info[6:]\n                if isinstance(message, memoryview):\n                    message = message.tobytes()\n\n                if magic != b\"P\" or protocol_version != g.protocol_version or pack_type != 1:\n                    xlog.error(\"login_session time:%d head error:%s\", 1000 * time_cost, utils.str2hex(info[:6]))\n                    return False\n\n                if res != 0:\n                    g.last_api_error = \"session server login fail, code:%d msg:%s\" % (res, message)\n                    xlog.warn(\"login_session time:%d fail, res:%d msg:%s\", 1000 * time_cost, res, message)\n                    return False\n\n                try:\n                    msg_info = json.loads(message)\n                    if msg_info.get(\"full_log\"):\n                        xlog.debug(\"keep full log\")\n                        keep_log(temp=True)\n                except Exception as e:\n                    xlog.warn(\"login_session %s json error:%r\", message, e)\n                    msg_info = {}\n\n                g.http_client.set_session_host(g.server_host)\n                g.last_api_error = \"\"\n                xlog.info(\"login_session %s time:%d msg:%s\", self.session_id, 1000 * time_cost, message)\n                return True\n            except Exception as e:\n                xlog.exception(\"login_session e:%r\", e)\n                time.sleep(1)\n\n        return False\n\n    def create_conn(self, sock, host, port, log=False):\n        if not self.running:\n            xlog.debug(\"session not running, try to connect\")\n            time.sleep(1)\n            return None\n\n        with self.lock:\n            self.last_conn_id += 2\n            conn_id = self.last_conn_id\n\n        if isinstance(host, str):\n            host = host.encode(\"ascii\")\n\n        seq = 0\n        cmd_type = 0  # create connection\n        sock_type = 0  # TCP\n        data = struct.pack(\"<IBBH\", seq, cmd_type, sock_type, len(host)) + host + struct.pack(\"<H\", port)\n        self.send_conn_data(conn_id, data)\n\n        self.conn_list[conn_id] = base_container.Conn(self, conn_id, sock, host, port, g.config.windows_size,\n                                                      g.config.windows_ack, True, xlog)\n\n        self.target_on_roads = \\\n            min(g.config.concurent_thread_num - g.config.min_on_road, self.target_on_roads + 2)\n        self.trigger_more()\n\n        if log:\n            xlog.info(\"Connect to %s:%d conn:%d\", host, port, conn_id)\n        return conn_id\n\n    # Called by stop\n    def close_all_connection(self):\n        xlog.info(\"start close all connection\")\n        conn_list = dict(self.conn_list)\n        for conn_id in conn_list:\n            try:\n                # xlog.debug(\"stopping conn:%d\", conn_id)\n                self.conn_list[conn_id].stop(reason=\"system reset\")\n            except Exception as e:\n                xlog.warn(\"stopping conn:%d fail:%r\", conn_id, e)\n                pass\n        # self.conn_list = {}\n        xlog.debug(\"stop all connection finished\")\n\n    def remove_conn(self, conn_id):\n        try:\n            if conn_id in self.conn_list:\n                conn = self.conn_list[conn_id]\n                # xlog.debug(\"remove conn:%d %s:%d\", conn_id, conn.host, conn.port)\n                del self.conn_list[conn_id]\n        except Exception as e:\n            xlog.warn(\"remove conn:%d except:%r\", conn_id, e)\n\n        if len(self.conn_list) == 0:\n            self.target_on_roads = 0\n\n    def send_conn_data(self, conn_id, data):\n        if not self.running:\n            xlog.warn(\"send_conn_data but not running\")\n            return\n\n        # xlog.debug(\"upload conn:%d, len:%d\", conn_id, len(data))\n        buf = base_container.WriteBuffer()\n        buf.append(struct.pack(\"<II\", conn_id, len(data)))\n        buf.append(data)\n        self.send_buffer.put(buf)\n\n        if self.oldest_received_time == 0:\n            self.oldest_received_time = time.time()\n        elif self.send_buffer.pool_size > g.config.max_payload:\n            # xlog.debug(\"notify on send conn data\")\n            self.wait_queue.notify()\n\n    @staticmethod\n    def sn_payload_head(sn, payload):\n        return struct.pack(\"<II\", sn, len(payload))\n\n    def get_data(self, work_id):\n        time_now = time.time()\n        buf = base_container.WriteBuffer()\n\n        with self.lock:\n            for sn in self.wait_ack_send_list:\n                pk = self.wait_ack_send_list[sn]\n                if isinstance(pk, str):\n                    continue\n\n                payload, send_time = pk\n                if time_now - send_time > self.resend_timeout:\n                    g.stat[\"resend\"] += 1\n                    buf.append(self.sn_payload_head(sn, payload))\n                    buf.append(payload)\n                    self.wait_ack_send_list[sn] = (payload, time_now)\n                    if len(buf) > g.config.max_payload:\n                        return buf\n\n            if self.send_buffer.pool_size > g.config.max_payload or \\\n                    (self.send_buffer.pool_size > 0 and\n                     time.time() - self.oldest_received_time > self.send_delay\n                    ):\n                payload, sn = self.send_buffer.get()\n                self.wait_ack_send_list[sn] = (payload, time_now)\n                buf.append(self.sn_payload_head(sn, payload))\n                buf.append(payload)\n\n                if self.send_buffer.pool_size == 0:\n                    self.oldest_received_time = 0\n\n                if len(buf) > g.config.max_payload:\n                    return buf\n            # else:\n            #     xlog.debug(\"pool_size:%d work_id:%d target_on_road:%d\",\n            #                self.send_buffer.pool_size, work_id, self.target_on_roads)\n\n        return buf\n\n    def get_ack(self, force=False):\n        time_now = time.time()\n        # xlog.debug(\"get_ack force:%d, last_receive_time:%f, last_send_time:%f, time_now - self.last_send_time:%f\",\n        #           force, self.last_receive_time, self.last_send_time, time_now - self.last_send_time)\n\n        if force or \\\n                (self.last_receive_time > self.last_send_time and\n                 time_now - self.last_receive_time > self.ack_delay):\n\n            buf = base_container.WriteBuffer()\n            buf.append(struct.pack(\"<I\", self.receive_process.next_sn - 1))\n            for sn in self.receive_process.block_list:\n                buf.append(struct.pack(\"<I\", sn))\n            return buf\n\n        return \"\"\n\n    def get_down_sn_timeout_list_pack(self):\n        buf = base_container.WriteBuffer()\n        if self.server_time_deviation > g.config.server_time_max_deviation:\n            return buf\n\n        server_time = int(time.time() + self.server_time_offset)\n        timeout_list = self.receive_process.get_timeout_list(server_time, g.config.server_download_timeout_retry)\n        for sn in timeout_list:\n            buf.append(struct.pack(\"<I\", sn))\n        buf.insert(struct.pack(\"<I\", len(timeout_list)))\n        return buf\n\n    def get_send_data(self, work_id):\n        force = False\n        while self.running:\n            data = self.get_data(work_id)\n            down_sn_timeout_list_pack = self.get_down_sn_timeout_list_pack()\n            # xlog.debug(\"get_send_data work_id:%d len:%d\", work_id, len(data))\n            if data or len(down_sn_timeout_list_pack) > 4:\n                # xlog.debug(\"got data, force to get ack\")\n                force = True\n\n            if self.on_road_num < self.target_on_roads:\n                # xlog.debug(\"need more on_road, force to get ack\")\n                force = True\n\n            ack = self.get_ack(force=force)\n            if force or ack:\n                # xlog.debug(\"get_send_data work_id:%d data_len:%d ack_len:%d force:%d\", work_id, len(data), len(ack), force)\n                return data, ack, down_sn_timeout_list_pack\n\n            self.wait_queue.wait(work_id)\n\n        xlog.debug(\"get_send_data on stop\")\n        return b\"\", b\"\", b\"\"\n\n    def ack_process(self, ack):\n        self.lock.acquire()\n        try:\n            last_ack = struct.unpack(\"<I\", ack.get(4))[0]\n\n            while len(ack):\n                sn = struct.unpack(\"<I\", ack.get(4))[0]\n                # xlog.debug(\"ack: %d\", sn)\n                if sn in self.wait_ack_send_list:\n                    self.wait_ack_send_list[sn] = \"acked\"\n\n            for sn in self.wait_ack_send_list:\n                if sn > last_ack:\n                    continue\n                if self.wait_ack_send_list[sn] == \"acked\":\n                    continue\n\n                # xlog.debug(\"last_ack:%d sn:%d\", last_ack, sn)\n                self.wait_ack_send_list[sn] = \"acked\"\n\n            while (self.ack_send_continue_sn + 1) in self.wait_ack_send_list and \\\n                    self.wait_ack_send_list[self.ack_send_continue_sn + 1] == \"acked\":\n                self.ack_send_continue_sn += 1\n                del self.wait_ack_send_list[self.ack_send_continue_sn]\n\n        except Exception as e:\n            xlog.exception(\"ack_process:%r\", e)\n        finally:\n            self.lock.release()\n\n    def download_data_processor(self, data):\n        try:\n            while len(data):\n                conn_id, payload_len = struct.unpack(\"<II\", data.get(8))\n                payload = data.get_buf(payload_len)\n\n                # xlog.debug(\"conn:%d upload data len:%d\", conn_id, len(payload))\n                if conn_id not in self.conn_list:\n                    xlog.debug(\"conn:%d not exist\", conn_id)\n                    continue\n                self.conn_list[conn_id].put_cmd_data(payload)\n        except Exception as e:\n            xlog.exception(\"download_data_processor:%r\", e)\n\n    def check_upload_not_acked(self, server_time):\n        server_local_time = server_time - self.server_time_offset\n        if self.server_time_deviation > g.config.server_time_max_deviation:\n            return\n\n        timeout_num = 0\n        entry_time = time.time()\n        with self.lock:\n            now = time.time()\n            if now - entry_time > 0.1:\n                xlog.error(\"check_upload_not_acked lock time:%f\", now - entry_time)\n                return\n\n            for no, data_info in self.transfer_list.items():\n                if data_info[\"stat\"] == \"timeout\":\n                    continue\n\n                if data_info[\"server_received\"] == False and server_local_time - data_info[\"start_time\"] > g.config.send_timeout_retry:\n                    data_info[\"stat\"] = \"timeout\"\n                    xlog.warn(\"check_upload_not_acked found transfer_no:%d upload timeout:%f\", no,\n                              server_local_time - data_info[\"start_time\"])\n                    timeout_num += 1\n                    continue\n\n                if data_info[\"server_sent\"] and server_time - data_info[\"server_sent\"] > g.config.send_timeout_retry:\n                    data_info[\"stat\"] = \"timeout\"\n                    xlog.warn(\"check_upload_not_acked found transfer_no:%d down timeout:%f\", no,\n                              server_time - data_info[\"server_sent\"])\n                    timeout_num += 1\n                    continue\n\n        if timeout_num:\n            self.target_on_roads = \\\n                min(g.config.concurent_thread_num - g.config.min_on_road, self.target_on_roads + timeout_num)\n            self.trigger_more()\n\n    def process_server_received_transfer_no(self, server_received_no_list, server_sent_no_list, server_time):\n        server_received_next_no = struct.unpack(\"<I\", server_received_no_list.get(4))[0]\n        server_sent_next_no = struct.unpack(\"<I\", server_sent_no_list.get(4))[0]\n        with self.lock:\n            for no, info in self.transfer_list.items():\n                if no < server_received_next_no:\n                    info[\"server_received\"] = True\n\n                if no < server_sent_next_no:\n                    info[\"server_sent\"] = server_time\n\n            server_unordered_received_no_num = struct.unpack(\"<I\", server_received_no_list.get(4))[0]\n            for i in range(0, server_unordered_received_no_num):\n                no, t = struct.unpack(\"<Id\", server_received_no_list.get(12))\n                if no in self.transfer_list:\n                    # xlog.debug(\"server unordered confirmed transfer_no:%d\", sn)\n                    self.transfer_list[no][\"server_received\"] = t\n\n            server_unordered_sent_no_num = struct.unpack(\"<I\", server_sent_no_list.get(4))[0]\n            for i in range(0, server_unordered_sent_no_num):\n                no, t = struct.unpack(\"<Id\", server_sent_no_list.get(12))\n                if no in self.transfer_list:\n                    # xlog.debug(\"server unordered confirmed transfer_no:%d\", sn)\n                    self.transfer_list[no][\"server_sent\"] = t\n\n    def process_server_unacked_sent_sn(self, data):\n        if self.server_time_deviation > g.config.server_time_max_deviation:\n            return\n\n        server_time = time.time() + self.server_time_offset\n\n        sn_num = struct.unpack(\"<I\", data.get(4))[0]\n        timeout_num = 0\n        for i in range(0, sn_num):\n            sn, t = struct.unpack(\"<Id\", data.get(12))\n            if self.receive_process.is_received(sn):\n                continue\n\n            if server_time - t > g.config.server_download_timeout_retry:\n                # xlog.warn(\"server unacked sn:%d timeout:%f\", sn, server_time - t)\n                self.receive_process.mark_sn_timeout(sn, t, server_time)\n                timeout_num += 1\n\n    def round_trip_process(self, data, ack, server_rcvd_no_list, server_sent_no_list, server_unack_snd_sn, server_time):\n        while len(data):\n            sn, plen = struct.unpack(\"<II\", data.get(8))\n            pdata = data.get_buf(plen)\n            if g.config.show_debug:\n                xlog.debug(\"download sn:%d len:%d\", sn, plen)\n\n            self.receive_process.put(sn, pdata)\n\n        self.ack_process(ack)\n\n        self.process_server_received_transfer_no(server_rcvd_no_list, server_sent_no_list, server_time)\n\n        self.process_server_unacked_sent_sn(server_unack_snd_sn)\n\n    def get_transfer_no(self):\n        with self.lock:\n            self.last_transfer_no += 1\n            transfer_no = self.last_transfer_no\n\n        return transfer_no\n\n    def trigger_more(self):\n        running_num = g.config.concurent_thread_num - len(self.wait_queue.waiters)\n        action_num = self.target_on_roads - running_num\n        if action_num <= 0:\n            return\n\n        if g.config.show_debug:\n            xlog.debug(\"running_num:%d on_road:%d target:%d trigger_more:%d\",\n                       running_num, self.on_road_num, self.target_on_roads, action_num)\n\n        for _ in range(0, action_num):\n            self.wait_queue.notify()\n\n    def normal_round_trip_worker(self, work_id):\n        try:\n            while self.running:\n                self.roundtrip_task(work_id)\n        finally:\n            del self.round_trip_thread[work_id]\n            xlog.info(\"roundtrip thread %d exit\", work_id)\n\n    def get_upload_data(self, work_id):\n        if not self.running:\n            return\n\n        # Get a timeout request to retry\n        time_now = time.time()\n        with self.lock:\n            wrong_sn = []\n            for sn, data_info in self.transfer_list.items():\n                if data_info[\"session_id\"] != self.session_id:\n                    wrong_sn.append(sn)\n                    continue\n\n                if data_info[\"stat\"] == \"timeout\":\n                    xlog.warn(\"retry transfer_no:%d t:%f\", sn, time_now - data_info[\"start_time\"])\n                    data_info[\"stat\"] = \"retry\"\n                    data_info[\"retry\"] += 1\n                    data_info[\"start_time\"] = time_now\n\n                    return data_info\n\n            for sn in wrong_sn:\n                del self.transfer_list[sn]\n\n        # Generate a new request\n        data, ack, download_timeout = self.get_send_data(work_id)\n        transfer_no = self.get_transfer_no()\n        # xlog.debug(\"trip:%d no:%d send data:%s\", work_id, transfer_no, parse_data(data))\n\n        start_time = time.time()\n        info = {\n            \"session_id\": self.session_id,\n            \"transfer_no\": transfer_no,\n            \"stat\": \"request\",\n            \"server_received\": False,\n            \"server_sent\": False,\n            \"start_time\": start_time,\n            \"server_timeout\": g.config.roundtrip_timeout,\n            \"send_data\": data,\n            \"send_ack\": ack,\n            \"download_timeout\": download_timeout,\n            \"request_session_id\": self.session_id,\n            \"retry\": 0,\n        }\n\n        with self.lock:\n            self.transfer_list[transfer_no] = info\n\n        return info\n\n    def roundtrip_task(self, work_id):\n        with self.get_data_lock:\n            data_info = self.get_upload_data(work_id)\n            if not data_info:\n                return\n\n            request_session_id = data_info[\"request_session_id\"]\n            if request_session_id != self.session_id:\n                return\n\n            transfer_no = data_info[\"transfer_no\"]\n            start_time = data_info[\"start_time\"]\n            send_data = data_info[\"send_data\"]\n            send_ack = data_info[\"send_ack\"]\n            download_timeout = data_info[\"download_timeout\"]\n\n            # Generate upload data package\n            send_data_len = len(send_data)\n            send_ack_len = len(send_ack)\n            download_timeout_len = len(download_timeout)\n\n            if self.send_buffer.pool_size > g.config.max_payload or \\\n                    g.config.concurent_thread_num - self.on_road_num < g.config.min_on_road or \\\n                    self.server_time_deviation > g.config.server_time_max_deviation or \\\n                    data_info[\"stat\"] == \"retry\":\n                # xlog.debug(\"pool_size:%s waiters:%d\", self.send_buffer.pool_size, len(self.wait_queue.waiters))\n                server_timeout = 0\n            else:\n                server_timeout = g.config.roundtrip_timeout\n\n            with self.lock:\n                if transfer_no not in self.transfer_list:\n                    xlog.warn(\"roundtrip transfer_no not found:%d\", transfer_no)\n                    return\n\n                self.on_road_num += 1\n                # xlog.debug(f\"worker: {work_id} on_road_num plus: {self.on_road_num}\")\n                self.transfer_list[transfer_no][\"server_timeout\"] = server_timeout\n\n        magic = b\"P\"\n        pack_type = 2\n        upload_data_head = struct.pack(\"<cBB8sIBIHH\", magic, g.protocol_version, pack_type,\n                                       utils.to_bytes(self.session_id), transfer_no,\n                                       server_timeout, send_data_len, send_ack_len, download_timeout_len)\n        upload_post_buf = base_container.WriteBuffer(upload_data_head)\n        upload_post_buf.append(send_data)\n        upload_post_buf.append(send_ack)\n        upload_post_buf.append(download_timeout)\n        upload_post_data = upload_post_buf.to_bytes()\n        upload_post_data = encrypt_data(upload_post_data)\n        self.last_send_time = time.time()\n\n        if g.config.show_debug:\n            self.traffic_speed_calculation()\n            xlog.debug(\"start trip, tid:%d target:%d running:%d timeout:%d send:%d\",\n                       transfer_no, self.target_on_roads, self.on_road_num, server_timeout,\n                       len(upload_post_data))\n\n        sleep_time = 1\n        # Use one time loop for easy quit and clean up.\n        for _ in range(1):\n            upload_post_data2 = bytearray(upload_post_data)\n            try:\n                content, status, response = g.http_client.request(method=\"POST\", host=g.server_host,\n                                                                  path=\"/data?tid=%d\" % transfer_no,\n                                                                  data=upload_post_data2,\n                                                                  headers={\n                                                                      \"Content-Length\": str(len(upload_post_data2)),\n                                                                  },\n                                                                  timeout=server_timeout + g.config.network_timeout)\n\n                traffic = len(upload_post_data2) + len(content) + 645\n                self.traffic_upload += len(upload_post_data2) + 645\n                self.traffic_download += len(content)\n                g.quota -= traffic\n                if g.quota < 0:\n                    g.quota = 0\n            except Exception as e:\n                if self.running:\n                    xlog.exception(\"request except:%r \", e)\n\n                data_info[\"stat\"] = \"timeout\"\n                time.sleep(sleep_time)\n                continue\n            finally:\n                with self.lock:\n                    self.on_road_num -= 1\n\n            g.stat[\"roundtrip_num\"] += 1\n            time_now = time.time()\n            roundtrip_time = (time_now - start_time)\n\n            if status == 521:\n                xlog.warn(\"X-tunnel server is down, try get new server.\")\n                g.server_host = None\n                self.stop()\n                login_process()\n                return\n\n            if status != 200:\n                head = upload_post_data2[:3]\n                xlog.warn(\"roundtrip time:%f transfer_no:%d send:%d head:%s status:%r \",\n                          roundtrip_time, transfer_no, send_data_len, utils.str2hex(head), status)\n                data_info[\"stat\"] = \"timeout\"\n                time.sleep(sleep_time)\n                continue\n\n            content_length = int(response.headers.get(b\"Content-Length\", b\"0\"))\n            content_len = len(content)\n            if content_len < 6 or (content_length and content_length != content_len):\n                xlog.warn(\"roundtrip time:%f transfer_no:%d send:%d recv:%d Head:%d\",\n                          roundtrip_time, transfer_no, send_data_len, content_len, content_length)\n\n                data_info[\"stat\"] = \"timeout\"\n                continue\n\n            try:\n                content = decrypt_data(content)\n                payload = base_container.ReadBuffer(content)\n\n                magic, version, pack_type = struct.unpack(\"<cBB\", payload.get(3))\n                if magic != b\"P\" or version != g.protocol_version or pack_type not in [2, 3]:\n                    xlog.warn(\"get data head:%s\", utils.str2hex(content[:2]))\n                    data_info[\"stat\"] = \"timeout\"\n                    time.sleep(sleep_time)\n                    continue\n\n                if pack_type == 3:  # error report\n                    error_code, message_len = struct.unpack(\"<BH\", payload.get(3))\n                    message = payload.get(message_len)\n                    # xlog.warn(\"report code:%d, msg:%s\", error_code, message)\n                    if error_code == 1:\n                        # no quota\n                        xlog.warn(\"x_server error:no quota\")\n                        self.stop()\n                        return\n                    elif error_code == 2:\n                        # unpack error\n                        xlog.warn(\"roundtrip time:%f transfer_no:%d send:%d recv:%d unpack_error:%s\",\n                                  roundtrip_time, transfer_no, send_data_len, len(content), message)\n                        data_info[\"stat\"] = \"timeout\"\n                        continue\n                    elif error_code == 3:\n                        # session not exist\n                        if self.session_id == request_session_id:\n                            xlog.warn(\"server session_id:%s not exist, reset session.\", request_session_id)\n                            self.reset()\n                        return\n                    else:\n                        xlog.error(\"unknown error code:%d, message:%s\", error_code, message)\n                        time.sleep(sleep_time)\n                        continue\n\n                server_time, time_cost, server_send_pool_size, data_len, ack_len, rcvd_no_len, sent_no_len, unack_snd_sn_len, ext_len \\\n                    = struct.unpack(\"<dIIIIIIII\", payload.get(40))\n                head_len = (content_len - data_len - ack_len - rcvd_no_len - sent_no_len - unack_snd_sn_len - ext_len)\n                if head_len < 3 + 40:\n                    xlog.warn(\"no:%d recv_len:%d data:%d ack:%d head:%d\",\n                              transfer_no, content_len, data_len, ack_len, head_len)\n                    data_info[\"stat\"] = \"timeout\"\n                    continue\n\n                rtt = roundtrip_time - (time_cost/1000.0)\n                speed = (send_data_len + len(content) + 400) / rtt\n\n                if roundtrip_time < self.server_time_deviation:\n                    new_offset = server_time - time_now\n                    xlog.info(\"adjust server time offset:%f->%f, deviation:%f->%f\", self.server_time_offset, new_offset,\n                               self.server_time_deviation, roundtrip_time)\n                    self.server_time_offset = new_offset\n                    self.server_time_deviation = roundtrip_time\n\n                xlog.debug(\n                    \"no:%d %s \"\n                    \"road_time:%f \"\n                    \"snd:%d rcv:%d \"\n                    \"s_pool:%d on_road:%d target_worker:%d speed:%d \"\n                    \"roundtrip_time:%f server_timeout:%d \",\n                    transfer_no, response.worker.ip_str,\n                    roundtrip_time - time_cost / 1000.0,\n                    send_data_len, len(content),\n                    server_send_pool_size,\n                    self.on_road_num,\n                    self.target_on_roads,\n                    speed, roundtrip_time, server_timeout\n                )\n                if g.config.show_debug:\n                    xlog.debug(\"data:%d ack:%d rcvd_no:%d sent_no:%d unack_sent_no:%d\", data_len, ack_len, rcvd_no_len, sent_no_len, unack_snd_sn_len)\n\n                if len(self.conn_list) == 0:\n                    self.target_on_roads = 0\n                elif len(content) >= g.config.max_payload:\n                    self.target_on_roads = \\\n                        min(g.config.concurent_thread_num - g.config.min_on_road, self.target_on_roads + 10)\n                elif data_len <= 200:\n                    self.target_on_roads = max(g.config.min_on_road, self.target_on_roads - 5)\n                self.trigger_more()\n                # xlog.debug(\"target roundtrip: %d, on_road: %d\", self.target_on_roads, self.on_road_num)\n\n                if rtt > 8000:\n                    xlog.warn(\"rtt:%d speed:%d trace:%s\", rtt, speed, response.worker.get_trace())\n                    xlog.warn(\"task trace:%s\", response.task.get_trace())\n                    g.stat[\"slow_roundtrip\"] += 1\n\n                data = payload.get_buf(data_len)\n                ack = payload.get_buf(ack_len)\n                rcvd_no_list = payload.get_buf(rcvd_no_len)\n                sent_no_list = payload.get_buf(sent_no_len)\n                unack_snd_sn = payload.get_buf(unack_snd_sn_len)\n                ext = payload.get_buf(ext_len)\n\n                if len(payload) > 32:\n                    checksum_str = utils.to_str(payload.get(32).tobytes())\n                    checksum = hashlib.md5(bytes(content[:-32])).hexdigest()\n                    if checksum != checksum_str:\n                        xlog.warn(\"checksum error:%s %s\", checksum_str, checksum)\n\n                        data_info[\"stat\"] = \"timeout\"\n                        continue\n\n                self.last_receive_time = time.time()\n\n                with self.lock:\n                    if transfer_no in self.transfer_list:\n                        del self.transfer_list[transfer_no]\n\n                self.round_trip_process(data, ack, rcvd_no_list, sent_no_list, unack_snd_sn, server_time)\n                self.check_upload_not_acked(server_time)\n\n                if self.on_road_num + 1 < self.target_on_roads:\n                    self.wait_queue.notify()\n\n                self.wait_queue.notify()\n                return\n            except Exception as e:\n                xlog.exception(\"trip:%d no:%d data not enough %r\", work_id, transfer_no, e)\n\n                data_info[\"stat\"] = \"timeout\"\n                continue\n\n                # xlog.debug(\"trip:%d no:%d recv data:%s\", work_id, transfer_no, parse_data(data))\n\n        xlog.warn(\"roundtrip failed, no:%d target:%d on_road:%d timeout:%d send:%d\",\n                   transfer_no, self.target_on_roads, self.on_road_num, server_timeout,\n                   len(upload_post_data))\n        self.wait_queue.notify()\n\n\ndef parse_data(data):\n    if len(data) == 0:\n        return \"\"\n\n    o = \"\"\n\n    data = bytes(data)\n    data = base_container.ReadBuffer(data)\n    while len(data):\n\n        sn, block_len = struct.unpack(\"<II\", data.get(8))\n        block = data.get_buf(block_len)\n\n        o += \"sn:%d {\" % sn\n\n        while len(block):\n            conn_id, payload_len = struct.unpack(\"<II\", block.get(8))\n\n            o += \"conn:%d [\" % conn_id\n            conn_data = block.get_buf(payload_len)\n\n            seq = struct.unpack(\"<I\", conn_data.get(4))[0]\n            cmd_id = struct.unpack(\"<B\", conn_data.get(1))[0]\n            conn_payload = conn_data.get_buf()\n            if cmd_id == 0:  # create connection\n                sock_type = struct.unpack(\"<B\", conn_payload.get(1))[0]\n                host_len = struct.unpack(\"<H\", conn_payload.get(2))[0]\n                host = str(bytes(conn_payload.get(host_len)))\n                port = struct.unpack(\"<H\", conn_payload.get(2))[0]\n                o += \"%d|Connect:%s:%d\" % (seq, host, port)\n            elif cmd_id == 1:  # data\n                o += \"%d|D:%d\" % (seq, len(conn_payload))\n            elif cmd_id == 2:  # closed\n                o += \"%d|Closed:%s\" % (seq, conn_payload)\n            elif cmd_id == 3:  # ack\n                position = struct.unpack(\"<Q\", conn_payload.get())[0]\n                o += \"%d|Ack:%d\" % (seq, position)\n\n            o += \"],\"\n        o += \"},\"\n\n    return o\n\n\ndef calculate_quota_left(quota_list):\n    time_now = int(time.time())\n    quota_left = 0\n\n    try:\n        if \"current\" in quota_list:\n            c_q_end_time = quota_list[\"current\"][\"end_time\"]\n            if c_q_end_time > time_now:\n                quota_left += quota_list[\"current\"][\"quota\"]\n\n        if \"backup\" in quota_list:\n            for qt in quota_list[\"backup\"]:\n                b_q_quota = qt[\"quota\"]\n                b_q_end_time = qt[\"end_time\"]\n                if b_q_end_time < time_now:\n                    continue\n\n                quota_left += b_q_quota\n\n    except Exception as e:\n        xlog.exception(\"calculate_quota_left %s %r\", quota_list, e)\n\n    return quota_left\n\n\ndef call_api(path, req_info):\n    if not path.startswith(\"/\"):\n        path = \"/\" + path\n\n    try:\n        upload_post_data = json.dumps(req_info)\n        upload_post_data = encrypt_data(upload_post_data)\n\n        start_time = time.time()\n        while time.time() - start_time < 30:\n            content, status, response = g.http_client.request(method=\"POST\", host=g.config.api_server, path=path,\n                                                              headers={\"Content-Type\": \"application/json\"},\n                                                              data=upload_post_data, timeout=5)\n            if status >= 400:\n                time.sleep(1)\n                continue\n            else:\n                break\n\n        time_cost = time.time() - start_time\n        if status != 200:\n            reason = \"status:%r\" % status\n            xlog.warn(\"api:%s fail:%s t:%d\", path, reason, time_cost)\n            g.last_api_error = reason\n            return False, reason\n\n        content = decrypt_data(content)\n        if isinstance(content, memoryview):\n            content = content.tobytes()\n\n        content = utils.to_str(content)\n        try:\n            info = json.loads(content)\n        except Exception as e:\n            g.last_api_error = \"parse json fail\"\n            xlog.warn(\"api:%s parse json:%s fail:%r\", path, content, e)\n            return False, \"parse json fail\"\n\n        res = info[\"res\"]\n        if res != \"success\":\n            g.last_api_error = info[\"reason\"]\n            xlog.warn(\"api:%s fail:%s\", path, info[\"reason\"])\n            return False, info[\"reason\"]\n\n        xlog.info(\"api:%s success t:%d\", path, time_cost * 1000)\n        g.last_api_error = \"\"\n        return True, info\n    except Exception as e:\n        xlog.exception(\"order e:%r\", e)\n        g.last_api_error = \"%r\" % e\n        return False, \"except:%r\" % e\n\n\ncenter_login_process = False\n\n\ndef get_app_name():\n    app_info_file = os.path.join(root_path, os.path.pardir, \"app_info.json\")\n    try:\n        with open(app_info_file, \"r\") as fd:\n            dat = json.load(fd)\n        return dat[\"app_name\"]\n    except Exception as e:\n        xlog.exception(\"get version fail:%r\", e)\n    return \"XX-Net\"\n\n\ndef request_balance(account=None, password=None, is_register=False, update_server=True, promoter=\"\"):\n    global center_login_process\n    if not g.config.api_server:\n        g.server_host = str(\"%s:%d\" % (g.config.server_host, g.config.server_port))\n        xlog.info(\"not api_server set, use server:%s specify in config.\", g.server_host)\n        return True, \"success\"\n\n    if is_register:\n        login_path = \"/register\"\n        xlog.info(\"request_balance register:%s\", account)\n    else:\n        login_path = \"/login\"\n\n    if account is None:\n        if not (g.config.login_account and g.config.login_password):\n            xlog.debug(\"request_balance no account\")\n            return False, \"no default account\"\n\n        account = g.config.login_account\n        password = g.config.login_password\n\n    app_name = get_app_name()\n    req_info = {\n        \"account\": account,\n        \"password\": password,\n        \"protocol_version\": \"2\",\n        \"promoter\": promoter,\n        \"app_id\": app_name,\n        \"client_version\": g.xxnet_version,\n        \"sys_info\": g.system,\n    }\n\n    try:\n        center_login_process = True\n        if g.tls_relay_front:\n            g.tls_relay_front.set_x_tunnel_account(account, password)\n        if g.seley_front:\n            g.seley_front.set_x_tunnel_account(account, password)\n\n        res, info = call_api(login_path, req_info)\n        if not res:\n            return False, info\n\n        g.quota_list = info[\"quota_list\"]\n        g.quota = calculate_quota_left(g.quota_list)\n        g.paypal_button_id = info[\"paypal_button_id\"]\n        g.plans = info[\"plans\"]\n        if g.quota <= 0:\n            xlog.warn(\"no quota\")\n\n        if g.config.server_host:\n            xlog.info(\"use server:%s specify in config.\", g.config.server_host)\n            g.server_host = str(g.config.server_host)\n        elif update_server or not g.server_host:\n            g.server_host = str(info[\"host\"])\n            g.server_port = info[\"port\"]\n            xlog.info(\"update xt_server %s:%d\", g.server_host, g.server_port)\n\n        g.selectable = info[\"selectable\"]\n\n        if g.config.update_cloudflare_domains:\n            g.http_client.save_cloudflare_domain(info.get(\"cloudflare_domains\"))\n\n        g.promote_code = utils.to_str(info[\"promote_code\"])\n        g.promoter = info[\"promoter\"]\n        g.balance = info[\"balance\"]\n        g.openai_balance = info[\"openai_balance\"]\n        g.openai_proxies = info[\"openai_proxies\"]\n        g.tls_relays = info[\"tls_relays\"]\n        seleys = info.get(\"seleys\", {})\n        if g.tls_relay_front:\n            g.tls_relay_front.set_ips(g.tls_relays[\"ips\"])\n        if g.seley_front:\n            g.seley_front.set_hosts(seleys.get(\"hosts\", {}))\n        xlog.info(\"request_balance host:%s port:%d balance:%f quota:%f\", g.server_host, g.server_port,\n                  g.balance, g.quota)\n        return True, \"success\"\n    except Exception as e:\n        g.last_api_error = \"login center except: %r\" % e\n        xlog.exception(\"request_balance e:%r\", e)\n        return False, e\n    finally:\n        center_login_process = False\n\n\ndef jwt_login(account, password, node):\n    global center_login_process\n    g.server_host = str(\"%s:%d\" % (g.config.server_host, g.config.server_port))\n    xlog.info(\"not api_server set, use server:%s specify in config.\", g.server_host)\n    return True, \"success\"\n\n\nlogin_lock = threading.Lock()\n\n\ndef login_process():\n    if not g.session:\n        return\n\n    with login_lock:\n        if not (g.config.login_account and g.config.login_password):\n            xlog.debug(\"x-tunnel no account\")\n            return False\n\n        if not g.server_host:\n            xlog.debug(\"session not running, try login..\")\n            res, reason = request_balance(g.config.login_account, g.config.login_password)\n            if not res:\n                xlog.warn(\"x-tunnel request_balance fail when create_conn:%s\", reason)\n                return False\n\n        if time.time() - g.session.last_send_time > 5 * 60 - 5:\n            xlog.info(\"session timeout, reset it.\")\n            g.session.stop()\n\n        if g.tls_relay_front:\n            g.tls_relay_front.set_x_tunnel_account(g.config.login_account, g.config.login_password)\n        if g.seley_front:\n            g.seley_front.set_x_tunnel_account(g.config.login_account, g.config.login_password)\n\n        if not g.session.running:\n            return g.session.start()\n\n    return True\n\n\ndef create_conn(sock, host, port, log=False):\n    if not (g.config.login_account and g.config.login_password):\n        time.sleep(1)\n        return False\n\n    for _ in range(0, 3):\n        if login_process():\n            break\n        else:\n            time.sleep(1)\n\n    return g.session.create_conn(sock, host, port, log)\n\n\ndef update_quota_loop():\n    xlog.debug(\"update_quota_loop start.\")\n\n    start_time = time.time()\n    last_quota = g.quota\n    while g.running and time.time() - start_time < 10 * 60:\n        if not g.config.login_account:\n            xlog.info(\"update_quota_loop but logout.\")\n            return\n\n        request_balance(\n            g.config.login_account, g.config.login_password,\n            is_register=False, update_server=False)\n\n        if g.quota - last_quota > 1024 * 1024 * 1024:\n            xlog.info(\"update_quota_loop quota updated\")\n            return\n\n        time.sleep(60)\n\n    xlog.warn(\"update_quota_loop timeout fail.\")\n"
  },
  {
    "path": "code/default/x_tunnel/local/seley_front/__init__.py",
    "content": "\nfrom .front import front"
  },
  {
    "path": "code/default/x_tunnel/local/seley_front/config.py",
    "content": "\nfrom front_base.config import ConfigBase\n\n\nclass Config(ConfigBase):\n    def __init__(self, fn):\n        super(Config, self).__init__(fn)\n\n        # front\n        self.set_var(\"front_continue_fail_num\", 10)\n        self.set_var(\"front_continue_fail_block\", 60)\n        self.set_var(\"allow_set_hosts\", 1)\n\n        # http_dispatcher\n        self.set_var(\"dispather_work_min_idle_time\", 0)\n        self.set_var(\"dispather_work_max_score\", 1)\n        self.set_var(\"dispather_min_workers\", 20)\n        self.set_var(\"dispather_max_workers\", 60)\n        self.set_var(\"dispather_connect_all_workers_on_startup\", 1)\n        self.set_var(\"dispather_ping_check_speed_interval\", 50)\n\n        # http1\n        self.set_var(\"http1_first_ping_wait\", 50)\n        self.set_var(\"http1_ping_interval\", 57)\n        self.set_var(\"http1_idle_time\", 230)\n        self.set_var(\"http1_max_process_tasks\", 999999)\n        self.set_var(\"http2_max_process_tasks\", 999999)\n        self.set_var(\"http2_status_to_close\", [404])\n\n        # connect_manager\n        self.set_var(\"connection_pool_min\", 0)\n        self.set_var(\"max_links_per_ip\", 20)\n        self.set_var(\"connect_create_interval\", 0)\n\n        self.load()"
  },
  {
    "path": "code/default/x_tunnel/local/seley_front/connect_creator.py",
    "content": "import socket\nimport struct\nimport time\n\nimport socks\nimport utils\n\n\nfrom front_base.connect_creator import ConnectCreator as ConnectCreatorBase\nfrom . import rc4_wrap\n\n\nclass ConnectCreator(ConnectCreatorBase):\n\n    def connect_ssl(self, ip_str, sni, host, close_cb=None):\n        ip_str = utils.to_str(ip_str)\n\n        if self.debug:\n            self.logger.debug(\"connect ip:%s sni:%s host:%s\", ip_str, sni, host)\n\n        ip, port = utils.get_ip_port(ip_str)\n        if isinstance(ip, str):\n            ip = utils.to_bytes(ip)\n\n        if not utils.check_ip_valid(ip):\n            try:\n                info = socket.getaddrinfo(ip, port, socket.AF_UNSPEC,\n                                          socket.SOCK_STREAM)\n\n                af, socktype, proto, canonname, sa = info[0]\n                ip = utils.to_bytes(sa[0])\n                ip_str = b\"%s:%d\" % (ip, port)\n            except socket.gaierror:\n                pass\n\n        if int(self.config.PROXY_ENABLE):\n            sock = socks.socksocket(socket.AF_INET if b':' not in ip else socket.AF_INET6)\n        else:\n            sock = socket.socket(socket.AF_INET if b':' not in ip else socket.AF_INET6)\n\n        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)\n\n        # set struct linger{l_onoff=1,l_linger=0} to avoid 10048 socket error\n        # Close the connection with a TCP RST instead of a TCP FIN.\n        sock.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack('ii', 1, 0))\n\n        # resize socket receive buffer ->64 above to improve browser related application performance\n        sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, self.config.connect_receive_buffer)\n        sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, self.config.connect_send_buffer)\n        sock.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, True)\n        sock.settimeout(self.timeout)\n\n        time_begin = time.time()\n        ssl_sock = rc4_wrap.SSLConnection(sock,\n                                              ip_str=ip_str,\n                                              sni=sni,\n                                              on_close=close_cb)\n        ssl_sock.ip = ip\n        ssl_sock.sni = utils.to_str(sni)\n\n        time_connected = time.time()\n        try:\n            ssl_sock.do_handshake()\n        except Exception as e:\n            raise socket.error('tls handshake fail, sni:%s, ip_str:%s e:%r' % (sni, ip_str, e))\n\n        time_handshaked = time.time()\n\n        connect_time = int((time_connected - time_begin) * 1000)\n        handshake_time = int((time_handshaked - time_begin) * 1000)\n        if sock:\n            ssl_sock.fd = sock.fileno()\n        ssl_sock.create_time = time_begin\n        ssl_sock.connect_time = connect_time\n        ssl_sock.handshake_time = handshake_time\n        ssl_sock.last_use_time = time_handshaked\n        ssl_sock.host = host\n        ssl_sock.received_size = 0\n\n        if self.debug:\n            self.logger.debug(\"connect ip:%s sni:%s host:%s success\", ip_str, sni, host)\n\n        return ssl_sock\n\n    def check_cert(self, ssl_sock):\n        return\n"
  },
  {
    "path": "code/default/x_tunnel/local/seley_front/front.py",
    "content": "import os\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nroot_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir, os.pardir))\n\nimport env_info\nimport xlog\n\nfrom front_base.http_dispatcher import HttpsDispatcher\nfrom front_base.connect_manager import ConnectManager\nfrom gae_proxy.local import check_local_network\n\nfrom .config import Config\nfrom .connect_creator import ConnectCreator\n\ndata_path = env_info.data_path\nmodule_data_path = os.path.join(data_path, 'x_tunnel')\n\nlogger = xlog.getLogger(\"seley_front\", log_path=module_data_path, save_start_log=1500, save_warning_log=True)\nlogger.set_buffer(300)\n\nfrom .ip_manager import IpManager\n\n\nclass Front(object):\n    name = \"seley_front\"\n\n    def __init__(self):\n        self.running = False\n        self.account = \"\"\n        self.password = \"\"\n        self.logger = logger\n        config_path = os.path.join(module_data_path, \"seley_front.json\")\n        self.config = Config(config_path)\n\n    def start(self):\n        self.running = True\n        self.connect_creator = ConnectCreator(logger, self.config)\n\n        hosts_fn = os.path.join(module_data_path, \"seley_host.json\")\n        ip_speed_fn = os.path.join(module_data_path, \"seley_speed.json\")\n        self.ip_manager = IpManager(self.config, logger, hosts_fn, ip_speed_fn)\n\n        self.connect_manager = ConnectManager(logger, self.config, self.connect_creator, self.ip_manager,\n                                              check_local_network)\n        self.http_dispatcher = HttpsDispatcher(logger, self.config, self.ip_manager, self.connect_manager)\n\n    def set_x_tunnel_account(self, account, password):\n        self.account = account\n        self.password = password\n        self.http_dispatcher.account = account\n\n    def set_hosts(self, hosts):\n        if not self.config.allow_set_hosts:\n            return\n\n        self.ip_manager.set_hosts(hosts)\n        self.logger.debug(\"set_hosts:%s\", hosts)\n\n        self.http_dispatcher.start_connect_all_ips()\n\n    def get_dispatcher(self, host=None):\n        if len(self.ip_manager.hosts) == 0:\n            return None\n\n        return self.http_dispatcher\n\n    def request(self, method, host, path=\"/\", headers={}, data=\"\", timeout=120):\n        headers = dict(headers)\n        headers[\"XX-Account\"] = self.account\n        headers[\"X-Host\"] = host\n        headers[\"X-Path\"] = path\n\n        response = self.http_dispatcher.request(method, host, \"/\", dict(headers), data, timeout=timeout)\n        if not response:\n            logger.warn(\"req %s get response timeout\", path)\n            return \"\", 602, {}\n\n        status = response.status\n        content = response.task.read_all()\n        if status == 200:\n            logger.debug(\"%s %s%s send:%d recv:%d trace:%s\", method, host, path, len(data), len(content),\n                       response.task.get_trace())\n        else:\n            logger.warn(\"%s %s%s status:%d trace:%s\", method, host, path, status,\n                       response.task.get_trace())\n        return content, status, response\n\n    def stop(self):\n        logger.info(\"terminate\")\n        self.connect_manager.set_ssl_created_cb(None)\n        self.http_dispatcher.stop()\n        self.connect_manager.stop()\n\n        self.running = False\n\n    def set_proxy(self, args):\n        logger.info(\"set_proxy:%s\", args)\n\n        self.config.PROXY_ENABLE = args[\"enable\"]\n        self.config.PROXY_TYPE = args[\"type\"]\n        self.config.PROXY_HOST = args[\"host\"]\n        self.config.PROXY_PORT = args[\"port\"]\n        self.config.PROXY_USER = args[\"user\"]\n        self.config.PROXY_PASSWD = args[\"passwd\"]\n\n        self.config.save()\n\n        self.connect_creator.update_config()\n\n\nfront = Front()\n"
  },
  {
    "path": "code/default/x_tunnel/local/seley_front/front_domains.json",
    "content": "{\n}"
  },
  {
    "path": "code/default/x_tunnel/local/seley_front/ip_manager.py",
    "content": "import time\nimport os\nimport json\nimport socket\nimport threading\n\nfrom front_base.ip_manager import IpManagerBase\nimport utils\nfrom xlog import getLogger\nxlog = getLogger(\"seley_front\")\n\n\nclass IpManager(IpManagerBase):\n    def __init__(self, config, logger, config_fn, speed_fn):\n        super().__init__(config, None, logger, speed_fn)\n        self.config_fn = config_fn\n        self.hosts = {}\n        self.ip_dict = {}\n        self.load()\n\n    def __str__(self):\n        o = super().__str__()\n        o += \" seley_host: \\r\\n%s\\r\\n\" % json.dumps(self.hosts, indent=2)\n        o += \" seley_dict: \\r\\n%s\\r\\n\" % json.dumps(self.ip_dict, indent=2)\n        return o\n\n    def set_hosts(self, hosts):\n        try:\n            with open(self.config_fn, \"w\") as fd:\n                json.dump(hosts, fd, indent=2)\n\n            self.load()\n        except Exception as e:\n            xlog.error(\"save hosts %s e:%r\", self.config_fn, e)\n\n    def load(self):\n        if not os.path.isfile(self.config_fn):\n            return\n\n        try:\n            with open(self.config_fn, \"r\") as fd:\n                domain_hosts = json.load(fd)\n        except Exception as e:\n            xlog.warn(\"load hosts %s e:%r\", self.config_fn, e)\n            return\n\n        self.hosts = domain_hosts\n\n    def _get_ip_dict(self, host_port):\n        host_port = utils.to_str(host_port)\n\n        host, port = utils.get_ip_port(host_port)\n        ip = None\n        if not utils.check_ip_valid(host):\n            try:\n                info = socket.getaddrinfo(host, port, socket.AF_UNSPEC,\n                                          socket.SOCK_STREAM)\n\n                for af, socktype, proto, canonname, sa in info:\n                    ip = sa[0]\n            except socket.gaierror:\n                return None\n        else:\n            ip = host\n\n        if not ip:\n            return None\n\n        ip_str = utils.get_ip_str(ip, port)\n\n        self.ip_dict.setdefault(ip_str, {\n            \"ip_str\": ip_str,\n            \"host_port\": host_port,\n            \"fail_times\": 0,\n            \"links\": 0,\n            \"rtt\": 1000,\n            \"last_try\": 0.0\n        })\n        return self.ip_dict[ip_str]\n\n    def _get_ip_sni_host(self, force=False):\n        now = time.time()\n\n        best_dict = None\n        best_score = 99\n\n        for host_port, params in self.hosts.items():\n            if not params.get(\"key\") or host_port.startswith(\"_\"):\n                continue\n\n            ip_dict = self._get_ip_dict(host_port)\n            if not ip_dict:\n                continue\n\n            ip_str = ip_dict[\"ip_str\"]\n            if ip_dict[\"links\"] < 0:\n                # self.logger.error(\"ip %s link:%d\", ip, info[\"links\"])\n                ip_dict[\"links\"] = 0\n\n            if ip_dict[\"links\"] >= self.config.max_links_per_ip:\n                continue\n\n            if ip_dict[\"fail_times\"]:\n                last_try = now - ip_dict[\"last_try\"]\n                if last_try < 5 or (not force and last_try < 60):\n                    continue\n                else:\n                    best_dict = ip_dict\n                    # xlog.debug(\"get_ip_sni_host last_try %s\", ip_str)\n                    break\n\n            score = self.get_score(ip_str)\n            if score < best_score:\n                best_score = score\n                best_dict = ip_dict\n                # xlog.debug(\"get_ip_sni_host best speed %s\", ip_str)\n\n        return best_dict\n\n    def get_ip_sni_host(self):\n        if not self.hosts:\n            return None\n\n        best_dict = self._get_ip_sni_host()\n        if not best_dict:\n            # try again, incase the network is disconnected\n            best_dict = self._get_ip_sni_host(force=True)\n\n        if not best_dict:\n            time.sleep(1)\n            return None\n\n        ip_str = best_dict[\"ip_str\"]\n        host_port = best_dict[\"host_port\"]\n        best_params = self.hosts[host_port]\n\n        best_dict[\"links\"] += 1\n        best_dict[\"last_try\"] = time.time()\n\n        return {\n            \"ip_str\": ip_str,\n            \"sni\": best_params[\"key\"],\n            \"host\": ip_str,\n            \"adjust\": best_params.get(\"adjust\", 0),\n        }\n\n    def update_ip(self, ip_str, sni, handshake_time):\n        info = self._get_ip_dict(ip_str)\n        info[\"fail_times\"] = 0\n        info[\"rtt\"] = handshake_time\n        # self.logger.debug(\"ip %s connect success\", ip)\n\n    def report_connect_fail(self, ip_str, sni=None, reason=\"\", force_remove=False):\n        info = self._get_ip_dict(ip_str)\n        info[\"fail_times\"] += 1\n        info[\"links\"] -= 1\n        self.logger.debug(\"ip %s connect fail:%s\", ip_str, reason)\n\n    def report_connect_closed(self, ip_str, sni=None, reason=\"\"):\n        info = self._get_ip_dict(ip_str)\n        info[\"links\"] -= 1\n        self.logger.debug(\"%s report_connect_closed:%s\", ip_str, reason)\n\n    def recheck_ip(self, ip_str):\n        pass\n"
  },
  {
    "path": "code/default/x_tunnel/local/seley_front/rc4_wrap.py",
    "content": "import socket\nimport time\nimport struct\nimport json\nimport os\nimport errno\n\nimport env_info\nimport xlog\ndata_path = env_info.data_path\nmodule_data_path = os.path.join(data_path, 'x_tunnel')\n\nlogger = xlog.getLogger(\"seley_front\", log_path=module_data_path, save_start_log=1500, save_warning_log=True)\nlogger.set_buffer(300)\n\ntry:\n    from py_aes_cfb import lib as aes\n    logger.debug(\"load py_aes_cfb success\")\nexcept Exception as e:\n    aes = None\n\n    try:\n        from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes\n        logger.debug(\"load cryptography success\")\n    except:\n        logger.warn(\"load cryptography failed:%r\", e)\n        algorithms = None\n\n\nimport utils\n\n\nclass SSLConnection(object):\n    def __init__(self, sock, ip_str=None, sni=None, on_close=None):\n        self._sock = sock\n        self.ip_str = ip_str\n        self.sni = utils.to_bytes(sni)\n        self._makefile_refs = 0\n        self._on_close = on_close\n        self.peer_cert = None\n        self.socket_closed = False\n        self.timeout = self._sock.gettimeout() or 0.1\n        self.running = True\n        self.h2 = False\n\n        if not aes and not algorithms:\n            raise socket.error('no cryptography')\n\n        key = self.sni\n        iv = b'\\x00' * 16\n        if aes:\n            self.encryptor = aes.encryptor_create(key, len(key), iv, len(iv))\n            self.decryptor = aes.decryptor_create(key, len(key), iv, len(iv))\n        else:\n            algorithm = algorithms.AES(key)\n            self.cipher = Cipher(algorithm, mode=modes.CFB(iv))\n            self.decryptor = self.cipher.decryptor()\n            self.encryptor = self.cipher.encryptor()\n        self.wrap()\n\n    def encode(self, input):\n        if aes:\n            out = bytes(input)\n            aes.encryptor_update(self.encryptor, input, len(input), out)\n            return out\n        else:\n            return self.encryptor.update(input)\n\n    def decode(self, input):\n        if aes:\n            out = bytes(input)\n            aes.decryptor_update(self.decryptor, input, len(input), out)\n            return out\n        else:\n            return self.decryptor.update(input)\n\n    def wrap(self):\n        ip, port = utils.get_ip_port(self.ip_str)\n        if isinstance(ip, str):\n            ip = utils.to_bytes(ip)\n\n        try:\n            self._sock.connect((ip, port))\n        except Exception as e:\n            raise socket.error('conn %s fail, sni:%s, e:%r' % (self.ip_str, self.sni, e))\n\n    def do_handshake(self):\n        magic = b\"SE\"\n        info = {\n            \"ts\": time.time()\n        }\n        data = json.dumps(info)\n        data_len = len(data)\n        dat = magic + struct.pack(\"I\", data_len) + utils.to_bytes(data)\n        dat = self.encode(dat)\n        sended = self._sock.send(dat)\n\n        res = self._sock.recv(6)\n        res = self.decode(res)\n        if res[0:2] != b\"SE\":\n            raise Exception(\"handshake failed\")\n\n        data_len = struct.unpack(\"I\", res[2:])[0]\n        res = self._sock.recv(data_len)\n        res = self.decode(res)\n        info = json.loads(res)\n\n    def is_support_h2(self):\n        return False\n\n    def setblocking(self, block):\n        self._sock.setblocking(block)\n\n    def getsockname(self):\n        self._sock.getsockname()\n\n    def __getattr__(self, attr):\n        if attr == \"socket_closed\":\n            # work around in case close before finished init.\n            return True\n\n        # '_connection',\n        elif attr in ('is_support_h2', \"_on_close\", '_context', '_sock', '_makefile_refs',\n                      'sni', 'wrap', 'socket_closed', 'cipher', 'decryptor', 'encryptor'):\n            return getattr(self, attr)\n\n    def __del__(self):\n        if not self.socket_closed:\n            self.socket_closed = True\n            if self._on_close:\n                self._on_close(self.ip_str, self.sni)\n\n        if aes:\n            aes.encryptor_destroy(self.encryptor)\n            aes.decryptor_destroy(self.decryptor)\n\n    def get_cert(self):\n        self.peer_cert = {\n            \"cert\": \"\",\n            \"issuer_commonname\": \"\",\n            \"commonName\": \"\",\n            \"altName\": \"\"\n        }\n        return self.peer_cert\n\n    def connect(self, *args, **kwargs):\n        return\n\n    def send(self, data, flags=0):\n        data = self.encode(data)\n        while True:\n            try:\n                bytes_sent = self._sock.send(data)\n                return bytes_sent\n            except BlockingIOError as e:\n                time.sleep(0.1)\n                continue\n            except socket.error as e:\n                if e.errno == errno.EAGAIN:\n                    # if str(e) == \"[Errno 35] Resource temporarily unavailable\":\n                    time.sleep(0.1)\n                else:\n                    raise e\n\n    def recv(self, bufsiz, flags=0):\n        data = self._sock.recv(bufsiz)\n        data = self.decode(data)\n        return data\n\n    def recv_into(self, buf, nbytes=None):\n        if not nbytes:\n            nbytes = len(buf)\n\n        data = self._connection.read(nbytes)\n        if not data:\n            return None\n\n        data = self.decode(data)\n        buf[:len(data)] = data\n        return len(data)\n\n    def read(self, bufsiz, flags=0):\n        return self.recv(bufsiz, flags)\n\n    def write(self, buf, flags=0):\n        return self.sendall(buf, flags)\n\n    def close(self, reason=\"\"):\n        if self._makefile_refs < 1:\n            self.running = False\n            if not self.socket_closed:\n                socket.socket.close(self._sock)\n                self.socket_closed = True\n                if self._on_close:\n                    self._on_close(self.ip_str, self.sni, reason=reason)\n        else:\n            self._makefile_refs -= 1\n\n    def settimeout(self, t):\n        if not self.running:\n            return\n\n        if self.timeout != t:\n            self._sock.settimeout(t)\n            self.timeout = t\n\n    def makefile(self, mode='r', bufsize=-1):\n        self._makefile_refs += 1\n        return socket._fileobject(self, mode, bufsize, close=True)\n\n    def fileno(self):\n        return self._sock.fileno()\n"
  },
  {
    "path": "code/default/x_tunnel/local/seley_front/test.py",
    "content": "#!/usr/bin/env python2\n# coding:utf-8\n\nimport os\nimport sys\nimport time\nimport threading\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nroot_path = os.path.abspath( os.path.join(current_path, os.pardir, os.pardir, os.pardir))\npython_path = root_path\n\nsys.path.append(root_path)\n\nnoarch_lib = os.path.abspath( os.path.join(python_path, 'lib', 'noarch'))\nsys.path.append(noarch_lib)\n\nif sys.platform == \"win32\":\n    win32_lib = os.path.abspath( os.path.join(python_path, 'lib', 'win32'))\n    sys.path.append(win32_lib)\nelif sys.platform.startswith(\"linux\"):\n    linux_lib = os.path.abspath( os.path.join(python_path, 'lib', 'linux'))\n    sys.path.append(linux_lib)\nelif sys.platform == \"darwin\":\n    darwin_lib = os.path.abspath( os.path.join(python_path, 'lib', 'darwin'))\n    sys.path.append(darwin_lib)\n    extra_lib = \"/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python\"\n    sys.path.append(extra_lib)\n\n\nimport env_info\nfrom .front import front\nfrom xlog import getLogger\nxlog = getLogger(\"heroku_front\")\nxlog.set_buffer(2000)\n\ndata_path = env_info.data_path\nmodule_data_path = os.path.join(data_path, 'x_tunnel')\n\n\ndef get():\n    start_time = time.time()\n    content, status, response = front.request(\"GET\", \"dns.xx-net.org\", path=\"/query?domain=www.google.com\")\n    time_cost = time.time() - start_time\n    xlog.info(\"GET cost:%f\", time_cost)\n    xlog.info(\"status:%d content:%s\", status, content.tobytes())\n    front.stop()\n\n\nif __name__ == '__main__':\n    import traceback\n\n    try:\n        get()\n    except Exception:\n        traceback.print_exc(file=sys.stdout)\n    except KeyboardInterrupt:\n        front.stop()\n        sys.exit()\n"
  },
  {
    "path": "code/default/x_tunnel/local/seley_front/web_control.py",
    "content": "#!/usr/bin/env python\n# coding:utf-8\n\n\nimport os\nimport time\n\ntry:\n    from urllib.parse import urlparse, parse_qs\nexcept ImportError:\n    from urlparse import urlparse, parse_qs\n\n\nimport simple_http_server\nfrom .front import front\n\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nroot_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))\ntop_path = os.path.abspath(os.path.join(root_path, os.pardir, os.pardir, os.pardir))\nweb_ui_path = os.path.join(current_path, os.path.pardir, \"web_ui\")\n\n\nclass ControlHandler(simple_http_server.HttpServerHandler):\n    def __init__(self, client_address, headers, command, path, rfile, wfile):\n        self.client_address = client_address\n        self.headers = headers\n        self.command = command\n        self.path = path\n        self.rfile = rfile\n        self.wfile = wfile\n\n    def do_GET(self):\n        path = urlparse(self.path).path\n        if path == \"/log\":\n            return self.req_log_handler()\n        elif path == \"/debug\":\n            return self.req_debug_handler()\n        else:\n            front.logger.warn('Control Req %s %s %s ', self.address_string(), self.command, self.path)\n\n        self.wfile.write(b'HTTP/1.1 404\\r\\nContent-Type: text/plain\\r\\nConnection: close\\r\\n\\r\\n404 Not Found')\n        front.logger.info('%s \"%s %s HTTP/1.1\" 404 -', self.address_string(), self.command, self.path)\n\n    def req_log_handler(self):\n        req = urlparse(self.path).query\n        reqs = parse_qs(req, keep_blank_values=True)\n        data = ''\n\n        cmd = \"get_last\"\n        if reqs[\"cmd\"]:\n            cmd = reqs[\"cmd\"][0]\n\n        if cmd == \"get_last\":\n            max_line = int(reqs[\"max_line\"][0])\n            data = front.logger.get_last_lines(max_line)\n        elif cmd == \"get_new\":\n            last_no = int(reqs[\"last_no\"][0])\n            data = front.logger.get_new_lines(last_no)\n        else:\n            front.logger.error('PAC %s %s %s ', self.address_string(), self.command, self.path)\n\n        mimetype = 'text/plain'\n        self.send_response_nc(mimetype, data)\n\n    def req_debug_handler(self):\n        if not front.running:\n            return self.send_response_nc('text/plain', \"Not running\")\n\n        data = \"\"\n        for obj in [front.connect_manager, front.http_dispatcher]:\n            data += \"%s\\r\\n\" % obj.__class__\n            for attr in dir(obj):\n                if attr.startswith(\"__\"):\n                    continue\n                sub_obj = getattr(obj, attr)\n                if callable(sub_obj):\n                    continue\n\n                if isinstance(sub_obj, list):\n                    data += \"    %s:[%d]\\r\\n\" % (attr, len(sub_obj))\n                    for item in sub_obj:\n                        data += \"      %s\\r\\n\" % item\n                    data += \"\\r\\n\"\n                elif hasattr(sub_obj, \"to_string\"):\n                    data += \"    %s:\\r\\n\" % (attr)\n                    data += sub_obj.to_string()\n                else:\n                    data += \"    %s = %s\\r\\n\" % (attr, sub_obj)\n            if hasattr(obj, \"to_string\"):\n                data += obj.to_string()\n\n        mimetype = 'text/plain'\n        self.send_response_nc(mimetype, data)"
  },
  {
    "path": "code/default/x_tunnel/local/tls_relay_front/__init__.py",
    "content": "\nfrom .front import front"
  },
  {
    "path": "code/default/x_tunnel/local/tls_relay_front/check_ip.py",
    "content": "#!/usr/bin/env python\n# coding:utf-8\n\nimport sys\nimport os\n\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nroot_path = os.path.abspath( os.path.join(current_path, os.pardir, os.pardir, os.pardir))\npython_path = root_path\n\nsys.path.append(root_path)\n\nnoarch_lib = os.path.abspath( os.path.join(python_path, 'lib', 'noarch'))\nsys.path.append(noarch_lib)\n\nif sys.platform == \"win32\":\n    win32_lib = os.path.abspath( os.path.join(python_path, 'lib', 'win32'))\n    sys.path.append(win32_lib)\nelif sys.platform.startswith(\"linux\"):\n    linux_lib = os.path.abspath( os.path.join(python_path, 'lib', 'linux'))\n    sys.path.append(linux_lib)\nelif sys.platform == \"darwin\":\n    darwin_lib = os.path.abspath( os.path.join(python_path, 'lib', 'darwin'))\n    sys.path.append(darwin_lib)\n    extra_lib = \"/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python\"\n    sys.path.append(extra_lib)\n\n\nimport env_info\nimport xlog\nlogger = xlog.getLogger(\"tls_relay\")\nlogger.set_buffer(500)\n\nfrom front_base.openssl_wrap import SSLContext\nfrom front_base.connect_creator import ConnectCreator\nfrom front_base.check_ip import CheckIp\n\nfrom x_tunnel.local.tls_relay_front.config import Config\nfrom x_tunnel.local.tls_relay_front.host_manager import HostManager\n\ndata_path = env_info.data_path\nmodule_data_path = os.path.join(data_path, 'x_tunnel')\n\n\nif __name__ == \"__main__\":\n    # case 1: only ip\n    # case 2: ip + domain\n    #    connect use domain\n    # case 3: ip domain path\n\n    wait_time = 0\n    ip = \"127.0.0.1:60000\"\n    top_domain = \"agentnobody.pics\"\n    path = \"/\"\n    headers = {\n        \"xx-account\": \"test@xx-net.com\",\n        \"X-Host\": \"scan1.xx-net.org\",\n        \"X-Path\": \"/\"\n    }\n\n    if len(sys.argv) > 1:\n        ip = sys.argv[1]\n        if len(sys.argv) > 2:\n            top_domain = sys.argv[2]\n            if len(sys.argv) > 3:\n                path += sys.argv[3]\n    else:\n        print(\"Usage: check_ip.py [ip] [top_domain] [wait_time=0]\")\n\n    print((\"test ip:%s\" % ip))\n    print(\"sni: %s\" % top_domain)\n    print(\"path: %s\" % path)\n\n    config_path = os.path.join(module_data_path, \"tls_relay.json\")\n    config = Config(config_path)\n\n    openssl_context = SSLContext(logger)\n\n    host_fn = os.path.join(module_data_path, \"tls_host.json\")\n    host_manager = HostManager(host_fn)\n    connect_creator = ConnectCreator(logger, config, openssl_context, host_manager)\n    check_ip = CheckIp(logger, config, connect_creator)\n\n    res = check_ip.check_ip(ip, sni=top_domain, host=top_domain, wait_time=wait_time, path=path, headers=headers)\n    if not res:\n        print(\"connect fail\")\n    elif res.ok:\n        print((\"Check success, domain:%s handshake:%d\" % (res.host, res.handshake_time)))\n    else:\n        print(\"not support\")\n\n    sys.exit(0)\n"
  },
  {
    "path": "code/default/x_tunnel/local/tls_relay_front/config.py",
    "content": "\nfrom front_base.config import ConfigBase\n\n\nclass Config(ConfigBase):\n    def __init__(self, fn):\n        super(Config, self).__init__(fn)\n\n        # front\n        self.set_var(\"front_continue_fail_num\", 10)\n        self.set_var(\"front_continue_fail_block\", 10)\n        self.set_var(\"allow_set_ips\", 1)\n\n        # https_dispatcher\n        self.set_var(\"dispather_min_idle_workers\", 0)\n        self.set_var(\"dispather_work_max_score\", 1)\n        self.set_var(\"dispather_min_workers\", 1)\n        self.set_var(\"dispather_max_workers\", 60)\n        self.set_var(\"dispather_connect_all_workers_on_startup\", 1)\n\n        # connect_manager\n        self.set_var(\"https_connection_pool_min\", 0)\n        self.set_var(\"max_links_per_ip\", 1)\n        self.set_var(\"https_connection_pool_max\", 20)\n        self.set_var(\"connect_create_interval\", 0)\n\n        # connect_creator\n        self.set_var(\"connect_force_http2\", 1)\n\n        # http 2 worker\n        self.set_var(\"http2_status_to_close\", [400, 404, 500])\n        self.set_var(\"http2_idle_ping_min_interval\", 110)\n        self.set_var(\"http2_max_process_tasks\", 9900)\n\n        self.load()\n"
  },
  {
    "path": "code/default/x_tunnel/local/tls_relay_front/connect_creator.py",
    "content": "import os\nimport socket\nimport struct\nimport time\n\nimport socks\nimport utils\nimport front_base.openssl_wrap\n\n\nfrom front_base.connect_creator import ConnectCreator as ConnectCreatorBase\n\n\nclass ConnectCreator(ConnectCreatorBase):\n\n    def connect_ssl(self, ip_str, sni, host, close_cb=None):\n        info = self.host_manager.get_info(ip_str)\n        sni = str(info[\"sni\"])\n        url_path = info[\"url_path\"]\n        host = sni\n        ip, port = utils.get_ip_port(ip_str)\n\n        if int(self.config.PROXY_ENABLE):\n            sock = socks.socksocket(socket.AF_INET if b':' not in ip else socket.AF_INET6)\n        else:\n            sock = socket.socket(socket.AF_INET if b':' not in ip else socket.AF_INET6)\n        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)\n        # set struct linger{l_onoff=1,l_linger=0} to avoid 10048 socket error\n        sock.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack('ii', 1, 0))\n        # resize socket recv buffer ->64 above to improve browser releated application performance\n        sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, self.config.connect_receive_buffer)\n        sock.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, True)\n        sock.settimeout(self.timeout)\n\n        time_begin = time.time()\n        if info.get(\"client_ca\"):\n            self.openssl_context.context.load_cert_chain(os.path.abspath(info[\"client_ca_fn\"]),\n                                                         os.path.abspath(info[\"client_key_fn\"]))\n\n        ssl_sock = front_base.openssl_wrap.SSLConnection(self.openssl_context.context, sock,\n                                                         ip_str=ip_str,\n                                                         sni=sni,\n                                                         on_close=close_cb)\n        time_connected = time.time()\n        try:\n            ssl_sock.do_handshake()\n        except Exception as e:\n            raise socket.error('tls handshake fail, sni:%s, top:%s e:%r' % (sni, host, e))\n\n        if ssl_sock.is_support_h2():\n            ssl_sock.h2 = True\n        else:\n            ssl_sock.h2 = False\n\n        time_handshaked = time.time()\n\n        ssl_sock.sni = sni\n        ssl_sock.url_path = utils.to_bytes(url_path)\n        self.check_cert(ssl_sock)\n\n        connect_time = int((time_connected - time_begin) * 1000)\n        handshake_time = int((time_handshaked - time_begin) * 1000)\n        # sometimes, we want to use raw tcp socket directly(select/epoll), so setattr it to ssl socket.\n        ssl_sock.ip_str = ip_str\n        ssl_sock._sock = sock\n        ssl_sock.fd = sock.fileno()\n        ssl_sock.create_time = time_begin\n        ssl_sock.connect_time = connect_time\n        ssl_sock.handshake_time = handshake_time\n        ssl_sock.last_use_time = time_handshaked\n        ssl_sock.host = host\n        ssl_sock.received_size = 0\n\n        return ssl_sock\n"
  },
  {
    "path": "code/default/x_tunnel/local/tls_relay_front/front.py",
    "content": "import os\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nroot_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir, os.pardir))\n\nimport xlog\nimport env_info\n\nfrom .config import Config\nfrom . import host_manager\nfrom . import connect_creator\nfrom . import ip_manager\nfrom front_base.openssl_wrap import SSLContext\nfrom front_base.http_dispatcher import HttpsDispatcher\nfrom front_base.connect_manager import ConnectManager\nfrom gae_proxy.local import check_local_network\nfrom . import http2_stream\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\ndata_path = env_info.data_path\nmodule_data_path = os.path.join(data_path, 'x_tunnel')\n\nlogger = xlog.getLogger(\"tls_relay\", log_path=module_data_path, save_start_log=1500, save_warning_log=True)\nlogger.set_buffer(100)\n\n\nclass Front(object):\n    name = \"tls_relay_front\"\n\n    def __init__(self):\n        self.running = False\n        self.logger = logger\n        config_path = os.path.join(module_data_path, \"tls_relay.json\")\n        self.config = Config(config_path)\n\n    def start(self):\n        self.running = True\n\n        self.openssl_context = SSLContext(logger)\n\n        if not os.path.isdir(module_data_path):\n            os.mkdir(module_data_path)\n\n        host_fn = os.path.join(module_data_path, \"relay_host.json\")\n        self.host_manager = host_manager.HostManager(host_fn)\n\n        self.connect_creator = connect_creator.ConnectCreator(logger, self.config, self.openssl_context, self.host_manager)\n\n        ip_speed_fn = os.path.join(module_data_path, \"relay_speed.json\")\n        self.ip_manager = ip_manager.IpManager(self.config, self.host_manager, logger, ip_speed_fn)\n        self.connect_manager = ConnectManager(logger, self.config, self.connect_creator, self.ip_manager, check_local_network)\n        self.http_dispatcher = HttpsDispatcher(logger, self.config, self.ip_manager, self.connect_manager,\n                                               http2stream_class=http2_stream.Stream)\n\n        self.account = \"\"\n        self.password = \"\"\n\n    def get_dispatcher(self, host=None):\n        return self.http_dispatcher\n\n    def set_x_tunnel_account(self, account, password):\n        self.account = account\n        self.password = password\n        self.http_dispatcher.account = account\n\n    def set_ips(self, ips):\n        if not self.config.allow_set_ips:\n            return\n\n        host_info = {}\n        for ip_str in ips:\n            dat = ips[ip_str]\n            sni = dat[\"sni\"]\n            url_path = dat[\"url_path\"]\n            port = dat.get(\"port\", 443)\n\n            host_info[ip_str] = {\n                \"sni\":sni,\n                \"url_path\": url_path,\n                \"port\": port,\n            }\n\n            ipv6 = dat[\"ipv6\"]\n            if ipv6:\n                host_info[ipv6] = {\n                    \"sni\": sni,\n                    \"url_path\": url_path,\n                    \"port\": port,\n                }\n\n        self.host_manager.set_host(host_info)\n        self.logger.debug(\"set_ips:%s\", ips)\n\n        self.http_dispatcher.start_connect_all_ips()\n\n    def request(self, method, host, path=\"/\", headers={}, data=\"\", timeout=120):\n        headers = dict(headers)\n        if self.account:\n            headers[\"XX-Account\"] = self.account\n        headers[\"X-Path\"] = path\n\n        response = self.http_dispatcher.request(method, host, path, dict(headers), data, timeout=timeout)\n        if not response:\n            logger.warn(\"req %s get response timeout\", path)\n            return \"\", 602, {}\n\n        status = response.status\n\n        content = response.task.read_all()\n        if status == 200:\n            logger.debug(\"%s %s%s send:%d recv:%d trace:%s\", method, host, path, len(data), len(content),\n                       response.task.get_trace())\n        else:\n            logger.warn(\"%s %s%s status:%d trace:%s\", method, host, path, status,\n                       response.task.get_trace())\n        return content, status, response\n\n    def stop(self):\n        logger.info(\"terminate\")\n        self.connect_manager.set_ssl_created_cb(None)\n        self.http_dispatcher.stop()\n        self.connect_manager.stop()\n\n        self.running = False\n\n    def set_proxy(self, args):\n        logger.info(\"set_proxy:%s\", args)\n\n        self.config.PROXY_ENABLE = args[\"enable\"]\n        self.config.PROXY_TYPE = args[\"type\"]\n        self.config.PROXY_HOST = args[\"host\"]\n        self.config.PROXY_PORT = args[\"port\"]\n        self.config.PROXY_USER = args[\"user\"]\n        self.config.PROXY_PASSWD = args[\"passwd\"]\n\n        self.config.save()\n\n        self.connect_creator.update_config()\n\n\nfront = Front()\n"
  },
  {
    "path": "code/default/x_tunnel/local/tls_relay_front/host_manager.py",
    "content": "import os\nimport json\n\nimport utils\nfrom front_base.host_manager import HostManagerBase\n\n\nclass HostManager(HostManagerBase):\n    def __init__(self, config_fn):\n        self.config_fn = config_fn\n        self.info = {}\n        self.load()\n\n    def load(self):\n        if not os.path.isfile(self.config_fn):\n            return\n\n        try:\n            with open(self.config_fn, \"r\") as fd:\n                self.info = json.load(fd)\n        except:\n            pass\n\n    def save(self):\n        with open(self.config_fn, \"w\") as fd:\n            json.dump(self.info, fd, indent=2)\n\n    def set_host(self, info):\n        self.info = info\n        self.save()\n\n    @property\n    def ips(self):\n        ips = list(self.info.keys())\n        return ips\n\n    def get_sni_host(self, ip):\n        if ip not in self.info:\n            return \"\", \"\"\n\n        return self.info[ip][\"sni\"], \"\"\n\n    def get_info(self, ip_str):\n        ip, _ = utils.get_ip_port(ip_str)\n        ip = utils.to_str(ip)\n        if ip not in self.info:\n            raise Exception\n\n        info = self.info[ip]\n\n        return info\n\n    def reset(self):\n        self.info = {}\n"
  },
  {
    "path": "code/default/x_tunnel/local/tls_relay_front/http2_stream.py",
    "content": "\n\nfrom front_base.http2_stream import Stream as StreamBase\nfrom front_base.http2_stream import STATE_OPEN\n\nfrom hyper.packages.hyperframe.frame import (\n    FRAME_MAX_LEN, HeadersFrame\n)\nfrom hyper.common.util import to_native_string\n\n\nclass Stream(StreamBase):\n\n    def start_request(self):\n        \"\"\"\n        Open the stream. Does this by encoding and sending the headers: no more\n        calls to ``add_header`` are allowed after this method is called.\n        The `end` flag controls whether this will be the end of the stream, or\n        whether data will follow.\n        \"\"\"\n        # Strip any headers invalid in H2.\n\n        # Use the sni as host\n        host = self.connection.ssl_sock.host\n\n        # build the path\n        path = self.connection.ssl_sock.url_path + self.task.path\n\n        self.add_header(\":method\", self.task.method)\n        self.add_header(\":scheme\", \"https\")\n        self.add_header(\":authority\", host)\n        self.add_header(\":path\", path)\n\n        default_headers = (':method', ':scheme', ':authority', ':path')\n\n        for name, value in list(self.task.headers.items()):\n            is_default = to_native_string(name) in default_headers\n            self.add_header(name, value, replace=is_default)\n\n        # set the target host in header\n        self.add_header(b\"X-Host\", self.task.host, replace=False)\n\n        # Encode the headers.\n        encoded_headers = self._encoder(self.request_headers)\n\n        # It's possible that there is a substantial amount of data here. The\n        # data needs to go into one HEADERS frame, followed by a number of\n        # CONTINUATION frames. For now, for ease of implementation, let's just\n        # assume that's never going to happen (16kB of headers is lots!).\n        # Additionally, since this is so unlikely, there's no point writing a\n        # test for this: it's just so simple.\n        if len(encoded_headers) > FRAME_MAX_LEN:  # pragma: no cover\n            raise ValueError(\"Header block too large.\")\n\n        header_frame = HeadersFrame(self.stream_id)\n        header_frame.data = encoded_headers\n\n        # If no data has been provided, this is the end of the stream. Either\n        # way, due to the restriction above it's definitely the end of the\n        # headers.\n        header_frame.flags.add('END_HEADERS')\n        if self.request_body_left == 0:\n            header_frame.flags.add('END_STREAM')\n\n        # Send the header frame.\n        self.task.set_state(\"start send header\")\n        self._send_cb(header_frame)\n\n        # Transition the stream state appropriately.\n        self.state = STATE_OPEN\n\n        self.task.set_state(\"start send left body\")\n        if self.request_body_left > 0:\n            self.send_left_body()\n"
  },
  {
    "path": "code/default/x_tunnel/local/tls_relay_front/ip_manager.py",
    "content": "import time\nimport json\n\nimport utils\nfrom front_base.ip_manager import IpManagerBase\n\n\nclass IpManager(IpManagerBase):\n    def __init__(self, config, host_manager, logger, speed_fn):\n        super(IpManager, self).__init__(config, None, logger, speed_fn)\n        self.host_manager = host_manager\n        self.ip_dict = {}\n\n    def __str__(self):\n        o = \"\"\n        o += \" ip_dict: \\r\\n%s\\r\\n\" % json.dumps(self.ip_dict, indent=2)\n        return o\n\n    def _get_ip_info(self, ip):\n        self.ip_dict.setdefault(ip, {\n            \"ip\": ip,\n            \"fail_times\": 0,\n            \"links\": 0,\n            \"rtt\": 1000,\n            \"last_try\": 0.0\n        })\n        return self.ip_dict[ip]\n\n    def get_ip_sni_host(self):\n        now = time.time()\n\n        best_info = None\n        best_speed = 0\n\n        for ip, ip_info in self.host_manager.info.items():\n            if \"sni\" not in ip_info:\n                continue\n\n            port = int(ip_info.get(\"port\", 443))\n            ip_str = utils.get_ip_str(ip, port)\n\n            info = self._get_ip_info(ip)\n            if info[\"links\"] < 0:\n                # self.logger.error(\"ip %s link:%d\", ip, info[\"links\"])\n                info[\"links\"] = 0\n\n            if info[\"links\"] >= self.config.max_links_per_ip:\n                continue\n\n            if info[\"fail_times\"] and now - info[\"last_try\"] < 60:\n                continue\n\n            speed, rtt = self.get_speed(ip_str)\n            if speed > best_speed:\n                best_speed = speed\n                best_info = info\n\n        if not best_info:\n            return None\n\n        best_info[\"links\"] += 1\n        best_info[\"last_try\"] = now\n        # self.logger.debug(\"get ip:%s\", ip)\n\n        ip = best_info[\"ip\"]\n        port = int(self.host_manager.info[ip].get(\"port\", 443))\n        ip_str = utils.get_ip_str(ip, port)\n        return {\n            \"ip_str\": ip_str,\n            \"sni\": None,\n            \"host\": None,\n        }\n\n    def update_ip(self, ip_str, sni, handshake_time):\n        ip, _ = utils.get_ip_port(ip_str)\n        ip = utils.to_str(ip)\n        info = self._get_ip_info(ip)\n        info[\"fail_times\"] = 0\n        info[\"rtt\"] = handshake_time\n        info[\"last_try\"] = 0.0\n        # self.logger.debug(\"ip %s connect success\", ip)\n\n    def report_connect_fail(self, ip_str, sni=None, reason=\"\", force_remove=False):\n        ip, _ = utils.get_ip_port(ip_str)\n        ip = utils.to_str(ip)\n        info = self._get_ip_info(ip)\n        info[\"fail_times\"] += 1\n        if info[\"links\"] <= 0:\n            self.logger.error(\"report_connect_fail %s sni:%s links:%d reason:%s\", ip, sni, info[\"links\"], reason)\n        else:\n            info[\"links\"] -= 1\n        self.logger.debug(\"ip %s connect fail:%s\", ip, reason)\n\n    def report_connect_closed(self, ip_str, sni=None, reason=\"\"):\n        try:\n            ip, _ = utils.get_ip_port(ip_str)\n            ip = utils.to_str(ip)\n            info = self._get_ip_info(ip)\n            if info[\"links\"] <= 0:\n                self.logger.error(\"report_connect_closed %s sni:%s links:%d reason:%s\", ip, sni, info[\"links\"], reason)\n            else:\n                info[\"links\"] -= 1\n            self.logger.debug(\"ip %s sni:%s connect closed reason %s\", ip, sni, reason)\n        except Exception as e:\n            self.logger.warn(\"report_connect_closed %s sni:%s reason:%s except:%r\", ip_str, sni, reason, e)\n"
  },
  {
    "path": "code/default/x_tunnel/local/tls_relay_front/test.py",
    "content": "#!/usr/bin/env python2\n# coding:utf-8\n\nimport os\nimport sys\nimport time\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nfront_path = os.path.abspath( os.path.join(current_path, os.pardir))\nroot_path = os.path.abspath( os.path.join(current_path, os.pardir, os.pardir, os.pardir))\npython_path = root_path\n\nsys.path.append(root_path)\nsys.path.append(front_path)\n\nnoarch_lib = os.path.abspath( os.path.join(python_path, 'lib', 'noarch'))\nsys.path.append(noarch_lib)\n\nif sys.platform == \"win32\":\n    win32_lib = os.path.abspath( os.path.join(python_path, 'lib', 'win32'))\n    sys.path.append(win32_lib)\nelif sys.platform.startswith(\"linux\"):\n    linux_lib = os.path.abspath( os.path.join(python_path, 'lib', 'linux'))\n    sys.path.append(linux_lib)\nelif sys.platform == \"darwin\":\n    darwin_lib = os.path.abspath( os.path.join(python_path, 'lib', 'darwin'))\n    sys.path.append(darwin_lib)\n    extra_lib = \"/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python\"\n    sys.path.append(extra_lib)\n\nimport tls_relay_front as tls_relay\nfrom xlog import getLogger\nxlog = getLogger(\"tls_relay\")\nimport env_info\n\ndata_path = env_info.data_path\nmodule_data_path = os.path.join(data_path, 'x_tunnel')\n\n\ndef t1():\n    content, status, response = tls_relay.front.request(\"GET\", \"scan1.xx-net.org\", timeout=1000)\n    print(status)\n\n    tls_relay.front.stop()\n\n\ndef get_dns():\n    start_time = time.time()\n    # content, status, response = front.request(\"GET\", \"scan1.xx-net.org\", \"/\", timeout=10)\n    content, status, response = tls_relay.front.request(\"GET\", \"dns.xx-net.org\", path=\"/query?domain=www.google.com\")\n\n    time_cost = time.time() - start_time\n    xlog.info(\"GET cost:%f\", time_cost)\n    xlog.info(\"status:%d content:%s\", status, content)\n    tls_relay.front.stop()\n\n\nif __name__ == '__main__':\n    try:\n        # t1()\n        get_dns()\n    except KeyboardInterrupt:\n        import sys\n\n        sys.exit()\n"
  },
  {
    "path": "code/default/x_tunnel/local/tls_relay_front/web_control.py",
    "content": "#!/usr/bin/env python\n# coding:utf-8\n\n\nimport os\nimport time\n\ntry:\n    from urllib.parse import urlparse, parse_qs\nexcept ImportError:\n    from urlparse import urlparse, parse_qs\n\nimport simple_http_server\nfrom .front import front\n\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nroot_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))\ntop_path = os.path.abspath(os.path.join(root_path, os.pardir, os.pardir, os.pardir))\nweb_ui_path = os.path.join(current_path, os.path.pardir, \"web_ui\")\n\n\nclass ControlHandler(simple_http_server.HttpServerHandler):\n    def __init__(self, client_address, headers, command, path, rfile, wfile):\n        self.client_address = client_address\n        self.headers = headers\n        self.command = command\n        self.path = path\n        self.rfile = rfile\n        self.wfile = wfile\n\n    def do_GET(self):\n        path = urlparse(self.path).path\n        if path == \"/log\":\n            return self.req_log_handler()\n        elif path == \"/ip_list\":\n            return self.req_ip_list_handler()\n        elif path == \"/debug\":\n            return self.req_debug_handler()\n        else:\n            front.logger.warn('Control Req %s %s %s ', self.address_string(), self.command, self.path)\n\n        self.wfile.write(b'HTTP/1.1 404\\r\\nContent-Type: text/plain\\r\\nConnection: close\\r\\n\\r\\n404 Not Found')\n        front.logger.info('%s \"%s %s HTTP/1.1\" 404 -', self.address_string(), self.command, self.path)\n\n    def req_log_handler(self):\n        req = urlparse(self.path).query\n        reqs = self.unpack_reqs(parse_qs(req, keep_blank_values=True))\n        data = ''\n\n        cmd = \"get_last\"\n        if reqs[\"cmd\"]:\n            cmd = reqs[\"cmd\"]\n\n        if cmd == \"get_last\":\n            max_line = int(reqs[\"max_line\"])\n            data = front.logger.get_last_lines(max_line)\n        elif cmd == \"get_new\":\n            last_no = int(reqs[\"last_no\"])\n            data = front.logger.get_new_lines(last_no)\n        else:\n            front.logger.error('PAC %s %s %s ', self.address_string(), self.command, self.path)\n\n        mimetype = 'text/plain'\n        self.send_response_nc(mimetype, data)\n\n    def req_ip_list_handler(self):\n        time_now = time.time()\n        data = \"<html><body><div  style='float: left; white-space:nowrap;font-family: monospace;'>\"\n        data += \"time:%d  pointer:%d<br>\\r\\n\" % (time_now, front.ip_manager.gws_ip_pointer)\n        data += \"<table><tr><th>N</th><th>IP</th><th>HS</th><th>Fails</th>\"\n        data += \"<th>down_fail</th><th>links</th>\"\n        data += \"<th>get_time</th><th>success_time</th><th>fail_time</th><th>down_fail_time</th>\"\n        data += \"<th>data_active</th><th>transfered_data</th><th>Trans</th>\"\n        data += \"<th>history</th></tr>\\n\"\n        i = 1\n        for ip in front.ip_manager.gws_ip_list:\n            handshake_time = front.ip_manager.ip_dict[ip][\"handshake_time\"]\n\n            fail_times = front.ip_manager.ip_dict[ip][\"fail_times\"]\n            down_fail = front.ip_manager.ip_dict[ip][\"down_fail\"]\n            links = front.ip_manager.ip_dict[ip][\"links\"]\n\n            get_time = front.ip_manager.ip_dict[ip][\"get_time\"]\n            if get_time:\n                get_time = time_now - get_time\n\n            success_time = front.ip_manager.ip_dict[ip][\"success_time\"]\n            if success_time:\n                success_time = time_now - success_time\n\n            fail_time = front.ip_manager.ip_dict[ip][\"fail_time\"]\n            if fail_time:\n                fail_time = time_now - fail_time\n\n            down_fail_time = front.ip_manager.ip_dict[ip][\"down_fail_time\"]\n            if down_fail_time:\n                down_fail_time = time_now - down_fail_time\n\n            data_active = front.ip_manager.ip_dict[ip][\"data_active\"]\n            if data_active:\n                active_time = time_now - data_active\n            else:\n                active_time = 0\n\n            history = front.ip_manager.ip_dict[ip][\"history\"]\n            t0 = 0\n            str_out = ''\n            for item in history:\n                t = item[0]\n                v = item[1]\n                if t0 == 0:\n                    t0 = t\n                time_per = int((t - t0) * 1000)\n                t0 = t\n                str_out += \"%d(%s) \" % (time_per, v)\n            data += \"<tr><td>%d</td><td>%s</td><td>%d</td><td>%d</td><td>%d</td><td>%d</td><td>%d</td><td>%d</td><td>%d</td>\" \\\n                    \"<td>%d</td><td>%d</td><td>%s</td></tr>\\n\" % \\\n                    (i, ip, handshake_time, fail_times, down_fail, links, get_time, success_time, fail_time, down_fail_time, \\\n                    active_time, str_out)\n            i += 1\n\n        data += \"</table></div></body></html>\"\n        mimetype = 'text/html'\n        self.send_response_nc(mimetype, data)\n\n    def req_debug_handler(self):\n        if not front.running:\n            return self.send_response_nc('text/plain', \"Not running\")\n\n        data = \"\"\n        for obj in [front.connect_manager, front.http_dispatcher]:\n            data += \"%s\\r\\n\" % obj.__class__\n            for attr in dir(obj):\n                if attr.startswith(\"__\"):\n                    continue\n                sub_obj = getattr(obj, attr)\n                if callable(sub_obj):\n                    continue\n\n                if isinstance(sub_obj, list):\n                    data += \"    %s:\\r\\n\" % (attr)\n                    for item in sub_obj:\n                        data += \"      %s\\r\\n\" % item\n                    data += \"\\r\\n\"\n                elif hasattr(sub_obj, \"to_string\"):\n                    data += \"    %s:\\r\\n\" % (attr)\n                    data += sub_obj.to_string()\n                else:\n                    data += \"    %s = %s\\r\\n\" % (attr, sub_obj)\n            if hasattr(obj, \"to_string\"):\n                data += obj.to_string()\n\n        mimetype = 'text/plain'\n        self.send_response_nc(mimetype, data)"
  },
  {
    "path": "code/default/x_tunnel/local/upload_logs.py",
    "content": "import os\nimport time\nimport io\nimport json\nimport zipfile\nimport operator\n\nimport simple_http_client\nimport env_info\nimport utils\nfrom xlog import getLogger, reset_log_files\nxlog = getLogger(\"x_tunnel\")\n\nfrom x_tunnel.local import global_var as g\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\nroot_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))\ndata_path = env_info.data_path\ndata_xtunnel_path = os.path.join(data_path, 'x_tunnel')\n\n\ndef sleep(t):\n    end_time = time.time() + t\n    while g.running:\n        if time.time() > end_time:\n            return\n\n        sleep_time = min(10, end_time - time.time())\n        if sleep_time < 0:\n            break\n\n        time.sleep(sleep_time)\n\n\ndef mask_x_tunnel_password(fp):\n    # xlog.debug(\"mask_x_tunnel_password:%s\", fp)\n    with open(fp, \"r\") as fd:\n        content = fd.read()\n        try:\n            dat = json.loads(content)\n            del dat[\"login_password\"]\n            dat_str = json.dumps(dat)\n            return dat_str\n        except Exception as e:\n            xlog.exception(\"mask_x_tunnel_password fail, %s, content:%s e:%r\", fp, content, e)\n            return content\n\n\ndef get_launcher_port():\n    launcher_config_fn = os.path.join(data_path, \"launcher\", \"config.json\")\n    try:\n        with open(launcher_config_fn, \"r\", encoding='utf-8') as fd:\n            info = json.load(fd)\n            return info.get(\"control_port\", 8085)\n    except Exception as e:\n        xlog.exception(\"get_launcher_port except:%r\", e)\n        return 8085\n\n\ndef collect_debug_and_log():\n    port = get_launcher_port()\n\n    # collect debug info and save to folders\n    debug_infos = {\n        \"system_info\": f\"http://127.0.0.1:{port}/debug\",\n        \"gae_info\": f\"http://127.0.0.1:{port}/module/gae_proxy/control/debug\",\n        \"gae_log\": f\"http://127.0.0.1:{port}/module/gae_proxy/control/log?cmd=get_new&last_no=1\",\n        \"xtunnel_info\": f\"http://127.0.0.1:{port}/module/x_tunnel/control/debug\",\n        \"xtunnel_status\": f\"http://127.0.0.1:{port}/module/x_tunnel/control/status\",\n        \"cloudflare_info\": f\"http://127.0.0.1:{port}/module/x_tunnel/control/cloudflare_front/debug\",\n        \"tls_info\": f\"http://127.0.0.1:{port}/module/x_tunnel/control/tls_relay_front/debug\",\n        \"seley_info\": f\"http://127.0.0.1:{port}/module/x_tunnel/control/seley_front/debug\",\n        \"cloudflare_log\": f\"http://127.0.0.1:{port}/module/x_tunnel/control/cloudflare_front/log?cmd=get_new&last_no=1\",\n        \"tls_log\": f\"http://127.0.0.1:{port}/module/x_tunnel/control/tls_relay_front/log?cmd=get_new&last_no=1\",\n        \"seley_log\": f\"http://127.0.0.1:{port}/module/x_tunnel/control/seley_front/log?cmd=get_new&last_no=1\",\n        \"xtunnel_log\": f\"http://127.0.0.1:{port}/module/x_tunnel/control/log?cmd=get_new&last_no=1\",\n        \"smartroute_log\": f\"http://127.0.0.1:{port}/module/smart_router/control/log?cmd=get_new&last_no=1\",\n        \"launcher_log\": f\"http://127.0.0.1:{port}/log?cmd=get_new&last_no=1\"\n    }\n\n    download_path = os.path.join(env_info.data_path, \"downloads\")\n    if not os.path.isdir(download_path):\n        os.mkdir(download_path)\n\n    for name, url in debug_infos.items():\n        # xlog.debug(\"fetch %s %s\", name, url)\n        try:\n            res = simple_http_client.request(\"GET\", url, timeout=1)\n            if name.endswith(\"log\"):\n                dat = json.loads(res.text)\n                no_line = list(dat.items())\n                no_line = [[int(line[0]), line[1]] for line in no_line]\n                no_line = sorted(no_line, key=operator.itemgetter(0))\n                lines = [line[1] for line in no_line]\n                data = \"\".join(lines)\n                data = utils.to_bytes(data)\n            else:\n                data = res.text\n\n            fn = os.path.join(download_path, name + \".txt\")\n            with open(fn, \"wb\") as fd:\n                fd.write(data)\n        except Exception as e:\n            xlog.warn(\"fetch info %s fail:%r\", url, e)\n\n\ndef list_files():\n    log_files = {}\n    other_files = []\n    for root, subdirs, files in os.walk(data_path):\n        for filename in files:\n            src_file = os.path.join(root, filename)\n\n            extension = filename.split(\".\")[-1]\n            if extension in [\"json\", \"txt\"]:\n                other_files.append(src_file)\n\n            if extension not in [\"log\",]:\n                continue\n\n            mtime = os.path.getmtime(src_file)\n            log_files[src_file] = mtime\n\n    # pack new log first, skip old log if size exceed.\n    files = sorted(list(log_files.items()), key=operator.itemgetter(1), reverse=True)\n    log_files_list = [src_file for src_file, mtime in files]\n\n    # always pack other files(.json and .txt).\n    return other_files + log_files_list\n\n\ndef pack_logs(max_size=10 * 1024 * 1024):\n    content_size = 0\n\n    collect_debug_and_log()\n\n    try:\n        files = list_files()\n        zip_buffer = io.BytesIO()\n        with zipfile.ZipFile(zip_buffer, mode=\"w\", compression=zipfile.ZIP_DEFLATED) as zfd:\n            for src_file in files:\n                file_size = os.path.getsize(src_file)\n                if content_size + file_size > max_size:\n                    break\n\n                relate_path = src_file[len(data_path) + 1:]\n                # xlog.debug(\"Add file:%s size:%d\", relate_path, file_size)\n\n                if relate_path.endswith(\"client.json\"):\n                    content = mask_x_tunnel_password(src_file)\n                    zfd.writestr(relate_path, content)\n                else:\n                    zfd.write(src_file, arcname=relate_path)\n                content_size += file_size\n\n        compressed_data = zip_buffer.getvalue()\n        xlog.debug(\"compress log size:%d to %d\", content_size, len(compressed_data))\n        return compressed_data\n    except Exception as e:\n        xlog.exception(\"packing logs except:%r\", e)\n        return None\n\n\ndef upload_logs_thread():\n    sleep(g.config.delay_collect_log)\n    while g.running:\n        if not g.running or not g.server_host or not g.session or g.session.last_receive_time == 0:\n            time.sleep(10)\n        else:\n            break\n\n    sleep(g.config.delay_collect_log2)\n    if not g.running:\n        return\n\n    session_id = utils.to_str(g.session.session_id)\n    data = pack_logs()\n    if data:\n        upload(session_id, data)\n\n\ndef upload(session_id, data):\n    try:\n        content, status, response = g.http_client.request(method=\"POST\", host=g.server_host,\n                                                          path=\"/upload_logs?session_id=%s\" % session_id,\n                                                          data=data,\n                                                          headers={\"Content-Length\": str(len(data))})\n\n    except Exception as e:\n        xlog.exception(\"upload logs:%r \", e)\n        return\n\n    if status != 200:\n        xlog.warn(\"upload logs status:%r \", status)\n        return\n\n    # xlog.info(\"upload logs successful\")\n    reset_log_files()\n"
  },
  {
    "path": "code/default/x_tunnel/local/web_control.py",
    "content": "#!/usr/bin/env python\n# coding:utf-8\n\n\ntry:\n    from urllib.parse import urlparse, parse_qs\nexcept ImportError:\n    from urlparse import urlparse, parse_qs\n\nimport os\nimport time\nimport hashlib\nimport threading\nimport json\nimport base64\n\nimport utils\nfrom xlog import getLogger\nxlog = getLogger(\"x_tunnel\")\n\nimport simple_http_server\nfrom . import global_var as g\nfrom . import proxy_session\nfrom .tls_relay_front import web_control as tls_relay_web\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\ndefault_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))\nroot_path = os.path.abspath(os.path.join(default_path, os.pardir, os.pardir))\nweb_ui_path = os.path.join(current_path, os.path.pardir, \"web_ui\")\n\nimport env_info\ndata_path = os.path.join(env_info.data_path, 'smart_router')\n\n\ndef check_email(email):\n    import re\n    if not re.match(r\"[^@]+@[^@]+\\.[^@]+\", email):\n        return False\n    else:\n        return True\n\n\ndef get_lang():\n    app_info_file = os.path.join(env_info.data_path, \"launcher\", \"config.json\")\n    try:\n        with open(app_info_file, \"r\") as fd:\n            dat = json.load(fd)\n        return dat.get(\"language\", \"en\")\n    except Exception as e:\n        xlog.exception(\"get version fail:%r\", e)\n    return \"en\"\n\n\nclass ControlHandler(simple_http_server.HttpServerHandler):\n    def __init__(self, client_address, headers, command, path, rfile, wfile):\n        self.client_address = client_address\n        self.headers = headers\n        self.command = command\n        self.path = path\n        self.rfile = rfile\n        self.wfile = wfile\n\n    def do_GET(self):\n        path = urlparse(self.path).path\n        if path == \"/log\":\n            return self.req_log_handler()\n        elif path == \"/debug\":\n            data = g.session.status()\n            return self.send_response('text/plain', data)\n        elif path == \"/info\":\n            return self.req_info_handler()\n        elif path == \"/config\":\n            return self.req_config_handler()\n        elif path == \"/get_history\":\n            return self.req_get_history_handler()\n        elif path == \"/status\":\n            return self.req_status()\n        elif path.startswith(\"/cloudflare_front/\"):\n            path = self.path[17:]\n            from .cloudflare_front import web_control as cloudflare_web\n            controler = cloudflare_web.ControlHandler(self.client_address,\n                             self.headers,\n                             self.command, path,\n                             self.rfile, self.wfile)\n            controler.do_GET()\n        elif path.startswith(\"/cloudfront_front/\"):\n            if not g.config.enable_cloudfront:\n                return self.send_not_found()\n\n            path = self.path[17:]\n            from .cloudfront_front import web_control as cloudfront_web\n            controler = cloudfront_web.ControlHandler(self.client_address,\n                             self.headers,\n                             self.command, path,\n                             self.rfile, self.wfile)\n            controler.do_GET()\n        elif path.startswith(\"/seley_front/\"):\n            path = self.path[12:]\n            from .seley_front import web_control as seley_web\n            controler = seley_web.ControlHandler(self.client_address,\n                             self.headers,\n                             self.command, path,\n                             self.rfile, self.wfile)\n            controler.do_GET()\n        elif path.startswith(\"/tls_relay_front/\"):\n            path = self.path[16:]\n            controler = tls_relay_web.ControlHandler(self.client_address,\n                             self.headers,\n                             self.command, path,\n                             self.rfile, self.wfile)\n            controler.do_GET()\n        else:\n            xlog.warn('Control Req %s %s %s ', self.address_string(), self.command, self.path)\n\n    def do_POST(self):\n        xlog.debug('x-tunnel web_control %s %s %s ', self.address_string(), self.command, self.path)\n\n        path = urlparse(self.path).path\n        if path == '/token_login':\n            return self.req_token_login_handler()\n        elif path == '/login':\n            return self.req_login_handler()\n        elif path == \"/logout\":\n            return self.req_logout_handler()\n        elif path == \"/register\":\n            return self.req_login_handler()\n        elif path == \"/config\":\n            return self.req_config_handler()\n        elif path == \"/order\":\n            return self.req_order_handler()\n        elif path == \"/transfer\":\n            return self.req_transfer_handler()\n        elif path == \"/reset_password\":\n            return self.req_reset_password()\n        elif path.startswith(\"/cloudflare_front/\"):\n            path = path[17:]\n            from .cloudflare_front import web_control as cloudflare_web\n            controler = cloudflare_web.ControlHandler(self.client_address,\n                                                      self.headers,\n                                                      self.command, path,\n                                                      self.rfile, self.wfile)\n            controler.do_POST()\n        elif path.startswith(\"/cloudfront_front/\"):\n            path = path[17:]\n            from .cloudfront_front import web_control as cloudfront_web\n            controler = cloudfront_web.ControlHandler(self.client_address,\n                                                      self.headers,\n                                                      self.command, path,\n                                                      self.rfile, self.wfile)\n            controler.do_POST()\n        elif path.startswith(\"/seley_front/\"):\n            path = path[13:]\n\n            from .seley_front import web_control as seley_web\n            controler = seley_web.ControlHandler(self.client_address,\n                                                      self.headers,\n                                                      self.command, path,\n                                                      self.rfile, self.wfile)\n            controler.do_POST()\n        elif path.startswith(\"/tls_relay_front/\"):\n            path = path[16:]\n            controler = tls_relay_web.ControlHandler(self.client_address,\n                                                      self.headers,\n                                                      self.command, path,\n                                                      self.rfile, self.wfile)\n            controler.do_POST()\n        else:\n            xlog.info('%s \"%s %s HTTP/1.1\" 404 -', self.address_string(), self.command, self.path)\n            return self.send_not_found()\n\n    def req_log_handler(self):\n        req = urlparse(self.path).query\n        reqs = self.unpack_reqs(parse_qs(req, keep_blank_values=True))\n        data = ''\n\n        if reqs[\"cmd\"]:\n            cmd = reqs[\"cmd\"]\n        else:\n            cmd = \"get_last\"\n\n        if cmd == \"get_last\":\n            max_line = int(reqs[\"max_line\"])\n            data = xlog.get_last_lines(max_line)\n        elif cmd == \"get_new\":\n            last_no = int(reqs[\"last_no\"])\n            data = xlog.get_new_lines(last_no)\n        else:\n            xlog.error('xtunnel log cmd:%s', cmd)\n\n        mimetype = 'text/plain'\n        self.send_response(mimetype, data)\n\n    def req_info_handler(self):\n        if len(g.config.login_account) == 0 or len(g.config.login_password) == 0:\n            return self.response_json({\n                \"res\": \"logout\"\n            })\n\n        if proxy_session.center_login_process:\n            return self.response_json({\n                \"res\": \"login_process\"\n            })\n\n        req = urlparse(self.path).query\n        reqs = parse_qs(req, keep_blank_values=True)\n\n        force = False\n        if 'force' in reqs:\n            xlog.debug(\"req_info in force\")\n            force = 1\n\n        time_now = time.time()\n        if force or time_now - g.last_refresh_time > 3600 or \\\n                (g.last_api_error.startswith(\"status:\") and (time_now - g.last_refresh_time > 30)):\n            xlog.debug(\"x_tunnel force update info\")\n            g.last_refresh_time = time_now\n\n            threading.Thread(target=proxy_session.request_balance, args=(None,None,False,False),\n                             name=\"info__request_balance\").start()\n\n            return self.response_json({\n                \"res\": \"login_process\"\n            })\n\n        if len(g.last_api_error) and g.last_api_error != 'balance not enough':\n            res_arr = {\n                \"res\": \"fail\",\n                \"login_account\": \"%s\" % (g.config.login_account),\n                \"reason\": g.last_api_error\n            }\n        else:\n            res_arr = {\n                \"res\": \"success\",\n                \"login_account\": \"%s\" % (g.config.login_account),\n                \"promote_code\": g.promote_code,\n                \"promoter\": g.promoter,\n                \"paypal_button_id\": g.paypal_button_id,\n                \"plans\": g.plans,\n                \"balance\": \"%f\" % (g.balance),\n                \"openai_balance\": float(g.openai_balance),\n                \"quota\": \"%d\" % (g.quota),\n                \"quota_list\": g.quota_list,\n                \"traffic\": g.session.traffic_upload + g.session.traffic_download,\n                \"last_fail\": g.last_api_error\n            }\n        self.response_json(res_arr)\n\n    def req_token_login_handler(self):\n        login_token = str(self.postvars['login_token'])\n        try:\n            login_str = base64.b64decode(login_token)\n            data = json.loads(utils.to_str(login_str))\n            username = data[\"login_account\"]\n            password_hash = data[\"login_password\"]\n            cloudflare_domains = data.get(\"cloudflare_domains\")\n            tls_relay = data[\"tls_relay\"]\n            seleys = data.get(\"seleys\", {})\n        except Exception as e:\n            xlog.warn(\"token_login except:%r\", e)\n            return self.response_json({\n                \"res\": \"fail\",\n                \"reason\": \"token invalid\"\n            })\n\n        pa = check_email(username)\n        if not pa:\n            xlog.warn(\"login with invalid email: %s\", username)\n            return self.response_json({\n                \"res\": \"fail\",\n                \"reason\": \"Invalid email.\"\n            })\n        elif len(password_hash) < 64:\n            return self.response_json({\n                \"res\": \"fail\",\n                \"reason\": \"Password format fail\"\n            })\n\n        g.config.api_server = g.config.default_config[\"api_server\"]\n        if g.config.update_cloudflare_domains and cloudflare_domains:\n            g.http_client.save_cloudflare_domain(cloudflare_domains)\n        if g.tls_relay_front and tls_relay.get(\"ips\"):\n            g.tls_relay_front.set_ips(tls_relay[\"ips\"])\n        if g.seley_front:\n            g.seley_front.set_hosts(seleys.get(\"hosts\", {}))\n\n        res, reason = proxy_session.request_balance(username, password_hash, False,\n                                                    update_server=True, promoter=\"\")\n        if res:\n            g.config.login_account  = username\n            g.config.login_password = password_hash\n            g.config.save()\n            res_arr = {\n                \"res\": \"success\",\n                \"balance\": float(g.balance),\n                \"openai_balance\": float(g.openai_balance)\n            }\n            g.last_refresh_time = time.time()\n            g.session.start()\n        else:\n            res_arr = {\n                \"res\": \"fail\",\n                \"reason\": reason\n            }\n\n        return self.response_json(res_arr)\n\n    def req_login_handler(self):\n        username    = str(self.postvars['username'])\n        #username = utils.get_printable(username)\n        password    = str(self.postvars['password'])\n        promoter = self.postvars.get(\"promoter\", [\"\"])\n        is_register = int(self.postvars['is_register'])\n\n        pa = check_email(username)\n        if not pa:\n            xlog.warn(\"login with invalid email: %s\", username)\n            return self.response_json({\n                \"res\": \"fail\",\n                \"reason\": \"Invalid email.\"\n            })\n        elif len(password) < 6:\n            return self.response_json({\n                \"res\": \"fail\",\n                \"reason\": \"Password needs at least 6 charactors.\"\n            })\n\n        if password == \"_HiddenPassword\":\n            if username == g.config.login_account and len(g.config.login_password):\n                password_hash = g.config.login_password\n            else:\n\n                res_arr = {\n                    \"res\": \"fail\",\n                    \"reason\": \"account not exist\"\n                }\n                return self.response_json(res_arr)\n        else:\n            password_hash = str(hashlib.sha256(utils.to_bytes(password)).hexdigest())\n\n        res, reason = proxy_session.request_balance(username, password_hash, is_register,\n                                                    update_server=True, promoter=promoter)\n        if res:\n            g.config.login_account  = username\n            g.config.login_password = password_hash\n            g.config.save()\n            res_arr = {\n                \"res\": \"success\",\n                \"balance\": float(g.balance),\n                \"openai_balance\": float(g.openai_balance)\n            }\n            g.last_refresh_time = time.time()\n            g.session.start()\n        else:\n            res_arr = {\n                \"res\": \"fail\",\n                \"reason\": reason\n            }\n\n        return self.response_json(res_arr)\n\n    def req_reset_password(self):\n        app_name = proxy_session.get_app_name()\n        account = self.postvars.get('username', [\"\"])\n        stage = self.postvars.get('stage', [\"\"])\n        code = self.postvars.get('code', [\"\"])\n        xlog.info(\"reset password, stage:%s\", stage)\n\n        if stage == \"request_reset_password\":\n            res, info = proxy_session.call_api(\"/request_reset_password\", {\n                \"account\": account,\n                \"app_id\": app_name,\n                \"lang\": get_lang(),\n            })\n            if not res:\n                xlog.warn(\"request reset password fail:%s\", info)\n                threading.Thread(target=proxy_session.update_quota_loop).start()\n                return self.response_json({\"res\": \"fail\", \"reason\": info})\n\n            self.response_json(info)\n\n        elif stage == \"reset_password_check\":\n            res, info = proxy_session.call_api(\"/reset_password_check\", {\n                \"account\": account,\n                \"code\": code,\n                \"app_id\": app_name,\n                \"lang\": get_lang(),\n            })\n            if not res:\n                xlog.warn(\"reset password check fail:%s\", info)\n                threading.Thread(target=proxy_session.update_quota_loop).start()\n                return self.response_json({\"res\": \"fail\", \"reason\": info})\n\n            self.response_json(info)\n\n        elif stage == \"change_password\":\n            password = self.postvars.get('password', [\"\"])\n            password_hash = str(hashlib.sha256(utils.to_bytes(password)).hexdigest())\n            res, info = proxy_session.call_api(\"/change_password\", {\n                \"account\": account,\n                \"code\": code,\n                \"password\": password_hash,\n                \"app_id\": app_name,\n                \"lang\": get_lang(),\n            })\n            if not res:\n                xlog.warn(\"change password fail:%s\", info)\n                threading.Thread(target=proxy_session.update_quota_loop).start()\n                return self.response_json({\"res\": \"fail\", \"reason\": info})\n\n            self.response_json(info)\n        else:\n            self.response_json({\"res\": \"fail\", \"reason\": \"wrong stage\"})\n\n    def req_logout_handler(self):\n        g.config.login_account = \"\"\n        g.config.login_password = \"\"\n        g.config.save()\n\n        if g.session:\n            g.session.stop()\n\n        return self.response_json({\"res\": \"success\"})\n\n    def req_config_handler(self):\n        req = urlparse(self.path).query\n        reqs = parse_qs(req, keep_blank_values=True)\n\n        def is_server_available(server):\n            if g.selectable and server == '':\n                return True # \"auto\"\n            else:\n                for choice in g.selectable:\n                    if choice[0] == server:\n                        return True # \"selectable\"\n                return False # \"unselectable\"\n\n        if reqs['cmd'] == ['get']:\n            g.config.load()\n            server = {\n                'selectable': g.selectable,\n                'selected': 'auto' if g.config.server_host == '' else g.config.server_host,  # \"auto\" as default\n                'available': is_server_available(g.config.server_host)\n            }\n            res = {\n                'server': server,\n                'promoter': g.promoter\n            }\n        elif reqs['cmd'] == ['set']:\n            if 'server' in self.postvars:\n                server = str(self.postvars['server'])\n                server = '' if server == 'auto' else server\n\n                if is_server_available(server):\n                    if server != g.config.server_host:\n                        xlog.info(\"change server to %s\", server)\n                        g.server_host = g.config.server_host = server\n                        g.server_port = g.config.server_port = 443\n                        g.config.save()\n\n                        threading.Thread(target=g.session.reset).start()\n\n                    res = {\"res\": \"success\"}\n                else:\n                    res = {\n                        \"res\": \"fail\",\n                        \"reason\": \"server not available\"\n                    }\n            else:\n                res = {\"res\": \"fail\"}\n\n        return self.response_json(res)\n\n    def req_order_handler(self):\n        product = self.postvars['product']\n        if product != 'x_tunnel':\n            xlog.warn(\"x_tunnel order product %s not support\", product)\n            return self.response_json({\n                \"res\": \"fail\",\n                \"reason\": \"product %s not support\" % product\n            })\n\n        plan = self.postvars['plan']\n        if plan not in g.plans:\n            xlog.warn(\"x_tunnel order plan %s not support\", plan)\n            return self.response_json({\n                \"res\": \"fail\",\n                \"reason\": \"plan %s not support\" % plan\n            })\n\n        res, info = proxy_session.call_api(\"/order\", {\n            \"account\": g.config.login_account,\n            \"password\": g.config.login_password,\n            \"product\": \"x_tunnel\",\n            \"plan\": plan\n        })\n        if not res:\n            xlog.warn(\"order fail:%s\", info)\n            threading.Thread(target=proxy_session.update_quota_loop).start()\n            return self.response_json({\"res\": \"fail\", \"reason\": info})\n\n        self.response_json({\"res\": \"success\"})\n\n    def req_transfer_handler(self):\n        to_account = self.postvars['to_account']\n        amount = float(self.postvars['amount'])\n        transfer_type = self.postvars['transfer_type']\n        if transfer_type == 'balance':\n            if amount > g.balance:\n                reason = \"balance not enough\"\n                xlog.warn(\"transfer fail:%s\", reason)\n                return self.response_json({\"res\": \"fail\", \"reason\": reason})\n            end_time = 0\n        elif transfer_type == \"quota\":\n            end_time = int(self.postvars['end_time'])\n        else:\n            reason = \"transfer type not support:%s\" % transfer_type\n            xlog.warn(\"transfer fail:%s\", reason)\n            return self.response_json({\"res\": \"fail\", \"reason\": reason})\n\n        req_info = {\n            \"account\": g.config.login_account,\n            \"password\": g.config.login_password,\n            \"transfer_type\": transfer_type,\n            \"end_time\": end_time,\n            \"to_account\": to_account,\n            \"amount\": amount\n        }\n\n        res, info = proxy_session.call_api(\"/transfer\", req_info)\n        if not res:\n            xlog.warn(\"transfer fail:%s\", info)\n            return self.response_json({\n                \"res\": \"fail\",\n                \"reason\": info\n            })\n\n        self.response_json({\"res\": \"success\"})\n\n    def req_get_history_handler(self):\n        req = urlparse(self.path).query\n        reqs = parse_qs(req, keep_blank_values=True)\n\n        req_info = {\n            \"account\": g.config.login_account,\n            \"password\": g.config.login_password,\n            \"start\": int(reqs['start'][0]),\n            \"end\": int(reqs['end'][0]),\n            \"limit\": int(reqs['limit'][0])\n        }\n\n        res, info = proxy_session.call_api(\"/get_history\", req_info)\n        if not res:\n            xlog.warn(\"get history fail:%s\", info)\n            return self.response_json({\n                \"res\": \"fail\",\n                \"reason\": info\n            })\n        self.response_json({\n            \"res\": \"success\",\n            \"history\": info[\"history\"]\n        })\n\n    def req_status(self):\n        res = g.session.get_stat()\n        res[\"bind_port\"] = g.bind_port\n\n        self.response_json({\n            \"res\": \"success\",\n            \"status\": res\n        })\n"
  },
  {
    "path": "code/default/x_tunnel/tests/test_proxy.py",
    "content": "from unittest import TestCase\nimport json\nimport os\nimport time\nimport sys\n\ncurrent_path = os.path.dirname(os.path.abspath(__file__))\ndefault_path = os.path.abspath(os.path.join(current_path, os.path.pardir, os.path.pardir))\nroot_path = os.path.abspath(os.path.join(default_path, os.path.pardir, os.path.pardir))\n\nnoarch_lib = os.path.abspath(os.path.join(default_path, 'lib', 'noarch'))\nsys.path.append(noarch_lib)\n\nimport utils\nimport simple_http_server\nfrom dnslib.dns import DNSRecord, DNSHeader, DNSQuestion\nimport socket\n\nimport simple_http_client\nfrom xlog import getLogger\nxlog = getLogger(\"test\")\n\n\nclass ProxyTest(TestCase):\n    def __init__(self):\n        super().__init__()\n\n    def test_xtunnel_logout(self):\n        xlog.info(\"Start testing XTunnel logout\")\n        res = simple_http_client.request(\"POST\", \"http://127.0.0.1:8085/module/x_tunnel/control/logout\", timeout=10)\n        self.assertEqual(res.status, 200)\n        self.xtunnel_login_status = False\n        xlog.info(\"Finished testing XTunnel logout\")\n\n    def smart_route_proxy_http(self):\n        xlog.info(\"Start testing SmartRouter HTTP proxy protocol\")\n        proxy = \"http://localhost:8086\"\n        res = simple_http_client.request(\"GET\", \"https://github.com/\", proxy=proxy, timeout=20)\n        self.assertEqual(res.status, 200)\n        xlog.info(\"Finished testing SmartRouter HTTP proxy protocol\")\n\n    def smart_route_proxy_socks4(self):\n        xlog.info(\"Start testing SmartRouter SOCKS4 proxy protocol\")\n        proxy = \"socks4://localhost:8086\"\n        res = simple_http_client.request(\"GET\", \"https://github.com/\", proxy=proxy, timeout=15)\n        self.assertEqual(res.status, 200)\n        xlog.info(\"Finished testing SmartRouter SOCKS4 proxy protocol\")\n\n    def smart_route_proxy_socks5(self):\n        xlog.info(\"Start testing SmartRouter SOCKS5 proxy protocol\")\n        proxy = \"socks5://localhost:8086\"\n        res = simple_http_client.request(\"GET\", \"https://github.com/\", proxy=proxy, timeout=15)\n        self.assertEqual(res.status, 200)\n        xlog.info(\"Finished testing SmartRouter SOCKS5 proxy protocol\")\n\n    def smart_route_dns_query(self):\n        xlog.info(\"Start testing SmartRouter DNS Query\")\n        domain = \"appsec.hicloud.com\"\n        d = DNSRecord(DNSHeader(123))\n        d.add_question(DNSQuestion(domain, 1))\n        req4_pack = d.pack()\n\n        for port in [8053, 53]:\n            sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)\n            sock.sendto(req4_pack, (\"127.0.0.1\", port))\n            sock.settimeout(5)\n\n            try:\n                response, server = sock.recvfrom(8192)\n            except Exception as e:\n                xlog.warn(\"recv fail for port:%s e:%r\", port, e)\n                continue\n\n            p = DNSRecord.parse(response)\n            for r in p.rr:\n                ip = utils.to_bytes(str(r.rdata))\n                xlog.info(\"IP:%s\" % ip)\n                self.assertEqual(utils.check_ip_valid(ip), True)\n\n            xlog.info(\"Finished testing SmartRouter DNS Query\")\n            return\n\n    def xtunnel_token_login(self):\n        xlog.info(\"Start testing XTunnel login\")\n        headers = {\n            \"Content-Type\": \"application/json\"\n        }\n        data = {\n            \"login_token\": os.getenv(\"XTUNNEL_TOKEN\"),\n        }\n        data = json.dumps(data)\n        res = simple_http_client.request(\"POST\", \"http://127.0.0.1:8085/module/x_tunnel/control/token_login\",\n                                         headers=headers, body=data, timeout=60)\n        self.assertEqual(res.status, 200)\n        self.xtunnel_login_status = True\n        xlog.info(\"Finished testing XTunnel login\")\n\n    def test_xtunnel_proxy_http(self):\n        xlog.info(\"Start testing XTunnel HTTP proxy protocol\")\n        # if not self.xtunnel_login_status:\n        #     self.xtunnel_token_login()\n        proxy = \"http://localhost:1080\"\n        for _ in range(3):\n            res = simple_http_client.request(\"GET\", \"https://github.com/\", proxy=proxy, timeout=30)\n            if not res:\n                time.sleep(5)\n                continue\n            self.assertEqual(res.status, 200)\n            xlog.info(\"Finished testing XTunnel HTTP proxy protocol\")\n\n        self.assertEqual(res.status, 200)\n\n    def xtunnel_proxy_socks4(self):\n        xlog.info(\"Start testing XTunnel Socks4 proxy protocol\")\n        if not self.xtunnel_login_status:\n            self.xtunnel_token_login()\n        proxy = \"socks4://localhost:1080\"\n        res = simple_http_client.request(\"GET\", \"https://github.com/\", proxy=proxy, timeout=15)\n        self.assertEqual(res.status, 200)\n        xlog.info(\"Finished testing XTunnel Socks4 proxy protocol\")\n\n    def xtunnel_proxy_socks5(self):\n        xlog.info(\"Start testing XTunnel Socks5 proxy protocol\")\n        if not self.xtunnel_login_status:\n            self.xtunnel_token_login()\n        proxy = \"socks5://localhost:1080\"\n        res = simple_http_client.request(\"GET\", \"https://github.com/\", proxy=proxy, timeout=15)\n        self.assertEqual(res.status, 200)\n        xlog.info(\"Finished testing XTunnel Socks5 proxy protocol\")\n"
  },
  {
    "path": "code/default/x_tunnel/web_ui/chatgpt.html",
    "content": "<div >\n\n    <div class=\"row-fluid\">\n        <div class=\"span1\"><strong>{{ _( \"Help\" ) }}</strong></div> <!-- .span4 -->\n        <div class=\"span7\" id=\"about_current_version\"> <a href=\"{{ _( \"https://github.com/XX-net/XX-Net/wiki/ChatGPT_EN\" ) }}\" target=\"_blank\">{{ _( \"ChatGPT Manual\" ) }}</a></div> <!-- .span8 -->\n    </div> <!-- .div.fluid -->\n\n    <div class=\"row-fluid\" id=\"output-area\">\n        <div id=\"output\" class=\"span12\"></div> <!-- #log -->\n    </div>\n\n    <div class=\"row-fluid\" id=\"input-area\">\n        <div class=\"span10\" id=\"input-box\">\n            <textarea id=\"prompt\" rows=\"2\"></textarea>\n        </div> <!-- .span10 -->\n        <div class=\"span2\">\n            <button class=\"btn btn-primary btn-block ask-button\" id=\"ask\" type=\"submit\">\n                <div id=\"submit-text\" >\n                    {{ _( \"Submit\" ) }}\n                </div>\n                <div id=\"submit-loading\" >\n                    <div class=\"lds-facebook\">             <div></div><div></div><div></div></div>\n                </div>\n            </button>\n\n        </div> <!-- .span12 -->\n    </div> <!-- .row-fluid -->\n\n</div> <!-- #log-container -->\n\n<script type=\"text/javascript\">\n    title('{{ _(\"ChatGPT\") }}');\n    $('#submit-loading').addClass('hide');\n</script>\n\n<script>\n    function append_output(text, text_class) {\n        text = text.replace(/\\n/g, \"<br>\");\n        while (text.includes(\"```\")){\n            text = text.replace(\"```\", \"</p><pre>\");\n            text = text.replace(\"```\", '</pre><p class=\"' + text_class + '\">');\n        }\n        var newlines = document.createDocumentFragment();\n        var template = '<p class=\"%s\">%s</p>\\n';\n        var newline = $(template.format(text_class, text));\n        $(newlines).append(newline);\n        $('#output').append(newlines);\n    }\n\n    $('#ask').click(function () {\n        var prompt = $('#prompt').val();\n        console.log(prompt);\n        append_output(prompt, 'prompt_text');\n        $('#prompt').val('');\n\n        const req = {\n            model: \"gpt-3.5-turbo\",\n            // Submit only the role and content of the messages, provide the previous messages as well for context\n            messages: [\n                {\n                    role: \"user\",\n                    content: prompt\n                }\n            ]\n        };\n        $('#submit-text').addClass('hide');\n        $('#submit-loading').removeClass('hide');\n\n        $.ajax({\n            type: 'POST',\n            url: '/openai/v1/chat/completions',\n            data: JSON.stringify(req),\n            dataType: 'JSON',\n            success: function (result) {\n                for (const choice of result['choices']) {\n                    const message = choice[\"message\"];\n                    const content = message[\"content\"];\n                    append_output(content, \"complete_text\");\n                }\n                $('#output').scrollTop($('#output')[0].scrollHeight);\n\n                $('#submit-text').removeClass('hide');\n                $('#submit-loading').addClass('hide');\n            },\n            error: function () {\n                tip('{{ _( \"Call API failed.\" ) }}', 'error');\n                $('#submit-text').removeClass('hide');\n                $('#submit-loading').addClass('hide');\n            }\n        });\n    });\n</script>\n\n\n<style type=\"text/css\">\n#output-area {\n}\n#output {\n    background-color: #f4f6f6;\n    border: 2px solid #d5dbdb;\n    border-radius: 6px;\n    color: #34495e;\n    font-size: 14.994px;\n    line-height: 24px;\n    max-width: 100%;\n    overflow-y: auto;\n    padding: 5px 11px;\n    text-indent: 0;\n    height: calc(100vh - 290px);\n}\n#input-area {\n}\n#input-box {\n    margin-top: 20px;\n}\ndiv#content textarea {\n    height: 60px;\n}\n.prompt_text {\n    color: blue;\n}\n.complete_text {\n    color: green;\n}\n.ask-button {\n    height: 80px;\n}\n#submit-loading{\n  margin-top: -10px;\n}\n.lds-facebook {\n  display: inline-block;\n  position: relative;\n  width: 80px;\n  height: 80px;\n}\n.lds-facebook div {\n  display: inline-block;\n  position: absolute;\n  left: 8px;\n  width: 16px;\n  background: #fff;\n  animation: lds-facebook 1.2s cubic-bezier(0, 0.5, 0.5, 1) infinite;\n}\n.lds-facebook div:nth-child(1) {\n  left: 8px;\n  animation-delay: -0.24s;\n}\n.lds-facebook div:nth-child(2) {\n  left: 32px;\n  animation-delay: -0.12s;\n}\n.lds-facebook div:nth-child(3) {\n  left: 56px;\n  animation-delay: 0;\n}\n@keyframes lds-facebook {\n  0% {\n    top: 8px;\n    height: 64px;\n  }\n  50%, 100% {\n    top: 24px;\n    height: 32px;\n  }\n}\n</style>"
  },
  {
    "path": "code/default/x_tunnel/web_ui/cloudflare_front_logging.html",
    "content": "<div id=\"log-container\" class=\"row-fluid\">\n    <div id=\"log\" class=\"span12\"></div> <!-- #log -->\n</div> <!-- #log-container -->\n\n<script type=\"text/javascript\">\n    title('{{ _(\"Cloudflare\") }}{{ _(\"Front\") }} {{ _(\"Log\") }}');\n</script>\n<style type=\"text/css\">\n    .DUMMY { color: black }\n    .DEBUG { color: #21610b }\n    .INFO { color: blue }\n    .WARNING { color: #ff8000 }\n    .ERROR { color: #fe2e2e }\n    .CRITICAL { color: #d7df01 }\n</style>\n<script type=\"text/javascript\">\n    $(function () {\n        resizeLogWindow();\n    });\n\n    $(window).resize(function () {\n        resizeLogWindow();\n    });\n</script>\n<script type=\"text/javascript\">\n    function resizeLogWindow() {\n        var windowHeight    = $(window).height(),\n            preservedHeight = 170;\n\n        $('#log').css('height', windowHeight - preservedHeight);\n    }\n</script>\n<script type=\"text/javascript\">\n    $(function () {\n        window.previousOffset     = 0;\n        window.offset             = 1;\n        window.logLineNum         = 0;\n        window.isAutoScrollLog    = true;\n        window.isgetLogProcessing = false;\n\n        var timer = $.timer(function () {\n            getLog();\n        });\n        timer.set({\n            time: 500,\n            autostart: true\n        });\n    });\n</script>\n<script type=\"text/javascript\">\n    $(function () {\n        getLog();\n    });\n</script>\n<script type=\"text/javascript\">\n    $('#log').scroll(function () {\n        var preservedHeight = $('#log').height() + 10,\n            scrollHeight    = $('#log')[0].scrollHeight,\n            scrollTop       = $('#log').scrollTop();\n\n        window.isAutoScrollLog = (scrollTop + preservedHeight === scrollHeight);\n    });\n</script>\n<script type=\"text/javascript\">\n    function scrollLog() {\n        if (window.isAutoScrollLog) {\n            $('#log').scrollTop($('#log')[0].scrollHeight);\n        }\n    }\n</script>\n<script type=\"text/javascript\">\n    function getLog() {\n        if (window.isgetLogProcessing) {\n            return;\n        }\n        if (!window.isAutoScrollLog) {\n            return;\n        }\n        window.isgetLogProcessing = true;\n\n        var pageRequests = {\n            'cmd': 'get_new',\n            'last_no': offset\n        };\n        $.ajax({\n            type: 'GET',\n            url: '/module/x_tunnel/control/cloudflare_front/log',\n            data: pageRequests,\n            dataType: 'JSON',\n            success: function (result) {\n                var newlines = document.createDocumentFragment();\n                var newlineNum = 0;\n                $.each(result, function (lineNumber, log) {\n                    window.offset = lineNumber;\n\n                    var logTemplate = '<p class=\"%s\">%s</p>\\n';\n                    if (window.previousOffset != window.offset) {\n                        var newline = $(logTemplate.format(getLogLevel(log), log));\n                        $(newlines).append(newline);\n                        newlineNum += 1;\n                    }\n                });\n                window.logLineNum += newlineNum;\n                $('#log').append(newlines);\n                var maxLineNum = 1000;\n                var cutStep = 10;\n                if (window.logLineNum > maxLineNum + cutStep) {\n                    var numToCut = window.logLineNum - maxLineNum;\n                    var textblock = $('#log').html();\n                    var lines = textblock.split('\\n');\n                    lines.splice(0, numToCut);\n                    var newtext = lines.join('\\n');\n                    $('#log').html(newtext);\n                    window.logLineNum -= numToCut;\n                }\n\n                scrollLog();\n                window.previousOffset = window.offset;\n                window.isgetLogProcessing = false;\n            },\n            error: function (xml, info, obj) {\n                window.isgetLogProcessing = false;\n            }\n        });\n    }\n</script>\n<script type=\"text/javascript\">\n    function getLogLevel(log) {\n        if (log.indexOf('[DEBUG]') != -1) {\n            return 'DEBUG';\n        } else if (log.indexOf('[INFO]') != -1) {\n            return 'INFO';\n        } else if (log.indexOf('[WARNING]') != -1) {\n            return 'WARNING';\n        } else if (log.indexOf('[ERROR]') != -1) {\n            return 'ERROR';\n        } else if (log.indexOf('[CRITICAL]') != -1) {\n            return 'CRITICAL';\n        } else return 'DUMMY';\n    }\n</script>\n"
  },
  {
    "path": "code/default/x_tunnel/web_ui/cloudfront_front_logging.html",
    "content": "<div id=\"log-container\" class=\"row-fluid\">\n    <div id=\"log\" class=\"span12\"></div> <!-- #log -->\n</div> <!-- #log-container -->\n\n<script type=\"text/javascript\">\n    title('{{ _(\"Cloudfront\") }}{{ _(\"Front\") }} {{ _(\"Log\") }}');\n</script>\n<style type=\"text/css\">\n    .DUMMY { color: black }\n    .DEBUG { color: #21610b }\n    .INFO { color: blue }\n    .WARNING { color: #ff8000 }\n    .ERROR { color: #fe2e2e }\n    .CRITICAL { color: #d7df01 }\n</style>\n<script type=\"text/javascript\">\n    $(function () {\n        resizeLogWindow();\n    });\n\n    $(window).resize(function () {\n        resizeLogWindow();\n    });\n</script>\n<script type=\"text/javascript\">\n    function resizeLogWindow() {\n        var windowHeight    = $(window).height(),\n            preservedHeight = 170;\n\n        $('#log').css('height', windowHeight - preservedHeight);\n    }\n</script>\n<script type=\"text/javascript\">\n    $(function () {\n        window.previousOffset     = 0;\n        window.offset             = 1;\n        window.logLineNum         = 0;\n        window.isAutoScrollLog    = true;\n        window.isgetLogProcessing = false;\n\n        var timer = $.timer(function () {\n            getLog();\n        });\n        timer.set({\n            time: 500,\n            autostart: true\n        });\n    });\n</script>\n<script type=\"text/javascript\">\n    $(function () {\n        getLog();\n    });\n</script>\n<script type=\"text/javascript\">\n    $('#log').scroll(function () {\n        var preservedHeight = $('#log').height() + 10,\n            scrollHeight    = $('#log')[0].scrollHeight,\n            scrollTop       = $('#log').scrollTop();\n\n        window.isAutoScrollLog = (scrollTop + preservedHeight === scrollHeight);\n    });\n</script>\n<script type=\"text/javascript\">\n    function scrollLog() {\n        if (window.isAutoScrollLog) {\n            $('#log').scrollTop($('#log')[0].scrollHeight);\n        }\n    }\n</script>\n<script type=\"text/javascript\">\n    function getLog() {\n        if (window.isgetLogProcessing) {\n            return;\n        }\n        if (!window.isAutoScrollLog) {\n            return;\n        }\n        window.isgetLogProcessing = true;\n\n        var pageRequests = {\n            'cmd': 'get_new',\n            'last_no': offset\n        };\n        $.ajax({\n            type: 'GET',\n            url: '/module/x_tunnel/control/cloudfront_front/log',\n            data: pageRequests,\n            dataType: 'JSON',\n            success: function (result) {\n                var newlines = document.createDocumentFragment();\n                var newlineNum = 0;\n                $.each(result, function (lineNumber, log) {\n                    window.offset = lineNumber;\n\n                    var logTemplate = '<p class=\"%s\">%s</p>\\n';\n                    if (window.previousOffset != window.offset) {\n                        var newline = $(logTemplate.format(getLogLevel(log), log));\n                        $(newlines).append(newline);\n                        newlineNum += 1;\n                    }\n                });\n                window.logLineNum += newlineNum;\n                $('#log').append(newlines);\n                var maxLineNum = 1000;\n                var cutStep = 10;\n                if (window.logLineNum > maxLineNum + cutStep) {\n                    var numToCut = window.logLineNum - maxLineNum;\n                    var textblock = $('#log').html();\n                    var lines = textblock.split('\\n');\n                    lines.splice(0, numToCut);\n                    var newtext = lines.join('\\n');\n                    $('#log').html(newtext);\n                    window.logLineNum -= numToCut;\n                }\n\n                scrollLog();\n                window.previousOffset = window.offset;\n                window.isgetLogProcessing = false;\n            },\n            error: function (xml, info, obj) {\n                window.isgetLogProcessing = false;\n            }\n        });\n    }\n</script>\n<script type=\"text/javascript\">\n    function getLogLevel(log) {\n        if (log.indexOf('[DEBUG]') != -1) {\n            return 'DEBUG';\n        } else if (log.indexOf('[INFO]') != -1) {\n            return 'INFO';\n        } else if (log.indexOf('[WARNING]') != -1) {\n            return 'WARNING';\n        } else if (log.indexOf('[ERROR]') != -1) {\n            return 'ERROR';\n        } else if (log.indexOf('[CRITICAL]') != -1) {\n            return 'CRITICAL';\n        } else return 'DUMMY';\n    }\n</script>\n"
  },
  {
    "path": "code/default/x_tunnel/web_ui/config.html",
    "content": "<ul class=\"nav nav-tabs\">\n    <li class=\"\" id=\"li-token-login\"><a href=\"#token-login-tab\" data-toggle=\"tab\">{{ _(\"Token Login\") }}</a></li>\n    <li class=\"\" id=\"li-password-login\" hidden><a href=\"#password-login-tab\" data-toggle=\"tab\">{{ _(\"Password Login\") }}</a></li>\n    <li class=\"hide\" id=\"li-info\"><a href=\"#info\" data-toggle=\"tab\">{{ _(\"Account\") }}</a></li>\n    <li class=\"hide\" id=\"li-setting\"><a href=\"#advanced\" data-toggle=\"tab\">{{ _(\"Settings\") }}</a></li>\n    <li class=\"hide\" id=\"li-plans\"><a href=\"#plans\" data-toggle=\"tab\">{{ _(\"Plans\") }}</a></li>\n    <li class=\"hide\" id=\"li-history\"><a href=\"#history\" data-toggle=\"tab\">{{ _(\"History\") }}</a></li>\n    <li class=\"hide\" id=\"li-help\"><a href=\"#help\" data-toggle=\"tab\">{{ _(\"Help\") }}</a></li>\n</ul>\n<div class=\"tab-content\">\n    <div id=\"token-login-tab\" class=\"tab-pane fade in hide\">\n        <form id=\"token-login-form\" onSubmit=\"onTokenLoginSubmit(); return false;\">\n            <p >{{ _(\"Input login token from https://xx-net.com.\") }}</p>\n            <p>\n                <label for=\"login-token\">{{ _(\"Token\") }}</label>\n                <input id=\"login-token\" type=\"text\"/>\n            </p>\n            <p>\n                <button class=\"btn btn-primary btn-block\" type=\"submit\">{{ _(\"Login\") }}</button>\n            </p>\n        </form> <!-- #login-form -->\n    </div>\n\n    <div id=\"password-login-tab\" class=\"tab-pane fade in \">\n        <form id=\"password-login-form\" onSubmit=\"onLoginSubmit(); return false;\">\n            <h4>{{ _(\"Login\") }}</h4>\n            <p>\n                <label for=\"login-username\">{{ _(\"Email\") }}</label>\n                <input id=\"login-username\" type=\"text\"/>\n            </p>\n            <p>\n                <label for=\"login-password\">{{ _(\"Password\") }}</label>\n                <input id=\"login-password\" type=\"password\"/>\n            </p>\n            <p>\n                <button class=\"btn btn-primary btn-block\" type=\"submit\">{{ _(\"Login\") }}</button>\n            </p>\n            <p class=\"text-center\" hidden>\n                <a id=\"register-trigger\" href=\"javascript:void(0);\">{{ _(\"Haven't an account?\") }}</a>\n            </p>\n            <p class=\"text-center\">\n                <a id=\"reset-password-trigger\" href=\"javascript:void(0);\">{{ _(\"Forget password?\") }}</a>\n            </p>\n        </form> <!-- #login-form -->\n\n        <form id=\"request-reset-form\" class=\"hide\" onSubmit=\"onResetRequest(); return false;\">\n            <h4>{{ _(\"Reset password\") }}</h4>\n            <p class=\"p80\" >\n                <label for=\"request-reset-username\">{{ _(\"Email\") }}</label>\n                <input id=\"request-reset-username\" type=\"text\"/>\n            </p>\n            <p>\n                <button class=\"btn btn-primary btn-block p80\" type=\"submit\">{{ _(\"Next\") }}</button>\n            </p>\n        </form> <!-- #register-form -->\n\n        <form id=\"reset-password-check-form\" class=\"hide\" onSubmit=\"onResetPasswordCheck(); return false;\">\n            <h4>{{ _(\"Input confirmation code\") }}</h4>\n            <p >{{ _(\"The confirmation code has sent to your email, please check your email box.\") }}</p>\n            <p class=\"p80\" >\n                <label for=\"reset-confirmation-code\">{{ _(\"Confirmation Code\") }}</label>\n                <input id=\"reset-confirmation-code\" type=\"text\"/>\n            </p>\n            <p>\n                <button class=\"btn btn-primary btn-block p80\" type=\"submit\">{{ _(\"Next\") }}</button>\n            </p>\n        </form> <!-- #register-form -->\n\n        <form id=\"change-password-form\" class=\"hide\" onSubmit=\"onChangePassword(); return false;\">\n            <h4>{{ _(\"Set new password\") }}</h4>\n            <p >{{ _(\"Please input your new password.\") }}</p>\n            <p class=\"p80\" >\n                <label for=\"new-password\">{{ _(\"Password\") }}</label>\n                <input id=\"new-password\" type=\"password\"/>\n            </p>\n            <p class=\"p80\" >\n                <label for=\"new-password2\">{{ _(\"Confirm your password\") }}</label>\n                <input id=\"new-password2\" type=\"password\"/>\n            </p>\n            <p>\n                <button class=\"btn btn-primary btn-block p80\" type=\"submit\">{{ _(\"Submit\") }}</button>\n            </p>\n        </form> <!-- #register-form -->\n\n        <div id=\"password-reset-successful\" class=\"hide\" >\n            <h4>{{ _(\"Your password has reset successfully.\") }}</h4>\n            <p >{{ _(\"Please use your new password to login.\") }}</p>\n            <p>\n                <button class=\"btn btn-primary btn-block p80\" id=\"goto-login-trigger\">{{ _(\"Login\") }}</button>\n            </p>\n        </div> <!-- #register-form -->\n\n        <form id=\"register-form\" class=\"hide\" onSubmit=\"onRegisterSubmit(); return false;\">\n            <h4>{{ _(\"Register\") }}</h4>\n            <p>\n                <label for=\"register-username\">{{ _(\"Email\") }}</label>\n                <input id=\"register-username\" type=\"text\"/>\n            </p>\n            <p>\n                <label for=\"register-password\">{{ _(\"Password\") }}</label>\n                <input id=\"register-password\" type=\"password\"/>\n            </p>\n            <p>\n                <label for=\"register-promoter\">{{ _(\"Promoter(Optional)\") }}</label>\n                <input id=\"register-promoter\" type=\"text\"/>\n            </p>\n            <p>\n                <button class=\"btn btn-primary btn-block\" type=\"submit\">{{ _(\"Register\") }}</button>\n            </p>\n            <p class=\"text-center\">\n                <a id=\"login-trigger\" href=\"javascript:void(0);\">{{ _(\"Already have an account?\") }}</a>\n            </p>\n        </form> <!-- #register-form -->\n    </div>\n    <div id=\"info\" class=\"tab-pane fade in active\">\n        <div id=\"account-information\" class=\"hide\">\n            <div class=\"section\">\n<!--                <h4>{{ _(\"Summary\") }}</h4>-->\n                <div class=\"row-fluid\">\n                    <div class=\"span2\">\n                        <label for=\"login-account\">{{ _(\"Account\") }}</label>\n                    </div> <!-- .span4 -->\n                    <div class=\"span6\">\n                        <p>\n                            <span id=\"login-account\">N/a</span>\n                            <a id=\"logout-trigger\" href=\"javascript:void(0)\">[{{ _(\"Logout\") }}]</a>\n                        </p>\n                    </div> <!-- .span8 -->\n                </div> <!-- .row-fluid -->\n                <div class=\"row-fluid\">\n                    <div class=\"span2\">\n                        <label for=\"credit\">{{ _(\"Credit\") }}</label>\n                    </div> <!-- .span4 -->\n                    <div class=\"span4\">\n                        <p>\n                            <span id=\"credit\">N/a</span>\n                            <!-- <a id=\"charge-trigger\" href=\"javascript:void(0);\">[{{ _(\"Charge\") }}]</a> -->\n<!--                            <a id=\"transfer-credit-trigger\" href=\"javascript:void(0);\">[{{ _(\"Transfer\") }}]</a>-->\n                        </p>\n                    </div> <!-- .span8 -->\n                </div> <!-- .row-fluid -->\n                <div class=\"row-fluid\">\n                    <div class=\"span2\">\n                        <label for=\"openai_balance\">{{ _(\"OpenAI Credit\") }}</label>\n                    </div> <!-- .span4 -->\n                    <div class=\"span4\">\n                        <p>\n                            <span id=\"openai_balance\">N/a</span>\n                            <!-- <a id=\"charge-trigger\" href=\"javascript:void(0);\">[{{ _(\"Charge\") }}]</a> -->\n<!--                            <a id=\"transfer-credit-trigger\" href=\"javascript:void(0);\">[{{ _(\"Transfer\") }}]</a>-->\n                        </p>\n                    </div> <!-- .span8 -->\n                </div> <!-- .row-fluid -->\n            </div> <!-- .section -->\n            <div class=\"section\">\n                <h4>{{ _(\"Available Plan\") }}:</h4>\n                <p id=\"no-bandwidth\">&nbsp;&nbsp;&nbsp;{{ _(\"No Valid Plan available.\") }}</p>\n                <div id=\"available-plan\">\n                    <table id=\"available-bandwidth\" class=\"table hide\">\n                        <thead>\n                            <tr>\n                                <th>{{ _(\"Expire Time\") }}</th>\n    <!--                            <th>{{ _(\"Left Bandwidth\") }}</th>-->\n                            </tr>\n                        </thead>\n                        <tbody></tbody>\n                    </table>\n                </div>\n            </div> <!-- .section -->\n        </div> <!-- #account-information -->\n    </div> <!-- #info -->\n    <div id=\"advanced\" class=\"tab-pane fade in\">\n        <form id=\"adv-setting\" onSubmit=\"onAdvSettingSubmit(); return false;\">\n            <div class=\"row-fluid\">\n                <div class=\"span3\">\n                    <label for=\"server-selector\">{{ _( \"server\" ) }}</label>\n                </div>\n                <div class=\"span6\">\n                    <select id=\"server-selector\">\n                        <option value=\"auto\">{{ _( \"AUTO\" ) }}</option>\n                    </select>\n                </div>\n            </div>\n            <br/>\n\n            <div class=\"row-fluid\" hidden>\n                <div class=\"span3\">\n                    <label for=\"promoter\">{{ _(\"Promoter (<a href='https://github.com/XX-net/XX-Net/wiki/X-Tunnel-Promote-Plan'>Help</a>)\") }}</label>\n                </div>\n                <div class=\"span6\">\n                    <input id=\"promoter\" type=\"text\"/>\n                </div>\n            </div>\n            <br/>\n\n            <div class=\"row-fluid\">\n                <div class=\"span12\">\n                    <button class=\"btn btn-primary btn-block\" type=\"submit\">{{ _(\"Submit\") }}</button>\n                </div>\n            </div>\n        </form>\n    </div> <!-- #info -->\n    <div id=\"plans\" class=\"tab-pane fade in\" style=\"padding-left:0\">\n        <div class=\"section\">\n            <h4>{{ _(\"Plans and Pricing\") }}</h4>\n            <div class=\"row-fluid\">\n                <ul class=\"thumbnails\" id=\"plan-list\">\n\n                </ul>\n            </div> <!-- .row-fluid -->\n        </div> <!-- .section -->\n        <div class=\"section\" hidden>\n            <h4>{{ _(\"Billing History\") }}</h4>\n            <p id=\"no-billing-history\">{{ _(\"No billing history.\") }}</p>\n            <table id=\"billing-history\" class=\"table hide\">\n                <thead>\n                    <tr>\n                        <th>{{ _(\"Time\") }}</th>\n                        <th>{{ _(\"Description\") }}</th>\n                    </tr>\n                </thead>\n                <tbody></tbody>\n            </table>\n        </div> <!-- .section -->\n    </div> <!-- #plans -->\n    <div id=\"history\" class=\"tab-pane fade in\">\n        <div class=\"row-fluid\">\n            <div class=\"span6\">\n                <h4>{{ _(\"History\") }}</h4>\n            </div> <!-- .span6 -->\n            <div class=\"span6 text-right\">\n                <button class=\"btn btn-primary\" id=\"get-history-button\">{{ _(\"Get\") }}</button>\n            </div> <!-- .span6 -->\n        </div> <!-- .row-fluid -->\n        <table id=\"history-list\" class=\"table table-bordered table-striped\">\n            <thead>\n                <tr>\n                    <th>{{ _(\"Time\") }}</th>\n                    <th>{{ _(\"Action\") }}</th>\n                </tr>\n            </thead>\n            <tbody>\n            </tbody>\n        </table>\n    </div> <!-- #history -->\n    <div id=\"help\" class=\"tab-pane fade in\">\n        <h4>{{ _(\"Help\") }}</h4>\n        <div class=\"row-fluid\">\n            <div class=\"span4\">\n                <label>SOCKS5</label>\n            </div> <!-- .span4 -->\n            <div class=\"span8\">\n                <p>127.0.0.1:1080</p>\n            </div> <!-- .span8 -->\n        </div> <!-- .row-fluid -->\n        <div class=\"row-fluid\">\n            <div class=\"span4\">\n                <label>Wiki</label>\n            </div> <!-- .span4 -->\n            <div class=\"span8\">\n                <p><a href='{{ _( \"https://github.com/XX-net/XX-Net/wiki/How-to-use-XTunnel\" ) }}' target=\"_blank\">X-Tunnel Wiki@GitHub</a></p>\n            </div> <!-- .span8 -->\n        </div> <!-- .row-fluid -->\n\n                <div class=\"row-fluid\">\n                    <div class=\"span4\">\n                        <label for=\"promote_code\">{{ _(\"Promote Code (<a href='https://github.com/XX-net/XX-Net/wiki/X-Tunnel-Promote-Plan'>Help</a>)\") }}</label>\n                    </div> <!-- .span4 -->\n                    <div class=\"span8\">\n                        <p>\n                            <span id=\"promote_code\">N/a</span>\n                        </p>\n                    </div> <!-- .span8 -->\n                    <div class=\"hidden\">\n                            <input type=\"text\" value=\"\" id=\"copyText\">\n                    </div>\n                </div> <!-- .row-fluid -->\n    </div> <!-- #help -->\n</div> <!-- #tab-content -->\n\n<!-- Modals -->\n<form id=\"charge-modal\" class=\"modal hide fade\" action=\"https://www.paypal.com/cgi-bin/webscr\" method=\"POST\" target=\"_blank\">\n    <div class=\"modal-header\">\n        <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-hidden=\"true\">&times;</button>\n        <h5>{{ _(\"Charge\") }}</h5>\n    </div> <!-- .modal-header -->\n    <div class=\"modal-body\">\n        <div class=\"alert alert-warning hide\">{{ _(\"You haven't enough credit. Please charge first.\") }}</div> <!-- .alert-warning -->\n        <!-- Plan Field -->\n        <input type=\"hidden\" name=\"on0\" value=\"Plan\">\n        <label for=\"charge-plan\">{{ _(\"Plan\") }}:</label>\n        <select id=\"charge-plan\" name=\"os0\">\n        </select>\n        <!-- Account Field -->\n        <input type=\"hidden\" name=\"on1\" value=\"account\">\n        <input class=\"login-account\" type=\"hidden\" name=\"os1\">\n    </div> <!-- .modal-body -->\n    <div class=\"modal-footer\">\n        <input type=\"hidden\" name=\"cmd\" value=\"_s-xclick\">\n        <input type=\"hidden\" name=\"hosted_button_id\" value=\"\">\n        <input type=\"hidden\" name=\"currency_code\" value=\"USD\">\n        <a href=\"javascript:void(0);\" class=\"btn\" data-dismiss=\"modal\">{{ _(\"Close\") }}</a>\n        <button class=\"btn btn-primary\">{{ _(\"Buy Now\") }}</button>\n    </div> <!-- .modal-footer -->\n</form> <!-- #charge-modal -->\n\n<div id=\"transfer-credit-modal\" class=\"modal hide fade\">\n    <div class=\"modal-header\">\n        <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-hidden=\"true\">&times;</button>\n        <h5>{{ _(\"Transfer Credit\") }}</h5>\n    </div> <!-- .modal-header -->\n    <div class=\"modal-body\">\n        <div class=\"alert alert-error hide\"></div> <!-- .alert-error -->\n        <p>\n            <label for=\"transfer-credit-username\">{{ _(\"Username transfer to\") }}</label>\n            <input id=\"transfer-credit-username\" type=\"text\" placeholder='{{ _(\"Email Address\") }}'/>\n        </p>\n        <p>\n            <label for=\"transfer-credit-amount\">{{ _(\"Credit to transfer\") }} (<strong>USD</strong>)</label>\n            <input id=\"transfer-credit-amount\" type=\"text\" value=\"0\" onkeyup=\"isDecimalNumber(this)\"/>\n        </p>\n    </div> <!-- .modal-body -->\n    <div class=\"modal-footer\">\n        <a href=\"javascript:void(0);\" class=\"btn\" data-dismiss=\"modal\">{{ _(\"Close\") }}</a>\n        <button class=\"btn btn-primary\">{{ _(\"Transfer\") }}</button>\n    </div> <!-- .modal-footer -->\n</div> <!-- #transfer-credit-modal -->\n\n<div id=\"transfer-bandwidth-modal\" class=\"modal hide fade\">\n    <div class=\"modal-header\">\n        <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-hidden=\"true\">&times;</button>\n        <h5>{{ _(\"Transfer Bandwidth\") }}</h5>\n    </div> <!-- .modal-header -->\n    <div class=\"modal-body\">\n        <div class=\"alert alert-error hide\"></div> <!-- .alert-error -->\n        <p>\n            <label for=\"transfer-bandwidth-username\">{{ _(\"Username transfer to\") }}</label>\n            <input id=\"transfer-bandwidth-username\" type=\"text\" placeholder='{{ _(\"Email Address\") }}'/>\n        </p>\n        <p>\n            <label for=\"transfer-bandwidth-amount\">{{ _(\"Bandwidth to transfer\") }} (<strong>MB</strong>)</label>\n            <input id=\"transfer-bandwidth-amount\" type=\"text\" onkeyup=\"isDecimalNumber(this)\"/>\n        </p>\n    </div> <!-- .modal-body -->\n    <div class=\"modal-footer\">\n        <input type=\"hidden\" id=\"bandwidth-expire-time\">\n        <a href=\"javascript:void(0);\" class=\"btn\" data-dismiss=\"modal\">{{ _(\"Close\") }}</a>\n        <button class=\"btn btn-primary\">{{ _(\"Transfer\") }}</button>\n    </div> <!-- .modal-footer -->\n</div> <!-- #transfer-bandwidth-modal -->\n\n<!-- JavaScript -->\n<script type=\"text/javascript\">\n    title('{{ _( \"X-Tunnel Configuration\" ) }}');\n</script>\n<script type=\"text/javascript\">\n\n    $('a[href=\"#plans\"]').click(function () {\n        window.refresh_timer.stop();\n        AdvSettingInit();\n    });\n\n    $(function () {\n        window.refresh_timer = $.timer(function () {\n            getUserInfo(0);\n        });\n\n        window.refresh_timer.set({\n            time: 1000,\n            autostart: true\n        });\n\n        var force_update = 0;\n        var navigationType = performance.navigation.type;\n        if (navigationType === performance.navigation.TYPE_BACK_FORWARD) {\n            // console.log(\"Back/Forward button\");\n        } else if (navigationType === performance.navigation.TYPE_RELOAD) {\n            console.log(\"Reloaded\");\n            force_update = 1;\n        } else if (navigationType === performance.navigation.TYPE_NAVIGATE) {\n            // console.log(\"Normal navigation\");\n        }\n\n        tip('{{ _(\"Logining ...\") }}', 'info', false);\n        $('button[type=submit]', '#login-form').html('{{ _(\"Please wait ...\") }}');\n        $('button[type=submit]', '#login-form').attr('disabled', 'disabled');\n        getUserInfo(force_update);\n    });\n</script>\n<script type=\"text/javascript\">\n    $('#promote_code').dblclick(function () {\n        var promote_code = $('#promote_code').val();\n        $('#copyText').html(promote_code);\n\n        /* Get the text field */\n        var copyText = document.getElementById(\"copyText\");\n\n        /* Select the text field */\n        copyText.select();\n\n        /* Copy the text inside the text field */\n        document.execCommand(\"copy\");\n\n        tip('{{ _(\"Promote Code copied to Clipboard.\") }} ', 'info', false);\n        window.refresh_timer.stop();\n    });\n</script>\n<!-- Summary -->\n<script type=\"text/javascript\">\n    $('#register-trigger').click(function () {\n        $('#password-login-form').addClass('hide');\n        $('#register-form').removeClass('hide');\n    });\n    $('#reset-password-trigger').click(function () {\n        $('#password-login-form').addClass('hide');\n        $('#request-reset-form').removeClass('hide');\n    });\n    $('#login-trigger').click(function () {\n        $('#register-form').addClass('hide');\n        $('#password-login-form').removeClass('hide');\n    });\n    $('#goto-login-trigger').click(function () {\n        $('#password-reset-successful').addClass('hide');\n        $('#password-login-form').removeClass('hide');\n    });\n</script>\n<script type=\"text/javascript\">\n    var standalone = window.navigator.standalone,\n        userAgent = window.navigator.userAgent.toLowerCase(),\n        safari = /safari/.test( userAgent ),\n        ios = /iphone|ipod|ipad/.test( userAgent );\n    var uiwebview = false;\n\n    if( ios ) {\n        if ( !standalone && safari ) {\n            //browser\n        } else if ( standalone && !safari ) {\n            //standalone\n        } else if ( !standalone && !safari ) {\n            uiwebview = true;\n        };\n    } else {\n        if (typeof window.Android !== \"undefined\"){\n            uiwebview = true;\n        }\n    }\n\n    function show_login_form(){\n        $('ul.nav-tabs > li').addClass('hide');\n        $('#li-token-login').removeClass('hide');\n        $('#li-password-login').removeClass('hide');\n\n        if(uiwebview || true) {\n            $('#li-token-login').addClass('active');\n\n            $('#password-login-tab').addClass('hide');\n\n            $('#token-login-tab').removeClass('hide');\n            $('#token-login-tab').addClass('active');\n        } else {\n            $('#li-password-login').addClass('active');\n\n            $('#token-login-tab').addClass('hide');\n\n            $('#password-login-tab').removeClass('hide');\n            $('#password-login-tab').addClass('active');\n        }\n\n        $('#account-information').addClass('hide');\n    }\n    show_login_form();\n\n    function show_uinfo_menus() {\n        $('#token-login-tab').removeClass('active');\n        $('#password-login-tab').removeClass('active');\n        $('#info').addClass('in');\n        $('#info').addClass('active');\n\n        $('#li-token-login').removeClass('active');\n        $('#li-password-login').removeClass('active');\n        $('#li-token-login').addClass('hide');\n        $('#li-password-login').addClass('hide');\n\n        $('#li-info').removeClass('hide');\n        $('#li-info').addClass('active');\n        $('#li-setting').removeClass('hide');\n        if (!uiwebview) {\n            $('#li-plans').removeClass('hide');\n            $('#li-history').removeClass('hide');\n            $('#li-help').removeClass('hide');\n        }\n    }\n\n    function getUserInfo(force) {\n        var url = '/module/x_tunnel/control/info';\n        if (force) {\n            url = url + \"?force=1\";\n        }\n\n        $.ajax({\n            type: 'GET',\n            url: url,\n            dataType: 'JSON',\n            success: function (result) {\n                if (result['res'] == 'logout') {\n                    tipClose();\n                    $('#login-form').removeClass('hide');\n                    $('#account-information').addClass('hide');\n\n                    $('button[type=submit]', '#login-form').html('{{ _(\"Login\") }}');\n                    $('button[type=submit]', '#login-form').removeAttr('disabled');\n\n                    window.refresh_timer.stop();\n                    return;\n                }\n\n                if (result['res'] == 'login_process') {\n                    tip('{{ _(\"Logining ...\") }}', 'info', false);\n                    window.refresh_timer.play();\n                    return;\n                }\n\n                if (result['res'] != 'success') {\n                    tip('{{ _(\"Connect to server fail:\") }}' + result['reason'], 'warning', false);\n                    $('#login-username').val(result['login_account']);\n                    $('#login-password').val('_HiddenPassword');\n\n                    $('button[type=submit]', '#login-form').html('{{ _(\"Login\") }}');\n                    $('button[type=submit]', '#login-form').removeAttr('disabled');\n\n                    window.refresh_timer.stop();\n\n                    return;\n                }\n\n                tipClose();\n                window.refresh_timer.play();\n\n                show_uinfo_menus();\n\n                $('#account-information').removeClass('hide');\n\n                $('#login-account').html(result['login_account']);\n                $('.login-account').val(result['login_account']);\n                $('#promote_code').html(result['promote_code']);\n                window.promote_code = result['promote_code'];\n                $('#promoter').html(result['promoter']);\n                $('#credit').html(getCreditForHumanReading(result['balance']));\n                $('#openai_balance').html(\"$\" + parseFloat(result['openai_balance']).toFixed(6));\n\n                $('#bandwidth').html(getBandwidthForHumanReading(result['quota']));\n\n                getAvailableBandwidth(result['quota_list']);\n\n                update_paypal_button_id(result['paypal_button_id']);\n                updatePlans(result['plans']);\n\n                window.refresh_timer.stop();\n            }\n        });\n    }\n</script>\n<script type=\"text/javascript\">\n    function getAvailableBandwidth(bandwidthList) {\n        $('#available-bandwidth tbody').empty();\n\n        var has_plan = false;\n        if (bandwidthList['current']) {\n            displayBandwidth(bandwidthList['current']);\n            has_plan = true;\n        }\n        if (bandwidthList['backup']) {\n            bandwidthList['backup'].forEach(function (entry) {\n                displayBandwidth(entry);\n                has_plan = true;\n            });\n        }\n\n        if (has_plan) {\n            $('#no-bandwidth').addClass('hide');\n            $('#available-plan').removeClass('hide');\n            $('#available-bandwidth').removeClass('hide');\n        }else{\n            $('#no-bandwidth').removeClass('hide');\n            $('#available-plan').addClass('hide');\n            $('#available-bandwidthn').addClass('hide');\n        }\n    }\n\n</script>\n<script type=\"text/javascript\">\n    function update_paypal_button_id(id){\n        $('input[name$=\"hosted_button_id\"]').val(id);\n    }\n\n    function plan_compare(a, b){\n        if (a[\"cost\"] > b[\"cost\"]) return 1;\n        if (b[\"cost\"] > a[\"cost\"]) return -1;\n        return 0;\n    }\n\n    function updatePlans(plans) {\n        $('#plan-list').empty();\n        $('#charge-plan').empty();\n\n        var unordered_plans = [];\n        for ( var plan in plans ) {\n            var pe = plans[plan];\n            pe[\"plan\"] = plan;\n            unordered_plans.push(pe);\n        }\n\n        var ordered_plans = unordered_plans.sort(plan_compare);\n\n        //for ( var plan_info in ordered_plans ) {\n        ordered_plans.forEach( function( plan_info ) {\n            var plan = plan_info[\"plan\"];\n            var title = plan_info[\"title\"];\n            var cost = plan_info[\"cost\"];\n            var quota_G = plan_info[\"quota_G\"];\n            var time_limit_month = plan_info[\"time_limit_month\"];\n            var monthly_cost = cost / time_limit_month;\n\n            var text = `<div class=\"plan-block span4\">\n                        <div class=\"thumbnail\">\n                            <div class=\"caption\">\n                                <p class=\"price\" style=\"text-align:center\">\n                                    <font style=\"font-size:2rem\"\n                                        <sup>$</sup>\n                                         %s\n                                     </font>\n                                     {{ _(\"Per Month\") }}\n                                </p>\n\n                                <ul class=\"details\">\n                                    <li>\n                                        <p style=\"text-align:center\">\n                                            %s\n                                            {{ _(\"Months\") }}\n                                        </p>\n                                    </li>\n                                    <li>\n                                        <p style=\"text-align:center\">\n                                            $\n                                            %s\n                                            {{ _(\"Total\") }}\n                                        </p>\n                                    </li>\n                                </ul>\n                                <p>\n                                    <a href=\"javascript:void(0);\" id=\"%s\" title=\"%s\" class=\"btn btn-primary btn-block plan-trigger\">{{ _(\"Buy Now\") }}</a>\n                                </p>\n                            </div> <!-- .caption -->\n                        </div> <!-- .thumbnail -->\n                    </div>`.format(monthly_cost, time_limit_month, cost, plan, title);\n            $('#plan-list').append(text);\n            $('#charge-plan').append('<option value=\"%s\">{{ _(\"%s\") }} $%s</option>'.format(title, title, cost));\n\n        });\n    }\n</script>\n\n<script type=\"text/javascript\">\n    function displayBandwidth(bandwidthRecord) {\n        var expireTime          = bandwidthRecord['end_time'],\n            expireTimeObj       = new Date(expireTime * 1000);\n            expireTimeString    = expireTimeObj.toISOString().substring(0, 10);\n            bandwidth           = getBandwidthForHumanReading(bandwidthRecord['quota']);\n\n        $('#available-bandwidth tbody').append('<tr><td><span class=\"expire-time\" data-value=\"%s\">%s</span></td></tr>'.format(expireTime, expireTimeString));\n    }\n</script>\n<script type=\"text/javascript\">\n    function getCreditForHumanReading(credit) {\n        if (parseFloat(credit) == 0) {\n            $('#transfer-credit-trigger').addClass('hide');\n        } else {\n            $('#transfer-credit-trigger').removeClass('hide');\n        }\n        return '$ ' + parseFloat(credit).toFixed(2);\n    }\n</script>\n<script type=\"text/javascript\">\n    function getBandwidthForHumanReading(bandwidth) {\n        var base        = 1000,\n            bandwidth   = Math.round(bandwidth) / base / base;\n\n        if (bandwidth > base) {\n            bandwidth = bandwidth / base;\n            bandwidth = parseFloat(bandwidth).toFixed(2) + ' GB';\n        } else {\n            bandwidth = parseFloat(bandwidth).toFixed(2) + ' MB';\n        }\n        return bandwidth;\n    }\n</script>\n<script type=\"text/javascript\">\n    function isEmailLegal(email) {\n        var regx = /^(([^<>()[\\]\\\\.,;:\\s@\"]+(\\.[^<>()[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$/;\n        return regx.test(email);\n    }\n\n    function isEmailQualified(email) {\n        if (!isEmailLegal(email)) return false;\n        var host = email.split('@')[1];\n        var weakhosts = ['qq.com', 'sina.cn', 'sina.com', '126.com', '163.com', '163.net', 'yeah.net'];\n        for (var i in weakhosts) {\n            if (host.indexOf(weakhosts[i]) >= 0) {\n                return false;\n            }\n            /*\n            var regx = /^$/;\n            if (regx.test(host)) {\n                return false;\n            }\n            */\n        }\n        return true;\n    }\n\n    function isPswLegal(password) {\n        var regx = /^[a-zA-Z0-9_~!@#$%^&()+\\-*/=.,:;'\"<>\\?\\[\\]\\{\\}]{6,20}$/;\n        return regx.test(password);\n    }\n</script>\n<script type=\"text/javascript\">\n    function onTokenLoginSubmit() {\n        var login_token = $('#login-token').val();\n\n        if (!login_token){\n            tip('{{ _(\"Please input login token.\" )}}', 'error', false);\n            return;\n        }\n\n        tip('{{ _(\"Logining ...\") }}', 'info', false);\n        $('button[type=submit]', '#token-login-form').html('{{ _(\"Please wait ...\") }}');\n        $('button[type=submit]', '#token-login-form').attr('disabled', 'disabled');\n        return doTokenLoginAction(login_token);\n    }\n\n    function doTokenLoginAction(login_token) {\n        var postData = {\n            'login_token': login_token,\n        };\n\n        $.ajax({\n            type: 'POST',\n            url: '/module/x_tunnel/control/token_login',\n            data: postData,\n            dataType: 'JSON',\n            success: function (result) {\n                if (result['res'] == 'success') {\n                    getUserInfo(0);\n                } else {\n                    if (result['reason'] == \"status:'UNKNOWN'\" || result['reason'] == \"status:False\") {\n                        tip('{{ _(\"Connect to server fail, check Front log first.\") }}', 'warning', false);\n                    } else if (result['reason'] == \"auth fail\") {\n                        tip('{{ _(\"Incorrect Email or password.\") }}', 'error', false);\n                    } else if (result['reason'] == \"token invalid\") {\n                        tip('{{ _(\"Invalid token.\") }}', 'error', false);\n                    } else {\n                        tip('{{ _(\"Login fail:\") }}' + result['reason'], 'error', false);\n                    }\n\n                    $('button[type=submit]', '#token-login-form').html('{{ _(\"Login\") }}');\n                    $('button[type=submit]', '#token-login-form').removeAttr('disabled');\n                }\n            }\n        });\n    }\n\n    function onLoginSubmit() {\n        var username = $('#login-username').val(),\n            password = $('#login-password').val();\n\n        if (!isEmailLegal(username)) {\n            tip('{{ _(\"Email seems invalid.\" )}}', 'error', false);\n            return;\n        } else if (password.length < 6) {\n            tip('{{ _(\"Password needs at least 6 characters, and no more than 20.\") }}', 'error', false);\n            return;\n        }\n\n        tip('{{ _(\"Logining ...\") }}', 'info', false);\n        $('button[type=submit]', '#login-form').html('{{ _(\"Please wait ...\") }}');\n        $('button[type=submit]', '#login-form').attr('disabled', 'disabled');\n        return doLoginAction(username, password);\n    }\n    function onResetRequest() {\n        var username = $('#request-reset-username').val();\n\n        if (!isEmailLegal(username)) {\n            tip('{{ _(\"Email seems invalid.\" )}}', 'error', false);\n            return;\n        }\n\n        tip('{{ _(\"Loading ...\") }}', 'info', false);\n        $('button[type=submit]', '#request-reset-form').html('{{ _(\"Please wait ...\") }}');\n        $('button[type=submit]', '#request-reset-form').attr('disabled', 'disabled');\n        return doRequestResetPassword(username);\n    }\n    function onResetPasswordCheck() {\n        var username = $('#request-reset-username').val();\n        var code = $('#reset-confirmation-code').val();\n\n        if (code.length < 6) {\n            tip('{{ _(\"Please input invalid confirmation code.\" )}}', 'error', false);\n            return;\n        }\n\n        tip('{{ _(\"Loading ...\") }}', 'info', false);\n        $('button[type=submit]', '#reset-password-check-form').html('{{ _(\"Please wait ...\") }}');\n        $('button[type=submit]', '#reset-password-check-form').attr('disabled', 'disabled');\n        return doResetPasswordCheck(username, code);\n    }\n    function onChangePassword() {\n        var username = $('#request-reset-username').val();\n        var code = $('#reset-confirmation-code').val();\n        var password = $('#new-password').val();\n        var password2 = $('#new-password2').val();\n\n        if (password.length < 6) {\n            tip('{{ _(\"Password needs at least 6 characters, and no more than 20.\") }}', 'error', false);\n            return;\n        } else if (password != password2) {\n            tip('{{ _(\"Passwords are not match.\") }}', 'error', false);\n            return;\n        }\n\n        tip('{{ _(\"Loading ...\") }}', 'info', false);\n        $('button[type=submit]', '#change-password-form').html('{{ _(\"Please wait ...\") }}');\n        $('button[type=submit]', '#change-password-form').attr('disabled', 'disabled');\n        return doChangePassword(username, code, password);\n    }\n</script>\n<script type=\"text/javascript\">\n    function doLoginAction(username, password) {\n        var postData = {\n            'username': username,\n            'password': password,\n            'is_register': 0\n        };\n\n        $.ajax({\n            type: 'POST',\n            url: '/module/x_tunnel/control/login',\n            data: postData,\n            dataType: 'JSON',\n            success: function (result) {\n                if (result['res'] == 'success') {\n                    getUserInfo(0);\n                } else {\n                    if (result['reason'] == \"status:'UNKNOWN'\" || result['reason'] == \"status:False\") {\n                        tip('{{ _(\"Connect to server fail, check Front log first.\") }}', 'warning', false);\n                    } else if (result['reason'] == \"auth fail\") {\n                        tip('{{ _(\"Incorrect Email or password.\") }}', 'error', false);\n                    } else if (result['reason'] == \"account not exist\") {\n                        tip('{{ _(\"Incorrect Email or password.\") }}', 'error', false);\n                    } else if (result['reason'] == \"status:602\") {\n                        tip('{{ _(\"Login failed, please try login using token.\") }}', 'error', false);\n                    } else {\n                        tip('{{ _(\"Login fail:\") }}' + result['reason'], 'error', false);\n                    }\n\n                    $('button[type=submit]', '#login-form').html('{{ _(\"Login\") }}');\n                    $('button[type=submit]', '#login-form').removeAttr('disabled');\n                }\n            }\n        });\n    }\n    function doRequestResetPassword(username) {\n        var postData = {\n            'stage': \"request_reset_password\",\n            'username': username,\n        };\n\n        $.ajax({\n            type: 'POST',\n            url: '/module/x_tunnel/control/reset_password',\n            data: postData,\n            dataType: 'JSON',\n            success: function (result) {\n                $('button[type=submit]', '#request-reset-form').html('{{ _(\"Next\") }}');\n                $('button[type=submit]', '#request-reset-form').removeAttr('disabled');\n\n                if (result['res'] == 'success') {\n                    $('#request-reset-form').addClass('hide');\n                    $('#reset-password-check-form').removeClass('hide');\n                    tipClose();\n                } else {\n                    if (result['reason'] == \"status:'UNKNOWN'\" || result['reason'] == \"network_fail\") {\n                        tip('{{ _(\"Connect to server fail, check Front log first.\") }}', 'warning', false);\n                    } else if (result['reason'] == \"account not exists\") {\n                        tip('{{ _(\"Account not exist.\") }}', 'error', false);\n                    } else if (result['reason'] == \"try again later\") {\n                        tip('{{ _(\"Try again later.\") }}', 'error', false);\n                    } else {\n                        tip('{{ _(\"Request fail:\") }}' + result['reason'], 'error', false);\n                    }\n                }\n            }\n        });\n    }\n    function doResetPasswordCheck(username, code) {\n        var postData = {\n            'stage': \"reset_password_check\",\n            'username': username,\n            'code': code,\n        };\n\n        $.ajax({\n            type: 'POST',\n            url: '/module/x_tunnel/control/reset_password',\n            data: postData,\n            dataType: 'JSON',\n            success: function (result) {\n                $('button[type=submit]', '#eset-password-check-form').html('{{ _(\"Next\") }}');\n                $('button[type=submit]', '#eset-password-check-form').removeAttr('disabled');\n\n                if (result['res'] == 'success') {\n                    $('#reset-password-check-form').addClass('hide');\n                    $('#change-password-form').removeClass('hide');\n                    tipClose();\n                } else {\n                    if (result['reason'] == \"status:'UNKNOWN'\" || result['reason'] == \"network_fail\") {\n                        tip('{{ _(\"Connect to server fail, check Front log first.\") }}', 'warning', false);\n                    } else if (result['reason'] == \"account not exists\") {\n                        tip('{{ _(\"Account not exist.\") }}', 'error', false);\n                    } else if (result['reason'] == \"code expired\") {\n                        tip('{{ _(\"Confirmation code expired, please restart again.\") }}', 'error', false);\n                    } else if (result['reason'] == \"exceed max retry times\") {\n                        tip('{{ _(\"You have exceeded the retry limitation.\") }}', 'error', false);\n                    } else if (result['reason'] == \"code not match\") {\n                        tip('{{ _(\"The code is not match, please check your code.\") }}', 'error', false);\n                    } else {\n                        tip('{{ _(\"Request fail:\") }}' + result['reason'], 'error', false);\n                    }\n                }\n            }\n        });\n    }\n    function doChangePassword(username, code, password) {\n        var postData = {\n            'stage': \"change_password\",\n            'username': username,\n            'code': code,\n            'password': password,\n        };\n\n        $.ajax({\n            type: 'POST',\n            url: '/module/x_tunnel/control/reset_password',\n            data: postData,\n            dataType: 'JSON',\n            success: function (result) {\n                $('button[type=submit]', '#change-password-form').html('{{ _(\"Submit\") }}');\n                $('button[type=submit]', '#change-password-form').removeAttr('disabled');\n\n                if (result['res'] == 'success') {\n                    $('#change-password-form').addClass('hide');\n                    $('#password-reset-successful').removeClass('hide');\n\n                    $('#request-reset-username').val(\"\");\n                    $('#reset-confirmation-code').val(\"\");\n                    tipClose();\n                } else {\n                    if (result['reason'] == \"status:'UNKNOWN'\" || result['reason'] == \"network_fail\") {\n                        tip('{{ _(\"Connect to server fail, check Front log first.\") }}', 'warning', false);\n                    } else if (result['reason'] == \"account not exists\") {\n                        tip('{{ _(\"Account not exist.\") }}', 'error', false);\n                    } else if (result['reason'] == \"code expired\") {\n                        tip('{{ _(\"Confirmation code expired, please restart again.\") }}', 'error', false);\n                    } else if (result['reason'] == \"exceed max retry times\") {\n                        tip('{{ _(\"You have exceeded the retry limitation.\") }}', 'error', false);\n                    } else if (result['reason'] == \"code not match\") {\n                        tip('{{ _(\"The code is not match, please check your code.\") }}', 'error', false);\n                    } else {\n                        tip('{{ _(\"Request fail:\") }}' + result['reason'], 'error', false);\n                    }\n                }\n            }\n        });\n    }\n</script>\n<script type=\"text/javascript\">\n    function onRegisterSubmit() {\n        var username = $('#register-username').val(),\n            password = $('#register-password').val();\n        var promoter = $('#register-promoter').val();\n\n        if (!isEmailLegal(username)) {\n            tip('{{ _(\"Email seems invalid.\" )}}', 'error', false);\n            return;\n        } else if (!isEmailQualified(username)) {\n            tip('{{ _(\"Do NOT use Chinese-service-provider\\'s Email!\") }}', 'error', false);\n            return;\n        } else if (password.length < 6 || password.length > 20) {\n            tip('{{ _(\"Password needs at least 6 charactors, and no more than 20.\") }}', 'error', false);\n            return;\n        } else if (!isPswLegal(password)) {\n            tip('{{ _(\"Password seems invalid.\") }}{{ _(\"(available:a-zA-Z0-9_~!@#$%^&()+-*/=.,:;\\'\\\"<>\\?[]{})\") }}', 'error', false);\n            return;\n        } else if (promoter.length != 0 && promoter.length != 8) {\n            tip('{{ _(\"Promoter is invalid.\") }}', 'error', false);\n            return;\n        }\n\n        $('button[type=submit]', '#register-form').html('{{ _(\"Please wait ...\") }}');\n        $('button[type=submit]', '#register-form').attr('disabled', 'disabled');\n        return doRegisterAction(username, password, promoter);\n    }\n</script>\n<script type=\"text/javascript\">\n    function doRegisterAction(username, password, promoter) {\n        var postData = {\n            'username': username,\n            'password': password,\n            'promoter': promoter,\n            'is_register': 1\n        };\n\n        $.ajax({\n            type: 'POST',\n            url: '/module/x_tunnel/control/register',\n            data: postData,\n            dataType: 'JSON',\n            success: function (result) {\n                if (result['res'] == 'success') {\n                    // register success, hide '#register-form' and login.\n                    // $('#register-form').addClass('hide');\n                    tip('{{ _(\"Registered successfully, \") }}{{ _(\"Logining ...\") }}', 'info', false);\n\n                    return doLoginAction(username, password);\n                } else {\n                    if (result['reason'] == 'user exist') {\n                        tip('{{ _(\"Email has been taken by another user.\") }}', 'error', false);\n                    } else if (result['reason'] == 'promoter not exist') {\n                        tip('{{ _(\"Promoter not exist, check it or keep it empty.\") }}', 'error', false);\n                    } else {\n                        tip('{{ _(\"Unknown error occurred.\") }}', 'error', false);\n                    }\n\n                    $('button[type=submit]', '#register-form').html('{{ _(\"Register\") }}');\n                    $('button[type=submit]', '#register-form').removeAttr('disabled');\n                }\n            }\n        });\n    }\n</script>\n<script type=\"text/javascript\">\n    $('a[href=\"#advanced\"]').click(function () {\n        window.refresh_timer.stop();\n        AdvSettingInit();\n    });\n\n    function AdvSettingInit() {\n        //$(\"#server-selector\").val('auto');\n        var pageRequests = {'cmd': 'get'};\n        $.ajax({\n            type: 'GET',\n            url: '/module/x_tunnel/control/config',\n            data: pageRequests,\n            dataType: 'JSON',\n            success: function (result) {\n                var server_selector = $(\"#server-selector\");\n                server_selector.find(\"option[value!='auto']\").remove(); //$(\"#server-selector\").empty();\n                var selectable = result['server']['selectable'];\n                for (var i in selectable) {\n                    var record = selectable[i];\n                    var new_option = document.createElement('option');\n                    new_option.value = record[0];\n                    new_option.text = record[1] + ' @ ' + record[2];\n                    server_selector.append(new_option);\n                }\n\n                if (result['server']['available']) {\n                    server_selector.val(result['server']['selected']);\n                } else {\n                    server_selector.val('auto');\n                    tip('{{ _( \"previously selected server nolonger available, automatically try \" ) }}{{_(\"AUTO\")}}', 'error');\n                }\n\n                $('#promoter').val(result['promoter']);\n            },\n            error: function (result) {\n                displayErrorMessage();\n            }\n        });\n    }\n\n    function onAdvSettingSubmit() {\n        $('button[type=submit]', '#adv-setting').html('{{ _(\"Please wait ...\") }}');\n        $('button[type=submit]', '#adv-setting').attr('disabled', 'disabled');\n\n        var server = $(\"#server-selector\").val();\n<!--        var promoter = $(\"#promoter\").val();-->\n<!--        if (promoter.length != 0 && promoter.length != 8) {-->\n<!--            tip('{{ _(\"Promoter is invalid.\") }}', 'error', false);-->\n<!--            window.refresh_timer.stop();-->\n<!--            return;-->\n<!--        }-->\n\n<!--        var promote_code = window.promote_code;-->\n<!--        if (promoter == promote_code){-->\n<!--            tip('{{ _(\"Can\\'t promote yourself.\") }}', 'error', false);-->\n<!--            window.refresh_timer.stop();-->\n<!--            return;-->\n<!--        }-->\n\n        $.ajax({\n            type: 'POST',\n            url: '/module/x_tunnel/control/config?cmd=set',\n            data: {\n                'server': server,\n<!--                'promoter': promoter-->\n            },\n            dataType: 'JSON',\n            success: function (result) {\n                $('button[type=submit]', '#adv-setting').html('{{ _(\"Submit\") }}');\n                $('button[type=submit]', '#adv-setting').removeAttr('disabled');\n\n                if (result['res'] === 'success') {\n                    tip('{{ _(\"Settings saved successfully.\") }}', 'success');\n                } else {\n                    tip('{{ _( \"Failed saving settings: \" ) }}'+ result['reason'], 'error');\n                }\n            },\n            error: function (result) {\n                displayErrorMessage();\n            }\n        });\n    }\n</script>\n<script type=\"text/javascript\">\n    $('#logout-trigger').click(function () {\n        $.ajax({\n            type: 'POST',\n            url: '/module/x_tunnel/control/logout',\n            dataType: 'JSON',\n            success: function (result) {\n                window.refresh_timer.stop();\n\n                show_login_form();\n\n                $('button[type=submit]', '#login-form').html('{{ _(\"Login\") }}');\n                // Fix bugs in Firefox\n                $('button[type=submit]').removeAttr('disabled');\n            },\n            error: function (result) {\n                tip('{{ _(\"Failed to log out.\") }}', false);\n            }\n        });\n    });\n</script>\n<script type=\"text/javascript\">\n    $('#charge-trigger').click(function () {\n        window.refresh_timer.stop();\n        $('.alert-warning', '#charge-modal').addClass('hide');\n        $('#charge-modal').modal();\n    });\n</script>\n<script type=\"text/javascript\">\n    $('.btn-primary', '#charge-modal').click(function () {\n        $(this).attr('disabled', 'disabled');\n        $(this).html('{{ _(\"Please refresh page.\") }}');\n\n        $('#charge-modal').submit();\n    });\n</script>\n<script type=\"text/javascript\">\n    $('#transfer-credit-trigger').click(function () {\n        $('.alert', '#transfer-credit-modal').addClass('hide');\n        $('#transfer-credit-modal').modal();\n    });\n</script>\n<script type=\"text/javascript\">\n    $('.btn-primary', '#transfer-credit-modal').click(function () {\n        var transferAccount = $('#transfer-credit-username').val(),\n            transferAmount  = $('#transfer-credit-amount').val();\n\n        if (!isEmailLegal(transferAccount)) {\n            $('.alert', '#transfer-credit-modal').html('{{ _(\"Transfer username seems not a valid Email address.\") }}');\n            $('.alert', '#transfer-credit-modal').removeClass('hide');\n            return;\n        }\n\n        $('.btn-primary', '#transfer-credit-modal').attr('disabled', 'disabled');\n        $('.btn-primary', '#transfer-credit-modal').html('{{ _(\"Please wait ...\") }}');\n        return doTransferCreditAction(transferAccount, transferAmount);\n    });\n</script>\n<script type=\"text/javascript\">\n    function doTransferCreditAction(transferAccount, transferAmount) {\n        var postData = {\n            'to_account': transferAccount,\n            'amount': transferAmount,\n            'transfer_type': 'balance'\n        };\n\n        $.ajax({\n            type: 'POST',\n            url: '/module/x_tunnel/control/transfer',\n            data: postData,\n            dataType: 'JSON',\n            success: function (result) {\n                if (result['res'] == 'success') {\n                    getUserInfo(1);\n                } else {\n                    $('.alert', '#transfer-credit-modal').html('{{ _(\"Error occurred: \") }}' + result['reason']);\n                    $('.alert', '#transfer-credit-modal').removeClass('hide');\n                }\n                $('.btn-primary', '#transfer-credit-modal').removeAttr('disabled', 'disabled');\n                $('.btn-primary', '#transfer-credit-modal').html('{{ _(\"Transfer\") }}');\n            }\n        });\n    }\n</script>\n<!--<script type=\"text/javascript\">-->\n<!--    $('#available-bandwidth').delegate('a.transfer', 'click', function () {-->\n<!--        var maxAvailableBandwidth = $('.bandwidth', $(this).parent()).html(),-->\n<!--            expireTime            = $('.expire-time', $(this).parent().parent()).attr('data-value');-->\n\n<!--        $('.alert', '#transfer-bandwidth-modal').addClass('hide');-->\n<!--        $('#transfer-bandwidth-amount').attr('placeholder', '{{ _(\"Max Available Bandwidth: \") }}' + maxAvailableBandwidth);-->\n<!--        $('#bandwidth-expire-time').val(expireTime);-->\n\n<!--        $('#transfer-bandwidth-modal').modal();-->\n<!--    });-->\n<!--</script>-->\n<script type=\"text/javascript\">\n    $('.btn-primary', '#transfer-bandwidth-modal').click(function () {\n        var transferAccount = $('#transfer-bandwidth-username').val(),\n            transferAmount  = $('#transfer-bandwidth-amount').val(),\n            expireTime      = $('#bandwidth-expire-time').val();\n\n        if (!isEmailLegal(transferAccount)) {\n            $('.alert', '#transfer-bandwidth-modal').html('{{ _(\"Transfer username seems not a valid Email address.\") }}');\n            $('.alert', '#transfer-bandwidth-modal').removeClass('hide');\n            return;\n        }\n\n        $('.btn-primary', '#transfer-bandwidth-modal').attr('disabled', 'disabled');\n        $('.btn-primary', '#transfer-bandwidth-modal').html('{{ _(\"Please wait ...\") }}');\n        return doTransferBandwidthAction(transferAccount, transferAmount, expireTime);\n    });\n</script>\n<script type=\"text/javascript\">\n    function parseUnit(str) {\n        var out = [0, ''];\n        str = String(str);\n        var num = parseFloat(str, 10);\n        out[0] = num;\n        out[1] = str.match(/[\\d.\\-\\+]*\\s*(.*)/)[1] || '';\n        return out\n    }\n\n    function doTransferBandwidthAction(transferAccount, transferAmount, expireTime) {\n        var amountUnit = parseUnit(transferAmount);\n        if (amountUnit[1].toUpperCase() == \"G\") {\n            var amount = amountUnit[0] * 1000 * 1000 * 1000;\n        } else {\n            var amount = amountUnit[0] * 1000 * 1000;\n        }\n        var postData = {\n            'to_account': transferAccount,\n            'amount': amount,\n            'end_time': expireTime,\n            'transfer_type': 'quota'\n        };\n\n        $.ajax({\n            type: 'POST',\n            url: '/module/x_tunnel/control/transfer',\n            data: postData,\n            dataType: 'JSON',\n            success: function (result) {\n                if (result['res'] == 'success') {\n                    getUserInfo(1);\n                } else {\n                    $('.alert', '#transfer-bandwidth-modal').html('{{ _(\"Error occurred: \") }}' + result['reason']);\n                    $('.alert', '#transfer-bandwidth-modal').removeClass('hide');\n                }\n                $('.btn-primary', '#transfer-bandwidth-modal').removeAttr('disabled', 'disabled');\n                $('.btn-primary', '#transfer-bandwidth-modal').html('{{ _(\"Transfer\") }}');\n            }\n        });\n    }\n</script>\n<script type=\"text/javascript\">\n    function isDecimalNumber(obj) {\n        var amountUnit = parseUnit(obj.value);\n        if (isNaN(amountUnit[0])) {\n            obj.value = '';\n            return;\n        }\n        if (amountUnit[1].toUpperCase() != \"G\" && amountUnit[1].toUpperCase() != \"M\" && amountUnit[1] != \"\") {\n            alert('{{ _(\"Unit should be M or G.\") }}');\n            return;\n        }\n        if (obj != null) {\n            if (amountUnit[0].toString().split('.').length > 1 &&\n                amountUnit[0].toString().split(\".\")[1].length > 2) {\n                alert('{{ _(\"Transfer amount should not more than 2 decimal places.\") }}');\n            }\n        }\n    }\n</script>\n<!-- Plans -->\n<script type=\"text/javascript\">\n    $('body').on('click', '.plan-trigger', function() {\n        var title = $(this).attr('title');\n        var plan = $(this).attr('id');\n        orderPlan(title, plan);\n    });\n\n</script>\n<script type=\"text/javascript\">\n    function orderPlan(planName, planValue) {\n        window.refresh_timer.stop();\n        $.ajax({\n            data: {\n                'product': 'x_tunnel',\n                'plan': planValue\n            },\n            type: 'POST',\n            url: '/module/x_tunnel/control/order',\n            dataType: 'JSON',\n            success: function (result) {\n                if (result['res'] != 'success') {\n                    if (result['reason'] == \"balance not enough\") {\n                        $('#charge-plan', '#charge-modal').val(planName);\n                        //$('.alert-warning', '#charge-modal').removeClass('hide');\n\n                        $('#charge-modal').modal();\n                    } else {\n                        tip('{{ _(\"Failed to order: \") }}' + result['reason'], 'warning', false);\n                    }\n                } else {\n                    getUserInfo(1);\n                    tip('{{ _(\"Order successfully complete.\") }}', 'info', false);\n                }\n            }\n        });\n    }\n</script>\n<script type=\"text/javascript\">\n    function getBillingHistory() {\n        // TODO\n        // Reference: function getHistory()\n        // \n        // $('#billing-history').removeClass('hide');\n        // $('#no-billing-history').addClass('hide');\n    }\n</script>\n<!-- History -->\n<script type=\"text/javascript\">\n    $('#get-history-button').click(function () {\n        getHistory();\n\n        $('#get-history-button').attr('disabled', 'disabled');\n        $('#get-history-button').html('{{ _(\"Please wait ...\") }}');\n    });\n</script>\n<script type=\"text/javascript\">\n    function getHistory() {\n        $('#history-list tbody').empty();\n\n        $.ajax({\n            type: 'GET',\n            data: {\n                'start': 1999999999,\n                'end': 0,\n                'limit': 1000\n            },\n            url: '/module/x_tunnel/control/get_history',\n            dataType: 'JSON',\n            success: function (result) {\n                if (result['res'] != 'success') {\n                    tip('{{ _(\"Get Fail:\") }}' + result['reason'], 'warning', false);\n                } else {\n                    tipClose();\n                }\n\n                result['history'].forEach(function (entry) {\n                    displayHistory(entry);\n                });\n\n                $('#get-history-button').html('{{ _(\"Get\") }}');\n                $('#get-history-button').removeAttr('disabled');\n            }\n        });\n    }\n</script>\n<script type=\"text/javascript\">\n    function displayHistory(item) {\n        var timestamp = item[0];\n        var t = new Date(timestamp*1000);\n        var timeString = t.getFullYear() + \"-\" + (t.getMonth()+1) + \"-\" + t.getDate() + \" \" + t.getHours() + \":\" + t.getMinutes();\n\n        var message = '';\n        for (property in item[1]) {\n            message += property + ':' + item[1][property] + '; ';\n        }\n\n        $('#history-list tbody').append('<tr><td>%s</td><td>%s</td></tr>'.format(timeString, message));\n    }\n</script>\n"
  },
  {
    "path": "code/default/x_tunnel/web_ui/logging.html",
    "content": "<div id=\"log-container\" class=\"row-fluid\">\n    <div id=\"log\" class=\"span12\"></div> <!-- #log -->\n</div> <!-- #log-container -->\n\n<script type=\"text/javascript\">\n    title('{{ _(\"X-Tunnel\") }} {{ _(\"Log\") }}');\n</script>\n<style type=\"text/css\">\n    .DUMMY { color: black }\n    .DEBUG { color: #21610b }\n    .INFO { color: blue }\n    .WARNING { color: #ff8000 }\n    .ERROR { color: #fe2e2e }\n    .CRITICAL { color: #d7df01 }\n</style>\n<script type=\"text/javascript\">\n    $(function () {\n        resizeLogWindow();\n    });\n\n    $(window).resize(function () {\n        resizeLogWindow();\n    });\n</script>\n<script type=\"text/javascript\">\n    function resizeLogWindow() {\n        var windowHeight    = $(window).height(),\n            preservedHeight = 170;\n\n        $('#log').css('height', windowHeight - preservedHeight);\n    }\n</script>\n<script type=\"text/javascript\">\n    $(function () {\n        window.previousOffset     = 0;\n        window.offset             = 1;\n        window.logLineNum         = 0;\n        window.isAutoScrollLog    = true;\n        window.isgetLogProcessing = false;\n\n        var timer = $.timer(function () {\n            getLog();\n        });\n        timer.set({\n            time: 500,\n            autostart: true\n        });\n    });\n</script>\n<script type=\"text/javascript\">\n    $(function () {\n        getLog();\n    });\n</script>\n<script type=\"text/javascript\">\n    $('#log').scroll(function () {\n        var preservedHeight = $('#log').height() + 10,\n            scrollHeight    = $('#log')[0].scrollHeight,\n            scrollTop       = $('#log').scrollTop();\n\n        window.isAutoScrollLog = (scrollTop + preservedHeight === scrollHeight);\n    });\n</script>\n<script type=\"text/javascript\">\n    function scrollLog() {\n        if (window.isAutoScrollLog) {\n            $('#log').scrollTop($('#log')[0].scrollHeight);\n        }\n    }\n</script>\n<script type=\"text/javascript\">\n    function getLog() {\n        if (window.isgetLogProcessing) {\n            return;\n        }\n        if (!window.isAutoScrollLog) {\n            return;\n        }\n        window.isgetLogProcessing = true;\n\n        var pageRequests = {\n            'cmd': 'get_new',\n            'last_no': offset\n        };\n        $.ajax({\n            type: 'GET',\n            url: '/module/x_tunnel/control/log',\n            data: pageRequests,\n            dataType: 'JSON',\n            success: function (result) {\n                var newlines = document.createDocumentFragment();\n                var newlineNum = 0;\n                $.each(result, function (lineNumber, log) {\n                    window.offset = lineNumber;\n\n                    var logTemplate = '<p class=\"%s\">%s</p>\\n';\n                    if (window.previousOffset != window.offset) {\n                        var newline = $(logTemplate.format(getLogLevel(log), log));\n                        $(newlines).append(newline);\n                        newlineNum += 1;\n                    }\n                });\n                window.logLineNum += newlineNum;\n                $('#log').append(newlines);\n                var maxLineNum = 1000;\n                var cutStep = 10;\n                if (window.logLineNum > maxLineNum + cutStep) {\n                    var numToCut = window.logLineNum - maxLineNum;\n                    var textblock = $('#log').html();\n                    var lines = textblock.split('\\n');\n                    lines.splice(0, numToCut);\n                    var newtext = lines.join('\\n');\n                    $('#log').html(newtext);\n                    window.logLineNum -= numToCut;\n                }\n\n                scrollLog();\n                window.previousOffset = window.offset;\n                window.isgetLogProcessing = false;\n            },\n            error: function (xml, info, obj) {\n                window.isgetLogProcessing = false;\n            }\n        });\n    }\n</script>\n<script type=\"text/javascript\">\n    function getLogLevel(log) {\n        if (log.indexOf('[DEBUG]') != -1) {\n            return 'DEBUG';\n        } else if (log.indexOf('[INFO]') != -1) {\n            return 'INFO';\n        } else if (log.indexOf('[WARNING]') != -1) {\n            return 'WARNING';\n        } else if (log.indexOf('[ERROR]') != -1) {\n            return 'ERROR';\n        } else if (log.indexOf('[CRITICAL]') != -1) {\n            return 'CRITICAL';\n        } else return 'DUMMY';\n    }\n</script>\n"
  },
  {
    "path": "code/default/x_tunnel/web_ui/menu.json",
    "content": "{\n  \"module_title\": \"X-Tunnel\",\n  \"menu_sort_id\": 3,\n  \"sub_menus\": {\n    \"1\":{\n      \"title\": \"{{ _( \"Configuration\" ) }}\",\n      \"url\": \"config\"\n    },\n    \"3\":{\n      \"title\": \"{{ _( \"ChatGPT\" ) }}\",\n      \"url\": \"chatgpt\"\n    },\n    \"20\":{\n      \"title\": \"{{ _( \"Status\" ) }}\",\n      \"url\": \"status\"\n    },\n    \"30\":{\n      \"title\": \"{{ _(\"Log\") }}\",\n      \"url\": \"logging\"\n    },\n    \"40\":{\n      \"title\": \"{{ _(\"Cloudflare\") }}{{ _(\"Front\") }}{{ _(\"Log\") }}\",\n      \"url\": \"cloudflare_front_logging\"\n    },\n    \"70\":{\n      \"title\": \"{{ _(\"TLS-Relay\") }}{{ _(\"Front\") }}{{ _(\"Log\") }}\",\n      \"url\": \"tls_relay_front_logging\"\n    },\n    \"80\":{\n      \"title\": \"{{ _(\"Seley\") }}{{ _(\"Front\") }}{{ _(\"Log\") }}\",\n      \"url\": \"seley_front_logging\"\n    }\n  }\n}"
  },
  {
    "path": "code/default/x_tunnel/web_ui/seley_front_logging.html",
    "content": "<div id=\"log-container\" class=\"row-fluid\">\n    <div id=\"log\" class=\"span12\"></div> <!-- #log -->\n</div> <!-- #log-container -->\n\n<script type=\"text/javascript\">\n    title('{{ _(\"Seley\") }}{{ _(\"Front\") }} {{ _(\"Log\") }}');\n</script>\n<style type=\"text/css\">\n    .DUMMY { color: black }\n    .DEBUG { color: #21610b }\n    .INFO { color: blue }\n    .WARNING { color: #ff8000 }\n    .ERROR { color: #fe2e2e }\n    .CRITICAL { color: #d7df01 }\n</style>\n<script type=\"text/javascript\">\n    $(function () {\n        resizeLogWindow();\n    });\n\n    $(window).resize(function () {\n        resizeLogWindow();\n    });\n</script>\n<script type=\"text/javascript\">\n    function resizeLogWindow() {\n        var windowHeight    = $(window).height(),\n            preservedHeight = 170;\n\n        $('#log').css('height', windowHeight - preservedHeight);\n    }\n</script>\n<script type=\"text/javascript\">\n    $(function () {\n        window.previousOffset     = 0;\n        window.offset             = 1;\n        window.logLineNum         = 0;\n        window.isAutoScrollLog    = true;\n        window.isgetLogProcessing = false;\n\n        var timer = $.timer(function () {\n            getLog();\n        });\n        timer.set({\n            time: 500,\n            autostart: true\n        });\n    });\n</script>\n<script type=\"text/javascript\">\n    $(function () {\n        getLog();\n    });\n</script>\n<script type=\"text/javascript\">\n    $('#log').scroll(function () {\n        var preservedHeight = $('#log').height() + 10,\n            scrollHeight    = $('#log')[0].scrollHeight,\n            scrollTop       = $('#log').scrollTop();\n\n        window.isAutoScrollLog = (scrollTop + preservedHeight === scrollHeight);\n    });\n</script>\n<script type=\"text/javascript\">\n    function scrollLog() {\n        if (window.isAutoScrollLog) {\n            $('#log').scrollTop($('#log')[0].scrollHeight);\n        }\n    }\n</script>\n<script type=\"text/javascript\">\n    function getLog() {\n        if (window.isgetLogProcessing) {\n            return;\n        }\n        if (!window.isAutoScrollLog) {\n            return;\n        }\n        window.isgetLogProcessing = true;\n\n        var pageRequests = {\n            'cmd': 'get_new',\n            'last_no': offset\n        };\n        $.ajax({\n            type: 'GET',\n            url: '/module/x_tunnel/control/seley_front/log',\n            data: pageRequests,\n            dataType: 'JSON',\n            success: function (result) {\n                var newlines = document.createDocumentFragment();\n                var newlineNum = 0;\n                $.each(result, function (lineNumber, log) {\n                    window.offset = lineNumber;\n\n                    var logTemplate = '<p class=\"%s\">%s</p>\\n';\n                    if (window.previousOffset != window.offset) {\n                        var newline = $(logTemplate.format(getLogLevel(log), log));\n                        $(newlines).append(newline);\n                        newlineNum += 1;\n                    }\n                });\n                window.logLineNum += newlineNum;\n                $('#log').append(newlines);\n                var maxLineNum = 1000;\n                var cutStep = 10;\n                if (window.logLineNum > maxLineNum + cutStep) {\n                    var numToCut = window.logLineNum - maxLineNum;\n                    var textblock = $('#log').html();\n                    var lines = textblock.split('\\n');\n                    lines.splice(0, numToCut);\n                    var newtext = lines.join('\\n');\n                    $('#log').html(newtext);\n                    window.logLineNum -= numToCut;\n                }\n\n                scrollLog();\n                window.previousOffset = window.offset;\n                window.isgetLogProcessing = false;\n            },\n            error: function (xml, info, obj) {\n                window.isgetLogProcessing = false;\n            }\n        });\n    }\n</script>\n<script type=\"text/javascript\">\n    function getLogLevel(log) {\n        if (log.indexOf('[DEBUG]') != -1) {\n            return 'DEBUG';\n        } else if (log.indexOf('[INFO]') != -1) {\n            return 'INFO';\n        } else if (log.indexOf('[WARNING]') != -1) {\n            return 'WARNING';\n        } else if (log.indexOf('[ERROR]') != -1) {\n            return 'ERROR';\n        } else if (log.indexOf('[CRITICAL]') != -1) {\n            return 'CRITICAL';\n        } else return 'DUMMY';\n    }\n</script>\n"
  },
  {
    "path": "code/default/x_tunnel/web_ui/status.html",
    "content": "<!--[if lte IE 9]>\n<div class=\"alert alert-warning\">\n    {{ _( \"Your browser is obsolete. Partial functionality will not be available.\" ) }}<br>\n    {{ _( \"The latest Chrome browser is recommended.\" ) }}\n</div>\n<![endif]-->\n\n<div id=\"noob-info\" class=\"hide\"></div>\n\n<div id=\"details\">\n    <h4>{{ _( \"Global\" ) }}</h4>\n    <table id=\"global\" class=\"table table-bordered table-striped\">\n        <thead>\n            <tr>\n                <th width=\"25%\">{{ _( \"Property\" ) }}</th>\n                <th>{{ _( \"Value\" ) }}</th>\n            </tr>\n        </thead>\n        <tbody>\n            <tr>\n                <td>{{ _( \"Handle num\" ) }}</td>\n                <td class=\"handle_num\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"Response time\" ) }}</td>\n                <td class=\"rtt\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"Roundtrip num\" ) }}</td>\n                <td class=\"roundtrip_num\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"Slow roundtrip\" ) }}</td>\n                <td class=\"slow_roundtrip\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"Resend\" ) }}</td>\n                <td class=\"resend\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"Timeout roundtrip\" ) }}</td>\n                <td class=\"timeout_roundtrip\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"Speed\" ) }}</td>\n                <td class=\"speed\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"Total use\" ) }}</td>\n                <td class=\"total_traffics\"></td>\n            </tr>\n        </tbody>\n    </table>\n\n    <h4 id=\"gae_title\" hidden>{{ _( \"GAE\" ) }} {{ _( \"Front\" ) }}</h4>\n    <table id=\"gae_front\" class=\"table table-bordered table-striped\" hidden>\n        <thead>\n            <tr>\n                <th width=\"25%\">{{ _( \"Property\" ) }}</th>\n                <th>{{ _( \"Value\" ) }}</th>\n            </tr>\n        </thead>\n        <tbody>\n            <tr>\n                <td>{{ _( \"Score\" ) }}</td>\n                <td class=\"score\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"Success num\" ) }}</td>\n                <td class=\"success_num\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"Fail num\" ) }}</td>\n                <td class=\"fail_num\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"Worker num\" ) }}</td>\n                <td class=\"worker_num\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"Total use\" ) }}</td>\n                <td class=\"total_traffics\"></td>\n            </tr>\n        </tbody>\n    </table>\n\n    <h4>{{ _( \"Cloudflare\" ) }} {{ _( \"Front\" ) }}</h4>\n    <table id=\"cloudflare_front\" class=\"table table-bordered table-striped\">\n        <thead>\n            <tr>\n                <th width=\"25%\">{{ _( \"Property\" ) }}</th>\n                <th>{{ _( \"Value\" ) }}</th>\n            </tr>\n        </thead>\n        <tbody>\n            <tr>\n                <td>{{ _( \"Score\" ) }}</td>\n                <td class=\"score\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"Success num\" ) }}</td>\n                <td class=\"success_num\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"Fail num\" ) }}</td>\n                <td class=\"fail_num\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"Worker num\" ) }}</td>\n                <td class=\"worker_num\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"Total use\" ) }}</td>\n                <td class=\"total_traffics\"></td>\n            </tr>\n        </tbody>\n    </table>\n\n    <h4 hidden>{{ _( \"Cloudfront\" ) }} {{ _( \"Front\" ) }}</h4>\n    <table id=\"cloudfront_front\" class=\"table table-bordered table-striped\" hidden>\n        <thead>\n            <tr>\n                <th width=\"25%\">{{ _( \"Property\" ) }}</th>\n                <th>{{ _( \"Value\" ) }}</th>\n            </tr>\n        </thead>\n        <tbody>\n            <tr>\n                <td>{{ _( \"Score\" ) }}</td>\n                <td class=\"score\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"Success num\" ) }}</td>\n                <td class=\"success_num\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"Fail num\" ) }}</td>\n                <td class=\"fail_num\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"Worker num\" ) }}</td>\n                <td class=\"worker_num\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"Total use\" ) }}</td>\n                <td class=\"total_traffics\"></td>\n            </tr>\n        </tbody>\n    </table>\n\n    <h4>{{ _( \"TLS_Relay\" ) }} {{ _( \"Front\" ) }}</h4>\n    <table id=\"tls_relay_front\" class=\"table table-bordered table-striped\">\n        <thead>\n            <tr>\n                <th width=\"25%\">{{ _( \"Property\" ) }}</th>\n                <th>{{ _( \"Value\" ) }}</th>\n            </tr>\n        </thead>\n        <tbody>\n            <tr>\n                <td>{{ _( \"Score\" ) }}</td>\n                <td class=\"score\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"Success num\" ) }}</td>\n                <td class=\"success_num\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"Fail num\" ) }}</td>\n                <td class=\"fail_num\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"Worker num\" ) }}</td>\n                <td class=\"worker_num\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"Total use\" ) }}</td>\n                <td class=\"total_traffics\"></td>\n            </tr>\n        </tbody>\n    </table>\n\n    <h4>{{ _( \"Seley\" ) }} {{ _( \"Front\" ) }}</h4>\n    <table id=\"seley_front\" class=\"table table-bordered table-striped\">\n        <thead>\n            <tr>\n                <th width=\"25%\">{{ _( \"Property\" ) }}</th>\n                <th>{{ _( \"Value\" ) }}</th>\n            </tr>\n        </thead>\n        <tbody>\n            <tr>\n                <td>{{ _( \"Score\" ) }}</td>\n                <td class=\"score\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"Success num\" ) }}</td>\n                <td class=\"success_num\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"Fail num\" ) }}</td>\n                <td class=\"fail_num\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"Worker num\" ) }}</td>\n                <td class=\"worker_num\"></td>\n            </tr>\n            <tr>\n                <td>{{ _( \"Total use\" ) }}</td>\n                <td class=\"total_traffics\"></td>\n            </tr>\n        </tbody>\n    </table>\n\n</div> <!-- #details -->\n\n<!-- JavaScript -->\n<script type=\"text/javascript\">\n    title('{{ _( \"X-Tunnel Status Info\" ) }}');\n</script>\n<script type=\"text/javascript\">\n    documentReadyToRun.push(function () {\n        var timer = $.timer(function () {\n            if ($(\"#details\").is(\":visible\")) {\n                updateDetailStatus();\n            }\n        });\n\n        timer.set({\n            time: 1000,\n            autostart: true\n        });\n\n        updateDetailStatus();\n    });\n\n</script>\n<script type=\"text/javascript\">\n    function updateProperty(table, key, value) {\n        var item = $('#' + table).find('.' + key);\n        var previousContent = item.html();\n        if (String(previousContent) != String(value)) {\n            item.html(value);\n        }\n    }\n\n    function updateDetailStatus() {\n        $.ajax({\n            type: 'GET',\n            url: '/module/x_tunnel/control/status',\n            dataType: 'JSON',\n            success: function (result) {\n                for (var front in result[\"status\"]) {\n                    for (key in result[\"status\"][front]) {\n                        value = result[\"status\"][front][key];\n                        updateProperty(front, key, value);\n                    }\n                }\n            },\n            error: function (result) {\n                var formValue = $('#sys-platform').html();\n\n                if (tipHasClose()) {\n                    $('html, body').animate({\n                        scrollTop: 0\n                    }, 'slow');\n                }\n\n                if (formValue == '') {\n                    tip('{{ _(\"The status page is empty. Highly likely that \")}}{{ _(\"X-Tunnel\")}}{{ _(\" failed getting started. Please follow \")}}<a href=\"https://github.com/XX-net/XX-Net/wiki/How-to-get-start-error-log\" target=\"_blank\">{{ _(\"guide\")}}</a>{{ _(\" to troubleshoot.\")}}<br>', 'warning', false);\n                }\n            }\n        });\n    }\n</script>\n"
  },
  {
    "path": "code/default/x_tunnel/web_ui/tls_relay_front_logging.html",
    "content": "<div id=\"log-container\" class=\"row-fluid\">\n    <div id=\"log\" class=\"span12\"></div> <!-- #log -->\n</div> <!-- #log-container -->\n\n<script type=\"text/javascript\">\n    title('{{ _(\"TLS-Relay\") }}{{ _(\"Front\") }} {{ _(\"Log\") }}');\n</script>\n<style type=\"text/css\">\n    .DUMMY { color: black }\n    .DEBUG { color: #21610b }\n    .INFO { color: blue }\n    .WARNING { color: #ff8000 }\n    .ERROR { color: #fe2e2e }\n    .CRITICAL { color: #d7df01 }\n</style>\n<script type=\"text/javascript\">\n    $(function () {\n        resizeLogWindow();\n    });\n\n    $(window).resize(function () {\n        resizeLogWindow();\n    });\n</script>\n<script type=\"text/javascript\">\n    function resizeLogWindow() {\n        var windowHeight    = $(window).height(),\n            preservedHeight = 170;\n\n        $('#log').css('height', windowHeight - preservedHeight);\n    }\n</script>\n<script type=\"text/javascript\">\n    $(function () {\n        window.previousOffset     = 0;\n        window.offset             = 1;\n        window.logLineNum         = 0;\n        window.isAutoScrollLog    = true;\n        window.isgetLogProcessing = false;\n\n        var timer = $.timer(function () {\n            getLog();\n        });\n        timer.set({\n            time: 500,\n            autostart: true\n        });\n    });\n</script>\n<script type=\"text/javascript\">\n    $(function () {\n        getLog();\n    });\n</script>\n<script type=\"text/javascript\">\n    $('#log').scroll(function () {\n        var preservedHeight = $('#log').height() + 10,\n            scrollHeight    = $('#log')[0].scrollHeight,\n            scrollTop       = $('#log').scrollTop();\n\n        window.isAutoScrollLog = (scrollTop + preservedHeight === scrollHeight);\n    });\n</script>\n<script type=\"text/javascript\">\n    function scrollLog() {\n        if (window.isAutoScrollLog) {\n            $('#log').scrollTop($('#log')[0].scrollHeight);\n        }\n    }\n</script>\n<script type=\"text/javascript\">\n    function getLog() {\n        if (window.isgetLogProcessing) {\n            return;\n        }\n        if (!window.isAutoScrollLog) {\n            return;\n        }\n        window.isgetLogProcessing = true;\n\n        var pageRequests = {\n            'cmd': 'get_new',\n            'last_no': offset\n        };\n        $.ajax({\n            type: 'GET',\n            url: '/module/x_tunnel/control/tls_relay_front/log',\n            data: pageRequests,\n            dataType: 'JSON',\n            success: function (result) {\n                var newlines = document.createDocumentFragment();\n                var newlineNum = 0;\n                $.each(result, function (lineNumber, log) {\n                    window.offset = lineNumber;\n\n                    var logTemplate = '<p class=\"%s\">%s</p>\\n';\n                    if (window.previousOffset != window.offset) {\n                        var newline = $(logTemplate.format(getLogLevel(log), log));\n                        $(newlines).append(newline);\n                        newlineNum += 1;\n                    }\n                });\n                window.logLineNum += newlineNum;\n                $('#log').append(newlines);\n                var maxLineNum = 1000;\n                var cutStep = 10;\n                if (window.logLineNum > maxLineNum + cutStep) {\n                    var numToCut = window.logLineNum - maxLineNum;\n                    var textblock = $('#log').html();\n                    var lines = textblock.split('\\n');\n                    lines.splice(0, numToCut);\n                    var newtext = lines.join('\\n');\n                    $('#log').html(newtext);\n                    window.logLineNum -= numToCut;\n                }\n\n                scrollLog();\n                window.previousOffset = window.offset;\n                window.isgetLogProcessing = false;\n            },\n            error: function (xml, info, obj) {\n                window.isgetLogProcessing = false;\n            }\n        });\n    }\n</script>\n<script type=\"text/javascript\">\n    function getLogLevel(log) {\n        if (log.indexOf('[DEBUG]') != -1) {\n            return 'DEBUG';\n        } else if (log.indexOf('[INFO]') != -1) {\n            return 'INFO';\n        } else if (log.indexOf('[WARNING]') != -1) {\n            return 'WARNING';\n        } else if (log.indexOf('[ERROR]') != -1) {\n            return 'ERROR';\n        } else if (log.indexOf('[CRITICAL]') != -1) {\n            return 'CRITICAL';\n        } else return 'DUMMY';\n    }\n</script>\n"
  },
  {
    "path": "pytest.ini",
    "content": "[pytest]\nlog_cli = true\nlog_cli_level = ERROR\nlog_level = ERROR\ntimeout = 200\n"
  },
  {
    "path": "requirements.txt",
    "content": "pyOpenSSL\nbabel\njinja2\ngoogletrans==4.0.0-rc1\n"
  },
  {
    "path": "start",
    "content": "#!/bin/sh\n\npath_to_script () {\n  TARGET=\"$1\"\n  BASENAME=\"$(basename \"$TARGET\")\"\n\n  (\n    cd -P \"$(dirname \"$TARGET\")\"\n    if [ -h \"$BASENAME\" ]\n    then\n        path_to_script \"$(readlink \"$BASENAME\")\"\n    else\n        echo \"$PWD\"\n    fi\n  )\n\n}\n\ngoto_script_path() {\n  PATH_TO_SCRIPT=\"$(path_to_script \"$0\")\"\n  # Fails to start if the install path contains spaces, so it must be quoted.\n  cd \"$PATH_TO_SCRIPT\"\n}\n\ngoto_script_path\nif ! type python > /dev/null 2>&1; then\n    PYTHON=\"python3\"\nelif python -V 2>&1| grep -q \"Python 3\" ;then\n    PYTHON=\"python\"\nelse\n    PYTHON=\"python3\"\nfi\n\n\nif [ -f code/version.txt ]; then\n    VERSION=`cat code/version.txt`\nelse\n    VERSION=\"default\"\nfi\n\n\nif [ ! -f \"code/$VERSION/launcher/start.py\" ]; then\n    VERSION=\"default\"\nfi\nREAL_VERSION=`cat code/$VERSION/version.txt`\necho \"Start version:$REAL_VERSION\"\n\n\n# launch xx-net service by ignore hungup signal\nlaunchWithNoHungup() {\n    nohup ${PYTHON} code/${VERSION}/launcher/start.py $@>/dev/null 2>&1 &\n}\n\n# launch xx-net service by hungup signal\nlaunchWithHungup() {\n    ${PYTHON} code/${VERSION}/launcher/start.py $@\n}\n\n\n# check command avalibility\nhas_command() {\n    type $1 > /dev/null 2>&1\n}\n\nopenwrt_setup_env()\n{\n echo \"It is OpenWrt.\"\n #TODO: Setup\n # check mount usb disk\n # install python, python-openssl, ipset to usb device\n # opkg --dest usb install python python-pyopenssl\n # setup dns\n # set auto start\n # echo \"It is openwrt.\"\n}\n\n# Install Packages\n# get operating system name\nos_name=`uname -s`\nif [ $os_name = 'Linux' ]; then\n\n  PYTHON3=\"python3/bin/python3\"\n  if test -f \"$PYTHON3\"; then\n    echo \"Linux using embedded python.\"\n    PYTHON=\"$PYTHON3\"\n  else\n    if ! ${PYTHON} --version 2> /dev/null; then\n        echo 'Installing python3 for your system... Please type in your password if requested'\n        if has_command zypper; then\n            # openSUSE\n            sudo zypper in -y python3\n        elif has_command apt-get; then\n            # Debian or Debian-like\n            sudo apt-get install -y python3\n        elif has_command dnf; then\n            # Fedora\n            sudo dnf install -y python3\n        elif has_command yum; then\n            # RedHat\n            sudo yum install -y python3\n        elif has_command pacman; then\n            # ArchLinux\n            sudo pacman -S --noconfirm python3\n        elif has_command opkg; then\n            # OpenWrt\n            echo \"install python\"\n            opkg install python3 python3\n        fi\n    fi\n  fi\nelif [ $os_name = 'Darwin' ]; then\n\n  PYTHON3=\"python3/bin/python3\"\n  if test -f \"$PYTHON3\"; then\n    echo \"Darwin using embedded python.\"\n    PYTHON=\"$PYTHON3\"\n  else\n    if ! ${PYTHON} -c 'import PyObjCTools, AppKit, SystemConfiguration' 2> /dev/null; then\n      sudo pip3 install -U PyObjC Pillow\n    fi\n  fi\n\n  if [ ! -d \"data/launcher/installed\" ]; then\n    # remove the mask for download file warning\n    xattr -c -r *\n    touch \"data/launcher/installed\"\n  fi\nfi\n\n\nhelp()\n{\necho \"\nUSAGE:\n\nstart -h\n  show help.\n\nstart\n -allow_remote\n   enable remote connect.\n\n -no_mess_system\n   Don't mess the system, include not install CA to browser, not add shortcut to desktop automatically.\n\n -no_popup\n   Don't popup Browser window when start.\n\n -no_systray\n   Don't show systray in task bar.\n\n -f\n   Run in foreground, in Mac will run in background as default.\n\n -hungup\n   start with nohup to run in background.\n\nstart set_iptables [interface]\n  set iptables for transparent proxy.\n  interface   The network interface which will be redirected\n              Default is br-lan\n\nstart unset_iptables [interface]\n\n\n\"\nexit 0\n}\n\n\nset_iptables(){\n    if [ \"$1\" = '' ]; then\n      INF=\"br-lan\"\n    else\n      INF=$1\n    fi\n    echo \"set interface $INF\"\n\n    # TODO: check if rule exist\n\n    iptables -t nat -N REDSOCKS\n    iptables -t nat -A REDSOCKS -d 0.0.0.0/8 -j RETURN\n    iptables -t nat -A REDSOCKS -d 10.0.0.0/8 -j RETURN\n    iptables -t nat -A REDSOCKS -d 127.0.0.0/8 -j RETURN\n    iptables -t nat -A REDSOCKS -d 169.254.0.0/16 -j RETURN\n    iptables -t nat -A REDSOCKS -d 172.16.0.0/12 -j RETURN\n    iptables -t nat -A REDSOCKS -d 192.168.0.0/16 -j RETURN\n    iptables -t nat -A REDSOCKS -d 224.0.0.0/4 -j RETURN\n    iptables -t nat -A REDSOCKS -d 240.0.0.0/4 -j RETURN\n    iptables -t nat -A REDSOCKS -p tcp -j REDIRECT --to-ports 8086\n    iptables -t nat -A PREROUTING --in-interface $INF -p tcp -j REDSOCKS\n    exit 0\n}\n\nunset_iptables(){\n    if [ \"$1\" = '' ]; then\n      INF=\"br-lan\"\n    else\n      INF=$1\n    fi\n\n    iptables -t nat -D PREROUTING --in-interface $INF -p tcp -j REDSOCKS\n    iptables -t nat -D REDSOCKS -d 0.0.0.0/8 -j RETURN\n    iptables -t nat -D REDSOCKS -d 10.0.0.0/8 -j RETURN\n    iptables -t nat -D REDSOCKS -d 127.0.0.0/8 -j RETURN\n    iptables -t nat -D REDSOCKS -d 169.254.0.0/16 -j RETURN\n    iptables -t nat -D REDSOCKS -d 172.16.0.0/12 -j RETURN\n    iptables -t nat -D REDSOCKS -d 192.168.0.0/16 -j RETURN\n    iptables -t nat -D REDSOCKS -d 224.0.0.0/4 -j RETURN\n    iptables -t nat -D REDSOCKS -d 240.0.0.0/4 -j RETURN\n    iptables -t nat -D REDSOCKS -p tcp -j REDIRECT --to-ports 8086\n    iptables -t nat -X REDSOCKS\n}\n\n\nARGS=$@\nif [ $os_name = 'Darwin' ] ; then\n  HANGUP='1'\nelse\n  HANGUP='0'\nfi\n\nwhile [ -n \"$1\" ]; do\ncase $1 in\n\n-h) help;shift 1;;\n-help) help;shift 1;;\n--help) help;shift 1;;\n-\\?) help;shift 1;;\n\n-allow_remote)shift 1;;\n\n-no_mess_system)shift 1;;\n\n-no_popup)shift 1;;\n\n-no_systray)shift 1;;\n\n-f)HANGUP='0'; shift 1;;\n-hungup)HANGUP='1';shift 1;;\n\nset_iptables) set_iptables $2;shift 1;;\n\nunset_iptables) unset_iptables $2;exit 1;;\n\n*) echo \"unknown option $1.\"; exit 1;;\nesac\ndone\n\n# Start Application\nif [ $HANGUP = '1' ]; then\n  echo \"Run XX-Net in background.\"\n  launchWithNoHungup $ARGS\nelse\n  launchWithHungup $ARGS\nfi\n\n"
  },
  {
    "path": "start.bat",
    "content": "SET PYTHONPATH=\nSET PYTHONHOME=\n\"%~dp0%start.vbs\" console\n\n"
  },
  {
    "path": "start.vbs",
    "content": "On Error Resume Next\n\nSub includeFile (fSpec)\n    dim fileSys, file, fileData\n    set fileSys = createObject (\"Scripting.FileSystemObject\")\n    set file = fileSys.openTextFile (fSpec)\n    fileData = file.readAll ()\n    file.close\n    executeGlobal fileData\n    set file = nothing\n    set fileSys = nothing\nEnd Sub\n\n\nSet fso=CreateObject(\"Scripting.FileSystemObject\")\n\nstrCurrentPath = CurrentPath()\nstrVersion = CurrentVersion()\nDim oShell : Set oShell = CreateObject(\"WScript.Shell\")\noShell.CurrentDirectory = strCurrentPath\n\npython_version = \"3\"\npythonDir = \"python\" & python_version & \"\\\"\nIf Not DirIsExist(pythonDir) then\n    includeFile strCurrentPath & \"\\code\\\" & strVersion & \"\\launcher\\download.vbs\"\n    includeFile strCurrentPath & \"\\code\\\" & strVersion & \"\\launcher\\unzip.vbs\"\nEnd If\n\nSub ChangeCurrentPathToRoot()\n    strCurrentPath = CurrentPath()\n\nEnd Sub\n\nFunction PreparePython(download_id)\n    ' Check if python have installed.\n    If DirIsExist(pythonDir) then\n        PreparePython = True\n        Exit Function\n    End If\n\n    CreateDir(\"data\")\n    CreateDir(\"data\\download\")\n\n    py_fn = \"py\" & python_version & \".zip\"\n    url = \"https://raw.githubusercontent.com/XX-net/XX-Net-dev/master/download/\" & py_fn\n    fp = \"data\\download\\\" & py_fn\n    fsize = 6594715\n    If download_id = 1 then\n        call DownloadFile1(url, fp)\n    Elseif download_id = 2 then\n        call DownloadFile2(url, fp)\n    End If\n\n    fs = GetFileSize(fp)\n    if not fs = fsize then\n        PreparePython = False\n        Exit Function\n    end if\n\n    call UnzipFiles(fp, \"data\\download\\py\" & python_version)\n\n    CreateDir(\"python27\")\n    call MoveDir(\"data\\download\\py\" & python_version, pythonDir)\n\n    call RemoveDir(\"data\\download\")\n    PreparePython = True\nEnd Function\n\nFunction DirIsExist(strPath)\n    Set fso = CreateObject(\"Scripting.FileSystemObject\")\n    Set shl = CreateObject(\"WScript.Shell\")\n\n    exists = fso.FolderExists(strPath)\n\n    if (exists) then\n        DirIsExist = True\n    Else\n        DirIsExist = False\n    end if\nEnd Function\n\nFunction CreateDir(strPath)\n    set filesys=CreateObject(\"Scripting.FileSystemObject\")\n    If Not filesys.FolderExists(strPath) Then\n        Set newfolder = filesys.CreateFolder(strPath)\n    End If\nEnd Function\n\nFunction GetFileSize(strPath)\n    set filesys=CreateObject(\"Scripting.FileSystemObject\")\n    GetFileSize = filesys.GetFile(strPath).Size\nEnd Function\n\nFunction GetAbslutePath(path)\n    Dim fso\n    Set fso = CreateObject(\"Scripting.FileSystemObject\")\n    GetAbslutePath = fso.GetAbsolutePathName(path)\nEnd Function\n\nSub UnzipFiles(zipFile, targetDir)\n    'WScript.Echo \"unzip \" & zipFile\n    call Unzip(zipFile, targetDir)\nEnd Sub\n\nSub MoveDir(srcDir, dstDir)\n    srcDir = GetAbslutePath(srcDir)\n    dstDir = GetAbslutePath(dstDir)\n    set fs = CreateObject(\"Scripting.FileSystemObject\")\n    set folder = fs.GetFolder(srcDir)\n    folder.Move dstDir\nEnd Sub\n\nSub RemoveDir(strFolderPath)\n    Dim objFSO, objFolder\n    Set objFSO = CreateObject (\"Scripting.FileSystemObject\")\n    If objFSO.FolderExists(strFolderPath) Then\n        objFSO.DeleteFolder strFolderPath, True\n    End If\nEnd Sub\n\n\npython_is_ready = PreparePython(1)\nIf not python_is_ready then\n    python_is_ready = PreparePython(2)\nEnd If\n\nIf not python_is_ready then\n    WScript.Echo \"XX-Net Download Python Environment fail, Please download Windows version.\"\n    Wscript.Quit\nEnd if\n\n\nFunction CurrentPath()\n    strPath = Wscript.ScriptFullName\n    Set objFSO = CreateObject(\"Scripting.FileSystemObject\")\n    Set objFile = objFSO.GetFile(strPath)\n    CurrentPath = objFSO.GetParentFolderName(objFile)\nEnd Function\n\nFunction CurrentVersion()\n    strCurrentPath = CurrentPath()\n    strVersionFile = strCurrentPath & \"/code/version.txt\"\n\n    Set fso = CreateObject(\"Scripting.FileSystemObject\")\n    If (fso.FileExists(strVersionFile)) Then\n\n        Set objFileToRead = CreateObject(\"Scripting.FileSystemObject\").OpenTextFile(strVersionFile,1)\n        CurrentVersion = objFileToRead.ReadLine()\n\n        version_path = strCurrentPath & \"/code/\" & CurrentVersion & \"/launcher/start.py\"\n        If( Not fso.FileExists(version_path) ) Then\n            CurrentVersion = \"default\"\n        End If\n\n        objFileToRead.Close\n        Set objFileToRead = Nothing\n    Else\n       CurrentVersion = \"default\"\n    End If\n\nEnd Function\n\n\nFunction isConsole()\n    Set objArgs = Wscript.Arguments\n    'WScript.Echo objArgs.Count\n    'WScript.Echo objArgs(0)\n    isConsole = 0\n    If objArgs.Count > 0 Then\n        if objArgs(0) = \"console\" Then\n            isConsole = 1\n        End If\n    End If\nEnd Function\n\n\nDim strArgs\nquo = \"\"\"\"\n\nIf isConsole() Then\n    python_cmd = \"python.exe\"\nElse\n    python_cmd = \"pythonw.exe\"\nEnd If\n\nstrExecutable = quo & strCurrentPath & \"\\\" & pythonDir & python_cmd & quo\nstrArgs = strExecutable & \" \" & quo & strCurrentPath & \"\\code\\\" & strVersion & \"\\launcher\\start.py\" & quo\nRunningLockFn = strCurrentPath & \"\\data\\launcher\\Running.Lck\"\n'WScript.Echo strArgs\n\nSet fso = CreateObject(\"Scripting.FileSystemObject\")\nSet oShell = CreateObject (\"Wscript.Shell\")\noShell.Environment(\"Process\")(\"PYTHONPATH\")=\"\"\noShell.Environment(\"Process\")(\"PYTHONHOME\")=\"\"\nDo\n    StartTime = Timer\n    oShell.Run strArgs, isConsole(), true\n    EndTime = Timer\n    run_cost = EndTime - StartTime\nLoop Until (not fso.FileExists(RunningLockFn)) or run_cost < 20\n"
  },
  {
    "path": "xx_net.sh",
    "content": "#!/bin/bash\n#\n# xx_net init script\n#\n\n### BEGIN INIT INFO\n# Provides:          xx_net\n# Required-Start:    $syslog\n# Required-Stop:     $syslog\n# Should-Start:      $local_fs\n# Should-Stop:       $local_fs\n# Default-Start:     2 3 4 5\n# Default-Stop:      0 1 6\n# Short-Description: Monitor for xx_net activity\n### END INIT INFO\n\n# **NOTE** bash will exit immediately if any command exits with non-zero.\nset -e\n\nPACKAGE_NAME=xx_net\nPACKAGE_DESC=\"XX-Net proxy server\"\nPATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:${PATH}\n\n\nif [ -L $0 ];then\n       PACKAGE_PATH=\"$(dirname $(readlink -n $0))/\"                                         \nelse\n    PACKAGE_PATH=`dirname $0`\nfi\ncd $PACKAGE_PATH\nPACKAGE_PATH=\"`pwd `/\"\nPACKAGE_START=\"${PACKAGE_PATH}start\"\n\n\nstart() {\n    echo -n \"Starting ${PACKAGE_DESC}: \"\n    nohup ${PACKAGE_START} >/dev/null 2>&1 &\n    echo \"${PACKAGE_NAME}.\"\n}\n\nstop() {\n    echo -n \"Stopping ${PACKAGE_DESC}: \"\n    kill -9 `ps aux | grep \"${PACKAGE_START}\" | grep -v grep | awk '{print $2}'` || true\n    kill -9 `ps aux | grep \"launcher/start.py\" | grep -v grep | awk '{print $2}'` || true\n    echo \"${PACKAGE_NAME}.\"\n}\n\nstatus() {\n    pid=\"PID`ps aux | grep \"${PACKAGE_START}\" | grep -v grep | awk '{print $2}'`\"\n    if [[ \"$pid\" == \"PID\" ]];then\n        echo \"xx-net stopped\"\n    else\n        echo \"xx-net running,pid: ${pid##\"PID\"}\"\n    fi\n}   \n\nrestart() {\n    stop\n    sleep 1\n    start\n}\n\nusage() {\n    N=$(basename \"$0\")\n    echo \"Usage: [sudo] $N {start|stop|restart|status}\" >&2\n    exit 1\n}\n\nif [ \"$(id -u)\" != \"0\" ]; then\n    echo \"please use sudo to run ${PACKAGE_NAME}\"\n    exit 0\nfi\n\n\ncase \"$1\" in\n    # If no arg is given, start the goagent.\n    # If arg `start` is given, also start goagent.\n    '' | start)\n        start\n        ;;\n    stop)\n        stop\n        ;;\n    #reload)\n    restart | force-reload)\n        restart\n        ;;\n       status)\n        status\n        ;;\n    *)\n        usage\n        ;;\nesac\n\nexit 0\n"
  }
]